dsh-asc-cli
Manifest valid★ 1ASC for DeepSeek Harness
Ship to TestFlight, check release readiness, triage feedback and audit compliance — from a conversation.
English | 中文
Current npm release: 0.2.0, verified with DeepSeek Harness 0.2.1-rc.5 and asc 6.3.0. See the changelog and upgrade steps.
App Store Connect is where iOS releases happen — and where teams lose hours to CLI flags, JSON blobs, half-documented states and approval rituals. This plugin puts it inside DeepSeek Harness: install once, ask in plain language, and the agent runs the right workflow, showing a plan and stopping for approval before anything ships.
The asc CLI (MIT, Go) remains the engine. This plugin is the product layer around it: five task-shaped jobs, a small read / plan / apply tool surface, bundled skills that teach the agent how to use it, and an engine manager that diagnoses, provisions and version-checks asc.
dsh plugin --profile desktop add @sleep9ull/dsh-asc-cli@0.2.0
The source tree includes unreleased version notices and maintenance tooling described below; npm
0.2.0does not include these additions yet./ascin this source version is a lightweight engine/capabilities card; use/asc-doctorfor authentication diagnostics.
What you can do
| Ask in the chat | What the plugin runs |
|---|---|
| "Is 1.2.3 ready to submit? Show blockers and fixes." | release-check — asc validate, then an ordered remediation list |
| "Ship this build to the Internal Testers group." | ship-testflight — upload, wait for processing, add the build to a group |
| "Prepare 1.2.3 with this metadata, but don't submit." | stage-release — validate, attach the build, apply metadata, stop before submission |
| "What are testers complaining about?" | triage-feedback — TestFlight feedback + crashes + reviews, clustered |
| "Are we compliant? Age rating, encryption, accessibility, pricing." | compliance-sweep — four read-only probes, best-effort |
| "Anything else — certificates, users, analytics, ads, raw API." | asc reads, discover to find commands, run for the long tail |
Every write follows the same shape: plan first → confirm: true → host approval → execute → auditable result.
Quick start
1 · Install the plugin
Open DeepSeek Harness Desktop once to initialize its profile, then fully quit it before installing. The command below installs 0.2.0; replace desktop with your profile name if you use another profile.
dsh plugin --profile desktop add @sleep9ull/dsh-asc-cli@0.2.0
Restart or reload the profile. The plugin inserts one row (mode: read-only) into the profile's cordis.patch.yml.
2 · Get the engine ready
brew install asc # or: curl -fsSL https://asccli.sh/install | bash
asc auth login --name "MyApp" --key-id ABC123 --issuer-id DEF456 --private-key /path/to/AuthKey.p8
Then run /asc — or ask the agent to run asc_setup with action diagnose. Nothing ready yet? The report gives exactly one next step. Do not paste a private key into the chat; authentication stays in your terminal.
Prefer the plugin to fetch the engine? Enable allowProvision and run asc_setup action provision: it downloads the pinned asc, verifies the released SHA-256, and caches it under $DSH_HOME/cache/asc-cli/.
3 · Just ask
List my apps and pick com.example.focus. Set it as the default app.
Is 1.2.3 ready to submit? Show the blockers in priority order.
Upload ./build/Focus.ipa as 1.2.3 build 42 to the Internal Testers group.
The third request runs the ship-testflight job. dryRun: true previews the upload and skips processing/group assignment, but upstream may contact App Store Connect to reserve upload operations; the write approval gate still applies.
What's inside
Five jobs
asc_job is the preferred entry point: one call, a plan-shaped result, per-step summaries, and a dry-run path where it matters.
| Job | Risk | Does |
|---|---|---|
release-check | read | Runs asc validate; returns blocking counts and ordered fixes |
ship-testflight | write | Uploads .ipa/.pkg (waits), extracts the build id, adds it to a TestFlight group; optional beta review |
stage-release | write | Validates, then prepares the version (metadata + build) without submitting |
triage-feedback | read | Aggregates TestFlight feedback, crashes and reviews |
compliance-sweep | read | Probes age rating, encryption declarations, accessibility, current pricing |
Write jobs need mode: write, confirm: true and a host approval.
Five tools
| Tool | Shape | Use for |
|---|---|---|
asc_job | task | Whole workflows (the five jobs above) |
asc | read | apps, builds, TestFlight, reviews, offline metadata validation, plus discover and run |
asc_plan | plan | validate, status, metadata-plan — never mutates App Store Connect |
asc_apply | write | upload, groups, metadata-init, metadata-apply, stage, publish |
asc_setup | environment | version, auth status, doctor, system status, diagnose, provision, install skills |
Commands
| Command | What it shows |
|---|---|
/asc | Lightweight card: engine/version notice, default app, five jobs; authentication is not checked |
/asc-doctor | Full diagnosis: binary/source, declared support range and verified pin, auth, default app, provisioning, upstream update |
Commands run directly in the host and do not create model messages.
Six bundled skills
Shipped inside the package, available right after install — no git, no global skill directory:
dsh-asc-quickstart · dsh-asc-auth · dsh-asc-release-readiness · dsh-asc-testflight-ship · dsh-asc-feedback-triage · dsh-asc-compliance-sweep
They cover first-run choices, authentication and CI, release readiness, TestFlight shipping, feedback triage and compliance — in the terms of this plugin's tools.
Engine manager
| Step | What happens |
|---|---|
| Locate | ascPath → ASC_CLI_PATH → plugin cache → PATH |
| Diagnose | version, declared range and verified pin, auth, default app, provisioning — one next step |
| Provision | optional: pinned asc 6.3.0, SHA-256 verified, cached per platform |
| Update | ordinary calls and /asc show source-aware advisories; /asc-doctor shows full facts; never upgrades itself |
With checkUpdates: true (the existing default), allowed calls can query the public GitHub release endpoint. Successful queries stay in memory for 24 hours; failures back off for 15 minutes. Ordinary calls wait at most one extra second, and checks have a five-second deadline. Notices preserve business success/failure and appear once per session/version combination; jobs show one top-level notice. Set checkUpdates: false to disable automatic checks and remote version queries; explicit local version/diagnostic commands still work.
The verified recommendation is the plugin's pin, not an untested latest release. Guidance follows the executable actually selected: configured path, environment, plugin cache or PATH. A Homebrew upgrade may not affect a configured/cached binary. Update checks no longer read or write update-check.json; old files remain untouched, and restarting the plugin may query again.
Developer maintenance is documented in MAINTENANCE: a local Desktop task plus repository scripts, GitHub gates and resumable main synchronization. Deployment and persistent write authorization are separate from installing the plugin; this does not publish npm releases automatically.
Documentation
| Document | Covers |
|---|---|
| Contract | What the plugin promises and refuses, the policy matrix, the ten invariants |
| Commands | Tools, actions, jobs, skills, slash commands, config, result shape |
| Architecture | Layers, module map, data flow, extension points |
| Testing | Test patterns, fixtures, known gaps |
| Contributing | Setup, Git flow, quality gates, release steps |
| Specs | Spec-first workflow and the spec index |
| Roadmap | Version plan and acceptance targets |
| ASC CLI reference | Upstream asc command catalog and workflow recipes (generated by asc init) |
Why a plugin instead of "just run asc in bash"?
- Approvals, not vibes. Read-only by default; writes need an explicit
confirmand a human approval. The model can't self-approve. - Plans before actions.
validate,statusand--dry-runare first-class, so the agent shows the change before making it. - Results fit in a conversation. Summaries, ordered fixes and counters replace huge JSON; oversized payloads are omitted with a next step (and a spill pointer only when the raw output was truncated).
- Jobs, not command soup. Upload → wait → group is one deterministic call, not five that the model might reorder.
- The agent already knows the workflow. Bundled skills explain jobs, policies and failure recovery.
- Auditable. Opt-in JSONL audit trail of every tool-initiated
ascinvocation (engine probes excluded); approval decisions stay in the harness session log.
Safety model
- Read-only mode (default). Every call gets
--read-onlyandASC_READ_ONLY=1; mutations are refused before a child process starts. - Write mode. Mutations require
confirm: trueand (by default) a host approval prompt. The plugin adds--confirmto the underlying command only when the model passesconfirm: true; it never invents confirmation. - Unknown commands are never silent. Commands that cannot be proven read-only are escalated to a human (
ask) or refused (unknownCommands: deny); write mode additionally requiresconfirm. Adding--report-filekeeps that policy and also requires confirmation for the file write. Global flags before the command cannot hide a forbidden command. - Invalid arguments fail before approval. Registered actions/jobs validate their flag combinations (exclusive flags, required metadata source, package requirements) before a confirm prompt or a human approval, so a bad call never costs an approval round-trip.
- Local writes need confirmation and approval.
metadata init/plan/pull,docs init,doctor --fix,builds dsyms,install-skills, and every file-writingdownload/exportleaf (screenshots download,profiles download,certificates export, ...). - No value expansion by default.
ascexpands@env:/@file:in flag values; the plugin escapes a leading@unlessallowValueExpansion: true. - Credentials stay outside the model. The plugin forwards
ASC_KEY_ID,ASC_ISSUER_ID,ASC_PRIVATE_KEY_PATH,ASC_PRIVATE_KEYbecause the harness scrubs credential-shaped variables, never reads, stores or prints key material, and tombstonesASC_WEB_SESSIONso a web-session cookie never reaches the child. - Always refused:
auth login/logout,asc web, andversions phased-release guard; commands the classifier cannot prove read-only are escalated to a human (unknownCommands: ask) or refused (deny). - No shell. argv is passed as an array; diagnostics are redacted; telemetry is off by default.
- Opt-in governance.
auditLogrecords what ran;approvedActionscan skip the prompt for known actions in write mode only.
Requirements
| Requirement | Version |
|---|---|
| DeepSeek Harness | 0.2.1-rc.5 line (engines.dsh: >=0.2.1-rc.5 <0.2.2-0) |
| Node.js | ^22.19.0 || >=24.0.0 (24 recommended) |
asc | verified baseline 6.3.0; support line >=6.3.0 <7.0.0 (/asc-doctor reports drift) |
| App Store Connect API key | team or individual key, authenticated outside the agent |
Configuration
Override the asc-tools row in ~/.dsh/profiles/<profile>/cordis.patch.yml. A patch replaces the whole config, so restate every key you need:
- id: asc-tools
name: '@sleep9ull/dsh-asc-cli'
config:
mode: write # required for uploads / submissions / metadata apply
requireApproval: true
profile: MyApp # asc --profile
defaultAppId: "123456789"
allowProvision: true # optional: let the plugin fetch the pinned engine
| Field | Default | Meaning |
|---|---|---|
mode | "read-only" | read-only or write |
requireApproval | true | Ask the host approval service before writes |
ascPath | "asc" | asc executable (PATH name or absolute path) |
profile | — | asc --profile |
defaultAppId | — | Fallback when a tool call omits app |
timeoutMs | 60000 | Ordinary command timeout |
longTimeoutMs | 1800000 | Uploads and release waits |
maxOutputBytes | 262144 | stdout cap before spill |
maxDataBytes | 8000 | Omit data above this JSON size (dataOmitted) |
workdir | — | Override the session working directory |
allowValueExpansion | false | Allow asc's @env: / @file: expansion |
unknownCommands | "ask" | ask or deny for commands that cannot be proven read-only |
allowProvision | false | Allow asc_setup action provision |
cacheDir | — | Override the provisioned-binary cache; relative paths resolve against the host process directory |
bypassKeychain | false | Set ASC_BYPASS_KEYCHAIN=1 (CI / headless) |
telemetryDisabled | true | Set ASC_TELEMETRY_DISABLED=1 |
auditLog | — | Append one JSONL audit line per executed invocation |
approvedActions | [] | Glob labels that skip the approval prompt in write mode |
checkUpdates | true | Automatic version notices and public GitHub release queries; false retains explicit local diagnosis |
env | {} | Extra environment for asc |
Skills
The package ships six skills at the bundled rank (600). Priority is: project .dsh/skills (100) → project .agents/skills (200) → custom (300) → ~/.dsh/skills (400) → ~/.agents/skills (500) → bundled (600). A skill you install yourself therefore wins a same-named bundled one — built-in fallback, user override.
Want the official 25-skill ASC pack as well?
asc install-skills # writes ~/.agents/skills, which DeepSeek Harness reads
DeepSeek Harness scans <project>/.dsh/skills, <project>/.agents/skills, customSkillDirs, ~/.dsh/skills, ~/.agents/skills and $DSH_BUNDLED_SKILL_DIR. ~/.claude/skills is not scanned.
Upgrading from 0.1.6 to 0.2.0
After upgrading DeepSeek Harness to 0.2.1-rc.5, fully quit Desktop and update the plugin in the profile where it is installed:
dsh plugin --profile desktop add @sleep9ull/dsh-asc-cli@0.2.0
Reopen Desktop or reload your profile, then run /asc and /asc-doctor to check the resolved engine, authentication and compatibility. Review your asc-tools configuration before enabling write workflows.
0.2.0 targets the current default upstream releases: DeepSeek Harness 0.2.1-rc.5 and asc 6.3.0. Upgrade the harness and engine, or explicitly provision the new engine after enabling allowProvision. Tool and job names stay the same. The supported asc line is >=6.3.0 <7.0.0; 6.3.0 is the version verified for this release, and daily upstream checks detect later drift. Independent alpha releases and unpublished upstream branches are outside this baseline.
File-producing flags such as --report-file, --save-logs and --write-state require confirmation and approval. publish rejects .ipa with MAC_OS before approval; use .pkg for macOS. versions phased-release guard is refused because it executes a caller-selected local program, including in dry-run mode.
The approval gate uses the host's final guard and a receipt from actual human approval, so another pre-execute listener cannot silently waive the plugin policy. Engine diagnostics, ordinary tools and jobs now resolve the same configured or cached binary.
Upgrading from 0.1.3
0.1.4 consolidated the tool surface. Old tools are gone; use this mapping:
| 0.1.3 | 0.1.4 |
|---|---|
asc_search | asc action discover |
asc_run | asc action run |
asc_apps list/view | asc apps-list/apps-view |
asc_builds list/next-number | asc builds-list/builds-next-number |
asc_builds upload/add-groups | asc_apply upload/groups |
asc_testflight feedback/crashes/groups | asc testflight-feedback/-crashes/-groups |
asc_metadata validate | asc metadata-validate |
asc_metadata init/plan/apply | asc_apply metadata-init; asc_plan metadata-plan; asc_apply metadata-apply |
asc_release status/validate/stage/publish | asc_plan status/validate; asc_apply stage/publish |
asc_job and asc_setup keep their names; jobs gained compliance-sweep.
Troubleshooting
| Symptom | Fix |
|---|---|
/asc says the binary is missing | brew install asc, or set ascPath, or enable allowProvision and run asc_setup provision |
| Auth error / exit 3 | asc auth status --validate in a terminal; check the key's role in App Store Connect |
| Keychain prompt hangs | authenticate in a terminal first, or set bypassKeychain: true |
| Write operation refused | still read-only: switch the asc-tools row to mode: write, then retry with confirm: true |
| Version drift warning | /asc-doctor shows installed, verified pin, support range and upstream latest; follow guidance for the selected source. An unverified latest is informational. |
| Large result | dataOmitted: the payload was dropped from the result — narrow the query. spillPath appears only when raw output was truncated and saved. |
| Unknown command asks for approval | expected; set unknownCommands: deny to refuse instead |
| pnpm peer warnings on install | expected: the harness provides @deepseek-ai/* peers at runtime |
Development
npm install
npm run build # clean + tsc -> lib/
npm run typecheck
npm test # vitest
node scripts/download-asc.mjs # download the baseline and verify SHA-256
npm run verify # typecheck, tests, build, pack, combos, contract, classify, smoke
npm run verify -- --unit-only # explicitly omit engine gates
node scripts/contract.mjs ./vendor/asc # contract test against a real asc binary
node scripts/smoke.mjs # real Harness subprocess; isolated offline engine smoke
# install a local build into a profile
npm pack && dsh plugin --profile desktop add ./sleep9ull-dsh-asc-cli-*.tgz
# separate dev instance with this checkout mounted
node scripts/dev-patch.mjs
dsh web --patch ./vendor/cordis.dev.patch.yml --no-open --port 3199
vendor/asc is git-ignored. Full verification requires the checksum-verified baseline binary; --unit-only explicitly leaves engine gates unverified. Ordinary CI checks the pinned baseline; nightly monitoring checks the latest release with contract, classification and offline smoke gates. Development overlays use absolute paths from the current checkout.
License
MIT
Comments
Loading…