@synap-core/cli 1.11.0 → 1.12.2

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 (452) hide show
  1. package/README.md +23 -198
  2. package/dist/build-info.json +6 -0
  3. package/dist/commands/agent-run.js +3 -2
  4. package/dist/commands/agent-run.js.map +1 -1
  5. package/dist/commands/agents.d.ts +33 -17
  6. package/dist/commands/agents.js +203 -237
  7. package/dist/commands/agents.js.map +1 -1
  8. package/dist/commands/app.d.ts +143 -0
  9. package/dist/commands/app.js +523 -0
  10. package/dist/commands/app.js.map +1 -0
  11. package/dist/commands/automate.d.ts +21 -0
  12. package/dist/commands/automate.js +42 -0
  13. package/dist/commands/automate.js.map +1 -0
  14. package/dist/commands/automation-schema.test.d.ts +16 -0
  15. package/dist/commands/automation-schema.test.js +77 -0
  16. package/dist/commands/automation-schema.test.js.map +1 -0
  17. package/dist/commands/automation.d.ts +12 -0
  18. package/dist/commands/automation.js +80 -35
  19. package/dist/commands/automation.js.map +1 -1
  20. package/dist/commands/bridge-setup.d.ts +14 -1
  21. package/dist/commands/bridge-setup.js +392 -128
  22. package/dist/commands/bridge-setup.js.map +1 -1
  23. package/dist/commands/cap-connections.d.ts +4 -4
  24. package/dist/commands/cap-connections.js +14 -14
  25. package/dist/commands/cap-connections.js.map +1 -1
  26. package/dist/commands/capability.d.ts +2 -0
  27. package/dist/commands/capability.js +218 -168
  28. package/dist/commands/capability.js.map +1 -1
  29. package/dist/commands/catalog.d.ts +275 -0
  30. package/dist/commands/catalog.js +481 -0
  31. package/dist/commands/catalog.js.map +1 -0
  32. package/dist/commands/cell.d.ts +155 -8
  33. package/dist/commands/cell.js +416 -40
  34. package/dist/commands/cell.js.map +1 -1
  35. package/dist/commands/centrality.js +1 -13
  36. package/dist/commands/centrality.js.map +1 -1
  37. package/dist/commands/connect.d.ts +38 -13
  38. package/dist/commands/connect.js +68 -167
  39. package/dist/commands/connect.js.map +1 -1
  40. package/dist/commands/connections.d.ts +3 -2
  41. package/dist/commands/connections.js +95 -25
  42. package/dist/commands/connections.js.map +1 -1
  43. package/dist/commands/context.js +7 -1
  44. package/dist/commands/context.js.map +1 -1
  45. package/dist/commands/data-extra.d.ts +34 -0
  46. package/dist/commands/data-extra.js +193 -23
  47. package/dist/commands/data-extra.js.map +1 -1
  48. package/dist/commands/data.d.ts +120 -2
  49. package/dist/commands/data.js +293 -20
  50. package/dist/commands/data.js.map +1 -1
  51. package/dist/commands/diagnose.d.ts +66 -4
  52. package/dist/commands/diagnose.js +285 -28
  53. package/dist/commands/diagnose.js.map +1 -1
  54. package/dist/commands/doc.d.ts +11 -4
  55. package/dist/commands/doc.js +39 -14
  56. package/dist/commands/doc.js.map +1 -1
  57. package/dist/commands/doctor.d.ts +112 -3
  58. package/dist/commands/doctor.js +657 -32
  59. package/dist/commands/doctor.js.map +1 -1
  60. package/dist/commands/explain.js +5 -5
  61. package/dist/commands/explain.js.map +1 -1
  62. package/dist/commands/import.d.ts +368 -13
  63. package/dist/commands/import.js +1064 -54
  64. package/dist/commands/import.js.map +1 -1
  65. package/dist/commands/init.d.ts +20 -9
  66. package/dist/commands/init.js +433 -973
  67. package/dist/commands/init.js.map +1 -1
  68. package/dist/commands/keys.d.ts +1 -0
  69. package/dist/commands/keys.js +15 -2
  70. package/dist/commands/keys.js.map +1 -1
  71. package/dist/commands/knowledge.d.ts +22 -6
  72. package/dist/commands/knowledge.js +117 -55
  73. package/dist/commands/knowledge.js.map +1 -1
  74. package/dist/commands/lens.d.ts +37 -1
  75. package/dist/commands/lens.js +192 -71
  76. package/dist/commands/lens.js.map +1 -1
  77. package/dist/commands/market-authoring.d.ts +29 -2
  78. package/dist/commands/market-authoring.js +348 -7
  79. package/dist/commands/market-authoring.js.map +1 -1
  80. package/dist/commands/market-official.d.ts +58 -0
  81. package/dist/commands/market-official.js +84 -0
  82. package/dist/commands/market-official.js.map +1 -0
  83. package/dist/commands/market.d.ts +400 -16
  84. package/dist/commands/market.js +1802 -146
  85. package/dist/commands/market.js.map +1 -1
  86. package/dist/commands/mcp.d.ts +60 -25
  87. package/dist/commands/mcp.js +251 -64
  88. package/dist/commands/mcp.js.map +1 -1
  89. package/dist/commands/open.d.ts +39 -9
  90. package/dist/commands/open.js +80 -25
  91. package/dist/commands/open.js.map +1 -1
  92. package/dist/commands/playbook.d.ts +42 -0
  93. package/dist/commands/playbook.js +162 -0
  94. package/dist/commands/playbook.js.map +1 -0
  95. package/dist/commands/pod.js +1 -1
  96. package/dist/commands/pod.js.map +1 -1
  97. package/dist/commands/pods.d.ts +5 -0
  98. package/dist/commands/pods.js +97 -116
  99. package/dist/commands/pods.js.map +1 -1
  100. package/dist/commands/proposals-actions.d.ts +62 -0
  101. package/dist/commands/proposals-actions.js +143 -8
  102. package/dist/commands/proposals-actions.js.map +1 -1
  103. package/dist/commands/proposals-await.d.ts +68 -0
  104. package/dist/commands/proposals-await.js +248 -0
  105. package/dist/commands/proposals-await.js.map +1 -0
  106. package/dist/commands/proton-setup.d.ts +73 -0
  107. package/dist/commands/proton-setup.js +577 -0
  108. package/dist/commands/proton-setup.js.map +1 -0
  109. package/dist/commands/providers.d.ts +23 -0
  110. package/dist/commands/providers.js +126 -1
  111. package/dist/commands/providers.js.map +1 -1
  112. package/dist/commands/raycast.js +6 -2
  113. package/dist/commands/raycast.js.map +1 -1
  114. package/dist/commands/rule.d.ts +150 -0
  115. package/dist/commands/rule.js +447 -0
  116. package/dist/commands/rule.js.map +1 -0
  117. package/dist/commands/session-wait.d.ts +111 -0
  118. package/dist/commands/session-wait.js +209 -0
  119. package/dist/commands/session-wait.js.map +1 -0
  120. package/dist/commands/sessions.d.ts +52 -0
  121. package/dist/commands/sessions.js +478 -58
  122. package/dist/commands/sessions.js.map +1 -1
  123. package/dist/commands/skill-manage.d.ts +21 -0
  124. package/dist/commands/skill-manage.js +136 -19
  125. package/dist/commands/skill-manage.js.map +1 -1
  126. package/dist/commands/skills.js +16 -0
  127. package/dist/commands/skills.js.map +1 -1
  128. package/dist/commands/status.d.ts +1 -4
  129. package/dist/commands/status.js +5 -34
  130. package/dist/commands/status.js.map +1 -1
  131. package/dist/commands/statusline.backoff.test.d.ts +13 -0
  132. package/dist/commands/statusline.backoff.test.js +100 -0
  133. package/dist/commands/statusline.backoff.test.js.map +1 -0
  134. package/dist/commands/statusline.js +16 -9
  135. package/dist/commands/statusline.js.map +1 -1
  136. package/dist/commands/sync-status.d.ts +12 -0
  137. package/dist/commands/sync-status.js +125 -0
  138. package/dist/commands/sync-status.js.map +1 -0
  139. package/dist/commands/templates-retire.d.ts +34 -0
  140. package/dist/commands/templates-retire.js +192 -0
  141. package/dist/commands/templates-retire.js.map +1 -0
  142. package/dist/commands/tools.js +6 -21
  143. package/dist/commands/tools.js.map +1 -1
  144. package/dist/commands/tracks.d.ts +51 -0
  145. package/dist/commands/tracks.js +291 -0
  146. package/dist/commands/tracks.js.map +1 -0
  147. package/dist/commands/update.d.ts +3 -11
  148. package/dist/commands/update.js +5 -134
  149. package/dist/commands/update.js.map +1 -1
  150. package/dist/commands/upload.d.ts +41 -3
  151. package/dist/commands/upload.js +120 -18
  152. package/dist/commands/upload.js.map +1 -1
  153. package/dist/commands/vendor.d.ts +28 -0
  154. package/dist/commands/vendor.js +110 -0
  155. package/dist/commands/vendor.js.map +1 -0
  156. package/dist/commands/versions.js +6 -0
  157. package/dist/commands/versions.js.map +1 -1
  158. package/dist/commands/view.js +10 -5
  159. package/dist/commands/view.js.map +1 -1
  160. package/dist/commands/whoami.d.ts +23 -3
  161. package/dist/commands/whoami.js +169 -23
  162. package/dist/commands/whoami.js.map +1 -1
  163. package/dist/commands/worker.d.ts +122 -0
  164. package/dist/commands/worker.js +435 -0
  165. package/dist/commands/worker.js.map +1 -0
  166. package/dist/commands/worker.test.d.ts +1 -0
  167. package/dist/commands/worker.test.js +116 -0
  168. package/dist/commands/worker.test.js.map +1 -0
  169. package/dist/commands/workspace-ops.d.ts +35 -0
  170. package/dist/commands/workspace-ops.js +153 -0
  171. package/dist/commands/workspace-ops.js.map +1 -0
  172. package/dist/index.d.ts +6 -6
  173. package/dist/index.js +900 -180
  174. package/dist/index.js.map +1 -1
  175. package/dist/lib/agent-connections.d.ts +31 -0
  176. package/dist/lib/agent-connections.js +33 -0
  177. package/dist/lib/agent-connections.js.map +1 -0
  178. package/dist/lib/agent-detect.d.ts +27 -0
  179. package/dist/lib/agent-detect.js +71 -0
  180. package/dist/lib/agent-detect.js.map +1 -0
  181. package/dist/lib/agent-door.d.ts +138 -0
  182. package/dist/lib/agent-door.js +426 -0
  183. package/dist/lib/agent-door.js.map +1 -0
  184. package/dist/lib/agents-config.d.ts +2 -0
  185. package/dist/lib/agents-config.js +4 -9
  186. package/dist/lib/agents-config.js.map +1 -1
  187. package/dist/lib/approval-poll.d.ts +31 -2
  188. package/dist/lib/approval-poll.js +20 -7
  189. package/dist/lib/approval-poll.js.map +1 -1
  190. package/dist/lib/atomic-file.d.ts +48 -0
  191. package/dist/lib/atomic-file.js +129 -0
  192. package/dist/lib/atomic-file.js.map +1 -0
  193. package/dist/lib/auth.d.ts +14 -9
  194. package/dist/lib/auth.js +44 -61
  195. package/dist/lib/auth.js.map +1 -1
  196. package/dist/lib/batch-approval.d.ts +85 -0
  197. package/dist/lib/batch-approval.js +170 -0
  198. package/dist/lib/batch-approval.js.map +1 -0
  199. package/dist/lib/capture-lane.d.ts +6 -5
  200. package/dist/lib/capture-lane.js +6 -5
  201. package/dist/lib/capture-lane.js.map +1 -1
  202. package/dist/lib/capture-structure.d.ts +230 -11
  203. package/dist/lib/capture-structure.js +251 -13
  204. package/dist/lib/capture-structure.js.map +1 -1
  205. package/dist/lib/catalog-templates.d.ts +59 -0
  206. package/dist/lib/catalog-templates.js +126 -0
  207. package/dist/lib/catalog-templates.js.map +1 -0
  208. package/dist/lib/cli-build.d.ts +19 -0
  209. package/dist/lib/cli-build.js +37 -0
  210. package/dist/lib/cli-build.js.map +1 -0
  211. package/dist/lib/conversation-headers.d.ts +18 -0
  212. package/dist/lib/conversation-headers.js +32 -0
  213. package/dist/lib/conversation-headers.js.map +1 -0
  214. package/dist/lib/cp-packages.d.ts +167 -11
  215. package/dist/lib/cp-packages.js +253 -21
  216. package/dist/lib/cp-packages.js.map +1 -1
  217. package/dist/lib/credential-class.d.ts +117 -0
  218. package/dist/lib/credential-class.js +116 -0
  219. package/dist/lib/credential-class.js.map +1 -0
  220. package/dist/lib/describe-lens.d.ts +35 -0
  221. package/dist/lib/describe-lens.js +40 -0
  222. package/dist/lib/describe-lens.js.map +1 -1
  223. package/dist/lib/device-connect.d.ts +125 -0
  224. package/dist/lib/device-connect.js +256 -0
  225. package/dist/lib/device-connect.js.map +1 -0
  226. package/dist/lib/directory-lens.d.ts +99 -0
  227. package/dist/lib/directory-lens.js +187 -0
  228. package/dist/lib/directory-lens.js.map +1 -0
  229. package/dist/lib/exporter-coverage.d.ts +71 -0
  230. package/dist/lib/exporter-coverage.js +97 -0
  231. package/dist/lib/exporter-coverage.js.map +1 -0
  232. package/dist/lib/hub-client.d.ts +29 -8
  233. package/dist/lib/hub-client.js +328 -55
  234. package/dist/lib/hub-client.js.map +1 -1
  235. package/dist/lib/init-connect.d.ts +41 -0
  236. package/dist/lib/init-connect.js +75 -0
  237. package/dist/lib/init-connect.js.map +1 -0
  238. package/dist/lib/init-exit.d.ts +24 -0
  239. package/dist/lib/init-exit.js +41 -0
  240. package/dist/lib/init-exit.js.map +1 -0
  241. package/dist/lib/init-flow.d.ts +25 -0
  242. package/dist/lib/init-flow.js +40 -0
  243. package/dist/lib/init-flow.js.map +1 -0
  244. package/dist/lib/init-handoff.d.ts +16 -0
  245. package/dist/lib/init-handoff.js +19 -0
  246. package/dist/lib/init-handoff.js.map +1 -0
  247. package/dist/lib/init-output.d.ts +18 -0
  248. package/dist/lib/init-output.js +43 -0
  249. package/dist/lib/init-output.js.map +1 -0
  250. package/dist/lib/init-pod.d.ts +45 -0
  251. package/dist/lib/init-pod.js +36 -0
  252. package/dist/lib/init-pod.js.map +1 -0
  253. package/dist/lib/installed.d.ts +210 -11
  254. package/dist/lib/installed.js +234 -36
  255. package/dist/lib/installed.js.map +1 -1
  256. package/dist/lib/key-approval.d.ts +57 -0
  257. package/dist/lib/key-approval.js +117 -0
  258. package/dist/lib/key-approval.js.map +1 -0
  259. package/dist/lib/key-diagnosis.d.ts +56 -0
  260. package/dist/lib/key-diagnosis.js +227 -0
  261. package/dist/lib/key-diagnosis.js.map +1 -0
  262. package/dist/lib/key-doctor.d.ts +136 -0
  263. package/dist/lib/key-doctor.js +286 -0
  264. package/dist/lib/key-doctor.js.map +1 -0
  265. package/dist/lib/key-locations.d.ts +120 -0
  266. package/dist/lib/key-locations.js +326 -0
  267. package/dist/lib/key-locations.js.map +1 -0
  268. package/dist/lib/key-source.d.ts +66 -0
  269. package/dist/lib/key-source.js +106 -0
  270. package/dist/lib/key-source.js.map +1 -0
  271. package/dist/lib/key-state.d.ts +70 -0
  272. package/dist/lib/key-state.js +115 -0
  273. package/dist/lib/key-state.js.map +1 -0
  274. package/dist/lib/kind-package.d.ts +181 -0
  275. package/dist/lib/kind-package.js +679 -0
  276. package/dist/lib/kind-package.js.map +1 -0
  277. package/dist/lib/knowledge-title.d.ts +24 -0
  278. package/dist/lib/knowledge-title.js +46 -0
  279. package/dist/lib/knowledge-title.js.map +1 -0
  280. package/dist/lib/knowledge-title.test.d.ts +1 -0
  281. package/dist/lib/knowledge-title.test.js +34 -0
  282. package/dist/lib/knowledge-title.test.js.map +1 -0
  283. package/dist/lib/machine-instance.d.ts +64 -0
  284. package/dist/lib/machine-instance.js +142 -0
  285. package/dist/lib/machine-instance.js.map +1 -0
  286. package/dist/lib/mcp-bridge.d.ts +42 -0
  287. package/dist/lib/mcp-bridge.js +147 -0
  288. package/dist/lib/mcp-bridge.js.map +1 -0
  289. package/dist/lib/mcp-bridge.test.d.ts +1 -0
  290. package/dist/lib/mcp-bridge.test.js +90 -0
  291. package/dist/lib/mcp-bridge.test.js.map +1 -0
  292. package/dist/lib/mcp-call.d.ts +30 -0
  293. package/dist/lib/mcp-call.js +107 -0
  294. package/dist/lib/mcp-call.js.map +1 -0
  295. package/dist/lib/mcp-snippets.d.ts +53 -0
  296. package/dist/lib/mcp-snippets.js +82 -0
  297. package/dist/lib/mcp-snippets.js.map +1 -0
  298. package/dist/lib/next-steps.d.ts +8 -0
  299. package/dist/lib/next-steps.js +31 -1
  300. package/dist/lib/next-steps.js.map +1 -1
  301. package/dist/lib/package-wire.d.ts +179 -0
  302. package/dist/lib/package-wire.js +68 -0
  303. package/dist/lib/package-wire.js.map +1 -0
  304. package/dist/lib/pair-link.d.ts +38 -0
  305. package/dist/lib/pair-link.js +68 -0
  306. package/dist/lib/pair-link.js.map +1 -0
  307. package/dist/lib/pod-wide.d.ts +40 -0
  308. package/dist/lib/pod-wide.js +46 -0
  309. package/dist/lib/pod-wide.js.map +1 -0
  310. package/dist/lib/pod.d.ts +66 -112
  311. package/dist/lib/pod.js +134 -412
  312. package/dist/lib/pod.js.map +1 -1
  313. package/dist/lib/project-ref.d.ts +9 -3
  314. package/dist/lib/project-ref.js +10 -4
  315. package/dist/lib/project-ref.js.map +1 -1
  316. package/dist/lib/review-credential.d.ts +119 -0
  317. package/dist/lib/review-credential.js +147 -0
  318. package/dist/lib/review-credential.js.map +1 -0
  319. package/dist/lib/safe-open.d.ts +49 -0
  320. package/dist/lib/safe-open.js +119 -0
  321. package/dist/lib/safe-open.js.map +1 -0
  322. package/dist/lib/session-lens.d.ts +40 -1
  323. package/dist/lib/session-lens.js +54 -4
  324. package/dist/lib/session-lens.js.map +1 -1
  325. package/dist/lib/superwhisper-import.d.ts +8 -0
  326. package/dist/lib/superwhisper-import.js +14 -7
  327. package/dist/lib/superwhisper-import.js.map +1 -1
  328. package/dist/lib/superwhisper-title.test.d.ts +1 -0
  329. package/dist/lib/superwhisper-title.test.js +18 -0
  330. package/dist/lib/superwhisper-title.test.js.map +1 -0
  331. package/dist/lib/targets.d.ts +134 -10
  332. package/dist/lib/targets.js +962 -258
  333. package/dist/lib/targets.js.map +1 -1
  334. package/dist/lib/template-file.d.ts +4 -0
  335. package/dist/lib/template-file.js.map +1 -1
  336. package/dist/lib/template-lifecycle.d.ts +217 -0
  337. package/dist/lib/template-lifecycle.js +433 -0
  338. package/dist/lib/template-lifecycle.js.map +1 -0
  339. package/dist/lib/template-steps.d.ts +88 -0
  340. package/dist/lib/template-steps.js +118 -0
  341. package/dist/lib/template-steps.js.map +1 -0
  342. package/dist/lib/time-ago.d.ts +2 -0
  343. package/dist/lib/time-ago.js +15 -0
  344. package/dist/lib/time-ago.js.map +1 -0
  345. package/dist/utils/logger.js +5 -2
  346. package/dist/utils/logger.js.map +1 -1
  347. package/package.json +23 -17
  348. package/skills/README.md +12 -10
  349. package/skills/agent-os/SKILL.md +214 -99
  350. package/skills/manifest.json +1 -1
  351. package/skills/onboard/SKILL.md +55 -26
  352. package/skills/synap/README.md +5 -8
  353. package/skills/synap/SKILL.md +1086 -283
  354. package/skills/synap/_order.txt +7 -0
  355. package/skills/synap/_skill.yaml +1 -1
  356. package/skills/synap/automations.md +15 -0
  357. package/skills/synap/capture.md +5 -0
  358. package/skills/synap/cli-operations.md +24 -18
  359. package/skills/synap/concepts.md +28 -0
  360. package/skills/synap/content-os.md +10 -1
  361. package/skills/synap/creative-loop.md +15 -10
  362. package/skills/synap/crm.md +21 -52
  363. package/skills/synap/document-embeds.md +141 -47
  364. package/skills/synap/escalation-ladder.md +20 -10
  365. package/skills/synap/focus-sessions.md +47 -21
  366. package/skills/synap/from-intent.md +142 -0
  367. package/skills/synap/governance-rules.md +4 -4
  368. package/skills/synap/governance.md +10 -7
  369. package/skills/synap/hand-off.md +33 -0
  370. package/skills/synap/inline-patterns.md +15 -7
  371. package/skills/synap/lenses.md +33 -15
  372. package/skills/synap/linking.md +41 -40
  373. package/skills/synap/mcp-remote-servers.md +64 -0
  374. package/skills/synap/mental-model.md +17 -15
  375. package/skills/synap/operating-mode-rules.md +1 -1
  376. package/skills/synap/processes.md +118 -0
  377. package/skills/synap/quick-reference.md +5 -1
  378. package/skills/synap/reading.md +3 -1
  379. package/skills/synap/reflexes.md +12 -42
  380. package/skills/synap/viewframe-cells.md +38 -5
  381. package/skills/synap/work-flow.md +1 -1
  382. package/skills/synap/work-model.md +96 -0
  383. package/skills/synap/worked-examples.md +4 -5
  384. package/skills/synap/workspace-design.md +14 -10
  385. package/skills/synap/writes.md +97 -24
  386. package/skills/synap/writing-titles.md +63 -0
  387. package/skills/synap-app/SKILL.md +2 -2
  388. package/skills/synap-app/_skill.yaml +1 -1
  389. package/skills/synap-app/install-commands.md +1 -1
  390. package/skills/synap-design/SKILL.md +474 -0
  391. package/skills/synap-design/_order.txt +4 -0
  392. package/skills/synap-design/_skill.yaml +21 -0
  393. package/skills/synap-design/loop.md +134 -0
  394. package/skills/synap-design/overview.md +44 -0
  395. package/skills/synap-design/principles.md +130 -0
  396. package/skills/synap-design/system.md +133 -0
  397. package/skills/synap-market/SKILL.md +306 -16
  398. package/skills/synap-market/_skill.yaml +1 -1
  399. package/skills/synap-market/author-and-publish.md +145 -8
  400. package/skills/synap-market/governance-and-catalog.md +7 -0
  401. package/skills/synap-market/install.md +79 -1
  402. package/skills/synap-market/overview.md +74 -6
  403. package/skills/synap-schema/SKILL.md +172 -10
  404. package/skills/synap-schema/_order.txt +2 -0
  405. package/skills/synap-schema/_skill.yaml +4 -2
  406. package/skills/synap-schema/common-mistakes.md +4 -2
  407. package/skills/synap-schema/discover-profiles.md +1 -1
  408. package/skills/synap-schema/entity-scope.md +15 -3
  409. package/skills/synap-schema/extend-first.md +29 -0
  410. package/skills/synap-schema/extend-vs-create.md +1 -1
  411. package/skills/synap-schema/intent-vocabulary-ssot.md +111 -0
  412. package/skills/synap-schema/property-types.md +1 -1
  413. package/skills/synap-schema/relations.md +1 -1
  414. package/skills/synap-ui/SKILL.md +19 -12
  415. package/skills/synap-ui/_skill.yaml +1 -1
  416. package/skills/synap-ui/ai-companion.md +1 -1
  417. package/skills/synap-ui/arranging-bento.md +2 -0
  418. package/skills/synap-ui/bento-layouts.md +10 -10
  419. package/skills/synap-ui/bento-recipes.md +313 -543
  420. package/skills/synap-ui/four-builds.md +5 -0
  421. package/skills/synap-ui/view-types.md +2 -2
  422. package/skills/synap-ui/widget-catalog.md +22 -278
  423. package/templates/automations/bookmark-enrichment.automation.json +290 -13
  424. package/templates/automations/url-bookmark-capture.automation.json +73 -11
  425. package/templates/skills/authoring-playbooks/SKILL.md +6 -3
  426. package/templates/skills/authoring-playbooks/reference/stages-contract.md +15 -0
  427. package/templates/skills/authoring-playbooks/reference/worked-example.md +3 -0
  428. package/dist/commands/infra.d.ts +0 -21
  429. package/dist/commands/infra.js +0 -262
  430. package/dist/commands/infra.js.map +0 -1
  431. package/dist/commands/template.d.ts +0 -42
  432. package/dist/commands/template.js +0 -191
  433. package/dist/commands/template.js.map +0 -1
  434. package/dist/lib/browser-auth.d.ts +0 -35
  435. package/dist/lib/browser-auth.js +0 -170
  436. package/dist/lib/browser-auth.js.map +0 -1
  437. package/dist/lib/openclaw.d.ts +0 -32
  438. package/dist/lib/openclaw.js +0 -164
  439. package/dist/lib/openclaw.js.map +0 -1
  440. package/dist/lib/seed.d.ts +0 -13
  441. package/dist/lib/seed.js +0 -135
  442. package/dist/lib/seed.js.map +0 -1
  443. package/node_modules/@synap/hub-rest-client/dist/index.cjs +0 -1261
  444. package/node_modules/@synap/hub-rest-client/dist/index.d.cts +0 -1647
  445. package/node_modules/@synap/hub-rest-client/dist/index.d.ts +0 -1647
  446. package/node_modules/@synap/hub-rest-client/dist/index.js +0 -1231
  447. package/node_modules/@synap/hub-rest-client/package.json +0 -45
  448. package/node_modules/@synap/hub-rest-client/src/client.ts +0 -1631
  449. package/node_modules/@synap/hub-rest-client/src/errors.ts +0 -30
  450. package/node_modules/@synap/hub-rest-client/src/index.ts +0 -153
  451. package/node_modules/@synap/hub-rest-client/src/setup.ts +0 -133
  452. package/node_modules/@synap/hub-rest-client/src/types.ts +0 -1299
@@ -0,0 +1,256 @@
1
+ /**
2
+ * Connect THIS computer to a pod — the pod-side device flow (RFC 8628,
3
+ * MACHINE-IDENTITY-PLAN §4). The only way `synap init` and `synap login` get a
4
+ * credential for a pod, on self-hosted and managed pods alike.
5
+ *
6
+ * 1. POST {pod}/api/hub/setup/device → a user code + where to enter it
7
+ * 2. the person opens the link on any device, signs in to the pod, approves
8
+ * the computer and the agents it asked for (one decision)
9
+ * 3. POST {pod}/api/hub/setup/device/token → 400 RFC 8628 errors until then,
10
+ * then ONCE: the computer's key + one key per approved agent
11
+ *
12
+ * The computer gets its OWN governed principal ("devbox"); each agent is a
13
+ * distinct agent on that computer ("Claude Code on devbox"). Nothing here needs
14
+ * a Synap account session, a browser on this machine, or a loopback port.
15
+ */
16
+ import os from "os";
17
+ import chalk from "chalk";
18
+ import { log } from "../utils/logger.js";
19
+ /**
20
+ * The agent types the device door accepts (`SURFACE_AGENT_TYPES`,
21
+ * synap-backend `routers/hub-protocol/rest/setup.ts`). A mirror: the CLI does
22
+ * not depend on the backend package. A type outside it would 400 the whole
23
+ * request, so it is filtered out before asking.
24
+ */
25
+ export const DEVICE_AGENT_TYPES = [
26
+ "claude-code",
27
+ "claude-desktop",
28
+ "cursor",
29
+ "raycast",
30
+ "codex",
31
+ "openwebui",
32
+ "discord",
33
+ "proton",
34
+ "generic",
35
+ ];
36
+ /** The pod's cap on agents per request (`DEVICE_MAX_AGENTS`). */
37
+ export const DEVICE_MAX_AGENTS = 8;
38
+ /** The agents of `targets` the device door can approve, deduped, capped. */
39
+ export function deviceAgentsFor(targets) {
40
+ const ok = targets.filter((t) => DEVICE_AGENT_TYPES.includes(t));
41
+ return [...new Set(ok)].slice(0, DEVICE_MAX_AGENTS);
42
+ }
43
+ /** The pod could not start a request (an older pod has no device door: 404). */
44
+ export class DeviceStartError extends Error {
45
+ status;
46
+ constructor(status, message) {
47
+ super(message);
48
+ this.status = status;
49
+ this.name = "DeviceStartError";
50
+ }
51
+ }
52
+ const podHost = (podUrl) => {
53
+ try {
54
+ return new URL(podUrl).host;
55
+ }
56
+ catch {
57
+ return podUrl;
58
+ }
59
+ };
60
+ /**
61
+ * Ask the pod to connect this computer, show the person where to approve it,
62
+ * and wait — honouring the pod's `interval` and `slow_down` — until it is
63
+ * approved, denied, or the code expires. Throws `DeviceStartError` only when
64
+ * the request could not be started at all.
65
+ */
66
+ export async function deviceConnect(podUrl, opts, deps = {}) {
67
+ const base = podUrl.replace(/\/+$/, "");
68
+ const scale = deps.timeScale ?? 1;
69
+ const host = podHost(base);
70
+ let res;
71
+ try {
72
+ res = await fetch(`${base}/api/hub/setup/device`, {
73
+ method: "POST",
74
+ headers: { "Content-Type": "application/json" },
75
+ body: JSON.stringify({
76
+ clientName: opts.clientName ?? "Synap CLI",
77
+ hostname: (opts.hostname ?? os.hostname()).slice(0, 253) || "computer",
78
+ platform: opts.platform ?? process.platform,
79
+ agents: deviceAgentsFor(opts.agents),
80
+ }),
81
+ signal: AbortSignal.timeout(15_000),
82
+ });
83
+ }
84
+ catch (err) {
85
+ throw new DeviceStartError(null, `Could not reach ${host}: ${err.message}`);
86
+ }
87
+ if (!res.ok) {
88
+ const body = (await res.json().catch(() => null));
89
+ throw new DeviceStartError(res.status, res.status === 404
90
+ ? `${host} cannot connect a computer yet (it needs an update).`
91
+ : `${host} could not start the request (HTTP ${res.status})${body?.error_description ? `: ${body.error_description}` : "."}`);
92
+ }
93
+ const auth = (await res.json());
94
+ // The instruction comes FIRST and stays on screen: on a headless box (SSH)
95
+ // there is no browser to open — the person uses their phone or laptop.
96
+ log.blank();
97
+ console.log(` Open ${chalk.cyan.bold(auth.verification_uri)} on any device and enter ${chalk.bold(auth.user_code)}`);
98
+ if (auth.verification_uri_complete) {
99
+ log.dim(`Or open: ${auth.verification_uri_complete}`);
100
+ try {
101
+ const qr = await (deps.renderQr ?? (await import("./pair-link.js")).renderTerminalQr)(auth.verification_uri_complete);
102
+ console.log("\n" + qr);
103
+ }
104
+ catch {
105
+ // The link above is enough; a QR is a convenience.
106
+ }
107
+ }
108
+ const minutes = Math.max(1, Math.round(auth.expires_in / 60));
109
+ log.dim(`Waiting for you to approve this computer on ${host} (the code lasts ${minutes} min)…`);
110
+ const poll = deps.poll ?? (await import("./approval-poll.js")).pollForApproval;
111
+ let lastError;
112
+ try {
113
+ const grant = await poll({
114
+ url: `${base}/api/hub/setup/device/token`,
115
+ method: "POST",
116
+ body: JSON.stringify({ device_code: auth.device_code }),
117
+ readErrorBodies: true,
118
+ intervalMs: (auth.interval ?? 5) * 1000 * scale,
119
+ timeoutMs: auth.expires_in * 1000 * scale,
120
+ isApproved: (d) => typeof d.access_token === "string",
121
+ isRejected: (d) => {
122
+ const e = d.error;
123
+ if (e === "access_denied" || e === "expired_token" || e === "invalid_grant") {
124
+ lastError = e;
125
+ return true;
126
+ }
127
+ return false;
128
+ },
129
+ // RFC 8628 §3.5: slow_down adds to the interval for the rest of the wait.
130
+ nextIntervalMs: (d, current) => {
131
+ const body = d;
132
+ if (body.error !== "slow_down")
133
+ return current;
134
+ return typeof body.interval === "number" ? body.interval * 1000 * scale : current + 5000 * scale;
135
+ },
136
+ onApproved: (d) => {
137
+ const b = d;
138
+ return { computer: b.computer, agents: b.agents ?? [] };
139
+ },
140
+ });
141
+ return { status: "approved", grant };
142
+ }
143
+ catch {
144
+ if (lastError === "access_denied")
145
+ return { status: "denied", message: `Denied on ${host}.` };
146
+ return { status: "expired", message: "Code expired — run again." };
147
+ }
148
+ }
149
+ /** Renew a computer key this close to (or past) its expiry. */
150
+ export const COMPUTER_KEY_RENEW_DAYS = 7;
151
+ /**
152
+ * True when a saved computer key expires within `COMPUTER_KEY_RENEW_DAYS`, or
153
+ * already has. A credential with no recorded expiry (a pasted key, an old
154
+ * operator key) is never "due": nothing says it expires.
155
+ */
156
+ export function computerKeyNeedsRenewal(config, now = Date.now()) {
157
+ if (!config.keyExpiresAt)
158
+ return false;
159
+ const at = Date.parse(config.keyExpiresAt);
160
+ if (Number.isNaN(at))
161
+ return false;
162
+ return at - now < COMPUTER_KEY_RENEW_DAYS * 24 * 60 * 60 * 1000;
163
+ }
164
+ /**
165
+ * Keep what the device flow returned, once, where each reader already looks:
166
+ * - the computer's key → the pod profile `name` (it IS the CLI's identity
167
+ * for this pod now), with its expiry so it can be renewed in time;
168
+ * - each agent's key → the surface key store (`agentKeys`) AND the
169
+ * pre-approved slot its installer takes from, so `synap connect`'s own
170
+ * installer writes it into Claude Code / Codex / Cursor instead of minting.
171
+ * Fields of an existing profile (label, podId) are kept.
172
+ */
173
+ export async function saveDeviceGrant(podUrl, grant, profile) {
174
+ const pod = await import("./pod.js");
175
+ const { presetApprovedKey } = await import("./batch-approval.js");
176
+ const prior = pod.listPodProfiles().find((p) => p.name === profile.name)?.config;
177
+ const podId = profile.podId ?? prior?.podId;
178
+ const config = {
179
+ ...prior,
180
+ podUrl,
181
+ ...(podId ? { podId } : {}),
182
+ workspaceId: prior?.workspaceId ?? "",
183
+ agentUserId: grant.computer.id,
184
+ hubApiKey: grant.computer.apiKey,
185
+ credential: "computer",
186
+ computerName: grant.computer.name,
187
+ savedAt: new Date().toISOString(),
188
+ };
189
+ if (grant.computer.expiresAt)
190
+ config.keyExpiresAt = grant.computer.expiresAt;
191
+ else
192
+ delete config.keyExpiresAt;
193
+ pod.addPodProfile(profile.name, config);
194
+ for (const a of grant.agents) {
195
+ if (pod.SURFACE_NAMES.includes(a.agentType)) {
196
+ pod.setSurfaceAgentKey(a.agentType, {
197
+ hubApiKey: a.apiKey,
198
+ agentUserId: a.agentUserId,
199
+ podUrl,
200
+ });
201
+ }
202
+ presetApprovedKey(a.agentType, { hubApiKey: a.apiKey, agentUserId: a.agentUserId });
203
+ }
204
+ return config;
205
+ }
206
+ /** The approved agents this CLI has an installer for, as `synap connect` targets. */
207
+ export async function approvedTargets(grant) {
208
+ const { isTargetName } = await import("./targets.js");
209
+ return grant.agents.map((a) => a.agentType).filter(isTargetName);
210
+ }
211
+ /**
212
+ * Write each approved agent's own key into its client config — the same
213
+ * installers (`connectAgentsBatch` → `installForTarget`) `synap init` uses —
214
+ * for the callers that have no agents step of their own (`synap login`,
215
+ * reconnect, renewal).
216
+ */
217
+ export async function wireApprovedAgents(podUrl, computerKey, grant) {
218
+ const targets = await approvedTargets(grant);
219
+ if (targets.length === 0)
220
+ return;
221
+ const { connectAgentsBatch } = await import("./agent-door.js");
222
+ await connectAgentsBatch({ podUrl, apiKey: computerKey }, targets, {});
223
+ }
224
+ /**
225
+ * Connect this computer to `podUrl` and save the result under profile `name`:
226
+ * the device flow, then `saveDeviceGrant`, then the agents' configs. The agents
227
+ * asked for are the ones found on this machine. Returns the saved profile, or
228
+ * null after printing why (denied, expired, or the pod can't do it).
229
+ */
230
+ export async function connectThisComputer(podUrl, profile, opts = {}) {
231
+ let agents = opts.agents;
232
+ if (!agents) {
233
+ const { detectAgents } = await import("./agent-detect.js");
234
+ agents = detectAgents()
235
+ .filter((r) => r.found)
236
+ .map((r) => r.target);
237
+ }
238
+ let outcome;
239
+ try {
240
+ outcome = await deviceConnect(podUrl, { agents });
241
+ }
242
+ catch (err) {
243
+ log.error(err instanceof Error ? err.message : String(err));
244
+ return null;
245
+ }
246
+ if (outcome.status !== "approved") {
247
+ log.error(outcome.message);
248
+ return null;
249
+ }
250
+ const config = await saveDeviceGrant(podUrl, outcome.grant, profile);
251
+ log.success(`${outcome.grant.computer.name} connected to ${podHost(podUrl)}`);
252
+ if (opts.wireAgents !== false)
253
+ await wireApprovedAgents(podUrl, config.hubApiKey, outcome.grant);
254
+ return config;
255
+ }
256
+ //# sourceMappingURL=device-connect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-connect.js","sourceRoot":"","sources":["../../src/lib/device-connect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Per-DIRECTORY lens — the durable default scope for a working tree.
3
+ *
4
+ * RATIFIED MODEL: a directory's `.synap/lens.json` is where a lens normally
5
+ * lives; the per-Claude-session lens (`session-lens.ts`) is an explicit
6
+ * OVERRIDE on top of it.
7
+ *
8
+ * The session lens alone could not express "this repo is always Builder" — it
9
+ * dies with the tab, so every new session started pod-wide (or, worse, on
10
+ * whatever the global config happened to hold) and the operator re-pinned by
11
+ * hand. A directory lens is discovered the way git discovers `.git`: walk UP
12
+ * from the cwd until a `.synap/lens.json` turns up.
13
+ *
14
+ * Full precedence, highest first (assembled in `hub-client.ts`):
15
+ *
16
+ * explicit flag › session lens › DIRECTORY LENS › env var › global config
17
+ *
18
+ * ── Pod qualification ────────────────────────────────────────────────────────
19
+ * Workspace and project ids are POD-LOCAL: sending workspace W (pod A) to pod B
20
+ * is the "Access denied to workspace" 403. A directory lens is exposed to that
21
+ * hazard MORE than a session lens is, because it outlives many `synap pods use`
22
+ * switches. It therefore carries the same `podUrl` stamp and is compared
23
+ * through the SAME door — {@link lensMatchesPod} from `session-lens.ts`. There
24
+ * is deliberately no second comparison implementation here; a duplicated
25
+ * "is this the right pod" rule that drifts is the bug, not the fix.
26
+ *
27
+ * ── Write safety ─────────────────────────────────────────────────────────────
28
+ * Writes never escape the user's own tree: the target is either an EXISTING
29
+ * lens found on the upward walk (only when it sits at or below the home dir) or
30
+ * the cwd itself. A lens is never created in an ancestor, never above the home
31
+ * dir, and never at the filesystem root.
32
+ */
33
+ import { type SessionLens } from "./session-lens.js";
34
+ /** A directory lens is the same shape as a session lens — same fields, different lifetime. */
35
+ export type DirectoryLens = SessionLens;
36
+ export interface FoundDirectoryLens {
37
+ lens: DirectoryLens;
38
+ /** Absolute path to the `.synap/lens.json` that supplied it — shown by `synap lens`. */
39
+ file: string;
40
+ /** The directory that owns it (the one containing `.synap/`). */
41
+ dir: string;
42
+ }
43
+ /**
44
+ * Every directory to consider, nearest first: the cwd, then each ancestor.
45
+ * The walk STOPS after the home dir (a lens above `~` would apply to every
46
+ * unrelated project on the machine) and at the filesystem root.
47
+ */
48
+ export declare function lensSearchPath(startDir?: string): string[];
49
+ /**
50
+ * The nearest directory lens at or above `startDir`, ignoring pod qualification.
51
+ * Callers that are about to SEND ids must use {@link resolveDirectoryLensForPod}.
52
+ */
53
+ export declare function findDirectoryLens(startDir?: string): FoundDirectoryLens | null;
54
+ /**
55
+ * The nearest directory lens, but ONLY if it belongs to `podUrl`.
56
+ *
57
+ * A lens stamped with a different pod returns null so the caller falls through
58
+ * to the next rung (env var, then the pod-qualified global config) instead of
59
+ * sending a foreign workspace id. Comparison is delegated to `lensMatchesPod`
60
+ * — including its deliberate leniency for lenses written before the `podUrl`
61
+ * stamp existed.
62
+ */
63
+ export declare function resolveDirectoryLensForPod(podUrl: string | undefined, startDir?: string): FoundDirectoryLens | null;
64
+ /**
65
+ * The fields of a directory lens that are in force for THIS process.
66
+ *
67
+ * Workspace and project are the tree's durable scope and always apply. The
68
+ * focus SESSION does not, inside a Claude Code conversation: a session is the
69
+ * conversation's own, and `attachActiveSessionId` writes it to the session lens
70
+ * there for exactly that reason. Read through, a directory-lens session —
71
+ * attached from a plain terminal, or migrated from a `.synap-session` — was
72
+ * sent as `X-Session-Id` by every conversation opened in the tree, long after
73
+ * it went quiet, so each one's writes were filed into that old session (and a
74
+ * stale one was revived by them). Outside Claude Code there is no conversation
75
+ * to own a session, so the directory lens still carries it.
76
+ */
77
+ export declare function effectiveDirectoryLens(lens: DirectoryLens): DirectoryLens;
78
+ /**
79
+ * Where would a write land? An existing lens on the upward walk wins (so
80
+ * `synap use` from a subdirectory re-pins the repo's lens rather than seeding a
81
+ * nested one), but only when that lens sits at or below the home dir. Otherwise
82
+ * the cwd — a lens is never CREATED in an ancestor.
83
+ */
84
+ export declare function directoryLensWriteTarget(startDir?: string): string;
85
+ /**
86
+ * Merge-write the directory lens. Returns the file it wrote, so the caller can
87
+ * TELL the user which path now owns their scope — a silently-resolved lens is
88
+ * exactly what produced the 403 class this module exists to make legible.
89
+ */
90
+ export declare function writeDirectoryLens(patch: Partial<DirectoryLens>, startDir?: string): {
91
+ lens: DirectoryLens;
92
+ file: string;
93
+ dir: string;
94
+ };
95
+ /**
96
+ * Clear one field (or the whole lens) from the nearest directory lens.
97
+ * Returns the file touched, or null when there was nothing to clear.
98
+ */
99
+ export declare function clearDirectoryLensField(field?: keyof DirectoryLens, startDir?: string): string | null;
@@ -0,0 +1,187 @@
1
+ /**
2
+ * Per-DIRECTORY lens — the durable default scope for a working tree.
3
+ *
4
+ * RATIFIED MODEL: a directory's `.synap/lens.json` is where a lens normally
5
+ * lives; the per-Claude-session lens (`session-lens.ts`) is an explicit
6
+ * OVERRIDE on top of it.
7
+ *
8
+ * The session lens alone could not express "this repo is always Builder" — it
9
+ * dies with the tab, so every new session started pod-wide (or, worse, on
10
+ * whatever the global config happened to hold) and the operator re-pinned by
11
+ * hand. A directory lens is discovered the way git discovers `.git`: walk UP
12
+ * from the cwd until a `.synap/lens.json` turns up.
13
+ *
14
+ * Full precedence, highest first (assembled in `hub-client.ts`):
15
+ *
16
+ * explicit flag › session lens › DIRECTORY LENS › env var › global config
17
+ *
18
+ * ── Pod qualification ────────────────────────────────────────────────────────
19
+ * Workspace and project ids are POD-LOCAL: sending workspace W (pod A) to pod B
20
+ * is the "Access denied to workspace" 403. A directory lens is exposed to that
21
+ * hazard MORE than a session lens is, because it outlives many `synap pods use`
22
+ * switches. It therefore carries the same `podUrl` stamp and is compared
23
+ * through the SAME door — {@link lensMatchesPod} from `session-lens.ts`. There
24
+ * is deliberately no second comparison implementation here; a duplicated
25
+ * "is this the right pod" rule that drifts is the bug, not the fix.
26
+ *
27
+ * ── Write safety ─────────────────────────────────────────────────────────────
28
+ * Writes never escape the user's own tree: the target is either an EXISTING
29
+ * lens found on the upward walk (only when it sits at or below the home dir) or
30
+ * the cwd itself. A lens is never created in an ancestor, never above the home
31
+ * dir, and never at the filesystem root.
32
+ */
33
+ import fs from "node:fs";
34
+ import os from "node:os";
35
+ import path from "node:path";
36
+ import { getClaudeSessionId, lensMatchesPod } from "./session-lens.js";
37
+ import { writeSecretFile } from "./atomic-file.js";
38
+ /** The directory name a lens lives in, and the file inside it. */
39
+ const LENS_DIR_NAME = ".synap";
40
+ const LENS_FILE_NAME = "lens.json";
41
+ function lensFileIn(dir) {
42
+ return path.join(dir, LENS_DIR_NAME, LENS_FILE_NAME);
43
+ }
44
+ /** Is `dir` the home dir or inside it? Used to bound where a lens may be WRITTEN. */
45
+ function isAtOrBelowHome(dir) {
46
+ const home = path.resolve(os.homedir());
47
+ const target = path.resolve(dir);
48
+ if (target === home)
49
+ return true;
50
+ return target.startsWith(home + path.sep);
51
+ }
52
+ /**
53
+ * Every directory to consider, nearest first: the cwd, then each ancestor.
54
+ * The walk STOPS after the home dir (a lens above `~` would apply to every
55
+ * unrelated project on the machine) and at the filesystem root.
56
+ */
57
+ export function lensSearchPath(startDir = process.cwd()) {
58
+ const home = path.resolve(os.homedir());
59
+ const dirs = [];
60
+ let dir = path.resolve(startDir);
61
+ for (;;) {
62
+ dirs.push(dir);
63
+ if (dir === home)
64
+ break;
65
+ const parent = path.dirname(dir);
66
+ if (parent === dir)
67
+ break; // filesystem root
68
+ dir = parent;
69
+ }
70
+ return dirs;
71
+ }
72
+ /** Read + parse one candidate, or null when absent/corrupt. A malformed lens must not crash the CLI. */
73
+ function readLensFile(dir) {
74
+ const file = lensFileIn(dir);
75
+ try {
76
+ const parsed = JSON.parse(fs.readFileSync(file, "utf-8"));
77
+ if (!parsed || typeof parsed !== "object")
78
+ return null;
79
+ return { lens: parsed, file, dir };
80
+ }
81
+ catch {
82
+ return null;
83
+ }
84
+ }
85
+ /**
86
+ * The nearest directory lens at or above `startDir`, ignoring pod qualification.
87
+ * Callers that are about to SEND ids must use {@link resolveDirectoryLensForPod}.
88
+ */
89
+ export function findDirectoryLens(startDir) {
90
+ for (const dir of lensSearchPath(startDir)) {
91
+ const found = readLensFile(dir);
92
+ if (found)
93
+ return found;
94
+ }
95
+ return null;
96
+ }
97
+ /**
98
+ * The nearest directory lens, but ONLY if it belongs to `podUrl`.
99
+ *
100
+ * A lens stamped with a different pod returns null so the caller falls through
101
+ * to the next rung (env var, then the pod-qualified global config) instead of
102
+ * sending a foreign workspace id. Comparison is delegated to `lensMatchesPod`
103
+ * — including its deliberate leniency for lenses written before the `podUrl`
104
+ * stamp existed.
105
+ */
106
+ export function resolveDirectoryLensForPod(podUrl, startDir) {
107
+ const found = findDirectoryLens(startDir);
108
+ if (!found)
109
+ return null;
110
+ return lensMatchesPod(found.lens, podUrl) ? found : null;
111
+ }
112
+ /**
113
+ * The fields of a directory lens that are in force for THIS process.
114
+ *
115
+ * Workspace and project are the tree's durable scope and always apply. The
116
+ * focus SESSION does not, inside a Claude Code conversation: a session is the
117
+ * conversation's own, and `attachActiveSessionId` writes it to the session lens
118
+ * there for exactly that reason. Read through, a directory-lens session —
119
+ * attached from a plain terminal, or migrated from a `.synap-session` — was
120
+ * sent as `X-Session-Id` by every conversation opened in the tree, long after
121
+ * it went quiet, so each one's writes were filed into that old session (and a
122
+ * stale one was revived by them). Outside Claude Code there is no conversation
123
+ * to own a session, so the directory lens still carries it.
124
+ */
125
+ export function effectiveDirectoryLens(lens) {
126
+ if (!getClaudeSessionId())
127
+ return lens;
128
+ const { focusSessionId: _conversationOwned, ...scope } = lens;
129
+ return scope;
130
+ }
131
+ /**
132
+ * Where would a write land? An existing lens on the upward walk wins (so
133
+ * `synap use` from a subdirectory re-pins the repo's lens rather than seeding a
134
+ * nested one), but only when that lens sits at or below the home dir. Otherwise
135
+ * the cwd — a lens is never CREATED in an ancestor.
136
+ */
137
+ export function directoryLensWriteTarget(startDir = process.cwd()) {
138
+ const found = findDirectoryLens(startDir);
139
+ if (found && isAtOrBelowHome(found.dir))
140
+ return found.dir;
141
+ return path.resolve(startDir);
142
+ }
143
+ /**
144
+ * Merge-write the directory lens. Returns the file it wrote, so the caller can
145
+ * TELL the user which path now owns their scope — a silently-resolved lens is
146
+ * exactly what produced the 403 class this module exists to make legible.
147
+ */
148
+ export function writeDirectoryLens(patch, startDir) {
149
+ const dir = directoryLensWriteTarget(startDir);
150
+ const prev = readLensFile(dir)?.lens ?? {};
151
+ const next = { ...prev, ...patch, updatedAt: Date.now() };
152
+ const file = lensFileIn(dir);
153
+ fs.mkdirSync(path.dirname(file), { recursive: true, mode: 0o700 });
154
+ writeSecretFile(file, JSON.stringify(next, null, 2) + "\n", { mode: 0o600 });
155
+ return { lens: next, file, dir };
156
+ }
157
+ /**
158
+ * Clear one field (or the whole lens) from the nearest directory lens.
159
+ * Returns the file touched, or null when there was nothing to clear.
160
+ */
161
+ export function clearDirectoryLensField(field, startDir) {
162
+ const found = findDirectoryLens(startDir);
163
+ if (!found)
164
+ return null;
165
+ if (!field) {
166
+ try {
167
+ fs.unlinkSync(found.file);
168
+ }
169
+ catch {
170
+ return null;
171
+ }
172
+ return found.file;
173
+ }
174
+ if (!(field in found.lens))
175
+ return null;
176
+ const next = { ...found.lens };
177
+ delete next[field];
178
+ next.updatedAt = Date.now();
179
+ try {
180
+ writeSecretFile(found.file, JSON.stringify(next, null, 2) + "\n", { mode: 0o600 });
181
+ }
182
+ catch {
183
+ return null;
184
+ }
185
+ return found.file;
186
+ }
187
+ //# sourceMappingURL=directory-lens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directory-lens.js","sourceRoot":"","sources":["../../src/lib/directory-lens.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * What `--from-workspace` / `--from-project` do NOT carry out of a live pod.
3
+ * ==========================================================================
4
+ *
5
+ * `synap market publish --from-workspace <id>` serialises a LIVE workspace
6
+ * through the pod's `workspaceToPackageDefinition`
7
+ * (synap-backend/packages/api/src/services/workspace-to-package-definition.ts)
8
+ * and posts the result. `--from-project` walks the same serialiser for every
9
+ * workspace a project `uses`, then composes a suite — so the same drop-list
10
+ * applies to each constituent. That serialiser is a **lossy projection**: it
11
+ * emits 21 of `packageDefinitionSchema`'s keys and has no projection at all
12
+ * for the ones below. A workspace carrying them exports WITHOUT them — no
13
+ * error, no signal.
14
+ *
15
+ * Loops stay here deliberately: there is no durable loop row to reverse-
16
+ * serialise (`createLoopFromDefinition` dissolves into playbooks + triggers).
17
+ *
18
+ * `TEMPLATE-DEV-GUIDE.md` used to assert, unqualified, that a
19
+ * `PackageDefinition` "round-trips". It does not, in this direction, and the
20
+ * consequence is the shape this repo keeps paying for: an author who built one
21
+ * of the things below publishes their workspace, ships a thinner-than-expected
22
+ * package, and gets a success message. Same class as `status ?? "installed"` —
23
+ * a claim of completeness nobody verified. (Cards authored in Card Studio USED
24
+ * to be one of these — `workspaceToPackageDefinition` now emits them into
25
+ * `cells[]`, so that loss is fixed; the list below is what remains.)
26
+ *
27
+ * ── WHY THIS LIST IS UNCONDITIONAL, NOT DETECTED ────────────────────────────
28
+ * The CLI never sees the workspace, only the projection's OUTPUT. "key absent
29
+ * because the workspace had none" and "key absent because the serialiser cannot
30
+ * emit it" are indistinguishable from here, and reporting a count would be
31
+ * inventing a fact. So this warns about the DOOR ("this door does not carry
32
+ * these"), which is true on every call, rather than about the payload.
33
+ *
34
+ * Keeping it honest across the repo boundary is
35
+ * `test/exporter-coverage-parity.test.ts`, which reads the exporter's own
36
+ * source and fails if a key listed here has gained an assignment (the list is
37
+ * stale and over-warns) or if a key it claims to emit has lost one.
38
+ */
39
+ /** A `packageDefinitionSchema` key the workspace serialiser cannot emit. */
40
+ export interface UnemittedKey {
41
+ /** The `PackageDefinition` key, verbatim. */
42
+ key: string;
43
+ /** What an author actually loses, in product words (Card, not cell). */
44
+ loses: string;
45
+ }
46
+ /**
47
+ * Keys with real user-authored content behind them that the serialiser drops.
48
+ *
49
+ * DELIBERATELY EXCLUDED, and why — these are absent from the export too, but
50
+ * warning about them would be noise rather than a loss:
51
+ * • `icon` / `color` / `domain` / `workspaceType` — a live workspace has no
52
+ * field to read them from (the exporter says so at L107-109). Honest
53
+ * under-convergence, not a silent drop.
54
+ * • `suggestedEntities` / `suggestedRelations` / `phases` / `composesFrom` —
55
+ * authoring-time seed hints and composition metadata. A live workspace has
56
+ * real entities, not "suggestions"; there is nothing to derive them from.
57
+ * • `capability` / `sourcePackage` / `contentHash` — a non-workspace package
58
+ * body and publish-time provenance. Not this door's business.
59
+ */
60
+ export declare const EXPORTER_UNEMITTED_KEYS: readonly UnemittedKey[];
61
+ /**
62
+ * The keys the serialiser DOES emit. Not consumed at runtime — it is the other
63
+ * half of the parity tripwire's assertion, so that "emits" and "does not emit"
64
+ * are pinned by the same read of the same source and cannot disagree.
65
+ */
66
+ export declare const EXPORTER_EMITTED_KEYS: readonly string[];
67
+ /**
68
+ * One human line per dropped key, for `--json`'s `warnings[]` and for the
69
+ * terminal hint list. Deliberately phrased as a property of the DOOR.
70
+ */
71
+ export declare function exporterDropWarnings(): string[];