specrails-core 4.11.3 → 5.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.
- package/README.md +96 -89
- package/bin/specrails-core.mjs +282 -39
- package/bin/tui-installer.mjs +117 -149
- package/commands/doctor.md +1 -1
- package/dist/installer/cli.js +13 -3
- package/dist/installer/cli.js.map +1 -1
- package/dist/installer/commands/doctor.js +487 -27
- package/dist/installer/commands/doctor.js.map +1 -1
- package/dist/installer/commands/framework.js +49 -7
- package/dist/installer/commands/framework.js.map +1 -1
- package/dist/installer/commands/init.js +443 -41
- package/dist/installer/commands/init.js.map +1 -1
- package/dist/installer/commands/update.js +51 -23
- package/dist/installer/commands/update.js.map +1 -1
- package/dist/installer/commands/v5-migration.js +119 -0
- package/dist/installer/commands/v5-migration.js.map +1 -0
- package/dist/installer/phases/framework-lifecycle.js +125 -0
- package/dist/installer/phases/framework-lifecycle.js.map +1 -0
- package/dist/installer/phases/install-config.js +160 -11
- package/dist/installer/phases/install-config.js.map +1 -1
- package/dist/installer/phases/manifest.js +29 -8
- package/dist/installer/phases/manifest.js.map +1 -1
- package/dist/installer/phases/prereqs.js +57 -3
- package/dist/installer/phases/prereqs.js.map +1 -1
- package/dist/installer/phases/provider-detect.js +116 -6
- package/dist/installer/phases/provider-detect.js.map +1 -1
- package/dist/installer/phases/scaffold.js +1217 -117
- package/dist/installer/phases/scaffold.js.map +1 -1
- package/dist/installer/runtime/kimi.js +255 -0
- package/dist/installer/runtime/kimi.js.map +1 -0
- package/dist/installer/util/paths.js +12 -0
- package/dist/installer/util/paths.js.map +1 -1
- package/dist/installer/util/registry.js +234 -14
- package/dist/installer/util/registry.js.map +1 -1
- package/docs/README.md +1 -0
- package/docs/deployment.md +6 -7
- package/docs/getting-started.md +11 -7
- package/docs/installation.md +34 -16
- package/docs/plugin-architecture.md +11 -8
- package/docs/updating.md +21 -3
- package/docs/user-docs/cli-reference.md +43 -22
- package/docs/user-docs/codex-vs-claude-code.md +11 -9
- package/docs/user-docs/faq.md +1 -1
- package/docs/user-docs/getting-started-codex.md +5 -8
- package/docs/user-docs/getting-started-kimi.md +423 -0
- package/docs/user-docs/installation.md +49 -14
- package/docs/user-docs/quick-start.md +11 -8
- package/docs/windows.md +29 -4
- package/integration-contract.json +85 -13
- package/package.json +9 -5
- package/schemas/profile.v1.json +68 -6
- package/templates/agents/sr-architect.md +30 -0
- package/templates/agents/sr-developer.md +21 -8
- package/templates/agents/sr-reviewer.md +44 -31
- package/templates/codex-skills/batch-implement/SKILL.md +9 -32
- package/templates/codex-skills/implement/SKILL.md +61 -143
- package/templates/codex-skills/rails/sr-architect/SKILL.md +38 -20
- package/templates/codex-skills/rails/sr-developer/SKILL.md +29 -10
- package/templates/codex-skills/rails/sr-reviewer/SKILL.md +21 -10
- package/templates/commands/specrails/doctor.md +1 -1
- package/templates/commands/specrails/implement.md +117 -288
- package/templates/commands/specrails/memory-inspect.md +6 -4
- package/templates/commands/specrails/propose-spec.md +1 -1
- package/templates/commands/specrails/refactor-recommender.md +8 -51
- package/templates/commands/specrails/retry.md +12 -48
- package/templates/commands/specrails/telemetry.md +1 -1
- package/templates/gemini-commands/implement.toml +9 -0
- package/templates/kimi/specrails/run-skill.mjs +3005 -0
- package/templates/kimi/specrails/vendor/js-yaml/LICENSE +21 -0
- package/templates/kimi/specrails/vendor/js-yaml/NOTICE.md +16 -0
- package/templates/kimi/specrails/vendor/js-yaml/js-yaml.mjs +3856 -0
- package/templates/profiles/default.json +5 -18
- package/templates/profiles/kimi-default.json +15 -0
- package/commands/enrich.md +0 -1456
- package/templates/agents/sr-backend-developer.md +0 -91
- package/templates/agents/sr-backend-reviewer.md +0 -152
- package/templates/agents/sr-doc-sync.md +0 -247
- package/templates/agents/sr-frontend-developer.md +0 -85
- package/templates/agents/sr-frontend-reviewer.md +0 -145
- package/templates/agents/sr-merge-resolver.md +0 -195
- package/templates/agents/sr-performance-reviewer.md +0 -186
- package/templates/agents/sr-product-analyst.md +0 -36
- package/templates/agents/sr-product-manager.md +0 -148
- package/templates/agents/sr-security-reviewer.md +0 -191
- package/templates/agents/sr-test-writer.md +0 -176
- package/templates/codex-skills/enrich/SKILL.md +0 -191
- package/templates/codex-skills/merge-resolve/SKILL.md +0 -88
- package/templates/codex-skills/rails/sr-backend-developer/SKILL.md +0 -93
- package/templates/codex-skills/rails/sr-backend-reviewer/SKILL.md +0 -120
- package/templates/codex-skills/rails/sr-doc-sync/SKILL.md +0 -124
- package/templates/codex-skills/rails/sr-frontend-developer/SKILL.md +0 -106
- package/templates/codex-skills/rails/sr-frontend-reviewer/SKILL.md +0 -111
- package/templates/codex-skills/rails/sr-merge-resolver/SKILL.md +0 -156
- package/templates/codex-skills/rails/sr-performance-reviewer/SKILL.md +0 -109
- package/templates/codex-skills/rails/sr-product-analyst/SKILL.md +0 -85
- package/templates/codex-skills/rails/sr-product-manager/SKILL.md +0 -131
- package/templates/codex-skills/rails/sr-security-reviewer/SKILL.md +0 -121
- package/templates/codex-skills/rails/sr-test-writer/SKILL.md +0 -115
- package/templates/commands/specrails/auto-propose-backlog-specs.md +0 -312
- package/templates/commands/specrails/enrich.md +0 -1456
- package/templates/commands/specrails/get-backlog-specs.md +0 -226
- package/templates/commands/specrails/merge-resolve.md +0 -172
- package/templates/commands/specrails/reconfig.md +0 -80
- package/templates/commands/specrails/vpc-drift.md +0 -405
- package/templates/commands/test.md +0 -58
- package/templates/personas/persona.md +0 -43
- package/templates/personas/the-maintainer.md +0 -98
- package/templates/settings/perf-thresholds.yml +0 -25
|
@@ -6,9 +6,9 @@ import { copyDir, isDir, pathExists, readTextFile } from '../util/fs.js';
|
|
|
6
6
|
import { loadInstallConfig, resolveConfigPath } from '../phases/install-config.js';
|
|
7
7
|
import { buildManifest, writeManifestFiles } from '../phases/manifest.js';
|
|
8
8
|
import { derivedPaths, detectAvailability, resolveProvider } from '../phases/provider-detect.js';
|
|
9
|
-
import { assembleProjectWorkspace } from '../phases/scaffold.js';
|
|
10
9
|
import { frameworkRoot, resolveArtifacts } from '../util/registry.js';
|
|
11
|
-
import {
|
|
10
|
+
import { migratePreV5Install } from './v5-migration.js';
|
|
11
|
+
import { ensureFramework, installOpenSpecProject, reassembleWorkspaceProviders, snapshotWorkspaceProviderSelections, warnUnknownSelectedAgents, } from './init.js';
|
|
12
12
|
const VALID_ONLY = new Set([
|
|
13
13
|
'all',
|
|
14
14
|
'core',
|
|
@@ -21,9 +21,6 @@ export async function runUpdate(flags) {
|
|
|
21
21
|
const currentVersion = readVersion(scriptDir);
|
|
22
22
|
const repoRoot = path.resolve(typeof flags['root-dir'] === 'string' ? flags['root-dir'] : process.cwd());
|
|
23
23
|
const dryRun = flags['dry-run'] === true;
|
|
24
|
-
// Read install-config.yaml so the user's original choices (tier) survive
|
|
25
|
-
// the update. Flag overrides win when present; missing config falls back to
|
|
26
|
-
// defaults (tier=full).
|
|
27
24
|
// ─── Resolve where artifacts live: in-repo (default) vs relocated ─────
|
|
28
25
|
// Mirrors init: standalone updates resolve IN-REPO by default (`allocate:false`
|
|
29
26
|
// + no registry entry ⇒ `artifactRoot === codeRoot === repoRoot`); desktop and
|
|
@@ -42,21 +39,25 @@ export async function runUpdate(flags) {
|
|
|
42
39
|
// can't know the relocated workspace path), so it is read from repoRoot — NOT
|
|
43
40
|
// the artifactRoot. Falls back to a workspace copy if present (none today).
|
|
44
41
|
const config = loadInstallConfig(resolveConfigPath(repoRoot)) ?? loadInstallConfig(resolveConfigPath(artifactRoot));
|
|
45
|
-
const tier = config?.tier ?? 'full';
|
|
46
42
|
const selectedAgents = config?.agents.selected;
|
|
43
|
+
warnUnknownSelectedAgents(selectedAgents);
|
|
47
44
|
const marker = path.join(artifactRoot, '.specrails', 'specrails-version');
|
|
48
45
|
if (!pathExists(marker)) {
|
|
49
46
|
throw new PrerequisiteError(`No existing specrails install detected at ${repoRoot}. Run \`npx specrails-core init\` first.`);
|
|
50
47
|
}
|
|
51
48
|
const previousVersion = readExistingVersion(artifactRoot);
|
|
49
|
+
const previousSelections = snapshotWorkspaceProviderSelections(artifactRoot);
|
|
52
50
|
// Provider can be FORCED via --provider (e.g. specrails-desktop updating one
|
|
53
51
|
// provider on a multi-provider workspace, where auto-detection would always
|
|
54
|
-
// resolve `.claude` first and never reach codex/gemini). Absent ⇒ auto-detect
|
|
52
|
+
// resolve `.claude` first and never reach codex/gemini/kimi). Absent ⇒ auto-detect
|
|
55
53
|
// from the existing install — byte-identical single-provider behaviour.
|
|
56
54
|
let provider;
|
|
57
55
|
if (typeof flags.provider === 'string') {
|
|
58
|
-
if (flags.provider !== 'claude' &&
|
|
59
|
-
|
|
56
|
+
if (flags.provider !== 'claude' &&
|
|
57
|
+
flags.provider !== 'codex' &&
|
|
58
|
+
flags.provider !== 'gemini' &&
|
|
59
|
+
flags.provider !== 'kimi') {
|
|
60
|
+
throw new InstallerError(`--provider value must be 'claude', 'codex', 'gemini', or 'kimi', got: ${flags.provider}`, 40);
|
|
60
61
|
}
|
|
61
62
|
provider = flags.provider;
|
|
62
63
|
step(`Update: using requested provider ${provider}`);
|
|
@@ -67,20 +68,39 @@ export async function runUpdate(flags) {
|
|
|
67
68
|
}
|
|
68
69
|
const { providerDir } = derivedPaths(provider);
|
|
69
70
|
ok(`Detected provider: ${provider} (${providerDir})`);
|
|
71
|
+
if (artifactRoot !== codeRoot) {
|
|
72
|
+
resolveArtifacts(repoRoot, {
|
|
73
|
+
allocate: true,
|
|
74
|
+
allocator: 'core-standalone',
|
|
75
|
+
home: process.env.SPECRAILS_REGISTRY_HOME,
|
|
76
|
+
providers: [provider],
|
|
77
|
+
coreVersion: currentVersion,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
70
80
|
// ─── Resolve --only scope ────────────────────────────────────────
|
|
71
81
|
const scope = resolveScope(flags.only);
|
|
72
82
|
if (scope === 'web-manager') {
|
|
73
83
|
warn('--only=web-manager is deprecated. The standalone web-manager has been retired; ' +
|
|
74
84
|
'specrails-desktop is the supported dashboard. Skipping with no changes.');
|
|
75
|
-
return { repoRoot, previousVersion, currentVersion, provider, dryRun, scope
|
|
85
|
+
return { repoRoot, previousVersion, currentVersion, provider, dryRun, scope };
|
|
76
86
|
}
|
|
77
|
-
if (
|
|
78
|
-
|
|
87
|
+
if (provider === 'kimi' &&
|
|
88
|
+
(scope === 'rules' || scope === 'agents')) {
|
|
89
|
+
throw new InstallerError(`--only=${scope} cannot safely refresh Kimi's linked direct-child skill ` +
|
|
90
|
+
'catalogue in isolation. Run `npx specrails-core update --provider kimi` ' +
|
|
91
|
+
'without --only so framework, live workspace, and manifest advance together.', 40);
|
|
79
92
|
}
|
|
80
93
|
if (dryRun) {
|
|
81
|
-
info(`Dry run: would update [${scope}
|
|
94
|
+
info(`Dry run: would update [${scope}] ` +
|
|
82
95
|
`for ${previousVersion ?? '(unknown)'} → ${currentVersion}.`);
|
|
83
|
-
return { repoRoot, previousVersion, currentVersion, provider, dryRun, scope
|
|
96
|
+
return { repoRoot, previousVersion, currentVersion, provider, dryRun, scope };
|
|
97
|
+
}
|
|
98
|
+
// ─── v5 migration: remove artefacts a pre-v5 install left behind ─────
|
|
99
|
+
// Runs BEFORE the re-scaffold so obsolete agents/commands/staging are gone
|
|
100
|
+
// before the fresh v5 template set is placed. Reserved paths (profiles, custom-*)
|
|
101
|
+
// and files the installer never owned are left untouched.
|
|
102
|
+
if (scope === 'all' || scope === 'core') {
|
|
103
|
+
migratePreV5Install({ artifactRoot, providerDir });
|
|
84
104
|
}
|
|
85
105
|
step(`Update: refreshing scaffold [scope=${scope}] (${previousVersion ?? '?'} → ${currentVersion})`);
|
|
86
106
|
if (scope === 'all' || scope === 'core') {
|
|
@@ -97,18 +117,23 @@ export async function runUpdate(flags) {
|
|
|
97
117
|
version: currentVersion,
|
|
98
118
|
selectedAgents,
|
|
99
119
|
});
|
|
100
|
-
|
|
120
|
+
reassembleWorkspaceProviders({
|
|
101
121
|
workspace: artifactRoot,
|
|
102
122
|
frameworkDir: fwDir,
|
|
103
|
-
provider,
|
|
104
|
-
providerDir,
|
|
105
123
|
version: currentVersion,
|
|
106
124
|
codeRoot,
|
|
107
125
|
scriptDir,
|
|
108
|
-
|
|
126
|
+
selectedProvider: provider,
|
|
127
|
+
selectedAgents: config?.provider === provider
|
|
128
|
+
? selectedAgents
|
|
129
|
+
: previousSelections[provider] ?? selectedAgents,
|
|
130
|
+
previousSelections,
|
|
109
131
|
// In-repo updates COPY real files; relocated workspaces symlink.
|
|
110
132
|
copyStatics: artifactRoot === codeRoot,
|
|
111
133
|
});
|
|
134
|
+
if (provider === 'kimi') {
|
|
135
|
+
await installOpenSpecProject(codeRoot, provider, artifactRoot);
|
|
136
|
+
}
|
|
112
137
|
ok(`Re-linked ${providerDir}/ at framework ${currentVersion} + rewrote manifest`);
|
|
113
138
|
}
|
|
114
139
|
else if (scope === 'rules' || scope === 'agents') {
|
|
@@ -118,6 +143,8 @@ export async function runUpdate(flags) {
|
|
|
118
143
|
scriptDir,
|
|
119
144
|
repoRoot: artifactRoot,
|
|
120
145
|
version: currentVersion,
|
|
146
|
+
providers: [provider],
|
|
147
|
+
primaryProvider: provider,
|
|
121
148
|
});
|
|
122
149
|
const { manifestPath, versionPath } = writeManifestFiles(artifactRoot, manifest);
|
|
123
150
|
ok(`Wrote ${path.relative(artifactRoot, manifestPath)}`);
|
|
@@ -127,14 +154,13 @@ export async function runUpdate(flags) {
|
|
|
127
154
|
info(`specrails-core ${previousVersion ?? '?'} → ${currentVersion}`);
|
|
128
155
|
// Terminal sentinel for programmatic consumers (see comment in init.ts).
|
|
129
156
|
ok('update complete');
|
|
130
|
-
return { repoRoot, previousVersion, currentVersion, provider, dryRun: false, scope
|
|
157
|
+
return { repoRoot, previousVersion, currentVersion, provider, dryRun: false, scope };
|
|
131
158
|
}
|
|
132
159
|
/**
|
|
133
160
|
* Re-applies a single subtree (rules or agents) from the bundled
|
|
134
|
-
* templates into
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
* does — those should only run on a true (re-)install.
|
|
161
|
+
* templates into the staging dir (.specrails/setup-templates/). Skips the
|
|
162
|
+
* agent-memory bootstrap that scaffoldInstallation does — that should only
|
|
163
|
+
* run on a true (re-)install.
|
|
138
164
|
*/
|
|
139
165
|
function rescaffoldComponent(component, args) {
|
|
140
166
|
const src = path.join(args.scriptDir, 'templates', component);
|
|
@@ -171,6 +197,8 @@ async function resolveExistingProvider(artifactRoot) {
|
|
|
171
197
|
return 'codex';
|
|
172
198
|
if (pathExists(path.join(artifactRoot, '.gemini')))
|
|
173
199
|
return 'gemini';
|
|
200
|
+
if (pathExists(path.join(artifactRoot, '.kimi-code')))
|
|
201
|
+
return 'kimi';
|
|
174
202
|
// None present — fall back to resolving via CLI availability.
|
|
175
203
|
const avail = await detectAvailability();
|
|
176
204
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../../src/installer/commands/update.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAExC,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AACrE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAA;AACxD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAExE,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../../src/installer/commands/update.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { info, ok } from '../util/logger.js';
|
|
3
|
+
import { pathExists, removePath } from '../util/fs.js';
|
|
4
|
+
import { isReservedPath, repoRelative } from '../util/paths.js';
|
|
5
|
+
/**
|
|
6
|
+
* Agent ids removed in v5. On update of a pre-v5 install their live `.md`
|
|
7
|
+
* files (installer-owned by the manifest contract) are deleted. `custom-*`
|
|
8
|
+
* agents are NEVER in this set and are protected by the reserved-paths gate.
|
|
9
|
+
*/
|
|
10
|
+
const REMOVED_AGENTS = [
|
|
11
|
+
'sr-product-manager',
|
|
12
|
+
'sr-product-analyst',
|
|
13
|
+
'sr-test-writer',
|
|
14
|
+
'sr-doc-sync',
|
|
15
|
+
'sr-merge-resolver',
|
|
16
|
+
'sr-frontend-developer',
|
|
17
|
+
'sr-backend-developer',
|
|
18
|
+
'sr-frontend-reviewer',
|
|
19
|
+
'sr-backend-reviewer',
|
|
20
|
+
'sr-security-reviewer',
|
|
21
|
+
'sr-performance-reviewer',
|
|
22
|
+
];
|
|
23
|
+
/** Command ids removed in v5 (deleted across every provider surface). */
|
|
24
|
+
const REMOVED_COMMANDS = [
|
|
25
|
+
'enrich',
|
|
26
|
+
'reconfig',
|
|
27
|
+
'vpc-drift',
|
|
28
|
+
'auto-propose-backlog-specs',
|
|
29
|
+
'get-backlog-specs',
|
|
30
|
+
'merge-resolve',
|
|
31
|
+
'test',
|
|
32
|
+
];
|
|
33
|
+
/**
|
|
34
|
+
* Removes artefacts a pre-v5 install left behind so the fresh v5 template set
|
|
35
|
+
* places into a clean tree. Strictly subtractive and reserved-path-safe:
|
|
36
|
+
*
|
|
37
|
+
* - Removed agent files (`.claude/agents/sr-*.md`, `.gemini/agents/sr-*.md`)
|
|
38
|
+
* - Removed command files (`<providerDir>/commands/specrails/*.md`) and their
|
|
39
|
+
* codex skill dirs (`.codex/skills/<cmd>/`)
|
|
40
|
+
* - The generated top-level skills for removed commands (`.claude/skills/<id>/`)
|
|
41
|
+
* - Obsolete staging subtrees under `.specrails/setup-templates/`
|
|
42
|
+
* (`personas/`, `skills/enrich/`, and the removed command/agent templates)
|
|
43
|
+
* - VPC persona output dirs (`<providerDir>/agents/personas/`)
|
|
44
|
+
*
|
|
45
|
+
* `custom-*.md` agents and `.specrails/profiles/**` are protected by
|
|
46
|
+
* {@link isReservedPath}; files the installer never owned are not enumerated
|
|
47
|
+
* here, so they are untouched. When at least one path is removed a migration
|
|
48
|
+
* summary is printed so the user sees exactly what changed.
|
|
49
|
+
*/
|
|
50
|
+
export function migratePreV5Install(input) {
|
|
51
|
+
const { artifactRoot, providerDir } = input;
|
|
52
|
+
const removed = [];
|
|
53
|
+
const remove = (abs) => {
|
|
54
|
+
if (!pathExists(abs))
|
|
55
|
+
return;
|
|
56
|
+
const rel = repoRelative(artifactRoot, abs);
|
|
57
|
+
if (isReservedPath(rel))
|
|
58
|
+
return;
|
|
59
|
+
removePath(abs);
|
|
60
|
+
removed.push(rel);
|
|
61
|
+
};
|
|
62
|
+
// Agents (claude + gemini both store `<providerDir>/agents/<id>.md`).
|
|
63
|
+
const agentsDir = path.join(artifactRoot, providerDir, 'agents');
|
|
64
|
+
for (const id of REMOVED_AGENTS) {
|
|
65
|
+
remove(path.join(agentsDir, `${id}.md`));
|
|
66
|
+
}
|
|
67
|
+
// VPC persona output directory (created by the retired enrich flow).
|
|
68
|
+
remove(path.join(agentsDir, 'personas'));
|
|
69
|
+
// Commands (claude/gemini command files) + codex skill dirs.
|
|
70
|
+
const commandsDir = path.join(artifactRoot, providerDir, 'commands', 'specrails');
|
|
71
|
+
const skillsDir = path.join(artifactRoot, providerDir, 'skills');
|
|
72
|
+
for (const id of REMOVED_COMMANDS) {
|
|
73
|
+
remove(path.join(commandsDir, `${id}.md`));
|
|
74
|
+
remove(path.join(commandsDir, `${id}.toml`));
|
|
75
|
+
remove(path.join(skillsDir, id));
|
|
76
|
+
}
|
|
77
|
+
// Top-level generated skills for removed backlog commands (claude).
|
|
78
|
+
for (const id of ['sr-get-backlog-specs', 'sr-auto-propose-backlog-specs']) {
|
|
79
|
+
remove(path.join(skillsDir, id));
|
|
80
|
+
}
|
|
81
|
+
// Codex rail skills for removed agents.
|
|
82
|
+
const railsDir = path.join(skillsDir, 'rails');
|
|
83
|
+
for (const id of REMOVED_AGENTS) {
|
|
84
|
+
remove(path.join(railsDir, id));
|
|
85
|
+
}
|
|
86
|
+
// Obsolete staging subtrees under setup-templates/ (the dir itself stays).
|
|
87
|
+
const staging = path.join(artifactRoot, '.specrails', 'setup-templates');
|
|
88
|
+
remove(path.join(staging, 'personas'));
|
|
89
|
+
remove(path.join(staging, 'skills', 'enrich'));
|
|
90
|
+
const stagingRails = path.join(staging, 'skills', 'rails');
|
|
91
|
+
for (const id of REMOVED_AGENTS) {
|
|
92
|
+
remove(path.join(stagingRails, id));
|
|
93
|
+
}
|
|
94
|
+
const stagingAgents = path.join(staging, 'agents');
|
|
95
|
+
for (const id of REMOVED_AGENTS) {
|
|
96
|
+
remove(path.join(stagingAgents, `${id}.md`));
|
|
97
|
+
}
|
|
98
|
+
const stagingCommands = path.join(staging, 'commands', 'specrails');
|
|
99
|
+
for (const id of REMOVED_COMMANDS) {
|
|
100
|
+
remove(path.join(stagingCommands, `${id}.md`));
|
|
101
|
+
}
|
|
102
|
+
// Removed settings template (perf thresholds).
|
|
103
|
+
remove(path.join(staging, 'settings', 'perf-thresholds.yml'));
|
|
104
|
+
if (removed.length === 0)
|
|
105
|
+
return;
|
|
106
|
+
info(`v5 migration: removed ${removed.length} obsolete artefact(s) from a pre-v5 install:`);
|
|
107
|
+
for (const rel of removed.sort())
|
|
108
|
+
info(` - ${rel}`);
|
|
109
|
+
ok('Removed v4 artefacts — agents beyond the core trio now come from profiles (custom-*.md).');
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Test helper: enumerate removed agent/command ids so specs can assert the
|
|
113
|
+
* migration set stays in lock-step with the deleted templates.
|
|
114
|
+
*/
|
|
115
|
+
export const V5_REMOVED = {
|
|
116
|
+
agents: REMOVED_AGENTS,
|
|
117
|
+
commands: REMOVED_COMMANDS,
|
|
118
|
+
};
|
|
119
|
+
//# sourceMappingURL=v5-migration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"v5-migration.js","sourceRoot":"","sources":["../../../src/installer/commands/v5-migration.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { InstallerError } from '../util/errors.js';
|
|
3
|
+
import { isDir, pathExists } from '../util/fs.js';
|
|
4
|
+
import { readRegistryOrEmpty } from '../util/registry.js';
|
|
5
|
+
import { derivedPaths, } from './provider-detect.js';
|
|
6
|
+
import { ensureCurrentSymlink, frameworkMaterializationProblem, frameworkStampPath, installFramework, } from './scaffold.js';
|
|
7
|
+
/**
|
|
8
|
+
* Stable provider order for the global framework store. `framework/current` is
|
|
9
|
+
* shared by every relocated workspace, so a version transition must carry
|
|
10
|
+
* forward every provider that can still have live links through that pointer.
|
|
11
|
+
*/
|
|
12
|
+
export const FRAMEWORK_PROVIDERS = [
|
|
13
|
+
'claude',
|
|
14
|
+
'codex',
|
|
15
|
+
'gemini',
|
|
16
|
+
'kimi',
|
|
17
|
+
];
|
|
18
|
+
function isProvider(value) {
|
|
19
|
+
return (value === 'claude' ||
|
|
20
|
+
value === 'codex' ||
|
|
21
|
+
value === 'gemini' ||
|
|
22
|
+
value === 'kimi');
|
|
23
|
+
}
|
|
24
|
+
function stableProviders(values) {
|
|
25
|
+
const wanted = new Set(values);
|
|
26
|
+
return FRAMEWORK_PROVIDERS.filter((provider) => wanted.has(provider));
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Discover providers represented by a framework version.
|
|
30
|
+
*
|
|
31
|
+
* A provider is included when either its subtree or its stamp exists. For the
|
|
32
|
+
* current version this is deliberately conservative: an interrupted/legacy
|
|
33
|
+
* materialization without a stamp may still have live workspace symlinks, so
|
|
34
|
+
* the next version must carry that provider forward rather than dropping it.
|
|
35
|
+
*/
|
|
36
|
+
export function discoverFrameworkProviders(frameworkDir, version) {
|
|
37
|
+
const versionDir = path.join(frameworkDir, version);
|
|
38
|
+
return FRAMEWORK_PROVIDERS.filter((provider) => {
|
|
39
|
+
const { providerDir } = derivedPaths(provider);
|
|
40
|
+
return (pathExists(path.join(versionDir, providerDir)) ||
|
|
41
|
+
pathExists(frameworkStampPath(versionDir, providerDir)));
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Compute the provider set that MUST exist in a destination version before the
|
|
46
|
+
* process may move the global `current` pointer:
|
|
47
|
+
*
|
|
48
|
+
* 1. providers requested by this operation;
|
|
49
|
+
* 2. every supported provider recorded by any project in registry.json;
|
|
50
|
+
* 3. every provider represented by the version currently serving workspaces.
|
|
51
|
+
*
|
|
52
|
+
* Taking the global registry union (not just the active project) is essential:
|
|
53
|
+
* `framework/current` is global, while provider inventories are per project.
|
|
54
|
+
*/
|
|
55
|
+
export function resolveRequiredFrameworkProviders(input) {
|
|
56
|
+
const required = new Set(input.requested ?? []);
|
|
57
|
+
const registry = readRegistryOrEmpty(input.registryHome);
|
|
58
|
+
for (const entry of Object.values(registry.projects)) {
|
|
59
|
+
for (const provider of entry.providers ?? []) {
|
|
60
|
+
if (isProvider(provider))
|
|
61
|
+
required.add(provider);
|
|
62
|
+
}
|
|
63
|
+
if (isProvider(entry.primaryProvider))
|
|
64
|
+
required.add(entry.primaryProvider);
|
|
65
|
+
}
|
|
66
|
+
for (const provider of discoverFrameworkProviders(input.frameworkDir, 'current')) {
|
|
67
|
+
required.add(provider);
|
|
68
|
+
}
|
|
69
|
+
return stableProviders(required);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Fail closed when a destination version is missing or only partially
|
|
73
|
+
* materialized. A valid provider requires BOTH its provider subtree and the
|
|
74
|
+
* final stamp written after scaffold completion, with matching version/provider
|
|
75
|
+
* fields. The caller may supply an empty requirement only for a first install;
|
|
76
|
+
* in that case at least one complete provider must be discoverable in target.
|
|
77
|
+
*/
|
|
78
|
+
export function assertFrameworkVersionComplete(frameworkDir, version, requiredProviders) {
|
|
79
|
+
const versionDir = path.join(frameworkDir, version);
|
|
80
|
+
if (!isDir(versionDir)) {
|
|
81
|
+
throw new InstallerError(`framework version ${version} is not materialized at ${versionDir}`, 41);
|
|
82
|
+
}
|
|
83
|
+
const required = requiredProviders.length > 0
|
|
84
|
+
? stableProviders(requiredProviders)
|
|
85
|
+
: discoverFrameworkProviders(frameworkDir, version);
|
|
86
|
+
if (required.length === 0) {
|
|
87
|
+
throw new InstallerError(`framework version ${version} is incomplete: no provider was materialized`, 41);
|
|
88
|
+
}
|
|
89
|
+
const problems = [];
|
|
90
|
+
for (const provider of required) {
|
|
91
|
+
const { providerDir } = derivedPaths(provider);
|
|
92
|
+
const problem = frameworkMaterializationProblem(versionDir, version, provider, providerDir);
|
|
93
|
+
if (problem)
|
|
94
|
+
problems.push(`${provider}: ${problem}`);
|
|
95
|
+
}
|
|
96
|
+
if (problems.length > 0) {
|
|
97
|
+
throw new InstallerError(`framework version ${version} is incomplete; refusing to move current: ` +
|
|
98
|
+
problems.join('; '), 41);
|
|
99
|
+
}
|
|
100
|
+
return required;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Materialize a complete destination version and expose it with ONE atomic
|
|
104
|
+
* pointer swap. No call in the provider loop can move `current`; if any provider
|
|
105
|
+
* fails, existing workspaces continue resolving through the previous version.
|
|
106
|
+
*/
|
|
107
|
+
export function materializeFrameworkVersion(input) {
|
|
108
|
+
const required = resolveRequiredFrameworkProviders(input);
|
|
109
|
+
if (required.length === 0) {
|
|
110
|
+
throw new InstallerError(`framework version ${input.version} has no requested or registered provider`, 41);
|
|
111
|
+
}
|
|
112
|
+
for (const provider of required) {
|
|
113
|
+
installFramework({
|
|
114
|
+
scriptDir: input.scriptDir,
|
|
115
|
+
frameworkDir: input.frameworkDir,
|
|
116
|
+
provider,
|
|
117
|
+
providerDir: derivedPaths(provider).providerDir,
|
|
118
|
+
version: input.version,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
assertFrameworkVersionComplete(input.frameworkDir, input.version, required);
|
|
122
|
+
ensureCurrentSymlink(input.frameworkDir, input.version);
|
|
123
|
+
return required;
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=framework-lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"framework-lifecycle.js","sourceRoot":"","sources":["../../../src/installer/phases/framework-lifecycle.ts"],"names":[],"mappings":"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"}
|