@synap-core/cli 1.13.0 → 1.13.1-next.20261102.ec3d166

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 (221) hide show
  1. package/README.md +13 -3
  2. package/dist/build-info.json +2 -3
  3. package/dist/commands/agents.js +12 -2
  4. package/dist/commands/agents.js.map +1 -1
  5. package/dist/commands/capability.d.ts +86 -0
  6. package/dist/commands/capability.js +117 -30
  7. package/dist/commands/capability.js.map +1 -1
  8. package/dist/commands/data-extra.d.ts +13 -0
  9. package/dist/commands/data-extra.js +23 -2
  10. package/dist/commands/data-extra.js.map +1 -1
  11. package/dist/commands/doctor.d.ts +18 -0
  12. package/dist/commands/doctor.js +28 -1
  13. package/dist/commands/doctor.js.map +1 -1
  14. package/dist/commands/init.js +4 -2
  15. package/dist/commands/init.js.map +1 -1
  16. package/dist/commands/keys-request.d.ts +48 -0
  17. package/dist/commands/keys-request.js +236 -0
  18. package/dist/commands/keys-request.js.map +1 -0
  19. package/dist/commands/keys-request.test.d.ts +1 -0
  20. package/dist/commands/keys-request.test.js +176 -0
  21. package/dist/commands/keys-request.test.js.map +1 -0
  22. package/dist/commands/knowledge.d.ts +6 -0
  23. package/dist/commands/knowledge.js +9 -1
  24. package/dist/commands/knowledge.js.map +1 -1
  25. package/dist/commands/market.d.ts +61 -4
  26. package/dist/commands/market.js +106 -48
  27. package/dist/commands/market.js.map +1 -1
  28. package/dist/commands/mcp.d.ts +1 -1
  29. package/dist/commands/mcp.js +14 -9
  30. package/dist/commands/mcp.js.map +1 -1
  31. package/dist/commands/pods.js +6 -2
  32. package/dist/commands/pods.js.map +1 -1
  33. package/dist/commands/proposals-actions.js +7 -1
  34. package/dist/commands/proposals-actions.js.map +1 -1
  35. package/dist/commands/providers.d.ts +22 -6
  36. package/dist/commands/providers.js +39 -32
  37. package/dist/commands/providers.js.map +1 -1
  38. package/dist/commands/raycast.d.ts +15 -0
  39. package/dist/commands/raycast.js +36 -10
  40. package/dist/commands/raycast.js.map +1 -1
  41. package/dist/commands/status.js +12 -6
  42. package/dist/commands/status.js.map +1 -1
  43. package/dist/commands/statusline.backoff.test.js +13 -3
  44. package/dist/commands/statusline.backoff.test.js.map +1 -1
  45. package/dist/commands/statusline.d.ts +104 -9
  46. package/dist/commands/statusline.js +392 -148
  47. package/dist/commands/statusline.js.map +1 -1
  48. package/dist/commands/statusline.line2.test.d.ts +15 -0
  49. package/dist/commands/statusline.line2.test.js +226 -0
  50. package/dist/commands/statusline.line2.test.js.map +1 -0
  51. package/dist/commands/statusline.needs-you.test.d.ts +1 -0
  52. package/dist/commands/statusline.needs-you.test.js +17 -0
  53. package/dist/commands/statusline.needs-you.test.js.map +1 -0
  54. package/dist/commands/statusline.now.test.d.ts +10 -0
  55. package/dist/commands/statusline.now.test.js +250 -0
  56. package/dist/commands/statusline.now.test.js.map +1 -0
  57. package/dist/commands/tracks.d.ts +1 -0
  58. package/dist/commands/tracks.js +4 -0
  59. package/dist/commands/tracks.js.map +1 -1
  60. package/dist/commands/upload.js +12 -0
  61. package/dist/commands/upload.js.map +1 -1
  62. package/dist/commands/wait.d.ts +124 -0
  63. package/dist/commands/wait.js +384 -0
  64. package/dist/commands/wait.js.map +1 -0
  65. package/dist/commands/wait.test.d.ts +8 -0
  66. package/dist/commands/wait.test.js +308 -0
  67. package/dist/commands/wait.test.js.map +1 -0
  68. package/dist/commands/worker-github-app.d.ts +63 -0
  69. package/dist/commands/worker-github-app.js +161 -0
  70. package/dist/commands/worker-github-app.js.map +1 -0
  71. package/dist/commands/worker-github-app.test.d.ts +1 -0
  72. package/dist/commands/worker-github-app.test.js +102 -0
  73. package/dist/commands/worker-github-app.test.js.map +1 -0
  74. package/dist/commands/worker-github-broker.d.ts +39 -0
  75. package/dist/commands/worker-github-broker.js +106 -0
  76. package/dist/commands/worker-github-broker.js.map +1 -0
  77. package/dist/commands/worker-github-broker.test.d.ts +1 -0
  78. package/dist/commands/worker-github-broker.test.js +90 -0
  79. package/dist/commands/worker-github-broker.test.js.map +1 -0
  80. package/dist/commands/worker-runs.test.d.ts +1 -0
  81. package/dist/commands/worker-runs.test.js +150 -0
  82. package/dist/commands/worker-runs.test.js.map +1 -0
  83. package/dist/commands/worker-worktrees.d.ts +34 -0
  84. package/dist/commands/worker-worktrees.js +87 -0
  85. package/dist/commands/worker-worktrees.js.map +1 -0
  86. package/dist/commands/worker.d.ts +192 -5
  87. package/dist/commands/worker.js +467 -45
  88. package/dist/commands/worker.js.map +1 -1
  89. package/dist/commands/worker.test.js +269 -3
  90. package/dist/commands/worker.test.js.map +1 -1
  91. package/dist/index.js +59 -4
  92. package/dist/index.js.map +1 -1
  93. package/dist/lib/agents-config.d.ts +9 -0
  94. package/dist/lib/agents-config.js +20 -0
  95. package/dist/lib/agents-config.js.map +1 -1
  96. package/dist/lib/atomic-file.d.ts +20 -1
  97. package/dist/lib/atomic-file.js +100 -2
  98. package/dist/lib/atomic-file.js.map +1 -1
  99. package/dist/lib/auth.d.ts +25 -0
  100. package/dist/lib/auth.js +49 -9
  101. package/dist/lib/auth.js.map +1 -1
  102. package/dist/lib/box/job-server.js +4 -0
  103. package/dist/lib/box/job-server.js.map +1 -1
  104. package/dist/lib/bridge-invocation.test.d.ts +1 -0
  105. package/dist/lib/bridge-invocation.test.js +75 -0
  106. package/dist/lib/bridge-invocation.test.js.map +1 -0
  107. package/dist/lib/bridge-status.d.ts +144 -0
  108. package/dist/lib/bridge-status.js +227 -0
  109. package/dist/lib/bridge-status.js.map +1 -0
  110. package/dist/lib/bridge-status.test.d.ts +6 -0
  111. package/dist/lib/bridge-status.test.js +197 -0
  112. package/dist/lib/bridge-status.test.js.map +1 -0
  113. package/dist/lib/client-header.test.js +19 -1
  114. package/dist/lib/client-header.test.js.map +1 -1
  115. package/dist/lib/conversation-headers.d.ts +67 -2
  116. package/dist/lib/conversation-headers.js +122 -6
  117. package/dist/lib/conversation-headers.js.map +1 -1
  118. package/dist/lib/conversation-headers.test.d.ts +1 -0
  119. package/dist/lib/conversation-headers.test.js +78 -0
  120. package/dist/lib/conversation-headers.test.js.map +1 -0
  121. package/dist/lib/credential-class.d.ts +12 -1
  122. package/dist/lib/credential-class.js +20 -0
  123. package/dist/lib/credential-class.js.map +1 -1
  124. package/dist/lib/device-connect.d.ts +45 -0
  125. package/dist/lib/device-connect.js +60 -0
  126. package/dist/lib/device-connect.js.map +1 -1
  127. package/dist/lib/goal-words.js +6 -3
  128. package/dist/lib/goal-words.js.map +1 -1
  129. package/dist/lib/hub-client.d.ts +59 -1
  130. package/dist/lib/hub-client.js +130 -36
  131. package/dist/lib/hub-client.js.map +1 -1
  132. package/dist/lib/key-locations.d.ts +3 -3
  133. package/dist/lib/key-locations.js +3 -39
  134. package/dist/lib/key-locations.js.map +1 -1
  135. package/dist/lib/machine-instance.d.ts +7 -5
  136. package/dist/lib/machine-instance.js +7 -5
  137. package/dist/lib/machine-instance.js.map +1 -1
  138. package/dist/lib/mcp-bridge.d.ts +43 -0
  139. package/dist/lib/mcp-bridge.js +199 -11
  140. package/dist/lib/mcp-bridge.js.map +1 -1
  141. package/dist/lib/mcp-bridge.test.js +194 -2
  142. package/dist/lib/mcp-bridge.test.js.map +1 -1
  143. package/dist/lib/mcp-call.d.ts +5 -1
  144. package/dist/lib/mcp-call.js +7 -6
  145. package/dist/lib/mcp-call.js.map +1 -1
  146. package/dist/lib/mcp-connector-url.test.d.ts +1 -0
  147. package/dist/lib/mcp-connector-url.test.js +13 -0
  148. package/dist/lib/mcp-connector-url.test.js.map +1 -0
  149. package/dist/lib/mcp-snippets.d.ts +16 -0
  150. package/dist/lib/mcp-snippets.js +20 -2
  151. package/dist/lib/mcp-snippets.js.map +1 -1
  152. package/dist/lib/now-line.d.ts +66 -0
  153. package/dist/lib/now-line.js +193 -0
  154. package/dist/lib/now-line.js.map +1 -0
  155. package/dist/lib/now-line.test.d.ts +5 -0
  156. package/dist/lib/now-line.test.js +177 -0
  157. package/dist/lib/now-line.test.js.map +1 -0
  158. package/dist/lib/package-updates.d.ts +66 -0
  159. package/dist/lib/package-updates.js +76 -0
  160. package/dist/lib/package-updates.js.map +1 -0
  161. package/dist/lib/pod.d.ts +0 -4
  162. package/dist/lib/pod.js +0 -7
  163. package/dist/lib/pod.js.map +1 -1
  164. package/dist/lib/register-claude-code-mcp.test.js +19 -0
  165. package/dist/lib/register-claude-code-mcp.test.js.map +1 -1
  166. package/dist/lib/safe-open.d.ts +5 -3
  167. package/dist/lib/safe-open.js +9 -8
  168. package/dist/lib/safe-open.js.map +1 -1
  169. package/dist/lib/self-host.d.ts +17 -0
  170. package/dist/lib/self-host.js +24 -0
  171. package/dist/lib/self-host.js.map +1 -0
  172. package/dist/lib/targets.d.ts +31 -0
  173. package/dist/lib/targets.js +100 -104
  174. package/dist/lib/targets.js.map +1 -1
  175. package/dist/lib/term.d.ts +24 -0
  176. package/dist/lib/term.js +52 -0
  177. package/dist/lib/term.js.map +1 -0
  178. package/dist/lib/term.test.d.ts +1 -0
  179. package/dist/lib/term.test.js +29 -0
  180. package/dist/lib/term.test.js.map +1 -0
  181. package/dist/lib/transcript-index.d.ts +94 -0
  182. package/dist/lib/transcript-index.js +321 -0
  183. package/dist/lib/transcript-index.js.map +1 -0
  184. package/dist/lib/transcript-index.test.d.ts +10 -0
  185. package/dist/lib/transcript-index.test.js +200 -0
  186. package/dist/lib/transcript-index.test.js.map +1 -0
  187. package/dist/lib/wait-help.d.ts +11 -0
  188. package/dist/lib/wait-help.js +25 -0
  189. package/dist/lib/wait-help.js.map +1 -0
  190. package/dist/lib/wait-state.d.ts +57 -0
  191. package/dist/lib/wait-state.js +114 -0
  192. package/dist/lib/wait-state.js.map +1 -0
  193. package/package.json +2 -2
  194. package/skills/synap/SKILL.md +71 -38
  195. package/skills/synap/code-skills.md +15 -1
  196. package/skills/synap/concepts.md +36 -26
  197. package/skills/synap/document-embeds.md +15 -1
  198. package/skills/synap/focus-sessions.md +4 -4
  199. package/skills/synap/from-intent.md +2 -2
  200. package/skills/synap/governance-rules.md +2 -0
  201. package/skills/synap/reflexes.md +4 -4
  202. package/skills/synap/work-model.md +1 -1
  203. package/skills/synap/writing-titles.md +7 -0
  204. package/skills/synap-app/SKILL.md +2 -2
  205. package/skills/synap-app/overview.md +2 -2
  206. package/skills/synap-market/SKILL.md +1 -1
  207. package/skills/synap-market/governance-and-catalog.md +1 -1
  208. package/skills/synap-schema/SKILL.md +4 -1
  209. package/skills/synap-schema/intent-vocabulary-ssot.md +4 -1
  210. package/dist/commands/template.d.ts +0 -42
  211. package/dist/commands/template.js +0 -191
  212. package/dist/commands/template.js.map +0 -1
  213. package/dist/lib/browser-auth.d.ts +0 -35
  214. package/dist/lib/browser-auth.js +0 -170
  215. package/dist/lib/browser-auth.js.map +0 -1
  216. package/dist/lib/openclaw.d.ts +0 -32
  217. package/dist/lib/openclaw.js +0 -165
  218. package/dist/lib/openclaw.js.map +0 -1
  219. package/dist/lib/seed.d.ts +0 -13
  220. package/dist/lib/seed.js +0 -135
  221. package/dist/lib/seed.js.map +0 -1
@@ -204,7 +204,21 @@ Never rewrite a whole document to change part of it. Read it, then patch it:
204
204
  - `replace_all {content}` — the whole body; needs `baseRevision` and is
205
205
  always reviewed;
206
206
  - `set_title {title}` — renames the document (its one title). A human name,
207
- never an id or a slug; the content is left as it is.
207
+ never an id or a slug; the content is left as it is;
208
+ - `insert_embed {directive, ref, props?, fallback?, sectionId? | after?}` —
209
+ adds an embed written for you (`synap-cell` with `{cellKey}` and its props,
210
+ `synap-entity` with `{id}`, `synap-view` with `{viewId}`): prefer it to
211
+ typing directive text. It goes at the end, at the end of section
212
+ `sectionId`, or after the line holding `after` (exact once). Give it a
213
+ `fallback` sentence: it is what the phone and exports read;
214
+ - `set_scope {scope}` — what a LIVING document's cells read through:
215
+ `{kind:"pod"}`, `{kind:"workspace", workspaceId, projectId?}`,
216
+ `{kind:"project", projectId}`, `{kind:"track", trackId}` or
217
+ `{kind:"session", sessionId}` (null clears it). Never put a scope in a
218
+ cell's props: the host stamps the document's scope on every cell;
219
+ - `set_refresher {automationId}` — binds the automation that refreshes the
220
+ document (null unbinds). Its runs may rewrite the document's EXISTING
221
+ `ai` sections without review; anything else they write is reviewed.
208
222
 
209
223
  Refused, whatever the op: changing a section whose `owner` is `human` (the AI
210
224
  never rewrites a person's words — write a new section), and removing an embed
@@ -8,7 +8,7 @@ A **focus session** is a named, multi-step work room where you and AI agents col
8
8
 
9
9
  **Fetch the pod's processes before you invent one.** Without `templateId`, the start door hands back the pod's existing playbooks ranked against your title and goal — the response's `playbooks` block lists `candidates` (id, name, score, and the `reason` each one matched) and applies **nothing**. Read them: if one fits, start again naming it with `templateId` (the only way a playbook binds), and if none does, go ad-hoc deliberately. Pass `templateId: null` to skip matching entirely. You can also look first, with `synap_list_playbooks` / `synap_match_playbooks`.
10
10
 
11
- **Declare your OUTCOMES** — `outcomes: [{ key?, label, kind, verify?, owner? }]` on `synap_start_session` / `synap_update_session` (Hub: the same field on `POST`/`PATCH /focus-sessions`). One list of what the work must yield, each one verifiable. Two kinds:
11
+ **Declare your OUTCOMES** — a new session you start must declare at least one fact (or a deliverable with `verify`), or the start is refused (`NO_CRITERIA`); continuing an existing one needs none. `outcomes: [{ key?, label, kind, verify?, owner? }]` on `synap_start_session` / `synap_update_session` (Hub: the same field on `POST`/`PATCH /focus-sessions`). One list of what the work must yield, each one verifiable. Two kinds:
12
12
 
13
13
  - **A fact** (`kind: 'fact'`) — your definition of done, a binary, observable statement ("Typecheck passes with 0 errors"), checked by `verify` (`capability` → `judge` → `human`; default `judge`) through `synap_evaluate_session`. Two to five, not a checklist. **Propose them yourself and let the person validate or rewrite them**; they may equally be written by the person, but a session with none can only be reported on by opinion. Closing never blocks on them; unmet ones are flagged.
14
14
  - **A deliverable** (`kind: 'document'`, `'report'`, `'code'`, `'decision'`…). **Declare what the work will produce** — the documents, entities and decisions this session owes. That list is what makes "done" derivable instead of announced, and it is what the person's board shows as still outstanding. Give each a `key` (or one is derived from the label) and name it by that key from then on.
@@ -25,10 +25,10 @@ On `synap_update_session`, `outcomes` UPSERTS by key — a renamed label keeps i
25
25
  - **Targets get a result each.** A worker session holds its things as targets: your own move of a target marks it `done`, someone else's marks it `skipped`, and targets left at close are `skipped`. Put each outcome on its thing, not only in a summary. Model: `work-model`.
26
26
  - **Person-only steps** are an `owner: 'human'` output with a `blockedReason` and a `why` (below) — never a line buried in your reply.
27
27
  - **Room first.** Post progress, questions and results in the session room (below); your own chat may repeat them; show a question there with its short id, `Q-` + the first 8 characters of its message id (`Q-1a2b3c4d`).
28
- - **Grade before you say done.** `synap_evaluate_session { sessionId, evidence: { <criterionKey>: { passed, detail } } }` with the real evidence — the command output, the link, the count. Then close every question you asked that is still open (answer or withdraw it, below), then `synap_complete_session`: the pod refuses your close while your own room questions are undispositioned. Closing never blocks on criteria, but an ungraded one reads as unmeasured: a claim nobody checked.
28
+ - **Grade before you say done.** `synap_evaluate_session { sessionId, evidence: { <criterionKey>: { passed, detail } } }` with the real evidence — the command output, the link, the count. Then close every question you asked that is still open (answer or withdraw it, below), then `synap_complete_session`: the pod refuses your close while your own room questions are undispositioned. Your `closed` close is refused (`NOT_DONE`) while a required criterion you can still check is failed or ungraded, a required outcome an agent owes (yours or a delegate's) is open and unclaimed, or a required outcome the person owes is still open: then wait for them (leave the session open or pause it). What only awaits the person's grade or review (a criterion they check, one escalated to them, an outcome you claimed, a proposal pending) never refuses and comes back as `waiting`. To close anyway, pass `reason`: it is posted as one line in the session room.
29
29
  - **The doors remind you.** `synap_update_session` and `synap_complete_session` replies (and Hub `PATCH /focus-sessions/:id` / `POST …/complete`) carry `nudges` (criteria still ungraded, no criteria, a stage never set, outputs owed by the person, and — once, on a session born without a playbook — the playbooks that fit it). `orient`'s `startHere.sessionsOwingGrade` lists your open sessions with ungraded criteria.
30
30
  - **Goal, PR, close.** File the session into the goal it serves (`trackId`: the start reply's `offers.goals` lists the project's open goals, `offers.sessions` the open sessions already on close work — continue one of those rather than opening a twin). Record each PR as an outcome `pr-<repo>-<n>` (`kind: 'pull_request'`, `ref: { url }`; `sessionId` may be left out when this conversation has exactly one open session). When every outcome is met, the reply's `nudges.readyToClose` says so: grade, then close. `synap_get_session`'s continuation carries the `goal` (end state, criteria marks, KPI), the `siblings` (parallel, before, next) and the `workUnits` (your recorded PRs and their state).
31
- - **Keep the books: end what you started.** `orient`'s `startHere.looseEnds` lists YOUR leftovers — sessions you opened, idle over a week; asks you left owed by the person on sessions you ended; your proposals pending over a week; automations you made that never fired — each row with the call that ends it (`close`). Close your own idle session when no person touched it and it owes the person nothing. Otherwise withdraw its asks (`retireOutput`, the person confirms) or hand them over in its room first. A close that leaves asks with the person returns `leftOwed`: only a cancel retires them, so withdraw or hand over each one — never leave one owed without saying so.
31
+ - **Keep the books: end what you started.** `orient`'s `startHere.looseEnds` lists YOUR leftovers — sessions you opened, idle over a week; asks you left owed by the person on sessions you ended; your proposals pending over a week; automations you made that never fired — each row with the call that ends it (`close`). Close your own idle session when no person touched it and it owes the person nothing. Archive an automation you made that never ran (`automation.archive`): it applies at once; archiving anyone else's, or one that ran, is a proposal. Otherwise withdraw its asks (`retireOutput`, the person confirms) or hand them over in its room first. A close that leaves asks with the person returns `leftOwed`: only a cancel retires them, so withdraw or hand over each one — never leave one owed without saying so.
32
32
 
33
33
  **Hub Protocol REST** (for IS → backend; always include `workspaceId`):
34
34
 
@@ -72,7 +72,7 @@ Note: all hub-protocol writes are governance-gated server-side — a start may c
72
72
  **Asking the person.** On an `owner: 'human'` slot, add an `ask` so they answer in one tap instead of typing:
73
73
 
74
74
  - **Say it once.** The `label` is a short key (a few words: "Stripe account"), never the question and never "Decide: …". The `prompt` (confirm) or the options (choose) carry the question. `why` adds only what neither says: the fact that makes it matter, never a repeat of the label or prompt. Give each answer its consequence, and recommend one when you have a view. The person reads this card once and decides.
75
- - `confirm` — yes/no: `prompt` is the question; `yes` / `no` may each carry a one-line `description` of what that answer does, and ONE may be `recommended`. `choose` — 1–8 `options` (`label`, optional `value` and a one-line `description` of the consequence, at most ONE `recommended`; `allowOther: true` also takes free text). `form` — a small flat form (never a secret field). `act` — something to DO: an http(s) `url` and up to 7 `steps`. `provide` — a `connection`, `file` or `secret` handed over through the vault (you receive a reference, never the secret in the answer). A secret you asked for comes with a read for you alone, for 60 minutes: redeem the `vault://` ref (`POST /vault/redeem`). If the receipt says no agent can read it, ask for access through `POST /vault/request`.
75
+ - `confirm` — yes/no: `prompt` is the question; `yes` / `no` may each carry a one-line `description` of what that answer does, and ONE may be `recommended`. `choose` — 1–8 `options` (`label`, optional `value` and a one-line `description` of the consequence, at most ONE `recommended`; the person can always answer in their own words instead; `allowOther: false` closes that, only for a choice code reads as a value). `form` — a small flat form (never a secret field). `act` — something to DO: an http(s) `url` and up to 7 `steps`. `provide` — a `connection`, `file` or `secret` handed over through the vault (you receive a reference, never the secret in the answer). A secret you asked for comes with a read for you alone, for 60 minutes: redeem the `vault://` ref (`POST /vault/redeem`). If the receipt says no agent can read it, ask for access through `POST /vault/request`.
76
76
  - **Which mode.** A DECISION is `confirm` (one yes/no) or `choose` — never `act`. When you have a view, mark exactly ONE answer `recommended` (a choose option, or a confirm's `yes` / `no`): the person's pick vs your recommendation is recorded, and every answered `confirm`/`choose` files a `decision` entity automatically. Recall past decisions first (`synap_ask`) so your recommendation follows the user's past choices. Use `act` ONLY for a physical/world task with `steps` (they answer "I did this"). Always add an `ask`: a human-owned slot with only `blockedReason` + `why` shows a bare "I did this" button. Example: `ask: {"mode":"choose","options":[{"label":"Ship now","recommended":true,"description":"Publishes today"},{"label":"Wait a week"}]}`, or `ask: {"mode":"confirm","prompt":"Publish the post today?","yes":{"description":"Goes live at 9:00","recommended":true},"no":{"description":"Stays a draft"}}`.
77
77
  - **How it comes back.** `act` is resolved by "I did this" (attest): the slot is done and you are woken. Every other mode goes through the answer door: the slot comes back to you with `answer.text` (a readable summary) and `answer.value`, the typed pick (`confirm` → `confirmed`, `chip` → the option, `form` → `values`, `provide` → `ref`, `text`). Act on `answer.value`, not the prose. A plain reply in the room answers a typed slot only when the ask takes text (`choose` with `allowOther`); otherwise it answers your question and the slot stays owed.
78
78
  - **Then wait — don't end your turn.** After an ask, call `wait_for_answer` with the `sessionId` (when your tools list it; an in-app agent has no such tool, the answer wakes it): it returns the moment the person answers (`status: 'answered'`, `answers[]` with `text` and the typed `value`) or after `timeoutSeconds` (default 50, max 90; Codex: 55 or less) with `status: 'timeout'` and `nextSince` — call again with `since = nextSince` to keep waiting. Without `since` you get only answers you have not picked up yet. Your read marks the answer "Picked up" for the person. If you must stop, the answer stays on the slot for your next turn.
@@ -36,7 +36,7 @@ If a close project exists, **reuse it**. Do not mint a twin. Name-match is enoug
36
36
 
37
37
  4. `synap_start_session` — **name the unit of work before you build it.** Title + goal, nothing else; the session is the room the rest of this happens in, not a form to fill. Every write you make afterwards is attributed to it automatically, so the user can open ONE object and see the whole arc instead of loose proposals with no shared story. Reuse an open session that already covers this intent (`synap_list_sessions`) rather than starting a second one. If the intent is a single fact with no structure behind it, skip the session and use the `synap` skill instead — this whole conductor is the wrong door for that.
38
38
 
39
- **Propose its `criteria` — do not grade yourself without them.** Two to five binary, observable statements the person can validate or rewrite ("`list_profiles` returns the `grp-run` kind"), not "the pack is good". They may equally be written by the person; what is not allowed is neither. A session with no criteria leaves you nothing to report against but your own opinion, which is how "85% complete" gets said about work nobody can check. Criteria are declarable at `synap_start_session` (as `outcomes` with `kind: 'fact'`, or the older `criteria`) and upserted later with `synap_update_session` — a session created inside a plan carries `expectedOutputs`, not criteria, so set them on the session once it exists.
39
+ **Propose its `criteria` — do not grade yourself without them.** Two to five binary, observable statements the person can validate or rewrite ("`list_profiles` returns the `grp-run` kind"), not "the pack is good". They may equally be written by the person; what is not allowed is neither. A session with no criteria leaves you nothing to report against but your own opinion, which is how "85% complete" gets said about work nobody can check. Criteria are declarable at `synap_start_session` (as `outcomes` with `kind: 'fact'`, or the older `criteria`) and upserted later with `synap_update_session` — a session created inside a plan (`synap_capture` `sessions[]`) carries both: give each step its `criteria` with its `expectedOutputs`, and they land when the plan is approved.
40
40
 
41
41
  **A discovered prerequisite is a blocking child, not a paragraph in the same session.** When the goal cannot be finished until infrastructure exists, start that infrastructure as its own session: `parentSessionId` of the goal session, plus `suspendedIntent` — one line naming what the goal was about to do. That pair links the child (`spawned_from`) and blocks the parent (`blocked_by` the child). Work the child. Do not keep building the parent goal beside it. The parent stays open and waits; when the child is validated and closed, the parent unblocks and `suspendedIntent` is what you resume. A child that is only a slice of the same goal passes `parentSessionId` alone and does not block the parent.
42
42
 
@@ -120,7 +120,7 @@ A **goal** is a _track_ in every tool and field name (`synap_start_track`, `trac
120
120
  | new **kinds of things** no workspace owns | a workspace (four-test, `workspace-design`) — never to represent a goal |
121
121
  | a new long-lived commitment with its own gravity | a project — never a twin project for a goal of an existing one |
122
122
 
123
- **A goal steers; its sessions verify.** A session that passes a criterion CLAIMS it; the judge accepts or sends it back — never accept your own claim. Report a lasting goal's number with `synap_update_track` `kpi: { current }`: a STATED value, stamped with when and by whom — never invent a measurement. Reaching the target nudges the person to re-aim it or close the goal; never change the target or close the goal yourself. While a goal is active, its agent may work in the spaces its project links (`synap_project_use_workspace`); pausing it suspends that, closing or dropping it ends it. Pause, resume, close (`completed` + a `verdict`) or drop (`archived`, with a `verdict` saying why) it with `synap_set_track_status`; your close is a proposal the person approves. Goal writes are governed: `proposed` is success. Installing a pack onto a project does **not** start goals — start each one.
123
+ **A goal steers; its sessions verify.** A session that passes a criterion CLAIMS it; the judge accepts or sends it back — never accept your own claim. Report a lasting goal's number with `synap_update_track` `kpi: { current }`: a STATED value, stamped with when and by whom — never invent a measurement. Reaching the target nudges the person to re-aim it or close the goal; never change the target or close the goal yourself. While a goal is active, its agent may work in the spaces its project links (`synap_project_use_workspace`); pausing it suspends that, closing or dropping it ends it. Pause, resume, close (`completed` + a `verdict`) or drop (`archived`, with a `verdict` saying why) it with `synap_set_track_status`, sending `expectedStatus` = the status you read (`conflict` = someone moved it: re-read, decide again); your close is a proposal the person approves. Goal writes are governed: `proposed` is success. Installing a pack onto a project does **not** start goals — start each one.
124
124
 
125
125
  **Legacy: goals with steps.** A goal started from a goal template (`scope: "project"`, `playbookId` on `synap_start_track`) has re-enterable stages. Work a stage with `synap_start_stage_session` (`trackId`, optional `stageKey`); never `synap_advance_track` without the user — advancing returns an `offer` (show it, start it only on a yes). Do not create new goal templates; a new goal needs none.
126
126
 
@@ -8,6 +8,8 @@ Every write returns a `status` field:
8
8
  "denied" → blocked, explain reason to user
9
9
  ```
10
10
 
11
+ **`DENIED_BY_RULE` is a person's "Never".** A refusal whose reason opens with `DENIED_BY_RULE` (a write's `reason`, a run's `reasonCode`) means the person said never for this agent and this kind of act. It was not done. Do not retry it or do it another way; ask the person if it is needed. Only a pod admin can take that back, in pod admin Settings.
12
+
11
13
  **`"proposed"` is not an error.** It's the governance system queueing your change. When you get it:
12
14
 
13
15
  1. Tell the user exactly what was queued — use the `summary` field **verbatim**. Don't paraphrase.
@@ -4,13 +4,13 @@
4
4
 
5
5
  The user's Synap pod: source of truth. Tool names below are stems; your door may prefix them (`pod__ask`).
6
6
 
7
- 1. **Recall first.** Before answering or creating, `ask`.
8
- 2. **Capture after.** A durable fact, decision, person, task: `capture`; about the user: `remember_fact`. No private scratchpad.
9
- 3. **Orient once.** `orient`: pending review (raise first), open sessions.
7
+ 1. **Recall first.** `get_*` a known id, else `ask`.
8
+ 2. **Capture as you go.** A decision, learning, pain (`finding`), win (`proof-point`), fact or task: `capture` it when it happens; about the user: `remember_fact`.
9
+ 3. **Orient once.** `orient`: pending review, open sessions.
10
10
  4. **Work in a session.** `start_session` or resume (playbook `templateId`); goal (TRACK): `list_tracks`, else `start_track`; work in it = `start_session` + `trackId`; 2-5 `criteria`; status moves carry `expectedStatus`; person-only: `owner:'human'` slot + `blockedReason` + `ask` (confirm/choose with 1 `recommended`/form/act/provide), then `wait_for_answer` if listed; post progress, questions and results in its room (`post_message` to `session.channelId`); your own chat may repeat them (`Q-<id8>`); chat answer → `relay_answer`, words verbatim; PR = outcome `pr-<repo>-<n>` (`ref.url`); `evaluate_session`, close open asks, `complete_session`.
11
11
  5. **Never guess a project**: pin only what the user names (`set_*_focus`).
12
12
  6. **`proposed` is success**: keep going, never retry.
13
- 7. **Discover before inventing**: `list_profiles` / `list_capabilities`; **extend** (facet, overlay, parent), never a twin.
13
+ 7. **Discover before inventing**: `list_profiles` / `list_capabilities`; **extend**, never a twin.
14
14
  8. **One space per domain**; projects filter it (`file_into_project`, `project_use_workspace`).
15
15
 
16
16
  Depth: `load_skill` `system/synap/concepts`, `work-model`, `focus-sessions`, `from-intent`, `escalation-ladder`, `writes`.
@@ -53,7 +53,7 @@ A worker is a playbook **activator**, declared on the method and owned by the li
53
53
 
54
54
  ### Goals (tracks)
55
55
 
56
- A goal is a _track_ in every tool and field name (`start_track`, `trackId`) — say "goal" to the person; a session's one-line `goal` is its **Aim**. A goal holds an owner, a direction, instructions, the workers it turns on, and what done means (criteria, or a number measured as transitions into `done`). It has no stages. A goal can stay open as long as it matters, or finish: a person closes it with a verdict once its criteria are met (`set_track_status` `completed` + `verdict`; dropped = `archived`, with a `verdict` saying why). Your close is a proposal; a closed goal comes back only as a new version. Pause it while nobody should work on it. Work in it = `start_session` + `trackId`. A thing may count for two goals. Solo users may never need one: workers can run space-wide. Legacy: `start_stage_session` and `add_track_stage` serve old goals started from a method; never `advance_track` without the user.
56
+ A goal is a _track_ in every tool and field name (`start_track`, `trackId`) — say "goal" to the person; a session's one-line `goal` is its **Aim**. A goal holds an owner, a direction, instructions, the workers it turns on, and what done means (criteria, or a number measured as transitions into `done`). It has no stages. A goal can stay open as long as it matters, or finish: a person closes it with a verdict once its criteria are met (`set_track_status` `completed` + `verdict`; dropped = `archived`, with a `verdict` saying why; every move sends `expectedStatus`, the status you read). Your close is a proposal; a closed goal comes back only as a new version. Pause it while nobody should work on it. Work in it = `start_session` + `trackId`. A thing may count for two goals. Solo users may never need one: workers can run space-wide. Legacy: `start_stage_session` and `add_track_stage` serve old goals started from a method; never `advance_track` without the user.
57
57
 
58
58
  **Keep the pod current (every agent, every session)** — three rules, so the next agent picks your step up from the pod alone:
59
59
 
@@ -61,3 +61,10 @@ claim cut off. Everything else goes elsewhere:
61
61
 
62
62
  When unsure, ask: "will this still help someone in three months, and is it a
63
63
  fact, a pitfall or a rule?" If not, it is not knowledge.
64
+
65
+ ### Descriptions of projects, spaces and goals
66
+
67
+ A description says what the thing **is** and who it is for. A decision is
68
+ **linked, never restated**: a restated decision goes stale the day the decision
69
+ changes (the Synap project description repeated the 5 Oct branding split, which
70
+ a 13 Oct decision replaced). Link the `decision` entity; let it carry the rule.
@@ -65,8 +65,8 @@ Pin `@^1.0.0` on `sdk`/`react` so you never resolve an old, abandoned `0.x`.
65
65
  needed, fetches the release bundle, checks it against the release manifest's
66
66
  sha256 and runs `synap install`); see the backend's `deploy/README.md`. It
67
67
  also checks the manifest's signature: by default
68
- (`SYNAP_RELEASE_VERIFY=warn`) it only warns and carries on when the signature
69
- is missing or does not verify; `SYNAP_RELEASE_VERIFY=enforce` refuses.
68
+ (`SYNAP_RELEASE_VERIFY=enforce`) it refuses a release whose signature is
69
+ missing or does not verify; `SYNAP_RELEASE_VERIFY=warn` only warns.
70
70
  - **Managed (paid):** sign up at synap.live and provision a pod.
71
71
 
72
72
  You can develop the base app with **no pod at all** using its mock mode
@@ -42,8 +42,8 @@ Pin `@^1.0.0` on `sdk`/`react` so you never resolve an old, abandoned `0.x`.
42
42
  needed, fetches the release bundle, checks it against the release manifest's
43
43
  sha256 and runs `synap install`); see the backend's `deploy/README.md`. It
44
44
  also checks the manifest's signature: by default
45
- (`SYNAP_RELEASE_VERIFY=warn`) it only warns and carries on when the signature
46
- is missing or does not verify; `SYNAP_RELEASE_VERIFY=enforce` refuses.
45
+ (`SYNAP_RELEASE_VERIFY=enforce`) it refuses a release whose signature is
46
+ missing or does not verify; `SYNAP_RELEASE_VERIFY=warn` only warns.
47
47
  - **Managed (paid):** sign up at synap.live and provision a pod.
48
48
 
49
49
  You can develop the base app with **no pod at all** using its mock mode
@@ -622,4 +622,4 @@ wired at every install site). The browser UI is **display-only**: it threads
622
622
  `requiredTier` through to a "requires <tier>" badge but does NOT hard-block, and
623
623
  its lock/upgrade CTA only engages once a host wires a billing destination — so
624
624
  don't add a UI-side gate expecting it to enforce anything, and don't rebuild the
625
- badge thread (it exists). Full current-state: repo `TEMPLATE-DEV-GUIDE.md`.
625
+ badge thread (it exists). Full current-state: the catalog README (`synap-app/packages/workspace-templates/README.md`).
@@ -60,4 +60,4 @@ wired at every install site). The browser UI is **display-only**: it threads
60
60
  `requiredTier` through to a "requires <tier>" badge but does NOT hard-block, and
61
61
  its lock/upgrade CTA only engages once a host wires a billing destination — so
62
62
  don't add a UI-side gate expecting it to enforce anything, and don't rebuild the
63
- badge thread (it exists). Full current-state: repo `TEMPLATE-DEV-GUIDE.md`.
63
+ badge thread (it exists). Full current-state: the catalog README (`synap-app/packages/workspace-templates/README.md`).
@@ -404,7 +404,10 @@ a package that consumes nothing would go stale in the one direction that is invi
404
404
  consumers typecheck against the built `dist/`, so a skipped rebuild makes your gate lie.
405
405
  Post-seed rows today: `publish_post` (0284, write), `delegate_agent_task`
406
406
  (0314, act — every verb of an external-agent binding, `tools.config.agentBinding`:
407
- start / send / status / cancel) and `read_webpage` (0329).
407
+ start / send / status / cancel), `read_webpage` (0329, read), `search_web`
408
+ (0360, read) and `edit_video` (0370, act — sends the person's video to an
409
+ outside service; its one input, `{ video }`, is seeded on `input_schema` in
410
+ the same file).
408
411
  3. **Add it to mirror 2** — the same two lists in the control plane's
409
412
  `capability-intent-vocabulary.ts`.
410
413
  4. **Update the arity floors** — `SEED_SLUG_ARITY` / `EXTRA_SLUG_ARITY` in
@@ -87,7 +87,10 @@ a package that consumes nothing would go stale in the one direction that is invi
87
87
  consumers typecheck against the built `dist/`, so a skipped rebuild makes your gate lie.
88
88
  Post-seed rows today: `publish_post` (0284, write), `delegate_agent_task`
89
89
  (0314, act — every verb of an external-agent binding, `tools.config.agentBinding`:
90
- start / send / status / cancel) and `read_webpage` (0329).
90
+ start / send / status / cancel), `read_webpage` (0329, read), `search_web`
91
+ (0360, read) and `edit_video` (0370, act — sends the person's video to an
92
+ outside service; its one input, `{ video }`, is seeded on `input_schema` in
93
+ the same file).
91
94
  3. **Add it to mirror 2** — the same two lists in the control plane's
92
95
  `capability-intent-vocabulary.ts`.
93
96
  4. **Update the arity floors** — `SEED_SLUG_ARITY` / `EXTRA_SLUG_ARITY` in
@@ -1,42 +0,0 @@
1
- /**
2
- * `synap template` — the "one request" template surface (TEMPLATE-ONE-PATH-PLAN §3-4).
3
- * =====================================================================================
4
- *
5
- * The plan names ONE governed write door for adding/updating a workspace template:
6
- * `synap template publish <file>` → CP `POST /api/packages` (validated server-side).
7
- * No npm publish, no lockfile-bump, no redeploy. This file is that named surface.
8
- *
9
- * synap template publish <file> — validate + upsert to the CP (private by default; --public to share)
10
- * synap template publish --from-workspace <id> — serialize a LIVE workspace, then publish
11
- * synap template list — the caller-visible catalog (own private + public), slug/name/vis/version
12
- * synap template get <slug> — one template's metadata + definition shape
13
- *
14
- * REUSE, no reinvention: publish delegates to the existing `marketPublish` (same
15
- * validator, same CP transport). list/get read through `lib/cp-packages` — the ONE
16
- * authed CP `/api/packages` client (Bearer from `lib/auth`'s stored login token).
17
- * No `fetch` is hand-rolled here.
18
- *
19
- * NOTE (for the orchestrator): this overlaps `synap market publish/validate/
20
- * unpublish`, which already ship the same authoring loop. `synap template` is the
21
- * plan-canonical name; picking one and retiring/aliasing the other is a §4 Wave 2
22
- * cleanup decision, not made here.
23
- */
24
- /**
25
- * `synap template publish <file>` — the plan's "one request". A thin alias over
26
- * the existing `marketPublish` so there is exactly ONE publish implementation
27
- * (same validator, same CP write door, same `--public`/`--from-workspace`/`--json`).
28
- */
29
- export declare function templatePublish(file: string | undefined, opts: {
30
- public?: boolean;
31
- private?: boolean;
32
- fromWorkspace?: string;
33
- json?: boolean;
34
- podUrl?: string;
35
- apiKey?: string;
36
- }): Promise<void>;
37
- export declare function templateList(opts: {
38
- json?: boolean;
39
- }): Promise<void>;
40
- export declare function templateGet(slug: string, opts: {
41
- json?: boolean;
42
- }): Promise<void>;
@@ -1,191 +0,0 @@
1
- /**
2
- * `synap template` — the "one request" template surface (TEMPLATE-ONE-PATH-PLAN §3-4).
3
- * =====================================================================================
4
- *
5
- * The plan names ONE governed write door for adding/updating a workspace template:
6
- * `synap template publish <file>` → CP `POST /api/packages` (validated server-side).
7
- * No npm publish, no lockfile-bump, no redeploy. This file is that named surface.
8
- *
9
- * synap template publish <file> — validate + upsert to the CP (private by default; --public to share)
10
- * synap template publish --from-workspace <id> — serialize a LIVE workspace, then publish
11
- * synap template list — the caller-visible catalog (own private + public), slug/name/vis/version
12
- * synap template get <slug> — one template's metadata + definition shape
13
- *
14
- * REUSE, no reinvention: publish delegates to the existing `marketPublish` (same
15
- * validator, same CP transport). list/get read through `lib/cp-packages` — the ONE
16
- * authed CP `/api/packages` client (Bearer from `lib/auth`'s stored login token).
17
- * No `fetch` is hand-rolled here.
18
- *
19
- * NOTE (for the orchestrator): this overlaps `synap market publish/validate/
20
- * unpublish`, which already ship the same authoring loop. `synap template` is the
21
- * plan-canonical name; picking one and retiring/aliasing the other is a §4 Wave 2
22
- * cleanup decision, not made here.
23
- */
24
- import chalk from "chalk";
25
- import { log } from "../utils/logger.js";
26
- import { getStoredToken, isTokenLocallyExpired } from "../lib/auth.js";
27
- import { fetchMyRows, fetchPublicBrowseRows, fetchPackageDefinition, } from "../lib/cp-packages.js";
28
- // ─── publish ─────────────────────────────────────────────────────────────────
29
- /**
30
- * `synap template publish <file>` — the plan's "one request". A thin alias over
31
- * the existing `marketPublish` so there is exactly ONE publish implementation
32
- * (same validator, same CP write door, same `--public`/`--from-workspace`/`--json`).
33
- */
34
- export async function templatePublish(file, opts) {
35
- const { marketPublish } = await import("./market-authoring.js");
36
- await marketPublish(file, opts);
37
- }
38
- /** private/public/unknown → a short colored label. */
39
- function visLabel(isPublic) {
40
- if (isPublic === false)
41
- return chalk.yellow("private");
42
- if (isPublic === true)
43
- return chalk.green("public");
44
- return chalk.dim("public");
45
- }
46
- /**
47
- * Fetch the caller-visible catalog: the caller's own rows (incl. private) when
48
- * logged in, merged with the public browse rows. `/mine` wins a slug tie so the
49
- * real `isPublic` flag and owned marker survive.
50
- */
51
- async function fetchCatalog() {
52
- const creds = getStoredToken();
53
- const loggedIn = !!creds && !isTokenLocallyExpired(creds);
54
- const filters = { category: "workspace" };
55
- // Public browse is best-effort — a private catalog that resolves is still useful.
56
- const publicRows = await fetchPublicBrowseRows(filters).catch(() => []);
57
- const bySlug = new Map();
58
- for (const r of publicRows) {
59
- bySlug.set(r.slug, {
60
- slug: r.slug,
61
- displayName: r.displayName,
62
- description: r.description,
63
- version: r.version,
64
- isPublic: true,
65
- owned: false,
66
- });
67
- }
68
- if (loggedIn) {
69
- const mineRows = await fetchMyRows(creds.token, filters);
70
- for (const r of mineRows) {
71
- bySlug.set(r.slug, {
72
- slug: r.slug,
73
- displayName: r.displayName,
74
- description: r.description,
75
- version: r.version,
76
- isPublic: r.isPublic,
77
- owned: true,
78
- });
79
- }
80
- }
81
- const rows = [...bySlug.values()].sort((a, b) => a.slug.localeCompare(b.slug));
82
- return { rows, loggedIn };
83
- }
84
- export async function templateList(opts) {
85
- let catalog;
86
- try {
87
- catalog = await fetchCatalog();
88
- }
89
- catch (e) {
90
- if (opts.json) {
91
- console.log(JSON.stringify({ ok: false, error: e.message }, null, 2));
92
- }
93
- else {
94
- log.error(`Could not list templates: ${e.message}`);
95
- log.hint("Log in for your private templates: synap login");
96
- }
97
- process.exit(1);
98
- }
99
- if (opts.json) {
100
- console.log(JSON.stringify({ ok: true, loggedIn: catalog.loggedIn, templates: catalog.rows }, null, 2));
101
- return;
102
- }
103
- if (catalog.rows.length === 0) {
104
- log.info("No templates visible.");
105
- if (!catalog.loggedIn)
106
- log.hint("Your private templates are hidden until you log in: synap login");
107
- return;
108
- }
109
- log.heading(`Templates (${catalog.rows.length})`);
110
- if (!catalog.loggedIn)
111
- log.dim("Logged out — showing public templates only. `synap login` to see your private ones.");
112
- log.blank();
113
- for (const r of catalog.rows) {
114
- const ver = r.version ? chalk.dim(` ${r.version}`) : "";
115
- const owned = r.owned ? chalk.dim(" (yours)") : "";
116
- console.log(` ${chalk.bold(r.slug)}${ver} ${visLabel(r.isPublic)}${owned}`);
117
- console.log(` ${chalk.cyan(r.displayName)}${r.description ? chalk.dim(` ${r.description}`) : ""}`);
118
- }
119
- log.blank();
120
- log.dim("Publish a template: synap template publish <file>");
121
- log.dim("Inspect one: synap template get <slug>");
122
- }
123
- // ─── get ─────────────────────────────────────────────────────────────────────
124
- export async function templateGet(slug, opts) {
125
- const creds = getStoredToken();
126
- const token = creds && !isTokenLocallyExpired(creds) ? creds.token : undefined;
127
- // Metadata: prefer the caller's own row (carries isPublic + version), else the
128
- // public browse row for this slug.
129
- let meta;
130
- try {
131
- if (token) {
132
- const mine = await fetchMyRows(token, { category: "workspace", search: slug });
133
- const own = mine.find((r) => r.slug === slug);
134
- if (own) {
135
- meta = { slug: own.slug, displayName: own.displayName, description: own.description, version: own.version, isPublic: own.isPublic, owned: true };
136
- }
137
- }
138
- if (!meta) {
139
- const pub = await fetchPublicBrowseRows({ category: "workspace", search: slug });
140
- const row = pub.find((r) => r.slug === slug);
141
- if (row) {
142
- meta = { slug: row.slug, displayName: row.displayName, description: row.description, version: row.version, isPublic: true, owned: false };
143
- }
144
- }
145
- }
146
- catch (e) {
147
- if (opts.json) {
148
- console.log(JSON.stringify({ ok: false, slug, error: e.message }, null, 2));
149
- }
150
- else {
151
- log.error(`Could not fetch "${slug}": ${e.message}`);
152
- }
153
- process.exit(1);
154
- }
155
- // Full definition (the install payload) — authed so a private template resolves.
156
- const definition = await fetchPackageDefinition(slug, token).catch(() => null);
157
- if (!meta && !definition) {
158
- if (opts.json) {
159
- console.log(JSON.stringify({ ok: false, slug, error: "not found" }, null, 2));
160
- }
161
- else {
162
- log.error(`Template "${slug}" not found or not visible.`);
163
- if (!token)
164
- log.hint("If it is private, log in first: synap login");
165
- }
166
- process.exit(1);
167
- }
168
- if (opts.json) {
169
- console.log(JSON.stringify({ ok: true, slug, ...meta, definition }, null, 2));
170
- return;
171
- }
172
- const displayName = meta?.displayName ?? slug;
173
- log.heading(`${displayName} ${chalk.dim(`(${slug})`)}`);
174
- log.blank();
175
- if (meta?.description) {
176
- console.log(` ${meta.description}`);
177
- log.blank();
178
- }
179
- if (meta?.version)
180
- console.log(` ${chalk.dim("version:")} ${meta.version}`);
181
- console.log(` ${chalk.dim("visibility:")} ${visLabel(meta?.isPublic)}${meta?.owned ? chalk.dim(" (yours)") : ""}`);
182
- const def = definition;
183
- if (def) {
184
- const count = (v) => (Array.isArray(v) ? v.length : 0);
185
- console.log(` ${chalk.dim("profiles:")} ${count(def.profiles)}`);
186
- console.log(` ${chalk.dim("views:")} ${count(def.views)}`);
187
- }
188
- log.blank();
189
- log.dim(`Install it: synap market install ${slug}`);
190
- }
191
- //# sourceMappingURL=template.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"template.js","sourceRoot":"","sources":["../../src/commands/template.ts"],"names":[],"mappings":"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"}
@@ -1,35 +0,0 @@
1
- /**
2
- * Browser-based connect flow — the recommended provisioning path.
3
- *
4
- * 1. Start a local HTTP server on an ephemeral port.
5
- * 2. Build `{podUrl}/admin/connect?integration=cli&redirect_uri=http://127.0.0.1:<port>/callback`.
6
- * 3. Open the user's default browser at that URL.
7
- * 4. Admin UI authenticates the user (Kratos session), mints a scoped Hub
8
- * Protocol API key via `trpc.apiKeys.connectIntegration`, and redirects
9
- * to `http://127.0.0.1:<port>/callback?context={apiKey,podUrl,workspaceId}`.
10
- * 5. Local server receives the callback, extracts credentials, shuts down.
11
- *
12
- * This is the same flow Raycast uses (via a `raycast://` deeplink) — for CLI
13
- * we just swap the deeplink for a loopback HTTP URL. The admin UI's redirect
14
- * whitelist accepts both.
15
- *
16
- * Security notes:
17
- * - Loopback only (127.0.0.1) — no external network can intercept.
18
- * - One-shot: server only handles the first /callback, then exits.
19
- * - 5-minute timeout.
20
- * - No CSRF token: single-use, host-local, bound to the process.
21
- */
22
- export interface BrowserAuthResult {
23
- apiKey: string;
24
- podUrl: string;
25
- workspaceId?: string;
26
- }
27
- export interface BrowserAuthOptions {
28
- podUrl: string;
29
- integration: "cli" | "raycast" | "openclaw" | "custom";
30
- /** Milliseconds to wait for the callback. Default 5min. */
31
- timeoutMs?: number;
32
- /** Hook invoked with the admin-panel URL right before opening the browser. */
33
- onUrlReady?: (url: string) => void;
34
- }
35
- export declare function runBrowserAuth(opts: BrowserAuthOptions): Promise<BrowserAuthResult>;