@ai-sdlc/orchestrator 0.5.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/action-enforcement.d.ts +26 -0
- package/dist/action-enforcement.js +70 -0
- 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 +148 -0
- package/dist/admission-score.js +237 -0
- 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/cycle-utils.d.ts +51 -0
- package/dist/cycle-utils.js +77 -0
- 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/defaults.d.ts +5 -0
- package/dist/defaults.js +5 -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 +295 -30
- package/dist/fix-ci.js +40 -3
- package/dist/fix-review.d.ts +66 -0
- package/dist/fix-review.js +448 -0
- 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 +39 -5
- package/dist/index.js +48 -3
- 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/pipeline-cycle-detector.d.ts +70 -0
- package/dist/pipeline-cycle-detector.js +111 -0
- package/dist/priority.d.ts +7 -76
- 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 +35 -0
- package/dist/review.js +84 -0
- 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 +319 -73
- 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 +5 -1
- package/dist/runners/index.js +4 -0
- package/dist/runners/review-agent.d.ts +67 -0
- package/dist/runners/review-agent.js +350 -0
- 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 +42 -14
- package/dist/runners/types.d.ts +25 -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/index.d.ts +1 -1
- package/dist/state/schema.d.ts +6 -1
- package/dist/state/schema.js +276 -1
- package/dist/state/store.d.ts +71 -1
- package/dist/state/store.js +464 -7
- package/dist/state/types.d.ts +174 -0
- package/dist/types.d.ts +1 -1
- package/dist/validate-agent-output.js +4 -1
- package/dist/watch.js +6 -0
- package/dist/workflow-patterns/artifact-writer.d.ts +16 -0
- package/dist/workflow-patterns/artifact-writer.js +34 -0
- package/dist/workflow-patterns/classifiers.d.ts +10 -0
- package/dist/workflow-patterns/classifiers.js +72 -0
- package/dist/workflow-patterns/detector.d.ts +27 -0
- package/dist/workflow-patterns/detector.js +186 -0
- package/dist/workflow-patterns/index.d.ts +8 -0
- package/dist/workflow-patterns/index.js +7 -0
- package/dist/workflow-patterns/proposal-generator.d.ts +15 -0
- package/dist/workflow-patterns/proposal-generator.js +183 -0
- package/dist/workflow-patterns/telemetry-ingest.d.ts +27 -0
- package/dist/workflow-patterns/telemetry-ingest.js +103 -0
- package/dist/workflow-patterns/types.d.ts +61 -0
- package/dist/workflow-patterns/types.js +11 -0
- package/package.json +2 -2
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* git remote parsing — extract org/repo from `git remote get-url origin`
|
|
3
|
+
* to substitute into pipeline.yaml during init.
|
|
4
|
+
*
|
|
5
|
+
* Why this exists: AISDLC-78 — fresh installs got a literal `your-org`
|
|
6
|
+
* placeholder in their pipeline.yaml, which made the file unrunnable
|
|
7
|
+
* until the user noticed and edited it. We auto-detect the org/repo
|
|
8
|
+
* from the git remote and only fall back to placeholders when no
|
|
9
|
+
* remote is configured (e.g. a brand-new local-only repo).
|
|
10
|
+
*/
|
|
11
|
+
export interface RemoteInfo {
|
|
12
|
+
/** Organization or user name. */
|
|
13
|
+
org: string;
|
|
14
|
+
/** Repository name (without `.git` suffix). */
|
|
15
|
+
repo: string;
|
|
16
|
+
/** Whether the values came from a real git remote (vs the fallback). */
|
|
17
|
+
detected: boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Parse a single remote URL into org/repo. Supports:
|
|
21
|
+
* - https://github.com/foo/bar.git
|
|
22
|
+
* - https://github.com/foo/bar
|
|
23
|
+
* - git@github.com:foo/bar.git
|
|
24
|
+
* - ssh://git@github.com/foo/bar.git
|
|
25
|
+
* - git@gitlab.example.com:group/subgroup/repo.git (org=group, repo=repo)
|
|
26
|
+
*/
|
|
27
|
+
export declare function parseRemoteUrl(url: string): RemoteInfo | null;
|
|
28
|
+
export interface DetectRemoteOptions {
|
|
29
|
+
/** Override `execSync` for tests. */
|
|
30
|
+
execImpl?: (cmd: string, opts: {
|
|
31
|
+
cwd: string;
|
|
32
|
+
encoding: 'utf-8';
|
|
33
|
+
stdio: unknown;
|
|
34
|
+
}) => string;
|
|
35
|
+
/** Project directory (defaults to process.cwd). */
|
|
36
|
+
cwd?: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Detect the GitHub-style org/repo from the project's git origin remote.
|
|
40
|
+
* Returns FALLBACK with detected=false when no remote is configured or
|
|
41
|
+
* when the URL cannot be parsed.
|
|
42
|
+
*/
|
|
43
|
+
export declare function detectGitRemote(opts?: DetectRemoteOptions): RemoteInfo;
|
|
44
|
+
/**
|
|
45
|
+
* Substitute `your-org` (and optionally `your-repo`) placeholders in a
|
|
46
|
+
* template body with detected values.
|
|
47
|
+
*/
|
|
48
|
+
export declare function applyRemoteToPipelineYaml(template: string, info: RemoteInfo): string;
|
|
49
|
+
//# sourceMappingURL=git-remote.d.ts.map
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* git remote parsing — extract org/repo from `git remote get-url origin`
|
|
3
|
+
* to substitute into pipeline.yaml during init.
|
|
4
|
+
*
|
|
5
|
+
* Why this exists: AISDLC-78 — fresh installs got a literal `your-org`
|
|
6
|
+
* placeholder in their pipeline.yaml, which made the file unrunnable
|
|
7
|
+
* until the user noticed and edited it. We auto-detect the org/repo
|
|
8
|
+
* from the git remote and only fall back to placeholders when no
|
|
9
|
+
* remote is configured (e.g. a brand-new local-only repo).
|
|
10
|
+
*/
|
|
11
|
+
import { execSync } from 'node:child_process';
|
|
12
|
+
const FALLBACK = { org: 'your-org', repo: 'your-repo', detected: false };
|
|
13
|
+
/**
|
|
14
|
+
* Parse a single remote URL into org/repo. Supports:
|
|
15
|
+
* - https://github.com/foo/bar.git
|
|
16
|
+
* - https://github.com/foo/bar
|
|
17
|
+
* - git@github.com:foo/bar.git
|
|
18
|
+
* - ssh://git@github.com/foo/bar.git
|
|
19
|
+
* - git@gitlab.example.com:group/subgroup/repo.git (org=group, repo=repo)
|
|
20
|
+
*/
|
|
21
|
+
export function parseRemoteUrl(url) {
|
|
22
|
+
const trimmed = url.trim();
|
|
23
|
+
if (!trimmed)
|
|
24
|
+
return null;
|
|
25
|
+
// SSH shorthand: git@host:org/repo.git
|
|
26
|
+
const sshShort = /^[^@\s]+@[^:\s]+:(.+?)\/([^/\s]+?)(?:\.git)?$/.exec(trimmed);
|
|
27
|
+
if (sshShort) {
|
|
28
|
+
return { org: sshShort[1].split('/').slice(-1)[0], repo: sshShort[2], detected: true };
|
|
29
|
+
}
|
|
30
|
+
// SSH or HTTPS with a scheme
|
|
31
|
+
let parsed = null;
|
|
32
|
+
try {
|
|
33
|
+
parsed = new URL(trimmed);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
parsed = null;
|
|
37
|
+
}
|
|
38
|
+
if (parsed) {
|
|
39
|
+
const path = parsed.pathname.replace(/^\/+/, '').replace(/\.git$/, '');
|
|
40
|
+
const segments = path.split('/').filter(Boolean);
|
|
41
|
+
if (segments.length >= 2) {
|
|
42
|
+
const repo = segments[segments.length - 1];
|
|
43
|
+
const org = segments[segments.length - 2];
|
|
44
|
+
return { org, repo, detected: true };
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Detect the GitHub-style org/repo from the project's git origin remote.
|
|
51
|
+
* Returns FALLBACK with detected=false when no remote is configured or
|
|
52
|
+
* when the URL cannot be parsed.
|
|
53
|
+
*/
|
|
54
|
+
export function detectGitRemote(opts = {}) {
|
|
55
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
56
|
+
const exec = opts.execImpl ?? defaultExec;
|
|
57
|
+
let url;
|
|
58
|
+
try {
|
|
59
|
+
url = exec('git remote get-url origin', {
|
|
60
|
+
cwd,
|
|
61
|
+
encoding: 'utf-8',
|
|
62
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return FALLBACK;
|
|
67
|
+
}
|
|
68
|
+
const parsed = parseRemoteUrl(url);
|
|
69
|
+
return parsed ?? FALLBACK;
|
|
70
|
+
}
|
|
71
|
+
function defaultExec(cmd, opts) {
|
|
72
|
+
return execSync(cmd, {
|
|
73
|
+
cwd: opts.cwd,
|
|
74
|
+
encoding: opts.encoding,
|
|
75
|
+
stdio: opts.stdio,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Substitute `your-org` (and optionally `your-repo`) placeholders in a
|
|
80
|
+
* template body with detected values.
|
|
81
|
+
*/
|
|
82
|
+
export function applyRemoteToPipelineYaml(template, info) {
|
|
83
|
+
// Replace the literal `org: your-org` config line with the detected
|
|
84
|
+
// org. We deliberately match the exact YAML key shape rather than a
|
|
85
|
+
// bare token so we don't smear the placeholder if it appears elsewhere.
|
|
86
|
+
let out = template.replace(/(\borg:\s*)your-org(\b)/g, `$1${info.org}$2`);
|
|
87
|
+
// If the template ever introduces a repo: placeholder, substitute it too.
|
|
88
|
+
out = out.replace(/(\brepo:\s*)your-repo(\b)/g, `$1${info.repo}$2`);
|
|
89
|
+
return out;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=git-remote.js.map
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ai-sdlc health — validate config, state store, and adapter connectivity.
|
|
3
|
+
*
|
|
4
|
+
* AISDLC-78: surfaces the deferred-state-store wording (handled by the
|
|
5
|
+
* table formatter) and adds an opt-in `--init-state` flag for users who
|
|
6
|
+
* want the SQLite database created eagerly rather than on first run.
|
|
3
7
|
*/
|
|
4
8
|
import { Command } from 'commander';
|
|
5
9
|
export declare const healthCommand: Command;
|
|
@@ -1,18 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ai-sdlc health — validate config, state store, and adapter connectivity.
|
|
3
|
+
*
|
|
4
|
+
* AISDLC-78: surfaces the deferred-state-store wording (handled by the
|
|
5
|
+
* table formatter) and adds an opt-in `--init-state` flag for users who
|
|
6
|
+
* want the SQLite database created eagerly rather than on first run.
|
|
3
7
|
*/
|
|
4
8
|
import { Command } from 'commander';
|
|
9
|
+
import { join } from 'node:path';
|
|
5
10
|
import { Orchestrator } from '../../orchestrator.js';
|
|
6
11
|
import { formatOutput } from '../formatters/index.js';
|
|
7
12
|
export const healthCommand = new Command('health')
|
|
8
13
|
.description('Check orchestrator health')
|
|
9
14
|
.option('--state <path>', 'SQLite state database path')
|
|
15
|
+
.option('--init-state', 'Eagerly initialize the SQLite state store (defaults to .ai-sdlc/state.db when --state is omitted)')
|
|
10
16
|
.action(async (opts, cmd) => {
|
|
11
17
|
const globalOpts = cmd.parent?.opts() ?? {};
|
|
12
18
|
const format = globalOpts.format ?? 'table';
|
|
19
|
+
// When the user opts into eager initialization, default the path to
|
|
20
|
+
// .ai-sdlc/state.db inside the configured config dir so we don't
|
|
21
|
+
// litter cwd with an unexpected file.
|
|
22
|
+
const configDir = globalOpts.config ?? '.ai-sdlc';
|
|
23
|
+
const statePath = opts.state ??
|
|
24
|
+
(opts.initState ? join(configDir, 'state.db') : undefined);
|
|
13
25
|
const orchestrator = new Orchestrator({
|
|
14
26
|
configDir: globalOpts.config,
|
|
15
|
-
statePath
|
|
27
|
+
statePath,
|
|
16
28
|
});
|
|
17
29
|
try {
|
|
18
30
|
const result = await orchestrator.health();
|
|
@@ -1,6 +1,32 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ai-sdlc init — initialize a project with AI-SDLC config files.
|
|
3
|
+
*
|
|
4
|
+
* AISDLC-78 enhancements:
|
|
5
|
+
* - Print a 3-line version block at startup so operators see CLI,
|
|
6
|
+
* orchestrator, and plugin versions in one place. Drift triggers a
|
|
7
|
+
* visible warning instead of silently shipping mismatched binaries.
|
|
8
|
+
* - Substitute `your-org` in the pipeline.yaml template using
|
|
9
|
+
* `git remote get-url origin` (ssh + https forms supported). Falls
|
|
10
|
+
* back to the placeholder only when no remote is configured.
|
|
11
|
+
* - Pin `@ai-sdlc/mcp-advisor` in generated `.mcp.json` to the
|
|
12
|
+
* orchestrator version that ran init, with an inline opt-out hint.
|
|
13
|
+
* - Skip `.cursor/mcp.json` unless Cursor is detected (project-local
|
|
14
|
+
* `.cursor/`, user-global `~/.cursor/`) or `--cursor` is passed.
|
|
3
15
|
*/
|
|
4
16
|
import { Command } from 'commander';
|
|
17
|
+
/**
|
|
18
|
+
* Tier-based agent-role templates (AISDLC-79).
|
|
19
|
+
*
|
|
20
|
+
* Three named tiers map to escalating tool surfaces. The default (`coding`)
|
|
21
|
+
* preserves pre-AISDLC-79 behavior plus `NotebookEdit` (parity with the
|
|
22
|
+
* Claude Code SDK's filesystem editing surface). Higher tiers add tools only
|
|
23
|
+
* when their use-case justifies the additional surface area / risk.
|
|
24
|
+
*
|
|
25
|
+
* See `backlog/decisions/AISDLC-79-agent-role-tools-defaults.md` for rationale.
|
|
26
|
+
*/
|
|
27
|
+
export type AgentRoleTier = 'coding' | 'research' | 'meta';
|
|
28
|
+
export declare const AGENT_ROLE_TIERS: readonly AgentRoleTier[];
|
|
29
|
+
/** Resolve the agent-role.yaml template for a given tier. Default = `coding`. */
|
|
30
|
+
export declare function getAgentRoleYaml(tier?: AgentRoleTier): string;
|
|
5
31
|
export declare const initCommand: Command;
|
|
6
32
|
//# sourceMappingURL=init.d.ts.map
|
|
@@ -1,11 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ai-sdlc init — initialize a project with AI-SDLC config files.
|
|
3
|
+
*
|
|
4
|
+
* AISDLC-78 enhancements:
|
|
5
|
+
* - Print a 3-line version block at startup so operators see CLI,
|
|
6
|
+
* orchestrator, and plugin versions in one place. Drift triggers a
|
|
7
|
+
* visible warning instead of silently shipping mismatched binaries.
|
|
8
|
+
* - Substitute `your-org` in the pipeline.yaml template using
|
|
9
|
+
* `git remote get-url origin` (ssh + https forms supported). Falls
|
|
10
|
+
* back to the placeholder only when no remote is configured.
|
|
11
|
+
* - Pin `@ai-sdlc/mcp-advisor` in generated `.mcp.json` to the
|
|
12
|
+
* orchestrator version that ran init, with an inline opt-out hint.
|
|
13
|
+
* - Skip `.cursor/mcp.json` unless Cursor is detected (project-local
|
|
14
|
+
* `.cursor/`, user-global `~/.cursor/`) or `--cursor` is passed.
|
|
3
15
|
*/
|
|
4
16
|
import { Command } from 'commander';
|
|
5
17
|
import { existsSync, mkdirSync, writeFileSync, readFileSync, appendFileSync } from 'node:fs';
|
|
6
18
|
import { join, basename } from 'node:path';
|
|
7
|
-
import {
|
|
19
|
+
import { detectAgentsDetailed, installMcpServer } from './mcp-setup.js';
|
|
8
20
|
import { detectWorkspace, generateWorkspaceYaml } from './workspace-detect.js';
|
|
21
|
+
import { detectGitRemote, applyRemoteToPipelineYaml } from './git-remote.js';
|
|
22
|
+
import { resolveVersions, formatVersionBlock } from '../versions.js';
|
|
9
23
|
const PIPELINE_YAML = `apiVersion: ai-sdlc.io/v1alpha1
|
|
10
24
|
kind: Pipeline
|
|
11
25
|
metadata:
|
|
@@ -35,20 +49,31 @@ spec:
|
|
|
35
49
|
qualityGates:
|
|
36
50
|
- default-gates
|
|
37
51
|
`;
|
|
38
|
-
const
|
|
52
|
+
export const AGENT_ROLE_TIERS = ['coding', 'research', 'meta'];
|
|
53
|
+
const AGENT_ROLE_YAML_CODING = `apiVersion: ai-sdlc.io/v1alpha1
|
|
39
54
|
kind: AgentRole
|
|
40
55
|
metadata:
|
|
41
56
|
name: default-agent
|
|
42
57
|
spec:
|
|
43
58
|
role: developer
|
|
44
59
|
goal: Implement issue requirements with tests
|
|
60
|
+
# Tier: coding-agent (default).
|
|
61
|
+
# Filesystem + shell editing surface only. No web access, no sub-agent
|
|
62
|
+
# spawning, no Skill loading. This matches the pre-AISDLC-79 default
|
|
63
|
+
# plus NotebookEdit (parity with the Claude Code SDK's editing surface).
|
|
45
64
|
tools:
|
|
46
|
-
- Edit
|
|
47
|
-
- Write
|
|
48
|
-
- Read
|
|
49
|
-
- Glob
|
|
50
|
-
- Grep
|
|
51
|
-
- Bash
|
|
65
|
+
- Edit # write to existing files
|
|
66
|
+
- Write # create new files
|
|
67
|
+
- Read # read source / configs
|
|
68
|
+
- Glob # discover files by pattern
|
|
69
|
+
- Grep # search code
|
|
70
|
+
- Bash # run tests, lint, build, git
|
|
71
|
+
- NotebookEdit # edit Jupyter notebooks (parity with SDK editing surface)
|
|
72
|
+
# Excluded by default (opt in via --role research|meta during init):
|
|
73
|
+
# - WebFetch — pulls untrusted remote content into context (research tier)
|
|
74
|
+
# - WebSearch — same (research tier)
|
|
75
|
+
# - Task — spawns sub-agents; cost + reasoning amplification (meta tier)
|
|
76
|
+
# - Skill — loads external skill packs (meta tier)
|
|
52
77
|
constraints:
|
|
53
78
|
maxFilesPerChange: 15
|
|
54
79
|
requireTests: true
|
|
@@ -56,6 +81,75 @@ spec:
|
|
|
56
81
|
- .github/workflows/**
|
|
57
82
|
- .ai-sdlc/**
|
|
58
83
|
`;
|
|
84
|
+
const AGENT_ROLE_YAML_RESEARCH = `apiVersion: ai-sdlc.io/v1alpha1
|
|
85
|
+
kind: AgentRole
|
|
86
|
+
metadata:
|
|
87
|
+
name: default-agent
|
|
88
|
+
spec:
|
|
89
|
+
role: research-developer
|
|
90
|
+
goal: Investigate, gather references, and implement issue requirements with tests
|
|
91
|
+
# Tier: research-agent.
|
|
92
|
+
# Coding-tier surface plus read-only web access. Use for tasks that need
|
|
93
|
+
# to consult external docs, package registries, or RFCs.
|
|
94
|
+
tools:
|
|
95
|
+
- Edit # write to existing files
|
|
96
|
+
- Write # create new files
|
|
97
|
+
- Read # read source / configs
|
|
98
|
+
- Glob # discover files by pattern
|
|
99
|
+
- Grep # search code
|
|
100
|
+
- Bash # run tests, lint, build, git
|
|
101
|
+
- NotebookEdit # edit Jupyter notebooks
|
|
102
|
+
- WebFetch # fetch a known URL (docs, RFCs, API references)
|
|
103
|
+
- WebSearch # discover sources by query
|
|
104
|
+
# Excluded (use --role meta to opt in):
|
|
105
|
+
# - Task — spawns sub-agents (meta tier)
|
|
106
|
+
# - Skill — loads external skill packs (meta tier)
|
|
107
|
+
constraints:
|
|
108
|
+
maxFilesPerChange: 15
|
|
109
|
+
requireTests: true
|
|
110
|
+
blockedPaths:
|
|
111
|
+
- .github/workflows/**
|
|
112
|
+
- .ai-sdlc/**
|
|
113
|
+
`;
|
|
114
|
+
const AGENT_ROLE_YAML_META = `apiVersion: ai-sdlc.io/v1alpha1
|
|
115
|
+
kind: AgentRole
|
|
116
|
+
metadata:
|
|
117
|
+
name: default-agent
|
|
118
|
+
spec:
|
|
119
|
+
role: meta-developer
|
|
120
|
+
goal: Orchestrate sub-agents, load skill packs, and implement complex multi-step work
|
|
121
|
+
# Tier: meta-agent.
|
|
122
|
+
# Full surface: filesystem + shell + web + sub-agent + skill loading.
|
|
123
|
+
# Use only when the task legitimately needs sub-agent fan-out or external
|
|
124
|
+
# skill packs. Higher cost amplification and broader attack surface.
|
|
125
|
+
tools:
|
|
126
|
+
- Edit # write to existing files
|
|
127
|
+
- Write # create new files
|
|
128
|
+
- Read # read source / configs
|
|
129
|
+
- Glob # discover files by pattern
|
|
130
|
+
- Grep # search code
|
|
131
|
+
- Bash # run tests, lint, build, git
|
|
132
|
+
- NotebookEdit # edit Jupyter notebooks
|
|
133
|
+
- WebFetch # fetch a known URL
|
|
134
|
+
- WebSearch # discover sources by query
|
|
135
|
+
- Task # spawn sub-agents for parallel / specialized work
|
|
136
|
+
- Skill # load external skill packs (declared capabilities)
|
|
137
|
+
constraints:
|
|
138
|
+
maxFilesPerChange: 15
|
|
139
|
+
requireTests: true
|
|
140
|
+
blockedPaths:
|
|
141
|
+
- .github/workflows/**
|
|
142
|
+
- .ai-sdlc/**
|
|
143
|
+
`;
|
|
144
|
+
const AGENT_ROLE_YAML_BY_TIER = {
|
|
145
|
+
coding: AGENT_ROLE_YAML_CODING,
|
|
146
|
+
research: AGENT_ROLE_YAML_RESEARCH,
|
|
147
|
+
meta: AGENT_ROLE_YAML_META,
|
|
148
|
+
};
|
|
149
|
+
/** Resolve the agent-role.yaml template for a given tier. Default = `coding`. */
|
|
150
|
+
export function getAgentRoleYaml(tier = 'coding') {
|
|
151
|
+
return AGENT_ROLE_YAML_BY_TIER[tier];
|
|
152
|
+
}
|
|
59
153
|
const QUALITY_GATE_YAML = `apiVersion: ai-sdlc.io/v1alpha1
|
|
60
154
|
kind: QualityGate
|
|
61
155
|
metadata:
|
|
@@ -139,24 +233,26 @@ const GITIGNORE_PATHS = ['.ai-sdlc/state.db', '.ai-sdlc/state/', '.ai-sdlc/audit
|
|
|
139
233
|
function ensureGitignore(projectDir, dryRun, prefix = '') {
|
|
140
234
|
const gitignorePath = join(projectDir, '.gitignore');
|
|
141
235
|
const existing = existsSync(gitignorePath) ? readFileSync(gitignorePath, 'utf-8') : '';
|
|
142
|
-
|
|
143
|
-
|
|
236
|
+
const SENTINEL = '# ai-sdlc:runtime-gitignore';
|
|
237
|
+
if (existing.includes(SENTINEL))
|
|
238
|
+
return;
|
|
239
|
+
const missing = GITIGNORE_PATHS.filter((entry) => !existing.split('\n').some((line) => line.trim() === entry));
|
|
144
240
|
if (missing.length === 0)
|
|
145
241
|
return;
|
|
146
242
|
if (dryRun) {
|
|
147
243
|
console.log(`${prefix} Would update .gitignore`);
|
|
148
244
|
return;
|
|
149
245
|
}
|
|
150
|
-
const block = '\n
|
|
246
|
+
const block = (existing.length > 0 ? '\n' : '') + `${SENTINEL}\n` + missing.join('\n') + '\n';
|
|
151
247
|
appendFileSync(gitignorePath, block, 'utf-8');
|
|
152
248
|
console.log(`${prefix} updated .gitignore`);
|
|
153
249
|
}
|
|
154
250
|
/** Initialize a single project directory with AI-SDLC config files. */
|
|
155
|
-
function initProject(projectDir, configDirName, dryRun, prefix = '') {
|
|
251
|
+
function initProject(projectDir, configDirName, dryRun, prefix = '', options = { pipelineYaml: PIPELINE_YAML, tier: 'coding' }) {
|
|
156
252
|
const configDir = join(projectDir, configDirName);
|
|
157
253
|
const files = [
|
|
158
|
-
{ name: 'pipeline.yaml', content:
|
|
159
|
-
{ name: 'agent-role.yaml', content:
|
|
254
|
+
{ name: 'pipeline.yaml', content: options.pipelineYaml },
|
|
255
|
+
{ name: 'agent-role.yaml', content: getAgentRoleYaml(options.tier) },
|
|
160
256
|
{ name: 'quality-gate.yaml', content: QUALITY_GATE_YAML },
|
|
161
257
|
{ name: 'autonomy-policy.yaml', content: AUTONOMY_POLICY_YAML },
|
|
162
258
|
];
|
|
@@ -209,11 +305,35 @@ export const initCommand = new Command('init')
|
|
|
209
305
|
.description('Initialize AI-SDLC configuration in the current project')
|
|
210
306
|
.option('--dry-run', 'Show what would be created without writing files')
|
|
211
307
|
.option('--skip-mcp', 'Skip MCP server auto-configuration')
|
|
308
|
+
.option('--cursor', 'Force-install Cursor MCP config even if Cursor is not detected')
|
|
212
309
|
.option('-d, --dir <path>', 'Config directory name', '.ai-sdlc')
|
|
310
|
+
.option('--role <tier>', `Agent-role tool tier: ${AGENT_ROLE_TIERS.join(' | ')} (default: coding)`, 'coding')
|
|
213
311
|
.action(async (opts) => {
|
|
214
312
|
const projectDir = process.cwd();
|
|
215
313
|
const configDirName = opts.dir ?? '.ai-sdlc';
|
|
216
314
|
const dryRun = !!opts.dryRun;
|
|
315
|
+
const tierInput = (opts.role ?? 'coding');
|
|
316
|
+
if (!AGENT_ROLE_TIERS.includes(tierInput)) {
|
|
317
|
+
console.error(`Error: invalid --role value '${tierInput}'. Expected one of: ${AGENT_ROLE_TIERS.join(', ')}.`);
|
|
318
|
+
process.exitCode = 1;
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
const tier = tierInput;
|
|
322
|
+
const cursorOptIn = !!opts.cursor;
|
|
323
|
+
// ── version provenance (AC #1) ────────────────────────────────────
|
|
324
|
+
const versions = resolveVersions({ workDir: projectDir });
|
|
325
|
+
console.log(formatVersionBlock(versions));
|
|
326
|
+
console.log('');
|
|
327
|
+
// ── pipeline.yaml org/repo substitution (AC #2) ───────────────────
|
|
328
|
+
const remote = detectGitRemote({ cwd: projectDir });
|
|
329
|
+
const pipelineYaml = applyRemoteToPipelineYaml(PIPELINE_YAML, remote);
|
|
330
|
+
if (remote.detected) {
|
|
331
|
+
console.log(`Detected git remote: ${remote.org}/${remote.repo}`);
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
console.log(`No git origin remote detected — pipeline.yaml will use the 'your-org' placeholder.`);
|
|
335
|
+
}
|
|
336
|
+
console.log('');
|
|
217
337
|
// Detect workspace (multi-repo parent directory)
|
|
218
338
|
const workspace = detectWorkspace(projectDir);
|
|
219
339
|
if (workspace.isWorkspace) {
|
|
@@ -227,14 +347,30 @@ export const initCommand = new Command('init')
|
|
|
227
347
|
// Cascade into each child repo
|
|
228
348
|
for (const repo of workspace.repos) {
|
|
229
349
|
console.log(`\n${repo.name}/`);
|
|
230
|
-
|
|
350
|
+
// Per-repo remote detection so each child gets its own org/repo.
|
|
351
|
+
const childRemote = detectGitRemote({ cwd: repo.absPath });
|
|
352
|
+
const childPipeline = applyRemoteToPipelineYaml(PIPELINE_YAML, childRemote);
|
|
353
|
+
if (childRemote.detected) {
|
|
354
|
+
console.log(` detected remote: ${childRemote.org}/${childRemote.repo}`);
|
|
355
|
+
}
|
|
356
|
+
initProject(repo.absPath, configDirName, dryRun, ' ', {
|
|
357
|
+
pipelineYaml: childPipeline,
|
|
358
|
+
tier,
|
|
359
|
+
});
|
|
231
360
|
}
|
|
232
361
|
// MCP setup at workspace root (serves all repos)
|
|
233
362
|
if (!opts.skipMcp) {
|
|
234
|
-
const
|
|
363
|
+
const { detected, skipped } = detectAgentsDetailed(projectDir, {
|
|
364
|
+
isWorkspace: true,
|
|
365
|
+
pinVersion: versions.orchestrator,
|
|
366
|
+
cursorOptIn,
|
|
367
|
+
});
|
|
235
368
|
console.log(`\nMCP server setup (workspace root):`);
|
|
236
|
-
console.log(` detected ${
|
|
237
|
-
for (const
|
|
369
|
+
console.log(` detected ${detected.map((a) => a.name).join(', ') || '(none)'}`);
|
|
370
|
+
for (const sk of skipped) {
|
|
371
|
+
console.log(` skip ${sk.name} — ${sk.reason}`);
|
|
372
|
+
}
|
|
373
|
+
for (const agent of detected) {
|
|
238
374
|
const status = installMcpServer(projectDir, agent, dryRun);
|
|
239
375
|
const pad = status === 'merged' ? ' ' : '';
|
|
240
376
|
console.log(` ${status}${pad} ${agent.configPath} (${agent.name})`);
|
|
@@ -245,12 +381,18 @@ export const initCommand = new Command('init')
|
|
|
245
381
|
}
|
|
246
382
|
else {
|
|
247
383
|
// Single-repo mode (original behavior)
|
|
248
|
-
initProject(projectDir, configDirName, dryRun);
|
|
384
|
+
initProject(projectDir, configDirName, dryRun, '', { pipelineYaml, tier });
|
|
249
385
|
if (!opts.skipMcp) {
|
|
250
|
-
const
|
|
386
|
+
const { detected, skipped } = detectAgentsDetailed(projectDir, {
|
|
387
|
+
pinVersion: versions.orchestrator,
|
|
388
|
+
cursorOptIn,
|
|
389
|
+
});
|
|
251
390
|
console.log(`\nMCP server setup:`);
|
|
252
|
-
console.log(` detected ${
|
|
253
|
-
for (const
|
|
391
|
+
console.log(` detected ${detected.map((a) => a.name).join(', ') || '(none)'}`);
|
|
392
|
+
for (const sk of skipped) {
|
|
393
|
+
console.log(` skip ${sk.name} — ${sk.reason}`);
|
|
394
|
+
}
|
|
395
|
+
for (const agent of detected) {
|
|
254
396
|
const status = installMcpServer(projectDir, agent, dryRun);
|
|
255
397
|
const pad = status === 'merged' ? ' ' : '';
|
|
256
398
|
console.log(` ${status}${pad} ${agent.configPath} (${agent.name})`);
|
|
@@ -1,5 +1,17 @@
|
|
|
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
|
export interface DetectedAgent {
|
|
5
17
|
name: string;
|
|
@@ -10,7 +22,26 @@ export interface DetectedAgent {
|
|
|
10
22
|
export interface DetectAgentsOptions {
|
|
11
23
|
/** When true, adds AI_SDLC_WORKSPACE env to server entries. */
|
|
12
24
|
isWorkspace?: boolean;
|
|
25
|
+
/** Pin the mcp-advisor to this version in generated configs. */
|
|
26
|
+
pinVersion?: string;
|
|
27
|
+
/** User explicitly asked for Cursor MCP install. */
|
|
28
|
+
cursorOptIn?: boolean;
|
|
13
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Returned alongside detected agents to log skip decisions.
|
|
32
|
+
*/
|
|
33
|
+
export interface DetectAgentsResult {
|
|
34
|
+
detected: DetectedAgent[];
|
|
35
|
+
/** Per-spec skip explanations for human-readable logging. */
|
|
36
|
+
skipped: Array<{
|
|
37
|
+
name: string;
|
|
38
|
+
reason: string;
|
|
39
|
+
}>;
|
|
40
|
+
}
|
|
41
|
+
export declare function detectAgentsDetailed(projectDir: string, options?: DetectAgentsOptions): DetectAgentsResult;
|
|
42
|
+
/**
|
|
43
|
+
* Backwards-compatible wrapper. New code should prefer detectAgentsDetailed.
|
|
44
|
+
*/
|
|
14
45
|
export declare function detectAgents(projectDir: string, options?: DetectAgentsOptions): DetectedAgent[];
|
|
15
46
|
export declare function installMcpServer(projectDir: string, agent: DetectedAgent, dryRun: boolean): 'created' | 'merged' | 'skipped';
|
|
16
47
|
//# sourceMappingURL=mcp-setup.d.ts.map
|