specrails-core 4.11.2 → 4.12.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 (56) hide show
  1. package/README.md +56 -20
  2. package/bin/specrails-core.mjs +343 -20
  3. package/bin/tui-installer.mjs +103 -52
  4. package/dist/installer/cli.js +1 -1
  5. package/dist/installer/cli.js.map +1 -1
  6. package/dist/installer/commands/doctor.js +486 -24
  7. package/dist/installer/commands/doctor.js.map +1 -1
  8. package/dist/installer/commands/framework.js +49 -7
  9. package/dist/installer/commands/framework.js.map +1 -1
  10. package/dist/installer/commands/init.js +423 -25
  11. package/dist/installer/commands/init.js.map +1 -1
  12. package/dist/installer/commands/update.js +36 -9
  13. package/dist/installer/commands/update.js.map +1 -1
  14. package/dist/installer/phases/framework-lifecycle.js +125 -0
  15. package/dist/installer/phases/framework-lifecycle.js.map +1 -0
  16. package/dist/installer/phases/install-config.js +157 -5
  17. package/dist/installer/phases/install-config.js.map +1 -1
  18. package/dist/installer/phases/manifest.js +27 -2
  19. package/dist/installer/phases/manifest.js.map +1 -1
  20. package/dist/installer/phases/prereqs.js +57 -2
  21. package/dist/installer/phases/prereqs.js.map +1 -1
  22. package/dist/installer/phases/provider-detect.js +116 -6
  23. package/dist/installer/phases/provider-detect.js.map +1 -1
  24. package/dist/installer/phases/scaffold.js +1222 -12
  25. package/dist/installer/phases/scaffold.js.map +1 -1
  26. package/dist/installer/runtime/kimi.js +255 -0
  27. package/dist/installer/runtime/kimi.js.map +1 -0
  28. package/dist/installer/util/paths.js +12 -0
  29. package/dist/installer/util/paths.js.map +1 -1
  30. package/dist/installer/util/registry.js +234 -14
  31. package/dist/installer/util/registry.js.map +1 -1
  32. package/docs/README.md +1 -0
  33. package/docs/deployment.md +6 -7
  34. package/docs/getting-started.md +11 -7
  35. package/docs/installation.md +34 -16
  36. package/docs/plugin-architecture.md +11 -8
  37. package/docs/updating.md +21 -3
  38. package/docs/user-docs/cli-reference.md +43 -22
  39. package/docs/user-docs/codex-vs-claude-code.md +11 -9
  40. package/docs/user-docs/faq.md +1 -1
  41. package/docs/user-docs/getting-started-codex.md +5 -8
  42. package/docs/user-docs/getting-started-kimi.md +423 -0
  43. package/docs/user-docs/installation.md +49 -14
  44. package/docs/user-docs/quick-start.md +11 -8
  45. package/docs/windows.md +29 -4
  46. package/integration-contract.json +85 -13
  47. package/package.json +9 -5
  48. package/schemas/profile.v1.json +67 -5
  49. package/templates/codex-skills/batch-implement/SKILL.md +4 -0
  50. package/templates/commands/specrails/batch-implement.md +11 -0
  51. package/templates/gemini-commands/batch-implement.toml +4 -0
  52. package/templates/kimi/specrails/run-skill.mjs +3005 -0
  53. package/templates/kimi/specrails/vendor/js-yaml/LICENSE +21 -0
  54. package/templates/kimi/specrails/vendor/js-yaml/NOTICE.md +16 -0
  55. package/templates/kimi/specrails/vendor/js-yaml/js-yaml.mjs +3856 -0
  56. package/templates/profiles/kimi-default.json +15 -0
@@ -1,5 +1,5 @@
1
1
  {
2
- "schemaVersion": "3.0",
2
+ "schemaVersion": "3.2",
3
3
  "providers": {
4
4
  "claude": {
5
5
  "enrichCommand": "/specrails:enrich",
@@ -22,6 +22,59 @@
22
22
  "enrichArgs": ["exec", "run enrich"],
23
23
  "enrichFromConfigArgs": ["exec", "run enrich --from-config"]
24
24
  }
25
+ },
26
+ "gemini": {
27
+ "enrichCommand": "/specrails:enrich",
28
+ "enrichArgs": ["--from-config"],
29
+ "updateCommand": "/specrails:enrich",
30
+ "updateArgs": ["--update"],
31
+ "cli": {
32
+ "initArgs": [],
33
+ "enrichArgs": ["-p", "/specrails:enrich", "--output-format", "stream-json"],
34
+ "enrichFromConfigArgs": ["-p", "/specrails:enrich --from-config", "--output-format", "stream-json"]
35
+ }
36
+ },
37
+ "kimi": {
38
+ "enrichCommand": "/skill:specrails-enrich",
39
+ "enrichArgs": ["--from-config"],
40
+ "updateCommand": "/skill:specrails-enrich",
41
+ "updateArgs": ["--update"],
42
+ "cli": {
43
+ "binary": "node",
44
+ "providerBinary": "kimi",
45
+ "skillRunner": ".kimi-code/specrails/run-skill.mjs",
46
+ "skillMaterialization": "kimi-0.27-user-slash-prompt",
47
+ "nestedSkillInvocation": "Kimi built-in Skill tool with { skill, args }; never literal /skill text",
48
+ "modelIdPattern": "^[A-Za-z0-9][A-Za-z0-9._/:-]{0,127}$",
49
+ "sessionIdPattern": "^(?!\\.{1,2}$)[A-Za-z0-9._-]{1,128}$",
50
+ "roleWave": {
51
+ "path": ".specrails/kimi-role-wave.json",
52
+ "schema": "{ run: safe-id, roles: Array<{ key: safe-id, skill: direct-child-id, model: safe-model-id, profile: \"inherit\" | safe-id, args: string, workspace: \"current\" | \"worktree:<safe-id>\" }> } with no extra keys",
53
+ "maxBytes": 1048576,
54
+ "maxRoles": 32,
55
+ "transport": "structured WriteFile followed by one static foreground --role-wave-file command; the one-shot file is deleted before setup and every role is awaited. Inspection, merge, and cleanup use the separate static --role-wave-status, --role-merge-file, and --role-wave-cleanup modes",
56
+ "workspaces": "current roles receive unique execution directories with SPECRAILS_REPO_DIR set to the target repository; isolated roles create/reuse detached git worktrees from a synthetic baseline that includes the starting tracked/untracked overlay but excludes provider/runtime control files, with SPECRAILS_REPO_DIR set to that worktree",
57
+ "manifest": ".specrails/kimi-role-worktrees/<run>.json records the immutable synthetic base commit, source head, worktree ids, and role key to execution/repository paths",
58
+ "status": "--role-wave-status <run> validates the persisted manifest/ref/worktrees and emits one specrails.merge.inventory frame before any downstream merge",
59
+ "merge": ".specrails/kimi-role-merge.json is the only accepted merge request path; { run, actions: Array<{ worktree: safe-id, path: safe-relative-path, operation: \"copy\" | \"delete\" }> } applies an explicit A/M/D inventory through --role-merge-file without attributing the starting overlay or provider control files",
60
+ "cleanup": "--role-wave-cleanup <run> removes owned worktrees, temporary execution roots, persisted manifest, and synthetic baseline ref, then emits specrails.role.cleanup",
61
+ "output": "newline-delimited attributed specrails.role.workspace, specrails.role.event/output, specrails.role.completed, specrails.merge.inventory, specrails.merge.applied, and specrails.role.cleanup frames; aggregate role-wave exit is nonzero when any role fails"
62
+ },
63
+ "stableEngineEnv": {
64
+ "KIMI_CODE_EXPERIMENTAL_FLAG": null,
65
+ "KIMI_DISABLE_CRON": "1",
66
+ "KIMI_CODE_NO_AUTO_UPDATE": "1",
67
+ "KIMI_MODEL_THINKING_EFFORT": "low|high|max only for kimi-code/k3; omitted K3 effort preserves Kimi's documented high default; unset for every other model"
68
+ },
69
+ "windowsPromptTransport": "For the standard npm kimi.cmd/bat shim, prompt bytes travel over stdin to a fixed Node bootstrap which restores process.argv before importing Kimi; native executables fail above a 30000 UTF-16 command-line budget.",
70
+ "initialActivationTelemetry": "Visible prompt parity only; the external materializer cannot emit Kimi-private skill.activated/origin telemetry.",
71
+ "cancellation": "Single-skill mode forwards SIGINT/SIGTERM/SIGHUP to its direct Kimi child. Role-wave mode forwards each termination signal to every live Kimi child and waits for aggregate completion; the embedding host remains responsible for platform process-tree teardown.",
72
+ "initArgs": [],
73
+ "enrichArgs": [".kimi-code/specrails/run-skill.mjs", "--skill", "specrails-enrich", "--model", "k3"],
74
+ "enrichFromConfigArgs": [".kimi-code/specrails/run-skill.mjs", "--skill", "specrails-enrich", "--model", "k3", "--args", "--from-config"],
75
+ "resumeArgs": ["--session=<session-id>"],
76
+ "notes": "CLI-only integration. enrichCommand/updateCommand are interactive Kimi TUI syntax only. Headless callers must execute binary + enrichArgs; plain `kimi -p \"/skill:...\"` is literal prompt text in Kimi 0.27 and does not activate a skill. The managed Node runner materializes the upstream user-slash prompt, then launches external Kimi with stream-json and no shell. Generated multi-role workflows use one bounded role-wave file so context never enters shell source and parallel roles cannot race on request paths. Do not start kimi web/server; authenticate once with `kimi login`."
77
+ }
25
78
  }
26
79
  },
27
80
  "tiers": {
@@ -43,13 +96,13 @@
43
96
  "version": 1,
44
97
  "fields": {
45
98
  "version": "number — schema version, currently 1",
46
- "provider": "string — claude | codex | gemini | auto",
99
+ "provider": "string — claude | codex | gemini | kimi",
47
100
  "tier": "string — full | quick",
48
- "agents.selected": "string[] — agent names to install",
49
- "agents.excluded": "string[] — agent names to skip",
50
- "models.preset": "string — balanced | budget | max",
51
- "models.defaults.model": "string — sonnet | opus | haiku (overrides preset)",
52
- "models.overrides": "Record<string, string> — per-agent model (highest priority)"
101
+ "agents.selected": "string[] — unique lowercase kebab-case agent ids to install (1-64 characters)",
102
+ "agents.excluded": "string[] — unique lowercase kebab-case agent ids to skip; must not overlap agents.selected",
103
+ "models.preset": "string — balanced | budget | max; resolved within the selected provider catalog",
104
+ "models.defaults.model": "string — exact provider model id or configured alias (overrides preset; Kimi: 1-128 characters matching [A-Za-z0-9][A-Za-z0-9._/:-]*; default: k3)",
105
+ "models.overrides": "Record<safe-agent-id, string> — exact per-agent provider model ids or configured aliases with the same provider-specific validation (highest priority)"
53
106
  }
54
107
  },
55
108
  "checkpoints": {
@@ -63,19 +116,38 @@
63
116
  },
64
117
  "modelPresets": {
65
118
  "balanced": {
66
- "description": "Flagship models for architects and PMs, efficient models for others",
119
+ "scope": "claude",
120
+ "description": "Legacy Claude preset view retained for existing consumers. Other providers resolve this preset through providerModelCatalogs.",
67
121
  "defaults": { "model": "sonnet" },
68
- "overrides": { "sr-architect": "opus", "sr-product-manager": "opus" }
122
+ "overrides": {}
69
123
  },
70
124
  "budget": {
71
- "description": "All agents use the most cost-efficient model",
125
+ "scope": "claude",
126
+ "description": "Legacy Claude preset view retained for existing consumers. Other providers resolve this preset through providerModelCatalogs.",
72
127
  "defaults": { "model": "haiku" },
73
128
  "overrides": {}
74
129
  },
75
130
  "max": {
76
- "description": "All agents use the most capable model",
77
- "defaults": { "model": "opus" },
78
- "overrides": {}
131
+ "scope": "claude",
132
+ "description": "Legacy Claude preset view retained for existing consumers. Other providers resolve this preset through providerModelCatalogs.",
133
+ "defaults": { "model": "sonnet" },
134
+ "overrides": { "sr-architect": "opus", "sr-product-manager": "opus" }
135
+ }
136
+ },
137
+ "providerModelCatalogs": {
138
+ "kimi": {
139
+ "default": "k3",
140
+ "models": ["k3", "kimi-for-coding", "kimi-for-coding-highspeed"],
141
+ "presets": {
142
+ "balanced": { "defaults": { "model": "k3" }, "overrides": {} },
143
+ "budget": { "defaults": { "model": "k3" }, "overrides": {} },
144
+ "max": { "defaults": { "model": "k3" }, "overrides": {} }
145
+ },
146
+ "cliAliasPrefix": "kimi-code/",
147
+ "reasoningEfforts": {
148
+ "k3": ["low", "high", "max"]
149
+ },
150
+ "note": "Install config and profiles retain exact ids or safe custom aliases. Preset names do not imply Claude aliases for Kimi. Process launch prefixes only the three documented official short ids with kimi-code/; every custom alias that matches the published model grammar passes through unchanged."
79
151
  }
80
152
  },
81
153
  "legacyCompat": {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "specrails-core",
3
- "version": "4.11.2",
4
- "description": "AI agent workflow system for Claude Code — installs 12 specialized agents, orchestration commands, and persona-driven product discovery into any repository",
3
+ "version": "4.12.0",
4
+ "description": "Provider-independent AI agent workflow system for Claude Code, Codex, Gemini CLI, and Kimi Code",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "specrails-core": "bin/specrails-core.mjs"
@@ -17,7 +17,7 @@
17
17
  "pinned-versions.json"
18
18
  ],
19
19
  "engines": {
20
- "node": ">=20.0.0"
20
+ "node": ">=20.19.0"
21
21
  },
22
22
  "repository": {
23
23
  "type": "git",
@@ -30,6 +30,10 @@
30
30
  "workflow",
31
31
  "developer-tools",
32
32
  "anthropic",
33
+ "kimi",
34
+ "moonshot-ai",
35
+ "gemini",
36
+ "codex",
33
37
  "llm",
34
38
  "ai",
35
39
  "automation",
@@ -53,9 +57,9 @@
53
57
  "build": "tsc -p tsconfig.json",
54
58
  "build:watch": "tsc -p tsconfig.json --watch",
55
59
  "typecheck": "tsc -p tsconfig.test.json --noEmit",
56
- "test": "npm run typecheck && vitest run",
60
+ "test": "npm run build && npm run typecheck && vitest run",
57
61
  "test:watch": "vitest",
58
- "test:coverage": "vitest run --coverage",
62
+ "test:coverage": "npm run build && vitest run --coverage",
59
63
  "dogfood": "npm run build && node bin/specrails-core.mjs init --yes",
60
64
  "prepack": "npm run build"
61
65
  },
@@ -23,14 +23,19 @@
23
23
  "maxLength": 512,
24
24
  "description": "Optional short summary of when to use this profile."
25
25
  },
26
+ "provider": {
27
+ "type": "string",
28
+ "enum": ["claude", "codex", "gemini", "kimi"],
29
+ "description": "Optional provider binding. Omitted profiles retain the legacy Claude model-alias contract. Provider-bound profiles retain exact model identifiers; Kimi additionally enforces its safe process-boundary grammar."
30
+ },
26
31
  "orchestrator": {
27
32
  "type": "object",
28
33
  "required": ["model"],
29
34
  "additionalProperties": false,
30
35
  "properties": {
31
36
  "model": {
32
- "$ref": "#/$defs/modelAlias",
33
- "description": "Model used to run the top-level implement orchestrator."
37
+ "$ref": "#/$defs/providerModelId",
38
+ "description": "Provider model identifier used to run the top-level implement orchestrator."
34
39
  }
35
40
  }
36
41
  },
@@ -73,12 +78,69 @@
73
78
  "items": { "$ref": "#/$defs/routingRule" }
74
79
  }
75
80
  },
81
+ "allOf": [
82
+ {
83
+ "if": {
84
+ "anyOf": [
85
+ { "not": { "required": ["provider"] } },
86
+ {
87
+ "required": ["provider"],
88
+ "properties": { "provider": { "const": "claude" } }
89
+ }
90
+ ]
91
+ },
92
+ "then": {
93
+ "properties": {
94
+ "orchestrator": {
95
+ "properties": { "model": { "$ref": "#/$defs/modelAlias" } }
96
+ },
97
+ "agents": {
98
+ "items": {
99
+ "properties": { "model": { "$ref": "#/$defs/modelAlias" } }
100
+ }
101
+ }
102
+ }
103
+ }
104
+ },
105
+ {
106
+ "if": {
107
+ "required": ["provider"],
108
+ "properties": { "provider": { "const": "kimi" } }
109
+ },
110
+ "then": {
111
+ "properties": {
112
+ "orchestrator": {
113
+ "properties": { "model": { "$ref": "#/$defs/kimiModelId" } }
114
+ },
115
+ "agents": {
116
+ "items": {
117
+ "properties": { "model": { "$ref": "#/$defs/kimiModelId" } }
118
+ }
119
+ }
120
+ }
121
+ }
122
+ }
123
+ ],
76
124
  "$defs": {
77
125
  "modelAlias": {
78
126
  "type": "string",
79
127
  "enum": ["sonnet", "opus", "haiku"],
80
128
  "description": "Accepted model alias. Resolved to the current concrete model ID by the pipeline."
81
129
  },
130
+ "providerModelId": {
131
+ "type": "string",
132
+ "minLength": 1,
133
+ "maxLength": 256,
134
+ "pattern": "^\\S(?:.*\\S)?$",
135
+ "description": "Exact provider model identifier or user-configured alias. Core retains this value verbatim and applies documented provider-specific validation/normalization."
136
+ },
137
+ "kimiModelId": {
138
+ "type": "string",
139
+ "minLength": 1,
140
+ "maxLength": 128,
141
+ "pattern": "^[A-Za-z0-9][A-Za-z0-9._/:-]*$",
142
+ "description": "Kimi model identifier accepted at the shell-free process boundary."
143
+ },
82
144
  "agentEntry": {
83
145
  "type": "object",
84
146
  "required": ["id"],
@@ -87,11 +149,11 @@
87
149
  "id": {
88
150
  "type": "string",
89
151
  "pattern": "^(sr|custom)-[a-z0-9][a-z0-9-]*$",
90
- "description": "Agent identifier. MUST correspond to a file at `.claude/agents/<id>.md`."
152
+ "description": "Agent identifier. MUST correspond to the selected provider's role artifact."
91
153
  },
92
154
  "model": {
93
- "$ref": "#/$defs/modelAlias",
94
- "description": "Model override for this agent when this profile is active. When omitted, the agent's frontmatter `model:` is used as a fallback."
155
+ "$ref": "#/$defs/providerModelId",
156
+ "description": "Exact provider model override for this agent. When omitted, the provider default is used."
95
157
  },
96
158
  "required": {
97
159
  "type": "boolean",
@@ -43,6 +43,10 @@ ticket, no more nesting. The contract that `$implement` enforces
43
43
 
44
44
  Default execution mode is sequential.
45
45
 
46
+ ## Desktop rail execution context
47
+
48
+ When the working directory is a specrails-desktop isolated rail worktree (path contains `/worktrees/`, typically on a `feat/...` branch), you are the ASSIGNED executor of that rail: implement every ticket sequentially in THIS worktree on THIS branch — the desktop assembles it into a batch PR afterwards, nothing needs to land on the integration branch first. The desktop's own bookkeeping (ticket-ownership rows in its `jobs.sqlite`, state under `~/.specrails/`) describes this very launch — never read those internals, and never stop to ask which process should run the batch.
49
+
46
50
  ## Steps
47
51
 
48
52
  ### 0. Bootstrap
@@ -16,6 +16,17 @@ Macro-orchestrator above `/specrails:implement`. Accepts a set of feature refere
16
16
 
17
17
  ---
18
18
 
19
+ ## Desktop rail execution context (isolated worktree)
20
+
21
+ specrails-desktop launches this command INSIDE an isolated rail worktree allocated for the batch. Detect it: the working directory path contains `/worktrees/` (e.g. `~/.specrails/projects/<slug>/worktrees/ticket-N`), typically on a `feat/...` branch. When that is the case, ALL of the following hold — they override any instinct to the contrary:
22
+
23
+ - **You ARE the assigned executor of this rail.** The desktop's own bookkeeping (rail slots, ticket-ownership rows in its `jobs.sqlite`, state under `~/.specrails/`) describes THIS very launch — it is never evidence of a competing process. NEVER read specrails-desktop's internal databases or state files, and NEVER stop to ask "which process should run this batch".
24
+ - **The current worktree + current branch ARE the workspace for the WHOLE batch.** Implement every ticket here, in dependency order — including tickets whose refs differ from the branch name. The desktop assembles this branch into a batch PR after you finish; nothing needs to land on the integration branch (main) first. Do NOT create sibling worktrees, do NOT switch branches, do NOT run any ticket "against main in the base repo".
25
+ - **Run tickets SEQUENTIALLY (effective concurrency 1)** regardless of `--concurrency`: parallel pipelines editing one shared checkout corrupt each other. Wave order still sequences the work; only the parallelism collapses.
26
+ - Everything else (per-ticket `/specrails:implement` delegation, wave gates, failure isolation, final report) applies unchanged.
27
+
28
+ ---
29
+
19
30
  ## Phase 0: Parse Input
20
31
 
21
32
  ### Step 1: Extract feature refs
@@ -11,6 +11,10 @@ How the user invokes you:
11
11
  - `/specrails:batch-implement #1 #2 --parallel` — opt-in parallel, only when the
12
12
  tickets touch disjoint files (run a safety check first; fall back to sequential).
13
13
 
14
+ ## Desktop rail execution context
15
+
16
+ When the working directory is a specrails-desktop isolated rail worktree (path contains `/worktrees/`, typically on a `feat/...` branch), you are the ASSIGNED executor of that rail: implement every ticket sequentially in THIS worktree on THIS branch — the desktop assembles it into a batch PR afterwards, nothing needs to land on the integration branch first. The desktop's own bookkeeping (ticket-ownership rows in its `jobs.sqlite`, state under `~/.specrails/`) describes this very launch — never read those internals, and never stop to ask which process should run the batch.
17
+
14
18
  ## Why this drives the spawns at the ROOT level
15
19
 
16
20
  Do NOT delegate to a nested `/specrails:implement` subagent per ticket that then