@scotthuang/agent-knock-knock 0.12.36 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +44 -0
- package/README.md +3 -0
- package/dist/src/agent-session-provider.d.ts +5 -0
- package/dist/src/agent-session-provider.js +10 -1
- package/dist/src/agent-session-provider.js.map +1 -1
- package/dist/src/callback-outbox-service.d.ts +2 -0
- package/dist/src/callback-outbox-service.js +1 -1
- package/dist/src/callback-outbox-service.js.map +1 -1
- package/dist/src/callback-transport.d.ts +7 -0
- package/dist/src/callback-transport.js +1 -1
- package/dist/src/callback-transport.js.map +1 -1
- package/dist/src/cli-core.js +35 -32
- package/dist/src/cli-core.js.map +1 -1
- package/dist/src/codex-store-adapter.d.ts +1 -1
- package/dist/src/codex-store-adapter.js +35 -8
- package/dist/src/codex-store-adapter.js.map +1 -1
- package/dist/src/deferred-foreground-authority-cli-adapter.d.ts +20 -0
- package/dist/src/deferred-foreground-authority-cli-adapter.js +216 -8
- package/dist/src/deferred-foreground-authority-cli-adapter.js.map +1 -1
- package/dist/src/host-adapter.d.ts +1 -1
- package/dist/src/host-adapter.js +1 -1
- package/dist/src/host-bridge-tools.js +2 -2
- package/dist/src/managed-turn-recovery-service.d.ts +8 -1
- package/dist/src/managed-turn-recovery-service.js +55 -13
- package/dist/src/managed-turn-recovery-service.js.map +1 -1
- package/dist/src/mutation-transaction.d.ts +1 -0
- package/dist/src/mutation-transaction.js +19 -15
- package/dist/src/mutation-transaction.js.map +1 -1
- package/dist/src/native-thread-lifecycle-cli-adapter.d.ts +39 -3
- package/dist/src/native-thread-lifecycle-cli-adapter.js +307 -7
- package/dist/src/native-thread-lifecycle-cli-adapter.js.map +1 -1
- package/dist/src/openclaw-plugin-callback-adapter.js +17 -7
- package/dist/src/openclaw-plugin-callback-adapter.js.map +1 -1
- package/dist/src/openclaw-plugin-command-adapter.js +299 -79
- package/dist/src/openclaw-plugin-command-adapter.js.map +1 -1
- package/dist/src/openclaw-plugin-schemas.d.ts +57 -0
- package/dist/src/openclaw-plugin-schemas.js +59 -1
- package/dist/src/openclaw-plugin-schemas.js.map +1 -1
- package/dist/src/openclaw-private-authority-offers.d.ts +17 -0
- package/dist/src/openclaw-private-authority-offers.js +75 -3
- package/dist/src/openclaw-private-authority-offers.js.map +1 -1
- package/dist/src/store.d.ts +1 -1
- package/dist/src/store.js +6 -4
- package/dist/src/store.js.map +1 -1
- package/dist/src/terminal-acceptance-application-service.js +2 -2
- package/dist/src/terminal-acceptance-application-service.js.map +1 -1
- package/dist/src/terminal-acceptance-cli-adapter.d.ts +11 -1
- package/dist/src/terminal-acceptance-cli-adapter.js +290 -16
- package/dist/src/terminal-acceptance-cli-adapter.js.map +1 -1
- package/dist/src/terminal-action-projection.d.ts +1 -1
- package/dist/src/terminal-action-projection.js +6 -0
- package/dist/src/terminal-action-projection.js.map +1 -1
- package/dist/src/terminal-agent-adapter.d.ts +9 -0
- package/dist/src/terminal-agent-adapter.js.map +1 -1
- package/dist/src/terminal-agent-bridge.d.ts +52 -8
- package/dist/src/terminal-agent-bridge.js +133 -104
- package/dist/src/terminal-agent-bridge.js.map +1 -1
- package/dist/src/terminal-authority-policy.js +3 -0
- package/dist/src/terminal-authority-policy.js.map +1 -1
- package/dist/src/terminal-binding-authority.d.ts +2 -0
- package/dist/src/terminal-binding-authority.js +8 -0
- package/dist/src/terminal-binding-authority.js.map +1 -1
- package/dist/src/terminal-command-cli-adapter.d.ts +17 -1
- package/dist/src/terminal-command-cli-adapter.js +784 -286
- package/dist/src/terminal-command-cli-adapter.js.map +1 -1
- package/dist/src/terminal-delegate-cli-adapter.js +21 -7
- package/dist/src/terminal-delegate-cli-adapter.js.map +1 -1
- package/dist/src/terminal-dispatch-application.d.ts +3 -1
- package/dist/src/terminal-dispatch-application.js +13 -5
- package/dist/src/terminal-dispatch-application.js.map +1 -1
- package/dist/src/terminal-dispatch-composition.d.ts +43 -0
- package/dist/src/terminal-dispatch-execution.d.ts +2 -2
- package/dist/src/terminal-dispatch-execution.js +53 -3
- package/dist/src/terminal-dispatch-execution.js.map +1 -1
- package/dist/src/terminal-dispatch-policy.d.ts +20 -0
- package/dist/src/terminal-dispatch-policy.js +33 -1
- package/dist/src/terminal-dispatch-policy.js.map +1 -1
- package/dist/src/terminal-dispatch-presenter.d.ts +45 -0
- package/dist/src/terminal-dispatch-presenter.js +220 -18
- package/dist/src/terminal-dispatch-presenter.js.map +1 -1
- package/dist/src/terminal-dispatch-receipt.d.ts +5 -1
- package/dist/src/terminal-dispatch-receipt.js +26 -3
- package/dist/src/terminal-dispatch-receipt.js.map +1 -1
- package/dist/src/terminal-identity-authority-cli-adapter.js +103 -4
- package/dist/src/terminal-identity-authority-cli-adapter.js.map +1 -1
- package/dist/src/terminal-interaction-authority.d.ts +48 -1
- package/dist/src/terminal-interaction-authority.js +30 -0
- package/dist/src/terminal-interaction-authority.js.map +1 -1
- package/dist/src/terminal-interaction-cli-adapter.js +19 -9
- package/dist/src/terminal-interaction-cli-adapter.js.map +1 -1
- package/dist/src/terminal-interaction-core.d.ts +104 -0
- package/dist/src/terminal-interaction-core.js +407 -0
- package/dist/src/terminal-interaction-core.js.map +1 -0
- package/dist/src/terminal-interaction-protocol.d.ts +95 -0
- package/dist/src/terminal-interaction-protocol.js +201 -1
- package/dist/src/terminal-interaction-protocol.js.map +1 -1
- package/dist/src/terminal-list-cli-adapter.d.ts +5 -0
- package/dist/src/terminal-list-cli-adapter.js +190 -40
- package/dist/src/terminal-list-cli-adapter.js.map +1 -1
- package/dist/src/terminal-list-renderer.js +60 -7
- package/dist/src/terminal-list-renderer.js.map +1 -1
- package/dist/src/terminal-maintenance-cli-adapter.js +14 -3
- package/dist/src/terminal-maintenance-cli-adapter.js.map +1 -1
- package/dist/src/terminal-monitor-application-service.d.ts +1 -0
- package/dist/src/terminal-monitor-application-service.js +72 -10
- package/dist/src/terminal-monitor-application-service.js.map +1 -1
- package/dist/src/terminal-monitor-cli-adapter.d.ts +3 -0
- package/dist/src/terminal-monitor-cli-adapter.js +24 -8
- package/dist/src/terminal-monitor-cli-adapter.js.map +1 -1
- package/dist/src/terminal-monitor-state-cli-adapter.js +15 -2
- package/dist/src/terminal-monitor-state-cli-adapter.js.map +1 -1
- package/dist/src/terminal-mutation-cli-runtime.d.ts +11 -1
- package/dist/src/terminal-mutation-cli-runtime.js +9 -4
- package/dist/src/terminal-mutation-cli-runtime.js.map +1 -1
- package/dist/src/terminal-questionnaire-adapter.d.ts +1 -1
- package/dist/src/terminal-questionnaire-adapter.js +106 -39
- package/dist/src/terminal-questionnaire-adapter.js.map +1 -1
- package/dist/src/terminal-status-cli-adapter.d.ts +1 -7
- package/dist/src/terminal-status-cli-adapter.js +29 -3
- package/dist/src/terminal-status-cli-adapter.js.map +1 -1
- package/dist/src/terminal-status-facts.d.ts +17 -1
- package/dist/src/terminal-status-facts.js +59 -0
- package/dist/src/terminal-status-facts.js.map +1 -1
- package/dist/src/terminal-submission-acceptance.d.ts +37 -2
- package/dist/src/terminal-submission-acceptance.js +633 -30
- package/dist/src/terminal-submission-acceptance.js.map +1 -1
- package/dist/src/terminal-submission-facts.d.ts +5 -0
- package/dist/src/terminal-submission-facts.js.map +1 -1
- package/dist/src/terminal-watch-callback-cli-adapter.d.ts +2 -1
- package/dist/src/terminal-watch-callback-cli-adapter.js +2 -1
- package/dist/src/terminal-watch-callback-cli-adapter.js.map +1 -1
- package/dist/src/terminal-watch-cli-adapter.d.ts +6 -2
- package/dist/src/terminal-watch-cli-adapter.js +1051 -15
- package/dist/src/terminal-watch-cli-adapter.js.map +1 -1
- package/dist/src/terminal-watch-service.d.ts +15 -1
- package/dist/src/terminal-watch-service.js +169 -13
- package/dist/src/terminal-watch-service.js.map +1 -1
- package/dist/src/terminal-watch-store.d.ts +72 -3
- package/dist/src/terminal-watch-store.js +407 -27
- package/dist/src/terminal-watch-store.js.map +1 -1
- package/docs/host-bridge-profiles.md +2 -2
- package/docs/quickstart-herdr.md +5 -3
- package/docs/quickstart-tmux.md +7 -5
- package/openclaw.plugin.json +8 -0
- package/package.json +1 -1
- package/templates/openclaw-skills/agent-knock-knock/SKILL.md +15 -11
|
@@ -35,10 +35,12 @@ Core slash-command forms:
|
|
|
35
35
|
- `/akk respond <turn-selector>: <answer>`: answer a coding-agent question inside a `waiting_for_openclaw` Turn.
|
|
36
36
|
- `/akk cancel <turn-selector>`: interrupt the exact Turn without closing its terminal pane.
|
|
37
37
|
|
|
38
|
-
For human-facing ordinary-send slash forms, a selector may be `codex`, `claude`, `only`, `latest`, or an `@short-ref` returned by `AKK list`. These selectors are only a resolution layer and fail closed when the target is missing or ambiguous. The
|
|
38
|
+
For human-facing ordinary-send slash forms, a selector may be `codex`, `claude`, `only`, `latest`, or an `@short-ref` returned by `AKK list`. These selectors are only a resolution layer and fail closed when the target is missing or ambiguous. The v25 structured-tool contract never exposes a selector or opaque authority value: the model supplies semantic IDs only. `send({session_id,request})` is strict `session_exact`; `send({terminal_id,request})` is either managed `terminal_follow_current` or user-priority `terminal_user_explicit`, exactly as advertised; the two target fields are mutually exclusive, and both may be omitted only when AKK must prove one unique send-ready pane. Codex `terminal_user_explicit` depends on the exact live terminal/process, a scanned non-blocked approval state, and no active native questionnaire—not Composer visibility, stability, exactness, parsed working activity, or AKK Store, Turn, Session, transfer, transition, ledger, or ownership. It applies `replace_current_composer_and_submit`: physical fallback sends `C-u` once to replace the current Composer, injects the request, waits through the paste window, and dispatches Enter exactly once. After text injection, Composer observation must never veto Enter. Claude Code remains exact-empty-only. AKK tries managed delivery where its strict empty-Composer pre-input authority exists; after user-explicit Codex text injection, that path follows the same no-Composer-veto Enter rule. A source-less Codex terminal with zero, one, or many pre-existing rollout roots freezes that full candidate set before input and binds only the unique rollout that later persists the exact request hash; a unique stale root is never assumed to be foreground. If managed preparation still fails before input, AKK sends once without a managed callback Turn, then best-effort attaches an exact request-bound Terminal Watch callback and releases stale management. Watch failure is a warning and never revokes or retries a successful Send. Native inspection and native lifecycle input remain exact-empty-only. With runtime durability, an omitted target binds its `message_id` to the first selected physical terminal and existing or uncertain same-ID evidence rejects replay. If fresh durability is unavailable, user priority wins: AKK proceeds with a warning, and the degraded result must not be automatically retried. Once the Codex mutation sequence begins, an uncertain result must not be automatically retried. Read Send results as orthogonal facts: `terminal_input_dispatched`, `agent_acceptance`, `management_mode`, `observation_mode`, and `capabilities` distinguish physical dispatch from durable native acceptance and callback/interaction authority; do not infer one from another. If the result returns `observation_mode="terminal_watch"`, wait for that callback and retain `watch-status` as the recovery path. The only non-ordinary Send form is an exact `send({turn_id})` copied unchanged from a current `available_actions.retry_submission`; it accepts no request text or other target and requires explicit user confirmation. Native-thread actions use the full `terminal_id`, never an `@short-ref`. Other managed controls use `turn_id`; terminal-scoped approval uses `terminal_id` after explicit user confirmation. The trusted plugin/CLI derives terminal, binding, candidate, prompt, composer, handoff, and compare-and-swap fences privately. Never ask the user or model to copy draft text, a composer digest, a token, fingerprint, revision, binding ID/generation, or handoff-only live native UUID from an action; `native_thread_id` is the intentional semantic UUID for resume. For every side effect, AKK must revalidate the selected agent PID and provider-owned terminal identity and revalidate the relevant approval prompt; Composer revalidation remains action-specific and is not Codex user-explicit Send authority.
|
|
39
39
|
|
|
40
40
|
The human-priority Codex path may proceed when the pane/process and complete open-rollout candidate inventory are exact even though no single foreground UUID can be selected, including a supported manual `/clear` whose new logical thread appears before its rollout materializes. The complete exact inventory domain binds the provider terminal, PID and process birth, workspace and canonical endpoint, and every open rollout's UUID, descriptor, device, inode, canonical path, and pre-submit byte offset. A `/clear` resume hint is advisory only, never routing or acceptance authority. Under the terminal lock, AKK isolates the predecessor, creates a separate zero-UUID provisional Session and Turn, sends the real task once, and binds only the single candidate rollout that durably accepts that exact request. A rollout-backed Codex row therefore advertises `terminal_follow_current` with `terminal_id`, not `session_exact`; a cached strict Session attempt rejects before task text and never downgrades itself. Only released predecessor Turn history from a strictly earlier binding epoch is excluded from current-send authority; unresolved current-epoch state still blocks. Use only the freshly listed semantic-ID action. Until promotion commits, strict `session_id` send, `respond`, managed `approve`, `cancel`, native lifecycle, callback delivery, and `native_inspect` remain unavailable. If delivery or acceptance is uncertain, do not retry automatically. Terminal-scoped manual Codex approval likewise exposes only `terminal_id`, requires explicit confirmation, leaves managed identity unchanged, never participates in auto-approval, and must not be retried blindly after an uncertain result.
|
|
41
41
|
|
|
42
|
+
For an exact-empty idle Codex pane whose native identity is ambiguous, List may advertise `identify_foreground` and `identify_and_send`. `agent_knock_knock_identify_foreground({terminal_id})` is explicit and Codex-only: it mutates no Store record but does send `/status` and Enter exactly once to the visible pane. Its 30-second proof is diagnostic, never reusable authority; do not feed its UUID or expiry into another tool. `agent_knock_knock_identify_and_send({terminal_id,request})` keeps one terminal lock across the probe and task and is the only actionable consumer of that observation. It still binds a durable Session/Turn only from unique exact request acceptance. A changed or uncertain probe sends no task and must not be retried automatically. Never invoke either action unless the current terminal row advertises it. Ordinary `agent_knock_knock_send`, List, and Status do not run `/status` and must not be redirected through these tools implicitly.
|
|
43
|
+
|
|
42
44
|
The private approval fence remains prompt-scoped. It binds the adapter-isolated exact unredacted approval region plus terminal/process identity, decision keys and label, prompt kind, working directory, reason/detail, and request or policy evidence. The whole-screen digest and redacted excerpt are diagnostic only: output outside the approval region may continue scrolling without invalidating the same reviewed prompt. After explicit user confirmation, the plugin/CLI retains a private confirmation offer and recaptures the region under lock. Any change inside the exact region—including a command or otherwise identically redacted secret—rejects and sends zero approval keys. Never expose, persist as public action data, log, infer, or reconstruct the raw prompt evidence or its opaque fingerprint.
|
|
43
45
|
|
|
44
46
|
Coding-agent versions are verification metadata, not action authority. A complete but unverified Codex or Claude Code `x.y.z` version keeps every otherwise eligible action advertised; preserve and surface its compatibility warning, then let the same runtime structure and postcondition checks decide success. Never suppress an action only because its exact version lacks a regression-tested AKK profile. If input may already have occurred and the result is unproven, report the uncertainty and never retry automatically.
|
|
@@ -56,6 +58,8 @@ Natural-language forms:
|
|
|
56
58
|
- Requests to continue in the current terminal context after the human may have run `/clear`, `/new`, `/resume`, or an equivalent native operation: first call `agent_knock_knock_list`, then use only that exact terminal row's advertised `send({terminal_id,request})`; do not substitute the stale `session_id`.
|
|
57
59
|
- Requests to recover an AKK submission reported as uncertain: refresh `agent_knock_knock_list`. Only if the current exact Turn advertises `retry_submission`, explain that AKK will revalidate the immutable original request and may either press one Enter for the exact existing draft or retransmit that original text once after structured no-Enter proof and a positively empty composer. Require explicit user confirmation, then call the prefilled `agent_knock_knock_send({turn_id})` unchanged. Never add `request`, terminal/Session IDs, timeout fields, or callback route data, and never retry it automatically.
|
|
58
60
|
- Requests for the coding agent's native Codex status card or Claude Status panel: first call `agent_knock_knock_list`, then call `agent_knock_knock_native_inspect({terminal_id,inspection:"status"})` only when the exact terminal row advertises it; do not substitute AKK Turn status or ordinary send.
|
|
61
|
+
- Explicit requests to diagnose an ambiguous current Codex foreground: call `agent_knock_knock_identify_foreground({terminal_id})` only from that row's current action. Explain that it types one `/status` command, changes no Store state, and returns a non-authorizing 30-second observation. Never use the result as authority for a later mutation.
|
|
62
|
+
- Explicit requests to identify an ambiguous Codex foreground and send one task atomically: use the row's exact `agent_knock_knock_identify_and_send({terminal_id,request})` action. Do not synthesize this path for an ordinary Send or split it into identify-then-send calls.
|
|
59
63
|
- Requests to list resumable native threads for an exact terminal: call `agent_knock_knock_list_resumable_threads` with the terminal row's prefilled `terminal_id`.
|
|
60
64
|
- Explicit requests to start a new thread or clear context: call `agent_knock_knock_new_thread({terminal_id})` only from an advertised `new_thread` action.
|
|
61
65
|
- Explicit requests for low-level recovery of a listed binding conflict: after explicit user confirmation, call only the advertised `agent_knock_knock_reconcile_binding({terminal_id,conflicting_session_id})`. AKK derives its revision and binding fences privately, detaches the stale/conflicting binding without adopting the live thread, and requires a fresh list afterward. Do not use it in place of an advertised follow-current send.
|
|
@@ -64,7 +68,7 @@ Natural-language forms:
|
|
|
64
68
|
- A later ordinary request: refresh `agent_knock_knock_list` and use only the selected terminal row's advertised send. Use `send({session_id,request})` for `session_exact` or `send({terminal_id,request})` for `terminal_follow_current`; never substitute a retained Session or Turn identity.
|
|
65
69
|
- Requests to continue the current terminal context are ordinary terminal-scoped sends, not lifecycle actions. Use only a freshly advertised action carrying the exact `terminal_id` when a human-driven switch is present.
|
|
66
70
|
- An answer to a coding-agent question in a `waiting_for_openclaw` Turn: call `agent_knock_knock_respond` with its authoritative `turn_id` and `request=<answer>`.
|
|
67
|
-
- An answer to a native coding-agent questionnaire is a different flow: in the same controller conversation, call `agent_knock_knock_status({turn_id})
|
|
71
|
+
- An answer to a native coding-agent questionnaire is a different flow: in the same controller conversation, call `agent_knock_knock_status` with exactly one authoritative subject (`{turn_id}` for a managed Turn or `{watch_id}` for a response-capable exact Watch), show the current pending `interaction_state` to the user, and require their explicit choice or text. Only when `capabilities.respond=true`, call `agent_knock_knock_respond_interaction` with that projection's same exact subject id, `interaction_id`, and typed `answers` using its opaque `question_id` and `option_id` values. One call answers only the current step; call Status again before each later question or final confirmation. Never guess ids, translate a label into terminal keys, answer a `manual_required` or secret-input state, or retry an uncertain response blindly.
|
|
68
72
|
- Requests to stop current work: call `agent_knock_knock_cancel`.
|
|
69
73
|
|
|
70
74
|
## Sessions and Turns
|
|
@@ -80,8 +84,8 @@ For ordinary send or an in-flight answer:
|
|
|
80
84
|
1. Reuse an AKK session only when the user's reference uniquely identifies its verified native session and terminal incarnation.
|
|
81
85
|
2. If no ID is supplied and more than one eligible pane may exist, call `agent_knock_knock_list`.
|
|
82
86
|
3. Treat `terminals[]` as the primary resource list. Its managed context exposes `session_id`; `managed.current_turn` is the only current AKK owner, while `managed.recent_turn` and `managed.history` are retained Turn history. Records in `unavailable_managed_turns[]` have no live pane in this snapshot.
|
|
83
|
-
4. Read the selected resource's `available_actions`. For every mutation, use only an action present there, start with its prefilled semantic IDs, supply every `missing_required` field, and consult the top-level
|
|
84
|
-
5. If an existing managed Session advertises send with `session_id`, call `agent_knock_knock_send({session_id,request})`; it creates a new Turn strictly in that Session's native context and may require exact empty before input. If the selected row advertises terminal-scoped send, call `agent_knock_knock_send({terminal_id,request})`. `terminal_follow_current` may adopt a safe human-driven handoff or send once within an exact, complete Codex rollout-candidate inventory before binding the uniquely accepting native thread. `terminal_user_explicit` instead preserves the user's Send when internal AKK state is broken: Codex replaces the current Composer with the new request and submits exactly once without a post-text Composer veto; Claude remains exact-empty-only. Managed delivery is attempted where eligible, but a proven zero-input failure falls back to one unmanaged delivery with no managed callback Turn. After Enter, AKK best-effort attaches a Terminal Watch callback; Watch failure never changes the successful Send. Once Codex mutation begins, an uncertain result must not be retried automatically. Wait for an attached Watch callback or use its status as recovery. The status-card-only first-task path remains the zero-rollout special case. `send({turn_id})` is never an ordinary target: use it only for a fresh `retry_submission` action after explicit confirmation, with no other field. Never construct or pass an opaque fence or composer authority. Use `respond` with its `turn_id` only when that Turn is explicitly `waiting_for_openclaw`; the answer stays in the same Turn. Do not add timeout fields for ordinary use; `timeoutSeconds` is unsupported.
|
|
87
|
+
4. Read the selected resource's `available_actions`. For every mutation, use only an action present there, start with its prefilled semantic IDs, supply every `missing_required` field, and consult the top-level v25 `action_contracts`. Read-only Watch is the exception: explicit user intent plus one complete exact `terminal_id` is sufficient even when `available_actions.watch` is absent. The only additional mutation sources are a terminal row's `handoff_decision.choices.take_over_current.action` and an exact `blocking_turns[].recovery_action`: use either only after explicit user confirmation and refresh the list immediately afterward.
|
|
88
|
+
5. If an existing managed Session advertises send with `session_id`, call `agent_knock_knock_send({session_id,request})`; it creates a new Turn strictly in that Session's native context and may require exact empty before input. If the selected row advertises terminal-scoped send, call `agent_knock_knock_send({terminal_id,request})`. `terminal_follow_current` may adopt a safe human-driven handoff or send once within an exact, complete Codex rollout-candidate inventory before binding the uniquely accepting native thread. `terminal_user_explicit` instead preserves the user's Send when internal AKK state is broken: Codex replaces the current Composer with the new request and submits exactly once without a post-text Composer veto; Claude remains exact-empty-only. For source-less Codex sends, zero exact acceptors remains pending for monitor recovery, one promotes the provisional Session/Turn, and multiple acceptors or identity drift becomes uncertain without replay. Managed delivery is attempted where eligible, but a proven zero-input failure falls back to one unmanaged delivery with no managed callback Turn. After Enter, AKK best-effort attaches a Terminal Watch callback; Watch failure never changes the successful Send. Once Codex mutation begins, an uncertain result must not be retried automatically. Wait for an attached Watch callback or use its status as recovery. The status-card-only first-task path remains the zero-rollout special case. `send({turn_id})` is never an ordinary target: use it only for a fresh `retry_submission` action after explicit confirmation, with no other field. Never construct or pass an opaque fence or composer authority. Use `respond` with its `turn_id` only when that Turn is explicitly `waiting_for_openclaw`; the answer stays in the same Turn. Do not add timeout fields for ordinary use; `timeoutSeconds` is unsupported.
|
|
85
89
|
6. If multiple terminals match, show their `short_ref`, agent, provider, and terminal target, then ask the user to choose. If a human switch has an unresolved Turn, ambiguous ownership, or unverifiable identity and no follow-current send is advertised, report that blocker and ask the user which context to resolve; never guess, supersede active work, or bypass the fence.
|
|
86
90
|
|
|
87
91
|
An idle pane is at a verified ready prompt, with no current work or unresolved permission request. A previously completed managed turn alone is not proof that the pane is still idle.
|
|
@@ -90,9 +94,9 @@ Do not treat ordinary send as native clear, new-session, fork, branch, side thre
|
|
|
90
94
|
|
|
91
95
|
## Terminal Watch
|
|
92
96
|
|
|
93
|
-
Terminal Watch is read-only and user-intent-first. The normal sequence is user selects a Codex or Claude Code terminal → fresh `agent_knock_knock_list` or `/akk list` → copy its complete `terminal_id` and, when present, its advertised `watch` action → retain the returned `watch_id` for status or unwatch. Advertisement is discovery help, not Watch authorization. If the user explicitly supplies one complete exact terminal ID, call `agent_knock_knock_watch({terminal_id})` even when that row does not advertise Watch. Never infer a terminal or use a selector/short ID.
|
|
97
|
+
Creating and observing a Terminal Watch is read-only and user-intent-first; answering a supported questionnaire later is a separate explicit, owner-bound mutation. The normal sequence is user selects a Codex or Claude Code terminal → fresh `agent_knock_knock_list` or `/akk list` → copy its complete `terminal_id` and, when present, its advertised `watch` action → retain the returned `watch_id` for status or unwatch. Advertisement is discovery help, not Watch authorization. If the user explicitly supplies one complete exact terminal ID, call `agent_knock_knock_watch({terminal_id})` even when that row does not advertise Watch. Never infer a terminal or use a selector/short ID.
|
|
94
98
|
|
|
95
|
-
Managed ownership is not a veto. Prefer an existing managed Turn monitor when exact Turn attribution is wanted, but an explicit Watch may coexist because
|
|
99
|
+
Managed ownership is not a veto. Prefer an existing managed Turn monitor when exact Turn attribution is wanted, but an explicit Watch may coexist because observation sends no input and does not adopt, replace, close, reserve, block, interrupt, approve, or otherwise mutate that Turn, Session, terminal, or task. A successful `terminal_user_explicit` unmanaged fallback may separately return an automatic exact request-bound Watch after AKK sends; retain that `watch_id` and use Status for recovery. Once exact request acceptance, terminal identity, owner, and one current supported questionnaire are established, that Watch may emit an idempotent `interaction_required` callback. The callback itself is notification only; call `agent_knock_knock_status({watch_id})` in the owning controller conversation to obtain the single-use private response offer, and respond only when its projection says `capabilities.respond=true`. When exact response authority cannot be proven, AKK emits `interaction_manual_required` instead; that state and every terminal-activity Watch remain notify-only with `capabilities.interaction_respond=false`, so the human must answer in the live TUI.
|
|
96
100
|
|
|
97
101
|
At creation, AKK first tries to build a privacy-safe exact provider task anchor. Codex binds rollout identity and request/turn byte boundaries; Claude binds transcript identity, root prompt, and current-turn byte boundaries. Success returns `watch_mode="exact_task"`, `confidence="exact"`. Later process, endpoint, native-thread, file identity, truncation/replacement, boundary, successor-task, or fingerprint drift invalidates that exact Watch rather than silently following another task.
|
|
98
102
|
|
|
@@ -102,9 +106,9 @@ Treat a terminal-activity completion-shaped callback exactly as labeled: it mean
|
|
|
102
106
|
|
|
103
107
|
Hard creation failure is limited to an absent exact terminal, inability to identify its endpoint/process, absence of both a durable exact-task anchor and a read-only screen-status activity path, or inability to create/write the durable Watch Store. Existing identical active observation may return its current `watch_id` instead of failing as a duplicate.
|
|
104
108
|
|
|
105
|
-
Approval is notification-only
|
|
109
|
+
Approval attention is notification-only for every Watch: never call an approval tool for a `watch_id`, send approval keys, or apply `autoApprove`. Questionnaire attention is different. An automatic exact request-bound Watch created by `terminal_user_explicit` unmanaged fallback can, after exact request acceptance and attribution, emit `interaction_required`; call Status with its exact `watch_id`, show the projected question to the user, and use `respond_interaction({watch_id,...})` only when that fresh owner-bound projection advertises `capabilities.respond=true`. A terminal-activity Watch or `interaction_manual_required` callback remains notify-only: tell the user to inspect and answer in the live TUI, and send no questionnaire input. Each new exact attention fingerprint is notified once while the Watch remains active. Terminal outcomes settle once. The durable outbox uses deterministic notification IDs/idempotency and leased retry, so startup and periodic supervision can safely recover callback delivery after AKK, OpenClaw, or Gateway restart.
|
|
106
110
|
|
|
107
|
-
The current plugin registers
|
|
111
|
+
The current plugin registers 19 OpenClaw tools and list action-contract v25. Every structured model action carries semantic IDs only; opaque fences, Composer digests, and draft text are derived or retained privately. Watch uses `agent_knock_knock_watch({terminal_id})`, `agent_knock_knock_status({watch_id})`, and `agent_knock_knock_unwatch({watch_id})`; its internal CLI boundary is `watch-terminal`, `watch-status`, `unwatch-terminal`, and `reconcile-watches`.
|
|
108
112
|
|
|
109
113
|
For native status inspection:
|
|
110
114
|
|
|
@@ -160,7 +164,7 @@ After an asynchronous send operation is accepted, end the OpenClaw turn. Wait fo
|
|
|
160
164
|
|
|
161
165
|
For managed terminal entries, `agent_knock_knock_status` captures AKK Turn state plus a bounded terminal screen and returns `terminal_screen`. With `watch_id`, it returns the exact durable Terminal Watch record, including `watch_mode`, `confidence`, and any warnings. It must not imply that an exact task completed when a `terminal_activity` Watch only observed stable idle, or that Watch sent/adopted the task. Neither form actively executes the coding agent's native `/status`. Use `agent_knock_knock_native_inspect` only for a terminal row's advertised, version-scoped native status action. Do not inspect the pane with raw provider or shell commands unless the relevant AKK inspection is unavailable or fails.
|
|
162
166
|
|
|
163
|
-
For an exact managed Turn, Status may
|
|
167
|
+
For an exact managed Turn or a response-capable exact Watch, Status may return a native questionnaire `interaction_state`. The managed monitor or exact Watch proactively sends an `interaction_required` callback for each supported actionable step, but that callback is notification only: it does not create response authority. In the owning controller conversation, call Status with the callback's exact `turn_id` or `watch_id`, treat the returned state as a single-use current-step projection rather than ordinary response text, and display it to the user. The private response offer exists only in the same controller conversation that displayed that Status result. Require `state="pending"` and `capabilities.respond=true`, review the projected question with the user, and pass exactly the same subject id plus only its semantic ids and typed answer to `agent_knock_knock_respond_interaction`. For a Codex custom answer, choose the guarded `Type something.` option advertised beside the exact client-generated `None of the above` row; AKK derives this semantic option when the client rendered only native Other. AKK moves to that native Other row, opens its Notes editor, and the next fresh interaction accepts `free_text`; choosing `None of the above` itself still submits it directly without Notes. Codex delivers custom text as `user_note: ...` alongside the native Other label, not as a Claude-style bare value. One call answers one step; wait for the next callback or refresh Status after success because the next question, custom-text editor, or final confirmation has a new `interaction_id`. If only the displayed `expires_at` has elapsed while its session-bound private offer remains live, Respond performs an exact locked terminal recapture before input; changed, missing, `manual_required`, secret, multi-select, uncertain, terminal-activity, or subject-mismatched interactions still fail closed. Never send raw keys or retry blindly.
|
|
164
168
|
|
|
165
169
|
## Cancellation and Recovery
|
|
166
170
|
|
|
@@ -197,9 +201,9 @@ A trusted, default-disabled plugin `autoApprove` policy may independently approv
|
|
|
197
201
|
|
|
198
202
|
## Terminal Sessions
|
|
199
203
|
|
|
200
|
-
`agent_knock_knock_list` is terminal-first: every eligible already-running Codex or Claude Code pane appears once in `terminals[]`, even when retained managed Turns reference it. The resource chain is terminal → verified native session → managed AKK `session_id` → Turns; independent observation-only records appear in `terminal_watches[]` and are addressed only by `watch_id`. `process_state` reports process liveness and `activity_state`
|
|
204
|
+
`agent_knock_knock_list` is terminal-first: every eligible already-running Codex or Claude Code pane appears once in `terminals[]`, even when retained managed Turns reference it. The resource chain is terminal → verified native session → managed AKK `session_id` → Turns; independent observation-only records appear in `terminal_watches[]` and are addressed only by `watch_id`. `process_state` reports process liveness. Read `screen_state` as bounded live-TUI evidence, `native_identity_state` as foreground native-session resolution, and `durable_activity_state` as exact artifact-backed task activity. The legacy `activity_state` is a conservative compatibility projection and may remain `unknown` while `screen_state="idle"`; none of these diagnostic fields replaces `available_actions` authority. `managed.current_turn` is the authoritative active Turn for that terminal; otherwise `managed.recent_turn` shows the newest retained context. A human-driven thread mismatch remains `management_state="conflict"`; `handoff_state="external_handoff_adoptable"` authorizes only the exact fenced `send` advertised on that row, while `external_handoff_blocked` means do not send or guess a recovery. Listing itself never adopts the new context. Request `all=true` only when older `managed.history`, settled Terminal Watches, or retained unavailable history is needed. By default, `unavailable_managed_turns[]` contains attention-needed records whose terminal is unavailable.
|
|
201
205
|
|
|
202
|
-
The top-level
|
|
206
|
+
The top-level v25 `action_contracts` summarizes each tool's semantic-ID inputs. `available_actions` is the authoritative current-action source for mutations after listing except for the explicitly modeled nested handoff decision and `blocking_turns[].recovery_action`; read-only `watch({terminal_id})` deliberately honors an exact user-selected terminal even without advertisement. A native questionnaire response instead requires the current `interaction_state` returned by Status in the same controller conversation. Approval, questionnaire response, handoff takeover, and `reconcile_binding` require explicit user intent and fresh source state. Model-facing shapes are: `watch({terminal_id})`; `send({session_id|terminal_id,request})`, with the targets mutually exclusive; `identify_foreground({terminal_id})`; `identify_and_send({terminal_id,request})`; `respond_interaction({turn_id|watch_id,interaction_id,answers})`, with exactly one subject id and only projected question/option ids; managed `approve({turn_id,decision})` or approve-once-only terminal-scoped `approve({terminal_id})`; `native_inspect({terminal_id,inspection})`; `new_thread({terminal_id})`; `resume_thread({terminal_id,native_thread_id})`; and `reconcile_binding({terminal_id,conflicting_session_id})`. A top-level `previous` block, when present, is the only authority for a “previous/刚才那个” request; human-facing numbers and short IDs remain slash-navigation aids and are never structured tool arguments. The model never carries terminal, binding, candidate, composer, handoff, approval, interaction-fingerprint, revision, binding ID/generation, or handoff-only live-native-UUID fences; it never receives draft text or composer digests. `native_thread_id` remains the semantic resume identity. AKK derives those private fences and revalidates them before side effects. Orphan-close `expected_message_id` and `expected_transition_id` remain because they are entity IDs. Store format remains 1 and writer protocol is 7; Terminal Watch schema remains 3.
|
|
203
207
|
|
|
204
208
|
Before every terminal operation, AKK revalidates the expected agent PID and provider-owned terminal identity. Native inspection, lifecycle input, and every Claude Code Send additionally require an exactly empty Composer; managed Send may require exact empty before input. Codex `terminal_user_explicit` instead requires a scanned, non-blocked approval state. Composer visibility, stability, exactness, and parsed working activity do not veto this user-priority path, and after text injection no Composer observation may veto Enter. Humans can attach to the same tmux or Herdr session and continue directly at any time.
|
|
205
209
|
|