@moreih29/nexus-core 0.17.0 → 0.18.2

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 (415) hide show
  1. package/README.md +101 -67
  2. package/dist/cli/sync.d.ts +3 -0
  3. package/dist/cli/sync.d.ts.map +1 -0
  4. package/dist/cli/sync.js +59 -0
  5. package/dist/cli/sync.js.map +1 -0
  6. package/dist/generate/index.d.ts +3 -0
  7. package/dist/generate/index.d.ts.map +1 -0
  8. package/dist/generate/index.js +2 -0
  9. package/dist/generate/index.js.map +1 -0
  10. package/dist/generate/load-data.d.ts +8 -0
  11. package/dist/generate/load-data.d.ts.map +1 -0
  12. package/dist/generate/load-data.js +45 -0
  13. package/dist/generate/load-data.js.map +1 -0
  14. package/dist/generate/load-spec.d.ts +3 -0
  15. package/dist/generate/load-spec.d.ts.map +1 -0
  16. package/dist/generate/load-spec.js +48 -0
  17. package/dist/generate/load-spec.js.map +1 -0
  18. package/dist/generate/macros/expand.d.ts +3 -0
  19. package/dist/generate/macros/expand.d.ts.map +1 -0
  20. package/dist/generate/macros/expand.js +48 -0
  21. package/dist/generate/macros/expand.js.map +1 -0
  22. package/dist/generate/macros/parse.d.ts +4 -0
  23. package/dist/generate/macros/parse.d.ts.map +1 -0
  24. package/dist/generate/macros/parse.js +142 -0
  25. package/dist/generate/macros/parse.js.map +1 -0
  26. package/dist/generate/macros/validate.d.ts +3 -0
  27. package/dist/generate/macros/validate.d.ts.map +1 -0
  28. package/dist/generate/macros/validate.js +23 -0
  29. package/dist/generate/macros/validate.js.map +1 -0
  30. package/dist/generate/renderers/claude.d.ts +3 -0
  31. package/dist/generate/renderers/claude.d.ts.map +1 -0
  32. package/dist/generate/renderers/claude.js +48 -0
  33. package/dist/generate/renderers/claude.js.map +1 -0
  34. package/dist/generate/renderers/codex.d.ts +3 -0
  35. package/dist/generate/renderers/codex.d.ts.map +1 -0
  36. package/dist/generate/renderers/codex.js +79 -0
  37. package/dist/generate/renderers/codex.js.map +1 -0
  38. package/dist/generate/renderers/markdown.d.ts +2 -0
  39. package/dist/generate/renderers/markdown.d.ts.map +1 -0
  40. package/dist/generate/renderers/markdown.js +6 -0
  41. package/dist/generate/renderers/markdown.js.map +1 -0
  42. package/dist/generate/renderers/opencode.d.ts +3 -0
  43. package/dist/generate/renderers/opencode.d.ts.map +1 -0
  44. package/dist/generate/renderers/opencode.js +69 -0
  45. package/dist/generate/renderers/opencode.js.map +1 -0
  46. package/dist/generate/sync.d.ts +4 -0
  47. package/dist/generate/sync.d.ts.map +1 -0
  48. package/dist/generate/sync.js +60 -0
  49. package/dist/generate/sync.js.map +1 -0
  50. package/dist/generate/types.d.ts +74 -0
  51. package/dist/generate/types.d.ts.map +1 -0
  52. package/dist/generate/types.js +2 -0
  53. package/dist/generate/types.js.map +1 -0
  54. package/dist/index.d.ts +4 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +2 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/mcp/definitions/artifact.d.ts +20 -0
  59. package/dist/mcp/definitions/artifact.d.ts.map +1 -0
  60. package/dist/mcp/definitions/artifact.js +14 -0
  61. package/dist/mcp/definitions/artifact.js.map +1 -0
  62. package/dist/mcp/definitions/history.d.ts +20 -0
  63. package/dist/mcp/definitions/history.d.ts.map +1 -0
  64. package/dist/mcp/definitions/history.js +18 -0
  65. package/dist/mcp/definitions/history.js.map +1 -0
  66. package/dist/mcp/definitions/index.d.ts +276 -0
  67. package/dist/mcp/definitions/index.d.ts.map +1 -0
  68. package/dist/mcp/definitions/index.js +16 -0
  69. package/dist/mcp/definitions/index.js.map +1 -0
  70. package/dist/mcp/definitions/plan.d.ts +111 -0
  71. package/dist/mcp/definitions/plan.d.ts.map +1 -0
  72. package/dist/mcp/definitions/plan.js +89 -0
  73. package/dist/mcp/definitions/plan.js.map +1 -0
  74. package/dist/mcp/definitions/task.d.ts +138 -0
  75. package/dist/mcp/definitions/task.d.ts.map +1 -0
  76. package/dist/mcp/definitions/task.js +78 -0
  77. package/dist/mcp/definitions/task.js.map +1 -0
  78. package/dist/mcp/handlers/artifact.d.ts.map +1 -0
  79. package/dist/mcp/handlers/artifact.js +42 -0
  80. package/dist/mcp/handlers/artifact.js.map +1 -0
  81. package/dist/mcp/handlers/history.d.ts.map +1 -0
  82. package/dist/mcp/handlers/history.js +35 -0
  83. package/dist/mcp/handlers/history.js.map +1 -0
  84. package/dist/mcp/handlers/plan.d.ts.map +1 -0
  85. package/dist/mcp/handlers/plan.js +324 -0
  86. package/dist/mcp/handlers/plan.js.map +1 -0
  87. package/dist/mcp/handlers/task.d.ts.map +1 -0
  88. package/dist/mcp/handlers/task.js +216 -0
  89. package/dist/mcp/handlers/task.js.map +1 -0
  90. package/dist/{src/mcp → mcp}/server.d.ts +1 -1
  91. package/dist/mcp/server.d.ts.map +1 -0
  92. package/dist/mcp/server.js +58 -0
  93. package/dist/mcp/server.js.map +1 -0
  94. package/dist/shared/json-store.d.ts.map +1 -0
  95. package/dist/{src/shared → shared}/json-store.js +5 -4
  96. package/dist/shared/json-store.js.map +1 -0
  97. package/dist/shared/mcp-utils.d.ts.map +1 -0
  98. package/dist/shared/mcp-utils.js.map +1 -0
  99. package/dist/{src/shared → shared}/paths.d.ts +0 -6
  100. package/dist/shared/paths.d.ts.map +1 -0
  101. package/dist/shared/paths.js +62 -0
  102. package/dist/shared/paths.js.map +1 -0
  103. package/dist/shared/register-tool.d.ts +20 -0
  104. package/dist/shared/register-tool.d.ts.map +1 -0
  105. package/dist/shared/register-tool.js +15 -0
  106. package/dist/shared/register-tool.js.map +1 -0
  107. package/dist/{src/types → types}/state.d.ts +65 -65
  108. package/dist/types/state.d.ts.map +1 -0
  109. package/dist/{src/types → types}/state.js +1 -1
  110. package/dist/types/state.js.map +1 -0
  111. package/harness/claude/agent-rules.yml +21 -0
  112. package/harness/claude/invocations.yml +11 -0
  113. package/harness/claude/layout.yml +3 -0
  114. package/harness/codex/agent-rules.yml +28 -0
  115. package/harness/codex/invocations.yml +13 -0
  116. package/harness/codex/layout.yml +3 -0
  117. package/harness/opencode/agent-rules.yml +18 -0
  118. package/harness/opencode/invocations.yml +12 -0
  119. package/harness/opencode/layout.yml +3 -0
  120. package/package.json +38 -43
  121. package/{assets → spec}/agents/architect/body.ko.md +92 -84
  122. package/spec/agents/architect/body.md +185 -0
  123. package/spec/agents/designer/body.ko.md +330 -0
  124. package/spec/agents/designer/body.md +330 -0
  125. package/spec/agents/engineer/body.ko.md +166 -0
  126. package/spec/agents/engineer/body.md +166 -0
  127. package/spec/agents/lead/body.ko.md +276 -0
  128. package/spec/agents/lead/body.md +276 -0
  129. package/{assets → spec}/agents/postdoc/body.ko.md +116 -46
  130. package/spec/agents/postdoc/body.md +192 -0
  131. package/{assets → spec}/agents/researcher/body.ko.md +131 -45
  132. package/spec/agents/researcher/body.md +223 -0
  133. package/spec/agents/reviewer/body.ko.md +219 -0
  134. package/spec/agents/reviewer/body.md +219 -0
  135. package/{assets → spec}/agents/strategist/body.ko.md +108 -35
  136. package/spec/agents/strategist/body.md +187 -0
  137. package/spec/agents/tester/body.ko.md +272 -0
  138. package/spec/agents/tester/body.md +272 -0
  139. package/{assets → spec}/agents/writer/body.ko.md +109 -33
  140. package/spec/agents/writer/body.md +198 -0
  141. package/spec/skills/nx-auto-plan/body.ko.md +150 -0
  142. package/spec/skills/nx-auto-plan/body.md +150 -0
  143. package/spec/skills/nx-plan/body.ko.md +159 -0
  144. package/spec/skills/nx-plan/body.md +159 -0
  145. package/spec/skills/nx-run/body.ko.md +132 -0
  146. package/spec/skills/nx-run/body.md +132 -0
  147. package/vocabulary/enums/task-register-state.yml +4 -0
  148. package/vocabulary/invocations.yml +43 -0
  149. package/assets/agents/architect/body.md +0 -177
  150. package/assets/agents/designer/body.ko.md +0 -125
  151. package/assets/agents/designer/body.md +0 -125
  152. package/assets/agents/engineer/body.ko.md +0 -106
  153. package/assets/agents/engineer/body.md +0 -106
  154. package/assets/agents/lead/body.ko.md +0 -70
  155. package/assets/agents/lead/body.md +0 -70
  156. package/assets/agents/postdoc/body.md +0 -122
  157. package/assets/agents/researcher/body.md +0 -137
  158. package/assets/agents/reviewer/body.ko.md +0 -138
  159. package/assets/agents/reviewer/body.md +0 -138
  160. package/assets/agents/strategist/body.md +0 -116
  161. package/assets/agents/tester/body.ko.md +0 -195
  162. package/assets/agents/tester/body.md +0 -195
  163. package/assets/agents/writer/body.md +0 -122
  164. package/assets/capability-matrix.yml +0 -200
  165. package/assets/hooks/agent-bootstrap/handler.test.ts +0 -369
  166. package/assets/hooks/agent-bootstrap/handler.ts +0 -132
  167. package/assets/hooks/agent-bootstrap/meta.yml +0 -10
  168. package/assets/hooks/agent-finalize/handler.test.ts +0 -368
  169. package/assets/hooks/agent-finalize/handler.ts +0 -76
  170. package/assets/hooks/agent-finalize/meta.yml +0 -10
  171. package/assets/hooks/capability-matrix.yml +0 -313
  172. package/assets/hooks/post-tool-telemetry/handler.test.ts +0 -302
  173. package/assets/hooks/post-tool-telemetry/handler.ts +0 -49
  174. package/assets/hooks/post-tool-telemetry/meta.yml +0 -10
  175. package/assets/hooks/prompt-router/handler.test.ts +0 -801
  176. package/assets/hooks/prompt-router/handler.ts +0 -272
  177. package/assets/hooks/prompt-router/meta.yml +0 -11
  178. package/assets/hooks/session-init/handler.test.ts +0 -274
  179. package/assets/hooks/session-init/handler.ts +0 -31
  180. package/assets/hooks/session-init/meta.yml +0 -9
  181. package/assets/lsp-servers.json +0 -55
  182. package/assets/schema/lsp-servers.schema.json +0 -67
  183. package/assets/skills/nx-init/body.ko.md +0 -197
  184. package/assets/skills/nx-init/body.md +0 -197
  185. package/assets/skills/nx-plan/body.ko.md +0 -361
  186. package/assets/skills/nx-plan/body.md +0 -361
  187. package/assets/skills/nx-run/body.ko.md +0 -161
  188. package/assets/skills/nx-run/body.md +0 -160
  189. package/assets/skills/nx-sync/body.ko.md +0 -92
  190. package/assets/skills/nx-sync/body.md +0 -92
  191. package/assets/tools/tool-name-map.yml +0 -353
  192. package/dist/assets/hooks/agent-bootstrap/handler.d.ts +0 -4
  193. package/dist/assets/hooks/agent-bootstrap/handler.d.ts.map +0 -1
  194. package/dist/assets/hooks/agent-bootstrap/handler.js +0 -114
  195. package/dist/assets/hooks/agent-bootstrap/handler.js.map +0 -1
  196. package/dist/assets/hooks/agent-finalize/handler.d.ts +0 -4
  197. package/dist/assets/hooks/agent-finalize/handler.d.ts.map +0 -1
  198. package/dist/assets/hooks/agent-finalize/handler.js +0 -63
  199. package/dist/assets/hooks/agent-finalize/handler.js.map +0 -1
  200. package/dist/assets/hooks/post-tool-telemetry/handler.d.ts +0 -4
  201. package/dist/assets/hooks/post-tool-telemetry/handler.d.ts.map +0 -1
  202. package/dist/assets/hooks/post-tool-telemetry/handler.js +0 -40
  203. package/dist/assets/hooks/post-tool-telemetry/handler.js.map +0 -1
  204. package/dist/assets/hooks/prompt-router/handler.d.ts +0 -4
  205. package/dist/assets/hooks/prompt-router/handler.d.ts.map +0 -1
  206. package/dist/assets/hooks/prompt-router/handler.js +0 -214
  207. package/dist/assets/hooks/prompt-router/handler.js.map +0 -1
  208. package/dist/assets/hooks/session-init/handler.d.ts +0 -4
  209. package/dist/assets/hooks/session-init/handler.d.ts.map +0 -1
  210. package/dist/assets/hooks/session-init/handler.js +0 -22
  211. package/dist/assets/hooks/session-init/handler.js.map +0 -1
  212. package/dist/claude/.claude-plugin/marketplace.json +0 -75
  213. package/dist/claude/.claude-plugin/plugin.json +0 -67
  214. package/dist/claude/agents/architect.md +0 -172
  215. package/dist/claude/agents/designer.md +0 -120
  216. package/dist/claude/agents/engineer.md +0 -98
  217. package/dist/claude/agents/lead.md +0 -59
  218. package/dist/claude/agents/postdoc.md +0 -117
  219. package/dist/claude/agents/researcher.md +0 -132
  220. package/dist/claude/agents/reviewer.md +0 -133
  221. package/dist/claude/agents/strategist.md +0 -111
  222. package/dist/claude/agents/tester.md +0 -190
  223. package/dist/claude/agents/writer.md +0 -114
  224. package/dist/claude/dist/hooks/agent-bootstrap.js +0 -238
  225. package/dist/claude/dist/hooks/agent-finalize.js +0 -180
  226. package/dist/claude/dist/hooks/post-tool-telemetry.js +0 -71
  227. package/dist/claude/dist/hooks/prompt-router.js +0 -7336
  228. package/dist/claude/dist/hooks/session-init.js +0 -50
  229. package/dist/claude/hooks/hooks.json +0 -64
  230. package/dist/claude/settings.json +0 -3
  231. package/dist/claude/skills/nx-init/SKILL.md +0 -189
  232. package/dist/claude/skills/nx-plan/SKILL.md +0 -353
  233. package/dist/claude/skills/nx-run/SKILL.md +0 -154
  234. package/dist/claude/skills/nx-sync/SKILL.md +0 -87
  235. package/dist/codex/agents/architect.toml +0 -175
  236. package/dist/codex/agents/designer.toml +0 -123
  237. package/dist/codex/agents/engineer.toml +0 -105
  238. package/dist/codex/agents/lead.toml +0 -64
  239. package/dist/codex/agents/postdoc.toml +0 -120
  240. package/dist/codex/agents/researcher.toml +0 -136
  241. package/dist/codex/agents/reviewer.toml +0 -137
  242. package/dist/codex/agents/strategist.toml +0 -114
  243. package/dist/codex/agents/tester.toml +0 -194
  244. package/dist/codex/agents/writer.toml +0 -121
  245. package/dist/codex/dist/hooks/agent-bootstrap.js +0 -238
  246. package/dist/codex/dist/hooks/agent-finalize.js +0 -180
  247. package/dist/codex/dist/hooks/prompt-router.js +0 -7336
  248. package/dist/codex/dist/hooks/session-init.js +0 -50
  249. package/dist/codex/hooks/hooks.json +0 -28
  250. package/dist/codex/install/AGENTS.fragment.md +0 -60
  251. package/dist/codex/install/config.fragment.toml +0 -5
  252. package/dist/codex/install/install.sh +0 -60
  253. package/dist/codex/package.json +0 -20
  254. package/dist/codex/plugin/.codex-plugin/plugin.json +0 -57
  255. package/dist/codex/plugin/skills/nx-init/SKILL.md +0 -189
  256. package/dist/codex/plugin/skills/nx-plan/SKILL.md +0 -353
  257. package/dist/codex/plugin/skills/nx-run/SKILL.md +0 -154
  258. package/dist/codex/plugin/skills/nx-sync/SKILL.md +0 -87
  259. package/dist/codex/prompts/architect.md +0 -166
  260. package/dist/codex/prompts/designer.md +0 -114
  261. package/dist/codex/prompts/engineer.md +0 -97
  262. package/dist/codex/prompts/lead.md +0 -60
  263. package/dist/codex/prompts/postdoc.md +0 -111
  264. package/dist/codex/prompts/researcher.md +0 -127
  265. package/dist/codex/prompts/reviewer.md +0 -128
  266. package/dist/codex/prompts/strategist.md +0 -105
  267. package/dist/codex/prompts/tester.md +0 -185
  268. package/dist/codex/prompts/writer.md +0 -113
  269. package/dist/hooks/agent-bootstrap.js +0 -238
  270. package/dist/hooks/agent-finalize.js +0 -180
  271. package/dist/hooks/post-tool-telemetry.js +0 -71
  272. package/dist/hooks/prompt-router.js +0 -7336
  273. package/dist/hooks/session-init.js +0 -50
  274. package/dist/manifests/claude-hooks.json +0 -64
  275. package/dist/manifests/codex-hooks.json +0 -28
  276. package/dist/manifests/opencode-manifest.json +0 -54
  277. package/dist/manifests/portability-report.json +0 -75
  278. package/dist/opencode/.opencode/skills/nx-init/SKILL.md +0 -189
  279. package/dist/opencode/.opencode/skills/nx-plan/SKILL.md +0 -353
  280. package/dist/opencode/.opencode/skills/nx-run/SKILL.md +0 -154
  281. package/dist/opencode/.opencode/skills/nx-sync/SKILL.md +0 -87
  282. package/dist/opencode/package.json +0 -23
  283. package/dist/opencode/src/agents/architect.ts +0 -176
  284. package/dist/opencode/src/agents/designer.ts +0 -124
  285. package/dist/opencode/src/agents/engineer.ts +0 -105
  286. package/dist/opencode/src/agents/lead.ts +0 -66
  287. package/dist/opencode/src/agents/postdoc.ts +0 -121
  288. package/dist/opencode/src/agents/researcher.ts +0 -136
  289. package/dist/opencode/src/agents/reviewer.ts +0 -137
  290. package/dist/opencode/src/agents/strategist.ts +0 -115
  291. package/dist/opencode/src/agents/tester.ts +0 -194
  292. package/dist/opencode/src/agents/writer.ts +0 -121
  293. package/dist/opencode/src/index.ts +0 -25
  294. package/dist/opencode/src/plugin.ts +0 -6
  295. package/dist/scripts/build-agents.d.ts +0 -170
  296. package/dist/scripts/build-agents.d.ts.map +0 -1
  297. package/dist/scripts/build-agents.js +0 -907
  298. package/dist/scripts/build-agents.js.map +0 -1
  299. package/dist/scripts/build-hooks.d.ts +0 -57
  300. package/dist/scripts/build-hooks.d.ts.map +0 -1
  301. package/dist/scripts/build-hooks.js +0 -562
  302. package/dist/scripts/build-hooks.js.map +0 -1
  303. package/dist/scripts/cli.d.ts +0 -54
  304. package/dist/scripts/cli.d.ts.map +0 -1
  305. package/dist/scripts/cli.js +0 -504
  306. package/dist/scripts/cli.js.map +0 -1
  307. package/dist/scripts/smoke/smoke-claude.d.ts +0 -2
  308. package/dist/scripts/smoke/smoke-claude.d.ts.map +0 -1
  309. package/dist/scripts/smoke/smoke-claude.js +0 -58
  310. package/dist/scripts/smoke/smoke-claude.js.map +0 -1
  311. package/dist/scripts/smoke/smoke-codex.d.ts +0 -2
  312. package/dist/scripts/smoke/smoke-codex.d.ts.map +0 -1
  313. package/dist/scripts/smoke/smoke-codex.js +0 -50
  314. package/dist/scripts/smoke/smoke-codex.js.map +0 -1
  315. package/dist/scripts/smoke/smoke-consumer.d.ts +0 -2
  316. package/dist/scripts/smoke/smoke-consumer.d.ts.map +0 -1
  317. package/dist/scripts/smoke/smoke-consumer.js +0 -230
  318. package/dist/scripts/smoke/smoke-consumer.js.map +0 -1
  319. package/dist/scripts/smoke/smoke-opencode.d.ts +0 -2
  320. package/dist/scripts/smoke/smoke-opencode.d.ts.map +0 -1
  321. package/dist/scripts/smoke/smoke-opencode.js +0 -99
  322. package/dist/scripts/smoke/smoke-opencode.js.map +0 -1
  323. package/dist/src/hooks/opencode-mount.d.ts +0 -35
  324. package/dist/src/hooks/opencode-mount.d.ts.map +0 -1
  325. package/dist/src/hooks/opencode-mount.js +0 -352
  326. package/dist/src/hooks/opencode-mount.js.map +0 -1
  327. package/dist/src/hooks/runtime.d.ts +0 -37
  328. package/dist/src/hooks/runtime.d.ts.map +0 -1
  329. package/dist/src/hooks/runtime.js +0 -274
  330. package/dist/src/hooks/runtime.js.map +0 -1
  331. package/dist/src/hooks/types.d.ts +0 -196
  332. package/dist/src/hooks/types.d.ts.map +0 -1
  333. package/dist/src/hooks/types.js +0 -85
  334. package/dist/src/hooks/types.js.map +0 -1
  335. package/dist/src/lsp/cache.d.ts +0 -9
  336. package/dist/src/lsp/cache.d.ts.map +0 -1
  337. package/dist/src/lsp/cache.js +0 -216
  338. package/dist/src/lsp/cache.js.map +0 -1
  339. package/dist/src/lsp/client.d.ts +0 -24
  340. package/dist/src/lsp/client.d.ts.map +0 -1
  341. package/dist/src/lsp/client.js +0 -166
  342. package/dist/src/lsp/client.js.map +0 -1
  343. package/dist/src/lsp/detect.d.ts +0 -77
  344. package/dist/src/lsp/detect.d.ts.map +0 -1
  345. package/dist/src/lsp/detect.js +0 -116
  346. package/dist/src/lsp/detect.js.map +0 -1
  347. package/dist/src/mcp/server.d.ts.map +0 -1
  348. package/dist/src/mcp/server.js +0 -34
  349. package/dist/src/mcp/server.js.map +0 -1
  350. package/dist/src/mcp/tools/artifact.d.ts.map +0 -1
  351. package/dist/src/mcp/tools/artifact.js +0 -36
  352. package/dist/src/mcp/tools/artifact.js.map +0 -1
  353. package/dist/src/mcp/tools/history.d.ts.map +0 -1
  354. package/dist/src/mcp/tools/history.js +0 -29
  355. package/dist/src/mcp/tools/history.js.map +0 -1
  356. package/dist/src/mcp/tools/lsp.d.ts +0 -13
  357. package/dist/src/mcp/tools/lsp.d.ts.map +0 -1
  358. package/dist/src/mcp/tools/lsp.js +0 -225
  359. package/dist/src/mcp/tools/lsp.js.map +0 -1
  360. package/dist/src/mcp/tools/plan.d.ts.map +0 -1
  361. package/dist/src/mcp/tools/plan.js +0 -317
  362. package/dist/src/mcp/tools/plan.js.map +0 -1
  363. package/dist/src/mcp/tools/task.d.ts.map +0 -1
  364. package/dist/src/mcp/tools/task.js +0 -252
  365. package/dist/src/mcp/tools/task.js.map +0 -1
  366. package/dist/src/shared/invocations.d.ts +0 -74
  367. package/dist/src/shared/invocations.d.ts.map +0 -1
  368. package/dist/src/shared/invocations.js +0 -247
  369. package/dist/src/shared/invocations.js.map +0 -1
  370. package/dist/src/shared/json-store.d.ts.map +0 -1
  371. package/dist/src/shared/json-store.js.map +0 -1
  372. package/dist/src/shared/mcp-utils.d.ts.map +0 -1
  373. package/dist/src/shared/mcp-utils.js.map +0 -1
  374. package/dist/src/shared/package-root.d.ts +0 -6
  375. package/dist/src/shared/package-root.d.ts.map +0 -1
  376. package/dist/src/shared/package-root.js +0 -19
  377. package/dist/src/shared/package-root.js.map +0 -1
  378. package/dist/src/shared/paths.d.ts.map +0 -1
  379. package/dist/src/shared/paths.js +0 -117
  380. package/dist/src/shared/paths.js.map +0 -1
  381. package/dist/src/shared/tool-log.d.ts +0 -8
  382. package/dist/src/shared/tool-log.d.ts.map +0 -1
  383. package/dist/src/shared/tool-log.js +0 -22
  384. package/dist/src/shared/tool-log.js.map +0 -1
  385. package/dist/src/types/agent-config.d.ts +0 -22
  386. package/dist/src/types/agent-config.d.ts.map +0 -1
  387. package/dist/src/types/agent-config.js +0 -2
  388. package/dist/src/types/agent-config.js.map +0 -1
  389. package/dist/src/types/index.d.ts +0 -2
  390. package/dist/src/types/index.d.ts.map +0 -1
  391. package/dist/src/types/index.js +0 -2
  392. package/dist/src/types/index.js.map +0 -1
  393. package/dist/src/types/state.d.ts.map +0 -1
  394. package/dist/src/types/state.js.map +0 -1
  395. package/docs/consuming/codex-lead-merge.md +0 -106
  396. package/docs/contract/harness-io.md +0 -333
  397. package/docs/plugin-guide.md +0 -355
  398. package/docs/plugin-template/claude/.github/workflows/build.yml +0 -60
  399. package/docs/plugin-template/claude/README.md +0 -110
  400. package/docs/plugin-template/claude/package.json +0 -16
  401. package/docs/plugin-template/codex/.github/workflows/build.yml +0 -51
  402. package/docs/plugin-template/codex/README.md +0 -147
  403. package/docs/plugin-template/codex/install/install.sh +0 -60
  404. package/docs/plugin-template/codex/package.json +0 -17
  405. package/docs/plugin-template/opencode/.github/workflows/build.yml +0 -61
  406. package/docs/plugin-template/opencode/README.md +0 -121
  407. package/docs/plugin-template/opencode/package.json +0 -25
  408. package/docs/plugin-template/opencode/src/plugin.ts +0 -6
  409. /package/dist/{src/mcp/tools → mcp/handlers}/artifact.d.ts +0 -0
  410. /package/dist/{src/mcp/tools → mcp/handlers}/history.d.ts +0 -0
  411. /package/dist/{src/mcp/tools → mcp/handlers}/plan.d.ts +0 -0
  412. /package/dist/{src/mcp/tools → mcp/handlers}/task.d.ts +0 -0
  413. /package/dist/{src/shared → shared}/json-store.d.ts +0 -0
  414. /package/dist/{src/shared → shared}/mcp-utils.d.ts +0 -0
  415. /package/dist/{src/shared → shared}/mcp-utils.js +0 -0
@@ -1,907 +0,0 @@
1
- /**
2
- * scripts/build-agents.ts
3
- *
4
- * Build pipeline for nexus agents and skills.
5
- *
6
- * Inputs:
7
- * assets/agents/<n>/body.md × 9 agents
8
- * assets/skills/<n>/body.md × 4 skills
9
- * assets/capability-matrix.yml
10
- * assets/tools/tool-name-map.yml (invocations section)
11
- *
12
- * Outputs per harness:
13
- * dist/claude/
14
- * .claude-plugin/plugin.json (Template — skip if exists, --force to overwrite)
15
- * .claude-plugin/marketplace.json (Template — skip if exists, --force to overwrite)
16
- * agents/<n>.md × N
17
- * skills/<n>/SKILL.md × 4
18
- * settings.json (Managed — primary agent injection, omitted if no primary)
19
- *
20
- * dist/opencode/
21
- * package.json (Template — skip if exists)
22
- * src/index.ts (Managed — always overwrite)
23
- * src/agents/<n>.ts × N (Managed — always overwrite, mode:primary gets mode field)
24
- * .opencode/skills/<n>/SKILL.md × 4 (Managed)
25
- *
26
- * dist/codex/
27
- * plugin/.codex-plugin/plugin.json (Managed)
28
- * plugin/skills/<n>/SKILL.md × 4 (Managed)
29
- * agents/<n>.toml × N (Managed)
30
- * prompts/<n>.md × N (Managed)
31
- * install/config.fragment.toml (Managed)
32
- * install/AGENTS.fragment.md (Managed — primary agents only, omitted if none)
33
- *
34
- * Overwrite policy:
35
- * Managed paths — always overwrite (unless --dry-run)
36
- * Template paths — skip if file exists (overwrite only with --force)
37
- *
38
- * CLI flags:
39
- * --harness=claude|opencode|codex (default: all)
40
- * --target=<dir> (default: dist/)
41
- * --dry-run print affected files, no writes
42
- * --force force Template file overwrite
43
- * --strict error if Managed output has untracked modifications
44
- * --only=<agent|skill name> restrict to a single asset
45
- */
46
- import { readFileSync, readdirSync, existsSync, mkdirSync, writeFileSync, } from "node:fs";
47
- import { join, resolve, dirname } from "node:path";
48
- import { fileURLToPath } from "node:url";
49
- import { execSync } from "node:child_process";
50
- import { parse as parseYaml } from "yaml";
51
- import { expandInvocations } from "../src/shared/invocations.js";
52
- import { findPackageRoot } from "../src/shared/package-root.js";
53
- // ---------------------------------------------------------------------------
54
- // Constants
55
- // ---------------------------------------------------------------------------
56
- const __dirname = dirname(fileURLToPath(import.meta.url));
57
- export const ROOT = findPackageRoot(__dirname);
58
- export const AGENTS_DIR = join(ROOT, "assets/agents");
59
- export const SKILLS_DIR = join(ROOT, "assets/skills");
60
- export const CAPABILITY_MATRIX_PATH = join(ROOT, "assets/capability-matrix.yml");
61
- export const TOOL_NAME_MAP_PATH = join(ROOT, "assets/tools/tool-name-map.yml");
62
- const HARNESSES = ["claude", "opencode", "codex"];
63
- const CODEX_MCP_NX_COMMAND = "nexus-mcp";
64
- // Track dry-run affected files (cleared after each buildAgents call)
65
- const dryRunRecords = [];
66
- // ---------------------------------------------------------------------------
67
- // Frontmatter parsing
68
- // ---------------------------------------------------------------------------
69
- const FRONTMATTER_RE = /^---\n([\s\S]*?)\n---\n?([\s\S]*)$/;
70
- /**
71
- * Split a body.md file into frontmatter object and body text.
72
- * Throws on YAML parse failure.
73
- */
74
- export function parseFrontmatter(raw, filePath) {
75
- const match = FRONTMATTER_RE.exec(raw);
76
- if (!match) {
77
- throw new Error(`[build-agents] Missing or malformed frontmatter in: ${filePath}`);
78
- }
79
- let fm;
80
- try {
81
- fm = parseYaml(match[1]);
82
- }
83
- catch (err) {
84
- throw new Error(`[build-agents] YAML parse failure in frontmatter of: ${filePath}\n ${String(err)}`);
85
- }
86
- if (!fm.id || !fm.name) {
87
- throw new Error(`[build-agents] Missing required frontmatter fields (id, name) in: ${filePath}`);
88
- }
89
- const VALID_MODES = ["primary", "subagent", "all"];
90
- if (fm.mode !== undefined && !VALID_MODES.includes(fm.mode)) {
91
- throw new Error(`[build-agents] Invalid mode "${fm.mode}" in: ${filePath}. Valid values: ${VALID_MODES.join(", ")}`);
92
- }
93
- return { fm, body: (match[2] ?? "").trimStart() };
94
- }
95
- // ---------------------------------------------------------------------------
96
- // Stage 1: Load assets
97
- // ---------------------------------------------------------------------------
98
- /**
99
- * Load all agents and skills from assets/, whitelisting only body.md.
100
- */
101
- export function loadAssets(opts) {
102
- const entries = [];
103
- // Load agents
104
- if (existsSync(AGENTS_DIR)) {
105
- for (const entry of readdirSync(AGENTS_DIR, { withFileTypes: true })) {
106
- if (!entry.isDirectory())
107
- continue;
108
- if (opts?.only && entry.name !== opts.only)
109
- continue;
110
- const bodyPath = join(AGENTS_DIR, entry.name, "body.md");
111
- if (!existsSync(bodyPath)) {
112
- throw new Error(`[build-agents] Missing body.md for agent: ${entry.name}`);
113
- }
114
- const raw = readFileSync(bodyPath, "utf-8");
115
- const { fm, body } = parseFrontmatter(raw, bodyPath);
116
- entries.push({ type: "agent", name: entry.name, frontmatter: fm, body, bodyPath });
117
- }
118
- }
119
- // Load skills
120
- if (existsSync(SKILLS_DIR)) {
121
- for (const entry of readdirSync(SKILLS_DIR, { withFileTypes: true })) {
122
- if (!entry.isDirectory())
123
- continue;
124
- if (opts?.only && entry.name !== opts.only)
125
- continue;
126
- const bodyPath = join(SKILLS_DIR, entry.name, "body.md");
127
- if (!existsSync(bodyPath)) {
128
- throw new Error(`[build-agents] Missing body.md for skill: ${entry.name}`);
129
- }
130
- const raw = readFileSync(bodyPath, "utf-8");
131
- const { fm, body } = parseFrontmatter(raw, bodyPath);
132
- entries.push({ type: "skill", name: entry.name, frontmatter: fm, body, bodyPath });
133
- }
134
- }
135
- return entries;
136
- }
137
- // ---------------------------------------------------------------------------
138
- // Stage 2: Load capability matrix
139
- // ---------------------------------------------------------------------------
140
- export function loadCapabilityMatrix() {
141
- if (!existsSync(CAPABILITY_MATRIX_PATH)) {
142
- throw new Error(`[build-agents] capability-matrix.yml not found at: ${CAPABILITY_MATRIX_PATH}`);
143
- }
144
- const raw = readFileSync(CAPABILITY_MATRIX_PATH, "utf-8");
145
- return parseYaml(raw);
146
- }
147
- // ---------------------------------------------------------------------------
148
- // Stage 3: Load invocations
149
- // ---------------------------------------------------------------------------
150
- export function loadInvocations() {
151
- if (!existsSync(TOOL_NAME_MAP_PATH)) {
152
- throw new Error(`[build-agents] tool-name-map.yml not found at: ${TOOL_NAME_MAP_PATH}`);
153
- }
154
- const raw = readFileSync(TOOL_NAME_MAP_PATH, "utf-8");
155
- const parsed = parseYaml(raw);
156
- if (!parsed.invocations) {
157
- throw new Error(`[build-agents] tool-name-map.yml missing 'invocations' section`);
158
- }
159
- return parsed.invocations;
160
- }
161
- // ---------------------------------------------------------------------------
162
- // Capability resolution helpers
163
- // ---------------------------------------------------------------------------
164
- /**
165
- * Collect all Claude disallowedTools for an agent based on its capabilities[].
166
- */
167
- export function resolveClaudeDisallowedTools(capabilities, capMatrix) {
168
- const tools = [];
169
- for (const cap of capabilities) {
170
- const entry = capMatrix.capabilities[cap];
171
- if (!entry) {
172
- throw new Error(`[build-agents] Unknown capability: ${cap}`);
173
- }
174
- if (entry.claude?.disallowedTools) {
175
- for (const t of entry.claude.disallowedTools) {
176
- if (!tools.includes(t))
177
- tools.push(t);
178
- }
179
- }
180
- }
181
- return tools;
182
- }
183
- /**
184
- * Collect merged OpenCode permission block for an agent.
185
- */
186
- export function resolveOpencodePermissions(capabilities, capMatrix) {
187
- const perms = {};
188
- for (const cap of capabilities) {
189
- const entry = capMatrix.capabilities[cap];
190
- if (!entry) {
191
- throw new Error(`[build-agents] Unknown capability: ${cap}`);
192
- }
193
- if (entry.opencode?.permission) {
194
- Object.assign(perms, entry.opencode.permission);
195
- }
196
- }
197
- return perms;
198
- }
199
- /**
200
- * Resolve codex sandbox_mode and disabled_tools for an agent.
201
- * sandbox_mode: take the most restrictive non-null value ("read-only" wins).
202
- */
203
- export function resolveCodexConfig(capabilities, capMatrix) {
204
- let sandboxMode = null;
205
- const disabledTools = [];
206
- for (const cap of capabilities) {
207
- const entry = capMatrix.capabilities[cap];
208
- if (!entry) {
209
- throw new Error(`[build-agents] Unknown capability: ${cap}`);
210
- }
211
- if (entry.codex?.sandbox_mode) {
212
- // "read-only" is the most restrictive
213
- sandboxMode = entry.codex.sandbox_mode;
214
- }
215
- if (entry.codex?.disabled_tools) {
216
- for (const t of entry.codex.disabled_tools) {
217
- if (t && !disabledTools.includes(t))
218
- disabledTools.push(t);
219
- }
220
- }
221
- }
222
- return { sandbox_mode: sandboxMode, disabled_tools: disabledTools };
223
- }
224
- /**
225
- * Resolve model slug for a given model_tier and harness.
226
- */
227
- export function resolveModel(modelTier, harness, capMatrix) {
228
- const tierEntry = capMatrix.model_tier[modelTier];
229
- if (!tierEntry)
230
- return null;
231
- const val = tierEntry[harness];
232
- return val === null || val === undefined ? null : val;
233
- }
234
- const CLAUDE_MODEL_ALIAS_RE = /^(opus|sonnet|haiku)$/;
235
- const CLAUDE_MODEL_DATED_RE = /^claude-(opus|sonnet|haiku)-\d+-\d+(-\d{8})?$/;
236
- /**
237
- * Validate a resolved model value for the claude harness.
238
- * Allowed: alias (opus|sonnet|haiku), dated ID (claude-opus-4-7 etc.), or null/undefined.
239
- * Throws on any other value.
240
- */
241
- export function validateClaudeModel(model, role) {
242
- if (model === null || model === undefined)
243
- return;
244
- if (CLAUDE_MODEL_ALIAS_RE.test(model))
245
- return;
246
- if (CLAUDE_MODEL_DATED_RE.test(model))
247
- return;
248
- throw new Error(`[build-agents] Invalid model value: "${model}" for role "${role}" on harness "claude". Allowed: alias(opus|sonnet|haiku) or dated ID.`);
249
- }
250
- // ---------------------------------------------------------------------------
251
- // Overwrite policy
252
- // ---------------------------------------------------------------------------
253
- /**
254
- * Write a file according to the managed/template overwrite policy.
255
- *
256
- * Managed: always overwrite (unless --dry-run)
257
- * Template: skip if exists (overwrite only with --force)
258
- * --dry-run: record path and intent, no write
259
- * --strict: error if Managed path has untracked git modifications
260
- */
261
- export function applyOverwritePolicy(filePath, content, isManaged, opts) {
262
- if (isManaged) {
263
- const record = {
264
- path: filePath,
265
- kind: "managed",
266
- willWrite: true,
267
- reason: "managed",
268
- };
269
- if (opts.dryRun) {
270
- dryRunRecords.push(record);
271
- return record;
272
- }
273
- if (opts.strict) {
274
- // managed 파일에 대해서만 git drift 검사 — template skip은 strict 대상 아님
275
- if (existsSync(filePath)) {
276
- try {
277
- const rel = filePath.startsWith(ROOT)
278
- ? filePath.slice(ROOT.length + 1)
279
- : filePath;
280
- const result = execSync(`git status --short -- ${JSON.stringify(rel)}`, {
281
- cwd: ROOT,
282
- encoding: "utf-8",
283
- stdio: ["pipe", "pipe", "pipe"],
284
- }).trim();
285
- if (result && !result.startsWith("?")) {
286
- throw new Error(`[build-agents] --strict: managed file has untracked modifications: ${filePath}`);
287
- }
288
- }
289
- catch (err) {
290
- if (String(err).includes("--strict:"))
291
- throw err;
292
- // git 미설치 또는 미추적 파일 — 허용
293
- }
294
- }
295
- }
296
- mkdirSync(dirname(filePath), { recursive: true });
297
- writeFileSync(filePath, content, "utf-8");
298
- return record;
299
- }
300
- else {
301
- // Template: skip if exists unless --force
302
- const exists = existsSync(filePath);
303
- let reason;
304
- let willWrite;
305
- if (exists && !opts.force) {
306
- reason = "template-skipped";
307
- willWrite = false;
308
- }
309
- else if (exists && opts.force) {
310
- reason = "template-force-overwrite";
311
- willWrite = true;
312
- }
313
- else {
314
- reason = "template-create";
315
- willWrite = true;
316
- }
317
- const record = { path: filePath, kind: "template", willWrite, reason };
318
- if (opts.dryRun) {
319
- dryRunRecords.push(record);
320
- return record;
321
- }
322
- if (!willWrite) {
323
- return record;
324
- }
325
- mkdirSync(dirname(filePath), { recursive: true });
326
- writeFileSync(filePath, content, "utf-8");
327
- return record;
328
- }
329
- }
330
- // ---------------------------------------------------------------------------
331
- // Harness: Claude
332
- // ---------------------------------------------------------------------------
333
- function claudeAgentMarkdown(asset, capMatrix, invocations) {
334
- const fm = asset.frontmatter;
335
- const disallowed = resolveClaudeDisallowedTools(fm.capabilities ?? [], capMatrix);
336
- const model = resolveModel(fm.model_tier, "claude", capMatrix);
337
- validateClaudeModel(model, asset.name);
338
- const fmLines = ["---"];
339
- if (fm.description)
340
- fmLines.push(`description: ${JSON.stringify(fm.description)}`);
341
- if (model)
342
- fmLines.push(`model: ${model}`);
343
- if (disallowed.length > 0) {
344
- fmLines.push(`disallowedTools:`);
345
- for (const t of disallowed) {
346
- fmLines.push(` - ${t}`);
347
- }
348
- }
349
- fmLines.push("---");
350
- fmLines.push("");
351
- const expandedBody = expandInvocations(asset.body, "claude", invocations);
352
- return fmLines.join("\n") + expandedBody;
353
- }
354
- function claudeSkillMarkdown(asset, invocations) {
355
- const fm = asset.frontmatter;
356
- const fmLines = ["---"];
357
- if (fm.description)
358
- fmLines.push(`description: ${JSON.stringify(fm.description)}`);
359
- if (fm.triggers && fm.triggers.length > 0) {
360
- fmLines.push(`triggers:`);
361
- for (const t of fm.triggers) {
362
- fmLines.push(` - ${t}`);
363
- }
364
- }
365
- fmLines.push("---");
366
- fmLines.push("");
367
- const expandedBody = expandInvocations(asset.body, "claude", invocations);
368
- return fmLines.join("\n") + expandedBody;
369
- }
370
- function buildPluginJson(agents) {
371
- return JSON.stringify({
372
- name: "claude-nexus",
373
- version: "0.13.0",
374
- description: "Nexus agent suite for Claude Code",
375
- agents: agents.map((a) => ({
376
- id: a.frontmatter.id,
377
- name: a.frontmatter.name,
378
- description: a.frontmatter.description,
379
- file: `agents/${a.name}.md`,
380
- })),
381
- }, null, 2) + "\n";
382
- }
383
- function buildMarketplaceJson(agents) {
384
- return JSON.stringify({
385
- schema_version: "1.0",
386
- agents: agents.map((a) => ({
387
- id: a.frontmatter.id,
388
- name: a.frontmatter.name,
389
- description: a.frontmatter.description,
390
- category: a.frontmatter.category,
391
- model_tier: a.frontmatter.model_tier,
392
- })),
393
- }, null, 2) + "\n";
394
- }
395
- export function buildForClaude(assets, capMatrix, invocations, opts) {
396
- const baseDir = opts.targetDir;
397
- const agentAssets = assets.filter((a) => a.type === "agent");
398
- const skillAssets = assets.filter((a) => a.type === "skill");
399
- // Template files: .claude-plugin/plugin.json and marketplace.json
400
- const pluginJsonPath = join(baseDir, ".claude-plugin", "plugin.json");
401
- const marketplacePath = join(baseDir, ".claude-plugin", "marketplace.json");
402
- applyOverwritePolicy(pluginJsonPath, buildPluginJson(agentAssets), false, opts);
403
- applyOverwritePolicy(marketplacePath, buildMarketplaceJson(agentAssets), false, opts);
404
- // Managed: agents/<n>.md
405
- for (const agent of agentAssets) {
406
- const outPath = join(baseDir, "agents", `${agent.name}.md`);
407
- const content = claudeAgentMarkdown(agent, capMatrix, invocations);
408
- applyOverwritePolicy(outPath, content, true, opts);
409
- }
410
- // Managed: skills/<n>/SKILL.md
411
- for (const skill of skillAssets) {
412
- const outPath = join(baseDir, "skills", skill.name, "SKILL.md");
413
- const content = claudeSkillMarkdown(skill, invocations);
414
- applyOverwritePolicy(outPath, content, true, opts);
415
- }
416
- // Managed: settings.json (primary agent injection)
417
- const primaryAgents = agentAssets.filter((a) => (a.frontmatter.mode ?? "subagent") === "primary");
418
- if (primaryAgents.length > 0) {
419
- if (primaryAgents.length > 1) {
420
- console.warn(`[build-agents] Warning: multiple primary agents found (${primaryAgents.map((a) => a.name).join(", ")}). Using first: ${primaryAgents[0].name}`);
421
- }
422
- const primaryAgent = primaryAgents[0];
423
- const settingsPath = join(baseDir, "settings.json");
424
- const settingsContent = JSON.stringify({ agent: primaryAgent.frontmatter.id }, null, 2) + "\n";
425
- applyOverwritePolicy(settingsPath, settingsContent, true, opts);
426
- }
427
- }
428
- // ---------------------------------------------------------------------------
429
- // Harness: OpenCode
430
- // ---------------------------------------------------------------------------
431
- /**
432
- * Generate OpenCode src/agents/<n>.ts content.
433
- * Uses template literal inline. Backtick and ${ are escaped via string concatenation.
434
- */
435
- function opencodeAgentTs(asset, capMatrix, invocations) {
436
- const fm = asset.frontmatter;
437
- const perms = resolveOpencodePermissions(fm.capabilities ?? [], capMatrix);
438
- const expandedBody = expandInvocations(asset.body, "opencode", invocations);
439
- // Build permission block
440
- const permEntries = Object.entries(perms);
441
- const permBlock = permEntries.length > 0
442
- ? ` permission: {\n${permEntries.map(([k, v]) => ` ${k}: "${v}",`).join("\n")}\n },`
443
- : "";
444
- // Escape content for embedding in a template literal
445
- // We use string concatenation to avoid issues with backtick and ${ in the template
446
- const escapedBody = expandedBody.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
447
- const escapedDesc = fm.description.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
448
- const lines = [
449
- `// Auto-generated by build-agents.ts — do not edit`,
450
- `// Source: assets/agents/${asset.name}/body.md`,
451
- `import type { AgentConfig } from "@moreih29/nexus-core/types";`,
452
- ``,
453
- `export const ${camelCase(asset.name)}: AgentConfig = {`,
454
- ` id: ${JSON.stringify(fm.id)},`,
455
- ` name: ${JSON.stringify(fm.name)},`,
456
- ` description: \`${escapedDesc}\`,`,
457
- ];
458
- if (permBlock)
459
- lines.push(permBlock);
460
- // Emit mode field only for primary agents (subagent is the OpenCode default)
461
- if (fm.mode === "primary") {
462
- lines.push(` mode: "primary",`);
463
- }
464
- lines.push(` system: \`${escapedBody}\`,`, `};`, ``);
465
- return lines.join("\n");
466
- }
467
- function opencodeIndexTs(agents) {
468
- const imports = agents
469
- .map((a) => `import { ${camelCase(a.name)} } from "./agents/${a.name}.js";`)
470
- .join("\n");
471
- const exports = `export const agents = [\n${agents.map((a) => ` ${camelCase(a.name)},`).join("\n")}\n];`;
472
- return [
473
- `// Auto-generated by build-agents.ts — do not edit`,
474
- ``,
475
- imports,
476
- ``,
477
- exports,
478
- ``,
479
- ].join("\n");
480
- }
481
- function opencodePackageJson(agents) {
482
- return (JSON.stringify({
483
- name: "opencode-nexus",
484
- version: "0.13.0",
485
- description: "Nexus agent suite for OpenCode",
486
- type: "module",
487
- main: "./src/plugin.ts",
488
- exports: {
489
- ".": "./src/plugin.ts",
490
- },
491
- peerDependencies: {
492
- opencode: "*",
493
- },
494
- dependencies: {
495
- "@moreih29/nexus-core": "^0.14.0",
496
- },
497
- devDependencies: {
498
- "@opencode-ai/plugin": "*",
499
- typescript: "^5",
500
- },
501
- engines: {
502
- node: ">=22",
503
- },
504
- }, null, 2) + "\n");
505
- }
506
- function opencodePluginTs() {
507
- return [
508
- `import type { Plugin } from "@opencode-ai/plugin";`,
509
- `import { mountHooks } from "@moreih29/nexus-core/hooks/opencode-mount";`,
510
- `import manifest from "@moreih29/nexus-core/hooks/opencode-manifest" with { type: "json" };`,
511
- ``,
512
- `export const OpencodeNexus: Plugin = async (ctx) => mountHooks(ctx, manifest);`,
513
- `export default OpencodeNexus;`,
514
- ``,
515
- ].join("\n");
516
- }
517
- function opencodeSkillMarkdown(asset, invocations) {
518
- const fm = asset.frontmatter;
519
- const fmLines = ["---"];
520
- if (fm.description)
521
- fmLines.push(`description: ${JSON.stringify(fm.description)}`);
522
- if (fm.triggers && fm.triggers.length > 0) {
523
- fmLines.push(`triggers:`);
524
- for (const t of fm.triggers) {
525
- fmLines.push(` - ${t}`);
526
- }
527
- }
528
- fmLines.push("---");
529
- fmLines.push("");
530
- const expandedBody = expandInvocations(asset.body, "opencode", invocations);
531
- return fmLines.join("\n") + expandedBody;
532
- }
533
- export function buildForOpencode(assets, capMatrix, invocations, opts) {
534
- const baseDir = opts.targetDir;
535
- const agentAssets = assets.filter((a) => a.type === "agent");
536
- const skillAssets = assets.filter((a) => a.type === "skill");
537
- // Template: package.json
538
- const pkgPath = join(baseDir, "package.json");
539
- applyOverwritePolicy(pkgPath, opencodePackageJson(agentAssets), false, opts);
540
- // Template: src/plugin.ts (mountHooks 진입점)
541
- const pluginTsPath = join(baseDir, "src", "plugin.ts");
542
- applyOverwritePolicy(pluginTsPath, opencodePluginTs(), false, opts);
543
- // Managed: src/index.ts
544
- const indexPath = join(baseDir, "src", "index.ts");
545
- applyOverwritePolicy(indexPath, opencodeIndexTs(agentAssets), true, opts);
546
- // Managed: src/agents/<n>.ts
547
- for (const agent of agentAssets) {
548
- const outPath = join(baseDir, "src", "agents", `${agent.name}.ts`);
549
- const content = opencodeAgentTs(agent, capMatrix, invocations);
550
- applyOverwritePolicy(outPath, content, true, opts);
551
- }
552
- // Managed: .opencode/skills/<n>/SKILL.md
553
- for (const skill of skillAssets) {
554
- const outPath = join(baseDir, ".opencode", "skills", skill.name, "SKILL.md");
555
- const content = opencodeSkillMarkdown(skill, invocations);
556
- applyOverwritePolicy(outPath, content, true, opts);
557
- }
558
- }
559
- // ---------------------------------------------------------------------------
560
- // Harness: Codex
561
- // ---------------------------------------------------------------------------
562
- /**
563
- * Escape a string for TOML multi-line literal string (''' ''').
564
- * Literal strings do not allow escapes, so we must not include '''.
565
- * Fallback: use basic multi-line string with minimal escaping.
566
- */
567
- function tomlMultilineString(value) {
568
- // Use basic multi-line string: """ ... """
569
- // Escape backslash and double-quote sequences
570
- const escaped = value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
571
- return `"""\n${escaped}\n"""`;
572
- }
573
- function codexAgentToml(asset, capMatrix, invocations) {
574
- const fm = asset.frontmatter;
575
- const { sandbox_mode, disabled_tools } = resolveCodexConfig(fm.capabilities ?? [], capMatrix);
576
- const model = resolveModel(fm.model_tier, "codex", capMatrix);
577
- const expandedBody = expandInvocations(asset.body, "codex", invocations);
578
- const lines = [
579
- `# Auto-generated by build-agents.ts — do not edit`,
580
- `# Source: assets/agents/${asset.name}/body.md`,
581
- ``,
582
- `name = ${JSON.stringify(fm.id)}`,
583
- `description = ${JSON.stringify(fm.description)}`,
584
- `developer_instructions = ${tomlMultilineString(expandedBody)}`,
585
- ];
586
- if (model)
587
- lines.push(`model = ${JSON.stringify(model)}`);
588
- if (sandbox_mode)
589
- lines.push(`sandbox_mode = ${JSON.stringify(sandbox_mode)}`);
590
- if (disabled_tools.length > 0) {
591
- lines.push(``);
592
- lines.push(`[mcp_servers.nx]`);
593
- lines.push(`command = ${JSON.stringify(CODEX_MCP_NX_COMMAND)}`);
594
- lines.push(`disabled_tools = [${disabled_tools.map((t) => JSON.stringify(t)).join(", ")}]`);
595
- }
596
- lines.push(``);
597
- return lines.join("\n");
598
- }
599
- function codexPromptMarkdown(asset, invocations) {
600
- const expandedBody = expandInvocations(asset.body, "codex", invocations);
601
- const fm = asset.frontmatter;
602
- return [
603
- `---`,
604
- `name: ${JSON.stringify(fm.name)}`,
605
- `description: ${JSON.stringify(fm.description)}`,
606
- `---`,
607
- ``,
608
- expandedBody,
609
- ].join("\n");
610
- }
611
- function codexSkillMarkdown(asset, invocations) {
612
- const fm = asset.frontmatter;
613
- const fmLines = ["---"];
614
- if (fm.description)
615
- fmLines.push(`description: ${JSON.stringify(fm.description)}`);
616
- if (fm.triggers && fm.triggers.length > 0) {
617
- fmLines.push(`triggers:`);
618
- for (const t of fm.triggers) {
619
- fmLines.push(` - ${t}`);
620
- }
621
- }
622
- fmLines.push("---");
623
- fmLines.push("");
624
- const expandedBody = expandInvocations(asset.body, "codex", invocations);
625
- return fmLines.join("\n") + expandedBody;
626
- }
627
- function codexPluginJson(agents) {
628
- return (JSON.stringify({
629
- name: "codex-nexus",
630
- version: "0.13.0",
631
- description: "Nexus agent suite for Codex",
632
- agents: agents.map((a) => ({
633
- id: a.frontmatter.id,
634
- config: `agents/${a.name}.toml`,
635
- prompt: `prompts/${a.name}.md`,
636
- })),
637
- }, null, 2) + "\n");
638
- }
639
- function codexConfigFragment(agents) {
640
- const lines = [
641
- `# Auto-generated by build-agents.ts — do not edit`,
642
- `# Merge this fragment into your codex config.toml`,
643
- ``,
644
- `[mcp_servers.nx]`,
645
- `command = ${JSON.stringify(CODEX_MCP_NX_COMMAND)}`,
646
- ``,
647
- ];
648
- return lines.join("\n");
649
- }
650
- function codexPackageJson() {
651
- return (JSON.stringify({
652
- name: "codex-nexus",
653
- version: "0.13.0",
654
- description: "Nexus agent suite for Codex CLI",
655
- private: true,
656
- scripts: {
657
- sync: "bunx @moreih29/nexus-core sync --harness=codex --target=./",
658
- "sync:dry": "bunx @moreih29/nexus-core sync --harness=codex --target=./ --dry-run",
659
- build: "bun run sync",
660
- validate: "bunx @moreih29/nexus-core validate",
661
- list: "bunx @moreih29/nexus-core list",
662
- "install-plugin": "bash install/install.sh",
663
- },
664
- devDependencies: {
665
- "@moreih29/nexus-core": "^0.14.0",
666
- },
667
- engines: {
668
- node: ">=22",
669
- },
670
- }, null, 2) + "\n");
671
- }
672
- function codexInstallSh() {
673
- return [
674
- `#!/usr/bin/env bash`,
675
- `# Codex plugin installer — block-marker merge pattern.`,
676
- `# nexus-core Model 2: wrapper owns integration seams.`,
677
- `# Merges config.fragment.toml into ~/.codex/config.toml,`,
678
- `# copies native agent TOMLs to ~/.codex/agents/,`,
679
- `# and merges AGENTS.fragment.md into ~/.codex/AGENTS.md.`,
680
- `set -euo pipefail`,
681
- ``,
682
- `PLUGIN_NAME="\${PLUGIN_NAME:-codex-nexus}"`,
683
- `CODEX_HOME="\${CODEX_HOME:-\$HOME/.codex}"`,
684
- `SCRIPT_DIR="\$(cd "\$(dirname "\${BASH_SOURCE[0]}")" && pwd)"`,
685
- `REPO_ROOT="\$(cd "\$SCRIPT_DIR/.." && pwd)"`,
686
- ``,
687
- `mkdir -p "\$CODEX_HOME" "\$CODEX_HOME/agents" "\$CODEX_HOME/plugins"`,
688
- ``,
689
- `# 1. config.toml — block-marker merge`,
690
- `MARKER_BEGIN="# BEGIN \${PLUGIN_NAME}"`,
691
- `MARKER_END="# END \${PLUGIN_NAME}"`,
692
- `CONFIG="\$CODEX_HOME/config.toml"`,
693
- `CONFIG_FRAGMENT="\$SCRIPT_DIR/config.fragment.toml"`,
694
- ``,
695
- `touch "\$CONFIG"`,
696
- `if grep -q "\${MARKER_BEGIN}" "\$CONFIG" 2>/dev/null; then`,
697
- ` sed -i.bak "/\${MARKER_BEGIN}/,/\${MARKER_END}/d" "\$CONFIG"`,
698
- `fi`,
699
- `{`,
700
- ` echo ""`,
701
- ` echo "\${MARKER_BEGIN}"`,
702
- ` cat "\$CONFIG_FRAGMENT"`,
703
- ` echo "\${MARKER_END}"`,
704
- `} >> "\$CONFIG"`,
705
- ``,
706
- `# 2. native agent TOMLs`,
707
- `cp "\$REPO_ROOT"/agents/*.toml "\$CODEX_HOME/agents/" 2>/dev/null || true`,
708
- ``,
709
- `# 3. plugin body → ~/.codex/plugins/<name>/`,
710
- `PLUGIN_DEST="\$CODEX_HOME/plugins/\${PLUGIN_NAME}"`,
711
- `rm -rf "\$PLUGIN_DEST"`,
712
- `mkdir -p "\$PLUGIN_DEST"`,
713
- `cp -R "\$REPO_ROOT"/plugin/. "\$PLUGIN_DEST/"`,
714
- ``,
715
- `# 4. AGENTS.md — block-marker merge`,
716
- `AGENTS_TARGET="\$CODEX_HOME/AGENTS.md"`,
717
- `AGENTS_FRAGMENT="\$SCRIPT_DIR/AGENTS.fragment.md"`,
718
- `FRAG_BEGIN="<!-- nexus-core:lead:start -->"`,
719
- `FRAG_END="<!-- nexus-core:lead:end -->"`,
720
- ``,
721
- `if [ -f "\$AGENTS_FRAGMENT" ]; then`,
722
- ` touch "\$AGENTS_TARGET"`,
723
- ` if grep -q "\${FRAG_BEGIN}" "\$AGENTS_TARGET" 2>/dev/null; then`,
724
- ` awk -v begin="\${FRAG_BEGIN}" -v end="\${FRAG_END}" '`,
725
- ` \$0 ~ begin { skip=1; next }`,
726
- ` \$0 ~ end { skip=0; next }`,
727
- ` !skip { print }`,
728
- ` ' "\$AGENTS_TARGET" > "\$AGENTS_TARGET.tmp" && mv "\$AGENTS_TARGET.tmp" "\$AGENTS_TARGET"`,
729
- ` fi`,
730
- ` cat "\$AGENTS_FRAGMENT" >> "\$AGENTS_TARGET"`,
731
- `fi`,
732
- ``,
733
- `echo "Installed \${PLUGIN_NAME} → \$CODEX_HOME"`,
734
- ``,
735
- ].join("\n");
736
- }
737
- export function buildForCodex(assets, capMatrix, invocations, opts) {
738
- const baseDir = opts.targetDir;
739
- const agentAssets = assets.filter((a) => a.type === "agent");
740
- const skillAssets = assets.filter((a) => a.type === "skill");
741
- // Template: package.json (wrapper meta)
742
- const pkgPath = join(baseDir, "package.json");
743
- applyOverwritePolicy(pkgPath, codexPackageJson(), false, opts);
744
- // Template: install/install.sh (block-marker merge installer)
745
- const installShPath = join(baseDir, "install", "install.sh");
746
- applyOverwritePolicy(installShPath, codexInstallSh(), false, opts);
747
- // Managed: plugin/.codex-plugin/plugin.json
748
- const pluginJsonPath = join(baseDir, "plugin", ".codex-plugin", "plugin.json");
749
- applyOverwritePolicy(pluginJsonPath, codexPluginJson(agentAssets), true, opts);
750
- // Managed: plugin/skills/<n>/SKILL.md
751
- for (const skill of skillAssets) {
752
- const outPath = join(baseDir, "plugin", "skills", skill.name, "SKILL.md");
753
- const content = codexSkillMarkdown(skill, invocations);
754
- applyOverwritePolicy(outPath, content, true, opts);
755
- }
756
- // Managed: agents/<n>.toml
757
- for (const agent of agentAssets) {
758
- const outPath = join(baseDir, "agents", `${agent.name}.toml`);
759
- const content = codexAgentToml(agent, capMatrix, invocations);
760
- applyOverwritePolicy(outPath, content, true, opts);
761
- }
762
- // Managed: prompts/<n>.md
763
- for (const agent of agentAssets) {
764
- const outPath = join(baseDir, "prompts", `${agent.name}.md`);
765
- const content = codexPromptMarkdown(agent, invocations);
766
- applyOverwritePolicy(outPath, content, true, opts);
767
- }
768
- // Managed: install/config.fragment.toml
769
- const fragmentPath = join(baseDir, "install", "config.fragment.toml");
770
- applyOverwritePolicy(fragmentPath, codexConfigFragment(agentAssets), true, opts);
771
- // Managed: install/AGENTS.fragment.md (primary agents only)
772
- const primaryAgents = agentAssets.filter((a) => (a.frontmatter.mode ?? "subagent") === "primary");
773
- if (primaryAgents.length > 0) {
774
- const agentsFragmentPath = join(baseDir, "install", "AGENTS.fragment.md");
775
- const blocks = primaryAgents.map((agent) => {
776
- const expandedBody = expandInvocations(agent.body, "codex", invocations);
777
- return [
778
- `<!-- nexus-core:${agent.frontmatter.id}:start -->`,
779
- `# ${agent.frontmatter.name}`,
780
- ``,
781
- expandedBody,
782
- `<!-- nexus-core:${agent.frontmatter.id}:end -->`,
783
- ].join("\n");
784
- });
785
- const agentsFragmentContent = blocks.join("\n\n") + "\n";
786
- applyOverwritePolicy(agentsFragmentPath, agentsFragmentContent, true, opts);
787
- }
788
- }
789
- // ---------------------------------------------------------------------------
790
- // Utilities
791
- // ---------------------------------------------------------------------------
792
- function camelCase(str) {
793
- return str.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
794
- }
795
- // ---------------------------------------------------------------------------
796
- // CLI arg parsing
797
- // ---------------------------------------------------------------------------
798
- export function parseArgs(argv) {
799
- const args = argv.slice(2); // remove node and script path
800
- let harnesses = [...HARNESSES];
801
- let targetDir = join(ROOT, "dist");
802
- let dryRun = false;
803
- let force = false;
804
- let strict = false;
805
- let only;
806
- for (const arg of args) {
807
- if (arg.startsWith("--harness=")) {
808
- const val = arg.slice("--harness=".length);
809
- if (!HARNESSES.includes(val)) {
810
- throw new Error(`[build-agents] Unknown harness: ${val}. Valid: ${HARNESSES.join(", ")}`);
811
- }
812
- harnesses = [val];
813
- }
814
- else if (arg.startsWith("--target=")) {
815
- targetDir = resolve(arg.slice("--target=".length));
816
- }
817
- else if (arg === "--dry-run") {
818
- dryRun = true;
819
- }
820
- else if (arg === "--force") {
821
- force = true;
822
- }
823
- else if (arg === "--strict") {
824
- strict = true;
825
- }
826
- else if (arg.startsWith("--only=")) {
827
- only = arg.slice("--only=".length);
828
- }
829
- }
830
- return { harnesses, targetDir, dryRun, force, strict, only };
831
- }
832
- // ---------------------------------------------------------------------------
833
- // Main
834
- // ---------------------------------------------------------------------------
835
- export async function buildAgents(opts) {
836
- // Stage 1: Load assets
837
- const assets = loadAssets({ only: opts.only });
838
- const agentCount = assets.filter((a) => a.type === "agent").length;
839
- const skillCount = assets.filter((a) => a.type === "skill").length;
840
- console.log(`[build-agents] Loaded ${agentCount} agents, ${skillCount} skills`);
841
- // Stage 2: Load capability matrix
842
- const capMatrix = loadCapabilityMatrix();
843
- // Validate all capability IDs referenced by assets
844
- const knownCapIds = new Set(Object.keys(capMatrix.capabilities));
845
- for (const asset of assets) {
846
- for (const cap of asset.frontmatter.capabilities ?? []) {
847
- if (!knownCapIds.has(cap)) {
848
- throw new Error(`[build-agents] "${asset.name}" references unknown capability: "${cap}". ` +
849
- `Known: ${[...knownCapIds].join(", ")}`);
850
- }
851
- }
852
- }
853
- // Stage 3: Load invocations
854
- const invocations = loadInvocations();
855
- // Stage 4: Build per harness
856
- if (opts.dryRun) {
857
- console.log(`[build-agents] --dry-run mode: listing affected files only`);
858
- }
859
- for (const harness of opts.harnesses) {
860
- console.log(`[build-agents] Building for harness: ${harness}`);
861
- if (harness === "claude") {
862
- buildForClaude(assets, capMatrix, invocations, opts);
863
- }
864
- else if (harness === "opencode") {
865
- buildForOpencode(assets, capMatrix, invocations, opts);
866
- }
867
- else if (harness === "codex") {
868
- buildForCodex(assets, capMatrix, invocations, opts);
869
- }
870
- }
871
- if (opts.dryRun) {
872
- const managed = dryRunRecords.filter((r) => r.reason === "managed").length;
873
- const templateCreate = dryRunRecords.filter((r) => r.reason === "template-create").length;
874
- const templateSkipped = dryRunRecords.filter((r) => r.reason === "template-skipped").length;
875
- const templateForce = dryRunRecords.filter((r) => r.reason === "template-force-overwrite").length;
876
- console.log(`[build-agents] ${managed} managed, ${templateCreate} template-create, ${templateSkipped} template-skipped, ${templateForce} template-force-overwrite`);
877
- for (const r of dryRunRecords) {
878
- if (r.kind === "managed") {
879
- console.log(` [M] ${r.path}`);
880
- }
881
- else if (r.reason === "template-skipped") {
882
- console.log(` [T]{skip} ${r.path}`);
883
- }
884
- else if (r.reason === "template-force-overwrite") {
885
- console.log(` [T]{force} ${r.path}`);
886
- }
887
- else {
888
- console.log(` [T] ${r.path}`);
889
- }
890
- }
891
- // 다음 호출을 위해 초기화
892
- dryRunRecords.length = 0;
893
- return;
894
- }
895
- console.log(`[build-agents] Done`);
896
- }
897
- // Run when executed directly
898
- if (import.meta.url === `file://${process.argv[1]}` ||
899
- process.argv[1]?.endsWith("build-agents.ts") ||
900
- process.argv[1]?.endsWith("build-agents.js")) {
901
- const opts = parseArgs(process.argv);
902
- buildAgents(opts).catch((err) => {
903
- process.stderr.write(`[build-agents] FATAL: ${String(err)}\n`);
904
- process.exit(1);
905
- });
906
- }
907
- //# sourceMappingURL=build-agents.js.map