@opengsd/gsd-core 1.5.0-rc.4 → 1.5.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/.claude-plugin/plugin.json +1 -1
- package/LICENSE +1 -1
- package/agents/gsd-executor.md +22 -0
- package/agents/gsd-phase-researcher.md +1 -1
- package/agents/gsd-planner.md +4 -0
- package/agents/gsd-project-researcher.md +1 -1
- package/agents/gsd-verifier.md +45 -13
- package/bin/install.js +56 -100
- package/commands/gsd/autonomous.md +1 -1
- package/commands/gsd/execute-phase.md +1 -1
- package/commands/gsd/plan-phase.md +1 -1
- package/gemini-extension.json +1 -1
- package/gsd-core/bin/gsd-tools.cjs +85 -53
- package/gsd-core/bin/lib/agent-command-router.cjs +2 -2
- package/gsd-core/bin/lib/agent-install-check.cjs +143 -0
- package/gsd-core/bin/lib/audit-command-router.cjs +4 -4
- package/gsd-core/bin/lib/capability-activation.cjs +37 -10
- package/gsd-core/bin/lib/capability-registry.cjs +2 -0
- package/gsd-core/bin/lib/capability-state.cjs +80 -30
- package/gsd-core/bin/lib/capability-writer.cjs +5 -4
- package/gsd-core/bin/lib/check-command-router.cjs +50 -51
- package/gsd-core/bin/lib/commands.cjs +20 -2
- package/gsd-core/bin/lib/config-loader.cjs +3 -4
- package/gsd-core/bin/lib/config-schema.cjs +1 -1
- package/gsd-core/bin/lib/config-types.cjs +2 -1
- package/gsd-core/bin/lib/config.cjs +5 -2
- package/gsd-core/bin/lib/decisions.cjs +19 -1
- package/gsd-core/bin/lib/docs.cjs +14 -2
- package/gsd-core/bin/lib/frontmatter.cjs +2 -2
- package/gsd-core/bin/lib/gap-checker.cjs +5 -2
- package/gsd-core/bin/lib/git-base-branch.cjs +27 -1
- package/gsd-core/bin/lib/graphify-command-router.cjs +6 -8
- package/gsd-core/bin/lib/graphify.cjs +7 -31
- package/gsd-core/bin/lib/gsd2-import.cjs +2 -2
- package/gsd-core/bin/lib/init.cjs +30 -4
- package/gsd-core/bin/lib/intel-command-router.cjs +6 -3
- package/gsd-core/bin/lib/intel.cjs +28 -34
- package/gsd-core/bin/lib/io.cjs +2 -4
- package/gsd-core/bin/lib/learnings.cjs +2 -2
- package/gsd-core/bin/lib/loop-resolver.cjs +45 -167
- package/gsd-core/bin/lib/milestone.cjs +13 -5
- package/gsd-core/bin/lib/model-resolver.cjs +3 -4
- package/gsd-core/bin/lib/phase-id.cjs +3 -5
- package/gsd-core/bin/lib/phase-locator.cjs +3 -6
- package/gsd-core/bin/lib/phase.cjs +59 -13
- package/gsd-core/bin/lib/probe-core.cjs +40 -11
- package/gsd-core/bin/lib/profile-output.cjs +5 -2
- package/gsd-core/bin/lib/prohibition-enforcement.cjs +660 -0
- package/gsd-core/bin/lib/roadmap-command-router.cjs +2 -2
- package/gsd-core/bin/lib/roadmap-parser.cjs +28 -25
- package/gsd-core/bin/lib/roadmap.cjs +9 -4
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +4 -1
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +24 -3
- package/gsd-core/bin/lib/state.cjs +75 -17
- package/gsd-core/bin/lib/task-command-router.cjs +2 -2
- package/gsd-core/bin/lib/teams-status.cjs +74 -0
- package/gsd-core/bin/lib/template.cjs +11 -2
- package/gsd-core/bin/lib/uat.cjs +64 -2
- package/gsd-core/bin/lib/verification.cjs +8 -5
- package/gsd-core/bin/lib/verify.cjs +311 -4
- package/gsd-core/bin/lib/workstream-inventory.cjs +2 -2
- package/gsd-core/bin/lib/workstream.cjs +8 -2
- package/gsd-core/bin/lib/worktree-safety.cjs +44 -3
- package/gsd-core/bin/shared/config-schema.manifest.json +2 -0
- package/gsd-core/references/planner-antipatterns.md +46 -0
- package/gsd-core/references/planning-config.md +5 -1
- package/gsd-core/references/prohibition-probe.md +80 -2
- package/gsd-core/references/worktree-branch-check.md +11 -5
- package/gsd-core/templates/verification-report.md +16 -3
- package/gsd-core/workflows/docs-update.md +23 -31
- package/gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md +9 -0
- package/gsd-core/workflows/execute-phase.md +7 -2
- package/gsd-core/workflows/map-codebase.md +8 -10
- package/gsd-core/workflows/plan-phase.md +6 -0
- package/gsd-core/workflows/quick.md +26 -2
- package/gsd-core/workflows/settings-advanced.md +5 -5
- package/gsd-core/workflows/settings-integrations.md +5 -5
- package/gsd-core/workflows/spec-phase.md +30 -2
- package/gsd-core/workflows/verify-phase.md +22 -7
- package/hooks/dist/gsd-worktree-path-guard.js +34 -18
- package/hooks/gsd-worktree-path-guard.js +34 -18
- package/package.json +3 -3
- package/scripts/ci-prepare-test-scope.cjs +56 -14
- package/scripts/diff-touches-shipped-paths.cjs +5 -11
- package/scripts/gen-capability-registry.cjs +27 -1
- package/scripts/lint-allow-test-rule-refs.allowlist.json +0 -2
- package/scripts/research-profiles.cjs +2 -2
- package/scripts/run-tests.cjs +1 -0
- package/gsd-core/bin/lib/core.cjs +0 -345
|
@@ -16,8 +16,20 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
16
16
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
17
17
|
const node_path_1 = __importDefault(require("node:path"));
|
|
18
18
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
19
|
-
const
|
|
20
|
-
const { output
|
|
19
|
+
const io = require("./io.cjs");
|
|
20
|
+
const { output } = io;
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
22
|
+
const configLoader = require("./config-loader.cjs");
|
|
23
|
+
const { loadConfig } = configLoader;
|
|
24
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
25
|
+
const modelResolver = require("./model-resolver.cjs");
|
|
26
|
+
const { resolveModelInternal } = modelResolver;
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
28
|
+
const coreUtils = require("./core-utils.cjs");
|
|
29
|
+
const { pathExistsInternal, toPosixPath } = coreUtils;
|
|
30
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
31
|
+
const agentInstallCheck = require("./agent-install-check.cjs");
|
|
32
|
+
const { checkAgentsInstalled } = agentInstallCheck;
|
|
21
33
|
const shell_command_projection_cjs_1 = require("./shell-command-projection.cjs");
|
|
22
34
|
// ─── Constants ────────────────────────────────────────────────────────────────
|
|
23
35
|
const GSD_MARKER = '<!-- generated-by: gsd-doc-writer -->';
|
|
@@ -12,8 +12,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
13
13
|
const node_path_1 = __importDefault(require("node:path"));
|
|
14
14
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
15
|
-
const
|
|
16
|
-
const { output, error } =
|
|
15
|
+
const ioMod = require("./io.cjs");
|
|
16
|
+
const { output, error } = ioMod;
|
|
17
17
|
const shell_command_projection_cjs_1 = require("./shell-command-projection.cjs");
|
|
18
18
|
// ─── Parsing engine ───────────────────────────────────────────────────────────
|
|
19
19
|
/**
|
|
@@ -22,8 +22,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
22
22
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
23
23
|
const node_path_1 = __importDefault(require("node:path"));
|
|
24
24
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
25
|
-
const
|
|
26
|
-
const {
|
|
25
|
+
const io = require("./io.cjs");
|
|
26
|
+
const { output, error } = io;
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
28
|
+
const phaseId = require("./phase-id.cjs");
|
|
29
|
+
const { escapeRegex } = phaseId;
|
|
27
30
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
28
31
|
const planningWorkspace = require("./planning-workspace.cjs");
|
|
29
32
|
const { planningPaths, planningDir, findContextMdIn } = planningWorkspace;
|
|
@@ -32,6 +32,7 @@ exports.trySymbolicRef = trySymbolicRef;
|
|
|
32
32
|
exports.tryRemoteShow = tryRemoteShow;
|
|
33
33
|
exports.tryLocalBranch = tryLocalBranch;
|
|
34
34
|
exports.resolveBaseBranch = resolveBaseBranch;
|
|
35
|
+
exports.gitWorktreeInfoInternal = gitWorktreeInfoInternal;
|
|
35
36
|
exports.cmdGitBaseBranch = cmdGitBaseBranch;
|
|
36
37
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
37
38
|
const node_path_1 = __importDefault(require("node:path"));
|
|
@@ -159,7 +160,7 @@ function tryLocalBranch(cwd, execGit) {
|
|
|
159
160
|
*/
|
|
160
161
|
function resolveBaseBranch(cwd, deps) {
|
|
161
162
|
const execGit = deps?.execGit ?? shell_command_projection_cjs_1.execGit;
|
|
162
|
-
// Derive .planning dir relative to cwd (mirrors planningDir() in
|
|
163
|
+
// Derive .planning dir relative to cwd (mirrors planningDir() in planning-workspace.cjs)
|
|
163
164
|
const planningDir = node_path_1.default.join(cwd, '.planning');
|
|
164
165
|
// 1. Config override
|
|
165
166
|
const configured = readConfigBaseBranch(planningDir, deps);
|
|
@@ -180,6 +181,31 @@ function resolveBaseBranch(cwd, deps) {
|
|
|
180
181
|
// 5. Last-resort default
|
|
181
182
|
return 'main';
|
|
182
183
|
}
|
|
184
|
+
/**
|
|
185
|
+
* Detect whether `cwd` sits inside a git worktree, and if so, return the
|
|
186
|
+
* absolute path of the worktree root.
|
|
187
|
+
*/
|
|
188
|
+
function gitWorktreeInfoInternal(cwd) {
|
|
189
|
+
try {
|
|
190
|
+
const insideResult = (0, shell_command_projection_cjs_1.execGit)(['rev-parse', '--is-inside-work-tree'], { cwd, timeout: 5000 });
|
|
191
|
+
if (insideResult.exitCode !== 0) {
|
|
192
|
+
return { inside: false, worktreeRoot: null };
|
|
193
|
+
}
|
|
194
|
+
const insideStdout = String(insideResult.stdout || '').trim();
|
|
195
|
+
if (insideStdout !== 'true') {
|
|
196
|
+
return { inside: false, worktreeRoot: null };
|
|
197
|
+
}
|
|
198
|
+
const rootResult = (0, shell_command_projection_cjs_1.execGit)(['rev-parse', '--show-toplevel'], { cwd, timeout: 5000 });
|
|
199
|
+
if (rootResult.exitCode !== 0) {
|
|
200
|
+
return { inside: true, worktreeRoot: null };
|
|
201
|
+
}
|
|
202
|
+
const root = String(rootResult.stdout || '').trim();
|
|
203
|
+
return { inside: true, worktreeRoot: root || null };
|
|
204
|
+
}
|
|
205
|
+
catch {
|
|
206
|
+
return { inside: false, worktreeRoot: null };
|
|
207
|
+
}
|
|
208
|
+
}
|
|
183
209
|
// ─── CLI entry point ──────────────────────────────────────────────────────────
|
|
184
210
|
/**
|
|
185
211
|
* CLI command: `gsd-tools git base-branch`
|
|
@@ -25,10 +25,8 @@
|
|
|
25
25
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
26
26
|
const graphify = require("./graphify.cjs");
|
|
27
27
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
28
|
-
const core = require("./core.cjs");
|
|
29
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
30
28
|
const io = require("./io.cjs");
|
|
31
|
-
const { ERROR_REASON } = io;
|
|
29
|
+
const { output, ERROR_REASON } = io;
|
|
32
30
|
// ─── Implementation ───────────────────────────────────────────────────────────
|
|
33
31
|
function routeGraphifyCommand({ args, cwd, raw, error, _graphify }) {
|
|
34
32
|
const subcommand = args[1];
|
|
@@ -49,20 +47,20 @@ function routeGraphifyCommand({ args, cwd, raw, error, _graphify }) {
|
|
|
49
47
|
}
|
|
50
48
|
budget = parseInt(rawBudget, 10);
|
|
51
49
|
}
|
|
52
|
-
|
|
50
|
+
output(g.graphifyQuery(cwd, term, { budget }), raw);
|
|
53
51
|
}
|
|
54
52
|
else if (subcommand === 'status') {
|
|
55
|
-
|
|
53
|
+
output(g.graphifyStatus(cwd), raw);
|
|
56
54
|
}
|
|
57
55
|
else if (subcommand === 'diff') {
|
|
58
|
-
|
|
56
|
+
output(g.graphifyDiff(cwd), raw);
|
|
59
57
|
}
|
|
60
58
|
else if (subcommand === 'build') {
|
|
61
59
|
if (args[2] === 'snapshot') {
|
|
62
|
-
|
|
60
|
+
output(g.writeSnapshot(cwd), raw);
|
|
63
61
|
}
|
|
64
62
|
else {
|
|
65
|
-
|
|
63
|
+
output(g.graphifyBuild(cwd), raw);
|
|
66
64
|
}
|
|
67
65
|
}
|
|
68
66
|
else {
|
|
@@ -13,32 +13,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
13
13
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
14
14
|
const node_path_1 = __importDefault(require("node:path"));
|
|
15
15
|
const shell_command_projection_cjs_1 = require("./shell-command-projection.cjs");
|
|
16
|
-
//
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
* Reads config.json directly via fs. Returns false by default
|
|
20
|
-
* (when no config, no graphify key, or on error).
|
|
21
|
-
*/
|
|
22
|
-
function isGraphifyEnabled(planningDir) {
|
|
23
|
-
try {
|
|
24
|
-
const configPath = node_path_1.default.join(planningDir, 'config.json');
|
|
25
|
-
if (!node_fs_1.default.existsSync(configPath))
|
|
26
|
-
return false;
|
|
27
|
-
const config = JSON.parse(node_fs_1.default.readFileSync(configPath, 'utf8'));
|
|
28
|
-
if (config &&
|
|
29
|
-
typeof config === 'object' &&
|
|
30
|
-
'graphify' in config &&
|
|
31
|
-
config.graphify &&
|
|
32
|
-
typeof config.graphify === 'object' &&
|
|
33
|
-
'enabled' in config.graphify &&
|
|
34
|
-
config.graphify.enabled === true)
|
|
35
|
-
return true;
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
38
|
-
catch {
|
|
39
|
-
return false;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
17
|
+
const capabilityStateMod = require("./capability-state.cjs");
|
|
18
|
+
const { isCapabilityActive } = capabilityStateMod;
|
|
42
19
|
/**
|
|
43
20
|
* Return the standard disabled response object.
|
|
44
21
|
*/
|
|
@@ -290,7 +267,7 @@ function countCommitsBetween(cwd, from, to) {
|
|
|
290
267
|
*/
|
|
291
268
|
function graphifyQuery(cwd, term, options = {}) {
|
|
292
269
|
const planningDir = node_path_1.default.join(cwd, '.planning');
|
|
293
|
-
if (!
|
|
270
|
+
if (!isCapabilityActive('graphify', cwd))
|
|
294
271
|
return disabledResponse();
|
|
295
272
|
const graphPath = node_path_1.default.join(planningDir, 'graphs', 'graph.json');
|
|
296
273
|
if (!node_fs_1.default.existsSync(graphPath)) {
|
|
@@ -324,7 +301,7 @@ function graphifyQuery(cwd, term, options = {}) {
|
|
|
324
301
|
*/
|
|
325
302
|
function graphifyStatus(cwd) {
|
|
326
303
|
const planningDir = node_path_1.default.join(cwd, '.planning');
|
|
327
|
-
if (!
|
|
304
|
+
if (!isCapabilityActive('graphify', cwd))
|
|
328
305
|
return disabledResponse();
|
|
329
306
|
const graphPath = node_path_1.default.join(planningDir, 'graphs', 'graph.json');
|
|
330
307
|
if (!node_fs_1.default.existsSync(graphPath)) {
|
|
@@ -381,7 +358,7 @@ function graphifyStatus(cwd) {
|
|
|
381
358
|
*/
|
|
382
359
|
function graphifyDiff(cwd) {
|
|
383
360
|
const planningDir = node_path_1.default.join(cwd, '.planning');
|
|
384
|
-
if (!
|
|
361
|
+
if (!isCapabilityActive('graphify', cwd))
|
|
385
362
|
return disabledResponse();
|
|
386
363
|
const snapshotPath = node_path_1.default.join(planningDir, 'graphs', '.last-build-snapshot.json');
|
|
387
364
|
const graphPath = node_path_1.default.join(planningDir, 'graphs', 'graph.json');
|
|
@@ -422,7 +399,7 @@ function graphifyDiff(cwd) {
|
|
|
422
399
|
*/
|
|
423
400
|
function graphifyBuild(cwd) {
|
|
424
401
|
const planningDir = node_path_1.default.join(cwd, '.planning');
|
|
425
|
-
if (!
|
|
402
|
+
if (!isCapabilityActive('graphify', cwd))
|
|
426
403
|
return disabledResponse();
|
|
427
404
|
const installed = checkGraphifyInstalled();
|
|
428
405
|
if (!installed.installed)
|
|
@@ -472,7 +449,6 @@ function writeSnapshot(cwd) {
|
|
|
472
449
|
}
|
|
473
450
|
module.exports = {
|
|
474
451
|
// Config gate
|
|
475
|
-
isGraphifyEnabled,
|
|
476
452
|
disabledResponse,
|
|
477
453
|
// Subprocess
|
|
478
454
|
execGraphify,
|
|
@@ -27,8 +27,8 @@ const node_path_1 = __importDefault(require("node:path"));
|
|
|
27
27
|
const shell_command_projection_cjs_1 = require("./shell-command-projection.cjs");
|
|
28
28
|
const runtime_slash_cjs_1 = require("./runtime-slash.cjs");
|
|
29
29
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
30
|
-
const
|
|
31
|
-
const { output } =
|
|
30
|
+
const ioMod = require("./io.cjs");
|
|
31
|
+
const { output } = ioMod;
|
|
32
32
|
// ─── Utilities ──────────────────────────────────────────────────────────────
|
|
33
33
|
function readOptional(filePath) {
|
|
34
34
|
try {
|
|
@@ -13,8 +13,22 @@ const node_fs_1 = __importDefault(require("node:fs"));
|
|
|
13
13
|
const node_path_1 = __importDefault(require("node:path"));
|
|
14
14
|
const node_os_1 = __importDefault(require("node:os"));
|
|
15
15
|
const shell_command_projection_cjs_1 = require("./shell-command-projection.cjs");
|
|
16
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports --
|
|
17
|
-
const
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports -- io.cjs is an export= CommonJS module
|
|
17
|
+
const io = require("./io.cjs");
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports -- config-loader.cjs is an export= CommonJS module
|
|
19
|
+
const configLoader = require("./config-loader.cjs");
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports -- model-resolver.cjs is an export= CommonJS module
|
|
21
|
+
const modelResolver = require("./model-resolver.cjs");
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports -- phase-locator.cjs is an export= CommonJS module
|
|
23
|
+
const phaseLocator = require("./phase-locator.cjs");
|
|
24
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports -- roadmap-parser.cjs is an export= CommonJS module
|
|
25
|
+
const roadmapParser = require("./roadmap-parser.cjs");
|
|
26
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports -- core-utils.cjs is an export= CommonJS module
|
|
27
|
+
const coreUtils = require("./core-utils.cjs");
|
|
28
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports -- phase-id.cjs is an export= CommonJS module
|
|
29
|
+
const phaseId = require("./phase-id.cjs");
|
|
30
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports -- worktree-safety.cjs is an export= CommonJS module
|
|
31
|
+
const worktreeSafety = require("./worktree-safety.cjs");
|
|
18
32
|
// eslint-disable-next-line @typescript-eslint/no-require-imports -- planning-workspace.cjs is an export= CommonJS module
|
|
19
33
|
const planningWorkspace = require("./planning-workspace.cjs");
|
|
20
34
|
const secrets_cjs_1 = require("./secrets.cjs");
|
|
@@ -28,7 +42,20 @@ const security_cjs_1 = require("./security.cjs");
|
|
|
28
42
|
const runtime_homes_cjs_1 = require("./runtime-homes.cjs");
|
|
29
43
|
// eslint-disable-next-line @typescript-eslint/no-require-imports -- frontmatter.cjs is an export= CommonJS module
|
|
30
44
|
const frontmatterMod = require("./frontmatter.cjs");
|
|
31
|
-
|
|
45
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports -- agent-install-check.cjs is an export= CommonJS module
|
|
46
|
+
const agentInstallCheck = require("./agent-install-check.cjs");
|
|
47
|
+
const { checkAgentsInstalled } = agentInstallCheck;
|
|
48
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports -- git-base-branch.cjs is an export= CommonJS module
|
|
49
|
+
const gitBaseBranch = require("./git-base-branch.cjs");
|
|
50
|
+
const { gitWorktreeInfoInternal } = gitBaseBranch;
|
|
51
|
+
const { output, error } = io;
|
|
52
|
+
const { loadConfig } = configLoader;
|
|
53
|
+
const { resolveModelInternal, resolveGranularityInternal, assertValidGranularityOverride } = modelResolver;
|
|
54
|
+
const { findPhaseInternal } = phaseLocator;
|
|
55
|
+
const { getRoadmapPhaseInternal, getMilestoneInfo, getMilestonePhaseFilter, stripShippedMilestones, extractCurrentMilestone, } = roadmapParser;
|
|
56
|
+
const { pathExistsInternal, generateSlugInternal, toPosixPath } = coreUtils;
|
|
57
|
+
const { normalizePhaseName, phaseTokenMatches } = phaseId;
|
|
58
|
+
const { pruneOrphanedWorktrees } = worktreeSafety;
|
|
32
59
|
const { planningPaths, planningDir, planningRoot, findContextMdIn, } = planningWorkspace;
|
|
33
60
|
const { determinePhaseStatus } = commandsMod;
|
|
34
61
|
const { extractFrontmatter } = frontmatterMod;
|
|
@@ -1222,7 +1249,6 @@ function cmdInitManager(cwd, raw) {
|
|
|
1222
1249
|
}
|
|
1223
1250
|
function cmdInitProgress(cwd, raw) {
|
|
1224
1251
|
try {
|
|
1225
|
-
const { pruneOrphanedWorktrees } = core;
|
|
1226
1252
|
pruneOrphanedWorktrees(cwd);
|
|
1227
1253
|
}
|
|
1228
1254
|
catch {
|
|
@@ -38,17 +38,20 @@
|
|
|
38
38
|
* the case block).
|
|
39
39
|
*/
|
|
40
40
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
41
|
-
const core = require("./core.cjs");
|
|
42
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
43
41
|
const io = require("./io.cjs");
|
|
44
42
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
43
|
+
const coreUtils = require("./core-utils.cjs");
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
45
45
|
const path = require("path");
|
|
46
46
|
const { ERROR_REASON } = io;
|
|
47
|
+
// Default CoreModule implementation assembled from leaf modules.
|
|
48
|
+
// _core seam overrides this entirely for test injection.
|
|
49
|
+
const _defaultCore = { output: io.output, timeAgo: coreUtils.timeAgo };
|
|
47
50
|
// ─── Implementation ───────────────────────────────────────────────────────────
|
|
48
51
|
function routeIntelCommand({ args, cwd, raw, error, _intel, _core }) {
|
|
49
52
|
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-unsafe-assignment
|
|
50
53
|
const intel = _intel ?? require('./intel.cjs');
|
|
51
|
-
const c = _core ??
|
|
54
|
+
const c = _core ?? _defaultCore;
|
|
52
55
|
const subcommand = args[1];
|
|
53
56
|
if (subcommand === 'query') {
|
|
54
57
|
const term = args[2];
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
* Intel files live in .planning/intel/ and store structured data about
|
|
7
7
|
* the project's files, APIs, dependencies, architecture, and tech stack.
|
|
8
8
|
*
|
|
9
|
-
* All public functions gate on intel
|
|
9
|
+
* All public functions gate on isCapabilityActive('intel', cwd) — the shared
|
|
10
|
+
* tri-state resolver (installed + surfaced + intel.enabled config key).
|
|
10
11
|
*
|
|
11
12
|
* ADR-457 build-at-publish: the hand-written bin/lib/intel.cjs collapsed
|
|
12
13
|
* to a TypeScript source of truth. Behaviour is preserved byte-for-behaviour
|
|
@@ -19,6 +20,9 @@ const node_fs_1 = __importDefault(require("node:fs"));
|
|
|
19
20
|
const node_path_1 = __importDefault(require("node:path"));
|
|
20
21
|
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
21
22
|
const shell_command_projection_cjs_1 = require("./shell-command-projection.cjs");
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
24
|
+
const capabilityStateMod = require("./capability-state.cjs");
|
|
25
|
+
const { isCapabilityActive } = capabilityStateMod;
|
|
22
26
|
// ─── Constants ───────────────────────────────────────────────────────────────
|
|
23
27
|
const INTEL_DIR = '.planning/intel';
|
|
24
28
|
const INTEL_FILES = {
|
|
@@ -38,30 +42,20 @@ function ensureIntelDir(planningDir) {
|
|
|
38
42
|
return intelPath;
|
|
39
43
|
}
|
|
40
44
|
/**
|
|
41
|
-
* Check whether intel is enabled
|
|
42
|
-
*
|
|
43
|
-
*
|
|
45
|
+
* Check whether intel is active (installed, surfaced, and config-enabled) for the project at cwd.
|
|
46
|
+
* Delegates to the shared tri-state capability resolver (isCapabilityActive) which honours the
|
|
47
|
+
* install profile, runtime surface, and activationKey (intel.enabled config gate).
|
|
48
|
+
*
|
|
49
|
+
* NOTE: planningDir is the legacy entry-point; cwd is derived as path.dirname(planningDir).
|
|
50
|
+
* Callers that have cwd directly may call isCapabilityActive('intel', cwd) themselves.
|
|
51
|
+
*
|
|
52
|
+
* INVARIANT: planningDir is always `<cwd>/.planning` (i.e. path.join(cwd, '.planning')).
|
|
53
|
+
* The intel-command-router always constructs planningDir as path.join(cwd, '.planning'),
|
|
54
|
+
* so path.dirname(planningDir) === cwd is guaranteed. If a workstream-aware planningDir
|
|
55
|
+
* were ever passed here, the dirname would be wrong — but no caller does that.
|
|
44
56
|
*/
|
|
45
|
-
function
|
|
46
|
-
|
|
47
|
-
const configPath = node_path_1.default.join(planningDir, 'config.json');
|
|
48
|
-
const raw = (0, shell_command_projection_cjs_1.platformReadSync)(configPath);
|
|
49
|
-
if (raw === null)
|
|
50
|
-
return false;
|
|
51
|
-
const config = JSON.parse(raw);
|
|
52
|
-
if (config &&
|
|
53
|
-
typeof config === 'object' &&
|
|
54
|
-
'intel' in config &&
|
|
55
|
-
config.intel &&
|
|
56
|
-
typeof config.intel === 'object' &&
|
|
57
|
-
'enabled' in config.intel &&
|
|
58
|
-
config.intel.enabled === true)
|
|
59
|
-
return true;
|
|
60
|
-
return false;
|
|
61
|
-
}
|
|
62
|
-
catch {
|
|
63
|
-
return false;
|
|
64
|
-
}
|
|
57
|
+
function isIntelCapabilityActive(planningDir) {
|
|
58
|
+
return isCapabilityActive('intel', node_path_1.default.dirname(planningDir));
|
|
65
59
|
}
|
|
66
60
|
/**
|
|
67
61
|
* Return the standard disabled response object.
|
|
@@ -152,7 +146,7 @@ function matchesInValue(value, lowerTerm) {
|
|
|
152
146
|
* Searches across all JSON intel files in INTEL_FILES (keys and values), including arch-decisions.json (parsed as JSON, not as text).
|
|
153
147
|
*/
|
|
154
148
|
function intelQuery(term, planningDir) {
|
|
155
|
-
if (!
|
|
149
|
+
if (!isIntelCapabilityActive(planningDir))
|
|
156
150
|
return disabledResponse();
|
|
157
151
|
const matches = [];
|
|
158
152
|
let total = 0;
|
|
@@ -175,7 +169,7 @@ function intelQuery(term, planningDir) {
|
|
|
175
169
|
* A file is considered stale if its updated_at is older than 24 hours.
|
|
176
170
|
*/
|
|
177
171
|
function intelStatus(planningDir) {
|
|
178
|
-
if (!
|
|
172
|
+
if (!isIntelCapabilityActive(planningDir))
|
|
179
173
|
return disabledResponse();
|
|
180
174
|
const STALE_MS = 24 * 60 * 60 * 1000; // 24 hours
|
|
181
175
|
const now = Date.now();
|
|
@@ -210,7 +204,7 @@ function intelStatus(planningDir) {
|
|
|
210
204
|
* Show changes since the last full refresh by comparing file hashes.
|
|
211
205
|
*/
|
|
212
206
|
function intelDiff(planningDir) {
|
|
213
|
-
if (!
|
|
207
|
+
if (!isIntelCapabilityActive(planningDir))
|
|
214
208
|
return disabledResponse();
|
|
215
209
|
const snapshotPath = intelFilePath(planningDir, '.last-refresh.json');
|
|
216
210
|
const snapshot = safeReadJson(snapshotPath);
|
|
@@ -242,7 +236,7 @@ function intelDiff(planningDir) {
|
|
|
242
236
|
* The actual update is performed by the intel-updater agent (PLAN-02).
|
|
243
237
|
*/
|
|
244
238
|
function intelUpdate(planningDir) {
|
|
245
|
-
if (!
|
|
239
|
+
if (!isIntelCapabilityActive(planningDir))
|
|
246
240
|
return disabledResponse();
|
|
247
241
|
return {
|
|
248
242
|
action: 'spawn_agent',
|
|
@@ -280,7 +274,7 @@ function saveRefreshSnapshot(planningDir) {
|
|
|
280
274
|
* Writes .last-refresh.json with accurate timestamps and hashes.
|
|
281
275
|
*/
|
|
282
276
|
function intelSnapshot(planningDir) {
|
|
283
|
-
if (!
|
|
277
|
+
if (!isIntelCapabilityActive(planningDir))
|
|
284
278
|
return disabledResponse();
|
|
285
279
|
return saveRefreshSnapshot(planningDir);
|
|
286
280
|
}
|
|
@@ -288,7 +282,7 @@ function intelSnapshot(planningDir) {
|
|
|
288
282
|
* Validate all intel files for correctness and freshness.
|
|
289
283
|
*/
|
|
290
284
|
function intelValidate(planningDir) {
|
|
291
|
-
if (!
|
|
285
|
+
if (!isIntelCapabilityActive(planningDir))
|
|
292
286
|
return disabledResponse();
|
|
293
287
|
const errors = [];
|
|
294
288
|
const warnings = [];
|
|
@@ -375,7 +369,7 @@ function intelValidate(planningDir) {
|
|
|
375
369
|
* mistake silence for "nothing exists".
|
|
376
370
|
*/
|
|
377
371
|
function intelApiSurface(planningDir) {
|
|
378
|
-
if (!
|
|
372
|
+
if (!isIntelCapabilityActive(planningDir))
|
|
379
373
|
return disabledResponse();
|
|
380
374
|
const intelPath = ensureIntelDir(planningDir);
|
|
381
375
|
const apiMapPath = node_path_1.default.join(intelPath, INTEL_FILES.apis);
|
|
@@ -426,7 +420,7 @@ function intelApiSurface(planningDir) {
|
|
|
426
420
|
* Patch _meta.updated_at in a JSON intel file to the current timestamp.
|
|
427
421
|
* Reads the file, updates _meta.updated_at, increments version, writes back.
|
|
428
422
|
*
|
|
429
|
-
* NOTE: Does not gate on
|
|
423
|
+
* NOTE: Does not gate on isCapabilityActive — operates on arbitrary file paths
|
|
430
424
|
* for use by agents patching individual files outside the intel store.
|
|
431
425
|
*/
|
|
432
426
|
function intelPatchMeta(filePath) {
|
|
@@ -458,7 +452,7 @@ function intelPatchMeta(filePath) {
|
|
|
458
452
|
/**
|
|
459
453
|
* Extract exports from a JS/CJS file by parsing module.exports or exports.X patterns.
|
|
460
454
|
*
|
|
461
|
-
* NOTE: Does not gate on
|
|
455
|
+
* NOTE: Does not gate on isCapabilityActive — operates on arbitrary source files
|
|
462
456
|
* for use by agents building intel data from project files.
|
|
463
457
|
*/
|
|
464
458
|
function intelExtractExports(filePath) {
|
|
@@ -583,7 +577,7 @@ module.exports = {
|
|
|
583
577
|
intelApiSurface,
|
|
584
578
|
// Utilities
|
|
585
579
|
ensureIntelDir,
|
|
586
|
-
|
|
580
|
+
isIntelCapabilityActive,
|
|
587
581
|
// Constants
|
|
588
582
|
INTEL_FILES,
|
|
589
583
|
INTEL_DIR,
|
package/gsd-core/bin/lib/io.cjs
CHANGED
|
@@ -5,10 +5,8 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Extracted from core.cts (ADR-857 rollout phase 1 / issue #859).
|
|
7
7
|
* The hand-written bodies are preserved byte-for-behaviour; only the module
|
|
8
|
-
* boundary moved. core.
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* New imports should pull I/O primitives from io.cjs directly.
|
|
8
|
+
* boundary moved. The core.cjs re-export spine was retired in epic #1267;
|
|
9
|
+
* callers import I/O primitives from io.cjs directly.
|
|
12
10
|
*/
|
|
13
11
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
@@ -23,8 +23,8 @@ const node_path_1 = __importDefault(require("node:path"));
|
|
|
23
23
|
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
24
24
|
const node_os_1 = __importDefault(require("node:os"));
|
|
25
25
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
26
|
-
const
|
|
27
|
-
const { output, error: coreError } =
|
|
26
|
+
const ioMod = require("./io.cjs");
|
|
27
|
+
const { output, error: coreError } = ioMod;
|
|
28
28
|
const shell_command_projection_cjs_1 = require("./shell-command-projection.cjs");
|
|
29
29
|
// ─── Constants ───────────────────────────────────────────────────────────────
|
|
30
30
|
const DEFAULT_STORE_DIR = node_path_1.default.join(node_os_1.default.homedir(), '.gsd', 'knowledge');
|