@pugi/cli 0.1.0-beta.99 → 1.0.0-alpha.2
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/LICENSE +1 -1
- package/README.md +11 -191
- package/bin/pugi +8 -0
- package/package.json +15 -71
- package/postinstall.mjs +31 -0
- package/CHANGELOG.md +0 -132
- package/THIRD_PARTY_NOTICES.md +0 -40
- package/assets/pugi-mascot.ansi +0 -16
- package/assets/pugi-prozr2-mascot.ansi +0 -9
- package/bin/run.js +0 -34
- package/dist/commands/deploy.js +0 -439
- package/dist/commands/flatten.js +0 -191
- package/dist/commands/jobs-watch.js +0 -201
- package/dist/commands/jobs.js +0 -260
- package/dist/commands/retro.js +0 -210
- package/dist/commands/smoke.js +0 -133
- package/dist/core/agent-progress/cleanup.js +0 -134
- package/dist/core/agent-progress/schema.js +0 -144
- package/dist/core/agent-progress/writer.js +0 -101
- package/dist/core/agents/adaptive-router.js +0 -330
- package/dist/core/agents/loader.js +0 -104
- package/dist/core/agents/query-decomposer.js +0 -297
- package/dist/core/agents/registry.js +0 -69
- package/dist/core/approvals/shortcut-resolver.js +0 -98
- package/dist/core/artifact-chain/dispatcher.js +0 -148
- package/dist/core/artifact-chain/exporter.js +0 -164
- package/dist/core/artifact-chain/state.js +0 -243
- package/dist/core/artifact-chain/steps.js +0 -169
- package/dist/core/ask-user/question.js +0 -92
- package/dist/core/audit/audit-trail.js +0 -275
- package/dist/core/auth/ensure-authenticated.js +0 -129
- package/dist/core/auth/env-provider.js +0 -238
- package/dist/core/auto-open-browser.js +0 -128
- package/dist/core/auto-update/channels.js +0 -122
- package/dist/core/auto-update/checker.js +0 -241
- package/dist/core/auto-update/state.js +0 -235
- package/dist/core/bare-mode/index.js +0 -107
- package/dist/core/bash/redirect.js +0 -281
- package/dist/core/bash-classifier.js +0 -1397
- package/dist/core/checkpoint/resumer.js +0 -149
- package/dist/core/checkpoint/rewinder.js +0 -291
- package/dist/core/checkpoints/shadow-git.js +0 -670
- package/dist/core/citations/parser.js +0 -109
- package/dist/core/classifier/yolo-classifier.js +0 -88
- package/dist/core/clipboard.js +0 -70
- package/dist/core/codegraph/decision-store.js +0 -248
- package/dist/core/codegraph/detect-repo.js +0 -459
- package/dist/core/codegraph/install.js +0 -134
- package/dist/core/codegraph/offer-hook.js +0 -220
- package/dist/core/compact/auto-trigger.js +0 -96
- package/dist/core/compact/buffer-rewriter.js +0 -115
- package/dist/core/compact/summarizer.js +0 -208
- package/dist/core/compact/token-counter.js +0 -108
- package/dist/core/consensus/anvil-fanout.js +0 -276
- package/dist/core/consensus/diff-capture.js +0 -491
- package/dist/core/consensus/rubric.js +0 -233
- package/dist/core/context/builder.js +0 -114
- package/dist/core/context/compaction-events.js +0 -99
- package/dist/core/context/compaction.js +0 -602
- package/dist/core/context/index.js +0 -28
- package/dist/core/context/invariants.js +0 -250
- package/dist/core/context/markdown-loader.js +0 -288
- package/dist/core/context/markdown-traverse.js +0 -255
- package/dist/core/context/pugiignore.js +0 -316
- package/dist/core/context/repo-skeleton.js +0 -533
- package/dist/core/context/tool-eviction.js +0 -55
- package/dist/core/context/watcher.js +0 -342
- package/dist/core/context/working-set.js +0 -165
- package/dist/core/coordinator/agent-tools.js +0 -77
- package/dist/core/coordinator/agent-toolset.js +0 -65
- package/dist/core/coordinator/fsm.js +0 -73
- package/dist/core/coordinator/mode-fsm.js +0 -70
- package/dist/core/cost/rate-card.js +0 -129
- package/dist/core/cost/tracker.js +0 -221
- package/dist/core/credentials.js +0 -355
- package/dist/core/cron/scheduler.js +0 -138
- package/dist/core/denial-tracking/index.js +0 -8
- package/dist/core/denial-tracking/state.js +0 -264
- package/dist/core/diagnostics/probe-runner.js +0 -93
- package/dist/core/diagnostics/probes/api.js +0 -46
- package/dist/core/diagnostics/probes/auth.js +0 -93
- package/dist/core/diagnostics/probes/bare-mode.js +0 -42
- package/dist/core/diagnostics/probes/cli-version.js +0 -127
- package/dist/core/diagnostics/probes/config.js +0 -72
- package/dist/core/diagnostics/probes/denial-tracking.js +0 -57
- package/dist/core/diagnostics/probes/disk.js +0 -81
- package/dist/core/diagnostics/probes/engine-live.js +0 -46
- package/dist/core/diagnostics/probes/git.js +0 -65
- package/dist/core/diagnostics/probes/hooks.js +0 -118
- package/dist/core/diagnostics/probes/mcp.js +0 -75
- package/dist/core/diagnostics/probes/node.js +0 -59
- package/dist/core/diagnostics/probes/pnpm.js +0 -36
- package/dist/core/diagnostics/probes/pugi-md.js +0 -89
- package/dist/core/diagnostics/probes/sandbox.js +0 -72
- package/dist/core/diagnostics/probes/session.js +0 -74
- package/dist/core/diagnostics/probes/status-snapshot.js +0 -488
- package/dist/core/diagnostics/probes/workspace.js +0 -63
- package/dist/core/diagnostics/types.js +0 -70
- package/dist/core/dispatch/cache-cleanup.js +0 -197
- package/dist/core/dispatch/cache-handoff.js +0 -295
- package/dist/core/edits/apply-patch-layer-e.js +0 -189
- package/dist/core/edits/dispatch.js +0 -511
- package/dist/core/edits/format-detector.js +0 -260
- package/dist/core/edits/format-matrix.js +0 -26
- package/dist/core/edits/fuzzy-ladder.js +0 -650
- package/dist/core/edits/index.js +0 -19
- package/dist/core/edits/journal.js +0 -199
- package/dist/core/edits/layer-a-apply.js +0 -217
- package/dist/core/edits/layer-a-fuzzy-apply.js +0 -198
- package/dist/core/edits/layer-b-apply.js +0 -211
- package/dist/core/edits/layer-c-apply.js +0 -160
- package/dist/core/edits/layer-d-ast.js +0 -572
- package/dist/core/edits/marker-parser.js +0 -401
- package/dist/core/edits/security-gate.js +0 -223
- package/dist/core/edits/verify-hook.js +0 -273
- package/dist/core/edits/worktree.js +0 -322
- package/dist/core/engine/adapter-runner.js +0 -8
- package/dist/core/engine/anvil-client.js +0 -344
- package/dist/core/engine/auto-compact.js +0 -179
- package/dist/core/engine/budgets.js +0 -195
- package/dist/core/engine/context-prefix.js +0 -155
- package/dist/core/engine/index.js +0 -12
- package/dist/core/engine/intensity.js +0 -163
- package/dist/core/engine/intent.js +0 -260
- package/dist/core/engine/native-pugi.js +0 -1616
- package/dist/core/engine/noop.js +0 -27
- package/dist/core/engine/prompts.js +0 -236
- package/dist/core/engine/strip-internal-fields.js +0 -124
- package/dist/core/engine/tool-bridge.js +0 -2173
- package/dist/core/engine/verification-patterns.js +0 -195
- package/dist/core/evaluation/golden-dataset.js +0 -293
- package/dist/core/feedback/queue.js +0 -177
- package/dist/core/feedback/submitter.js +0 -145
- package/dist/core/file-cache.js +0 -141
- package/dist/core/flatten/flatten-repo.js +0 -439
- package/dist/core/format/osc8-link.js +0 -28
- package/dist/core/hook-chains.js +0 -392
- package/dist/core/hooks/citation-verify-hook.js +0 -138
- package/dist/core/hooks/citation-verify.js +0 -112
- package/dist/core/hooks/events.js +0 -46
- package/dist/core/hooks/index.js +0 -15
- package/dist/core/hooks/registry.js +0 -216
- package/dist/core/hooks/runner.js +0 -236
- package/dist/core/hooks/v2/event-emitter.js +0 -115
- package/dist/core/hooks/v2/executor.js +0 -282
- package/dist/core/hooks/v2/index.js +0 -25
- package/dist/core/hooks/v2/lifecycle.js +0 -104
- package/dist/core/hooks/v2/loader.js +0 -216
- package/dist/core/hooks/v2/matcher.js +0 -125
- package/dist/core/hooks/v2/trust.js +0 -143
- package/dist/core/hooks/v2/types.js +0 -86
- package/dist/core/hooks/worktree-events.js +0 -158
- package/dist/core/hooks.js +0 -415
- package/dist/core/image/renderer.js +0 -71
- package/dist/core/index-store.js +0 -260
- package/dist/core/init/detector.js +0 -582
- package/dist/core/init/template-renderer.js +0 -242
- package/dist/core/jobs/registry.js +0 -462
- package/dist/core/ledger/results-tsv.js +0 -142
- package/dist/core/log-discipline/stdout-redirect.js +0 -51
- package/dist/core/lsp/cache.js +0 -105
- package/dist/core/lsp/client.js +0 -1229
- package/dist/core/lsp/language-detect.js +0 -66
- package/dist/core/lsp/post-edit-diagnostics.js +0 -171
- package/dist/core/lsp/server-detect.js +0 -173
- package/dist/core/lsp/symbol-cache.js +0 -162
- package/dist/core/lsp/symbol-tools.js +0 -664
- package/dist/core/mcp/client.js +0 -385
- package/dist/core/mcp/http-server.js +0 -553
- package/dist/core/mcp/orchestrator-config.js +0 -192
- package/dist/core/mcp/orchestrator-tools.js +0 -806
- package/dist/core/mcp/permission.js +0 -190
- package/dist/core/mcp/registry.js +0 -193
- package/dist/core/mcp/server-tools.js +0 -219
- package/dist/core/mcp/server.js +0 -397
- package/dist/core/mcp/trust.js +0 -91
- package/dist/core/memory/dual-write.js +0 -416
- package/dist/core/memory/passive-extract.js +0 -130
- package/dist/core/memory/phase1-kinds.js +0 -20
- package/dist/core/memory/secret-scanner.js +0 -304
- package/dist/core/memory-sync/queue.js +0 -170
- package/dist/core/metrics/extract.js +0 -113
- package/dist/core/modes/roo-modes.js +0 -68
- package/dist/core/onboarding/ensure-initialized.js +0 -133
- package/dist/core/onboarding/marker.js +0 -111
- package/dist/core/onboarding/telemetry-state.js +0 -108
- package/dist/core/output-style/presets.js +0 -176
- package/dist/core/output-style/state.js +0 -185
- package/dist/core/path-security.js +0 -345
- package/dist/core/permission.js +0 -369
- package/dist/core/permissions/auto-classifier.js +0 -124
- package/dist/core/permissions/bash-parser.js +0 -371
- package/dist/core/permissions/circuit-breaker.js +0 -83
- package/dist/core/permissions/constrained-edit.js +0 -91
- package/dist/core/permissions/gate.js +0 -278
- package/dist/core/permissions/index.js +0 -20
- package/dist/core/permissions/mode.js +0 -174
- package/dist/core/permissions/network-egress.js +0 -137
- package/dist/core/permissions/state.js +0 -241
- package/dist/core/permissions/tool-class.js +0 -107
- package/dist/core/plan-mode/ui-state.js +0 -51
- package/dist/core/plans/plan-artifact.js +0 -721
- package/dist/core/policy-limits/etag-store.js +0 -122
- package/dist/core/prd-check/parser.js +0 -215
- package/dist/core/prd-check/reporter.js +0 -127
- package/dist/core/prd-check/session-review.js +0 -557
- package/dist/core/prd-check/verifiers.js +0 -223
- package/dist/core/prompt-cache/client-cache.js +0 -99
- package/dist/core/prompts/assembly.js +0 -29
- package/dist/core/prompts/registry.js +0 -364
- package/dist/core/pugi-gitignore.js +0 -52
- package/dist/core/pugi-md/cc-compat-rules.js +0 -735
- package/dist/core/pugi-md/context-injector.js +0 -76
- package/dist/core/pugi-md/walk-up.js +0 -207
- package/dist/core/python/uv-installer.js +0 -270
- package/dist/core/python/uv-resolver.js +0 -83
- package/dist/core/rate-limit/narrator.js +0 -146
- package/dist/core/recipes/cli-types.js +0 -20
- package/dist/core/recipes/loader.js +0 -103
- package/dist/core/recipes/runner.js +0 -345
- package/dist/core/recipes/schema.js +0 -587
- package/dist/core/release-notes/parser.js +0 -241
- package/dist/core/release-notes/state.js +0 -116
- package/dist/core/repl/ask.js +0 -512
- package/dist/core/repl/cancellation.js +0 -98
- package/dist/core/repl/cap-warning.js +0 -91
- package/dist/core/repl/clipboard-read.js +0 -174
- package/dist/core/repl/dispatch-fsm.js +0 -220
- package/dist/core/repl/engine-bridge.js +0 -303
- package/dist/core/repl/history-search.js +0 -175
- package/dist/core/repl/history.js +0 -182
- package/dist/core/repl/kill-ring.js +0 -138
- package/dist/core/repl/model-pricing.js +0 -135
- package/dist/core/repl/privacy-banner.js +0 -71
- package/dist/core/repl/session.js +0 -4962
- package/dist/core/repl/slash-commands.js +0 -747
- package/dist/core/repl/store/index.js +0 -12
- package/dist/core/repl/store/jsonl-log.js +0 -321
- package/dist/core/repl/store/lockfile.js +0 -155
- package/dist/core/repl/store/session-store.js +0 -821
- package/dist/core/repl/store/types.js +0 -44
- package/dist/core/repl/store/uuid-v7.js +0 -68
- package/dist/core/repl/tool-route.js +0 -382
- package/dist/core/repl/workspace-context.js +0 -206
- package/dist/core/repo-map/build.js +0 -125
- package/dist/core/repo-map/cache.js +0 -185
- package/dist/core/repo-map/extractor.js +0 -254
- package/dist/core/repo-map/formatter.js +0 -145
- package/dist/core/repo-map/page-rank.js +0 -105
- package/dist/core/repo-map/scanner.js +0 -211
- package/dist/core/retro/git-collector.js +0 -251
- package/dist/core/retro/health-card.js +0 -25
- package/dist/core/retro/metrics.js +0 -342
- package/dist/core/retro/narrative.js +0 -249
- package/dist/core/retro/plane-collector.js +0 -274
- package/dist/core/retro/pr-issue-link.js +0 -65
- package/dist/core/retro/types.js +0 -16
- package/dist/core/retry-budget/budget.js +0 -284
- package/dist/core/retry-budget/index.js +0 -5
- package/dist/core/retry-budget/retry-cap.js +0 -74
- package/dist/core/routing/lead-worker.js +0 -43
- package/dist/core/routing/pre-flight-estimator.js +0 -108
- package/dist/core/runs/run-tree.js +0 -103
- package/dist/core/sandboxing/adapter.js +0 -29
- package/dist/core/sandboxing/index.js +0 -49
- package/dist/core/sandboxing/none.js +0 -19
- package/dist/core/sandboxing/seatbelt.js +0 -183
- package/dist/core/security/injection-scanner.js +0 -367
- package/dist/core/security/output-filter.js +0 -418
- package/dist/core/session/env-file.js +0 -105
- package/dist/core/session/section-budgets.js +0 -140
- package/dist/core/session.js +0 -377
- package/dist/core/settings.js +0 -400
- package/dist/core/share/formatter.js +0 -271
- package/dist/core/share/redactor.js +0 -221
- package/dist/core/share/uploader.js +0 -267
- package/dist/core/skills/defaults.js +0 -457
- package/dist/core/skills/loader.js +0 -454
- package/dist/core/skills/sources.js +0 -480
- package/dist/core/skills/trust.js +0 -172
- package/dist/core/smoke/headless-driver.js +0 -174
- package/dist/core/smoke/orchestrator.js +0 -194
- package/dist/core/smoke/runner.js +0 -238
- package/dist/core/smoke/scenario-parser.js +0 -316
- package/dist/core/statusline.js +0 -99
- package/dist/core/subagents/dispatcher-real.js +0 -600
- package/dist/core/subagents/dispatcher.js +0 -352
- package/dist/core/subagents/index.js +0 -39
- package/dist/core/subagents/isolation-matrix.js +0 -213
- package/dist/core/subagents/spawn.js +0 -101
- package/dist/core/telemetry/emitter.js +0 -229
- package/dist/core/telemetry/queue.js +0 -251
- package/dist/core/theme/context.js +0 -91
- package/dist/core/theme/presets.js +0 -228
- package/dist/core/theme/state.js +0 -181
- package/dist/core/todos/invariant.js +0 -10
- package/dist/core/todos/state.js +0 -177
- package/dist/core/tool-schema/compressor.js +0 -89
- package/dist/core/transport/version-interceptor.js +0 -166
- package/dist/core/trust.js +0 -109
- package/dist/core/tui/thinking-block.js +0 -64
- package/dist/core/vim/keymap.js +0 -288
- package/dist/core/vim/state.js +0 -92
- package/dist/core/watch-markers/marker-watcher.js +0 -133
- package/dist/core/worktree/include-parser.js +0 -249
- package/dist/core/worktree-manager/cleanup.js +0 -123
- package/dist/core/worktree-manager/manager.js +0 -303
- package/dist/index.js +0 -44
- package/dist/runtime/bootstrap.js +0 -190
- package/dist/runtime/cli.js +0 -8121
- package/dist/runtime/commands/agents.js +0 -385
- package/dist/runtime/commands/budget.js +0 -192
- package/dist/runtime/commands/cancel.js +0 -231
- package/dist/runtime/commands/chain.js +0 -489
- package/dist/runtime/commands/codegraph-status.js +0 -227
- package/dist/runtime/commands/compact.js +0 -297
- package/dist/runtime/commands/config.js +0 -595
- package/dist/runtime/commands/cost.js +0 -199
- package/dist/runtime/commands/delegate.js +0 -312
- package/dist/runtime/commands/dispatch.js +0 -126
- package/dist/runtime/commands/doctor.js +0 -579
- package/dist/runtime/commands/feedback.js +0 -184
- package/dist/runtime/commands/hooks.js +0 -187
- package/dist/runtime/commands/init.js +0 -254
- package/dist/runtime/commands/lsp.js +0 -368
- package/dist/runtime/commands/mcp.js +0 -935
- package/dist/runtime/commands/memory.js +0 -582
- package/dist/runtime/commands/model.js +0 -237
- package/dist/runtime/commands/onboarding.js +0 -275
- package/dist/runtime/commands/patch.js +0 -128
- package/dist/runtime/commands/permissions.js +0 -112
- package/dist/runtime/commands/plan.js +0 -143
- package/dist/runtime/commands/prd-check.js +0 -285
- package/dist/runtime/commands/privacy.js +0 -107
- package/dist/runtime/commands/recipe.js +0 -325
- package/dist/runtime/commands/redo-blob-store.js +0 -92
- package/dist/runtime/commands/redo.js +0 -361
- package/dist/runtime/commands/release-notes.js +0 -229
- package/dist/runtime/commands/repo-map.js +0 -95
- package/dist/runtime/commands/report.js +0 -299
- package/dist/runtime/commands/resume.js +0 -118
- package/dist/runtime/commands/review-consensus.js +0 -414
- package/dist/runtime/commands/rewind.js +0 -333
- package/dist/runtime/commands/roster.js +0 -117
- package/dist/runtime/commands/sessions.js +0 -163
- package/dist/runtime/commands/share.js +0 -316
- package/dist/runtime/commands/skills.js +0 -401
- package/dist/runtime/commands/status.js +0 -186
- package/dist/runtime/commands/stickers.js +0 -82
- package/dist/runtime/commands/style.js +0 -194
- package/dist/runtime/commands/theme.js +0 -196
- package/dist/runtime/commands/undo.js +0 -361
- package/dist/runtime/commands/update.js +0 -289
- package/dist/runtime/commands/vim.js +0 -140
- package/dist/runtime/commands/worktree.js +0 -177
- package/dist/runtime/commands/worktrees.js +0 -155
- package/dist/runtime/deprecation-warning.js +0 -69
- package/dist/runtime/engine-exit-code.js +0 -50
- package/dist/runtime/headless-repl.js +0 -195
- package/dist/runtime/headless.js +0 -548
- package/dist/runtime/load-hooks-or-exit.js +0 -71
- package/dist/runtime/plan-decompose.js +0 -531
- package/dist/runtime/sigint-guard.js +0 -272
- package/dist/runtime/stream-renderer.js +0 -195
- package/dist/runtime/update-check.js +0 -294
- package/dist/runtime/version.js +0 -65
- package/dist/runtime/worktree-bootstrap.js +0 -579
- package/dist/skills/bundled/batch.js +0 -617
- package/dist/skills/bundled/index.js +0 -45
- package/dist/skills/bundled/loop.js +0 -358
- package/dist/skills/bundled/remember.js +0 -383
- package/dist/skills/bundled/simplify.js +0 -289
- package/dist/skills/bundled/skillify.js +0 -373
- package/dist/skills/bundled/stuck.js +0 -558
- package/dist/skills/bundled/verify.js +0 -439
- package/dist/testing/vcr.js +0 -486
- package/dist/tools/agent-tool.js +0 -229
- package/dist/tools/apply-patch.js +0 -556
- package/dist/tools/ask-user-question.js +0 -337
- package/dist/tools/ask-user.js +0 -115
- package/dist/tools/bash.js +0 -1238
- package/dist/tools/brief.js +0 -224
- package/dist/tools/cron.js +0 -433
- package/dist/tools/enter-worktree.js +0 -250
- package/dist/tools/exit-worktree.js +0 -147
- package/dist/tools/file-tools.js +0 -553
- package/dist/tools/http-request.js +0 -336
- package/dist/tools/lsp-tools.js +0 -565
- package/dist/tools/mcp-tool.js +0 -260
- package/dist/tools/multi-edit.js +0 -361
- package/dist/tools/powershell.js +0 -268
- package/dist/tools/registry.js +0 -166
- package/dist/tools/server-tools.js +0 -892
- package/dist/tools/skill-tool.js +0 -96
- package/dist/tools/sleep.js +0 -99
- package/dist/tools/synthetic-output.js +0 -133
- package/dist/tools/tasks.js +0 -208
- package/dist/tools/todo-write.js +0 -184
- package/dist/tools/verify-plan-execution.js +0 -295
- package/dist/tools/web-fetch-injection-scanner.js +0 -207
- package/dist/tools/web-fetch.js +0 -720
- package/dist/tools/web-search.js +0 -458
- package/dist/tui/agent-progress-card.js +0 -111
- package/dist/tui/agent-tree-pane.js +0 -9
- package/dist/tui/agent-tree.js +0 -87
- package/dist/tui/ask-cli.js +0 -52
- package/dist/tui/ask-modal.js +0 -211
- package/dist/tui/ask-user-question-chips.js +0 -315
- package/dist/tui/ask-user-question-prompt.js +0 -203
- package/dist/tui/compact-banner.js +0 -81
- package/dist/tui/conversation-pane.js +0 -164
- package/dist/tui/cost-table.js +0 -111
- package/dist/tui/device-flow.js +0 -142
- package/dist/tui/doctor-table.js +0 -46
- package/dist/tui/feedback-prompt.js +0 -156
- package/dist/tui/input-box.js +0 -732
- package/dist/tui/login-picker.js +0 -69
- package/dist/tui/markdown-render.js +0 -266
- package/dist/tui/multi-file-diff-approval.js +0 -375
- package/dist/tui/onboarding-wizard.js +0 -240
- package/dist/tui/permissions-picker.js +0 -86
- package/dist/tui/render.js +0 -160
- package/dist/tui/repl-render.js +0 -770
- package/dist/tui/repl-splash-art.js +0 -64
- package/dist/tui/repl-splash-mascot.js +0 -154
- package/dist/tui/repl-splash.js +0 -117
- package/dist/tui/repl.js +0 -378
- package/dist/tui/slash-palette.js +0 -106
- package/dist/tui/splash-data.js +0 -61
- package/dist/tui/splash.js +0 -31
- package/dist/tui/status-bar.js +0 -209
- package/dist/tui/status-table.js +0 -7
- package/dist/tui/stickers-art.js +0 -136
- package/dist/tui/style-table.js +0 -28
- package/dist/tui/theme-table.js +0 -29
- package/dist/tui/thinking-spinner.js +0 -123
- package/dist/tui/tool-stream-pane.js +0 -140
- package/dist/tui/update-banner.js +0 -33
- package/dist/tui/vim-input.js +0 -267
- package/dist/tui/welcome-banner.js +0 -107
- package/dist/tui/welcome-data.js +0 -293
- package/dist/tui/workspace-context.js +0 -105
- package/docs/examples/codegraph.mcp.json +0 -10
- package/test/scenarios/codegen-create-file.scenario.txt +0 -13
- package/test/scenarios/compact-force.scenario.txt +0 -12
- package/test/scenarios/identity.scenario.txt +0 -11
- package/test/scenarios/persona-handoff.scenario.txt +0 -12
- package/test/scenarios/walkback.scenario.txt +0 -12
|
@@ -1,414 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `pugi review --consensus` — customer-facing triple-review .
|
|
3
|
-
*
|
|
4
|
-
* The differentiator: the upstream tool ships single-Claude review, peer CLI
|
|
5
|
-
* ships single-GPT review, Gemini CLI ships single-Gemini review. Pugi
|
|
6
|
-
* ships a 3-model consensus gate as a first-class command so customers
|
|
7
|
-
* get the same production-readiness signal we use internally - without the
|
|
8
|
-
* three CLI installs, three OAuth flows, and three subscriptions.
|
|
9
|
-
*
|
|
10
|
-
* Flow:
|
|
11
|
-
*
|
|
12
|
-
* 1. Resolve diff source from flags (`--commit` / `--pr` / `--branch`
|
|
13
|
-
* OR default to merge-base vs `origin/main`).
|
|
14
|
-
* 2. POST diff to Anvil's `POST /api/pugi/review-consensus`. Anvil
|
|
15
|
-
* fans out to 3 reviewer routes server-side and streams an SSE.
|
|
16
|
-
* 3. Render per-reviewer state inline as the SSE stream emits events.
|
|
17
|
-
* 4. After the stream closes, recompute the rubric locally (never
|
|
18
|
-
* trust the server's verdict - see anvil-fanout.ts) and print:
|
|
19
|
-
* - per-reviewer summary
|
|
20
|
-
* - rubric verdict + reasoning
|
|
21
|
-
* - recommended next action
|
|
22
|
-
* 5. Exit with 0 PASS / 1 WARN / 2 BLOCK.
|
|
23
|
-
*
|
|
24
|
-
* Backend status: at ship the admin-api endpoint is not yet
|
|
25
|
-
* deployed. The handler degrades gracefully — on `endpoint_missing`
|
|
26
|
-
* the CLI prints an actionable "backend not deployed yet" notice and
|
|
27
|
-
* exits 0 (the gate didn't run, but failing CI would be wrong because
|
|
28
|
-
* the operator did nothing wrong). The sprint lands the server.
|
|
29
|
-
*/
|
|
30
|
-
import { captureDiff } from '../../core/consensus/diff-capture.js';
|
|
31
|
-
import { dispatchConsensus, } from '../../core/consensus/anvil-fanout.js';
|
|
32
|
-
import { aggregate, exitCodeFor, reviewerVerdictFromRaw, } from '../../core/consensus/rubric.js';
|
|
33
|
-
/**
|
|
34
|
-
* Parse the command-line tail for the consensus selector + base ref. The
|
|
35
|
-
* arg list excludes the dispatcher's leading `review` keyword.
|
|
36
|
-
*
|
|
37
|
-
* Accepted forms:
|
|
38
|
-
* `--commit <sha>` / `--commit=<sha>`
|
|
39
|
-
* `--pr <number>` / `--pr=<number>`
|
|
40
|
-
* `--branch <name>` / `--branch=<name>`
|
|
41
|
-
* `--base <ref>` / `--base=<ref>` (override default origin/main)
|
|
42
|
-
*/
|
|
43
|
-
export function parseConsensusArgs(args,
|
|
44
|
-
/**
|
|
45
|
-
* (Codex r0 P1 on PR): cli.ts now parses --commit /
|
|
46
|
-
* --base in the GLOBAL flag pass for the new triple-provider path.
|
|
47
|
-
* Those tokens are consumed BEFORE this function sees `args`, so
|
|
48
|
-
* `pugi review --consensus --commit X` would silently fall back to
|
|
49
|
-
* the default diff and review the wrong changes. Pass the global
|
|
50
|
-
* flags through here so consensus picks them up when present.
|
|
51
|
-
* Inline `--commit`/`--base` tokens in args still win — explicit
|
|
52
|
-
* caller intent is preserved.
|
|
53
|
-
*/
|
|
54
|
-
fallback) {
|
|
55
|
-
const spec = {};
|
|
56
|
-
if (fallback?.commit)
|
|
57
|
-
spec.commit = fallback.commit;
|
|
58
|
-
if (fallback?.base)
|
|
59
|
-
spec.baseRef = fallback.base;
|
|
60
|
-
for (let i = 0; i < args.length; i += 1) {
|
|
61
|
-
const arg = args[i] ?? '';
|
|
62
|
-
const equalsIdx = arg.indexOf('=');
|
|
63
|
-
const key = equalsIdx === -1 ? arg : arg.slice(0, equalsIdx);
|
|
64
|
-
const inline = equalsIdx === -1 ? null : arg.slice(equalsIdx + 1);
|
|
65
|
-
const value = inline ?? args[i + 1] ?? '';
|
|
66
|
-
const consumed = inline !== null ? 0 : 1;
|
|
67
|
-
if (key === '--commit') {
|
|
68
|
-
if (!value)
|
|
69
|
-
throw new Error('--commit requires a SHA');
|
|
70
|
-
spec.commit = value;
|
|
71
|
-
i += consumed;
|
|
72
|
-
}
|
|
73
|
-
else if (key === '--pr') {
|
|
74
|
-
if (!value)
|
|
75
|
-
throw new Error('--pr requires a number');
|
|
76
|
-
const parsed = Number.parseInt(value, 10);
|
|
77
|
-
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
78
|
-
throw new Error(`--pr expects a positive integer, got "${value}"`);
|
|
79
|
-
}
|
|
80
|
-
spec.pr = parsed;
|
|
81
|
-
i += consumed;
|
|
82
|
-
}
|
|
83
|
-
else if (key === '--branch') {
|
|
84
|
-
if (!value)
|
|
85
|
-
throw new Error('--branch requires a name');
|
|
86
|
-
spec.branch = value;
|
|
87
|
-
i += consumed;
|
|
88
|
-
}
|
|
89
|
-
else if (key === '--base') {
|
|
90
|
-
if (!value)
|
|
91
|
-
throw new Error('--base requires a ref');
|
|
92
|
-
spec.baseRef = value;
|
|
93
|
-
i += consumed;
|
|
94
|
-
}
|
|
95
|
-
// Unknown args are dropped — `--consensus` itself, `--remote`, `--json`
|
|
96
|
-
// and other passthrough flags are interpreted by the cli.ts parser
|
|
97
|
-
// before this function ever sees them.
|
|
98
|
-
}
|
|
99
|
-
return spec;
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Run the consensus review. Returns the intended process exit code so
|
|
103
|
-
* the caller owns the global `process.exitCode` write. This avoids the
|
|
104
|
-
* REPL leak where a slash-invocation would otherwise inherit a stale
|
|
105
|
-
* exit code from a previous consensus run.
|
|
106
|
-
*
|
|
107
|
-
* Exit code contract (matches `handleFanoutFailure` + `exitCodeFor`):
|
|
108
|
-
*
|
|
109
|
-
* 0 = endpoint_missing (graceful degrade, consensus disabled on tier)
|
|
110
|
-
* 0 = PASS (rubric clean) OR empty diff (nothing to review)
|
|
111
|
-
* 1 = WARN (rubric: one reviewer P1, informational)
|
|
112
|
-
* 2 = BLOCK (rubric: P0 or consensus P1) / failed / capture_failed
|
|
113
|
-
* 5 = auth_missing (no credentials) / unauthenticated (token rejected)
|
|
114
|
-
* 7 = rate_limited (quota exhausted, retry after backoff)
|
|
115
|
-
*
|
|
116
|
-
* Aligned with the legacy `describeSubmitFailure` in cli.ts so shell
|
|
117
|
-
* scripts can branch on identical codes across both review surfaces.
|
|
118
|
-
*/
|
|
119
|
-
export async function runReviewConsensus(args, ctx) {
|
|
120
|
-
if (!ctx.config) {
|
|
121
|
-
const text = [
|
|
122
|
-
'pugi review --consensus needs Pugi credentials.',
|
|
123
|
-
'Run `pugi login --token <PAT>` or export PUGI_API_KEY for CI.',
|
|
124
|
-
].join('\n');
|
|
125
|
-
ctx.writeOutput({
|
|
126
|
-
command: 'review-consensus',
|
|
127
|
-
status: 'auth_missing',
|
|
128
|
-
message: text,
|
|
129
|
-
}, text);
|
|
130
|
-
return 5;
|
|
131
|
-
}
|
|
132
|
-
// Capture the diff. Failures here are operator-correctable (bad ref,
|
|
133
|
-
// gh not installed for --pr, etc) so we surface a clean error and
|
|
134
|
-
// exit 2 — same as BLOCK because the gate could not even run.
|
|
135
|
-
let captured;
|
|
136
|
-
try {
|
|
137
|
-
const spec = parseConsensusArgs(args, ctx.flagsFallback);
|
|
138
|
-
captured = captureDiff({ ...spec, cwd: ctx.cwd });
|
|
139
|
-
}
|
|
140
|
-
catch (error) {
|
|
141
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
142
|
-
const text = `Failed to capture diff: ${message}`;
|
|
143
|
-
ctx.writeOutput({ command: 'review-consensus', status: 'capture_failed', message }, text);
|
|
144
|
-
return 2;
|
|
145
|
-
}
|
|
146
|
-
if (captured.diff.trim().length === 0) {
|
|
147
|
-
const text = [
|
|
148
|
-
`No diff captured for ${captured.context.ref}.`,
|
|
149
|
-
'The consensus gate has nothing to review, nothing to do.',
|
|
150
|
-
].join('\n');
|
|
151
|
-
ctx.writeOutput({
|
|
152
|
-
command: 'review-consensus',
|
|
153
|
-
status: 'completed',
|
|
154
|
-
verdict: 'PASS',
|
|
155
|
-
reasoning: 'Empty diff: trivial PASS.',
|
|
156
|
-
reviewers: [],
|
|
157
|
-
ref: captured.context.ref,
|
|
158
|
-
stats: captured.context.stats,
|
|
159
|
-
message: text,
|
|
160
|
-
}, text);
|
|
161
|
-
return 0;
|
|
162
|
-
}
|
|
163
|
-
// Banner — operator sees this immediately so a slow Anvil call does
|
|
164
|
-
// not look like the CLI hanging.
|
|
165
|
-
ctx.emit(`Capturing diff (${captured.context.ref})… ${captured.context.stats.filesChanged} files, ` +
|
|
166
|
-
`+${captured.context.stats.insertions} -${captured.context.stats.deletions}\n`);
|
|
167
|
-
ctx.emit('Dispatching to 3 reviewers: codex · claude · deepseek\n\n');
|
|
168
|
-
const reviewerEvents = [];
|
|
169
|
-
const sink = (event) => {
|
|
170
|
-
if (event.type === 'consensus') {
|
|
171
|
-
// Server-side verdict is informational — we recompute below. We
|
|
172
|
-
// still surface it on the stream so the operator sees activity.
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
reviewerEvents.push(event);
|
|
176
|
-
ctx.emit(formatReviewerEventLine(event));
|
|
177
|
-
};
|
|
178
|
-
const dispatch = ctx.dispatch ?? dispatchConsensus;
|
|
179
|
-
const fanoutResult = await dispatch(ctx.config, {
|
|
180
|
-
diff: captured.diff,
|
|
181
|
-
context: {
|
|
182
|
-
branch: captured.context.branch,
|
|
183
|
-
commit: captured.context.commit,
|
|
184
|
-
title: captured.context.title,
|
|
185
|
-
},
|
|
186
|
-
}, sink);
|
|
187
|
-
if (fanoutResult.status !== 'ok') {
|
|
188
|
-
return handleFanoutFailure(fanoutResult, ctx);
|
|
189
|
-
}
|
|
190
|
-
// Collapse the SSE event stream into one `ReviewerVerdict` per
|
|
191
|
-
// reviewer. The final `verdict` event for a reviewer wins; earlier
|
|
192
|
-
// `started` events are scaffolding for the live UI only.
|
|
193
|
-
const verdicts = collapseVerdicts(reviewerEvents);
|
|
194
|
-
const result = aggregate(verdicts);
|
|
195
|
-
ctx.emit('\n────────────────────────────────────────\n');
|
|
196
|
-
for (const verdict of verdicts) {
|
|
197
|
-
ctx.emit(formatReviewerSummaryLine(verdict));
|
|
198
|
-
}
|
|
199
|
-
ctx.emit('\n────────────────────────────────────────\n');
|
|
200
|
-
ctx.emit(`Rubric: ${result.verdict}\n`);
|
|
201
|
-
ctx.emit(` ${result.reasoning}\n`);
|
|
202
|
-
ctx.emit('\n');
|
|
203
|
-
ctx.emit(`Recommended action: ${recommendedAction(result)}\n`);
|
|
204
|
-
ctx.writeOutput({
|
|
205
|
-
command: 'review-consensus',
|
|
206
|
-
status: 'completed',
|
|
207
|
-
verdict: result.verdict,
|
|
208
|
-
reasoning: result.reasoning,
|
|
209
|
-
reviewers: verdicts.map((v) => ({
|
|
210
|
-
reviewer: v.reviewer,
|
|
211
|
-
topSeverity: v.topSeverity,
|
|
212
|
-
findingCount: v.findings.length,
|
|
213
|
-
errored: v.errored,
|
|
214
|
-
})),
|
|
215
|
-
ref: captured.context.ref,
|
|
216
|
-
stats: captured.context.stats,
|
|
217
|
-
}, [
|
|
218
|
-
`Pugi consensus ${result.verdict}`,
|
|
219
|
-
result.reasoning,
|
|
220
|
-
`Reviewers: ${verdicts.map((v) => `${v.reviewer}=${v.topSeverity ?? 'CLEAN'}`).join(' · ')}`,
|
|
221
|
-
].join('\n'));
|
|
222
|
-
return exitCodeFor(result.verdict);
|
|
223
|
-
}
|
|
224
|
-
/**
|
|
225
|
-
* Translate a fanout failure variant to the matching exit code + output
|
|
226
|
-
* envelope. Returns the exit code so the caller owns `process.exitCode`
|
|
227
|
-
* (avoiding the REPL-inherited-exit-code leak).
|
|
228
|
-
*/
|
|
229
|
-
function handleFanoutFailure(result, ctx) {
|
|
230
|
-
if (result.status === 'endpoint_missing') {
|
|
231
|
-
const message = [
|
|
232
|
-
'Backend not deployed yet: the consensus endpoint lands in alpha 6.7.1.',
|
|
233
|
-
'No exit-1/2 gate: this is a CLI-side surface waiting for the server.',
|
|
234
|
-
'Run `pugi review --triple --remote` for the legacy artifact-based flow.',
|
|
235
|
-
].join('\n');
|
|
236
|
-
ctx.emit('\n');
|
|
237
|
-
ctx.emit(`${message}\n`);
|
|
238
|
-
ctx.writeOutput({ command: 'review-consensus', status: 'endpoint_missing', message }, message);
|
|
239
|
-
// Graceful: operator did nothing wrong, server pending. Exit 0 so
|
|
240
|
-
// CI does not redden on the deploy-lag window.
|
|
241
|
-
return 0;
|
|
242
|
-
}
|
|
243
|
-
if (result.status === 'unauthenticated') {
|
|
244
|
-
const message = `${result.message}. Run \`pugi login --token <PAT>\` and retry.`;
|
|
245
|
-
ctx.emit('\n');
|
|
246
|
-
ctx.emit(`${message}\n`);
|
|
247
|
-
ctx.writeOutput({ command: 'review-consensus', status: 'unauthenticated', message }, message);
|
|
248
|
-
return 5;
|
|
249
|
-
}
|
|
250
|
-
if (result.status === 'rate_limited') {
|
|
251
|
-
const seconds = Math.round(result.retryAfterMs / 1000);
|
|
252
|
-
const message = `Rate limit: retry after ${seconds}s.`;
|
|
253
|
-
ctx.emit('\n');
|
|
254
|
-
ctx.emit(`${message}\n`);
|
|
255
|
-
ctx.writeOutput({ command: 'review-consensus', status: 'rate_limited', message }, message);
|
|
256
|
-
// Exit code contract (kept in sync with `runReviewConsensus`):
|
|
257
|
-
// 0 = endpoint_missing (graceful degrade, consensus disabled on tier)
|
|
258
|
-
// 0 = PASS / empty diff
|
|
259
|
-
// 1 = WARN (informational, single asymmetric P1)
|
|
260
|
-
// 2 = BLOCK / failed / capture_failed (real findings or unrecoverable)
|
|
261
|
-
// 5 = auth_missing / unauthenticated (token rejected by Anvil)
|
|
262
|
-
// 7 = rate_limited (quota exhausted, retry with backoff)
|
|
263
|
-
//
|
|
264
|
-
// Aligned with the legacy `describeSubmitFailure` in cli.ts so a
|
|
265
|
-
// shell script branching on exit code behaves identically across
|
|
266
|
-
// the legacy triple-review and consensus surfaces.
|
|
267
|
-
return 7;
|
|
268
|
-
}
|
|
269
|
-
const message = result.message;
|
|
270
|
-
ctx.emit('\n');
|
|
271
|
-
ctx.emit(`Consensus call failed: ${message}\n`);
|
|
272
|
-
ctx.writeOutput({ command: 'review-consensus', status: 'failed', message }, `Consensus call failed: ${message}`);
|
|
273
|
-
return 2;
|
|
274
|
-
}
|
|
275
|
-
/**
|
|
276
|
-
* Map per-reviewer SSE events to the rubric input shape. One reviewer
|
|
277
|
-
* may emit `started` then `verdict`; the `verdict` event carries the
|
|
278
|
-
* raw text we feed parseFindings.
|
|
279
|
-
*
|
|
280
|
-
* Precedence (verdict wins over error):
|
|
281
|
-
*
|
|
282
|
-
* started -> verdict => verdict (rubric processes findings)
|
|
283
|
-
* started -> error => error (errored=true, no signal)
|
|
284
|
-
* started -> verdict -> error => verdict (terminal verdict wins; the
|
|
285
|
-
* trailing error is a stale retry/transport artifact and must NOT
|
|
286
|
-
* silently downgrade a real P0 BLOCK to "all errored")
|
|
287
|
-
* started -> error -> verdict => verdict (verdict still wins)
|
|
288
|
-
* started (no terminal) => errored placeholder so the reviewer
|
|
289
|
-
* appears in the output instead of being
|
|
290
|
-
* silently dropped
|
|
291
|
-
*
|
|
292
|
-
* The verdict-wins-over-error rule is the fix for a real BLOCK
|
|
293
|
-
* downgrade: Anvil's SSE emitter can send a verdict frame followed by
|
|
294
|
-
* an error frame when a retry layer fires after the terminal verdict
|
|
295
|
-
* already shipped. Without precedence the error would clobber the
|
|
296
|
-
* real verdict and produce a false "errored=true" -> no findings ->
|
|
297
|
-
* possible PASS instead of BLOCK.
|
|
298
|
-
*/
|
|
299
|
-
function collapseVerdicts(events) {
|
|
300
|
-
const byReviewer = new Map();
|
|
301
|
-
for (const event of events) {
|
|
302
|
-
const prior = byReviewer.get(event.reviewer);
|
|
303
|
-
if (event.type === 'verdict') {
|
|
304
|
-
// Verdict is always the terminal outcome - overwrite anything we
|
|
305
|
-
// had before (started placeholder, or a stale error frame).
|
|
306
|
-
byReviewer.set(event.reviewer, event);
|
|
307
|
-
}
|
|
308
|
-
else if (event.type === 'error') {
|
|
309
|
-
// Error only wins if no verdict has arrived yet for this reviewer.
|
|
310
|
-
// Once we hold a verdict, a trailing error is transport noise and
|
|
311
|
-
// must not downgrade the verdict to "errored".
|
|
312
|
-
if (!prior || prior.type !== 'verdict') {
|
|
313
|
-
byReviewer.set(event.reviewer, event);
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
else if (!prior) {
|
|
317
|
-
// started: hold as placeholder so the reviewer appears in the
|
|
318
|
-
// output even if the stream cuts off before a terminal frame.
|
|
319
|
-
byReviewer.set(event.reviewer, event);
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
const out = [];
|
|
323
|
-
for (const [reviewer, event] of byReviewer) {
|
|
324
|
-
if (event.type === 'verdict' && typeof event.rawContent === 'string') {
|
|
325
|
-
out.push(reviewerVerdictFromRaw(reviewer, event.rawContent, false));
|
|
326
|
-
}
|
|
327
|
-
else if (event.type === 'error' || event.error) {
|
|
328
|
-
out.push(reviewerVerdictFromRaw(reviewer, '', true));
|
|
329
|
-
}
|
|
330
|
-
else {
|
|
331
|
-
// Stream ended mid-flight for this reviewer - treat as errored
|
|
332
|
-
// so the rubric's "all errored -> BLOCK" branch fires instead of
|
|
333
|
-
// a misleading PASS.
|
|
334
|
-
out.push(reviewerVerdictFromRaw(reviewer, '', true));
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
// Deterministic order: codex, claude, deepseek first, then anyone else
|
|
338
|
-
// alphabetical. Matches the UX preview in the spec and stabilizes JSON
|
|
339
|
-
// output for snapshot diffs.
|
|
340
|
-
const priority = { codex: 0, claude: 1, deepseek: 2 };
|
|
341
|
-
out.sort((a, b) => {
|
|
342
|
-
const pa = priority[a.reviewer] ?? 99;
|
|
343
|
-
const pb = priority[b.reviewer] ?? 99;
|
|
344
|
-
if (pa !== pb)
|
|
345
|
-
return pa - pb;
|
|
346
|
-
return a.reviewer.localeCompare(b.reviewer);
|
|
347
|
-
});
|
|
348
|
-
return out;
|
|
349
|
-
}
|
|
350
|
-
function formatReviewerEventLine(event) {
|
|
351
|
-
const name = event.reviewer.padEnd(9);
|
|
352
|
-
if (event.type === 'started') {
|
|
353
|
-
return ` ${name} reviewing…\n`;
|
|
354
|
-
}
|
|
355
|
-
if (event.type === 'error') {
|
|
356
|
-
const why = event.error ?? 'unknown';
|
|
357
|
-
const ms = event.latencyMs ? ` ${event.latencyMs}ms` : '';
|
|
358
|
-
return ` ${name} ERROR: ${why}${ms}\n`;
|
|
359
|
-
}
|
|
360
|
-
const severity = event.severity ?? 'CLEAN';
|
|
361
|
-
const ms = event.latencyMs ? ` ${event.latencyMs}ms` : '';
|
|
362
|
-
return ` ${name} ${severity}${ms}\n`;
|
|
363
|
-
}
|
|
364
|
-
function formatReviewerSummaryLine(verdict) {
|
|
365
|
-
const name = verdict.reviewer.padEnd(9);
|
|
366
|
-
if (verdict.errored) {
|
|
367
|
-
return ` ${name} ERROR (no signal)\n`;
|
|
368
|
-
}
|
|
369
|
-
if (verdict.findings.length === 0) {
|
|
370
|
-
return ` ${name} CLEAN\n`;
|
|
371
|
-
}
|
|
372
|
-
// Group counts: shows operator the severity breakdown in one line.
|
|
373
|
-
const counts = countSeverities(verdict);
|
|
374
|
-
const summary = formatCounts(counts);
|
|
375
|
-
const top = verdict.findings.slice(0, 3);
|
|
376
|
-
const tail = verdict.findings.length > 3 ? `\n … ${verdict.findings.length - 3} more` : '';
|
|
377
|
-
const findings = top.map((f) => `\n - [${f.severity}] ${f.summary}`).join('');
|
|
378
|
-
return ` ${name} ${summary}${findings}${tail}\n`;
|
|
379
|
-
}
|
|
380
|
-
function countSeverities(verdict) {
|
|
381
|
-
const counts = { P0: 0, P1: 0, P2: 0, P3: 0 };
|
|
382
|
-
for (const f of verdict.findings)
|
|
383
|
-
counts[f.severity] += 1;
|
|
384
|
-
return counts;
|
|
385
|
-
}
|
|
386
|
-
function formatCounts(counts) {
|
|
387
|
-
const parts = [];
|
|
388
|
-
if (counts.P0 > 0)
|
|
389
|
-
parts.push(`${counts.P0}× P0`);
|
|
390
|
-
if (counts.P1 > 0)
|
|
391
|
-
parts.push(`${counts.P1}× P1`);
|
|
392
|
-
if (counts.P2 > 0)
|
|
393
|
-
parts.push(`${counts.P2}× P2`);
|
|
394
|
-
if (counts.P3 > 0)
|
|
395
|
-
parts.push(`${counts.P3}× P3`);
|
|
396
|
-
if (parts.length === 0)
|
|
397
|
-
return 'CLEAN';
|
|
398
|
-
return `[${parts.join(', ')}]`;
|
|
399
|
-
}
|
|
400
|
-
/**
|
|
401
|
-
* Recommended action surfaced as the last line of the human-readable
|
|
402
|
-
* UX. Maps to the rubric verdict + finding shape so the operator does
|
|
403
|
-
* not need to interpret `[P1]` themselves.
|
|
404
|
-
*/
|
|
405
|
-
function recommendedAction(result) {
|
|
406
|
-
if (result.verdict === 'PASS') {
|
|
407
|
-
return 'Ship it: no blocking findings.';
|
|
408
|
-
}
|
|
409
|
-
if (result.verdict === 'WARN') {
|
|
410
|
-
return 'Examine the lone P1, decide accept-as-FP or fix, then re-run.';
|
|
411
|
-
}
|
|
412
|
-
return 'Fix the blocking findings, then re-run `pugi review --consensus`.';
|
|
413
|
-
}
|
|
414
|
-
//# sourceMappingURL=review-consensus.js.map
|