@ai-sdlc/orchestrator 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters.d.ts +18 -3
- package/dist/adapters.js +92 -2
- package/dist/cli/commands/init.js +4 -8
- package/dist/cli/commands/run.js +2 -2
- package/dist/config.d.ts +3 -0
- package/dist/config.js +14 -5
- package/dist/execute.d.ts +5 -2
- package/dist/execute.js +101 -46
- package/dist/fix-ci.js +13 -11
- package/dist/index.d.ts +6 -4
- package/dist/index.js +6 -3
- package/dist/orchestrator.d.ts +1 -1
- package/dist/orchestrator.js +31 -9
- package/dist/plugin.d.ts +9 -3
- package/dist/priority.d.ts +102 -0
- package/dist/priority.js +230 -0
- package/dist/runners/claude-code.js +56 -6
- package/dist/runners/codex.js +15 -4
- package/dist/runners/copilot.js +15 -4
- package/dist/runners/cursor.js +15 -4
- package/dist/runners/generic-llm.js +1 -1
- package/dist/runners/index.d.ts +1 -0
- package/dist/runners/index.js +1 -0
- package/dist/runners/security-triage.d.ts +43 -0
- package/dist/runners/security-triage.js +154 -0
- package/dist/runners/types.d.ts +5 -1
- package/dist/security.d.ts +8 -3
- package/dist/security.js +13 -2
- package/dist/shared.d.ts +17 -0
- package/dist/shared.js +27 -0
- package/dist/state/index.d.ts +1 -1
- package/dist/state/schema.d.ts +3 -1
- package/dist/state/schema.js +36 -1
- package/dist/state/store.d.ts +15 -1
- package/dist/state/store.js +86 -13
- package/dist/state/types.d.ts +17 -0
- package/dist/triage.d.ts +36 -0
- package/dist/triage.js +133 -0
- package/dist/types.d.ts +1 -1
- package/dist/watch.d.ts +6 -2
- package/dist/watch.js +34 -6
- package/package.json +4 -2
package/dist/adapters.d.ts
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* webhook bridge, git-based adapter resolver, and adapter registry/scanner
|
|
4
4
|
* into the dogfood pipeline.
|
|
5
5
|
*/
|
|
6
|
-
import
|
|
6
|
+
import type { AiSdlcConfig } from './config.js';
|
|
7
|
+
import { type IssueTracker, type AdapterRegistry, type ScanOptions, type ScanResult, type WebhookBridge, type GitAdapterFetcher, type GitResolveResult, type AuditLog, type AuditSink, type Sandbox, type SecretStore, type MemoryStore, type EventBus, type CIPipeline } from '@ai-sdlc/reference';
|
|
7
8
|
/**
|
|
8
9
|
* Create an adapter registry pre-loaded with all built-in and community adapters.
|
|
9
10
|
*/
|
|
@@ -55,6 +56,20 @@ export declare function scanPipelineAdapters(options: ScanOptions): Promise<Scan
|
|
|
55
56
|
* Requires `GITHUB_REPOSITORY_OWNER` and `GITHUB_REPOSITORY` env vars.
|
|
56
57
|
*/
|
|
57
58
|
export declare function createPipelineCIAdapter(): CIPipeline;
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
/**
|
|
60
|
+
* Resolve an IssueTracker from the adapterBindings in config.
|
|
61
|
+
*
|
|
62
|
+
* - 0 bindings → falls back to GitHub IssueTracker
|
|
63
|
+
* - 1 binding → returns that tracker directly
|
|
64
|
+
* - N bindings → wraps in CompositeIssueTracker
|
|
65
|
+
*/
|
|
66
|
+
export declare function resolveIssueTrackerFromConfig(config: AiSdlcConfig, fallbackGitHubConfig: {
|
|
67
|
+
org: string;
|
|
68
|
+
repo: string;
|
|
69
|
+
token: {
|
|
70
|
+
secretRef: string;
|
|
71
|
+
};
|
|
72
|
+
}): IssueTracker;
|
|
73
|
+
export { createGitHubCIPipeline, createDockerSandbox, createLinearIssueTracker, resolveSecret, createGitLabSourceControl, createGitLabCIPipeline, createJiraIssueTracker, createBacklogMdIssueTracker, createWebhookServer, createGitHubWebhookProvider, verifyGitHubSignature, createGitLabWebhookProvider, verifyGitLabToken, createJiraWebhookProvider, createLinearWebhookProvider, verifyLinearSignature, createAdapterRegistry, validateAdapterMetadata, parseMetadataYaml, scanLocalAdapters, createStubCodeAnalysis, createStubMessenger, createStubDeploymentTarget, createStubGitLabCI, createStubGitLabSource, createStubJira, createStubBitbucket, createStubSonarQube, createStubSemgrep, createInMemoryAuditSink, createFileSink, createEnvSecretStore, createInMemoryMemoryStore, createInProcessEventBus, createStubSandbox, createCompositeIssueTracker, createWebhookBridge, parseGitAdapterRef, buildRawUrl, createGitAdapterFetcher, createStubGitAdapterFetcher, resolveGitAdapter, } from '@ai-sdlc/reference';
|
|
74
|
+
export type { AdapterRegistry, AdapterMetadata, AdapterStability, AdapterFactory, MetadataValidationResult, ScanOptions, ScanResult, WebhookBridge, WebhookTransformer, GitAdapterReference, GitAdapterFetcher, GitResolveResult, CIPipeline, CodeAnalysis, Messenger, DeploymentTarget, EventBus, IssueTracker, LinearClientLike, IssueComment, AdapterInterfaces, EventStream, IssueFilter, CommitStatus, TestResults, CoverageReport, Finding, SeveritySummary, DeploymentStatus, StubCodeAnalysisConfig, StubCodeAnalysisAdapter, NotificationLogEntry, StubMessengerAdapter, StubDeploymentTargetAdapter, StubGitLabCIAdapter, StubGitLabSourceAdapter, StubJiraAdapter, StubBitbucketAdapter, StubSonarQubeConfig, StubSonarQubeAdapter, StubSemgrepConfig, StubSemgrepAdapter, AuditSink, AuditLog, InMemoryAuditSink, SecretStore, Sandbox, MemoryStore, InMemoryMemoryStore, InProcessEventBus, DockerSandboxConfig, BuildStatus, GitLabConfig, JiraConfig, BacklogMdConfig, BacklogFs, WebhookServer, WebhookServerConfig, WebhookProviderConfig, GitHubWebhookConfig, GitHubWebhookBridges, GitLabWebhookConfig, JiraWebhookConfig, LinearWebhookConfig, CompositeIssueTrackerConfig, BackendRoute, } from '@ai-sdlc/reference';
|
|
60
75
|
//# sourceMappingURL=adapters.d.ts.map
|
package/dist/adapters.js
CHANGED
|
@@ -14,6 +14,8 @@ createStubCodeAnalysis, createStubMessenger, createStubDeploymentTarget, createS
|
|
|
14
14
|
createInMemoryAuditSink, createFileSink, createAuditLog, createEnvSecretStore, createInMemoryMemoryStore, createInProcessEventBus, createStubSandbox,
|
|
15
15
|
// Docker sandbox
|
|
16
16
|
createDockerSandbox,
|
|
17
|
+
// OpenShell sandbox
|
|
18
|
+
createOpenShellSandbox,
|
|
17
19
|
// Backlog.md adapter
|
|
18
20
|
createBacklogMdIssueTracker,
|
|
19
21
|
// Webhook bridge (used in function body)
|
|
@@ -21,7 +23,13 @@ createWebhookBridge,
|
|
|
21
23
|
// Git resolver (used in function bodies)
|
|
22
24
|
createStubGitAdapterFetcher, createGitAdapterFetcher, resolveGitAdapter,
|
|
23
25
|
// GitHub CI adapter
|
|
24
|
-
createGitHubCIPipeline,
|
|
26
|
+
createGitHubCIPipeline,
|
|
27
|
+
// GitHub issue tracker
|
|
28
|
+
createGitHubIssueTracker,
|
|
29
|
+
// Composite issue tracker
|
|
30
|
+
createCompositeIssueTracker,
|
|
31
|
+
// Production adapters (for resolveIssueTrackerFromConfig)
|
|
32
|
+
createJiraIssueTracker, createLinearIssueTracker, } from '@ai-sdlc/reference';
|
|
25
33
|
/**
|
|
26
34
|
* Create an adapter registry pre-loaded with all built-in and community adapters.
|
|
27
35
|
*/
|
|
@@ -69,6 +77,24 @@ export function createPipelineAdapterRegistry() {
|
|
|
69
77
|
};
|
|
70
78
|
return createDockerSandbox(exec, config);
|
|
71
79
|
});
|
|
80
|
+
registry.register(stubMeta('openshell-sandbox', 'OpenShell Sandbox', 'Sandbox@v1', 'openshell'), () => {
|
|
81
|
+
const exec = async (cmd) => {
|
|
82
|
+
const { exec: cpExec } = await import('node:child_process');
|
|
83
|
+
const { promisify } = await import('node:util');
|
|
84
|
+
const execAsync = promisify(cpExec);
|
|
85
|
+
const { stdout } = await execAsync(cmd);
|
|
86
|
+
return stdout;
|
|
87
|
+
};
|
|
88
|
+
const config = {
|
|
89
|
+
workDir: process.env.AI_SDLC_WORK_DIR,
|
|
90
|
+
binaryPath: process.env.AI_SDLC_OPENSHELL_BIN,
|
|
91
|
+
autoProviders: [
|
|
92
|
+
{ name: 'claude', type: 'claude' },
|
|
93
|
+
{ name: 'github', type: 'github' },
|
|
94
|
+
],
|
|
95
|
+
};
|
|
96
|
+
return createOpenShellSandbox(exec, config);
|
|
97
|
+
});
|
|
72
98
|
registry.register(stubMeta('env-secret-store', 'Environment Secret Store', 'SecretStore@v1', 'env'), () => createEnvSecretStore());
|
|
73
99
|
registry.register(stubMeta('memory-store', 'In-Memory Memory Store', 'MemoryStore@v1', 'memory'), () => createInMemoryMemoryStore());
|
|
74
100
|
registry.register(stubMeta('in-process-event-bus', 'In-Process Event Bus', 'EventBus@v1', 'in-process'), () => createInProcessEventBus());
|
|
@@ -87,7 +113,12 @@ export function resolveInfrastructure(registry, config) {
|
|
|
87
113
|
const auditLog = createAuditLog(auditSink);
|
|
88
114
|
// Resolve from registry — factories are guaranteed present when using
|
|
89
115
|
// createPipelineAdapterRegistry(), but we guard for custom registries.
|
|
90
|
-
const
|
|
116
|
+
const sandboxEnv = process.env.AI_SDLC_SANDBOX_PROVIDER;
|
|
117
|
+
const sandboxProvider = sandboxEnv === 'openshell'
|
|
118
|
+
? 'openshell-sandbox'
|
|
119
|
+
: sandboxEnv === 'docker'
|
|
120
|
+
? 'docker-sandbox'
|
|
121
|
+
: 'stub-sandbox';
|
|
91
122
|
const sandbox = registry.getFactory(sandboxProvider)?.() ?? createStubSandbox();
|
|
92
123
|
const secretStore = registry.getFactory('env-secret-store')?.() ??
|
|
93
124
|
createEnvSecretStore();
|
|
@@ -140,6 +171,63 @@ export function createPipelineCIAdapter() {
|
|
|
140
171
|
workflowFile: process.env.AI_SDLC_WORKFLOW_FILE ?? DEFAULT_WORKFLOW_FILE,
|
|
141
172
|
});
|
|
142
173
|
}
|
|
174
|
+
// ── Issue tracker resolution from config ────────────────────────────
|
|
175
|
+
/**
|
|
176
|
+
* Resolve an IssueTracker from the adapterBindings in config.
|
|
177
|
+
*
|
|
178
|
+
* - 0 bindings → falls back to GitHub IssueTracker
|
|
179
|
+
* - 1 binding → returns that tracker directly
|
|
180
|
+
* - N bindings → wraps in CompositeIssueTracker
|
|
181
|
+
*/
|
|
182
|
+
export function resolveIssueTrackerFromConfig(config, fallbackGitHubConfig) {
|
|
183
|
+
const bindings = (config.adapterBindings ?? []).filter((b) => b.spec.interface === 'IssueTracker');
|
|
184
|
+
if (bindings.length === 0) {
|
|
185
|
+
return createGitHubIssueTracker(fallbackGitHubConfig);
|
|
186
|
+
}
|
|
187
|
+
const backends = bindings.map((binding) => {
|
|
188
|
+
const cfg = binding.spec.config ?? {};
|
|
189
|
+
switch (binding.spec.type) {
|
|
190
|
+
case 'backlog-md':
|
|
191
|
+
return {
|
|
192
|
+
prefix: cfg.taskPrefix ?? 'AISDLC',
|
|
193
|
+
adapter: createBacklogMdIssueTracker({
|
|
194
|
+
backlogDir: cfg.backlogDir ?? './backlog',
|
|
195
|
+
taskPrefix: cfg.taskPrefix,
|
|
196
|
+
}),
|
|
197
|
+
};
|
|
198
|
+
case 'github':
|
|
199
|
+
return {
|
|
200
|
+
prefix: null,
|
|
201
|
+
adapter: createGitHubIssueTracker({
|
|
202
|
+
org: cfg.org ?? fallbackGitHubConfig.org,
|
|
203
|
+
repo: cfg.repo ?? fallbackGitHubConfig.repo,
|
|
204
|
+
token: fallbackGitHubConfig.token,
|
|
205
|
+
}),
|
|
206
|
+
};
|
|
207
|
+
case 'jira':
|
|
208
|
+
return {
|
|
209
|
+
prefix: cfg.projectKey ?? null,
|
|
210
|
+
adapter: createJiraIssueTracker(cfg),
|
|
211
|
+
};
|
|
212
|
+
case 'linear':
|
|
213
|
+
return {
|
|
214
|
+
prefix: cfg.teamKey ?? null,
|
|
215
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
216
|
+
adapter: createLinearIssueTracker(cfg),
|
|
217
|
+
};
|
|
218
|
+
default:
|
|
219
|
+
// Unknown type — fall back to GitHub
|
|
220
|
+
return {
|
|
221
|
+
prefix: null,
|
|
222
|
+
adapter: createGitHubIssueTracker(fallbackGitHubConfig),
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
if (backends.length === 1) {
|
|
227
|
+
return backends[0].adapter;
|
|
228
|
+
}
|
|
229
|
+
return createCompositeIssueTracker({ backends });
|
|
230
|
+
}
|
|
143
231
|
// Direct re-exports (passthrough)
|
|
144
232
|
export {
|
|
145
233
|
// Core adapters
|
|
@@ -158,6 +246,8 @@ createAdapterRegistry, validateAdapterMetadata, parseMetadataYaml, scanLocalAdap
|
|
|
158
246
|
createStubCodeAnalysis, createStubMessenger, createStubDeploymentTarget, createStubGitLabCI, createStubGitLabSource, createStubJira, createStubBitbucket, createStubSonarQube, createStubSemgrep,
|
|
159
247
|
// Infrastructure adapter stubs
|
|
160
248
|
createInMemoryAuditSink, createFileSink, createEnvSecretStore, createInMemoryMemoryStore, createInProcessEventBus, createStubSandbox,
|
|
249
|
+
// Composite issue tracker
|
|
250
|
+
createCompositeIssueTracker,
|
|
161
251
|
// Webhook bridge
|
|
162
252
|
createWebhookBridge,
|
|
163
253
|
// Git resolver
|
|
@@ -134,24 +134,20 @@ spec:
|
|
|
134
134
|
action: demote-one-level
|
|
135
135
|
cooldown: 2w
|
|
136
136
|
`;
|
|
137
|
-
const
|
|
138
|
-
'# AI-SDLC runtime artifacts',
|
|
139
|
-
'.ai-sdlc/state.db',
|
|
140
|
-
'.ai-sdlc/state/',
|
|
141
|
-
'.ai-sdlc/audit.jsonl',
|
|
142
|
-
];
|
|
137
|
+
const GITIGNORE_PATHS = ['.ai-sdlc/state.db', '.ai-sdlc/state/', '.ai-sdlc/audit.jsonl'];
|
|
143
138
|
/** Ensure .gitignore includes AI-SDLC runtime artifact entries. */
|
|
144
139
|
function ensureGitignore(projectDir, dryRun, prefix = '') {
|
|
145
140
|
const gitignorePath = join(projectDir, '.gitignore');
|
|
146
141
|
const existing = existsSync(gitignorePath) ? readFileSync(gitignorePath, 'utf-8') : '';
|
|
147
|
-
|
|
142
|
+
// Only check path entries (not comments) to avoid duplicate blocks
|
|
143
|
+
const missing = GITIGNORE_PATHS.filter((entry) => !existing.includes(entry));
|
|
148
144
|
if (missing.length === 0)
|
|
149
145
|
return;
|
|
150
146
|
if (dryRun) {
|
|
151
147
|
console.log(`${prefix} Would update .gitignore`);
|
|
152
148
|
return;
|
|
153
149
|
}
|
|
154
|
-
const block = '\n' + missing.join('\n') + '\n';
|
|
150
|
+
const block = '\n# AI-SDLC runtime artifacts\n' + missing.join('\n') + '\n';
|
|
155
151
|
appendFileSync(gitignorePath, block, 'utf-8');
|
|
156
152
|
console.log(`${prefix} updated .gitignore`);
|
|
157
153
|
}
|
package/dist/cli/commands/run.js
CHANGED
|
@@ -6,7 +6,7 @@ import { Orchestrator } from '../../orchestrator.js';
|
|
|
6
6
|
import { formatOutput } from '../formatters/index.js';
|
|
7
7
|
export const runCommand = new Command('run')
|
|
8
8
|
.description('Run the AI-SDLC pipeline for a specific issue')
|
|
9
|
-
.requiredOption('-i, --issue <
|
|
9
|
+
.requiredOption('-i, --issue <id>', 'Issue ID to process')
|
|
10
10
|
.option('--state <path>', 'SQLite state database path')
|
|
11
11
|
.action(async (opts, cmd) => {
|
|
12
12
|
const globalOpts = cmd.parent?.opts() ?? {};
|
|
@@ -19,7 +19,7 @@ export const runCommand = new Command('run')
|
|
|
19
19
|
const result = await orchestrator.run(opts.issue);
|
|
20
20
|
console.log(formatOutput(format, {
|
|
21
21
|
type: 'run',
|
|
22
|
-
|
|
22
|
+
issueId: opts.issue,
|
|
23
23
|
prUrl: result.prUrl,
|
|
24
24
|
filesChanged: result.filesChanged.length,
|
|
25
25
|
promotionEligible: result.promotionEligible,
|
package/dist/config.d.ts
CHANGED
|
@@ -11,7 +11,10 @@ export interface AiSdlcConfig {
|
|
|
11
11
|
agentRole?: AgentRole;
|
|
12
12
|
qualityGate?: QualityGate;
|
|
13
13
|
autonomyPolicy?: AutonomyPolicy;
|
|
14
|
+
/** @deprecated Use `adapterBindings` instead. Returns the first binding if any exist. */
|
|
14
15
|
adapterBinding?: AdapterBinding;
|
|
16
|
+
/** All AdapterBinding resources found in the config directory. */
|
|
17
|
+
adapterBindings?: AdapterBinding[];
|
|
15
18
|
adapterRegistry?: AdapterRegistry;
|
|
16
19
|
}
|
|
17
20
|
/**
|
package/dist/config.js
CHANGED
|
@@ -9,12 +9,12 @@ import { readFileSync, readdirSync, existsSync } from 'node:fs';
|
|
|
9
9
|
import { resolve, join } from 'node:path';
|
|
10
10
|
import { parse as parseYaml } from 'yaml';
|
|
11
11
|
import { validateResource, createAdapterRegistry, scanLocalAdapters, } from '@ai-sdlc/reference';
|
|
12
|
+
/** Resource kinds that allow only a single instance. */
|
|
12
13
|
const KIND_KEY = {
|
|
13
14
|
Pipeline: 'pipeline',
|
|
14
15
|
AgentRole: 'agentRole',
|
|
15
16
|
QualityGate: 'qualityGate',
|
|
16
17
|
AutonomyPolicy: 'autonomyPolicy',
|
|
17
|
-
AdapterBinding: 'adapterBinding',
|
|
18
18
|
};
|
|
19
19
|
/**
|
|
20
20
|
* Load all YAML files from the given directory, validate each against
|
|
@@ -39,11 +39,20 @@ export function loadConfig(configDir) {
|
|
|
39
39
|
throw new Error(`Validation failed for ${file}:\n${msgs}`);
|
|
40
40
|
}
|
|
41
41
|
const resource = result.data;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
45
|
-
config[key] = resource;
|
|
42
|
+
if (resource.kind === 'AdapterBinding') {
|
|
43
|
+
(config.adapterBindings ??= []).push(resource);
|
|
46
44
|
}
|
|
45
|
+
else {
|
|
46
|
+
const key = KIND_KEY[resource.kind];
|
|
47
|
+
if (key) {
|
|
48
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
49
|
+
config[key] = resource;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// Backward compat: set adapterBinding to the first binding
|
|
54
|
+
if (config.adapterBindings?.length) {
|
|
55
|
+
config.adapterBinding = config.adapterBindings[0];
|
|
47
56
|
}
|
|
48
57
|
return config;
|
|
49
58
|
}
|
package/dist/execute.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ import type { CodebaseContext } from './analysis/types.js';
|
|
|
14
14
|
import type { AutonomyTracker } from './autonomy-tracker.js';
|
|
15
15
|
import { CostTracker } from './cost-tracker.js';
|
|
16
16
|
import type { StateStore } from './state/store.js';
|
|
17
|
+
import type { PriorityScore } from './priority.js';
|
|
17
18
|
export interface PipelineResult {
|
|
18
19
|
prUrl: string;
|
|
19
20
|
filesChanged: string[];
|
|
@@ -73,9 +74,11 @@ export interface ExecuteOptions {
|
|
|
73
74
|
costTracker?: CostTracker;
|
|
74
75
|
/** StateStore for episodic context enrichment. */
|
|
75
76
|
stateStore?: StateStore;
|
|
77
|
+
/** Priority score from PPA scoring (set by watch loop or caller). */
|
|
78
|
+
priorityScore?: PriorityScore;
|
|
76
79
|
}
|
|
77
80
|
/**
|
|
78
|
-
* Execute the full AI-SDLC pipeline for a given issue
|
|
81
|
+
* Execute the full AI-SDLC pipeline for a given issue ID.
|
|
79
82
|
*/
|
|
80
|
-
export declare function executePipeline(
|
|
83
|
+
export declare function executePipeline(issueId: string, options?: ExecuteOptions): Promise<PipelineResult>;
|
|
81
84
|
//# sourceMappingURL=execute.d.ts.map
|