specrails-core 5.5.1 → 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 (276) 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 +4 -3
  6. package/dist/agent-runtime/cli-process.js +0 -1
  7. package/dist/agent-runtime/cli.d.ts +8 -0
  8. package/dist/agent-runtime/cli.js +31 -5
  9. package/dist/agent-runtime/codex-schema.js +0 -1
  10. package/dist/agent-runtime/compact/architect.d.ts +3 -272
  11. package/dist/agent-runtime/compact/architect.js +8 -9
  12. package/dist/agent-runtime/compact/chat-client.d.ts +3 -3
  13. package/dist/agent-runtime/compact/chat-client.js +1 -2
  14. package/dist/agent-runtime/compact/developer.d.ts +3 -70
  15. package/dist/agent-runtime/compact/developer.js +13 -14
  16. package/dist/agent-runtime/compact/environment.d.ts +4 -5
  17. package/dist/agent-runtime/compact/environment.js +1 -2
  18. package/dist/agent-runtime/compact/exit-code-honesty.d.ts +2 -1
  19. package/dist/agent-runtime/compact/exit-code-honesty.js +0 -1
  20. package/dist/agent-runtime/compact/guarded-loop.d.ts +2 -18
  21. package/dist/agent-runtime/compact/guarded-loop.js +7 -8
  22. package/dist/agent-runtime/compact/prompt-inputs.d.ts +0 -2
  23. package/dist/agent-runtime/compact/prompt-inputs.js +1 -2
  24. package/dist/agent-runtime/compact/reviewer.d.ts +0 -13
  25. package/dist/agent-runtime/compact/reviewer.js +5 -6
  26. package/dist/agent-runtime/compact/step.d.ts +0 -1
  27. package/dist/agent-runtime/compact/step.js +1 -2
  28. package/dist/agent-runtime/compact/test-reachability.js +0 -1
  29. package/dist/agent-runtime/config.js +0 -1
  30. package/dist/agent-runtime/core-host.d.ts +1 -1
  31. package/dist/agent-runtime/core-host.js +5 -3
  32. package/dist/agent-runtime/durable-store.d.ts +0 -1
  33. package/dist/agent-runtime/durable-store.js +1 -2
  34. package/dist/agent-runtime/efficiency-summary.d.ts +2 -2
  35. package/dist/agent-runtime/efficiency-summary.js +1 -2
  36. package/dist/agent-runtime/efficiency-types.js +0 -1
  37. package/dist/agent-runtime/efficiency.js +0 -1
  38. package/dist/agent-runtime/evaluation-corpus.js +0 -1
  39. package/dist/agent-runtime/evaluation.d.ts +2 -1
  40. package/dist/agent-runtime/evaluation.js +1 -2
  41. package/dist/agent-runtime/executor-types.d.ts +1 -1
  42. package/dist/agent-runtime/executor-types.js +0 -1
  43. package/dist/agent-runtime/executors.js +0 -1
  44. package/dist/agent-runtime/gemini-policy.js +0 -1
  45. package/dist/agent-runtime/graph/artifacts.d.ts +1 -1
  46. package/dist/agent-runtime/graph/artifacts.js +11 -5
  47. package/dist/agent-runtime/graph/nodes.d.ts +1 -1
  48. package/dist/agent-runtime/graph/nodes.js +1 -2
  49. package/dist/agent-runtime/graph/review-policy.js +0 -1
  50. package/dist/agent-runtime/graph/roles.d.ts +2 -5
  51. package/dist/agent-runtime/graph/roles.js +2 -8
  52. package/dist/agent-runtime/graph/state.d.ts +1 -1
  53. package/dist/agent-runtime/graph/state.js +0 -1
  54. package/dist/agent-runtime/graph-checkpointer.d.ts +2 -1
  55. package/dist/agent-runtime/graph-checkpointer.js +0 -1
  56. package/dist/agent-runtime/guardrails.d.ts +3 -3
  57. package/dist/agent-runtime/guardrails.js +1 -2
  58. package/dist/agent-runtime/index.d.ts +2 -1
  59. package/dist/agent-runtime/index.js +2 -2
  60. package/dist/agent-runtime/kimi-acp.js +1 -2
  61. package/dist/agent-runtime/kimi-model.d.ts +6 -0
  62. package/dist/agent-runtime/kimi-model.js +12 -0
  63. package/dist/agent-runtime/openai-executor.d.ts +0 -9
  64. package/dist/agent-runtime/openai-executor.js +6 -7
  65. package/dist/agent-runtime/openspec-tool-server.js +1 -2
  66. package/dist/agent-runtime/openspec.d.ts +0 -2
  67. package/dist/agent-runtime/openspec.js +3 -7
  68. package/dist/agent-runtime/prompts.d.ts +4 -3
  69. package/dist/agent-runtime/prompts.js +0 -1
  70. package/dist/agent-runtime/provider-diagnostic.js +1 -2
  71. package/dist/agent-runtime/recovery.d.ts +46 -0
  72. package/dist/agent-runtime/recovery.js +169 -0
  73. package/dist/agent-runtime/repository-context.d.ts +1 -1
  74. package/dist/agent-runtime/repository-context.js +0 -1
  75. package/dist/agent-runtime/review-context.d.ts +1 -1
  76. package/dist/agent-runtime/review-context.js +0 -1
  77. package/dist/agent-runtime/role-routing.js +0 -1
  78. package/dist/agent-runtime/role-state.js +0 -1
  79. package/dist/agent-runtime/runtime-identity.js +1 -2
  80. package/dist/agent-runtime/tool-event.js +0 -1
  81. package/dist/agent-runtime/verification-plan.d.ts +5 -4
  82. package/dist/agent-runtime/verification-plan.js +1 -2
  83. package/dist/agent-runtime/workflow-types.js +0 -1
  84. package/dist/agent-runtime/workflow.js +0 -1
  85. package/dist/agent-runtime/workspace-tools.d.ts +2 -2
  86. package/dist/agent-runtime/workspace-tools.js +1 -2
  87. package/dist/installer/cli.d.ts +3 -32
  88. package/dist/installer/cli.js +26 -101
  89. package/dist/installer/commands/framework.d.ts +4 -3
  90. package/dist/installer/commands/framework.js +0 -1
  91. package/dist/installer/commands/init.d.ts +4 -25
  92. package/dist/installer/commands/init.js +5 -8
  93. package/dist/installer/phases/framework-lifecycle.d.ts +3 -17
  94. package/dist/installer/phases/framework-lifecycle.js +2 -3
  95. package/dist/installer/phases/install-config.d.ts +7 -8
  96. package/dist/installer/phases/install-config.js +2 -7
  97. package/dist/installer/phases/manifest.d.ts +6 -7
  98. package/dist/installer/phases/manifest.js +2 -7
  99. package/dist/installer/phases/prereqs.d.ts +6 -7
  100. package/dist/installer/phases/prereqs.js +4 -6
  101. package/dist/installer/phases/provider-detect.d.ts +6 -7
  102. package/dist/installer/phases/provider-detect.js +2 -4
  103. package/dist/installer/phases/scaffold.d.ts +9 -10
  104. package/dist/installer/phases/scaffold.js +82 -805
  105. package/dist/installer/util/errors.js +0 -1
  106. package/dist/installer/util/exec.d.ts +3 -2
  107. package/dist/installer/util/exec.js +0 -1
  108. package/dist/installer/util/fs.d.ts +0 -10
  109. package/dist/installer/util/fs.js +1 -2
  110. package/dist/installer/util/git.js +0 -1
  111. package/dist/installer/util/install-transaction.d.ts +2 -2
  112. package/dist/installer/util/install-transaction.js +1 -2
  113. package/dist/installer/util/logger.d.ts +1 -3
  114. package/dist/installer/util/logger.js +0 -1
  115. package/dist/installer/util/paths.js +0 -1
  116. package/dist/installer/util/registry.d.ts +4 -8
  117. package/dist/installer/util/registry.js +2 -3
  118. package/dist/{installer/runtime → pipeline}/pipeline-state.js +0 -3
  119. package/dist/shared/args.d.ts +18 -0
  120. package/dist/shared/args.js +53 -0
  121. package/integration-contract.json +10 -46
  122. package/package.json +3 -10
  123. package/templates/agents/sr-architect.md +15 -310
  124. package/templates/agents/sr-developer.md +15 -269
  125. package/templates/agents/sr-reviewer.md +13 -367
  126. package/templates/codex-skills/rails/sr-architect/SKILL.md +14 -308
  127. package/templates/codex-skills/rails/sr-developer/SKILL.md +14 -201
  128. package/templates/codex-skills/rails/sr-reviewer/SKILL.md +15 -289
  129. package/templates/kimi/specrails/run-skill.mjs +91 -2173
  130. package/bin/tui-installer.mjs +0 -430
  131. package/commands/doctor.md +0 -62
  132. package/dist/agent-runtime/capabilities.js.map +0 -1
  133. package/dist/agent-runtime/cli-executor.js.map +0 -1
  134. package/dist/agent-runtime/cli-process.js.map +0 -1
  135. package/dist/agent-runtime/cli.js.map +0 -1
  136. package/dist/agent-runtime/codex-schema.js.map +0 -1
  137. package/dist/agent-runtime/compact/architect.js.map +0 -1
  138. package/dist/agent-runtime/compact/chat-client.js.map +0 -1
  139. package/dist/agent-runtime/compact/developer.js.map +0 -1
  140. package/dist/agent-runtime/compact/environment.js.map +0 -1
  141. package/dist/agent-runtime/compact/exit-code-honesty.js.map +0 -1
  142. package/dist/agent-runtime/compact/guarded-loop.js.map +0 -1
  143. package/dist/agent-runtime/compact/prompt-inputs.js.map +0 -1
  144. package/dist/agent-runtime/compact/reviewer.js.map +0 -1
  145. package/dist/agent-runtime/compact/step.js.map +0 -1
  146. package/dist/agent-runtime/compact/test-reachability.js.map +0 -1
  147. package/dist/agent-runtime/config.js.map +0 -1
  148. package/dist/agent-runtime/core-host.js.map +0 -1
  149. package/dist/agent-runtime/durable-store.js.map +0 -1
  150. package/dist/agent-runtime/efficiency-summary.js.map +0 -1
  151. package/dist/agent-runtime/efficiency-types.js.map +0 -1
  152. package/dist/agent-runtime/efficiency.js.map +0 -1
  153. package/dist/agent-runtime/evaluation-corpus.js.map +0 -1
  154. package/dist/agent-runtime/evaluation.js.map +0 -1
  155. package/dist/agent-runtime/executor-types.js.map +0 -1
  156. package/dist/agent-runtime/executors.js.map +0 -1
  157. package/dist/agent-runtime/gemini-policy.js.map +0 -1
  158. package/dist/agent-runtime/graph/artifacts.js.map +0 -1
  159. package/dist/agent-runtime/graph/nodes.js.map +0 -1
  160. package/dist/agent-runtime/graph/review-policy.js.map +0 -1
  161. package/dist/agent-runtime/graph/roles.js.map +0 -1
  162. package/dist/agent-runtime/graph/state.js.map +0 -1
  163. package/dist/agent-runtime/graph-checkpointer.js.map +0 -1
  164. package/dist/agent-runtime/guardrails.js.map +0 -1
  165. package/dist/agent-runtime/index.js.map +0 -1
  166. package/dist/agent-runtime/kimi-acp.js.map +0 -1
  167. package/dist/agent-runtime/openai-executor.js.map +0 -1
  168. package/dist/agent-runtime/openspec-tool-server.js.map +0 -1
  169. package/dist/agent-runtime/openspec.js.map +0 -1
  170. package/dist/agent-runtime/prompts.js.map +0 -1
  171. package/dist/agent-runtime/provider-diagnostic.js.map +0 -1
  172. package/dist/agent-runtime/repository-context.js.map +0 -1
  173. package/dist/agent-runtime/review-context.js.map +0 -1
  174. package/dist/agent-runtime/role-routing.js.map +0 -1
  175. package/dist/agent-runtime/role-state.js.map +0 -1
  176. package/dist/agent-runtime/runtime-identity.js.map +0 -1
  177. package/dist/agent-runtime/tool-event.js.map +0 -1
  178. package/dist/agent-runtime/verification-plan.js.map +0 -1
  179. package/dist/agent-runtime/workflow-types.js.map +0 -1
  180. package/dist/agent-runtime/workflow.js.map +0 -1
  181. package/dist/agent-runtime/workspace-tools.js.map +0 -1
  182. package/dist/installer/cli.js.map +0 -1
  183. package/dist/installer/commands/doctor.d.ts +0 -27
  184. package/dist/installer/commands/doctor.js +0 -615
  185. package/dist/installer/commands/doctor.js.map +0 -1
  186. package/dist/installer/commands/framework.js.map +0 -1
  187. package/dist/installer/commands/init.js.map +0 -1
  188. package/dist/installer/commands/update.d.ts +0 -56
  189. package/dist/installer/commands/update.js +0 -257
  190. package/dist/installer/commands/update.js.map +0 -1
  191. package/dist/installer/commands/v5-migration.d.ts +0 -32
  192. package/dist/installer/commands/v5-migration.js +0 -133
  193. package/dist/installer/commands/v5-migration.js.map +0 -1
  194. package/dist/installer/phases/framework-lifecycle.js.map +0 -1
  195. package/dist/installer/phases/install-config.js.map +0 -1
  196. package/dist/installer/phases/manifest.js.map +0 -1
  197. package/dist/installer/phases/prereqs.js.map +0 -1
  198. package/dist/installer/phases/provider-detect.js.map +0 -1
  199. package/dist/installer/phases/scaffold.js.map +0 -1
  200. package/dist/installer/runtime/kimi.d.ts +0 -84
  201. package/dist/installer/runtime/kimi.js +0 -255
  202. package/dist/installer/runtime/kimi.js.map +0 -1
  203. package/dist/installer/runtime/pipeline-state.js.map +0 -1
  204. package/dist/installer/util/errors.js.map +0 -1
  205. package/dist/installer/util/exec.js.map +0 -1
  206. package/dist/installer/util/fs.js.map +0 -1
  207. package/dist/installer/util/git.js.map +0 -1
  208. package/dist/installer/util/install-transaction.js.map +0 -1
  209. package/dist/installer/util/logger.js.map +0 -1
  210. package/dist/installer/util/paths.js.map +0 -1
  211. package/dist/installer/util/prompts.d.ts +0 -23
  212. package/dist/installer/util/prompts.js +0 -49
  213. package/dist/installer/util/prompts.js.map +0 -1
  214. package/dist/installer/util/registry.js.map +0 -1
  215. package/dist/installer/util/template.d.ts +0 -23
  216. package/dist/installer/util/template.js +0 -60
  217. package/dist/installer/util/template.js.map +0 -1
  218. package/docs/README.md +0 -40
  219. package/docs/agent-runtime-efficiency.md +0 -65
  220. package/docs/agent-runtime.md +0 -347
  221. package/docs/agents.md +0 -315
  222. package/docs/changelog.md +0 -168
  223. package/docs/ci-cd.md +0 -60
  224. package/docs/concepts.md +0 -183
  225. package/docs/customization.md +0 -363
  226. package/docs/deployment.md +0 -234
  227. package/docs/getting-started.md +0 -122
  228. package/docs/installation.md +0 -395
  229. package/docs/local-tickets.md +0 -191
  230. package/docs/migration-guide.md +0 -140
  231. package/docs/playbook-oss-maintainer.md +0 -112
  232. package/docs/playbook-parallel-dev.md +0 -124
  233. package/docs/playbook-product-discovery.md +0 -115
  234. package/docs/plugin-architecture.md +0 -144
  235. package/docs/research/codex-compatibility-analysis.md +0 -365
  236. package/docs/research/mcp-feasibility-analysis.md +0 -382
  237. package/docs/testing/test-matrix-codex.md +0 -130
  238. package/docs/updating.md +0 -89
  239. package/docs/user-docs/cli-reference.md +0 -428
  240. package/docs/user-docs/codex-vs-claude-code.md +0 -23
  241. package/docs/user-docs/core-updates.md +0 -70
  242. package/docs/user-docs/faq.md +0 -146
  243. package/docs/user-docs/getting-started-codex.md +0 -194
  244. package/docs/user-docs/getting-started-kimi.md +0 -423
  245. package/docs/user-docs/installation.md +0 -237
  246. package/docs/user-docs/provider-pipelines.md +0 -96
  247. package/docs/user-docs/quick-start.md +0 -161
  248. package/docs/windows.md +0 -78
  249. package/docs/workflows.md +0 -463
  250. package/schemas/profile.v1.json +0 -207
  251. package/templates/claude-md/CLAUDE-quickstart.md +0 -54
  252. package/templates/claude-md/root.md +0 -50
  253. package/templates/codex-skills/batch-implement/SKILL.md +0 -38
  254. package/templates/codex-skills/implement/SKILL.md +0 -38
  255. package/templates/codex-skills/retry/SKILL.md +0 -16
  256. package/templates/commands/specrails/compat-check.md +0 -271
  257. package/templates/commands/specrails/doctor.md +0 -62
  258. package/templates/commands/specrails/explore-spec.md +0 -173
  259. package/templates/commands/specrails/health-check.md +0 -527
  260. package/templates/commands/specrails/memory-inspect.md +0 -261
  261. package/templates/commands/specrails/opsx-diff.md +0 -419
  262. package/templates/commands/specrails/propose-spec.md +0 -102
  263. package/templates/commands/specrails/refactor-recommender.md +0 -169
  264. package/templates/commands/specrails/telemetry.md +0 -552
  265. package/templates/commands/specrails/why.md +0 -96
  266. package/templates/gemini-commands/batch-implement.toml +0 -37
  267. package/templates/gemini-commands/implement.toml +0 -37
  268. package/templates/gemini-commands/retry.toml +0 -15
  269. package/templates/profiles/default.json +0 -14
  270. package/templates/profiles/kimi-default.json +0 -15
  271. package/templates/rules/layer.md +0 -8
  272. package/templates/runtime/provider-pipeline.md +0 -113
  273. package/templates/security/security-exemptions.yaml +0 -20
  274. package/templates/settings/confidence-config.json +0 -17
  275. package/templates/settings/settings.json +0 -15
  276. /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';
@@ -24,7 +24,9 @@ const CLAUDE_DEVELOPER_DISALLOWED = 'Agent,Task,Skill';
24
24
  */
25
25
  export function buildCliInvocation(provider, request, options = {}) {
26
26
  const readOnly = request.role !== 'developer';
27
- const model = request.model ? ['--model', request.model] : [];
27
+ // Pin the product alias; explicit IDs remain reproducible across releases.
28
+ const modelId = provider === 'claude' && request.model === 'opus' ? 'claude-opus-5-5' : request.model;
29
+ const model = modelId ? ['--model', modelId] : [];
28
30
  const extraRoots = request.allowedRoots.filter(root => root !== request.cwd);
29
31
  const resume = request.resumeSessionId;
30
32
  switch (provider) {
@@ -407,4 +409,3 @@ export class CliExecutor {
407
409
  }
408
410
  }
409
411
  }
410
- //# 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
@@ -34,6 +34,14 @@ export declare function compactState(state: WorkflowState | null): {
34
34
  visits: number;
35
35
  };
36
36
  };
37
+ recentFailures: {
38
+ stepId: string;
39
+ status: "running" | "interrupted" | import("./workflow-types.js").StepStatus;
40
+ attempt: number;
41
+ visit: number;
42
+ at: string;
43
+ error: string | undefined;
44
+ }[];
37
45
  metrics: import("./efficiency-types.js").RuntimeEfficiency;
38
46
  } | null;
39
47
  export declare function runRuntimeCommand(flags: Record<string, string | boolean>, positionals: string[], emit?: (value: unknown) => void): Promise<number>;