@ai-sdlc/orchestrator 0.6.0 → 0.9.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/dist/admission-composite.d.ts +67 -0
- package/dist/admission-composite.js +158 -0
- package/dist/admission-enrichment.d.ts +142 -0
- package/dist/admission-enrichment.js +331 -0
- package/dist/admission-hc.d.ts +62 -0
- package/dist/admission-hc.js +83 -0
- package/dist/admission-score.d.ts +95 -5
- package/dist/admission-score.js +84 -11
- package/dist/analysis/analyzer.js +3 -2
- package/dist/analysis/convention-detector.d.ts +85 -2
- package/dist/analysis/convention-detector.js +375 -70
- package/dist/analysis/diff-analyzer.d.ts +33 -0
- package/dist/analysis/diff-analyzer.js +122 -0
- package/dist/analysis/hotspot-analyzer.js +3 -1
- package/dist/analysis/index.d.ts +2 -1
- package/dist/analysis/index.js +2 -1
- package/dist/artifacts/index.d.ts +65 -0
- package/dist/artifacts/index.js +142 -0
- package/dist/backlog-adapter.d.ts +121 -0
- package/dist/backlog-adapter.js +438 -0
- package/dist/calibration.d.ts +43 -0
- package/dist/calibration.js +76 -0
- package/dist/cli/commands/agents.d.ts +24 -0
- package/dist/cli/commands/agents.js +66 -1
- package/dist/cli/commands/git-remote.d.ts +49 -0
- package/dist/cli/commands/git-remote.js +91 -0
- package/dist/cli/commands/health.d.ts +4 -0
- package/dist/cli/commands/health.js +13 -1
- package/dist/cli/commands/init.d.ts +26 -0
- package/dist/cli/commands/init.js +164 -22
- package/dist/cli/commands/mcp-setup.d.ts +31 -0
- package/dist/cli/commands/mcp-setup.js +78 -8
- package/dist/cli/formatters/table.js +15 -2
- package/dist/cli/index.d.ts +14 -1
- package/dist/cli/index.js +81 -20
- package/dist/cli/versions.d.ts +57 -0
- package/dist/cli/versions.js +128 -0
- package/dist/code-area-classifier.d.ts +21 -0
- package/dist/code-area-classifier.js +48 -0
- package/dist/config.d.ts +33 -1
- package/dist/config.js +78 -8
- package/dist/database/adapters/external.d.ts +24 -0
- package/dist/database/adapters/external.js +80 -0
- package/dist/database/adapters/neon.d.ts +41 -0
- package/dist/database/adapters/neon.js +98 -0
- package/dist/database/adapters/pg-snapshot-restore.d.ts +28 -0
- package/dist/database/adapters/pg-snapshot-restore.js +68 -0
- package/dist/database/adapters/sqlite-copy.d.ts +32 -0
- package/dist/database/adapters/sqlite-copy.js +145 -0
- package/dist/database/connection-injection.d.ts +35 -0
- package/dist/database/connection-injection.js +93 -0
- package/dist/database/index.d.ts +12 -0
- package/dist/database/index.js +23 -0
- package/dist/database/registry.d.ts +13 -0
- package/dist/database/registry.js +27 -0
- package/dist/database/topology.d.ts +52 -0
- package/dist/database/topology.js +44 -0
- package/dist/database/types.d.ts +89 -0
- package/dist/database/types.js +26 -0
- package/dist/design-authority.d.ts +40 -0
- package/dist/design-authority.js +71 -0
- package/dist/design-lookahead.d.ts +64 -0
- package/dist/design-lookahead.js +86 -0
- package/dist/design-quality-trend.d.ts +87 -0
- package/dist/design-quality-trend.js +190 -0
- package/dist/design-system-context.d.ts +46 -0
- package/dist/design-system-context.js +80 -0
- package/dist/design-system-correction-loop.d.ts +64 -0
- package/dist/design-system-correction-loop.js +128 -0
- package/dist/design-system-metrics.d.ts +61 -0
- package/dist/design-system-metrics.js +104 -0
- package/dist/design-system-stewardship.d.ts +22 -0
- package/dist/design-system-stewardship.js +85 -0
- package/dist/design-system-validation.d.ts +37 -0
- package/dist/design-system-validation.js +88 -0
- package/dist/dispatch/index.d.ts +4 -0
- package/dist/dispatch/index.js +4 -0
- package/dist/dispatch/merge-gate.d.ts +46 -0
- package/dist/dispatch/merge-gate.js +90 -0
- package/dist/dispatch/requeue.d.ts +57 -0
- package/dist/dispatch/requeue.js +131 -0
- package/dist/dispatch/worker-pool.d.ts +62 -0
- package/dist/dispatch/worker-pool.js +60 -0
- package/dist/execute.d.ts +40 -0
- package/dist/execute.js +185 -15
- package/dist/fix-ci.js +8 -1
- package/dist/fix-review.js +8 -1
- package/dist/harness/adapters/claude-code.d.ts +29 -0
- package/dist/harness/adapters/claude-code.js +191 -0
- package/dist/harness/adapters/codex.d.ts +25 -0
- package/dist/harness/adapters/codex.js +61 -0
- package/dist/harness/independence.d.ts +51 -0
- package/dist/harness/independence.js +67 -0
- package/dist/harness/index.d.ts +14 -0
- package/dist/harness/index.js +20 -0
- package/dist/harness/registry.d.ts +17 -0
- package/dist/harness/registry.js +31 -0
- package/dist/harness/types.d.ts +123 -0
- package/dist/harness/types.js +8 -0
- package/dist/harness/version-probe.d.ts +14 -0
- package/dist/harness/version-probe.js +123 -0
- package/dist/index.d.ts +30 -4
- package/dist/index.js +35 -2
- package/dist/models/classifier.d.ts +76 -0
- package/dist/models/classifier.js +221 -0
- package/dist/models/index.d.ts +3 -0
- package/dist/models/index.js +3 -0
- package/dist/models/registry.d.ts +97 -0
- package/dist/models/registry.js +173 -0
- package/dist/pillar-breakdown.d.ts +63 -0
- package/dist/pillar-breakdown.js +153 -0
- package/dist/priority.d.ts +5 -0
- package/dist/priority.js +18 -5
- package/dist/review-meta.d.ts +65 -0
- package/dist/review-meta.js +149 -0
- package/dist/review.d.ts +4 -0
- package/dist/review.js +12 -2
- package/dist/runners/claude-code-sdk.d.ts +31 -0
- package/dist/runners/claude-code-sdk.js +238 -0
- package/dist/runners/claude-code.d.ts +3 -0
- package/dist/runners/claude-code.js +30 -66
- package/dist/runners/codex.js +4 -1
- package/dist/runners/copilot.js +4 -1
- package/dist/runners/cursor.js +4 -1
- package/dist/runners/git-utils.d.ts +81 -0
- package/dist/runners/git-utils.js +201 -0
- package/dist/runners/index.d.ts +3 -0
- package/dist/runners/index.js +3 -0
- package/dist/runners/review-agent.d.ts +20 -0
- package/dist/runners/review-agent.js +171 -41
- package/dist/runners/runner-registry.js +10 -0
- package/dist/runners/sdk-review-runner.d.ts +65 -0
- package/dist/runners/sdk-review-runner.js +185 -0
- package/dist/runners/security-triage.d.ts +20 -4
- package/dist/runners/security-triage.js +39 -15
- package/dist/runners/types.d.ts +6 -0
- package/dist/runtime/attestations.d.ts +274 -0
- package/dist/runtime/attestations.js +460 -0
- package/dist/runtime/git-env.d.ts +53 -0
- package/dist/runtime/git-env.js +60 -0
- package/dist/runtime/index.d.ts +7 -0
- package/dist/runtime/index.js +7 -0
- package/dist/runtime/parallelism-flag.d.ts +10 -0
- package/dist/runtime/parallelism-flag.js +18 -0
- package/dist/runtime/port-allocator.d.ts +21 -0
- package/dist/runtime/port-allocator.js +66 -0
- package/dist/runtime/worktree-pool.d.ts +86 -0
- package/dist/runtime/worktree-pool.js +204 -0
- package/dist/runtime/worktree.d.ts +25 -0
- package/dist/runtime/worktree.js +111 -0
- package/dist/sa-scoring/auto-calibrate.d.ts +69 -0
- package/dist/sa-scoring/auto-calibrate.js +107 -0
- package/dist/sa-scoring/c1-sa2-computable.d.ts +42 -0
- package/dist/sa-scoring/c1-sa2-computable.js +59 -0
- package/dist/sa-scoring/composite.d.ts +107 -0
- package/dist/sa-scoring/composite.js +139 -0
- package/dist/sa-scoring/depparse-client.d.ts +79 -0
- package/dist/sa-scoring/depparse-client.js +187 -0
- package/dist/sa-scoring/did-compiler.d.ts +122 -0
- package/dist/sa-scoring/did-compiler.js +286 -0
- package/dist/sa-scoring/drift-monitor.d.ts +84 -0
- package/dist/sa-scoring/drift-monitor.js +186 -0
- package/dist/sa-scoring/exemplar-bank.d.ts +78 -0
- package/dist/sa-scoring/exemplar-bank.js +154 -0
- package/dist/sa-scoring/feedback-store.d.ts +100 -0
- package/dist/sa-scoring/feedback-store.js +156 -0
- package/dist/sa-scoring/index.d.ts +71 -0
- package/dist/sa-scoring/index.js +158 -0
- package/dist/sa-scoring/layer1-deterministic.d.ts +115 -0
- package/dist/sa-scoring/layer1-deterministic.js +298 -0
- package/dist/sa-scoring/layer2-structural.d.ts +71 -0
- package/dist/sa-scoring/layer2-structural.js +151 -0
- package/dist/sa-scoring/layer3-llm.d.ts +86 -0
- package/dist/sa-scoring/layer3-llm.js +282 -0
- package/dist/sa-scoring/rescore-orchestrator.d.ts +52 -0
- package/dist/sa-scoring/rescore-orchestrator.js +47 -0
- package/dist/scheduling/burn-down.d.ts +27 -0
- package/dist/scheduling/burn-down.js +43 -0
- package/dist/scheduling/calibration.d.ts +42 -0
- package/dist/scheduling/calibration.js +150 -0
- package/dist/scheduling/index.d.ts +8 -0
- package/dist/scheduling/index.js +8 -0
- package/dist/scheduling/ledger.d.ts +59 -0
- package/dist/scheduling/ledger.js +216 -0
- package/dist/scheduling/off-peak.d.ts +27 -0
- package/dist/scheduling/off-peak.js +112 -0
- package/dist/scheduling/schedule-decision.d.ts +39 -0
- package/dist/scheduling/schedule-decision.js +89 -0
- package/dist/scheduling/tier-analysis.d.ts +47 -0
- package/dist/scheduling/tier-analysis.js +81 -0
- package/dist/scheduling/types.d.ts +140 -0
- package/dist/scheduling/types.js +11 -0
- package/dist/shared.d.ts +13 -0
- package/dist/shared.js +32 -0
- package/dist/state/schema.d.ts +5 -1
- package/dist/state/schema.js +223 -1
- package/dist/state/store.d.ts +55 -1
- package/dist/state/store.js +342 -7
- package/dist/state/types.d.ts +139 -0
- package/dist/types.d.ts +1 -1
- package/dist/validate-agent-output.js +4 -1
- package/dist/watch.js +6 -0
- package/package.json +2 -2
|
@@ -1,23 +1,48 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MCP server setup — detect coding agents and install MCP config.
|
|
3
|
+
*
|
|
4
|
+
* AISDLC-78 changes:
|
|
5
|
+
* - The `npx -y` arg list now pins `@ai-sdlc/mcp-advisor@<version>` so
|
|
6
|
+
* fresh installs don't silently jump to whatever is published when
|
|
7
|
+
* the orchestrator binary itself was last updated. Each generated
|
|
8
|
+
* config file carries a single top-level `_aiSdlcComment` documenting
|
|
9
|
+
* how to opt back into floating-tag behaviour.
|
|
10
|
+
* - Cursor is no longer detected by binary-on-PATH alone; the user
|
|
11
|
+
* must either have a `.cursor/` directory present (real signal of
|
|
12
|
+
* use) or pass `--cursor` to opt in. This avoids writing
|
|
13
|
+
* `.cursor/mcp.json` into projects whose author has Cursor
|
|
14
|
+
* installed but is not using it on this repo.
|
|
3
15
|
*/
|
|
4
16
|
import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
5
17
|
import { join, dirname } from 'node:path';
|
|
6
18
|
import { execSync } from 'node:child_process';
|
|
7
|
-
|
|
19
|
+
/**
|
|
20
|
+
* The opt-out comment we write alongside the pinned mcp-advisor entry.
|
|
21
|
+
* Lives at the top level of the generated MCP config under a leading-
|
|
22
|
+
* underscore key so JSON parsers and MCP clients ignore it; humans
|
|
23
|
+
* editing by hand see exactly how to re-enable floating-latest behaviour.
|
|
24
|
+
*/
|
|
25
|
+
const PIN_OPT_OUT_COMMENT = 'Pinned to the orchestrator version that ran `ai-sdlc init`. ' +
|
|
26
|
+
'To always pull the latest published mcp-advisor, change args to ["-y", "@ai-sdlc/mcp-advisor"].';
|
|
27
|
+
function pinnedSpec(version) {
|
|
28
|
+
return version && version !== '0.0.0'
|
|
29
|
+
? `@ai-sdlc/mcp-advisor@${version}`
|
|
30
|
+
: '@ai-sdlc/mcp-advisor';
|
|
31
|
+
}
|
|
32
|
+
function standardEntry(version, env) {
|
|
8
33
|
const entry = {
|
|
9
34
|
command: 'npx',
|
|
10
|
-
args: ['-y',
|
|
35
|
+
args: ['-y', pinnedSpec(version)],
|
|
11
36
|
};
|
|
12
37
|
if (env)
|
|
13
38
|
entry.env = env;
|
|
14
39
|
return entry;
|
|
15
40
|
}
|
|
16
|
-
function vscodeEntry(env) {
|
|
41
|
+
function vscodeEntry(version, env) {
|
|
17
42
|
const entry = {
|
|
18
43
|
type: 'stdio',
|
|
19
44
|
command: 'npx',
|
|
20
|
-
args: ['-y',
|
|
45
|
+
args: ['-y', pinnedSpec(version)],
|
|
21
46
|
};
|
|
22
47
|
if (env)
|
|
23
48
|
entry.env = env;
|
|
@@ -39,6 +64,7 @@ const AGENT_SPECS = [
|
|
|
39
64
|
entryFn: standardEntry,
|
|
40
65
|
configDir: '.cursor',
|
|
41
66
|
binary: 'cursor',
|
|
67
|
+
requiresOptIn: true,
|
|
42
68
|
},
|
|
43
69
|
{
|
|
44
70
|
name: 'VS Code',
|
|
@@ -66,31 +92,67 @@ function hasBinary(name) {
|
|
|
66
92
|
return false;
|
|
67
93
|
}
|
|
68
94
|
}
|
|
69
|
-
|
|
95
|
+
function hasUserCursorDir() {
|
|
96
|
+
const home = process.env.HOME ?? process.env.USERPROFILE;
|
|
97
|
+
if (!home)
|
|
98
|
+
return false;
|
|
99
|
+
return existsSync(join(home, '.cursor'));
|
|
100
|
+
}
|
|
101
|
+
export function detectAgentsDetailed(projectDir, options) {
|
|
70
102
|
const detected = [];
|
|
103
|
+
const skipped = [];
|
|
71
104
|
const env = options?.isWorkspace ? { AI_SDLC_WORKSPACE: '.' } : undefined;
|
|
105
|
+
const pinVersion = options?.pinVersion;
|
|
72
106
|
for (const spec of AGENT_SPECS) {
|
|
73
107
|
if (spec.alwaysDetect) {
|
|
74
108
|
detected.push({
|
|
75
109
|
name: spec.name,
|
|
76
110
|
configPath: spec.configPath,
|
|
77
111
|
configKey: spec.configKey,
|
|
78
|
-
serverEntry: spec.entryFn(env),
|
|
112
|
+
serverEntry: spec.entryFn(pinVersion, env),
|
|
79
113
|
});
|
|
80
114
|
continue;
|
|
81
115
|
}
|
|
82
116
|
const hasDir = spec.configDir ? existsSync(join(projectDir, spec.configDir)) : false;
|
|
83
117
|
const hasBin = spec.binary ? hasBinary(spec.binary) : false;
|
|
118
|
+
if (spec.requiresOptIn) {
|
|
119
|
+
// For Cursor specifically: explicit --cursor flag, OR a project-local
|
|
120
|
+
// .cursor/ dir, OR a user-global ~/.cursor/ presence. Just having
|
|
121
|
+
// `cursor` on PATH is no longer sufficient (too noisy on dev boxes
|
|
122
|
+
// where Cursor is installed but not used per-project).
|
|
123
|
+
const userOptIn = options?.cursorOptIn === true;
|
|
124
|
+
if (userOptIn || hasDir || hasUserCursorDir()) {
|
|
125
|
+
detected.push({
|
|
126
|
+
name: spec.name,
|
|
127
|
+
configPath: spec.configPath,
|
|
128
|
+
configKey: spec.configKey,
|
|
129
|
+
serverEntry: spec.entryFn(pinVersion, env),
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
skipped.push({
|
|
134
|
+
name: spec.name,
|
|
135
|
+
reason: 'no .cursor/ directory in project or $HOME; pass --cursor to install Cursor MCP config',
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
84
140
|
if (hasDir || hasBin) {
|
|
85
141
|
detected.push({
|
|
86
142
|
name: spec.name,
|
|
87
143
|
configPath: spec.configPath,
|
|
88
144
|
configKey: spec.configKey,
|
|
89
|
-
serverEntry: spec.entryFn(env),
|
|
145
|
+
serverEntry: spec.entryFn(pinVersion, env),
|
|
90
146
|
});
|
|
91
147
|
}
|
|
92
148
|
}
|
|
93
|
-
return detected;
|
|
149
|
+
return { detected, skipped };
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Backwards-compatible wrapper. New code should prefer detectAgentsDetailed.
|
|
153
|
+
*/
|
|
154
|
+
export function detectAgents(projectDir, options) {
|
|
155
|
+
return detectAgentsDetailed(projectDir, options).detected;
|
|
94
156
|
}
|
|
95
157
|
export function installMcpServer(projectDir, agent, dryRun) {
|
|
96
158
|
const fullPath = join(projectDir, agent.configPath);
|
|
@@ -110,6 +172,13 @@ export function installMcpServer(projectDir, agent, dryRun) {
|
|
|
110
172
|
if (!dryRun) {
|
|
111
173
|
section['ai-sdlc'] = agent.serverEntry;
|
|
112
174
|
existing[agent.configKey] = section;
|
|
175
|
+
// Top-level pin-comment: standard convention is a single
|
|
176
|
+
// `_aiSdlcComment` key at the root of the document, not inside each
|
|
177
|
+
// server entry. We add it on first write but never overwrite an
|
|
178
|
+
// existing top-level value (caller may have customised it).
|
|
179
|
+
if (!('_aiSdlcComment' in existing)) {
|
|
180
|
+
existing._aiSdlcComment = PIN_OPT_OUT_COMMENT;
|
|
181
|
+
}
|
|
113
182
|
writeFileSync(fullPath, JSON.stringify(existing, null, 2) + '\n', 'utf-8');
|
|
114
183
|
}
|
|
115
184
|
return 'merged';
|
|
@@ -120,6 +189,7 @@ export function installMcpServer(projectDir, agent, dryRun) {
|
|
|
120
189
|
mkdirSync(dir, { recursive: true });
|
|
121
190
|
}
|
|
122
191
|
const config = {
|
|
192
|
+
_aiSdlcComment: PIN_OPT_OUT_COMMENT,
|
|
123
193
|
[agent.configKey]: {
|
|
124
194
|
'ai-sdlc': agent.serverEntry,
|
|
125
195
|
},
|
|
@@ -37,7 +37,12 @@ export function formatTable(data) {
|
|
|
37
37
|
lines.push('Health Check');
|
|
38
38
|
lines.push('─'.repeat(40));
|
|
39
39
|
lines.push(`Config: ${data.configValid ? 'valid' : 'INVALID'}`);
|
|
40
|
-
|
|
40
|
+
// AISDLC-78: the previous "not configured" string read like a setup
|
|
41
|
+
// failure to fresh users. The state store is created on demand by
|
|
42
|
+
// the first pipeline run; explicitly flag deferred initialization.
|
|
43
|
+
lines.push(`State Store: ${data.stateStoreConnected
|
|
44
|
+
? 'connected'
|
|
45
|
+
: 'deferred (initializes on first pipeline run; pass --init-state to create now)'}`);
|
|
41
46
|
const errors = data.errors;
|
|
42
47
|
if (errors.length > 0) {
|
|
43
48
|
lines.push('');
|
|
@@ -65,8 +70,16 @@ export function formatTable(data) {
|
|
|
65
70
|
for (const agent of agents) {
|
|
66
71
|
const total = agent.totalTasks;
|
|
67
72
|
const success = agent.successCount;
|
|
73
|
+
const declaredOnly = agent.declaredOnly === true;
|
|
68
74
|
const pct = total > 0 ? `${Math.round((success / total) * 100)}%` : '-';
|
|
69
|
-
|
|
75
|
+
// AISDLC-78 (AC #10): mark declared-but-not-executed rows so a
|
|
76
|
+
// fresh-install user sees their `agent-role.yaml` declarations
|
|
77
|
+
// even before the first pipeline run populates the ledger.
|
|
78
|
+
const lastTask = declaredOnly
|
|
79
|
+
? '(declared, not yet executed)'
|
|
80
|
+
: agent.lastTaskAt
|
|
81
|
+
? agent.lastTaskAt.split('T')[0]
|
|
82
|
+
: '-';
|
|
70
83
|
lines.push(String(agent.agentName ?? '').padEnd(20) +
|
|
71
84
|
String(agent.currentLevel ?? 0).padEnd(7) +
|
|
72
85
|
String(total).padEnd(7) +
|
package/dist/cli/index.d.ts
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
3
|
* AI-SDLC CLI — entry point for the Commander-based CLI.
|
|
4
|
+
*
|
|
5
|
+
* AISDLC-78: replaces the literal `0.1.0` version with the real package
|
|
6
|
+
* version, prints a 3-line provenance block on `--version`, and adds an
|
|
7
|
+
* unknown-subcommand hint that points at the upgrade flow when version
|
|
8
|
+
* drift is detected.
|
|
4
9
|
*/
|
|
5
|
-
|
|
10
|
+
import { Command } from 'commander';
|
|
11
|
+
import { type VersionTriple } from './versions.js';
|
|
12
|
+
/**
|
|
13
|
+
* Build the Commander program. Exported so integration tests can drive
|
|
14
|
+
* the real argv pipeline (`--version`, unknown-subcommand) without
|
|
15
|
+
* invoking the bundled binary on disk. The bin shim below calls this
|
|
16
|
+
* exact factory at startup.
|
|
17
|
+
*/
|
|
18
|
+
export declare function buildProgram(versions: VersionTriple): Command;
|
|
6
19
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/cli/index.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
3
|
* AI-SDLC CLI — entry point for the Commander-based CLI.
|
|
4
|
+
*
|
|
5
|
+
* AISDLC-78: replaces the literal `0.1.0` version with the real package
|
|
6
|
+
* version, prints a 3-line provenance block on `--version`, and adds an
|
|
7
|
+
* unknown-subcommand hint that points at the upgrade flow when version
|
|
8
|
+
* drift is detected.
|
|
4
9
|
*/
|
|
5
10
|
import { Command } from 'commander';
|
|
6
11
|
import { initCommand } from './commands/init.js';
|
|
@@ -14,24 +19,80 @@ import { complexityCommand } from './commands/complexity.js';
|
|
|
14
19
|
import { costCommand } from './commands/cost.js';
|
|
15
20
|
import { dashboardCommand } from './commands/dashboard.js';
|
|
16
21
|
import { validateCommand } from './commands/validate.js';
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
program
|
|
26
|
-
program
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
22
|
+
import { resolveVersions, formatVersionBlock, upgradeHint, } from './versions.js';
|
|
23
|
+
/**
|
|
24
|
+
* Build the Commander program. Exported so integration tests can drive
|
|
25
|
+
* the real argv pipeline (`--version`, unknown-subcommand) without
|
|
26
|
+
* invoking the bundled binary on disk. The bin shim below calls this
|
|
27
|
+
* exact factory at startup.
|
|
28
|
+
*/
|
|
29
|
+
export function buildProgram(versions) {
|
|
30
|
+
const program = new Command();
|
|
31
|
+
program
|
|
32
|
+
.name('ai-sdlc')
|
|
33
|
+
.description('AI-SDLC Orchestrator — drive issues through the SDLC with AI agents')
|
|
34
|
+
// Anchor commander's --version to the real package version so a user
|
|
35
|
+
// who just ran `npm i -g @ai-sdlc/orchestrator` sees the version they
|
|
36
|
+
// installed, not the literal that was hardcoded years ago.
|
|
37
|
+
.version(versions.cli, '-V, --version', 'Print the CLI version')
|
|
38
|
+
.option('-c, --config <dir>', 'Config directory path', '.ai-sdlc')
|
|
39
|
+
.option('-f, --format <type>', 'Output format: table, json, minimal', 'table')
|
|
40
|
+
.option('-v, --verbose', 'Enable verbose output');
|
|
41
|
+
// Override commander's default --version handler so we can emit the full
|
|
42
|
+
// 3-line block (CLI + orchestrator + plugin) instead of just the literal.
|
|
43
|
+
//
|
|
44
|
+
// IMPORTANT: commander 12's `.version()` registers its own
|
|
45
|
+
// `option:version` listener (in registration order) that writes the
|
|
46
|
+
// bare version string and calls `_exit`. Plain `.on()` would queue
|
|
47
|
+
// *after* commander's listener, so our 3-line block would never
|
|
48
|
+
// print. `prependListener` puts ours first; calling commander's own
|
|
49
|
+
// `_exit` here prevents the default listener from ever firing while
|
|
50
|
+
// still going through `exitOverride()` so tests can intercept.
|
|
51
|
+
// commander's Command extends EventEmitter; the .d.ts only re-exports
|
|
52
|
+
// .on/.once, so we reach for prependListener via the EventEmitter cast.
|
|
53
|
+
program.prependListener('option:version', () => {
|
|
54
|
+
const writeOut = program.configureOutput().writeOut ?? ((s) => process.stdout.write(s));
|
|
55
|
+
writeOut(`${formatVersionBlock(versions)}\n`);
|
|
56
|
+
program._exit(0, 'commander.version', versions.cli);
|
|
57
|
+
});
|
|
58
|
+
program.addCommand(initCommand);
|
|
59
|
+
program.addCommand(runCommand);
|
|
60
|
+
program.addCommand(startCommand);
|
|
61
|
+
program.addCommand(statusCommand);
|
|
62
|
+
program.addCommand(healthCommand);
|
|
63
|
+
program.addCommand(agentsCommand);
|
|
64
|
+
program.addCommand(routingCommand);
|
|
65
|
+
program.addCommand(complexityCommand);
|
|
66
|
+
program.addCommand(costCommand);
|
|
67
|
+
program.addCommand(dashboardCommand);
|
|
68
|
+
program.addCommand(validateCommand);
|
|
69
|
+
// Unknown-subcommand handler (AC #9): hint at version drift / upgrade so
|
|
70
|
+
// users who installed an outdated CLI find out fast.
|
|
71
|
+
program.on('command:*', (operands) => {
|
|
72
|
+
const unknown = operands[0] ?? '';
|
|
73
|
+
const writeErr = program.configureOutput().writeErr ?? ((s) => process.stderr.write(s));
|
|
74
|
+
writeErr(`Unknown subcommand: ${unknown}\n`);
|
|
75
|
+
writeErr('\n');
|
|
76
|
+
writeErr(`${upgradeHint(versions)}\n`);
|
|
77
|
+
writeErr('\n');
|
|
78
|
+
writeErr('Run `ai-sdlc --help` to see the available subcommands.\n');
|
|
79
|
+
program._exit(1, 'commander.unknownCommand', unknown);
|
|
80
|
+
});
|
|
81
|
+
return program;
|
|
82
|
+
}
|
|
83
|
+
// Bin entry: only run argv parsing when invoked as a script, not when the
|
|
84
|
+
// module is imported by tests.
|
|
85
|
+
//
|
|
86
|
+
// `process.argv[1]` is the path Node resolved for the entry script.
|
|
87
|
+
// When it ends with the compiled CLI bundle (`dist/cli/index.js`) we are
|
|
88
|
+
// the main entry. When imported (e.g. via Vitest) argv[1] points at the
|
|
89
|
+
// test runner, so we skip parsing.
|
|
90
|
+
const isMainEntry = (() => {
|
|
91
|
+
const entry = process.argv[1] ?? '';
|
|
92
|
+
return entry.endsWith('cli/index.js') || entry.endsWith('cli/index.ts');
|
|
93
|
+
})();
|
|
94
|
+
if (isMainEntry) {
|
|
95
|
+
const program = buildProgram(resolveVersions());
|
|
96
|
+
program.parse();
|
|
97
|
+
}
|
|
37
98
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Version provenance — surface the running CLI, orchestrator runtime,
|
|
3
|
+
* and (optionally) plugin versions in one place so users can spot drift.
|
|
4
|
+
*
|
|
5
|
+
* Why this exists: the original CLI hardcoded `0.1.0` in commander while
|
|
6
|
+
* the published `@ai-sdlc/orchestrator` package was at 0.6.0+. Operators
|
|
7
|
+
* who ran `ai-sdlc --version` saw the stale literal and assumed the
|
|
8
|
+
* orchestrator itself was that old. AISDLC-78 anchors `--version` to
|
|
9
|
+
* the package.json that ships with the binary and warns when components
|
|
10
|
+
* disagree.
|
|
11
|
+
*/
|
|
12
|
+
export interface VersionTriple {
|
|
13
|
+
/** The CLI binary's reported version. Tracks the orchestrator package. */
|
|
14
|
+
cli: string;
|
|
15
|
+
/** The orchestrator runtime version (from @ai-sdlc/orchestrator/package.json). */
|
|
16
|
+
orchestrator: string;
|
|
17
|
+
/** The plugin version, if discoverable in the workspace. */
|
|
18
|
+
plugin?: string;
|
|
19
|
+
/** Whether any of the discoverable components disagree on version. */
|
|
20
|
+
drift: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface ResolveVersionsOptions {
|
|
23
|
+
/** Override the working directory used to discover the plugin. */
|
|
24
|
+
workDir?: string;
|
|
25
|
+
/** Inject an orchestrator package.json path (testing). */
|
|
26
|
+
orchestratorPackageJsonPath?: string;
|
|
27
|
+
/** Inject a plugin version (testing). */
|
|
28
|
+
pluginVersionOverride?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Compute the active CLI/orchestrator/plugin versions.
|
|
32
|
+
*
|
|
33
|
+
* Drift detection: when at least two known components disagree on
|
|
34
|
+
* version string (case-insensitive), `drift` is set. The plugin is
|
|
35
|
+
* compared only when discovered.
|
|
36
|
+
*/
|
|
37
|
+
export declare function resolveVersions(opts?: ResolveVersionsOptions): VersionTriple;
|
|
38
|
+
/**
|
|
39
|
+
* Render the canonical 3-line version block. Always emits a
|
|
40
|
+
* trailing newline. When drift is detected, appends a warning line
|
|
41
|
+
* pointing at the upgrade hint.
|
|
42
|
+
*
|
|
43
|
+
* The CLI and orchestrator rows are rendered separately even though
|
|
44
|
+
* today they always show the same number — both ship from the same
|
|
45
|
+
* `@ai-sdlc/orchestrator` package.json. The shape is intentionally
|
|
46
|
+
* future-proofed: when the CLI is split into a thinner veneer with
|
|
47
|
+
* its own version it will start to differ from the orchestrator
|
|
48
|
+
* runtime, and operators are then trained to read both rows. Until
|
|
49
|
+
* then a duplicate value is the honest answer.
|
|
50
|
+
*/
|
|
51
|
+
export declare function formatVersionBlock(versions: VersionTriple): string;
|
|
52
|
+
/**
|
|
53
|
+
* Return the upgrade hint shown by unknown-subcommand handler and by
|
|
54
|
+
* version drift warnings. Centralised so tests can assert one string.
|
|
55
|
+
*/
|
|
56
|
+
export declare function upgradeHint(versions: VersionTriple): string;
|
|
57
|
+
//# sourceMappingURL=versions.d.ts.map
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Version provenance — surface the running CLI, orchestrator runtime,
|
|
3
|
+
* and (optionally) plugin versions in one place so users can spot drift.
|
|
4
|
+
*
|
|
5
|
+
* Why this exists: the original CLI hardcoded `0.1.0` in commander while
|
|
6
|
+
* the published `@ai-sdlc/orchestrator` package was at 0.6.0+. Operators
|
|
7
|
+
* who ran `ai-sdlc --version` saw the stale literal and assumed the
|
|
8
|
+
* orchestrator itself was that old. AISDLC-78 anchors `--version` to
|
|
9
|
+
* the package.json that ships with the binary and warns when components
|
|
10
|
+
* disagree.
|
|
11
|
+
*/
|
|
12
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
13
|
+
import { dirname, join, resolve } from 'node:path';
|
|
14
|
+
import { fileURLToPath } from 'node:url';
|
|
15
|
+
const FALLBACK_VERSION = '0.0.0';
|
|
16
|
+
function readPackageVersion(pkgPath) {
|
|
17
|
+
try {
|
|
18
|
+
if (!existsSync(pkgPath))
|
|
19
|
+
return undefined;
|
|
20
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
21
|
+
return pkg.version;
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Resolve the orchestrator package's own package.json. The CLI bundle
|
|
29
|
+
* lives at `dist/cli/index.js` so we walk up two levels.
|
|
30
|
+
*/
|
|
31
|
+
function findOrchestratorPackageJson() {
|
|
32
|
+
// import.meta.url points at the compiled CLI module location.
|
|
33
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
34
|
+
// Try ../package.json (when running from dist/cli/) and ../../package.json
|
|
35
|
+
// (when running from src/cli/ in tests via tsx).
|
|
36
|
+
const candidates = [
|
|
37
|
+
resolve(here, '..', 'package.json'),
|
|
38
|
+
resolve(here, '..', '..', 'package.json'),
|
|
39
|
+
];
|
|
40
|
+
for (const candidate of candidates) {
|
|
41
|
+
if (existsSync(candidate)) {
|
|
42
|
+
try {
|
|
43
|
+
const pkg = JSON.parse(readFileSync(candidate, 'utf-8'));
|
|
44
|
+
if (pkg.name === '@ai-sdlc/orchestrator')
|
|
45
|
+
return candidate;
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// continue
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return candidates[0];
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Best-effort search for the plugin manifest. We look in the project
|
|
56
|
+
* working directory first (the common case for a co-located checkout),
|
|
57
|
+
* then a few well-known parent paths. Returns undefined silently when
|
|
58
|
+
* not found — the plugin is optional metadata.
|
|
59
|
+
*/
|
|
60
|
+
function findPluginVersion(workDir) {
|
|
61
|
+
const tries = [
|
|
62
|
+
join(workDir, 'ai-sdlc-plugin', 'plugin.json'),
|
|
63
|
+
join(workDir, '..', 'ai-sdlc-plugin', 'plugin.json'),
|
|
64
|
+
join(workDir, '..', '..', 'ai-sdlc-plugin', 'plugin.json'),
|
|
65
|
+
];
|
|
66
|
+
for (const t of tries) {
|
|
67
|
+
const v = readPackageVersion(t);
|
|
68
|
+
if (v)
|
|
69
|
+
return v;
|
|
70
|
+
}
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Compute the active CLI/orchestrator/plugin versions.
|
|
75
|
+
*
|
|
76
|
+
* Drift detection: when at least two known components disagree on
|
|
77
|
+
* version string (case-insensitive), `drift` is set. The plugin is
|
|
78
|
+
* compared only when discovered.
|
|
79
|
+
*/
|
|
80
|
+
export function resolveVersions(opts = {}) {
|
|
81
|
+
const orchPath = opts.orchestratorPackageJsonPath ?? findOrchestratorPackageJson();
|
|
82
|
+
const orchestrator = readPackageVersion(orchPath) ?? FALLBACK_VERSION;
|
|
83
|
+
// The CLI ships from the same package.json today, so cli === orchestrator
|
|
84
|
+
// by construction. Drift detection between cli/orchestrator is therefore
|
|
85
|
+
// a no-op until the CLI is split out (planned: a thinner veneer that
|
|
86
|
+
// versions independently of the runtime). We keep them logically
|
|
87
|
+
// separate so callers and tests don't have to change shape on that day.
|
|
88
|
+
const cli = orchestrator;
|
|
89
|
+
const plugin = opts.pluginVersionOverride ?? findPluginVersion(opts.workDir ?? process.cwd());
|
|
90
|
+
const observed = [cli, orchestrator, plugin].filter((v) => Boolean(v));
|
|
91
|
+
const drift = new Set(observed.map((v) => v.toLowerCase())).size > 1;
|
|
92
|
+
return { cli, orchestrator, plugin, drift };
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Render the canonical 3-line version block. Always emits a
|
|
96
|
+
* trailing newline. When drift is detected, appends a warning line
|
|
97
|
+
* pointing at the upgrade hint.
|
|
98
|
+
*
|
|
99
|
+
* The CLI and orchestrator rows are rendered separately even though
|
|
100
|
+
* today they always show the same number — both ship from the same
|
|
101
|
+
* `@ai-sdlc/orchestrator` package.json. The shape is intentionally
|
|
102
|
+
* future-proofed: when the CLI is split into a thinner veneer with
|
|
103
|
+
* its own version it will start to differ from the orchestrator
|
|
104
|
+
* runtime, and operators are then trained to read both rows. Until
|
|
105
|
+
* then a duplicate value is the honest answer.
|
|
106
|
+
*/
|
|
107
|
+
export function formatVersionBlock(versions) {
|
|
108
|
+
const lines = [
|
|
109
|
+
`ai-sdlc CLI: ${versions.cli}`,
|
|
110
|
+
`orchestrator: ${versions.orchestrator}`,
|
|
111
|
+
`plugin: ${versions.plugin ?? '(not detected)'}`,
|
|
112
|
+
];
|
|
113
|
+
if (versions.drift) {
|
|
114
|
+
lines.push('', 'WARN versions out of sync — components disagree.', ' Run `npm install -g @ai-sdlc/orchestrator@latest` (or pnpm equivalent) to align.');
|
|
115
|
+
}
|
|
116
|
+
return lines.join('\n');
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Return the upgrade hint shown by unknown-subcommand handler and by
|
|
120
|
+
* version drift warnings. Centralised so tests can assert one string.
|
|
121
|
+
*/
|
|
122
|
+
export function upgradeHint(versions) {
|
|
123
|
+
if (versions.drift) {
|
|
124
|
+
return `Detected version drift (cli=${versions.cli}, orchestrator=${versions.orchestrator}${versions.plugin ? `, plugin=${versions.plugin}` : ''}). Run \`npm install -g @ai-sdlc/orchestrator@latest\` to align.`;
|
|
125
|
+
}
|
|
126
|
+
return `Run \`ai-sdlc --version\` to confirm you are on the latest @ai-sdlc/orchestrator (currently ${versions.orchestrator}).`;
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=versions.js.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Classify a code area as frontend-bearing or not (RFC-0008 C3).
|
|
3
|
+
*
|
|
4
|
+
* `hasFrontendComponents` is the branch predicate in the §A.5 defect-risk
|
|
5
|
+
* blend: frontend-bearing areas blend code-quality signals with design-
|
|
6
|
+
* quality signals; pure-code areas use only code signals.
|
|
7
|
+
*
|
|
8
|
+
* Classification order:
|
|
9
|
+
* 1. If the state store has a recent `code_area_metrics` row for the
|
|
10
|
+
* area, trust that explicitly — operators can correct the default
|
|
11
|
+
* by writing the metric.
|
|
12
|
+
* 2. Otherwise, apply a path-string heuristic: common frontend
|
|
13
|
+
* directory/extension markers.
|
|
14
|
+
*
|
|
15
|
+
* The state-store path matters because this runs in the hot admission
|
|
16
|
+
* loop — we don't want to ship a filesystem crawl on every issue score.
|
|
17
|
+
*/
|
|
18
|
+
import type { StateStore } from './state/store.js';
|
|
19
|
+
export declare function checkHasFrontendComponents(codeArea: string, store?: StateStore): boolean;
|
|
20
|
+
export declare function matchesFrontendHeuristic(codeArea: string): boolean;
|
|
21
|
+
//# sourceMappingURL=code-area-classifier.d.ts.map
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Classify a code area as frontend-bearing or not (RFC-0008 C3).
|
|
3
|
+
*
|
|
4
|
+
* `hasFrontendComponents` is the branch predicate in the §A.5 defect-risk
|
|
5
|
+
* blend: frontend-bearing areas blend code-quality signals with design-
|
|
6
|
+
* quality signals; pure-code areas use only code signals.
|
|
7
|
+
*
|
|
8
|
+
* Classification order:
|
|
9
|
+
* 1. If the state store has a recent `code_area_metrics` row for the
|
|
10
|
+
* area, trust that explicitly — operators can correct the default
|
|
11
|
+
* by writing the metric.
|
|
12
|
+
* 2. Otherwise, apply a path-string heuristic: common frontend
|
|
13
|
+
* directory/extension markers.
|
|
14
|
+
*
|
|
15
|
+
* The state-store path matters because this runs in the hot admission
|
|
16
|
+
* loop — we don't want to ship a filesystem crawl on every issue score.
|
|
17
|
+
*/
|
|
18
|
+
const FRONTEND_PATH_MARKERS = [
|
|
19
|
+
'components/',
|
|
20
|
+
'ui/',
|
|
21
|
+
'frontend/',
|
|
22
|
+
'web/',
|
|
23
|
+
'webapp/',
|
|
24
|
+
'src/app/', // Next.js app-dir convention
|
|
25
|
+
'pages/',
|
|
26
|
+
'routes/',
|
|
27
|
+
'views/',
|
|
28
|
+
];
|
|
29
|
+
const FRONTEND_EXTENSIONS = ['.tsx', '.jsx', '.vue', '.svelte', '.astro'];
|
|
30
|
+
export function checkHasFrontendComponents(codeArea, store) {
|
|
31
|
+
const authoritative = store?.getCodeAreaMetrics(codeArea);
|
|
32
|
+
if (authoritative)
|
|
33
|
+
return authoritative.hasFrontendComponents ?? false;
|
|
34
|
+
return matchesFrontendHeuristic(codeArea);
|
|
35
|
+
}
|
|
36
|
+
export function matchesFrontendHeuristic(codeArea) {
|
|
37
|
+
const lower = codeArea.toLowerCase();
|
|
38
|
+
for (const marker of FRONTEND_PATH_MARKERS) {
|
|
39
|
+
if (lower.includes(marker))
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
for (const ext of FRONTEND_EXTENSIONS) {
|
|
43
|
+
if (lower.endsWith(ext))
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=code-area-classifier.js.map
|
package/dist/config.d.ts
CHANGED
|
@@ -5,9 +5,17 @@
|
|
|
5
5
|
* Unlike the dogfood config loader, this version does NOT import builder
|
|
6
6
|
* functions — it performs pure YAML loading and validation only.
|
|
7
7
|
*/
|
|
8
|
-
import { type Pipeline, type AgentRole, type QualityGate, type AutonomyPolicy, type AdapterBinding, type AdapterRegistry } from '@ai-sdlc/reference';
|
|
8
|
+
import { type Pipeline, type AgentRole, type QualityGate, type AutonomyPolicy, type AdapterBinding, type DesignSystemBinding, type DesignIntentDocument, type AdapterRegistry } from '@ai-sdlc/reference';
|
|
9
9
|
export interface AiSdlcConfig {
|
|
10
|
+
/** Default pipeline (first Pipeline resource loaded; preserved for backward compat). */
|
|
10
11
|
pipeline?: Pipeline;
|
|
12
|
+
/**
|
|
13
|
+
* All Pipeline resources found in the config directory. The dual-workflow setup
|
|
14
|
+
* (RFC-0010 §11): one pipeline for the public GitHub-issue path (API-key billed),
|
|
15
|
+
* another for the internal backlog path (subscription-billed). cli-watch picks
|
|
16
|
+
* by name based on the issue ID prefix.
|
|
17
|
+
*/
|
|
18
|
+
pipelines?: Pipeline[];
|
|
11
19
|
agentRole?: AgentRole;
|
|
12
20
|
qualityGate?: QualityGate;
|
|
13
21
|
autonomyPolicy?: AutonomyPolicy;
|
|
@@ -15,13 +23,37 @@ export interface AiSdlcConfig {
|
|
|
15
23
|
adapterBinding?: AdapterBinding;
|
|
16
24
|
/** All AdapterBinding resources found in the config directory. */
|
|
17
25
|
adapterBindings?: AdapterBinding[];
|
|
26
|
+
/** All DesignSystemBinding resources found in the config directory (RFC-0006). */
|
|
27
|
+
designSystemBindings?: DesignSystemBinding[];
|
|
28
|
+
/** All DesignIntentDocument resources found in the config directory (RFC-0008). */
|
|
29
|
+
designIntentDocuments?: DesignIntentDocument[];
|
|
18
30
|
adapterRegistry?: AdapterRegistry;
|
|
31
|
+
/**
|
|
32
|
+
* Per-file load issues collected during a non-fatal load. Each entry
|
|
33
|
+
* is `{ file, error }` for a YAML file that failed to parse or
|
|
34
|
+
* validate. Non-resource YAMLs (no `apiVersion`/`kind`) and DID→DSB
|
|
35
|
+
* cross-reference failures are NOT recorded here — the former are
|
|
36
|
+
* silently skipped, the latter throw outright.
|
|
37
|
+
*/
|
|
38
|
+
warnings?: ConfigLoadWarning[];
|
|
39
|
+
}
|
|
40
|
+
export interface ConfigLoadWarning {
|
|
41
|
+
file: string;
|
|
42
|
+
error: string;
|
|
19
43
|
}
|
|
20
44
|
/**
|
|
21
45
|
* Load all YAML files from the given directory, validate each against
|
|
22
46
|
* the AI-SDLC JSON Schema, and return typed resources keyed by kind.
|
|
23
47
|
*/
|
|
24
48
|
export declare function loadConfig(configDir: string): AiSdlcConfig;
|
|
49
|
+
/**
|
|
50
|
+
* Validate that every DesignIntentDocument's `spec.designSystemRef.name`
|
|
51
|
+
* resolves to a loaded DesignSystemBinding. Namespace match is required
|
|
52
|
+
* only when both resources declare a namespace (RFC-0008 §4.5).
|
|
53
|
+
*
|
|
54
|
+
* Unidirectional: DID → DSB. DesignSystemBinding surface is not modified.
|
|
55
|
+
*/
|
|
56
|
+
export declare function validateDesignIntentDocumentReferences(config: AiSdlcConfig): void;
|
|
25
57
|
/**
|
|
26
58
|
* Async variant of loadConfig that also scans for local adapter plugins.
|
|
27
59
|
*/
|