sdd-agent-platform 0.2.0 → 0.3.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/packages/cli/src/main.js +167 -9
- package/dist/packages/cli/src/main.js.map +1 -1
- package/dist/packages/core/src/ai-tools.d.ts +1 -1
- package/dist/packages/core/src/ai-tools.js +3 -2
- package/dist/packages/core/src/ai-tools.js.map +1 -1
- package/dist/packages/core/src/index.d.ts +237 -2
- package/dist/packages/core/src/index.js +1379 -61
- package/dist/packages/core/src/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
3
|
import { readFile } from 'node:fs/promises';
|
|
3
|
-
import
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import { writeArtifact, archiveRun, applyAiToolEntries, applySyncBack, createWorktreeLifecycle, createRun, doctor, buildContextBuildPackage, buildEvidenceSummaryProjection, evaluateLifecycleDecisionGate, extractLifecycleRiskSignalsFromText, evaluateGovernancePolicy, getProjectStatus, getDelegationStateMachine, getSddInstructions, initProject, inspectRun, claimResidentWorkerRuntime, heartbeatResidentWorkerRuntime, inspectSddTask, inspectToolPluginContract, inspectToolCapability, inspectDelegationQueueItem, inspectSyncBack, inspectTaskGraph, inspectWavePlan, inspectWaveExecutor, inspectBackgroundExecutor, inspectResidentWorkerRuntime, inspectArtifactResultIngestions, inspectWorktreeLifecycle, inspectWorkerAdapterContract, inspectWorktreeIsolation, inspectGovernancePolicy, inspectWorkflowGate, inspectAgentRegistryEntry, inspectQueryStatusContract, inspectSkillAgentEvalContract, inspectHarnessLearningContract, inspectProjectContextPackContract, inspectAgentSkillTeamRuntime, inspectSkillCapability, inspectCapabilitySource, inspectExternalAgentPackImport, inspectTeamModePolicy, keepWorktreeLifecycle, removeWorktreeLifecycle, listRuns, rebuildLocalRunIndex, inspectLocalRunIndex, queryLocalRunIndex, listToolPluginContracts, listToolCapabilities, listDelegationQueueItems, listWorkerAdapterContracts, listResidentWorkerRuntimes, listWorkflowGates, listAgentRegistry, listSkillCapabilities, listCapabilitySources, ingestArtifactResult, parseSddBranch, readRunState, resolveSddContext, recordLifecycleDecision, parseContextProfile, renderDoctorReport, renderGoalVerifyResult, renderLifecycleDecisionGate, renderSddResultArtifactTemplate, renderSddInstructions, renderSingleTaskLoopResult, renderTaskGapReport, renderTaskInspect, renderTaskList, runGoalVerify, runSingleTaskLoop, runBackgroundExecutor, runWaveExecutor, SDD_VERSION, summarizeAiProjectionStatus, validateSddResultArtifact, validateWorkflowGates, validateAgentRegistry, validateQueryStatusContract, validateSkillAgentEvalContract, validateHarnessLearningContract, validateProjectContextPackContract, routeSddTask, validateAgentSkillTeamRuntime, toArtifactRootRelativePath } from '../../core/src/index.js';
|
|
4
7
|
import { readOption, readPositiveIntegerOption, readRepeatedOption, readRepeatedOptions } from './options.js';
|
|
5
8
|
async function main(args) {
|
|
6
9
|
const projectRoot = process.cwd();
|
|
@@ -17,10 +20,11 @@ async function main(args) {
|
|
|
17
20
|
output: helpText(subcommand)
|
|
18
21
|
};
|
|
19
22
|
}
|
|
20
|
-
if (command === '--version' || command === '-v') {
|
|
23
|
+
if (command === '--version' || command === '-v' || command === 'version') {
|
|
24
|
+
const identity = getCliIdentity();
|
|
21
25
|
return {
|
|
22
26
|
exitCode: 0,
|
|
23
|
-
output:
|
|
27
|
+
output: wantsJson(args) ? jsonOutput(identity, args) : identity.version
|
|
24
28
|
};
|
|
25
29
|
}
|
|
26
30
|
if (command === 'init') {
|
|
@@ -61,12 +65,13 @@ async function main(args) {
|
|
|
61
65
|
if (doctorArgs.includes('--latest-only') && doctorArgs.includes('--all-runs')) {
|
|
62
66
|
return {
|
|
63
67
|
exitCode: 2,
|
|
64
|
-
error: 'Usage: sdd doctor [--latest-only] [--all-runs] (choose only one scope flag)'
|
|
68
|
+
error: 'Usage: sdd doctor [--latest-only] [--all-runs] [--branch <branch>] (choose only one scope flag)'
|
|
65
69
|
};
|
|
66
70
|
}
|
|
67
71
|
const report = await doctor(projectRoot, {
|
|
68
72
|
latestOnly: doctorArgs.includes('--latest-only'),
|
|
69
|
-
allRuns: doctorArgs.includes('--all-runs')
|
|
73
|
+
allRuns: doctorArgs.includes('--all-runs'),
|
|
74
|
+
branch: readBranchOption(doctorArgs)
|
|
70
75
|
});
|
|
71
76
|
const json = wantsJson(doctorArgs);
|
|
72
77
|
return {
|
|
@@ -182,6 +187,46 @@ async function main(args) {
|
|
|
182
187
|
output: JSON.stringify({ runId: state.runId, status: state.status, updatedAt: state.updatedAt }, null, 2)
|
|
183
188
|
};
|
|
184
189
|
}
|
|
190
|
+
if (command === 'evidence' && subcommand === 'summary') {
|
|
191
|
+
const runId = rest.find((item) => !item.startsWith('--'));
|
|
192
|
+
if (!runId) {
|
|
193
|
+
return {
|
|
194
|
+
exitCode: 2,
|
|
195
|
+
error: 'Usage: sdd evidence summary <run_id> [--task <task_id>] [--json|--compact-json]'
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
const summary = await buildEvidenceSummaryProjection(projectRoot, {
|
|
199
|
+
runId,
|
|
200
|
+
taskId: readOption(rest, '--task') ?? undefined
|
|
201
|
+
});
|
|
202
|
+
const json = wantsJson(rest);
|
|
203
|
+
return {
|
|
204
|
+
exitCode: 0,
|
|
205
|
+
output: json ? jsonOutput(summary, rest) : renderEvidenceSummaryProjection(summary)
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
if (command === 'context' && subcommand === 'build') {
|
|
209
|
+
const taskId = readOption(rest, '--task') ?? undefined;
|
|
210
|
+
const mode = readContextBuildMode(rest, '--mode');
|
|
211
|
+
if (!taskId || !mode) {
|
|
212
|
+
return {
|
|
213
|
+
exitCode: 2,
|
|
214
|
+
error: 'Usage: sdd context build --task <task_id> --mode do|verify|sync-back|doctor [--agent <agent>] [--branch <branch>] [--profile brief|normal|forensic] [--json|--compact-json]'
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
const contextPackage = await buildContextBuildPackage(projectRoot, {
|
|
218
|
+
taskId,
|
|
219
|
+
branch: readBranchOption(rest),
|
|
220
|
+
mode,
|
|
221
|
+
agent: readOption(rest, '--agent') ?? undefined,
|
|
222
|
+
profile: parseContextProfile(readOption(rest, '--profile'))
|
|
223
|
+
});
|
|
224
|
+
const json = wantsJson(rest);
|
|
225
|
+
return {
|
|
226
|
+
exitCode: 0,
|
|
227
|
+
output: json ? jsonOutput(contextPackage, rest) : renderContextBuildPackage(contextPackage)
|
|
228
|
+
};
|
|
229
|
+
}
|
|
185
230
|
if (command === 'sync-back' && subcommand === 'inspect') {
|
|
186
231
|
const runId = readOptionalPositionalArgument(rest);
|
|
187
232
|
const taskId = readOption(rest, '--task') ?? undefined;
|
|
@@ -263,13 +308,15 @@ async function main(args) {
|
|
|
263
308
|
if (!taskId) {
|
|
264
309
|
return {
|
|
265
310
|
exitCode: 2,
|
|
266
|
-
error: 'Usage: sdd tasks route <task_id> [--branch <branch>] [--team-mode [auto|force|off]] [--no-team-mode] [--json]'
|
|
311
|
+
error: 'Usage: sdd tasks route <task_id> [--branch <branch>] [--team-mode [auto|force|off]] [--no-team-mode] [--profile] [--cache] [--json]'
|
|
267
312
|
};
|
|
268
313
|
}
|
|
269
314
|
const decision = await routeSddTask(projectRoot, {
|
|
270
315
|
taskId,
|
|
271
316
|
branch: readBranchOption(rest),
|
|
272
|
-
teamModeActivation: readTeamModeActivation(rest)
|
|
317
|
+
teamModeActivation: readTeamModeActivation(rest),
|
|
318
|
+
profile: rest.includes('--profile'),
|
|
319
|
+
cache: rest.includes('--cache'),
|
|
273
320
|
});
|
|
274
321
|
return {
|
|
275
322
|
exitCode: decision.blockedReason ? 1 : 0,
|
|
@@ -955,14 +1002,15 @@ async function main(args) {
|
|
|
955
1002
|
error: 'Usage: sdd artifact template <artifacts/path.md> --task <task_id> --agent <agent> [--run <run_id> --write] [--branch <branch>] [--status <status>]'
|
|
956
1003
|
};
|
|
957
1004
|
}
|
|
1005
|
+
const runId = readOption(rest, '--run');
|
|
958
1006
|
const template = await renderSddResultArtifactTemplate(projectRoot, {
|
|
959
1007
|
artifactPath,
|
|
960
1008
|
taskId,
|
|
961
1009
|
agent,
|
|
962
1010
|
branch: readBranchOption(rest),
|
|
1011
|
+
runId: runId ?? undefined,
|
|
963
1012
|
status: readSddResultStatus(rest, '--status') ?? 'PASS'
|
|
964
1013
|
});
|
|
965
|
-
const runId = readOption(rest, '--run');
|
|
966
1014
|
if (rest.includes('--write')) {
|
|
967
1015
|
if (!runId) {
|
|
968
1016
|
return {
|
|
@@ -1063,6 +1111,8 @@ Evidence helpers:
|
|
|
1063
1111
|
sdd run index rebuild|inspect|query [options] [--json|--compact-json]
|
|
1064
1112
|
sdd artifact template <path> --task <task_id> --agent <agent> [--run <run_id> --write]
|
|
1065
1113
|
sdd artifact validate <run_id> <path> [--task <task_id>] [--agent <agent>] [--json|--compact-json]
|
|
1114
|
+
sdd evidence summary <run_id> [--task <task_id>] [--json|--compact-json]
|
|
1115
|
+
sdd context build --task <task_id> --mode do|verify|sync-back|doctor [--agent <agent>] [--branch <branch>] [--profile brief|normal|forensic] [--json|--compact-json]
|
|
1066
1116
|
|
|
1067
1117
|
Generated AI entries:
|
|
1068
1118
|
sdd update [--check] [--ai <mode>]
|
|
@@ -1136,6 +1186,101 @@ function wantsJson(args) {
|
|
|
1136
1186
|
function jsonOutput(value, args) {
|
|
1137
1187
|
return JSON.stringify(value, null, args.includes('--compact-json') ? 0 : 2);
|
|
1138
1188
|
}
|
|
1189
|
+
function getCliIdentity() {
|
|
1190
|
+
const cliEntryPath = fileURLToPath(import.meta.url);
|
|
1191
|
+
const packageRoot = findPackageRoot(path.dirname(cliEntryPath));
|
|
1192
|
+
const packageJsonPath = packageRoot ? path.join(packageRoot, 'package.json') : null;
|
|
1193
|
+
return {
|
|
1194
|
+
version: readPackageVersion(packageJsonPath) ?? SDD_VERSION,
|
|
1195
|
+
cliEntryPath,
|
|
1196
|
+
packageRoot,
|
|
1197
|
+
packageJsonPath
|
|
1198
|
+
};
|
|
1199
|
+
}
|
|
1200
|
+
function findPackageRoot(startDir) {
|
|
1201
|
+
let current = startDir;
|
|
1202
|
+
while (true) {
|
|
1203
|
+
const packageJsonPath = path.join(current, 'package.json');
|
|
1204
|
+
if (existsSync(packageJsonPath) && isCliPackageRoot(packageJsonPath)) {
|
|
1205
|
+
return current;
|
|
1206
|
+
}
|
|
1207
|
+
const parent = path.dirname(current);
|
|
1208
|
+
if (parent === current) {
|
|
1209
|
+
return null;
|
|
1210
|
+
}
|
|
1211
|
+
current = parent;
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
function isCliPackageRoot(packageJsonPath) {
|
|
1215
|
+
try {
|
|
1216
|
+
const parsed = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
|
1217
|
+
return parsed.name === '@sdd-agent-platform/cli' || parsed.name === 'sdd-agent-platform';
|
|
1218
|
+
}
|
|
1219
|
+
catch {
|
|
1220
|
+
return false;
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
function readPackageVersion(packageJsonPath) {
|
|
1224
|
+
if (!packageJsonPath) {
|
|
1225
|
+
return null;
|
|
1226
|
+
}
|
|
1227
|
+
try {
|
|
1228
|
+
const parsed = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
|
1229
|
+
return typeof parsed.version === 'string' ? parsed.version : null;
|
|
1230
|
+
}
|
|
1231
|
+
catch {
|
|
1232
|
+
return null;
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
function readContextBuildMode(args, name) {
|
|
1236
|
+
const value = readOption(args, name);
|
|
1237
|
+
return value === 'do' || value === 'verify' || value === 'sync-back' || value === 'doctor' ? value : null;
|
|
1238
|
+
}
|
|
1239
|
+
function renderEvidenceSummaryProjection(summary) {
|
|
1240
|
+
const lines = [`Evidence summary ${summary.runId}`];
|
|
1241
|
+
lines.push(`task=${summary.taskId ?? 'none'} authoritative=${summary.authoritative} usable_for_pass=${summary.usableForPass}`);
|
|
1242
|
+
lines.push(`pass=${summary.passCount} blocked=${summary.blockedCount} fail=${summary.failCount} issues=${summary.issueCodes.join(',') || 'none'}`);
|
|
1243
|
+
lines.push('highlights');
|
|
1244
|
+
for (const highlight of summary.highlights.slice(0, 8)) {
|
|
1245
|
+
lines.push(`- ${highlight}`);
|
|
1246
|
+
}
|
|
1247
|
+
lines.push('sources');
|
|
1248
|
+
for (const source of summary.sources.slice(0, 12)) {
|
|
1249
|
+
lines.push(`- ${source.kind}:${source.path} hash=${source.hash.slice(0, 12)}`);
|
|
1250
|
+
}
|
|
1251
|
+
if (summary.sources.length > 12) {
|
|
1252
|
+
lines.push(`- omitted_sources=${summary.sources.length - 12}`);
|
|
1253
|
+
}
|
|
1254
|
+
return lines.join('\n');
|
|
1255
|
+
}
|
|
1256
|
+
function renderContextBuildPackage(contextPackage) {
|
|
1257
|
+
const lines = [`Context package ${contextPackage.taskId}`];
|
|
1258
|
+
lines.push(`mode=${contextPackage.mode} agent=${contextPackage.agent ?? 'none'} profile=${contextPackage.profile} branch=${contextPackage.branch}`);
|
|
1259
|
+
lines.push(`authoritative=${contextPackage.authoritative} usable_for_pass=${contextPackage.usableForPass}`);
|
|
1260
|
+
renderContextRefs(lines, 'must_read', contextPackage.mustRead, 10);
|
|
1261
|
+
renderContextRefs(lines, 'optional_read', contextPackage.optionalRead, 8);
|
|
1262
|
+
renderContextRefs(lines, 'deferred', contextPackage.doNotReadUnlessNeeded, 6);
|
|
1263
|
+
lines.push('next_commands');
|
|
1264
|
+
for (const command of contextPackage.nextCommands) {
|
|
1265
|
+
lines.push(`- ${command}`);
|
|
1266
|
+
}
|
|
1267
|
+
if (contextPackage.warnings.length > 0) {
|
|
1268
|
+
lines.push('warnings');
|
|
1269
|
+
for (const warning of contextPackage.warnings.slice(0, 6)) {
|
|
1270
|
+
lines.push(`- ${warning}`);
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
return lines.join('\n');
|
|
1274
|
+
}
|
|
1275
|
+
function renderContextRefs(lines, label, refs, limit) {
|
|
1276
|
+
lines.push(label);
|
|
1277
|
+
for (const ref of refs.slice(0, limit)) {
|
|
1278
|
+
lines.push(`- ${ref.kind}:${ref.path} hash=${ref.hash.slice(0, 12)}`);
|
|
1279
|
+
}
|
|
1280
|
+
if (refs.length > limit) {
|
|
1281
|
+
lines.push(`- omitted_${label}=${refs.length - limit}`);
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1139
1284
|
function renderTextOrJson(args, value, renderText) {
|
|
1140
1285
|
return wantsJson(args) ? jsonOutput(value, args) : renderText(value);
|
|
1141
1286
|
}
|
|
@@ -1472,8 +1617,21 @@ function renderAgentRouterDecision(decision) {
|
|
|
1472
1617
|
lines.push(`approval=${decision.toolPermission.approvalPolicy}`);
|
|
1473
1618
|
}
|
|
1474
1619
|
lines.push(`model_policy=${decision.modelPolicy.id} category=${decision.modelPolicy.category}`);
|
|
1475
|
-
lines.push(`team_mode=${decision.teamMode.decision} mode=${decision.teamMode.mode} activation=${decision.teamMode.activation} cost=${decision.teamMode.costClass} waves=${decision.teamMode.waveRecommendation.join(',') || 'none'}`);
|
|
1620
|
+
lines.push(`team_mode=${decision.teamMode.decision} mode=${decision.teamMode.mode} activation=${decision.teamMode.activation} cost=${decision.teamMode.costClass} cost_route=${decision.teamMode.costRoute} waves=${decision.teamMode.waveRecommendation.join(',') || 'none'}`);
|
|
1476
1621
|
lines.push(`team_mode_reason=${decision.teamMode.reason}`);
|
|
1622
|
+
if (decision.teamMode.downgradeReason) {
|
|
1623
|
+
lines.push(`team_mode_downgrade=${decision.teamMode.downgradeReason}`);
|
|
1624
|
+
}
|
|
1625
|
+
lines.push(`trust_policy_enforced=${decision.teamMode.trustPolicyEnforced}`);
|
|
1626
|
+
if (decision.cache) {
|
|
1627
|
+
lines.push(`route_cache=${decision.cache.status} key=${decision.cache.key} authoritative=${decision.cache.authoritative}`);
|
|
1628
|
+
}
|
|
1629
|
+
if (decision.profile && decision.profile.length > 0) {
|
|
1630
|
+
lines.push('profile');
|
|
1631
|
+
for (const span of decision.profile) {
|
|
1632
|
+
lines.push(`- ${span.name}: ${span.durationMs}ms`);
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
1477
1635
|
lines.push(`required_artifacts=${decision.requiredArtifacts.join(',') || 'none'}`);
|
|
1478
1636
|
if (decision.blockedReason) {
|
|
1479
1637
|
lines.push(`blocked_reason=${decision.blockedReason}`);
|