@scotthuang/agent-knock-knock 0.12.0 → 0.12.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scotthuang/agent-knock-knock",
3
- "version": "0.12.0",
3
+ "version": "0.12.2",
4
4
  "description": "Control local Codex and Claude Code from OpenClaw through shared tmux or Herdr terminals, with seamless human-agent handoff.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -33,7 +33,7 @@ Core slash-command forms:
33
33
  - `/akk respond <turn-selector>: <answer>`: answer a coding-agent question inside a `waiting_for_openclaw` Turn.
34
34
  - `/akk cancel <turn-selector>`: interrupt the exact Turn without closing its terminal pane.
35
35
 
36
- 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. A natural-language tool call may preserve a selector explicitly named by the user; otherwise use a list-prefilled selector or omit it and require a unique pane. Never pass a selector as `session_id` or `turn_id`. Native-thread slash commands are stricter: copy the full `terminal_id` returned by `/akk list`, not its `@short-ref`. The slash handler reads a fresh lifecycle snapshot and immediately supplies its compare-and-swap binding token internally; the human never copies that token. Once an AKK session exists, plugin actions prefill the authoritative full `session_id` for ordinary send or `turn_id` for respond and managed controls. The same raw terminal row may advertise status, approval, cancellation, or orphan-close with its own prefilled `conversation_id` compatibility selector. Use only the exact returned action; never infer, copy, or reuse compatibility selectors. For every send, AKK must revalidate the selected agent PID and provider-owned terminal identity, confirm that the process and pane working directories match, and verify the idle prompt.
36
+ 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. A natural-language tool call may preserve a selector explicitly named by the user; otherwise use a list-prefilled action or omit the target and require a unique pane. Never pass a selector as `session_id` or `turn_id`. A send action with `session_id` is session-scoped and must remain pinned to that exact native context. A listed follow-current send is terminal-scoped: preserve its exact full terminal `selector` and fresh `expected_terminal_token` together so AKK can safely absorb a verified, quiescent human thread switch. Never add that token to `session_id`, infer it, copy it to another row, or reuse it after another terminal action. Native-thread slash commands are stricter: copy the full `terminal_id` returned by `/akk list`, not its `@short-ref`. The slash handler reads a fresh lifecycle snapshot and immediately supplies its compare-and-swap binding token internally; the human never copies that token. Plugin actions prefill the authoritative arguments for ordinary send and the exact `turn_id` for respond and managed controls. The same raw terminal row may advertise status, approval, cancellation, or orphan-close with its own prefilled `conversation_id` compatibility selector. Use only the exact returned action; never infer, copy, or reuse compatibility selectors. For every send, AKK must revalidate the selected agent PID and provider-owned terminal identity, confirm that the process and pane working directories match, and verify the idle prompt.
37
37
 
38
38
  AKK discovers eligible panes across workspaces. When more than one target matches, use a selector returned by `AKK list`; never guess based on a workspace name or path.
39
39
 
@@ -43,20 +43,21 @@ Natural-language forms:
43
43
  - `AKK Codex: <task>`: call `agent_knock_knock_send` with `request=<task>` and `selector="codex"`.
44
44
  - `AKK Claude: <task>`: call `agent_knock_knock_send` with `request=<task>` and `selector="claude"`.
45
45
  - Requests to list AKK or local coding-agent work: call `agent_knock_knock_list`.
46
+ - 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`. Preserve its full `selector` and `expected_terminal_token`, add the user's text as `request`, and do not substitute the stale `session_id`.
46
47
  - 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` only when the exact terminal row advertises `native_inspect`. Preserve its complete `terminal_id`, `inspection="status"`, and `expected_binding_token`; do not substitute AKK Turn status or ordinary send.
47
48
  - 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`.
48
49
  - Explicit requests to start a new thread or clear context: call `agent_knock_knock_new_thread` only from an advertised `new_thread` action, preserving its exact `terminal_id` and `expected_binding_token`.
49
- - Explicit requests to recover a listed binding conflict: call `agent_knock_knock_reconcile_binding` only from that terminal row's advertised `reconcile_binding` action, preserving its exact terminal, Session revision, binding token, and terminal token. This detaches the stale/conflicting binding without adopting the live thread; refresh the list before any later control.
50
+ - Explicit requests for low-level recovery of a listed binding conflict: call `agent_knock_knock_reconcile_binding` only from that terminal row's advertised `reconcile_binding` action, preserving its exact terminal, Session revision, binding token, and terminal token. This detaches the stale/conflicting binding without adopting the live thread; refresh the list before any later control. Do not use it in place of an advertised terminal-scoped `send` when the user simply wants to continue in the human-selected current context.
50
51
  - Explicit requests to resume prior native context: first call `agent_knock_knock_list_resumable_threads`; then call `agent_knock_knock_resume_thread` with the same exact `terminal_id`, the complete UUID and opaque `candidate_token` from one `resumable=true` row, and the `expected_binding_token` from that same result. For “previous” / “刚才那个”, proceed only when that fresh result contains `previous.available_actions.resume_thread`, and use that exact action; never substitute the newest row.
51
52
  - Requests to inspect current output or ask what a task is doing: call `agent_knock_knock_status`.
52
- - A later request for an existing listed AKK session: call `agent_knock_knock_send` with its authoritative `session_id` and `request=<message>`; this creates a new Turn in the same native context.
53
- - Requests to continue the current thread are ordinary sends, not lifecycle actions.
53
+ - A later request for an existing listed AKK session: call `agent_knock_knock_send` with its authoritative `session_id` and `request=<message>`; this creates a new Turn in that exact native context and never follows a different thread now visible in its pane.
54
+ - 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 selector and token when a human-driven switch is present.
54
55
  - 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>`.
55
56
  - Requests to stop current work: call `agent_knock_knock_cancel`.
56
57
 
57
58
  ## Sessions and Turns
58
59
 
59
- AKK's identity hierarchy is terminal → native Codex or Claude Code session → AKK session → Turns. Once the AKK session exists, its `session_id` is the ordinary-send target. Each accepted send creates a distinct `turn_id` without clearing the native agent context. A `turn_id` is only for history, callbacks, respond, status, approval, cancellation, renewal, callback retry, and close.
60
+ AKK's identity hierarchy is terminal → native Codex or Claude Code session → AKK session → Turns. A `session_id` is the strict ordinary-send target for one exact native context. A terminal-scoped follow-current action is deliberately different: its exact `selector` plus `expected_terminal_token` lets the user hand the pane's currently verified context back to AKK after a safe human-driven switch. Each accepted send creates a distinct `turn_id` without clearing the native agent context. A `turn_id` is only for history, callbacks, respond, status, approval, cancellation, renewal, callback retry, and close.
60
61
 
61
62
  Use `agent_knock_knock_send` with `request` and neither `session_id` nor `selector` only when the target is unspecified. AKK must resolve exactly one eligible Codex or Claude Code pane across all workspaces, attach or discover its AKK session, and verify that it is idle immediately before writing the request. If no eligible pane exists, report AKK's setup guidance; do not substitute another execution path.
62
63
 
@@ -65,9 +66,9 @@ For ordinary send or an in-flight answer:
65
66
  1. Reuse an AKK session only when the user's reference uniquely identifies its verified native session and terminal incarnation.
66
67
  2. If no ID is supplied and more than one eligible pane may exist, call `agent_knock_knock_list`.
67
68
  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.
68
- 4. Read the selected resource's `available_actions`. Use only an action present there, start with its prefilled authoritative arguments, supply every `missing_required` field, and consult the top-level v7 `action_contracts` for optional fields.
69
- 5. For an existing managed Session, use `send` with its prefilled `session_id`; it creates a new Turn. For first attach only, use a discovery selector explicitly named by the user or the selected unmanaged raw-terminal row's prefilled `selector`. Never infer or reuse a selector. Use `respond` with its prefilled `turn_id` only when that Turn is explicitly `waiting_for_openclaw`; the answer stays in the same Turn. Add the text as `request`. Do not add timeout fields for ordinary use; `timeoutSeconds` is unsupported.
70
- 6. If multiple terminals match, show their `short_ref`, agent, provider, and terminal target, then ask the user to choose. Never guess or send to a pane that AKK has not verified as idle.
69
+ 4. Read the selected resource's `available_actions`. Use only an action present there, start with its prefilled authoritative arguments, supply every `missing_required` field, and consult the top-level v8 `action_contracts` for optional fields. The sole additional action source is a terminal row's `handoff_decision.choices.take_over_current.action`: use it only after explicit user confirmation, preserve the complete action unchanged, and refresh the list immediately afterward.
70
+ 5. For an existing managed Session, use `send` with its prefilled `session_id`; it creates a new Turn strictly in that Session's native context. If the selected row instead advertises a follow-current `send`, preserve its full terminal `selector` and `expected_terminal_token` exactly and add the text as `request`; this action may adopt a safe human-driven handoff before creating the Turn. Legacy first attach may use a discovery selector explicitly named by the user or the selected unmanaged raw-terminal row's prefilled `selector`. Never infer or reuse a selector or token. Use `respond` with its prefilled `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.
71
+ 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.
71
72
 
72
73
  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.
73
74
 
@@ -134,7 +135,7 @@ Use `agent_knock_knock_renew` only when AKK marked the same live terminal Turn `
134
135
 
135
136
  Use `agent_knock_knock_retry_callback` only for a `callback_failed` managed turn, for example `/akk retry-callback @a1b2c3d4`.
136
137
 
137
- Use `agent_knock_knock_close` only when the user explicitly wants to close AKK's managed record. If `AKK list` reports an orphaned terminal dispatch or lifecycle transition, inspect the pane first and use the exact `/akk close <terminal-id> ...` recovery command it returns. That command contains exactly one fresh `--expected-message-id <id>` or `--expected-transition-id <id>` fence. Never invent, substitute, or reuse the fence. Closing a managed record does not close the coding agent or terminal pane.
138
+ Use `agent_knock_knock_close` only when the user explicitly wants to close AKK's managed record. If `AKK list` reports an orphaned terminal dispatch or lifecycle transition, inspect the pane first and use the exact `/akk close <terminal-id> ...` recovery command it returns. That command contains exactly one fresh `--expected-message-id <id>` or `--expected-transition-id <id>` fence. Never invent, substitute, or reuse the fence. If a verified human native-thread switch conflicts with one active Turn, do not redirect or close it automatically. Present `handoff_decision` to the user. Only after the user chooses takeover may you invoke the complete nested `take_over_current.action`, including its exact `turn_id`, `reason="superseded_by_human_context_switch"`, and `expected_handoff_token`. This snapshot-bound close sends no terminal input. Refresh `agent_knock_knock_list` afterward and use only its new follow-current send. If the user keeps the source Turn, make no AKK mutation; ask them to restore its native thread in the TUI and then refresh. Closing a managed record does not close the coding agent or terminal pane.
138
139
 
139
140
  Use `/akk doctor` only for installation checks or troubleshooting.
140
141
 
@@ -161,9 +162,9 @@ A trusted, default-disabled plugin `autoApprove` policy may independently approv
161
162
 
162
163
  ## Terminal Sessions
163
164
 
164
- `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. `process_state` reports process liveness and `activity_state` reports the parsed screen state. `managed.current_turn` is the authoritative active Turn for that terminal; otherwise `managed.recent_turn` shows the newest retained context. Request `all=true` only when older `managed.history` or retained unavailable history is needed. By default, `unavailable_managed_turns[]` contains attention-needed records whose terminal is unavailable.
165
+ `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. `process_state` reports process liveness and `activity_state` reports the parsed screen state. `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` or retained unavailable history is needed. By default, `unavailable_managed_turns[]` contains attention-needed records whose terminal is unavailable.
165
166
 
166
- The top-level v7 `action_contracts` summarizes each tool's managed target and its narrow compatibility inputs; `available_actions` is the authoritative current-action source after listing. An existing managed Session's ordinary `send` targets `session_id` and starts a new managed Turn. On first attach only, `selector` may preserve a discovery target explicitly named by the user or the exact selector prefilled by an unmanaged raw-terminal row; it must never be passed as `session_id`. `respond` and every managed control target `turn_id`; `respond` is offered only for a Turn waiting on OpenClaw. The read-only `list_resumable_threads` action is advertised on the terminal row, requires only its full `terminal_id`, and returns a fresh `expected_binding_token` plus candidate rows. The `new_thread` mutation is advertised on the terminal row and requires that terminal ID and token; each resumable candidate row advertises its own `resume_thread` mutation with the same snapshot token, its complete `native_thread_id`, and its opaque `candidate_token`. A conflict-only `reconcile_binding` action may be advertised for one exact, idle binding conflict; it preserves the listed Session revision, binding token, and terminal token, then CAS-detaches the old binding without adopting the live thread, sending terminal input, or creating a Turn. A top-level `previous` block, when present, is the only authority for a “previous/刚才那个” request. Number, short ID, and snapshot handle fields are human-facing navigation only; never pass them to the exact resume tool. Lifecycle discovery and mutations never create a Turn. A raw terminal may be controlled only through the exact action that its own row advertises; prefilled compatibility selectors, lifecycle IDs, and tokens must never be inferred, copied from another row, or reused from another snapshot. Start with the prefilled full argument, supply all `missing_required` fields, and use a returned `@short-ref` only for human-facing ordinary-send selection. Availability is a snapshot, so AKK revalidates it before side effects.
167
+ The top-level v8 `action_contracts` summarizes each tool's managed target and its narrow compatibility inputs; `available_actions` is the authoritative current-action source after listing except for the explicitly modeled, nested `handoff_decision.choices.take_over_current.action`. That decision action is authoritative only after explicit user confirmation, is snapshot-bound, and must be followed by a fresh list. An existing managed Session's strict `send` targets `session_id` and starts a new managed Turn without following a replacement context in the pane. An adoptable human handoff instead advertises `send` with the exact terminal `selector` and fresh `expected_terminal_token`; preserving both expresses terminal-scoped follow-current intent and allows adoption only inside that fenced send. Legacy first attach may still use a discovery selector explicitly named by the user or the exact selector prefilled by an unmanaged raw-terminal row; no selector may be passed as `session_id`. `respond` and every managed control target `turn_id`; `respond` is offered only for a Turn waiting on OpenClaw. The read-only `list_resumable_threads` action is advertised on the terminal row, requires only its full `terminal_id`, and returns a fresh `expected_binding_token` plus candidate rows. The `new_thread` mutation is advertised on the terminal row and requires that terminal ID and token; each resumable candidate row advertises its own `resume_thread` mutation with the same snapshot token, its complete `native_thread_id`, and its opaque `candidate_token`. A conflict-only `reconcile_binding` action remains available as low-level recovery for one safely detachable exact binding; it preserves the listed Session revision, binding token, and terminal token, then CAS-detaches the old binding without adopting the live thread, sending terminal input, or creating a Turn. A top-level `previous` block, when present, is the only authority for a “previous/刚才那个” request. Number, short ID, and snapshot handle fields are human-facing navigation only; never pass them to the exact resume tool. Lifecycle discovery and mutations never create a Turn. A raw terminal may be controlled only through the exact action that its own row advertises; prefilled compatibility selectors, lifecycle IDs, and tokens must never be inferred, copied from another row, or reused from another snapshot. Start with the prefilled full argument, supply all `missing_required` fields, and use a returned `@short-ref` only for human-facing ordinary-send selection. Availability is a snapshot, so AKK revalidates it before side effects.
167
168
 
168
169
  Before every terminal operation, AKK revalidates the expected agent PID and provider-owned terminal identity, then confirms that the process and pane working directories match. Sending new work additionally requires a verified idle prompt. Humans can attach to the same tmux or Herdr session and continue directly at any time.
169
170