specrails-core 4.1.1 → 4.2.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 +4 -4
- package/bin/specrails-core.mjs +302 -0
- package/commands/doctor.md +5 -5
- package/commands/enrich.md +9 -9
- package/dist/installer/cli.js +167 -0
- package/dist/installer/cli.js.map +1 -0
- package/dist/installer/commands/doctor.js +144 -0
- package/dist/installer/commands/doctor.js.map +1 -0
- package/dist/installer/commands/init.js +182 -0
- package/dist/installer/commands/init.js.map +1 -0
- package/dist/installer/commands/perf-check.js +16 -0
- package/dist/installer/commands/perf-check.js.map +1 -0
- package/dist/installer/commands/update.js +170 -0
- package/dist/installer/commands/update.js.map +1 -0
- package/dist/installer/phases/install-config.js +120 -0
- package/dist/installer/phases/install-config.js.map +1 -0
- package/dist/installer/phases/manifest.js +93 -0
- package/dist/installer/phases/manifest.js.map +1 -0
- package/dist/installer/phases/prereqs.js +116 -0
- package/dist/installer/phases/prereqs.js.map +1 -0
- package/dist/installer/phases/provider-detect.js +111 -0
- package/dist/installer/phases/provider-detect.js.map +1 -0
- package/dist/installer/phases/scaffold.js +373 -0
- package/dist/installer/phases/scaffold.js.map +1 -0
- package/dist/installer/util/errors.js +79 -0
- package/dist/installer/util/errors.js.map +1 -0
- package/dist/installer/util/exec.js +151 -0
- package/dist/installer/util/exec.js.map +1 -0
- package/dist/installer/util/fs.js +153 -0
- package/dist/installer/util/fs.js.map +1 -0
- package/dist/installer/util/git.js +113 -0
- package/dist/installer/util/git.js.map +1 -0
- package/dist/installer/util/logger.js +55 -0
- package/dist/installer/util/logger.js.map +1 -0
- package/dist/installer/util/paths.js +66 -0
- package/dist/installer/util/paths.js.map +1 -0
- package/dist/installer/util/prompts.js +49 -0
- package/dist/installer/util/prompts.js.map +1 -0
- package/dist/installer/util/template.js +60 -0
- package/dist/installer/util/template.js.map +1 -0
- package/docs/deployment.md +2 -1
- package/docs/installation.md +6 -3
- package/docs/testing/test-matrix-codex.md +19 -11
- package/docs/updating.md +24 -49
- package/docs/user-docs/faq.md +1 -1
- package/docs/windows.md +53 -0
- package/{templates/settings/integration-contract.json → integration-contract.json} +2 -2
- package/package.json +25 -10
- package/pinned-versions.json +4 -0
- package/schemas/profile.v1.json +11 -3
- package/templates/agents/sr-architect.md +1 -1
- package/templates/agents/sr-reviewer.md +1 -1
- package/templates/commands/specrails/compat-check.md +3 -3
- package/templates/commands/specrails/doctor.md +5 -5
- package/templates/commands/specrails/enrich.md +9 -9
- package/templates/commands/specrails/reconfig.md +2 -2
- package/templates/commands/specrails/refactor-recommender.md +2 -2
- package/templates/commands/specrails/vpc-drift.md +1 -1
- package/templates/skills/sr-compat-check/SKILL.md +3 -3
- package/templates/skills/sr-refactor-recommender/SKILL.md +2 -2
- package/bin/doctor.sh +0 -127
- package/bin/perf-check.sh +0 -21
- package/bin/specrails-core.js +0 -262
- package/commands/setup.md +0 -1461
- package/install.sh +0 -1231
- package/update.sh +0 -870
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { appendFileSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { info, ok, fail as logFail, rawOut } from '../util/logger.js';
|
|
5
|
+
import { commandExists, runCommand } from '../util/exec.js';
|
|
6
|
+
import { isDir, isFile, listDir, mkdirp } from '../util/fs.js';
|
|
7
|
+
import { assertClaudeAuthenticated } from '../phases/provider-detect.js';
|
|
8
|
+
import { derivedPaths } from '../phases/provider-detect.js';
|
|
9
|
+
export async function runDoctor(flags = {}) {
|
|
10
|
+
const projectRoot = path.resolve(typeof flags['root-dir'] === 'string' ? flags['root-dir'] : process.cwd());
|
|
11
|
+
rawOut('\nspecrails doctor\n\n');
|
|
12
|
+
const results = [];
|
|
13
|
+
const addPass = (message) => {
|
|
14
|
+
results.push({ kind: 'pass', message });
|
|
15
|
+
};
|
|
16
|
+
const addFail = (message, fix) => {
|
|
17
|
+
results.push({ kind: 'fail', message, fix });
|
|
18
|
+
};
|
|
19
|
+
const provider = resolveInstalledProvider(projectRoot);
|
|
20
|
+
const { providerDir, instructionsFile } = derivedPaths(provider);
|
|
21
|
+
// Check 1: Claude Code CLI
|
|
22
|
+
if (await commandExists('claude')) {
|
|
23
|
+
const path_ = await resolveCommandPath('claude');
|
|
24
|
+
addPass(`Claude Code CLI: found${path_ ? ` (${path_})` : ''}`);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
addFail('Claude Code CLI: not found', 'Install Claude Code: https://claude.ai/download');
|
|
28
|
+
}
|
|
29
|
+
// Check 2: Claude authentication (only meaningful if the CLI is installed)
|
|
30
|
+
if (await commandExists('claude')) {
|
|
31
|
+
try {
|
|
32
|
+
await assertClaudeAuthenticated({ skipPrereqs: false });
|
|
33
|
+
addPass('Claude: authenticated');
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
addFail('Claude: not authenticated', 'Option 1: claude config set api_key <your-key> | Option 2: claude auth login');
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// Check 3: Agent files present in the active provider directory.
|
|
40
|
+
const agentsDir = path.join(projectRoot, providerDir, 'agents');
|
|
41
|
+
if (isDir(agentsDir)) {
|
|
42
|
+
const agentFiles = findInstalledAgentFiles(agentsDir, provider);
|
|
43
|
+
if (agentFiles.length >= 1) {
|
|
44
|
+
const names = agentFiles
|
|
45
|
+
.map((f) => path.basename(f, path.extname(f)))
|
|
46
|
+
.join(', ');
|
|
47
|
+
addPass(`Agent files: ${agentFiles.length} agent(s) found in ${providerDir}/agents (${names})`);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
addFail(`Agent files: ${providerDir}/agents exists but no generated agent files were found`, 'Run specrails-core init to set up agents');
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
addFail(`Agent files: ${providerDir}/agents directory not found`, 'Run specrails-core init to set up agents');
|
|
55
|
+
}
|
|
56
|
+
// Check 4: provider instructions file present
|
|
57
|
+
if (isFile(path.join(projectRoot, instructionsFile))) {
|
|
58
|
+
addPass(`${instructionsFile}: present`);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
addFail(`${instructionsFile}: missing`, provider === 'codex'
|
|
62
|
+
? 'Run specrails-core init to regenerate the provider instructions.'
|
|
63
|
+
: 'Run /specrails:enrich inside Claude Code to regenerate.');
|
|
64
|
+
}
|
|
65
|
+
// Check 5: Git initialized
|
|
66
|
+
if (isDir(path.join(projectRoot, '.git'))) {
|
|
67
|
+
addPass('Git: initialized');
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
addFail('Git: not a git repository', 'Initialize with: git init');
|
|
71
|
+
}
|
|
72
|
+
// Check 6: npm present
|
|
73
|
+
if (await commandExists('npm')) {
|
|
74
|
+
try {
|
|
75
|
+
const { stdout } = await runCommand('npm', ['--version'], { inherit: false });
|
|
76
|
+
addPass(`npm: found (v${stdout.trim()})`);
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
addPass('npm: found');
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
addFail('npm: not found', 'Install npm: https://docs.npmjs.com/downloading-and-installing-node-js-and-npm');
|
|
84
|
+
}
|
|
85
|
+
// Render results in order.
|
|
86
|
+
for (const r of results) {
|
|
87
|
+
if (r.kind === 'pass')
|
|
88
|
+
ok(r.message);
|
|
89
|
+
else
|
|
90
|
+
logFail(`${r.message}\n Fix: ${r.fix ?? ''}`);
|
|
91
|
+
}
|
|
92
|
+
const passed = results.filter((r) => r.kind === 'pass').length;
|
|
93
|
+
const failed = results.length - passed;
|
|
94
|
+
rawOut('\n');
|
|
95
|
+
if (failed === 0) {
|
|
96
|
+
info(`All ${passed + failed} checks passed. Run /specrails:get-backlog-specs to get started.`);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
rawOut(`${failed} check(s) failed.\n`);
|
|
100
|
+
}
|
|
101
|
+
rawOut('\n');
|
|
102
|
+
appendDoctorLog(passed, failed);
|
|
103
|
+
return { passed, failed, results };
|
|
104
|
+
}
|
|
105
|
+
async function resolveCommandPath(cmd) {
|
|
106
|
+
const probe = process.platform === 'win32' ? 'where' : 'which';
|
|
107
|
+
try {
|
|
108
|
+
const { stdout } = await runCommand(probe, [cmd], { inherit: false });
|
|
109
|
+
const first = stdout.trim().split(/\r?\n/)[0];
|
|
110
|
+
return first && first.length > 0 ? first : null;
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function resolveInstalledProvider(projectRoot) {
|
|
117
|
+
if (isDir(path.join(projectRoot, '.codex')))
|
|
118
|
+
return 'codex';
|
|
119
|
+
return 'claude';
|
|
120
|
+
}
|
|
121
|
+
function findInstalledAgentFiles(root, provider) {
|
|
122
|
+
if (!isDir(root))
|
|
123
|
+
return [];
|
|
124
|
+
const matcher = provider === 'codex'
|
|
125
|
+
? /^(custom-|sr-).+\.toml$/
|
|
126
|
+
: /^(custom-|sr-).+\.md$/;
|
|
127
|
+
return listDir(root)
|
|
128
|
+
.filter((entry) => isFile(entry) && matcher.test(path.basename(entry)))
|
|
129
|
+
.sort();
|
|
130
|
+
}
|
|
131
|
+
function appendDoctorLog(passed, failed) {
|
|
132
|
+
try {
|
|
133
|
+
const logDir = path.join(homedir(), '.specrails');
|
|
134
|
+
mkdirp(logDir);
|
|
135
|
+
const logFile = path.join(logDir, 'doctor.log');
|
|
136
|
+
const stamp = new Date().toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
137
|
+
const total = passed + failed;
|
|
138
|
+
appendFileSync(logFile, `${stamp} checks=${total} passed=${passed} failed=${failed}\n`);
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
// Best-effort logging — never fail doctor because we can't write the log.
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/installer/commands/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import { InstallerError } from '../util/errors.js';
|
|
4
|
+
import { runCommand } from '../util/exec.js';
|
|
5
|
+
import { info, ok, step } from '../util/logger.js';
|
|
6
|
+
import { readTextFile, pathExists } from '../util/fs.js';
|
|
7
|
+
import { loadInstallConfig, resolveConfigPath, } from '../phases/install-config.js';
|
|
8
|
+
import { buildManifest, writeManifestFiles } from '../phases/manifest.js';
|
|
9
|
+
import { checkPrerequisites } from '../phases/prereqs.js';
|
|
10
|
+
import { derivedPaths } from '../phases/provider-detect.js';
|
|
11
|
+
import { scaffoldInstallation } from '../phases/scaffold.js';
|
|
12
|
+
/**
|
|
13
|
+
* Entry called by cli.ts. Returns a {@link InitResult} on success;
|
|
14
|
+
* throws a typed error (translated to an exit code by the outer CLI)
|
|
15
|
+
* on failure.
|
|
16
|
+
*/
|
|
17
|
+
export async function runInit(flags) {
|
|
18
|
+
const scriptDir = resolveScriptDir();
|
|
19
|
+
const version = readVersion(scriptDir);
|
|
20
|
+
const repoRoot = path.resolve(typeof flags['root-dir'] === 'string' ? flags['root-dir'] : process.cwd());
|
|
21
|
+
const autoYes = flags.yes === true;
|
|
22
|
+
const skipPrereqs = process.env.SPECRAILS_SKIP_PREREQS === '1';
|
|
23
|
+
// --from-config: read provider + tier + agent_teams from yaml.
|
|
24
|
+
const fromConfigFlag = flags['from-config'];
|
|
25
|
+
let providerHint;
|
|
26
|
+
let tierHint;
|
|
27
|
+
let agentTeamsHint = flags['agent-teams'] === true;
|
|
28
|
+
let selectedAgentsHint;
|
|
29
|
+
if (fromConfigFlag !== undefined) {
|
|
30
|
+
const explicitPath = typeof fromConfigFlag === 'string' ? fromConfigFlag : undefined;
|
|
31
|
+
const resolved = resolveConfigPath(repoRoot, explicitPath);
|
|
32
|
+
const config = loadInstallConfig(resolved);
|
|
33
|
+
if (config) {
|
|
34
|
+
providerHint = config.provider;
|
|
35
|
+
tierHint = config.tier;
|
|
36
|
+
if (config.agent_teams)
|
|
37
|
+
agentTeamsHint = true;
|
|
38
|
+
selectedAgentsHint = config.agents.selected;
|
|
39
|
+
info(`Loaded install config from ${resolved}`);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
info(`install-config.yaml not found at ${resolved} — falling back to auto-detection`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
else if (typeof flags.provider === 'string') {
|
|
46
|
+
if (flags.provider === 'codex') {
|
|
47
|
+
throw new InstallerError('Codex (OpenAI) support is coming soon — currently being tested in our lab. ' +
|
|
48
|
+
'Use --provider claude for now.', 40);
|
|
49
|
+
}
|
|
50
|
+
if (flags.provider !== 'claude') {
|
|
51
|
+
throw new InstallerError(`--provider value must be 'claude', got: ${flags.provider}`, 40);
|
|
52
|
+
}
|
|
53
|
+
providerHint = 'claude';
|
|
54
|
+
}
|
|
55
|
+
if (flags.quick === true) {
|
|
56
|
+
tierHint = 'quick';
|
|
57
|
+
}
|
|
58
|
+
// ─── Phase 1 ──────────────────────────────────────────────────────────
|
|
59
|
+
step('Phase 1: Checking prerequisites');
|
|
60
|
+
const prereqs = await checkPrerequisites({
|
|
61
|
+
repoRoot,
|
|
62
|
+
autoYes,
|
|
63
|
+
explicitProvider: providerHint,
|
|
64
|
+
skipPrereqs,
|
|
65
|
+
});
|
|
66
|
+
// ─── Phase 2 + 3 ──────────────────────────────────────────────────────
|
|
67
|
+
step('Phase 2 & 3: Installing specrails artifacts');
|
|
68
|
+
const { providerDir } = derivedPaths(prereqs.provider);
|
|
69
|
+
scaffoldInstallation({
|
|
70
|
+
scriptDir,
|
|
71
|
+
repoRoot,
|
|
72
|
+
provider: prereqs.provider,
|
|
73
|
+
providerDir,
|
|
74
|
+
agentTeams: agentTeamsHint,
|
|
75
|
+
tier: tierHint ?? 'full',
|
|
76
|
+
selectedAgents: selectedAgentsHint,
|
|
77
|
+
});
|
|
78
|
+
// ─── Phase 3b — manifest ──────────────────────────────────────────────
|
|
79
|
+
step('Phase 3b: Writing manifest');
|
|
80
|
+
const manifest = buildManifest({ scriptDir, repoRoot, version });
|
|
81
|
+
const { manifestPath, versionPath } = writeManifestFiles(repoRoot, manifest);
|
|
82
|
+
ok(`Wrote ${path.relative(repoRoot, manifestPath)}`);
|
|
83
|
+
ok(`Wrote ${path.relative(repoRoot, versionPath)}`);
|
|
84
|
+
await installOpenSpecProject(repoRoot, prereqs.provider);
|
|
85
|
+
const tier = tierHint ?? 'full';
|
|
86
|
+
if (tier === 'full') {
|
|
87
|
+
step('Next steps');
|
|
88
|
+
info('Run `/specrails:enrich` inside Claude Code to complete your setup.');
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
step('Installation complete');
|
|
92
|
+
info('Quick tier: agents + rules were placed directly; enrich not required.');
|
|
93
|
+
}
|
|
94
|
+
// Terminal sentinel for programmatic consumers (specrails-hub's setup
|
|
95
|
+
// wizard matches this exact line via regex to mark the "init complete"
|
|
96
|
+
// checkpoint). Keep the spelling stable.
|
|
97
|
+
ok('init complete');
|
|
98
|
+
return {
|
|
99
|
+
repoRoot,
|
|
100
|
+
provider: prereqs.provider,
|
|
101
|
+
tier,
|
|
102
|
+
agentTeams: agentTeamsHint,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Resolves the package root (where VERSION, templates/, commands/ live).
|
|
107
|
+
* - Published: `<pkg>/dist/installer/commands/init.js`
|
|
108
|
+
* - Source: `<repo>/src/installer/commands/init.ts`
|
|
109
|
+
* Both cases are three levels deep (commands → installer → src|dist → root).
|
|
110
|
+
*
|
|
111
|
+
* The SPECRAILS_CORE_SCRIPT_DIR env var is an override for tests that
|
|
112
|
+
* need to inject a fake package directory.
|
|
113
|
+
*/
|
|
114
|
+
function resolveScriptDir() {
|
|
115
|
+
const override = process.env.SPECRAILS_CORE_SCRIPT_DIR;
|
|
116
|
+
if (override && override.length > 0)
|
|
117
|
+
return path.resolve(override);
|
|
118
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
119
|
+
return path.resolve(here, '..', '..', '..');
|
|
120
|
+
}
|
|
121
|
+
function readVersion(scriptDir) {
|
|
122
|
+
const p = path.join(scriptDir, 'VERSION');
|
|
123
|
+
if (!pathExists(p))
|
|
124
|
+
return 'unknown';
|
|
125
|
+
try {
|
|
126
|
+
return readTextFile(p).trim() || 'unknown';
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return 'unknown';
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
function readPinnedVersion(scriptDir, key, fallback) {
|
|
133
|
+
const p = path.join(scriptDir, 'pinned-versions.json');
|
|
134
|
+
if (!pathExists(p))
|
|
135
|
+
return fallback;
|
|
136
|
+
try {
|
|
137
|
+
const parsed = JSON.parse(readTextFile(p));
|
|
138
|
+
const value = parsed[key];
|
|
139
|
+
return typeof value === 'string' && value.length > 0 ? value : fallback;
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
return fallback;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
async function installOpenSpecProject(repoRoot, provider) {
|
|
146
|
+
if (process.env.SPECRAILS_SKIP_OPENSPEC_INIT === '1') {
|
|
147
|
+
info('Skipping OpenSpec project init (SPECRAILS_SKIP_OPENSPEC_INIT=1)');
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
// Tests can point this at a fake binary on PATH to avoid hitting npm.
|
|
151
|
+
// Default: invoke through npx so users never need a global install.
|
|
152
|
+
const override = process.env.SPECRAILS_OPENSPEC_BIN;
|
|
153
|
+
const pinnedVersion = readPinnedVersion(resolveScriptDir(), 'openspec', '1.3.1');
|
|
154
|
+
const { bin, args } = override
|
|
155
|
+
? { bin: override, args: ['init', '--tools', provider, repoRoot] }
|
|
156
|
+
: {
|
|
157
|
+
bin: 'npx',
|
|
158
|
+
args: [
|
|
159
|
+
'--yes',
|
|
160
|
+
'-p',
|
|
161
|
+
`@fission-ai/openspec@${pinnedVersion}`,
|
|
162
|
+
'--',
|
|
163
|
+
'openspec',
|
|
164
|
+
'init',
|
|
165
|
+
'--tools',
|
|
166
|
+
provider,
|
|
167
|
+
repoRoot,
|
|
168
|
+
],
|
|
169
|
+
};
|
|
170
|
+
step('Phase 3c: Installing OpenSpec');
|
|
171
|
+
try {
|
|
172
|
+
await runCommand(bin, args, {
|
|
173
|
+
cwd: repoRoot,
|
|
174
|
+
timeoutMs: 180000,
|
|
175
|
+
});
|
|
176
|
+
ok(`OpenSpec project files installed (${provider})`);
|
|
177
|
+
}
|
|
178
|
+
catch (err) {
|
|
179
|
+
throw new InstallerError(`OpenSpec init failed: ${err.message}`, 50);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/installer/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAExC,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAA;AAClD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAExD,OAAO,EAGL,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,6BAA6B,CAAA;AACpC,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AAgC5D;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,KAAgB;IAC5C,MAAM,SAAS,GAAG,gBAAgB,EAAE,CAAA;IACpC,MAAM,OAAO,GAAG,WAAW,CAAC,SAAS,CAAC,CAAA;IAEtC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAC3B,OAAO,KAAK,CAAC,UAAU,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAC1E,CAAA;IACD,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,KAAK,IAAI,CAAA;IAClC,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,KAAK,GAAG,CAAA;IAE9D,+DAA+D;IAC/D,MAAM,cAAc,GAAG,KAAK,CAAC,aAAa,CAAC,CAAA;IAC3C,IAAI,YAAkC,CAAA;IACtC,IAAI,QAA0B,CAAA;IAC9B,IAAI,cAAc,GAAG,KAAK,CAAC,aAAa,CAAC,KAAK,IAAI,CAAA;IAClD,IAAI,kBAAwC,CAAA;IAE5C,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,YAAY,GAAG,OAAO,cAAc,KAAK,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CAAA;QACpF,MAAM,QAAQ,GAAG,iBAAiB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAA;QAC1D,MAAM,MAAM,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAA;QAC1C,IAAI,MAAM,EAAE,CAAC;YACX,YAAY,GAAG,MAAM,CAAC,QAAQ,CAAA;YAC9B,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAA;YACtB,IAAI,MAAM,CAAC,WAAW;gBAAE,cAAc,GAAG,IAAI,CAAA;YAC7C,kBAAkB,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAA;YAC3C,IAAI,CAAC,8BAA8B,QAAQ,EAAE,CAAC,CAAA;QAChD,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,oCAAoC,QAAQ,mCAAmC,CAAC,CAAA;QACvF,CAAC;IACH,CAAC;SAAM,IAAI,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC9C,IAAI,KAAK,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;YAC/B,MAAM,IAAI,cAAc,CACtB,6EAA6E;gBAC3E,gCAAgC,EAClC,EAAE,CACH,CAAA;QACH,CAAC;QACD,IAAI,KAAK,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAChC,MAAM,IAAI,cAAc,CAAC,2CAA2C,KAAK,CAAC,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAA;QAC3F,CAAC;QACD,YAAY,GAAG,QAAQ,CAAA;IACzB,CAAC;IAED,IAAI,KAAK,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;QACzB,QAAQ,GAAG,OAAO,CAAA;IACpB,CAAC;IAED,yEAAyE;IACzE,IAAI,CAAC,iCAAiC,CAAC,CAAA;IACvC,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC;QACvC,QAAQ;QACR,OAAO;QACP,gBAAgB,EAAE,YAAY;QAC9B,WAAW;KACZ,CAAC,CAAA;IAEF,yEAAyE;IACzE,IAAI,CAAC,6CAA6C,CAAC,CAAA;IACnD,MAAM,EAAE,WAAW,EAAE,GAAG,YAAY,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IACtD,oBAAoB,CAAC;QACnB,SAAS;QACT,QAAQ;QACR,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,WAAW;QACX,UAAU,EAAE,cAAc;QAC1B,IAAI,EAAE,QAAQ,IAAI,MAAM;QACxB,cAAc,EAAE,kBAAkB;KACnC,CAAC,CAAA;IAEF,yEAAyE;IACzE,IAAI,CAAC,4BAA4B,CAAC,CAAA;IAClC,MAAM,QAAQ,GAAG,aAAa,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAA;IAChE,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,GAAG,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;IAC5E,EAAE,CAAC,SAAS,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC,EAAE,CAAC,CAAA;IACpD,EAAE,CAAC,SAAS,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,EAAE,CAAC,CAAA;IAEnD,MAAM,sBAAsB,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;IAExD,MAAM,IAAI,GAAS,QAAQ,IAAI,MAAM,CAAA;IACrC,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACpB,IAAI,CAAC,YAAY,CAAC,CAAA;QAClB,IAAI,CAAC,oEAAoE,CAAC,CAAA;IAC5E,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,uBAAuB,CAAC,CAAA;QAC7B,IAAI,CAAC,uEAAuE,CAAC,CAAA;IAC/E,CAAC;IACD,sEAAsE;IACtE,uEAAuE;IACvE,yCAAyC;IACzC,EAAE,CAAC,eAAe,CAAC,CAAA;IAEnB,OAAO;QACL,QAAQ;QACR,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,IAAI;QACJ,UAAU,EAAE,cAAc;KAC3B,CAAA;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,gBAAgB;IACvB,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAA;IACtD,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IAClE,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;IACzD,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;AAC7C,CAAC;AAED,SAAS,WAAW,CAAC,SAAiB;IACpC,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;IACzC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAAE,OAAO,SAAS,CAAA;IACpC,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,SAAS,CAAA;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC;AAED,SAAS,iBAAiB,CAAC,SAAiB,EAAE,GAAW,EAAE,QAAgB;IACzE,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,sBAAsB,CAAC,CAAA;IACtD,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAAE,OAAO,QAAQ,CAAA;IACnC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,CAA4B,CAAA;QACrE,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;QACzB,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAA;IACzE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAA;IACjB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,sBAAsB,CAAC,QAAgB,EAAE,QAAkB;IACxE,IAAI,OAAO,CAAC,GAAG,CAAC,4BAA4B,KAAK,GAAG,EAAE,CAAC;QACrD,IAAI,CAAC,iEAAiE,CAAC,CAAA;QACvE,OAAM;IACR,CAAC;IAED,sEAAsE;IACtE,oEAAoE;IACpE,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAA;IACnD,MAAM,aAAa,GAAG,iBAAiB,CAAC,gBAAgB,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,CAAA;IAChF,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,QAAQ;QAC5B,CAAC,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE;QAClE,CAAC,CAAC;YACE,GAAG,EAAE,KAAK;YACV,IAAI,EAAE;gBACJ,OAAO;gBACP,IAAI;gBACJ,wBAAwB,aAAa,EAAE;gBACvC,IAAI;gBACJ,UAAU;gBACV,MAAM;gBACN,SAAS;gBACT,QAAQ;gBACR,QAAQ;aACT;SACF,CAAA;IAEL,IAAI,CAAC,+BAA+B,CAAC,CAAA;IACrC,IAAI,CAAC;QACH,MAAM,UAAU,CAAC,GAAG,EAAE,IAAI,EAAE;YAC1B,GAAG,EAAE,QAAQ;YACb,SAAS,EAAE,MAAM;SAClB,CAAC,CAAA;QACF,EAAE,CAAC,qCAAqC,QAAQ,GAAG,CAAC,CAAA;IACtD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,cAAc,CACtB,yBAA0B,GAAa,CAAC,OAAO,EAAE,EACjD,EAAE,CACH,CAAA;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { info, rawOut } from '../util/logger.js';
|
|
2
|
+
export async function runPerfCheck(flags = {}) {
|
|
3
|
+
const modifiedFiles = resolveModifiedFiles(flags);
|
|
4
|
+
rawOut('specrails-core performance check\n');
|
|
5
|
+
rawOut(`Modified files: ${modifiedFiles.length > 0 ? modifiedFiles : '<none>'}\n\n`);
|
|
6
|
+
info('This repository contains an installer + Markdown templates — no runtime benchmarks apply.');
|
|
7
|
+
rawOut('\nPERF_STATUS: NO_PERF_IMPACT\n');
|
|
8
|
+
return { status: 'NO_PERF_IMPACT', modifiedFiles };
|
|
9
|
+
}
|
|
10
|
+
function resolveModifiedFiles(flags) {
|
|
11
|
+
if (typeof flags.files === 'string')
|
|
12
|
+
return flags.files;
|
|
13
|
+
const envList = process.env.MODIFIED_FILES_LIST;
|
|
14
|
+
return envList && envList.length > 0 ? envList : '';
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=perf-check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"perf-check.js","sourceRoot":"","sources":["../../../src/installer/commands/perf-check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAoBhD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAwB,EAAE;IAC3D,MAAM,aAAa,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAA;IAEjD,MAAM,CAAC,oCAAoC,CAAC,CAAA;IAC5C,MAAM,CAAC,mBAAmB,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,MAAM,CAAC,CAAA;IAEpF,IAAI,CACF,2FAA2F,CAC5F,CAAA;IAED,MAAM,CAAC,iCAAiC,CAAC,CAAA;IACzC,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,aAAa,EAAE,CAAA;AACpD,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAqB;IACjD,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC,KAAK,CAAA;IACvD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAA;IAC/C,OAAO,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAA;AACrD,CAAC"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import { InstallerError, PrerequisiteError } from '../util/errors.js';
|
|
4
|
+
import { info, ok, step, warn } from '../util/logger.js';
|
|
5
|
+
import { copyDir, isDir, pathExists, readTextFile } from '../util/fs.js';
|
|
6
|
+
import { loadInstallConfig, resolveConfigPath } from '../phases/install-config.js';
|
|
7
|
+
import { buildManifest, writeManifestFiles } from '../phases/manifest.js';
|
|
8
|
+
import { derivedPaths, detectAvailability, resolveProvider } from '../phases/provider-detect.js';
|
|
9
|
+
import { scaffoldInstallation } from '../phases/scaffold.js';
|
|
10
|
+
const VALID_ONLY = new Set([
|
|
11
|
+
'all',
|
|
12
|
+
'core',
|
|
13
|
+
'rules',
|
|
14
|
+
'agents',
|
|
15
|
+
'web-manager',
|
|
16
|
+
]);
|
|
17
|
+
export async function runUpdate(flags) {
|
|
18
|
+
const scriptDir = resolveScriptDir();
|
|
19
|
+
const currentVersion = readVersion(scriptDir);
|
|
20
|
+
const repoRoot = path.resolve(typeof flags['root-dir'] === 'string' ? flags['root-dir'] : process.cwd());
|
|
21
|
+
const dryRun = flags['dry-run'] === true;
|
|
22
|
+
// Read install-config.yaml so the user's original choices (tier,
|
|
23
|
+
// agent_teams) survive the update. Flag overrides win when present;
|
|
24
|
+
// missing config falls back to defaults (tier=full, agent_teams=false).
|
|
25
|
+
const config = loadInstallConfig(resolveConfigPath(repoRoot));
|
|
26
|
+
const tier = config?.tier ?? 'full';
|
|
27
|
+
const agentTeams = flags['agent-teams'] === true || config?.agent_teams === true;
|
|
28
|
+
const selectedAgents = config?.agents.selected;
|
|
29
|
+
const marker = path.join(repoRoot, '.specrails', 'specrails-version');
|
|
30
|
+
if (!pathExists(marker)) {
|
|
31
|
+
throw new PrerequisiteError(`No existing specrails install detected at ${repoRoot}. Run \`npx specrails-core init\` first.`);
|
|
32
|
+
}
|
|
33
|
+
const previousVersion = readExistingVersion(repoRoot);
|
|
34
|
+
step('Update: resolving provider from existing install');
|
|
35
|
+
const provider = await resolveExistingProvider(repoRoot);
|
|
36
|
+
const { providerDir } = derivedPaths(provider);
|
|
37
|
+
ok(`Detected provider: ${provider} (${providerDir})`);
|
|
38
|
+
// ─── Resolve --only scope ────────────────────────────────────────
|
|
39
|
+
const scope = resolveScope(flags.only);
|
|
40
|
+
if (scope === 'web-manager') {
|
|
41
|
+
warn('--only=web-manager is deprecated. The standalone web-manager has been retired; ' +
|
|
42
|
+
'specrails-hub is the supported dashboard. Skipping with no changes.');
|
|
43
|
+
return { repoRoot, previousVersion, currentVersion, provider, dryRun, scope, tier, agentTeams };
|
|
44
|
+
}
|
|
45
|
+
if (config) {
|
|
46
|
+
info(`Honouring install-config.yaml: tier=${tier}, agent_teams=${agentTeams}`);
|
|
47
|
+
}
|
|
48
|
+
if (dryRun) {
|
|
49
|
+
info(`Dry run: would update [${scope}, tier=${tier}, agent_teams=${agentTeams}] ` +
|
|
50
|
+
`for ${previousVersion ?? '(unknown)'} → ${currentVersion}.`);
|
|
51
|
+
return { repoRoot, previousVersion, currentVersion, provider, dryRun, scope, tier, agentTeams };
|
|
52
|
+
}
|
|
53
|
+
step(`Update: refreshing scaffold [scope=${scope}] (${previousVersion ?? '?'} → ${currentVersion})`);
|
|
54
|
+
if (scope === 'all' || scope === 'core') {
|
|
55
|
+
scaffoldInstallation({
|
|
56
|
+
scriptDir,
|
|
57
|
+
repoRoot,
|
|
58
|
+
provider,
|
|
59
|
+
providerDir,
|
|
60
|
+
agentTeams,
|
|
61
|
+
selectedAgents,
|
|
62
|
+
// tier read from install-config.yaml above. If the user installed
|
|
63
|
+
// with --quick, we re-apply the quick-tier direct placement
|
|
64
|
+
// (agents + commands into <providerDir> with placeholder substitution
|
|
65
|
+
// and VPC exclusion) instead of leaving the live agents/ stale.
|
|
66
|
+
tier,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
else if (scope === 'rules') {
|
|
70
|
+
rescaffoldComponent('rules', { scriptDir, repoRoot });
|
|
71
|
+
}
|
|
72
|
+
else if (scope === 'agents') {
|
|
73
|
+
rescaffoldComponent('agents', { scriptDir, repoRoot });
|
|
74
|
+
}
|
|
75
|
+
step('Update: rewriting manifest');
|
|
76
|
+
const manifest = buildManifest({
|
|
77
|
+
scriptDir,
|
|
78
|
+
repoRoot,
|
|
79
|
+
version: currentVersion,
|
|
80
|
+
});
|
|
81
|
+
const { manifestPath, versionPath } = writeManifestFiles(repoRoot, manifest);
|
|
82
|
+
ok(`Wrote ${path.relative(repoRoot, manifestPath)}`);
|
|
83
|
+
ok(`Wrote ${path.relative(repoRoot, versionPath)}`);
|
|
84
|
+
step('Update complete');
|
|
85
|
+
info(`specrails-core ${previousVersion ?? '?'} → ${currentVersion}`);
|
|
86
|
+
// Terminal sentinel for programmatic consumers (see comment in init.ts).
|
|
87
|
+
ok('update complete');
|
|
88
|
+
return { repoRoot, previousVersion, currentVersion, provider, dryRun: false, scope, tier, agentTeams };
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Re-applies a single subtree (rules or agents) from the bundled
|
|
92
|
+
* templates into both the staging dir (.specrails/setup-templates/)
|
|
93
|
+
* and the live provider directory if it already exists. Skips the
|
|
94
|
+
* enrich placeholders + agent-memory bootstrap that scaffoldInstallation
|
|
95
|
+
* does — those should only run on a true (re-)install.
|
|
96
|
+
*/
|
|
97
|
+
function rescaffoldComponent(component, args) {
|
|
98
|
+
const src = path.join(args.scriptDir, 'templates', component);
|
|
99
|
+
if (!isDir(src)) {
|
|
100
|
+
warn(`templates/${component} not found at ${src} — nothing to update`);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const stagingDest = path.join(args.repoRoot, '.specrails', 'setup-templates', component);
|
|
104
|
+
copyDir(src, stagingDest, {
|
|
105
|
+
filter: (_s, rel) => !rel.includes('node_modules') && !rel.endsWith('package-lock.json'),
|
|
106
|
+
});
|
|
107
|
+
ok(`Refreshed .specrails/setup-templates/${component}/`);
|
|
108
|
+
}
|
|
109
|
+
function resolveScope(only) {
|
|
110
|
+
if (only === undefined)
|
|
111
|
+
return 'all';
|
|
112
|
+
if (only === true) {
|
|
113
|
+
warn('--only requires a value (one of: all, core, rules, agents, web-manager) — defaulting to "all"');
|
|
114
|
+
return 'all';
|
|
115
|
+
}
|
|
116
|
+
if (typeof only !== 'string')
|
|
117
|
+
return 'all';
|
|
118
|
+
const normalised = only.toLowerCase();
|
|
119
|
+
if (!VALID_ONLY.has(normalised)) {
|
|
120
|
+
warn(`--only=${only} is not recognised; defaulting to "all"`);
|
|
121
|
+
return 'all';
|
|
122
|
+
}
|
|
123
|
+
return normalised;
|
|
124
|
+
}
|
|
125
|
+
async function resolveExistingProvider(repoRoot) {
|
|
126
|
+
if (pathExists(path.join(repoRoot, '.claude')))
|
|
127
|
+
return 'claude';
|
|
128
|
+
if (pathExists(path.join(repoRoot, '.codex')))
|
|
129
|
+
return 'codex';
|
|
130
|
+
// Neither present — fall back to resolving via CLI availability.
|
|
131
|
+
const avail = await detectAvailability();
|
|
132
|
+
try {
|
|
133
|
+
return await resolveProvider(avail, { skipPrereqs: true });
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
if (err instanceof InstallerError)
|
|
137
|
+
throw err;
|
|
138
|
+
throw new InstallerError(`could not determine provider of existing install at ${repoRoot}`, 40);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
function readExistingVersion(repoRoot) {
|
|
142
|
+
const p = path.join(repoRoot, '.specrails', 'specrails-version');
|
|
143
|
+
if (!pathExists(p))
|
|
144
|
+
return null;
|
|
145
|
+
try {
|
|
146
|
+
return readTextFile(p).trim() || null;
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
function resolveScriptDir() {
|
|
153
|
+
const override = process.env.SPECRAILS_CORE_SCRIPT_DIR;
|
|
154
|
+
if (override && override.length > 0)
|
|
155
|
+
return path.resolve(override);
|
|
156
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
157
|
+
return path.resolve(here, '..', '..', '..');
|
|
158
|
+
}
|
|
159
|
+
function readVersion(scriptDir) {
|
|
160
|
+
const p = path.join(scriptDir, 'VERSION');
|
|
161
|
+
if (!pathExists(p))
|
|
162
|
+
return 'unknown';
|
|
163
|
+
try {
|
|
164
|
+
return readTextFile(p).trim() || 'unknown';
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
return 'unknown';
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../../src/installer/commands/update.ts"],"names":[],"mappings":"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"}
|