blun-king-cli 9.1.567 → 9.1.569

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 (262) hide show
  1. package/agent-spine-plugin/.claude-plugin/marketplace.json +1 -1
  2. package/agent-spine-plugin/.claude-plugin/plugin.json +1 -1
  3. package/agent-spine-plugin/.codex-plugin/plugin.json +2 -1
  4. package/agent-spine-plugin/CHANGELOG.md +1581 -0
  5. package/agent-spine-plugin/README.md +30 -4
  6. package/agent-spine-plugin/blun.plugin.json +3 -3
  7. package/agent-spine-plugin/docs/acceptance.md +61 -0
  8. package/agent-spine-plugin/docs/assignment-continuation.md +48 -0
  9. package/agent-spine-plugin/docs/host-integration.md +178 -0
  10. package/agent-spine-plugin/docs/preflight-recall.md +69 -0
  11. package/agent-spine-plugin/docs/preservation-contract.md +53 -0
  12. package/agent-spine-plugin/docs/quality-gates.md +50 -0
  13. package/agent-spine-plugin/docs/releasing.md +85 -0
  14. package/agent-spine-plugin/docs/session-timeline.md +251 -0
  15. package/agent-spine-plugin/docs/source-roots.md +113 -0
  16. package/agent-spine-plugin/docs/structured-completion.md +67 -0
  17. package/agent-spine-plugin/docs/world-model.md +94 -0
  18. package/agent-spine-plugin/hooks/codex.json +2 -2
  19. package/agent-spine-plugin/hooks/hooks.json +1 -1
  20. package/agent-spine-plugin/hooks/version.json +1 -1
  21. package/agent-spine-plugin/package.json +13 -3
  22. package/agent-spine-plugin/scripts/check-codex-install.js +226 -0
  23. package/agent-spine-plugin/scripts/check-hosts.js +14 -5
  24. package/agent-spine-plugin/scripts/check-install-hook.js +226 -0
  25. package/agent-spine-plugin/scripts/check-install-selfstarter.js +154 -0
  26. package/agent-spine-plugin/scripts/check-install.js +478 -0
  27. package/agent-spine-plugin/scripts/check-line-budget.js +58 -0
  28. package/agent-spine-plugin/scripts/check-syntax.js +29 -0
  29. package/agent-spine-plugin/scripts/github-actions.js +11 -0
  30. package/agent-spine-plugin/scripts/hermetic-process.js +183 -0
  31. package/agent-spine-plugin/scripts/release-check.js +145 -0
  32. package/agent-spine-plugin/scripts/run-acceptance.js +19 -0
  33. package/agent-spine-plugin/scripts/run-checks.js +47 -0
  34. package/agent-spine-plugin/scripts/run-tests-hermetic.js +89 -0
  35. package/agent-spine-plugin/skills/agent-spine/SKILL.md +16 -2
  36. package/agent-spine-plugin/spine-example/1-identity.md +12 -0
  37. package/agent-spine-plugin/spine-example/2-voice.md +6 -0
  38. package/agent-spine-plugin/spine-example/3-conduct.md +8 -0
  39. package/agent-spine-plugin/spine-example/4-history.md +4 -0
  40. package/agent-spine-plugin/src/cli-agent.js +296 -0
  41. package/agent-spine-plugin/src/cli-attention.js +95 -0
  42. package/agent-spine-plugin/src/cli-autonomy.js +36 -0
  43. package/agent-spine-plugin/src/cli-common.js +71 -0
  44. package/agent-spine-plugin/src/cli-continuity.js +116 -0
  45. package/agent-spine-plugin/src/cli-core.js +128 -0
  46. package/agent-spine-plugin/src/cli-diagnostics.js +291 -0
  47. package/agent-spine-plugin/src/cli-host.js +21 -0
  48. package/agent-spine-plugin/src/cli-learning.js +305 -0
  49. package/agent-spine-plugin/src/cli-premortem.js +16 -0
  50. package/agent-spine-plugin/src/cli-sharing.js +230 -0
  51. package/agent-spine-plugin/src/cli.js +40 -1350
  52. package/agent-spine-plugin/src/codex-reader-launcher.js +182 -0
  53. package/agent-spine-plugin/src/hook.js +185 -567
  54. package/agent-spine-plugin/src/index.js +16 -2
  55. package/agent-spine-plugin/src/lib/acceptance.js +113 -11
  56. package/agent-spine-plugin/src/lib/action-lesson-recall.js +53 -0
  57. package/agent-spine-plugin/src/lib/attention-context.js +167 -0
  58. package/agent-spine-plugin/src/lib/attention-events.js +113 -0
  59. package/agent-spine-plugin/src/lib/attention-privacy.js +72 -0
  60. package/agent-spine-plugin/src/lib/attention-schema.js +164 -0
  61. package/agent-spine-plugin/src/lib/attention-storage.js +93 -0
  62. package/agent-spine-plugin/src/lib/attention.js +9 -600
  63. package/agent-spine-plugin/src/lib/audit-premortem.js +223 -0
  64. package/agent-spine-plugin/src/lib/audit.js +56 -6
  65. package/agent-spine-plugin/src/lib/autonomy-policy.js +110 -0
  66. package/agent-spine-plugin/src/lib/autonomy-store.js +202 -0
  67. package/agent-spine-plugin/src/lib/autonomy.js +8 -0
  68. package/agent-spine-plugin/src/lib/briefing.js +67 -4
  69. package/agent-spine-plugin/src/lib/catalog-document-read.js +51 -0
  70. package/agent-spine-plugin/src/lib/catalog.js +1 -1
  71. package/agent-spine-plugin/src/lib/codex-installation.js +231 -0
  72. package/agent-spine-plugin/src/lib/codex-skill-installation.js +211 -0
  73. package/agent-spine-plugin/src/lib/context.js +3 -1
  74. package/agent-spine-plugin/src/lib/delivery-agent-usage.js +224 -0
  75. package/agent-spine-plugin/src/lib/delivery-assignment.js +220 -0
  76. package/agent-spine-plugin/src/lib/delivery-command-actions.js +453 -0
  77. package/agent-spine-plugin/src/lib/delivery-knowledge.js +78 -0
  78. package/agent-spine-plugin/src/lib/delivery-premortem-binding.js +107 -0
  79. package/agent-spine-plugin/src/lib/delivery-premortem-closure.js +171 -0
  80. package/agent-spine-plugin/src/lib/delivery-premortem-codec.js +45 -0
  81. package/agent-spine-plugin/src/lib/delivery-premortem-correction.js +101 -0
  82. package/agent-spine-plugin/src/lib/delivery-premortem-file.js +21 -0
  83. package/agent-spine-plugin/src/lib/delivery-premortem-index.js +493 -0
  84. package/agent-spine-plugin/src/lib/delivery-premortem-inspection.js +37 -0
  85. package/agent-spine-plugin/src/lib/delivery-premortem-recovery.js +120 -0
  86. package/agent-spine-plugin/src/lib/delivery-premortem-rejection.js +65 -0
  87. package/agent-spine-plugin/src/lib/delivery-premortem-results.js +28 -0
  88. package/agent-spine-plugin/src/lib/delivery-premortem-session-guard.js +46 -0
  89. package/agent-spine-plugin/src/lib/delivery-premortem-write-ledger.js +285 -0
  90. package/agent-spine-plugin/src/lib/delivery-premortem.js +499 -0
  91. package/agent-spine-plugin/src/lib/delivery-shell-heredoc.js +115 -0
  92. package/agent-spine-plugin/src/lib/delivery-shell-substitutions.js +111 -0
  93. package/agent-spine-plugin/src/lib/delivery-shell-wrapper.js +64 -0
  94. package/agent-spine-plugin/src/lib/delivery-target.js +73 -0
  95. package/agent-spine-plugin/src/lib/delivery-verification.js +445 -0
  96. package/agent-spine-plugin/src/lib/documents.js +27 -5
  97. package/agent-spine-plugin/src/lib/filesystem-retry.js +2 -0
  98. package/agent-spine-plugin/src/lib/gateway-common.js +68 -0
  99. package/agent-spine-plugin/src/lib/gateway-control.js +302 -0
  100. package/agent-spine-plugin/src/lib/gateway-delivery.js +103 -0
  101. package/agent-spine-plugin/src/lib/gateway-execution.js +350 -0
  102. package/agent-spine-plugin/src/lib/gateway-host-lifecycle.js +185 -0
  103. package/agent-spine-plugin/src/lib/gateway-inspection.js +85 -0
  104. package/agent-spine-plugin/src/lib/gateway-knowledge.js +129 -0
  105. package/agent-spine-plugin/src/lib/gateway-policy-provenance.js +197 -0
  106. package/agent-spine-plugin/src/lib/gateway-premortem-disposition.js +82 -0
  107. package/agent-spine-plugin/src/lib/gateway-premortem.js +363 -0
  108. package/agent-spine-plugin/src/lib/gateway-runs.js +300 -0
  109. package/agent-spine-plugin/src/lib/gateway-runtime-identity.js +31 -0
  110. package/agent-spine-plugin/src/lib/gateway-runtime-records.js +21 -0
  111. package/agent-spine-plugin/src/lib/gateway-runtime.js +18 -1623
  112. package/agent-spine-plugin/src/lib/gateway-state-transaction.js +356 -0
  113. package/agent-spine-plugin/src/lib/gateway-state.js +342 -0
  114. package/agent-spine-plugin/src/lib/hook-artifact-guards.js +356 -0
  115. package/agent-spine-plugin/src/lib/hook-audit.js +16 -2
  116. package/agent-spine-plugin/src/lib/hook-briefing-use.js +68 -0
  117. package/agent-spine-plugin/src/lib/hook-context.js +424 -0
  118. package/agent-spine-plugin/src/lib/hook-final-message.js +26 -0
  119. package/agent-spine-plugin/src/lib/hook-input.js +27 -0
  120. package/agent-spine-plugin/src/lib/hook-output.js +140 -0
  121. package/agent-spine-plugin/src/lib/hook-premortem.js +257 -0
  122. package/agent-spine-plugin/src/lib/hook-process-advisory.js +37 -0
  123. package/agent-spine-plugin/src/lib/hook-protection.js +95 -0
  124. package/agent-spine-plugin/src/lib/hook-stop-verification.js +84 -0
  125. package/agent-spine-plugin/src/lib/hook-timeline.js +91 -0
  126. package/agent-spine-plugin/src/lib/identifier-analysis.js +446 -0
  127. package/agent-spine-plugin/src/lib/indexed-memory.js +23 -6
  128. package/agent-spine-plugin/src/lib/knowledge-evidence.js +431 -0
  129. package/agent-spine-plugin/src/lib/learning-applications.js +441 -0
  130. package/agent-spine-plugin/src/lib/learning-candidates.js +274 -0
  131. package/agent-spine-plugin/src/lib/learning-context.js +130 -0
  132. package/agent-spine-plugin/src/lib/learning-delivery-contracts.js +310 -0
  133. package/agent-spine-plugin/src/lib/learning-evaluation-contracts.js +350 -0
  134. package/agent-spine-plugin/src/lib/learning-evaluation-registration.js +372 -0
  135. package/agent-spine-plugin/src/lib/learning-evaluation-revocation.js +292 -0
  136. package/agent-spine-plugin/src/lib/learning-evidence-contracts.js +321 -0
  137. package/agent-spine-plugin/src/lib/learning-findings.js +458 -0
  138. package/agent-spine-plugin/src/lib/learning-measurement-contracts.js +285 -0
  139. package/agent-spine-plugin/src/lib/learning-measurements.js +265 -0
  140. package/agent-spine-plugin/src/lib/learning-outcome-contracts.js +165 -0
  141. package/agent-spine-plugin/src/lib/learning-outcomes.js +343 -0
  142. package/agent-spine-plugin/src/lib/learning-reconciliation.js +290 -0
  143. package/agent-spine-plugin/src/lib/learning-retry-contracts.js +188 -0
  144. package/agent-spine-plugin/src/lib/learning-schema.js +229 -0
  145. package/agent-spine-plugin/src/lib/learning-scope-targets.js +424 -0
  146. package/agent-spine-plugin/src/lib/learning-state-upgrade.js +477 -0
  147. package/agent-spine-plugin/src/lib/learning-status-configuration.js +476 -0
  148. package/agent-spine-plugin/src/lib/learning-storage.js +203 -0
  149. package/agent-spine-plugin/src/lib/learning-trial-recovery.js +218 -0
  150. package/agent-spine-plugin/src/lib/learning-validation-contracts.js +375 -0
  151. package/agent-spine-plugin/src/lib/learning-validation-renewal.js +298 -0
  152. package/agent-spine-plugin/src/lib/learning-validation-runtime.js +234 -0
  153. package/agent-spine-plugin/src/lib/learning.js +36 -6923
  154. package/agent-spine-plugin/src/lib/lesson-recall-session.js +172 -0
  155. package/agent-spine-plugin/src/lib/mcp-autonomy-tools.js +37 -0
  156. package/agent-spine-plugin/src/lib/mcp-delivery-completion.js +124 -0
  157. package/agent-spine-plugin/src/lib/mcp-delivery-tools.js +45 -0
  158. package/agent-spine-plugin/src/lib/mcp-premortem.js +68 -0
  159. package/agent-spine-plugin/src/lib/mcp-runtime.js +269 -0
  160. package/agent-spine-plugin/src/lib/mcp-source-context.js +51 -0
  161. package/agent-spine-plugin/src/lib/mcp-timeline-tools.js +164 -0
  162. package/agent-spine-plugin/src/lib/mcp-world-tools.js +52 -0
  163. package/agent-spine-plugin/src/lib/owned-file-lock.js +30 -10
  164. package/agent-spine-plugin/src/lib/project-portfolio.js +176 -0
  165. package/agent-spine-plugin/src/lib/selfstarter-core.js +382 -0
  166. package/agent-spine-plugin/src/lib/selfstarter-jobs.js +149 -0
  167. package/agent-spine-plugin/src/lib/selfstarter-lease.js +204 -0
  168. package/agent-spine-plugin/src/lib/selfstarter-policy.js +90 -0
  169. package/agent-spine-plugin/src/lib/selfstarter-workspace.js +111 -0
  170. package/agent-spine-plugin/src/lib/selfstarter.js +11 -911
  171. package/agent-spine-plugin/src/lib/session-timeline-auth.js +316 -0
  172. package/agent-spine-plugin/src/lib/session-timeline-codex.js +58 -0
  173. package/agent-spine-plugin/src/lib/session-timeline-contract.js +48 -0
  174. package/agent-spine-plugin/src/lib/session-timeline-enrollment-source.js +41 -0
  175. package/agent-spine-plugin/src/lib/session-timeline-enrollment-storage.js +132 -0
  176. package/agent-spine-plugin/src/lib/session-timeline-enrollment-transport.js +17 -0
  177. package/agent-spine-plugin/src/lib/session-timeline-enrollment.js +500 -0
  178. package/agent-spine-plugin/src/lib/session-timeline-event-extract.js +157 -0
  179. package/agent-spine-plugin/src/lib/session-timeline-host-origin.js +74 -0
  180. package/agent-spine-plugin/src/lib/session-timeline-host-receipt.js +117 -0
  181. package/agent-spine-plugin/src/lib/session-timeline-invocation.js +201 -0
  182. package/agent-spine-plugin/src/lib/session-timeline-king.js +79 -0
  183. package/agent-spine-plugin/src/lib/session-timeline-prior.js +59 -0
  184. package/agent-spine-plugin/src/lib/session-timeline-provider.js +34 -0
  185. package/agent-spine-plugin/src/lib/session-timeline-query.js +55 -0
  186. package/agent-spine-plugin/src/lib/session-timeline-results.js +31 -0
  187. package/agent-spine-plugin/src/lib/session-timeline-root.js +11 -0
  188. package/agent-spine-plugin/src/lib/session-timeline-search.js +82 -0
  189. package/agent-spine-plugin/src/lib/session-timeline-sid-acl.js +217 -0
  190. package/agent-spine-plugin/src/lib/session-timeline-source.js +83 -0
  191. package/agent-spine-plugin/src/lib/session-timeline-state.js +45 -0
  192. package/agent-spine-plugin/src/lib/session-timeline-transport.js +50 -0
  193. package/agent-spine-plugin/src/lib/session-timeline-windows-acl.js +148 -0
  194. package/agent-spine-plugin/src/lib/session-timeline.js +453 -0
  195. package/agent-spine-plugin/src/lib/source-roots.js +69 -136
  196. package/agent-spine-plugin/src/lib/source-tree-scan.js +178 -0
  197. package/agent-spine-plugin/src/lib/task-knowledge-context.js +78 -0
  198. package/agent-spine-plugin/src/lib/timeline-tool-guard.js +202 -0
  199. package/agent-spine-plugin/src/lib/world-knowledge.js +249 -0
  200. package/agent-spine-plugin/src/lib/world-model.js +278 -0
  201. package/agent-spine-plugin/src/mcp.js +20 -161
  202. package/agent-spine-plugin/src/version.js +1 -1
  203. package/agent-spine-plugin/src/worker.js +22 -5
  204. package/bin/agent-resume-snapshot.cjs +2 -2
  205. package/bin/agentspine-king-goal-inbox.mjs +111 -0
  206. package/bin/agentspine-king-goal-intake.mjs +106 -0
  207. package/bin/baseline-skill-performance-policy.cjs +1 -16
  208. package/bin/core-bootstrap.js +2 -0
  209. package/bin/curiosity-scout-policy.cjs +5 -1
  210. package/bin/input-draft-persistence.cjs +2 -2
  211. package/bin/king-tui-function-contract.json +33 -0
  212. package/bin/launcher-restart-policy.cjs +150 -0
  213. package/bin/launcher-runtime.js +56 -44
  214. package/bin/managed-context-startup-policy.cjs +27 -0
  215. package/bin/managed-plugin-selection.cjs +116 -0
  216. package/bin/mistake-relevance-policy.cjs +1 -1
  217. package/bin/observer-hooks.cjs +14 -0
  218. package/bin/oversized-context-offload-policy.cjs +86 -0
  219. package/bin/plugin-bootstrap.js +7 -40
  220. package/bin/proactive-compaction-policy.cjs +1 -1
  221. package/bin/provider-model-refresh-deadline.cjs +53 -0
  222. package/bin/provider-model-refresh-policy.cjs +107 -0
  223. package/bin/release-artifact-freeze-policy.cjs +30 -0
  224. package/bin/repeated-user-message-projection.cjs +3 -126
  225. package/bin/research-page-result.cjs +74 -0
  226. package/bin/runtime-exit-ledger.cjs +1 -0
  227. package/bin/session-compaction-policy.cjs +84 -0
  228. package/bin/skill-listing-performance-policy.cjs +2 -2
  229. package/bin/standard-tools-bootstrap.js +0 -37
  230. package/bin/subagent-skill-policy.cjs +3 -1
  231. package/bin/telegram-approval-relay.cjs +12 -7
  232. package/bin/telegram-private-conversation-policy.cjs +3 -2
  233. package/bin/telegram-queue-handoff-policy.cjs +24 -0
  234. package/bin/thinking-activity-status-policy.cjs +1 -1
  235. package/bin/thinking-only-guard.cjs +16 -12
  236. package/bin/tool-call-loop-policy.cjs +0 -2
  237. package/bin/tool-result-offload-policy.cjs +11 -2
  238. package/bin/tui-functional-contract.cjs +55 -0
  239. package/bin/update-notice.js +18 -14
  240. package/bin/user-message-offload-policy.cjs +1 -1
  241. package/bin/user-prompt-hook-origin-policy.cjs +34 -0
  242. package/bin/windows-node-crash-dump.cjs +110 -0
  243. package/blun.mjs +2517 -1048
  244. package/codebase-index/codebase_index.py +4 -3
  245. package/package.json +3 -17
  246. package/standard-skills/research-evidence/SKILL.md +39 -0
  247. package/standard-skills/research-evidence/references/evidence-format.md +82 -0
  248. package/standard-skills/research-evidence/scripts/evidence-collection.cjs +254 -0
  249. package/standard-skills/research-evidence/scripts/score-report.cjs +112 -0
  250. package/standard-skills/web-lesen/SKILL.md +37 -22
  251. package/standard-skills/web-lesen/scripts/crawl_public.py +376 -0
  252. package/telegram-plugin/DELIVERY.md +36 -0
  253. package/telegram-plugin/bin/telegram-approval-relay.cjs +13 -7
  254. package/telegram-plugin/bin/telegram-launcher-status-queue.cjs +122 -0
  255. package/telegram-plugin/bin/telegram-private-conversation-policy.cjs +3 -2
  256. package/telegram-plugin/bin/telegram-reply-parts.cjs +149 -0
  257. package/telegram-plugin/dist/bridge.mjs +7 -56
  258. package/telegram-plugin/dist/mcp-server.mjs +33 -4
  259. package/agent-spine-plugin/skill/SKILL.md +0 -76
  260. package/bin/mnemo-connect-heartbeat.cjs +0 -204
  261. package/bin/mnemo-tool-agent-policy.cjs +0 -22
  262. package/telegram-plugin/bin/telegram-mnemo-capture.cjs +0 -297
@@ -0,0 +1,296 @@
1
+ import { checkDelegation, createTask, deleteTask, grantDelegation, loadDelegationPolicy, revokeDelegation, taskContext, updateTask } from "./lib/coordination.js";
2
+ import { cancelJob, deleteJob, grantExecution, loadExecutionPolicy, registerJob, revokeExecution, selfstarterContext } from "./lib/selfstarter.js";
3
+ import { channelRuntimeContext, grantChannelBinding, loadChannelPolicy, revokeChannelBinding } from "./lib/channel-runtime.js";
4
+ import { personaContext, syncPersonaRosterFromEnvironment } from "./lib/persona-runtime.js";
5
+ import { assignGoal, gatewayContext, resolveGoalKnowledgeGap, setGatewayControl } from "./lib/gateway-runtime.js";
6
+ import {
7
+ currentHostTranscriptReceipt, enrollPrivateSessionTimeline, LOCAL_TIMELINE_ENROLLMENT_CONFIRMATION,
8
+ LOCAL_TIMELINE_ENROLLMENT_RECOVERY_CONFIRMATION, resetPrivateSessionTimelineEnrollment
9
+ } from "./lib/session-timeline-enrollment.js";
10
+ import { bootstrapSessionTimelineEnrollment } from "./lib/session-timeline.js";
11
+ import { booleanFlag, goalPlanFlag, output } from "./cli-common.js";
12
+
13
+ export const agentCommands = new Set([
14
+ "delegation-grant",
15
+ "delegation-revoke",
16
+ "delegation-check",
17
+ "delegation-policy",
18
+ "task-create",
19
+ "task-update",
20
+ "tasks",
21
+ "task-delete",
22
+ "execution-grant",
23
+ "execution-revoke",
24
+ "execution-policy",
25
+ "job-register",
26
+ "jobs",
27
+ "job-cancel",
28
+ "job-delete",
29
+ "channel-bind",
30
+ "channel-revoke",
31
+ "channel-policy",
32
+ "channel-events",
33
+ "persona-sync",
34
+ "personas",
35
+ "goal-assign",
36
+ "goal-clarify",
37
+ "gateway-control",
38
+ "gateway-status",
39
+ "timeline-receipt",
40
+ "timeline-enroll",
41
+ "timeline-enrollment-recover"
42
+ ]);
43
+
44
+ function timelineFlagValue(flags, name) {
45
+ const value = flags[name];
46
+ if (typeof value !== "string" || !value) throw new Error(`timeline command requires --${name}`);
47
+ return value;
48
+ }
49
+
50
+ function onlyTimelineFlags(flags, allowed, command) {
51
+ const unexpected = Object.keys(flags).filter((name) => !allowed.has(name));
52
+ if (unexpected.length) {
53
+ throw new Error(`${command} accepts only ${[...allowed].filter((name) => name !== "json").map((name) => `--${name}`).join(", ")}`);
54
+ }
55
+ }
56
+
57
+ export async function runAgentCommand({ command, flags, positional, json }) {
58
+ if (command === "timeline-receipt") {
59
+ if (positional.length) throw new Error("timeline receipt accepts no positional arguments; pass --root explicitly");
60
+ onlyTimelineFlags(flags, new Set(["root", "json"]), "timeline receipt");
61
+ return output(await currentHostTranscriptReceipt({ root: timelineFlagValue(flags, "root") }), json);
62
+ }
63
+
64
+ if (command === "timeline-enroll") {
65
+ if (positional.length) throw new Error("timeline enrollment accepts no positional arguments; pass --root explicitly");
66
+ onlyTimelineFlags(flags, new Set(["root", "receipt", "confirm-local-timeline", "json"]), "timeline enrollment");
67
+ if (!booleanFlag(flags["confirm-local-timeline"])) {
68
+ throw new Error("timeline enrollment requires --confirm-local-timeline");
69
+ }
70
+ const enrollment = await enrollPrivateSessionTimeline({
71
+ root: timelineFlagValue(flags, "root"), hostReceipt: timelineFlagValue(flags, "receipt"),
72
+ confirmation: LOCAL_TIMELINE_ENROLLMENT_CONFIRMATION
73
+ });
74
+ if (enrollment.status !== "enrolled") return output(enrollment, json);
75
+ const bootstrap = await bootstrapSessionTimelineEnrollment({
76
+ root: timelineFlagValue(flags, "root"), enrollmentDigest: enrollment.enrollmentDigest
77
+ });
78
+ return output({ ...enrollment, stateBootstrap: { status: bootstrap.status, reason: bootstrap.reason ?? null } }, json);
79
+ }
80
+
81
+ if (command === "timeline-enrollment-recover") {
82
+ if (positional.length) throw new Error("timeline enrollment recovery accepts no positional arguments; pass --root explicitly");
83
+ onlyTimelineFlags(flags, new Set(["root", "confirm-local-timeline-recovery", "json"]), "timeline enrollment recovery");
84
+ if (!booleanFlag(flags["confirm-local-timeline-recovery"])) {
85
+ throw new Error("timeline enrollment recovery requires --confirm-local-timeline-recovery");
86
+ }
87
+ const recovered = await resetPrivateSessionTimelineEnrollment({
88
+ root: timelineFlagValue(flags, "root"), confirmation: LOCAL_TIMELINE_ENROLLMENT_RECOVERY_CONFIRMATION
89
+ });
90
+ return output({ status: recovered ? "recovered" : "unavailable",
91
+ reason: recovered ? null : "timeline-enrollment-recovery-unavailable", authority: "context-only" }, json);
92
+ }
93
+
94
+ if (command === "delegation-grant") {
95
+ return output(await grantDelegation({
96
+ root: flags.root || process.cwd(), actorId: positional[0],
97
+ id: flags.id, actions: String(flags.actions || "").split(",").filter(Boolean),
98
+ targetIds: String(flags.targets || "*").split(",").filter(Boolean), reason: flags.reason,
99
+ confirmation: booleanFlag(flags["confirm-local-policy"]) ? "local-owner-confirmed" : null
100
+ }), json);
101
+ }
102
+
103
+ if (command === "delegation-revoke") {
104
+ return output(await revokeDelegation({
105
+ root: flags.root || process.cwd(), id: positional[0], reason: flags.reason,
106
+ confirmation: booleanFlag(flags["confirm-local-policy"]) ? "local-owner-confirmed" : null
107
+ }), json);
108
+ }
109
+
110
+ if (command === "delegation-check") {
111
+ return output(await checkDelegation({
112
+ root: flags.root || process.cwd(), actorId: positional[0], action: flags.action,
113
+ targetId: flags.target || null
114
+ }), json);
115
+ }
116
+
117
+ if (command === "delegation-policy") {
118
+ return output((await loadDelegationPolicy(positional[0] || process.cwd())).policy, json);
119
+ }
120
+
121
+ if (command === "task-create") {
122
+ return output(await createTask({
123
+ root: flags.root || process.cwd(), id: positional[0], actorId: flags.actor,
124
+ assigneeId: flags.assignee || null, kind: flags.kind || "task", title: flags.title,
125
+ summary: flags.summary || null, projectId: flags.project || null,
126
+ privacy: flags.privacy || "private", groupId: flags.group || null,
127
+ priority: Number(flags.priority ?? 50), dueAt: flags.due || null
128
+ }), json);
129
+ }
130
+
131
+ if (command === "task-update") {
132
+ const patch = {};
133
+ if (flags.status !== undefined) patch.status = flags.status;
134
+ if (flags.assignee !== undefined) patch.assigneeId = flags.assignee;
135
+ if (flags.unassign !== undefined) patch.assigneeId = null;
136
+ if (flags.title !== undefined) patch.title = flags.title;
137
+ if (flags.summary !== undefined) patch.summary = flags.summary;
138
+ if (flags.priority !== undefined) patch.priority = Number(flags.priority);
139
+ if (flags.due !== undefined) patch.dueAt = flags.due;
140
+ if (flags["clear-due"] !== undefined) patch.dueAt = null;
141
+ if (flags.note !== undefined) patch.note = flags.note;
142
+ return output(await updateTask({
143
+ root: flags.root || process.cwd(), id: positional[0], actorId: flags.actor, patch
144
+ }), json);
145
+ }
146
+
147
+ if (command === "tasks") {
148
+ return output(await taskContext({
149
+ root: positional[0] || process.cwd(), includePrivate: booleanFlag(flags["include-private"]),
150
+ groupId: flags.group || null, actorId: flags.actor || null, assigneeId: flags.assignee || null,
151
+ projectId: flags.project || null, includeClosed: booleanFlag(flags.closed),
152
+ maxItems: Number(flags["max-items"] ?? 20)
153
+ }), json);
154
+ }
155
+
156
+ if (command === "task-delete") {
157
+ return output(await deleteTask({
158
+ root: flags.root || process.cwd(), id: positional[0],
159
+ confirmation: booleanFlag(flags["confirm-local-policy"]) ? "local-owner-confirmed" : null
160
+ }), json);
161
+ }
162
+
163
+ if (command === "execution-grant") {
164
+ return output(await grantExecution({
165
+ root: flags.root || process.cwd(), id: flags.id, jobId: positional[0], actorId: flags.actor,
166
+ taskId: flags.task, targetId: flags.target, projectId: flags.project, groupId: flags.group || null,
167
+ host: flags.host, capabilities: String(flags.capabilities || "").split(",").filter(Boolean),
168
+ reason: flags.reason, expiresAt: flags.expires || null,
169
+ confirmation: booleanFlag(flags["confirm-local-execution"]) ? "local-owner-confirmed" : null
170
+ }), json);
171
+ }
172
+
173
+ if (command === "execution-revoke") {
174
+ return output(await revokeExecution({
175
+ root: flags.root || process.cwd(), id: positional[0], reason: flags.reason,
176
+ confirmation: booleanFlag(flags["confirm-local-execution"]) ? "local-owner-confirmed" : null
177
+ }), json);
178
+ }
179
+
180
+ if (command === "execution-policy") {
181
+ return output((await loadExecutionPolicy(positional[0] || process.cwd())).policy, json);
182
+ }
183
+
184
+ if (command === "job-register") {
185
+ return output(await registerJob({
186
+ root: flags.root || process.cwd(), id: positional[0], grantId: flags.grant,
187
+ maxRetries: Number(flags["max-retries"] ?? 3), leaseSeconds: Number(flags["lease-seconds"] ?? 120),
188
+ baseRetrySeconds: Number(flags["retry-seconds"] ?? 5),
189
+ confirmation: booleanFlag(flags["confirm-local-execution"]) ? "local-owner-confirmed" : null
190
+ }), json);
191
+ }
192
+
193
+ if (command === "jobs") {
194
+ return output(await selfstarterContext({
195
+ root: positional[0] || process.cwd(), actorId: flags.actor || null,
196
+ projectId: flags.project || null, taskId: flags.task || null,
197
+ includeTerminal: booleanFlag(flags["include-terminal"])
198
+ }), json);
199
+ }
200
+
201
+ if (command === "job-cancel") {
202
+ return output(await cancelJob({
203
+ root: flags.root || process.cwd(), id: positional[0], reason: flags.reason,
204
+ confirmation: booleanFlag(flags["confirm-local-execution"]) ? "local-owner-confirmed" : null
205
+ }), json);
206
+ }
207
+
208
+ if (command === "job-delete") {
209
+ return output(await deleteJob({
210
+ root: flags.root || process.cwd(), id: positional[0],
211
+ confirmation: booleanFlag(flags["confirm-local-execution"]) ? "local-owner-confirmed" : null
212
+ }), json);
213
+ }
214
+
215
+ if (command === "channel-bind") {
216
+ return output(await grantChannelBinding({
217
+ root: flags.root || process.cwd(), id: positional[0], provider: flags.provider,
218
+ tenantId: flags.tenant, accountId: flags.account, chatId: flags.chat,
219
+ threadId: flags.thread || null,
220
+ senderIds: String(flags.senders || "").split(",").filter(Boolean),
221
+ agentId: flags.agent, projectId: flags.project, groupId: flags.group || null,
222
+ sessionKey: flags.session, secretEnv: flags["secret-env"], outboundSecretEnv: flags["outbound-secret-env"] || null,
223
+ capabilities: String(flags.capabilities || "receive,reply").split(",").filter(Boolean),
224
+ confirmation: booleanFlag(flags["confirm-local-channel"]) ? "local-owner-confirmed" : null
225
+ }), json);
226
+ }
227
+
228
+ if (command === "channel-revoke") {
229
+ return output(await revokeChannelBinding({
230
+ root: flags.root || process.cwd(), id: positional[0], reason: flags.reason,
231
+ confirmation: booleanFlag(flags["confirm-local-channel"]) ? "local-owner-confirmed" : null
232
+ }), json);
233
+ }
234
+
235
+ if (command === "channel-policy") {
236
+ return output((await loadChannelPolicy(positional[0] || process.cwd())).policy, json);
237
+ }
238
+
239
+ if (command === "channel-events") {
240
+ return output(await channelRuntimeContext({
241
+ root: positional[0] || process.cwd(), agentId: flags.agent || null,
242
+ projectId: flags.project || null,
243
+ ...(flags.group !== undefined ? { groupId: flags.group || null } : {}),
244
+ provider: flags.provider || null,
245
+ includeTerminal: booleanFlag(flags["include-terminal"]),
246
+ maxItems: Number(flags["max-items"] ?? 20)
247
+ }), json);
248
+ }
249
+
250
+ if (command === "persona-sync") {
251
+ if (!booleanFlag(flags["confirm-local-persona"])) throw new Error("persona synchronization requires --confirm-local-persona");
252
+ return output(await syncPersonaRosterFromEnvironment({
253
+ root: positional[0] || process.cwd(), env: { ...process.env, AGENTSPINE_PERSONA_ROSTER_FILE: flags.roster }
254
+ }), json);
255
+ }
256
+
257
+ if (command === "personas") {
258
+ return output(await personaContext({
259
+ root: positional[0] || process.cwd(), personaId: flags.persona || null,
260
+ ...(flags.group !== undefined ? { groupId: flags.group || null } : {}),
261
+ includeInactive: booleanFlag(flags["include-inactive"])
262
+ }), json);
263
+ }
264
+
265
+ if (command === "goal-assign") {
266
+ return output(await assignGoal({
267
+ root: flags.root || process.cwd(), goalId: positional[0], agentId: flags.agent,
268
+ ownerSubjectId: flags.owner, projectId: flags.project, groupId: flags.group || null,
269
+ priority: Number(flags.priority ?? 70), successCriterion: flags.success,
270
+ nextSafeStep: flags["next-step"] || null, steps: await goalPlanFlag(flags.plan), deadline: flags.deadline || null,
271
+ confirmation: booleanFlag(flags["confirm-local-goal"]) ? "local-owner-confirmed" : null
272
+ }), json);
273
+ }
274
+
275
+ if (command === "goal-clarify") {
276
+ return output(await resolveGoalKnowledgeGap({
277
+ root: flags.root || process.cwd(), goalId: positional[0], gapId: flags.gap,
278
+ answer: flags.answer, answerSource: flags.source || "owner-input",
279
+ sourceDigest: flags["source-digest"] || null,
280
+ confirmation: booleanFlag(flags["confirm-local-goal"]) ? "local-owner-confirmed" : null
281
+ }), json);
282
+ }
283
+
284
+ if (command === "gateway-control") {
285
+ return output(await setGatewayControl({
286
+ root: positional[0] || process.cwd(),
287
+ ...(flags.enabled !== undefined ? { enabled: booleanFlag(flags.enabled) } : {}),
288
+ ...(flags["kill-switch"] !== undefined ? { killSwitch: booleanFlag(flags["kill-switch"]) } : {}),
289
+ confirmation: booleanFlag(flags["confirm-local-gateway"]) ? "local-owner-confirmed" : null
290
+ }), json);
291
+ }
292
+
293
+ if (command === "gateway-status") {
294
+ return output(await gatewayContext({ root: positional[0] || process.cwd(), agentId: flags.agent || null }), json);
295
+ }
296
+ }
@@ -0,0 +1,95 @@
1
+ import { attentionContext, configureAttention, deleteAttention, loadAttention, recordActivity, resolveAttention, upsertAttention } from "./lib/attention.js";
2
+ import { booleanFlag, output } from "./cli-common.js";
3
+
4
+ export const attentionCommands = new Set([
5
+ "attention",
6
+ "attention-events",
7
+ "attention-add",
8
+ "attention-resolve",
9
+ "attention-touch",
10
+ "attention-delete",
11
+ "attention-event-delete",
12
+ "attention-purge",
13
+ "attention-config"
14
+ ]);
15
+
16
+ export async function runAttentionCommand({ command, flags, positional, json }) {
17
+ if (command === "attention") {
18
+ return output(await attentionContext({
19
+ root: positional[0] || process.cwd(),
20
+ includePrivate: booleanFlag(flags["include-private"]),
21
+ focusActive: booleanFlag(flags["focus-active"]),
22
+ markPresented: booleanFlag(flags["mark-presented"]),
23
+ entityId: flags.entity || null,
24
+ groupId: flags.group || null,
25
+ projectId: flags.project || null,
26
+ currentTaskId: flags.task || null,
27
+ maxItems: flags["max-items"] === undefined ? null : Number(flags["max-items"])
28
+ }), json);
29
+ }
30
+
31
+ if (command === "attention-events") {
32
+ const { attention, attentionPath } = await loadAttention(positional[0] || process.cwd());
33
+ return output({
34
+ schema: "agentspine.attention-events/v1", attentionPath,
35
+ events: attention.events,
36
+ receipts: attention.receipts,
37
+ history: booleanFlag(flags["include-history"]) ? attention.history.filter((item) => item.kind === "attention-event") : [],
38
+ authority: "context-only"
39
+ }, json);
40
+ }
41
+
42
+ if (command === "attention-add") {
43
+ return output(await upsertAttention({
44
+ root: flags.root || process.cwd(), id: positional[0], kind: flags.kind,
45
+ summary: flags.summary, entityId: flags.entity || null, dueAt: flags.due || null,
46
+ priority: Number(flags.priority ?? 50), privacy: flags.privacy || "private",
47
+ groupId: flags.group || null,
48
+ sourceDocument: flags.source || null, confidence: Number(flags.confidence ?? 0.5)
49
+ }), json);
50
+ }
51
+
52
+ if (command === "attention-resolve") {
53
+ return output(await resolveAttention({
54
+ root: flags.root || process.cwd(), id: positional[0], status: flags.status || "completed"
55
+ }), json);
56
+ }
57
+
58
+ if (command === "attention-touch") {
59
+ return output(await recordActivity({
60
+ root: flags.root || process.cwd(), entityId: positional[0], kind: flags.kind || "interaction",
61
+ at: flags.at || new Date(), privacy: flags.privacy || "private", groupId: flags.group || null
62
+ }), json);
63
+ }
64
+
65
+ if (command === "attention-delete") {
66
+ return output(await deleteAttention({ root: flags.root || process.cwd(), signalId: positional[0] }), json);
67
+ }
68
+
69
+ if (command === "attention-event-delete") {
70
+ return output(await deleteAttention({ root: flags.root || process.cwd(), eventId: positional[0] }), json);
71
+ }
72
+
73
+ if (command === "attention-purge") {
74
+ return output(await deleteAttention({ root: flags.root || process.cwd(), entityId: positional[0] }), json);
75
+ }
76
+
77
+ if (command === "attention-config") {
78
+ const root = positional[0] || process.cwd();
79
+ const config = {};
80
+ if (flags.enabled !== undefined) config.enabled = booleanFlag(flags.enabled);
81
+ if (flags["min-interval-hours"] !== undefined) config.minIntervalHours = Number(flags["min-interval-hours"]);
82
+ if (flags["silence-days"] !== undefined) config.entitySilenceDays = Number(flags["silence-days"]);
83
+ if (flags["heartbeat-stale-minutes"] !== undefined) config.heartbeatStaleMinutes = Number(flags["heartbeat-stale-minutes"]);
84
+ if (flags["max-items"] !== undefined) config.maxItems = Number(flags["max-items"]);
85
+ if (flags["quiet-off"] !== undefined) config.quietHours = null;
86
+ else if (flags["quiet-start"] !== undefined || flags["quiet-end"] !== undefined) {
87
+ config.quietHours = {
88
+ start: Number(flags["quiet-start"]), end: Number(flags["quiet-end"]),
89
+ utcOffsetMinutes: Number(flags["utc-offset"] ?? 0)
90
+ };
91
+ }
92
+ if (!Object.keys(config).length) return output((await loadAttention(root)).attention.config, json);
93
+ return output(await configureAttention({ root, config }), json);
94
+ }
95
+ }
@@ -0,0 +1,36 @@
1
+ import {
2
+ autonomyStatus, configureAutonomyProject, evaluateAutonomyAction,
3
+ projectPortfolioContext, recordProjectObservation, revokeAutonomyProject, scanProjectPortfolio
4
+ } from "./lib/autonomy.js";
5
+ import { booleanFlag, output } from "./cli-common.js";
6
+
7
+ export const autonomyCommands = new Set([
8
+ "autonomy-project-set", "autonomy-project-revoke", "autonomy-scan",
9
+ "autonomy-observe", "autonomy-status", "autonomy-check", "portfolio"
10
+ ]);
11
+
12
+ function capabilities(value) { return String(value || "").split(",").filter(Boolean); }
13
+
14
+ export async function runAutonomyCommand({ command, flags, positional, json }) {
15
+ const root = flags.root || process.cwd();
16
+ if (command === "autonomy-project-set") return output(await configureAutonomyProject({
17
+ root, id: positional[0], projectId: flags.project, tenantId: flags.tenant, groupId: flags.group || null,
18
+ localRoot: flags["local-root"] || null, publicUrl: flags["public-url"] || null,
19
+ mode: flags.mode || "observe", capabilities: capabilities(flags.capabilities), goal: flags.goal,
20
+ confirmation: flags["confirm-local-autonomy"] ? "local-owner-confirmed" : null,
21
+ publishConfirmation: flags["confirm-local-publish"] ? "local-owner-publish-confirmed" : null
22
+ }), json);
23
+ if (command === "autonomy-project-revoke") return output(await revokeAutonomyProject({ root, id: positional[0],
24
+ reason: flags.reason, confirmation: flags["confirm-local-autonomy"] ? "local-owner-confirmed" : null }), json);
25
+ if (command === "autonomy-scan") return output(await scanProjectPortfolio({ root, tenantId: flags.tenant, groupId: flags.group || null }), json);
26
+ if (command === "autonomy-observe") return output(await recordProjectObservation({ root, registrationId: positional[0],
27
+ tenantId: flags.tenant, groupId: flags.group || null, kind: flags.kind, status: flags.status || "open",
28
+ evidenceClass: flags.evidence, summary: flags.summary, sourceDigest: flags["source-digest"], expiresAt: flags.expires || null }), json);
29
+ if (command === "autonomy-status") return output(await autonomyStatus({ root, tenantId: flags.tenant || null, groupId: flags.group || null }), json);
30
+ if (command === "autonomy-check") return output(await evaluateAutonomyAction({ root, registrationId: positional[0],
31
+ tenantId: flags.tenant, groupId: flags.group || null, action: flags.action, capability: flags.capability || null,
32
+ actorId: flags.actor || null, jobId: flags.job || null, taskId: flags.task || null, targetId: flags.target || null,
33
+ projectId: flags.project || null, host: flags.host || null }), json);
34
+ if (command === "portfolio") return output(await projectPortfolioContext({ root, tenantId: flags.tenant,
35
+ groupId: flags.group || null, markPresented: booleanFlag(flags["mark-presented"]) }), json);
36
+ }
@@ -0,0 +1,71 @@
1
+ import { readFile } from "node:fs/promises";
2
+
3
+ export function parseCli(argv) {
4
+ const [command = "help", ...rest] = argv;
5
+ const flags = {};
6
+ const positional = [];
7
+ for (let index = 0; index < rest.length; index += 1) {
8
+ const token = rest[index];
9
+ if (!token.startsWith("--")) {
10
+ positional.push(token);
11
+ continue;
12
+ }
13
+ const [name, inline] = token.slice(2).split("=", 2);
14
+ if (inline !== undefined) flags[name] = inline;
15
+ else if (rest[index + 1] && !rest[index + 1].startsWith("--")) flags[name] = rest[++index];
16
+ else flags[name] = true;
17
+ }
18
+ return { command, flags, positional };
19
+ }
20
+
21
+ export function outputCli(value, json = false) {
22
+ if (json) {
23
+ process.stdout.write(`${JSON.stringify(value, null, 2)}\n`);
24
+ return;
25
+ }
26
+ if (typeof value === "string") process.stdout.write(`${value}\n`);
27
+ else process.stdout.write(`${JSON.stringify(value, null, 2)}\n`);
28
+ }
29
+
30
+ export function booleanFlag(value, fallback = false) {
31
+ if (value === undefined) return fallback;
32
+ if (value === true || value === "true" || value === "1") return true;
33
+ if (value === false || value === "false" || value === "0") return false;
34
+ throw new Error(`expected boolean flag, received: ${value}`);
35
+ }
36
+
37
+ export async function goalPlanFlag(path) {
38
+ if (!path) return null;
39
+ const content = await readFile(path, "utf8");
40
+ if (Buffer.byteLength(content) > 64 * 1024) throw new Error("goal plan exceeds 64 KiB");
41
+ const parsed = JSON.parse(content);
42
+ const steps = Array.isArray(parsed) ? parsed : parsed?.steps;
43
+ if (!Array.isArray(steps)) throw new Error("goal plan must be a JSON array or an object with a steps array");
44
+ return steps;
45
+ }
46
+
47
+ export function learningScope(flags) {
48
+ return {
49
+ personaId: flags.persona || null,
50
+ userId: flags.user || null,
51
+ tenantId: flags.tenant || null,
52
+ projectId: flags.project || null,
53
+ groupId: flags.group || null,
54
+ taskId: flags.task || null
55
+ };
56
+ }
57
+
58
+ export function hasLearningScope(flags) {
59
+ return ["persona", "user", "tenant", "project", "group", "task"]
60
+ .some((name) => flags[name] !== undefined);
61
+ }
62
+
63
+ export function evaluatorRootsFlag(value) {
64
+ return String(value || "").split(",").filter(Boolean).map((entry) => {
65
+ const separator = entry.lastIndexOf("=");
66
+ if (separator <= 0) throw new Error("evaluator roots must use evaluator-id=sha256 entries");
67
+ return { evaluatorId: entry.slice(0, separator), principalDigest: entry.slice(separator + 1) };
68
+ });
69
+ }
70
+
71
+ export { outputCli as output, parseCli as parse };
@@ -0,0 +1,116 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { configureContinuity, loadContinuity, purgeContinuity } from "./lib/continuity.js";
3
+ import { configurePreflightPolicy, confirmMustRemember, preflightStatus, proposeMustRemember, purgeMustRemember, rollbackMustRemember } from "./lib/preflight.js";
4
+ import { bindSourceRoot, inspectSourceRegistry, purgeSourceBinding, resolveHostSourceCatalog, rollbackSourceBinding } from "./lib/source-roots.js";
5
+ import { booleanFlag, output } from "./cli-common.js";
6
+
7
+ export const continuityCommands = new Set([
8
+ "continuity-config",
9
+ "continuity-status",
10
+ "continuity-purge",
11
+ "preflight-policy",
12
+ "preflight-status",
13
+ "remember-propose",
14
+ "remember-confirm",
15
+ "remember-rollback",
16
+ "remember-purge",
17
+ "source-status",
18
+ "source-bind",
19
+ "source-rollback",
20
+ "source-purge"
21
+ ]);
22
+
23
+ export async function runContinuityCommand({ command, flags, positional, json }) {
24
+ if (command === "continuity-config") {
25
+ const root = positional[0] || process.cwd();
26
+ const config = {};
27
+ if (flags.enabled !== undefined) config.enabled = booleanFlag(flags.enabled);
28
+ if (flags.entity !== undefined) config.defaultEntityId = flags.entity === "none" ? null : flags.entity;
29
+ if (flags.project !== undefined) config.defaultProjectId = flags.project === "none" ? null : flags.project;
30
+ if (flags["min-confidence"] !== undefined) config.minConfidence = Number(flags["min-confidence"]);
31
+ if (flags["min-directness"] !== undefined) config.minDirectness = Number(flags["min-directness"]);
32
+ if (flags["min-evidence"] !== undefined) config.minEvidence = Number(flags["min-evidence"]);
33
+ if (flags["max-prompt-bytes"] !== undefined) config.maxPromptBytes = Number(flags["max-prompt-bytes"]);
34
+ if (flags["max-briefing-bytes"] !== undefined) config.maxBriefingBytes = Number(flags["max-briefing-bytes"]);
35
+ if (!Object.keys(config).length) return output((await loadContinuity(root)).continuity.config, json);
36
+ return output(await configureContinuity({
37
+ root, config,
38
+ confirmation: booleanFlag(flags["confirm-local-opt-in"]) ? "local-user-opt-in" : null
39
+ }), json);
40
+ }
41
+
42
+ if (command === "continuity-status") {
43
+ const { continuity, continuityPath } = await loadContinuity(positional[0] || process.cwd());
44
+ return output({
45
+ schema: continuity.schema, config: continuity.config,
46
+ signals: continuity.signals.length, history: continuity.history.length,
47
+ continuityPath, authority: "context-only"
48
+ }, json);
49
+ }
50
+
51
+ if (command === "continuity-purge") {
52
+ return output(await purgeContinuity({
53
+ root: flags.root || process.cwd(), subjectId: positional[0],
54
+ confirmation: booleanFlag(flags["confirm-local-purge"]) ? "local-user-confirmed" : null
55
+ }), json);
56
+ }
57
+
58
+ if (command === "preflight-policy") {
59
+ if (!positional[0]) throw new Error("preflight-policy requires one local JSON policy file");
60
+ const profile = JSON.parse(await readFile(positional[0], "utf8"));
61
+ return output(await configurePreflightPolicy({ profile,
62
+ confirmation: booleanFlag(flags["confirm-local-policy"]) ? "local-owner-confirmed" : null }), json);
63
+ }
64
+
65
+ if (command === "preflight-status") return output(await preflightStatus(), json);
66
+
67
+ if (command === "remember-propose") {
68
+ return output(await proposeMustRemember({ claim: flags.claim, kind: flags.kind || "critical",
69
+ userId: flags.user, tenantId: flags.tenant, projectId: flags.project || null,
70
+ groupId: flags.group || null, taskId: flags.task || null, sourceDigest: flags["source-digest"] || null }), json);
71
+ }
72
+
73
+ if (command === "remember-confirm") {
74
+ return output(await confirmMustRemember({ candidateId: positional[0], supersedes: flags.supersedes || null,
75
+ confirmation: booleanFlag(flags["confirm-local-user"]) ? "local-user-confirmed" : null }), json);
76
+ }
77
+
78
+ if (command === "remember-rollback") {
79
+ return output(await rollbackMustRemember({ id: positional[0],
80
+ confirmation: booleanFlag(flags["confirm-local-user"]) ? "local-user-confirmed" : null }), json);
81
+ }
82
+
83
+ if (command === "remember-purge") {
84
+ return output(await purgeMustRemember({ id: positional[0],
85
+ confirmation: booleanFlag(flags["confirm-local-purge"]) ? "local-user-purge-confirmed" : null }), json);
86
+ }
87
+
88
+ if (command === "source-status") {
89
+ const host = flags.host || process.env.AGENTSPINE_HOST;
90
+ if (!["claude", "codex"].includes(host)) throw new Error("source-status requires --host claude or --host codex");
91
+ const resolved = await resolveHostSourceCatalog({ host, cwd: flags.cwd || process.cwd() });
92
+ const registry = await inspectSourceRegistry();
93
+ return output({ diagnostics: resolved.diagnostics, sources: resolved.catalog.documents.map((item) => ({
94
+ id: item.relativePath, scope: item.sourceScope, binding: item.sourceBinding, sha256: item.sha256,
95
+ bytes: item.bytes, authority: item.authority
96
+ })), bindings: registry.registry.bindings, authority: "context-only" }, json);
97
+ }
98
+
99
+ if (command === "source-bind") {
100
+ return output(await bindSourceRoot({
101
+ host: flags.host, hostHome: flags["host-home"] || process.env.CLAUDE_CONFIG_DIR || process.env.CODEX_HOME || process.cwd(),
102
+ projectRoot: flags.project || process.cwd(), sourceRoot: positional[0], scope: flags.scope || "state-user",
103
+ confirmation: booleanFlag(flags["confirm-local-binding"]) ? "local-user-confirmed" : null
104
+ }), json);
105
+ }
106
+
107
+ if (command === "source-rollback") {
108
+ return output(await rollbackSourceBinding({ id: positional[0],
109
+ confirmation: booleanFlag(flags["confirm-local-binding"]) ? "local-user-confirmed" : null }), json);
110
+ }
111
+
112
+ if (command === "source-purge") {
113
+ return output(await purgeSourceBinding({ id: positional[0],
114
+ confirmation: booleanFlag(flags["confirm-local-binding"]) ? "local-user-confirmed" : null }), json);
115
+ }
116
+ }