@synap-core/cli 1.8.0 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (372) hide show
  1. package/dist/commands/agent-chat.d.ts +47 -0
  2. package/dist/commands/agent-chat.js +250 -0
  3. package/dist/commands/agent-chat.js.map +1 -0
  4. package/dist/commands/agent-run.js +3 -4
  5. package/dist/commands/agent-run.js.map +1 -1
  6. package/dist/commands/agents.js +85 -46
  7. package/dist/commands/agents.js.map +1 -1
  8. package/dist/commands/automation.js +2 -1
  9. package/dist/commands/automation.js.map +1 -1
  10. package/dist/commands/bridge-setup.d.ts +66 -0
  11. package/dist/commands/bridge-setup.js +1112 -0
  12. package/dist/commands/bridge-setup.js.map +1 -0
  13. package/dist/commands/cap-connections.d.ts +28 -0
  14. package/dist/commands/cap-connections.js +224 -0
  15. package/dist/commands/cap-connections.js.map +1 -0
  16. package/dist/commands/capability.d.ts +89 -0
  17. package/dist/commands/capability.js +1594 -0
  18. package/dist/commands/capability.js.map +1 -0
  19. package/dist/commands/centrality.d.ts +20 -0
  20. package/dist/commands/centrality.js +95 -0
  21. package/dist/commands/centrality.js.map +1 -0
  22. package/dist/commands/connect.d.ts +2 -0
  23. package/dist/commands/connect.js +16 -35
  24. package/dist/commands/connect.js.map +1 -1
  25. package/dist/commands/context.js +6 -7
  26. package/dist/commands/context.js.map +1 -1
  27. package/dist/commands/data-extra.d.ts +1 -0
  28. package/dist/commands/data-extra.js +41 -14
  29. package/dist/commands/data-extra.js.map +1 -1
  30. package/dist/commands/data.d.ts +4 -4
  31. package/dist/commands/data.js +254 -187
  32. package/dist/commands/data.js.map +1 -1
  33. package/dist/commands/diagnose.d.ts +20 -0
  34. package/dist/commands/diagnose.js +186 -0
  35. package/dist/commands/diagnose.js.map +1 -0
  36. package/dist/commands/digest.d.ts +17 -0
  37. package/dist/commands/digest.js +122 -0
  38. package/dist/commands/digest.js.map +1 -0
  39. package/dist/commands/discover.d.ts +2 -0
  40. package/dist/commands/discover.js +25 -8
  41. package/dist/commands/discover.js.map +1 -1
  42. package/dist/commands/doc.d.ts +14 -0
  43. package/dist/commands/doc.js +61 -4
  44. package/dist/commands/doc.js.map +1 -1
  45. package/dist/commands/doctor.d.ts +21 -0
  46. package/dist/commands/doctor.js +189 -0
  47. package/dist/commands/doctor.js.map +1 -0
  48. package/dist/commands/events.js +5 -2
  49. package/dist/commands/events.js.map +1 -1
  50. package/dist/commands/explain.d.ts +1 -1
  51. package/dist/commands/explain.js +18 -15
  52. package/dist/commands/explain.js.map +1 -1
  53. package/dist/commands/facet.d.ts +29 -0
  54. package/dist/commands/facet.js +113 -0
  55. package/dist/commands/facet.js.map +1 -0
  56. package/dist/commands/graph.js +7 -4
  57. package/dist/commands/graph.js.map +1 -1
  58. package/dist/commands/import.d.ts +38 -0
  59. package/dist/commands/import.js +471 -0
  60. package/dist/commands/import.js.map +1 -0
  61. package/dist/commands/init.js +35 -16
  62. package/dist/commands/init.js.map +1 -1
  63. package/dist/commands/keys.js +3 -4
  64. package/dist/commands/keys.js.map +1 -1
  65. package/dist/commands/knowledge.d.ts +8 -0
  66. package/dist/commands/knowledge.js +308 -33
  67. package/dist/commands/knowledge.js.map +1 -1
  68. package/dist/commands/launch.d.ts +50 -0
  69. package/dist/commands/launch.js +790 -0
  70. package/dist/commands/launch.js.map +1 -0
  71. package/dist/commands/lens.d.ts +45 -0
  72. package/dist/commands/lens.js +386 -0
  73. package/dist/commands/lens.js.map +1 -0
  74. package/dist/commands/market-authoring.d.ts +45 -0
  75. package/dist/commands/market-authoring.js +225 -0
  76. package/dist/commands/market-authoring.js.map +1 -0
  77. package/dist/commands/market.d.ts +224 -0
  78. package/dist/commands/market.js +1643 -0
  79. package/dist/commands/market.js.map +1 -0
  80. package/dist/commands/mcp.d.ts +64 -0
  81. package/dist/commands/mcp.js +265 -0
  82. package/dist/commands/mcp.js.map +1 -0
  83. package/dist/commands/observe.js +14 -11
  84. package/dist/commands/observe.js.map +1 -1
  85. package/dist/commands/open.d.ts +21 -4
  86. package/dist/commands/open.js +45 -4
  87. package/dist/commands/open.js.map +1 -1
  88. package/dist/commands/pod.d.ts +100 -0
  89. package/dist/commands/pod.js +359 -0
  90. package/dist/commands/pod.js.map +1 -0
  91. package/dist/commands/pods.d.ts +15 -0
  92. package/dist/commands/pods.js +233 -17
  93. package/dist/commands/pods.js.map +1 -1
  94. package/dist/commands/proposals-actions.js +43 -3
  95. package/dist/commands/proposals-actions.js.map +1 -1
  96. package/dist/commands/purge.d.ts +23 -0
  97. package/dist/commands/purge.js +148 -0
  98. package/dist/commands/purge.js.map +1 -0
  99. package/dist/commands/raycast.d.ts +15 -0
  100. package/dist/commands/raycast.js +153 -0
  101. package/dist/commands/raycast.js.map +1 -0
  102. package/dist/commands/sessions.js +47 -22
  103. package/dist/commands/sessions.js.map +1 -1
  104. package/dist/commands/skill-manage.d.ts +21 -0
  105. package/dist/commands/skill-manage.js +195 -0
  106. package/dist/commands/skill-manage.js.map +1 -0
  107. package/dist/commands/skills-commands.js +2 -1
  108. package/dist/commands/skills-commands.js.map +1 -1
  109. package/dist/commands/skills.js +7 -4
  110. package/dist/commands/skills.js.map +1 -1
  111. package/dist/commands/status.d.ts +3 -1
  112. package/dist/commands/status.js +166 -14
  113. package/dist/commands/status.js.map +1 -1
  114. package/dist/commands/statusline.d.ts +24 -0
  115. package/dist/commands/statusline.js +450 -0
  116. package/dist/commands/statusline.js.map +1 -0
  117. package/dist/commands/subscribe.js +2 -2
  118. package/dist/commands/subscribe.js.map +1 -1
  119. package/dist/commands/template.d.ts +42 -0
  120. package/dist/commands/template.js +191 -0
  121. package/dist/commands/template.js.map +1 -0
  122. package/dist/commands/tools.d.ts +30 -0
  123. package/dist/commands/tools.js +315 -0
  124. package/dist/commands/tools.js.map +1 -0
  125. package/dist/commands/upload.d.ts +30 -0
  126. package/dist/commands/upload.js +155 -0
  127. package/dist/commands/upload.js.map +1 -0
  128. package/dist/commands/versions.d.ts +27 -0
  129. package/dist/commands/versions.js +277 -0
  130. package/dist/commands/versions.js.map +1 -0
  131. package/dist/commands/view.js +3 -2
  132. package/dist/commands/view.js.map +1 -1
  133. package/dist/commands/whoami.d.ts +21 -0
  134. package/dist/commands/whoami.js +129 -0
  135. package/dist/commands/whoami.js.map +1 -0
  136. package/dist/index.js +894 -60
  137. package/dist/index.js.map +1 -1
  138. package/dist/lib/approval-poll.d.ts +42 -0
  139. package/dist/lib/approval-poll.js +52 -0
  140. package/dist/lib/approval-poll.js.map +1 -0
  141. package/dist/lib/auth.d.ts +29 -6
  142. package/dist/lib/auth.js +105 -94
  143. package/dist/lib/auth.js.map +1 -1
  144. package/dist/lib/bundle-version.d.ts +11 -0
  145. package/dist/lib/bundle-version.js +33 -0
  146. package/dist/lib/bundle-version.js.map +1 -0
  147. package/dist/lib/capture-lane.d.ts +30 -12
  148. package/dist/lib/capture-lane.js +73 -14
  149. package/dist/lib/capture-lane.js.map +1 -1
  150. package/dist/lib/capture-structure.d.ts +123 -0
  151. package/dist/lib/capture-structure.js +57 -0
  152. package/dist/lib/capture-structure.js.map +1 -0
  153. package/dist/lib/cp-packages.d.ts +177 -0
  154. package/dist/lib/cp-packages.js +389 -0
  155. package/dist/lib/cp-packages.js.map +1 -0
  156. package/dist/lib/describe-lens.d.ts +46 -0
  157. package/dist/lib/describe-lens.js +33 -0
  158. package/dist/lib/describe-lens.js.map +1 -0
  159. package/dist/lib/hub-client.d.ts +91 -1
  160. package/dist/lib/hub-client.js +565 -22
  161. package/dist/lib/hub-client.js.map +1 -1
  162. package/dist/lib/id.d.ts +23 -0
  163. package/dist/lib/id.js +35 -0
  164. package/dist/lib/id.js.map +1 -0
  165. package/dist/lib/installed.d.ts +51 -0
  166. package/dist/lib/installed.js +70 -0
  167. package/dist/lib/installed.js.map +1 -0
  168. package/dist/lib/next-steps.d.ts +61 -0
  169. package/dist/lib/next-steps.js +146 -0
  170. package/dist/lib/next-steps.js.map +1 -0
  171. package/dist/lib/pod.d.ts +144 -22
  172. package/dist/lib/pod.js +302 -64
  173. package/dist/lib/pod.js.map +1 -1
  174. package/dist/lib/project-ref.d.ts +95 -0
  175. package/dist/lib/project-ref.js +144 -0
  176. package/dist/lib/project-ref.js.map +1 -0
  177. package/dist/lib/project.d.ts +35 -0
  178. package/dist/lib/project.js +39 -0
  179. package/dist/lib/project.js.map +1 -0
  180. package/dist/lib/session-lens.d.ts +33 -0
  181. package/dist/lib/session-lens.js +76 -0
  182. package/dist/lib/session-lens.js.map +1 -0
  183. package/dist/lib/skill-import.d.ts +40 -0
  184. package/dist/lib/skill-import.js +203 -0
  185. package/dist/lib/skill-import.js.map +1 -0
  186. package/dist/lib/skills-installer.d.ts +17 -6
  187. package/dist/lib/skills-installer.js +133 -19
  188. package/dist/lib/skills-installer.js.map +1 -1
  189. package/dist/lib/suite.d.ts +28 -0
  190. package/dist/lib/suite.js +29 -0
  191. package/dist/lib/suite.js.map +1 -0
  192. package/dist/lib/superwhisper-import.d.ts +40 -0
  193. package/dist/lib/superwhisper-import.js +389 -0
  194. package/dist/lib/superwhisper-import.js.map +1 -0
  195. package/dist/lib/targets.d.ts +49 -1
  196. package/dist/lib/targets.js +420 -288
  197. package/dist/lib/targets.js.map +1 -1
  198. package/dist/lib/template-file.d.ts +74 -0
  199. package/dist/lib/template-file.js +140 -0
  200. package/dist/lib/template-file.js.map +1 -0
  201. package/dist/lib/unwrapList.d.ts +1 -0
  202. package/dist/lib/unwrapList.js +20 -0
  203. package/dist/lib/unwrapList.js.map +1 -0
  204. package/dist/utils/logger.d.ts +2 -0
  205. package/dist/utils/logger.js +10 -2
  206. package/dist/utils/logger.js.map +1 -1
  207. package/node_modules/@synap/hub-rest-client/dist/index.cjs +414 -34
  208. package/node_modules/@synap/hub-rest-client/dist/index.d.cts +762 -22
  209. package/node_modules/@synap/hub-rest-client/dist/index.d.ts +762 -22
  210. package/node_modules/@synap/hub-rest-client/dist/index.js +414 -34
  211. package/node_modules/@synap/hub-rest-client/package.json +1 -1
  212. package/node_modules/@synap/hub-rest-client/src/client.ts +525 -37
  213. package/node_modules/@synap/hub-rest-client/src/index.ts +42 -0
  214. package/node_modules/@synap/hub-rest-client/src/setup.ts +57 -1
  215. package/node_modules/@synap/hub-rest-client/src/types.ts +697 -37
  216. package/package.json +11 -5
  217. package/skills/agent-os/SKILL.md +218 -0
  218. package/skills/manifest.json +5 -0
  219. package/skills/onboard/SKILL.md +193 -0
  220. package/skills/synap/SKILL.md +1284 -58
  221. package/skills/synap/_order.txt +37 -0
  222. package/skills/synap/_skill.yaml +24 -0
  223. package/skills/synap/authentication.md +10 -0
  224. package/skills/synap/automations.md +264 -0
  225. package/skills/synap/capabilities.md +107 -0
  226. package/skills/synap/capture.md +50 -142
  227. package/skills/synap/cli-operations.md +107 -0
  228. package/skills/synap/common-mistakes.md +13 -0
  229. package/skills/synap/content-os.md +83 -0
  230. package/skills/synap/creative-loop.md +43 -0
  231. package/skills/synap/crm.md +117 -0
  232. package/skills/synap/diagnostics.md +35 -0
  233. package/skills/synap/digesting-a-channel.md +63 -0
  234. package/skills/synap/document-embeds.md +123 -0
  235. package/skills/synap/escalation-ladder.md +71 -0
  236. package/skills/synap/focus-sessions.md +47 -0
  237. package/skills/synap/governance-rules.md +64 -0
  238. package/skills/synap/governance.md +6 -6
  239. package/skills/synap/graph-gardening.md +21 -0
  240. package/skills/synap/inline-patterns.md +38 -0
  241. package/skills/synap/lenses.md +38 -0
  242. package/skills/synap/linking-principle.md +39 -0
  243. package/skills/synap/linking.md +1 -0
  244. package/skills/synap/mental-model.md +45 -0
  245. package/skills/synap/more.md +7 -0
  246. package/skills/synap/multi-entity-capture.md +12 -0
  247. package/skills/synap/next-action.md +37 -0
  248. package/skills/synap/north-star.md +17 -0
  249. package/skills/synap/operating-mode-rules.md +45 -0
  250. package/skills/synap/operating-mode.md +9 -0
  251. package/skills/synap/quick-reference.md +67 -0
  252. package/skills/synap/reading.md +43 -0
  253. package/skills/synap/recap.md +21 -0
  254. package/skills/synap/reflexes.md +46 -0
  255. package/skills/synap/response-style.md +21 -0
  256. package/skills/synap/scope.md +13 -0
  257. package/skills/synap/showing.md +17 -0
  258. package/skills/synap/user-model.md +25 -0
  259. package/skills/synap/viewframe-cells.md +290 -0
  260. package/skills/synap/work-flow.md +113 -0
  261. package/skills/synap/worked-examples.md +74 -0
  262. package/skills/synap/workspace-design.md +45 -0
  263. package/skills/synap/workspace-edges.md +49 -0
  264. package/skills/synap/writes.md +213 -0
  265. package/skills/synap-app/SKILL.md +319 -0
  266. package/skills/synap-app/_order.txt +5 -0
  267. package/skills/synap-app/_skill.yaml +20 -0
  268. package/skills/synap-app/creating-the-base-app.md +64 -0
  269. package/skills/synap-app/governance.md +42 -0
  270. package/skills/synap-app/install-commands.md +55 -0
  271. package/skills/synap-app/overview.md +50 -0
  272. package/skills/synap-app/using-the-sdk.md +73 -0
  273. package/skills/synap-market/SKILL.md +335 -0
  274. package/skills/synap-market/_order.txt +5 -0
  275. package/skills/synap-market/_skill.yaml +24 -0
  276. package/skills/synap-market/author-and-publish.md +75 -0
  277. package/skills/synap-market/discover-and-fetch.md +59 -0
  278. package/skills/synap-market/governance-and-catalog.md +56 -0
  279. package/skills/synap-market/install.md +55 -0
  280. package/skills/synap-market/overview.md +51 -0
  281. package/skills/synap-schema/SKILL.md +97 -6
  282. package/skills/synap-schema/_order.txt +13 -0
  283. package/skills/synap-schema/_skill.yaml +22 -0
  284. package/skills/synap-schema/before-you-touch.md +14 -0
  285. package/skills/synap-schema/common-mistakes.md +9 -0
  286. package/skills/synap-schema/creating-profiles.md +17 -0
  287. package/skills/synap-schema/discover-profiles.md +24 -0
  288. package/skills/synap-schema/entity-scope.md +8 -0
  289. package/skills/synap-schema/extend-vs-create.md +31 -0
  290. package/skills/synap-schema/more.md +6 -0
  291. package/skills/synap-schema/overlay-properties.md +22 -0
  292. package/skills/synap-schema/profiles.md +3 -0
  293. package/skills/synap-schema/property-defs.md +29 -0
  294. package/skills/synap-schema/read-before-write.md +50 -0
  295. package/skills/synap-schema/relations.md +18 -0
  296. package/skills/synap-schema/worked-example.md +30 -0
  297. package/skills/synap-ui/SKILL.md +26 -2
  298. package/skills/synap-ui/_order.txt +13 -0
  299. package/skills/synap-ui/_skill.yaml +23 -0
  300. package/skills/synap-ui/ai-companion.md +27 -0
  301. package/skills/synap-ui/arranging-bento.md +8 -0
  302. package/skills/synap-ui/before-you-build.md +20 -0
  303. package/skills/synap-ui/bento-layouts.md +35 -0
  304. package/skills/synap-ui/common-mistakes.md +10 -0
  305. package/skills/synap-ui/creating-views.md +26 -0
  306. package/skills/synap-ui/four-builds.md +24 -0
  307. package/skills/synap-ui/more.md +7 -0
  308. package/skills/synap-ui/proposing-vs-extending.md +11 -0
  309. package/skills/synap-ui/view-list.md +24 -0
  310. package/skills/synap-ui/views.md +3 -0
  311. package/skills/synap-ui/worked-example.md +18 -0
  312. package/skills/synap-ui/workspaces.md +47 -0
  313. package/templates/automations/bookmark-enrichment.automation.json +44 -0
  314. package/templates/automations/mail-feed.automation.json +86 -0
  315. package/templates/automations/url-bookmark-capture.automation.json +70 -0
  316. package/templates/skills/README.md +21 -0
  317. package/templates/skills/authoring-automations/SKILL.md +95 -0
  318. package/templates/skills/authoring-automations/reference/node-matrix.md +49 -0
  319. package/templates/skills/authoring-capabilities/SKILL.md +93 -0
  320. package/templates/skills/authoring-capabilities/reference/template-anatomy.md +70 -0
  321. package/templates/skills/authoring-playbooks/SKILL.md +102 -0
  322. package/templates/skills/authoring-playbooks/reference/stages-contract.md +35 -0
  323. package/templates/skills/authoring-playbooks/reference/worked-example.md +64 -0
  324. package/templates/skills/bookmark-enrichment/SKILL.md +40 -0
  325. package/templates/skills/coordinating-agents/SKILL.md +32 -0
  326. package/templates/skills/coordinating-branches/SKILL.md +27 -0
  327. package/templates/skills/mapping-the-server/SKILL.md +54 -0
  328. package/templates/skills/reading-client-progress/SKILL.md +65 -0
  329. package/templates/skills/routing-to-channels/SKILL.md +54 -0
  330. package/templates/skills/stellar-scf-grants-advisor/ASSOCIATE-CHEATSHEET.md +133 -0
  331. package/templates/skills/stellar-scf-grants-advisor/ASSOCIATE-ONBOARDING-GUIDE.md +761 -0
  332. package/templates/skills/stellar-scf-grants-advisor/CLIENT-FAQ.md +181 -0
  333. package/templates/skills/stellar-scf-grants-advisor/PARTNER-HANDOVER.md +130 -0
  334. package/templates/skills/stellar-scf-grants-advisor/SKILL.md +102 -0
  335. package/templates/skills/stellar-scf-grants-advisor/examples/README.md +43 -0
  336. package/templates/skills/stellar-scf-grants-advisor/examples/chat-summary-templates.md +158 -0
  337. package/templates/skills/stellar-scf-grants-advisor/examples/corpus-comparable-rows.md +136 -0
  338. package/templates/skills/stellar-scf-grants-advisor/examples/q10-team-rewrites.md +109 -0
  339. package/templates/skills/stellar-scf-grants-advisor/examples/q2-description-rewrites.md +88 -0
  340. package/templates/skills/stellar-scf-grants-advisor/examples/q6-integration-rewrites.md +107 -0
  341. package/templates/skills/stellar-scf-grants-advisor/examples/tranche-structures.md +176 -0
  342. package/templates/skills/stellar-scf-grants-advisor/reference/01-methodology.md +96 -0
  343. package/templates/skills/stellar-scf-grants-advisor/reference/02-scoring-framework.md +199 -0
  344. package/templates/skills/stellar-scf-grants-advisor/reference/03-rejection-patterns.md +241 -0
  345. package/templates/skills/stellar-scf-grants-advisor/reference/04-winner-patterns.md +120 -0
  346. package/templates/skills/stellar-scf-grants-advisor/reference/05-comeback-patterns.md +92 -0
  347. package/templates/skills/stellar-scf-grants-advisor/reference/06-budget-benchmarks.md +125 -0
  348. package/templates/skills/stellar-scf-grants-advisor/reference/07-integration-list.md +147 -0
  349. package/templates/skills/stellar-scf-grants-advisor/reference/08-abstract-fields.md +258 -0
  350. package/templates/skills/stellar-scf-grants-advisor/reference/09-build-fields.md +259 -0
  351. package/templates/skills/stellar-scf-grants-advisor/reference/10-corpus-winners.md +135 -0
  352. package/templates/skills/stellar-scf-grants-advisor/reference/11-corpus-rejects.md +267 -0
  353. package/templates/skills/stellar-scf-grants-advisor/reference/12-client-communication.md +131 -0
  354. package/templates/skills/stellar-scf-grants-advisor/reference/13-excel-output-spec.md +199 -0
  355. package/templates/skills/stellar-scf-grants-advisor/reference/14-worked-examples.md +160 -0
  356. package/templates/skills/stellar-scf-grants-advisor/templates/abstract-review-builder.py +253 -0
  357. package/templates/skills/stellar-scf-grants-advisor/templates/build-review-builder.py +213 -0
  358. package/dist/commands/connectors.d.ts +0 -31
  359. package/dist/commands/connectors.js +0 -276
  360. package/dist/commands/connectors.js.map +0 -1
  361. package/dist/commands/finish.d.ts +0 -25
  362. package/dist/commands/finish.js +0 -274
  363. package/dist/commands/finish.js.map +0 -1
  364. package/dist/commands/openclaw.d.ts +0 -40
  365. package/dist/commands/openclaw.js +0 -1148
  366. package/dist/commands/openclaw.js.map +0 -1
  367. package/dist/commands/security-audit.d.ts +0 -12
  368. package/dist/commands/security-audit.js +0 -100
  369. package/dist/commands/security-audit.js.map +0 -1
  370. package/dist/lib/hardening.d.ts +0 -18
  371. package/dist/lib/hardening.js +0 -214
  372. package/dist/lib/hardening.js.map +0 -1
@@ -0,0 +1,37 @@
1
+ operating-mode.md
2
+ reflexes.md
3
+ escalation-ladder.md
4
+ mental-model.md
5
+ quick-reference.md
6
+ lenses.md
7
+ operating-mode-rules.md
8
+ cli-operations.md
9
+ scope.md
10
+ work-flow.md
11
+ linking-principle.md
12
+ governance-rules.md
13
+ capabilities.md
14
+ writes.md
15
+ document-embeds.md
16
+ creative-loop.md
17
+ graph-gardening.md
18
+ next-action.md
19
+ reading.md
20
+ multi-entity-capture.md
21
+ worked-examples.md
22
+ crm.md
23
+ common-mistakes.md
24
+ inline-patterns.md
25
+ focus-sessions.md
26
+ automations.md
27
+ diagnostics.md
28
+ workspace-design.md
29
+ workspace-edges.md
30
+ more.md
31
+ viewframe-cells.md
32
+ authentication.md
33
+ response-style.md
34
+ recap.md
35
+ showing.md
36
+ user-model.md
37
+ north-star.md
@@ -0,0 +1,24 @@
1
+ name: synap
2
+ description: >
3
+ Use this skill whenever the user wants to capture, remember, find, or structure
4
+ information in their Synap data pod. Triggers: creating a task, note, person,
5
+ company, project, event, contact, or deal; saving an article or webpage;
6
+ storing a fact about someone ("Alice prefers async"); searching the user's
7
+ knowledge ("find my notes on X", "who did I meet last week"); linking entities;
8
+ logging a meeting or a contact; capturing unstructured text into structured
9
+ entities; reading what's in the user's pod before answering questions about
10
+ their life, work, or projects; posting to their personal AI channel. The pod
11
+ is the user's sovereign source of truth — prefer it over your own context
12
+ when the user asks about their own data. Do NOT use this skill for extending
13
+ the schema (use synap-schema) or building dashboards and views (use synap-ui).
14
+ metadata:
15
+ openclaw:
16
+ requires:
17
+ env: [SYNAP_HUB_API_KEY, SYNAP_POD_URL]
18
+ optional_env:
19
+ [SYNAP_WORKSPACE_ID, SYNAP_USER_ID, SYNAP_DEFAULT_CHANNEL_ID]
20
+ primaryEnv: SYNAP_HUB_API_KEY
21
+ homepage: https://synap.live
22
+ capabilities: [memory, knowledge-graph, channels]
23
+ os: [macos, linux, windows]
24
+ userInvocable: false
@@ -0,0 +1,10 @@
1
+ ## Authentication
2
+
3
+ ```
4
+ Authorization: Bearer {SYNAP_HUB_API_KEY}
5
+ X-Workspace-Id: {workspaceId} (optional; also pass in body/query)
6
+
7
+ Scopes:
8
+ hub-protocol.read → most GET endpoints
9
+ hub-protocol.write → all writes AND GET /channels/personal
10
+ ```
@@ -0,0 +1,264 @@
1
+ # Automations
2
+
3
+ Create workflow automations that trigger automatically based on events, schedules, or webhooks.
4
+
5
+ ## Automation Structure
6
+
7
+ Every automation has:
8
+
9
+ 1. **Trigger** (exactly one) — what starts the automation
10
+ 2. **Steps** (one or more) — commands, conditions, delays, outputs connected in a flow
11
+
12
+ ## Trigger Types
13
+
14
+ | Type | Config | Example |
15
+ | --------- | ---------------------------- | ------------------------------------ |
16
+ | `event` | `{ eventPattern, filters? }` | Entity created with specific profile |
17
+ | `cron` | `{ expression }` | Daily at 9am: `"0 9 * * *"` |
18
+ | `webhook` | `{ webhookSubscriptionId }` | External service sends data |
19
+ | `manual` | `{}` | User-triggered from UI |
20
+
21
+ ### Event Patterns
22
+
23
+ Format: `{subjectType}.{action}.completed`
24
+
25
+ Common patterns:
26
+
27
+ - `entity.create.completed` — entity created and persisted
28
+ - `entity.update.completed` — entity updated
29
+ - `entity.delete.completed` — entity deleted
30
+ - `document.create.completed` — document created
31
+ - `document.update.completed` — document updated
32
+
33
+ Filters narrow the event to specific conditions:
34
+
35
+ ```json
36
+ {
37
+ "eventPattern": "entity.create.completed",
38
+ "filters": { "profileSlug": "task", "metadata.priority": "high" }
39
+ }
40
+ ```
41
+
42
+ ### Cron Expressions
43
+
44
+ Standard 5-field cron (minute hour day month weekday):
45
+
46
+ - `"0 9 * * *"` — daily at 9am
47
+ - `"0 9 * * MON"` — every Monday at 9am
48
+ - `"*/30 * * * *"` — every 30 minutes
49
+ - `"0 0 1 * *"` — first day of month at midnight
50
+
51
+ ## Step Types
52
+
53
+ ### command
54
+
55
+ Execute an intelligence command. Reference by `commandId` or describe inline.
56
+
57
+ ```json
58
+ {
59
+ "id": "extract",
60
+ "type": "command",
61
+ "data": {
62
+ "commandTitle": "Extract key entities",
63
+ "inputMapping": {
64
+ "content": "{{trigger.payload.entity.content}}",
65
+ "context": "{{trigger.payload.entity.name}}"
66
+ }
67
+ }
68
+ }
69
+ ```
70
+
71
+ **Input mapping** uses template syntax:
72
+
73
+ - `{{trigger.payload.*}}` — data from the triggering event
74
+ - `{{steps.<stepId>.output.*}}` — output from a prior step
75
+ - `{{loop.item}}` — current item in a loop
76
+
77
+ ### condition
78
+
79
+ Branch the flow based on a boolean expression.
80
+
81
+ ```json
82
+ {
83
+ "id": "check-priority",
84
+ "type": "condition",
85
+ "data": {
86
+ "label": "High priority?",
87
+ "expression": "trigger.payload.entity.metadata.priority === 'high'",
88
+ "trueLabel": "Yes",
89
+ "falseLabel": "No"
90
+ }
91
+ }
92
+ ```
93
+
94
+ Conditions have two output handles: `yes` and `no`. Connect subsequent steps to the appropriate handle.
95
+
96
+ ### delay
97
+
98
+ Wait before continuing.
99
+
100
+ ```json
101
+ {
102
+ "id": "wait",
103
+ "type": "delay",
104
+ "data": { "duration": "5m", "label": "Cool down" }
105
+ }
106
+ ```
107
+
108
+ Supported durations: `30s`, `5m`, `1h`, `1d`, `1w`.
109
+
110
+ ### output
111
+
112
+ Terminal action — the end result of the automation.
113
+
114
+ ```json
115
+ {
116
+ "id": "notify",
117
+ "type": "output",
118
+ "data": {
119
+ "label": "Send notification",
120
+ "outputType": "notification",
121
+ "config": {
122
+ "message": "New high-priority task: {{trigger.payload.entity.name}}"
123
+ }
124
+ }
125
+ }
126
+ ```
127
+
128
+ Output types:
129
+
130
+ - `notification` — in-app notification to the user
131
+ - `entity_create` — create a new entity (config: `{ profileSlug, title, properties }`)
132
+ - `entity_update` — update an existing entity (config: `{ entityId, properties }`)
133
+ - `webhook` — POST to external URL (config: `{ url, headers?, body }`)
134
+ - `channel_message` — post a message to a channel (config: `{ channelId, content }`)
135
+
136
+ ### loop
137
+
138
+ Iterate over a collection from a prior step.
139
+
140
+ ```json
141
+ {
142
+ "id": "for-each-result",
143
+ "type": "loop",
144
+ "data": {
145
+ "label": "For each search result",
146
+ "iteratorExpression": "steps.search.output.results",
147
+ "itemVariable": "item"
148
+ }
149
+ }
150
+ ```
151
+
152
+ Inside the loop, reference `{{loop.item}}` for the current element.
153
+
154
+ ## Connecting Steps
155
+
156
+ Steps are connected via `dependsOn` (which step must complete first) and optional `conditionBranch` (which branch to follow from a condition).
157
+
158
+ ```json
159
+ {
160
+ "steps": [
161
+ { "id": "check", "type": "condition", "data": {...} },
162
+ { "id": "notify-high", "type": "output", "data": {...}, "dependsOn": ["check"], "conditionBranch": "yes" },
163
+ { "id": "log-normal", "type": "output", "data": {...}, "dependsOn": ["check"], "conditionBranch": "no" }
164
+ ]
165
+ }
166
+ ```
167
+
168
+ ## Discovering Commands
169
+
170
+ Before creating automations with command steps, call `list_commands` to discover available intelligence commands in the workspace. Use the command `id` in the step's `commandId` field.
171
+
172
+ If no suitable command exists, you can leave `commandId` empty and set `commandTitle` + `inputMapping` — the execution engine will use the title as a prompt template.
173
+
174
+ ## Vault References
175
+
176
+ Automation configs that need secrets (API keys, auth tokens) should use vault references instead of hardcoded values:
177
+
178
+ - `vault://secret-uuid` — resolves to the full secret value at runtime
179
+ - `vault://secret-uuid/field-name` — resolves a specific field from a JSON secret
180
+
181
+ Only server-encrypted secrets can be resolved by the automation engine. The user must store the credential in the vault first.
182
+
183
+ ## Best Practices
184
+
185
+ 1. **Keep it simple** — Start with trigger → command → output. Add complexity only when needed.
186
+ 2. **Name clearly** — Use descriptive labels: "When task created with high priority" not "Trigger 1".
187
+ 3. **One purpose** — Each automation should do one thing well. Compose multiple automations rather than building one complex flow.
188
+ 4. **Filter early** — Use trigger filters to avoid unnecessary execution. Don't use a condition step when a trigger filter suffices.
189
+ 5. **Test first** — Create automations as `draft` status. Let the user review the flow visualization before activating.
190
+
191
+ ## Example: Auto-archive completed tasks
192
+
193
+ ```json
194
+ {
195
+ "name": "Auto-archive completed tasks",
196
+ "description": "When a task status changes to 'done', archive it after 24 hours",
197
+ "trigger": {
198
+ "type": "event",
199
+ "config": {
200
+ "eventPattern": "entity.update.completed",
201
+ "filters": { "profileSlug": "task", "metadata.status": "done" }
202
+ }
203
+ },
204
+ "steps": [
205
+ {
206
+ "id": "wait-24h",
207
+ "type": "delay",
208
+ "data": { "duration": "1d", "label": "Wait 24h" }
209
+ },
210
+ {
211
+ "id": "archive",
212
+ "type": "output",
213
+ "data": {
214
+ "label": "Archive task",
215
+ "outputType": "entity_update",
216
+ "config": {
217
+ "entityId": "{{trigger.payload.entity.id}}",
218
+ "properties": { "archived": true }
219
+ }
220
+ },
221
+ "dependsOn": ["wait-24h"]
222
+ }
223
+ ]
224
+ }
225
+ ```
226
+
227
+ ## Example: Notify on high-priority tasks
228
+
229
+ ```json
230
+ {
231
+ "name": "High-priority task alerts",
232
+ "description": "Send a notification when a high-priority task is created",
233
+ "trigger": {
234
+ "type": "event",
235
+ "config": {
236
+ "eventPattern": "entity.create.completed",
237
+ "filters": { "profileSlug": "task" }
238
+ }
239
+ },
240
+ "steps": [
241
+ {
242
+ "id": "check-priority",
243
+ "type": "condition",
244
+ "data": {
245
+ "label": "High priority?",
246
+ "expression": "trigger.payload.entity.metadata.priority === 'high'"
247
+ }
248
+ },
249
+ {
250
+ "id": "notify",
251
+ "type": "output",
252
+ "data": {
253
+ "label": "Alert: high-priority task",
254
+ "outputType": "notification",
255
+ "config": {
256
+ "message": "New urgent task: {{trigger.payload.entity.name}}"
257
+ }
258
+ },
259
+ "dependsOn": ["check-priority"],
260
+ "conditionBranch": "yes"
261
+ }
262
+ ]
263
+ }
264
+ ```
@@ -0,0 +1,107 @@
1
+ # Capabilities — discover, run, and the when-blocked reflex
2
+
3
+ Capabilities are the verbs a workspace's connected services and applied
4
+ templates unlock — `gmail_send`, `gmail_search`, `calendar_create`,
5
+ `drive_search`, and so on. They are the bridge between "I can talk about it"
6
+ and "I can actually do it."
7
+
8
+ ## Discover: `list_capabilities`
9
+
10
+ MCP: `synap_list_capabilities`. IS: `list_capabilities`. Takes
11
+ `{ query, kind?, limit? }` (plus `workspaceId`).
12
+
13
+ **Search first — never dump-and-eyeball.** A workspace can carry 100+
14
+ capability entries; call with a `query` describing the action you're after
15
+ ("send email", "search calendar") and read the ranked, compact results. Don't
16
+ fetch the unfiltered list and scan it yourself.
17
+
18
+ Each entry carries:
19
+
20
+ - `name` (the `verbId` you pass to `run_capability`), `label`, backing tool
21
+ - `paramsSchema` — the shape `parameters` must satisfy; check it before calling
22
+ - `enabled` — `true` means it will run right now. `false`/DRAFT means it's
23
+ installed but the user hasn't approved it yet (Settings → Capabilities)
24
+
25
+ ## Run: `run_capability`
26
+
27
+ MCP: `synap_run_capability`. IS: `run_capability`. Pass `verbId` (or
28
+ `skillId`) + `parameters` + `workspaceId`.
29
+
30
+ ```json
31
+ {
32
+ "verbId": "gmail_send",
33
+ "parameters": { "to": "…", "subject": "…", "body": "…" },
34
+ "workspaceId": "{workspaceId}"
35
+ }
36
+ ```
37
+
38
+ Check `paramsSchema` from discovery before calling — a missing required
39
+ parameter is refused, not guessed.
40
+
41
+ **`proposed` is a normal outcome, not a failure.** A capability run can land
42
+ as a proposal exactly like any other governed write (see `governance.md`):
43
+ tell the user why, share the `reviewUrl`, and don't retry.
44
+
45
+ **Provider results can be 200-with-error-body.** A successful HTTP call to
46
+ Gmail/Calendar/Drive can still carry `result.success: false` +
47
+ `result.error` — an auth expiry, a bad recipient, a quota limit. **Always
48
+ check `result.success`/`result.error` in the response before telling the
49
+ user the action worked.** A 200 status is not proof of success here.
50
+
51
+ ## The when-blocked reflex
52
+
53
+ When you cannot do something the user asked for — no matching tool, a
54
+ "not found" verb, "no connection", "not enabled" — do not fabricate a result
55
+ and do not silently give up. Follow this order:
56
+
57
+ 1. **Search first.** `list_capabilities({ query })` for what the user actually
58
+ wants. Capabilities are added over time; don't assume today's tool list is
59
+ the ceiling.
60
+ 2. **Found but blocked?** If the verb exists but is DRAFT (not enabled) or its
61
+ backing connection is missing, tell the user exactly what to do and where:
62
+ "This needs Gmail connected — enable it in Settings → Capabilities" (or
63
+ the equivalent connect deep-link the error hands you). Don't attempt the
64
+ run again until they've acted.
65
+ 3. **Still nothing? Search the marketplace.** `market.search({query, kind?})`
66
+ over what could be _installed_ (capabilities, automations, workspace
67
+ templates, cells) — a cache read, not a live fetch, so it's always fast.
68
+ 4. **Found in the marketplace?** `market.install({slug, kind, version?})`. As
69
+ an agent this ALWAYS lands as a reviewable proposal — never auto-installs,
70
+ even with a grant on the verb itself. Share the `reviewUrl`; don't retry.
71
+ 5. **Truly nothing, anywhere?** That is escalation-ladder **L2 empty → L3**:
72
+ say precisely what's missing (the action, not "I can't"), offer to capture
73
+ the gap, and if the need is structural (new capability package, template,
74
+ automation), propose via marketplace/install or meta tools — never
75
+ dead-end and never fabricate a result.
76
+
77
+ <!-- brief:start -->
78
+
79
+ When blocked (ladder L2→L3): (1) `list_capabilities({query})` first — never
80
+ assume today's list is the ceiling. (2) Found but DRAFT/no connection → tell
81
+ the user exactly what to enable/connect and where; don't retry until they've
82
+ acted. (3) Still nothing → `market.search({query, kind?})`; `market.install`
83
+ on a hit always proposes for an agent. (4) Truly nothing → say precisely
84
+ what's missing, offer to capture the gap or propose L3 structure — never
85
+ fabricate, never silent give-up. Provider 200-with-error-body: always check
86
+ `result.success`/`result.error` before claiming success.
87
+
88
+ <!-- brief:end -->
89
+
90
+ ## Errors — what they mean, what to do next
91
+
92
+ | You see roughly... | Meaning | Next step |
93
+ | ------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
94
+ | verb/skill "not found" in this workspace | No capability by that name is registered here | `list_capabilities({query})`; if nothing, tell the user what's missing |
95
+ | capability "not approved" / DRAFT | It exists but the user hasn't enabled it yet | Tell the user to enable it (Settings → Capabilities); don't retry |
96
+ | a required parameter is missing | Your `parameters` didn't satisfy the verb's `paramsSchema` | Re-check `paramsSchema` from discovery, fill the gap, retry once |
97
+ | no connection / credential for this service | The verb needs a connected account (Gmail, Calendar, …) that isn't set up | Hand the user the connect link; don't retry until connected |
98
+ | `status: "proposed"` | Normal governed outcome — this run needs human approval | Share `summary` + `reviewUrl`; don't retry (see `governance.md`) |
99
+ | `status: "denied"` | Workspace policy blocked it outright | Explain the reason; don't retry |
100
+ | provider result with `success: false` | The call reached the provider but the provider itself rejected it | Read `result.error`; tell the user what actually happened, don't report success |
101
+
102
+ ## What NOT to do
103
+
104
+ - Don't dump the full unfiltered capability list and eyeball it — search.
105
+ - Don't retry a `proposed` or `denied` result as if it were a transient error.
106
+ - Don't tell the user an action "worked" without checking `result.success`.
107
+ - Don't invent a capability, verb, or connection that discovery didn't return.
@@ -1,170 +1,78 @@
1
- # Capture pipeline — reference
1
+ # Capture — the one write door
2
2
 
3
- Use the capture pipeline when the user pastes a block of unstructured text (email, meeting transcript, LinkedIn bio, article, screenshot of a whiteboard) and you need to extract multiple entities with their relations.
3
+ `synap_capture` (CLI: `synap capture`) is THE door for writing what you learn into the pod. **Never classify your input first.** The payload is a _gradient_ — send as much structure as you already have, in ONE call. Precision comes from sending MORE structure in the SAME call, never from picking a different tool and never from a second "commit" step.
4
4
 
5
- Chaining manual `POST /entities` + `POST /relations` for this is wasteful — the pipeline extracts everything in one server-side LLM call and returns proposals you can review before committing.
6
-
7
- ## Two-step flow
8
-
9
- ### 1. Structure the text
10
-
11
- ```json
12
- POST /api/hub/capture/structure
13
- {
14
- "userId": "{userId}",
15
- "workspaceId": "{workspaceId}",
16
- "text": "Had lunch with Sarah Chen from Acme Corp today. \
17
- She's leading their Series B and asked me to send \
18
- our sales deck by Friday. Mentioned her VP Engineering \
19
- Tom Walker also wants a demo.",
20
- "context": { "source": "chat", "channelId": "ch_…" }, // optional
21
- "profileSlugs": ["person", "company", "task", "event"] // optional filter
22
- }
23
5
  ```
24
-
25
- Response:
26
-
27
- ```json
28
- {
29
- "proposals": [
30
- {
31
- "tempId": "t1",
32
- "profileSlug": "person",
33
- "title": "Sarah Chen",
34
- "properties": { "companyId": "t2" },
35
- "action": "create"
36
- },
37
- {
38
- "tempId": "t2",
39
- "profileSlug": "company",
40
- "title": "Acme Corp",
41
- "properties": {},
42
- "action": "create"
43
- },
44
- {
45
- "tempId": "t3",
46
- "profileSlug": "person",
47
- "title": "Tom Walker",
48
- "properties": { "role": "VP Engineering", "companyId": "t2" },
49
- "action": "create"
50
- },
51
- {
52
- "tempId": "t4",
53
- "profileSlug": "task",
54
- "title": "Send sales deck to Sarah",
55
- "properties": {
56
- "status": "todo",
57
- "dueDate": "2026-04-24",
58
- "assignee": null
59
- },
60
- "action": "create"
61
- },
62
- {
63
- "tempId": "t5",
64
- "profileSlug": "event",
65
- "title": "Lunch with Sarah",
66
- "properties": { "startDate": "2026-04-20", "attendees": ["t1"] },
67
- "action": "create"
68
- }
69
- ],
70
- "relations": [
71
- {
72
- "sourceTempId": "t4",
73
- "targetTempId": "t1",
74
- "relationType": "for_person"
75
- },
76
- {
77
- "sourceTempId": "t4",
78
- "targetTempId": "t5",
79
- "relationType": "from_meeting"
80
- }
81
- ],
82
- "followUp": "Should I also schedule a reminder to follow up with Tom?"
83
- }
6
+ text → free prose; the AI structures it into the right entities (raw text kept as provenance)
7
+ entities[] → you already know the kind + fields
8
+ entities[] + relations[] → a graph; refs link things that don't exist yet, reviewed as ONE proposal
84
9
  ```
85
10
 
86
- **`tempId` is only valid within this response.** It's used to link proposals together before they have real entity IDs.
11
+ There is no wrong door to pick, because there is one door. `text` alone is the old "capture"; `entities[]` is the old "rich create"; `entities[] + relations[]` is the composite graph. All three go through `synap_capture`.
87
12
 
88
- **`action` can be:**
13
+ ## One call → one receipt (no plan-and-commit)
89
14
 
90
- - `"create"` — new entity
91
- - `"update"` — existing entity found by title match; `existingEntityId` will be set
92
- - `"skip"` — duplicate already exists, nothing to do
15
+ You are an agent, so a capture is **one call**. The backend derives that from your identity (agent key ⇒ agent mode) — you never pass a mode. Policy decides the terminal automatically:
93
16
 
94
- ### 2. Execute (commit) after user confirmation
17
+ - every op is safe/whitelisted → **auto-applied**
18
+ - any op is destructive or non-whitelisted → the whole graph is **proposed** (atomic, all-or-nothing)
95
19
 
96
- Present the proposals to the user. Let them edit, remove, or add items. Then:
20
+ It always returns the same receipt:
97
21
 
98
22
  ```json
99
- POST /api/hub/capture/execute
100
- {
101
- "userId": "{userId}",
102
- "workspaceId": "{workspaceId}",
103
- "entities": [ /* edited proposals array */ ],
104
- "relations": [ /* edited relations array */ ]
105
- }
23
+ { "status": "applied" | "proposed" | "rejected",
24
+ "scope": { "workspaceId": "…", "projectId": "…", "sessionId": "…" },
25
+ "writeReceipt": { … } }
106
26
  ```
107
27
 
108
- Response:
109
-
110
- ```json
111
- {
112
- "created": [{ "tempId": "t1", "entityId": "ent_real_1" }, …],
113
- "updated": [{ "tempId": "t2", "entityId": "ent_existing" }, …],
114
- "skipped": [{ "tempId": "t5", "reason": "duplicate" }],
115
- "relations": { "created": 2, "failed": 0 },
116
- "status": "approved"
117
- }
118
- ```
28
+ **`status: "proposed"` is SUCCESS**, not a failure — the write is queued for the user's review like a PR. Surface the `reviewUrl` and keep working. Never report "done" for a `proposed` result, and there is **no** separate step you must call after capture — the one call is the whole write.
119
29
 
120
- The executor goes through governance (see `governance.md`). Expect the same three `status` values.
30
+ ## capture vs create_entity
121
31
 
122
- ## When to use the pipeline vs. manual CRUD
32
+ - **`synap_create_entity`** — use ONLY when you already have exactly ONE fully-structured, typed entity (a known `profileSlug` + fields). Deterministic, direct.
33
+ - **`synap_capture`** — everything else: unstructured text, several entities, a graph, or **when in doubt**. It handles the whole gradient; you don't have to decide "loose fact vs structured object."
123
34
 
124
- | Situation | Use |
125
- | ---------------------------------------------------------------- | --------------------------------------------------- |
126
- | User pastes a chunk of text with multiple people/companies/tasks | Pipeline |
127
- | User says "create a task to call Sarah at 3pm" | Manual create (1 entity) |
128
- | User forwards an email | Pipeline |
129
- | User asks "remind me to X" | Manual create |
130
- | OCR'd screenshot, meeting transcript, article body | Pipeline |
131
- | User edits an existing entity | Manual PATCH |
132
- | User wants to save a webpage they're on | Manual create (article) + optional capture for body |
35
+ ## Worked examples
133
36
 
134
- Rule of thumb: **one intent, one call.** Multi-entity content, use the pipeline.
37
+ ```json
38
+ // 1 — raw text (the AI structures it)
39
+ { "text": "Met Ada Lovelace of Acme at the conference — she owns their data platform and wants a demo in March." }
40
+
41
+ // 2 — one structured entity with a long body
42
+ { "entities": [
43
+ { "profileSlug": "person", "title": "Ada Lovelace",
44
+ "properties": { "email": "ada@acme.com", "role": "Head of Data" },
45
+ "content": "## Notes\nOwns the data platform. Wants a March demo." }
46
+ ] }
47
+
48
+ // 3 — a small graph (refs link entities that don't exist yet)
49
+ { "entities": [
50
+ { "ref": "p1", "profileSlug": "person", "title": "Ada Lovelace", "properties": { "email": "ada@acme.com" } },
51
+ { "ref": "c1", "profileSlug": "company", "title": "Acme Corp", "properties": { "website": "https://acme.com" } }
52
+ ],
53
+ "relations": [ { "sourceRef": "p1", "targetRef": "c1", "type": "works_at" } ] }
54
+ ```
135
55
 
136
- ## Dedup within the pipeline
56
+ ## Dedup — strong signals only
137
57
 
138
- The pipeline does its own duplicate check per entity (by title + profileSlug within workspace). When it finds a match, `action` becomes `"update"` with `existingEntityId` set, so the real entity is updated in place, not duplicated.
58
+ The dedup signals are the exact property keys `email`, `phone`, `website`, `linkedinUrl`, `twitterHandle`, `githubUsername`. Sending a URL under any other key (e.g. a bare `url`) is **not** a dedup signal and will duplicate the entity.
139
59
 
140
- You can still prefix with a manual search if you want to show the user "I found 3 existing people that might match" before running capture. But the pipeline alone is usually good enough.
60
+ A same-title hit in a _different_ kind is **advisory** (`crossKindCandidates`), never an auto-merge. So "no exact match" does **not** mean "safe to create" when advisory candidates come back — review them first. To link to something that already exists, give it a `ref` plus `existingEntityId`.
141
61
 
142
- ## Presenting proposals to the user
62
+ ## Name-refs — never ask for a UUID
143
63
 
144
- A good UX turn:
64
+ Reference an existing project by **name**, not id — the server resolves `{ project: { name: "Synap" } }` against the caller's own projects. Exact match ⇒ it files there; no match ⇒ it proposes/creates, never silently mis-files. Never ask the user for a UUID.
145
65
 
146
- > I picked up **5 things** from that paste:
147
- >
148
- > - **Sarah Chen** — person at Acme Corp (new)
149
- > - **Acme Corp** — company (new)
150
- > - **Tom Walker** — person at Acme (new)
151
- > - **Task**: Send sales deck to Sarah, due Friday
152
- > - **Event**: Lunch with Sarah today
153
- >
154
- > Plus 2 connections: task → Sarah, task → lunch.
155
- >
156
- > Ship it?
66
+ ## Placement — existing lenses only
157
67
 
158
- Keep the user in control. Don't auto-execute without confirmation unless the user explicitly told you to.
68
+ Capture **never invents a workspace** (or other meta-structure) to "find a home". It routes into **existing** workspaces/projects/profiles — `synap orient` + `list_profiles` first when placement is ambiguous. Structure emerges progressively: capture into what exists; suggest a new profile only when the user repeatedly tracks a thing that fits none, and a view only once that profile has 3+ entities. Missing structure is an escalation-ladder L2→L3 conversation (discover, then propose), not a side effect of capture. `global: true` stores a pod-wide runbook (text lane only).
159
69
 
160
- ## Edge cases
70
+ ## Rejection is a correct outcome — don't retry
161
71
 
162
- - **Empty text → empty proposals.** Don't call execute with zero entities.
163
- - **Ambiguous references ("he", "they").** The pipeline will often return null properties. Prompt the user to clarify before executing.
164
- - **Dates.** Always absolute in responses (ISO 8601). If the input says "Friday," the pipeline resolves it against today.
165
- - **Custom profiles.** If you want the pipeline to consider custom profiles, pass `profileSlugs` in the request. Otherwise it defaults to system profiles only.
166
- - **Rate limits.** 20 captures/hour per user. If you hit the limit, fall back to manual CRUD.
72
+ `status: "rejected"` means the door protected the graph on purpose. Read the `reason` and act, don't loop:
167
73
 
168
- ## Followup question
74
+ - **`already-known`** — a lone entity carrying nothing but identity signals that already resolve to an existing one. Its id is returned; re-send with content / extra properties / relations to **enrich** it instead.
75
+ - **`no-durable-content`** — nothing storable was sent (empty / whitespace / punctuation-only). Don't call capture with zero substance.
76
+ - **`structuring-unavailable`** — text lane only: the AI structurer is down. Tell the user and retry later.
169
77
 
170
- The response includes a `followUp` field — a single sentence question the pipeline thinks is worth asking next. Surface it to the user verbatim. It's a cheap way to deepen capture without extra prompts.
78
+ (There is no "recall-loop" rejection.)