supipowers 1.5.2 → 2.0.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/README.md +14 -8
- package/bin/install.mjs +20 -5
- package/bin/install.ts +95 -0
- package/package.json +8 -4
- package/skills/context-mode/SKILL.md +17 -10
- package/skills/harness/SKILL.md +94 -0
- package/skills/ui-design/SKILL.md +63 -0
- package/skills/ui-design/sub-agent-templates/component-builder.md +29 -0
- package/skills/ui-design/sub-agent-templates/design-critic.md +46 -0
- package/skills/ui-design/sub-agent-templates/pencil/component-builder.md +29 -0
- package/skills/ui-design/sub-agent-templates/pencil/design-critic.md +42 -0
- package/skills/ui-design/sub-agent-templates/pencil/section-assembler.md +27 -0
- package/skills/ui-design/sub-agent-templates/section-assembler.md +27 -0
- package/skills/ultraplan-discover/SKILL.md +96 -0
- package/skills/ultraplan-intake/SKILL.md +89 -0
- package/skills/ultraplan-research/SKILL.md +129 -0
- package/skills/ultraplan-review/SKILL.md +86 -0
- package/skills/ultraplan-review-scope/SKILL.md +111 -0
- package/skills/ultraplan-review-structure/SKILL.md +120 -0
- package/skills/ultraplan-review-tdd/SKILL.md +142 -0
- package/skills/ultraplan-scout/SKILL.md +110 -0
- package/skills/ultraplan-synthesize/SKILL.md +124 -0
- package/src/{quality/ai-session.ts → ai/final-message.ts} +27 -0
- package/src/ai/schema-text.ts +129 -0
- package/src/ai/structured-output.ts +274 -0
- package/src/ai/template.ts +27 -0
- package/src/bootstrap.ts +63 -28
- package/src/commands/agents.ts +149 -45
- package/src/commands/ai-review.ts +251 -30
- package/src/commands/clear.ts +434 -0
- package/src/commands/commit.ts +1 -0
- package/src/commands/config.ts +242 -44
- package/src/commands/context.ts +55 -28
- package/src/commands/doctor.ts +234 -6
- package/src/commands/fix-pr.ts +306 -131
- package/src/commands/generate.ts +111 -21
- package/src/commands/memory.ts +192 -0
- package/src/commands/model-picker.ts +28 -21
- package/src/commands/model.ts +19 -9
- package/src/commands/optimize-context.ts +408 -29
- package/src/commands/plan.ts +2 -0
- package/src/commands/qa.ts +312 -137
- package/src/commands/release.ts +259 -76
- package/src/commands/review.ts +293 -59
- package/src/commands/status.ts +200 -13
- package/src/commands/supi.ts +3 -35
- package/src/commands/ui-design.ts +394 -0
- package/src/commands/ultraplan.ts +1518 -0
- package/src/commands/update.ts +86 -0
- package/src/config/defaults.ts +62 -0
- package/src/config/loader.ts +448 -60
- package/src/config/schema.ts +108 -2
- package/src/context/optimizer.ts +25 -33
- package/src/context/rule-renderer.ts +223 -0
- package/src/context/savings.ts +258 -0
- package/src/context/startup-check.ts +380 -0
- package/src/context/startup-optimizer.ts +355 -0
- package/src/context/tokenignore.ts +146 -0
- package/src/context-mode/cache-handle.ts +49 -0
- package/src/context-mode/cache-preview.ts +71 -0
- package/src/context-mode/cache-store.ts +738 -0
- package/src/context-mode/compressor.ts +131 -26
- package/src/context-mode/dedup.ts +108 -0
- package/src/context-mode/detector.ts +35 -4
- package/src/context-mode/event-extractor.ts +14 -12
- package/src/context-mode/event-store.ts +91 -36
- package/src/context-mode/hooks.ts +798 -56
- package/src/context-mode/knowledge/store.ts +255 -11
- package/src/context-mode/memory-store.ts +325 -0
- package/src/context-mode/metrics-recorder.ts +158 -0
- package/src/context-mode/metrics-store.ts +765 -0
- package/src/context-mode/model.ts +24 -0
- package/src/context-mode/processor-keys.ts +29 -0
- package/src/context-mode/processors/build.ts +66 -0
- package/src/context-mode/processors/docker.ts +57 -0
- package/src/context-mode/processors/git.ts +111 -0
- package/src/context-mode/processors/json.ts +112 -0
- package/src/context-mode/processors/k8s.ts +67 -0
- package/src/context-mode/processors/lint.ts +67 -0
- package/src/context-mode/processors/log.ts +86 -0
- package/src/context-mode/processors/registry.ts +116 -0
- package/src/context-mode/processors/test-runner.ts +102 -0
- package/src/context-mode/processors/types.ts +20 -0
- package/src/context-mode/repomap.ts +400 -0
- package/src/context-mode/routing.ts +97 -24
- package/src/context-mode/sandbox/runners.ts +5 -1
- package/src/context-mode/snapshot-builder.ts +106 -11
- package/src/context-mode/source-hash.ts +173 -0
- package/src/context-mode/tool-name.ts +11 -0
- package/src/context-mode/tools.ts +654 -22
- package/src/context-mode/web/fetcher.ts +31 -12
- package/src/debug/logger.ts +2 -1
- package/src/deps/registry.ts +1 -1
- package/src/discipline/failure-summarizer.ts +170 -0
- package/src/discipline/failure-taxonomy.ts +131 -0
- package/src/discipline/workflow-invariants.ts +125 -0
- package/src/discovery/index.ts +31 -0
- package/src/discovery/lsp.ts +87 -0
- package/src/discovery/rank.ts +144 -0
- package/src/discovery/sources.ts +89 -0
- package/src/discovery/workflow.ts +87 -0
- package/src/docs/contracts.ts +39 -0
- package/src/docs/drift.ts +117 -87
- package/src/fix-pr/assessment.ts +200 -0
- package/src/fix-pr/contracts.ts +47 -0
- package/src/fix-pr/fetch-comments.ts +80 -0
- package/src/fix-pr/prompt-builder.ts +58 -40
- package/src/fix-pr/scripts/exec.ts +34 -0
- package/src/fix-pr/scripts/trigger-review.ts +106 -0
- package/src/fix-pr/scripts/wait-and-check.ts +108 -0
- package/src/fix-pr/types.ts +4 -0
- package/src/git/branch-finish.ts +5 -0
- package/src/git/commit-contract.ts +83 -0
- package/src/git/commit.ts +121 -184
- package/src/git/status.ts +62 -8
- package/src/harness/anti_slop/architecture-parser.ts +210 -0
- package/src/harness/anti_slop/backend-factory.ts +30 -0
- package/src/harness/anti_slop/backend.ts +140 -0
- package/src/harness/anti_slop/desloppify-adapter.ts +319 -0
- package/src/harness/anti_slop/fallow-adapter.ts +305 -0
- package/src/harness/anti_slop/installer.ts +227 -0
- package/src/harness/anti_slop/queue.ts +216 -0
- package/src/harness/anti_slop/recommend.ts +84 -0
- package/src/harness/anti_slop/score.ts +180 -0
- package/src/harness/anti_slop/synthetic-edit-test.ts +128 -0
- package/src/harness/artifacts/agents-md.ts +88 -0
- package/src/harness/artifacts/checks-wiring.ts +57 -0
- package/src/harness/artifacts/docs-tree.ts +79 -0
- package/src/harness/artifacts/lint-configs.ts +136 -0
- package/src/harness/artifacts/review-agents.ts +67 -0
- package/src/harness/bare-entry.ts +108 -0
- package/src/harness/command.ts +1010 -0
- package/src/harness/default-agents/design.md +23 -0
- package/src/harness/default-agents/discover.md +18 -0
- package/src/harness/default-agents/implement.md +24 -0
- package/src/harness/default-agents/plan.md +19 -0
- package/src/harness/default-agents/research.md +21 -0
- package/src/harness/default-agents/validate.md +22 -0
- package/src/harness/gc/reporter.ts +28 -0
- package/src/harness/gc/runner.ts +136 -0
- package/src/harness/hooks/layer-context-inject.ts +155 -0
- package/src/harness/hooks/post-session-sweep.ts +130 -0
- package/src/harness/hooks/pre-edit-dupe-probe.ts +224 -0
- package/src/harness/hooks/register.ts +118 -0
- package/src/harness/model.ts +117 -0
- package/src/harness/pipeline.ts +348 -0
- package/src/harness/project-paths.ts +235 -0
- package/src/harness/stage-runner.ts +107 -0
- package/src/harness/stages/design.ts +386 -0
- package/src/harness/stages/discover.ts +454 -0
- package/src/harness/stages/implement.ts +162 -0
- package/src/harness/stages/plan.ts +335 -0
- package/src/harness/stages/research.ts +263 -0
- package/src/harness/stages/validate.ts +684 -0
- package/src/harness/storage.ts +467 -0
- package/src/harness/tools.ts +426 -0
- package/src/lsp/bridge.ts +56 -95
- package/src/lsp/capabilities.ts +108 -0
- package/src/lsp/contracts.ts +35 -0
- package/src/lsp/detector.ts +8 -12
- package/src/markdown-frontmatter.ts +68 -0
- package/src/mempalace/bridge.ts +129 -0
- package/src/mempalace/config.ts +75 -0
- package/src/mempalace/format.ts +163 -0
- package/src/mempalace/hooks.ts +370 -0
- package/src/mempalace/installer-helper.ts +194 -0
- package/src/mempalace/python/mempalace_bridge.py +440 -0
- package/src/mempalace/runtime.ts +565 -0
- package/src/mempalace/schema.ts +264 -0
- package/src/mempalace/session-summary.ts +198 -0
- package/src/mempalace/tool.ts +186 -0
- package/src/mempalace/uv.ts +256 -0
- package/src/migrate/runner.ts +354 -0
- package/src/planning/approval-flow.ts +206 -9
- package/src/planning/plan-writer-prompt.ts +4 -3
- package/src/planning/planning-ask-tool.ts +39 -0
- package/src/planning/render-markdown.ts +74 -0
- package/src/planning/spec.ts +42 -0
- package/src/planning/system-prompt.ts +11 -8
- package/src/planning/validate.ts +84 -0
- package/src/platform/omp.ts +15 -2
- package/src/platform/system-prompt.ts +37 -0
- package/src/platform/test-utils.ts +3 -0
- package/src/platform/types.ts +6 -1
- package/src/qa/config.ts +12 -6
- package/src/qa/detect-app-type.ts +13 -6
- package/src/qa/matrix.ts +12 -6
- package/src/qa/prompt-builder.ts +28 -30
- package/src/qa/scripts/dev-server-utils.ts +72 -0
- package/src/qa/scripts/run-e2e-tests.ts +226 -0
- package/src/qa/scripts/start-dev-server.ts +138 -0
- package/src/qa/scripts/stop-dev-server.ts +77 -0
- package/src/qa/session.ts +13 -7
- package/src/quality/ai-setup.ts +27 -25
- package/src/quality/contracts.ts +34 -0
- package/src/quality/gates/ai-review.ts +20 -58
- package/src/quality/gates/command.ts +249 -46
- package/src/quality/review-gates.ts +18 -2
- package/src/quality/runner.ts +63 -22
- package/src/quality/schemas.ts +37 -2
- package/src/quality/setup.ts +96 -16
- package/src/release/changelog.ts +1 -1
- package/src/release/channels/custom.ts +13 -3
- package/src/release/channels/types.ts +5 -0
- package/src/release/contracts.ts +90 -0
- package/src/release/executor.ts +122 -45
- package/src/release/prompt.ts +18 -2
- package/src/release/targets.ts +86 -0
- package/src/release/version.ts +96 -71
- package/src/review/agent-loader.ts +298 -127
- package/src/review/fixer.ts +10 -6
- package/src/review/multi-agent-runner.ts +115 -14
- package/src/review/output.ts +12 -139
- package/src/review/runner.ts +12 -6
- package/src/review/scope.ts +144 -24
- package/src/review/types.ts +11 -20
- package/src/review/validator.ts +12 -6
- package/src/storage/fix-pr-sessions.ts +21 -14
- package/src/storage/plans.ts +14 -5
- package/src/storage/qa-sessions.ts +25 -19
- package/src/storage/reliability-metrics.ts +180 -0
- package/src/storage/reports.ts +8 -7
- package/src/storage/review-sessions.ts +55 -20
- package/src/tool-catalog/active-tool-controller.ts +164 -0
- package/src/tool-catalog/active-tool-planner.ts +212 -0
- package/src/tool-catalog/tool-groups.ts +102 -0
- package/src/types.ts +1401 -5
- package/src/ui-design/backend-adapter.ts +78 -0
- package/src/ui-design/backends/local-html.ts +82 -0
- package/src/ui-design/backends/pencil-mcp.ts +111 -0
- package/src/ui-design/components-scanner.ts +124 -0
- package/src/ui-design/config.ts +55 -0
- package/src/ui-design/pen-scanner.ts +95 -0
- package/src/ui-design/pen-selector.ts +72 -0
- package/src/ui-design/prompt-builder.ts +73 -0
- package/src/ui-design/scanner.ts +136 -0
- package/src/ui-design/session.ts +974 -0
- package/src/ui-design/system-prompt.ts +312 -0
- package/src/ui-design/tokens-scanner.ts +181 -0
- package/src/ui-design/types.ts +96 -0
- package/src/ultraplan/agent-catalog.ts +522 -0
- package/src/ultraplan/authoring/agent-catalog.ts +310 -0
- package/src/ultraplan/authoring/authoring-tools.ts +552 -0
- package/src/ultraplan/authoring/command-handlers.ts +339 -0
- package/src/ultraplan/authoring/markdown.ts +510 -0
- package/src/ultraplan/authoring/model.ts +162 -0
- package/src/ultraplan/authoring/pipeline.ts +319 -0
- package/src/ultraplan/authoring/stage-runner.ts +141 -0
- package/src/ultraplan/authoring/stages/approve.ts +249 -0
- package/src/ultraplan/authoring/stages/discover.ts +289 -0
- package/src/ultraplan/authoring/stages/intake.ts +203 -0
- package/src/ultraplan/authoring/stages/research.ts +399 -0
- package/src/ultraplan/authoring/stages/review.ts +333 -0
- package/src/ultraplan/authoring/stages/scout.ts +188 -0
- package/src/ultraplan/authoring/stages/synthesize.ts +348 -0
- package/src/ultraplan/authoring/storage.ts +594 -0
- package/src/ultraplan/authoring/synth-gate.ts +165 -0
- package/src/ultraplan/authoring-draft.ts +653 -0
- package/src/ultraplan/authoring-persist.ts +180 -0
- package/src/ultraplan/authoring-tool.ts +608 -0
- package/src/ultraplan/authoring-wizard.ts +587 -0
- package/src/ultraplan/batch/merge.ts +98 -0
- package/src/ultraplan/batch/planner.ts +150 -0
- package/src/ultraplan/batch/presenter.ts +97 -0
- package/src/ultraplan/batch/storage.ts +420 -0
- package/src/ultraplan/batch/supervisor.ts +317 -0
- package/src/ultraplan/batch/worker.ts +26 -0
- package/src/ultraplan/batch/worktree.ts +110 -0
- package/src/ultraplan/contracts.ts +1593 -0
- package/src/ultraplan/default-agents/authoring/discoverer.md +12 -0
- package/src/ultraplan/default-agents/authoring/intake.md +12 -0
- package/src/ultraplan/default-agents/authoring/planner.md +12 -0
- package/src/ultraplan/default-agents/authoring/researcher.md +12 -0
- package/src/ultraplan/default-agents/authoring/scope-checker.md +12 -0
- package/src/ultraplan/default-agents/authoring/scout.md +12 -0
- package/src/ultraplan/default-agents/authoring/structure-checker.md +12 -0
- package/src/ultraplan/default-agents/authoring/tdd-checker.md +12 -0
- package/src/ultraplan/default-agents/backend-domain-reviewer.md +10 -0
- package/src/ultraplan/default-agents/backend-executor.md +10 -0
- package/src/ultraplan/default-agents/backend-stack-reviewer.md +10 -0
- package/src/ultraplan/default-agents/backend-tester.md +10 -0
- package/src/ultraplan/default-agents/frontend-domain-reviewer.md +10 -0
- package/src/ultraplan/default-agents/frontend-executor.md +10 -0
- package/src/ultraplan/default-agents/frontend-stack-reviewer.md +10 -0
- package/src/ultraplan/default-agents/frontend-tester.md +10 -0
- package/src/ultraplan/default-agents/infrastructure-domain-reviewer.md +10 -0
- package/src/ultraplan/default-agents/infrastructure-executor.md +10 -0
- package/src/ultraplan/default-agents/infrastructure-stack-reviewer.md +10 -0
- package/src/ultraplan/default-agents/infrastructure-tester.md +10 -0
- package/src/ultraplan/execution/contract.ts +71 -0
- package/src/ultraplan/execution/policy.ts +217 -0
- package/src/ultraplan/execution/runtime-tools.ts +107 -0
- package/src/ultraplan/execution/session-runner.ts +281 -0
- package/src/ultraplan/next-router.ts +85 -0
- package/src/ultraplan/presenter.ts +359 -0
- package/src/ultraplan/project-paths.ts +342 -0
- package/src/ultraplan/runtime/active-execution.ts +72 -0
- package/src/ultraplan/runtime/apply-mutation.ts +416 -0
- package/src/ultraplan/runtime/blockers.ts +243 -0
- package/src/ultraplan/runtime/hook-bridge.ts +486 -0
- package/src/ultraplan/runtime/launch-context.ts +207 -0
- package/src/ultraplan/runtime/migration.ts +524 -0
- package/src/ultraplan/runtime/normalize.ts +281 -0
- package/src/ultraplan/runtime/proof.ts +260 -0
- package/src/ultraplan/runtime/reducer.ts +416 -0
- package/src/ultraplan/runtime/repair.ts +251 -0
- package/src/ultraplan/runtime/tracker-storage.ts +368 -0
- package/src/ultraplan/session-selection.ts +291 -0
- package/src/ultraplan/storage.ts +374 -0
- package/src/utils/editor.ts +38 -0
- package/src/utils/executable.ts +80 -0
- package/src/utils/paths.ts +1 -20
- package/src/utils/shell.ts +31 -0
- package/src/visual/companion.ts +2 -1
- package/src/visual/scripts/frame-template.html +60 -0
- package/src/visual/scripts/index.js +59 -13
- package/src/visual/scripts/package.json +3 -0
- package/src/visual/start-server.ts +2 -1
- package/src/workspace/git-scope.ts +64 -0
- package/src/workspace/locks.ts +23 -0
- package/src/workspace/package-manager.ts +117 -0
- package/src/workspace/path-mapping.ts +75 -0
- package/src/workspace/project-slug.ts +92 -0
- package/src/workspace/repo-root.ts +137 -0
- package/src/workspace/selector.ts +115 -0
- package/src/workspace/state-paths.ts +118 -0
- package/src/workspace/targets.ts +313 -0
- package/src/fix-pr/scripts/diff-comments.sh +0 -33
- package/src/fix-pr/scripts/fetch-pr-comments.sh +0 -25
- package/src/fix-pr/scripts/trigger-review.sh +0 -36
- package/src/fix-pr/scripts/wait-and-check.sh +0 -37
- package/src/qa/scripts/detect-app-type.sh +0 -68
- package/src/qa/scripts/discover-routes.sh +0 -143
- package/src/qa/scripts/run-e2e-tests.sh +0 -131
- package/src/qa/scripts/start-dev-server.sh +0 -46
- package/src/qa/scripts/stop-dev-server.sh +0 -36
- package/src/review/prompts/fix-output-schema.md +0 -18
- package/src/review/prompts/review-output-schema.md +0 -38
- package/src/review/template.ts +0 -15
- /package/src/{review → ai}/prompts/invalid-output-retry.md +0 -0
package/src/commands/review.ts
CHANGED
|
@@ -10,7 +10,11 @@ import { modelRegistry } from "../config/model-registry-instance.js";
|
|
|
10
10
|
import { resolveModelForAction, createModelBridge, applyModelOverride } from "../config/model-resolver.js";
|
|
11
11
|
import { loadModelConfig } from "../config/model-config.js";
|
|
12
12
|
import { createWorkflowProgress } from "../platform/progress.js";
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
discoverChangedRepoFiles,
|
|
15
|
+
runQualityGates,
|
|
16
|
+
type ReviewRunEvent,
|
|
17
|
+
} from "../quality/runner.js";
|
|
14
18
|
import {
|
|
15
19
|
interactivelySaveGateSetup,
|
|
16
20
|
setupGates,
|
|
@@ -23,10 +27,20 @@ import type {
|
|
|
23
27
|
QualityGatesConfig,
|
|
24
28
|
ReviewReport,
|
|
25
29
|
SupipowersConfig,
|
|
30
|
+
WorkspaceTarget,
|
|
26
31
|
} from "../types.js";
|
|
27
32
|
import { CANONICAL_GATE_ORDER, GATE_DISPLAY_NAMES } from "../quality/registry.js";
|
|
28
33
|
import { REVIEW_GATE_REGISTRY } from "../quality/review-gates.js";
|
|
29
34
|
import { saveReviewReport } from "../storage/reports.js";
|
|
35
|
+
import { resolvePackageManager } from "../workspace/package-manager.js";
|
|
36
|
+
import { resolveRepoRoot } from "../workspace/repo-root.js";
|
|
37
|
+
import { getChangedWorkspaceTargets } from "../workspace/path-mapping.js";
|
|
38
|
+
import {
|
|
39
|
+
parseTargetArg,
|
|
40
|
+
selectWorkspaceTarget,
|
|
41
|
+
sortWorkspaceTargetOptions,
|
|
42
|
+
} from "../workspace/selector.js";
|
|
43
|
+
import { discoverWorkspaceTargets } from "../workspace/targets.js";
|
|
30
44
|
|
|
31
45
|
modelRegistry.register({
|
|
32
46
|
id: "checks",
|
|
@@ -61,6 +75,8 @@ export interface ChecksCommandDependencies {
|
|
|
61
75
|
interactivelySaveGateSetup: typeof interactivelySaveGateSetup;
|
|
62
76
|
runQualityGates: typeof runQualityGates;
|
|
63
77
|
saveReviewReport: typeof saveReviewReport;
|
|
78
|
+
resolvePackageManager: typeof resolvePackageManager;
|
|
79
|
+
discoverWorkspaceTargets: typeof discoverWorkspaceTargets;
|
|
64
80
|
notifyInfo: typeof notifyInfo;
|
|
65
81
|
}
|
|
66
82
|
|
|
@@ -77,9 +93,35 @@ const CHECKS_COMMAND_DEPENDENCIES: ChecksCommandDependencies = {
|
|
|
77
93
|
interactivelySaveGateSetup,
|
|
78
94
|
runQualityGates,
|
|
79
95
|
saveReviewReport,
|
|
96
|
+
resolvePackageManager,
|
|
97
|
+
discoverWorkspaceTargets,
|
|
80
98
|
notifyInfo,
|
|
81
99
|
};
|
|
82
100
|
|
|
101
|
+
interface ResolvedChecksTargets {
|
|
102
|
+
mode: "single" | "all";
|
|
103
|
+
runTargets: WorkspaceTarget[];
|
|
104
|
+
workspaceTargets: WorkspaceTarget[];
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
interface CompletedChecksRun {
|
|
108
|
+
target: WorkspaceTarget;
|
|
109
|
+
report: ReviewReport;
|
|
110
|
+
reportPath: string;
|
|
111
|
+
failedGates: GateResult[];
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
interface RunChecksForTargetInput {
|
|
115
|
+
platform: Platform;
|
|
116
|
+
ctx: any;
|
|
117
|
+
deps: ChecksCommandDependencies;
|
|
118
|
+
target: WorkspaceTarget;
|
|
119
|
+
workspaceTargets: WorkspaceTarget[];
|
|
120
|
+
filters: GateFilters;
|
|
121
|
+
reviewModel: ReturnType<ChecksCommandDependencies["resolveModelForAction"]>;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
|
|
83
125
|
function tokenizeGateList(raw: string): string[] {
|
|
84
126
|
return raw
|
|
85
127
|
.split(/[\s,]+/)
|
|
@@ -156,7 +198,7 @@ function validateGateSelection(enabledGateIds: GateId[], filters: GateFilters):
|
|
|
156
198
|
}
|
|
157
199
|
|
|
158
200
|
function describeScope(scope: ConfigScope): string {
|
|
159
|
-
return scope === "global" ? "global" : "
|
|
201
|
+
return scope === "global" ? "global" : "repository";
|
|
160
202
|
}
|
|
161
203
|
|
|
162
204
|
function buildRecoveryDetail(scopes: ConfigScope[]): string {
|
|
@@ -168,6 +210,122 @@ function buildRecoveryDetail(scopes: ConfigScope[]): string {
|
|
|
168
210
|
].join("\n");
|
|
169
211
|
}
|
|
170
212
|
|
|
213
|
+
function getTargetConfigOptions(target: WorkspaceTarget) {
|
|
214
|
+
return { repoRoot: target.repoRoot };
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function formatTargetLocation(target: WorkspaceTarget): string {
|
|
218
|
+
return target.kind === "root" ? "root" : target.relativeDir;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function formatTargetLabel(target: WorkspaceTarget): string {
|
|
222
|
+
return target.kind === "root" ? `${target.name} (root)` : `${target.name} (${target.relativeDir})`;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function buildChecksTargetOptionLabel(option: { target: WorkspaceTarget; changed: boolean }): string {
|
|
226
|
+
return `${option.target.name} — ${formatTargetLocation(option.target)} — ${option.changed ? "changed" : "unchanged"}`;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function buildAllChecksTargetLabel(
|
|
230
|
+
workspaceTargets: WorkspaceTarget[],
|
|
231
|
+
changedTargetIds: Set<string>,
|
|
232
|
+
): string {
|
|
233
|
+
const workspaceCount = workspaceTargets.filter((target) => target.kind === "workspace").length;
|
|
234
|
+
const base = workspaceCount === 0
|
|
235
|
+
? "All — root target"
|
|
236
|
+
: `All — root + ${workspaceCount} workspace${workspaceCount === 1 ? "" : "s"}`;
|
|
237
|
+
const changedCount = workspaceTargets.filter((target) => changedTargetIds.has(target.id)).length;
|
|
238
|
+
return changedCount > 0 ? `${base} — ${changedCount} changed` : `${base} — no changed targets`;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function getDefaultChecksTarget(workspaceTargets: WorkspaceTarget[]): WorkspaceTarget {
|
|
242
|
+
return workspaceTargets.find((target) => target.kind === "root") ?? workspaceTargets[0]!;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function isMonorepoTargets(workspaceTargets: WorkspaceTarget[]): boolean {
|
|
246
|
+
return workspaceTargets.some((target) => target.kind === "workspace");
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
async function resolveChecksTargets(
|
|
250
|
+
platform: Platform,
|
|
251
|
+
ctx: any,
|
|
252
|
+
args: string | undefined,
|
|
253
|
+
deps: ChecksCommandDependencies,
|
|
254
|
+
): Promise<ResolvedChecksTargets | null> {
|
|
255
|
+
const requestedTarget = parseTargetArg(args);
|
|
256
|
+
const repoRoot = await resolveRepoRoot(platform, ctx.cwd);
|
|
257
|
+
const packageManager = deps.resolvePackageManager(repoRoot);
|
|
258
|
+
const workspaceTargets = deps.discoverWorkspaceTargets(repoRoot, packageManager.id);
|
|
259
|
+
|
|
260
|
+
if (workspaceTargets.length === 0) {
|
|
261
|
+
throw new Error("No workspace targets found for checks.");
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (requestedTarget?.toLowerCase() === "all") {
|
|
265
|
+
return { mode: "all", runTargets: workspaceTargets, workspaceTargets };
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (requestedTarget) {
|
|
269
|
+
const target = await selectWorkspaceTarget(
|
|
270
|
+
ctx,
|
|
271
|
+
workspaceTargets.map((target) => ({ target, changed: false })),
|
|
272
|
+
requestedTarget,
|
|
273
|
+
{
|
|
274
|
+
title: "Checks target",
|
|
275
|
+
helpText: "Pick one target to run checks for. Use --target all to run the root target and every workspace target.",
|
|
276
|
+
},
|
|
277
|
+
);
|
|
278
|
+
if (!target) {
|
|
279
|
+
throw new Error(`Checks target not found: ${requestedTarget}`);
|
|
280
|
+
}
|
|
281
|
+
return { mode: "single", runTargets: [target], workspaceTargets };
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (!isMonorepoTargets(workspaceTargets)) {
|
|
285
|
+
return {
|
|
286
|
+
mode: "single",
|
|
287
|
+
runTargets: [getDefaultChecksTarget(workspaceTargets)],
|
|
288
|
+
workspaceTargets,
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const changedRepoFiles = await discoverChangedRepoFiles(platform.exec.bind(platform), repoRoot);
|
|
293
|
+
const changedTargetIds = new Set(
|
|
294
|
+
getChangedWorkspaceTargets(workspaceTargets, changedRepoFiles).map((target) => target.id),
|
|
295
|
+
);
|
|
296
|
+
const options = sortWorkspaceTargetOptions(
|
|
297
|
+
workspaceTargets.map((target) => ({
|
|
298
|
+
target,
|
|
299
|
+
changed: changedTargetIds.has(target.id),
|
|
300
|
+
label: buildChecksTargetOptionLabel({
|
|
301
|
+
target,
|
|
302
|
+
changed: changedTargetIds.has(target.id),
|
|
303
|
+
}),
|
|
304
|
+
})),
|
|
305
|
+
);
|
|
306
|
+
|
|
307
|
+
if (!ctx.hasUI) {
|
|
308
|
+
return { mode: "all", runTargets: workspaceTargets, workspaceTargets };
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
const allLabel = buildAllChecksTargetLabel(workspaceTargets, changedTargetIds);
|
|
312
|
+
const labels = [allLabel, ...options.map((option) => option.label ?? buildChecksTargetOptionLabel(option))];
|
|
313
|
+
const choice = await ctx.ui.select("Checks target", labels, {
|
|
314
|
+
initialIndex: 0,
|
|
315
|
+
helpText: "All runs the root target and every workspace target. Choose a single target to narrow the run.",
|
|
316
|
+
});
|
|
317
|
+
if (!choice) {
|
|
318
|
+
return null;
|
|
319
|
+
}
|
|
320
|
+
if (choice === allLabel) {
|
|
321
|
+
return { mode: "all", runTargets: workspaceTargets, workspaceTargets };
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
const selectedIndex = labels.indexOf(choice) - 1;
|
|
325
|
+
const target = selectedIndex >= 0 ? options[selectedIndex]?.target ?? null : null;
|
|
326
|
+
return target ? { mode: "single", runTargets: [target], workspaceTargets } : null;
|
|
327
|
+
}
|
|
328
|
+
|
|
171
329
|
function gateStepKey(gateId: GateId): string {
|
|
172
330
|
return `gate-${gateId}`;
|
|
173
331
|
}
|
|
@@ -350,12 +508,15 @@ async function recoverInvalidQualityGateConfig(
|
|
|
350
508
|
ctx: any,
|
|
351
509
|
deps: ChecksCommandDependencies,
|
|
352
510
|
reviewProgress: ReturnType<typeof createReviewProgress>,
|
|
511
|
+
target: WorkspaceTarget,
|
|
353
512
|
): Promise<
|
|
354
513
|
| { status: "unrecoverable" }
|
|
355
514
|
| { status: "cancelled" }
|
|
356
515
|
| { status: "recovered"; config: SupipowersConfig }
|
|
357
516
|
> {
|
|
358
|
-
const
|
|
517
|
+
const configRoot = target.repoRoot;
|
|
518
|
+
const configOptions = getTargetConfigOptions(target);
|
|
519
|
+
const recovery = deps.inspectQualityGateRecovery(platform.paths, configRoot, configOptions);
|
|
359
520
|
const recoverableScopes = recovery.scopes
|
|
360
521
|
.filter((scope) => scope.recoverableInvalidQualityGates)
|
|
361
522
|
.map((scope) => scope.scope);
|
|
@@ -374,7 +535,7 @@ async function recoverInvalidQualityGateConfig(
|
|
|
374
535
|
reviewProgress.startRepair(`cleaning ${recoverableScopes.join(" + ")}`);
|
|
375
536
|
|
|
376
537
|
for (const scope of recoverableScopes) {
|
|
377
|
-
deps.removeQualityGatesConfig(platform.paths,
|
|
538
|
+
deps.removeQualityGatesConfig(platform.paths, configRoot, scope, configOptions);
|
|
378
539
|
}
|
|
379
540
|
|
|
380
541
|
deps.notifyInfo(
|
|
@@ -385,8 +546,8 @@ async function recoverInvalidQualityGateConfig(
|
|
|
385
546
|
|
|
386
547
|
const setupResult = await deps.setupGates(
|
|
387
548
|
platform,
|
|
388
|
-
|
|
389
|
-
deps.inspectConfig(platform.paths,
|
|
549
|
+
configRoot,
|
|
550
|
+
deps.inspectConfig(platform.paths, configRoot, configOptions),
|
|
390
551
|
{ mode: "deterministic" },
|
|
391
552
|
);
|
|
392
553
|
if (setupResult.status !== "proposed") {
|
|
@@ -400,7 +561,7 @@ async function recoverInvalidQualityGateConfig(
|
|
|
400
561
|
const saveResult = await deps.interactivelySaveGateSetup(
|
|
401
562
|
ctx,
|
|
402
563
|
platform.paths,
|
|
403
|
-
|
|
564
|
+
configRoot,
|
|
404
565
|
setupResult.proposal,
|
|
405
566
|
);
|
|
406
567
|
if (saveResult !== "saved") {
|
|
@@ -414,7 +575,7 @@ async function recoverInvalidQualityGateConfig(
|
|
|
414
575
|
return { status: "cancelled" };
|
|
415
576
|
}
|
|
416
577
|
|
|
417
|
-
const config = deps.loadConfig(platform.paths,
|
|
578
|
+
const config = deps.loadConfig(platform.paths, configRoot, configOptions);
|
|
418
579
|
reviewProgress.completeRepair("reconfigured");
|
|
419
580
|
return {
|
|
420
581
|
status: "recovered",
|
|
@@ -422,6 +583,96 @@ async function recoverInvalidQualityGateConfig(
|
|
|
422
583
|
};
|
|
423
584
|
}
|
|
424
585
|
|
|
586
|
+
async function runChecksForTarget(input: RunChecksForTargetInput): Promise<CompletedChecksRun | null> {
|
|
587
|
+
const { platform, ctx, deps, target, workspaceTargets, filters, reviewModel } = input;
|
|
588
|
+
const reviewProgress = createReviewProgress(ctx);
|
|
589
|
+
const configRoot = target.repoRoot;
|
|
590
|
+
const configOptions = getTargetConfigOptions(target);
|
|
591
|
+
|
|
592
|
+
try {
|
|
593
|
+
reviewProgress.startLoadingConfig();
|
|
594
|
+
|
|
595
|
+
let config: SupipowersConfig;
|
|
596
|
+
try {
|
|
597
|
+
config = deps.loadConfig(platform.paths, configRoot, configOptions);
|
|
598
|
+
reviewProgress.completeLoadingConfig();
|
|
599
|
+
} catch (error) {
|
|
600
|
+
const recovered = await recoverInvalidQualityGateConfig(
|
|
601
|
+
platform,
|
|
602
|
+
ctx,
|
|
603
|
+
deps,
|
|
604
|
+
reviewProgress,
|
|
605
|
+
target,
|
|
606
|
+
);
|
|
607
|
+
if (recovered.status === "unrecoverable") {
|
|
608
|
+
throw error;
|
|
609
|
+
}
|
|
610
|
+
if (recovered.status === "cancelled") {
|
|
611
|
+
return null;
|
|
612
|
+
}
|
|
613
|
+
config = recovered.config;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
const enabledGateIds = getEnabledGateIds(config.quality.gates);
|
|
617
|
+
reviewProgress.configureGateSteps(config.quality.gates, filters);
|
|
618
|
+
validateGateSelection(enabledGateIds, filters);
|
|
619
|
+
|
|
620
|
+
reviewProgress.startScopeDiscovery();
|
|
621
|
+
const report = await deps.runQualityGates({
|
|
622
|
+
platform,
|
|
623
|
+
cwd: target.packageDir,
|
|
624
|
+
target,
|
|
625
|
+
workspaceTargets,
|
|
626
|
+
gates: config.quality.gates,
|
|
627
|
+
filters,
|
|
628
|
+
reviewModel,
|
|
629
|
+
gateRegistry: REVIEW_GATE_REGISTRY,
|
|
630
|
+
onEvent: (event) => reviewProgress.handleRunnerEvent(event),
|
|
631
|
+
});
|
|
632
|
+
|
|
633
|
+
reviewProgress.startSavingReport();
|
|
634
|
+
const reportPath = deps.saveReviewReport(platform.paths, target, report);
|
|
635
|
+
reviewProgress.completeSavingReport(report.overallStatus);
|
|
636
|
+
|
|
637
|
+
return {
|
|
638
|
+
target,
|
|
639
|
+
report,
|
|
640
|
+
reportPath,
|
|
641
|
+
failedGates: getFailedGates(report),
|
|
642
|
+
};
|
|
643
|
+
} catch (error) {
|
|
644
|
+
reviewProgress.failActive((error as Error).message);
|
|
645
|
+
throw error;
|
|
646
|
+
} finally {
|
|
647
|
+
reviewProgress.dispose();
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
function buildBatchChecksTitle(results: CompletedChecksRun[]): string {
|
|
652
|
+
const counts = results.reduce(
|
|
653
|
+
(summary, result) => {
|
|
654
|
+
summary[result.report.overallStatus] += 1;
|
|
655
|
+
return summary;
|
|
656
|
+
},
|
|
657
|
+
{ passed: 0, failed: 0, blocked: 0 } satisfies Record<ReviewReport["overallStatus"], number>,
|
|
658
|
+
);
|
|
659
|
+
const parts = [
|
|
660
|
+
counts.passed > 0 ? `${counts.passed} passed` : null,
|
|
661
|
+
counts.failed > 0 ? `${counts.failed} failed` : null,
|
|
662
|
+
counts.blocked > 0 ? `${counts.blocked} blocked` : null,
|
|
663
|
+
].filter((part): part is string => part !== null);
|
|
664
|
+
|
|
665
|
+
return `Checks complete: ${parts.join(", ")}`;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
function buildBatchChecksSummary(results: CompletedChecksRun[]): string {
|
|
669
|
+
return results.map((result) => {
|
|
670
|
+
const { passed, failed, blocked, skipped } = result.report.summary;
|
|
671
|
+
return `${formatTargetLabel(result.target)}: ${result.report.overallStatus} — ${passed} passed, ${failed} failed, ${blocked} blocked, ${skipped} skipped — saved: ${result.reportPath}`;
|
|
672
|
+
}).join("\n");
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
|
|
425
676
|
export function buildReviewSummary(report: ReviewReport, reportPath: string): string {
|
|
426
677
|
const orderedGates = [...report.gates].sort(
|
|
427
678
|
(left, right) =>
|
|
@@ -548,7 +799,6 @@ function buildFixPrompt(failedGates: GateResult[]): string {
|
|
|
548
799
|
].join("\n"));
|
|
549
800
|
}
|
|
550
801
|
|
|
551
|
-
const gateNames = failedGates.map((g) => GATE_DISPLAY_NAMES[g.gate] ?? g.gate);
|
|
552
802
|
const rerunCmd = `/supi:checks --only ${failedGates.map((g) => g.gate).join(" ")}`;
|
|
553
803
|
|
|
554
804
|
return [
|
|
@@ -565,7 +815,6 @@ export async function handleChecks(
|
|
|
565
815
|
args: string | undefined,
|
|
566
816
|
deps: ChecksCommandDependencies = CHECKS_COMMAND_DEPENDENCIES,
|
|
567
817
|
): Promise<void> {
|
|
568
|
-
const reviewProgress = createReviewProgress(ctx);
|
|
569
818
|
let modelCleanup: (() => Promise<void>) | undefined;
|
|
570
819
|
|
|
571
820
|
try {
|
|
@@ -574,82 +823,67 @@ export async function handleChecks(
|
|
|
574
823
|
const resolved = deps.resolveModelForAction("checks", modelRegistry, modelCfg, bridge);
|
|
575
824
|
modelCleanup = await deps.applyModelOverride(platform, ctx, "checks", resolved);
|
|
576
825
|
|
|
577
|
-
|
|
826
|
+
const filters = parseGateFilters(args);
|
|
827
|
+
const selection = await resolveChecksTargets(platform, ctx, args, deps);
|
|
828
|
+
if (!selection) {
|
|
829
|
+
return;
|
|
830
|
+
}
|
|
578
831
|
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
832
|
+
const results: CompletedChecksRun[] = [];
|
|
833
|
+
for (const target of selection.runTargets) {
|
|
834
|
+
const result = await runChecksForTarget({
|
|
835
|
+
platform,
|
|
836
|
+
ctx,
|
|
837
|
+
deps,
|
|
838
|
+
target,
|
|
839
|
+
workspaceTargets: selection.workspaceTargets,
|
|
840
|
+
filters,
|
|
841
|
+
reviewModel: resolved,
|
|
842
|
+
});
|
|
843
|
+
if (!result) {
|
|
589
844
|
return;
|
|
590
845
|
}
|
|
591
|
-
|
|
846
|
+
results.push(result);
|
|
592
847
|
}
|
|
593
848
|
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
reviewProgress.startScopeDiscovery();
|
|
600
|
-
const report = await deps.runQualityGates({
|
|
601
|
-
platform,
|
|
602
|
-
cwd: ctx.cwd,
|
|
603
|
-
gates: config.quality.gates,
|
|
604
|
-
filters,
|
|
605
|
-
reviewModel: resolved,
|
|
606
|
-
gateRegistry: REVIEW_GATE_REGISTRY,
|
|
607
|
-
onEvent: (event) => reviewProgress.handleRunnerEvent(event),
|
|
608
|
-
});
|
|
609
|
-
|
|
610
|
-
reviewProgress.startSavingReport();
|
|
611
|
-
const reportPath = deps.saveReviewReport(platform.paths, ctx.cwd, report);
|
|
612
|
-
reviewProgress.completeSavingReport(report.overallStatus);
|
|
613
|
-
|
|
614
|
-
// Dispose widget before showing any TUI dialogs
|
|
615
|
-
reviewProgress.dispose();
|
|
849
|
+
if (selection.mode === "all" && results.length > 1) {
|
|
850
|
+
deps.notifyInfo(ctx, buildBatchChecksTitle(results), buildBatchChecksSummary(results));
|
|
851
|
+
return;
|
|
852
|
+
}
|
|
616
853
|
|
|
617
|
-
const
|
|
854
|
+
const [result] = results;
|
|
855
|
+
if (!result) {
|
|
856
|
+
return;
|
|
857
|
+
}
|
|
618
858
|
|
|
619
|
-
if (failedGates.length === 0) {
|
|
859
|
+
if (result.failedGates.length === 0) {
|
|
620
860
|
deps.notifyInfo(
|
|
621
861
|
ctx,
|
|
622
|
-
`Checks complete: ${report.overallStatus}`,
|
|
623
|
-
buildReviewSummary(report, reportPath),
|
|
862
|
+
`Checks complete: ${result.report.overallStatus}`,
|
|
863
|
+
buildReviewSummary(result.report, result.reportPath),
|
|
624
864
|
);
|
|
625
865
|
return;
|
|
626
866
|
}
|
|
627
867
|
|
|
628
|
-
|
|
629
|
-
const failureNames = failedGates.map((g) => GATE_DISPLAY_NAMES[g.gate] ?? g.gate);
|
|
868
|
+
const failureNames = result.failedGates.map((gate) => GATE_DISPLAY_NAMES[gate.gate] ?? gate.gate);
|
|
630
869
|
deps.notifyInfo(
|
|
631
870
|
ctx,
|
|
632
|
-
`Checks complete: ${report.overallStatus}`,
|
|
633
|
-
buildFailureSummary(failedGates),
|
|
871
|
+
`Checks complete: ${result.report.overallStatus}`,
|
|
872
|
+
buildFailureSummary(result.failedGates),
|
|
634
873
|
);
|
|
635
874
|
|
|
636
|
-
// Offer to fix
|
|
637
875
|
const FIX_NOW = `Yes, fix ${failureNames.join(", ")}`;
|
|
638
876
|
const SAVE_ONLY = "No, just save for later";
|
|
639
877
|
const choice = await ctx.ui.select(
|
|
640
|
-
`${failedGates.length} check${failedGates.length === 1 ? "" : "s"} failed — do you want to fix now?`,
|
|
878
|
+
`${result.failedGates.length} check${result.failedGates.length === 1 ? "" : "s"} failed — do you want to fix now?`,
|
|
641
879
|
[FIX_NOW, SAVE_ONLY],
|
|
642
880
|
);
|
|
643
881
|
|
|
644
882
|
if (choice === FIX_NOW) {
|
|
645
|
-
platform.sendUserMessage(buildFixPrompt(failedGates));
|
|
883
|
+
platform.sendUserMessage(buildFixPrompt(result.failedGates));
|
|
646
884
|
}
|
|
647
|
-
} catch (error) {
|
|
648
|
-
reviewProgress.failActive((error as Error).message);
|
|
649
|
-
throw error;
|
|
650
885
|
} finally {
|
|
651
886
|
await modelCleanup?.();
|
|
652
|
-
reviewProgress.dispose();
|
|
653
887
|
}
|
|
654
888
|
}
|
|
655
889
|
|