@synap-core/cli 1.10.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 (461) 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 +297 -176
  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 +3 -14
  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 +9 -2
  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 +198 -25
  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 +307 -24
  50. package/dist/commands/data.js.map +1 -1
  51. package/dist/commands/diagnose.d.ts +66 -4
  52. package/dist/commands/diagnose.js +329 -29
  53. package/dist/commands/diagnose.js.map +1 -1
  54. package/dist/commands/digest.js +2 -1
  55. package/dist/commands/digest.js.map +1 -1
  56. package/dist/commands/doc.d.ts +25 -4
  57. package/dist/commands/doc.js +100 -18
  58. package/dist/commands/doc.js.map +1 -1
  59. package/dist/commands/doctor.d.ts +130 -0
  60. package/dist/commands/doctor.js +814 -0
  61. package/dist/commands/doctor.js.map +1 -0
  62. package/dist/commands/events.js +3 -1
  63. package/dist/commands/events.js.map +1 -1
  64. package/dist/commands/explain.js +5 -5
  65. package/dist/commands/explain.js.map +1 -1
  66. package/dist/commands/graph.js +5 -3
  67. package/dist/commands/graph.js.map +1 -1
  68. package/dist/commands/import.d.ts +368 -13
  69. package/dist/commands/import.js +1096 -55
  70. package/dist/commands/import.js.map +1 -1
  71. package/dist/commands/init.d.ts +20 -9
  72. package/dist/commands/init.js +433 -973
  73. package/dist/commands/init.js.map +1 -1
  74. package/dist/commands/keys.d.ts +1 -0
  75. package/dist/commands/keys.js +15 -2
  76. package/dist/commands/keys.js.map +1 -1
  77. package/dist/commands/knowledge.d.ts +28 -6
  78. package/dist/commands/knowledge.js +358 -73
  79. package/dist/commands/knowledge.js.map +1 -1
  80. package/dist/commands/launch.js +2 -2
  81. package/dist/commands/launch.js.map +1 -1
  82. package/dist/commands/lens.d.ts +37 -1
  83. package/dist/commands/lens.js +193 -72
  84. package/dist/commands/lens.js.map +1 -1
  85. package/dist/commands/market-authoring.d.ts +72 -0
  86. package/dist/commands/market-authoring.js +566 -0
  87. package/dist/commands/market-authoring.js.map +1 -0
  88. package/dist/commands/market-official.d.ts +58 -0
  89. package/dist/commands/market-official.js +84 -0
  90. package/dist/commands/market-official.js.map +1 -0
  91. package/dist/commands/market.d.ts +419 -20
  92. package/dist/commands/market.js +2124 -193
  93. package/dist/commands/market.js.map +1 -1
  94. package/dist/commands/mcp.d.ts +70 -13
  95. package/dist/commands/mcp.js +308 -40
  96. package/dist/commands/mcp.js.map +1 -1
  97. package/dist/commands/open.d.ts +39 -9
  98. package/dist/commands/open.js +80 -25
  99. package/dist/commands/open.js.map +1 -1
  100. package/dist/commands/playbook.d.ts +42 -0
  101. package/dist/commands/playbook.js +162 -0
  102. package/dist/commands/playbook.js.map +1 -0
  103. package/dist/commands/pod.js +1 -1
  104. package/dist/commands/pod.js.map +1 -1
  105. package/dist/commands/pods.d.ts +19 -0
  106. package/dist/commands/pods.js +220 -85
  107. package/dist/commands/pods.js.map +1 -1
  108. package/dist/commands/proposals-actions.d.ts +62 -0
  109. package/dist/commands/proposals-actions.js +146 -8
  110. package/dist/commands/proposals-actions.js.map +1 -1
  111. package/dist/commands/proposals-await.d.ts +68 -0
  112. package/dist/commands/proposals-await.js +248 -0
  113. package/dist/commands/proposals-await.js.map +1 -0
  114. package/dist/commands/proton-setup.d.ts +73 -0
  115. package/dist/commands/proton-setup.js +577 -0
  116. package/dist/commands/proton-setup.js.map +1 -0
  117. package/dist/commands/providers.d.ts +23 -0
  118. package/dist/commands/providers.js +126 -1
  119. package/dist/commands/providers.js.map +1 -1
  120. package/dist/commands/raycast.js +6 -2
  121. package/dist/commands/raycast.js.map +1 -1
  122. package/dist/commands/rule.d.ts +150 -0
  123. package/dist/commands/rule.js +447 -0
  124. package/dist/commands/rule.js.map +1 -0
  125. package/dist/commands/session-wait.d.ts +111 -0
  126. package/dist/commands/session-wait.js +209 -0
  127. package/dist/commands/session-wait.js.map +1 -0
  128. package/dist/commands/sessions.d.ts +52 -0
  129. package/dist/commands/sessions.js +479 -58
  130. package/dist/commands/sessions.js.map +1 -1
  131. package/dist/commands/skill-manage.d.ts +21 -0
  132. package/dist/commands/skill-manage.js +136 -19
  133. package/dist/commands/skill-manage.js.map +1 -1
  134. package/dist/commands/skills.js +19 -1
  135. package/dist/commands/skills.js.map +1 -1
  136. package/dist/commands/status.d.ts +1 -4
  137. package/dist/commands/status.js +5 -34
  138. package/dist/commands/status.js.map +1 -1
  139. package/dist/commands/statusline.backoff.test.d.ts +13 -0
  140. package/dist/commands/statusline.backoff.test.js +100 -0
  141. package/dist/commands/statusline.backoff.test.js.map +1 -0
  142. package/dist/commands/statusline.js +16 -9
  143. package/dist/commands/statusline.js.map +1 -1
  144. package/dist/commands/sync-status.d.ts +12 -0
  145. package/dist/commands/sync-status.js +125 -0
  146. package/dist/commands/sync-status.js.map +1 -0
  147. package/dist/commands/templates-retire.d.ts +34 -0
  148. package/dist/commands/templates-retire.js +192 -0
  149. package/dist/commands/templates-retire.js.map +1 -0
  150. package/dist/commands/tools.js +6 -21
  151. package/dist/commands/tools.js.map +1 -1
  152. package/dist/commands/tracks.d.ts +51 -0
  153. package/dist/commands/tracks.js +291 -0
  154. package/dist/commands/tracks.js.map +1 -0
  155. package/dist/commands/update.d.ts +3 -11
  156. package/dist/commands/update.js +5 -134
  157. package/dist/commands/update.js.map +1 -1
  158. package/dist/commands/upload.d.ts +68 -0
  159. package/dist/commands/upload.js +257 -0
  160. package/dist/commands/upload.js.map +1 -0
  161. package/dist/commands/vendor.d.ts +28 -0
  162. package/dist/commands/vendor.js +110 -0
  163. package/dist/commands/vendor.js.map +1 -0
  164. package/dist/commands/versions.js +6 -0
  165. package/dist/commands/versions.js.map +1 -1
  166. package/dist/commands/view.js +10 -5
  167. package/dist/commands/view.js.map +1 -1
  168. package/dist/commands/whoami.d.ts +23 -3
  169. package/dist/commands/whoami.js +169 -23
  170. package/dist/commands/whoami.js.map +1 -1
  171. package/dist/commands/worker.d.ts +122 -0
  172. package/dist/commands/worker.js +435 -0
  173. package/dist/commands/worker.js.map +1 -0
  174. package/dist/commands/worker.test.d.ts +1 -0
  175. package/dist/commands/worker.test.js +116 -0
  176. package/dist/commands/worker.test.js.map +1 -0
  177. package/dist/commands/workspace-ops.d.ts +35 -0
  178. package/dist/commands/workspace-ops.js +153 -0
  179. package/dist/commands/workspace-ops.js.map +1 -0
  180. package/dist/index.d.ts +6 -6
  181. package/dist/index.js +1009 -171
  182. package/dist/index.js.map +1 -1
  183. package/dist/lib/agent-connections.d.ts +31 -0
  184. package/dist/lib/agent-connections.js +33 -0
  185. package/dist/lib/agent-connections.js.map +1 -0
  186. package/dist/lib/agent-detect.d.ts +27 -0
  187. package/dist/lib/agent-detect.js +71 -0
  188. package/dist/lib/agent-detect.js.map +1 -0
  189. package/dist/lib/agent-door.d.ts +138 -0
  190. package/dist/lib/agent-door.js +426 -0
  191. package/dist/lib/agent-door.js.map +1 -0
  192. package/dist/lib/agents-config.d.ts +2 -0
  193. package/dist/lib/agents-config.js +4 -9
  194. package/dist/lib/agents-config.js.map +1 -1
  195. package/dist/lib/approval-poll.d.ts +31 -2
  196. package/dist/lib/approval-poll.js +20 -7
  197. package/dist/lib/approval-poll.js.map +1 -1
  198. package/dist/lib/atomic-file.d.ts +48 -0
  199. package/dist/lib/atomic-file.js +129 -0
  200. package/dist/lib/atomic-file.js.map +1 -0
  201. package/dist/lib/auth.d.ts +14 -9
  202. package/dist/lib/auth.js +44 -61
  203. package/dist/lib/auth.js.map +1 -1
  204. package/dist/lib/batch-approval.d.ts +85 -0
  205. package/dist/lib/batch-approval.js +170 -0
  206. package/dist/lib/batch-approval.js.map +1 -0
  207. package/dist/lib/capture-lane.d.ts +6 -5
  208. package/dist/lib/capture-lane.js +11 -8
  209. package/dist/lib/capture-lane.js.map +1 -1
  210. package/dist/lib/capture-structure.d.ts +342 -0
  211. package/dist/lib/capture-structure.js +295 -0
  212. package/dist/lib/capture-structure.js.map +1 -0
  213. package/dist/lib/catalog-templates.d.ts +59 -0
  214. package/dist/lib/catalog-templates.js +126 -0
  215. package/dist/lib/catalog-templates.js.map +1 -0
  216. package/dist/lib/cli-build.d.ts +19 -0
  217. package/dist/lib/cli-build.js +37 -0
  218. package/dist/lib/cli-build.js.map +1 -0
  219. package/dist/lib/conversation-headers.d.ts +18 -0
  220. package/dist/lib/conversation-headers.js +32 -0
  221. package/dist/lib/conversation-headers.js.map +1 -0
  222. package/dist/lib/cp-packages.d.ts +216 -4
  223. package/dist/lib/cp-packages.js +414 -11
  224. package/dist/lib/cp-packages.js.map +1 -1
  225. package/dist/lib/credential-class.d.ts +117 -0
  226. package/dist/lib/credential-class.js +116 -0
  227. package/dist/lib/credential-class.js.map +1 -0
  228. package/dist/lib/describe-lens.d.ts +35 -0
  229. package/dist/lib/describe-lens.js +40 -0
  230. package/dist/lib/describe-lens.js.map +1 -1
  231. package/dist/lib/device-connect.d.ts +125 -0
  232. package/dist/lib/device-connect.js +256 -0
  233. package/dist/lib/device-connect.js.map +1 -0
  234. package/dist/lib/directory-lens.d.ts +99 -0
  235. package/dist/lib/directory-lens.js +187 -0
  236. package/dist/lib/directory-lens.js.map +1 -0
  237. package/dist/lib/exporter-coverage.d.ts +71 -0
  238. package/dist/lib/exporter-coverage.js +97 -0
  239. package/dist/lib/exporter-coverage.js.map +1 -0
  240. package/dist/lib/hub-client.d.ts +43 -9
  241. package/dist/lib/hub-client.js +429 -65
  242. package/dist/lib/hub-client.js.map +1 -1
  243. package/dist/lib/id.d.ts +23 -0
  244. package/dist/lib/id.js +35 -0
  245. package/dist/lib/id.js.map +1 -0
  246. package/dist/lib/init-connect.d.ts +41 -0
  247. package/dist/lib/init-connect.js +75 -0
  248. package/dist/lib/init-connect.js.map +1 -0
  249. package/dist/lib/init-exit.d.ts +24 -0
  250. package/dist/lib/init-exit.js +41 -0
  251. package/dist/lib/init-exit.js.map +1 -0
  252. package/dist/lib/init-flow.d.ts +25 -0
  253. package/dist/lib/init-flow.js +40 -0
  254. package/dist/lib/init-flow.js.map +1 -0
  255. package/dist/lib/init-handoff.d.ts +16 -0
  256. package/dist/lib/init-handoff.js +19 -0
  257. package/dist/lib/init-handoff.js.map +1 -0
  258. package/dist/lib/init-output.d.ts +18 -0
  259. package/dist/lib/init-output.js +43 -0
  260. package/dist/lib/init-output.js.map +1 -0
  261. package/dist/lib/init-pod.d.ts +45 -0
  262. package/dist/lib/init-pod.js +36 -0
  263. package/dist/lib/init-pod.js.map +1 -0
  264. package/dist/lib/installed.d.ts +210 -11
  265. package/dist/lib/installed.js +234 -36
  266. package/dist/lib/installed.js.map +1 -1
  267. package/dist/lib/key-approval.d.ts +57 -0
  268. package/dist/lib/key-approval.js +117 -0
  269. package/dist/lib/key-approval.js.map +1 -0
  270. package/dist/lib/key-diagnosis.d.ts +56 -0
  271. package/dist/lib/key-diagnosis.js +227 -0
  272. package/dist/lib/key-diagnosis.js.map +1 -0
  273. package/dist/lib/key-doctor.d.ts +136 -0
  274. package/dist/lib/key-doctor.js +286 -0
  275. package/dist/lib/key-doctor.js.map +1 -0
  276. package/dist/lib/key-locations.d.ts +120 -0
  277. package/dist/lib/key-locations.js +326 -0
  278. package/dist/lib/key-locations.js.map +1 -0
  279. package/dist/lib/key-source.d.ts +66 -0
  280. package/dist/lib/key-source.js +106 -0
  281. package/dist/lib/key-source.js.map +1 -0
  282. package/dist/lib/key-state.d.ts +70 -0
  283. package/dist/lib/key-state.js +115 -0
  284. package/dist/lib/key-state.js.map +1 -0
  285. package/dist/lib/kind-package.d.ts +181 -0
  286. package/dist/lib/kind-package.js +679 -0
  287. package/dist/lib/kind-package.js.map +1 -0
  288. package/dist/lib/knowledge-title.d.ts +24 -0
  289. package/dist/lib/knowledge-title.js +46 -0
  290. package/dist/lib/knowledge-title.js.map +1 -0
  291. package/dist/lib/knowledge-title.test.d.ts +1 -0
  292. package/dist/lib/knowledge-title.test.js +34 -0
  293. package/dist/lib/knowledge-title.test.js.map +1 -0
  294. package/dist/lib/machine-instance.d.ts +64 -0
  295. package/dist/lib/machine-instance.js +142 -0
  296. package/dist/lib/machine-instance.js.map +1 -0
  297. package/dist/lib/mcp-bridge.d.ts +42 -0
  298. package/dist/lib/mcp-bridge.js +147 -0
  299. package/dist/lib/mcp-bridge.js.map +1 -0
  300. package/dist/lib/mcp-bridge.test.d.ts +1 -0
  301. package/dist/lib/mcp-bridge.test.js +90 -0
  302. package/dist/lib/mcp-bridge.test.js.map +1 -0
  303. package/dist/lib/mcp-call.d.ts +30 -0
  304. package/dist/lib/mcp-call.js +107 -0
  305. package/dist/lib/mcp-call.js.map +1 -0
  306. package/dist/lib/mcp-snippets.d.ts +53 -0
  307. package/dist/lib/mcp-snippets.js +82 -0
  308. package/dist/lib/mcp-snippets.js.map +1 -0
  309. package/dist/lib/next-steps.d.ts +8 -0
  310. package/dist/lib/next-steps.js +31 -1
  311. package/dist/lib/next-steps.js.map +1 -1
  312. package/dist/lib/package-wire.d.ts +179 -0
  313. package/dist/lib/package-wire.js +68 -0
  314. package/dist/lib/package-wire.js.map +1 -0
  315. package/dist/lib/pair-link.d.ts +38 -0
  316. package/dist/lib/pair-link.js +68 -0
  317. package/dist/lib/pair-link.js.map +1 -0
  318. package/dist/lib/pod-wide.d.ts +40 -0
  319. package/dist/lib/pod-wide.js +46 -0
  320. package/dist/lib/pod-wide.js.map +1 -0
  321. package/dist/lib/pod.d.ts +119 -115
  322. package/dist/lib/pod.js +206 -412
  323. package/dist/lib/pod.js.map +1 -1
  324. package/dist/lib/project-ref.d.ts +9 -3
  325. package/dist/lib/project-ref.js +10 -4
  326. package/dist/lib/project-ref.js.map +1 -1
  327. package/dist/lib/review-credential.d.ts +119 -0
  328. package/dist/lib/review-credential.js +147 -0
  329. package/dist/lib/review-credential.js.map +1 -0
  330. package/dist/lib/safe-open.d.ts +49 -0
  331. package/dist/lib/safe-open.js +119 -0
  332. package/dist/lib/safe-open.js.map +1 -0
  333. package/dist/lib/session-lens.d.ts +40 -1
  334. package/dist/lib/session-lens.js +54 -4
  335. package/dist/lib/session-lens.js.map +1 -1
  336. package/dist/lib/superwhisper-import.d.ts +8 -0
  337. package/dist/lib/superwhisper-import.js +14 -7
  338. package/dist/lib/superwhisper-import.js.map +1 -1
  339. package/dist/lib/superwhisper-title.test.d.ts +1 -0
  340. package/dist/lib/superwhisper-title.test.js +18 -0
  341. package/dist/lib/superwhisper-title.test.js.map +1 -0
  342. package/dist/lib/targets.d.ts +134 -10
  343. package/dist/lib/targets.js +962 -258
  344. package/dist/lib/targets.js.map +1 -1
  345. package/dist/lib/template-file.d.ts +78 -0
  346. package/dist/lib/template-file.js +140 -0
  347. package/dist/lib/template-file.js.map +1 -0
  348. package/dist/lib/template-lifecycle.d.ts +217 -0
  349. package/dist/lib/template-lifecycle.js +433 -0
  350. package/dist/lib/template-lifecycle.js.map +1 -0
  351. package/dist/lib/template-steps.d.ts +88 -0
  352. package/dist/lib/template-steps.js +118 -0
  353. package/dist/lib/template-steps.js.map +1 -0
  354. package/dist/lib/time-ago.d.ts +2 -0
  355. package/dist/lib/time-ago.js +15 -0
  356. package/dist/lib/time-ago.js.map +1 -0
  357. package/dist/utils/logger.js +5 -2
  358. package/dist/utils/logger.js.map +1 -1
  359. package/package.json +25 -18
  360. package/skills/README.md +12 -10
  361. package/skills/agent-os/SKILL.md +220 -99
  362. package/skills/manifest.json +2 -2
  363. package/skills/onboard/SKILL.md +61 -25
  364. package/skills/synap/README.md +5 -8
  365. package/skills/synap/SKILL.md +1185 -301
  366. package/skills/synap/_order.txt +7 -0
  367. package/skills/synap/_skill.yaml +1 -1
  368. package/skills/synap/automations.md +15 -0
  369. package/skills/synap/capture.md +54 -151
  370. package/skills/synap/cli-operations.md +24 -18
  371. package/skills/synap/common-mistakes.md +1 -0
  372. package/skills/synap/concepts.md +28 -0
  373. package/skills/synap/content-os.md +92 -0
  374. package/skills/synap/creative-loop.md +15 -10
  375. package/skills/synap/crm.md +21 -52
  376. package/skills/synap/digesting-a-channel.md +25 -0
  377. package/skills/synap/document-embeds.md +141 -47
  378. package/skills/synap/escalation-ladder.md +20 -10
  379. package/skills/synap/focus-sessions.md +47 -21
  380. package/skills/synap/from-intent.md +142 -0
  381. package/skills/synap/governance-rules.md +4 -4
  382. package/skills/synap/governance.md +10 -7
  383. package/skills/synap/hand-off.md +33 -0
  384. package/skills/synap/inline-patterns.md +15 -7
  385. package/skills/synap/lenses.md +33 -15
  386. package/skills/synap/linking.md +41 -40
  387. package/skills/synap/mcp-remote-servers.md +64 -0
  388. package/skills/synap/mental-model.md +24 -22
  389. package/skills/synap/multi-entity-capture.md +6 -4
  390. package/skills/synap/operating-mode-rules.md +1 -1
  391. package/skills/synap/processes.md +118 -0
  392. package/skills/synap/quick-reference.md +5 -1
  393. package/skills/synap/reading.md +3 -1
  394. package/skills/synap/reflexes.md +12 -42
  395. package/skills/synap/viewframe-cells.md +38 -5
  396. package/skills/synap/work-flow.md +1 -1
  397. package/skills/synap/work-model.md +96 -0
  398. package/skills/synap/worked-examples.md +21 -1
  399. package/skills/synap/workspace-design.md +14 -10
  400. package/skills/synap/writes.md +165 -35
  401. package/skills/synap/writing-titles.md +63 -0
  402. package/skills/synap-app/SKILL.md +319 -0
  403. package/skills/synap-app/_order.txt +5 -0
  404. package/skills/synap-app/_skill.yaml +20 -0
  405. package/skills/synap-app/creating-the-base-app.md +64 -0
  406. package/skills/synap-app/governance.md +42 -0
  407. package/skills/synap-app/install-commands.md +55 -0
  408. package/skills/synap-app/overview.md +50 -0
  409. package/skills/synap-app/using-the-sdk.md +73 -0
  410. package/skills/synap-design/SKILL.md +474 -0
  411. package/skills/synap-design/_order.txt +4 -0
  412. package/skills/synap-design/_skill.yaml +21 -0
  413. package/skills/synap-design/loop.md +134 -0
  414. package/skills/synap-design/overview.md +44 -0
  415. package/skills/synap-design/principles.md +130 -0
  416. package/skills/synap-design/system.md +133 -0
  417. package/skills/synap-market/SKILL.md +625 -0
  418. package/skills/synap-market/_order.txt +5 -0
  419. package/skills/synap-market/_skill.yaml +24 -0
  420. package/skills/synap-market/author-and-publish.md +212 -0
  421. package/skills/synap-market/discover-and-fetch.md +59 -0
  422. package/skills/synap-market/governance-and-catalog.md +63 -0
  423. package/skills/synap-market/install.md +133 -0
  424. package/skills/synap-market/overview.md +119 -0
  425. package/skills/synap-schema/SKILL.md +172 -10
  426. package/skills/synap-schema/_order.txt +2 -0
  427. package/skills/synap-schema/_skill.yaml +4 -2
  428. package/skills/synap-schema/common-mistakes.md +4 -2
  429. package/skills/synap-schema/discover-profiles.md +1 -1
  430. package/skills/synap-schema/entity-scope.md +15 -3
  431. package/skills/synap-schema/extend-first.md +29 -0
  432. package/skills/synap-schema/extend-vs-create.md +1 -1
  433. package/skills/synap-schema/intent-vocabulary-ssot.md +111 -0
  434. package/skills/synap-schema/property-types.md +1 -1
  435. package/skills/synap-schema/relations.md +1 -1
  436. package/skills/synap-ui/SKILL.md +19 -12
  437. package/skills/synap-ui/_skill.yaml +1 -1
  438. package/skills/synap-ui/ai-companion.md +1 -1
  439. package/skills/synap-ui/arranging-bento.md +2 -0
  440. package/skills/synap-ui/bento-layouts.md +10 -10
  441. package/skills/synap-ui/bento-recipes.md +313 -543
  442. package/skills/synap-ui/four-builds.md +5 -0
  443. package/skills/synap-ui/view-types.md +2 -2
  444. package/skills/synap-ui/widget-catalog.md +22 -278
  445. package/templates/automations/bookmark-enrichment.automation.json +290 -13
  446. package/templates/automations/url-bookmark-capture.automation.json +73 -11
  447. package/templates/skills/authoring-playbooks/SKILL.md +6 -3
  448. package/templates/skills/authoring-playbooks/reference/stages-contract.md +15 -0
  449. package/templates/skills/authoring-playbooks/reference/worked-example.md +3 -0
  450. package/dist/commands/infra.d.ts +0 -21
  451. package/dist/commands/infra.js +0 -262
  452. package/dist/commands/infra.js.map +0 -1
  453. package/dist/lib/browser-auth.d.ts +0 -35
  454. package/dist/lib/browser-auth.js +0 -170
  455. package/dist/lib/browser-auth.js.map +0 -1
  456. package/dist/lib/openclaw.d.ts +0 -32
  457. package/dist/lib/openclaw.js +0 -164
  458. package/dist/lib/openclaw.js.map +0 -1
  459. package/dist/lib/seed.d.ts +0 -13
  460. package/dist/lib/seed.js +0 -135
  461. package/dist/lib/seed.js.map +0 -1
@@ -12,43 +12,168 @@
12
12
  * `engineering_knowledge`). A formal decision RECORD (rationale/alternatives/status
13
13
  * lifecycle) comes from smart `capture "<text>"` or `create entity --profile=decision`.
14
14
  *
15
- * Workspace routing: --workspace > --team (first product ws) > memory ws (default,
16
- * auto-approved, agent-private) > active ws.
15
+ * Workspace routing for Work-lane knowledge: --workspace (explicit pin) >
16
+ * --team (first product ws, when configured) > omit workspaceId (server-derived
17
+ * / pod-wide preferred). Never default-pin to the active profile workspace —
18
+ * that commonly is Pod Admin and would dump domain knowledge into admin.
17
19
  */
18
20
  import chalk from "chalk";
19
21
  import * as readline from "node:readline/promises";
20
22
  import { stdin as input, stdout as output } from "node:process";
21
23
  import { log } from "../utils/logger.js";
22
- import { resolveHubConfig, resolveUserId, hubPost, readActiveSessionId, renderHubError, } from "../lib/hub-client.js";
24
+ import { resolveHubConfig, resolveUserId, hubPost, hubGet, resolveActiveSessionId, renderHubError, } from "../lib/hub-client.js";
25
+ import { unwrapList } from "../lib/unwrapList.js";
23
26
  import { getAgentWorkspaceRouting } from "../lib/pod.js";
24
- import { laneFromSource, resolveWorkspaceName, formatLaneLine, laneJsonFields, } from "../lib/capture-lane.js";
27
+ import { resolvePodWide } from "../lib/pod-wide.js";
28
+ import { laneFromSource, resolveWorkspaceName, formatLaneLine, laneJsonFields, writeGovernance, } from "../lib/capture-lane.js";
29
+ import { isDegraded, degradedMessage, readCaptureExecute, formatWorkspaceRouting, formatPendingWorkspaceSwitch, headlessPlacementFields, projectRoutingHints, workspaceRoutingHints, } from "../lib/capture-structure.js";
30
+ import { UUID_RE } from "../lib/id.js";
31
+ import { chooseKnowledgeTitle } from "../lib/knowledge-title.js";
32
+ // ─── Client-side length guard ────────────────────────────────────────────────
33
+ // Captures used to die SERVER-SIDE with a raw "String length 1404 > maximum
34
+ // 1000" after the user had already composed + confirmed — surface the same
35
+ // caps client-side, BEFORE sending, so a too-long capture gets a heads-up
36
+ // instead of a mid-flight rejection. Not a hard block: --yes/--json paths and
37
+ // a declined truncation still send as-is and let the pod be the final judge
38
+ // (the caps below mirror the pod's contract but are not re-validated here).
39
+ //
40
+ // Mirrors:
41
+ // - synap-backend CaptureStructureRequestSchema.text
42
+ // (packages/api/src/routers/hub-protocol/rest/_codecs/misc.ts)
43
+ // - the `knowledge` profile's ek_claim/ek_why/ek_evidence property defs
44
+ // (packages/database/src/utils/ensure-system-profiles.ts)
45
+ const SMART_TEXT_MAX = 8000;
46
+ const CLAIM_MAX = 1000;
47
+ const WHY_MAX = 5000;
48
+ const EVIDENCE_MAX = 2000;
49
+ /**
50
+ * Warn when `value` exceeds `max`, and offer to truncate (interactive) or
51
+ * proceed as-is. Returns the value to send (possibly truncated), or
52
+ * `undefined` if the user aborted.
53
+ *
54
+ * Non-interactive (`--yes` / `--json`): warns to stderr and proceeds unchanged
55
+ * — this is a heads-up, not a client-side hard block; the pod is still free to
56
+ * accept a since-raised cap.
57
+ */
58
+ async function guardLength(label, value, max, opts) {
59
+ if (value.length <= max)
60
+ return value;
61
+ if (opts.yes || opts.json) {
62
+ log.warn(`${label} is ${value.length} chars (pod limit ~${max}) — sending as-is; the pod may reject it.`);
63
+ return value;
64
+ }
65
+ log.warn(`${label} is ${value.length} chars — the pod's limit is ~${max}.`);
66
+ const rl = readline.createInterface({ input, output });
67
+ try {
68
+ const answer = await rl.question(chalk.bold(` Truncate to ${max} chars and continue? [Y/n/(a)bort] `));
69
+ const a = answer.trim().toLowerCase();
70
+ if (a === "n" || a === "abort" || a === "a")
71
+ return undefined;
72
+ return value.slice(0, max);
73
+ }
74
+ finally {
75
+ rl.close();
76
+ }
77
+ }
25
78
  /**
26
79
  * Resolve the workspace for a DOMAIN capture (the `knowledge` entity, the Work
27
- * lane). Knowledge is workspace-scoped, so the destination IS the separation:
28
- * a Builder lesson stays in Builder, a marketing one in marketing.
80
+ * lane).
29
81
  *
30
- * Priority: --workspace > --team (first product ws) > active ws.
82
+ * Priority: --workspace (explicit pin) > --team (first product ws when
83
+ * configured) > omit workspaceId.
31
84
  *
32
- * NOTE: the agent-memory ("AI-self") lane was removed — the AI no longer dumps
33
- * captures into a private agent workspace. Everything it learns routes to a real
34
- * lane: Work (here), Global (`--global` → knowledge_keys), or User
35
- * (`record_observation` → user_observation). The per-adjunct memory workspace is
36
- * being decommissioned.
85
+ * Default is intentional omit: sending an ambient/active workspaceId is a
86
+ * backend rung-1 pin. Team profiles often default active workspace to Pod Admin,
87
+ * which dumped domain knowledge into admin. Leaving workspaceId out lets the
88
+ * server place knowledge (pod-wide preferred for knowledge kinds / AI routing on
89
+ * smart capture).
90
+ *
91
+ * NOTE: the agent-memory ("AI-self") lane was removed — everything routes to a
92
+ * real lane: Work (here), Global (`--global` → knowledge_keys), or User
93
+ * (`record_observation` → user_observation).
37
94
  */
38
- async function resolveKnowledgeWorkspace(opts, _cfg, activeWorkspaceId) {
95
+ async function resolveKnowledgeWorkspace(opts) {
39
96
  if (opts.workspace) {
40
97
  return { workspaceId: opts.workspace, source: "explicit" };
41
98
  }
42
99
  if (opts.team) {
43
100
  const routing = getAgentWorkspaceRouting();
44
101
  const teamWs = routing?.productWorkspaceIds?.[0];
45
- return { workspaceId: teamWs ?? activeWorkspaceId, source: teamWs ? "team" : "active (no team workspace configured)" };
102
+ if (teamWs) {
103
+ return { workspaceId: teamWs, source: "team" };
104
+ }
105
+ // --team asked for a product pin but none is configured: still omit.
106
+ // Do not fall back to active workspace (that reintroduces the Admin dump).
107
+ return {
108
+ workspaceId: undefined,
109
+ source: "server-derived (no team workspace configured — pod-wide preferred for knowledge)",
110
+ };
46
111
  }
47
112
  return {
48
- workspaceId: activeWorkspaceId,
49
- source: activeWorkspaceId ? "active" : "active (run `synap use <id>` to set a workspace)",
113
+ workspaceId: undefined,
114
+ source: "server-derived (pod-wide preferred for knowledge)",
50
115
  };
51
116
  }
117
+ /**
118
+ * Resolve a `--project` value (id or name) to a project id on the active pod.
119
+ * Mirrors `synap import`'s resolveProjectArg — same shape, same "not found"
120
+ * wording, kept local here since neither command shares a project-resolution
121
+ * lib yet. Throws on no match so a typo'd project name fails loud instead of
122
+ * silently dropping the pin.
123
+ */
124
+ async function resolveProjectArg(value, cfg) {
125
+ if (UUID_RE.test(value))
126
+ return value;
127
+ const res = (await hubGet("/projects", {}, cfg));
128
+ const list = unwrapList(res, ["projects"]);
129
+ const match = list.find((p) => String(p.name ?? "").toLowerCase() === value.toLowerCase());
130
+ if (!match) {
131
+ const names = list.map((p) => String(p.name ?? p.id)).join(", ");
132
+ throw new Error(`Project '${value}' not found.${names ? ` Available: ${names}` : ""}`);
133
+ }
134
+ return String(match.id);
135
+ }
136
+ /**
137
+ * Render the pod's project-link receipt honestly — never a bare "✓ stored"
138
+ * that hides a dropped project coordinate. Read DEFENSIVELY: the two write
139
+ * doors this command uses shape their receipt differently —
140
+ * - POST /capture/execute → `res.project = { projectId, rung, status }`
141
+ * - POST /entities → `res.writeReceipt.projectId` (present only once
142
+ * applied — omitted while the write is still a pending proposal)
143
+ * and the exact field name may still shift as the backend's receipt work
144
+ * lands, so this checks both shapes rather than assuming one.
145
+ */
146
+ function renderProjectReceipt(res, requestedProjectId, isProposed) {
147
+ if (!requestedProjectId)
148
+ return;
149
+ const captureProject = res.project;
150
+ if (captureProject?.projectId) {
151
+ if (captureProject.status === "linked") {
152
+ log.dim(` → linked to project ${captureProject.projectId.slice(0, 8)}`);
153
+ }
154
+ else if (captureProject.status === "proposed") {
155
+ log.dim(` → project ${captureProject.projectId.slice(0, 8)} proposed (advisory — awaiting confirm, not yet linked)`);
156
+ }
157
+ else {
158
+ log.dim(` → project ${captureProject.projectId.slice(0, 8)} (${captureProject.status ?? "unknown"})`);
159
+ }
160
+ return;
161
+ }
162
+ const writeReceipt = res.writeReceipt;
163
+ if (writeReceipt?.projectId) {
164
+ log.dim(` → linked to project ${writeReceipt.projectId.slice(0, 8)}`);
165
+ return;
166
+ }
167
+ if (isProposed) {
168
+ // The whole write is pending review — the project link rides along with
169
+ // it and applies on approval, not dropped.
170
+ log.dim(` → project ${requestedProjectId.slice(0, 8)} will link on approval (write is pending review)`);
171
+ return;
172
+ }
173
+ // A project pin was sent but no receipt confirms it — say so plainly rather
174
+ // than letting a silent drop look like success.
175
+ log.dim(` → project NOT linked (pod did not confirm ${requestedProjectId.slice(0, 8)} — it may not be reachable from this workspace)`);
176
+ }
52
177
  /** Slugify free text into a knowledge_keys slug fragment. */
53
178
  function slugify(text) {
54
179
  return text
@@ -101,12 +226,14 @@ async function captureGlobalRunbook(opts, cfg, authorUserId) {
101
226
  log.dim(` key: ${key}`);
102
227
  console.log(" " + formatLaneLine(report));
103
228
  }
229
+ // ─── Smart capture mode (no --type) ──────────────────────────────────────────
230
+ // Structure/execute wire shapes + the degraded/execute interpreters are shared
231
+ // with `synap import` in lib/capture-structure.ts (ONE mirror, no drift).
104
232
  /** Render the /capture/structure result as a compact human-readable summary. */
105
233
  function renderStructureResult(result) {
106
- const { proposals, relations, followUp, degraded } = result;
107
- if (degraded) {
108
- log.warn("AI structuring unavailable — degraded fallback.");
109
- }
234
+ const proposals = result.proposals ?? [];
235
+ const relations = result.relations ?? [];
236
+ const followUp = result.followUp;
110
237
  if (proposals.length === 0) {
111
238
  log.dim("No entity proposals extracted.");
112
239
  return;
@@ -140,11 +267,10 @@ function renderStructureResult(result) {
140
267
  }
141
268
  if (result.targetWorkspaceId || result.targetProjectId) {
142
269
  log.blank();
143
- if (result.targetWorkspaceId) {
144
- const conf = typeof result.targetWorkspaceConfidence === "number"
145
- ? ` (${Math.round(result.targetWorkspaceConfidence * 100)}%)`
146
- : "";
147
- log.dim(` → workspace: ${result.targetWorkspaceId}${conf}`);
270
+ const workspaceLine = formatWorkspaceRouting(result);
271
+ if (workspaceLine) {
272
+ // The pod's NAME for its pick, with its confidence once.
273
+ log.dim(` → workspace: ${workspaceLine}`);
148
274
  if (result.targetWorkspaceReason) {
149
275
  log.dim(` ${result.targetWorkspaceReason.slice(0, 90)}`);
150
276
  }
@@ -174,35 +300,92 @@ function renderStructureResult(result) {
174
300
  }
175
301
  }
176
302
  }
177
- async function runSmartCapture(text, opts) {
303
+ async function runSmartCapture(rawText, opts) {
304
+ const guarded = await guardLength("Capture text", rawText, SMART_TEXT_MAX, opts);
305
+ if (guarded === undefined) {
306
+ log.dim("Aborted.");
307
+ return;
308
+ }
309
+ const text = guarded;
178
310
  const cfg = await resolveHubConfig();
179
311
  const userId = await resolveUserId(cfg);
180
- const { workspaceId, source } = await resolveKnowledgeWorkspace(opts, cfg, cfg.workspaceId);
181
- if (!workspaceId) {
182
- console.error(chalk.red("No workspace set. Run:\n" +
183
- " synap connect (sets up memory + team workspace routing)\n" +
184
- " synap use <workspace-id> (manual override)"));
312
+ // Do NOT default-pin cfg.workspaceId — omit unless --workspace / --team.
313
+ const { workspaceId, source } = await resolveKnowledgeWorkspace(opts);
314
+ // Default Work-lane knowledge omits workspaceId so the pod can place it
315
+ // (AI routing on smart capture / pod-wide preferred for knowledge kinds).
316
+ if (!workspaceId && !opts.json) {
317
+ log.dim(` Placement: ${source} — workspaceId omitted.`);
318
+ log.dim(" Pin with --workspace <id> or --team (first product workspace).");
319
+ }
320
+ // Project pin: explicit --project (id or name) wins; otherwise the ambient
321
+ // lens (SYNAP_PROJECT_ID / the active Claude session's pinned project,
322
+ // already resolved into cfg.projectId by resolveHubConfig).
323
+ let projectId;
324
+ try {
325
+ projectId = opts.project ? await resolveProjectArg(opts.project, cfg) : cfg.projectId;
326
+ }
327
+ catch (e) {
328
+ console.error(chalk.red(e.message));
185
329
  process.exit(1);
186
330
  }
187
331
  // 1. Structure
188
- const smartSessionId = opts.session ? readActiveSessionId() : undefined;
189
- const structureBody = { userId, text, workspaceId, ...(smartSessionId ? { sessionId: smartSessionId } : {}) };
332
+ const smartSessionId = opts.session ? resolveActiveSessionId(cfg.podUrl) : undefined;
333
+ const structureBody = {
334
+ userId,
335
+ text,
336
+ ...(workspaceId ? { workspaceId } : {}),
337
+ ...(smartSessionId ? { sessionId: smartSessionId } : {}),
338
+ };
190
339
  const structureRes = await hubPost("/capture/structure", structureBody, cfg);
340
+ // Degraded: the IS structurer is down. The server returns a raw fallback-kind
341
+ // stand-in (`note`; `degraded: true` on the wire), but we create nothing (browser does the same via
342
+ // offlineFallback:false) — tell the user, don't silently downgrade the
343
+ // capture into an unstructured blob behind a success line.
344
+ if (isDegraded(structureRes)) {
345
+ if (opts.json) {
346
+ console.log(JSON.stringify({
347
+ degraded: true,
348
+ degradedReason: structureRes.degradedReason ?? null,
349
+ created: 0,
350
+ message: degradedMessage(structureRes),
351
+ }, null, 2));
352
+ }
353
+ else {
354
+ log.warn(degradedMessage(structureRes));
355
+ }
356
+ return;
357
+ }
191
358
  // Explicit --workspace is a deliberate pin: send it as-is, no AI routing hints.
192
359
  // Otherwise forward the AI's routing signal and let the backend decide
193
360
  // (auto = AI target wins over ambient when confidence is high enough AND the
194
- // user is a member). Project from structure is forwarded when present.
361
+ // user is a member).
195
362
  const isExplicitOverride = Boolean(opts.workspace);
363
+ // The AI's advice goes through the ONE structure → execute mapper
364
+ // (`captureExecuteRoutingHints`, mirrored in capture-structure.ts).
365
+ // Headless door: the structure step's PLACEMENT decides what is pinned
366
+ // (`headlessPlacementFields` — the ONE derivation, shared with the pod's own
367
+ // headless doors). A deterministic placement rides as an explicit
368
+ // `targetWorkspaceId`; an AI suggestion stays a proposal and is recorded as
369
+ // `workspaceChoice: "ignored"` — the CLI never shows it before saving.
196
370
  const routingFields = isExplicitOverride
197
371
  ? {}
198
372
  : {
199
373
  workspaceRouting: "auto",
200
- aiWorkspaceId: structureRes.targetWorkspaceId,
201
- aiWorkspaceConfidence: structureRes.targetWorkspaceConfidence,
202
- aiWorkspaceReason: structureRes.targetWorkspaceReason,
374
+ ...headlessPlacementFields(structureRes),
375
+ ...workspaceRoutingHints(structureRes),
203
376
  };
204
- if (structureRes.targetProjectId) {
205
- routingFields.projectId = structureRes.targetProjectId;
377
+ // Project: the explicit pin (--project / ambient lens) is the ONE
378
+ // deterministic field and always wins when present. The AI's own guess is
379
+ // forwarded ONLY as advisory (aiProjectId) — never promoted to the
380
+ // deterministic `projectId` field. That promotion was a real bug here
381
+ // (an AI guess would auto-link and widen cross-workspace access before the
382
+ // user ever confirmed it); the backend's aiProjectId path records it as a
383
+ // suggestion instead and never auto-links it.
384
+ if (projectId) {
385
+ routingFields.projectId = projectId;
386
+ }
387
+ else if (structureRes.targetProjectId) {
388
+ Object.assign(routingFields, projectRoutingHints(structureRes));
206
389
  }
207
390
  if (opts.json) {
208
391
  // --json without --yes: print structure result and exit
@@ -213,14 +396,19 @@ async function runSmartCapture(text, opts) {
213
396
  // --json + --yes: also execute and print combined result
214
397
  const executeRes = await hubPost("/capture/execute", {
215
398
  userId,
216
- workspaceId,
399
+ ...(workspaceId ? { workspaceId } : {}),
217
400
  ...(smartSessionId ? { sessionId: smartSessionId } : {}),
218
401
  ...routingFields,
219
402
  entities: structureRes.proposals,
220
403
  relations: structureRes.relations ?? [],
221
404
  }, cfg);
222
405
  const report = await buildSmartLaneReport(executeRes, workspaceId, source, cfg);
223
- console.log(JSON.stringify({ structure: structureRes, execute: executeRes, ...laneJsonFields(report) }, null, 2));
406
+ console.log(JSON.stringify({
407
+ structure: structureRes,
408
+ execute: executeRes,
409
+ ...(projectId ? { requestedProjectId: projectId } : {}),
410
+ ...laneJsonFields(report),
411
+ }, null, 2));
224
412
  return;
225
413
  }
226
414
  // 2. Render proposals
@@ -248,39 +436,52 @@ async function runSmartCapture(text, opts) {
248
436
  // 4. Execute
249
437
  const executeRes = await hubPost("/capture/execute", {
250
438
  userId,
251
- workspaceId,
439
+ ...(workspaceId ? { workspaceId } : {}),
252
440
  ...(smartSessionId ? { sessionId: smartSessionId } : {}),
253
441
  ...routingFields,
254
442
  entities: structureRes.proposals,
255
443
  relations: structureRes.relations ?? [],
256
444
  }, cfg);
257
- const created = executeRes.entitiesCreated
258
- ?? executeRes.created
259
- ?? count;
260
- log.success(`${created} entr${created !== 1 ? "ies" : "y"} created.`);
261
- if (executeRes.relationsCreated) {
262
- log.dim(` ${executeRes.relationsCreated} relation${Number(executeRes.relationsCreated) !== 1 ? "s" : ""} created.`);
445
+ // Report what the pod ACTUALLY returned — applied vs proposed vs
446
+ // nothing-new — never the planned proposal count.
447
+ const outcome = readCaptureExecute(executeRes);
448
+ const report = await buildSmartLaneReport(executeRes, workspaceId, source, cfg);
449
+ if (outcome.proposed) {
450
+ log.info("Capture proposed — under review, not yet stored.");
451
+ if (outcome.proposalId)
452
+ log.dim(` proposal: ${outcome.proposalId}`);
453
+ if (outcome.reviewUrl)
454
+ log.dim(` review: ${outcome.reviewUrl}`);
263
455
  }
264
- if (executeRes.movedToWorkspace) {
265
- log.dim(` → filed into workspace ${String(executeRes.movedToWorkspace)}`);
456
+ else {
457
+ const n = outcome.entitiesCreated;
458
+ log.success(`${n} entr${n !== 1 ? "ies" : "y"} created.`);
459
+ if (outcome.entitiesLinked) {
460
+ log.dim(` ${outcome.entitiesLinked} linked to existing entit${outcome.entitiesLinked !== 1 ? "ies" : "y"}.`);
461
+ }
462
+ if (outcome.relationsCreated) {
463
+ log.dim(` ${outcome.relationsCreated} relation${outcome.relationsCreated !== 1 ? "s" : ""} created.`);
464
+ }
465
+ const pending = formatPendingWorkspaceSwitch(outcome);
466
+ if (pending)
467
+ log.dim(` ${pending}`);
266
468
  }
267
- const report = await buildSmartLaneReport(executeRes, workspaceId, source, cfg);
268
469
  console.log(" " + formatLaneLine(report));
470
+ renderProjectReceipt(executeRes, projectId, outcome.proposed);
269
471
  }
270
472
  /**
271
- * Build the lane report for a smart-capture execute response. Smart capture may
272
- * land directly or be queued as proposals — detect the latter from the execute
273
- * payload (proposed/proposalsCreated/status) and fall back to auto otherwise.
473
+ * Build the lane report for a smart-capture execute response. Governance
474
+ * (auto vs proposed) is derived by the ONE shared interpreter so this doesn't
475
+ * re-implement a third detector.
274
476
  */
275
477
  async function buildSmartLaneReport(executeRes, workspaceId, source, cfg) {
276
- const isProposed = executeRes.status === "proposed" ||
277
- Boolean(executeRes.proposalId) ||
278
- Number(executeRes.proposalsCreated ?? 0) > 0;
279
478
  return {
280
479
  lane: laneFromSource(source),
281
480
  workspaceId,
282
- workspaceName: await resolveWorkspaceName(workspaceId, cfg),
283
- governance: isProposed ? "proposed" : "auto",
481
+ workspaceName: workspaceId
482
+ ? await resolveWorkspaceName(workspaceId, cfg)
483
+ : "server-derived (pod-wide preferred)",
484
+ governance: readCaptureExecute(executeRes).proposed ? "proposed" : "auto",
284
485
  };
285
486
  }
286
487
  // ─── Legacy engineering-memory capture ────────────────────────────────────────
@@ -308,67 +509,132 @@ export async function captureKnowledge(opts) {
308
509
  console.error(chalk.red("Missing required option: --claim <text>"));
309
510
  process.exit(1);
310
511
  }
512
+ // Client-side length guard — catch the "String length N > maximum 1000"
513
+ // server rejection BEFORE it fires, with a chance to truncate/abort
514
+ // instead of a mid-flight failure after composing + confirming.
515
+ const guardedClaim = await guardLength("--claim", opts.claim, CLAIM_MAX, opts);
516
+ if (guardedClaim === undefined) {
517
+ log.dim("Aborted.");
518
+ return;
519
+ }
520
+ opts.claim = guardedClaim;
521
+ if (opts.why) {
522
+ const guardedWhy = await guardLength("--why", opts.why, WHY_MAX, opts);
523
+ if (guardedWhy === undefined) {
524
+ log.dim("Aborted.");
525
+ return;
526
+ }
527
+ opts.why = guardedWhy;
528
+ }
529
+ if (opts.evidence) {
530
+ const guardedEvidence = await guardLength("--evidence", opts.evidence, EVIDENCE_MAX, opts);
531
+ if (guardedEvidence === undefined) {
532
+ log.dim("Aborted.");
533
+ return;
534
+ }
535
+ opts.evidence = guardedEvidence;
536
+ }
311
537
  const cfg = await resolveHubConfig();
312
538
  const userId = await resolveUserId(cfg);
313
539
  // GLOBAL lane: pod-wide procedural runbook → knowledge_keys.
314
- if (opts.global) {
540
+ // Canonical spelling is `--pod-wide`; `--global` is the retained alias.
541
+ if (resolvePodWide(opts)) {
315
542
  await captureGlobalRunbook(opts, cfg, userId);
316
543
  return;
317
544
  }
318
- const { workspaceId, source } = await resolveKnowledgeWorkspace(opts, cfg, cfg.workspaceId);
319
- if (!workspaceId) {
320
- console.error(chalk.red("No workspace set. Run:\n" +
321
- " synap connect (sets up memory + team workspace routing)\n" +
322
- " synap use <workspace-id> (manual override)"));
545
+ // Do NOT default-pin cfg.workspaceId — omit unless --workspace / --team.
546
+ const { workspaceId, source } = await resolveKnowledgeWorkspace(opts);
547
+ // Default Work-lane knowledge omits workspaceId so the pod can place it
548
+ // (server-derived / pod-wide preferred for knowledge kinds).
549
+ if (!workspaceId && !opts.json) {
550
+ log.dim(` Placement: ${source} — workspaceId omitted.`);
551
+ log.dim(" Pin with --workspace <id> or --team (first product workspace).");
552
+ }
553
+ // Project pin: explicit --project (id or name) wins; otherwise the ambient
554
+ // lens already resolved by resolveHubConfig (SYNAP_PROJECT_ID / the active
555
+ // Claude session's pinned project). Previously this coordinate was simply
556
+ // dropped by `capture` — --pod resolved url+key but never the project lens.
557
+ let projectId;
558
+ try {
559
+ projectId = opts.project ? await resolveProjectArg(opts.project, cfg) : cfg.projectId;
560
+ }
561
+ catch (e) {
562
+ console.error(chalk.red(e.message));
323
563
  process.exit(1);
324
564
  }
325
565
  const tags = opts.tags
326
566
  ? opts.tags.split(",").map((t) => t.trim()).filter(Boolean)
327
567
  : [];
328
- const title = opts.claim.slice(0, 120);
568
+ // A title is a short NAME; the claim itself stays in `ek_claim`.
569
+ const chosen = chooseKnowledgeTitle(opts.claim, opts.title);
570
+ if (!chosen.ok) {
571
+ console.error(chalk.red(chosen.reason));
572
+ process.exit(1);
573
+ }
574
+ const title = chosen.title;
329
575
  // Every --type entry is a typed `knowledge` entity; ek_type discriminates the
330
576
  // kind. This is "one store, type tags" (the research-canonical pattern) — NOT a
331
577
  // residual catch-all: each row is typed by ek_type and lives in the workspace
332
578
  // lens that supplies its domain (so no `engineering_knowledge`). A structured
333
579
  // decision RECORD (rationale/alternatives/status) is a different artifact, reached
334
580
  // via smart `capture "<text>"` or `create entity --profile=decision`.
335
- const sessionId = opts.session ? readActiveSessionId() : undefined;
581
+ const sessionId = opts.session ? resolveActiveSessionId(cfg.podUrl) : undefined;
336
582
  const res = await hubPost("/entities", {
337
583
  userId,
338
- workspaceId,
584
+ ...(workspaceId ? { workspaceId } : {}),
339
585
  profileSlug: "knowledge",
340
586
  title,
341
587
  ...(sessionId ? { sessionId } : {}),
588
+ ...(projectId ? { projectId } : {}),
342
589
  properties: {
590
+ knowledgeForm: opts.type === "gotcha" ? "caution" : "insight",
343
591
  ek_type: opts.type,
344
592
  ek_claim: opts.claim,
345
593
  ...(opts.why ? { ek_why: opts.why } : {}),
346
594
  ...(opts.evidence ? { ek_evidence: opts.evidence } : {}),
347
595
  ...(tags.length > 0 ? { ek_tags: tags } : {}),
348
596
  },
597
+ ...(opts.content?.trim().length ? { content: opts.content } : {}),
349
598
  }, cfg);
350
- // Governance may queue the write as a proposal rather than creating directly
351
- const isProposed = res.status === "proposed" || Boolean(res.proposalId);
599
+ // Governance may queue the write as a proposal rather than creating
600
+ // directly — read the real outcome via the ONE shared detector.
601
+ const isProposed = writeGovernance(res) === "proposed";
602
+ // The pod's title rubric verdict (absent when the title is clean).
603
+ const titleLint = readTitleLint(res);
352
604
  // Declare which lane + workspace + governance this capture took, so the
353
605
  // caller always knows where its knowledge landed.
354
606
  const report = {
355
607
  lane: laneFromSource(source),
356
608
  workspaceId,
357
- workspaceName: await resolveWorkspaceName(workspaceId, cfg),
609
+ workspaceName: workspaceId
610
+ ? await resolveWorkspaceName(workspaceId, cfg)
611
+ : "server-derived (pod-wide preferred)",
358
612
  governance: isProposed ? "proposed" : "auto",
359
613
  };
360
614
  if (opts.json) {
615
+ const writeReceipt = res.writeReceipt;
361
616
  if (isProposed) {
362
617
  console.log(JSON.stringify({
363
618
  proposed: true,
364
619
  proposalId: res.proposalId ?? res.id,
365
620
  reviewUrl: res.reviewUrl ?? null,
366
621
  message: "Write queued for approval — not yet stored.",
622
+ title,
623
+ ...(titleLint.length ? { titleLint } : {}),
624
+ ...(projectId ? { requestedProjectId: projectId } : {}),
367
625
  ...laneJsonFields(report),
368
626
  }, null, 2));
369
627
  }
370
628
  else {
371
- console.log(JSON.stringify({ id: res.id, stored: true, workspace: source, ...laneJsonFields(report) }, null, 2));
629
+ console.log(JSON.stringify({
630
+ id: res.id,
631
+ stored: true,
632
+ title,
633
+ ...(titleLint.length ? { titleLint } : {}),
634
+ workspace: source,
635
+ ...(projectId ? { requestedProjectId: projectId, linkedProjectId: writeReceipt?.projectId ?? null } : {}),
636
+ ...laneJsonFields(report),
637
+ }, null, 2));
372
638
  }
373
639
  return;
374
640
  }
@@ -380,18 +646,37 @@ export async function captureKnowledge(opts) {
380
646
  else
381
647
  log.dim(` Open Synap and approve the pending proposal to persist this entry.`);
382
648
  console.log(" " + formatLaneLine(report));
649
+ renderProjectReceipt(res, projectId, true);
383
650
  }
384
651
  else {
385
- log.success(`[${opts.type}] ${opts.claim.slice(0, 80)}`);
652
+ log.success(`[${opts.type}] ${title}`);
386
653
  log.dim(` workspace: ${source} id: ${String(res.id ?? "")}`);
387
654
  console.log(" " + formatLaneLine(report));
655
+ renderProjectReceipt(res, projectId, false);
388
656
  }
657
+ renderTitleLint(titleLint);
389
658
  }
390
659
  catch (e) {
391
660
  renderHubError(e);
392
661
  process.exit(1);
393
662
  }
394
663
  }
664
+ /** `writeReceipt.titleLint` from a POST /entities response; [] when clean or absent. */
665
+ export function readTitleLint(res) {
666
+ const receipt = res.writeReceipt;
667
+ const raw = Array.isArray(receipt?.titleLint) ? receipt.titleLint : [];
668
+ return raw.filter((i) => !!i && typeof i === "object" && typeof i.message === "string");
669
+ }
670
+ /** Tell the writer what to rewrite — the title was stored as sent. */
671
+ function renderTitleLint(issues) {
672
+ const defects = issues.filter((i) => i.severity === "defect");
673
+ if (!defects.length)
674
+ return;
675
+ log.warn(" Title stored as sent, but it should be rewritten:");
676
+ for (const i of defects)
677
+ log.dim(` - ${i.message}`);
678
+ log.dim(` Rewrite it with the MCP tool synap_update_entity (title), and pass --title next time.`);
679
+ }
395
680
  export async function provisionAgentWorkspace(opts) {
396
681
  try {
397
682
  const cfg = await resolveHubConfig();