opensquid 0.5.441 → 0.5.447

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 (380) hide show
  1. package/README.md +1 -0
  2. package/dist/functions/arm_scope.d.ts +27 -0
  3. package/dist/functions/arm_scope.d.ts.map +1 -0
  4. package/dist/functions/arm_scope.js +52 -0
  5. package/dist/functions/arm_scope.js.map +1 -0
  6. package/dist/functions/index.d.ts +1 -0
  7. package/dist/functions/index.d.ts.map +1 -1
  8. package/dist/functions/index.js +1 -0
  9. package/dist/functions/index.js.map +1 -1
  10. package/dist/runtime/bootstrap.d.ts.map +1 -1
  11. package/dist/runtime/bootstrap.js +2 -0
  12. package/dist/runtime/bootstrap.js.map +1 -1
  13. package/dist/runtime/handoff/render.d.ts +5 -4
  14. package/dist/runtime/handoff/render.d.ts.map +1 -1
  15. package/dist/runtime/handoff/render.js +7 -7
  16. package/dist/runtime/handoff/render.js.map +1 -1
  17. package/dist/runtime/hooks/active_task_mirror.js +0 -0
  18. package/dist/runtime/hooks/apply_patch.js +0 -0
  19. package/dist/runtime/hooks/dispatch.js +0 -0
  20. package/dist/runtime/hooks/hook_output.js +0 -0
  21. package/dist/runtime/hooks/memory_reconcile.js +0 -0
  22. package/dist/runtime/hooks/new_project_detect.js +0 -0
  23. package/dist/runtime/hooks/profession_resolver.js +0 -0
  24. package/dist/runtime/hooks/scope_intent.js +0 -0
  25. package/dist/runtime/hooks/session_id.js +0 -0
  26. package/dist/runtime/hooks/session_liveness.js +0 -0
  27. package/dist/runtime/hooks/stop_drive.js +0 -0
  28. package/dist/runtime/hooks/stop_stream.js +0 -0
  29. package/dist/runtime/hooks/subagent_guard.js +0 -0
  30. package/dist/runtime/hooks/transcript.js +0 -0
  31. package/dist/runtime/hooks/transcript_tasks.js +0 -0
  32. package/dist/runtime/ralph/orchestrator.d.ts.map +1 -1
  33. package/dist/runtime/ralph/orchestrator.js +2 -1
  34. package/dist/runtime/ralph/orchestrator.js.map +1 -1
  35. package/dist/setup/cli/limits_state.d.ts.map +1 -1
  36. package/dist/setup/cli/limits_state.js +6 -40
  37. package/dist/setup/cli/limits_state.js.map +1 -1
  38. package/dist/setup/cli/pack_walk.d.ts +32 -0
  39. package/dist/setup/cli/pack_walk.d.ts.map +1 -0
  40. package/dist/setup/cli/pack_walk.js +76 -0
  41. package/dist/setup/cli/pack_walk.js.map +1 -0
  42. package/dist/setup/cli/permissions_state.d.ts.map +1 -1
  43. package/dist/setup/cli/permissions_state.js +6 -37
  44. package/dist/setup/cli/permissions_state.js.map +1 -1
  45. package/dist/setup/cli/triggers_state.d.ts.map +1 -1
  46. package/dist/setup/cli/triggers_state.js +3 -29
  47. package/dist/setup/cli/triggers_state.js.map +1 -1
  48. package/dist/workgraph/events.d.ts.map +1 -1
  49. package/dist/workgraph/events.js +10 -0
  50. package/dist/workgraph/events.js.map +1 -1
  51. package/dist/workgraph/store.d.ts.map +1 -1
  52. package/dist/workgraph/store.js +5 -0
  53. package/dist/workgraph/store.js.map +1 -1
  54. package/dist/workgraph/types.d.ts +2 -1
  55. package/dist/workgraph/types.d.ts.map +1 -1
  56. package/docs/ARCHITECTURE.md +268 -0
  57. package/package.json +5 -3
  58. package/packs/builtin/coding-flow/skills/entry-and-handoffs/skill.yaml +13 -17
  59. package/dist/anti-drift/evaluator.d.ts +0 -88
  60. package/dist/anti-drift/evaluator.d.ts.map +0 -1
  61. package/dist/anti-drift/evaluator.js +0 -417
  62. package/dist/anti-drift/evaluator.js.map +0 -1
  63. package/dist/anti-drift/evaluator.test.js +0 -78
  64. package/dist/anti-drift/rules.d.ts +0 -80
  65. package/dist/anti-drift/rules.d.ts.map +0 -1
  66. package/dist/anti-drift/rules.js +0 -368
  67. package/dist/anti-drift/rules.js.map +0 -1
  68. package/dist/anti-drift/rules.test.js +0 -213
  69. package/dist/anti-drift/state.d.ts +0 -107
  70. package/dist/anti-drift/state.d.ts.map +0 -1
  71. package/dist/anti-drift/state.js +0 -177
  72. package/dist/anti-drift/state.js.map +0 -1
  73. package/dist/anti-drift/state.test.js +0 -120
  74. package/dist/chat/adapters/discord.d.ts +0 -41
  75. package/dist/chat/adapters/discord.d.ts.map +0 -1
  76. package/dist/chat/adapters/discord.js +0 -176
  77. package/dist/chat/adapters/discord.js.map +0 -1
  78. package/dist/chat/adapters/discord.test.js +0 -25
  79. package/dist/chat/adapters/slack.d.ts +0 -43
  80. package/dist/chat/adapters/slack.d.ts.map +0 -1
  81. package/dist/chat/adapters/slack.js +0 -172
  82. package/dist/chat/adapters/slack.js.map +0 -1
  83. package/dist/chat/adapters/slack.test.js +0 -30
  84. package/dist/chat/adapters/telegram.d.ts +0 -148
  85. package/dist/chat/adapters/telegram.d.ts.map +0 -1
  86. package/dist/chat/adapters/telegram.js +0 -498
  87. package/dist/chat/adapters/telegram.js.map +0 -1
  88. package/dist/chat/adapters/telegram.test.js +0 -94
  89. package/dist/chat/config.d.ts +0 -98
  90. package/dist/chat/config.d.ts.map +0 -1
  91. package/dist/chat/config.js +0 -185
  92. package/dist/chat/config.js.map +0 -1
  93. package/dist/chat/daemon/active-project.d.ts +0 -17
  94. package/dist/chat/daemon/active-project.d.ts.map +0 -1
  95. package/dist/chat/daemon/active-project.js +0 -23
  96. package/dist/chat/daemon/active-project.js.map +0 -1
  97. package/dist/chat/daemon/autospawn.d.ts +0 -40
  98. package/dist/chat/daemon/autospawn.d.ts.map +0 -1
  99. package/dist/chat/daemon/autospawn.js +0 -129
  100. package/dist/chat/daemon/autospawn.js.map +0 -1
  101. package/dist/chat/daemon/autospawn.test.js +0 -112
  102. package/dist/chat/daemon/cli.d.ts +0 -18
  103. package/dist/chat/daemon/cli.d.ts.map +0 -1
  104. package/dist/chat/daemon/cli.js +0 -71
  105. package/dist/chat/daemon/cli.js.map +0 -1
  106. package/dist/chat/daemon/collisions.js +0 -384
  107. package/dist/chat/daemon/health-check.d.ts +0 -69
  108. package/dist/chat/daemon/health-check.d.ts.map +0 -1
  109. package/dist/chat/daemon/health-check.js +0 -112
  110. package/dist/chat/daemon/health-check.js.map +0 -1
  111. package/dist/chat/daemon/inbox-read.d.ts +0 -35
  112. package/dist/chat/daemon/inbox-read.d.ts.map +0 -1
  113. package/dist/chat/daemon/inbox-read.js +0 -75
  114. package/dist/chat/daemon/inbox-read.js.map +0 -1
  115. package/dist/chat/daemon/inbox-read.test.js +0 -97
  116. package/dist/chat/daemon/inbox.d.ts +0 -63
  117. package/dist/chat/daemon/inbox.d.ts.map +0 -1
  118. package/dist/chat/daemon/inbox.js +0 -56
  119. package/dist/chat/daemon/inbox.js.map +0 -1
  120. package/dist/chat/daemon/inbox.test.js +0 -110
  121. package/dist/chat/daemon/lifecycle.d.ts +0 -71
  122. package/dist/chat/daemon/lifecycle.d.ts.map +0 -1
  123. package/dist/chat/daemon/lifecycle.js +0 -221
  124. package/dist/chat/daemon/lifecycle.js.map +0 -1
  125. package/dist/chat/daemon/lifecycle.test.js +0 -163
  126. package/dist/chat/daemon/protocol.d.ts +0 -107
  127. package/dist/chat/daemon/protocol.d.ts.map +0 -1
  128. package/dist/chat/daemon/protocol.js +0 -54
  129. package/dist/chat/daemon/protocol.js.map +0 -1
  130. package/dist/chat/daemon/routing.d.ts +0 -140
  131. package/dist/chat/daemon/routing.d.ts.map +0 -1
  132. package/dist/chat/daemon/routing.js +0 -198
  133. package/dist/chat/daemon/routing.js.map +0 -1
  134. package/dist/chat/daemon/routing.test.js +0 -259
  135. package/dist/chat/daemon/rpc-client.d.ts +0 -45
  136. package/dist/chat/daemon/rpc-client.d.ts.map +0 -1
  137. package/dist/chat/daemon/rpc-client.js +0 -133
  138. package/dist/chat/daemon/rpc-client.js.map +0 -1
  139. package/dist/chat/daemon/rpc-server.d.ts +0 -39
  140. package/dist/chat/daemon/rpc-server.d.ts.map +0 -1
  141. package/dist/chat/daemon/rpc-server.js +0 -385
  142. package/dist/chat/daemon/rpc-server.js.map +0 -1
  143. package/dist/chat/daemon/rpc.test.js +0 -177
  144. package/dist/chat/daemon/subscribers.js +0 -257
  145. package/dist/chat/daemon/worker.d.ts +0 -27
  146. package/dist/chat/daemon/worker.d.ts.map +0 -1
  147. package/dist/chat/daemon/worker.js +0 -313
  148. package/dist/chat/daemon/worker.js.map +0 -1
  149. package/dist/chat/daemon/workspace-topic.js +0 -324
  150. package/dist/chat/env-token.d.ts +0 -60
  151. package/dist/chat/env-token.d.ts.map +0 -1
  152. package/dist/chat/env-token.js +0 -137
  153. package/dist/chat/env-token.js.map +0 -1
  154. package/dist/chat/env-token.test.js +0 -160
  155. package/dist/chat/factory.d.ts +0 -30
  156. package/dist/chat/factory.d.ts.map +0 -1
  157. package/dist/chat/factory.js +0 -50
  158. package/dist/chat/factory.js.map +0 -1
  159. package/dist/chat/factory.test.js +0 -55
  160. package/dist/chat/gateway.d.ts +0 -176
  161. package/dist/chat/gateway.d.ts.map +0 -1
  162. package/dist/chat/gateway.js +0 -146
  163. package/dist/chat/gateway.js.map +0 -1
  164. package/dist/chat/gateway.test.js +0 -192
  165. package/dist/claude-md.d.ts +0 -39
  166. package/dist/claude-md.d.ts.map +0 -1
  167. package/dist/claude-md.js +0 -113
  168. package/dist/claude-md.js.map +0 -1
  169. package/dist/claude-md.test.js +0 -91
  170. package/dist/codex/activate.d.ts +0 -66
  171. package/dist/codex/activate.d.ts.map +0 -1
  172. package/dist/codex/activate.js +0 -329
  173. package/dist/codex/activate.js.map +0 -1
  174. package/dist/codex/activate.test.js +0 -229
  175. package/dist/codex/bundled-default/bundled-default.test.js +0 -161
  176. package/dist/codex/cli-publish.test.js +0 -133
  177. package/dist/codex/cli.d.ts +0 -35
  178. package/dist/codex/cli.d.ts.map +0 -1
  179. package/dist/codex/cli.js +0 -554
  180. package/dist/codex/cli.js.map +0 -1
  181. package/dist/codex/cli.test.js +0 -277
  182. package/dist/codex/import-skill-md.d.ts +0 -53
  183. package/dist/codex/import-skill-md.d.ts.map +0 -1
  184. package/dist/codex/import-skill-md.js +0 -236
  185. package/dist/codex/import-skill-md.js.map +0 -1
  186. package/dist/codex/import-skill-md.test.js +0 -225
  187. package/dist/codex/loader.d.ts +0 -27
  188. package/dist/codex/loader.d.ts.map +0 -1
  189. package/dist/codex/loader.js +0 -86
  190. package/dist/codex/loader.js.map +0 -1
  191. package/dist/codex/loader.test.js +0 -75
  192. package/dist/codex/parse.d.ts +0 -28
  193. package/dist/codex/parse.d.ts.map +0 -1
  194. package/dist/codex/parse.js +0 -309
  195. package/dist/codex/parse.js.map +0 -1
  196. package/dist/codex/parse.test.js +0 -241
  197. package/dist/codex/store.d.ts +0 -87
  198. package/dist/codex/store.d.ts.map +0 -1
  199. package/dist/codex/store.js +0 -205
  200. package/dist/codex/store.js.map +0 -1
  201. package/dist/codex/store.test.js +0 -242
  202. package/dist/codex/types.d.ts +0 -398
  203. package/dist/codex/types.d.ts.map +0 -1
  204. package/dist/codex/types.js +0 -21
  205. package/dist/codex/types.js.map +0 -1
  206. package/dist/config.d.ts +0 -53
  207. package/dist/config.d.ts.map +0 -1
  208. package/dist/config.js +0 -202
  209. package/dist/config.js.map +0 -1
  210. package/dist/config.test.js +0 -117
  211. package/dist/engine/cli.d.ts +0 -14
  212. package/dist/engine/cli.d.ts.map +0 -1
  213. package/dist/engine/cli.js +0 -171
  214. package/dist/engine/cli.js.map +0 -1
  215. package/dist/engine/client.d.ts +0 -219
  216. package/dist/engine/client.d.ts.map +0 -1
  217. package/dist/engine/client.js +0 -312
  218. package/dist/engine/client.js.map +0 -1
  219. package/dist/engine/config.d.ts +0 -62
  220. package/dist/engine/config.d.ts.map +0 -1
  221. package/dist/engine/config.js +0 -223
  222. package/dist/engine/config.js.map +0 -1
  223. package/dist/engine/index.d.ts +0 -17
  224. package/dist/engine/index.d.ts.map +0 -1
  225. package/dist/engine/index.js +0 -16
  226. package/dist/engine/index.js.map +0 -1
  227. package/dist/engine/resolver.d.ts +0 -62
  228. package/dist/engine/resolver.d.ts.map +0 -1
  229. package/dist/engine/resolver.js +0 -103
  230. package/dist/engine/resolver.js.map +0 -1
  231. package/dist/engine/singleton.d.ts +0 -95
  232. package/dist/engine/singleton.d.ts.map +0 -1
  233. package/dist/engine/singleton.js +0 -325
  234. package/dist/engine/singleton.js.map +0 -1
  235. package/dist/engine/types.d.ts +0 -402
  236. package/dist/engine/types.d.ts.map +0 -1
  237. package/dist/engine/types.js +0 -22
  238. package/dist/engine/types.js.map +0 -1
  239. package/dist/engine-binary-resolver.js +0 -110
  240. package/dist/engine-binary-resolver.test.js +0 -61
  241. package/dist/engine-cli.js +0 -60
  242. package/dist/engine-client.js +0 -301
  243. package/dist/engine-client.test.js +0 -118
  244. package/dist/functions/chain_state.d.ts +0 -51
  245. package/dist/functions/chain_state.d.ts.map +0 -1
  246. package/dist/functions/chain_state.js +0 -59
  247. package/dist/functions/chain_state.js.map +0 -1
  248. package/dist/hooks/drift-catalog.d.ts +0 -68
  249. package/dist/hooks/drift-catalog.d.ts.map +0 -1
  250. package/dist/hooks/drift-catalog.js +0 -184
  251. package/dist/hooks/drift-catalog.js.map +0 -1
  252. package/dist/hooks/drift-catalog.test.js +0 -154
  253. package/dist/hooks/drift-patterns.d.ts +0 -110
  254. package/dist/hooks/drift-patterns.d.ts.map +0 -1
  255. package/dist/hooks/drift-patterns.js +0 -289
  256. package/dist/hooks/drift-patterns.js.map +0 -1
  257. package/dist/hooks/drift-patterns.test.js +0 -325
  258. package/dist/hooks/engine-vocab-gate.d.ts +0 -108
  259. package/dist/hooks/engine-vocab-gate.d.ts.map +0 -1
  260. package/dist/hooks/engine-vocab-gate.js +0 -225
  261. package/dist/hooks/engine-vocab-gate.js.map +0 -1
  262. package/dist/hooks/engine-vocab-gate.test.js +0 -170
  263. package/dist/hooks/heartbeat.d.ts +0 -107
  264. package/dist/hooks/heartbeat.d.ts.map +0 -1
  265. package/dist/hooks/heartbeat.js +0 -316
  266. package/dist/hooks/heartbeat.js.map +0 -1
  267. package/dist/hooks/heartbeat.test.js +0 -393
  268. package/dist/hooks/honesty-ledger-session-scope.test.js +0 -100
  269. package/dist/hooks/honesty-ledger.d.ts +0 -123
  270. package/dist/hooks/honesty-ledger.d.ts.map +0 -1
  271. package/dist/hooks/honesty-ledger.js +0 -226
  272. package/dist/hooks/honesty-ledger.js.map +0 -1
  273. package/dist/hooks/honesty-ledger.test.js +0 -466
  274. package/dist/hooks/inline-report-check.d.ts +0 -63
  275. package/dist/hooks/inline-report-check.d.ts.map +0 -1
  276. package/dist/hooks/inline-report-check.js +0 -88
  277. package/dist/hooks/inline-report-check.js.map +0 -1
  278. package/dist/hooks/inline-report-check.test.js +0 -96
  279. package/dist/hooks/pre-tool-use.d.ts +0 -62
  280. package/dist/hooks/pre-tool-use.d.ts.map +0 -1
  281. package/dist/hooks/pre-tool-use.js +0 -342
  282. package/dist/hooks/pre-tool-use.js.map +0 -1
  283. package/dist/hooks/pre-tool-use.test.js +0 -134
  284. package/dist/hooks/session-end.d.ts +0 -15
  285. package/dist/hooks/session-end.d.ts.map +0 -1
  286. package/dist/hooks/session-end.js +0 -60
  287. package/dist/hooks/session-end.js.map +0 -1
  288. package/dist/hooks/session-end.test.js +0 -52
  289. package/dist/hooks/stop.d.ts +0 -35
  290. package/dist/hooks/stop.d.ts.map +0 -1
  291. package/dist/hooks/stop.js +0 -136
  292. package/dist/hooks/stop.js.map +0 -1
  293. package/dist/hooks/transcript-active-task.test.js +0 -342
  294. package/dist/hooks/transcript.d.ts +0 -26
  295. package/dist/hooks/transcript.d.ts.map +0 -1
  296. package/dist/hooks/transcript.js +0 -266
  297. package/dist/hooks/transcript.js.map +0 -1
  298. package/dist/hooks/transcript.test.js +0 -103
  299. package/dist/hooks/user-prompt-submit.d.ts +0 -74
  300. package/dist/hooks/user-prompt-submit.d.ts.map +0 -1
  301. package/dist/hooks/user-prompt-submit.js +0 -256
  302. package/dist/hooks/user-prompt-submit.js.map +0 -1
  303. package/dist/hooks/user-prompt-submit.test.js +0 -118
  304. package/dist/hooks/versioning-gate.d.ts +0 -101
  305. package/dist/hooks/versioning-gate.d.ts.map +0 -1
  306. package/dist/hooks/versioning-gate.js +0 -245
  307. package/dist/hooks/versioning-gate.js.map +0 -1
  308. package/dist/hooks/versioning-gate.test.js +0 -368
  309. package/dist/hooks/workflow-gate.d.ts +0 -64
  310. package/dist/hooks/workflow-gate.d.ts.map +0 -1
  311. package/dist/hooks/workflow-gate.js +0 -152
  312. package/dist/hooks/workflow-gate.js.map +0 -1
  313. package/dist/hooks/workflow-gate.test.js +0 -197
  314. package/dist/hooks-cli.d.ts +0 -25
  315. package/dist/hooks-cli.d.ts.map +0 -1
  316. package/dist/hooks-cli.js +0 -286
  317. package/dist/hooks-cli.js.map +0 -1
  318. package/dist/hooks-cli.test.js +0 -148
  319. package/dist/origin.d.ts +0 -16
  320. package/dist/origin.d.ts.map +0 -1
  321. package/dist/origin.js +0 -92
  322. package/dist/origin.js.map +0 -1
  323. package/dist/packs/seed_lessons_ingest.d.ts +0 -30
  324. package/dist/packs/seed_lessons_ingest.d.ts.map +0 -1
  325. package/dist/packs/seed_lessons_ingest.js +0 -107
  326. package/dist/packs/seed_lessons_ingest.js.map +0 -1
  327. package/dist/project-cli.d.ts +0 -7
  328. package/dist/project-cli.d.ts.map +0 -1
  329. package/dist/project-cli.js +0 -145
  330. package/dist/project-cli.js.map +0 -1
  331. package/dist/project.d.ts +0 -127
  332. package/dist/project.d.ts.map +0 -1
  333. package/dist/project.js +0 -281
  334. package/dist/project.js.map +0 -1
  335. package/dist/project.test.js +0 -287
  336. package/dist/rag/backends/loop_engine.d.ts +0 -61
  337. package/dist/rag/backends/loop_engine.d.ts.map +0 -1
  338. package/dist/rag/backends/loop_engine.js +0 -160
  339. package/dist/rag/backends/loop_engine.js.map +0 -1
  340. package/dist/recall.d.ts +0 -82
  341. package/dist/recall.d.ts.map +0 -1
  342. package/dist/recall.js +0 -81
  343. package/dist/recall.js.map +0 -1
  344. package/dist/runtime/agent_bridge/autospawn.d.ts +0 -131
  345. package/dist/runtime/agent_bridge/autospawn.d.ts.map +0 -1
  346. package/dist/runtime/agent_bridge/autospawn.js +0 -251
  347. package/dist/runtime/agent_bridge/autospawn.js.map +0 -1
  348. package/dist/runtime/chain_state.d.ts +0 -124
  349. package/dist/runtime/chain_state.d.ts.map +0 -1
  350. package/dist/runtime/chain_state.js +0 -189
  351. package/dist/runtime/chain_state.js.map +0 -1
  352. package/dist/runtime/hooks/permission_decision.d.ts +0 -34
  353. package/dist/runtime/hooks/permission_decision.d.ts.map +0 -1
  354. package/dist/runtime/hooks/permission_decision.js +0 -39
  355. package/dist/runtime/hooks/permission_decision.js.map +0 -1
  356. package/dist/runtime/workflow_fsm.d.ts +0 -21
  357. package/dist/runtime/workflow_fsm.d.ts.map +0 -1
  358. package/dist/runtime/workflow_fsm.js +0 -25
  359. package/dist/runtime/workflow_fsm.js.map +0 -1
  360. package/dist/runtime/workflow_map.d.ts +0 -26
  361. package/dist/runtime/workflow_map.d.ts.map +0 -1
  362. package/dist/runtime/workflow_map.js +0 -38
  363. package/dist/runtime/workflow_map.js.map +0 -1
  364. package/dist/scope.d.ts +0 -48
  365. package/dist/scope.d.ts.map +0 -1
  366. package/dist/scope.js +0 -111
  367. package/dist/scope.js.map +0 -1
  368. package/dist/setup/cli/topic_create_step.d.ts +0 -84
  369. package/dist/setup/cli/topic_create_step.d.ts.map +0 -1
  370. package/dist/setup/cli/topic_create_step.js +0 -213
  371. package/dist/setup/cli/topic_create_step.js.map +0 -1
  372. package/dist/system-export.d.ts +0 -65
  373. package/dist/system-export.d.ts.map +0 -1
  374. package/dist/system-export.js +0 -194
  375. package/dist/system-export.js.map +0 -1
  376. package/dist/utterance/classifier.d.ts +0 -53
  377. package/dist/utterance/classifier.d.ts.map +0 -1
  378. package/dist/utterance/classifier.js +0 -184
  379. package/dist/utterance/classifier.js.map +0 -1
  380. package/dist/utterance/classifier.test.js +0 -147
@@ -1,277 +0,0 @@
1
- import * as crypto from "node:crypto";
2
- import { promises as fs } from "node:fs";
3
- import * as os from "node:os";
4
- import * as path from "node:path";
5
- import { afterEach, beforeEach, describe, expect, it } from "vitest";
6
- import { CodexCliError, runCodexCli } from "./cli.js";
7
- import { codexDir, codexesDir, getCodex } from "./store.js";
8
- import { isFocusedCodex } from "./types.js";
9
- // ---------------------------------------------------------------------
10
- // Isolation
11
- // ---------------------------------------------------------------------
12
- let tmpRoot;
13
- let sourceRoot;
14
- const origConsoleLog = console.log;
15
- const origConsoleError = console.error;
16
- beforeEach(async () => {
17
- const uniq = crypto.randomUUID();
18
- tmpRoot = path.join(os.tmpdir(), `opensquid-cli-test-${uniq}`);
19
- sourceRoot = path.join(os.tmpdir(), `opensquid-cli-src-${uniq}`);
20
- await fs.mkdir(tmpRoot, { recursive: true });
21
- await fs.mkdir(sourceRoot, { recursive: true });
22
- // Silence console during tests.
23
- console.log = () => { };
24
- console.error = () => { };
25
- });
26
- afterEach(async () => {
27
- await fs.rm(tmpRoot, { recursive: true, force: true });
28
- await fs.rm(sourceRoot, { recursive: true, force: true });
29
- console.log = origConsoleLog;
30
- console.error = origConsoleError;
31
- });
32
- // Fixture: write a minimal valid codex YAML + lesson body at sourceRoot.
33
- async function makeSourceCodex(opts) {
34
- const yaml = `
35
- id: react-19
36
- version: 1.0.0
37
- foundation:
38
- tools:
39
- - { name: react, semver: ">=19,<20" }
40
- domains: [software-engineering]
41
- detected_by:
42
- - { kind: file_exists, path: "package.json" }
43
- seed_lessons:
44
- - id: atomic-search
45
- trigger: "before creating a component"
46
- bank_strategy: full
47
- body_path: "lessons/atomic-search/lesson.md"
48
- `;
49
- await fs.writeFile(path.join(sourceRoot, "codex.yaml"), yaml, "utf8");
50
- if (opts?.withLessonBody) {
51
- const lessonDir = path.join(sourceRoot, "lessons", "atomic-search");
52
- await fs.mkdir(lessonDir, { recursive: true });
53
- await fs.writeFile(path.join(lessonDir, "lesson.md"), "# Atomic search\n\nSearch atoms/molecules/organisms first.\n", "utf8");
54
- }
55
- }
56
- async function makeCompositeSource() {
57
- const yaml = `
58
- id: fullstack-bundle
59
- kind: composite
60
- version: 1.0.0
61
- includes:
62
- - { id: react, semver: ">=18" }
63
- - { id: tdd, semver: ">=1" }
64
- `;
65
- await fs.writeFile(path.join(sourceRoot, "codex.yaml"), yaml, "utf8");
66
- }
67
- // ---------------------------------------------------------------------
68
- // install
69
- // ---------------------------------------------------------------------
70
- describe("runCodexCli install", () => {
71
- it("installs a focused codex from a local directory", async () => {
72
- await makeSourceCodex({ withLessonBody: true });
73
- await runCodexCli("install", [sourceRoot, "--root", tmpRoot, "--no-seed"]);
74
- const manifest = path.join(codexDir("react-19", tmpRoot), "codex.yaml");
75
- expect((await fs.stat(manifest)).isFile()).toBe(true);
76
- });
77
- it("copies lesson bodies + companion files into canonical location", async () => {
78
- await makeSourceCodex({ withLessonBody: true });
79
- await runCodexCli("install", [sourceRoot, "--root", tmpRoot, "--no-seed"]);
80
- const lessonBody = path.join(codexDir("react-19", tmpRoot), "lessons", "atomic-search", "lesson.md");
81
- expect((await fs.stat(lessonBody)).isFile()).toBe(true);
82
- const content = await fs.readFile(lessonBody, "utf8");
83
- expect(content).toContain("Atomic search");
84
- });
85
- it("installs a composite codex (no content copy)", async () => {
86
- await makeCompositeSource();
87
- await runCodexCli("install", [sourceRoot, "--root", tmpRoot, "--no-seed"]);
88
- const dir = codexDir("fullstack-bundle", tmpRoot);
89
- const entries = await fs.readdir(dir);
90
- expect(entries).toEqual(["codex.yaml"]);
91
- });
92
- it("accepts an explicit codex.yaml path (not just the dir)", async () => {
93
- await makeSourceCodex();
94
- const explicitFile = path.join(sourceRoot, "codex.yaml");
95
- await runCodexCli("install", [explicitFile, "--root", tmpRoot, "--no-seed"]);
96
- expect((await fs.stat(path.join(codexDir("react-19", tmpRoot), "codex.yaml"))).isFile()).toBe(true);
97
- });
98
- it("throws when source path doesn't exist", async () => {
99
- await expect(runCodexCli("install", ["/nonexistent/path", "--root", tmpRoot])).rejects.toThrow(CodexCliError);
100
- });
101
- it("throws when codex.yaml is missing from source dir", async () => {
102
- await expect(runCodexCli("install", [sourceRoot, "--root", tmpRoot])).rejects.toThrow(CodexCliError);
103
- });
104
- it("throws on malformed codex.yaml", async () => {
105
- await fs.writeFile(path.join(sourceRoot, "codex.yaml"), "id: bad-id-uppercase\nNOT_A: VALID_FIELD\n", "utf8");
106
- await expect(runCodexCli("install", [sourceRoot, "--root", tmpRoot])).rejects.toThrow(CodexCliError);
107
- });
108
- it("respects --force on re-install", async () => {
109
- await makeSourceCodex();
110
- await runCodexCli("install", [sourceRoot, "--root", tmpRoot, "--no-seed"]);
111
- // Second install without --force throws ALREADY_INSTALLED.
112
- await expect(runCodexCli("install", [sourceRoot, "--root", tmpRoot])).rejects.toThrow();
113
- // With --force succeeds.
114
- await runCodexCli("install", [sourceRoot, "--root", tmpRoot, "--force", "--no-seed"]);
115
- });
116
- it("rejects missing source arg", async () => {
117
- await expect(runCodexCli("install", ["--root", tmpRoot])).rejects.toThrow(CodexCliError);
118
- });
119
- });
120
- // ---------------------------------------------------------------------
121
- // list
122
- // ---------------------------------------------------------------------
123
- describe("runCodexCli list", () => {
124
- it("succeeds on empty root", async () => {
125
- await runCodexCli("list", ["--root", tmpRoot]);
126
- });
127
- it("succeeds when codexes are installed", async () => {
128
- await makeSourceCodex();
129
- await runCodexCli("install", [sourceRoot, "--root", tmpRoot, "--no-seed"]);
130
- await runCodexCli("list", ["--root", tmpRoot]);
131
- });
132
- });
133
- // ---------------------------------------------------------------------
134
- // remove
135
- // ---------------------------------------------------------------------
136
- describe("runCodexCli remove", () => {
137
- it("removes an installed codex", async () => {
138
- await makeSourceCodex();
139
- await runCodexCli("install", [sourceRoot, "--root", tmpRoot, "--no-seed"]);
140
- await runCodexCli("remove", ["react-19", "--root", tmpRoot]);
141
- await expect(fs.access(codexDir("react-19", tmpRoot))).rejects.toThrow();
142
- });
143
- it("is idempotent on missing codex", async () => {
144
- // No throw — just no-op.
145
- await runCodexCli("remove", ["ghost", "--root", tmpRoot]);
146
- });
147
- it("rejects missing id arg", async () => {
148
- await expect(runCodexCli("remove", ["--root", tmpRoot])).rejects.toThrow(CodexCliError);
149
- });
150
- });
151
- // ---------------------------------------------------------------------
152
- // doctor
153
- // ---------------------------------------------------------------------
154
- describe("runCodexCli doctor", () => {
155
- it("reports empty state", async () => {
156
- await runCodexCli("doctor", ["--root", tmpRoot]);
157
- });
158
- it("reports per-codex detail when id is passed", async () => {
159
- await makeSourceCodex();
160
- await runCodexCli("install", [sourceRoot, "--root", tmpRoot, "--no-seed"]);
161
- await runCodexCli("doctor", ["react-19", "--root", tmpRoot]);
162
- });
163
- it("reports gracefully on missing codex when id is passed", async () => {
164
- await runCodexCli("doctor", ["ghost", "--root", tmpRoot]);
165
- });
166
- });
167
- // ---------------------------------------------------------------------
168
- // flag parsing
169
- // ---------------------------------------------------------------------
170
- describe("flag parsing", () => {
171
- it("honors --root override", async () => {
172
- await makeSourceCodex();
173
- await runCodexCli("install", [sourceRoot, "--root", tmpRoot, "--no-seed"]);
174
- // Codex should be in tmpRoot, NOT in the user's actual ~/.opensquid.
175
- expect((await fs.stat(codexesDir(tmpRoot))).isDirectory()).toBe(true);
176
- });
177
- });
178
- // ---------------------------------------------------------------------
179
- // v0.6d — SKILL.md foreign-format auto-detect + install
180
- // ---------------------------------------------------------------------
181
- const ANTHROPIC_SKILL_MD = `---
182
- name: pdf
183
- description: Use when extracting text or tables from PDF files.
184
- license: Apache-2.0
185
- ---
186
-
187
- # PDF Skill
188
-
189
- Use pdfplumber for text, PyMuPDF for images.
190
- `;
191
- const HERMES_SKILL_MD = `---
192
- name: google_meet
193
- description: Schedule and join Google Meet calls.
194
- version: 1.2.0
195
- author: Hermes Team
196
- license: MIT
197
- platforms:
198
- - hermes
199
- metadata:
200
- hermes:
201
- tags: [calendar, meetings]
202
- ---
203
-
204
- # google_meet
205
-
206
- Hermes integration for Meet.
207
- `;
208
- describe("install — SKILL.md auto-detect", () => {
209
- it("converts a directory containing SKILL.md and installs as native codex", async () => {
210
- await fs.writeFile(path.join(sourceRoot, "SKILL.md"), ANTHROPIC_SKILL_MD, "utf8");
211
- await runCodexCli("install", [sourceRoot, "--root", tmpRoot, "--no-seed"]);
212
- const installed = await getCodex("pdf", { rootDir: tmpRoot });
213
- expect(installed.id).toBe("pdf");
214
- expect(installed.version).toBe("1.0.0");
215
- expect(installed.license).toBe("Apache-2.0");
216
- if (!isFocusedCodex(installed))
217
- throw new Error("expected focused codex");
218
- expect(installed.source?.kind).toBe("skill_md");
219
- expect(installed.source?.original_variant).toBe("anthropic");
220
- expect(installed.source?.original_name).toBe("pdf");
221
- // Lesson body got materialized.
222
- const lessonBody = await fs.readFile(path.join(codexDir("pdf", tmpRoot), "lessons", "pdf", "lesson.md"), "utf8");
223
- expect(lessonBody).toContain("Use pdfplumber for text");
224
- });
225
- it("converts a SKILL.md file path directly (not a directory)", async () => {
226
- const filePath = path.join(sourceRoot, "SKILL.md");
227
- await fs.writeFile(filePath, ANTHROPIC_SKILL_MD, "utf8");
228
- await runCodexCli("install", [filePath, "--root", tmpRoot, "--no-seed"]);
229
- const installed = await getCodex("pdf", { rootDir: tmpRoot });
230
- expect(installed.id).toBe("pdf");
231
- });
232
- it("rewrites underscore names to hyphens (google_meet → google-meet)", async () => {
233
- await fs.writeFile(path.join(sourceRoot, "SKILL.md"), HERMES_SKILL_MD, "utf8");
234
- await runCodexCli("install", [sourceRoot, "--root", tmpRoot, "--no-seed"]);
235
- const installed = await getCodex("google-meet", { rootDir: tmpRoot });
236
- expect(installed.id).toBe("google-meet");
237
- expect(installed.version).toBe("1.2.0");
238
- if (!isFocusedCodex(installed))
239
- throw new Error("expected focused codex");
240
- expect(installed.source?.original_variant).toBe("hermes");
241
- expect(installed.source?.original_name).toBe("google_meet");
242
- expect(installed.metadata?.platforms).toEqual(["hermes"]);
243
- });
244
- it("prefers codex.yaml over SKILL.md when both exist (auto-detect)", async () => {
245
- // Native codex says id=react-19; SKILL.md says id=pdf. Auto-detect
246
- // picks codex.yaml. --source skill_md would override.
247
- await makeSourceCodex({ withLessonBody: true });
248
- await fs.writeFile(path.join(sourceRoot, "SKILL.md"), ANTHROPIC_SKILL_MD, "utf8");
249
- await runCodexCli("install", [sourceRoot, "--root", tmpRoot, "--no-seed"]);
250
- const installed = await getCodex("react-19", { rootDir: tmpRoot });
251
- expect(installed.id).toBe("react-19");
252
- // pdf should NOT be installed.
253
- await expect(getCodex("pdf", { rootDir: tmpRoot })).rejects.toThrow();
254
- });
255
- it("--source skill_md forces SKILL.md branch when both files exist", async () => {
256
- await makeSourceCodex({ withLessonBody: true });
257
- await fs.writeFile(path.join(sourceRoot, "SKILL.md"), ANTHROPIC_SKILL_MD, "utf8");
258
- await runCodexCli("install", [
259
- sourceRoot,
260
- "--root",
261
- tmpRoot,
262
- "--no-seed",
263
- "--source",
264
- "skill_md",
265
- ]);
266
- const installed = await getCodex("pdf", { rootDir: tmpRoot });
267
- expect(installed.id).toBe("pdf");
268
- });
269
- it("rejects invalid --source value", async () => {
270
- await fs.writeFile(path.join(sourceRoot, "SKILL.md"), ANTHROPIC_SKILL_MD, "utf8");
271
- await expect(runCodexCli("install", [sourceRoot, "--root", tmpRoot, "--no-seed", "--source", "yaml"])).rejects.toThrow(CodexCliError);
272
- });
273
- it("reports a clear error for malformed SKILL.md (missing description)", async () => {
274
- await fs.writeFile(path.join(sourceRoot, "SKILL.md"), "---\nname: broken\n---\nbody\n", "utf8");
275
- await expect(runCodexCli("install", [sourceRoot, "--root", tmpRoot, "--no-seed"])).rejects.toThrow(/description/);
276
- });
277
- });
@@ -1,53 +0,0 @@
1
- /**
2
- * SKILL.md → opensquid native codex converter (v0.6d).
3
- *
4
- * Pure functions. No filesystem side effects. Takes a raw SKILL.md
5
- * string + optional path metadata, returns a `{codex, lesson}` pair
6
- * that the install pipeline materializes to disk before calling the
7
- * existing `installCodex` + `copyCodexContent` path.
8
- *
9
- * Handles the union of:
10
- * - Anthropic skills (https://platform.claude.com/docs/en/agents-and-tools/agent-skills/overview) — `name`, `description`, optional `license`, optional experimental `allowed-tools` / `model` / `compatibility`
11
- * - obra/superpowers — strict Anthropic subset (name + description, CSO description discipline)
12
- * - everything-claude-code (ECC) — Anthropic + non-standard `origin: ECC`
13
- * - Hermes Agent skills (~/projects/hermes-agent/skills/) — Anthropic + `version` + `author` + `platforms` + `metadata.hermes.{tags, related_skills}`
14
- *
15
- * 100% deterministic. No LLM call. Per [[find-simple-solutions]]:
16
- * frontmatter → codex.yaml is structural mapping; body → one lesson is
17
- * the trivial 1:1 case that every sampled SKILL.md follows. Sub-skill
18
- * body-splitting is deferred until a real corpus demands it.
19
- */
20
- import type { Codex, CodexSource } from "./types.js";
21
- export type SkillMdVariant = NonNullable<CodexSource["original_variant"]>;
22
- export interface SkillMdParseResult {
23
- frontmatter: Record<string, unknown>;
24
- body: string;
25
- }
26
- export interface ConvertOptions {
27
- /** Absolute path to the source SKILL.md (or its containing dir). */
28
- originalPath?: string;
29
- /** Wall-clock at conversion time. Defaults to `new Date().toISOString()`. */
30
- now?: string;
31
- }
32
- export interface ConvertedLesson {
33
- /** Lesson id (slug). */
34
- id: string;
35
- /** Path relative to the codex root — written via `lessons/<id>/lesson.md`. */
36
- bodyPath: string;
37
- /** Raw markdown body to write at `bodyPath`. */
38
- body: string;
39
- }
40
- export interface ConvertedCodex {
41
- codex: Codex;
42
- lessons: ConvertedLesson[];
43
- variant: SkillMdVariant;
44
- }
45
- export declare class SkillMdImportError extends Error {
46
- readonly hint?: string | undefined;
47
- constructor(message: string, hint?: string | undefined);
48
- }
49
- export declare function parseSkillMd(source: string): SkillMdParseResult;
50
- export declare function slugify(name: string): string;
51
- export declare function detectVariant(frontmatter: Record<string, unknown>, originalPath?: string): SkillMdVariant;
52
- export declare function convertSkillMdToCodex(source: string, options?: ConvertOptions): ConvertedCodex;
53
- //# sourceMappingURL=import-skill-md.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"import-skill-md.d.ts","sourceRoot":"","sources":["../../src.legacy/codex/import-skill-md.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,OAAO,KAAK,EAAE,KAAK,EAAmB,WAAW,EAA2B,MAAM,YAAY,CAAC;AAM/F,MAAM,MAAM,cAAc,GAAG,WAAW,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC,CAAC;AAE1E,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,oEAAoE;IACpE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,6EAA6E;IAC7E,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,wBAAwB;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,8EAA8E;IAC9E,QAAQ,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,OAAO,EAAE,cAAc,CAAC;CACzB;AAMD,qBAAa,kBAAmB,SAAQ,KAAK;aAGzB,IAAI,CAAC,EAAE,MAAM;gBAD7B,OAAO,EAAE,MAAM,EACC,IAAI,CAAC,EAAE,MAAM,YAAA;CAKhC;AAQD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,kBAAkB,CA6C/D;AAQD,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAY5C;AAMD,wBAAgB,aAAa,CAC3B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,YAAY,CAAC,EAAE,MAAM,GACpB,cAAc,CA6BhB;AAMD,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,cAAmB,GAC3B,cAAc,CA8HhB"}
@@ -1,236 +0,0 @@
1
- /**
2
- * SKILL.md → opensquid native codex converter (v0.6d).
3
- *
4
- * Pure functions. No filesystem side effects. Takes a raw SKILL.md
5
- * string + optional path metadata, returns a `{codex, lesson}` pair
6
- * that the install pipeline materializes to disk before calling the
7
- * existing `installCodex` + `copyCodexContent` path.
8
- *
9
- * Handles the union of:
10
- * - Anthropic skills (https://platform.claude.com/docs/en/agents-and-tools/agent-skills/overview) — `name`, `description`, optional `license`, optional experimental `allowed-tools` / `model` / `compatibility`
11
- * - obra/superpowers — strict Anthropic subset (name + description, CSO description discipline)
12
- * - everything-claude-code (ECC) — Anthropic + non-standard `origin: ECC`
13
- * - Hermes Agent skills (~/projects/hermes-agent/skills/) — Anthropic + `version` + `author` + `platforms` + `metadata.hermes.{tags, related_skills}`
14
- *
15
- * 100% deterministic. No LLM call. Per [[find-simple-solutions]]:
16
- * frontmatter → codex.yaml is structural mapping; body → one lesson is
17
- * the trivial 1:1 case that every sampled SKILL.md follows. Sub-skill
18
- * body-splitting is deferred until a real corpus demands it.
19
- */
20
- import { parse as parseYaml } from "yaml";
21
- // ---------------------------------------------------------------------
22
- // Errors
23
- // ---------------------------------------------------------------------
24
- export class SkillMdImportError extends Error {
25
- hint;
26
- constructor(message, hint) {
27
- super(message);
28
- this.hint = hint;
29
- this.name = "SkillMdImportError";
30
- }
31
- }
32
- // ---------------------------------------------------------------------
33
- // Parse SKILL.md frontmatter + body
34
- // ---------------------------------------------------------------------
35
- const FRONTMATTER_FENCE_RE = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/;
36
- export function parseSkillMd(source) {
37
- if (!source || !source.trim()) {
38
- throw new SkillMdImportError("SKILL.md is empty", "SKILL.md must have a YAML frontmatter block + body");
39
- }
40
- // v0.6d audit fix (L1): strip UTF-8 BOM if present. The fence regex
41
- // requires `---` at the very start; a BOM-prefixed file (common from
42
- // Windows editors) would silently fail the match.
43
- const stripped = source.charCodeAt(0) === 0xfeff ? source.slice(1) : source;
44
- const match = stripped.match(FRONTMATTER_FENCE_RE);
45
- if (!match) {
46
- throw new SkillMdImportError("SKILL.md missing YAML frontmatter (--- ... ---) at top", "wrap your frontmatter in triple-dash fences and ensure the closing fence is on its own line");
47
- }
48
- const [, yamlText, bodyText] = match;
49
- let parsed;
50
- try {
51
- parsed = parseYaml(yamlText);
52
- }
53
- catch (e) {
54
- throw new SkillMdImportError(`SKILL.md frontmatter is not valid YAML: ${e instanceof Error ? e.message : String(e)}`, "frontmatter must be parseable as YAML (key: value pairs)");
55
- }
56
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
57
- throw new SkillMdImportError("SKILL.md frontmatter must be a YAML mapping (key: value pairs)");
58
- }
59
- const frontmatter = parsed;
60
- if (typeof frontmatter.name !== "string" || !frontmatter.name.trim()) {
61
- throw new SkillMdImportError("SKILL.md frontmatter missing required `name` field", "per the Anthropic spec, `name` is required (max 64 chars, [a-z0-9-])");
62
- }
63
- if (typeof frontmatter.description !== "string" || !frontmatter.description.trim()) {
64
- throw new SkillMdImportError("SKILL.md frontmatter missing required `description` field", "per the Anthropic spec, `description` is required (max 1024 chars)");
65
- }
66
- return { frontmatter, body: (bodyText ?? "").trim() };
67
- }
68
- // ---------------------------------------------------------------------
69
- // Slugify (ASCII-safe — sampled SKILL.md names are all ASCII)
70
- // ---------------------------------------------------------------------
71
- const SLUG_MAX_LEN = 64;
72
- export function slugify(name) {
73
- const lower = name.toLowerCase();
74
- // Replace any run of non-alphanumerics with a single dash. Trim
75
- // leading/trailing dashes. Cap length per Anthropic spec.
76
- const dashed = lower.replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
77
- if (!dashed) {
78
- throw new SkillMdImportError(`cannot slugify name "${name}" (no alphanumeric characters)`, "skill names must include at least one ASCII letter or digit");
79
- }
80
- return dashed.slice(0, SLUG_MAX_LEN);
81
- }
82
- // ---------------------------------------------------------------------
83
- // Variant detection
84
- // ---------------------------------------------------------------------
85
- export function detectVariant(frontmatter, originalPath) {
86
- if (frontmatter.origin === "ECC")
87
- return "ecc";
88
- // Hermes: rich frontmatter (`platforms`, `metadata.hermes.*`)
89
- if (Array.isArray(frontmatter.platforms))
90
- return "hermes";
91
- const meta = frontmatter.metadata;
92
- if (meta && typeof meta === "object" && !Array.isArray(meta)) {
93
- if (meta.hermes !== undefined)
94
- return "hermes";
95
- }
96
- // superpowers: path-based detection only. The CSO "Use when..." phrasing
97
- // is recommended by superpowers but Anthropic's own skill-creator also
98
- // uses it, so description alone is too noisy to distinguish.
99
- const path = (originalPath ?? "").toLowerCase();
100
- if (path.includes("superpowers/skills/") || path.includes("/superpowers/")) {
101
- return "superpowers";
102
- }
103
- // Pure Anthropic minimum: only name + description (+ optional license)
104
- const keys = new Set(Object.keys(frontmatter));
105
- const anthropicKnown = new Set([
106
- "name",
107
- "description",
108
- "license",
109
- "compatibility",
110
- "metadata",
111
- "allowed-tools",
112
- "model",
113
- ]);
114
- const allKnown = [...keys].every((k) => anthropicKnown.has(k));
115
- if (allKnown)
116
- return "anthropic";
117
- return "unknown";
118
- }
119
- // ---------------------------------------------------------------------
120
- // Main conversion
121
- // ---------------------------------------------------------------------
122
- export function convertSkillMdToCodex(source, options = {}) {
123
- const { frontmatter, body } = parseSkillMd(source);
124
- const rawName = frontmatter.name.trim();
125
- const id = slugify(rawName);
126
- const description = frontmatter.description.trim();
127
- const variant = detectVariant(frontmatter, options.originalPath);
128
- const now = options.now ?? new Date().toISOString();
129
- // ----- version: Hermes provides one; default to "1.0.0" otherwise -----
130
- let version = "1.0.0";
131
- let versionSynthesized = true;
132
- if (typeof frontmatter.version === "string" && frontmatter.version.trim()) {
133
- version = frontmatter.version.trim();
134
- versionSynthesized = false;
135
- }
136
- // ----- author: Hermes "author" is a flat string; opensquid wants {name, contact?} -----
137
- let author;
138
- const rawAuthor = frontmatter.author;
139
- if (typeof rawAuthor === "string" && rawAuthor.trim()) {
140
- author = { name: rawAuthor.trim() };
141
- }
142
- else {
143
- author = { name: "Imported from SKILL.md" };
144
- }
145
- // ----- license: pass through if present -----
146
- const license = typeof frontmatter.license === "string" && frontmatter.license.trim()
147
- ? frontmatter.license.trim()
148
- : undefined;
149
- // ----- foundation.tools from Anthropic experimental `allowed-tools` -----
150
- let tools;
151
- const allowedTools = frontmatter["allowed-tools"];
152
- if (Array.isArray(allowedTools) && allowedTools.length > 0) {
153
- tools = [];
154
- for (const t of allowedTools) {
155
- if (typeof t === "string" && t.trim()) {
156
- tools.push({ name: t.trim() });
157
- }
158
- }
159
- if (tools.length === 0)
160
- tools = undefined;
161
- }
162
- // ----- preserved non-standard frontmatter → metadata extensibility bucket -----
163
- const metadata = { imported_from: "skill_md" };
164
- if (versionSynthesized) {
165
- // mark for downstream auditing
166
- metadata.imported = { synthesized_version: true };
167
- }
168
- // Preserve every frontmatter key we don't have a first-class slot for.
169
- for (const [k, v] of Object.entries(frontmatter)) {
170
- if (k === "name" ||
171
- k === "description" ||
172
- k === "version" ||
173
- k === "author" ||
174
- k === "license" ||
175
- k === "allowed-tools") {
176
- continue;
177
- }
178
- // Anthropic optional `model` → metadata.model. Hermes `platforms` →
179
- // metadata.platforms. ECC `origin` → metadata.origin. Hermes
180
- // `metadata.hermes.*` is already a nested object; preserve it under
181
- // metadata.hermes (don't flatten).
182
- if (k === "metadata" && v && typeof v === "object" && !Array.isArray(v)) {
183
- // Merge into our metadata bucket without overwriting our own keys.
184
- for (const [mk, mv] of Object.entries(v)) {
185
- if (!(mk in metadata)) {
186
- metadata[mk] = mv;
187
- }
188
- }
189
- continue;
190
- }
191
- metadata[k] = v;
192
- }
193
- // ----- source provenance -----
194
- const sourceBlock = {
195
- kind: "skill_md",
196
- original_variant: variant,
197
- original_name: rawName,
198
- original_path: options.originalPath,
199
- imported_at: now,
200
- };
201
- // ----- seed lesson (one cohesive lesson per SKILL.md) -----
202
- // The lesson trigger is the description verbatim — lossy in tone but
203
- // functionally correct. Future LLM-mediated trigger synthesis (deferred)
204
- // could rewrite into the imperative voice opensquid prefers.
205
- const seedLesson = {
206
- id,
207
- trigger: description,
208
- priority: "medium",
209
- bank_strategy: "full",
210
- body_path: `lessons/${id}/lesson.md`,
211
- };
212
- // Lesson body = the SKILL.md body verbatim. If empty (extremely rare —
213
- // would mean a frontmatter-only file), synthesize a stub.
214
- const lessonBody = body.length > 0
215
- ? body
216
- : `# ${rawName}\n\n${description}\n\n*(Imported from SKILL.md with no body content.)*\n`;
217
- const codex = {
218
- id,
219
- version,
220
- description,
221
- author,
222
- license,
223
- source: sourceBlock,
224
- metadata,
225
- kind: "focused",
226
- foundation: tools ? { tools } : undefined,
227
- seed_lessons: [seedLesson],
228
- evolves: true,
229
- };
230
- return {
231
- codex,
232
- lessons: [{ id, bodyPath: seedLesson.body_path, body: lessonBody }],
233
- variant,
234
- };
235
- }
236
- //# sourceMappingURL=import-skill-md.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"import-skill-md.js","sourceRoot":"","sources":["../../src.legacy/codex/import-skill-md.ts"],"names":[],"mappings":"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"}