@hongmaple0820/scale-engine 0.14.0 → 0.15.1
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/README.en.md +13 -5
- package/README.md +13 -5
- package/dist/adapters/AiderAdapter.js +52 -52
- package/dist/adapters/ClaudeCodeAdapter.js +5 -5
- package/dist/adapters/DeepSeekTuiAdapter.js +5 -5
- package/dist/adapters/DoubaoAdapter.js +33 -33
- package/dist/adapters/KimiAdapter.js +32 -32
- package/dist/adapters/KiroAdapter.js +26 -26
- package/dist/adapters/WindsurfAdapter.js +32 -32
- package/dist/api/cli.js +296 -3
- package/dist/api/cli.js.map +1 -1
- package/dist/api/doctor.d.ts +2 -0
- package/dist/api/doctor.js +83 -0
- package/dist/api/doctor.js.map +1 -1
- package/dist/api/mcp.js +2 -1
- package/dist/api/mcp.js.map +1 -1
- package/dist/capabilities/InstalledSkillsIntegration.d.ts +3 -0
- package/dist/capabilities/InstalledSkillsIntegration.js +41 -17
- package/dist/capabilities/InstalledSkillsIntegration.js.map +1 -1
- package/dist/cli/phaseCommands.js +63 -5
- package/dist/cli/phaseCommands.js.map +1 -1
- package/dist/core/logger.d.ts +2 -0
- package/dist/core/logger.js +33 -1
- package/dist/core/logger.js.map +1 -1
- package/dist/output/HTMLDocumentRenderer.js +3 -2
- package/dist/output/HTMLDocumentRenderer.js.map +1 -1
- package/dist/skills/ExternalSkills.js +9 -4
- package/dist/skills/ExternalSkills.js.map +1 -1
- package/dist/skills/SkillDiscovery.js +5 -3
- package/dist/skills/SkillDiscovery.js.map +1 -1
- package/dist/skills/SkillDoctor.js +178 -1
- package/dist/skills/SkillDoctor.js.map +1 -1
- package/dist/skills/SkillInstaller.js +5 -0
- package/dist/skills/SkillInstaller.js.map +1 -1
- package/dist/skills/routing/SkillPlanner.js +40 -40
- package/dist/skills/routing/SkillPolicy.js +168 -5
- package/dist/skills/routing/SkillPolicy.js.map +1 -1
- package/dist/version.d.ts +3 -0
- package/dist/version.js +15 -0
- package/dist/version.js.map +1 -0
- package/dist/workflow/EngineeringStandards.d.ts +143 -0
- package/dist/workflow/EngineeringStandards.js +679 -0
- package/dist/workflow/EngineeringStandards.js.map +1 -0
- package/dist/workflow/GovernanceTemplatePacks.d.ts +1 -1
- package/dist/workflow/GovernanceTemplatePacks.js +136 -10
- package/dist/workflow/GovernanceTemplatePacks.js.map +1 -1
- package/dist/workflow/GovernanceTemplates.d.ts +1 -1
- package/dist/workflow/GovernanceTemplates.js +606 -429
- package/dist/workflow/GovernanceTemplates.js.map +1 -1
- package/dist/workflow/ResourceGovernance.d.ts +120 -0
- package/dist/workflow/ResourceGovernance.js +512 -0
- package/dist/workflow/ResourceGovernance.js.map +1 -0
- package/dist/workflow/TaskArtifactScaffolder.js +13 -10
- package/dist/workflow/TaskArtifactScaffolder.js.map +1 -1
- package/dist/workflow/VerificationProfile.d.ts +2 -0
- package/dist/workflow/VerificationProfile.js +7 -0
- package/dist/workflow/VerificationProfile.js.map +1 -1
- package/dist/workflow/WorkspaceLifecycle.d.ts +2 -0
- package/dist/workflow/WorkspaceLifecycle.js +34 -8
- package/dist/workflow/WorkspaceLifecycle.js.map +1 -1
- package/dist/workflow/WorkspaceTopology.d.ts +49 -0
- package/dist/workflow/WorkspaceTopology.js +125 -0
- package/dist/workflow/WorkspaceTopology.js.map +1 -0
- package/dist/workflow/index.d.ts +3 -0
- package/dist/workflow/index.js +3 -0
- package/dist/workflow/index.js.map +1 -1
- package/package.json +2 -2
package/dist/api/cli.js
CHANGED
|
@@ -31,12 +31,16 @@ import { WorkflowEngine } from '../workflow/WorkflowEngine.js';
|
|
|
31
31
|
import { resolveVerificationTargets } from '../workflow/VerificationProfile.js';
|
|
32
32
|
import { writeGovernanceTemplates } from '../workflow/GovernanceTemplates.js';
|
|
33
33
|
import { computeGovernanceDrift } from '../workflow/GovernanceLock.js';
|
|
34
|
+
import { doctorEngineeringStandards, scanEngineeringStandards, settleEngineeringStandards, } from '../workflow/EngineeringStandards.js';
|
|
35
|
+
import { doctorResourceAssets, scanResourceAssets, settleResourceAssets } from '../workflow/ResourceGovernance.js';
|
|
34
36
|
import { TaskMetricsStore } from '../workflow/TaskMetricsStore.js';
|
|
35
37
|
import { checkTaskArtifactCompleteness } from '../workflow/TaskArtifactScaffolder.js';
|
|
36
38
|
import { WorkflowArtifactWriter } from '../workflow/WorkflowArtifactWriter.js';
|
|
37
39
|
import { cleanupWorkspaceLifecycle, inspectWorkspaceLifecycle, } from '../workflow/WorkspaceLifecycle.js';
|
|
40
|
+
import { resolveWorkspaceTopology, workspaceTopologyPath, workspaceTopologyTemplate, } from '../workflow/WorkspaceTopology.js';
|
|
38
41
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
39
42
|
import { join, resolve } from 'node:path';
|
|
43
|
+
import { SCALE_ENGINE_VERSION } from '../version.js';
|
|
40
44
|
// ============================================================================
|
|
41
45
|
// Engine bootstrap (单例 + lazy init)
|
|
42
46
|
// ============================================================================
|
|
@@ -68,6 +72,42 @@ function gatesForPreflightProfile(profile) {
|
|
|
68
72
|
return ['G3', 'G0', 'G4', 'G5'];
|
|
69
73
|
return ['G3', 'G0', 'G4', 'G5', 'G6', 'G7'];
|
|
70
74
|
}
|
|
75
|
+
function evaluateEngineeringStandardsGate(options) {
|
|
76
|
+
const mode = normalizeEngineeringStandardsGateMode(options.policy.engineeringStandardsGate);
|
|
77
|
+
if (mode === 'off') {
|
|
78
|
+
return {
|
|
79
|
+
mode,
|
|
80
|
+
checked: false,
|
|
81
|
+
blocked: false,
|
|
82
|
+
ok: true,
|
|
83
|
+
findings: [],
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
const settlement = options.settle && options.artifactsDir
|
|
87
|
+
? settleEngineeringStandards({
|
|
88
|
+
projectDir: PROJECT_DIR,
|
|
89
|
+
scaleDir: SCALE_DIR,
|
|
90
|
+
taskId: options.taskId,
|
|
91
|
+
artifactsDir: options.artifactsDir,
|
|
92
|
+
})
|
|
93
|
+
: undefined;
|
|
94
|
+
const doctor = settlement?.doctor ?? doctorEngineeringStandards({
|
|
95
|
+
projectDir: PROJECT_DIR,
|
|
96
|
+
scaleDir: SCALE_DIR,
|
|
97
|
+
});
|
|
98
|
+
return {
|
|
99
|
+
mode,
|
|
100
|
+
checked: true,
|
|
101
|
+
blocked: mode === 'block' && !doctor.ok,
|
|
102
|
+
ok: doctor.ok,
|
|
103
|
+
findings: doctor.findings,
|
|
104
|
+
summary: doctor.scan.summary,
|
|
105
|
+
standardsImpactPath: settlement?.standardsImpactPath,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
function normalizeEngineeringStandardsGateMode(value) {
|
|
109
|
+
return value === 'off' || value === 'block' ? value : 'warn';
|
|
110
|
+
}
|
|
71
111
|
let _engine = null;
|
|
72
112
|
function getEngine() {
|
|
73
113
|
if (!_engine)
|
|
@@ -826,6 +866,7 @@ const taskArtifacts = defineCommand({
|
|
|
826
866
|
});
|
|
827
867
|
function printWorkspaceLifecycle(report) {
|
|
828
868
|
console.log('\nSCALE Workspace Lifecycle');
|
|
869
|
+
console.log(` Topology: ${report.topology.topology}${report.topology.configured ? '' : ' (default)'}`);
|
|
829
870
|
console.log(` Root: ${report.root.path}`);
|
|
830
871
|
console.log(` Branch: ${report.root.branch ?? '(detached)'}`);
|
|
831
872
|
console.log(` Linked worktree: ${report.root.isLinkedWorktree ? 'yes' : 'no'}`);
|
|
@@ -852,6 +893,19 @@ function printWorkspaceLifecycle(report) {
|
|
|
852
893
|
for (const action of report.finish.nextActions)
|
|
853
894
|
console.log(` [NEXT] ${action}`);
|
|
854
895
|
}
|
|
896
|
+
function printWorkspaceTopology(topology, written) {
|
|
897
|
+
console.log('\nSCALE Workspace Topology');
|
|
898
|
+
console.log(` Topology: ${topology.topology}${topology.configured ? '' : ' (default)'}`);
|
|
899
|
+
console.log(` Config: ${topology.configPath}`);
|
|
900
|
+
if (written)
|
|
901
|
+
console.log(` Written: ${written}`);
|
|
902
|
+
console.log('\n Repositories:');
|
|
903
|
+
for (const repo of topology.repositories) {
|
|
904
|
+
console.log(` - ${repo.name}: ${repo.path} (${repo.role}) required=${repo.required !== false ? 'yes' : 'no'}`);
|
|
905
|
+
}
|
|
906
|
+
for (const warning of topology.warnings)
|
|
907
|
+
console.log(` [WARN] ${warning}`);
|
|
908
|
+
}
|
|
855
909
|
function printWorkspaceCleanup(result) {
|
|
856
910
|
printWorkspaceLifecycle(result.report);
|
|
857
911
|
console.log('\n Cleanup plan:');
|
|
@@ -885,6 +939,35 @@ const workspaceStatus = defineCommand({
|
|
|
885
939
|
process.exitCode = 1;
|
|
886
940
|
},
|
|
887
941
|
});
|
|
942
|
+
const workspaceMap = defineCommand({
|
|
943
|
+
meta: { name: 'map', description: 'Resolve or write explicit workspace topology for single, monorepo, polyrepo, submodule, or MOE projects' },
|
|
944
|
+
args: {
|
|
945
|
+
dir: { type: 'string', description: 'Project directory; defaults to current project directory' },
|
|
946
|
+
topology: { type: 'string', default: 'moe', description: 'Starter topology for --write (single/monorepo/polyrepo/submodule-workspace/moe)' },
|
|
947
|
+
write: { type: 'boolean', default: false, description: 'Create .scale/workspace.json when it does not exist' },
|
|
948
|
+
json: { type: 'boolean', default: false },
|
|
949
|
+
},
|
|
950
|
+
run({ args }) {
|
|
951
|
+
const projectDir = resolve(args.dir ?? PROJECT_DIR);
|
|
952
|
+
const target = workspaceTopologyPath(projectDir);
|
|
953
|
+
let written = null;
|
|
954
|
+
if (isTruthyFlag(args.write) && !existsSync(target)) {
|
|
955
|
+
ensureDir(join(projectDir, '.scale'));
|
|
956
|
+
writeFileSync(target, workspaceTopologyTemplate({
|
|
957
|
+
topology: normalizeWorkspaceTopologyKind(args.topology),
|
|
958
|
+
}), 'utf-8');
|
|
959
|
+
written = target;
|
|
960
|
+
}
|
|
961
|
+
const topology = resolveWorkspaceTopology({ projectDir });
|
|
962
|
+
const result = { ...topology, written };
|
|
963
|
+
if (args.json) {
|
|
964
|
+
console.log(JSON.stringify(result, null, 2));
|
|
965
|
+
}
|
|
966
|
+
else {
|
|
967
|
+
printWorkspaceTopology(topology, written);
|
|
968
|
+
}
|
|
969
|
+
},
|
|
970
|
+
});
|
|
888
971
|
const workspaceFinish = defineCommand({
|
|
889
972
|
meta: { name: 'finish', description: 'Check whether a temporary worktree can be safely finished or cleaned up' },
|
|
890
973
|
args: {
|
|
@@ -896,6 +979,7 @@ const workspaceFinish = defineCommand({
|
|
|
896
979
|
const result = {
|
|
897
980
|
root: report.root,
|
|
898
981
|
childRepositories: report.childRepositories,
|
|
982
|
+
topology: report.topology,
|
|
899
983
|
finish: report.finish,
|
|
900
984
|
};
|
|
901
985
|
if (args.json) {
|
|
@@ -936,11 +1020,23 @@ const workspaceCleanup = defineCommand({
|
|
|
936
1020
|
const workspace = defineCommand({
|
|
937
1021
|
meta: { name: 'workspace', description: 'Inspect worktree, branch, and child repository lifecycle safety' },
|
|
938
1022
|
subCommands: {
|
|
1023
|
+
map: workspaceMap,
|
|
939
1024
|
status: workspaceStatus,
|
|
940
1025
|
finish: workspaceFinish,
|
|
941
1026
|
cleanup: workspaceCleanup,
|
|
942
1027
|
},
|
|
943
1028
|
});
|
|
1029
|
+
function normalizeWorkspaceTopologyKind(value) {
|
|
1030
|
+
const normalized = String(value ?? 'moe').trim();
|
|
1031
|
+
if (normalized === 'single'
|
|
1032
|
+
|| normalized === 'monorepo'
|
|
1033
|
+
|| normalized === 'polyrepo'
|
|
1034
|
+
|| normalized === 'submodule-workspace'
|
|
1035
|
+
|| normalized === 'moe') {
|
|
1036
|
+
return normalized;
|
|
1037
|
+
}
|
|
1038
|
+
return 'moe';
|
|
1039
|
+
}
|
|
944
1040
|
const preflight = defineCommand({
|
|
945
1041
|
meta: { name: 'preflight', description: 'Run service-aware verification without a task artifact' },
|
|
946
1042
|
args: {
|
|
@@ -965,6 +1061,9 @@ const preflight = defineCommand({
|
|
|
965
1061
|
profile: args.profile,
|
|
966
1062
|
service: args.service,
|
|
967
1063
|
});
|
|
1064
|
+
const engineeringStandards = evaluateEngineeringStandardsGate({
|
|
1065
|
+
policy: resolved.policy,
|
|
1066
|
+
});
|
|
968
1067
|
const targetResults = [];
|
|
969
1068
|
if (!args.json) {
|
|
970
1069
|
console.log('\nSCALE Preflight');
|
|
@@ -973,6 +1072,13 @@ const preflight = defineCommand({
|
|
|
973
1072
|
console.log(` Profile: ${resolved.profileName}`);
|
|
974
1073
|
console.log(` Preflight profile: ${preflightProfile}`);
|
|
975
1074
|
console.log(` Gates: ${gateStages.join(', ')}`);
|
|
1075
|
+
if (engineeringStandards.checked) {
|
|
1076
|
+
const status = engineeringStandards.blocked ? 'BLOCKED' : engineeringStandards.ok ? 'OK' : 'WARN';
|
|
1077
|
+
console.log(` Engineering standards: ${status} (${engineeringStandards.mode})`);
|
|
1078
|
+
}
|
|
1079
|
+
else {
|
|
1080
|
+
console.log(' Engineering standards: skipped');
|
|
1081
|
+
}
|
|
976
1082
|
}
|
|
977
1083
|
for (const target of resolved.targets) {
|
|
978
1084
|
if (!args.json) {
|
|
@@ -1004,7 +1110,9 @@ const preflight = defineCommand({
|
|
|
1004
1110
|
}
|
|
1005
1111
|
}
|
|
1006
1112
|
}
|
|
1007
|
-
const passed = targetResults.length > 0 &&
|
|
1113
|
+
const passed = targetResults.length > 0 &&
|
|
1114
|
+
targetResults.every(target => target.passed) &&
|
|
1115
|
+
!engineeringStandards.blocked;
|
|
1008
1116
|
const result = {
|
|
1009
1117
|
phase: 'PREFLIGHT',
|
|
1010
1118
|
profile: resolved.profileName,
|
|
@@ -1012,6 +1120,7 @@ const preflight = defineCommand({
|
|
|
1012
1120
|
gates: gateStages,
|
|
1013
1121
|
services: targetResults.map(target => target.service).filter(Boolean),
|
|
1014
1122
|
policy: resolved.policy,
|
|
1123
|
+
engineeringStandards,
|
|
1015
1124
|
targets: targetResults,
|
|
1016
1125
|
passed,
|
|
1017
1126
|
};
|
|
@@ -1150,7 +1259,7 @@ const init = defineCommand({
|
|
|
1150
1259
|
'governance-pack': {
|
|
1151
1260
|
type: 'string',
|
|
1152
1261
|
default: 'standard',
|
|
1153
|
-
description: 'Governance template pack (standard/project-scaffold/go-service-matrix/node-library/frontend-app)',
|
|
1262
|
+
description: 'Governance template pack (standard/project-scaffold/moe-workspace/resource-governance/go-service-matrix/node-library/frontend-app)',
|
|
1154
1263
|
},
|
|
1155
1264
|
quick: { type: 'boolean', default: false, description: 'Quick start with auto-detection' },
|
|
1156
1265
|
interactive: { type: 'boolean', default: false, description: 'Interactive configuration mode with prompts' },
|
|
@@ -1357,6 +1466,188 @@ const governance = defineCommand({
|
|
|
1357
1466
|
subCommands: { diff: governanceDiff },
|
|
1358
1467
|
});
|
|
1359
1468
|
// ============================================================================
|
|
1469
|
+
// assets command - Resource lifecycle governance
|
|
1470
|
+
// ============================================================================
|
|
1471
|
+
const assetsScan = defineCommand({
|
|
1472
|
+
meta: { name: 'scan', description: 'Classify project docs, reports, media, scripts, and temporary outputs' },
|
|
1473
|
+
args: {
|
|
1474
|
+
dir: { type: 'string', default: '.', description: 'Project directory' },
|
|
1475
|
+
json: { type: 'boolean', default: false, description: 'Print JSON output' },
|
|
1476
|
+
},
|
|
1477
|
+
run({ args }) {
|
|
1478
|
+
const report = scanResourceAssets({ projectDir: args.dir });
|
|
1479
|
+
if (args.json) {
|
|
1480
|
+
console.log(JSON.stringify(report, null, 2));
|
|
1481
|
+
return;
|
|
1482
|
+
}
|
|
1483
|
+
console.log('SCALE Asset Scan');
|
|
1484
|
+
console.log(` Project: ${report.projectDir}`);
|
|
1485
|
+
console.log(` Total resources: ${report.summary.total}`);
|
|
1486
|
+
console.log(` Tracked forbidden: ${report.summary.trackedForbidden}`);
|
|
1487
|
+
console.log(` Large tracked: ${report.summary.largeTracked}`);
|
|
1488
|
+
console.log(` Expired: ${report.summary.expired}`);
|
|
1489
|
+
console.log('\nBy type:');
|
|
1490
|
+
for (const [type, count] of Object.entries(report.summary.byType)) {
|
|
1491
|
+
if (count > 0)
|
|
1492
|
+
console.log(` ${type}: ${count}`);
|
|
1493
|
+
}
|
|
1494
|
+
},
|
|
1495
|
+
});
|
|
1496
|
+
const assetsDoctor = defineCommand({
|
|
1497
|
+
meta: { name: 'doctor', description: 'Find resource lifecycle and Git policy problems' },
|
|
1498
|
+
args: {
|
|
1499
|
+
dir: { type: 'string', default: '.', description: 'Project directory' },
|
|
1500
|
+
json: { type: 'boolean', default: false, description: 'Print JSON output' },
|
|
1501
|
+
},
|
|
1502
|
+
run({ args }) {
|
|
1503
|
+
const report = doctorResourceAssets({ projectDir: args.dir });
|
|
1504
|
+
if (args.json) {
|
|
1505
|
+
console.log(JSON.stringify(report, null, 2));
|
|
1506
|
+
return;
|
|
1507
|
+
}
|
|
1508
|
+
console.log(`SCALE Asset Doctor: ${report.ok ? 'OK' : 'FAILED'}`);
|
|
1509
|
+
if (report.findings.length === 0) {
|
|
1510
|
+
console.log(' No resource lifecycle findings.');
|
|
1511
|
+
return;
|
|
1512
|
+
}
|
|
1513
|
+
for (const finding of report.findings) {
|
|
1514
|
+
const path = finding.path ? ` ${finding.path}` : '';
|
|
1515
|
+
console.log(` [${finding.severity.toUpperCase()}] ${finding.code}${path}: ${finding.message}`);
|
|
1516
|
+
if (finding.fix)
|
|
1517
|
+
console.log(` fix: ${finding.fix}`);
|
|
1518
|
+
}
|
|
1519
|
+
if (!report.ok)
|
|
1520
|
+
process.exitCode = 1;
|
|
1521
|
+
},
|
|
1522
|
+
});
|
|
1523
|
+
const assetsSettle = defineCommand({
|
|
1524
|
+
meta: { name: 'settle', description: 'Record resource lifecycle settlement evidence for a task' },
|
|
1525
|
+
args: {
|
|
1526
|
+
dir: { type: 'string', default: '.', description: 'Project directory' },
|
|
1527
|
+
'task-id': { type: 'string', description: 'Task id for the settlement record' },
|
|
1528
|
+
'artifact-dir': { type: 'string', description: 'Task artifact directory where resource-impact.md should be updated' },
|
|
1529
|
+
json: { type: 'boolean', default: false, description: 'Print JSON output' },
|
|
1530
|
+
},
|
|
1531
|
+
run({ args }) {
|
|
1532
|
+
const report = settleResourceAssets({
|
|
1533
|
+
projectDir: args.dir,
|
|
1534
|
+
taskId: args['task-id'],
|
|
1535
|
+
artifactsDir: args['artifact-dir'],
|
|
1536
|
+
});
|
|
1537
|
+
if (args.json) {
|
|
1538
|
+
console.log(JSON.stringify(report, null, 2));
|
|
1539
|
+
}
|
|
1540
|
+
else {
|
|
1541
|
+
console.log(`SCALE Asset Settlement: ${report.ok ? 'OK' : 'FAILED'}`);
|
|
1542
|
+
if (report.resourceImpactPath)
|
|
1543
|
+
console.log(` Resource impact: ${report.resourceImpactPath}`);
|
|
1544
|
+
if (report.doctor.findings.length > 0) {
|
|
1545
|
+
for (const finding of report.doctor.findings) {
|
|
1546
|
+
const path = finding.path ? ` ${finding.path}` : '';
|
|
1547
|
+
console.log(` [${finding.severity.toUpperCase()}] ${finding.code}${path}: ${finding.message}`);
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
if (!report.ok)
|
|
1552
|
+
process.exitCode = 1;
|
|
1553
|
+
},
|
|
1554
|
+
});
|
|
1555
|
+
const assets = defineCommand({
|
|
1556
|
+
meta: { name: 'assets', description: 'Resource lifecycle governance for generated and maintained project assets' },
|
|
1557
|
+
subCommands: { scan: assetsScan, doctor: assetsDoctor, settle: assetsSettle },
|
|
1558
|
+
});
|
|
1559
|
+
// ============================================================================
|
|
1560
|
+
// standards command - Engineering standards governance
|
|
1561
|
+
// ============================================================================
|
|
1562
|
+
const standardsScan = defineCommand({
|
|
1563
|
+
meta: { name: 'scan', description: 'Scan source files for engineering standard violations' },
|
|
1564
|
+
args: {
|
|
1565
|
+
dir: { type: 'string', default: '.', description: 'Project directory' },
|
|
1566
|
+
json: { type: 'boolean', default: false, description: 'Print JSON output' },
|
|
1567
|
+
},
|
|
1568
|
+
run({ args }) {
|
|
1569
|
+
const report = scanEngineeringStandards({ projectDir: args.dir });
|
|
1570
|
+
if (args.json) {
|
|
1571
|
+
console.log(JSON.stringify(report, null, 2));
|
|
1572
|
+
return;
|
|
1573
|
+
}
|
|
1574
|
+
console.log('SCALE Standards Scan');
|
|
1575
|
+
console.log(` Project: ${report.projectDir}`);
|
|
1576
|
+
console.log(` Files scanned: ${report.summary.filesScanned}`);
|
|
1577
|
+
console.log(` Findings: ${report.summary.totalFindings}`);
|
|
1578
|
+
console.log(` Blocking findings: ${report.summary.blockingFindings}`);
|
|
1579
|
+
for (const finding of report.findings.slice(0, 20)) {
|
|
1580
|
+
const line = finding.line ? `:${finding.line}` : '';
|
|
1581
|
+
console.log(` [${finding.severity.toUpperCase()}] ${finding.ruleId} ${finding.path}${line}: ${finding.message}`);
|
|
1582
|
+
}
|
|
1583
|
+
if (report.findings.length > 20)
|
|
1584
|
+
console.log(` ... ${report.findings.length - 20} more finding(s)`);
|
|
1585
|
+
},
|
|
1586
|
+
});
|
|
1587
|
+
const standardsDoctor = defineCommand({
|
|
1588
|
+
meta: { name: 'doctor', description: 'Find blocking engineering standards problems' },
|
|
1589
|
+
args: {
|
|
1590
|
+
dir: { type: 'string', default: '.', description: 'Project directory' },
|
|
1591
|
+
json: { type: 'boolean', default: false, description: 'Print JSON output' },
|
|
1592
|
+
},
|
|
1593
|
+
run({ args }) {
|
|
1594
|
+
const report = doctorEngineeringStandards({ projectDir: args.dir });
|
|
1595
|
+
if (args.json) {
|
|
1596
|
+
console.log(JSON.stringify(report, null, 2));
|
|
1597
|
+
if (!report.ok)
|
|
1598
|
+
process.exitCode = 1;
|
|
1599
|
+
return;
|
|
1600
|
+
}
|
|
1601
|
+
console.log(`SCALE Standards Doctor: ${report.ok ? 'OK' : 'FAILED'}`);
|
|
1602
|
+
if (report.findings.length === 0) {
|
|
1603
|
+
console.log(' No engineering standards findings.');
|
|
1604
|
+
return;
|
|
1605
|
+
}
|
|
1606
|
+
for (const finding of report.findings) {
|
|
1607
|
+
const line = finding.line ? `:${finding.line}` : '';
|
|
1608
|
+
console.log(` [${finding.severity.toUpperCase()}] ${finding.ruleId} ${finding.path}${line}: ${finding.message}`);
|
|
1609
|
+
if (finding.fix)
|
|
1610
|
+
console.log(` fix: ${finding.fix}`);
|
|
1611
|
+
}
|
|
1612
|
+
if (!report.ok)
|
|
1613
|
+
process.exitCode = 1;
|
|
1614
|
+
},
|
|
1615
|
+
});
|
|
1616
|
+
const standardsSettle = defineCommand({
|
|
1617
|
+
meta: { name: 'settle', description: 'Record engineering standards settlement evidence for a task' },
|
|
1618
|
+
args: {
|
|
1619
|
+
dir: { type: 'string', default: '.', description: 'Project directory' },
|
|
1620
|
+
'task-id': { type: 'string', description: 'Task id for the settlement record' },
|
|
1621
|
+
'artifact-dir': { type: 'string', description: 'Task artifact directory where standards-impact.md should be updated' },
|
|
1622
|
+
json: { type: 'boolean', default: false, description: 'Print JSON output' },
|
|
1623
|
+
},
|
|
1624
|
+
run({ args }) {
|
|
1625
|
+
const report = settleEngineeringStandards({
|
|
1626
|
+
projectDir: args.dir,
|
|
1627
|
+
taskId: args['task-id'],
|
|
1628
|
+
artifactsDir: args['artifact-dir'],
|
|
1629
|
+
});
|
|
1630
|
+
if (args.json) {
|
|
1631
|
+
console.log(JSON.stringify(report, null, 2));
|
|
1632
|
+
}
|
|
1633
|
+
else {
|
|
1634
|
+
console.log(`SCALE Standards Settlement: ${report.ok ? 'OK' : 'FAILED'}`);
|
|
1635
|
+
if (report.standardsImpactPath)
|
|
1636
|
+
console.log(` Standards impact: ${report.standardsImpactPath}`);
|
|
1637
|
+
for (const finding of report.doctor.findings) {
|
|
1638
|
+
const line = finding.line ? `:${finding.line}` : '';
|
|
1639
|
+
console.log(` [${finding.severity.toUpperCase()}] ${finding.ruleId} ${finding.path}${line}: ${finding.message}`);
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1642
|
+
if (!report.ok)
|
|
1643
|
+
process.exitCode = 1;
|
|
1644
|
+
},
|
|
1645
|
+
});
|
|
1646
|
+
const standards = defineCommand({
|
|
1647
|
+
meta: { name: 'standards', description: 'Engineering standards governance for logs, security, architecture, database, and code quality' },
|
|
1648
|
+
subCommands: { scan: standardsScan, doctor: standardsDoctor, settle: standardsSettle },
|
|
1649
|
+
});
|
|
1650
|
+
// ============================================================================
|
|
1360
1651
|
// evolve command
|
|
1361
1652
|
// ============================================================================
|
|
1362
1653
|
const evolve = defineCommand({
|
|
@@ -1919,7 +2210,7 @@ import * as phaseCommands from '../cli/phaseCommands.js';
|
|
|
1919
2210
|
import * as liteCommands from '../cli/liteCommands.js';
|
|
1920
2211
|
import * as vibeCommands from '../cli/vibeCommands.js';
|
|
1921
2212
|
const main = defineCommand({
|
|
1922
|
-
meta: { name: 'scale', version:
|
|
2213
|
+
meta: { name: 'scale', version: SCALE_ENGINE_VERSION, description: `SCALE Engine v${SCALE_ENGINE_VERSION} CLI - hardened phase workflow gates, governance templates, platform adapters, skill routing, and verification automation` },
|
|
1923
2214
|
subCommands: {
|
|
1924
2215
|
// Lite Mode (agent-skills style interactive entry)
|
|
1925
2216
|
lite: liteCommands.liteCommand,
|
|
@@ -1951,6 +2242,8 @@ const main = defineCommand({
|
|
|
1951
2242
|
stats,
|
|
1952
2243
|
preflight,
|
|
1953
2244
|
governance,
|
|
2245
|
+
assets,
|
|
2246
|
+
standards,
|
|
1954
2247
|
metrics,
|
|
1955
2248
|
'task-artifacts': taskArtifacts,
|
|
1956
2249
|
workspace,
|