@prismer/runtime 2.0.7 → 2.2.55

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 (291) hide show
  1. package/CHANGELOG.md +3631 -0
  2. package/README.md +34 -12
  3. package/apc/skills/FIELD-DICTIONARY.md +111 -0
  4. package/apc/skills/bug-reproduce/SKILL.md +150 -0
  5. package/apc/skills/bug-reproduce/skill.json +96 -0
  6. package/apc/skills/code-review/SKILL.md +198 -0
  7. package/apc/skills/code-review/skill.json +124 -0
  8. package/apc/skills/design-review/SKILL.md +122 -0
  9. package/apc/skills/design-review/skill.json +88 -0
  10. package/apc/skills/doc-sync/SKILL.md +168 -0
  11. package/apc/skills/doc-sync/skill.json +81 -0
  12. package/apc/skills/env-doctor/SKILL.md +194 -0
  13. package/apc/skills/env-doctor/skill.json +209 -0
  14. package/apc/skills/git-ops/SKILL.md +189 -0
  15. package/apc/skills/git-ops/skill.json +94 -0
  16. package/apc/skills/impact-trace/SKILL.md +168 -0
  17. package/apc/skills/impact-trace/skill.json +104 -0
  18. package/apc/skills/observability/SKILL.md +195 -0
  19. package/apc/skills/observability/skill.json +116 -0
  20. package/apc/skills/release-db-config-sync/SKILL.md +186 -0
  21. package/apc/skills/release-db-config-sync/skill.json +109 -0
  22. package/apc/skills/release-ota-promote/SKILL.md +195 -0
  23. package/apc/skills/release-ota-promote/skill.json +176 -0
  24. package/apc/skills/release-preflight/SKILL.md +174 -0
  25. package/apc/skills/release-preflight/skill.json +175 -0
  26. package/apc/skills/release-rollback/SKILL.md +214 -0
  27. package/apc/skills/release-rollback/skill.json +230 -0
  28. package/apc/skills/release-tag/SKILL.md +194 -0
  29. package/apc/skills/release-tag/skill.json +94 -0
  30. package/apc/skills/releasing-prod/SKILL.md +49 -0
  31. package/apc/skills/releasing-test/SKILL.md +135 -0
  32. package/apc/skills/sdk-release/SKILL.md +200 -0
  33. package/apc/skills/spec-intake/SKILL.md +169 -0
  34. package/apc/skills/spec-intake/skill.json +93 -0
  35. package/apc/skills/test-result-feedback/SKILL.md +239 -0
  36. package/apc/skills/test-result-feedback/skill.json +193 -0
  37. package/apc/skills/test-runner/SKILL.md +169 -0
  38. package/apc/skills/test-runner/skill.json +103 -0
  39. package/apc/skills/ui-align/SKILL.md +209 -0
  40. package/apc/skills/ui-align/skill.json +114 -0
  41. package/apc/skills/ui-canvas/SKILL.md +148 -0
  42. package/apc/skills/ui-canvas/skill.json +127 -0
  43. package/built-in-skills/agent-coordination/SKILL.md +257 -0
  44. package/built-in-skills/agent-meta/SKILL.md +53 -0
  45. package/built-in-skills/assets/SKILL.md +133 -0
  46. package/built-in-skills/browser-use/SKILL.md +93 -0
  47. package/built-in-skills/canvas-design/LICENSE.txt +202 -0
  48. package/built-in-skills/canvas-design/SKILL.md +157 -0
  49. package/built-in-skills/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +93 -0
  50. package/built-in-skills/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
  51. package/built-in-skills/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
  52. package/built-in-skills/canvas-design/canvas-fonts/BigShoulders-OFL.txt +93 -0
  53. package/built-in-skills/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
  54. package/built-in-skills/canvas-design/canvas-fonts/Boldonse-OFL.txt +93 -0
  55. package/built-in-skills/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
  56. package/built-in-skills/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
  57. package/built-in-skills/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +93 -0
  58. package/built-in-skills/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
  59. package/built-in-skills/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
  60. package/built-in-skills/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
  61. package/built-in-skills/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +93 -0
  62. package/built-in-skills/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
  63. package/built-in-skills/canvas-design/canvas-fonts/DMMono-OFL.txt +93 -0
  64. package/built-in-skills/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
  65. package/built-in-skills/canvas-design/canvas-fonts/EricaOne-OFL.txt +94 -0
  66. package/built-in-skills/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
  67. package/built-in-skills/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
  68. package/built-in-skills/canvas-design/canvas-fonts/GeistMono-OFL.txt +93 -0
  69. package/built-in-skills/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
  70. package/built-in-skills/canvas-design/canvas-fonts/Gloock-OFL.txt +93 -0
  71. package/built-in-skills/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
  72. package/built-in-skills/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
  73. package/built-in-skills/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +93 -0
  74. package/built-in-skills/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
  75. package/built-in-skills/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
  76. package/built-in-skills/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
  77. package/built-in-skills/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
  78. package/built-in-skills/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
  79. package/built-in-skills/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
  80. package/built-in-skills/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
  81. package/built-in-skills/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
  82. package/built-in-skills/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +93 -0
  83. package/built-in-skills/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
  84. package/built-in-skills/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
  85. package/built-in-skills/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
  86. package/built-in-skills/canvas-design/canvas-fonts/Italiana-OFL.txt +93 -0
  87. package/built-in-skills/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
  88. package/built-in-skills/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
  89. package/built-in-skills/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +93 -0
  90. package/built-in-skills/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
  91. package/built-in-skills/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
  92. package/built-in-skills/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
  93. package/built-in-skills/canvas-design/canvas-fonts/Jura-OFL.txt +93 -0
  94. package/built-in-skills/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +93 -0
  95. package/built-in-skills/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
  96. package/built-in-skills/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
  97. package/built-in-skills/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
  98. package/built-in-skills/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
  99. package/built-in-skills/canvas-design/canvas-fonts/Lora-OFL.txt +93 -0
  100. package/built-in-skills/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
  101. package/built-in-skills/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
  102. package/built-in-skills/canvas-design/canvas-fonts/NationalPark-OFL.txt +93 -0
  103. package/built-in-skills/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
  104. package/built-in-skills/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -0
  105. package/built-in-skills/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
  106. package/built-in-skills/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
  107. package/built-in-skills/canvas-design/canvas-fonts/Outfit-OFL.txt +93 -0
  108. package/built-in-skills/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
  109. package/built-in-skills/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
  110. package/built-in-skills/canvas-design/canvas-fonts/PixelifySans-OFL.txt +93 -0
  111. package/built-in-skills/canvas-design/canvas-fonts/PoiretOne-OFL.txt +93 -0
  112. package/built-in-skills/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
  113. package/built-in-skills/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
  114. package/built-in-skills/canvas-design/canvas-fonts/RedHatMono-OFL.txt +93 -0
  115. package/built-in-skills/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
  116. package/built-in-skills/canvas-design/canvas-fonts/Silkscreen-OFL.txt +93 -0
  117. package/built-in-skills/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
  118. package/built-in-skills/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
  119. package/built-in-skills/canvas-design/canvas-fonts/SmoochSans-OFL.txt +93 -0
  120. package/built-in-skills/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
  121. package/built-in-skills/canvas-design/canvas-fonts/Tektur-OFL.txt +93 -0
  122. package/built-in-skills/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
  123. package/built-in-skills/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
  124. package/built-in-skills/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
  125. package/built-in-skills/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
  126. package/built-in-skills/canvas-design/canvas-fonts/WorkSans-OFL.txt +93 -0
  127. package/built-in-skills/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
  128. package/built-in-skills/canvas-design/canvas-fonts/YoungSerif-OFL.txt +93 -0
  129. package/built-in-skills/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
  130. package/built-in-skills/claim-agent-ownership/SKILL.md +255 -0
  131. package/built-in-skills/claude-api/LICENSE.txt +202 -0
  132. package/built-in-skills/claude-api/SKILL.md +325 -0
  133. package/built-in-skills/claude-api/csharp/claude-api.md +402 -0
  134. package/built-in-skills/claude-api/curl/examples.md +216 -0
  135. package/built-in-skills/claude-api/curl/managed-agents.md +336 -0
  136. package/built-in-skills/claude-api/go/claude-api.md +421 -0
  137. package/built-in-skills/claude-api/go/managed-agents/README.md +561 -0
  138. package/built-in-skills/claude-api/java/claude-api.md +432 -0
  139. package/built-in-skills/claude-api/java/managed-agents/README.md +442 -0
  140. package/built-in-skills/claude-api/php/claude-api.md +375 -0
  141. package/built-in-skills/claude-api/php/managed-agents/README.md +435 -0
  142. package/built-in-skills/claude-api/python/claude-api/README.md +420 -0
  143. package/built-in-skills/claude-api/python/claude-api/batches.md +185 -0
  144. package/built-in-skills/claude-api/python/claude-api/files-api.md +165 -0
  145. package/built-in-skills/claude-api/python/claude-api/streaming.md +162 -0
  146. package/built-in-skills/claude-api/python/claude-api/tool-use.md +590 -0
  147. package/built-in-skills/claude-api/python/managed-agents/README.md +332 -0
  148. package/built-in-skills/claude-api/ruby/claude-api.md +113 -0
  149. package/built-in-skills/claude-api/ruby/managed-agents/README.md +389 -0
  150. package/built-in-skills/claude-api/shared/agent-design.md +101 -0
  151. package/built-in-skills/claude-api/shared/error-codes.md +213 -0
  152. package/built-in-skills/claude-api/shared/live-sources.md +135 -0
  153. package/built-in-skills/claude-api/shared/managed-agents-api-reference.md +378 -0
  154. package/built-in-skills/claude-api/shared/managed-agents-client-patterns.md +209 -0
  155. package/built-in-skills/claude-api/shared/managed-agents-core.md +238 -0
  156. package/built-in-skills/claude-api/shared/managed-agents-environments.md +215 -0
  157. package/built-in-skills/claude-api/shared/managed-agents-events.md +195 -0
  158. package/built-in-skills/claude-api/shared/managed-agents-memory.md +197 -0
  159. package/built-in-skills/claude-api/shared/managed-agents-multiagent.md +99 -0
  160. package/built-in-skills/claude-api/shared/managed-agents-onboarding.md +114 -0
  161. package/built-in-skills/claude-api/shared/managed-agents-outcomes.md +106 -0
  162. package/built-in-skills/claude-api/shared/managed-agents-overview.md +68 -0
  163. package/built-in-skills/claude-api/shared/managed-agents-self-hosted-sandboxes.md +173 -0
  164. package/built-in-skills/claude-api/shared/managed-agents-tools.md +321 -0
  165. package/built-in-skills/claude-api/shared/managed-agents-webhooks.md +110 -0
  166. package/built-in-skills/claude-api/shared/model-migration.md +779 -0
  167. package/built-in-skills/claude-api/shared/models.md +121 -0
  168. package/built-in-skills/claude-api/shared/prompt-caching.md +171 -0
  169. package/built-in-skills/claude-api/shared/tool-use-concepts.md +327 -0
  170. package/built-in-skills/claude-api/typescript/claude-api/README.md +333 -0
  171. package/built-in-skills/claude-api/typescript/claude-api/batches.md +106 -0
  172. package/built-in-skills/claude-api/typescript/claude-api/files-api.md +98 -0
  173. package/built-in-skills/claude-api/typescript/claude-api/streaming.md +178 -0
  174. package/built-in-skills/claude-api/typescript/claude-api/tool-use.md +527 -0
  175. package/built-in-skills/claude-api/typescript/managed-agents/README.md +359 -0
  176. package/built-in-skills/codebase-design/DEEPENING.md +37 -0
  177. package/built-in-skills/codebase-design/DESIGN-IT-TWICE.md +44 -0
  178. package/built-in-skills/codebase-design/LICENSE +21 -0
  179. package/built-in-skills/codebase-design/SKILL.md +116 -0
  180. package/built-in-skills/conversation-compaction/SKILL.md +114 -0
  181. package/built-in-skills/council-creator/SKILL.md +426 -0
  182. package/built-in-skills/diagnosing-bugs/LICENSE +21 -0
  183. package/built-in-skills/diagnosing-bugs/SKILL.md +136 -0
  184. package/built-in-skills/diagnosing-bugs/scripts/hitl-loop.template.sh +41 -0
  185. package/built-in-skills/doc-coauthoring/SKILL.md +376 -0
  186. package/built-in-skills/document-generation/SKILL.md +105 -0
  187. package/built-in-skills/domain-modeling/ADR-FORMAT.md +47 -0
  188. package/built-in-skills/domain-modeling/CONTEXT-FORMAT.md +60 -0
  189. package/built-in-skills/domain-modeling/LICENSE +21 -0
  190. package/built-in-skills/domain-modeling/SKILL.md +76 -0
  191. package/built-in-skills/frontend-design/LICENSE.txt +177 -0
  192. package/built-in-skills/frontend-design/SKILL.md +43 -0
  193. package/built-in-skills/human-approval/SKILL.md +129 -0
  194. package/built-in-skills/image-generate/SKILL.md +128 -0
  195. package/built-in-skills/image-generate/scripts/generate-and-deliver.mjs +289 -0
  196. package/built-in-skills/ingest/SKILL.md +73 -0
  197. package/built-in-skills/internal-comms/LICENSE.txt +202 -0
  198. package/built-in-skills/internal-comms/SKILL.md +33 -0
  199. package/built-in-skills/internal-comms/examples/3p-updates.md +47 -0
  200. package/built-in-skills/internal-comms/examples/company-newsletter.md +65 -0
  201. package/built-in-skills/internal-comms/examples/faq-answers.md +30 -0
  202. package/built-in-skills/internal-comms/examples/general-comms.md +16 -0
  203. package/built-in-skills/liteparse/SKILL.md +176 -0
  204. package/built-in-skills/mcp-builder/LICENSE.txt +202 -0
  205. package/built-in-skills/mcp-builder/SKILL.md +237 -0
  206. package/built-in-skills/mcp-builder/reference/evaluation.md +602 -0
  207. package/built-in-skills/mcp-builder/reference/mcp_best_practices.md +249 -0
  208. package/built-in-skills/mcp-builder/reference/node_mcp_server.md +970 -0
  209. package/built-in-skills/mcp-builder/reference/python_mcp_server.md +719 -0
  210. package/built-in-skills/mcp-builder/scripts/connections.py +151 -0
  211. package/built-in-skills/mcp-builder/scripts/evaluation.py +373 -0
  212. package/built-in-skills/mcp-builder/scripts/example_evaluation.xml +22 -0
  213. package/built-in-skills/mcp-builder/scripts/requirements.txt +2 -0
  214. package/built-in-skills/memory/SKILL.md +471 -0
  215. package/built-in-skills/memory-dream/SKILL.md +339 -0
  216. package/built-in-skills/office-artifacts/SKILL.md +211 -0
  217. package/built-in-skills/okr/SKILL.md +154 -0
  218. package/built-in-skills/persona/SKILL.md +81 -0
  219. package/built-in-skills/persona-generator/SKILL.md +296 -0
  220. package/built-in-skills/pkf-svg/SKILL.md +253 -0
  221. package/built-in-skills/pkf-writing/SKILL.md +236 -0
  222. package/built-in-skills/prismer-im-collab/SKILL.md +168 -0
  223. package/built-in-skills/proactivity/SKILL.md +84 -0
  224. package/built-in-skills/remotion/SKILL.md +431 -0
  225. package/built-in-skills/role-builder/SKILL.md +203 -0
  226. package/built-in-skills/role-builder/scripts/author-role.mjs +334 -0
  227. package/built-in-skills/role-builder/scripts/ingest-role.mjs +223 -0
  228. package/built-in-skills/role-builder/scripts/instantiate-and-run.mjs +290 -0
  229. package/built-in-skills/role-builder/scripts/operation-harness.mjs +267 -0
  230. package/built-in-skills/skill-authoring/SKILL.md +134 -0
  231. package/built-in-skills/skill-authoring/skill.json +74 -0
  232. package/built-in-skills/skill-builder/SKILL.md +171 -0
  233. package/built-in-skills/skill-builder/scripts/ingest.mjs +265 -0
  234. package/built-in-skills/skill-creator/LICENSE.txt +202 -0
  235. package/built-in-skills/skill-creator/SKILL.md +227 -0
  236. package/built-in-skills/skill-creator/agents/analyzer.md +274 -0
  237. package/built-in-skills/skill-creator/agents/comparator.md +202 -0
  238. package/built-in-skills/skill-creator/agents/grader.md +223 -0
  239. package/built-in-skills/skill-creator/assets/eval_review.html +146 -0
  240. package/built-in-skills/skill-creator/eval-viewer/generate_review.py +471 -0
  241. package/built-in-skills/skill-creator/eval-viewer/viewer.html +1325 -0
  242. package/built-in-skills/skill-creator/references/external-library-import.md +110 -0
  243. package/built-in-skills/skill-creator/references/schemas.md +430 -0
  244. package/built-in-skills/skill-creator/scripts/__init__.py +0 -0
  245. package/built-in-skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
  246. package/built-in-skills/skill-creator/scripts/generate_report.py +326 -0
  247. package/built-in-skills/skill-creator/scripts/import-library.mjs +475 -0
  248. package/built-in-skills/skill-creator/scripts/improve_description.py +247 -0
  249. package/built-in-skills/skill-creator/scripts/package_skill.py +136 -0
  250. package/built-in-skills/skill-creator/scripts/quick_validate.py +103 -0
  251. package/built-in-skills/skill-creator/scripts/run_eval.py +310 -0
  252. package/built-in-skills/skill-creator/scripts/run_loop.py +328 -0
  253. package/built-in-skills/skill-creator/scripts/utils.py +47 -0
  254. package/built-in-skills/slack-gif-creator/LICENSE.txt +202 -0
  255. package/built-in-skills/slack-gif-creator/SKILL.md +291 -0
  256. package/built-in-skills/slack-gif-creator/core/easing.py +234 -0
  257. package/built-in-skills/slack-gif-creator/core/frame_composer.py +176 -0
  258. package/built-in-skills/slack-gif-creator/core/gif_builder.py +269 -0
  259. package/built-in-skills/slack-gif-creator/core/validators.py +136 -0
  260. package/built-in-skills/slack-gif-creator/requirements.txt +4 -0
  261. package/built-in-skills/tasks/SKILL.md +413 -0
  262. package/built-in-skills/tdd/LICENSE +21 -0
  263. package/built-in-skills/tdd/SKILL.md +110 -0
  264. package/built-in-skills/tdd/mocking.md +59 -0
  265. package/built-in-skills/tdd/refactoring.md +10 -0
  266. package/built-in-skills/tdd/tests.md +61 -0
  267. package/built-in-skills/team/SKILL.md +77 -0
  268. package/built-in-skills/web-artifacts-builder/LICENSE.txt +202 -0
  269. package/built-in-skills/web-artifacts-builder/SKILL.md +105 -0
  270. package/built-in-skills/web-artifacts-builder/scripts/bundle-artifact.sh +54 -0
  271. package/built-in-skills/web-artifacts-builder/scripts/init-artifact.sh +334 -0
  272. package/built-in-skills/web-artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
  273. package/built-in-skills/webapp-testing/LICENSE.txt +202 -0
  274. package/built-in-skills/webapp-testing/SKILL.md +97 -0
  275. package/built-in-skills/webapp-testing/examples/console_logging.py +35 -0
  276. package/built-in-skills/webapp-testing/examples/element_discovery.py +40 -0
  277. package/built-in-skills/webapp-testing/examples/static_html_automation.py +33 -0
  278. package/built-in-skills/webapp-testing/scripts/with_server.py +106 -0
  279. package/built-in-skills/wechat-pay/SKILL.md +59 -0
  280. package/dist/cli.cjs +72577 -16101
  281. package/dist/cli.js +72752 -16232
  282. package/dist/index.cjs +72632 -16024
  283. package/dist/index.d.cts +4956 -640
  284. package/dist/index.d.ts +4956 -640
  285. package/dist/index.js +72564 -15963
  286. package/package.json +39 -6
  287. package/plugins/memory/prismer/__init__.py +1211 -0
  288. package/plugins/memory/prismer/plugin.yaml +8 -0
  289. package/plugins/memory/prismer/tool-schemas.generated.json +249 -0
  290. package/plugins/tools/prismer-recall/__init__.py +282 -0
  291. package/plugins/tools/prismer-recall/plugin.yaml +15 -0
@@ -0,0 +1,290 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {
4
+ HarnessError,
5
+ invocationHash,
6
+ loadHarnessConfig,
7
+ readLedger,
8
+ requestJson,
9
+ sleep,
10
+ taskIdempotencyKey,
11
+ writeLedger,
12
+ } from './operation-harness.mjs';
13
+
14
+ const HELP = `Usage:
15
+ # with the required PRISMER_* environment already injected:
16
+ node scripts/instantiate-and-run.mjs [--json]
17
+
18
+ Configuration stays in environment variables. Non-secret flags are available:
19
+ --role --workspace --task --title --handle --display-name --adapter
20
+ --target-daemon --request-id --ledger --timeout-ms --poll-ms
21
+ --preflight-only --no-wait --json
22
+
23
+ Remote writes require PRISMER_ALLOW_REMOTE_WRITE=1 from the trusted environment.
24
+ Set PRISMER_REQUEST_ID once when an interrupted operation must be resumed.
25
+
26
+ Exit codes: 2 local harness rejection, 3 auth, 4 transient/network, 5 remote contract.`;
27
+
28
+ function instanceBody(config) {
29
+ return {
30
+ workspaceId: config.workspaceId,
31
+ requestId: config.requestId,
32
+ ...(config.handle ? { handle: config.handle } : {}),
33
+ ...(config.displayName ? { displayName: config.displayName } : {}),
34
+ adapterName: config.adapterName,
35
+ ...(config.targetDaemonId ? { targetDaemonId: config.targetDaemonId } : {}),
36
+ };
37
+ }
38
+
39
+ function emit(config, ledger) {
40
+ if (config.json) process.stdout.write(`${JSON.stringify(ledger)}\n`);
41
+ else {
42
+ process.stdout.write(
43
+ `[role-builder] ${ledger.stage}: role=${config.role} workspace=${config.workspaceId}` +
44
+ `${ledger.agent?.id ? ` agent=${ledger.agent.id}` : ''}${ledger.task?.id ? ` task=${ledger.task.id}` : ''}\n`,
45
+ );
46
+ }
47
+ }
48
+
49
+ async function findExistingInstance(config) {
50
+ try {
51
+ const read = await requestJson(
52
+ config,
53
+ 'GET',
54
+ `/api/im/role-templates/${encodeURIComponent(config.role)}/instances/${encodeURIComponent(config.requestId)}`,
55
+ undefined,
56
+ 'operation_lookup',
57
+ );
58
+ return read.data;
59
+ } catch (error) {
60
+ if (error instanceof HarnessError && error.details?.status === 404) return null;
61
+ throw error;
62
+ }
63
+ }
64
+
65
+ async function waitForInstance(config, initial, ledger) {
66
+ let instance = initial;
67
+ const started = Date.now();
68
+ let lastResumeAt = started;
69
+ while (Date.now() - started < config.timeoutMs) {
70
+ if (instance.status === 'failed') {
71
+ throw new HarnessError(
72
+ 'instance',
73
+ instance.error?.code || 'ROLE_INSTANCE_FAILED',
74
+ instance.error?.message || 'role instance provisioning failed',
75
+ instance.error?.retryable ? 4 : 5,
76
+ );
77
+ }
78
+ if (instance.execution?.state === 'wrong_daemon') {
79
+ throw new HarnessError(
80
+ 'instance_wait',
81
+ 'ROLE_INSTANCE_WRONG_DAEMON',
82
+ `agent is bound to ${instance.execution.boundDaemonId || 'an unknown daemon'} instead of ${instance.execution.targetDaemonId || 'the requested daemon'}`,
83
+ 5,
84
+ {
85
+ targetDaemonId: instance.execution.targetDaemonId ?? null,
86
+ boundDaemonId: instance.execution.boundDaemonId ?? null,
87
+ },
88
+ );
89
+ }
90
+ // A task must never be created for an agent that the runtime has not yet
91
+ // adopted. `--no-wait` skips only the final task-result wait.
92
+ if (instance.status === 'ready' && instance.execution?.state === 'ready') return instance;
93
+ await sleep(config.pollMs);
94
+ const read = await requestJson(
95
+ config,
96
+ 'GET',
97
+ `/api/im/role-templates/${encodeURIComponent(config.role)}/instances/${encodeURIComponent(config.requestId)}`,
98
+ undefined,
99
+ 'instance_wait',
100
+ );
101
+ instance = read.data;
102
+ ledger.instance = instance;
103
+ ledger.stage = instance.status === 'ready' ? 'waiting_for_runtime' : 'provisioning_agent';
104
+ ledger.updatedAt = new Date().toISOString();
105
+ writeLedger(config.ledgerPath, ledger);
106
+
107
+ // A process may die after accepting the operation. Periodically re-POSTing
108
+ // is safe: the server lease decides whether this caller may resume it.
109
+ if (instance.status === 'provisioning' && Date.now() - lastResumeAt >= 35_000) {
110
+ const resumed = await requestJson(
111
+ config,
112
+ 'POST',
113
+ `/api/im/role-templates/${encodeURIComponent(config.role)}/instances`,
114
+ instanceBody(config),
115
+ 'instance_resume',
116
+ );
117
+ instance = resumed.data;
118
+ lastResumeAt = Date.now();
119
+ }
120
+ }
121
+ throw new HarnessError('instance_wait', 'WORKFLOW_TIMEOUT', 'timed out waiting for agent runtime binding', 4);
122
+ }
123
+
124
+ async function waitForTask(config, task, ledger) {
125
+ const started = Date.now();
126
+ while (Date.now() - started < config.timeoutMs) {
127
+ if (['completed', 'failed', 'cancelled'].includes(task.status)) return task;
128
+ await sleep(config.pollMs);
129
+ const read = await requestJson(
130
+ config,
131
+ 'GET',
132
+ `/api/im/tasks/${encodeURIComponent(task.id)}`,
133
+ undefined,
134
+ 'task_wait',
135
+ );
136
+ task = read.data;
137
+ ledger.task = task;
138
+ ledger.stage = 'waiting_for_task';
139
+ ledger.updatedAt = new Date().toISOString();
140
+ writeLedger(config.ledgerPath, ledger);
141
+ }
142
+ throw new HarnessError('task_wait', 'WORKFLOW_TIMEOUT', 'timed out waiting for task result', 4);
143
+ }
144
+
145
+ export async function runRoleWorkflow(config) {
146
+ const acceptedHash = invocationHash(config);
147
+ const previous = readLedger(config.ledgerPath);
148
+ if (
149
+ previous &&
150
+ (previous.requestId !== config.requestId ||
151
+ previous.role !== config.role ||
152
+ previous.workspaceId !== config.workspaceId ||
153
+ (previous.invocationHash && previous.invocationHash !== acceptedHash))
154
+ ) {
155
+ throw new HarnessError(
156
+ 'local_validation',
157
+ 'OPERATION_LEDGER_CONFLICT',
158
+ 'the ledger path belongs to a different role workflow request',
159
+ 2,
160
+ );
161
+ }
162
+ const ledger = {
163
+ schemaVersion: 2,
164
+ requestId: config.requestId,
165
+ invocationHash: acceptedHash,
166
+ role: config.role,
167
+ workspaceId: config.workspaceId,
168
+ stage: 'local_validation_complete',
169
+ startedAt: new Date().toISOString(),
170
+ updatedAt: new Date().toISOString(),
171
+ };
172
+ // Persist the recovery key before the first request. Credentials are never
173
+ // written to the ledger or included in the result.
174
+ writeLedger(config.ledgerPath, ledger);
175
+
176
+ const existing = config.preflightOnly ? null : await findExistingInstance(config);
177
+ if (!existing || config.preflightOnly) {
178
+ const preflight = await requestJson(
179
+ config,
180
+ 'POST',
181
+ `/api/im/role-templates/${encodeURIComponent(config.role)}/instances/preflight`,
182
+ instanceBody(config),
183
+ 'remote_preflight',
184
+ );
185
+ ledger.preflight = preflight.data;
186
+ ledger.stage = 'remote_preflight_complete';
187
+ ledger.updatedAt = new Date().toISOString();
188
+ writeLedger(config.ledgerPath, ledger);
189
+ if (config.preflightOnly) return ledger;
190
+ } else {
191
+ ledger.instance = existing;
192
+ ledger.stage = 'operation_recovered';
193
+ ledger.updatedAt = new Date().toISOString();
194
+ writeLedger(config.ledgerPath, ledger);
195
+ }
196
+
197
+ // A ready/provisioning durable operation can be resumed from its read face.
198
+ // A failed operation needs an idempotent POST to re-enter server recovery.
199
+ const provisioned =
200
+ existing && existing.status !== 'failed'
201
+ ? { data: existing }
202
+ : await requestJson(
203
+ config,
204
+ 'POST',
205
+ `/api/im/role-templates/${encodeURIComponent(config.role)}/instances`,
206
+ instanceBody(config),
207
+ 'instance',
208
+ );
209
+ ledger.instance = provisioned.data;
210
+ ledger.stage = 'provisioning_agent';
211
+ ledger.updatedAt = new Date().toISOString();
212
+ writeLedger(config.ledgerPath, ledger);
213
+ const instance = await waitForInstance(config, provisioned.data, ledger);
214
+ ledger.instance = instance;
215
+ ledger.agent = instance.agent;
216
+ ledger.stage = config.wait ? 'agent_ready' : 'agent_created';
217
+ ledger.updatedAt = new Date().toISOString();
218
+ writeLedger(config.ledgerPath, ledger);
219
+
220
+ const taskRequestKey = taskIdempotencyKey(config.requestId);
221
+ const createdTask = await requestJson(
222
+ config,
223
+ 'POST',
224
+ '/api/im/tasks',
225
+ {
226
+ title: config.title,
227
+ description: config.task,
228
+ workspaceId: config.workspaceId,
229
+ assigneeId: instance.agent.id,
230
+ runtimeRoute: 'agent',
231
+ dispatchPolicy: 'on-assign',
232
+ idempotencyKey: taskRequestKey,
233
+ metadata: {
234
+ kind: 'agent_run',
235
+ createdVia: 'role-builder-script',
236
+ roleInstanceRequestId: config.requestId,
237
+ },
238
+ },
239
+ 'task_create',
240
+ );
241
+ ledger.task = createdTask.data;
242
+ ledger.stage = 'task_created';
243
+ ledger.updatedAt = new Date().toISOString();
244
+ writeLedger(config.ledgerPath, ledger);
245
+
246
+ if (config.wait) {
247
+ ledger.task = await waitForTask(config, createdTask.data, ledger);
248
+ if (ledger.task.status !== 'completed') {
249
+ throw new HarnessError(
250
+ 'task_wait',
251
+ `TASK_${String(ledger.task.status).toUpperCase()}`,
252
+ ledger.task.error || `task ended as ${ledger.task.status}`,
253
+ 5,
254
+ );
255
+ }
256
+ }
257
+ ledger.stage = config.wait ? 'completed' : 'dispatched';
258
+ ledger.completedAt = new Date().toISOString();
259
+ ledger.updatedAt = ledger.completedAt;
260
+ writeLedger(config.ledgerPath, ledger);
261
+ return ledger;
262
+ }
263
+
264
+ async function main() {
265
+ let config;
266
+ try {
267
+ config = loadHarnessConfig(process.argv.slice(2));
268
+ if (config.help) {
269
+ process.stdout.write(`${HELP}\n`);
270
+ return;
271
+ }
272
+ const result = await runRoleWorkflow(config);
273
+ emit(config, result);
274
+ } catch (error) {
275
+ const harnessError =
276
+ error instanceof HarnessError
277
+ ? error
278
+ : new HarnessError('internal', 'UNEXPECTED_ERROR', error?.message || String(error), 1);
279
+ const failure = {
280
+ ok: false,
281
+ stage: harnessError.stage,
282
+ error: { code: harnessError.code, message: harnessError.message, details: harnessError.details },
283
+ ...(config ? { requestId: config.requestId, ledger: config.ledgerPath } : {}),
284
+ };
285
+ process.stderr.write(`${JSON.stringify(failure)}\n`);
286
+ process.exitCode = harnessError.exitCode;
287
+ }
288
+ }
289
+
290
+ if (import.meta.url === `file://${process.argv[1]}`) await main();
@@ -0,0 +1,267 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { createHash, randomUUID } from 'node:crypto';
4
+ import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
5
+ import { dirname, resolve } from 'node:path';
6
+
7
+ export class HarnessError extends Error {
8
+ constructor(stage, code, message, exitCode = 1, details = undefined) {
9
+ super(message);
10
+ this.name = 'HarnessError';
11
+ this.stage = stage;
12
+ this.code = code;
13
+ this.exitCode = exitCode;
14
+ this.details = details;
15
+ }
16
+ }
17
+
18
+ const VALUE_OPTIONS = new Set([
19
+ '--role',
20
+ '--workspace',
21
+ '--task',
22
+ '--title',
23
+ '--handle',
24
+ '--display-name',
25
+ '--adapter',
26
+ '--target-daemon',
27
+ '--request-id',
28
+ '--timeout-ms',
29
+ '--poll-ms',
30
+ '--ledger',
31
+ ]);
32
+ const BOOLEAN_OPTIONS = new Set(['--json', '--no-wait', '--preflight-only', '--help']);
33
+ const SECRET_OPTIONS = new Set(['--api-key', '--token', '--jwt', '--secret', '--password']);
34
+
35
+ function optionName(arg) {
36
+ if (typeof arg !== 'string') return '';
37
+ const equalsAt = arg.indexOf('=');
38
+ return equalsAt === -1 ? arg : arg.slice(0, equalsAt);
39
+ }
40
+
41
+ export function parseHarnessArgs(argv) {
42
+ const values = {};
43
+ const flags = new Set();
44
+ for (let index = 0; index < argv.length; index += 1) {
45
+ const arg = argv[index];
46
+ const name = optionName(arg);
47
+ if (SECRET_OPTIONS.has(name)) {
48
+ throw new HarnessError(
49
+ 'local_validation',
50
+ 'SECRET_ARGUMENT_FORBIDDEN',
51
+ `${name} is forbidden; credentials must come from environment variables`,
52
+ 2,
53
+ );
54
+ }
55
+ if (BOOLEAN_OPTIONS.has(arg)) {
56
+ flags.add(arg);
57
+ continue;
58
+ }
59
+ if (!VALUE_OPTIONS.has(arg)) {
60
+ // Never reflect an untrusted argv token. Besides ordinary typos, it may
61
+ // contain a credential in an unrecognised --name=value form.
62
+ throw new HarnessError('local_validation', 'UNKNOWN_ARGUMENT', `unknown argument at position ${index + 1}`, 2);
63
+ }
64
+ const value = argv[index + 1];
65
+ if (!value || value.startsWith('--')) {
66
+ throw new HarnessError('local_validation', 'MISSING_ARGUMENT_VALUE', `${arg} requires a value`, 2);
67
+ }
68
+ values[arg] = value;
69
+ index += 1;
70
+ }
71
+ return { values, flags };
72
+ }
73
+
74
+ function envOrArg(parsed, argName, envName, env) {
75
+ return parsed.values[argName] ?? env[envName];
76
+ }
77
+
78
+ function positiveInt(raw, fallback, name) {
79
+ if (raw === undefined) return fallback;
80
+ const value = Number(raw);
81
+ if (!Number.isSafeInteger(value) || value <= 0) {
82
+ throw new HarnessError('local_validation', 'INVALID_NUMBER', `${name} must be a positive integer`, 2);
83
+ }
84
+ return value;
85
+ }
86
+
87
+ function isLocalWriteTarget(hostname) {
88
+ return ['localhost', '127.0.0.1', '::1', 'host.docker.internal'].includes(hostname);
89
+ }
90
+
91
+ export function loadHarnessConfig(argv, env = process.env) {
92
+ const parsed = parseHarnessArgs(argv);
93
+ if (parsed.flags.has('--help')) return { help: true };
94
+
95
+ const apiKey = envOrArg(parsed, '__never__', 'PRISMER_API_KEY', env);
96
+ const role = envOrArg(parsed, '--role', 'PRISMER_ROLE_SLUG', env)?.trim();
97
+ const workspaceId = envOrArg(parsed, '--workspace', 'PRISMER_WORKSPACE_ID', env)?.trim();
98
+ const task = envOrArg(parsed, '--task', 'PRISMER_TASK', env)?.trim();
99
+ const preflightOnly = parsed.flags.has('--preflight-only');
100
+ const missing = [
101
+ !apiKey && 'PRISMER_API_KEY',
102
+ !role && 'PRISMER_ROLE_SLUG/--role',
103
+ !workspaceId && 'PRISMER_WORKSPACE_ID/--workspace',
104
+ !task && !preflightOnly && 'PRISMER_TASK/--task',
105
+ ].filter(Boolean);
106
+ if (missing.length > 0) {
107
+ throw new HarnessError(
108
+ 'local_validation',
109
+ 'CONFIG_MISSING',
110
+ `missing required environment/config: ${missing.join(', ')}`,
111
+ 2,
112
+ );
113
+ }
114
+
115
+ let baseUrl;
116
+ try {
117
+ baseUrl = new URL((env.PRISMER_CLOUD_BASE || 'http://127.0.0.1:3000').replace(/\/$/, ''));
118
+ } catch {
119
+ throw new HarnessError('local_validation', 'INVALID_BASE_URL', 'PRISMER_CLOUD_BASE must be a valid URL', 2);
120
+ }
121
+ if (
122
+ !['http:', 'https:'].includes(baseUrl.protocol) ||
123
+ baseUrl.username ||
124
+ baseUrl.password ||
125
+ baseUrl.search ||
126
+ baseUrl.hash
127
+ ) {
128
+ throw new HarnessError(
129
+ 'local_validation',
130
+ 'UNSAFE_BASE_URL',
131
+ 'PRISMER_CLOUD_BASE must be a plain http(s) origin without credentials, query, or hash',
132
+ 2,
133
+ );
134
+ }
135
+ // Remote mutation authority is deliberately environment-owned. A prompt or
136
+ // copied command must not be able to grant itself authority with a CLI flag.
137
+ const allowRemote = ['1', 'true', 'yes'].includes(String(env.PRISMER_ALLOW_REMOTE_WRITE).toLowerCase());
138
+ if (!preflightOnly && !isLocalWriteTarget(baseUrl.hostname) && !allowRemote) {
139
+ throw new HarnessError(
140
+ 'local_validation',
141
+ 'REMOTE_WRITE_NOT_CONFIRMED',
142
+ 'remote mutation is blocked; set PRISMER_ALLOW_REMOTE_WRITE=1 after confirming the target environment',
143
+ 2,
144
+ );
145
+ }
146
+
147
+ const adapterName = envOrArg(parsed, '--adapter', 'PRISMER_AGENT_ADAPTER', env)?.trim() || 'hermes';
148
+ if (!['hermes', 'pi-core', 'claude-code'].includes(adapterName)) {
149
+ throw new HarnessError('local_validation', 'INVALID_ADAPTER', 'adapter must be hermes, pi-core, or claude-code', 2);
150
+ }
151
+ const requestId =
152
+ envOrArg(parsed, '--request-id', 'PRISMER_REQUEST_ID', env)?.trim() ||
153
+ `role-run-${randomUUID()}`;
154
+ if (requestId.length > 191) {
155
+ throw new HarnessError('local_validation', 'INVALID_REQUEST_ID', 'request id exceeds 191 characters', 2);
156
+ }
157
+
158
+ const config = {
159
+ apiKey,
160
+ baseUrl: baseUrl.toString().replace(/\/$/, ''),
161
+ role,
162
+ workspaceId,
163
+ task: task || '',
164
+ title:
165
+ envOrArg(parsed, '--title', 'PRISMER_TASK_TITLE', env)?.trim() || (task || `Preflight ${role}`).slice(0, 100),
166
+ handle: envOrArg(parsed, '--handle', 'PRISMER_AGENT_HANDLE', env)?.trim(),
167
+ displayName: envOrArg(parsed, '--display-name', 'PRISMER_AGENT_DISPLAY_NAME', env)?.trim(),
168
+ adapterName,
169
+ targetDaemonId: envOrArg(parsed, '--target-daemon', 'PRISMER_TARGET_DAEMON_ID', env)?.trim(),
170
+ requestId,
171
+ timeoutMs: positiveInt(envOrArg(parsed, '--timeout-ms', 'PRISMER_WORKFLOW_TIMEOUT_MS', env), 600_000, 'timeout'),
172
+ pollMs: positiveInt(envOrArg(parsed, '--poll-ms', 'PRISMER_WORKFLOW_POLL_MS', env), 2_000, 'poll interval'),
173
+ ledgerPath: resolve(
174
+ envOrArg(parsed, '--ledger', 'PRISMER_OPERATION_LEDGER', env) || `.prismer/operations/${requestId}.json`,
175
+ ),
176
+ wait: !parsed.flags.has('--no-wait'),
177
+ preflightOnly,
178
+ json: parsed.flags.has('--json'),
179
+ };
180
+ if (config.handle && !/^[a-z0-9][a-z0-9_-]{1,63}$/.test(config.handle)) {
181
+ throw new HarnessError('local_validation', 'INVALID_HANDLE', 'agent handle has an invalid shape', 2);
182
+ }
183
+ return config;
184
+ }
185
+
186
+ export function writeLedger(path, value) {
187
+ mkdirSync(dirname(path), { recursive: true });
188
+ const temporary = `${path}.tmp`;
189
+ writeFileSync(temporary, `${JSON.stringify(value, null, 2)}\n`, { mode: 0o600 });
190
+ renameSync(temporary, path);
191
+ }
192
+
193
+ export function readLedger(path) {
194
+ if (!existsSync(path)) return null;
195
+ try {
196
+ const value = JSON.parse(readFileSync(path, 'utf8'));
197
+ return value && typeof value === 'object' && !Array.isArray(value) ? value : null;
198
+ } catch {
199
+ throw new HarnessError(
200
+ 'local_validation',
201
+ 'INVALID_OPERATION_LEDGER',
202
+ 'the operation ledger exists but is not valid JSON',
203
+ 2,
204
+ );
205
+ }
206
+ }
207
+
208
+ export function invocationHash(config) {
209
+ return createHash('sha256')
210
+ .update(
211
+ JSON.stringify({
212
+ requestId: config.requestId,
213
+ role: config.role,
214
+ workspaceId: config.workspaceId,
215
+ task: config.task,
216
+ title: config.title,
217
+ handle: config.handle ?? null,
218
+ displayName: config.displayName ?? null,
219
+ adapterName: config.adapterName,
220
+ targetDaemonId: config.targetDaemonId ?? null,
221
+ }),
222
+ )
223
+ .digest('hex');
224
+ }
225
+
226
+ export function taskIdempotencyKey(requestId) {
227
+ return `role-task-${createHash('sha256').update(requestId).digest('hex')}`;
228
+ }
229
+
230
+ export async function requestJson(config, method, path, body, stage) {
231
+ const controller = new AbortController();
232
+ const timer = setTimeout(() => controller.abort(), Math.min(config.timeoutMs, 120_000));
233
+ let response;
234
+ try {
235
+ response = await fetch(`${config.baseUrl}${path}`, {
236
+ method,
237
+ headers: {
238
+ authorization: `Bearer ${config.apiKey}`,
239
+ 'content-type': 'application/json',
240
+ ...(body?.idempotencyKey ? { 'x-idempotency-key': body.idempotencyKey } : {}),
241
+ },
242
+ ...(body === undefined ? {} : { body: JSON.stringify(body) }),
243
+ signal: controller.signal,
244
+ });
245
+ } catch (error) {
246
+ const message = error?.name === 'AbortError' ? 'request timed out' : error?.message || String(error);
247
+ throw new HarnessError(stage, 'NETWORK_ERROR', message, 4);
248
+ } finally {
249
+ clearTimeout(timer);
250
+ }
251
+ const payload = await response.json().catch(() => null);
252
+ if (!response.ok || payload?.ok === false) {
253
+ const serverError = payload?.error;
254
+ throw new HarnessError(
255
+ stage,
256
+ serverError?.code || `HTTP_${response.status}`,
257
+ serverError?.message || serverError || `request failed with HTTP ${response.status}`,
258
+ response.status === 401 || response.status === 403 ? 3 : response.status >= 500 ? 4 : 5,
259
+ { status: response.status, retryable: serverError?.retryable === true },
260
+ );
261
+ }
262
+ return { status: response.status, data: payload?.data ?? payload };
263
+ }
264
+
265
+ export function sleep(ms) {
266
+ return new Promise((resolveSleep) => setTimeout(resolveSleep, ms));
267
+ }
@@ -0,0 +1,134 @@
1
+ ---
2
+ name: skill-authoring
3
+ scope: common
4
+ description: Low-level helper for the DRAFT-GATED (review) tier of skill authoring — it is NOT the entry point for creating skills. To make/build/author a skill, use `skill-creator` (the single canonical skill author). This page only documents skill-creator's draft tier — generating a `status=draft` skill via `POST /api/im/skills/draft` (`cloud skill draft create`) for human review in Studio Authoring, plus the skill.json + sampleTasks/acceptanceCriteria test contract. Do NOT route here when the user wants to create a skill — route to skill-creator and add `--draft` only when human review is required.
5
+ license: MIT
6
+ compatibility:
7
+ - prismer-sdk
8
+ - hermes
9
+ - claude-code
10
+ - codex
11
+ ---
12
+
13
+ # Skill Authoring — the draft-gated tier of `skill-creator`
14
+
15
+ > **Not an authoring entry point.** Creating or editing a skill is the job of
16
+ > **`skill-creator`** — the single canonical skill author. This page only
17
+ > documents one of skill-creator's two publish trust tiers (**draft-gated**),
18
+ > for the case where a skill must be reviewed by a human before it goes live.
19
+ > If the user says "make this a skill" / "create a skill for X", **use
20
+ > `skill-creator`**, not this.
21
+
22
+ ## Where this fits
23
+
24
+ `skill-creator` drives the full lifecycle author→validate→test→package→publish.
25
+ At the publish step there are two trust tiers ([[16-skill-role-authoring-as-agent-capability]] §5.3):
26
+
27
+ - **Direct create (default)** — `cloud skill create ./<dir>` → `status=active`,
28
+ `publishScope=workspace` (**private**, installable — NOT the public marketplace).
29
+ Putting it in the marketplace is a separate `cloud skill publish`. Under `skill-builder`.
30
+ - **Draft-gated (explicit, this page)** — `cloud skill draft create` →
31
+ `status=draft`, Studio Authoring reviews and promotes it. Opt into this **only
32
+ when human review is required** — the default is direct publish (decision 4,
33
+ locked 2026-06-24).
34
+
35
+ Both tiers are reached from inside `skill-creator`; this is a publish-verb
36
+ choice, not a separate skill to author in.
37
+
38
+ ## Draft submission (the review-gated path)
39
+
40
+ When the workflow requires human review before a skill is live, submit a draft
41
+ instead of publishing directly:
42
+
43
+ ```bash
44
+ cloud skill draft create ./<bundle-dir> # optional: --workspace-id <id> --json
45
+ # → POST /api/im/skills/draft. Cloud reads the directory, runs the 7 validation
46
+ # gates, and returns { id, slug, status: draft }. Does NOT publish.
47
+ ```
48
+
49
+ > ⚠️ **`<bundle-dir>` is a directory** holding `SKILL.md` + `skill.json` (+ an
50
+ > optional `scripts/`). The CLI reads and packages the directory on every run, so
51
+ > edits on disk take effect immediately — there is no separate manifest to
52
+ > regenerate. There is **no** `--slug` / `--manifest` flag; the slug is taken from
53
+ > the SKILL.md frontmatter `name`.
54
+
55
+ The draft lands in `status=draft`; the workspace owner reviews and promotes it
56
+ via Studio Authoring (`/evolution → Studio → Authoring`). Do **not** auto-publish
57
+ or chain into install — promotion is the owner's call.
58
+
59
+ > Do NOT call `POST /api/im/skills` (direct publish) when the intent is review-gated —
60
+ > that bypasses the draft state. Use `--draft` deliberately.
61
+
62
+ ## `skill.json` — where security + the test contract live
63
+
64
+ **Read this first — it is the #1 draft-tier gotcha.** The bundle must contain a
65
+ `skill.json` alongside `SKILL.md` (cloud locates each file by name, so a
66
+ `scripts/` dir sorted in between is fine). Cloud reads `security` and the test
67
+ contract from **`skill.json`**, and **NEVER** from the `SKILL.md` YAML
68
+ frontmatter. If you put `security:` / `dataAccess:` in the
69
+ SKILL.md frontmatter, gate 5 still fails with "security.dataAccess must be
70
+ non-empty" no matter how you format the YAML — it is reading a different file.
71
+
72
+ ### `security` (blocking — gate 5)
73
+
74
+ ```json
75
+ {
76
+ "schemaVersion": 1,
77
+ "slug": "<slug>",
78
+ "security": {
79
+ "dataAccess": ["workspace-assets"],
80
+ "humanApprovalRequiredFor": []
81
+ }
82
+ }
83
+ ```
84
+
85
+ - **`security.dataAccess`** — non-empty array. Scopes: `workspace-assets` |
86
+ `memory` | `external-network` | `secrets` | `filesystem`.
87
+ - **`security.humanApprovalRequiredFor`** — **required non-empty IF** `dataAccess`
88
+ contains a **sensitive** scope (`external-network`, `secrets`, `filesystem`).
89
+ List the actions needing human approval (e.g. `["filesystem-write"]`).
90
+ - **Least privilege:** if the skill only reads env + prints (no arbitrary user
91
+ files), declare `["memory"]` — a non-sensitive scope — and
92
+ `humanApprovalRequiredFor` may stay empty. Only reach for `filesystem` when the
93
+ skill genuinely reads/writes user files, and then you must also declare
94
+ approval.
95
+
96
+ ### test contract (drives `cloud skill test`)
97
+
98
+ The same `skill.json` also carries the VERIFICATION contract exercised by
99
+ `cloud skill test --agent` in lifecycle step ③:
100
+
101
+ - `runtime.kind` = `'inline-script'` (or `'http-endpoint'`), `runtime.requires`
102
+ declaring `bins`/`env` the script needs.
103
+ - `inputs` / `outputs` describing the call contract.
104
+ - **`sampleTasks[]`** — at least 2 concrete tasks. EACH MUST have
105
+ `acceptanceCriteria[]` written as substrings/regex the dispatch OUTPUT must
106
+ contain (e.g. `"\"status\":\\s*200"`, `"results"`). These are the auto-scored
107
+ tests: `cloud skill test` dispatches each sampleTask to a real agent and
108
+ matches its output against the criteria. A sampleTask with no
109
+ acceptanceCriteria scores `inconclusive` (NOT a pass), so always write them.
110
+
111
+ > Derive acceptanceCriteria from the spec: required response fields, status
112
+ > codes, schema keys. Tight enough to catch a broken call, not so tight they
113
+ > depend on volatile data.
114
+
115
+ ## Draft validation gates (self-check before submit)
116
+
117
+ The cloud server runs these at `createDraft` time and rejects with HTTP 400 on a
118
+ blocking failure. Run the same checks locally first (or just `cloud skill validate ./<dir>`):
119
+
120
+ | Gate | Check | Blocking |
121
+ |----------------|------------------------------------------------------------------|----------|
122
+ | `manifest` | files[] complete; merkle root reproducible | yes |
123
+ | `frontmatter` | `name` matches `^[a-z][a-z0-9-]*$`; description ≥ 50 quality units (ASCII=1, non-ASCII=2); YAML `|`/`>` supported | yes |
124
+ | `package` | bundle contains SKILL.md + skill.json (located by name) | yes |
125
+ | `requires` | runtime.requires declares env/bins/python/node explicitly | warn |
126
+ | `security` | **skill.json** security.dataAccess non-empty; sensitive scopes (external-network/secrets/filesystem) require security.humanApprovalRequiredFor. NOT read from SKILL.md frontmatter. | yes |
127
+ | `sample` | at least 1 sampleTask + 1 acceptance criterion | warn |
128
+ | `runtime` | sandbox executes sample task | deferred |
129
+
130
+ ## Reference
131
+
132
+ - The skill author (use this): `built-in-skills/skill-creator/SKILL.md`
133
+ - Direct-publish tier: `built-in-skills/skill-builder/SKILL.md`
134
+ - Bundle + catalog contract: `public/docs/Standardization/01-skill-standard.md` (SS-01)