@hongmaple0820/scale-engine 0.16.0 → 0.17.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/api/cli.js +280 -2
- package/dist/api/cli.js.map +1 -1
- package/dist/cli/phaseCommands.js +36 -6
- package/dist/cli/phaseCommands.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/tools/ToolOrchestrator.js +53 -0
- package/dist/tools/ToolOrchestrator.js.map +1 -1
- package/dist/workflow/ContextGovernance.d.ts +51 -0
- package/dist/workflow/ContextGovernance.js +233 -0
- package/dist/workflow/ContextGovernance.js.map +1 -0
- package/dist/workflow/DiagnosticLoop.d.ts +40 -0
- package/dist/workflow/DiagnosticLoop.js +105 -0
- package/dist/workflow/DiagnosticLoop.js.map +1 -0
- package/dist/workflow/TaskArtifactScaffolder.d.ts +22 -0
- package/dist/workflow/TaskArtifactScaffolder.js +55 -0
- package/dist/workflow/TaskArtifactScaffolder.js.map +1 -1
- package/dist/workflow/TddLoop.d.ts +47 -0
- package/dist/workflow/TddLoop.js +76 -0
- package/dist/workflow/TddLoop.js.map +1 -0
- package/dist/workflow/WorkflowGuidance.d.ts +26 -0
- package/dist/workflow/WorkflowGuidance.js +173 -0
- package/dist/workflow/WorkflowGuidance.js.map +1 -0
- package/dist/workflow/WorkflowOpenTasks.d.ts +16 -0
- package/dist/workflow/WorkflowOpenTasks.js +37 -0
- package/dist/workflow/WorkflowOpenTasks.js.map +1 -0
- package/dist/workflow/index.d.ts +5 -0
- package/dist/workflow/index.js +5 -0
- package/dist/workflow/index.js.map +1 -1
- package/package.json +2 -2
package/dist/api/cli.js
CHANGED
|
@@ -35,8 +35,12 @@ import { writeGovernanceTemplates } from '../workflow/GovernanceTemplates.js';
|
|
|
35
35
|
import { computeGovernanceDrift } from '../workflow/GovernanceLock.js';
|
|
36
36
|
import { baselineEngineeringStandards, doctorEngineeringStandards, scanEngineeringStandards, settleEngineeringStandards, } from '../workflow/EngineeringStandards.js';
|
|
37
37
|
import { doctorResourceAssets, scanResourceAssets, settleResourceAssets } from '../workflow/ResourceGovernance.js';
|
|
38
|
+
import { analyzeContextGovernance, renderContextGrillPrompt, writeContextGovernanceTemplates, } from '../workflow/ContextGovernance.js';
|
|
39
|
+
import { createDiagnosticLoop, renderDiagnosticLoopMarkdown, validateDiagnosticLoop, } from '../workflow/DiagnosticLoop.js';
|
|
40
|
+
import { createTddSlice, evaluateTddSlice, renderTddSliceMarkdown, } from '../workflow/TddLoop.js';
|
|
41
|
+
import { nextWorkflowOpenTask, removeWorkflowOpenTask, toolEvidenceRunCompletesOpenTask } from '../workflow/WorkflowOpenTasks.js';
|
|
38
42
|
import { TaskMetricsStore } from '../workflow/TaskMetricsStore.js';
|
|
39
|
-
import { checkTaskArtifactCompleteness } from '../workflow/TaskArtifactScaffolder.js';
|
|
43
|
+
import { appendContextGrillArtifact, appendDiagnosticLoopArtifact, appendTddSliceArtifact, checkTaskArtifactCompleteness, } from '../workflow/TaskArtifactScaffolder.js';
|
|
40
44
|
import { WorkflowArtifactWriter } from '../workflow/WorkflowArtifactWriter.js';
|
|
41
45
|
import { inspectToolCapabilities } from '../tools/ToolCapabilityRegistry.js';
|
|
42
46
|
import { evaluateToolEvidenceGate } from '../tools/ToolEvidenceGate.js';
|
|
@@ -69,6 +73,18 @@ function ensureDir(dir) {
|
|
|
69
73
|
function isTruthyFlag(value) {
|
|
70
74
|
return value === true || value === '' || value === 'true' || value === '1';
|
|
71
75
|
}
|
|
76
|
+
function commandEvidence(command, exitCode, summary) {
|
|
77
|
+
if (exitCode === undefined || exitCode === null || exitCode === '')
|
|
78
|
+
return undefined;
|
|
79
|
+
const parsed = Number.parseInt(String(exitCode), 10);
|
|
80
|
+
if (Number.isNaN(parsed))
|
|
81
|
+
return undefined;
|
|
82
|
+
return {
|
|
83
|
+
command,
|
|
84
|
+
exitCode: parsed,
|
|
85
|
+
outputSummary: summary ? String(summary) : `Command exited ${parsed}`,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
72
88
|
function normalizePreflightProfile(value) {
|
|
73
89
|
const normalized = String(value ?? 'quick').trim().toLowerCase();
|
|
74
90
|
if (normalized === 'full' || normalized === 'ci')
|
|
@@ -776,9 +792,239 @@ const contextGlossary = defineCommand({
|
|
|
776
792
|
}
|
|
777
793
|
},
|
|
778
794
|
});
|
|
795
|
+
const contextInit = defineCommand({
|
|
796
|
+
meta: { name: 'init', description: 'Create CONTEXT.md and CONTEXT-MAP.md starter templates' },
|
|
797
|
+
args: {
|
|
798
|
+
dir: { type: 'string', default: PROJECT_DIR, description: 'Project directory' },
|
|
799
|
+
name: { type: 'string', description: 'Project display name' },
|
|
800
|
+
force: { type: 'boolean', default: false, description: 'Overwrite existing templates' },
|
|
801
|
+
json: { type: 'boolean', default: false },
|
|
802
|
+
},
|
|
803
|
+
run({ args }) {
|
|
804
|
+
const result = writeContextGovernanceTemplates({
|
|
805
|
+
projectDir: resolve(String(args.dir ?? PROJECT_DIR)),
|
|
806
|
+
projectName: args.name ? String(args.name) : undefined,
|
|
807
|
+
force: isTruthyFlag(args.force),
|
|
808
|
+
});
|
|
809
|
+
if (args.json) {
|
|
810
|
+
console.log(JSON.stringify(result, null, 2));
|
|
811
|
+
return;
|
|
812
|
+
}
|
|
813
|
+
console.log('\nSCALE Context Templates');
|
|
814
|
+
for (const file of result.created)
|
|
815
|
+
console.log(` [CREATED] ${file}`);
|
|
816
|
+
for (const file of result.skipped)
|
|
817
|
+
console.log(` [SKIPPED] ${file}`);
|
|
818
|
+
},
|
|
819
|
+
});
|
|
820
|
+
const contextGrill = defineCommand({
|
|
821
|
+
meta: { name: 'grill', description: 'Check project context docs and generate request-specific grill questions' },
|
|
822
|
+
args: {
|
|
823
|
+
dir: { type: 'string', default: PROJECT_DIR, description: 'Project directory' },
|
|
824
|
+
'task-id': { type: 'string', description: 'Task id for workflow state and artifact linkage' },
|
|
825
|
+
task: { type: 'string', required: true, description: 'Task or requirement description' },
|
|
826
|
+
files: { type: 'string', description: 'Comma-separated changed or target files' },
|
|
827
|
+
'artifact-dir': { type: 'string', description: 'Task artifact directory where explore.md should be updated' },
|
|
828
|
+
write: { type: 'boolean', default: false, description: 'Append context grill output to the task explore artifact' },
|
|
829
|
+
json: { type: 'boolean', default: false },
|
|
830
|
+
},
|
|
831
|
+
run({ args }) {
|
|
832
|
+
const projectDir = resolve(String(args.dir ?? PROJECT_DIR));
|
|
833
|
+
const taskId = String(args['task-id'] ?? `context-${Date.now()}`);
|
|
834
|
+
const changedFiles = parseCommaList(args.files);
|
|
835
|
+
const report = analyzeContextGovernance({
|
|
836
|
+
projectDir,
|
|
837
|
+
request: String(args.task ?? ''),
|
|
838
|
+
changedFiles,
|
|
839
|
+
});
|
|
840
|
+
const artifactPath = isTruthyFlag(args.write)
|
|
841
|
+
? appendContextGrillArtifact({
|
|
842
|
+
projectDir,
|
|
843
|
+
artifactsDir: args['artifact-dir'] ? String(args['artifact-dir']) : undefined,
|
|
844
|
+
report,
|
|
845
|
+
}) ?? undefined
|
|
846
|
+
: undefined;
|
|
847
|
+
if (args['task-id'] || artifactPath) {
|
|
848
|
+
const writer = new WorkflowArtifactWriter(SCALE_DIR);
|
|
849
|
+
const current = writer.readCurrentState();
|
|
850
|
+
const currentOpenTasks = current?.taskId === taskId ? current.openTasks : [];
|
|
851
|
+
writer.updateCurrentState({
|
|
852
|
+
taskId,
|
|
853
|
+
phase: 'explore',
|
|
854
|
+
artifactsDir: args['artifact-dir'] ? String(args['artifact-dir']).replace(/\\/g, '/') : undefined,
|
|
855
|
+
exploredFiles: changedFiles,
|
|
856
|
+
fileCount: changedFiles.length,
|
|
857
|
+
mainContradiction: report.findings[0]?.message ?? 'context governance ready',
|
|
858
|
+
openTasks: removeWorkflowOpenTask(currentOpenTasks, 'context-grill'),
|
|
859
|
+
});
|
|
860
|
+
}
|
|
861
|
+
if (args.json) {
|
|
862
|
+
console.log(JSON.stringify({ ...report, artifactPath }, null, 2));
|
|
863
|
+
return;
|
|
864
|
+
}
|
|
865
|
+
console.log(renderContextGrillPrompt(report));
|
|
866
|
+
if (artifactPath)
|
|
867
|
+
console.log(`\nArtifact: ${artifactPath}`);
|
|
868
|
+
},
|
|
869
|
+
});
|
|
779
870
|
const context = defineCommand({
|
|
780
871
|
meta: { name: 'context', description: 'Context assembly' },
|
|
781
|
-
subCommands: { build: contextBuild, status: contextStatus, inject: contextInject, glossary: contextGlossary },
|
|
872
|
+
subCommands: { build: contextBuild, status: contextStatus, inject: contextInject, glossary: contextGlossary, init: contextInit, grill: contextGrill },
|
|
873
|
+
});
|
|
874
|
+
// ============================================================================
|
|
875
|
+
// diagnose command - evidence-first debugging loop
|
|
876
|
+
// ============================================================================
|
|
877
|
+
const diagnosePlanCommand = defineCommand({
|
|
878
|
+
meta: { name: 'plan', description: 'Create a reproducible diagnostic loop before fixing a bug' },
|
|
879
|
+
args: {
|
|
880
|
+
'task-id': { type: 'string', required: true },
|
|
881
|
+
symptom: { type: 'string', required: true },
|
|
882
|
+
repro: { type: 'string', description: 'Command that reproduces the current failure' },
|
|
883
|
+
'expected-failure': { type: 'string', description: 'Expected failing behavior or assertion' },
|
|
884
|
+
files: { type: 'string', description: 'Comma-separated changed or suspicious files' },
|
|
885
|
+
verify: { type: 'string', description: 'Comma-separated verification commands after the fix' },
|
|
886
|
+
'artifact-dir': { type: 'string', description: 'Task artifact directory where plan.md should be updated' },
|
|
887
|
+
write: { type: 'boolean', default: false, description: 'Append diagnostic loop output to the task plan artifact' },
|
|
888
|
+
json: { type: 'boolean', default: false },
|
|
889
|
+
},
|
|
890
|
+
run({ args }) {
|
|
891
|
+
const changedFiles = parseCommaList(args.files);
|
|
892
|
+
const loop = createDiagnosticLoop({
|
|
893
|
+
taskId: String(args['task-id']),
|
|
894
|
+
symptom: String(args.symptom),
|
|
895
|
+
reproductionCommand: args.repro ? String(args.repro) : undefined,
|
|
896
|
+
expectedFailure: args['expected-failure'] ? String(args['expected-failure']) : undefined,
|
|
897
|
+
changedFiles,
|
|
898
|
+
verificationCommands: parseCommaList(args.verify),
|
|
899
|
+
});
|
|
900
|
+
const validation = validateDiagnosticLoop(loop);
|
|
901
|
+
const artifactPath = isTruthyFlag(args.write)
|
|
902
|
+
? appendDiagnosticLoopArtifact({
|
|
903
|
+
projectDir: PROJECT_DIR,
|
|
904
|
+
artifactsDir: args['artifact-dir'] ? String(args['artifact-dir']) : undefined,
|
|
905
|
+
loop,
|
|
906
|
+
validation,
|
|
907
|
+
}) ?? undefined
|
|
908
|
+
: undefined;
|
|
909
|
+
if (artifactPath || args['artifact-dir']) {
|
|
910
|
+
const writer = new WorkflowArtifactWriter(SCALE_DIR);
|
|
911
|
+
const current = writer.readCurrentState();
|
|
912
|
+
const currentOpenTasks = current?.taskId === loop.taskId ? current.openTasks : [];
|
|
913
|
+
writer.updateCurrentState({
|
|
914
|
+
taskId: loop.taskId,
|
|
915
|
+
phase: 'plan',
|
|
916
|
+
artifactsDir: args['artifact-dir'] ? String(args['artifact-dir']).replace(/\\/g, '/') : undefined,
|
|
917
|
+
filesModified: changedFiles,
|
|
918
|
+
openTasks: validation.ready
|
|
919
|
+
? removeWorkflowOpenTask(currentOpenTasks.filter(task => task.trim().startsWith('scale ')), 'diagnostic-loop')
|
|
920
|
+
: uniqueStrings([
|
|
921
|
+
...currentOpenTasks,
|
|
922
|
+
...validation.blockers,
|
|
923
|
+
]),
|
|
924
|
+
});
|
|
925
|
+
}
|
|
926
|
+
if (args.json) {
|
|
927
|
+
console.log(JSON.stringify({ loop, validation, artifactPath }, null, 2));
|
|
928
|
+
return;
|
|
929
|
+
}
|
|
930
|
+
console.log(renderDiagnosticLoopMarkdown(loop));
|
|
931
|
+
if (!validation.ready) {
|
|
932
|
+
console.log('\nBlockers:');
|
|
933
|
+
for (const blocker of validation.blockers)
|
|
934
|
+
console.log(` - ${blocker}`);
|
|
935
|
+
}
|
|
936
|
+
if (artifactPath)
|
|
937
|
+
console.log(`\nArtifact: ${artifactPath}`);
|
|
938
|
+
},
|
|
939
|
+
});
|
|
940
|
+
const diagnose = defineCommand({
|
|
941
|
+
meta: { name: 'diagnose', description: 'Evidence-first debugging workflows' },
|
|
942
|
+
subCommands: { plan: diagnosePlanCommand },
|
|
943
|
+
});
|
|
944
|
+
// ============================================================================
|
|
945
|
+
// tdd command - vertical slice RED/GREEN/REFACTOR loop
|
|
946
|
+
// ============================================================================
|
|
947
|
+
const tddSliceCommand = defineCommand({
|
|
948
|
+
meta: { name: 'slice', description: 'Create and evaluate a TDD vertical slice' },
|
|
949
|
+
args: {
|
|
950
|
+
'task-id': { type: 'string', required: true },
|
|
951
|
+
behavior: { type: 'string', required: true },
|
|
952
|
+
'public-interface': { type: 'string', required: true },
|
|
953
|
+
'failing-test': { type: 'string', required: true },
|
|
954
|
+
'test-file': { type: 'string', required: true },
|
|
955
|
+
'impl-files': { type: 'string', required: true },
|
|
956
|
+
'red-exit-code': { type: 'string', description: 'Exit code from the RED command' },
|
|
957
|
+
'red-summary': { type: 'string', description: 'Short RED output summary' },
|
|
958
|
+
'green-exit-code': { type: 'string', description: 'Exit code from the GREEN command' },
|
|
959
|
+
'green-summary': { type: 'string', description: 'Short GREEN output summary' },
|
|
960
|
+
'refactor-exit-code': { type: 'string', description: 'Exit code from the REFACTOR command' },
|
|
961
|
+
'refactor-summary': { type: 'string', description: 'Short REFACTOR output summary' },
|
|
962
|
+
'artifact-dir': { type: 'string', description: 'Task artifact directory where verification.md should be updated' },
|
|
963
|
+
write: { type: 'boolean', default: false, description: 'Append TDD slice output to the task verification artifact' },
|
|
964
|
+
json: { type: 'boolean', default: false },
|
|
965
|
+
},
|
|
966
|
+
run({ args }) {
|
|
967
|
+
const failingTest = String(args['failing-test']);
|
|
968
|
+
const slice = createTddSlice({
|
|
969
|
+
taskId: String(args['task-id']),
|
|
970
|
+
behavior: String(args.behavior),
|
|
971
|
+
publicInterface: String(args['public-interface']),
|
|
972
|
+
failingTestCommand: failingTest,
|
|
973
|
+
testFile: String(args['test-file']),
|
|
974
|
+
implementationFiles: parseCommaList(args['impl-files']),
|
|
975
|
+
redEvidence: commandEvidence(failingTest, args['red-exit-code'], args['red-summary']),
|
|
976
|
+
greenEvidence: commandEvidence(failingTest, args['green-exit-code'], args['green-summary']),
|
|
977
|
+
refactorEvidence: commandEvidence(failingTest, args['refactor-exit-code'], args['refactor-summary']),
|
|
978
|
+
});
|
|
979
|
+
const evaluation = evaluateTddSlice(slice);
|
|
980
|
+
const artifactPath = isTruthyFlag(args.write)
|
|
981
|
+
? appendTddSliceArtifact({
|
|
982
|
+
projectDir: PROJECT_DIR,
|
|
983
|
+
artifactsDir: args['artifact-dir'] ? String(args['artifact-dir']) : undefined,
|
|
984
|
+
slice,
|
|
985
|
+
}) ?? undefined
|
|
986
|
+
: undefined;
|
|
987
|
+
let tddStatePath;
|
|
988
|
+
if (slice.redEvidence && slice.greenEvidence && slice.refactorEvidence) {
|
|
989
|
+
const writer = new WorkflowArtifactWriter(SCALE_DIR);
|
|
990
|
+
writer.writeTDDEvidence({
|
|
991
|
+
timestamp: new Date().toISOString(),
|
|
992
|
+
taskId: slice.taskId,
|
|
993
|
+
red: slice.redEvidence.exitCode !== 0,
|
|
994
|
+
green: slice.greenEvidence.exitCode === 0,
|
|
995
|
+
refactor: slice.refactorEvidence.exitCode === 0,
|
|
996
|
+
testFirst: slice.redEvidence.exitCode !== 0,
|
|
997
|
+
testFile: slice.testFile,
|
|
998
|
+
implFile: slice.implementationFiles[0] ?? '',
|
|
999
|
+
});
|
|
1000
|
+
writer.updateCurrentState({
|
|
1001
|
+
taskId: slice.taskId,
|
|
1002
|
+
phase: 'verify',
|
|
1003
|
+
artifactsDir: args['artifact-dir'] ? String(args['artifact-dir']).replace(/\\/g, '/') : undefined,
|
|
1004
|
+
filesModified: slice.implementationFiles,
|
|
1005
|
+
openTasks: removeWorkflowOpenTask(writer.readCurrentState()?.openTasks, 'tdd-slice'),
|
|
1006
|
+
});
|
|
1007
|
+
tddStatePath = join(writer.getStateDir(), `tdd-${slice.taskId}.json`);
|
|
1008
|
+
}
|
|
1009
|
+
if (args.json) {
|
|
1010
|
+
console.log(JSON.stringify({ slice, evaluation, artifactPath, tddStatePath }, null, 2));
|
|
1011
|
+
return;
|
|
1012
|
+
}
|
|
1013
|
+
console.log(renderTddSliceMarkdown(slice));
|
|
1014
|
+
if (evaluation.blockers.length > 0) {
|
|
1015
|
+
console.log('\nBlockers:');
|
|
1016
|
+
for (const blocker of evaluation.blockers)
|
|
1017
|
+
console.log(` - ${blocker}`);
|
|
1018
|
+
}
|
|
1019
|
+
if (artifactPath)
|
|
1020
|
+
console.log(`\nArtifact: ${artifactPath}`);
|
|
1021
|
+
if (tddStatePath)
|
|
1022
|
+
console.log(`TDD state: ${tddStatePath}`);
|
|
1023
|
+
},
|
|
1024
|
+
});
|
|
1025
|
+
const tdd = defineCommand({
|
|
1026
|
+
meta: { name: 'tdd', description: 'TDD vertical slice workflows' },
|
|
1027
|
+
subCommands: { slice: tddSliceCommand },
|
|
782
1028
|
});
|
|
783
1029
|
// ============================================================================
|
|
784
1030
|
// stats
|
|
@@ -1224,6 +1470,9 @@ const status = defineCommand({
|
|
|
1224
1470
|
const latestReviews = reviewStore.listReviews(5);
|
|
1225
1471
|
const latestTask = tasks[0];
|
|
1226
1472
|
const taskPayload = latestTask?.payload;
|
|
1473
|
+
const workflowState = new WorkflowArtifactWriter(SCALE_DIR).readCurrentState();
|
|
1474
|
+
const currentOpenTasks = workflowState?.taskId === latestTask?.id ? workflowState.openTasks ?? [] : [];
|
|
1475
|
+
const nextOpenTask = nextWorkflowOpenTask(currentOpenTasks);
|
|
1227
1476
|
const blockers = [];
|
|
1228
1477
|
const latestBlockingEvidence = latestEvidence.find(record => !record.passed);
|
|
1229
1478
|
const latestBlockingReview = latestReviews.find(record => !record.passed);
|
|
@@ -1244,6 +1493,10 @@ const status = defineCommand({
|
|
|
1244
1493
|
return `scale plan ${specs[0].id}`;
|
|
1245
1494
|
if (!latestTask)
|
|
1246
1495
|
return `scale build ${plans[0].id}`;
|
|
1496
|
+
if (nextOpenTask?.kind === 'command')
|
|
1497
|
+
return nextOpenTask.value;
|
|
1498
|
+
if (nextOpenTask?.kind === 'blocker')
|
|
1499
|
+
return `Resolve workflow blocker: ${nextOpenTask.value}`;
|
|
1247
1500
|
if (!taskPayload?.verificationEvidenceIds?.length)
|
|
1248
1501
|
return `scale verify ${latestTask.id}`;
|
|
1249
1502
|
if (latestTask.status !== 'COMPLETED')
|
|
@@ -1285,6 +1538,14 @@ const status = defineCommand({
|
|
|
1285
1538
|
summary: record.summary,
|
|
1286
1539
|
createdAt: record.createdAt,
|
|
1287
1540
|
})),
|
|
1541
|
+
workflowState: workflowState ? {
|
|
1542
|
+
taskId: workflowState.taskId,
|
|
1543
|
+
level: workflowState.level,
|
|
1544
|
+
phase: workflowState.phase,
|
|
1545
|
+
artifactsDir: workflowState.artifactsDir,
|
|
1546
|
+
openTasks: workflowState.openTasks,
|
|
1547
|
+
skillIntents: workflowState.skillIntents,
|
|
1548
|
+
} : null,
|
|
1288
1549
|
blockers,
|
|
1289
1550
|
nextCommand,
|
|
1290
1551
|
};
|
|
@@ -1314,6 +1575,11 @@ const status = defineCommand({
|
|
|
1314
1575
|
for (const blocker of blockers)
|
|
1315
1576
|
console.log(` - ${blocker}`);
|
|
1316
1577
|
}
|
|
1578
|
+
if (result.workflowState?.openTasks.length) {
|
|
1579
|
+
console.log('\nOpen Tasks:');
|
|
1580
|
+
for (const task of result.workflowState.openTasks)
|
|
1581
|
+
console.log(` - ${task}`);
|
|
1582
|
+
}
|
|
1317
1583
|
console.log(`\nNext: ${nextCommand}`);
|
|
1318
1584
|
},
|
|
1319
1585
|
});
|
|
@@ -2480,6 +2746,16 @@ const toolRunCommand = defineCommand({
|
|
|
2480
2746
|
const report = await result.orchestrator.run(result.plan, {
|
|
2481
2747
|
dryRun: isTruthyFlag(args['dry-run']),
|
|
2482
2748
|
});
|
|
2749
|
+
if (toolEvidenceRunCompletesOpenTask(report)) {
|
|
2750
|
+
const writer = new WorkflowArtifactWriter(SCALE_DIR);
|
|
2751
|
+
const current = writer.readCurrentState();
|
|
2752
|
+
if (current?.taskId === report.taskId) {
|
|
2753
|
+
writer.updateCurrentState({
|
|
2754
|
+
taskId: report.taskId,
|
|
2755
|
+
openTasks: removeWorkflowOpenTask(current.openTasks, 'tool-evidence'),
|
|
2756
|
+
});
|
|
2757
|
+
}
|
|
2758
|
+
}
|
|
2483
2759
|
if (args.json) {
|
|
2484
2760
|
console.log(JSON.stringify(report, null, 2));
|
|
2485
2761
|
}
|
|
@@ -2737,6 +3013,8 @@ const main = defineCommand({
|
|
|
2737
3013
|
status,
|
|
2738
3014
|
workflow,
|
|
2739
3015
|
evidence,
|
|
3016
|
+
diagnose,
|
|
3017
|
+
tdd,
|
|
2740
3018
|
tool,
|
|
2741
3019
|
skill,
|
|
2742
3020
|
skills: skill,
|