popeye-cli 2.1.0 → 2.7.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/adapters/gemini.d.ts +14 -0
- package/dist/adapters/gemini.d.ts.map +1 -1
- package/dist/adapters/gemini.js +41 -6
- package/dist/adapters/gemini.js.map +1 -1
- package/dist/adapters/grok.d.ts +14 -0
- package/dist/adapters/grok.d.ts.map +1 -1
- package/dist/adapters/grok.js +42 -6
- package/dist/adapters/grok.js.map +1 -1
- package/dist/adapters/openai.d.ts +10 -0
- package/dist/adapters/openai.d.ts.map +1 -1
- package/dist/adapters/openai.js +44 -5
- package/dist/adapters/openai.js.map +1 -1
- package/dist/cli/commands/create.js +1 -1
- package/dist/cli/commands/create.js.map +1 -1
- package/dist/cli/interactive.d.ts.map +1 -1
- package/dist/cli/interactive.js +328 -21
- package/dist/cli/interactive.js.map +1 -1
- package/dist/generators/all.d.ts.map +1 -1
- package/dist/generators/all.js +25 -2
- package/dist/generators/all.js.map +1 -1
- package/dist/generators/doc-parser.d.ts +21 -6
- package/dist/generators/doc-parser.d.ts.map +1 -1
- package/dist/generators/doc-parser.js +55 -4
- package/dist/generators/doc-parser.js.map +1 -1
- package/dist/generators/templates/fullstack.js +1 -1
- package/dist/generators/templates/website-components.js +1 -1
- package/dist/generators/templates/website-components.js.map +1 -1
- package/dist/generators/templates/website-config.d.ts +4 -1
- package/dist/generators/templates/website-config.d.ts.map +1 -1
- package/dist/generators/templates/website-config.js +17 -11
- package/dist/generators/templates/website-config.js.map +1 -1
- package/dist/generators/templates/website-conversion.js +1 -1
- package/dist/generators/templates/website-conversion.js.map +1 -1
- package/dist/generators/templates/website-landing.js +1 -1
- package/dist/generators/templates/website-landing.js.map +1 -1
- package/dist/generators/templates/website-layout.d.ts +36 -4
- package/dist/generators/templates/website-layout.d.ts.map +1 -1
- package/dist/generators/templates/website-layout.js +466 -23
- package/dist/generators/templates/website-layout.js.map +1 -1
- package/dist/generators/templates/website-pricing.js +1 -1
- package/dist/generators/templates/website-pricing.js.map +1 -1
- package/dist/generators/templates/website-sections.js +1 -1
- package/dist/generators/templates/website-sections.js.map +1 -1
- package/dist/generators/templates/website-seo.d.ts.map +1 -1
- package/dist/generators/templates/website-seo.js +4 -1
- package/dist/generators/templates/website-seo.js.map +1 -1
- package/dist/generators/templates/website.d.ts +1 -1
- package/dist/generators/templates/website.d.ts.map +1 -1
- package/dist/generators/templates/website.js +1 -1
- package/dist/generators/templates/website.js.map +1 -1
- package/dist/generators/website-content-ai.d.ts +52 -0
- package/dist/generators/website-content-ai.d.ts.map +1 -0
- package/dist/generators/website-content-ai.js +141 -0
- package/dist/generators/website-content-ai.js.map +1 -0
- package/dist/generators/website-content-scanner.d.ts +1 -1
- package/dist/generators/website-content-scanner.d.ts.map +1 -1
- package/dist/generators/website-content-scanner.js +98 -1
- package/dist/generators/website-content-scanner.js.map +1 -1
- package/dist/generators/website-context.d.ts +34 -1
- package/dist/generators/website-context.d.ts.map +1 -1
- package/dist/generators/website-context.js +131 -9
- package/dist/generators/website-context.js.map +1 -1
- package/dist/generators/website-debug.d.ts +12 -0
- package/dist/generators/website-debug.d.ts.map +1 -1
- package/dist/generators/website-debug.js +16 -0
- package/dist/generators/website-debug.js.map +1 -1
- package/dist/generators/website.d.ts.map +1 -1
- package/dist/generators/website.js +26 -4
- package/dist/generators/website.js.map +1 -1
- package/dist/pipeline/artifact-manager.d.ts.map +1 -1
- package/dist/pipeline/artifact-manager.js +3 -0
- package/dist/pipeline/artifact-manager.js.map +1 -1
- package/dist/pipeline/auto-recovery.d.ts +56 -0
- package/dist/pipeline/auto-recovery.d.ts.map +1 -0
- package/dist/pipeline/auto-recovery.js +185 -0
- package/dist/pipeline/auto-recovery.js.map +1 -0
- package/dist/pipeline/change-request.d.ts +39 -0
- package/dist/pipeline/change-request.d.ts.map +1 -1
- package/dist/pipeline/change-request.js +40 -1
- package/dist/pipeline/change-request.js.map +1 -1
- package/dist/pipeline/check-runner.d.ts +30 -1
- package/dist/pipeline/check-runner.d.ts.map +1 -1
- package/dist/pipeline/check-runner.js +122 -1
- package/dist/pipeline/check-runner.js.map +1 -1
- package/dist/pipeline/command-resolver.d.ts.map +1 -1
- package/dist/pipeline/command-resolver.js +33 -2
- package/dist/pipeline/command-resolver.js.map +1 -1
- package/dist/pipeline/consensus/arbitrator-query.d.ts +22 -0
- package/dist/pipeline/consensus/arbitrator-query.d.ts.map +1 -0
- package/dist/pipeline/consensus/arbitrator-query.js +70 -0
- package/dist/pipeline/consensus/arbitrator-query.js.map +1 -0
- package/dist/pipeline/consensus/consensus-runner.d.ts +131 -7
- package/dist/pipeline/consensus/consensus-runner.d.ts.map +1 -1
- package/dist/pipeline/consensus/consensus-runner.js +809 -35
- package/dist/pipeline/consensus/consensus-runner.js.map +1 -1
- package/dist/pipeline/cr-lifecycle.d.ts +42 -0
- package/dist/pipeline/cr-lifecycle.d.ts.map +1 -0
- package/dist/pipeline/cr-lifecycle.js +89 -0
- package/dist/pipeline/cr-lifecycle.js.map +1 -0
- package/dist/pipeline/gate-engine.d.ts +1 -0
- package/dist/pipeline/gate-engine.d.ts.map +1 -1
- package/dist/pipeline/gate-engine.js +27 -8
- package/dist/pipeline/gate-engine.js.map +1 -1
- package/dist/pipeline/migration.d.ts.map +1 -1
- package/dist/pipeline/migration.js +3 -26
- package/dist/pipeline/migration.js.map +1 -1
- package/dist/pipeline/orchestrator.d.ts +1 -1
- package/dist/pipeline/orchestrator.d.ts.map +1 -1
- package/dist/pipeline/orchestrator.js +311 -16
- package/dist/pipeline/orchestrator.js.map +1 -1
- package/dist/pipeline/packets/consensus-packet-builder.d.ts +15 -4
- package/dist/pipeline/packets/consensus-packet-builder.d.ts.map +1 -1
- package/dist/pipeline/packets/consensus-packet-builder.js +29 -17
- package/dist/pipeline/packets/consensus-packet-builder.js.map +1 -1
- package/dist/pipeline/phases/architecture.d.ts.map +1 -1
- package/dist/pipeline/phases/architecture.js +5 -3
- package/dist/pipeline/phases/architecture.js.map +1 -1
- package/dist/pipeline/phases/audit.d.ts.map +1 -1
- package/dist/pipeline/phases/audit.js +5 -3
- package/dist/pipeline/phases/audit.js.map +1 -1
- package/dist/pipeline/phases/consensus-architecture.d.ts.map +1 -1
- package/dist/pipeline/phases/consensus-architecture.js +10 -1
- package/dist/pipeline/phases/consensus-architecture.js.map +1 -1
- package/dist/pipeline/phases/consensus-master-plan.d.ts.map +1 -1
- package/dist/pipeline/phases/consensus-master-plan.js +10 -3
- package/dist/pipeline/phases/consensus-master-plan.js.map +1 -1
- package/dist/pipeline/phases/consensus-role-plans.d.ts.map +1 -1
- package/dist/pipeline/phases/consensus-role-plans.js +10 -1
- package/dist/pipeline/phases/consensus-role-plans.js.map +1 -1
- package/dist/pipeline/phases/done.d.ts.map +1 -1
- package/dist/pipeline/phases/done.js +9 -4
- package/dist/pipeline/phases/done.js.map +1 -1
- package/dist/pipeline/phases/intake.d.ts +1 -0
- package/dist/pipeline/phases/intake.d.ts.map +1 -1
- package/dist/pipeline/phases/intake.js +56 -13
- package/dist/pipeline/phases/intake.js.map +1 -1
- package/dist/pipeline/phases/phase-context.d.ts +2 -0
- package/dist/pipeline/phases/phase-context.d.ts.map +1 -1
- package/dist/pipeline/phases/phase-context.js +3 -1
- package/dist/pipeline/phases/phase-context.js.map +1 -1
- package/dist/pipeline/phases/production-gate.d.ts.map +1 -1
- package/dist/pipeline/phases/production-gate.js +28 -3
- package/dist/pipeline/phases/production-gate.js.map +1 -1
- package/dist/pipeline/phases/qa-validation.d.ts.map +1 -1
- package/dist/pipeline/phases/qa-validation.js +38 -5
- package/dist/pipeline/phases/qa-validation.js.map +1 -1
- package/dist/pipeline/phases/recovery-loop.d.ts +2 -0
- package/dist/pipeline/phases/recovery-loop.d.ts.map +1 -1
- package/dist/pipeline/phases/recovery-loop.js +200 -6
- package/dist/pipeline/phases/recovery-loop.js.map +1 -1
- package/dist/pipeline/phases/review.d.ts.map +1 -1
- package/dist/pipeline/phases/review.js +58 -28
- package/dist/pipeline/phases/review.js.map +1 -1
- package/dist/pipeline/phases/role-planning.d.ts.map +1 -1
- package/dist/pipeline/phases/role-planning.js +20 -5
- package/dist/pipeline/phases/role-planning.js.map +1 -1
- package/dist/pipeline/phases/stuck.d.ts.map +1 -1
- package/dist/pipeline/phases/stuck.js +10 -0
- package/dist/pipeline/phases/stuck.js.map +1 -1
- package/dist/pipeline/repo-snapshot.d.ts.map +1 -1
- package/dist/pipeline/repo-snapshot.js +3 -0
- package/dist/pipeline/repo-snapshot.js.map +1 -1
- package/dist/pipeline/role-execution-adapter.d.ts +2 -1
- package/dist/pipeline/role-execution-adapter.d.ts.map +1 -1
- package/dist/pipeline/role-execution-adapter.js +22 -7
- package/dist/pipeline/role-execution-adapter.js.map +1 -1
- package/dist/pipeline/skill-loader.d.ts +19 -0
- package/dist/pipeline/skill-loader.d.ts.map +1 -1
- package/dist/pipeline/skill-loader.js +22 -0
- package/dist/pipeline/skill-loader.js.map +1 -1
- package/dist/pipeline/skills/constitution-generator.d.ts +51 -0
- package/dist/pipeline/skills/constitution-generator.d.ts.map +1 -0
- package/dist/pipeline/skills/constitution-generator.js +210 -0
- package/dist/pipeline/skills/constitution-generator.js.map +1 -0
- package/dist/pipeline/skills/coverage-gate.d.ts +44 -0
- package/dist/pipeline/skills/coverage-gate.d.ts.map +1 -0
- package/dist/pipeline/skills/coverage-gate.js +143 -0
- package/dist/pipeline/skills/coverage-gate.js.map +1 -0
- package/dist/pipeline/skills/generator.d.ts +65 -0
- package/dist/pipeline/skills/generator.d.ts.map +1 -0
- package/dist/pipeline/skills/generator.js +221 -0
- package/dist/pipeline/skills/generator.js.map +1 -0
- package/dist/pipeline/skills/role-map.d.ts +38 -0
- package/dist/pipeline/skills/role-map.d.ts.map +1 -0
- package/dist/pipeline/skills/role-map.js +234 -0
- package/dist/pipeline/skills/role-map.js.map +1 -0
- package/dist/pipeline/skills/types.d.ts +47 -0
- package/dist/pipeline/skills/types.d.ts.map +1 -0
- package/dist/pipeline/skills/types.js +5 -0
- package/dist/pipeline/skills/types.js.map +1 -0
- package/dist/pipeline/skills/usage-registry.d.ts +48 -0
- package/dist/pipeline/skills/usage-registry.d.ts.map +1 -0
- package/dist/pipeline/skills/usage-registry.js +55 -0
- package/dist/pipeline/skills/usage-registry.js.map +1 -0
- package/dist/pipeline/strategy-context.d.ts +20 -0
- package/dist/pipeline/strategy-context.d.ts.map +1 -0
- package/dist/pipeline/strategy-context.js +55 -0
- package/dist/pipeline/strategy-context.js.map +1 -0
- package/dist/pipeline/type-defs/artifacts.d.ts +30 -5
- package/dist/pipeline/type-defs/artifacts.d.ts.map +1 -1
- package/dist/pipeline/type-defs/artifacts.js +5 -0
- package/dist/pipeline/type-defs/artifacts.js.map +1 -1
- package/dist/pipeline/type-defs/audit.d.ts +28 -13
- package/dist/pipeline/type-defs/audit.d.ts.map +1 -1
- package/dist/pipeline/type-defs/checks.d.ts +19 -8
- package/dist/pipeline/type-defs/checks.d.ts.map +1 -1
- package/dist/pipeline/type-defs/checks.js +4 -0
- package/dist/pipeline/type-defs/checks.js.map +1 -1
- package/dist/pipeline/type-defs/packets.d.ts +119 -18
- package/dist/pipeline/type-defs/packets.d.ts.map +1 -1
- package/dist/pipeline/type-defs/packets.js +17 -1
- package/dist/pipeline/type-defs/packets.js.map +1 -1
- package/dist/pipeline/type-defs/state.d.ts +165 -16
- package/dist/pipeline/type-defs/state.d.ts.map +1 -1
- package/dist/pipeline/type-defs/state.js +26 -1
- package/dist/pipeline/type-defs/state.js.map +1 -1
- package/dist/shared/text-utils.d.ts +23 -0
- package/dist/shared/text-utils.d.ts.map +1 -0
- package/dist/shared/text-utils.js +66 -0
- package/dist/shared/text-utils.js.map +1 -0
- package/dist/shared/website-strategy-format.d.ts +18 -0
- package/dist/shared/website-strategy-format.d.ts.map +1 -0
- package/dist/shared/website-strategy-format.js +47 -0
- package/dist/shared/website-strategy-format.js.map +1 -0
- package/dist/state/index.d.ts +2 -0
- package/dist/state/index.d.ts.map +1 -1
- package/dist/state/index.js +57 -8
- package/dist/state/index.js.map +1 -1
- package/dist/types/consensus.d.ts +1 -0
- package/dist/types/consensus.d.ts.map +1 -1
- package/dist/types/consensus.js.map +1 -1
- package/dist/types/website-strategy.d.ts +1 -1
- package/dist/types/workflow.d.ts +447 -0
- package/dist/types/workflow.d.ts.map +1 -1
- package/dist/types/workflow.js +3 -0
- package/dist/types/workflow.js.map +1 -1
- package/dist/upgrade/handlers.d.ts.map +1 -1
- package/dist/upgrade/handlers.js +6 -3
- package/dist/upgrade/handlers.js.map +1 -1
- package/dist/workflow/consensus.d.ts.map +1 -1
- package/dist/workflow/consensus.js +1 -0
- package/dist/workflow/consensus.js.map +1 -1
- package/dist/workflow/website-strategy.d.ts.map +1 -1
- package/dist/workflow/website-strategy.js +2 -29
- package/dist/workflow/website-strategy.js.map +1 -1
- package/dist/workflow/website-updater.d.ts.map +1 -1
- package/dist/workflow/website-updater.js +3 -2
- package/dist/workflow/website-updater.js.map +1 -1
- package/package.json +1 -1
- package/src/adapters/gemini.ts +51 -6
- package/src/adapters/grok.ts +51 -6
- package/src/adapters/openai.ts +53 -5
- package/src/cli/commands/create.ts +1 -1
- package/src/cli/interactive.ts +337 -20
- package/src/generators/all.ts +25 -2
- package/src/generators/doc-parser.ts +75 -15
- package/src/generators/templates/fullstack.ts +1 -1
- package/src/generators/templates/website-components.ts +1 -1
- package/src/generators/templates/website-config.ts +23 -11
- package/src/generators/templates/website-conversion.ts +1 -1
- package/src/generators/templates/website-landing.ts +1 -1
- package/src/generators/templates/website-layout.ts +491 -23
- package/src/generators/templates/website-pricing.ts +1 -1
- package/src/generators/templates/website-sections.ts +1 -1
- package/src/generators/templates/website-seo.ts +4 -1
- package/src/generators/templates/website.ts +3 -0
- package/src/generators/website-content-ai.ts +186 -0
- package/src/generators/website-content-scanner.ts +113 -1
- package/src/generators/website-context.ts +151 -12
- package/src/generators/website-debug.ts +26 -0
- package/src/generators/website.ts +28 -3
- package/src/pipeline/artifact-manager.ts +3 -0
- package/src/pipeline/auto-recovery.ts +283 -0
- package/src/pipeline/change-request.ts +63 -1
- package/src/pipeline/check-runner.ts +141 -2
- package/src/pipeline/command-resolver.ts +34 -2
- package/src/pipeline/consensus/arbitrator-query.ts +101 -0
- package/src/pipeline/consensus/consensus-runner.ts +1099 -42
- package/src/pipeline/cr-lifecycle.ts +103 -0
- package/src/pipeline/gate-engine.ts +36 -8
- package/src/pipeline/migration.ts +5 -30
- package/src/pipeline/orchestrator.ts +367 -16
- package/src/pipeline/packets/consensus-packet-builder.ts +44 -18
- package/src/pipeline/phases/architecture.ts +6 -3
- package/src/pipeline/phases/audit.ts +6 -3
- package/src/pipeline/phases/consensus-architecture.ts +10 -1
- package/src/pipeline/phases/consensus-master-plan.ts +10 -3
- package/src/pipeline/phases/consensus-role-plans.ts +10 -1
- package/src/pipeline/phases/done.ts +15 -4
- package/src/pipeline/phases/intake.ts +67 -14
- package/src/pipeline/phases/phase-context.ts +6 -1
- package/src/pipeline/phases/production-gate.ts +41 -3
- package/src/pipeline/phases/qa-validation.ts +51 -5
- package/src/pipeline/phases/recovery-loop.ts +229 -7
- package/src/pipeline/phases/review.ts +73 -30
- package/src/pipeline/phases/role-planning.ts +23 -5
- package/src/pipeline/phases/stuck.ts +10 -0
- package/src/pipeline/repo-snapshot.ts +3 -0
- package/src/pipeline/role-execution-adapter.ts +30 -4
- package/src/pipeline/skill-loader.ts +33 -0
- package/src/pipeline/skills/constitution-generator.ts +236 -0
- package/src/pipeline/skills/coverage-gate.ts +199 -0
- package/src/pipeline/skills/generator.ts +287 -0
- package/src/pipeline/skills/role-map.ts +248 -0
- package/src/pipeline/skills/types.ts +53 -0
- package/src/pipeline/skills/usage-registry.ts +87 -0
- package/src/pipeline/strategy-context.ts +60 -0
- package/src/pipeline/type-defs/artifacts.ts +5 -0
- package/src/pipeline/type-defs/checks.ts +4 -0
- package/src/pipeline/type-defs/packets.ts +18 -1
- package/src/pipeline/type-defs/state.ts +26 -1
- package/src/shared/text-utils.ts +70 -0
- package/src/shared/website-strategy-format.ts +56 -0
- package/src/state/index.ts +60 -8
- package/src/types/consensus.ts +1 -0
- package/src/types/workflow.ts +6 -0
- package/src/upgrade/handlers.ts +9 -3
- package/src/workflow/consensus.ts +1 -0
- package/src/workflow/website-strategy.ts +2 -36
- package/src/workflow/website-updater.ts +4 -2
- package/tests/adapters/gemini.test.ts +165 -0
- package/tests/adapters/grok.test.ts +137 -0
- package/tests/adapters/openai.test.ts +128 -0
- package/tests/generators/doc-parser.test.ts +88 -9
- package/tests/generators/quality-gate.test.ts +19 -3
- package/tests/generators/website-components.test.ts +34 -0
- package/tests/generators/website-content-ai.test.ts +308 -0
- package/tests/generators/website-content-scanner.test.ts +86 -0
- package/tests/generators/website-context.test.ts +3 -2
- package/tests/integration/smokestack-scaffold.test.ts +385 -0
- package/tests/pipeline/auto-recovery.test.ts +337 -0
- package/tests/pipeline/change-request.test.ts +70 -0
- package/tests/pipeline/command-resolver.test.ts +42 -0
- package/tests/pipeline/consensus/arbitrator-query.test.ts +107 -0
- package/tests/pipeline/consensus-runner.test.ts +1333 -10
- package/tests/pipeline/consensus-scoring.test.ts +602 -18
- package/tests/pipeline/gate-engine.test.ts +34 -0
- package/tests/pipeline/install-check.test.ts +261 -0
- package/tests/pipeline/migration.test.ts +4 -3
- package/tests/pipeline/orchestrator.test.ts +1506 -15
- package/tests/pipeline/packets/builders.test.ts +29 -6
- package/tests/pipeline/phases/role-planning.strategy.test.ts +204 -0
- package/tests/pipeline/pipeline-persistence.test.ts +230 -0
- package/tests/pipeline/recovery-loop-guidance.test.ts +280 -0
- package/tests/pipeline/role-execution-adapter.test.ts +88 -0
- package/tests/pipeline/skills/constitution-generator.test.ts +201 -0
- package/tests/pipeline/skills/coverage-gate.test.ts +370 -0
- package/tests/pipeline/skills/generator.test.ts +213 -0
- package/tests/pipeline/skills/role-map.test.ts +198 -0
- package/tests/pipeline/skills/usage-registry.test.ts +114 -0
- package/tests/pipeline/strategy-context.test.ts +148 -0
- package/tests/shared/text-utils.test.ts +155 -0
- package/tests/state/progress-analysis.test.ts +375 -0
- package/tests/upgrade/handlers.test.ts +33 -2
- package/tests/workflow/consensus.test.ts +6 -0
- package/tsconfig.json +1 -1
|
@@ -13,7 +13,7 @@ import type { AuditFinding, ArtifactEntry, ChangeRequest } from '../types.js';
|
|
|
13
13
|
import type { ArtifactManager } from '../artifact-manager.js';
|
|
14
14
|
|
|
15
15
|
export async function runAudit(context: PhaseContext): Promise<PhaseResult> {
|
|
16
|
-
const { pipeline, artifactManager, skillLoader, projectDir } = context;
|
|
16
|
+
const { pipeline, artifactManager, skillLoader, skillUsageRegistry, projectDir } = context;
|
|
17
17
|
const artifacts = [];
|
|
18
18
|
|
|
19
19
|
try {
|
|
@@ -23,8 +23,8 @@ export async function runAudit(context: PhaseContext): Promise<PhaseResult> {
|
|
|
23
23
|
artifacts.push(snapshotEntry);
|
|
24
24
|
pipeline.latestRepoSnapshot = artifactManager.toArtifactRef(snapshotEntry);
|
|
25
25
|
|
|
26
|
-
// 2. Load auditor skill
|
|
27
|
-
const auditorSkill = skillLoader.
|
|
26
|
+
// 2. Load auditor skill with metadata
|
|
27
|
+
const { definition: auditorSkill, meta: auditorMeta } = skillLoader.loadSkillWithMeta('AUDITOR');
|
|
28
28
|
|
|
29
29
|
// 3. Run audit checks via Claude
|
|
30
30
|
const { executePrompt } = await import('../../adapters/claude.js');
|
|
@@ -53,6 +53,9 @@ export async function runAudit(context: PhaseContext): Promise<PhaseResult> {
|
|
|
53
53
|
const auditResult = await executePrompt(auditPrompt);
|
|
54
54
|
const auditResponse = auditResult.response;
|
|
55
55
|
|
|
56
|
+
// Record skill usage — auditor skill injected into audit prompt
|
|
57
|
+
skillUsageRegistry.record('AUDITOR', 'AUDIT', 'system_prompt', auditorMeta.source, auditorMeta.version);
|
|
58
|
+
|
|
56
59
|
// 4. Parse findings from audit response (simplified extraction)
|
|
57
60
|
const findings = parseAuditFindings(auditResponse);
|
|
58
61
|
|
|
@@ -44,6 +44,7 @@ export async function runConsensusArchitecture(context: PhaseContext): Promise<P
|
|
|
44
44
|
const masterPlanArtifact = pipeline.artifacts.find((a) => a.type === 'master_plan');
|
|
45
45
|
|
|
46
46
|
// 3. Build plan packet
|
|
47
|
+
// v2.4.4: version tracks plan revision count for recovery loop convergence
|
|
47
48
|
const planPacket = buildPlanPacket({
|
|
48
49
|
phase: 'CONSENSUS_ARCHITECTURE',
|
|
49
50
|
submittedBy: 'ARCHITECT',
|
|
@@ -61,11 +62,18 @@ export async function runConsensusArchitecture(context: PhaseContext): Promise<P
|
|
|
61
62
|
],
|
|
62
63
|
dependencies: [],
|
|
63
64
|
constraints: [],
|
|
65
|
+
version: pipeline.recoveryCount + 1,
|
|
64
66
|
});
|
|
65
67
|
|
|
66
68
|
// 4. Run consensus
|
|
69
|
+
// v2.4.4: pass revisionDirective from sessionGuidance so reviewers see prior feedback
|
|
67
70
|
const gateDef = gateEngine.getGateDefinition('CONSENSUS_ARCHITECTURE');
|
|
68
|
-
const
|
|
71
|
+
const revisionDirective = pipeline.recoveryCount > 0 && pipeline.sessionGuidance?.trim()
|
|
72
|
+
? pipeline.sessionGuidance
|
|
73
|
+
: undefined;
|
|
74
|
+
const consensusPacket = await consensusRunner.runStructuredConsensus(planPacket, gateDef, {
|
|
75
|
+
revisionDirective,
|
|
76
|
+
});
|
|
69
77
|
|
|
70
78
|
// 5. Store consensus artifact
|
|
71
79
|
const consensusEntry = artifactManager.createAndStoreJson(
|
|
@@ -85,6 +93,7 @@ export async function runConsensusArchitecture(context: PhaseContext): Promise<P
|
|
|
85
93
|
missingArtifacts: [],
|
|
86
94
|
failedChecks: [],
|
|
87
95
|
consensusScore: consensusPacket.consensus_result.score,
|
|
96
|
+
finalStatus: consensusPacket.final_status, // v2.4.3: propagate for gate engine
|
|
88
97
|
timestamp: new Date().toISOString(),
|
|
89
98
|
};
|
|
90
99
|
|
|
@@ -35,13 +35,14 @@ export async function runConsensusMasterPlan(context: PhaseContext): Promise<Pha
|
|
|
35
35
|
artifacts.push(snapshotEntry);
|
|
36
36
|
pipeline.latestRepoSnapshot = artifactManager.toArtifactRef(snapshotEntry);
|
|
37
37
|
|
|
38
|
-
// 2. Find master plan artifact
|
|
39
|
-
const masterPlanArtifact = pipeline.artifacts.find((a) => a.type === 'master_plan');
|
|
38
|
+
// 2. Find latest master plan artifact (v2.4.3: reverse to get latest revision, not stale v1)
|
|
39
|
+
const masterPlanArtifact = [...pipeline.artifacts].reverse().find((a) => a.type === 'master_plan');
|
|
40
40
|
if (!masterPlanArtifact) {
|
|
41
41
|
return failureResult('CONSENSUS_MASTER_PLAN', 'No master plan artifact found');
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
// 3. Build plan packet
|
|
45
|
+
// v2.4.2: version tracks plan revision count for recovery loop convergence
|
|
45
46
|
const planPacket = buildPlanPacket({
|
|
46
47
|
phase: 'CONSENSUS_MASTER_PLAN',
|
|
47
48
|
submittedBy: 'DISPATCHER',
|
|
@@ -57,11 +58,16 @@ export async function runConsensusMasterPlan(context: PhaseContext): Promise<Pha
|
|
|
57
58
|
],
|
|
58
59
|
dependencies: [],
|
|
59
60
|
constraints: [],
|
|
61
|
+
version: pipeline.recoveryCount + 1,
|
|
60
62
|
});
|
|
61
63
|
|
|
62
64
|
// 4. Run structured consensus
|
|
65
|
+
// v2.4.2: pass revisionDirective from sessionGuidance so reviewers see prior feedback
|
|
63
66
|
const gateDef = gateEngine.getGateDefinition('CONSENSUS_MASTER_PLAN');
|
|
64
|
-
const
|
|
67
|
+
const revisionDirective = pipeline.recoveryCount > 0 ? pipeline.sessionGuidance : undefined;
|
|
68
|
+
const consensusPacket = await consensusRunner.runStructuredConsensus(planPacket, gateDef, {
|
|
69
|
+
revisionDirective,
|
|
70
|
+
});
|
|
65
71
|
|
|
66
72
|
// 5. Store consensus artifact
|
|
67
73
|
const consensusEntry = artifactManager.createAndStoreJson(
|
|
@@ -81,6 +87,7 @@ export async function runConsensusMasterPlan(context: PhaseContext): Promise<Pha
|
|
|
81
87
|
missingArtifacts: [],
|
|
82
88
|
failedChecks: [],
|
|
83
89
|
consensusScore: consensusPacket.consensus_result.score,
|
|
90
|
+
finalStatus: consensusPacket.final_status, // v2.4.3: propagate for gate engine
|
|
84
91
|
timestamp: new Date().toISOString(),
|
|
85
92
|
};
|
|
86
93
|
|
|
@@ -44,6 +44,7 @@ export async function runConsensusRolePlans(context: PhaseContext): Promise<Phas
|
|
|
44
44
|
const masterPlanArtifact = pipeline.artifacts.find((a) => a.type === 'master_plan');
|
|
45
45
|
|
|
46
46
|
// 3. Build plan packet referencing all role plans
|
|
47
|
+
// v2.4.4: version tracks plan revision count for recovery loop convergence
|
|
47
48
|
const planPacket = buildPlanPacket({
|
|
48
49
|
phase: 'CONSENSUS_ROLE_PLANS',
|
|
49
50
|
submittedBy: 'DISPATCHER',
|
|
@@ -62,11 +63,18 @@ export async function runConsensusRolePlans(context: PhaseContext): Promise<Phas
|
|
|
62
63
|
],
|
|
63
64
|
dependencies: [],
|
|
64
65
|
constraints: [],
|
|
66
|
+
version: pipeline.recoveryCount + 1,
|
|
65
67
|
});
|
|
66
68
|
|
|
67
69
|
// 4. Run consensus
|
|
70
|
+
// v2.4.4: pass revisionDirective from sessionGuidance so reviewers see prior feedback
|
|
68
71
|
const gateDef = gateEngine.getGateDefinition('CONSENSUS_ROLE_PLANS');
|
|
69
|
-
const
|
|
72
|
+
const revisionDirective = pipeline.recoveryCount > 0 && pipeline.sessionGuidance?.trim()
|
|
73
|
+
? pipeline.sessionGuidance
|
|
74
|
+
: undefined;
|
|
75
|
+
const consensusPacket = await consensusRunner.runStructuredConsensus(planPacket, gateDef, {
|
|
76
|
+
revisionDirective,
|
|
77
|
+
});
|
|
70
78
|
|
|
71
79
|
// 5. Store consensus artifact
|
|
72
80
|
const consensusEntry = artifactManager.createAndStoreJson(
|
|
@@ -86,6 +94,7 @@ export async function runConsensusRolePlans(context: PhaseContext): Promise<Phas
|
|
|
86
94
|
missingArtifacts: [],
|
|
87
95
|
failedChecks: [],
|
|
88
96
|
consensusScore: consensusPacket.consensus_result.score,
|
|
97
|
+
finalStatus: consensusPacket.final_status, // v2.4.3: propagate for gate engine
|
|
89
98
|
timestamp: new Date().toISOString(),
|
|
90
99
|
};
|
|
91
100
|
|
|
@@ -7,12 +7,12 @@ import type { PhaseContext, PhaseResult } from './phase-context.js';
|
|
|
7
7
|
import { successResult, failureResult } from './phase-context.js';
|
|
8
8
|
|
|
9
9
|
export async function runDone(context: PhaseContext): Promise<PhaseResult> {
|
|
10
|
-
const { pipeline, artifactManager, skillLoader } = context;
|
|
10
|
+
const { pipeline, artifactManager, skillLoader, skillUsageRegistry } = context;
|
|
11
11
|
const artifacts = [];
|
|
12
12
|
|
|
13
13
|
try {
|
|
14
|
-
// 1. Load release manager skill
|
|
15
|
-
const rmSkill = skillLoader.
|
|
14
|
+
// 1. Load release manager skill with metadata
|
|
15
|
+
const { definition: rmSkill, meta: rmMeta } = skillLoader.loadSkillWithMeta('RELEASE_MANAGER');
|
|
16
16
|
|
|
17
17
|
// 2. Generate release notes
|
|
18
18
|
const { executePrompt } = await import('../../adapters/claude.js');
|
|
@@ -31,6 +31,9 @@ export async function runDone(context: PhaseContext): Promise<PhaseResult> {
|
|
|
31
31
|
const releaseResult = await executePrompt(releasePrompt);
|
|
32
32
|
const releaseResponse = releaseResult.response;
|
|
33
33
|
|
|
34
|
+
// Record skill usage — release manager skill injected into prompt
|
|
35
|
+
skillUsageRegistry.record('RELEASE_MANAGER', 'DONE', 'system_prompt', rmMeta.source, rmMeta.version);
|
|
36
|
+
|
|
34
37
|
// 3. Create release notes artifact
|
|
35
38
|
const releaseEntry = artifactManager.createAndStoreText(
|
|
36
39
|
'release_notes',
|
|
@@ -55,9 +58,17 @@ export async function runDone(context: PhaseContext): Promise<PhaseResult> {
|
|
|
55
58
|
);
|
|
56
59
|
artifacts.push(rollbackEntry);
|
|
57
60
|
|
|
61
|
+
// 6. Store skill usage log artifact
|
|
62
|
+
const usageLogEntry = artifactManager.createAndStoreJson(
|
|
63
|
+
'skill_usage_log',
|
|
64
|
+
pipeline.skillUsageEvents ?? [],
|
|
65
|
+
'DONE',
|
|
66
|
+
);
|
|
67
|
+
artifacts.push(usageLogEntry);
|
|
68
|
+
|
|
58
69
|
pipeline.artifacts.push(...artifacts);
|
|
59
70
|
|
|
60
|
-
//
|
|
71
|
+
// 7. Final INDEX.md update
|
|
61
72
|
artifactManager.updateIndex(pipeline.artifacts);
|
|
62
73
|
|
|
63
74
|
return successResult('DONE', artifacts, 'Pipeline complete. Release artifacts created.');
|
|
@@ -2,12 +2,19 @@
|
|
|
2
2
|
* INTAKE phase — normalize user prompt into structured Master Plan v1.
|
|
3
3
|
* Reuses expandIdea() and createPlan() from workflow.
|
|
4
4
|
* v1.1: Creates constitution artifact and stores hash.
|
|
5
|
+
* v1.2: Generates project-specific skills and constitution.
|
|
5
6
|
*/
|
|
6
7
|
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
|
|
7
10
|
import type { PhaseContext, PhaseResult } from './phase-context.js';
|
|
8
11
|
import { successResult, failureResult } from './phase-context.js';
|
|
9
12
|
import { generateRepoSnapshot, createSnapshotArtifact } from '../repo-snapshot.js';
|
|
10
13
|
import { createConstitutionArtifact, computeConstitutionHash } from '../constitution.js';
|
|
14
|
+
import { getActiveRoles, inferTechStack } from '../skills/role-map.js';
|
|
15
|
+
import { generateProjectSkills } from '../skills/generator.js';
|
|
16
|
+
import { generateConstitution } from '../skills/constitution-generator.js';
|
|
17
|
+
import type { OutputLanguage } from '../../types/project.js';
|
|
11
18
|
|
|
12
19
|
export async function runIntake(context: PhaseContext): Promise<PhaseResult> {
|
|
13
20
|
const { projectDir, pipeline, artifactManager } = context;
|
|
@@ -20,14 +27,7 @@ export async function runIntake(context: PhaseContext): Promise<PhaseResult> {
|
|
|
20
27
|
artifacts.push(snapshotEntry);
|
|
21
28
|
pipeline.latestRepoSnapshot = artifactManager.toArtifactRef(snapshotEntry);
|
|
22
29
|
|
|
23
|
-
// 2.
|
|
24
|
-
const constitutionEntry = createConstitutionArtifact(projectDir, artifactManager);
|
|
25
|
-
if (constitutionEntry) {
|
|
26
|
-
artifacts.push(constitutionEntry);
|
|
27
|
-
}
|
|
28
|
-
pipeline.constitutionHash = computeConstitutionHash(projectDir);
|
|
29
|
-
|
|
30
|
-
// 3. Store additional_context artifact if session guidance provided
|
|
30
|
+
// 2. Store additional_context artifact if session guidance provided
|
|
31
31
|
const guidance = pipeline.sessionGuidance ?? '';
|
|
32
32
|
if (guidance) {
|
|
33
33
|
const ctxEntry = artifactManager.createAndStoreText(
|
|
@@ -38,6 +38,9 @@ export async function runIntake(context: PhaseContext): Promise<PhaseResult> {
|
|
|
38
38
|
artifacts.push(ctxEntry);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
// 3. Push pre-AI artifacts to pipeline state now (survives if AI calls fail below)
|
|
42
|
+
pipeline.artifacts.push(...artifacts);
|
|
43
|
+
|
|
41
44
|
// 4. Expand idea using existing workflow
|
|
42
45
|
const { expandIdea, createPlan } = await import('../../workflow/plan-mode.js');
|
|
43
46
|
const expandedIdea = await expandIdea(
|
|
@@ -45,20 +48,70 @@ export async function runIntake(context: PhaseContext): Promise<PhaseResult> {
|
|
|
45
48
|
context.state.language,
|
|
46
49
|
);
|
|
47
50
|
|
|
48
|
-
// 5.
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
// 5. Determine active roles
|
|
52
|
+
const language = context.state.language as OutputLanguage;
|
|
53
|
+
pipeline.activeRoles = getActiveRoles(language);
|
|
54
|
+
|
|
55
|
+
// 6-8. Generate project-specific skills and constitution (non-fatal)
|
|
56
|
+
const skillsDir = join(projectDir, 'skills');
|
|
57
|
+
try {
|
|
58
|
+
const projectName = context.state.name ?? 'Project';
|
|
59
|
+
|
|
60
|
+
await generateProjectSkills(
|
|
61
|
+
{
|
|
62
|
+
language,
|
|
63
|
+
expandedSpec: expandedIdea,
|
|
64
|
+
snapshot,
|
|
65
|
+
sessionGuidance: guidance || undefined,
|
|
66
|
+
activeRoles: pipeline.activeRoles,
|
|
67
|
+
skillsDir,
|
|
68
|
+
projectName,
|
|
69
|
+
},
|
|
70
|
+
artifactManager,
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
const techStack = inferTechStack(language, snapshot, expandedIdea);
|
|
74
|
+
generateConstitution({
|
|
75
|
+
language,
|
|
76
|
+
projectName,
|
|
77
|
+
techStack,
|
|
78
|
+
expandedSpec: expandedIdea,
|
|
79
|
+
sessionGuidance: guidance || undefined,
|
|
80
|
+
skillsDir,
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// Clear skill loader cache so it picks up new .md files
|
|
84
|
+
context.skillLoader.clearCache();
|
|
85
|
+
} catch {
|
|
86
|
+
// Skill/constitution generation is non-fatal — pipeline continues with defaults
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// 9. Create constitution artifact and store hash (AFTER generation)
|
|
90
|
+
const constitutionEntry = createConstitutionArtifact(projectDir, artifactManager);
|
|
91
|
+
if (constitutionEntry) {
|
|
92
|
+
artifacts.push(constitutionEntry);
|
|
93
|
+
pipeline.artifacts.push(constitutionEntry);
|
|
94
|
+
}
|
|
95
|
+
pipeline.constitutionHash = computeConstitutionHash(projectDir);
|
|
96
|
+
|
|
97
|
+
// 10. Create master plan — prepend guidance so planner sees constraints first
|
|
98
|
+
// Detect revision directive and instruct plan to include "Addressed Reviewer Feedback" section
|
|
99
|
+
const isRevision = guidance.includes('--- REVISION DIRECTIVE ---');
|
|
100
|
+
const planInput = isRevision
|
|
101
|
+
? `${guidance}\n\nIMPORTANT: Include a "## Addressed Reviewer Feedback" section mapping each Required Change to the concrete revision made.\n\n${expandedIdea}`
|
|
102
|
+
: guidance
|
|
103
|
+
? `${guidance}\n\n---\n\n${expandedIdea}`
|
|
104
|
+
: expandedIdea;
|
|
52
105
|
const plan = await createPlan(planInput, '', context.state.language);
|
|
53
106
|
|
|
54
|
-
//
|
|
107
|
+
// 11. Store master plan as artifact
|
|
55
108
|
const planEntry = artifactManager.createAndStoreText(
|
|
56
109
|
'master_plan',
|
|
57
110
|
plan,
|
|
58
111
|
'INTAKE',
|
|
59
112
|
);
|
|
60
113
|
artifacts.push(planEntry);
|
|
61
|
-
pipeline.artifacts.push(
|
|
114
|
+
pipeline.artifacts.push(planEntry);
|
|
62
115
|
|
|
63
116
|
return successResult('INTAKE', artifacts, 'Master Plan v1 created');
|
|
64
117
|
} catch (err) {
|
|
@@ -8,6 +8,7 @@ import type { GateEngine } from '../gate-engine.js';
|
|
|
8
8
|
import type { SkillLoader } from '../skill-loader.js';
|
|
9
9
|
import type { ConsensusRunner } from '../consensus/consensus-runner.js';
|
|
10
10
|
import type { ProjectState } from '../../types/workflow.js';
|
|
11
|
+
import type { SkillUsageRegistry } from '../skills/usage-registry.js';
|
|
11
12
|
|
|
12
13
|
// ─── PhaseContext ────────────────────────────────────────
|
|
13
14
|
|
|
@@ -19,6 +20,7 @@ export interface PhaseContext {
|
|
|
19
20
|
artifactManager: ArtifactManager;
|
|
20
21
|
gateEngine: GateEngine;
|
|
21
22
|
consensusRunner: ConsensusRunner;
|
|
23
|
+
skillUsageRegistry: SkillUsageRegistry;
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
// ─── PhaseResult ─────────────────────────────────────────
|
|
@@ -39,7 +41,7 @@ export async function triggerJournalist(
|
|
|
39
41
|
artifacts: ArtifactEntry[],
|
|
40
42
|
context: PhaseContext,
|
|
41
43
|
): Promise<ArtifactEntry | null> {
|
|
42
|
-
const skill = context.skillLoader.
|
|
44
|
+
const { definition: skill, meta } = context.skillLoader.loadSkillWithMeta('JOURNALIST');
|
|
43
45
|
|
|
44
46
|
const traceContent = [
|
|
45
47
|
`# Journalist Trace — ${phase}`,
|
|
@@ -55,6 +57,9 @@ export async function triggerJournalist(
|
|
|
55
57
|
`${skill.systemPrompt.slice(0, 200)}...`,
|
|
56
58
|
].join('\n');
|
|
57
59
|
|
|
60
|
+
// Record skill usage — journalist skill injected into trace context
|
|
61
|
+
context.skillUsageRegistry.record('JOURNALIST', phase, 'other', meta.source, meta.version);
|
|
62
|
+
|
|
58
63
|
const entry = context.artifactManager.createAndStoreText(
|
|
59
64
|
'journalist_trace',
|
|
60
65
|
traceContent,
|
|
@@ -4,10 +4,22 @@
|
|
|
4
4
|
* v1.1: Adds start check and env check.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import { join } from 'node:path';
|
|
8
|
+
import { existsSync } from 'node:fs';
|
|
9
|
+
|
|
7
10
|
import type { PhaseContext, PhaseResult } from './phase-context.js';
|
|
8
11
|
import { successResult, failureResult, triggerJournalist } from './phase-context.js';
|
|
9
12
|
import { resolveCommands } from '../command-resolver.js';
|
|
10
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
runAllChecks,
|
|
15
|
+
runPlaceholderScan,
|
|
16
|
+
runStartCheck,
|
|
17
|
+
runEnvCheck,
|
|
18
|
+
runCheck,
|
|
19
|
+
storeCheckResults,
|
|
20
|
+
shouldSkipInstall,
|
|
21
|
+
writeInstallMarker,
|
|
22
|
+
} from '../check-runner.js';
|
|
11
23
|
import { generateRepoSnapshot } from '../repo-snapshot.js';
|
|
12
24
|
|
|
13
25
|
export async function runProductionGate(context: PhaseContext): Promise<PhaseResult> {
|
|
@@ -20,6 +32,25 @@ export async function runProductionGate(context: PhaseContext): Promise<PhaseRes
|
|
|
20
32
|
const commands = resolveCommands(snapshot);
|
|
21
33
|
pipeline.resolvedCommands = commands;
|
|
22
34
|
|
|
35
|
+
// 1.5. Install dependencies if needed (skips if unchanged since QA_VALIDATION)
|
|
36
|
+
if (commands.install) {
|
|
37
|
+
const installCwd = commands.install_cwd
|
|
38
|
+
? join(projectDir, commands.install_cwd)
|
|
39
|
+
: projectDir;
|
|
40
|
+
const skipInstall = shouldSkipInstall(projectDir, snapshot);
|
|
41
|
+
if (!skipInstall) {
|
|
42
|
+
const installResult = await runCheck('install', commands.install, installCwd);
|
|
43
|
+
if (installResult.status === 'fail') {
|
|
44
|
+
const stored = storeCheckResults([installResult], artifactManager, 'PRODUCTION_GATE');
|
|
45
|
+
artifacts.push(...stored);
|
|
46
|
+
pipeline.artifacts.push(...artifacts);
|
|
47
|
+
pipeline.gateChecks['PRODUCTION_GATE'] = [installResult];
|
|
48
|
+
return failureResult('PRODUCTION_GATE', 'Dependency installation failed', installResult.stderr_summary ?? '');
|
|
49
|
+
}
|
|
50
|
+
writeInstallMarker(projectDir, snapshot);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
23
54
|
// 2. Run all checks
|
|
24
55
|
const checkResults = await runAllChecks(commands, projectDir);
|
|
25
56
|
|
|
@@ -52,7 +83,14 @@ export async function runProductionGate(context: PhaseContext): Promise<PhaseRes
|
|
|
52
83
|
);
|
|
53
84
|
const hasPlaceholders = placeholderResult.status === 'fail';
|
|
54
85
|
const auditPassed = pipeline.artifacts.some((a) => a.type === 'audit_report');
|
|
55
|
-
|
|
86
|
+
|
|
87
|
+
// Detect website projects — placeholder_scan blocks for these
|
|
88
|
+
const isWebsiteProject =
|
|
89
|
+
existsSync(join(projectDir, 'next.config.mjs')) ||
|
|
90
|
+
existsSync(join(projectDir, 'next.config.js')) ||
|
|
91
|
+
existsSync(join(projectDir, 'src', 'app', 'layout.tsx'));
|
|
92
|
+
const placeholderBlocking = hasPlaceholders && isWebsiteProject;
|
|
93
|
+
const passed = failedChecks.length === 0 && auditPassed && !placeholderBlocking;
|
|
56
94
|
|
|
57
95
|
// 9. Create production readiness report
|
|
58
96
|
const report = [
|
|
@@ -77,7 +115,7 @@ export async function runProductionGate(context: PhaseContext): Promise<PhaseRes
|
|
|
77
115
|
`- Env: ${findCheckStatus(checkResults, 'env_check')}`,
|
|
78
116
|
`- Start: ${findCheckStatus(checkResults, 'start')}`,
|
|
79
117
|
`- Audit: ${auditPassed ? 'PASS' : 'MISSING'}`,
|
|
80
|
-
`- Placeholders: ${hasPlaceholders ? 'WARNING' : 'CLEAN'}`,
|
|
118
|
+
`- Placeholders: ${hasPlaceholders ? (placeholderBlocking ? 'FAIL (blocking for website)' : 'WARNING') : 'CLEAN'}`,
|
|
81
119
|
].join('\n');
|
|
82
120
|
|
|
83
121
|
const reportEntry = artifactManager.createAndStoreText(
|
|
@@ -3,23 +3,60 @@
|
|
|
3
3
|
* Runs tests via checkRunner. Creates qa_validation artifact.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
import { join } from 'node:path';
|
|
7
|
+
|
|
6
8
|
import type { PhaseContext, PhaseResult } from './phase-context.js';
|
|
7
9
|
import { successResult, failureResult } from './phase-context.js';
|
|
8
10
|
import { resolveCommands } from '../command-resolver.js';
|
|
9
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
runCheck,
|
|
13
|
+
storeCheckResults,
|
|
14
|
+
shouldSkipInstall,
|
|
15
|
+
writeInstallMarker,
|
|
16
|
+
invalidateInstallMarker,
|
|
17
|
+
} from '../check-runner.js';
|
|
10
18
|
import { generateRepoSnapshot } from '../repo-snapshot.js';
|
|
11
19
|
|
|
12
20
|
export async function runQaValidation(context: PhaseContext): Promise<PhaseResult> {
|
|
13
|
-
const { pipeline, artifactManager, projectDir } = context;
|
|
21
|
+
const { pipeline, artifactManager, skillLoader, skillUsageRegistry, projectDir } = context;
|
|
14
22
|
const artifacts = [];
|
|
15
23
|
|
|
16
24
|
try {
|
|
17
|
-
// 1.
|
|
25
|
+
// 1. Load QA_TESTER skill and record usage
|
|
26
|
+
const { definition: _qaSkill, meta: qaMeta } = skillLoader.loadSkillWithMeta('QA_TESTER');
|
|
27
|
+
skillUsageRegistry.record('QA_TESTER', 'QA_VALIDATION', 'system_prompt', qaMeta.source, qaMeta.version);
|
|
28
|
+
|
|
29
|
+
// 2. Resolve test command
|
|
18
30
|
const snapshot = await generateRepoSnapshot(projectDir);
|
|
19
31
|
const commands = resolveCommands(snapshot);
|
|
20
32
|
pipeline.resolvedCommands = commands;
|
|
21
33
|
|
|
22
|
-
// 2.
|
|
34
|
+
// 2.5. Install dependencies if needed
|
|
35
|
+
if (commands.install) {
|
|
36
|
+
const installCwd = commands.install_cwd
|
|
37
|
+
? join(projectDir, commands.install_cwd)
|
|
38
|
+
: projectDir;
|
|
39
|
+
const skipInstall = shouldSkipInstall(projectDir, snapshot);
|
|
40
|
+
if (!skipInstall) {
|
|
41
|
+
const installResult = await runCheck('install', commands.install, installCwd);
|
|
42
|
+
const stored = storeCheckResults([installResult], artifactManager, 'QA_VALIDATION');
|
|
43
|
+
artifacts.push(...stored);
|
|
44
|
+
|
|
45
|
+
if (!pipeline.gateChecks['QA_VALIDATION']) {
|
|
46
|
+
pipeline.gateChecks['QA_VALIDATION'] = [];
|
|
47
|
+
}
|
|
48
|
+
pipeline.gateChecks['QA_VALIDATION'].push(installResult);
|
|
49
|
+
|
|
50
|
+
if (installResult.status === 'fail') {
|
|
51
|
+
pipeline.artifacts.push(...artifacts);
|
|
52
|
+
return failureResult('QA_VALIDATION', 'Dependency installation failed', installResult.stderr_summary ?? '');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
writeInstallMarker(projectDir, snapshot);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// 3. Run test command
|
|
23
60
|
if (commands.test) {
|
|
24
61
|
const testResult = await runCheck('test', commands.test, projectDir);
|
|
25
62
|
const stored = storeCheckResults([testResult], artifactManager, 'QA_VALIDATION');
|
|
@@ -30,9 +67,18 @@ export async function runQaValidation(context: PhaseContext): Promise<PhaseResul
|
|
|
30
67
|
pipeline.gateChecks['QA_VALIDATION'] = [];
|
|
31
68
|
}
|
|
32
69
|
pipeline.gateChecks['QA_VALIDATION'].push(testResult);
|
|
70
|
+
|
|
71
|
+
// Invalidate install marker on missing-module errors
|
|
72
|
+
if (testResult.status === 'fail' && testResult.stderr_summary) {
|
|
73
|
+
const missingModule = /Cannot find module|ModuleNotFoundError|Failed to resolve import/
|
|
74
|
+
.test(testResult.stderr_summary);
|
|
75
|
+
if (missingModule) {
|
|
76
|
+
invalidateInstallMarker(projectDir);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
33
79
|
}
|
|
34
80
|
|
|
35
|
-
//
|
|
81
|
+
// 4. Create QA validation summary artifact
|
|
36
82
|
const qaReport = [
|
|
37
83
|
'# QA Validation Report',
|
|
38
84
|
'',
|