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
package/dist/claude-md.js DELETED
@@ -1,113 +0,0 @@
1
- /**
2
- * CLAUDE.md sentinel-block management.
3
- *
4
- * Two managed blocks live inside `~/.claude/CLAUDE.md`:
5
- *
6
- * 1. `opensquid-automation:start vX.Y.Z` ... `opensquid-automation:end`
7
- * — the outer behavioral instructions block, written by
8
- * `opensquid install` (src/cli.ts).
9
- *
10
- * 2. `opensquid-rules:start (auto-managed)` ... `opensquid-rules:end`
11
- * — an inner block nested INSIDE the automation block, holding
12
- * one-line summaries of promoted lessons. Auto-managed at
13
- * runtime: every `lesson.promote` success appends an entry here
14
- * so the agent reads promoted rules at session start with no
15
- * recall lag.
16
- *
17
- * This module exposes the runtime updater for the inner rules block.
18
- * The CLAUDE.md installer / uninstaller (src/cli.ts) owns the outer
19
- * block; this module ONLY touches what's between the inner sentinels.
20
- */
21
- import { promises as fs } from "node:fs";
22
- import * as os from "node:os";
23
- import * as path from "node:path";
24
- const RULES_START = "<!-- opensquid-rules:start (auto-managed) -->";
25
- const RULES_END = "<!-- opensquid-rules:end -->";
26
- const PLACEHOLDER = "(no promoted lessons yet";
27
- /** Resolved path to the user's global CLAUDE.md. */
28
- export function defaultClaudeMdPath() {
29
- return path.join(os.homedir(), ".claude", "CLAUDE.md");
30
- }
31
- /**
32
- * Append a one-line entry for a newly promoted lesson into the
33
- * CLAUDE.md rules sub-block. Idempotent — if an entry for `id` already
34
- * exists, the line is left untouched. Returns the path written + the
35
- * new content of the rules block (without sentinels).
36
- *
37
- * No-op (silent) when:
38
- * - CLAUDE.md doesn't exist
39
- * - The rules sub-block isn't installed yet (user hasn't run
40
- * `opensquid install` against this CLAUDE.md)
41
- *
42
- * Failure is intentionally non-fatal: lesson promotion is the
43
- * authoritative event; CLAUDE.md is downstream display. We never block
44
- * the promote on a CLAUDE.md write failure.
45
- */
46
- export async function appendPromotedLessonToClaudeMd(entry, options = {}) {
47
- const target = options.target ?? defaultClaudeMdPath();
48
- let content;
49
- try {
50
- content = await fs.readFile(target, "utf8");
51
- }
52
- catch {
53
- return null;
54
- }
55
- const block = findRulesBlock(content);
56
- if (!block)
57
- return null;
58
- // Idempotency: skip if this lesson id already appears in the block.
59
- const idMarker = `(lesson:${entry.id})`;
60
- if (block.inner.includes(idMarker)) {
61
- return { target, appended: false };
62
- }
63
- // Strip the placeholder if it's the only thing in the block.
64
- const cleaned = block.inner.includes(PLACEHOLDER) ? "" : block.inner.trimEnd();
65
- const newLine = `- ${entry.description.trim()} ${idMarker} — promoted ${entry.promoted_at}`;
66
- const nextInner = cleaned.length === 0 ? `\n${newLine}\n` : `${cleaned}\n${newLine}\n`;
67
- const nextContent = content.slice(0, block.innerStart) + nextInner + content.slice(block.innerEnd);
68
- await fs.writeFile(target, nextContent, "utf8");
69
- return { target, appended: true };
70
- }
71
- function findRulesBlock(content) {
72
- const startIdx = content.indexOf(RULES_START);
73
- if (startIdx === -1)
74
- return null;
75
- const endIdx = content.indexOf(RULES_END, startIdx + RULES_START.length);
76
- if (endIdx === -1)
77
- return null;
78
- // inner starts right after the start sentinel (allowing a trailing newline).
79
- let innerStart = startIdx + RULES_START.length;
80
- if (content[innerStart] === "\n")
81
- innerStart++;
82
- // inner ends at the start of the end sentinel.
83
- const innerEnd = endIdx;
84
- return {
85
- inner: content.slice(innerStart, innerEnd),
86
- innerStart,
87
- innerEnd,
88
- };
89
- }
90
- /**
91
- * For tests + diagnostics: list the lesson ids currently appearing in
92
- * the rules sub-block of a given CLAUDE.md.
93
- */
94
- export async function listRulesBlockLessonIds(options = {}) {
95
- const target = options.target ?? defaultClaudeMdPath();
96
- let content;
97
- try {
98
- content = await fs.readFile(target, "utf8");
99
- }
100
- catch {
101
- return [];
102
- }
103
- const block = findRulesBlock(content);
104
- if (!block)
105
- return [];
106
- const ids = [];
107
- const re = /\(lesson:([a-z0-9-]+)\)/g;
108
- for (const m of block.inner.matchAll(re)) {
109
- ids.push(m[1]);
110
- }
111
- return ids;
112
- }
113
- //# sourceMappingURL=claude-md.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"claude-md.js","sourceRoot":"","sources":["../src.legacy/claude-md.ts"],"names":[],"mappings":"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"}
@@ -1,91 +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 { appendPromotedLessonToClaudeMd, listRulesBlockLessonIds } from "./claude-md.js";
7
- let tmpFile;
8
- beforeEach(async () => {
9
- tmpFile = path.join(os.tmpdir(), `oscli-claude-md-${crypto.randomUUID()}.md`);
10
- });
11
- afterEach(async () => {
12
- await fs.rm(tmpFile, { force: true });
13
- });
14
- const INSTALLED_BLOCK = `<!-- opensquid-automation:start v0.4.0 -->
15
- ## opensquid
16
-
17
- Use recall before substantive answers.
18
-
19
- ### Active lessons (auto-managed — do not edit by hand)
20
-
21
- <!-- opensquid-rules:start (auto-managed) -->
22
- (no promoted lessons yet — this block populates as \`lesson.promote\`
23
- succeeds for user-endorsed candidates)
24
- <!-- opensquid-rules:end -->
25
- <!-- opensquid-automation:end -->
26
- `;
27
- describe("appendPromotedLessonToClaudeMd", () => {
28
- it("returns null when CLAUDE.md doesn't exist", async () => {
29
- const res = await appendPromotedLessonToClaudeMd({ id: "les-x", description: "anything", promoted_at: "2026-05-15T00:00:00Z" }, { target: tmpFile });
30
- expect(res).toBeNull();
31
- });
32
- it("returns null when the rules block isn't installed", async () => {
33
- await fs.writeFile(tmpFile, "# Just a regular CLAUDE.md\nNothing fancy.\n", "utf8");
34
- const res = await appendPromotedLessonToClaudeMd({ id: "les-x", description: "anything", promoted_at: "now" }, { target: tmpFile });
35
- expect(res).toBeNull();
36
- });
37
- it("replaces the placeholder with the first promoted lesson", async () => {
38
- await fs.writeFile(tmpFile, INSTALLED_BLOCK, "utf8");
39
- const res = await appendPromotedLessonToClaudeMd({
40
- id: "les-abc12345",
41
- description: "before any git push or release",
42
- promoted_at: "2026-05-15T19:00:00Z",
43
- }, { target: tmpFile });
44
- expect(res?.appended).toBe(true);
45
- const content = await fs.readFile(tmpFile, "utf8");
46
- expect(content).not.toContain("(no promoted lessons yet");
47
- expect(content).toContain("(lesson:les-abc12345)");
48
- expect(content).toContain("before any git push or release");
49
- expect(content).toContain("promoted 2026-05-15T19:00:00Z");
50
- });
51
- it("appends subsequent lessons without removing prior ones", async () => {
52
- await fs.writeFile(tmpFile, INSTALLED_BLOCK, "utf8");
53
- await appendPromotedLessonToClaudeMd({ id: "les-1", description: "first rule", promoted_at: "2026-05-15T19:00:00Z" }, { target: tmpFile });
54
- await appendPromotedLessonToClaudeMd({ id: "les-2", description: "second rule", promoted_at: "2026-05-15T19:01:00Z" }, { target: tmpFile });
55
- const content = await fs.readFile(tmpFile, "utf8");
56
- expect(content).toContain("(lesson:les-1)");
57
- expect(content).toContain("(lesson:les-2)");
58
- expect(content).toContain("first rule");
59
- expect(content).toContain("second rule");
60
- });
61
- it("is idempotent — re-promoting the same id is a no-op", async () => {
62
- await fs.writeFile(tmpFile, INSTALLED_BLOCK, "utf8");
63
- await appendPromotedLessonToClaudeMd({ id: "les-1", description: "rule one", promoted_at: "2026-05-15T19:00:00Z" }, { target: tmpFile });
64
- const before = await fs.readFile(tmpFile, "utf8");
65
- const res = await appendPromotedLessonToClaudeMd({ id: "les-1", description: "rule one", promoted_at: "2026-05-15T19:30:00Z" }, { target: tmpFile });
66
- expect(res?.appended).toBe(false);
67
- const after = await fs.readFile(tmpFile, "utf8");
68
- expect(after).toBe(before);
69
- });
70
- it("preserves the outer automation block sentinels", async () => {
71
- await fs.writeFile(tmpFile, INSTALLED_BLOCK, "utf8");
72
- await appendPromotedLessonToClaudeMd({ id: "les-x", description: "anything", promoted_at: "2026-05-15T00:00:00Z" }, { target: tmpFile });
73
- const content = await fs.readFile(tmpFile, "utf8");
74
- expect(content).toContain("<!-- opensquid-automation:start v0.4.0 -->");
75
- expect(content).toContain("<!-- opensquid-automation:end -->");
76
- expect(content).toContain("<!-- opensquid-rules:start (auto-managed) -->");
77
- expect(content).toContain("<!-- opensquid-rules:end -->");
78
- });
79
- });
80
- describe("listRulesBlockLessonIds", () => {
81
- it("returns [] when no rules block", async () => {
82
- await fs.writeFile(tmpFile, "# plain\n", "utf8");
83
- expect(await listRulesBlockLessonIds({ target: tmpFile })).toEqual([]);
84
- });
85
- it("returns ids in append order", async () => {
86
- await fs.writeFile(tmpFile, INSTALLED_BLOCK, "utf8");
87
- await appendPromotedLessonToClaudeMd({ id: "les-aaa", description: "a", promoted_at: "t1" }, { target: tmpFile });
88
- await appendPromotedLessonToClaudeMd({ id: "les-bbb", description: "b", promoted_at: "t2" }, { target: tmpFile });
89
- expect(await listRulesBlockLessonIds({ target: tmpFile })).toEqual(["les-aaa", "les-bbb"]);
90
- });
91
- });
@@ -1,66 +0,0 @@
1
- /**
2
- * Codex activation evaluation — decide whether a codex's `detected_by`
3
- * matches the current project context (typically `process.cwd()`).
4
- *
5
- * Used by the recall handler to filter out lessons from codexes that
6
- * don't apply to the active project. Without this, recall would
7
- * surface React-specific lessons inside a Rust project (cross-codex
8
- * contamination).
9
- *
10
- * Coverage:
11
- * - file_exists / dir_exists / file_match / file_glob → filesystem-evaluated
12
- * - user_pinned → always true (codex was explicitly installed)
13
- * - all_of / any_of → recursive combinators
14
- * - memory_match / conversation_signal → default true (need runtime
15
- * context the recall handler doesn't carry; orchestrator (O3) is
16
- * the proper place for these)
17
- */
18
- import type { Codex, CodexDetection } from "./types.js";
19
- /**
20
- * Evaluate a codex's activation against a project context.
21
- *
22
- * - Composite codexes are not directly activatable; treat as inactive
23
- * here (their `includes` activate independently via their own
24
- * `detected_by`).
25
- * - Focused codex with no `detected_by`: defaults to active (the codex
26
- * author wanted always-on).
27
- * - `activation_scope: user` + `user_pinned`: always active.
28
- * - Otherwise: evaluate the `detected_by` list (any-of semantics —
29
- * matching ANY listed signal activates).
30
- */
31
- export declare function isCodexActive(codex: Codex, cwd: string): Promise<boolean>;
32
- /**
33
- * Evaluate a single detection signal against a project context.
34
- *
35
- * Returns false on unknown kinds (forward-compat — future engine
36
- * versions could add detection kinds opensquid doesn't recognize yet;
37
- * fail closed rather than over-activate).
38
- */
39
- export declare function evaluateDetection(detection: CodexDetection, cwd: string): Promise<boolean>;
40
- /**
41
- * Caches codex activation decisions for one project context.
42
- *
43
- * Reuse across multiple recall calls in the same session — avoids
44
- * re-reading codex.yaml files on every recall. Per-cwd because the
45
- * answer depends on the project being worked in.
46
- */
47
- export declare class CodexActivationCache {
48
- private readonly cwd;
49
- private readonly rootDir?;
50
- private decisions;
51
- constructor(cwd: string, rootDir?: string | undefined);
52
- /** Returns true iff the codex's `detected_by` matches this cwd. */
53
- isActive(codexId: string): Promise<boolean>;
54
- private evaluate;
55
- }
56
- /**
57
- * Extract the codex id from a lesson description.
58
- *
59
- * opensquid's codex CLI seeds lessons with descriptions like:
60
- * "before any git push or release (codex:loop-engineering-workflow)"
61
- *
62
- * Returns null for lessons not seeded from a codex (the pre-codex
63
- * lessons created by `lesson.create` without `pack_id`).
64
- */
65
- export declare function extractCodexId(description: string): string | null;
66
- //# sourceMappingURL=activate.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"activate.d.ts","sourceRoot":"","sources":["../../src.legacy/codex/activate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAgB,MAAM,YAAY,CAAC;AAOtE;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAI/E;AAYD;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAuChG;AAMD;;;;;;GAMG;AACH,qBAAa,oBAAoB;IAI7B,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IAJ3B,OAAO,CAAC,SAAS,CAAuC;gBAGrC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,MAAM,YAAA;IAGnC,mEAAmE;IAC7D,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;YASnC,QAAQ;CAWvB;AAMD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGjE"}
@@ -1,329 +0,0 @@
1
- /**
2
- * Codex activation evaluation — decide whether a codex's `detected_by`
3
- * matches the current project context (typically `process.cwd()`).
4
- *
5
- * Used by the recall handler to filter out lessons from codexes that
6
- * don't apply to the active project. Without this, recall would
7
- * surface React-specific lessons inside a Rust project (cross-codex
8
- * contamination).
9
- *
10
- * Coverage:
11
- * - file_exists / dir_exists / file_match / file_glob → filesystem-evaluated
12
- * - user_pinned → always true (codex was explicitly installed)
13
- * - all_of / any_of → recursive combinators
14
- * - memory_match / conversation_signal → default true (need runtime
15
- * context the recall handler doesn't carry; orchestrator (O3) is
16
- * the proper place for these)
17
- */
18
- import { promises as fs } from "node:fs";
19
- import * as path from "node:path";
20
- import { getCodex } from "./store.js";
21
- import { isCompositeCodex, isFocusedCodex } from "./types.js";
22
- // ---------------------------------------------------------------------
23
- // Public API
24
- // ---------------------------------------------------------------------
25
- /**
26
- * Evaluate a codex's activation against a project context.
27
- *
28
- * - Composite codexes are not directly activatable; treat as inactive
29
- * here (their `includes` activate independently via their own
30
- * `detected_by`).
31
- * - Focused codex with no `detected_by`: defaults to active (the codex
32
- * author wanted always-on).
33
- * - `activation_scope: user` + `user_pinned`: always active.
34
- * - Otherwise: evaluate the `detected_by` list (any-of semantics —
35
- * matching ANY listed signal activates).
36
- */
37
- export async function isCodexActive(codex, cwd) {
38
- if (isCompositeCodex(codex))
39
- return false;
40
- if (!isFocusedCodex(codex))
41
- return false;
42
- return isFocusedCodexActive(codex, cwd);
43
- }
44
- async function isFocusedCodexActive(codex, cwd) {
45
- // No detection signals declared → activate (author wanted always-on).
46
- if (!codex.detected_by || codex.detected_by.length === 0)
47
- return true;
48
- // Top-level list = OR — any matching signal activates.
49
- for (const detection of codex.detected_by) {
50
- if (await evaluateDetection(detection, cwd))
51
- return true;
52
- }
53
- return false;
54
- }
55
- /**
56
- * Evaluate a single detection signal against a project context.
57
- *
58
- * Returns false on unknown kinds (forward-compat — future engine
59
- * versions could add detection kinds opensquid doesn't recognize yet;
60
- * fail closed rather than over-activate).
61
- */
62
- export async function evaluateDetection(detection, cwd) {
63
- switch (detection.kind) {
64
- case "user_pinned":
65
- return true;
66
- case "file_exists":
67
- return fileExistsAt(path.resolve(cwd, detection.path));
68
- case "dir_exists":
69
- return dirExistsAt(path.resolve(cwd, detection.path));
70
- case "file_match":
71
- return fileMatches(path.resolve(cwd, detection.path), detection.matches);
72
- case "file_glob":
73
- return globAtLeast(cwd, detection.pattern, detection.min_count ?? 1);
74
- case "all_of": {
75
- for (const c of detection.conditions) {
76
- if (!(await evaluateDetection(c, cwd)))
77
- return false;
78
- }
79
- return true;
80
- }
81
- case "any_of": {
82
- for (const c of detection.conditions) {
83
- if (await evaluateDetection(c, cwd))
84
- return true;
85
- }
86
- return false;
87
- }
88
- case "memory_match":
89
- case "conversation_signal":
90
- // These need runtime context the recall handler doesn't carry.
91
- // Defaulting to true is the conservative choice: don't filter
92
- // lessons out solely because we can't evaluate these signals here.
93
- // Orchestrator (O3) will evaluate them properly.
94
- return true;
95
- default: {
96
- // Forward-compat: unknown kinds → fail closed.
97
- // Exhaustiveness check at compile time via the `never` cast.
98
- const _exhaustive = detection;
99
- void _exhaustive;
100
- return false;
101
- }
102
- }
103
- }
104
- // ---------------------------------------------------------------------
105
- // Activation cache (per-cwd, per-recall-handler-session)
106
- // ---------------------------------------------------------------------
107
- /**
108
- * Caches codex activation decisions for one project context.
109
- *
110
- * Reuse across multiple recall calls in the same session — avoids
111
- * re-reading codex.yaml files on every recall. Per-cwd because the
112
- * answer depends on the project being worked in.
113
- */
114
- export class CodexActivationCache {
115
- cwd;
116
- rootDir;
117
- decisions = new Map();
118
- constructor(cwd, rootDir) {
119
- this.cwd = cwd;
120
- this.rootDir = rootDir;
121
- }
122
- /** Returns true iff the codex's `detected_by` matches this cwd. */
123
- async isActive(codexId) {
124
- let pending = this.decisions.get(codexId);
125
- if (!pending) {
126
- pending = this.evaluate(codexId);
127
- this.decisions.set(codexId, pending);
128
- }
129
- return pending;
130
- }
131
- async evaluate(codexId) {
132
- try {
133
- const codex = await getCodex(codexId, { rootDir: this.rootDir });
134
- return isCodexActive(codex, this.cwd);
135
- }
136
- catch {
137
- // Missing or malformed codex → treat as inactive. Lessons from
138
- // an uninstalled codex shouldn't surface even if they're still
139
- // in the lesson store (stale state).
140
- return false;
141
- }
142
- }
143
- }
144
- // ---------------------------------------------------------------------
145
- // Lesson → codex id extraction
146
- // ---------------------------------------------------------------------
147
- /**
148
- * Extract the codex id from a lesson description.
149
- *
150
- * opensquid's codex CLI seeds lessons with descriptions like:
151
- * "before any git push or release (codex:loop-engineering-workflow)"
152
- *
153
- * Returns null for lessons not seeded from a codex (the pre-codex
154
- * lessons created by `lesson.create` without `pack_id`).
155
- */
156
- export function extractCodexId(description) {
157
- const m = description.match(/\(codex:([a-z0-9][a-z0-9._-]{0,127})\)\s*$/);
158
- return m ? m[1] : null;
159
- }
160
- // ---------------------------------------------------------------------
161
- // Filesystem primitives
162
- // ---------------------------------------------------------------------
163
- async function fileExistsAt(p) {
164
- try {
165
- const stat = await fs.stat(p);
166
- return stat.isFile();
167
- }
168
- catch {
169
- return false;
170
- }
171
- }
172
- async function dirExistsAt(p) {
173
- try {
174
- const stat = await fs.stat(p);
175
- return stat.isDirectory();
176
- }
177
- catch {
178
- return false;
179
- }
180
- }
181
- async function fileMatches(filePath, matches) {
182
- let content;
183
- try {
184
- content = await fs.readFile(filePath, "utf8");
185
- }
186
- catch {
187
- return false;
188
- }
189
- // Try JSON first (the most common manifest format). Fall back to
190
- // tolerant key-presence check for non-JSON files.
191
- let parsed;
192
- try {
193
- parsed = JSON.parse(content);
194
- }
195
- catch {
196
- // Non-JSON: do a substring check on the dotted-path key. Coarse
197
- // but correct for the "contains" use case.
198
- for (const key of Object.keys(matches)) {
199
- if (!content.includes(key))
200
- return false;
201
- }
202
- return true;
203
- }
204
- for (const [keyPath, _expected] of Object.entries(matches)) {
205
- const value = walkPath(parsed, keyPath);
206
- // MVP semantics: a key being PRESENT (truthy + non-null) at the
207
- // path means "match." Full semver-range matching is future work;
208
- // for activation gating, key-presence is sufficient — a project
209
- // with `dependencies.react` defined IS a React project.
210
- if (value === undefined || value === null || value === "")
211
- return false;
212
- }
213
- return true;
214
- }
215
- function walkPath(obj, dottedPath) {
216
- const parts = dottedPath.split(".");
217
- let cur = obj;
218
- for (const part of parts) {
219
- if (cur === null || cur === undefined)
220
- return undefined;
221
- if (typeof cur !== "object")
222
- return undefined;
223
- cur = cur[part];
224
- }
225
- return cur;
226
- }
227
- async function globAtLeast(cwd, pattern, minCount) {
228
- // Lightweight glob — supports `**/*.ext` and `dir/**/*.{a,b}` patterns.
229
- // Avoids pulling in a full glob dependency for one detection kind.
230
- const matches = await collectGlobMatches(cwd, pattern);
231
- return matches.length >= minCount;
232
- }
233
- async function collectGlobMatches(cwd, pattern) {
234
- // Split into a fixed-prefix and the matchable tail. Walk only what
235
- // the tail says.
236
- const segments = pattern.split("/");
237
- let prefix = cwd;
238
- let firstWildcard = -1;
239
- for (let i = 0; i < segments.length; i++) {
240
- if (segments[i].includes("*")) {
241
- firstWildcard = i;
242
- break;
243
- }
244
- prefix = path.join(prefix, segments[i]);
245
- }
246
- if (firstWildcard === -1) {
247
- // No wildcards — the pattern is literal; check existence directly.
248
- try {
249
- await fs.access(prefix);
250
- return [prefix];
251
- }
252
- catch {
253
- return [];
254
- }
255
- }
256
- const tail = segments.slice(firstWildcard).join("/");
257
- const fileRegex = globTailToRegex(tail);
258
- const results = [];
259
- await walkDir(prefix, "", fileRegex, results);
260
- return results;
261
- }
262
- async function walkDir(rootAbs, relPath, fileRegex, out) {
263
- let entries;
264
- try {
265
- entries = await fs.readdir(path.join(rootAbs, relPath), {
266
- withFileTypes: true,
267
- });
268
- }
269
- catch {
270
- return;
271
- }
272
- for (const entry of entries) {
273
- const childRel = relPath ? `${relPath}/${entry.name}` : entry.name;
274
- if (entry.isDirectory()) {
275
- if (entry.name === "node_modules" || entry.name.startsWith("."))
276
- continue;
277
- await walkDir(rootAbs, childRel, fileRegex, out);
278
- }
279
- else if (entry.isFile() && fileRegex.test(childRel)) {
280
- out.push(path.join(rootAbs, childRel));
281
- }
282
- }
283
- }
284
- function globTailToRegex(tail) {
285
- // Translate a glob tail (supports `**`, `*`, `{a,b}`) into a regex.
286
- let re = "";
287
- let i = 0;
288
- while (i < tail.length) {
289
- const c = tail[i];
290
- if (c === "*" && tail[i + 1] === "*") {
291
- re += ".*";
292
- i += 2;
293
- if (tail[i] === "/")
294
- i++;
295
- }
296
- else if (c === "*") {
297
- re += "[^/]*";
298
- i++;
299
- }
300
- else if (c === "?") {
301
- re += "[^/]";
302
- i++;
303
- }
304
- else if (c === "{") {
305
- const end = tail.indexOf("}", i);
306
- if (end === -1) {
307
- re += "\\{";
308
- i++;
309
- continue;
310
- }
311
- const opts = tail.slice(i + 1, end).split(",");
312
- re += `(?:${opts.map(escapeRegexLiteral).join("|")})`;
313
- i = end + 1;
314
- }
315
- else if (".+^$()|\\".includes(c)) {
316
- re += "\\" + c;
317
- i++;
318
- }
319
- else {
320
- re += c;
321
- i++;
322
- }
323
- }
324
- return new RegExp(`^${re}$`);
325
- }
326
- function escapeRegexLiteral(s) {
327
- return s.replace(/[.+*?^$()|[\]\\{}]/g, "\\$&");
328
- }
329
- //# sourceMappingURL=activate.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"activate.js","sourceRoot":"","sources":["../../src.legacy/codex/activate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE9D,wEAAwE;AACxE,aAAa;AACb,wEAAwE;AAExE;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,KAAY,EAAE,GAAW;IAC3D,IAAI,gBAAgB,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1C,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACzC,OAAO,oBAAoB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAC1C,CAAC;AAED,KAAK,UAAU,oBAAoB,CAAC,KAAmB,EAAE,GAAW;IAClE,sEAAsE;IACtE,IAAI,CAAC,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACtE,uDAAuD;IACvD,KAAK,MAAM,SAAS,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;QAC1C,IAAI,MAAM,iBAAiB,CAAC,SAAS,EAAE,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;IAC3D,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,SAAyB,EAAE,GAAW;IAC5E,QAAQ,SAAS,CAAC,IAAI,EAAE,CAAC;QACvB,KAAK,aAAa;YAChB,OAAO,IAAI,CAAC;QACd,KAAK,aAAa;YAChB,OAAO,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QACzD,KAAK,YAAY;YACf,OAAO,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QACxD,KAAK,YAAY;YACf,OAAO,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;QAC3E,KAAK,WAAW;YACd,OAAO,WAAW,CAAC,GAAG,EAAE,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC;QACvE,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,KAAK,MAAM,CAAC,IAAI,SAAS,CAAC,UAAU,EAAE,CAAC;gBACrC,IAAI,CAAC,CAAC,MAAM,iBAAiB,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;oBAAE,OAAO,KAAK,CAAC;YACvD,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,KAAK,MAAM,CAAC,IAAI,SAAS,CAAC,UAAU,EAAE,CAAC;gBACrC,IAAI,MAAM,iBAAiB,CAAC,CAAC,EAAE,GAAG,CAAC;oBAAE,OAAO,IAAI,CAAC;YACnD,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QACD,KAAK,cAAc,CAAC;QACpB,KAAK,qBAAqB;YACxB,+DAA+D;YAC/D,8DAA8D;YAC9D,mEAAmE;YACnE,iDAAiD;YACjD,OAAO,IAAI,CAAC;QACd,OAAO,CAAC,CAAC,CAAC;YACR,+CAA+C;YAC/C,6DAA6D;YAC7D,MAAM,WAAW,GAAU,SAAS,CAAC;YACrC,KAAK,WAAW,CAAC;YACjB,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;AACH,CAAC;AAED,wEAAwE;AACxE,yDAAyD;AACzD,wEAAwE;AAExE;;;;;;GAMG;AACH,MAAM,OAAO,oBAAoB;IAIZ;IACA;IAJX,SAAS,GAAG,IAAI,GAAG,EAA4B,CAAC;IAExD,YACmB,GAAW,EACX,OAAgB;QADhB,QAAG,GAAH,GAAG,CAAQ;QACX,YAAO,GAAP,OAAO,CAAS;IAChC,CAAC;IAEJ,mEAAmE;IACnE,KAAK,CAAC,QAAQ,CAAC,OAAe;QAC5B,IAAI,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC1C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YACjC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACvC,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,KAAK,CAAC,QAAQ,CAAC,OAAe;QACpC,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;YACjE,OAAO,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QACxC,CAAC;QAAC,MAAM,CAAC;YACP,+DAA+D;YAC/D,+DAA+D;YAC/D,qCAAqC;YACrC,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;CACF;AAED,wEAAwE;AACxE,+BAA+B;AAC/B,wEAAwE;AAExE;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAAC,WAAmB;IAChD,MAAM,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAC1E,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACzB,CAAC;AAED,wEAAwE;AACxE,wBAAwB;AACxB,wEAAwE;AAExE,KAAK,UAAU,YAAY,CAAC,CAAS;IACnC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC9B,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,CAAS;IAClC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC9B,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,QAAgB,EAAE,OAAgC;IAC3E,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IACD,iEAAiE;IACjE,kDAAkD;IAClD,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,gEAAgE;QAChE,2CAA2C;QAC3C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACvC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAAE,OAAO,KAAK,CAAC;QAC3C,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,KAAK,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3D,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACxC,gEAAgE;QAChE,iEAAiE;QACjE,gEAAgE;QAChE,wDAAwD;QACxD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE;YAAE,OAAO,KAAK,CAAC;IAC1E,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,QAAQ,CAAC,GAAY,EAAE,UAAkB;IAChD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,GAAG,GAAY,GAAG,CAAC;IACvB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QACxD,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,SAAS,CAAC;QAC9C,GAAG,GAAI,GAA+B,CAAC,IAAI,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,GAAW,EAAE,OAAe,EAAE,QAAgB;IACvE,wEAAwE;IACxE,mEAAmE;IACnE,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACvD,OAAO,OAAO,CAAC,MAAM,IAAI,QAAQ,CAAC;AACpC,CAAC;AAED,KAAK,UAAU,kBAAkB,CAAC,GAAW,EAAE,OAAe;IAC5D,mEAAmE;IACnE,iBAAiB;IACjB,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,MAAM,GAAG,GAAG,CAAC;IACjB,IAAI,aAAa,GAAG,CAAC,CAAC,CAAC;IACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC9B,aAAa,GAAG,CAAC,CAAC;YAClB,MAAM;QACR,CAAC;QACD,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC;IACD,IAAI,aAAa,KAAK,CAAC,CAAC,EAAE,CAAC;QACzB,mEAAmE;QACnE,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACxB,OAAO,CAAC,MAAM,CAAC,CAAC;QAClB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IACD,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACrD,MAAM,SAAS,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,OAAO,CAAC,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAC9C,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,OAAO,CACpB,OAAe,EACf,OAAe,EACf,SAAiB,EACjB,GAAa;IAEb,IAAI,OAAmC,CAAC;IACxC,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE;YACtD,aAAa,EAAE,IAAI;SACpB,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;QACnE,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,SAAS;YAC1E,MAAM,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;QACnD,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YACtD,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,IAAY;IACnC,oEAAoE;IACpE,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACvB,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,IAAI,CAAC,KAAK,GAAG,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YACrC,EAAE,IAAI,IAAI,CAAC;YACX,CAAC,IAAI,CAAC,CAAC;YACP,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG;gBAAE,CAAC,EAAE,CAAC;QAC3B,CAAC;aAAM,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;YACrB,EAAE,IAAI,OAAO,CAAC;YACd,CAAC,EAAE,CAAC;QACN,CAAC;aAAM,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;YACrB,EAAE,IAAI,MAAM,CAAC;YACb,CAAC,EAAE,CAAC;QACN,CAAC;aAAM,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;YACrB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACjC,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;gBACf,EAAE,IAAI,KAAK,CAAC;gBACZ,CAAC,EAAE,CAAC;gBACJ,SAAS;YACX,CAAC;YACD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC/C,EAAE,IAAI,MAAM,IAAI,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YACtD,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC;QACd,CAAC;aAAM,IAAI,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;YACnC,EAAE,IAAI,IAAI,GAAG,CAAC,CAAC;YACf,CAAC,EAAE,CAAC;QACN,CAAC;aAAM,CAAC;YACN,EAAE,IAAI,CAAC,CAAC;YACR,CAAC,EAAE,CAAC;QACN,CAAC;IACH,CAAC;IACD,OAAO,IAAI,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AAC/B,CAAC;AAED,SAAS,kBAAkB,CAAC,CAAS;IACnC,OAAO,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAClD,CAAC"}