@synap-core/cli 1.12.2 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (234) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +25 -8
  3. package/dist/build-info.json +2 -2
  4. package/dist/commands/agents.d.ts +0 -1
  5. package/dist/commands/agents.js +1 -1
  6. package/dist/commands/agents.js.map +1 -1
  7. package/dist/commands/app.js +2 -1
  8. package/dist/commands/app.js.map +1 -1
  9. package/dist/commands/automation.js +46 -41
  10. package/dist/commands/automation.js.map +1 -1
  11. package/dist/commands/box.d.ts +42 -0
  12. package/dist/commands/box.js +89 -0
  13. package/dist/commands/box.js.map +1 -0
  14. package/dist/commands/bridge-setup.js +3 -1
  15. package/dist/commands/bridge-setup.js.map +1 -1
  16. package/dist/commands/capability.d.ts +1 -1
  17. package/dist/commands/capability.js +57 -34
  18. package/dist/commands/capability.js.map +1 -1
  19. package/dist/commands/close-questions.d.ts +27 -0
  20. package/dist/commands/close-questions.js +49 -0
  21. package/dist/commands/close-questions.js.map +1 -0
  22. package/dist/commands/close-questions.test.d.ts +1 -0
  23. package/dist/commands/close-questions.test.js +52 -0
  24. package/dist/commands/close-questions.test.js.map +1 -0
  25. package/dist/commands/connect.d.ts +1 -3
  26. package/dist/commands/connect.js +2 -2
  27. package/dist/commands/connect.js.map +1 -1
  28. package/dist/commands/context.js +72 -43
  29. package/dist/commands/context.js.map +1 -1
  30. package/dist/commands/data-extra.js +12 -4
  31. package/dist/commands/data-extra.js.map +1 -1
  32. package/dist/commands/data.js +2 -1
  33. package/dist/commands/data.js.map +1 -1
  34. package/dist/commands/doctor.d.ts +21 -0
  35. package/dist/commands/doctor.js +108 -13
  36. package/dist/commands/doctor.js.map +1 -1
  37. package/dist/commands/hooks.d.ts +19 -0
  38. package/dist/commands/hooks.js +70 -0
  39. package/dist/commands/hooks.js.map +1 -0
  40. package/dist/commands/import.d.ts +25 -0
  41. package/dist/commands/import.js +98 -12
  42. package/dist/commands/import.js.map +1 -1
  43. package/dist/commands/init.d.ts +14 -0
  44. package/dist/commands/init.js +59 -19
  45. package/dist/commands/init.js.map +1 -1
  46. package/dist/commands/knowledge.js +4 -2
  47. package/dist/commands/knowledge.js.map +1 -1
  48. package/dist/commands/lens.js +2 -1
  49. package/dist/commands/lens.js.map +1 -1
  50. package/dist/commands/market-authoring.js +1 -1
  51. package/dist/commands/market-authoring.js.map +1 -1
  52. package/dist/commands/mcp.js +2 -2
  53. package/dist/commands/mcp.js.map +1 -1
  54. package/dist/commands/observe.category.test.d.ts +1 -0
  55. package/dist/commands/observe.category.test.js +59 -0
  56. package/dist/commands/observe.category.test.js.map +1 -0
  57. package/dist/commands/observe.d.ts +3 -0
  58. package/dist/commands/observe.js +7 -5
  59. package/dist/commands/observe.js.map +1 -1
  60. package/dist/commands/observe.title.test.d.ts +1 -0
  61. package/dist/commands/observe.title.test.js +37 -0
  62. package/dist/commands/observe.title.test.js.map +1 -0
  63. package/dist/commands/playbook.js +9 -0
  64. package/dist/commands/playbook.js.map +1 -1
  65. package/dist/commands/pods.d.ts +6 -1
  66. package/dist/commands/pods.js +32 -15
  67. package/dist/commands/pods.js.map +1 -1
  68. package/dist/commands/proton-setup.js +3 -1
  69. package/dist/commands/proton-setup.js.map +1 -1
  70. package/dist/commands/session-feed-wait.d.ts +48 -0
  71. package/dist/commands/session-feed-wait.js +261 -0
  72. package/dist/commands/session-feed-wait.js.map +1 -0
  73. package/dist/commands/session-post.d.ts +40 -0
  74. package/dist/commands/session-post.js +96 -0
  75. package/dist/commands/session-post.js.map +1 -0
  76. package/dist/commands/session-wait.d.ts +9 -4
  77. package/dist/commands/session-wait.js +20 -5
  78. package/dist/commands/session-wait.js.map +1 -1
  79. package/dist/commands/sessions.d.ts +2 -0
  80. package/dist/commands/sessions.js +23 -0
  81. package/dist/commands/sessions.js.map +1 -1
  82. package/dist/commands/skills-commands.d.ts +2 -0
  83. package/dist/commands/skills-commands.js +9 -1
  84. package/dist/commands/skills-commands.js.map +1 -1
  85. package/dist/commands/skills-commands.test.d.ts +1 -0
  86. package/dist/commands/skills-commands.test.js +57 -0
  87. package/dist/commands/skills-commands.test.js.map +1 -0
  88. package/dist/commands/status.js +1 -1
  89. package/dist/commands/status.js.map +1 -1
  90. package/dist/commands/template.d.ts +42 -0
  91. package/dist/commands/template.js +191 -0
  92. package/dist/commands/template.js.map +1 -0
  93. package/dist/commands/tracks.d.ts +67 -6
  94. package/dist/commands/tracks.js +268 -16
  95. package/dist/commands/tracks.js.map +1 -1
  96. package/dist/commands/whoami.d.ts +7 -0
  97. package/dist/commands/whoami.js +17 -0
  98. package/dist/commands/whoami.js.map +1 -1
  99. package/dist/commands/worker-accounts.d.ts +149 -0
  100. package/dist/commands/worker-accounts.js +339 -0
  101. package/dist/commands/worker-accounts.js.map +1 -0
  102. package/dist/commands/worker-accounts.test.d.ts +1 -0
  103. package/dist/commands/worker-accounts.test.js +224 -0
  104. package/dist/commands/worker-accounts.test.js.map +1 -0
  105. package/dist/commands/worker.d.ts +219 -10
  106. package/dist/commands/worker.js +749 -117
  107. package/dist/commands/worker.js.map +1 -1
  108. package/dist/commands/worker.test.js +321 -10
  109. package/dist/commands/worker.test.js.map +1 -1
  110. package/dist/index.js +164 -27
  111. package/dist/index.js.map +1 -1
  112. package/dist/lib/agent-door.d.ts +1 -3
  113. package/dist/lib/agent-door.js +10 -7
  114. package/dist/lib/agent-door.js.map +1 -1
  115. package/dist/lib/auth.d.ts +3 -2
  116. package/dist/lib/auth.js +3 -3
  117. package/dist/lib/auth.js.map +1 -1
  118. package/dist/lib/box/egress.d.ts +82 -0
  119. package/dist/lib/box/egress.js +264 -0
  120. package/dist/lib/box/egress.js.map +1 -0
  121. package/dist/lib/box/evidence.d.ts +86 -0
  122. package/dist/lib/box/evidence.js +121 -0
  123. package/dist/lib/box/evidence.js.map +1 -0
  124. package/dist/lib/box/job-server.d.ts +72 -0
  125. package/dist/lib/box/job-server.js +246 -0
  126. package/dist/lib/box/job-server.js.map +1 -0
  127. package/dist/lib/box/provisioner.d.ts +83 -0
  128. package/dist/lib/box/provisioner.js +312 -0
  129. package/dist/lib/box/provisioner.js.map +1 -0
  130. package/dist/lib/box/proxmox.d.ts +112 -0
  131. package/dist/lib/box/proxmox.js +211 -0
  132. package/dist/lib/box/proxmox.js.map +1 -0
  133. package/dist/lib/box/wire.d.ts +98 -0
  134. package/dist/lib/box/wire.js +70 -0
  135. package/dist/lib/box/wire.js.map +1 -0
  136. package/dist/lib/browser-auth.d.ts +35 -0
  137. package/dist/lib/browser-auth.js +170 -0
  138. package/dist/lib/browser-auth.js.map +1 -0
  139. package/dist/lib/client-header.test.d.ts +1 -0
  140. package/dist/lib/client-header.test.js +85 -0
  141. package/dist/lib/client-header.test.js.map +1 -0
  142. package/dist/lib/conversation-headers.d.ts +24 -9
  143. package/dist/lib/conversation-headers.js +40 -3
  144. package/dist/lib/conversation-headers.js.map +1 -1
  145. package/dist/lib/credential-class.d.ts +28 -1
  146. package/dist/lib/credential-class.js +28 -6
  147. package/dist/lib/credential-class.js.map +1 -1
  148. package/dist/lib/exporter-coverage.d.ts +1 -1
  149. package/dist/lib/exporter-coverage.js +1 -1
  150. package/dist/lib/goal-words.d.ts +38 -0
  151. package/dist/lib/goal-words.js +112 -0
  152. package/dist/lib/goal-words.js.map +1 -0
  153. package/dist/lib/hub-client.d.ts +28 -7
  154. package/dist/lib/hub-client.js +75 -34
  155. package/dist/lib/hub-client.js.map +1 -1
  156. package/dist/lib/init-handoff.d.ts +8 -0
  157. package/dist/lib/init-handoff.js +9 -2
  158. package/dist/lib/init-handoff.js.map +1 -1
  159. package/dist/lib/key-source.d.ts +3 -1
  160. package/dist/lib/key-source.js +7 -4
  161. package/dist/lib/key-source.js.map +1 -1
  162. package/dist/lib/knowledge-title.d.ts +3 -2
  163. package/dist/lib/knowledge-title.js +3 -2
  164. package/dist/lib/knowledge-title.js.map +1 -1
  165. package/dist/lib/mcp-bridge.d.ts +7 -0
  166. package/dist/lib/mcp-bridge.js +34 -1
  167. package/dist/lib/mcp-bridge.js.map +1 -1
  168. package/dist/lib/mcp-bridge.test.js +31 -3
  169. package/dist/lib/mcp-bridge.test.js.map +1 -1
  170. package/dist/lib/openclaw.d.ts +32 -0
  171. package/dist/lib/openclaw.js +165 -0
  172. package/dist/lib/openclaw.js.map +1 -0
  173. package/dist/lib/pod-moved.d.ts +70 -0
  174. package/dist/lib/pod-moved.js +146 -0
  175. package/dist/lib/pod-moved.js.map +1 -0
  176. package/dist/lib/pod-reach.d.ts +39 -0
  177. package/dist/lib/pod-reach.js +117 -0
  178. package/dist/lib/pod-reach.js.map +1 -0
  179. package/dist/lib/pod-reach.test.d.ts +1 -0
  180. package/dist/lib/pod-reach.test.js +67 -0
  181. package/dist/lib/pod-reach.test.js.map +1 -0
  182. package/dist/lib/pod.d.ts +8 -0
  183. package/dist/lib/pod.js +12 -3
  184. package/dist/lib/pod.js.map +1 -1
  185. package/dist/lib/register-claude-code-mcp.test.d.ts +1 -0
  186. package/dist/lib/register-claude-code-mcp.test.js +78 -0
  187. package/dist/lib/register-claude-code-mcp.test.js.map +1 -0
  188. package/dist/lib/review-credential.js +3 -1
  189. package/dist/lib/review-credential.js.map +1 -1
  190. package/dist/lib/seed.d.ts +13 -0
  191. package/dist/lib/seed.js +135 -0
  192. package/dist/lib/seed.js.map +1 -0
  193. package/dist/lib/session-feed.d.ts +185 -0
  194. package/dist/lib/session-feed.js +257 -0
  195. package/dist/lib/session-feed.js.map +1 -0
  196. package/dist/lib/targets.d.ts +21 -3
  197. package/dist/lib/targets.js +52 -107
  198. package/dist/lib/targets.js.map +1 -1
  199. package/dist/lib/wake-hook-settings.d.ts +57 -0
  200. package/dist/lib/wake-hook-settings.js +153 -0
  201. package/dist/lib/wake-hook-settings.js.map +1 -0
  202. package/dist/lib/wake-state.d.ts +65 -0
  203. package/dist/lib/wake-state.js +122 -0
  204. package/dist/lib/wake-state.js.map +1 -0
  205. package/package.json +5 -2
  206. package/skills/README.md +1 -1
  207. package/skills/agent-os/SKILL.md +8 -8
  208. package/skills/synap/SKILL.md +141 -84
  209. package/skills/synap/code-skills.md +70 -0
  210. package/skills/synap/concepts.md +28 -20
  211. package/skills/synap/creative-loop.md +1 -1
  212. package/skills/synap/document-embeds.md +3 -1
  213. package/skills/synap/focus-sessions.md +16 -7
  214. package/skills/synap/from-intent.md +32 -16
  215. package/skills/synap/governance-rules.md +1 -1
  216. package/skills/synap/lenses.md +4 -4
  217. package/skills/synap/linking.md +2 -2
  218. package/skills/synap/mental-model.md +1 -1
  219. package/skills/synap/operating-mode-rules.md +1 -1
  220. package/skills/synap/quick-reference.md +2 -1
  221. package/skills/synap/reflexes.md +6 -6
  222. package/skills/synap/viewframe-cells.md +1 -1
  223. package/skills/synap/work-model.md +24 -10
  224. package/skills/synap/workspace-design.md +5 -5
  225. package/skills/synap/writes.md +16 -9
  226. package/skills/synap-app/SKILL.md +148 -66
  227. package/skills/synap-app/creating-the-base-app.md +12 -7
  228. package/skills/synap-app/governance.md +27 -16
  229. package/skills/synap-app/install-commands.md +18 -9
  230. package/skills/synap-app/overview.md +16 -9
  231. package/skills/synap-app/using-the-sdk.md +75 -25
  232. package/skills/synap-schema/SKILL.md +21 -21
  233. package/skills/synap-schema/intent-vocabulary-ssot.md +21 -21
  234. package/templates/box/runner.py +206 -0
package/dist/index.js CHANGED
@@ -115,7 +115,7 @@ program
115
115
  .option("--api-key <key>", "Hub Protocol API key")
116
116
  .option("--name <name>", "Pod profile to use (default: active pod)")
117
117
  .option("--list", "List what can be connected and exit")
118
- .option("--with-mcp", "Raycast only: also install the full 56-tool MCP server via mcp-remote (names overlap @synap)")
118
+ .addOption(new Option("--with-mcp", "deprecated, ignored: Raycast always gets the pod's MCP server").hideHelp())
119
119
  .option("--target <name>", "Legacy spelling of <thing>")
120
120
  .option("--pin-workspace <id>", "Legacy spelling of --workspace")
121
121
  .option("--pin-project <id>", "Legacy spelling of --project")
@@ -157,7 +157,8 @@ pods
157
157
  .option("--yes", "Non-interactive: skip prompts (won't recreate a rejected key)")
158
158
  .action(async (name, url, opts) => {
159
159
  const { podsUpdate } = await import("./commands/pods.js");
160
- await podsUpdate(name, url, { url: opts.url, yes: opts.yes });
160
+ if (!(await podsUpdate(name, url, { url: opts.url, yes: opts.yes })))
161
+ process.exitCode = 1;
161
162
  });
162
163
  pods
163
164
  .command("remove <name>")
@@ -188,6 +189,7 @@ program
188
189
  .option("--json", "Output as JSON")
189
190
  .option("--fix", "Fix key problems: finish a pending approval, give this computer its own key, or rewrite stale copies — then verify over MCP")
190
191
  .option("-v, --verbose", "Every check with its details, ids and addresses")
192
+ .option("--pod-url <url>", "Probe this pod URL (works with no pod configured)")
191
193
  .action(async (opts) => {
192
194
  const { doctor } = await import("./commands/doctor.js");
193
195
  await doctor(opts);
@@ -468,7 +470,7 @@ program
468
470
  }
469
471
  }
470
472
  else {
471
- console.log(chalk.dim(" Later: synap login · or synap login --token <token> (synap.live/account/tokens)"));
473
+ console.log(chalk.dim(" Later: synap login (prints a link you can open on any device)"));
472
474
  }
473
475
  }
474
476
  const { renderNextSteps, FLOW } = await import("./lib/next-steps.js");
@@ -1041,11 +1043,12 @@ program
1041
1043
  .requiredOption("--agent <name>", "The named agent this machine works as (its key comes from ~/.synap)")
1042
1044
  .option("--interval <dur>", "How often to check for handed sessions (e.g. 30s, 2m)", "30s")
1043
1045
  .option("--once", "Check once, run what is handed, wait for it, exit")
1044
- .option("--cwd <dir>", "Where the launched Claude Code works (default ~/Documents/Code/synap)")
1046
+ .option("--cwd <dir>", "Where code sessions' Claude Code works (default ~/Documents/Code/synap)")
1047
+ .option("--work-root <dir>", "Where playbook runs over pod data (no repo) get a folder each, <dir>/<session id> (default ~/synap-work)")
1045
1048
  .option("--max-parallel <n>", "Runs at the same time", "1")
1046
1049
  .option("--claude-bin <path>", "The claude binary", "claude")
1047
1050
  .option("--claude-config-dir <dir>", "CLAUDE_CONFIG_DIR for launched runs — picks which Claude subscription they use")
1048
- .option("--mcp-server <name>", "Claude Code MCP server name for this pod (detected from ~/.claude.json by default)")
1051
+ .option("--accounts <file>", "Claude accounts to rotate across ({version:1, reserve, accounts:[{id,label,token,design?}]}, mode 600); default ~/.config/synap-worker/accounts.json when it exists, else the environment's login")
1049
1052
  .option("--allowed-tools <list>", "Comma-separated Claude tools allowed without asking (the pod MCP server is always added)")
1050
1053
  .option("--skip-permissions", "Launch with --dangerously-skip-permissions instead of an allow-list")
1051
1054
  .option("--dry-run", "Claim and log what would launch, without launching Claude")
@@ -1053,6 +1056,27 @@ program
1053
1056
  const { workerCommand } = await import("./commands/worker.js");
1054
1057
  await workerCommand(opts);
1055
1058
  });
1059
+ // ─── box ──────────────────────────────────────────────────────────────────────
1060
+ // Run THIS computer as a run box provisioner: lease the box runs queued on the
1061
+ // pod, run each in a fresh isolated LXC, hand back the evidence. See src/commands/box.ts.
1062
+ const box = program.command("box").description("Run scripts in fresh isolated boxes on this computer (run box provisioner)");
1063
+ box
1064
+ .command("serve")
1065
+ .description("Lease queued box runs from the pod and run each in a fresh box")
1066
+ .option("--config <file>", "Provisioner config", "/etc/synap-box/config.json")
1067
+ .option("--once", "Lease at most one run, work it, exit")
1068
+ .action(async (opts) => {
1069
+ const { boxServeCommand } = await import("./commands/box.js");
1070
+ await boxServeCommand(opts);
1071
+ });
1072
+ box
1073
+ .command("reap")
1074
+ .description("Destroy every box no run holds (after a crash)")
1075
+ .option("--config <file>", "Provisioner config", "/etc/synap-box/config.json")
1076
+ .action(async (opts) => {
1077
+ const { boxReapCommand } = await import("./commands/box.js");
1078
+ await boxReapCommand(opts);
1079
+ });
1056
1080
  // ─── session ──────────────────────────────────────────────────────────────────
1057
1081
  // Focus sessions — goal-bound work rooms tracked on the pod.
1058
1082
  // AI agents: use start_session to begin, update_session to report progress,
@@ -1068,7 +1092,7 @@ session
1068
1092
  .option("--workspace <id>", "Workspace that owns the session")
1069
1093
  .option("--project <id>", "Project that owns the session (defaults to the active project lens; the pod accepts a workspace OR a project)")
1070
1094
  .option("--task-id <id>", "Link session to an existing task entity")
1071
- .option("--track <id>", "Born inside a track (a project's lasting goal) — implies its project")
1095
+ .option("--track <id>", "Born inside a track (a project's goal) — implies its project")
1072
1096
  .option("--template <id>", "Start from a playbook (seeds currentStage from its stages)")
1073
1097
  .option("--no-template", "Opt out of auto-matching a playbook — start ad-hoc")
1074
1098
  .option("--parent <id>", "Push from another session — records session --spawned_from--> session (the parent stays open)")
@@ -1136,6 +1160,8 @@ session
1136
1160
  // TERMINAL_SESSION_STATUSES. Re-listing them here would be a second copy of
1137
1161
  // an enum this CLI cannot import — the hand-mirrored-vocabulary defect.
1138
1162
  .option("--as <status>", "How it ended: closed (default, finished) | cancelled (abandoned) | failed (could not complete)")
1163
+ .option("--withdraw <messageId=note>", "An open question you asked that your work overtook, with why (repeatable)", collect, [])
1164
+ .option("--keep-owed <messageId>", "An open question the person still owes you an answer to after this session (repeatable)", collect, [])
1139
1165
  .option("--json", "Output full pack (or close result) as JSON")
1140
1166
  .option("--pod-url <url>", "Pod URL override")
1141
1167
  .option("--api-key <key>", "API key override")
@@ -1195,19 +1221,55 @@ session
1195
1221
  await evaluateSession(opts);
1196
1222
  });
1197
1223
  session
1198
- .command("wait <sessionId>")
1199
- .description("Block until the human replies in the session room, then print the reply. Exit 0 replied · 1 timeout · 2 failure (auth/network/broken read)")
1200
- .option("--since <iso>", "Only answers strictly after this ISO timestamp (default: now — skips anything that predates this wait)")
1224
+ .command("wait [sessionId]")
1225
+ .description("Block until the human replies in the session room (or, with --events, until the session changes), then print it. Session: the argument, else the one attached to this terminal. Exit 0 replied · 1 timeout · 2 failure (auth/network/broken read); with --hook: 2 wake · 0 anything else")
1226
+ .option("--since <iso>", "Only events strictly after this ISO timestamp (default: now — skips anything that predates this wait; with --events: the unread ones)")
1227
+ .option("--events <kinds>", "Wait on the session change feed: comma list of answer, proposal_decided, stage_moved, owner_message, session_message (a message from another session's agent), or all")
1228
+ .option("--wake-only", "Stop only on what should wake an agent: answers, owner messages, and agent messages the pod marked wake (the rest is read and skipped)")
1229
+ .option("--once", "One read, no waiting loop")
1230
+ .option("--peek", "Mark nothing picked up or read (a watcher that is not the agent doing the work)")
1231
+ .option("--hook", "Run as a Claude Code asyncRewake Stop hook: wait for a wake-worthy event, print it on stderr, exit 2 (see: synap hooks install-wake)")
1201
1232
  .option("--timeout <duration>", "Give up after this long (e.g. 30m, 2h)", "30m")
1202
- .option("--interval <duration>", "Delay between checks (e.g. 10s)", "10s")
1203
- .option("--limit <n>", "Max answers per page, 1-100", "20")
1204
- .option("--json", "Output the reply(ies) — or the timeout — as JSON")
1233
+ .option("--interval <duration>", "Delay between checks of the answer-only wait (e.g. 10s)", "10s")
1234
+ .option("--limit <n>", "Max answers / events per page, 1-100", "20")
1235
+ .option("--json", "Output the reply(ies) or events — or the timeout — as JSON")
1205
1236
  .option("--pod-url <url>", "Pod URL override")
1206
1237
  .option("--api-key <key>", "API key override")
1207
1238
  .action(async (sessionId, opts) => {
1208
1239
  const { waitSessionCommand } = await import("./commands/session-wait.js");
1209
1240
  await waitSessionCommand(sessionId, opts);
1210
1241
  });
1242
+ session
1243
+ .command("post <toSessionId> <text...>")
1244
+ .description("Message ANOTHER of your sessions' agent: blocked_on_you / handoff may wake it, done / fyi never do. Replying to a message that woke you? Pass its id as --cause. Exit 0 delivered · 1 pod does not deliver agent messages · 2 failure")
1245
+ .option("--intent <intent>", "blocked_on_you | handoff | done | fyi", "fyi")
1246
+ .option("--cause <messageId>", "The message that woke you (the id `synap session wait` printed), when this replies to it")
1247
+ .option("--from <sessionId>", "Your session, when this terminal is not bound to it")
1248
+ .option("--ref <kind:id[:label]>", "The state behind the message: session:<id>, blocked_by:<id>, proposal:<id>, slot:<sessionId>:<label> (repeatable)", collect, [])
1249
+ .option("--json", "Output the pod's reply as JSON")
1250
+ .option("--pod-url <url>", "Pod URL override")
1251
+ .option("--api-key <key>", "API key override")
1252
+ .action(async (toSessionId, text, opts) => {
1253
+ const { sessionPostCommand } = await import("./commands/session-post.js");
1254
+ await sessionPostCommand(toSessionId, text, opts);
1255
+ });
1256
+ // ─── hooks ────────────────────────────────────────────────────────────────────
1257
+ // Claude Code hooks the CLI owns. install-wake: the asyncRewake Stop hook that
1258
+ // lets another session's agent (or the person) wake an idle terminal.
1259
+ const hooksCmd = program
1260
+ .command("hooks")
1261
+ .description("Claude Code hooks that connect a terminal to its Synap session");
1262
+ hooksCmd
1263
+ .command("install-wake")
1264
+ .description("Add the wake hook (a Stop hook running `synap session wait --hook`) to this project's .claude/settings.json — idempotent, other hooks kept")
1265
+ .option("--uninstall", "Remove the wake hook instead")
1266
+ .option("--user", "Use ~/.claude/settings.json (every project) instead of the project's")
1267
+ .option("--dir <path>", "The project directory (default: the current one)")
1268
+ .option("--json", "Output the result as JSON")
1269
+ .action(async (opts) => {
1270
+ const { installWakeCommand } = await import("./commands/hooks.js");
1271
+ installWakeCommand(opts);
1272
+ });
1211
1273
  // ─── playbook ─────────────────────────────────────────────────────────────────
1212
1274
  // Start a governed process in one step — the Hub door MCP synap_run_playbook
1213
1275
  // shares. A proposal ("queued for your review") is success.
@@ -1229,17 +1291,20 @@ playbookCmd
1229
1291
  await runPlaybook(ref, opts);
1230
1292
  });
1231
1293
  // ─── track ────────────────────────────────────────────────────────────────────
1232
- // A LASTING goal inside a project, worked in sessions (`session start --track`).
1233
- // Legacy tracks also run a method with steps. Writes are governed —
1294
+ // A goal inside a project, worked in sessions (`session start --track`); a
1295
+ // person closes it with a verdict. Legacy tracks also run a method with steps. Writes are governed —
1234
1296
  // "queued for your review" is success.
1235
1297
  const track = program
1236
1298
  .command("track")
1237
- .description("Manage tracks — the lasting goals a project pursues");
1299
+ .description("Manage tracks — the goals a project pursues");
1238
1300
  track
1239
1301
  .command("list")
1240
- .description("List a project's tracks (defaults to the active project lens)")
1302
+ .description("List a project's goals (the active project lens); with no project in scope, every goal on the pod")
1241
1303
  .option("--project <id>", "Project id (defaults to the active project lens)")
1242
- .option("--all", "Include archived tracks")
1304
+ .option("--everywhere", "List every goal on the pod, ignoring the project lens")
1305
+ .option("--limit <n>", "Pod-wide: page size (default 50)")
1306
+ .option("--cursor <cursor>", "Pod-wide: the next page (printed under the last one)")
1307
+ .option("--all", "Include dropped (archived) tracks")
1243
1308
  .option("--json", "Output as JSON")
1244
1309
  .option("--pod-url <url>", "Pod URL override")
1245
1310
  .option("--api-key <key>", "API key override")
@@ -1259,12 +1324,18 @@ track
1259
1324
  });
1260
1325
  track
1261
1326
  .command("start")
1262
- .description("Start a track — a lasting goal — on a project")
1327
+ .description("Start a track — a goal — on a project")
1263
1328
  .option("--name <name>", "The track's name (required without --playbook)")
1264
1329
  .option("--direction <text>", "Where it is heading, one line")
1265
1330
  .option("--playbook <id>", "Legacy: a track template (project-scoped playbook with steps)")
1266
1331
  .option("--project <id>", "Project id (defaults to the active project lens)")
1267
1332
  .option("--param <key=value>", "Answer a declared param (repeatable)", collect, [])
1333
+ .option("--end-state <text>", "What done looks like, in your words")
1334
+ .option("--criterion <text>", "How it is judged done — '[measured|judged|handed_over|learning|decided_outside|certified:] statement'; give 0 or 2-5 (repeatable)", collect, [])
1335
+ .option("--drop-condition <text>", "When to stop pursuing it (repeatable, at most 5)", collect, [])
1336
+ .option("--kind <kind>", "Kind of work: project|flow|operation|investigation|incident|commission|pathway (a proposal until you confirm)")
1337
+ .option("--uncertainty <level>", "How well the way is known: clear|complicated|complex|chaotic|unknown")
1338
+ .option("--loop <on|off|n>", "Let the goal propose its next session: on, off, or n sessions a week")
1268
1339
  .option("--reason <text>", "Why — shown to the reviewer")
1269
1340
  .option("--json", "Output as JSON")
1270
1341
  .option("--pod-url <url>", "Pod URL override")
@@ -1273,6 +1344,37 @@ track
1273
1344
  const { startTrack } = await import("./commands/tracks.js");
1274
1345
  await startTrack(opts);
1275
1346
  });
1347
+ track
1348
+ .command("update <id>")
1349
+ .description("Set a goal's direction, KPI and what it holds (each field is written whole; kpi is merged)")
1350
+ .option("--direction <text>", "Where it is heading, one line")
1351
+ .option("--kpi-current <n>", "The KPI's latest value (stated, never measured)")
1352
+ .option("--kpi-target <n>", "Move the KPI's target")
1353
+ .option("--end-state <text>", "What done looks like, in your words")
1354
+ .option("--criterion <text>", "How it is judged done — '[measured|judged|handed_over|learning|decided_outside|certified:] statement'; give 0 or 2-5 (repeatable)", collect, [])
1355
+ .option("--drop-condition <text>", "When to stop pursuing it (repeatable, at most 5)", collect, [])
1356
+ .option("--kind <kind>", "Kind of work: project|flow|operation|investigation|incident|commission|pathway (a proposal until you confirm)")
1357
+ .option("--uncertainty <level>", "How well the way is known: clear|complicated|complex|chaotic|unknown")
1358
+ .option("--loop <on|off|n>", "Let the goal propose its next session: on, off, or n sessions a week")
1359
+ .option("--reason <text>", "Why — shown to the reviewer")
1360
+ .option("--json", "Output as JSON")
1361
+ .option("--pod-url <url>", "Pod URL override")
1362
+ .option("--api-key <key>", "API key override")
1363
+ .action(async (id, opts) => {
1364
+ const { updateTrack } = await import("./commands/tracks.js");
1365
+ await updateTrack(id, opts);
1366
+ });
1367
+ track
1368
+ .command("accept <id> <criterion> <decision>")
1369
+ .description("The goal's judge decides a claimed criterion: accepted | changes_asked | rejected (a person's act)")
1370
+ .option("--note <text>", "What to change, or why it was rejected")
1371
+ .option("--json", "Output as JSON")
1372
+ .option("--pod-url <url>", "Pod URL override")
1373
+ .option("--api-key <key>", "API key override")
1374
+ .action(async (id, criterion, decision, opts) => {
1375
+ const { acceptCriterion } = await import("./commands/tracks.js");
1376
+ await acceptCriterion(id, criterion, decision, opts);
1377
+ });
1276
1378
  track
1277
1379
  .command("advance <id> <stage>")
1278
1380
  .description("Legacy (tracks with steps): move a track to a step; prints the session that step offers")
@@ -1286,7 +1388,12 @@ track
1286
1388
  });
1287
1389
  track
1288
1390
  .command("status <id> <status>")
1289
- .description("Pause, resume or archive a track (active|paused|archived)")
1391
+ .description("Move a track: proposed|agreed|ready|active|paused|completed (Closed)|archived (Dropped). " +
1392
+ "Closing needs --verdict met|partly_met|not_met (an operation closes retired, and only one does); dropping should carry " +
1393
+ "no_longer_needed|impossible|replaced|mistake (impossible and replaced need --verdict-reason). " +
1394
+ "Both are final — reopen makes a new version.")
1395
+ .option("--verdict <verdict>", "How the goal ended (required to close; advised to drop)")
1396
+ .option("--verdict-reason <text>", "Why — required for impossible and replaced")
1290
1397
  .option("--reason <text>", "Why — shown to the reviewer")
1291
1398
  .option("--json", "Output as JSON")
1292
1399
  .option("--pod-url <url>", "Pod URL override")
@@ -1295,6 +1402,34 @@ track
1295
1402
  const { setTrackStatus } = await import("./commands/tracks.js");
1296
1403
  await setTrackStatus(id, status, opts);
1297
1404
  });
1405
+ track
1406
+ .command("reopen <id>")
1407
+ .description("Reopen a closed or dropped goal as a NEW version (the old one keeps its verdict)")
1408
+ .option("--name <name>", "A new name (default: the old one's)")
1409
+ .option("--reason <text>", "Why — shown to the reviewer")
1410
+ .option("--json", "Output as JSON")
1411
+ .option("--pod-url <url>", "Pod URL override")
1412
+ .option("--api-key <key>", "API key override")
1413
+ .action(async (id, opts) => {
1414
+ const { reopenTrack } = await import("./commands/tracks.js");
1415
+ await reopenTrack(id, opts);
1416
+ });
1417
+ const goal = program
1418
+ .command("goal")
1419
+ .description("Goals — what people call a track");
1420
+ goal
1421
+ .command("convert <entityId>")
1422
+ .description("Make a goal, objective or OKR entity a goal (once; the entity is kept and linked)")
1423
+ .option("--project <id>", "The goal's project — only when the entity is filed in none or several")
1424
+ .option("--name <name>", "A name other than the entity's title")
1425
+ .option("--reason <text>", "Why — shown to the reviewer")
1426
+ .option("--json", "Output as JSON")
1427
+ .option("--pod-url <url>", "Pod URL override")
1428
+ .option("--api-key <key>", "API key override")
1429
+ .action(async (entityId, opts) => {
1430
+ const { convertToGoal } = await import("./commands/tracks.js");
1431
+ await convertToGoal(entityId, opts);
1432
+ });
1298
1433
  track
1299
1434
  .command("params <id> <pairs...>")
1300
1435
  .description("Answer the method's params as key=value (merged; key=null clears one)")
@@ -1352,6 +1487,7 @@ skillCmd
1352
1487
  skillCmd
1353
1488
  .command("get <slug>")
1354
1489
  .description("Fetch a skill from the knowledge base by slug and print its body")
1490
+ .option("--raw", "Print only the stored body, exactly (for scripts)")
1355
1491
  .option("--pod-url <url>", "Pod URL override")
1356
1492
  .option("--api-key <key>", "API key override")
1357
1493
  .action(async (slug, opts) => {
@@ -1444,7 +1580,7 @@ const observe = program
1444
1580
  observe
1445
1581
  .command("write <text>", { isDefault: true })
1446
1582
  .description("Record an observation about the user (pod-scoped, AI-maintained)")
1447
- .option("--category <cat>", "working_style | communication | focus | technical | preference", "preference")
1583
+ .option("--category <cat>", "working_style | communication | focus | preferences | habits | technical", "preferences")
1448
1584
  .option("--confidence <n>", "Confidence score 0-1", "0.5")
1449
1585
  .option("--json", "Output as JSON")
1450
1586
  .option("--pod-url <url>", "Pod URL override")
@@ -1573,7 +1709,7 @@ agents
1573
1709
  .option("--role <role>", "Workspace role: admin | editor | viewer (default: editor)")
1574
1710
  .option("--workspace <id>", "Focus on one workspace (default: pod-wide)")
1575
1711
  .option("--project <id>", "Focus on one project (composable with --workspace)")
1576
- .option("--with-mcp", "Raycast only: also install the full MCP server via mcp-remote")
1712
+ .addOption(new Option("--with-mcp", "deprecated, ignored: Raycast always gets the pod's MCP server").hideHelp())
1577
1713
  .option("--api-key <key>", "Register a key you already hold, on this machine only (mints nothing)")
1578
1714
  .option("--label <label>", "Human-readable description")
1579
1715
  .action(async (kind, opts) => {
@@ -2092,12 +2228,12 @@ Examples:
2092
2228
  // ─── artifact ─────────────────────────────────────────────────────────────────
2093
2229
  const artifact = program
2094
2230
  .command("artifact")
2095
- .description("Create and manage HTML artifacts as Synap documents");
2231
+ .description("Create HTML artifacts as Synap cells: an HTML/JS page that opens in the desktop app and can read pod data");
2096
2232
  artifact
2097
2233
  .command("create")
2098
- .description("Create an HTML artifact from a local file")
2234
+ .description("Define a cell from a local HTML file (governed: an agent key files a proposal)")
2099
2235
  .requiredOption("--html <file>", "HTML file to upload")
2100
- .option("--name <name>", "Document title (default: filename)")
2236
+ .option("--name <name>", "Cell name (default: filename)")
2101
2237
  .option("--workspace <id>", "Workspace context")
2102
2238
  .option("--open", "Open in the Synap desktop app after creation")
2103
2239
  .option("--json", "JSON output")
@@ -2665,14 +2801,15 @@ sync
2665
2801
  await capabilitySyncStatus(provider, opts);
2666
2802
  });
2667
2803
  // ─── raycast (hidden power-user escape) ───────────────────────────────────────
2668
- // Prefer the native Synap Raycast extension (@synap). Capability verbs there go
2669
- // through list-actions / run-action. Script Commands are a per-verb escape hatch.
2804
+ // Prefer Raycast AI on the pod's MCP server (`synap connect raycast`), where
2805
+ // capability verbs run through synap_run_capability. Script Commands are a
2806
+ // per-verb escape hatch.
2670
2807
  const raycast = program
2671
2808
  .command("raycast", { hidden: true })
2672
2809
  .description("(hidden) Power-user escape: generate Raycast Script Commands per capability verb");
2673
2810
  raycast
2674
2811
  .command("generate")
2675
- .description("Power-user escape: emit a Script Command per enabled verb (extension uses list-actions/run-action)")
2812
+ .description("Power-user escape: emit a Script Command per enabled verb (Raycast AI uses the pod's MCP server)")
2676
2813
  .option("--out <dir>", "Output directory (default: ~/.synap/raycast-commands)")
2677
2814
  .option("--workspace <id>", "Workspace context")
2678
2815
  .action(async (opts) => {