# Agent Knock Knock for DeepSeek Harness This package is the native DeepSeek Harness Web connector for Agent Knock Knock (AKK). When the Web Host mounts the bundle, it adds `/akk`, the 22 AKK semantic tools, and the bundled `agent-knock-knock` skill to every live Agent. There is no `/akk-bind` step, separate skill installation, or session id for the user to copy. The connector is developed in the AKK repository but is an independent npm package. It does not modify DeepSeek Harness and has its own version, build, tests, lockfile, bundle manifest, and connector-specific release tag. ## Compatibility This prerelease supports DeepSeek Harness `0.1.1-rc.2`, `0.1.2-alpha.1`, and `0.1.5-rc.2` on the resident Web Host and Node.js `>=22.19.0`. Activation locates the real `@deepseek-ai/dsh` launcher and requires that launcher plus its `dsh-base`, `dsh-agent`, `dsh-commands`, `dsh-llm`, and `dsh-tools` packages to form one coherent set at one reviewed version. An unsupported, missing, or split Host fails before mounting. The detected launcher version is also projected into the private AKK Host Profile instead of being replaced with a connector build-time version. Runtime message and schema helpers are imported from that verified Host package tree, so a source checkout's development dependencies cannot replace them. Headless/one-shot Harness processes, Host-exit callback continuity, and Windows named pipes are not supported in this release. AKK discovers existing Codex and Claude Code processes in tmux or Herdr; this connector does not start those processes or create terminal panes. ## Five-minute quick start ### 1. Check the prerequisites The Web Host must be one of the supported DeepSeek Harness releases, Node must satisfy the engine above, and `pnpm` must be on `PATH` because `dsh plugin` forwards package operations to pnpm. ```sh node --version dsh --version pnpm --version npm view @scotthuang/agent-knock-knock-deepseek-harness dist-tags --json ``` The last command reports registry state; this repository does not assume that a particular prerelease is present in every configured npm registry. Connector prereleases use the `next` tag when published. ### 2. Add the connector to the Web profile ```sh dsh plugin --profile web add @scotthuang/agent-knock-knock-deepseek-harness@next ``` Stop the current Web Host cleanly if it is running, then start a fresh process so the new bundle is mounted: ```sh dsh web ``` Do not start a second Web Host merely to reload the connector. The callback route belongs to the Host process and exact Agent that accepted the command or tool invocation. ### 3. Verify discovery in a Web conversation Make sure at least one Codex or Claude Code process is already running inside a tmux or Herdr pane, then enter: ```text /akk list ``` The compact result contains that live terminal, current action names, and only the dynamic inputs needed for those actions. Static action meanings and safety rules come from the automatically registered `agent-knock-knock` skill. AKK never asks callers to invent identifiers: copy only the complete `terminal_id`, `session_id`, `turn_id`, `watch_id`, or `native_thread_id` returned by AKK. ### 4. Send one task and receive its callback If exactly one matching terminal is send-ready, this is a complete smoke test: ```text /akk codex: Inspect package.json and report the package name. Do not modify files. ``` Use `claude:` instead when testing Claude Code. With multiple matching panes, run `/akk list` first and use the displayed session selector, or let the Agent call `agent_knock_knock_send` with the exact semantic identifier in that row's advertised action. An accepted managed Send creates a `turn_id`. When the coding agent finishes, asks a question, becomes blocked, or requests approval, AKK sends a callback to the same live DeepSeek Harness Agent. A running Agent receives the update via `inject()`; an idle Agent receives it via `followup()`. If stale or broken AKK management prevents managed delivery before terminal input, an explicit user Send can instead be delivered once through the physical terminal and best-effort attach a Terminal Watch. That result has no managed callback Turn; retain its returned `watch_id` for callback recovery. A warning that Watch attachment failed does not undo an already successful Send. ### 5. Observe work that AKK did not send Terminal Watch is read-only and can follow an existing human-started task without creating an AKK Session or Turn: ```text /akk list /akk watch /akk status /akk unwatch ``` Watch prefers an exact task anchor and otherwise degrades to warning-bearing terminal activity observation. A fallback Watch can prove stable idle, not that one uniquely identified task produced the final output. ## Tool workflow The slash command is the human-facing shortcut. Agents receive the same behavior through the complete capability-handshake-verified tool catalog: | Tool | Purpose | | --- | --- | | `agent_knock_knock_list` | List live Codex/Claude terminals, managed state, Terminal Watches, and each row's currently available actions. | | `agent_knock_knock_watch` | Start durable, read-only observation of one exact `terminal_id`. | | `agent_knock_knock_unwatch` | Stop one exact `watch_id` without sending terminal input. | | `agent_knock_knock_list_resumable_threads` | List structurally verified native threads for one terminal. | | `agent_knock_knock_native_inspect` | Run only the adapter-owned native `status` inspection advertised for an idle terminal. | | `agent_knock_knock_model_options` | Read one exact idle terminal's native model and reasoning catalog and create a single-use typed offer. | | `agent_knock_knock_repair_model_control` | Dismiss only an exactly recognized stale model-control surface; it never selects a model or submits work. | | `agent_knock_knock_set_model` | Consume the current catalog offer to choose one advertised semantic model and reasoning effort. | | `agent_knock_knock_identify_foreground` | Run a bounded diagnostic native identity probe without creating durable authority. | | `agent_knock_knock_identify_and_send` | Keep one terminal lock across identity observation and one explicit Send when foreground identity is ambiguous. | | `agent_knock_knock_new_thread` | Start and verify a clean native coding-agent thread after explicit user intent. | | `agent_knock_knock_reconcile_binding` | Detach one proven stale conflicting binding after explicit confirmation; it neither sends work nor adopts a thread. | | `agent_knock_knock_resume_thread` | Resume one complete `native_thread_id` from a fresh resumable-thread listing. | | `agent_knock_knock_status` | Inspect one AKK `turn_id` or Terminal Watch `watch_id` plus a bounded current screen. | | `agent_knock_knock_send` | Send a new task through the exact action advertised by `list`. | | `agent_knock_knock_respond` | Answer a question or unblock one existing managed Turn; it does not create a new Turn. | | `agent_knock_knock_respond_interaction` | Answer the current typed native questionnaire step for one exact response-capable Turn or Watch. | | `agent_knock_knock_approve` | Approve the current exact permission request once, only after human review and confirmation. | | `agent_knock_knock_renew` | Renew monitoring for a still-live stalled Turn without typing into the terminal. | | `agent_knock_knock_retry_callback` | Retry one persisted failed callback with its original message and delivery identity. | | `agent_knock_knock_cancel` | Interrupt one exact active Turn while leaving the shared pane open. | | `agent_knock_knock_close` | Release AKK management of a Turn without terminal input, process interruption, or pane closure. | The ordinary closed loop is: 1. Call `list` and select one exact terminal row. 2. Use only that row's advertised `send` action and semantic identifier. 3. Retain the returned `turn_id` for managed delivery, or the `watch_id` from an automatic physical-Send fallback. Completion or attention callbacks return to the originating DeepSeek Harness Agent. 4. For a managed question or blocked callback, use `respond` with its `turn_id`. For a permission request, follow the approval procedure below. 5. Use `status` when a callback is late or uncertain. Use an explicit `watch` for other work that was not sent as a managed AKK Turn. Do not cache `available_actions` or private terminal state. Refresh `list` or `status` before a mutation, and never blindly retry an uncertain Send, approval, cancel, native inspection, or native thread transition. ## Active approval The DeepSeek Harness connector registers AKK's approval tool directly; unlike the Pi connector, this prerelease does **not** add a Host-native confirm/select dialog around that tool. Explicit human confirmation is therefore a required calling contract for the Agent and user, not a UI gate enforced by this connector. With the default configuration, the manual flow is: 1. Receive the approval callback, then call `agent_knock_knock_status({turn_id})` to refresh the exact current request and terminal screen. 2. Present the current request, tool name, and relevant arguments to the user. 3. Obtain an explicit approve or reject decision in the same Web conversation. 4. Only for an explicit approval, invoke the currently advertised `agent_knock_knock_approve({turn_id})`, or let the user enter `/akk approve `. 5. If approval was interrupted or returned an uncertain result, refresh status and let the human inspect the live TUI. Never retry it blindly. AKK's deterministic `pluginConfig.autoApprove` policy remains disabled by default. If an administrator deliberately enables it, only the exact configured agent, workspace, and command-vector rules may bypass this manual flow; unmatched or ambiguous requests still require the confirmation procedure above. A separately advertised terminal-scoped approval has no managed `turn_id`. Refresh `list`, show that row's current approval request to the user, and after explicit confirmation call the advertised `approve` action with its complete `terminal_id`. Never convert a terminal-scoped approval into a guessed Turn. The related controls are deliberately different: - `respond` supplies text to a question or blocked managed Turn. It is not an approval and is not a generic denial button. - `cancel` interrupts the exact active task after explicit user intent. It does not close the pane. A user's rejection must not be silently converted into Cancel; ask separately whether they want the task interrupted or prefer to handle the permission prompt in the live TUI. - `close` only releases AKK's management records. It sends no terminal input and does not stop the coding agent; refresh `list` and use `watch` if the process continues working. - `unwatch` stops observation only. It never interrupts the watched task. ## Callback delivery and recovery The synchronous callback acknowledgement means that the message was admitted to the exact DeepSeek Harness Agent's inbox/session log. It does not prove that the model consumed the message or that asynchronous persistence reached stable storage. `status` and Terminal Watch are the recovery path. - If the exact Agent and Host are still live, inspect the `turn_id` with `status`. A persisted callback failure can be retried with `agent_knock_knock_retry_callback`; AKK reuses the original callback message id and Turn identity for idempotent delivery. - For a Terminal Watch, inspect its `watch_id` with `status`. If the route is no longer valid, `unwatch` it and start a fresh Watch from a current `list` row. - A Host restart creates a new private Profile revision. Existing watches retain their original route, so callbacks owned by the old Host incarnation fail closed instead of being redirected to a new Agent. There is deliberately no cross-restart callback migration in this prerelease. - Replacing an Agent object with another Agent that has the same session id also does not transfer its route. Start a current command/tool invocation from the new Agent before expecting new callback ownership. - Exact process-lifetime idempotency records return the original acceptance id for a duplicate callback. Reusing an idempotency key with different content is rejected. ## Configuration The connector accepts an optional lifecycle cadence and the existing AKK plugin configuration object: ```yaml - id: agent-knock-knock-deepseek-harness name: '@scotthuang/agent-knock-knock-deepseek-harness' config: lifecycleIntervalMs: 5000 pluginConfig: storeDir: /absolute/path/to/akk-store ``` `lifecycleIntervalMs` must be at least 50 milliseconds. Use an absolute `storeDir`; a relative value is resolved from the Web Host's working directory. When omitted, AKK uses `~/.agent-knock-knock/store`. The optional bundle patch mounts only the Host plugin: ```yaml - insert: - id: agent-knock-knock-deepseek-harness name: '@scotthuang/agent-knock-knock-deepseek-harness' ``` ## Security and storage - Each Host process creates a private temporary directory with mode `0700`. Its generated Host Profile is mode `0600`; the directory is removed during a clean connector shutdown. - The callback socket path and random token travel only through an allowlisted environment. They are not command arguments. The callback helper uses the absolute Node executable and package artifact without a shell or `PATH` lookup. - The callback IPC frame is authenticated and bounded. Successful admission is tied to one exact Agent object and one Host incarnation. - AKK's durable Store contains task, Session, Turn, receipt, watch, and callback recovery metadata and may contain user request or callback text. AKK creates Store directories as `0700` and files as `0600`; keep a custom Store on a trusted local filesystem owned by the Host user. Do not share one writable Store between unrelated users. - Uninstalling the connector does not delete the durable AKK Store. Retain it if recovery or audit history is still needed; archive or remove it only after confirming there are no active Turns or Watches that depend on it. ## Troubleshooting | Symptom | Check and recovery | | --- | --- | | `dsh plugin` cannot run | Confirm `pnpm --version` succeeds. The DeepSeek Harness plugin command forwards its arguments to pnpm. | | `@next` cannot be resolved | Run `npm view @scotthuang/agent-knock-knock-deepseek-harness dist-tags --json`. Use an exact published version if your registry has no `next` tag, or use the local-development installation below. | | `/akk` and AKK tools are missing | Verify installation with `dsh plugin --profile web why @scotthuang/agent-knock-knock-deepseek-harness`, then fully restart the Web Host. Existing Host processes do not gain a newly added bundle. | | Activation reports an unsupported or split Harness | Check `dsh --version` and run `dsh plugin --profile web why @deepseek-ai/dsh-base @deepseek-ai/dsh-agent @deepseek-ai/dsh-commands @deepseek-ai/dsh-llm @deepseek-ai/dsh-tools`. Update the whole Host coherently; do not repair it with a standalone connector npm install. | | `/akk list` finds no terminals | Start or locate a real Codex/Claude Code process inside tmux or Herdr. AKK never launches the coding agent or creates its pane. | | A mutation is absent or rejected | Refresh `/akk list` or structured `list` and use only the action currently advertised for that exact row. Resolve a current approval first when it blocks input. Do not reuse stale IDs or action payloads. | | The callback never appears | Run `/akk status `. If the same route is live, use the persisted `retry_callback` tool for a failed Turn callback. After a Host restart or Agent replacement, old delivery fails closed; recreate a Watch or start new work from the current Agent. | | Callback delivery reports IPC unavailable or timeout | Keep the originating Web Host alive and inspect whether it was restarted or disposed. The socket is Host-process-private and has an eight-second callback boundary; there is no cross-process fallback route. | | A Watch completed but its callback was missed | Query `status` by `watch_id`. Under a new Host incarnation, unwatch the old record and create a fresh Watch from a current terminal row. | | A tool call fails schema validation | Pass only the documented fields and complete semantic IDs returned by AKK. DeepSeek's discovery schema is a projection; the connector always enforces the full original AKK schema before execution. | | Windows, headless, or one-shot use fails | These surfaces are outside this prerelease's supported scope. Use the resident POSIX Web Host. | ## Upgrade and uninstall Inspect available versions before changing the profile: ```sh npm view @scotthuang/agent-knock-knock-deepseek-harness versions --json npm view @scotthuang/agent-knock-knock-deepseek-harness dist-tags --json ``` Update to the registry's current prerelease, or pin an exact reviewed version: ```sh dsh plugin --profile web add @scotthuang/agent-knock-knock-deepseek-harness@next dsh plugin --profile web add @scotthuang/agent-knock-knock-deepseek-harness@0.1.0-rc.4 ``` Restart the Web Host after either operation. The connector pins the exact AKK runtime version it was tested against, so updating the connector updates that tested unit instead of letting the Host Adapter API drift independently. To uninstall: ```sh dsh plugin --profile web remove @scotthuang/agent-knock-knock-deepseek-harness ``` Restart the Web Host once more. Removal withdraws `/akk`, the tools, and live callback routes; it does not delete the durable AKK Store. ## Local development From the AKK repository root, install and build the child package, then add that connector checkout to the Web profile: ```sh npm --prefix connectors/deepseek-harness ci npm run deepseek:build dsh plugin --profile web add "file:$(pwd -P)/connectors/deepseek-harness" ``` Restart `dsh web` after installation. The child package currently installs and tests against its pinned published AKK runtime `0.13.3`; building the current repository root does not silently replace that dependency. Testing connector changes against another AKK runtime requires an explicit dependency change and compatibility review rather than an implicit local link. ## Tests and release status The package manifest is currently `0.1.0-rc.4`, so this remains a prerelease and is published under `next`; `latest` remains on the earlier `0.1.0-rc.1` tag. Registry state can change independently of this source file, so the `npm view` commands above remain authoritative. From `connectors/deepseek-harness`, the normal development gate is: ```sh npm ci npm run typecheck npm run test:fast npm run pack:check ``` These commands typecheck the connector, run its fast wiring/profile/IPC/schema tests, and inspect the package tarball. They do not publish anything. The `0.1.0-rc.4` compatibility work is typechecked against the published DeepSeek Harness `0.1.5-rc.2` SDK packages and runtime-smoked against that exact official launcher package tree. The reproducible development lock therefore uses `0.1.5-rc.2`, while peer and runtime checks retain the two older reviewed Host versions for existing installations. ## Release safety `npm run release:check` is check-only. The shared connector gate first proves the generated Skill hash, package manifest/constants/lock/dependency parity, then runs typecheck, fast tests, and inspection of the real package tarball. In release mode it additionally rejects a dirty tree, a non-`main` branch, an unsynchronized upstream, an existing npm version or connector repository tag, and any runtime `file:`, `link:`, or `workspace:` dependency. Activation separately verifies the pinned AKK HostAdapter's versioned, secretless capability handshake. The authoritative catalog digest, ordered tool names and derived count, and Skill digest must match the generated Skill and the tools registered with DeepSeek Harness. A missing/unknown handshake, forged digest, or partial registration fails closed; the connector has no independent hard-coded tool count. For deterministic local verification without a registry or git-remote query: ```sh npm run release:check -- --offline ``` From the repository root, `npm run connectors:verify` applies that same offline gate to both connectors. Their package versions are validated independently. Publishing additionally requires both explicit flags: ```sh npm run release:check -- --publish --confirm-version 0.1.0-rc.4 ``` Prereleases use npm tag `next`; stable versions use `latest`. Repository tags and GitHub Releases use the connector-specific namespace `deepseek-harness-v` and are created separately after npm verification.