@ai-sdlc/orchestrator 0.1.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/adapters.d.ts +60 -0
- package/dist/adapters.js +160 -0
- package/dist/admission.d.ts +49 -0
- package/dist/admission.js +90 -0
- package/dist/analysis/analyzer.d.ts +10 -0
- package/dist/analysis/analyzer.js +67 -0
- package/dist/analysis/complexity-scorer.d.ts +24 -0
- package/dist/analysis/complexity-scorer.js +39 -0
- package/dist/analysis/context-builder.d.ts +14 -0
- package/dist/analysis/context-builder.js +79 -0
- package/dist/analysis/convention-detector.d.ts +9 -0
- package/dist/analysis/convention-detector.js +177 -0
- package/dist/analysis/dependency-parser.d.ts +17 -0
- package/dist/analysis/dependency-parser.js +167 -0
- package/dist/analysis/file-walker.d.ts +18 -0
- package/dist/analysis/file-walker.js +158 -0
- package/dist/analysis/hotspot-analyzer.d.ts +28 -0
- package/dist/analysis/hotspot-analyzer.js +85 -0
- package/dist/analysis/index.d.ts +13 -0
- package/dist/analysis/index.js +12 -0
- package/dist/analysis/pattern-detector.d.ts +10 -0
- package/dist/analysis/pattern-detector.js +86 -0
- package/dist/analysis/types.d.ts +94 -0
- package/dist/analysis/types.js +5 -0
- package/dist/audit-archival.d.ts +48 -0
- package/dist/audit-archival.js +72 -0
- package/dist/audit-export.d.ts +45 -0
- package/dist/audit-export.js +100 -0
- package/dist/audit-extended.d.ts +28 -0
- package/dist/audit-extended.js +38 -0
- package/dist/audit-scheduler.d.ts +32 -0
- package/dist/audit-scheduler.js +52 -0
- package/dist/audit-sqlite-sink.d.ts +11 -0
- package/dist/audit-sqlite-sink.js +51 -0
- package/dist/autonomy-tracker.d.ts +76 -0
- package/dist/autonomy-tracker.js +277 -0
- package/dist/check-runs.d.ts +37 -0
- package/dist/check-runs.js +72 -0
- package/dist/cli/commands/agents.d.ts +6 -0
- package/dist/cli/commands/agents.js +33 -0
- package/dist/cli/commands/complexity.d.ts +6 -0
- package/dist/cli/commands/complexity.js +35 -0
- package/dist/cli/commands/cost.d.ts +6 -0
- package/dist/cli/commands/cost.js +53 -0
- package/dist/cli/commands/dashboard.d.ts +9 -0
- package/dist/cli/commands/dashboard.js +50 -0
- package/dist/cli/commands/health.d.ts +6 -0
- package/dist/cli/commands/health.js +33 -0
- package/dist/cli/commands/init.d.ts +6 -0
- package/dist/cli/commands/init.js +127 -0
- package/dist/cli/commands/routing.d.ts +6 -0
- package/dist/cli/commands/routing.js +46 -0
- package/dist/cli/commands/run.d.ts +6 -0
- package/dist/cli/commands/run.js +36 -0
- package/dist/cli/commands/start.d.ts +6 -0
- package/dist/cli/commands/start.js +26 -0
- package/dist/cli/commands/status.d.ts +6 -0
- package/dist/cli/commands/status.js +34 -0
- package/dist/cli/dashboard-renderer.d.ts +24 -0
- package/dist/cli/dashboard-renderer.js +129 -0
- package/dist/cli/formatters/index.d.ts +6 -0
- package/dist/cli/formatters/index.js +18 -0
- package/dist/cli/formatters/json.d.ts +5 -0
- package/dist/cli/formatters/json.js +7 -0
- package/dist/cli/formatters/minimal.d.ts +5 -0
- package/dist/cli/formatters/minimal.js +36 -0
- package/dist/cli/formatters/table.d.ts +5 -0
- package/dist/cli/formatters/table.js +184 -0
- package/dist/cli/index.d.ts +6 -0
- package/dist/cli/index.js +35 -0
- package/dist/compliance-extended.d.ts +41 -0
- package/dist/compliance-extended.js +58 -0
- package/dist/config.d.ts +26 -0
- package/dist/config.js +66 -0
- package/dist/context-enrichment.d.ts +33 -0
- package/dist/context-enrichment.js +125 -0
- package/dist/cost-governance.d.ts +22 -0
- package/dist/cost-governance.js +106 -0
- package/dist/cost-tracker.d.ts +75 -0
- package/dist/cost-tracker.js +177 -0
- package/dist/defaults.d.ts +140 -0
- package/dist/defaults.js +218 -0
- package/dist/deploy/flyio-target.d.ts +19 -0
- package/dist/deploy/flyio-target.js +114 -0
- package/dist/deploy/index.d.ts +15 -0
- package/dist/deploy/index.js +11 -0
- package/dist/deploy/kubernetes-target.d.ts +25 -0
- package/dist/deploy/kubernetes-target.js +124 -0
- package/dist/deploy/metrics-collector.d.ts +31 -0
- package/dist/deploy/metrics-collector.js +75 -0
- package/dist/deploy/rollout-controller.d.ts +42 -0
- package/dist/deploy/rollout-controller.js +192 -0
- package/dist/deploy/rollout-types.d.ts +86 -0
- package/dist/deploy/rollout-types.js +5 -0
- package/dist/deploy/types.d.ts +47 -0
- package/dist/deploy/types.js +5 -0
- package/dist/deploy/vercel-target.d.ts +16 -0
- package/dist/deploy/vercel-target.js +115 -0
- package/dist/discovery.d.ts +26 -0
- package/dist/discovery.js +46 -0
- package/dist/episodic-enhanced.d.ts +88 -0
- package/dist/episodic-enhanced.js +212 -0
- package/dist/execute.d.ts +81 -0
- package/dist/execute.js +703 -0
- package/dist/fix-ci.d.ts +61 -0
- package/dist/fix-ci.js +380 -0
- package/dist/handoff-executor.d.ts +61 -0
- package/dist/handoff-executor.js +119 -0
- package/dist/index.d.ts +70 -0
- package/dist/index.js +87 -0
- package/dist/instrumented.d.ts +27 -0
- package/dist/instrumented.js +34 -0
- package/dist/logger.d.ts +17 -0
- package/dist/logger.js +37 -0
- package/dist/multi-repo/impact-analyzer.d.ts +22 -0
- package/dist/multi-repo/impact-analyzer.js +95 -0
- package/dist/multi-repo/index.d.ts +5 -0
- package/dist/multi-repo/index.js +4 -0
- package/dist/multi-repo/monorepo-detector.d.ts +16 -0
- package/dist/multi-repo/monorepo-detector.js +246 -0
- package/dist/multi-repo/service-map-builder.d.ts +24 -0
- package/dist/multi-repo/service-map-builder.js +235 -0
- package/dist/multi-repo/types.d.ts +54 -0
- package/dist/multi-repo/types.js +5 -0
- package/dist/notifications/index.d.ts +4 -0
- package/dist/notifications/index.js +4 -0
- package/dist/notifications/notification-router.d.ts +62 -0
- package/dist/notifications/notification-router.js +206 -0
- package/dist/notifications/slack-messenger.d.ts +26 -0
- package/dist/notifications/slack-messenger.js +69 -0
- package/dist/notifications/teams-messenger.d.ts +21 -0
- package/dist/notifications/teams-messenger.js +85 -0
- package/dist/notifications.d.ts +13 -0
- package/dist/notifications.js +15 -0
- package/dist/orchestration.d.ts +20 -0
- package/dist/orchestration.js +53 -0
- package/dist/orchestrator.d.ts +160 -0
- package/dist/orchestrator.js +372 -0
- package/dist/otel-exporter.d.ts +37 -0
- package/dist/otel-exporter.js +128 -0
- package/dist/plugin.d.ts +45 -0
- package/dist/plugin.js +8 -0
- package/dist/policy-evaluators.d.ts +40 -0
- package/dist/policy-evaluators.js +57 -0
- package/dist/process-escalation.d.ts +38 -0
- package/dist/process-escalation.js +129 -0
- package/dist/progressive-gates.d.ts +54 -0
- package/dist/progressive-gates.js +135 -0
- package/dist/provenance.d.ts +29 -0
- package/dist/provenance.js +61 -0
- package/dist/reconcilers.d.ts +28 -0
- package/dist/reconcilers.js +37 -0
- package/dist/runners/claude-code.d.ts +17 -0
- package/dist/runners/claude-code.js +200 -0
- package/dist/runners/codex.d.ts +19 -0
- package/dist/runners/codex.js +153 -0
- package/dist/runners/copilot-stub.d.ts +9 -0
- package/dist/runners/copilot-stub.js +15 -0
- package/dist/runners/copilot.d.ts +15 -0
- package/dist/runners/copilot.js +119 -0
- package/dist/runners/cursor-stub.d.ts +9 -0
- package/dist/runners/cursor-stub.js +15 -0
- package/dist/runners/cursor.d.ts +20 -0
- package/dist/runners/cursor.js +140 -0
- package/dist/runners/devin-stub.d.ts +9 -0
- package/dist/runners/devin-stub.js +15 -0
- package/dist/runners/generic-llm.d.ts +51 -0
- package/dist/runners/generic-llm.js +125 -0
- package/dist/runners/index.d.ts +8 -0
- package/dist/runners/index.js +7 -0
- package/dist/runners/runner-registry.d.ts +50 -0
- package/dist/runners/runner-registry.js +156 -0
- package/dist/runners/types.d.ts +59 -0
- package/dist/runners/types.js +7 -0
- package/dist/security.d.ts +51 -0
- package/dist/security.js +70 -0
- package/dist/shared.d.ts +134 -0
- package/dist/shared.js +284 -0
- package/dist/state/index.d.ts +4 -0
- package/dist/state/index.js +3 -0
- package/dist/state/schema.d.ts +16 -0
- package/dist/state/schema.js +264 -0
- package/dist/state/store.d.ts +109 -0
- package/dist/state/store.js +644 -0
- package/dist/state/types.d.ts +190 -0
- package/dist/state/types.js +5 -0
- package/dist/structured-logger.d.ts +20 -0
- package/dist/structured-logger.js +64 -0
- package/dist/task-decomposer.d.ts +61 -0
- package/dist/task-decomposer.js +265 -0
- package/dist/telemetry-extended.d.ts +24 -0
- package/dist/telemetry-extended.js +31 -0
- package/dist/types.d.ts +9 -0
- package/dist/types.js +7 -0
- package/dist/validate-agent-output.d.ts +30 -0
- package/dist/validate-agent-output.js +81 -0
- package/dist/validate-issue.d.ts +25 -0
- package/dist/validate-issue.js +102 -0
- package/dist/watch.d.ts +43 -0
- package/dist/watch.js +99 -0
- package/dist/webhook-manager.d.ts +38 -0
- package/dist/webhook-manager.js +66 -0
- package/package.json +59 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Table output formatter — human-readable tabular output.
|
|
3
|
+
*/
|
|
4
|
+
export function formatTable(data) {
|
|
5
|
+
const type = data.type;
|
|
6
|
+
const lines = [];
|
|
7
|
+
switch (type) {
|
|
8
|
+
case 'run': {
|
|
9
|
+
lines.push('Pipeline Run Result');
|
|
10
|
+
lines.push('─'.repeat(40));
|
|
11
|
+
lines.push(`Issue: #${data.issueNumber}`);
|
|
12
|
+
lines.push(`PR URL: ${data.prUrl}`);
|
|
13
|
+
lines.push(`Files: ${data.filesChanged}`);
|
|
14
|
+
lines.push(`Promotion: ${data.promotionEligible ? 'eligible' : 'not eligible'}`);
|
|
15
|
+
break;
|
|
16
|
+
}
|
|
17
|
+
case 'status': {
|
|
18
|
+
lines.push(`Pipeline: ${data.pipeline}`);
|
|
19
|
+
lines.push('─'.repeat(50));
|
|
20
|
+
const runs = data.recentRuns;
|
|
21
|
+
if (runs.length === 0) {
|
|
22
|
+
lines.push('No recent runs.');
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
lines.push('Run ID'.padEnd(30) + 'Issue'.padEnd(10) + 'Status'.padEnd(12) + 'Started');
|
|
26
|
+
lines.push('─'.repeat(70));
|
|
27
|
+
for (const run of runs) {
|
|
28
|
+
lines.push(String(run.runId ?? '').padEnd(30) +
|
|
29
|
+
String(run.issueNumber ? `#${run.issueNumber}` : '-').padEnd(10) +
|
|
30
|
+
String(run.status ?? '').padEnd(12) +
|
|
31
|
+
String(run.startedAt ?? '-'));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
case 'health': {
|
|
37
|
+
lines.push('Health Check');
|
|
38
|
+
lines.push('─'.repeat(40));
|
|
39
|
+
lines.push(`Config: ${data.configValid ? 'valid' : 'INVALID'}`);
|
|
40
|
+
lines.push(`State Store: ${data.stateStoreConnected ? 'connected' : 'not configured'}`);
|
|
41
|
+
const errors = data.errors;
|
|
42
|
+
if (errors.length > 0) {
|
|
43
|
+
lines.push('');
|
|
44
|
+
lines.push('Errors:');
|
|
45
|
+
for (const e of errors) {
|
|
46
|
+
lines.push(` - ${e}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
case 'agents': {
|
|
52
|
+
lines.push('Agent Roster');
|
|
53
|
+
lines.push('─'.repeat(50));
|
|
54
|
+
const agents = data.agents;
|
|
55
|
+
if (agents.length === 0) {
|
|
56
|
+
lines.push('No agents registered.');
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
lines.push('Agent'.padEnd(20) +
|
|
60
|
+
'Level'.padEnd(7) +
|
|
61
|
+
'Tasks'.padEnd(7) +
|
|
62
|
+
'Success'.padEnd(9) +
|
|
63
|
+
'Last Task');
|
|
64
|
+
lines.push('─'.repeat(70));
|
|
65
|
+
for (const agent of agents) {
|
|
66
|
+
const total = agent.totalTasks;
|
|
67
|
+
const success = agent.successCount;
|
|
68
|
+
const pct = total > 0 ? `${Math.round((success / total) * 100)}%` : '-';
|
|
69
|
+
const lastTask = agent.lastTaskAt ? agent.lastTaskAt.split('T')[0] : '-';
|
|
70
|
+
lines.push(String(agent.agentName ?? '').padEnd(20) +
|
|
71
|
+
String(agent.currentLevel ?? 0).padEnd(7) +
|
|
72
|
+
String(total).padEnd(7) +
|
|
73
|
+
pct.padEnd(9) +
|
|
74
|
+
lastTask);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
case 'routing': {
|
|
80
|
+
const duration = data.duration ?? '30d';
|
|
81
|
+
lines.push(`Routing Distribution (last ${duration})`);
|
|
82
|
+
lines.push('─'.repeat(50));
|
|
83
|
+
const history = data.history;
|
|
84
|
+
// Group by strategy
|
|
85
|
+
const groups = new Map();
|
|
86
|
+
for (const entry of history) {
|
|
87
|
+
const strategy = entry.routingStrategy;
|
|
88
|
+
groups.set(strategy, (groups.get(strategy) ?? 0) + 1);
|
|
89
|
+
}
|
|
90
|
+
if (groups.size === 0) {
|
|
91
|
+
lines.push('No routing decisions recorded.');
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
lines.push('Strategy'.padEnd(20) + 'Count'.padEnd(8) + 'Percentage');
|
|
95
|
+
lines.push('─'.repeat(50));
|
|
96
|
+
const total = history.length;
|
|
97
|
+
const sorted = [...groups.entries()].sort((a, b) => b[1] - a[1]);
|
|
98
|
+
for (const [strategy, count] of sorted) {
|
|
99
|
+
const pct = `${Math.round((count / total) * 100)}%`;
|
|
100
|
+
lines.push(strategy.padEnd(20) + String(count).padEnd(8) + pct);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
case 'complexity': {
|
|
106
|
+
const profile = data.profile;
|
|
107
|
+
const _context = data.context;
|
|
108
|
+
lines.push('Codebase Complexity Profile');
|
|
109
|
+
lines.push('─'.repeat(50));
|
|
110
|
+
lines.push(`Score: ${profile.score}/10 | Files: ${profile.filesCount} | Modules: ${profile.modulesCount} | Deps: ${profile.dependencyCount}`);
|
|
111
|
+
const patterns = profile.architecturalPatterns;
|
|
112
|
+
if (patterns && patterns.length > 0) {
|
|
113
|
+
lines.push('');
|
|
114
|
+
lines.push('Architectural Patterns');
|
|
115
|
+
for (const p of patterns.slice(0, 5)) {
|
|
116
|
+
const pct = Math.round(p.confidence * 100);
|
|
117
|
+
lines.push(` ${String(p.name).padEnd(16)} ${pct}% — ${p.description}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const hotspots = profile.hotspots;
|
|
121
|
+
if (hotspots && hotspots.length > 0) {
|
|
122
|
+
lines.push('');
|
|
123
|
+
lines.push('Hotspots (top 5)');
|
|
124
|
+
for (const h of hotspots.slice(0, 5)) {
|
|
125
|
+
const churnPct = Math.round(h.churnRate * 100);
|
|
126
|
+
lines.push(` ${String(h.filePath).padEnd(40)} churn: ${churnPct}% complexity: ${h.complexity}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const conventions = profile.conventions;
|
|
130
|
+
if (conventions && conventions.length > 0) {
|
|
131
|
+
lines.push('');
|
|
132
|
+
lines.push('Conventions');
|
|
133
|
+
for (const c of conventions) {
|
|
134
|
+
lines.push(` ${c.category}: ${c.pattern}`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
case 'cost': {
|
|
140
|
+
const summary = data.summary;
|
|
141
|
+
const budget = data.budget;
|
|
142
|
+
const period = data.period ?? 'all-time';
|
|
143
|
+
lines.push(`Cost Summary (${period})`);
|
|
144
|
+
lines.push('─'.repeat(50));
|
|
145
|
+
lines.push(`Total Cost: $${summary.totalCostUsd.toFixed(2)}`);
|
|
146
|
+
lines.push(`Total Tokens: ${summary.totalTokens}`);
|
|
147
|
+
lines.push(`Runs: ${summary.entryCount}`);
|
|
148
|
+
lines.push(`Avg Cost/Run: $${summary.avgCostPerRun.toFixed(4)}`);
|
|
149
|
+
lines.push('');
|
|
150
|
+
lines.push('Budget Status');
|
|
151
|
+
lines.push('─'.repeat(50));
|
|
152
|
+
lines.push(`Budget: $${budget.budgetUsd}`);
|
|
153
|
+
lines.push(`Spent: $${budget.spentUsd.toFixed(2)}`);
|
|
154
|
+
lines.push(`Remaining: $${budget.remainingUsd.toFixed(2)}`);
|
|
155
|
+
lines.push(`Utilization: ${budget.utilizationPercent.toFixed(1)}%`);
|
|
156
|
+
if (budget.overBudget) {
|
|
157
|
+
lines.push(' ** OVER BUDGET **');
|
|
158
|
+
}
|
|
159
|
+
const costByAgent = summary.costByAgent;
|
|
160
|
+
if (costByAgent && Object.keys(costByAgent).length > 0) {
|
|
161
|
+
lines.push('');
|
|
162
|
+
lines.push('Cost by Agent');
|
|
163
|
+
lines.push('─'.repeat(50));
|
|
164
|
+
lines.push('Agent'.padEnd(20) + 'Cost');
|
|
165
|
+
for (const [agent, cost] of Object.entries(costByAgent)) {
|
|
166
|
+
lines.push(agent.padEnd(20) + `$${cost.toFixed(4)}`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (data.agent && data.filteredCost !== undefined) {
|
|
170
|
+
lines.push('');
|
|
171
|
+
lines.push(`Filtered (${data.agent}): $${data.filteredCost.toFixed(4)}`);
|
|
172
|
+
}
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
default: {
|
|
176
|
+
// Generic key-value output
|
|
177
|
+
for (const [key, value] of Object.entries(data)) {
|
|
178
|
+
lines.push(`${key}: ${JSON.stringify(value)}`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return lines.join('\n');
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=table.js.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* AI-SDLC CLI — entry point for the Commander-based CLI.
|
|
4
|
+
*/
|
|
5
|
+
import { Command } from 'commander';
|
|
6
|
+
import { initCommand } from './commands/init.js';
|
|
7
|
+
import { runCommand } from './commands/run.js';
|
|
8
|
+
import { startCommand } from './commands/start.js';
|
|
9
|
+
import { statusCommand } from './commands/status.js';
|
|
10
|
+
import { healthCommand } from './commands/health.js';
|
|
11
|
+
import { agentsCommand } from './commands/agents.js';
|
|
12
|
+
import { routingCommand } from './commands/routing.js';
|
|
13
|
+
import { complexityCommand } from './commands/complexity.js';
|
|
14
|
+
import { costCommand } from './commands/cost.js';
|
|
15
|
+
import { dashboardCommand } from './commands/dashboard.js';
|
|
16
|
+
const program = new Command();
|
|
17
|
+
program
|
|
18
|
+
.name('ai-sdlc')
|
|
19
|
+
.description('AI-SDLC Orchestrator — drive issues through the SDLC with AI agents')
|
|
20
|
+
.version('0.1.0')
|
|
21
|
+
.option('-c, --config <dir>', 'Config directory path', '.ai-sdlc')
|
|
22
|
+
.option('-f, --format <type>', 'Output format: table, json, minimal', 'table')
|
|
23
|
+
.option('-v, --verbose', 'Enable verbose output');
|
|
24
|
+
program.addCommand(initCommand);
|
|
25
|
+
program.addCommand(runCommand);
|
|
26
|
+
program.addCommand(startCommand);
|
|
27
|
+
program.addCommand(statusCommand);
|
|
28
|
+
program.addCommand(healthCommand);
|
|
29
|
+
program.addCommand(agentsCommand);
|
|
30
|
+
program.addCommand(routingCommand);
|
|
31
|
+
program.addCommand(complexityCommand);
|
|
32
|
+
program.addCommand(costCommand);
|
|
33
|
+
program.addCommand(dashboardCommand);
|
|
34
|
+
program.parse();
|
|
35
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extended compliance integration — covers individual framework checking,
|
|
3
|
+
* control IDs, framework mappings, and all 6 regulatory frameworks.
|
|
4
|
+
*/
|
|
5
|
+
import { type RegulatoryFramework, type ControlMapping, type ComplianceCoverageReport } from '@ai-sdlc/reference';
|
|
6
|
+
/**
|
|
7
|
+
* Check compliance against a single regulatory framework.
|
|
8
|
+
*/
|
|
9
|
+
export declare function checkFrameworkCompliance(framework: RegulatoryFramework, implementedControls: ReadonlySet<string>): ComplianceCoverageReport;
|
|
10
|
+
/**
|
|
11
|
+
* Get all control IDs defined in the AI-SDLC control catalog.
|
|
12
|
+
*/
|
|
13
|
+
export declare function getControlCatalog(): Set<string>;
|
|
14
|
+
/**
|
|
15
|
+
* Get the control mappings for a specific regulatory framework.
|
|
16
|
+
*/
|
|
17
|
+
export declare function getFrameworkMappings(framework: RegulatoryFramework): readonly ControlMapping[];
|
|
18
|
+
/**
|
|
19
|
+
* List all supported regulatory frameworks.
|
|
20
|
+
*/
|
|
21
|
+
export declare function listSupportedFrameworks(): readonly RegulatoryFramework[];
|
|
22
|
+
/**
|
|
23
|
+
* Detailed compliance report for a single framework.
|
|
24
|
+
*/
|
|
25
|
+
export interface DetailedFrameworkReport {
|
|
26
|
+
framework: RegulatoryFramework;
|
|
27
|
+
coveragePercent: number;
|
|
28
|
+
gaps: string[];
|
|
29
|
+
coveredControls: string[];
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Generate a detailed compliance report for each of the 6 regulatory frameworks.
|
|
33
|
+
*/
|
|
34
|
+
export declare function generateDetailedComplianceReport(implementedControls: ReadonlySet<string>): DetailedFrameworkReport[];
|
|
35
|
+
/**
|
|
36
|
+
* Get compliance gaps (missing controls) for a specific framework.
|
|
37
|
+
*/
|
|
38
|
+
export declare function getComplianceGaps(framework: RegulatoryFramework, implementedControls: ReadonlySet<string>): string[];
|
|
39
|
+
export { checkCompliance, checkAllFrameworks, getAllControlIds, getMappingsForFramework, AI_SDLC_CONTROLS, EU_AI_ACT_MAPPINGS, NIST_AI_RMF_MAPPINGS, ISO_42001_MAPPINGS, ISO_12207_MAPPINGS, OWASP_ASI_MAPPINGS, CSA_ATF_MAPPINGS, REGULATORY_FRAMEWORKS, } from '@ai-sdlc/reference';
|
|
40
|
+
export type { RegulatoryFramework, ComplianceControl, ControlMapping, ComplianceCoverageReport, } from '@ai-sdlc/reference';
|
|
41
|
+
//# sourceMappingURL=compliance-extended.d.ts.map
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extended compliance integration — covers individual framework checking,
|
|
3
|
+
* control IDs, framework mappings, and all 6 regulatory frameworks.
|
|
4
|
+
*/
|
|
5
|
+
import { checkCompliance, getAllControlIds, getMappingsForFramework, REGULATORY_FRAMEWORKS, } from '@ai-sdlc/reference';
|
|
6
|
+
/**
|
|
7
|
+
* Check compliance against a single regulatory framework.
|
|
8
|
+
*/
|
|
9
|
+
export function checkFrameworkCompliance(framework, implementedControls) {
|
|
10
|
+
return checkCompliance(implementedControls, framework);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Get all control IDs defined in the AI-SDLC control catalog.
|
|
14
|
+
*/
|
|
15
|
+
export function getControlCatalog() {
|
|
16
|
+
return getAllControlIds();
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Get the control mappings for a specific regulatory framework.
|
|
20
|
+
*/
|
|
21
|
+
export function getFrameworkMappings(framework) {
|
|
22
|
+
return getMappingsForFramework(framework);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* List all supported regulatory frameworks.
|
|
26
|
+
*/
|
|
27
|
+
export function listSupportedFrameworks() {
|
|
28
|
+
return [...REGULATORY_FRAMEWORKS];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Generate a detailed compliance report for each of the 6 regulatory frameworks.
|
|
32
|
+
*/
|
|
33
|
+
export function generateDetailedComplianceReport(implementedControls) {
|
|
34
|
+
const frameworks = listSupportedFrameworks();
|
|
35
|
+
return frameworks.map((framework) => {
|
|
36
|
+
const report = checkCompliance(implementedControls, framework);
|
|
37
|
+
const mappings = getMappingsForFramework(framework);
|
|
38
|
+
const requiredControls = mappings.map((m) => m.controlId);
|
|
39
|
+
const covered = requiredControls.filter((c) => implementedControls.has(c));
|
|
40
|
+
const gaps = requiredControls.filter((c) => !implementedControls.has(c));
|
|
41
|
+
return {
|
|
42
|
+
framework,
|
|
43
|
+
coveragePercent: report.coveragePercent,
|
|
44
|
+
gaps,
|
|
45
|
+
coveredControls: covered,
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Get compliance gaps (missing controls) for a specific framework.
|
|
51
|
+
*/
|
|
52
|
+
export function getComplianceGaps(framework, implementedControls) {
|
|
53
|
+
const mappings = getMappingsForFramework(framework);
|
|
54
|
+
return mappings.map((m) => m.controlId).filter((c) => !implementedControls.has(c));
|
|
55
|
+
}
|
|
56
|
+
// Direct re-exports (passthrough)
|
|
57
|
+
export { checkCompliance, checkAllFrameworks, getAllControlIds, getMappingsForFramework, AI_SDLC_CONTROLS, EU_AI_ACT_MAPPINGS, NIST_AI_RMF_MAPPINGS, ISO_42001_MAPPINGS, ISO_12207_MAPPINGS, OWASP_ASI_MAPPINGS, CSA_ATF_MAPPINGS, REGULATORY_FRAMEWORKS, } from '@ai-sdlc/reference';
|
|
58
|
+
//# sourceMappingURL=compliance-extended.js.map
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loads and validates .ai-sdlc/ resource YAML files using the reference
|
|
3
|
+
* implementation's schema validation.
|
|
4
|
+
*
|
|
5
|
+
* Unlike the dogfood config loader, this version does NOT import builder
|
|
6
|
+
* functions — it performs pure YAML loading and validation only.
|
|
7
|
+
*/
|
|
8
|
+
import { type Pipeline, type AgentRole, type QualityGate, type AutonomyPolicy, type AdapterBinding, type AdapterRegistry } from '@ai-sdlc/reference';
|
|
9
|
+
export interface AiSdlcConfig {
|
|
10
|
+
pipeline?: Pipeline;
|
|
11
|
+
agentRole?: AgentRole;
|
|
12
|
+
qualityGate?: QualityGate;
|
|
13
|
+
autonomyPolicy?: AutonomyPolicy;
|
|
14
|
+
adapterBinding?: AdapterBinding;
|
|
15
|
+
adapterRegistry?: AdapterRegistry;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Load all YAML files from the given directory, validate each against
|
|
19
|
+
* the AI-SDLC JSON Schema, and return typed resources keyed by kind.
|
|
20
|
+
*/
|
|
21
|
+
export declare function loadConfig(configDir: string): AiSdlcConfig;
|
|
22
|
+
/**
|
|
23
|
+
* Async variant of loadConfig that also scans for local adapter plugins.
|
|
24
|
+
*/
|
|
25
|
+
export declare function loadConfigAsync(configDir: string): Promise<AiSdlcConfig>;
|
|
26
|
+
//# sourceMappingURL=config.d.ts.map
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loads and validates .ai-sdlc/ resource YAML files using the reference
|
|
3
|
+
* implementation's schema validation.
|
|
4
|
+
*
|
|
5
|
+
* Unlike the dogfood config loader, this version does NOT import builder
|
|
6
|
+
* functions — it performs pure YAML loading and validation only.
|
|
7
|
+
*/
|
|
8
|
+
import { readFileSync, readdirSync, existsSync } from 'node:fs';
|
|
9
|
+
import { resolve, join } from 'node:path';
|
|
10
|
+
import { parse as parseYaml } from 'yaml';
|
|
11
|
+
import { validateResource, createAdapterRegistry, scanLocalAdapters, } from '@ai-sdlc/reference';
|
|
12
|
+
const KIND_KEY = {
|
|
13
|
+
Pipeline: 'pipeline',
|
|
14
|
+
AgentRole: 'agentRole',
|
|
15
|
+
QualityGate: 'qualityGate',
|
|
16
|
+
AutonomyPolicy: 'autonomyPolicy',
|
|
17
|
+
AdapterBinding: 'adapterBinding',
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Load all YAML files from the given directory, validate each against
|
|
21
|
+
* the AI-SDLC JSON Schema, and return typed resources keyed by kind.
|
|
22
|
+
*/
|
|
23
|
+
export function loadConfig(configDir) {
|
|
24
|
+
const dir = resolve(configDir);
|
|
25
|
+
if (!existsSync(dir)) {
|
|
26
|
+
return {};
|
|
27
|
+
}
|
|
28
|
+
const files = readdirSync(dir).filter((f) => f.endsWith('.yaml') || f.endsWith('.yml'));
|
|
29
|
+
const config = {};
|
|
30
|
+
for (const file of files) {
|
|
31
|
+
// Skip non-resource YAML files (e.g. manifest.yaml)
|
|
32
|
+
if (file === 'manifest.yaml')
|
|
33
|
+
continue;
|
|
34
|
+
const raw = readFileSync(resolve(dir, file), 'utf-8');
|
|
35
|
+
const doc = parseYaml(raw);
|
|
36
|
+
const result = validateResource(doc);
|
|
37
|
+
if (!result.valid) {
|
|
38
|
+
const msgs = (result.errors ?? []).map((e) => ` ${e.path}: ${e.message}`).join('\n');
|
|
39
|
+
throw new Error(`Validation failed for ${file}:\n${msgs}`);
|
|
40
|
+
}
|
|
41
|
+
const resource = result.data;
|
|
42
|
+
const key = KIND_KEY[resource.kind];
|
|
43
|
+
if (key) {
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
45
|
+
config[key] = resource;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return config;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Async variant of loadConfig that also scans for local adapter plugins.
|
|
52
|
+
*/
|
|
53
|
+
export async function loadConfigAsync(configDir) {
|
|
54
|
+
const config = loadConfig(configDir);
|
|
55
|
+
const registry = createAdapterRegistry();
|
|
56
|
+
try {
|
|
57
|
+
const scan = await scanLocalAdapters({ basePath: join(configDir, 'adapters') });
|
|
58
|
+
for (const m of scan.adapters)
|
|
59
|
+
registry.register(m);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
/* no adapters dir — fine */
|
|
63
|
+
}
|
|
64
|
+
return { ...config, adapterRegistry: registry };
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context enrichment — finds relevant episodic memory and formats
|
|
3
|
+
* it into a structured prompt section for agent context injection.
|
|
4
|
+
*
|
|
5
|
+
* RFC reference: Phase 2 context enrichment.
|
|
6
|
+
*/
|
|
7
|
+
import type { StateStore } from './state/store.js';
|
|
8
|
+
import type { EpisodicRecord } from './state/types.js';
|
|
9
|
+
export interface EpisodeSearchCriteria {
|
|
10
|
+
files?: string[];
|
|
11
|
+
module?: string;
|
|
12
|
+
labels?: string[];
|
|
13
|
+
issueNumber?: number;
|
|
14
|
+
agentName?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface ScoredEpisode {
|
|
17
|
+
episode: EpisodicRecord;
|
|
18
|
+
relevanceScore: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Find relevant episodes from the state store based on given criteria.
|
|
22
|
+
* Returns episodes sorted by relevance score (highest first).
|
|
23
|
+
*/
|
|
24
|
+
export declare function findRelevantEpisodes(store: StateStore, criteria: EpisodeSearchCriteria, limit?: number): ScoredEpisode[];
|
|
25
|
+
/**
|
|
26
|
+
* Format episodic memory entries into a structured prompt section.
|
|
27
|
+
*/
|
|
28
|
+
export declare function formatEpisodicContext(episodes: ScoredEpisode[]): string;
|
|
29
|
+
/**
|
|
30
|
+
* Top-level enrichment: find relevant episodes and format them.
|
|
31
|
+
*/
|
|
32
|
+
export declare function enrichAgentContext(store: StateStore, criteria: EpisodeSearchCriteria): string;
|
|
33
|
+
//# sourceMappingURL=context-enrichment.d.ts.map
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context enrichment — finds relevant episodic memory and formats
|
|
3
|
+
* it into a structured prompt section for agent context injection.
|
|
4
|
+
*
|
|
5
|
+
* RFC reference: Phase 2 context enrichment.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Find relevant episodes from the state store based on given criteria.
|
|
9
|
+
* Returns episodes sorted by relevance score (highest first).
|
|
10
|
+
*/
|
|
11
|
+
export function findRelevantEpisodes(store, criteria, limit = 10) {
|
|
12
|
+
// Pull recent episodes (broad search)
|
|
13
|
+
const candidates = store.searchEpisodicRecords({ limit: 200 });
|
|
14
|
+
// Score each candidate
|
|
15
|
+
const scored = [];
|
|
16
|
+
for (const ep of candidates) {
|
|
17
|
+
let score = 0;
|
|
18
|
+
// Score by issue number match
|
|
19
|
+
if (criteria.issueNumber && ep.issueNumber === criteria.issueNumber) {
|
|
20
|
+
score += 5;
|
|
21
|
+
}
|
|
22
|
+
// Score by agent name match
|
|
23
|
+
if (criteria.agentName && ep.agentName === criteria.agentName) {
|
|
24
|
+
score += 2;
|
|
25
|
+
}
|
|
26
|
+
// Score by file overlap
|
|
27
|
+
if (criteria.files && criteria.files.length > 0 && ep.metadata) {
|
|
28
|
+
try {
|
|
29
|
+
const parsed = JSON.parse(ep.metadata);
|
|
30
|
+
const epFiles = parsed.filesChanged ?? parsed.files ?? [];
|
|
31
|
+
const overlap = criteria.files.filter((f) => epFiles.some((ef) => ef.includes(f) || f.includes(ef)));
|
|
32
|
+
score += overlap.length * 3;
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// metadata not JSON
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// Score by module match (check metadata or routing strategy)
|
|
39
|
+
if (criteria.module && ep.metadata) {
|
|
40
|
+
if (ep.metadata.includes(criteria.module)) {
|
|
41
|
+
score += 2;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// Score by labels
|
|
45
|
+
if (criteria.labels && criteria.labels.length > 0 && ep.metadata) {
|
|
46
|
+
for (const label of criteria.labels) {
|
|
47
|
+
if (ep.metadata.includes(label)) {
|
|
48
|
+
score += 1;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// Bonus for regressions (more important context)
|
|
53
|
+
if (ep.isRegression === 1) {
|
|
54
|
+
score += 2;
|
|
55
|
+
}
|
|
56
|
+
// Bonus for failures (cautionary context)
|
|
57
|
+
if (ep.outcome === 'failure') {
|
|
58
|
+
score += 1;
|
|
59
|
+
}
|
|
60
|
+
// Time decay: reduce score for older episodes
|
|
61
|
+
if (ep.createdAt) {
|
|
62
|
+
const ageMs = Date.now() - new Date(ep.createdAt).getTime();
|
|
63
|
+
const ageDays = ageMs / (24 * 60 * 60 * 1000);
|
|
64
|
+
if (ageDays > 30)
|
|
65
|
+
score *= 0.5;
|
|
66
|
+
else if (ageDays > 7)
|
|
67
|
+
score *= 0.8;
|
|
68
|
+
}
|
|
69
|
+
if (score > 0) {
|
|
70
|
+
scored.push({ episode: ep, relevanceScore: score });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return scored.sort((a, b) => b.relevanceScore - a.relevanceScore).slice(0, limit);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Format episodic memory entries into a structured prompt section.
|
|
77
|
+
*/
|
|
78
|
+
export function formatEpisodicContext(episodes) {
|
|
79
|
+
if (episodes.length === 0) {
|
|
80
|
+
return '';
|
|
81
|
+
}
|
|
82
|
+
const lines = ['## Episodic Memory (relevant history)', ''];
|
|
83
|
+
for (const { episode } of episodes.slice(0, 5)) {
|
|
84
|
+
const outcome = episode.outcome === 'success' ? 'SUCCESS' : 'FAILURE';
|
|
85
|
+
const date = episode.createdAt?.split('T')[0] ?? 'unknown';
|
|
86
|
+
const agent = episode.agentName ? ` (${episode.agentName})` : '';
|
|
87
|
+
const regression = episode.isRegression === 1 ? ' [REGRESSION]' : '';
|
|
88
|
+
lines.push(`### ${outcome}${regression} — ${episode.pipelineType}${agent} (${date})`);
|
|
89
|
+
if (episode.errorMessage) {
|
|
90
|
+
lines.push(`Error: ${episode.errorMessage.slice(0, 200)}`);
|
|
91
|
+
}
|
|
92
|
+
if (episode.routingStrategy) {
|
|
93
|
+
lines.push(`Strategy: ${episode.routingStrategy}`);
|
|
94
|
+
}
|
|
95
|
+
if (episode.gatePassCount != null || episode.gateFailCount != null) {
|
|
96
|
+
lines.push(`Gates: ${episode.gatePassCount ?? 0} passed, ${episode.gateFailCount ?? 0} failed`);
|
|
97
|
+
}
|
|
98
|
+
if (episode.costUsd != null) {
|
|
99
|
+
lines.push(`Cost: $${episode.costUsd.toFixed(4)}`);
|
|
100
|
+
}
|
|
101
|
+
// Extract files from metadata
|
|
102
|
+
if (episode.metadata) {
|
|
103
|
+
try {
|
|
104
|
+
const parsed = JSON.parse(episode.metadata);
|
|
105
|
+
const files = parsed.filesChanged ?? parsed.files ?? [];
|
|
106
|
+
if (files.length > 0) {
|
|
107
|
+
lines.push(`Files: ${files.slice(0, 5).join(', ')}${files.length > 5 ? ` (+${files.length - 5} more)` : ''}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// not JSON
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
lines.push('');
|
|
115
|
+
}
|
|
116
|
+
return lines.join('\n');
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Top-level enrichment: find relevant episodes and format them.
|
|
120
|
+
*/
|
|
121
|
+
export function enrichAgentContext(store, criteria) {
|
|
122
|
+
const episodes = findRelevantEpisodes(store, criteria);
|
|
123
|
+
return formatEpisodicContext(episodes);
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=context-enrichment.js.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CostGovernancePlugin — orchestrator plugin that wires budget checks,
|
|
3
|
+
* circuit breaker, and cost alert evaluation into the pipeline lifecycle.
|
|
4
|
+
*
|
|
5
|
+
* Registered automatically when a Pipeline has a costPolicy.
|
|
6
|
+
*/
|
|
7
|
+
import type { CostPolicy } from '@ai-sdlc/reference';
|
|
8
|
+
import type { OrchestratorPlugin, PluginContext, BeforeRunEvent, AfterRunEvent } from './plugin.js';
|
|
9
|
+
export declare class CostGovernancePlugin implements OrchestratorPlugin {
|
|
10
|
+
private costPolicy;
|
|
11
|
+
name: string;
|
|
12
|
+
private costTracker?;
|
|
13
|
+
private notificationRouter?;
|
|
14
|
+
private log;
|
|
15
|
+
private budgetAmount?;
|
|
16
|
+
private budgetPeriod?;
|
|
17
|
+
constructor(costPolicy: CostPolicy);
|
|
18
|
+
initialize(ctx: PluginContext): void;
|
|
19
|
+
beforeRun(_event: BeforeRunEvent): Promise<void>;
|
|
20
|
+
afterRun(_event: AfterRunEvent): Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=cost-governance.d.ts.map
|