@izkac/forgekit 0.3.12 → 0.3.13
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/bin/forge.mjs +107 -107
- package/bin/forgekit.mjs +83 -83
- package/bin/review.mjs +81 -81
- package/package.json +1 -1
- package/scripts/prepack.mjs +78 -78
- package/scripts/run-tests.mjs +50 -50
- package/src/adr.mjs +236 -236
- package/src/adr.test.mjs +170 -170
- package/src/change.mjs +327 -234
- package/src/change.test.mjs +145 -83
- package/src/cleanup-sessions.mjs +84 -84
- package/src/config.mjs +103 -103
- package/src/defer.mjs +75 -75
- package/src/doctor.mjs +350 -341
- package/src/doctor.test.mjs +114 -114
- package/src/init.mjs +680 -621
- package/src/install.mjs +815 -815
- package/src/install.test.mjs +180 -180
- package/src/integrity-check.mjs +60 -60
- package/src/integrity.mjs +682 -682
- package/src/integrity.test.mjs +566 -566
- package/src/lib.mjs +143 -143
- package/src/models.defaults.json +41 -41
- package/src/new-session.mjs +99 -99
- package/src/openspec-overlays/README.md +19 -19
- package/src/openspec-overlays/openspec-apply-change-footer.md +14 -14
- package/src/openspec-overlays/opsx-apply-completion-step.md +1 -1
- package/src/openspec-overlays/opsx-apply-implement-step.md +11 -11
- package/src/paths.mjs +92 -92
- package/src/plan-engine.mjs +321 -278
- package/src/plan-engine.test.mjs +447 -283
- package/src/preferences.defaults.json +78 -78
- package/src/preferences.mjs +438 -438
- package/src/preferences.test.mjs +174 -174
- package/src/record-evidence.mjs +204 -204
- package/src/resolve-model.mjs +312 -312
- package/src/resolve-model.test.mjs +194 -194
- package/src/review/cli.test.mjs +117 -117
- package/src/review/export.mjs +172 -172
- package/src/review/export.test.mjs +197 -197
- package/src/review/fixtures/valid-review.json +42 -42
- package/src/review/lib.mjs +894 -894
- package/src/review/lib.test.mjs +266 -266
- package/src/review/schema.json +196 -196
- package/src/review/signals.test.mjs +62 -62
- package/src/score-cli.mjs +68 -68
- package/src/score.mjs +568 -568
- package/src/score.test.mjs +366 -366
- package/src/session-reminder.mjs +207 -207
- package/src/session-status.mjs +70 -70
- package/src/set-models.mjs +186 -186
- package/src/set-phase.mjs +205 -205
- package/src/set-prefs.mjs +294 -294
- package/src/specs-sync.mjs +234 -0
- package/src/specs-sync.test.mjs +114 -0
- package/src/spine.mjs +93 -93
- package/src/triage-prompt.mjs +175 -175
- package/src/triage-prompt.test.mjs +50 -50
- package/src/vendor-openspec-overlays.mjs +176 -176
- package/src/vendor-openspec-overlays.test.mjs +62 -62
- package/vendor/skills/archive-to-adr/SKILL.md +149 -149
- package/vendor/skills/forge/SKILL.md +136 -136
- package/vendor/skills/forge/docs/forge.md +650 -647
- package/vendor/skills/forge/phases/brainstorm.md +23 -23
- package/vendor/skills/forge/phases/finish.md +90 -87
- package/vendor/skills/forge/phases/implement.md +77 -77
- package/vendor/skills/forge/phases/plan-openspec.md +60 -60
- package/vendor/skills/forge/phases/plan-specs.md +163 -117
- package/vendor/skills/forge/phases/review.md +25 -25
- package/vendor/skills/forge/phases/verify.md +124 -124
- package/vendor/skills/forge/references/forge-layout.md +85 -85
- package/vendor/skills/forge/references/pace.md +115 -115
- package/vendor/skills/forge/references/plan-routing.md +52 -51
- package/vendor/skills/forge/references/runtime-integrity.md +232 -232
- package/vendor/skills/forge/references/substantial-work.md +37 -37
- package/vendor/skills/forge/references/test-evidence.md +30 -30
- package/vendor/skills/forge/references/test-strategy.md +68 -68
- package/vendor/skills/forge/skills/subagent-driven-development/SKILL.md +87 -87
- package/vendor/skills/forge/subagents/final-reviewer-prompt.md +56 -56
- package/vendor/skills/forge/subagents/implementer-prompt.md +38 -38
- package/vendor/skills/git-resolve-adr-conflict/SKILL.md +132 -132
- package/vendor/skills/thorough-code-review/SKILL.md +290 -290
- package/vendor/skills/thorough-code-review/examples.md +133 -133
- package/vendor/skills/thorough-code-review/reference/accepted-risks.md +26 -26
- package/vendor/skills/thorough-code-review/reference/lenses.md +96 -96
- package/vendor/skills/thorough-code-review/reference/phase1-scout.md +62 -62
- package/vendor/skills/thorough-code-review/reference/phase2-skeptic.md +105 -105
- package/vendor/skills/thorough-code-review/reference/report-schema.json +222 -222
- package/vendor/skills/thorough-code-review/reference/report-template.md +115 -115
- package/vendor/skills/thorough-code-review/reference/severity-rubric.md +49 -49
- package/vendor/skills/thorough-code-review/reference/signals-preflight.md +55 -55
- package/vendor/templates/adr/README.md +7 -7
- package/vendor/templates/adr/decisions.md +141 -141
- package/vendor/templates/adr/hooks/check-pending-adrs.mjs +74 -74
- package/vendor/templates/adr/hooks/check-pending-adrs.sh +3 -3
- package/vendor/templates/adr/hooks/openspec-archive-agent-message.mjs +52 -52
- package/vendor/templates/adr/hooks/openspec-archive-agent-message.sh +3 -3
- package/vendor/templates/project/claude/commands/forge-apply.md +75 -75
- package/vendor/templates/project/claude/commands/forge-brainstorm.md +7 -7
- package/vendor/templates/project/claude/commands/forge-build.md +17 -17
- package/vendor/templates/project/claude/commands/forge-plan.md +12 -12
- package/vendor/templates/project/claude/commands/forge-skip.md +14 -14
- package/vendor/templates/project/claude/commands/forge-status.md +16 -16
- package/vendor/templates/project/claude/commands/forge.md +16 -16
- package/vendor/templates/project/claude/hooks/forge-prompt-hook.mjs +73 -73
- package/vendor/templates/project/claude/hooks/forge-session-start.mjs +19 -19
- package/vendor/templates/project/claude/hooks/forge-triage-hook.mjs +77 -77
- package/vendor/templates/project/cursor/commands/forge-apply.md +75 -75
- package/vendor/templates/project/cursor/commands/forge-brainstorm.md +10 -10
- package/vendor/templates/project/cursor/commands/forge-build.md +17 -17
- package/vendor/templates/project/cursor/commands/forge-plan.md +15 -15
- package/vendor/templates/project/cursor/commands/forge-skip.md +14 -14
- package/vendor/templates/project/cursor/commands/forge-status.md +16 -16
- package/vendor/templates/project/cursor/commands/forge.md +16 -16
- package/vendor/templates/project/cursor/hooks/forge-session-start.mjs +30 -30
- package/vendor/templates/project/cursor/hooks/forge-session-start.sh +3 -3
package/scripts/prepack.mjs
CHANGED
|
@@ -1,78 +1,78 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Copy skills/ and templates/ from the monorepo root into packages/cli/vendor/
|
|
4
|
-
* so the published npm package is self-contained.
|
|
5
|
-
*
|
|
6
|
-
* Usage: node packages/cli/scripts/prepack.mjs
|
|
7
|
-
* Triggered by npm prepack in @izkac/forgekit.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import fs from 'node:fs';
|
|
11
|
-
import path from 'node:path';
|
|
12
|
-
import { fileURLToPath } from 'node:url';
|
|
13
|
-
|
|
14
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
15
|
-
const cliRoot = path.resolve(__dirname, '..');
|
|
16
|
-
const monoRoot = path.resolve(cliRoot, '..', '..');
|
|
17
|
-
const vendorRoot = path.join(cliRoot, 'vendor');
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* @param {string} src
|
|
21
|
-
* @param {string} dest
|
|
22
|
-
*/
|
|
23
|
-
function copyDirRecursive(src, dest) {
|
|
24
|
-
fs.mkdirSync(dest, { recursive: true });
|
|
25
|
-
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
26
|
-
const from = path.join(src, entry.name);
|
|
27
|
-
const to = path.join(dest, entry.name);
|
|
28
|
-
if (entry.isDirectory()) copyDirRecursive(from, to);
|
|
29
|
-
else fs.copyFileSync(from, to);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Best-effort clear. On Windows EPERM, leave the tree and overwrite in place.
|
|
35
|
-
* @param {string} dir
|
|
36
|
-
* @returns {boolean} true if cleared
|
|
37
|
-
*/
|
|
38
|
-
function tryEmptyDir(dir) {
|
|
39
|
-
if (!fs.existsSync(dir)) return true;
|
|
40
|
-
try {
|
|
41
|
-
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
42
|
-
fs.rmSync(path.join(dir, entry.name), {
|
|
43
|
-
recursive: true,
|
|
44
|
-
force: true,
|
|
45
|
-
maxRetries: 5,
|
|
46
|
-
retryDelay: 100,
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
return true;
|
|
50
|
-
} catch (err) {
|
|
51
|
-
process.stderr.write(
|
|
52
|
-
`prepack: could not empty ${dir} (${err.code || err.message}); overwriting in place\n`,
|
|
53
|
-
);
|
|
54
|
-
return false;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function main() {
|
|
59
|
-
const skillsSrc = path.join(monoRoot, 'skills');
|
|
60
|
-
const templatesSrc = path.join(monoRoot, 'templates');
|
|
61
|
-
if (!fs.existsSync(skillsSrc) || !fs.existsSync(templatesSrc)) {
|
|
62
|
-
if (fs.existsSync(path.join(vendorRoot, 'skills'))) {
|
|
63
|
-
process.stdout.write(`prepack: vendor already present at ${vendorRoot}\n`);
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
throw new Error(
|
|
67
|
-
`prepack: monorepo skills/templates not found at ${monoRoot} and vendor/ missing`,
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
fs.mkdirSync(vendorRoot, { recursive: true });
|
|
72
|
-
tryEmptyDir(vendorRoot);
|
|
73
|
-
copyDirRecursive(skillsSrc, path.join(vendorRoot, 'skills'));
|
|
74
|
-
copyDirRecursive(templatesSrc, path.join(vendorRoot, 'templates'));
|
|
75
|
-
process.stdout.write(`prepack: vendored skills + templates → ${vendorRoot}\n`);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
main();
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Copy skills/ and templates/ from the monorepo root into packages/cli/vendor/
|
|
4
|
+
* so the published npm package is self-contained.
|
|
5
|
+
*
|
|
6
|
+
* Usage: node packages/cli/scripts/prepack.mjs
|
|
7
|
+
* Triggered by npm prepack in @izkac/forgekit.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import fs from 'node:fs';
|
|
11
|
+
import path from 'node:path';
|
|
12
|
+
import { fileURLToPath } from 'node:url';
|
|
13
|
+
|
|
14
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
15
|
+
const cliRoot = path.resolve(__dirname, '..');
|
|
16
|
+
const monoRoot = path.resolve(cliRoot, '..', '..');
|
|
17
|
+
const vendorRoot = path.join(cliRoot, 'vendor');
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @param {string} src
|
|
21
|
+
* @param {string} dest
|
|
22
|
+
*/
|
|
23
|
+
function copyDirRecursive(src, dest) {
|
|
24
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
25
|
+
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
26
|
+
const from = path.join(src, entry.name);
|
|
27
|
+
const to = path.join(dest, entry.name);
|
|
28
|
+
if (entry.isDirectory()) copyDirRecursive(from, to);
|
|
29
|
+
else fs.copyFileSync(from, to);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Best-effort clear. On Windows EPERM, leave the tree and overwrite in place.
|
|
35
|
+
* @param {string} dir
|
|
36
|
+
* @returns {boolean} true if cleared
|
|
37
|
+
*/
|
|
38
|
+
function tryEmptyDir(dir) {
|
|
39
|
+
if (!fs.existsSync(dir)) return true;
|
|
40
|
+
try {
|
|
41
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
42
|
+
fs.rmSync(path.join(dir, entry.name), {
|
|
43
|
+
recursive: true,
|
|
44
|
+
force: true,
|
|
45
|
+
maxRetries: 5,
|
|
46
|
+
retryDelay: 100,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
return true;
|
|
50
|
+
} catch (err) {
|
|
51
|
+
process.stderr.write(
|
|
52
|
+
`prepack: could not empty ${dir} (${err.code || err.message}); overwriting in place\n`,
|
|
53
|
+
);
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function main() {
|
|
59
|
+
const skillsSrc = path.join(monoRoot, 'skills');
|
|
60
|
+
const templatesSrc = path.join(monoRoot, 'templates');
|
|
61
|
+
if (!fs.existsSync(skillsSrc) || !fs.existsSync(templatesSrc)) {
|
|
62
|
+
if (fs.existsSync(path.join(vendorRoot, 'skills'))) {
|
|
63
|
+
process.stdout.write(`prepack: vendor already present at ${vendorRoot}\n`);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
throw new Error(
|
|
67
|
+
`prepack: monorepo skills/templates not found at ${monoRoot} and vendor/ missing`,
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
fs.mkdirSync(vendorRoot, { recursive: true });
|
|
72
|
+
tryEmptyDir(vendorRoot);
|
|
73
|
+
copyDirRecursive(skillsSrc, path.join(vendorRoot, 'skills'));
|
|
74
|
+
copyDirRecursive(templatesSrc, path.join(vendorRoot, 'templates'));
|
|
75
|
+
process.stdout.write(`prepack: vendored skills + templates → ${vendorRoot}\n`);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
main();
|
package/scripts/run-tests.mjs
CHANGED
|
@@ -1,50 +1,50 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Run all src test files (*.test.mjs) via node --test.
|
|
4
|
-
*
|
|
5
|
-
* Node 20 does not expand globs passed to `node --test`; Node 22+ does.
|
|
6
|
-
* Explicit file discovery keeps CI green on the engines.node >=20 matrix.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import fs from 'node:fs';
|
|
10
|
-
import os from 'node:os';
|
|
11
|
-
import path from 'node:path';
|
|
12
|
-
import { spawnSync } from 'node:child_process';
|
|
13
|
-
import { fileURLToPath } from 'node:url';
|
|
14
|
-
|
|
15
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
16
|
-
const cliRoot = path.resolve(__dirname, '..');
|
|
17
|
-
const srcRoot = path.join(cliRoot, 'src');
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* @param {string} dir
|
|
21
|
-
* @returns {string[]}
|
|
22
|
-
*/
|
|
23
|
-
function findTestFiles(dir) {
|
|
24
|
-
/** @type {string[]} */
|
|
25
|
-
const out = [];
|
|
26
|
-
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
27
|
-
const full = path.join(dir, entry.name);
|
|
28
|
-
if (entry.isDirectory()) out.push(...findTestFiles(full));
|
|
29
|
-
else if (entry.name.endsWith('.test.mjs')) out.push(full);
|
|
30
|
-
}
|
|
31
|
-
return out;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const files = findTestFiles(srcRoot).sort();
|
|
35
|
-
if (files.length === 0) {
|
|
36
|
-
console.error(`No *.test.mjs files under ${srcRoot}`);
|
|
37
|
-
process.exit(1);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const result = spawnSync(process.execPath, ['--test', ...files], {
|
|
41
|
-
cwd: cliRoot,
|
|
42
|
-
stdio: 'inherit',
|
|
43
|
-
env: {
|
|
44
|
-
...process.env,
|
|
45
|
-
// Keep saveSession's fleet-registry mirroring away from ~/.forgekit
|
|
46
|
-
// when tests exercise session saves with scratch projects.
|
|
47
|
-
FORGEKIT_FLEET_DIR: fs.mkdtempSync(path.join(os.tmpdir(), 'forgekit-test-fleet-')),
|
|
48
|
-
},
|
|
49
|
-
});
|
|
50
|
-
process.exit(result.status ?? 1);
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Run all src test files (*.test.mjs) via node --test.
|
|
4
|
+
*
|
|
5
|
+
* Node 20 does not expand globs passed to `node --test`; Node 22+ does.
|
|
6
|
+
* Explicit file discovery keeps CI green on the engines.node >=20 matrix.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import fs from 'node:fs';
|
|
10
|
+
import os from 'node:os';
|
|
11
|
+
import path from 'node:path';
|
|
12
|
+
import { spawnSync } from 'node:child_process';
|
|
13
|
+
import { fileURLToPath } from 'node:url';
|
|
14
|
+
|
|
15
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
16
|
+
const cliRoot = path.resolve(__dirname, '..');
|
|
17
|
+
const srcRoot = path.join(cliRoot, 'src');
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @param {string} dir
|
|
21
|
+
* @returns {string[]}
|
|
22
|
+
*/
|
|
23
|
+
function findTestFiles(dir) {
|
|
24
|
+
/** @type {string[]} */
|
|
25
|
+
const out = [];
|
|
26
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
27
|
+
const full = path.join(dir, entry.name);
|
|
28
|
+
if (entry.isDirectory()) out.push(...findTestFiles(full));
|
|
29
|
+
else if (entry.name.endsWith('.test.mjs')) out.push(full);
|
|
30
|
+
}
|
|
31
|
+
return out;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const files = findTestFiles(srcRoot).sort();
|
|
35
|
+
if (files.length === 0) {
|
|
36
|
+
console.error(`No *.test.mjs files under ${srcRoot}`);
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const result = spawnSync(process.execPath, ['--test', ...files], {
|
|
41
|
+
cwd: cliRoot,
|
|
42
|
+
stdio: 'inherit',
|
|
43
|
+
env: {
|
|
44
|
+
...process.env,
|
|
45
|
+
// Keep saveSession's fleet-registry mirroring away from ~/.forgekit
|
|
46
|
+
// when tests exercise session saves with scratch projects.
|
|
47
|
+
FORGEKIT_FLEET_DIR: fs.mkdtempSync(path.join(os.tmpdir(), 'forgekit-test-fleet-')),
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
process.exit(result.status ?? 1);
|