@hongmaple0820/scale-engine 0.15.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/api/cli.js +239 -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/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 +99 -18
- package/dist/workflow/GovernanceTemplatePacks.js.map +1 -1
- package/dist/workflow/GovernanceTemplates.d.ts +1 -1
- package/dist/workflow/GovernanceTemplates.js +211 -34
- 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 +3 -0
- 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/index.d.ts +2 -0
- package/dist/workflow/index.js +2 -0
- package/dist/workflow/index.js.map +1 -1
- package/package.json +2 -2
package/README.en.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img src="https://img.shields.io/badge/version-0.
|
|
2
|
+
<img src="https://img.shields.io/badge/version-0.15.1-orange?style=flat-square" alt="version" />
|
|
3
3
|
<img src="https://img.shields.io/badge/platforms-16-blue?style=flat-square" alt="platforms" />
|
|
4
4
|
<img src="https://img.shields.io/badge/agents-12-blue?style=flat-square" alt="agents" />
|
|
5
5
|
<img src="https://img.shields.io/badge/workflows-10-green?style=flat-square" alt="workflows" />
|
|
6
6
|
<img src="https://img.shields.io/badge/detectors-19-red?style=flat-square" alt="detectors" />
|
|
7
|
-
<img src="https://img.shields.io/badge/tests-
|
|
8
|
-
<img src="https://img.shields.io/badge/npm-0.
|
|
7
|
+
<img src="https://img.shields.io/badge/tests-822-passing-brightgreen?style=flat-square" alt="tests" />
|
|
8
|
+
<img src="https://img.shields.io/badge/npm-0.15.1-cb3837?style=flat-square&logo=npm" alt="npm" />
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
|
-
# SCALE Engine v0.
|
|
11
|
+
# SCALE Engine v0.15.1
|
|
12
12
|
|
|
13
13
|
SCALE Engine is an AI engineering workflow runtime for agentic coding tools. It turns prompt-level engineering rules into stateful workflow gates, persisted evidence, review records, and release checks.
|
|
14
14
|
|
|
@@ -28,7 +28,15 @@ Prompt instructions are advisory. Production engineering needs mechanisms:
|
|
|
28
28
|
|
|
29
29
|
## Current Release
|
|
30
30
|
|
|
31
|
-
v0.
|
|
31
|
+
v0.15.1 focuses on production-grade engineering governance templates:
|
|
32
|
+
|
|
33
|
+
- Supports MOE and non-MOE workspace topology, child repository blockers, and temporary worktree cleanup candidates.
|
|
34
|
+
- Adds resource asset governance for maintained docs, versioned outputs, task evidence, temporary files, and forbidden commit assets.
|
|
35
|
+
- Adds engineering standards scans for noisy logs, sensitive data redaction, secure input handling, ORM/database usage, framework conventions, and test rigor.
|
|
36
|
+
- Strengthens skill and tool orchestration with routing and evidence contracts for UI/UX, web research, browser E2E, desktop automation, and external Agent CLIs.
|
|
37
|
+
- `scale init` / governance packs now generate service matrix, verification profile, artifact templates, metrics, resource policy, engineering standards, and tool orchestration rules.
|
|
38
|
+
|
|
39
|
+
Historical v0.11.1 introduced four priority improvements:
|
|
32
40
|
|
|
33
41
|
### Phase Commands FSM Blocking
|
|
34
42
|
- `canTransition` + `process.exit(1)` ensures FSM guard failures block execution, not continue
|
package/README.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img src="https://img.shields.io/badge/version-0.
|
|
2
|
+
<img src="https://img.shields.io/badge/version-0.15.1-orange?style=flat-square" alt="version" />
|
|
3
3
|
<img src="https://img.shields.io/badge/platforms-16-blue?style=flat-square" alt="platforms" />
|
|
4
4
|
<img src="https://img.shields.io/badge/agents-12-blue?style=flat-square" alt="agents" />
|
|
5
5
|
<img src="https://img.shields.io/badge/workflows-10-green?style=flat-square" alt="workflows" />
|
|
6
6
|
<img src="https://img.shields.io/badge/detectors-19-red?style=flat-square" alt="detectors" />
|
|
7
|
-
<img src="https://img.shields.io/badge/tests-
|
|
8
|
-
<img src="https://img.shields.io/badge/npm-0.
|
|
7
|
+
<img src="https://img.shields.io/badge/tests-822-passing-brightgreen?style=flat-square" alt="tests" />
|
|
8
|
+
<img src="https://img.shields.io/badge/npm-0.15.1-cb3837?style=flat-square&logo=npm" alt="npm" />
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
|
-
# SCALE Engine v0.
|
|
11
|
+
# SCALE Engine v0.15.1
|
|
12
12
|
|
|
13
13
|
SCALE Engine 是一个面向 AI 编码 Agent 的工程化工作流运行时。它把提示词里的工程纪律,下沉为状态机、质量门禁、持久化证据、确定性 review 记录和发布检查。
|
|
14
14
|
|
|
@@ -28,7 +28,15 @@ npm:https://www.npmjs.com/package/@hongmaple0820/scale-engine
|
|
|
28
28
|
|
|
29
29
|
## 当前版本
|
|
30
30
|
|
|
31
|
-
v0.
|
|
31
|
+
v0.15.1 聚焦生产级工程治理模板:
|
|
32
|
+
|
|
33
|
+
- 支持 MOE / 非 MOE 工作区拓扑、子仓库变更阻断、临时 worktree 清理候选识别。
|
|
34
|
+
- 增加资源资产治理,区分长期维护文档、版本化产物、任务证据、临时文件和禁止提交资产。
|
|
35
|
+
- 增加工程规范扫描,覆盖日志噪音、敏感信息脱敏、安全输入、ORM/数据库、框架组件和测试验证。
|
|
36
|
+
- 增强技能与工具编排,UI/UX、联网研究、浏览器 E2E、桌面自动化、外部 Agent CLI 都有路由和证据契约。
|
|
37
|
+
- `scale init` / governance pack 会生成 service matrix、verification profile、artifact 模板、metrics、resource policy、engineering standards 和 tool orchestration 规则。
|
|
38
|
+
|
|
39
|
+
历史 v0.11.1 新增四大优先级改进:
|
|
32
40
|
|
|
33
41
|
### Phase Commands FSM 阻断
|
|
34
42
|
- `canTransition` + `process.exit(1)` 确保 FSM guard 失败时阻塞流程,而非继续执行
|
package/dist/api/cli.js
CHANGED
|
@@ -31,6 +31,8 @@ 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';
|
|
@@ -38,6 +40,7 @@ import { cleanupWorkspaceLifecycle, inspectWorkspaceLifecycle, } from '../workfl
|
|
|
38
40
|
import { resolveWorkspaceTopology, workspaceTopologyPath, workspaceTopologyTemplate, } from '../workflow/WorkspaceTopology.js';
|
|
39
41
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
40
42
|
import { join, resolve } from 'node:path';
|
|
43
|
+
import { SCALE_ENGINE_VERSION } from '../version.js';
|
|
41
44
|
// ============================================================================
|
|
42
45
|
// Engine bootstrap (单例 + lazy init)
|
|
43
46
|
// ============================================================================
|
|
@@ -69,6 +72,42 @@ function gatesForPreflightProfile(profile) {
|
|
|
69
72
|
return ['G3', 'G0', 'G4', 'G5'];
|
|
70
73
|
return ['G3', 'G0', 'G4', 'G5', 'G6', 'G7'];
|
|
71
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
|
+
}
|
|
72
111
|
let _engine = null;
|
|
73
112
|
function getEngine() {
|
|
74
113
|
if (!_engine)
|
|
@@ -1022,6 +1061,9 @@ const preflight = defineCommand({
|
|
|
1022
1061
|
profile: args.profile,
|
|
1023
1062
|
service: args.service,
|
|
1024
1063
|
});
|
|
1064
|
+
const engineeringStandards = evaluateEngineeringStandardsGate({
|
|
1065
|
+
policy: resolved.policy,
|
|
1066
|
+
});
|
|
1025
1067
|
const targetResults = [];
|
|
1026
1068
|
if (!args.json) {
|
|
1027
1069
|
console.log('\nSCALE Preflight');
|
|
@@ -1030,6 +1072,13 @@ const preflight = defineCommand({
|
|
|
1030
1072
|
console.log(` Profile: ${resolved.profileName}`);
|
|
1031
1073
|
console.log(` Preflight profile: ${preflightProfile}`);
|
|
1032
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
|
+
}
|
|
1033
1082
|
}
|
|
1034
1083
|
for (const target of resolved.targets) {
|
|
1035
1084
|
if (!args.json) {
|
|
@@ -1061,7 +1110,9 @@ const preflight = defineCommand({
|
|
|
1061
1110
|
}
|
|
1062
1111
|
}
|
|
1063
1112
|
}
|
|
1064
|
-
const passed = targetResults.length > 0 &&
|
|
1113
|
+
const passed = targetResults.length > 0 &&
|
|
1114
|
+
targetResults.every(target => target.passed) &&
|
|
1115
|
+
!engineeringStandards.blocked;
|
|
1065
1116
|
const result = {
|
|
1066
1117
|
phase: 'PREFLIGHT',
|
|
1067
1118
|
profile: resolved.profileName,
|
|
@@ -1069,6 +1120,7 @@ const preflight = defineCommand({
|
|
|
1069
1120
|
gates: gateStages,
|
|
1070
1121
|
services: targetResults.map(target => target.service).filter(Boolean),
|
|
1071
1122
|
policy: resolved.policy,
|
|
1123
|
+
engineeringStandards,
|
|
1072
1124
|
targets: targetResults,
|
|
1073
1125
|
passed,
|
|
1074
1126
|
};
|
|
@@ -1207,7 +1259,7 @@ const init = defineCommand({
|
|
|
1207
1259
|
'governance-pack': {
|
|
1208
1260
|
type: 'string',
|
|
1209
1261
|
default: 'standard',
|
|
1210
|
-
description: 'Governance template pack (standard/project-scaffold/moe-workspace/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)',
|
|
1211
1263
|
},
|
|
1212
1264
|
quick: { type: 'boolean', default: false, description: 'Quick start with auto-detection' },
|
|
1213
1265
|
interactive: { type: 'boolean', default: false, description: 'Interactive configuration mode with prompts' },
|
|
@@ -1414,6 +1466,188 @@ const governance = defineCommand({
|
|
|
1414
1466
|
subCommands: { diff: governanceDiff },
|
|
1415
1467
|
});
|
|
1416
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
|
+
// ============================================================================
|
|
1417
1651
|
// evolve command
|
|
1418
1652
|
// ============================================================================
|
|
1419
1653
|
const evolve = defineCommand({
|
|
@@ -1976,7 +2210,7 @@ import * as phaseCommands from '../cli/phaseCommands.js';
|
|
|
1976
2210
|
import * as liteCommands from '../cli/liteCommands.js';
|
|
1977
2211
|
import * as vibeCommands from '../cli/vibeCommands.js';
|
|
1978
2212
|
const main = defineCommand({
|
|
1979
|
-
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` },
|
|
1980
2214
|
subCommands: {
|
|
1981
2215
|
// Lite Mode (agent-skills style interactive entry)
|
|
1982
2216
|
lite: liteCommands.liteCommand,
|
|
@@ -2008,6 +2242,8 @@ const main = defineCommand({
|
|
|
2008
2242
|
stats,
|
|
2009
2243
|
preflight,
|
|
2010
2244
|
governance,
|
|
2245
|
+
assets,
|
|
2246
|
+
standards,
|
|
2011
2247
|
metrics,
|
|
2012
2248
|
'task-artifacts': taskArtifacts,
|
|
2013
2249
|
workspace,
|