@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,177 @@
1
+ /**
2
+ * Control-plane package registry client (read-only).
3
+ * ==================================================
4
+ *
5
+ * The ONE authed HTTP client for the CP package registry (`/api/packages`).
6
+ * Before this file there was NO `/api/packages` client in the CLI — `launch`
7
+ * read the whole catalog from the bundled `@synap-core/workspace-templates`
8
+ * package. The ratified architecture is: PUBLIC templates ship in the bundle,
9
+ * PRIVATE templates live in the CP behind the user's login. This client is the
10
+ * private half.
11
+ *
12
+ * Two list endpoints, one detail endpoint:
13
+ * • GET /api/packages — public browse rows (no auth, `definition` stripped)
14
+ * • GET /api/packages/mine — the caller's own packages (Bearer, incl. private)
15
+ * • GET /api/packages/:slug — full row WITH `definition` (Bearer → private visible to author)
16
+ *
17
+ * The row→`RemoteEntry` mapping is NOT here — it is the canonical
18
+ * `rowToRemoteEntry` in `@synap-core/workspace-templates` (browser + CLI share
19
+ * the ONE copy; the two hand-copies had already drifted). This file owns only
20
+ * TRANSPORT: the Bearer token, the base URL (`auth.ts`'s `getCpUrl()`), and the
21
+ * query params the CP `/api/packages` route supports (`search`/`category`/`tag`/
22
+ * `verified`).
23
+ */
24
+ import { type CpPackageRow, type RemoteEntry, type RemoteSourceStatus } from "@synap-core/workspace-templates";
25
+ import type { PackageDefinitionLike } from "./template-file.js";
26
+ /**
27
+ * The server-side filters `GET /api/packages` accepts (CP `routes/packages.ts`).
28
+ * `category` is a PACKAGE_TYPES value (`workspace`/`capability`/`skill`/…). The
29
+ * `/mine` route supports none of these — it is the caller's own small set — so
30
+ * they are applied CLIENT-side there.
31
+ */
32
+ export interface PackageFilters {
33
+ search?: string;
34
+ category?: string;
35
+ tag?: string;
36
+ verified?: boolean;
37
+ }
38
+ /** Tier / pricing signal the browse route carries but `RemoteEntry` drops. */
39
+ export interface TierInfo {
40
+ requiredTier?: string | null;
41
+ pricingModel?: string | null;
42
+ }
43
+ /**
44
+ * A public browse row — the canonical `CpPackageRow` PLUS the tier/pricing and
45
+ * count fields the browse route (`GET /api/packages`) returns but the shared
46
+ * `RemoteEntry` shape does not carry. Kept local because they are a
47
+ * discovery-surface concern, not part of the merge door's contract.
48
+ */
49
+ export interface CpBrowseRow extends CpPackageRow {
50
+ version?: string;
51
+ requiredTier?: string | null;
52
+ pricingModel?: string | null;
53
+ isVerified?: boolean;
54
+ installCount?: number;
55
+ }
56
+ /** `/mine` returns `isPublic` (and, like the browse route, `version`) on top of the canonical row shape. */
57
+ export type CpMineRow = CpPackageRow & {
58
+ isPublic?: boolean;
59
+ version?: string;
60
+ };
61
+ /**
62
+ * GET /api/packages — public browse rows, RAW (incl. `requiredTier`/
63
+ * `pricingModel`/`category`). No auth. Throws on non-2xx / network. This is the
64
+ * source both the merged launch catalog and the `market` command read from.
65
+ */
66
+ export declare function fetchPublicBrowseRows(filters?: PackageFilters): Promise<CpBrowseRow[]>;
67
+ /** GET /api/packages — public workspace templates as `RemoteEntry`. No auth. */
68
+ export declare function fetchPublicPackages(filters?: PackageFilters): Promise<RemoteEntry[]>;
69
+ /**
70
+ * GET /api/packages/mine — the caller's own packages (incl. private). Bearer
71
+ * required. The route has no `search`/`category` params, so those filters are
72
+ * applied client-side over this (small) set; `search` is honored, `category`
73
+ * only when the row actually carries one (the `/mine` select omits it, so a
74
+ * type filter never silently drops the user's own rows).
75
+ */
76
+ export declare function fetchMyRows(token: string, filters?: PackageFilters): Promise<CpMineRow[]>;
77
+ export declare function fetchMyPackages(token: string, filters?: PackageFilters): Promise<RemoteEntry[]>;
78
+ /**
79
+ * GET /api/packages/available — the slugs THIS account's subscription tier can
80
+ * install (Bearer required; the route reads the user's `subscriptions.tier`).
81
+ * Used to compute the "locked" set: a public package that declares a
82
+ * `requiredTier` but is absent here is ungrantable for this account. Only
83
+ * `category` is a real filter on this route — the others are ignored server-side.
84
+ */
85
+ export declare function fetchAvailableSlugs(token: string, filters?: PackageFilters): Promise<Set<string>>;
86
+ /**
87
+ * GET /api/packages/:slug — the full row, INCLUDING `definition` (the install
88
+ * payload). Authed when a token is given, which is REQUIRED for a private
89
+ * template (the author-only visibility gate 404s otherwise). Returns `null` if
90
+ * the package is absent / not visible.
91
+ */
92
+ export declare function fetchPackageDefinition(slug: string, token?: string): Promise<Record<string, unknown> | null>;
93
+ /** The remote half of the catalog, plus the health `mergeCatalog` needs. */
94
+ export interface RemoteCatalog {
95
+ rows: RemoteEntry[];
96
+ status: RemoteSourceStatus;
97
+ loggedIn: boolean;
98
+ email?: string;
99
+ /** How many private rows we actually fetched (meaningful only when status === "ok"). */
100
+ privateCount: number;
101
+ /** Tier/pricing per public slug — the browse route carries it, `RemoteEntry` drops it. */
102
+ tierBySlug: Map<string, TierInfo>;
103
+ /**
104
+ * Slugs that declare a `requiredTier` this account CANNOT install (browse ∖
105
+ * `/available`). Empty when logged out or when `/available` couldn't be read
106
+ * (older pod / failure) — absence means "unknown", never "locked".
107
+ */
108
+ lockedSlugs: Set<string>;
109
+ }
110
+ /**
111
+ * Assemble the remote catalog for `launch`, degrading HONESTLY rather than
112
+ * failing open empty:
113
+ *
114
+ * • Logged out → NO network. The bundle already IS the public catalog, and
115
+ * private templates are invisible without auth. Status "unauthenticated"
116
+ * tells the consumer to render the `synap login` path.
117
+ * • Logged in → fetch `/mine` (private + own public) and best-effort `/packages`
118
+ * (official / third-party public); merge, private-carrying rows win a tie.
119
+ * • `/mine` 401/403 → "unauthenticated" (session expired). Network failure →
120
+ * "unreachable". Either way `rows` is empty and the door keeps the bundle.
121
+ */
122
+ export declare function fetchRemoteCatalog(filters?: PackageFilters): Promise<RemoteCatalog>;
123
+ /**
124
+ * A CP write failure carrying the server's OWN message + status, so the caller
125
+ * can surface `detail` (never swallow it — the `readErrorBody`/`detail` lesson)
126
+ * and special-case a 403 reserved-slug rejection.
127
+ */
128
+ export declare class CpWriteError extends Error {
129
+ readonly status: number;
130
+ readonly serverMessage: string;
131
+ constructor(status: number, serverMessage: string);
132
+ }
133
+ /** Test seams — inject a fetch + token + base URL instead of touching the network / `~/.synap`. */
134
+ export interface CpWriteDeps {
135
+ fetchImpl?: typeof fetch;
136
+ token?: string;
137
+ cpUrl?: string;
138
+ }
139
+ export interface PublishResult {
140
+ /** `created` (201) · `updated` (200, content changed) · `no-op` (200, identical content). */
141
+ outcome: "created" | "updated" | "no-op";
142
+ slug: string;
143
+ displayName: string;
144
+ /** The `h-<hash>` version the CP derived from the definition. */
145
+ version: string;
146
+ isPublic: boolean;
147
+ }
148
+ /**
149
+ * `POST /api/packages` — publish (upsert) a package definition under the caller's
150
+ * account. `isPublic` decides visibility (default private — the command flips it
151
+ * with `--public`). The version is DERIVED server-side from the definition, so
152
+ * identical content re-published is a no-op. Surfaces a 403 reserved-slug
153
+ * rejection (and any other failure) as a `CpWriteError` carrying the server's
154
+ * own message.
155
+ *
156
+ * The definition's identity (`slug`, `displayName`) is read off its `_meta`/
157
+ * `workspaceName`; `_meta.icon`/`.color`/`.domain` are hoisted onto the
158
+ * definition's top level because the CP reads those off `definition.icon`/… for
159
+ * the list DTO (it strips the unknown `_meta` key).
160
+ */
161
+ export declare function publishPackage(def: PackageDefinitionLike, opts: {
162
+ isPublic: boolean;
163
+ }, deps?: CpWriteDeps): Promise<PublishResult>;
164
+ /**
165
+ * `PATCH /api/packages/:slug` — owner-gated flip of a package to private.
166
+ *
167
+ * ⚠️ TODO(cp): the CP PATCH handler's body validator is
168
+ * `z.object({ podId: z.string().min(1).nullable() })` TODAY — it does NOT accept
169
+ * `isPublic`, so this call currently fails (400) until the CP adds `isPublic` to
170
+ * that PATCH allow-list. This is deliberately the INTENDED endpoint (not a
171
+ * faked flip): it will start working the moment the CP door is widened. The
172
+ * command surfaces the CP's message honestly meanwhile.
173
+ */
174
+ export declare function unpublishPackage(slug: string, deps?: CpWriteDeps): Promise<{
175
+ slug: string;
176
+ isPublic: boolean;
177
+ }>;
@@ -0,0 +1,389 @@
1
+ /**
2
+ * Control-plane package registry client (read-only).
3
+ * ==================================================
4
+ *
5
+ * The ONE authed HTTP client for the CP package registry (`/api/packages`).
6
+ * Before this file there was NO `/api/packages` client in the CLI — `launch`
7
+ * read the whole catalog from the bundled `@synap-core/workspace-templates`
8
+ * package. The ratified architecture is: PUBLIC templates ship in the bundle,
9
+ * PRIVATE templates live in the CP behind the user's login. This client is the
10
+ * private half.
11
+ *
12
+ * Two list endpoints, one detail endpoint:
13
+ * • GET /api/packages — public browse rows (no auth, `definition` stripped)
14
+ * • GET /api/packages/mine — the caller's own packages (Bearer, incl. private)
15
+ * • GET /api/packages/:slug — full row WITH `definition` (Bearer → private visible to author)
16
+ *
17
+ * The row→`RemoteEntry` mapping is NOT here — it is the canonical
18
+ * `rowToRemoteEntry` in `@synap-core/workspace-templates` (browser + CLI share
19
+ * the ONE copy; the two hand-copies had already drifted). This file owns only
20
+ * TRANSPORT: the Bearer token, the base URL (`auth.ts`'s `getCpUrl()`), and the
21
+ * query params the CP `/api/packages` route supports (`search`/`category`/`tag`/
22
+ * `verified`).
23
+ */
24
+ import { rowToRemoteEntry, } from "@synap-core/workspace-templates";
25
+ import { getCpUrl, getStoredToken, isTokenLocallyExpired } from "./auth.js";
26
+ // Packages mount under `/api/packages` (CP `routes/index.ts`), unlike `/auth`
27
+ // and `/pods` which sit at the root — hence the explicit `/api` segment here.
28
+ const packagesBase = () => `${getCpUrl()}/api/packages`;
29
+ const FETCH_TIMEOUT_MS = 10_000;
30
+ /** Build the `/api/packages` query string from filters + any extra params. */
31
+ function buildQuery(filters, extra) {
32
+ const p = new URLSearchParams(extra);
33
+ if (filters?.search)
34
+ p.set("search", filters.search);
35
+ if (filters?.category)
36
+ p.set("category", filters.category);
37
+ if (filters?.tag)
38
+ p.set("tag", filters.tag);
39
+ if (filters?.verified)
40
+ p.set("verified", "true");
41
+ return p.toString();
42
+ }
43
+ /** An auth failure (401/403) — distinct from an unreachable-network failure. */
44
+ class CpAuthError extends Error {
45
+ authFailed = true;
46
+ }
47
+ /**
48
+ * GET /api/packages — public browse rows, RAW (incl. `requiredTier`/
49
+ * `pricingModel`/`category`). No auth. Throws on non-2xx / network. This is the
50
+ * source both the merged launch catalog and the `market` command read from.
51
+ */
52
+ export async function fetchPublicBrowseRows(filters) {
53
+ const qs = buildQuery(filters, { limit: "100" });
54
+ const res = await fetch(`${packagesBase()}?${qs}`, {
55
+ signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
56
+ });
57
+ if (!res.ok)
58
+ throw new Error(`CP GET /api/packages → HTTP ${res.status}`);
59
+ const data = (await res.json());
60
+ return data.packages ?? [];
61
+ }
62
+ /** GET /api/packages — public workspace templates as `RemoteEntry`. No auth. */
63
+ export async function fetchPublicPackages(filters) {
64
+ const rows = await fetchPublicBrowseRows(filters);
65
+ // Browse rows are all public by construction — pass `isPrivate` undefined.
66
+ return rows.map((r) => rowToRemoteEntry(r, undefined));
67
+ }
68
+ /**
69
+ * GET /api/packages/mine — the caller's own packages (incl. private). Bearer
70
+ * required. The route has no `search`/`category` params, so those filters are
71
+ * applied client-side over this (small) set; `search` is honored, `category`
72
+ * only when the row actually carries one (the `/mine` select omits it, so a
73
+ * type filter never silently drops the user's own rows).
74
+ */
75
+ export async function fetchMyRows(token, filters) {
76
+ const res = await fetch(`${packagesBase()}/mine?limit=100`, {
77
+ headers: { Authorization: `Bearer ${token}` },
78
+ signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
79
+ });
80
+ if (res.status === 401 || res.status === 403) {
81
+ throw new CpAuthError(`CP GET /api/packages/mine → HTTP ${res.status}`);
82
+ }
83
+ if (!res.ok)
84
+ throw new Error(`CP GET /api/packages/mine → HTTP ${res.status}`);
85
+ const data = (await res.json());
86
+ let rows = data.packages ?? [];
87
+ if (filters?.category) {
88
+ rows = rows.filter((r) => r.category == null || r.category === filters.category);
89
+ }
90
+ if (filters?.search) {
91
+ const q = filters.search.toLowerCase();
92
+ rows = rows.filter((r) => r.slug.toLowerCase().includes(q) ||
93
+ r.displayName.toLowerCase().includes(q) ||
94
+ (r.description ?? "").toLowerCase().includes(q));
95
+ }
96
+ return rows;
97
+ }
98
+ export async function fetchMyPackages(token, filters) {
99
+ const rows = await fetchMyRows(token, filters);
100
+ return rows.map((r) => rowToRemoteEntry(r, r.isPublic === false ? true : undefined));
101
+ }
102
+ /**
103
+ * GET /api/packages/available — the slugs THIS account's subscription tier can
104
+ * install (Bearer required; the route reads the user's `subscriptions.tier`).
105
+ * Used to compute the "locked" set: a public package that declares a
106
+ * `requiredTier` but is absent here is ungrantable for this account. Only
107
+ * `category` is a real filter on this route — the others are ignored server-side.
108
+ */
109
+ export async function fetchAvailableSlugs(token, filters) {
110
+ const qs = buildQuery({ category: filters?.category }, { limit: "100" });
111
+ const res = await fetch(`${packagesBase()}/available?${qs}`, {
112
+ headers: { Authorization: `Bearer ${token}` },
113
+ signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
114
+ });
115
+ if (!res.ok)
116
+ throw new Error(`CP GET /api/packages/available → HTTP ${res.status}`);
117
+ const data = (await res.json());
118
+ return new Set((data.packages ?? []).map((p) => p.slug));
119
+ }
120
+ /**
121
+ * GET /api/packages/:slug — the full row, INCLUDING `definition` (the install
122
+ * payload). Authed when a token is given, which is REQUIRED for a private
123
+ * template (the author-only visibility gate 404s otherwise). Returns `null` if
124
+ * the package is absent / not visible.
125
+ */
126
+ export async function fetchPackageDefinition(slug, token) {
127
+ const res = await fetch(`${packagesBase()}/${encodeURIComponent(slug)}`, {
128
+ headers: token ? { Authorization: `Bearer ${token}` } : {},
129
+ signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
130
+ });
131
+ if (!res.ok)
132
+ return null;
133
+ const data = (await res.json());
134
+ return data.package?.definition ?? null;
135
+ }
136
+ /**
137
+ * Assemble the remote catalog for `launch`, degrading HONESTLY rather than
138
+ * failing open empty:
139
+ *
140
+ * • Logged out → NO network. The bundle already IS the public catalog, and
141
+ * private templates are invisible without auth. Status "unauthenticated"
142
+ * tells the consumer to render the `synap login` path.
143
+ * • Logged in → fetch `/mine` (private + own public) and best-effort `/packages`
144
+ * (official / third-party public); merge, private-carrying rows win a tie.
145
+ * • `/mine` 401/403 → "unauthenticated" (session expired). Network failure →
146
+ * "unreachable". Either way `rows` is empty and the door keeps the bundle.
147
+ */
148
+ export async function fetchRemoteCatalog(filters) {
149
+ const creds = getStoredToken();
150
+ const loggedIn = !!creds && !isTokenLocallyExpired(creds);
151
+ if (!loggedIn) {
152
+ return {
153
+ rows: [],
154
+ status: "unauthenticated",
155
+ loggedIn: false,
156
+ privateCount: 0,
157
+ tierBySlug: new Map(),
158
+ lockedSlugs: new Set(),
159
+ };
160
+ }
161
+ let publicRows = [];
162
+ let mineRows = [];
163
+ let availableSlugs = null;
164
+ try {
165
+ [publicRows, mineRows, availableSlugs] = await Promise.all([
166
+ // Public is best-effort: a private catalog that resolves is still useful
167
+ // even if the browse route hiccups.
168
+ fetchPublicBrowseRows(filters).catch(() => []),
169
+ fetchMyPackages(creds.token, filters),
170
+ // Tier gate is best-effort: an older pod without `/available` ⇒ null ⇒
171
+ // "unknown", never "locked".
172
+ fetchAvailableSlugs(creds.token, filters).catch(() => null),
173
+ ]);
174
+ }
175
+ catch (e) {
176
+ const authFailed = e.authFailed === true;
177
+ return {
178
+ rows: [],
179
+ status: authFailed ? "unauthenticated" : "unreachable",
180
+ loggedIn: true,
181
+ email: creds.email,
182
+ privateCount: 0,
183
+ tierBySlug: new Map(),
184
+ lockedSlugs: new Set(),
185
+ };
186
+ }
187
+ const tierBySlug = new Map();
188
+ const lockedSlugs = new Set();
189
+ for (const r of publicRows) {
190
+ if (r.requiredTier != null || r.pricingModel != null) {
191
+ tierBySlug.set(r.slug, {
192
+ requiredTier: r.requiredTier ?? null,
193
+ pricingModel: r.pricingModel ?? null,
194
+ });
195
+ }
196
+ // Locked = declares a tier this account's `/available` set doesn't include.
197
+ if (availableSlugs && r.requiredTier && !availableSlugs.has(r.slug)) {
198
+ lockedSlugs.add(r.slug);
199
+ }
200
+ }
201
+ // Dedup by slug; `/mine` rows overwrite public ones so the private flag wins.
202
+ const bySlug = new Map();
203
+ for (const r of publicRows)
204
+ bySlug.set(r.slug, rowToRemoteEntry(r, undefined));
205
+ for (const r of mineRows)
206
+ bySlug.set(r.slug, r);
207
+ const rows = [...bySlug.values()];
208
+ return {
209
+ rows,
210
+ status: "ok",
211
+ loggedIn: true,
212
+ email: creds.email,
213
+ privateCount: rows.filter((r) => r.isPrivate).length,
214
+ tierBySlug,
215
+ lockedSlugs,
216
+ };
217
+ }
218
+ // ─── WRITE half: publish / unpublish ────────────────────────────────────────
219
+ // Everything above is GET-only. These are the CLI's publish-loop write door to
220
+ // `POST /api/packages` (upsert on (slug, authorId), content-hash version) and
221
+ // `PATCH /api/packages/:slug` (owner-gated). All CP HTTP goes through THIS file
222
+ // — the command layer never hand-rolls a `fetch`.
223
+ /**
224
+ * A CP write failure carrying the server's OWN message + status, so the caller
225
+ * can surface `detail` (never swallow it — the `readErrorBody`/`detail` lesson)
226
+ * and special-case a 403 reserved-slug rejection.
227
+ */
228
+ export class CpWriteError extends Error {
229
+ status;
230
+ serverMessage;
231
+ constructor(status, serverMessage) {
232
+ super(serverMessage);
233
+ this.status = status;
234
+ this.serverMessage = serverMessage;
235
+ this.name = "CpWriteError";
236
+ }
237
+ }
238
+ /**
239
+ * Extract the human cause from a CP error body, mirroring `hub-client`'s
240
+ * `readErrorBody` precedence (message → error+detail → error → detail) so the
241
+ * SPECIFIC cause in `detail` is never thrown away for the generic `error`.
242
+ */
243
+ function extractServerMessage(raw, status) {
244
+ const trimmed = raw.trim();
245
+ if (!trimmed)
246
+ return `HTTP ${status}`;
247
+ try {
248
+ const o = JSON.parse(trimmed);
249
+ const str = (v) => typeof v === "string" && v.trim() ? v.trim() : undefined;
250
+ const err = str(o.error);
251
+ const detail = str(o.detail);
252
+ const msg = str(o.message);
253
+ const base = msg ?? (err && detail ? `${err}: ${detail}` : (err ?? detail));
254
+ if (base) {
255
+ if (Array.isArray(o.issues) && o.issues.length) {
256
+ return `${base} (${o.issues.length} validation issue(s))`;
257
+ }
258
+ return base;
259
+ }
260
+ }
261
+ catch {
262
+ // not JSON — fall through to the plain-text body
263
+ }
264
+ return trimmed.length > 200 ? `${trimmed.slice(0, 200)}…` : trimmed;
265
+ }
266
+ function requireToken(deps) {
267
+ const token = deps.token ?? getStoredToken()?.token;
268
+ if (!token)
269
+ throw new CpWriteError(401, "Not logged in — run: synap login");
270
+ return token;
271
+ }
272
+ /**
273
+ * `POST /api/packages` — publish (upsert) a package definition under the caller's
274
+ * account. `isPublic` decides visibility (default private — the command flips it
275
+ * with `--public`). The version is DERIVED server-side from the definition, so
276
+ * identical content re-published is a no-op. Surfaces a 403 reserved-slug
277
+ * rejection (and any other failure) as a `CpWriteError` carrying the server's
278
+ * own message.
279
+ *
280
+ * The definition's identity (`slug`, `displayName`) is read off its `_meta`/
281
+ * `workspaceName`; `_meta.icon`/`.color`/`.domain` are hoisted onto the
282
+ * definition's top level because the CP reads those off `definition.icon`/… for
283
+ * the list DTO (it strips the unknown `_meta` key).
284
+ */
285
+ export async function publishPackage(def, opts, deps = {}) {
286
+ const fetchImpl = deps.fetchImpl ?? fetch;
287
+ const token = requireToken(deps);
288
+ const base = deps.cpUrl ?? getCpUrl();
289
+ const slug = def._meta?.slug;
290
+ const displayName = def.workspaceName;
291
+ if (!slug)
292
+ throw new CpWriteError(0, "Template has no slug (meta.slug) — cannot publish");
293
+ if (!displayName)
294
+ throw new CpWriteError(0, "Template has no workspace name — cannot publish");
295
+ // Best-effort pre-read of the caller's OWN row for this slug, so a
296
+ // content-identical no-op is told apart from an in-place update (the CP
297
+ // returns 200 for both). A failure here only loses that precision.
298
+ let priorVersion;
299
+ let existed = false;
300
+ try {
301
+ const pre = await fetchImpl(`${base}/api/packages/mine?limit=100`, {
302
+ headers: { Authorization: `Bearer ${token}` },
303
+ signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
304
+ });
305
+ if (pre.ok) {
306
+ const data = (await pre.json());
307
+ const row = (data.packages ?? []).find((r) => r.slug === slug);
308
+ if (row) {
309
+ existed = true;
310
+ priorVersion = row.version;
311
+ }
312
+ }
313
+ }
314
+ catch {
315
+ // best-effort
316
+ }
317
+ const definition = {
318
+ ...def,
319
+ icon: def._meta?.icon ?? def.icon,
320
+ color: def._meta?.color ?? def.color,
321
+ domain: def._meta?.domain ?? def.domain,
322
+ };
323
+ const res = await fetchImpl(`${base}/api/packages`, {
324
+ method: "POST",
325
+ headers: {
326
+ Authorization: `Bearer ${token}`,
327
+ "Content-Type": "application/json",
328
+ },
329
+ body: JSON.stringify({
330
+ slug,
331
+ displayName,
332
+ description: def.description,
333
+ isPublic: opts.isPublic,
334
+ tags: def._meta?.tags,
335
+ category: "workspace",
336
+ definition,
337
+ }),
338
+ signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
339
+ });
340
+ if (!res.ok) {
341
+ const raw = await res.text().catch(() => "");
342
+ throw new CpWriteError(res.status, extractServerMessage(raw, res.status));
343
+ }
344
+ const data = (await res.json());
345
+ const version = data.package?.version ?? "";
346
+ const outcome = res.status === 201
347
+ ? "created"
348
+ : existed && priorVersion === version
349
+ ? "no-op"
350
+ : "updated";
351
+ return {
352
+ outcome,
353
+ slug,
354
+ displayName,
355
+ version,
356
+ isPublic: data.package?.isPublic ?? opts.isPublic,
357
+ };
358
+ }
359
+ /**
360
+ * `PATCH /api/packages/:slug` — owner-gated flip of a package to private.
361
+ *
362
+ * ⚠️ TODO(cp): the CP PATCH handler's body validator is
363
+ * `z.object({ podId: z.string().min(1).nullable() })` TODAY — it does NOT accept
364
+ * `isPublic`, so this call currently fails (400) until the CP adds `isPublic` to
365
+ * that PATCH allow-list. This is deliberately the INTENDED endpoint (not a
366
+ * faked flip): it will start working the moment the CP door is widened. The
367
+ * command surfaces the CP's message honestly meanwhile.
368
+ */
369
+ export async function unpublishPackage(slug, deps = {}) {
370
+ const fetchImpl = deps.fetchImpl ?? fetch;
371
+ const token = requireToken(deps);
372
+ const base = deps.cpUrl ?? getCpUrl();
373
+ const res = await fetchImpl(`${base}/api/packages/${encodeURIComponent(slug)}`, {
374
+ method: "PATCH",
375
+ headers: {
376
+ Authorization: `Bearer ${token}`,
377
+ "Content-Type": "application/json",
378
+ },
379
+ body: JSON.stringify({ isPublic: false }),
380
+ signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
381
+ });
382
+ if (!res.ok) {
383
+ const raw = await res.text().catch(() => "");
384
+ throw new CpWriteError(res.status, extractServerMessage(raw, res.status));
385
+ }
386
+ const data = (await res.json());
387
+ return { slug, isPublic: data.isPublic ?? false };
388
+ }
389
+ //# sourceMappingURL=cp-packages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cp-packages.js","sourceRoot":"","sources":["../../src/lib/cp-packages.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Shared lens display formatter.
3
+ *
4
+ * The lens itself — `{ workspaceId, projectId, focusSessionId }` — is resolved
5
+ * by `resolveActiveLens()` in `session-lens.ts`; this module only answers "how
6
+ * do we SHOW it". Before this existed, `commands/lens.ts` and
7
+ * `commands/statusline.ts` each hand-rolled their own "no workspace → pod-wide"
8
+ * / "no project → none" fallback text. One formatter now owns that logic so
9
+ * new surfaces (Raycast, `orient`) can render the same lens consistently.
10
+ *
11
+ * Colors/links are deliberately NOT baked in here — `lens.ts` uses chalk,
12
+ * `statusline.ts` uses raw ANSI + OSC-8 hyperlinks, and a future Raycast
13
+ * consumer will use neither. Callers wrap the plain names/ids this module
14
+ * resolves in whatever presentation their surface needs.
15
+ */
16
+ export interface LensEntry {
17
+ id: string;
18
+ name?: string;
19
+ }
20
+ export interface ResolvedLens {
21
+ workspace?: LensEntry;
22
+ project?: LensEntry;
23
+ session?: LensEntry;
24
+ }
25
+ export interface DescribedLensField {
26
+ id: string;
27
+ /** Display name, falling back to the raw id when no name was resolved. */
28
+ name: string;
29
+ }
30
+ export interface DescribedLens {
31
+ structured: {
32
+ workspace?: DescribedLensField;
33
+ project?: DescribedLensField;
34
+ session?: DescribedLensField;
35
+ /** True iff neither a workspace nor a project is bound — fully pod-wide. */
36
+ podWide: boolean;
37
+ };
38
+ /** One "Label: value" line per field, in workspace/project/session order — value is the
39
+ * placeholder text when unset, so callers can print it as-is or re-color it. */
40
+ lines: Array<{
41
+ label: "Workspace" | "Project" | "Session";
42
+ value: string;
43
+ bound: boolean;
44
+ }>;
45
+ }
46
+ export declare function describeLens(lens: ResolvedLens): DescribedLens;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Shared lens display formatter.
3
+ *
4
+ * The lens itself — `{ workspaceId, projectId, focusSessionId }` — is resolved
5
+ * by `resolveActiveLens()` in `session-lens.ts`; this module only answers "how
6
+ * do we SHOW it". Before this existed, `commands/lens.ts` and
7
+ * `commands/statusline.ts` each hand-rolled their own "no workspace → pod-wide"
8
+ * / "no project → none" fallback text. One formatter now owns that logic so
9
+ * new surfaces (Raycast, `orient`) can render the same lens consistently.
10
+ *
11
+ * Colors/links are deliberately NOT baked in here — `lens.ts` uses chalk,
12
+ * `statusline.ts` uses raw ANSI + OSC-8 hyperlinks, and a future Raycast
13
+ * consumer will use neither. Callers wrap the plain names/ids this module
14
+ * resolves in whatever presentation their surface needs.
15
+ */
16
+ function describeField(entry) {
17
+ if (!entry?.id)
18
+ return undefined;
19
+ return { id: entry.id, name: entry.name?.trim() || entry.id };
20
+ }
21
+ export function describeLens(lens) {
22
+ const workspace = describeField(lens.workspace);
23
+ const project = describeField(lens.project);
24
+ const session = describeField(lens.session);
25
+ const podWide = !workspace && !project;
26
+ const lines = [
27
+ { label: "Workspace", value: workspace?.name ?? "— (pod-wide)", bound: Boolean(workspace) },
28
+ { label: "Project", value: project?.name ?? "— none", bound: Boolean(project) },
29
+ { label: "Session", value: session?.name ?? "— none", bound: Boolean(session) },
30
+ ];
31
+ return { structured: { workspace, project, session, podWide }, lines };
32
+ }
33
+ //# sourceMappingURL=describe-lens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"describe-lens.js","sourceRoot":"","sources":["../../src/lib/describe-lens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAgCH,SAAS,aAAa,CAAC,KAAiB;IACtC,IAAI,CAAC,KAAK,EAAE,EAAE;QAAE,OAAO,SAAS,CAAC;IACjC,OAAO,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,KAAK,CAAC,EAAE,EAAE,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAkB;IAC7C,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAChD,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAG,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC;IAEvC,MAAM,KAAK,GAA2B;QACpC,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,IAAI,cAAc,EAAE,KAAK,EAAE,OAAO,CAAC,SAAS,CAAC,EAAE;QAC3F,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,IAAI,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE;QAC/E,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,IAAI,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE;KAChF,CAAC;IAEF,OAAO,EAAE,UAAU,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC;AACzE,CAAC"}