@scotthuang/agent-knock-knock 0.12.28 → 0.12.30
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 +17 -0
- package/dist/src/claude-injected-paste-proof.d.ts +59 -0
- package/dist/src/claude-injected-paste-proof.js +153 -0
- package/dist/src/claude-injected-paste-proof.js.map +1 -0
- package/dist/src/claude-terminal-agent-adapter.js +20 -1
- package/dist/src/claude-terminal-agent-adapter.js.map +1 -1
- package/dist/src/cli-core.js +50 -35
- package/dist/src/cli-core.js.map +1 -1
- package/dist/src/codex-terminal-agent-adapter.d.ts +2 -1
- package/dist/src/codex-terminal-agent-adapter.js +40 -4
- package/dist/src/codex-terminal-agent-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/openclaw-plugin-command-adapter.js +155 -24
- package/dist/src/openclaw-plugin-command-adapter.js.map +1 -1
- package/dist/src/openclaw-plugin-helpers.d.ts +2 -0
- package/dist/src/openclaw-plugin-helpers.js +28 -7
- package/dist/src/openclaw-plugin-helpers.js.map +1 -1
- package/dist/src/openclaw-plugin-schemas.d.ts +104 -0
- package/dist/src/openclaw-plugin-schemas.js +108 -0
- package/dist/src/openclaw-plugin-schemas.js.map +1 -1
- package/dist/src/openclaw-private-authority-offers.d.ts +2 -0
- package/dist/src/openclaw-private-authority-offers.js +12 -0
- package/dist/src/openclaw-private-authority-offers.js.map +1 -1
- package/dist/src/terminal-agent-adapter.d.ts +34 -0
- package/dist/src/terminal-agent-adapter.js +54 -0
- package/dist/src/terminal-agent-adapter.js.map +1 -1
- package/dist/src/terminal-agent-bridge.d.ts +76 -1
- package/dist/src/terminal-agent-bridge.js +873 -153
- package/dist/src/terminal-agent-bridge.js.map +1 -1
- package/dist/src/terminal-command-cli-adapter.d.ts +2 -1
- package/dist/src/terminal-command-cli-adapter.js +46 -8
- package/dist/src/terminal-command-cli-adapter.js.map +1 -1
- package/dist/src/terminal-dispatch-execution.js +15 -0
- package/dist/src/terminal-dispatch-execution.js.map +1 -1
- package/dist/src/terminal-identity-authority-cli-adapter.d.ts +1 -0
- package/dist/src/terminal-identity-authority-cli-adapter.js +10 -1
- package/dist/src/terminal-identity-authority-cli-adapter.js.map +1 -1
- package/dist/src/terminal-interaction-authority.d.ts +33 -0
- package/dist/src/terminal-interaction-authority.js +3 -0
- package/dist/src/terminal-interaction-authority.js.map +1 -0
- package/dist/src/terminal-interaction-cli-adapter.d.ts +66 -0
- package/dist/src/terminal-interaction-cli-adapter.js +354 -0
- package/dist/src/terminal-interaction-cli-adapter.js.map +1 -0
- package/dist/src/terminal-interaction-protocol.d.ts +111 -0
- package/dist/src/terminal-interaction-protocol.js +432 -0
- package/dist/src/terminal-interaction-protocol.js.map +1 -0
- package/dist/src/terminal-list-renderer.js +31 -2
- package/dist/src/terminal-list-renderer.js.map +1 -1
- package/dist/src/terminal-monitor-cli-adapter.js +12 -3
- package/dist/src/terminal-monitor-cli-adapter.js.map +1 -1
- package/dist/src/terminal-monitor-decision-policy.d.ts +1 -1
- package/dist/src/terminal-monitor-state-cli-adapter.js +15 -1
- package/dist/src/terminal-monitor-state-cli-adapter.js.map +1 -1
- package/dist/src/terminal-mutation-cli-runtime.d.ts +44 -0
- package/dist/src/terminal-mutation-cli-runtime.js +41 -0
- package/dist/src/terminal-mutation-cli-runtime.js.map +1 -0
- package/dist/src/terminal-questionnaire-adapter.d.ts +84 -0
- package/dist/src/terminal-questionnaire-adapter.js +677 -0
- package/dist/src/terminal-questionnaire-adapter.js.map +1 -0
- package/docs/host-bridge-profiles.md +2 -2
- package/docs/quickstart-herdr.md +1 -1
- package/docs/quickstart-tmux.md +3 -1
- package/openclaw.plugin.json +4 -0
- package/package.json +1 -1
- package/templates/openclaw-skills/agent-knock-knock/SKILL.md +11 -8
|
@@ -14,6 +14,7 @@ import { readNdjsonLog } from "./transcript.js";
|
|
|
14
14
|
import { appendEvent, appendExplicitUserCloseEvent, defaultStoreDir, ensureDir, ensureStoreWritable, listConversations, loadState, messageEvent, pathsForConversation, pathsForConversationDir, saveExplicitUserCloseState, saveState, withStoreWriterLeaseAsync } from "./store.js";
|
|
15
15
|
import { createManagedSessionId, managedSessionBindingToken, managedSessionRevision, unmanagedTerminalBindingToken } from "./managed-session.js";
|
|
16
16
|
import { listManagedSessions, loadManagedSession, saveManagedSession, tryLoadManagedSession } from "./session-store.js";
|
|
17
|
+
import { isTerminalApprovalDecision } from "./terminal-agent-adapter.js";
|
|
17
18
|
import { terminalControlEvidenceMatches } from "./terminal-control-ref.js";
|
|
18
19
|
import { isExactClaudeNativeInspectionIdleComposer, TerminalEnterDispatchNotAttemptedError, TerminalInputNotStartedError } from "./terminal-agent-bridge.js";
|
|
19
20
|
import { decideTerminalSubmissionRetry, loadTerminalSubmissionRetry, projectTerminalSubmissionRetryPending, saveTerminalSubmissionRetry, terminalSubmissionRetryLedgerFields, TERMINAL_SUBMISSION_RETRY_SCHEMA, TERMINAL_SUBMISSION_RETRY_VERSION } from "./terminal-submission-retry-service.js";
|
|
@@ -4572,6 +4573,7 @@ async function runTurnResponse({ options, messageBody }) {
|
|
|
4572
4573
|
});
|
|
4573
4574
|
}
|
|
4574
4575
|
async function runApprove(options) {
|
|
4576
|
+
const decision = terminalApprovalDecisionFromOptions(options);
|
|
4575
4577
|
const terminalConversation = await resolveTerminalConversationFromOptions(options);
|
|
4576
4578
|
if (terminalConversation) {
|
|
4577
4579
|
assertExpectedHandoffTokenUsesExactTerminalSelector({
|
|
@@ -4581,6 +4583,9 @@ async function runApprove(options) {
|
|
|
4581
4583
|
if (options.autoApproved === true) {
|
|
4582
4584
|
throw new Error("automatic approval requires an exact managed Turn and cannot use a raw terminal selector");
|
|
4583
4585
|
}
|
|
4586
|
+
if (decision !== "approve_once") {
|
|
4587
|
+
throw new Error("terminal-scoped approval supports approve_once only; use an exact managed Turn to reject");
|
|
4588
|
+
}
|
|
4584
4589
|
await runTerminalConversationApprove({
|
|
4585
4590
|
options,
|
|
4586
4591
|
terminal: terminalConversation
|
|
@@ -4606,6 +4611,9 @@ async function runApprove(options) {
|
|
|
4606
4611
|
throw new Error(`conversation ${conversation.conversation_id} is not controlled through a terminal`);
|
|
4607
4612
|
}
|
|
4608
4613
|
const autoApproved = options.autoApproved === true;
|
|
4614
|
+
if (autoApproved && decision !== "approve_once") {
|
|
4615
|
+
throw new Error("automatic approval can only dispatch approve_once");
|
|
4616
|
+
}
|
|
4609
4617
|
const callbackAuthority = autoApprovalCallbackAuthorityFromOptions(options);
|
|
4610
4618
|
if (!["waiting_for_agent", "waiting_for_openclaw"].includes(conversation.status) &&
|
|
4611
4619
|
!(autoApproved && callbackAuthority)) {
|
|
@@ -4617,7 +4625,7 @@ async function runApprove(options) {
|
|
|
4617
4625
|
: undefined;
|
|
4618
4626
|
const suppliedExpectedFingerprint = stringValue(options.expectedApprovalFingerprint);
|
|
4619
4627
|
const expectedFingerprint = suppliedExpectedFingerprint ??
|
|
4620
|
-
|
|
4628
|
+
monitoredApprovalFingerprint(monitoredApproval, decision);
|
|
4621
4629
|
const claudeScreenApproval = executor.kind === "claude";
|
|
4622
4630
|
if (claudeScreenApproval) {
|
|
4623
4631
|
const monitoredState = isRecord(monitoredApproval?.approval_state)
|
|
@@ -4689,7 +4697,7 @@ async function runApprove(options) {
|
|
|
4689
4697
|
return;
|
|
4690
4698
|
}
|
|
4691
4699
|
if (!suppliedExpectedFingerprint ||
|
|
4692
|
-
expectedFingerprint !== monitoredApproval
|
|
4700
|
+
expectedFingerprint !== monitoredApprovalFingerprint(monitoredApproval, decision)) {
|
|
4693
4701
|
printJson({
|
|
4694
4702
|
conversation,
|
|
4695
4703
|
approved: false,
|
|
@@ -4728,9 +4736,27 @@ async function runApprove(options) {
|
|
|
4728
4736
|
options, conversation, statePath, logPath,
|
|
4729
4737
|
nativeTakeover: nativeTakeover,
|
|
4730
4738
|
terminalControl, executor, monitoredApproval, expectedFingerprint,
|
|
4731
|
-
autoApproved, claudeScreenApproval
|
|
4739
|
+
autoApproved, claudeScreenApproval, decision
|
|
4732
4740
|
});
|
|
4733
4741
|
}
|
|
4742
|
+
function terminalApprovalDecisionFromOptions(options) {
|
|
4743
|
+
const value = options.decision ?? "approve_once";
|
|
4744
|
+
if (!isTerminalApprovalDecision(value)) {
|
|
4745
|
+
throw new Error("--decision must be one of: approve_once, reject");
|
|
4746
|
+
}
|
|
4747
|
+
return value;
|
|
4748
|
+
}
|
|
4749
|
+
function monitoredApprovalFingerprint(approval, decision) {
|
|
4750
|
+
if (decision === "approve_once") {
|
|
4751
|
+
return stringValue(approval?.fingerprint);
|
|
4752
|
+
}
|
|
4753
|
+
const state = isRecord(approval?.approval_state)
|
|
4754
|
+
? approval.approval_state
|
|
4755
|
+
: undefined;
|
|
4756
|
+
const choices = Array.isArray(state?.choices) ? state.choices : [];
|
|
4757
|
+
const choice = choices.find((candidate) => isRecord(candidate) && candidate.decision === decision);
|
|
4758
|
+
return isRecord(choice) ? stringValue(choice.fingerprint) : undefined;
|
|
4759
|
+
}
|
|
4734
4760
|
function approvalPolicyCandidateForInspection({ agent, currentTerminalControl, inspection, fingerprint }) {
|
|
4735
4761
|
const evidence = inspection.approval.approvable
|
|
4736
4762
|
? inspection.approval.policyEvidence
|
|
@@ -4753,7 +4779,7 @@ function approvalPolicyCandidateForInspection({ agent, currentTerminalControl, i
|
|
|
4753
4779
|
: {})
|
|
4754
4780
|
};
|
|
4755
4781
|
}
|
|
4756
|
-
async function runManagedApprovalDispatch({ options, conversation, statePath, logPath, nativeTakeover, terminalControl, executor, monitoredApproval, expectedFingerprint, autoApproved, claudeScreenApproval }) {
|
|
4782
|
+
async function runManagedApprovalDispatch({ options, conversation, statePath, logPath, nativeTakeover, terminalControl, executor, monitoredApproval, expectedFingerprint, autoApproved, claudeScreenApproval, decision }) {
|
|
4757
4783
|
const policyRuleId = stringValue(options.policyRuleId);
|
|
4758
4784
|
const policyFingerprint = stringValue(options.policyFingerprint);
|
|
4759
4785
|
const autoApprovalPolicy = autoApproved
|
|
@@ -4804,7 +4830,8 @@ async function runManagedApprovalDispatch({ options, conversation, statePath, lo
|
|
|
4804
4830
|
currentTakeover?.terminal_bridge_message_id !==
|
|
4805
4831
|
nativeTakeover?.terminal_bridge_message_id ||
|
|
4806
4832
|
(claudeScreenApproval &&
|
|
4807
|
-
currentApproval
|
|
4833
|
+
monitoredApprovalFingerprint(currentApproval, decision) !==
|
|
4834
|
+
monitoredApprovalFingerprint(monitoredApproval, decision))))) {
|
|
4808
4835
|
throw new Error("approval state changed while waiting for terminal control; refresh status and retry");
|
|
4809
4836
|
}
|
|
4810
4837
|
lockedConversation = currentConversation;
|
|
@@ -4828,6 +4855,7 @@ async function runManagedApprovalDispatch({ options, conversation, statePath, lo
|
|
|
4828
4855
|
});
|
|
4829
4856
|
const currentRuntimeIdentity = terminalRuntimeIdentityForConversation(currentConversation, currentControl);
|
|
4830
4857
|
approval = await createTerminalAgentBridge(options).approve(executor.kind, currentControl, {
|
|
4858
|
+
decision,
|
|
4831
4859
|
expectedFingerprint,
|
|
4832
4860
|
scrollbackLines: Number(options.scrollbackLines ?? 120),
|
|
4833
4861
|
runtime: currentRuntimeIdentity,
|
|
@@ -4936,7 +4964,8 @@ async function runManagedApprovalDispatch({ options, conversation, statePath, lo
|
|
|
4936
4964
|
latestConversation.status !== "waiting_for_openclaw" ||
|
|
4937
4965
|
latestTakeover.terminal_bridge_message_id !==
|
|
4938
4966
|
nativeTakeover?.terminal_bridge_message_id ||
|
|
4939
|
-
latestApproval
|
|
4967
|
+
monitoredApprovalFingerprint(latestApproval, decision) !==
|
|
4968
|
+
fingerprint ||
|
|
4940
4969
|
latestNotifiedAt === undefined ||
|
|
4941
4970
|
cliNowMs() - latestNotifiedAt > CLAUDE_SCREEN_APPROVAL_TTL_MS ||
|
|
4942
4971
|
expectedFingerprint !== fingerprint ||
|
|
@@ -4960,6 +4989,7 @@ async function runManagedApprovalDispatch({ options, conversation, statePath, lo
|
|
|
4960
4989
|
terminal_bridge_approval_dispatch: {
|
|
4961
4990
|
state: "reserved",
|
|
4962
4991
|
attempt_id: randomUUID(),
|
|
4992
|
+
decision,
|
|
4963
4993
|
fingerprint,
|
|
4964
4994
|
keys,
|
|
4965
4995
|
terminal_target: dispatchControl.target,
|
|
@@ -4977,7 +5007,7 @@ async function runManagedApprovalDispatch({ options, conversation, statePath, lo
|
|
|
4977
5007
|
const actualFingerprint = approval.fingerprint;
|
|
4978
5008
|
const effectivePolicyRuleId = executorPolicyDecision?.ruleId ?? policyRuleId;
|
|
4979
5009
|
const effectivePolicyFingerprint = executorPolicyDecision?.policyFingerprint ?? policyFingerprint;
|
|
4980
|
-
if (
|
|
5010
|
+
if (approval.decisionDispatched !== true) {
|
|
4981
5011
|
releaseApprovalStateLock();
|
|
4982
5012
|
if (autoApproved) {
|
|
4983
5013
|
appendEvent(logPath, {
|
|
@@ -4996,6 +5026,8 @@ async function runManagedApprovalDispatch({ options, conversation, statePath, lo
|
|
|
4996
5026
|
printJson({
|
|
4997
5027
|
conversation,
|
|
4998
5028
|
approved: false,
|
|
5029
|
+
decision,
|
|
5030
|
+
decision_dispatched: false,
|
|
4999
5031
|
blocked: approval.blocked,
|
|
5000
5032
|
reason: approval.reason,
|
|
5001
5033
|
terminal_control: terminalControl,
|
|
@@ -5009,6 +5041,7 @@ async function runManagedApprovalDispatch({ options, conversation, statePath, lo
|
|
|
5009
5041
|
ts: cliNow().toISOString(),
|
|
5010
5042
|
conversation_id: conversation.conversation_id,
|
|
5011
5043
|
event: "terminal_approval_send",
|
|
5044
|
+
decision,
|
|
5012
5045
|
terminal_control: terminalControl,
|
|
5013
5046
|
key: approval.key,
|
|
5014
5047
|
keys: approval.keys,
|
|
@@ -5035,6 +5068,7 @@ async function runManagedApprovalDispatch({ options, conversation, statePath, lo
|
|
|
5035
5068
|
runtimeLog("info", "terminal_approval_send", {
|
|
5036
5069
|
conversation_id: conversation.conversation_id,
|
|
5037
5070
|
terminal_target: terminalControl.target,
|
|
5071
|
+
decision,
|
|
5038
5072
|
key: approval.key,
|
|
5039
5073
|
keys: approval.keys,
|
|
5040
5074
|
label: approval.label,
|
|
@@ -5069,6 +5103,7 @@ async function runManagedApprovalDispatch({ options, conversation, statePath, lo
|
|
|
5069
5103
|
terminal_bridge_approval_dispatch: undefined,
|
|
5070
5104
|
terminal_bridge_approval_resolved_at: approvalResolvedAt,
|
|
5071
5105
|
terminal_bridge_last_approval_fingerprint: actualFingerprint,
|
|
5106
|
+
terminal_bridge_last_approval_decision: decision,
|
|
5072
5107
|
terminal_bridge_last_approval_screen_digest: resolvedApprovalScreenDigest,
|
|
5073
5108
|
terminal_bridge_last_approval_request_id: resolvedTranscriptIdentity?.requestId,
|
|
5074
5109
|
terminal_bridge_last_approval_evidence_fingerprint: resolvedTranscriptIdentity?.evidenceFingerprint,
|
|
@@ -5106,7 +5141,10 @@ async function runManagedApprovalDispatch({ options, conversation, statePath, lo
|
|
|
5106
5141
|
});
|
|
5107
5142
|
printJson({
|
|
5108
5143
|
conversation: nextConversation,
|
|
5109
|
-
approved:
|
|
5144
|
+
approved: decision === "approve_once",
|
|
5145
|
+
rejected: decision === "reject",
|
|
5146
|
+
decision,
|
|
5147
|
+
decision_dispatched: true,
|
|
5110
5148
|
terminal_control: terminalControl,
|
|
5111
5149
|
key: approval.key,
|
|
5112
5150
|
keys: approval.keys,
|