specrails-core 5.6.0 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (275) hide show
  1. package/README.md +27 -145
  2. package/bin/specrails-core.mjs +12 -554
  3. package/dist/agent-runtime/capabilities.js +0 -1
  4. package/dist/agent-runtime/cli-executor.d.ts +1 -1
  5. package/dist/agent-runtime/cli-executor.js +1 -2
  6. package/dist/agent-runtime/cli-process.js +0 -1
  7. package/dist/agent-runtime/cli.js +3 -4
  8. package/dist/agent-runtime/codex-schema.js +0 -1
  9. package/dist/agent-runtime/compact/architect.d.ts +3 -272
  10. package/dist/agent-runtime/compact/architect.js +8 -9
  11. package/dist/agent-runtime/compact/chat-client.d.ts +3 -3
  12. package/dist/agent-runtime/compact/chat-client.js +1 -2
  13. package/dist/agent-runtime/compact/developer.d.ts +3 -70
  14. package/dist/agent-runtime/compact/developer.js +13 -14
  15. package/dist/agent-runtime/compact/environment.d.ts +4 -5
  16. package/dist/agent-runtime/compact/environment.js +1 -2
  17. package/dist/agent-runtime/compact/exit-code-honesty.d.ts +2 -1
  18. package/dist/agent-runtime/compact/exit-code-honesty.js +0 -1
  19. package/dist/agent-runtime/compact/guarded-loop.d.ts +2 -18
  20. package/dist/agent-runtime/compact/guarded-loop.js +7 -8
  21. package/dist/agent-runtime/compact/prompt-inputs.d.ts +0 -2
  22. package/dist/agent-runtime/compact/prompt-inputs.js +1 -2
  23. package/dist/agent-runtime/compact/reviewer.d.ts +0 -13
  24. package/dist/agent-runtime/compact/reviewer.js +5 -6
  25. package/dist/agent-runtime/compact/step.d.ts +0 -1
  26. package/dist/agent-runtime/compact/step.js +1 -2
  27. package/dist/agent-runtime/compact/test-reachability.js +0 -1
  28. package/dist/agent-runtime/config.js +0 -1
  29. package/dist/agent-runtime/core-host.d.ts +1 -1
  30. package/dist/agent-runtime/core-host.js +1 -2
  31. package/dist/agent-runtime/durable-store.d.ts +0 -1
  32. package/dist/agent-runtime/durable-store.js +1 -2
  33. package/dist/agent-runtime/efficiency-summary.d.ts +2 -2
  34. package/dist/agent-runtime/efficiency-summary.js +1 -2
  35. package/dist/agent-runtime/efficiency-types.js +0 -1
  36. package/dist/agent-runtime/efficiency.js +0 -1
  37. package/dist/agent-runtime/evaluation-corpus.js +0 -1
  38. package/dist/agent-runtime/evaluation.d.ts +2 -1
  39. package/dist/agent-runtime/evaluation.js +1 -2
  40. package/dist/agent-runtime/executor-types.d.ts +1 -1
  41. package/dist/agent-runtime/executor-types.js +0 -1
  42. package/dist/agent-runtime/executors.js +0 -1
  43. package/dist/agent-runtime/gemini-policy.js +0 -1
  44. package/dist/agent-runtime/graph/artifacts.d.ts +1 -1
  45. package/dist/agent-runtime/graph/artifacts.js +1 -2
  46. package/dist/agent-runtime/graph/nodes.d.ts +1 -1
  47. package/dist/agent-runtime/graph/nodes.js +1 -2
  48. package/dist/agent-runtime/graph/review-policy.js +0 -1
  49. package/dist/agent-runtime/graph/roles.d.ts +2 -5
  50. package/dist/agent-runtime/graph/roles.js +2 -8
  51. package/dist/agent-runtime/graph/state.d.ts +1 -1
  52. package/dist/agent-runtime/graph/state.js +0 -1
  53. package/dist/agent-runtime/graph-checkpointer.d.ts +2 -1
  54. package/dist/agent-runtime/graph-checkpointer.js +0 -1
  55. package/dist/agent-runtime/guardrails.d.ts +3 -3
  56. package/dist/agent-runtime/guardrails.js +1 -2
  57. package/dist/agent-runtime/index.d.ts +1 -1
  58. package/dist/agent-runtime/index.js +1 -2
  59. package/dist/agent-runtime/kimi-acp.js +1 -2
  60. package/dist/agent-runtime/kimi-model.d.ts +6 -0
  61. package/dist/agent-runtime/kimi-model.js +12 -0
  62. package/dist/agent-runtime/openai-executor.d.ts +0 -9
  63. package/dist/agent-runtime/openai-executor.js +6 -7
  64. package/dist/agent-runtime/openspec-tool-server.js +1 -2
  65. package/dist/agent-runtime/openspec.d.ts +0 -2
  66. package/dist/agent-runtime/openspec.js +1 -6
  67. package/dist/agent-runtime/prompts.d.ts +4 -3
  68. package/dist/agent-runtime/prompts.js +0 -1
  69. package/dist/agent-runtime/provider-diagnostic.js +1 -2
  70. package/dist/agent-runtime/recovery.js +1 -2
  71. package/dist/agent-runtime/repository-context.d.ts +1 -1
  72. package/dist/agent-runtime/repository-context.js +0 -1
  73. package/dist/agent-runtime/review-context.d.ts +1 -1
  74. package/dist/agent-runtime/review-context.js +0 -1
  75. package/dist/agent-runtime/role-routing.js +0 -1
  76. package/dist/agent-runtime/role-state.js +0 -1
  77. package/dist/agent-runtime/runtime-identity.js +1 -2
  78. package/dist/agent-runtime/tool-event.js +0 -1
  79. package/dist/agent-runtime/verification-plan.d.ts +5 -4
  80. package/dist/agent-runtime/verification-plan.js +1 -2
  81. package/dist/agent-runtime/workflow-types.js +0 -1
  82. package/dist/agent-runtime/workflow.js +0 -1
  83. package/dist/agent-runtime/workspace-tools.d.ts +2 -2
  84. package/dist/agent-runtime/workspace-tools.js +1 -2
  85. package/dist/installer/cli.d.ts +3 -32
  86. package/dist/installer/cli.js +26 -101
  87. package/dist/installer/commands/framework.d.ts +4 -3
  88. package/dist/installer/commands/framework.js +0 -1
  89. package/dist/installer/commands/init.d.ts +4 -25
  90. package/dist/installer/commands/init.js +5 -8
  91. package/dist/installer/phases/framework-lifecycle.d.ts +3 -17
  92. package/dist/installer/phases/framework-lifecycle.js +2 -3
  93. package/dist/installer/phases/install-config.d.ts +7 -8
  94. package/dist/installer/phases/install-config.js +2 -7
  95. package/dist/installer/phases/manifest.d.ts +6 -7
  96. package/dist/installer/phases/manifest.js +2 -7
  97. package/dist/installer/phases/prereqs.d.ts +6 -7
  98. package/dist/installer/phases/prereqs.js +4 -6
  99. package/dist/installer/phases/provider-detect.d.ts +6 -7
  100. package/dist/installer/phases/provider-detect.js +2 -4
  101. package/dist/installer/phases/scaffold.d.ts +9 -10
  102. package/dist/installer/phases/scaffold.js +82 -805
  103. package/dist/installer/util/errors.js +0 -1
  104. package/dist/installer/util/exec.d.ts +3 -2
  105. package/dist/installer/util/exec.js +0 -1
  106. package/dist/installer/util/fs.d.ts +0 -10
  107. package/dist/installer/util/fs.js +1 -2
  108. package/dist/installer/util/git.js +0 -1
  109. package/dist/installer/util/install-transaction.d.ts +2 -2
  110. package/dist/installer/util/install-transaction.js +1 -2
  111. package/dist/installer/util/logger.d.ts +1 -3
  112. package/dist/installer/util/logger.js +0 -1
  113. package/dist/installer/util/paths.js +0 -1
  114. package/dist/installer/util/registry.d.ts +4 -8
  115. package/dist/installer/util/registry.js +2 -3
  116. package/dist/{installer/runtime → pipeline}/pipeline-state.js +0 -3
  117. package/dist/shared/args.d.ts +18 -0
  118. package/dist/shared/args.js +53 -0
  119. package/integration-contract.json +10 -46
  120. package/package.json +3 -10
  121. package/templates/agents/sr-architect.md +15 -310
  122. package/templates/agents/sr-developer.md +15 -269
  123. package/templates/agents/sr-reviewer.md +13 -367
  124. package/templates/codex-skills/rails/sr-architect/SKILL.md +14 -308
  125. package/templates/codex-skills/rails/sr-developer/SKILL.md +14 -201
  126. package/templates/codex-skills/rails/sr-reviewer/SKILL.md +15 -289
  127. package/templates/kimi/specrails/run-skill.mjs +91 -2173
  128. package/bin/tui-installer.mjs +0 -430
  129. package/commands/doctor.md +0 -62
  130. package/dist/agent-runtime/capabilities.js.map +0 -1
  131. package/dist/agent-runtime/cli-executor.js.map +0 -1
  132. package/dist/agent-runtime/cli-process.js.map +0 -1
  133. package/dist/agent-runtime/cli.js.map +0 -1
  134. package/dist/agent-runtime/codex-schema.js.map +0 -1
  135. package/dist/agent-runtime/compact/architect.js.map +0 -1
  136. package/dist/agent-runtime/compact/chat-client.js.map +0 -1
  137. package/dist/agent-runtime/compact/developer.js.map +0 -1
  138. package/dist/agent-runtime/compact/environment.js.map +0 -1
  139. package/dist/agent-runtime/compact/exit-code-honesty.js.map +0 -1
  140. package/dist/agent-runtime/compact/guarded-loop.js.map +0 -1
  141. package/dist/agent-runtime/compact/prompt-inputs.js.map +0 -1
  142. package/dist/agent-runtime/compact/reviewer.js.map +0 -1
  143. package/dist/agent-runtime/compact/step.js.map +0 -1
  144. package/dist/agent-runtime/compact/test-reachability.js.map +0 -1
  145. package/dist/agent-runtime/config.js.map +0 -1
  146. package/dist/agent-runtime/core-host.js.map +0 -1
  147. package/dist/agent-runtime/durable-store.js.map +0 -1
  148. package/dist/agent-runtime/efficiency-summary.js.map +0 -1
  149. package/dist/agent-runtime/efficiency-types.js.map +0 -1
  150. package/dist/agent-runtime/efficiency.js.map +0 -1
  151. package/dist/agent-runtime/evaluation-corpus.js.map +0 -1
  152. package/dist/agent-runtime/evaluation.js.map +0 -1
  153. package/dist/agent-runtime/executor-types.js.map +0 -1
  154. package/dist/agent-runtime/executors.js.map +0 -1
  155. package/dist/agent-runtime/gemini-policy.js.map +0 -1
  156. package/dist/agent-runtime/graph/artifacts.js.map +0 -1
  157. package/dist/agent-runtime/graph/nodes.js.map +0 -1
  158. package/dist/agent-runtime/graph/review-policy.js.map +0 -1
  159. package/dist/agent-runtime/graph/roles.js.map +0 -1
  160. package/dist/agent-runtime/graph/state.js.map +0 -1
  161. package/dist/agent-runtime/graph-checkpointer.js.map +0 -1
  162. package/dist/agent-runtime/guardrails.js.map +0 -1
  163. package/dist/agent-runtime/index.js.map +0 -1
  164. package/dist/agent-runtime/kimi-acp.js.map +0 -1
  165. package/dist/agent-runtime/openai-executor.js.map +0 -1
  166. package/dist/agent-runtime/openspec-tool-server.js.map +0 -1
  167. package/dist/agent-runtime/openspec.js.map +0 -1
  168. package/dist/agent-runtime/prompts.js.map +0 -1
  169. package/dist/agent-runtime/provider-diagnostic.js.map +0 -1
  170. package/dist/agent-runtime/recovery.js.map +0 -1
  171. package/dist/agent-runtime/repository-context.js.map +0 -1
  172. package/dist/agent-runtime/review-context.js.map +0 -1
  173. package/dist/agent-runtime/role-routing.js.map +0 -1
  174. package/dist/agent-runtime/role-state.js.map +0 -1
  175. package/dist/agent-runtime/runtime-identity.js.map +0 -1
  176. package/dist/agent-runtime/tool-event.js.map +0 -1
  177. package/dist/agent-runtime/verification-plan.js.map +0 -1
  178. package/dist/agent-runtime/workflow-types.js.map +0 -1
  179. package/dist/agent-runtime/workflow.js.map +0 -1
  180. package/dist/agent-runtime/workspace-tools.js.map +0 -1
  181. package/dist/installer/cli.js.map +0 -1
  182. package/dist/installer/commands/doctor.d.ts +0 -27
  183. package/dist/installer/commands/doctor.js +0 -615
  184. package/dist/installer/commands/doctor.js.map +0 -1
  185. package/dist/installer/commands/framework.js.map +0 -1
  186. package/dist/installer/commands/init.js.map +0 -1
  187. package/dist/installer/commands/update.d.ts +0 -56
  188. package/dist/installer/commands/update.js +0 -257
  189. package/dist/installer/commands/update.js.map +0 -1
  190. package/dist/installer/commands/v5-migration.d.ts +0 -32
  191. package/dist/installer/commands/v5-migration.js +0 -133
  192. package/dist/installer/commands/v5-migration.js.map +0 -1
  193. package/dist/installer/phases/framework-lifecycle.js.map +0 -1
  194. package/dist/installer/phases/install-config.js.map +0 -1
  195. package/dist/installer/phases/manifest.js.map +0 -1
  196. package/dist/installer/phases/prereqs.js.map +0 -1
  197. package/dist/installer/phases/provider-detect.js.map +0 -1
  198. package/dist/installer/phases/scaffold.js.map +0 -1
  199. package/dist/installer/runtime/kimi.d.ts +0 -84
  200. package/dist/installer/runtime/kimi.js +0 -255
  201. package/dist/installer/runtime/kimi.js.map +0 -1
  202. package/dist/installer/runtime/pipeline-state.js.map +0 -1
  203. package/dist/installer/util/errors.js.map +0 -1
  204. package/dist/installer/util/exec.js.map +0 -1
  205. package/dist/installer/util/fs.js.map +0 -1
  206. package/dist/installer/util/git.js.map +0 -1
  207. package/dist/installer/util/install-transaction.js.map +0 -1
  208. package/dist/installer/util/logger.js.map +0 -1
  209. package/dist/installer/util/paths.js.map +0 -1
  210. package/dist/installer/util/prompts.d.ts +0 -23
  211. package/dist/installer/util/prompts.js +0 -49
  212. package/dist/installer/util/prompts.js.map +0 -1
  213. package/dist/installer/util/registry.js.map +0 -1
  214. package/dist/installer/util/template.d.ts +0 -23
  215. package/dist/installer/util/template.js +0 -60
  216. package/dist/installer/util/template.js.map +0 -1
  217. package/docs/README.md +0 -40
  218. package/docs/agent-runtime-efficiency.md +0 -65
  219. package/docs/agent-runtime.md +0 -393
  220. package/docs/agents.md +0 -315
  221. package/docs/changelog.md +0 -168
  222. package/docs/ci-cd.md +0 -60
  223. package/docs/concepts.md +0 -183
  224. package/docs/customization.md +0 -363
  225. package/docs/deployment.md +0 -234
  226. package/docs/getting-started.md +0 -122
  227. package/docs/installation.md +0 -395
  228. package/docs/local-tickets.md +0 -191
  229. package/docs/migration-guide.md +0 -140
  230. package/docs/playbook-oss-maintainer.md +0 -112
  231. package/docs/playbook-parallel-dev.md +0 -124
  232. package/docs/playbook-product-discovery.md +0 -115
  233. package/docs/plugin-architecture.md +0 -144
  234. package/docs/research/codex-compatibility-analysis.md +0 -365
  235. package/docs/research/mcp-feasibility-analysis.md +0 -382
  236. package/docs/testing/test-matrix-codex.md +0 -130
  237. package/docs/updating.md +0 -89
  238. package/docs/user-docs/cli-reference.md +0 -428
  239. package/docs/user-docs/codex-vs-claude-code.md +0 -23
  240. package/docs/user-docs/core-updates.md +0 -70
  241. package/docs/user-docs/faq.md +0 -146
  242. package/docs/user-docs/getting-started-codex.md +0 -194
  243. package/docs/user-docs/getting-started-kimi.md +0 -423
  244. package/docs/user-docs/installation.md +0 -237
  245. package/docs/user-docs/provider-pipelines.md +0 -96
  246. package/docs/user-docs/quick-start.md +0 -161
  247. package/docs/windows.md +0 -78
  248. package/docs/workflows.md +0 -463
  249. package/schemas/profile.v1.json +0 -207
  250. package/templates/claude-md/CLAUDE-quickstart.md +0 -54
  251. package/templates/claude-md/root.md +0 -50
  252. package/templates/codex-skills/batch-implement/SKILL.md +0 -38
  253. package/templates/codex-skills/implement/SKILL.md +0 -38
  254. package/templates/codex-skills/retry/SKILL.md +0 -16
  255. package/templates/commands/specrails/compat-check.md +0 -271
  256. package/templates/commands/specrails/doctor.md +0 -62
  257. package/templates/commands/specrails/explore-spec.md +0 -173
  258. package/templates/commands/specrails/health-check.md +0 -527
  259. package/templates/commands/specrails/memory-inspect.md +0 -261
  260. package/templates/commands/specrails/opsx-diff.md +0 -419
  261. package/templates/commands/specrails/propose-spec.md +0 -102
  262. package/templates/commands/specrails/refactor-recommender.md +0 -169
  263. package/templates/commands/specrails/telemetry.md +0 -553
  264. package/templates/commands/specrails/why.md +0 -96
  265. package/templates/gemini-commands/batch-implement.toml +0 -37
  266. package/templates/gemini-commands/implement.toml +0 -37
  267. package/templates/gemini-commands/retry.toml +0 -15
  268. package/templates/profiles/default.json +0 -14
  269. package/templates/profiles/kimi-default.json +0 -15
  270. package/templates/rules/layer.md +0 -8
  271. package/templates/runtime/provider-pipeline.md +0 -113
  272. package/templates/security/security-exemptions.yaml +0 -20
  273. package/templates/settings/confidence-config.json +0 -17
  274. package/templates/settings/settings.json +0 -15
  275. /package/dist/{installer/runtime → pipeline}/pipeline-state.d.ts +0 -0
@@ -1,561 +1,19 @@
1
1
  #!/usr/bin/env node
2
- /**
3
- * specrails-core CLI — thin ESM dispatcher.
4
- *
5
- * All installer subcommands (init, update, doctor) execute
6
- * in-process via the Node installer under dist/installer/. This file
7
- * only keeps logic that is local to the dispatcher:
8
- * - `profile validate` / `profile show` — schema validation via ajv.
9
- * - `init` TUI short-circuit — spawns tui-installer.mjs
10
- * then re-enters init with
11
- * --from-config.
12
- *
13
- * Nothing in this file shells out to bash.
14
- */
15
-
16
- import { spawnSync } from 'node:child_process'
17
- import { existsSync, readFileSync } from 'node:fs'
18
- import { createRequire } from 'node:module'
2
+ // Thin npm bin entry: every command lives in dist/installer/cli.js.
3
+ import { existsSync } from 'node:fs'
19
4
  import path from 'node:path'
20
5
  import { fileURLToPath, pathToFileURL } from 'node:url'
21
6
 
22
- const __filename = fileURLToPath(import.meta.url)
23
- const __dirname = path.dirname(__filename)
24
- const ROOT = path.resolve(__dirname, '..')
25
- const require_ = createRequire(import.meta.url)
26
-
27
- const args = process.argv.slice(2)
28
- const subcommand = args[0]
29
-
30
- // ─── Global --version / -V flag ──────────────────────────────────────────────
31
-
32
- // Treat version as a GLOBAL flag only when it is the command itself. Offline
33
- // lifecycle commands also carry a required `--version <target>` option; scanning
34
- // the whole argv would intercept `swap-current --version 4.12.0` here and exit 0
35
- // without ever validating or moving the framework pointer.
36
- if (subcommand === '--version' || subcommand === '-V') {
37
- const pkg = require_(path.resolve(ROOT, 'package.json'))
38
- console.log(`specrails-core v${pkg.version}`)
39
- process.exit(0)
40
- }
41
-
42
- // ─── Usage screen (no subcommand) ────────────────────────────────────────────
43
-
44
- if (!subcommand) {
45
- printUsage()
46
- process.exit(0)
47
- }
48
-
49
- // ─── Removed-in-v5 subcommands (clear error, not a generic "unknown") ────────
50
-
51
- const REMOVED_SUBCOMMANDS = new Set(['enrich'])
52
-
53
- if (REMOVED_SUBCOMMANDS.has(subcommand)) {
54
- console.error(`${subcommand} was removed in v5 — init now installs everything directly.`)
55
- process.exit(1)
56
- }
57
-
58
- // ─── Subcommand allowlist (kept for backwards compatibility) ─────────────────
59
-
60
- const KNOWN_SUBCOMMANDS = new Set([
61
- 'init',
62
- 'update',
63
- 'doctor',
64
- 'pipeline',
65
- 'runtime',
66
- 'install-framework',
67
- 'swap-current',
68
- 'assemble',
69
- 'version',
70
- 'profile',
71
- 'help',
72
- ])
73
-
74
- if (!KNOWN_SUBCOMMANDS.has(subcommand)) {
75
- console.error(`Unknown command: ${subcommand}\n`)
76
- console.error(
77
- 'Available commands: init, update, doctor, install-framework, swap-current, assemble, version, profile, pipeline, help',
78
- )
79
- process.exit(1)
80
- }
81
-
82
- // ─── Removed-in-v5 flags (clear error) ───────────────────────────────────────
83
-
84
- if (args.includes('--quick') || args.includes('--lite')) {
85
- console.error('--quick was removed in v5 — init now installs everything directly.')
86
- process.exit(1)
87
- }
88
-
89
- const subargs = args.slice(1)
90
-
91
- // ─── help / version handled by the dispatcher ────────────────────────────────
92
-
93
- if (subcommand === 'help') {
94
- printUsage()
95
- process.exit(0)
96
- }
97
-
98
- if (subcommand === 'version') {
99
- const pkg = require_(path.resolve(ROOT, 'package.json'))
100
- console.log(`specrails-core v${pkg.version}`)
101
- process.exit(0)
102
- }
103
-
104
- // ─── profile validate / show ─────────────────────────────────────────────────
105
- // Pure Node logic; no installer touch.
106
-
107
- if (subcommand === 'profile') {
108
- await runProfile(subargs)
109
- process.exit(0)
110
- }
111
-
112
- // ─── init: optional TUI short-circuit ────────────────────────────────────────
113
- // Default flow runs the TUI to collect agent/model configuration and
114
- // write .specrails/install-config.yaml, then falls through to the Node
115
- // init command with --from-config. Skipped when --no-tui / --from-config
116
- // / --yes is passed.
117
-
118
- if (subcommand === 'init') {
119
- const hasNoTui =
120
- subargs.includes('--no-tui') ||
121
- subargs.includes('--no-direct') ||
122
- subargs.includes('--from-config')
123
- const autoYes = subargs.includes('--yes') || subargs.includes('-y')
124
- const useTui = !hasNoTui && !autoYes
125
-
126
- if (useTui) {
127
- const rootDirIdx = subargs.indexOf('--root-dir')
128
- const rootDir =
129
- rootDirIdx >= 0 && subargs[rootDirIdx + 1]
130
- ? path.resolve(subargs[rootDirIdx + 1])
131
- : process.cwd()
132
-
133
- // Forward --provider so the TUI can honour an explicit choice and
134
- // skip the interactive picker. Other flags stay with the Node CLI step.
135
- const providerIdx = subargs.indexOf('--provider')
136
- const providerVal = providerIdx >= 0 ? subargs[providerIdx + 1] : null
137
- const providerEqArg = subargs.find((a) => a.startsWith('--provider='))
138
- const tuiArgs = [path.resolve(ROOT, 'bin', 'tui-installer.mjs'), rootDir]
139
- if (providerVal) tuiArgs.push('--provider', providerVal)
140
- else if (providerEqArg) tuiArgs.push(providerEqArg)
141
- if (subargs.includes('--with-profiles')) tuiArgs.push('--with-profiles')
142
- const tuiResult = spawnSync('node', tuiArgs, {
143
- stdio: 'inherit',
144
- cwd: process.cwd(),
145
- shell: process.platform === 'win32',
146
- })
147
-
148
- if (tuiResult.error) {
149
- console.error(
150
- '\nFailed to launch TUI installer:',
151
- tuiResult.error.message,
152
- '\nRun: npm install or pass --no-tui to skip the TUI.\n',
153
- )
154
- process.exit(1)
155
- }
156
- if (tuiResult.status !== 0) {
157
- process.exit(tuiResult.status ?? 1)
158
- }
159
-
160
- // TUI succeeded — re-enter init with --from-config so the Node
161
- // command reads provider/agents from install-config.yaml.
162
- const nextArgs = subargs
163
- .filter((a) => a !== '--no-tui' && a !== '--no-direct')
164
- .concat(['--yes', '--from-config'])
165
- await runNodeCli(['init', ...nextArgs])
166
- // runNodeCli calls process.exit itself; the following line is
167
- // defensive.
168
- process.exit(0)
169
- }
170
-
171
- // Direct mode — strip internal --no-tui / --no-direct flags and go.
172
- const cleanArgs = subargs.filter((a) => a !== '--no-tui' && a !== '--no-direct')
173
- await runNodeCli(['init', ...cleanArgs])
174
- process.exit(0)
175
- }
176
-
177
- // ─── update / doctor — direct dispatch to Node CLI ───────────────────────────
178
-
179
- await runNodeCli([subcommand, ...subargs])
180
- process.exit(0)
181
-
182
- // ─────────────────────────────────────────────────────────────────────────────
183
- // Helpers
184
- // ─────────────────────────────────────────────────────────────────────────────
185
-
186
- function printUsage() {
187
- console.log(`specrails-core — Provider-independent AI agent workflow system
188
-
189
- Usage:
190
- specrails-core init [--root-dir <path>] [--yes|-y] [--no-tui] Install into a repository
191
- specrails-core update [--only <component>] [--dry-run] Update an existing installation
192
- specrails-core pipeline <init|status|phase|verify|archive-check|preview|apply-preview> [--context <path>]
193
- specrails-core doctor Run health checks
194
- specrails-core install-framework --framework-dir <path> --provider <value> --version <value>
195
- Materialize an offline framework version
196
- specrails-core swap-current --framework-dir <path> --version <value> [--providers <csv>]
197
- Validate and atomically expose a framework version
198
- specrails-core assemble --workspace <path> --framework-dir <path> Assemble a workspace from the framework
199
- specrails-core profile <validate|show> [<path>] Validate or pretty-print a profile JSON
200
- specrails-core version Show installed version
201
-
202
- Flags for init:
203
- --root-dir <path> Target repository path (default: current directory)
204
- --yes | -y Non-interactive; use defaults, skip TUI
205
- --provider <value> Force provider: claude, codex, gemini, or kimi
206
- --no-tui Skip TUI; use defaults / flags directly
207
- --from-config Skip TUI; use existing .specrails/install-config.yaml
208
-
209
- Global flags:
210
- --version | -V Show installed version
211
-
212
- More info: https://github.com/fjpulidop/specrails-core`)
213
- }
214
-
215
- function resolveEnrichOptions(cwd, argv, artifactRoot = cwd) {
216
- const workflowArgs = []
217
- let explicitProvider
218
- let model
219
- for (let index = 0; index < argv.length; index++) {
220
- const token = argv[index]
221
- if (token === '--provider' || token === '--model') {
222
- const value = argv[++index]
223
- if (!value) {
224
- console.error(`${token} requires a value`)
225
- process.exit(1)
226
- }
227
- if (token === '--provider') explicitProvider = value
228
- else model = value
229
- continue
230
- }
231
- if (token.startsWith('--provider=')) {
232
- explicitProvider = token.slice('--provider='.length)
233
- continue
234
- }
235
- if (token.startsWith('--model=')) {
236
- model = token.slice('--model='.length)
237
- continue
238
- }
239
- workflowArgs.push(token)
240
- }
241
-
242
- const supported = new Set(['claude', 'codex', 'gemini', 'kimi'])
243
- if (explicitProvider && !supported.has(explicitProvider)) {
244
- console.error(
245
- `Unsupported provider "${explicitProvider}". Expected claude, codex, gemini, or kimi.`,
246
- )
247
- process.exit(1)
248
- }
249
-
250
- let provider = explicitProvider
251
- if (!provider) {
252
- for (const root of [cwd, artifactRoot]) {
253
- const manifestPath = path.join(
254
- root,
255
- '.specrails',
256
- 'specrails-manifest.json',
257
- )
258
- if (existsSync(manifestPath)) {
259
- try {
260
- const manifest = JSON.parse(readFileSync(manifestPath, 'utf8'))
261
- if (supported.has(manifest.primary_provider)) {
262
- provider = manifest.primary_provider
263
- break
264
- }
265
- } catch {
266
- // A malformed manifest is diagnosed by `specrails-core doctor`;
267
- // enrich continues to config/directory fallback.
268
- }
269
- }
270
- }
271
- }
272
- if (!provider) {
273
- for (const root of [cwd, artifactRoot]) {
274
- const configPath = path.join(root, '.specrails', 'install-config.yaml')
275
- if (!existsSync(configPath)) continue
276
- const match = readFileSync(configPath, 'utf8').match(
277
- /^provider:\s*(claude|codex|gemini|kimi)\s*$/m,
278
- )
279
- if (match) {
280
- provider = match[1]
281
- break
282
- }
283
- }
284
- }
285
- if (!provider) {
286
- provider =
287
- ['claude', 'codex', 'gemini', 'kimi'].find((candidate) =>
288
- existsSync(
289
- path.join(
290
- artifactRoot,
291
- candidate === 'kimi' ? '.kimi-code' : `.${candidate}`,
292
- ),
293
- ),
294
- ) ?? 'claude'
295
- }
296
- return { provider, model, workflowArgs }
297
- }
298
-
299
- async function resolveEnrichWorkspace(cwd) {
300
- const registryModulePath = path.resolve(
301
- ROOT,
302
- 'dist',
303
- 'installer',
304
- 'util',
305
- 'registry.js',
306
- )
307
- if (!existsSync(registryModulePath)) {
308
- return { artifactRoot: cwd, codeRoot: cwd }
309
- }
310
- try {
311
- const registry = await import(pathToFileURL(registryModulePath).href)
312
- const resolution = registry.resolveArtifacts(cwd, { allocate: false })
313
- return {
314
- artifactRoot: path.resolve(resolution.artifactRoot),
315
- codeRoot: path.resolve(resolution.codeRoot),
316
- }
317
- } catch {
318
- // Doctor reports malformed registry state. Enrich retains the legacy
319
- // in-repository fallback instead of guessing another relocated workspace.
320
- return { artifactRoot: cwd, codeRoot: cwd }
321
- }
322
- }
323
-
324
- function resolveConfiguredEnrichModel(codeRoot, artifactRoot) {
325
- const activeProfile = process.env.SPECRAILS_PROFILE_PATH
326
- if (activeProfile) {
327
- const activePath = path.isAbsolute(activeProfile)
328
- ? activeProfile
329
- : path.resolve(codeRoot, activeProfile)
330
- const activeModel = readProfileOrchestratorModel(activePath)
331
- if (activeModel) return activeModel
332
- }
333
- const configCandidates = [
334
- path.join(codeRoot, '.specrails', 'install-config.yaml'),
335
- path.join(artifactRoot, '.specrails', 'install-config.yaml'),
336
- ]
337
- for (const configPath of configCandidates) {
338
- if (!existsSync(configPath)) continue
339
- try {
340
- const config = require_('js-yaml').load(readFileSync(configPath, 'utf8'))
341
- const configured = config?.models?.defaults?.model
342
- if (typeof configured === 'string' && configured.trim() !== '') {
343
- return configured.trim()
344
- }
345
- } catch {
346
- // The installer/doctor owns full config diagnostics. Continue to a
347
- // provider profile rather than extracting a value from malformed YAML.
348
- }
349
- }
350
- const profileCandidates = [
351
- path.join(artifactRoot, '.specrails', 'profiles', 'kimi-default.json'),
352
- path.join(codeRoot, '.specrails', 'profiles', 'kimi-default.json'),
353
- ]
354
- for (const profilePath of profileCandidates) {
355
- const configured = readProfileOrchestratorModel(profilePath)
356
- if (configured) return configured
357
- }
358
- return null
359
- }
360
-
361
- function readProfileOrchestratorModel(profilePath) {
362
- if (!existsSync(profilePath)) return null
363
- try {
364
- const profile = JSON.parse(readFileSync(profilePath, 'utf8'))
365
- const configured = profile?.orchestrator?.model
366
- return typeof configured === 'string' && configured.trim() !== ''
367
- ? configured.trim()
368
- : null
369
- } catch {
370
- // Profile validation provides the actionable error. Fall through.
371
- return null
372
- }
373
- }
374
-
375
- function serializeWorkflowArgs(argv) {
376
- return argv
377
- .map((value) =>
378
- value === '' || /\s|["']/u.test(value) ? JSON.stringify(value) : value,
379
- )
380
- .join(' ')
381
- }
382
-
383
- /**
384
- * Loads the compiled Node CLI (dist/installer/cli.js) and invokes its
385
- * `main` function with the given argv array. Propagates the returned
386
- * exit code via process.exit.
387
- */
388
- async function runNodeCli(argv) {
389
- const cliPath = path.resolve(ROOT, 'dist', 'installer', 'cli.js')
390
- if (!existsSync(cliPath)) {
391
- console.error(
392
- `Installer runtime not found at ${cliPath}. ` +
393
- `If you are running from a source checkout, run: npm run build`,
394
- )
395
- process.exit(1)
396
- }
397
- const mod = await import(pathToFileURL(cliPath).href)
398
- if (typeof mod.main !== 'function') {
399
- console.error('Installer runtime is missing the expected main() export — corrupt install?')
400
- process.exit(1)
401
- }
402
- const code = await mod.main(argv)
403
- // Let pipe writes drain before exiting; runtime status can exceed a pipe buffer.
404
- await Promise.all([process.stdout, process.stderr].map(stream =>
405
- new Promise((resolve, reject) => stream.write('', error => error ? reject(error) : resolve()))
406
- ))
407
- process.exit(code)
408
- }
409
-
410
- async function runProfile(subargs) {
411
- const action = subargs[0]
412
- const pathArg = subargs[1]
413
- if (!action || (action !== 'validate' && action !== 'show')) {
414
- console.error('Usage: specrails-core profile validate [<path>]')
415
- console.error(' specrails-core profile show [<path>]')
416
- process.exit(1)
417
- }
418
-
419
- const workspace = await resolveEnrichWorkspace(process.cwd())
420
- const resolveProfilePath = () => {
421
- if (pathArg) return path.resolve(pathArg)
422
- if (process.env.SPECRAILS_PROFILE_PATH) return path.resolve(process.env.SPECRAILS_PROFILE_PATH)
423
- const configRoots = [workspace.codeRoot, workspace.artifactRoot]
424
- let provider
425
- for (const root of configRoots) {
426
- const configPath = path.join(root, '.specrails', 'install-config.yaml')
427
- if (!existsSync(configPath)) continue
428
- const match = readFileSync(configPath, 'utf8').match(
429
- /^provider:\s*(claude|codex|gemini|kimi)\s*$/m,
430
- )
431
- if (match) {
432
- provider = match[1]
433
- break
434
- }
435
- }
436
- const names =
437
- provider === 'kimi'
438
- ? ['kimi-default.json', 'project-default.json']
439
- : ['project-default.json', 'kimi-default.json']
440
- for (const root of [workspace.artifactRoot, workspace.codeRoot]) {
441
- for (const name of names) {
442
- const candidate = path.join(root, '.specrails', 'profiles', name)
443
- if (existsSync(candidate)) return candidate
444
- }
445
- }
446
- return null
447
- }
448
-
449
- const profilePath = resolveProfilePath()
450
- if (!profilePath) {
451
- console.error('No profile path given and none could be resolved.')
452
- console.error('Pass an explicit path or set SPECRAILS_PROFILE_PATH, or place a profile at')
453
- console.error(
454
- ' .specrails/profiles/project-default.json (or kimi-default.json for Kimi)',
455
- )
456
- process.exit(1)
457
- }
458
- if (!existsSync(profilePath)) {
459
- console.error(`Profile file not found: ${profilePath}`)
460
- process.exit(1)
461
- }
462
-
463
- let profile
464
- try {
465
- profile = JSON.parse(readFileSync(profilePath, 'utf8'))
466
- } catch (e) {
467
- console.error(`Profile is not valid JSON: ${e.message}`)
468
- process.exit(1)
469
- }
470
-
471
- if (action === 'show') {
472
- console.log(JSON.stringify(profile, null, 2))
473
- process.exit(0)
474
- }
475
-
476
- // action === 'validate'
477
- const schemaPath = path.resolve(ROOT, 'schemas', 'profile.v1.json')
478
- if (!existsSync(schemaPath)) {
479
- console.error(`Schema not found at ${schemaPath} — install may be corrupt`)
480
- process.exit(1)
481
- }
482
-
483
- let Ajv
484
- try {
485
- const mod = await import('ajv/dist/2020.js')
486
- Ajv = mod.default
487
- } catch {
488
- console.error(
489
- "'ajv' is not installed. Run `npm install` in the specrails-core package directory first.",
490
- )
491
- process.exit(1)
492
- }
493
-
494
- const schema = JSON.parse(readFileSync(schemaPath, 'utf8'))
495
- const ajv = new Ajv({ allErrors: true, strict: false })
496
- const validate = ajv.compile(schema)
497
- const schemaValid = validate(profile)
498
- const semanticErrors = schemaValid
499
- ? validateProfileSemantics(profile)
500
- : []
501
-
502
- if (schemaValid && semanticErrors.length === 0) {
503
- console.log(`✓ ${profilePath} is a valid v1 profile.`)
504
- process.exit(0)
505
- }
506
- console.error(`✗ ${profilePath} failed validation:`)
507
- for (const err of validate.errors || []) {
508
- console.error(` ${err.instancePath || '/'} ${err.message} (${JSON.stringify(err.params)})`)
509
- }
510
- for (const err of semanticErrors) {
511
- console.error(` ${err}`)
512
- }
7
+ const cli = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', 'dist', 'installer', 'cli.js')
8
+ if (!existsSync(cli)) {
9
+ console.error(`Installer runtime not found at ${cli}. From a source checkout, run: npm run build`)
513
10
  process.exit(1)
514
11
  }
515
12
 
516
- /**
517
- * JSON Schema validates each profile entry in isolation. These invariants span
518
- * multiple array entries and therefore require a second, semantic validation
519
- * pass after AJV has established the profile's structural shape.
520
- */
521
- function validateProfileSemantics(profile) {
522
- const errors = []
523
- const firstAgentIndex = new Map()
524
-
525
- for (const [index, agent] of profile.agents.entries()) {
526
- const previous = firstAgentIndex.get(agent.id)
527
- if (previous !== undefined) {
528
- errors.push(
529
- `/agents/${index}/id duplicates agent id "${agent.id}" first declared at /agents/${previous}/id`,
530
- )
531
- } else {
532
- firstAgentIndex.set(agent.id, index)
533
- }
534
- }
535
-
536
- const knownAgents = new Set(firstAgentIndex.keys())
537
- const defaultIndices = []
538
- for (const [index, rule] of profile.routing.entries()) {
539
- if (!knownAgents.has(rule.agent)) {
540
- errors.push(
541
- `/routing/${index}/agent references unknown agent "${rule.agent}"`,
542
- )
543
- }
544
- if (rule.default === true) {
545
- defaultIndices.push(index)
546
- }
547
- }
548
-
549
- if (defaultIndices.length > 1) {
550
- errors.push(
551
- `/routing must contain at most one default rule (found ${defaultIndices.length})`,
552
- )
553
- }
554
- for (const index of defaultIndices) {
555
- if (index !== profile.routing.length - 1) {
556
- errors.push(`/routing/${index} default rule must be the last routing entry`)
557
- }
558
- }
559
-
560
- return errors
561
- }
13
+ const { main } = await import(pathToFileURL(cli).href)
14
+ const code = await main(process.argv.slice(2))
15
+ // Let pipe writes drain before exiting; runtime status can exceed a pipe buffer.
16
+ await Promise.all([process.stdout, process.stderr].map((stream) =>
17
+ new Promise((resolve, reject) => stream.write('', (error) => (error ? reject(error) : resolve()))),
18
+ ))
19
+ process.exit(code)
@@ -78,4 +78,3 @@ export async function configuredCapabilities(config, registry) {
78
78
  }
79
79
  return { schemaVersion: 1, roles };
80
80
  }
81
- //# sourceMappingURL=capabilities.js.map
@@ -4,7 +4,7 @@ export interface CliExecutorOptions {
4
4
  runProcess?: CliProcessRunner;
5
5
  env?: NodeJS.ProcessEnv;
6
6
  }
7
- export interface CliInvocationOptions {
7
+ interface CliInvocationOptions {
8
8
  kimiAgentFile?: string;
9
9
  geminiPolicyFile?: string;
10
10
  codexSchemaFile?: string;
@@ -7,7 +7,7 @@ import { existsSync, readFileSync, mkdtempSync, rmSync, writeFileSync } from 'no
7
7
  import { tmpdir } from 'node:os';
8
8
  import path from 'node:path';
9
9
  import { sumCacheUsage } from './efficiency-types.js';
10
- import { normalizeKimiCliModel } from '../installer/runtime/kimi.js';
10
+ import { normalizeKimiCliModel } from './kimi-model.js';
11
11
  import { AgentExecutionError, unknownUsage, validateAgentRequest } from './executor-types.js';
12
12
  import { runCliProcess } from './cli-process.js';
13
13
  import { canonicalWorkspace } from './workspace-tools.js';
@@ -409,4 +409,3 @@ export class CliExecutor {
409
409
  }
410
410
  }
411
411
  }
412
- //# sourceMappingURL=cli-executor.js.map
@@ -167,4 +167,3 @@ export const runCliProcess = async (raw, options) => {
167
167
  child.stdin?.end(invocation.stdin ?? '', 'utf8');
168
168
  });
169
169
  };
170
- //# sourceMappingURL=cli-process.js.map
@@ -5,8 +5,8 @@ import { rolePromptDefaults } from './prompts.js';
5
5
  import { existsSync, mkdirSync, readFileSync, realpathSync, writeFileSync } from 'node:fs';
6
6
  import path from 'node:path';
7
7
  import { pathToFileURL } from 'node:url';
8
- import { parseArgs } from '../installer/cli.js';
9
- import { readVerificationEvidence, inspectPipeline, pipelineStateDirectory, validatePipelineContext } from '../installer/runtime/pipeline-state.js';
8
+ import { parseArgs } from '../shared/args.js';
9
+ import { readVerificationEvidence, inspectPipeline, pipelineStateDirectory, validatePipelineContext } from '../pipeline/pipeline-state.js';
10
10
  import { normalizeRuntimeConfig, validateRuntimeConfig } from './config.js';
11
11
  import { CORE_PACKAGE_VERSION, CORE_WORKFLOW_VERSION, RUNTIME_API_VERSION, coreRuntimeIdentity, preflightCoreWorkflow, runCoreWorkflow } from './core-host.js';
12
12
  import { sameRuntimeIdentity } from './runtime-identity.js';
@@ -88,7 +88,7 @@ function invocationUsage(state, priorCount) {
88
88
  return { costUsd: sum('costUsd'), inputTokens: sum('inputTokens'), outputTokens: sum('outputTokens') };
89
89
  }
90
90
  export async function runRuntimeCommand(flags, positionals, emit = value => process.stdout.write(JSON.stringify(value) + '\n')) {
91
- const command = positionals[0] ?? 'help';
91
+ const command = flags.help === true ? 'help' : positionals[0] ?? 'help';
92
92
  if (command === 'prompts') {
93
93
  emit({ type: 'runtime-role-prompts', defaults: rolePromptDefaults() });
94
94
  return 0;
@@ -241,4 +241,3 @@ if (process.argv[1] && existsSync(process.argv[1]) && import.meta.url === pathTo
241
241
  process.exitCode = 1;
242
242
  }
243
243
  }
244
- //# sourceMappingURL=cli.js.map
@@ -28,4 +28,3 @@ export function restoreOptionalFields(value, schema) {
28
28
  return Object.fromEntries(Object.entries(value).filter(([key, item]) => !(key in properties && item === null && !required.has(key)))
29
29
  .map(([key, item]) => [key, properties[key] ? restoreOptionalFields(item, properties[key]) : item]));
30
30
  }
31
- //# sourceMappingURL=codex-schema.js.map