@hongmaple0820/scale-engine 0.25.0 → 0.26.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.
Files changed (143) hide show
  1. package/LICENSE +15 -15
  2. package/README.en.md +368 -346
  3. package/README.md +548 -529
  4. package/dist/adapters/AiderAdapter.js +52 -52
  5. package/dist/adapters/AntigravityAdapter.d.ts +4 -0
  6. package/dist/adapters/AntigravityAdapter.js +21 -0
  7. package/dist/adapters/AntigravityAdapter.js.map +1 -0
  8. package/dist/adapters/ClaudeCodeAdapter.d.ts +4 -1
  9. package/dist/adapters/ClaudeCodeAdapter.js +34 -34
  10. package/dist/adapters/ClaudeCodeAdapter.js.map +1 -1
  11. package/dist/adapters/ClineAdapter.d.ts +4 -0
  12. package/dist/adapters/ClineAdapter.js +20 -0
  13. package/dist/adapters/ClineAdapter.js.map +1 -0
  14. package/dist/adapters/CodexAdapter.js +28 -28
  15. package/dist/adapters/CursorAdapter.js +26 -26
  16. package/dist/adapters/DeepSeekTuiAdapter.js +97 -97
  17. package/dist/adapters/DoubaoAdapter.js +33 -33
  18. package/dist/adapters/GeminiAdapter.js +26 -26
  19. package/dist/adapters/GenericProjectAgentAdapter.d.ts +29 -0
  20. package/dist/adapters/GenericProjectAgentAdapter.js +204 -0
  21. package/dist/adapters/GenericProjectAgentAdapter.js.map +1 -0
  22. package/dist/adapters/HermesAdapter.js +26 -26
  23. package/dist/adapters/JCodeAdapter.d.ts +4 -0
  24. package/dist/adapters/JCodeAdapter.js +19 -0
  25. package/dist/adapters/JCodeAdapter.js.map +1 -0
  26. package/dist/adapters/KiloCodeAdapter.d.ts +4 -0
  27. package/dist/adapters/KiloCodeAdapter.js +20 -0
  28. package/dist/adapters/KiloCodeAdapter.js.map +1 -0
  29. package/dist/adapters/KimiAdapter.js +32 -32
  30. package/dist/adapters/KiroAdapter.js +26 -26
  31. package/dist/adapters/OpenClawAdapter.js +26 -26
  32. package/dist/adapters/OpenCodeAdapter.js +26 -26
  33. package/dist/adapters/QCoderAdapter.js +26 -26
  34. package/dist/adapters/QoderAdapter.d.ts +4 -0
  35. package/dist/adapters/QoderAdapter.js +21 -0
  36. package/dist/adapters/QoderAdapter.js.map +1 -0
  37. package/dist/adapters/TraeAdapter.js +26 -26
  38. package/dist/adapters/VSCAdapter.js +26 -26
  39. package/dist/adapters/WindsurfAdapter.js +32 -32
  40. package/dist/adapters/WorkBuddyAdapter.js +26 -26
  41. package/dist/adapters/index.d.ts +5 -0
  42. package/dist/adapters/index.js +15 -0
  43. package/dist/adapters/index.js.map +1 -1
  44. package/dist/api/cli.js +133 -47
  45. package/dist/api/cli.js.map +1 -1
  46. package/dist/api/doctor.js +10 -3
  47. package/dist/api/doctor.js.map +1 -1
  48. package/dist/api/quickstart.js +7 -1
  49. package/dist/api/quickstart.js.map +1 -1
  50. package/dist/artifact/sqliteStore.js +89 -89
  51. package/dist/artifact/types.d.ts +1 -1
  52. package/dist/cli/phaseCommands.js +45 -45
  53. package/dist/context/AntiPatternRegistry.js +20 -20
  54. package/dist/context/ContextBuilder.js +155 -155
  55. package/dist/evolution/EvolutionEngine.js +31 -31
  56. package/dist/evolution/EvolutionEvaluator.d.ts +2 -0
  57. package/dist/evolution/EvolutionEvaluator.js +7 -1
  58. package/dist/evolution/EvolutionEvaluator.js.map +1 -1
  59. package/dist/fsm/FSMAgentBridge.js +11 -11
  60. package/dist/hooks/HookGeneratorEnhanced.js +218 -218
  61. package/dist/index.d.ts +1 -1
  62. package/dist/index.js +2 -2
  63. package/dist/index.js.map +1 -1
  64. package/dist/knowledge/SQLiteKnowledgeBase.js +28 -28
  65. package/dist/memory/MemoryBrain.js +52 -52
  66. package/dist/output/GovernanceDashboard.js +44 -44
  67. package/dist/output/HTMLArtifactLayer.js +31 -31
  68. package/dist/prompts/VibeTemplateGallery.js +121 -121
  69. package/dist/skills/SkillDiscovery.js +12 -1
  70. package/dist/skills/SkillDiscovery.js.map +1 -1
  71. package/dist/skills/routing/SkillPlanner.js +40 -40
  72. package/dist/workflow/EngineeringStandards.js +62 -62
  73. package/dist/workflow/GovernanceTemplatePacks.d.ts +1 -1
  74. package/dist/workflow/GovernanceTemplatePacks.js +1990 -162
  75. package/dist/workflow/GovernanceTemplatePacks.js.map +1 -1
  76. package/dist/workflow/GovernanceTemplates.d.ts +2 -0
  77. package/dist/workflow/GovernanceTemplates.js +1012 -1001
  78. package/dist/workflow/GovernanceTemplates.js.map +1 -1
  79. package/dist/workflow/ResourceGovernance.js +16 -16
  80. package/dist/workflow/TaskArtifactScaffolder.js +10 -10
  81. package/dist/workflow/UpgradeManager.d.ts +3 -2
  82. package/dist/workflow/UpgradeManager.js +134 -49
  83. package/dist/workflow/UpgradeManager.js.map +1 -1
  84. package/dist/workflow/WorkspaceTopology.js +18 -15
  85. package/dist/workflow/WorkspaceTopology.js.map +1 -1
  86. package/docs/ACTIVE_SECURITY_VISUAL_GATES.md +87 -87
  87. package/docs/BACKGROUND_HUNTER.md +62 -62
  88. package/docs/CODE_INTELLIGENCE.md +138 -138
  89. package/docs/CONTEXT_BUDGET.md +113 -113
  90. package/docs/DEPENDENCY_AUDIT.md +89 -89
  91. package/docs/EVOLUTION_SHADOW_MODE.md +63 -63
  92. package/docs/EXTERNAL_REFERENCES.md +63 -58
  93. package/docs/GITLAB_FLOW.md +125 -125
  94. package/docs/GOVERNANCE_DASHBOARD.md +85 -85
  95. package/docs/MEMORY_BRAIN.md +104 -104
  96. package/docs/MEMORY_FABRIC.md +134 -134
  97. package/docs/README.md +101 -92
  98. package/docs/RUNTIME_EVIDENCE.md +101 -101
  99. package/docs/SKILL-REPOSITORY.md +57 -57
  100. package/docs/SKILL_RADAR.md +122 -122
  101. package/docs/THIRD_PARTY_SKILLS.md +57 -57
  102. package/docs/WORKFLOW_EVAL.md +151 -151
  103. package/docs/guides/DEVELOPMENT_WORKFLOW.md +80 -0
  104. package/docs/guides/GETTING_STARTED.md +50 -0
  105. package/docs/start/README.md +78 -72
  106. package/docs/start/agent-governance-demo.md +107 -107
  107. package/docs/start/quickstart.md +137 -127
  108. package/docs/start/workflow-upgrade.md +32 -8
  109. package/docs/workflow/README.md +67 -0
  110. package/docs/workflow/node-library.md +52 -0
  111. package/docs/workflow/templates/api-contract.md +29 -0
  112. package/docs/workflow/templates/architecture-review.md +23 -0
  113. package/docs/workflow/templates/db-change-plan.md +20 -0
  114. package/docs/workflow/templates/docs-impact.md +17 -0
  115. package/docs/workflow/templates/e2e-plan.md +20 -0
  116. package/docs/workflow/templates/explore.md +16 -0
  117. package/docs/workflow/templates/github-actions-scale-preflight.yml +32 -0
  118. package/docs/workflow/templates/mini-prd.md +16 -0
  119. package/docs/workflow/templates/plan.md +37 -0
  120. package/docs/workflow/templates/pre-push-scale-preflight.sh +8 -0
  121. package/docs/workflow/templates/product-smoke.md +61 -0
  122. package/docs/workflow/templates/reality-check.md +28 -0
  123. package/docs/workflow/templates/resource-cleanup.md +17 -0
  124. package/docs/workflow/templates/resource-impact.md +25 -0
  125. package/docs/workflow/templates/review.md +12 -0
  126. package/docs/workflow/templates/runtime.md +23 -0
  127. package/docs/workflow/templates/security-review.md +26 -0
  128. package/docs/workflow/templates/skill-evidence.md +33 -0
  129. package/docs/workflow/templates/skill-plan.md +39 -0
  130. package/docs/workflow/templates/spec.md +17 -0
  131. package/docs/workflow/templates/standards-impact.md +28 -0
  132. package/docs/workflow/templates/summary.md +16 -0
  133. package/docs/workflow/templates/tasks.md +8 -0
  134. package/docs/workflow/templates/ui-spec.md +29 -0
  135. package/docs/workflow/templates/verification.md +20 -0
  136. package/docs/workflow/templates/visual-review.md +20 -0
  137. package/examples/demo-projects/agent-governance-demo/CONTEXT.md +14 -14
  138. package/examples/demo-projects/agent-governance-demo/README.md +48 -48
  139. package/examples/demo-projects/agent-governance-demo/docs/CONTEXT-MAP.md +14 -14
  140. package/examples/demo-projects/agent-governance-demo/package.json +22 -21
  141. package/examples/demo-projects/agent-governance-demo/src/oauth-state.ts +39 -39
  142. package/examples/demo-projects/agent-governance-demo/tests/oauth-state.test.ts +52 -52
  143. package/package.json +88 -78
@@ -5,36 +5,36 @@ import { dirname, isAbsolute, join, relative, resolve } from 'node:path';
5
5
  import { WorkflowEvalStore } from '../eval/WorkflowEval.js';
6
6
  import { RuntimeEvidenceLedger } from '../runtime/RuntimeEvidenceLedger.js';
7
7
  import { redactEvidenceText, redactEvidenceValue } from '../tools/ToolEvidenceStore.js';
8
- const SCHEMA = `
9
- CREATE TABLE IF NOT EXISTS memory_nodes (
10
- id TEXT PRIMARY KEY,
11
- type TEXT NOT NULL,
12
- title TEXT NOT NULL,
13
- summary TEXT NOT NULL,
14
- entities TEXT NOT NULL DEFAULT '[]',
15
- source TEXT NOT NULL,
16
- evidence_paths TEXT NOT NULL DEFAULT '[]',
17
- confidence REAL NOT NULL,
18
- scope TEXT NOT NULL,
19
- status TEXT NOT NULL,
20
- created_at TEXT NOT NULL,
21
- updated_at TEXT NOT NULL,
22
- last_verified_at TEXT,
23
- metadata TEXT NOT NULL DEFAULT '{}',
24
- fingerprint TEXT NOT NULL
25
- );
26
-
27
- CREATE INDEX IF NOT EXISTS idx_memory_nodes_type ON memory_nodes(type);
28
- CREATE INDEX IF NOT EXISTS idx_memory_nodes_status ON memory_nodes(status);
29
- CREATE INDEX IF NOT EXISTS idx_memory_nodes_scope ON memory_nodes(scope);
30
- CREATE INDEX IF NOT EXISTS idx_memory_nodes_fingerprint ON memory_nodes(fingerprint);
31
-
32
- CREATE TABLE IF NOT EXISTS memory_meta (
33
- key TEXT PRIMARY KEY,
34
- value TEXT NOT NULL
35
- );
36
-
37
- INSERT OR IGNORE INTO memory_meta (key, value) VALUES ('schema_version', '1');
8
+ const SCHEMA = `
9
+ CREATE TABLE IF NOT EXISTS memory_nodes (
10
+ id TEXT PRIMARY KEY,
11
+ type TEXT NOT NULL,
12
+ title TEXT NOT NULL,
13
+ summary TEXT NOT NULL,
14
+ entities TEXT NOT NULL DEFAULT '[]',
15
+ source TEXT NOT NULL,
16
+ evidence_paths TEXT NOT NULL DEFAULT '[]',
17
+ confidence REAL NOT NULL,
18
+ scope TEXT NOT NULL,
19
+ status TEXT NOT NULL,
20
+ created_at TEXT NOT NULL,
21
+ updated_at TEXT NOT NULL,
22
+ last_verified_at TEXT,
23
+ metadata TEXT NOT NULL DEFAULT '{}',
24
+ fingerprint TEXT NOT NULL
25
+ );
26
+
27
+ CREATE INDEX IF NOT EXISTS idx_memory_nodes_type ON memory_nodes(type);
28
+ CREATE INDEX IF NOT EXISTS idx_memory_nodes_status ON memory_nodes(status);
29
+ CREATE INDEX IF NOT EXISTS idx_memory_nodes_scope ON memory_nodes(scope);
30
+ CREATE INDEX IF NOT EXISTS idx_memory_nodes_fingerprint ON memory_nodes(fingerprint);
31
+
32
+ CREATE TABLE IF NOT EXISTS memory_meta (
33
+ key TEXT PRIMARY KEY,
34
+ value TEXT NOT NULL
35
+ );
36
+
37
+ INSERT OR IGNORE INTO memory_meta (key, value) VALUES ('schema_version', '1');
38
38
  `;
39
39
  export class MemoryBrain {
40
40
  constructor(options = {}) {
@@ -323,28 +323,28 @@ export class MemoryBrain {
323
323
  }
324
324
  upsert(node) {
325
325
  const fingerprint = fingerprintFor(node);
326
- this.db.prepare(`
327
- INSERT INTO memory_nodes (
328
- id, type, title, summary, entities, source, evidence_paths, confidence, scope, status,
329
- created_at, updated_at, last_verified_at, metadata, fingerprint
330
- ) VALUES (
331
- @id, @type, @title, @summary, @entities, @source, @evidencePaths, @confidence, @scope, @status,
332
- @createdAt, @updatedAt, @lastVerifiedAt, @metadata, @fingerprint
333
- )
334
- ON CONFLICT(id) DO UPDATE SET
335
- type = excluded.type,
336
- title = excluded.title,
337
- summary = excluded.summary,
338
- entities = excluded.entities,
339
- source = excluded.source,
340
- evidence_paths = excluded.evidence_paths,
341
- confidence = excluded.confidence,
342
- scope = excluded.scope,
343
- status = excluded.status,
344
- updated_at = excluded.updated_at,
345
- last_verified_at = excluded.last_verified_at,
346
- metadata = excluded.metadata,
347
- fingerprint = excluded.fingerprint
326
+ this.db.prepare(`
327
+ INSERT INTO memory_nodes (
328
+ id, type, title, summary, entities, source, evidence_paths, confidence, scope, status,
329
+ created_at, updated_at, last_verified_at, metadata, fingerprint
330
+ ) VALUES (
331
+ @id, @type, @title, @summary, @entities, @source, @evidencePaths, @confidence, @scope, @status,
332
+ @createdAt, @updatedAt, @lastVerifiedAt, @metadata, @fingerprint
333
+ )
334
+ ON CONFLICT(id) DO UPDATE SET
335
+ type = excluded.type,
336
+ title = excluded.title,
337
+ summary = excluded.summary,
338
+ entities = excluded.entities,
339
+ source = excluded.source,
340
+ evidence_paths = excluded.evidence_paths,
341
+ confidence = excluded.confidence,
342
+ scope = excluded.scope,
343
+ status = excluded.status,
344
+ updated_at = excluded.updated_at,
345
+ last_verified_at = excluded.last_verified_at,
346
+ metadata = excluded.metadata,
347
+ fingerprint = excluded.fingerprint
348
348
  `).run({
349
349
  id: node.id,
350
350
  type: node.type,
@@ -137,9 +137,9 @@ function dashboardFindings(summary) {
137
137
  return findings;
138
138
  }
139
139
  function runtimeSection(summary) {
140
- return `<table>
141
- <thead><tr><th>Status</th><th>Total</th><th>Passed</th><th>Failed</th><th>Skipped</th></tr></thead>
142
- <tbody><tr><td>${summary.runtime.ok ? 'OK' : 'FAILED'}</td><td>${summary.runtime.total}</td><td>${summary.runtime.passed}</td><td>${summary.runtime.failed}</td><td>${summary.runtime.skipped}</td></tr></tbody>
140
+ return `<table>
141
+ <thead><tr><th>Status</th><th>Total</th><th>Passed</th><th>Failed</th><th>Skipped</th></tr></thead>
142
+ <tbody><tr><td>${summary.runtime.ok ? 'OK' : 'FAILED'}</td><td>${summary.runtime.total}</td><td>${summary.runtime.passed}</td><td>${summary.runtime.failed}</td><td>${summary.runtime.skipped}</td></tr></tbody>
143
143
  </table>`;
144
144
  }
145
145
  function governanceMetricsSection(metrics) {
@@ -168,59 +168,59 @@ function governanceMetricsSection(metrics) {
168
168
  `;
169
169
  }
170
170
  function evalSection(runs, failures) {
171
- const latestRows = runs.slice(0, 5).map(run => `<tr>
172
- <td><code>${escapeHtml(run.id)}</code></td>
173
- <td>${escapeHtml(run.suiteId)}</td>
174
- <td>${run.ok ? 'pass' : 'fail'}</td>
175
- <td>${(run.metrics.passAt1Rate * 100).toFixed(1)}%</td>
176
- <td>${run.metrics.failureReplayCount}</td>
171
+ const latestRows = runs.slice(0, 5).map(run => `<tr>
172
+ <td><code>${escapeHtml(run.id)}</code></td>
173
+ <td>${escapeHtml(run.suiteId)}</td>
174
+ <td>${run.ok ? 'pass' : 'fail'}</td>
175
+ <td>${(run.metrics.passAt1Rate * 100).toFixed(1)}%</td>
176
+ <td>${run.metrics.failureReplayCount}</td>
177
177
  </tr>`).join('');
178
- const failureRows = failures.slice(0, 8).map(failure => `<tr>
179
- <td><code>${escapeHtml(failure.id)}</code></td>
180
- <td>${escapeHtml(failure.category)}</td>
181
- <td>${escapeHtml(failure.status)}</td>
182
- <td>${escapeHtml(failure.phase)}</td>
178
+ const failureRows = failures.slice(0, 8).map(failure => `<tr>
179
+ <td><code>${escapeHtml(failure.id)}</code></td>
180
+ <td>${escapeHtml(failure.category)}</td>
181
+ <td>${escapeHtml(failure.status)}</td>
182
+ <td>${escapeHtml(failure.phase)}</td>
183
183
  </tr>`).join('');
184
- return `
185
- <h3>Latest Runs</h3>
186
- <table><thead><tr><th>Run</th><th>Suite</th><th>Status</th><th>Pass@1</th><th>Failures</th></tr></thead><tbody>${latestRows || '<tr><td colspan="5">No eval runs found.</td></tr>'}</tbody></table>
187
- <h3>Recent Failures</h3>
188
- <table><thead><tr><th>Failure</th><th>Category</th><th>Status</th><th>Phase</th></tr></thead><tbody>${failureRows || '<tr><td colspan="4">No recent failure replays found.</td></tr>'}</tbody></table>
184
+ return `
185
+ <h3>Latest Runs</h3>
186
+ <table><thead><tr><th>Run</th><th>Suite</th><th>Status</th><th>Pass@1</th><th>Failures</th></tr></thead><tbody>${latestRows || '<tr><td colspan="5">No eval runs found.</td></tr>'}</tbody></table>
187
+ <h3>Recent Failures</h3>
188
+ <table><thead><tr><th>Failure</th><th>Category</th><th>Status</th><th>Phase</th></tr></thead><tbody>${failureRows || '<tr><td colspan="4">No recent failure replays found.</td></tr>'}</tbody></table>
189
189
  `;
190
190
  }
191
191
  function memorySection(memoryDream) {
192
- const contradictionRows = memoryDream.contradictions.slice(0, 8).map(item => `<tr>
193
- <td><code>${escapeHtml(item.id)}</code></td>
194
- <td>${escapeHtml(item.title)}</td>
195
- <td>${item.nodeIds.map(id => `<code>${escapeHtml(id)}</code>`).join(', ')}</td>
192
+ const contradictionRows = memoryDream.contradictions.slice(0, 8).map(item => `<tr>
193
+ <td><code>${escapeHtml(item.id)}</code></td>
194
+ <td>${escapeHtml(item.title)}</td>
195
+ <td>${item.nodeIds.map(id => `<code>${escapeHtml(id)}</code>`).join(', ')}</td>
196
196
  </tr>`).join('');
197
- const promoteRows = memoryDream.promotionCandidates.slice(0, 8).map(item => `<tr>
198
- <td><code>${escapeHtml(item.id)}</code></td>
199
- <td>${escapeHtml(item.title)}</td>
200
- <td>${item.confidence.toFixed(2)}</td>
197
+ const promoteRows = memoryDream.promotionCandidates.slice(0, 8).map(item => `<tr>
198
+ <td><code>${escapeHtml(item.id)}</code></td>
199
+ <td>${escapeHtml(item.title)}</td>
200
+ <td>${item.confidence.toFixed(2)}</td>
201
201
  </tr>`).join('');
202
- return `
203
- <table><thead><tr><th>Total</th><th>Active</th><th>Candidate</th><th>Stale</th><th>Contradictions</th></tr></thead>
204
- <tbody><tr><td>${memoryDream.summary.total}</td><td>${memoryDream.summary.active}</td><td>${memoryDream.summary.candidate}</td><td>${memoryDream.summary.stale}</td><td>${memoryDream.summary.contradictions}</td></tr></tbody></table>
205
- <h3>Contradictions</h3>
206
- <table><thead><tr><th>ID</th><th>Title</th><th>Nodes</th></tr></thead><tbody>${contradictionRows || '<tr><td colspan="3">No contradictions found.</td></tr>'}</tbody></table>
207
- <h3>Promotion Candidates</h3>
208
- <table><thead><tr><th>ID</th><th>Title</th><th>Confidence</th></tr></thead><tbody>${promoteRows || '<tr><td colspan="3">No promotion candidates found.</td></tr>'}</tbody></table>
202
+ return `
203
+ <table><thead><tr><th>Total</th><th>Active</th><th>Candidate</th><th>Stale</th><th>Contradictions</th></tr></thead>
204
+ <tbody><tr><td>${memoryDream.summary.total}</td><td>${memoryDream.summary.active}</td><td>${memoryDream.summary.candidate}</td><td>${memoryDream.summary.stale}</td><td>${memoryDream.summary.contradictions}</td></tr></tbody></table>
205
+ <h3>Contradictions</h3>
206
+ <table><thead><tr><th>ID</th><th>Title</th><th>Nodes</th></tr></thead><tbody>${contradictionRows || '<tr><td colspan="3">No contradictions found.</td></tr>'}</tbody></table>
207
+ <h3>Promotion Candidates</h3>
208
+ <table><thead><tr><th>ID</th><th>Title</th><th>Confidence</th></tr></thead><tbody>${promoteRows || '<tr><td colspan="3">No promotion candidates found.</td></tr>'}</tbody></table>
209
209
  `;
210
210
  }
211
211
  function resourceSection(resourceDoctor) {
212
- const findingRows = resourceDoctor.findings.slice(0, 12).map(finding => `<tr>
213
- <td>${escapeHtml(finding.severity)}</td>
214
- <td>${escapeHtml(finding.code)}</td>
215
- <td>${escapeHtml(finding.path ?? '')}</td>
216
- <td>${escapeHtml(finding.message)}</td>
212
+ const findingRows = resourceDoctor.findings.slice(0, 12).map(finding => `<tr>
213
+ <td>${escapeHtml(finding.severity)}</td>
214
+ <td>${escapeHtml(finding.code)}</td>
215
+ <td>${escapeHtml(finding.path ?? '')}</td>
216
+ <td>${escapeHtml(finding.message)}</td>
217
217
  </tr>`).join('');
218
218
  const summary = resourceDoctor.scan.summary;
219
- return `
220
- <table><thead><tr><th>Status</th><th>Total Assets</th><th>Tracked Forbidden</th><th>Expired</th><th>Large Tracked</th></tr></thead>
221
- <tbody><tr><td>${resourceDoctor.ok ? 'OK' : 'FAILED'}</td><td>${summary.total}</td><td>${summary.trackedForbidden}</td><td>${summary.expired}</td><td>${summary.largeTracked}</td></tr></tbody></table>
222
- <h3>Findings</h3>
223
- <table><thead><tr><th>Severity</th><th>Code</th><th>Path</th><th>Message</th></tr></thead><tbody>${findingRows || '<tr><td colspan="4">No resource findings.</td></tr>'}</tbody></table>
219
+ return `
220
+ <table><thead><tr><th>Status</th><th>Total Assets</th><th>Tracked Forbidden</th><th>Expired</th><th>Large Tracked</th></tr></thead>
221
+ <tbody><tr><td>${resourceDoctor.ok ? 'OK' : 'FAILED'}</td><td>${summary.total}</td><td>${summary.trackedForbidden}</td><td>${summary.expired}</td><td>${summary.largeTracked}</td></tr></tbody></table>
222
+ <h3>Findings</h3>
223
+ <table><thead><tr><th>Severity</th><th>Code</th><th>Path</th><th>Message</th></tr></thead><tbody>${findingRows || '<tr><td colspan="4">No resource findings.</td></tr>'}</tbody></table>
224
224
  `;
225
225
  }
226
226
  function htmlArtifactSection(paths) {
@@ -310,11 +310,11 @@ function renderPurposeSection(template, sections) {
310
310
  const missing = sections.missing.length
311
311
  ? `<p class="doc-warning">Missing source artifacts: ${sections.missing.map(item => `<code>${escapeHtml(item)}</code>`).join(', ')}</p>`
312
312
  : '<p>All configured source artifacts were found.</p>';
313
- return `
314
- <p>${escapeHtml(template.description)}</p>
315
- <h3>Source Artifacts</h3>
316
- ${present}
317
- ${missing}
313
+ return `
314
+ <p>${escapeHtml(template.description)}</p>
315
+ <h3>Source Artifacts</h3>
316
+ ${present}
317
+ ${missing}
318
318
  `;
319
319
  }
320
320
  function markdownToHtml(markdown) {
@@ -427,12 +427,12 @@ function writeArtifactIndex(projectDir, taskDir, policy, manifest) {
427
427
  });
428
428
  const rows = manifest.artifacts.map(artifact => {
429
429
  const href = basename(artifact.path);
430
- return `<tr>
431
- <td><a href="${escapeAttribute(href)}">${escapeHtml(artifact.type)}</a></td>
432
- <td>${escapeHtml(artifact.title)}</td>
433
- <td>${escapeHtml(artifact.gitPolicy)}</td>
434
- <td>${escapeHtml(artifact.generatedAt)}</td>
435
- <td>${artifact.missingSources.length ? artifact.missingSources.map(item => `<code>${escapeHtml(item)}</code>`).join(', ') : 'none'}</td>
430
+ return `<tr>
431
+ <td><a href="${escapeAttribute(href)}">${escapeHtml(artifact.type)}</a></td>
432
+ <td>${escapeHtml(artifact.title)}</td>
433
+ <td>${escapeHtml(artifact.gitPolicy)}</td>
434
+ <td>${escapeHtml(artifact.generatedAt)}</td>
435
+ <td>${artifact.missingSources.length ? artifact.missingSources.map(item => `<code>${escapeHtml(item)}</code>`).join(', ') : 'none'}</td>
436
436
  </tr>`;
437
437
  }).join('\n');
438
438
  const html = renderer.renderReport({
@@ -445,9 +445,9 @@ function writeArtifactIndex(projectDir, taskDir, policy, manifest) {
445
445
  },
446
446
  sections: [{
447
447
  heading: 'Artifact Index',
448
- content: `<table>
449
- <thead><tr><th>Type</th><th>Title</th><th>Git Policy</th><th>Generated</th><th>Missing Sources</th></tr></thead>
450
- <tbody>${rows}</tbody>
448
+ content: `<table>
449
+ <thead><tr><th>Type</th><th>Title</th><th>Git Policy</th><th>Generated</th><th>Missing Sources</th></tr></thead>
450
+ <tbody>${rows}</tbody>
451
451
  </table>`,
452
452
  }],
453
453
  });
@@ -520,23 +520,23 @@ function htmlArtifactSettlementMarkdown(taskId, doctor) {
520
520
  const artifacts = doctor.artifacts.length
521
521
  ? doctor.artifacts.map(artifact => `| ${artifact.type} | ${escapeCell(artifact.path)} | ${artifact.sourcePaths.length} | ${artifact.missingSources.length} | ${artifact.gitPolicy} |`).join('\n')
522
522
  : '| none | | 0 | 0 | |';
523
- return `# HTML Artifacts
524
-
525
- Task: ${taskId ?? 'unspecified'}
526
- Status: ${doctor.ok ? 'passed' : 'blocked'}
527
- Generated: ${new Date().toISOString()}
528
-
529
- ## Artifacts
530
-
531
- | Type | Path | Sources | Missing | Git policy |
532
- | --- | --- | ---: | ---: | --- |
533
- ${artifacts}
534
-
535
- ## Findings
536
-
537
- | Severity | Code | Path | Message |
538
- | --- | --- | --- | --- |
539
- ${findings}
523
+ return `# HTML Artifacts
524
+
525
+ Task: ${taskId ?? 'unspecified'}
526
+ Status: ${doctor.ok ? 'passed' : 'blocked'}
527
+ Generated: ${new Date().toISOString()}
528
+
529
+ ## Artifacts
530
+
531
+ | Type | Path | Sources | Missing | Git policy |
532
+ | --- | --- | ---: | ---: | --- |
533
+ ${artifacts}
534
+
535
+ ## Findings
536
+
537
+ | Severity | Code | Path | Message |
538
+ | --- | --- | --- | --- |
539
+ ${findings}
540
540
  `;
541
541
  }
542
542
  function sourceHeading(path) {
@@ -20,29 +20,29 @@ export const VISUAL_VIBE_TEMPLATES = [
20
20
  '如果只上线一个最小闭环,必须包含哪三个能力?',
21
21
  '哪些需求现在看起来诱人,但应该明确列为非目标?',
22
22
  ],
23
- copyPrompt: `请作为 CEO 和产品负责人,主导 {{appName}} 的产品发现工作。
24
-
25
- 场景:{{scenario}}
26
- 我当前身份:{{userRole}}
27
-
28
- 请按 SCALE 工作流执行:
29
- 1. explore:先明确用户、业务目标、约束、竞品或替代方案,不确定的事实必须标注 [UNCERTAIN]。
30
- 2. plan:输出 Mini-PRD,包含用户路径、非目标、权限/数据影响、异常场景和验收标准。
31
- 3. verify:逐条检查成功标准是否可测试、是否能形成端到端闭环。
32
-
33
- 必须主动使用 skills/MCP/CLI:
34
- - 如需联网资料,主动使用 web-access 或等价联网能力,并引用来源。
35
- - 如需求模糊,主动使用 deep-interview / idea-refine 类 Skill。
36
- - 如涉及用户界面,联动 UI/UX Skill 形成体验标准。
37
-
38
- 安全边界:
39
- - 不允许凭空编造市场数据、竞品能力或用户需求。
40
- - 不允许把临时想法写成确定需求。
41
- - 不允许跳过权限、隐私、数据生命周期和失败场景。
42
-
43
- 成功标准:
44
- - 产出一份可落地 Mini-PRD。
45
- - 每条验收标准都能被测试或人工验证。
23
+ copyPrompt: `请作为 CEO 和产品负责人,主导 {{appName}} 的产品发现工作。
24
+
25
+ 场景:{{scenario}}
26
+ 我当前身份:{{userRole}}
27
+
28
+ 请按 SCALE 工作流执行:
29
+ 1. explore:先明确用户、业务目标、约束、竞品或替代方案,不确定的事实必须标注 [UNCERTAIN]。
30
+ 2. plan:输出 Mini-PRD,包含用户路径、非目标、权限/数据影响、异常场景和验收标准。
31
+ 3. verify:逐条检查成功标准是否可测试、是否能形成端到端闭环。
32
+
33
+ 必须主动使用 skills/MCP/CLI:
34
+ - 如需联网资料,主动使用 web-access 或等价联网能力,并引用来源。
35
+ - 如需求模糊,主动使用 deep-interview / idea-refine 类 Skill。
36
+ - 如涉及用户界面,联动 UI/UX Skill 形成体验标准。
37
+
38
+ 安全边界:
39
+ - 不允许凭空编造市场数据、竞品能力或用户需求。
40
+ - 不允许把临时想法写成确定需求。
41
+ - 不允许跳过权限、隐私、数据生命周期和失败场景。
42
+
43
+ 成功标准:
44
+ - 产出一份可落地 Mini-PRD。
45
+ - 每条验收标准都能被测试或人工验证。
46
46
  - 明确本阶段要做什么、不做什么、后续如何验证。`,
47
47
  },
48
48
  {
@@ -61,30 +61,30 @@ export const VISUAL_VIBE_TEMPLATES = [
61
61
  '界面应该更像运营后台、消费产品、创作工具,还是管理系统?',
62
62
  '哪些状态必须完整设计:空态、加载、错误、权限不足、移动端?',
63
63
  ],
64
- copyPrompt: `请作为 UX Director 和高级视觉设计负责人,主导 {{appName}} 的 UI/UX 方案。
65
-
66
- 场景:{{scenario}}
67
- 我当前身份:{{userRole}}
68
-
69
- 请按 SCALE 工作流执行:
70
- 1. explore:阅读现有产品、页面、组件、品牌和设计系统,识别当前视觉语言。
71
- 2. plan:输出 UI-SPEC,包含信息架构、核心用户路径、组件状态、响应式规则、可访问性要求。
72
- 3. build:只给出可执行设计方案或实现切片,不要写营销式空话。
73
- 4. verify:要求截图、浏览器检查、控制台/网络检查和移动端适配证据。
74
-
75
- 必须主动使用 skills/MCP/CLI:
76
- - 设计方向用 awesome-design-md / ui-ux-pro-max / frontend-design。
77
- - 浏览器验证用 agent-browser / Chrome DevTools MCP / webapp-testing。
78
- - 如需真实网页或竞品参考,使用 web-access 并记录来源。
79
-
80
- 安全边界:
81
- - 不允许默认套用紫蓝渐变、模板化卡片堆叠或无意义装饰。
82
- - 不允许只描述功能而不定义状态、布局和交互。
83
- - 不允许未验证截图就声称 UI 完成。
84
-
85
- 成功标准:
86
- - 产出一份可以直接指导实现的 UI-SPEC。
87
- - 每个关键页面包含状态、布局、交互、移动端和验收规则。
64
+ copyPrompt: `请作为 UX Director 和高级视觉设计负责人,主导 {{appName}} 的 UI/UX 方案。
65
+
66
+ 场景:{{scenario}}
67
+ 我当前身份:{{userRole}}
68
+
69
+ 请按 SCALE 工作流执行:
70
+ 1. explore:阅读现有产品、页面、组件、品牌和设计系统,识别当前视觉语言。
71
+ 2. plan:输出 UI-SPEC,包含信息架构、核心用户路径、组件状态、响应式规则、可访问性要求。
72
+ 3. build:只给出可执行设计方案或实现切片,不要写营销式空话。
73
+ 4. verify:要求截图、浏览器检查、控制台/网络检查和移动端适配证据。
74
+
75
+ 必须主动使用 skills/MCP/CLI:
76
+ - 设计方向用 awesome-design-md / ui-ux-pro-max / frontend-design。
77
+ - 浏览器验证用 agent-browser / Chrome DevTools MCP / webapp-testing。
78
+ - 如需真实网页或竞品参考,使用 web-access 并记录来源。
79
+
80
+ 安全边界:
81
+ - 不允许默认套用紫蓝渐变、模板化卡片堆叠或无意义装饰。
82
+ - 不允许只描述功能而不定义状态、布局和交互。
83
+ - 不允许未验证截图就声称 UI 完成。
84
+
85
+ 成功标准:
86
+ - 产出一份可以直接指导实现的 UI-SPEC。
87
+ - 每个关键页面包含状态、布局、交互、移动端和验收规则。
88
88
  - 明确需要哪些浏览器证据证明体验达标。`,
89
89
  },
90
90
  {
@@ -103,32 +103,32 @@ export const VISUAL_VIBE_TEMPLATES = [
103
103
  '哪些契约一旦变更会影响其他服务、前端或数据迁移?',
104
104
  '失败、回滚、兼容、观测和权限边界如何设计?',
105
105
  ],
106
- copyPrompt: `请作为 CTO 和首席架构师,主导 {{appName}} 的技术实现架构方案。
107
-
108
- 场景:{{scenario}}
109
- 我当前身份:{{userRole}}
110
-
111
- 请按 SCALE 工作流执行:
112
- 1. explore:先读现有代码、目录、模块文档、接口和验证命令,列出事实证据。
113
- 2. plan:输出架构方案,包含模块边界、接口契约、数据影响、异常契约、回滚策略和测试策略。
114
- 3. build:把方案拆成可独立验证的实现切片,避免一次性大爆炸改动。
115
- 4. review:主动做架构、代码质量、安全和文档影响评审。
116
- 5. verify:给出必须运行的命令、预期证据和无法验证时的降级说明。
117
-
118
- 必须主动使用 skills/MCP/CLI:
119
- - 需要框架/SDK 当前用法时,主动查官方文档或 Context7。
120
- - 需要模块关系时,使用 rg/graphify 或代码图谱能力。
121
- - 需要交叉评审时,可使用 codex/gemini/opencode CLI,但必须记录版本、命令和输出摘要。
122
- - 工具与 Skill 编排必须写入 skill-plan 或 verification 证据。
123
-
124
- 安全边界:
125
- - 不允许编造调用链、接口或测试结果。
126
- - 不允许绕过 ORM、框架约定、日志脱敏、安全校验和权限边界。
127
- - 不允许把临时脚本、报告或调试日志混入长期资产。
128
-
129
- 成功标准:
130
- - 产出一份可执行架构方案。
131
- - 每个实现切片都有边界、风险、验证命令和回滚思路。
106
+ copyPrompt: `请作为 CTO 和首席架构师,主导 {{appName}} 的技术实现架构方案。
107
+
108
+ 场景:{{scenario}}
109
+ 我当前身份:{{userRole}}
110
+
111
+ 请按 SCALE 工作流执行:
112
+ 1. explore:先读现有代码、目录、模块文档、接口和验证命令,列出事实证据。
113
+ 2. plan:输出架构方案,包含模块边界、接口契约、数据影响、异常契约、回滚策略和测试策略。
114
+ 3. build:把方案拆成可独立验证的实现切片,避免一次性大爆炸改动。
115
+ 4. review:主动做架构、代码质量、安全和文档影响评审。
116
+ 5. verify:给出必须运行的命令、预期证据和无法验证时的降级说明。
117
+
118
+ 必须主动使用 skills/MCP/CLI:
119
+ - 需要框架/SDK 当前用法时,主动查官方文档或 Context7。
120
+ - 需要模块关系时,使用 rg/graphify 或代码图谱能力。
121
+ - 需要交叉评审时,可使用 codex/gemini/opencode CLI,但必须记录版本、命令和输出摘要。
122
+ - 工具与 Skill 编排必须写入 skill-plan 或 verification 证据。
123
+
124
+ 安全边界:
125
+ - 不允许编造调用链、接口或测试结果。
126
+ - 不允许绕过 ORM、框架约定、日志脱敏、安全校验和权限边界。
127
+ - 不允许把临时脚本、报告或调试日志混入长期资产。
128
+
129
+ 成功标准:
130
+ - 产出一份可执行架构方案。
131
+ - 每个实现切片都有边界、风险、验证命令和回滚思路。
132
132
  - 明确哪些文档需要长期维护,哪些产物是临时证据。`,
133
133
  },
134
134
  {
@@ -147,30 +147,30 @@ export const VISUAL_VIBE_TEMPLATES = [
147
147
  '哪些同类问题需要一起扫描,但不一定一起修改?',
148
148
  '验证失败时如何定位是实现问题、环境问题还是既有债务?',
149
149
  ],
150
- copyPrompt: `请作为 Engineering Lead,主导 {{appName}} 的实现切片。
151
-
152
- 场景:{{scenario}}
153
- 我当前身份:{{userRole}}
154
-
155
- 请按 SCALE 工作流执行:
156
- 1. explore:读相关代码、测试、规范和历史上下文,输出影响面。
157
- 2. plan:把工作拆成最小实现切片,每个切片有文件范围和验证方式。
158
- 3. build:优先 TDD 或补回归测试,保持改动可追溯。
159
- 4. verify:运行真实命令,记录 exit code、失败项、修复迭代和未验证项。
160
-
161
- 必须主动使用 skills/MCP/CLI:
162
- - 新逻辑或 Bug 修复使用 TDD / systematic-debugging。
163
- - 多文件变更使用 incremental-implementation。
164
- - 需要外部工具时先做安全扫描,再执行。
165
-
166
- 安全边界:
167
- - 不允许随手重构无关代码。
168
- - 不允许增加无脱敏日志、硬编码密钥、危险默认值或绕过框架约定。
169
- - 不允许测试未运行却声称通过。
170
-
171
- 成功标准:
172
- - 改动范围和用户请求可追溯。
173
- - 必要测试、lint、构建或人工验证有证据。
150
+ copyPrompt: `请作为 Engineering Lead,主导 {{appName}} 的实现切片。
151
+
152
+ 场景:{{scenario}}
153
+ 我当前身份:{{userRole}}
154
+
155
+ 请按 SCALE 工作流执行:
156
+ 1. explore:读相关代码、测试、规范和历史上下文,输出影响面。
157
+ 2. plan:把工作拆成最小实现切片,每个切片有文件范围和验证方式。
158
+ 3. build:优先 TDD 或补回归测试,保持改动可追溯。
159
+ 4. verify:运行真实命令,记录 exit code、失败项、修复迭代和未验证项。
160
+
161
+ 必须主动使用 skills/MCP/CLI:
162
+ - 新逻辑或 Bug 修复使用 TDD / systematic-debugging。
163
+ - 多文件变更使用 incremental-implementation。
164
+ - 需要外部工具时先做安全扫描,再执行。
165
+
166
+ 安全边界:
167
+ - 不允许随手重构无关代码。
168
+ - 不允许增加无脱敏日志、硬编码密钥、危险默认值或绕过框架约定。
169
+ - 不允许测试未运行却声称通过。
170
+
171
+ 成功标准:
172
+ - 改动范围和用户请求可追溯。
173
+ - 必要测试、lint、构建或人工验证有证据。
174
174
  - 交付说明包含完成内容、验证结果和未验证项。`,
175
175
  },
176
176
  {
@@ -189,30 +189,30 @@ export const VISUAL_VIBE_TEMPLATES = [
189
189
  '失败和跳过项是否被明确记录?',
190
190
  '是否存在临时文件、测试报告、截图或日志不应提交?',
191
191
  ],
192
- copyPrompt: `请作为 QA Lead 和 Release Manager,主导 {{appName}} 的验收与发版前检查。
193
-
194
- 场景:{{scenario}}
195
- 我当前身份:{{userRole}}
196
-
197
- 请按 SCALE 工作流执行:
198
- 1. explore:读取当前任务产物、git diff、测试配置和已知风险。
199
- 2. verify:运行最小相关验证和发版前门控,记录真实输出摘要。
200
- 3. review:执行代码质量、安全、文档资产和资源治理检查。
201
- 4. ship:只有证据闭环后才建议合并、打 tag 或发布。
202
-
203
- 必须主动使用 skills/MCP/CLI:
204
- - 使用 verification / code-reviewer / security review 类 Skill。
205
- - UI 或浏览器功能必须补截图、控制台和网络证据。
206
- - 发版必须记录版本、commit、tag、registry 或远程状态。
207
-
208
- 安全边界:
209
- - 不允许隐藏失败命令。
210
- - 不允许把 dry-run 当成真实通过。
211
- - 不允许提交临时脚本、敏感日志、未归档测试报告或本地配置。
212
-
213
- 成功标准:
214
- - 产出完整 verification/review/release evidence。
215
- - 所有 required gates 通过,optional gates 的缺失有说明。
192
+ copyPrompt: `请作为 QA Lead 和 Release Manager,主导 {{appName}} 的验收与发版前检查。
193
+
194
+ 场景:{{scenario}}
195
+ 我当前身份:{{userRole}}
196
+
197
+ 请按 SCALE 工作流执行:
198
+ 1. explore:读取当前任务产物、git diff、测试配置和已知风险。
199
+ 2. verify:运行最小相关验证和发版前门控,记录真实输出摘要。
200
+ 3. review:执行代码质量、安全、文档资产和资源治理检查。
201
+ 4. ship:只有证据闭环后才建议合并、打 tag 或发布。
202
+
203
+ 必须主动使用 skills/MCP/CLI:
204
+ - 使用 verification / code-reviewer / security review 类 Skill。
205
+ - UI 或浏览器功能必须补截图、控制台和网络证据。
206
+ - 发版必须记录版本、commit、tag、registry 或远程状态。
207
+
208
+ 安全边界:
209
+ - 不允许隐藏失败命令。
210
+ - 不允许把 dry-run 当成真实通过。
211
+ - 不允许提交临时脚本、敏感日志、未归档测试报告或本地配置。
212
+
213
+ 成功标准:
214
+ - 产出完整 verification/review/release evidence。
215
+ - 所有 required gates 通过,optional gates 的缺失有说明。
216
216
  - 明确是否可发版,以及剩余风险。`,
217
217
  },
218
218
  ];