@scotthuang/agent-knock-knock 0.14.17 → 0.15.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.
Files changed (121) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +5 -3
  3. package/connectors/deepseek-harness/README.md +17 -6
  4. package/connectors/pi/README.md +16 -5
  5. package/dist/src/claude-conversation-routing-cli-adapter.js +76 -6
  6. package/dist/src/claude-conversation-routing-cli-adapter.js.map +1 -1
  7. package/dist/src/claude-lifecycle-compatibility.js +3 -9
  8. package/dist/src/claude-lifecycle-compatibility.js.map +1 -1
  9. package/dist/src/claude-local-transcript-provider.d.ts +5 -15
  10. package/dist/src/claude-local-transcript-provider.js +38 -56
  11. package/dist/src/claude-local-transcript-provider.js.map +1 -1
  12. package/dist/src/claude-managed-send-route.d.ts +17 -0
  13. package/dist/src/claude-managed-send-route.js +51 -0
  14. package/dist/src/claude-managed-send-route.js.map +1 -0
  15. package/dist/src/claude-native-cli-adapter.js +11 -9
  16. package/dist/src/claude-native-cli-adapter.js.map +1 -1
  17. package/dist/src/claude-native-client.d.ts +2 -0
  18. package/dist/src/claude-native-client.js +6 -1
  19. package/dist/src/claude-native-client.js.map +1 -1
  20. package/dist/src/claude-native-discovery.js +14 -2
  21. package/dist/src/claude-native-discovery.js.map +1 -1
  22. package/dist/src/claude-native-observation.js +3 -1
  23. package/dist/src/claude-native-observation.js.map +1 -1
  24. package/dist/src/claude-native-outbox.js +15 -3
  25. package/dist/src/claude-native-outbox.js.map +1 -1
  26. package/dist/src/claude-native-peer-envelope.d.ts +3 -0
  27. package/dist/src/claude-native-peer-envelope.js +72 -0
  28. package/dist/src/claude-native-peer-envelope.js.map +1 -0
  29. package/dist/src/claude-native-public-projection.d.ts +635 -60
  30. package/dist/src/claude-native-public-projection.js +42 -11
  31. package/dist/src/claude-native-public-projection.js.map +1 -1
  32. package/dist/src/claude-native-runtime.d.ts +2 -0
  33. package/dist/src/claude-native-runtime.js +1 -1
  34. package/dist/src/claude-native-runtime.js.map +1 -1
  35. package/dist/src/claude-native-sender-policy.d.ts +3 -0
  36. package/dist/src/claude-native-sender-policy.js +14 -0
  37. package/dist/src/claude-native-sender-policy.js.map +1 -0
  38. package/dist/src/claude-native-state-store.d.ts +3 -0
  39. package/dist/src/claude-native-state-store.js +18 -6
  40. package/dist/src/claude-native-state-store.js.map +1 -1
  41. package/dist/src/claude-native-task-service.d.ts +2 -0
  42. package/dist/src/claude-native-task-service.js +37 -8
  43. package/dist/src/claude-native-task-service.js.map +1 -1
  44. package/dist/src/claude-reader-configuration.d.ts +14 -0
  45. package/dist/src/claude-reader-configuration.js +41 -0
  46. package/dist/src/claude-reader-configuration.js.map +1 -0
  47. package/dist/src/claude-terminal-agent-adapter.d.ts +4 -0
  48. package/dist/src/claude-terminal-agent-adapter.js +1 -1
  49. package/dist/src/claude-terminal-agent-adapter.js.map +1 -1
  50. package/dist/src/claude-terminal-agent-observation.d.ts +14 -0
  51. package/dist/src/claude-terminal-agent-observation.js +147 -0
  52. package/dist/src/claude-terminal-agent-observation.js.map +1 -0
  53. package/dist/src/claude-terminal-registry-observation.d.ts +29 -0
  54. package/dist/src/claude-terminal-registry-observation.js +122 -0
  55. package/dist/src/claude-terminal-registry-observation.js.map +1 -0
  56. package/dist/src/claude-transcript-config.d.ts +25 -0
  57. package/dist/src/claude-transcript-config.js +61 -0
  58. package/dist/src/claude-transcript-config.js.map +1 -0
  59. package/dist/src/cli-core.js +37 -13
  60. package/dist/src/cli-core.js.map +1 -1
  61. package/dist/src/codex-native-semantic.js +10 -2
  62. package/dist/src/codex-native-semantic.js.map +1 -1
  63. package/dist/src/codex-process-incarnation.js +3 -1
  64. package/dist/src/codex-process-incarnation.js.map +1 -1
  65. package/dist/src/conversation-list.d.ts +6 -0
  66. package/dist/src/conversation-list.js +61 -14
  67. package/dist/src/conversation-list.js.map +1 -1
  68. package/dist/src/conversation-route-dispatch.js +4 -3
  69. package/dist/src/conversation-route-dispatch.js.map +1 -1
  70. package/dist/src/conversation-route-store.d.ts +6 -1
  71. package/dist/src/conversation-route-store.js +13 -5
  72. package/dist/src/conversation-route-store.js.map +1 -1
  73. package/dist/src/conversation-runtime-route-store.js +5 -3
  74. package/dist/src/conversation-runtime-route-store.js.map +1 -1
  75. package/dist/src/semantic-tool-descriptions.d.ts +1 -1
  76. package/dist/src/semantic-tool-descriptions.js +10 -8
  77. package/dist/src/semantic-tool-descriptions.js.map +1 -1
  78. package/dist/src/semantic-tool-list-projection.js +24 -5
  79. package/dist/src/semantic-tool-list-projection.js.map +1 -1
  80. package/dist/src/semantic-tool-schemas.js +7 -5
  81. package/dist/src/semantic-tool-schemas.js.map +1 -1
  82. package/dist/src/terminal-action-projection.d.ts +1 -1
  83. package/dist/src/terminal-action-projection.js.map +1 -1
  84. package/dist/src/terminal-command-dispatch-preparation.js +6 -3
  85. package/dist/src/terminal-command-dispatch-preparation.js.map +1 -1
  86. package/dist/src/terminal-human-explicit-send-cli-adapter.js +14 -6
  87. package/dist/src/terminal-human-explicit-send-cli-adapter.js.map +1 -1
  88. package/dist/src/terminal-list-cli-adapter.d.ts +2 -0
  89. package/dist/src/terminal-list-cli-adapter.js +18 -3
  90. package/dist/src/terminal-list-cli-adapter.js.map +1 -1
  91. package/dist/src/terminal-list-ownership-service.js +1 -1
  92. package/dist/src/terminal-list-ownership-service.js.map +1 -1
  93. package/dist/src/terminal-list-projection-service.js +5 -0
  94. package/dist/src/terminal-list-projection-service.js.map +1 -1
  95. package/dist/src/terminal-list-renderer.js +1 -1
  96. package/dist/src/terminal-list-renderer.js.map +1 -1
  97. package/dist/src/terminal-managed-interaction-list-action.d.ts +17 -0
  98. package/dist/src/terminal-managed-interaction-list-action.js +59 -0
  99. package/dist/src/terminal-managed-interaction-list-action.js.map +1 -0
  100. package/dist/src/terminal-managed-send-cli-adapter.js +8 -1
  101. package/dist/src/terminal-managed-send-cli-adapter.js.map +1 -1
  102. package/dist/src/terminal-model-control-profile.d.ts +3 -2
  103. package/dist/src/terminal-model-control-profile.js +32 -9
  104. package/dist/src/terminal-model-control-profile.js.map +1 -1
  105. package/dist/src/terminal-monitor-decision-policy.d.ts +1 -1
  106. package/dist/src/terminal-process-source.js +3 -1
  107. package/dist/src/terminal-process-source.js.map +1 -1
  108. package/dist/src/terminal-questionnaire-adapter.js +11 -8
  109. package/dist/src/terminal-questionnaire-adapter.js.map +1 -1
  110. package/dist/src/terminal-runtime-cli-adapter.js +27 -72
  111. package/dist/src/terminal-runtime-cli-adapter.js.map +1 -1
  112. package/dist/src/terminal-watch-record.js +2 -0
  113. package/dist/src/terminal-watch-record.js.map +1 -1
  114. package/dist/src/terminal-watch-terminal-identity.js +1 -0
  115. package/dist/src/terminal-watch-terminal-identity.js.map +1 -1
  116. package/docs/claude-cli-direct.md +32 -13
  117. package/docs/list-output.md +8 -0
  118. package/docs/operator-guide.md +23 -4
  119. package/openclaw.plugin.json +1 -1
  120. package/package.json +1 -1
  121. package/templates/openclaw-skills/agent-knock-knock/SKILL.md +23 -11
@@ -1,7 +1,8 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import fs from "node:fs";
3
- import os from "node:os";
4
3
  import path from "node:path";
4
+ import { defaultClaudeHome, claudeTranscriptAnchorFingerprint, claudeTranscriptFileId as transcriptFileId, resolveClaudeTranscriptHome, validatedClaudeConfigDir } from "./claude-transcript-config.js";
5
+ export { defaultClaudeHome, claudeTranscriptAnchorFingerprint } from "./claude-transcript-config.js";
5
6
  import { isClaudeAgentIdleState } from "./claude-terminal-agent-adapter.js";
6
7
  import { claudeLifecycleSourceVersionSupported, claudeRuntimeLifecycleCompatibilityProfile, DEFAULT_CLAUDE_LIFECYCLE_VERSION, } from "./claude-lifecycle-compatibility.js";
7
8
  import { assertParentsPrecedeChildren, earliestClaudeTranscriptRecordOffset, initialClaudeTranscriptCheckpointRecords, orderClaudePrewrittenAttachments } from "./claude-transcript-record-order.js";
@@ -11,16 +12,11 @@ import { validateTerminalSubmissionAcceptanceEvidence } from "./terminal-submiss
11
12
  const CLAUDE_TRANSCRIPT_ANCHOR_VERSION = 1;
12
13
  const CLAUDE_TRANSCRIPT_MAX_TURN_BYTES = 64 * 1024 * 1024;
13
14
  const CLAUDE_SESSION_ID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/iu;
14
- const MINIMUM_CLAUDE_TRANSCRIPT_VERSION = [2, 1, 198];
15
15
  const CLAUDE_TRANSCRIPT_VERSION_PATTERN = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/u;
16
16
  const NO_FOLLOW_FLAG = typeof fs.constants.O_NOFOLLOW === "number"
17
17
  ? fs.constants.O_NOFOLLOW
18
18
  : 0;
19
19
  const CLAUDE_HISTORICAL_METADATA_MAX_BYTES = 1024 * 1024;
20
- export function defaultClaudeHome() {
21
- const configured = process.env.CLAUDE_CONFIG_DIR?.trim();
22
- return configured || path.join(os.homedir(), ".claude");
23
- }
24
20
  /** List exact, root-interactive Claude sessions from owner-private transcripts. */
25
21
  export function listClaudeHistoricalSessions(options) {
26
22
  if (!options.cwd || !path.isAbsolute(options.cwd)) {
@@ -371,7 +367,10 @@ export function captureClaudeTranscriptAnchor(options) {
371
367
  !isClaudeAgentIdleState(agent)) {
372
368
  return undefined;
373
369
  }
374
- const claudeHome = path.resolve(options.claudeHome ?? defaultClaudeHome());
370
+ const claudeHome = resolveClaudeTranscriptHome({
371
+ claudeHome: options.claudeHome, configDir: agent.configDir
372
+ });
373
+ const configDir = agent.configDir ? { config_dir: claudeHome } : {};
375
374
  const projectsRoot = projectsRootPath(claudeHome);
376
375
  if (!isRealDirectory(projectsRoot)) {
377
376
  if (lstatOrUndefined(projectsRoot) !== undefined ||
@@ -380,6 +379,7 @@ export function captureClaudeTranscriptAnchor(options) {
380
379
  }
381
380
  return {
382
381
  schema_version: CLAUDE_TRANSCRIPT_ANCHOR_VERSION,
382
+ ...configDir,
383
383
  session_id: sessionId,
384
384
  cwd: path.resolve(cwd),
385
385
  pid,
@@ -395,6 +395,7 @@ export function captureClaudeTranscriptAnchor(options) {
395
395
  if (!located) {
396
396
  return {
397
397
  schema_version: CLAUDE_TRANSCRIPT_ANCHOR_VERSION,
398
+ ...configDir,
398
399
  session_id: sessionId,
399
400
  cwd: path.resolve(cwd),
400
401
  pid,
@@ -415,6 +416,7 @@ export function captureClaudeTranscriptAnchor(options) {
415
416
  }
416
417
  return {
417
418
  schema_version: CLAUDE_TRANSCRIPT_ANCHOR_VERSION,
419
+ ...configDir,
418
420
  session_id: sessionId,
419
421
  cwd: path.resolve(cwd),
420
422
  pid,
@@ -448,7 +450,11 @@ export function captureClaudeHumanStartedActiveTaskAnchor(options) {
448
450
  !isActiveClaudeAgentState(agent)) {
449
451
  return undefined;
450
452
  }
451
- const projectsRoot = projectsRootPath(path.resolve(options.claudeHome ?? defaultClaudeHome()));
453
+ const claudeHome = resolveClaudeTranscriptHome({
454
+ claudeHome: options.claudeHome, configDir: agent.configDir
455
+ });
456
+ const configDir = agent.configDir ? { config_dir: claudeHome } : {};
457
+ const projectsRoot = projectsRootPath(claudeHome);
452
458
  if (!isRealDirectory(projectsRoot)) {
453
459
  return undefined;
454
460
  }
@@ -492,6 +498,7 @@ export function captureClaudeHumanStartedActiveTaskAnchor(options) {
492
498
  const fileId = transcriptFileId(sessionId, `${device}:${inode}`);
493
499
  const transcriptAnchor = {
494
500
  schema_version: CLAUDE_TRANSCRIPT_ANCHOR_VERSION,
501
+ ...configDir,
495
502
  session_id: sessionId,
496
503
  cwd: path.resolve(cwd),
497
504
  pid,
@@ -525,6 +532,7 @@ export function captureClaudeHumanStartedActiveTaskAnchor(options) {
525
532
  const base = {
526
533
  schema: "agent-knock-knock/claude-human-started-active-task-anchor",
527
534
  version: 1,
535
+ ...configDir,
528
536
  session_id: sessionId,
529
537
  cwd: path.resolve(cwd),
530
538
  pid,
@@ -555,7 +563,11 @@ export function observeClaudeHumanStartedActiveTask(options) {
555
563
  const anchor = validateClaudeHumanStartedActiveTaskAnchor(options.anchor);
556
564
  const checkpoint = claudeActiveTaskObservationCheckpoint(anchor, options);
557
565
  const resumeOffsetBytes = checkpoint.safe_resume_offset_bytes;
558
- const projectsRoot = projectsRootPath(path.resolve(options.claudeHome ?? defaultClaudeHome()));
566
+ const projectsRoot = projectsRootPath(resolveClaudeTranscriptHome({
567
+ claudeHome: options.claudeHome,
568
+ anchoredConfigDir: anchor.config_dir,
569
+ configDir: exactInteractiveAgent(options.agentRows, anchor.pid)?.configDir
570
+ }));
559
571
  if (!isRealDirectory(projectsRoot)) {
560
572
  return claudeActiveTaskUnavailable("Claude transcript projects directory is unavailable");
561
573
  }
@@ -656,12 +668,14 @@ export function validateClaudeHumanStartedActiveTaskAnchor(value) {
656
668
  "schema", "version", "session_id", "cwd", "pid", "agent_started_at_ms",
657
669
  "captured_at", "relative_path", "device", "inode", "prompt_uuid",
658
670
  "request_hash", "claude_version", "transcript_file_id",
659
- "turn_start_offset_bytes", "observed_end_offset_bytes", "anchor_fingerprint"
671
+ "turn_start_offset_bytes", "observed_end_offset_bytes", "anchor_fingerprint",
672
+ "config_dir"
660
673
  ]);
661
674
  if (Object.keys(value).some((key) => !allowedKeys.has(key))) {
662
675
  throw new Error("Claude human-started active-task anchor has unsupported fields");
663
676
  }
664
677
  const sessionId = uuidValue(value.session_id);
678
+ validatedClaudeConfigDir(value.config_dir);
665
679
  const promptUuid = uuidValue(value.prompt_uuid);
666
680
  const cwd = nonEmptyString(value.cwd);
667
681
  const pid = positiveInteger(value.pid);
@@ -721,6 +735,7 @@ export function validateClaudeHumanStartedActiveTaskAnchor(value) {
721
735
  function claudeTranscriptAnchorForHumanStartedTask(anchor) {
722
736
  return {
723
737
  schema_version: CLAUDE_TRANSCRIPT_ANCHOR_VERSION,
738
+ ...(anchor.config_dir ? { config_dir: anchor.config_dir } : {}),
724
739
  session_id: anchor.session_id,
725
740
  cwd: anchor.cwd,
726
741
  pid: anchor.pid,
@@ -951,7 +966,7 @@ function advanceClaudeHumanStartedActiveTaskCheckpoint(anchor, checkpoint, recor
951
966
  lastRecordUuid = recordUuid;
952
967
  }
953
968
  if (hasUnresolvedBackgroundWork(record) ||
954
- record.subtype === "stop_hook_summary") {
969
+ hasBlockingStopSummary(record)) {
955
970
  throw new Error("Claude anchored task acquired unsupported background or stop-hook work");
956
971
  }
957
972
  advanceClaudeCheckpointToolState(record, recordUuid, unresolvedToolUses);
@@ -1473,7 +1488,12 @@ function readClaudeTranscriptTurnSnapshot(request, options, requiredAgentStatus,
1473
1488
  return unavailable(`the exact Claude process is ${agent.status}, not ${requiredAgentStatus}`);
1474
1489
  }
1475
1490
  }
1476
- const projectsRoot = projectsRootPath(path.resolve(options.claudeHome ?? defaultClaudeHome()));
1491
+ const projectsRoot = projectsRootPath(resolveClaudeTranscriptHome({
1492
+ claudeHome: options.claudeHome,
1493
+ anchoredConfigDir: anchor.config_dir,
1494
+ configDir: readMode === "durable_fallback" ? undefined
1495
+ : exactInteractiveAgent(options.agentRows, anchor.pid)?.configDir
1496
+ }));
1477
1497
  if (!isRealDirectory(projectsRoot)) {
1478
1498
  return unavailable("Claude transcript projects directory is unavailable");
1479
1499
  }
@@ -1915,7 +1935,7 @@ function pendingApprovalEvidence(snapshot, promptUuid, lastDescendant, pending)
1915
1935
  if (!claudeVersion) {
1916
1936
  throw new Error("Claude pending Bash tool use has no compatible version");
1917
1937
  }
1918
- if (!isCompatiblePendingApprovalClaudeVersion(claudeVersion)) {
1938
+ if (!isCompatibleClaudeVersion(claudeVersion)) {
1919
1939
  return undefined;
1920
1940
  }
1921
1941
  const commandSha256 = sha256Hex(command);
@@ -1975,6 +1995,7 @@ function transcriptAnchorFromContext(context) {
1975
1995
  const device = nonEmptyString(value.device);
1976
1996
  const inode = nonEmptyString(value.inode);
1977
1997
  const fileExisted = value.file_existed;
1998
+ const configDir = validatedClaudeConfigDir(value.config_dir);
1978
1999
  if (schemaVersion !== CLAUDE_TRANSCRIPT_ANCHOR_VERSION ||
1979
2000
  !sessionId ||
1980
2001
  !cwd ||
@@ -1992,6 +2013,7 @@ function transcriptAnchorFromContext(context) {
1992
2013
  }
1993
2014
  return {
1994
2015
  schema_version: CLAUDE_TRANSCRIPT_ANCHOR_VERSION,
2016
+ ...(configDir ? { config_dir: configDir } : {}),
1995
2017
  session_id: sessionId,
1996
2018
  cwd,
1997
2019
  pid,
@@ -2371,30 +2393,9 @@ function isCompatibleClaudeVersion(value) {
2371
2393
  if (!match) {
2372
2394
  return false;
2373
2395
  }
2374
- const parsed = match.slice(1).map(Number);
2375
- if (!parsed.every(Number.isSafeInteger)) {
2376
- return false;
2377
- }
2378
- for (let index = 0; index < parsed.length; index += 1) {
2379
- if (parsed[index] !== MINIMUM_CLAUDE_TRANSCRIPT_VERSION[index]) {
2380
- return parsed[index] > MINIMUM_CLAUDE_TRANSCRIPT_VERSION[index];
2381
- }
2382
- }
2383
- return true;
2384
- }
2385
- function isCompatiblePendingApprovalClaudeVersion(value) {
2386
- const version = nonEmptyString(value);
2387
- const match = version === undefined
2388
- ? undefined
2389
- : CLAUDE_TRANSCRIPT_VERSION_PATTERN.exec(version);
2390
- if (!match) {
2391
- return false;
2392
- }
2393
- const [major, minor, patch] = match.slice(1).map(Number);
2394
- return major === MINIMUM_CLAUDE_TRANSCRIPT_VERSION[0] &&
2395
- minor === MINIMUM_CLAUDE_TRANSCRIPT_VERSION[1] &&
2396
- Number.isSafeInteger(patch) &&
2397
- patch >= MINIMUM_CLAUDE_TRANSCRIPT_VERSION[2];
2396
+ // The version binds evidence; the actual record shape and task chain prove
2397
+ // compatibility. A release number alone must not reject an otherwise valid turn.
2398
+ return match.slice(1).map(Number).every(Number.isSafeInteger);
2398
2399
  }
2399
2400
  function assertSameClaudeVersion(...records) {
2400
2401
  const versions = new Set(records.map((record) => nonEmptyString(record.version)));
@@ -2466,31 +2467,12 @@ function exactRequestFingerprint(value) {
2466
2467
  const text = String(value ?? "");
2467
2468
  return text ? createHash("sha256").update(text).digest("hex") : undefined;
2468
2469
  }
2469
- export function claudeTranscriptAnchorFingerprint(anchor) {
2470
- return sha256Hex(JSON.stringify({
2471
- schema: "agent-knock-knock/claude-transcript-acceptance-anchor",
2472
- version: 1,
2473
- session_id: anchor.session_id,
2474
- cwd: anchor.cwd,
2475
- pid: anchor.pid,
2476
- agent_started_at_ms: anchor.agent_started_at_ms,
2477
- captured_at: anchor.captured_at,
2478
- relative_path: anchor.relative_path,
2479
- offset_bytes: anchor.offset_bytes,
2480
- file_existed: anchor.file_existed,
2481
- device: anchor.device ?? null,
2482
- inode: anchor.inode ?? null
2483
- }));
2484
- }
2485
2470
  function exactPromptText(value) {
2486
2471
  const text = String(value ?? "")
2487
2472
  .replace(/\r\n/gu, "\n")
2488
2473
  .replace(/[\r\n]+$/u, "");
2489
2474
  return text.length > 0 ? text : undefined;
2490
2475
  }
2491
- function transcriptFileId(sessionId, fileIdentity) {
2492
- return sha256Hex(`${sessionId}\0${fileIdentity}`).slice(0, 24);
2493
- }
2494
2476
  function sha256Hex(value) {
2495
2477
  return createHash("sha256").update(value).digest("hex");
2496
2478
  }