supipowers 1.5.3 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.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 +131 -42
- 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 +18 -8
- 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 +135 -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 +268 -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 +221 -109
- package/src/review/fixer.ts +10 -6
- package/src/review/multi-agent-runner.ts +114 -13
- 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 +1 -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 +1399 -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
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slash-command handlers for the multi-stage authoring pipeline.
|
|
3
|
+
*
|
|
4
|
+
* Each exported `handle*` function corresponds to a `/supi:ultraplan <subcommand>`. They wire
|
|
5
|
+
* the picker, TUI input, and pipeline driver so the command file (`src/commands/ultraplan.ts`)
|
|
6
|
+
* stays focused on routing.
|
|
7
|
+
*
|
|
8
|
+
* These handlers are deliberately UI-light: they call `ctx.ui.input` and `ctx.ui.select` for
|
|
9
|
+
* the user gate moments specified in the plan; everything else is delegated to
|
|
10
|
+
* `runPipelineUntilGate` and the per-stage runners.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import * as fs from "node:fs";
|
|
14
|
+
|
|
15
|
+
import type { Platform } from "../../platform/types.js";
|
|
16
|
+
import { notifyError, notifyInfo, notifyWarning } from "../../notifications/renderer.js";
|
|
17
|
+
import { loadModelConfig } from "../../config/model-config.js";
|
|
18
|
+
import {
|
|
19
|
+
getUltraplanAuthoringDir,
|
|
20
|
+
getUltraplanSessionDir,
|
|
21
|
+
} from "../project-paths.js";
|
|
22
|
+
import {
|
|
23
|
+
ULTRAPLAN_AUTHORED_JSON_FILENAME,
|
|
24
|
+
} from "../project-paths.js";
|
|
25
|
+
import { loadUltraPlanIndex, saveUltraPlanManifest } from "../storage.js";
|
|
26
|
+
import {
|
|
27
|
+
listInFlightAuthoringSessions,
|
|
28
|
+
runPipelineUntilGate,
|
|
29
|
+
runStage,
|
|
30
|
+
type PipelineGateMode,
|
|
31
|
+
} from "./pipeline.js";
|
|
32
|
+
import type {
|
|
33
|
+
UltraPlanAuthoringStage,
|
|
34
|
+
UltraPlanManifest,
|
|
35
|
+
} from "../../types.js";
|
|
36
|
+
import path from "node:path";
|
|
37
|
+
|
|
38
|
+
const ULTRAPLAN_ID_PREFIX = "up-";
|
|
39
|
+
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
// Helpers
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
|
|
44
|
+
function newAuthoringSessionId(now: () => Date = () => new Date()): string {
|
|
45
|
+
// Mirrors the existing convention in authoring-wizard.ts: `up-<ms>-<rand>`.
|
|
46
|
+
const ms = now().getTime();
|
|
47
|
+
const rand = Math.floor(Math.random() * 0xffffff).toString(16).padStart(6, "0");
|
|
48
|
+
return `${ULTRAPLAN_ID_PREFIX}${ms.toString(36)}-${rand}`;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function projectName(cwd: string): string {
|
|
52
|
+
return path.basename(path.resolve(cwd));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function makeBootstrapManifest(sessionId: string, projName: string): UltraPlanManifest {
|
|
56
|
+
const nowIso = new Date().toISOString();
|
|
57
|
+
return {
|
|
58
|
+
sessionId,
|
|
59
|
+
projectName: projName,
|
|
60
|
+
title: "(authoring)",
|
|
61
|
+
authored: { json: ULTRAPLAN_AUTHORED_JSON_FILENAME, markdown: undefined as never },
|
|
62
|
+
state: "ready",
|
|
63
|
+
cursor: null,
|
|
64
|
+
lastCompleted: null,
|
|
65
|
+
progress: { total: 0, terminal: 0, blocked: 0 },
|
|
66
|
+
stacks: [],
|
|
67
|
+
blocker: null,
|
|
68
|
+
reviews: [],
|
|
69
|
+
createdAt: nowIso,
|
|
70
|
+
updatedAt: nowIso,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function isInFlightStage(stage: UltraPlanAuthoringStage): boolean {
|
|
75
|
+
return stage !== "approve";
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function readSessionsFromIndex(platform: Platform, cwd: string): string[] {
|
|
79
|
+
const index = loadUltraPlanIndex(platform.paths, cwd);
|
|
80
|
+
if (!index.ok) return [];
|
|
81
|
+
return index.value.sessions.map((s) => s.sessionId);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function isSessionPromoted(platform: Platform, cwd: string, sessionId: string): boolean {
|
|
85
|
+
// A promoted session has its canonical authored.json in the session dir.
|
|
86
|
+
const dir = getUltraplanSessionDir(platform.paths, cwd, sessionId);
|
|
87
|
+
return fs.existsSync(path.join(dir, ULTRAPLAN_AUTHORED_JSON_FILENAME));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// ---------------------------------------------------------------------------
|
|
91
|
+
// Bare-entry handler
|
|
92
|
+
// ---------------------------------------------------------------------------
|
|
93
|
+
|
|
94
|
+
export interface BareEntryInput {
|
|
95
|
+
platform: Platform;
|
|
96
|
+
ctx: any;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Bare `/supi:ultraplan` invocation: detect in-flight authoring sessions, offer Resume /
|
|
101
|
+
* Start fresh / Cancel, then drive the pipeline.
|
|
102
|
+
*/
|
|
103
|
+
export async function handleBareEntry(input: BareEntryInput): Promise<void> {
|
|
104
|
+
const { platform, ctx } = input;
|
|
105
|
+
if (!ctx.hasUI) {
|
|
106
|
+
notifyWarning(ctx, "UltraPlan authoring requires interactive mode");
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const allSessionIds = readSessionsFromIndex(platform, ctx.cwd);
|
|
111
|
+
const inFlight = listInFlightAuthoringSessions(platform.paths, ctx.cwd, allSessionIds)
|
|
112
|
+
.filter((s) => isInFlightStage(s.stage) && !isSessionPromoted(platform, ctx.cwd, s.sessionId));
|
|
113
|
+
|
|
114
|
+
// Step 1: in-flight picker.
|
|
115
|
+
let resumeSessionId: string | null = null;
|
|
116
|
+
if (inFlight.length > 0) {
|
|
117
|
+
const options = [
|
|
118
|
+
...inFlight.map((s) => ({
|
|
119
|
+
label: `Resume ${s.sessionId} (stage: ${s.stage}, status: ${s.status})`,
|
|
120
|
+
value: `resume:${s.sessionId}`,
|
|
121
|
+
})),
|
|
122
|
+
{ label: "Start fresh", value: "fresh" },
|
|
123
|
+
{ label: "Cancel", value: "cancel" },
|
|
124
|
+
];
|
|
125
|
+
const choice = await ctx.ui.select("In-flight UltraPlan authoring sessions", options);
|
|
126
|
+
if (!choice || choice === "cancel") return;
|
|
127
|
+
if (choice.startsWith("resume:")) resumeSessionId = choice.slice("resume:".length);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (resumeSessionId) {
|
|
131
|
+
await driveAuthoringPipeline({
|
|
132
|
+
platform,
|
|
133
|
+
ctx,
|
|
134
|
+
sessionId: resumeSessionId,
|
|
135
|
+
seedPrompt: "",
|
|
136
|
+
gates: "default",
|
|
137
|
+
});
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Step 2: capture seed prompt via TUI input.
|
|
142
|
+
const seed = await ctx.ui.input("What do you want to ship next?", {
|
|
143
|
+
multiline: true,
|
|
144
|
+
helpText: "Describe the work; press Enter to submit, Esc to cancel.",
|
|
145
|
+
});
|
|
146
|
+
if (!seed || seed.trim().length === 0) return;
|
|
147
|
+
|
|
148
|
+
const sessionId = newAuthoringSessionId();
|
|
149
|
+
// Bootstrap manifest so the authoring storage helpers have a host artifact.
|
|
150
|
+
const manifestSave = saveUltraPlanManifest(
|
|
151
|
+
platform.paths,
|
|
152
|
+
ctx.cwd,
|
|
153
|
+
sessionId,
|
|
154
|
+
makeBootstrapManifest(sessionId, projectName(ctx.cwd)),
|
|
155
|
+
);
|
|
156
|
+
if (!manifestSave.ok) {
|
|
157
|
+
notifyError(ctx, "Failed to create authoring session", manifestSave.error.message);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
await driveAuthoringPipeline({ platform, ctx, sessionId, seedPrompt: seed, gates: "default" });
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// ---------------------------------------------------------------------------
|
|
165
|
+
// Pipeline driver wrapper (UI-aware loop)
|
|
166
|
+
// ---------------------------------------------------------------------------
|
|
167
|
+
|
|
168
|
+
interface DriveInput {
|
|
169
|
+
platform: Platform;
|
|
170
|
+
ctx: any;
|
|
171
|
+
sessionId: string;
|
|
172
|
+
seedPrompt: string;
|
|
173
|
+
gates: PipelineGateMode;
|
|
174
|
+
iteration?: number;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Run the pipeline driver in a loop until the session is approved, blocked, or the user
|
|
179
|
+
* cancels. Between gates, presents a `ctx.ui.confirm` to advance.
|
|
180
|
+
*/
|
|
181
|
+
export async function driveAuthoringPipeline(input: DriveInput): Promise<void> {
|
|
182
|
+
const modelConfig = loadModelConfig(input.platform.paths, input.ctx.cwd);
|
|
183
|
+
let attempts = 0;
|
|
184
|
+
while (attempts < 8) {
|
|
185
|
+
attempts += 1;
|
|
186
|
+
const outcome = await runPipelineUntilGate({
|
|
187
|
+
platform: input.platform,
|
|
188
|
+
paths: input.platform.paths,
|
|
189
|
+
cwd: input.ctx.cwd,
|
|
190
|
+
sessionId: input.sessionId,
|
|
191
|
+
modelConfig,
|
|
192
|
+
seedPrompt: input.seedPrompt,
|
|
193
|
+
gates: input.gates,
|
|
194
|
+
iteration: input.iteration ?? 1,
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
if (outcome.status === "completed" || outcome.status === "skipped") {
|
|
198
|
+
if (outcome.promoted) {
|
|
199
|
+
notifyInfo(input.ctx, "UltraPlan approved", `Session ${input.sessionId} is ready to run.`);
|
|
200
|
+
} else {
|
|
201
|
+
notifyInfo(input.ctx, "UltraPlan stage completed", `Stage ${outcome.stage} done.`);
|
|
202
|
+
}
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (outcome.status === "failed" || outcome.status === "blocked") {
|
|
207
|
+
notifyError(input.ctx, `UltraPlan ${outcome.status} at ${outcome.stage}`, outcome.message ?? "");
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (outcome.status === "awaiting-user") {
|
|
212
|
+
const advance = await input.ctx.ui.confirm
|
|
213
|
+
? await input.ctx.ui.confirm(
|
|
214
|
+
`UltraPlan: ${outcome.stage} ready`,
|
|
215
|
+
`The ${outcome.stage} stage finished. Continue to the next stage?`,
|
|
216
|
+
)
|
|
217
|
+
: true;
|
|
218
|
+
if (!advance) {
|
|
219
|
+
notifyInfo(input.ctx, "UltraPlan paused", `Resume with /supi:ultraplan resume ${input.sessionId}`);
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
notifyWarning(input.ctx, "UltraPlan: too many gates", "Driver loop hit its safety cap; resume to continue.");
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// ---------------------------------------------------------------------------
|
|
229
|
+
// Per-stage subcommand handlers
|
|
230
|
+
// ---------------------------------------------------------------------------
|
|
231
|
+
|
|
232
|
+
export async function handleStageSubcommand(
|
|
233
|
+
stage: UltraPlanAuthoringStage,
|
|
234
|
+
platform: Platform,
|
|
235
|
+
ctx: any,
|
|
236
|
+
args: string,
|
|
237
|
+
): Promise<void> {
|
|
238
|
+
if (!ctx.hasUI) {
|
|
239
|
+
notifyWarning(ctx, "UltraPlan authoring requires interactive mode");
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const sessionId = args.trim() || (await pickInFlightSession(platform, ctx));
|
|
244
|
+
if (!sessionId) return;
|
|
245
|
+
|
|
246
|
+
const seedPrompt = stage === "intake"
|
|
247
|
+
? (await ctx.ui.input("What do you want to ship next?", { multiline: true })) ?? ""
|
|
248
|
+
: "";
|
|
249
|
+
|
|
250
|
+
const modelConfig = loadModelConfig(platform.paths, ctx.cwd);
|
|
251
|
+
const result = await runStage(stage, {
|
|
252
|
+
platform,
|
|
253
|
+
paths: platform.paths,
|
|
254
|
+
cwd: ctx.cwd,
|
|
255
|
+
sessionId,
|
|
256
|
+
modelConfig,
|
|
257
|
+
seedPrompt,
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
if (result.status === "completed" || result.status === "skipped") {
|
|
261
|
+
notifyInfo(ctx, `UltraPlan ${stage} done`, result.details ? JSON.stringify(result.details) : "");
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
if (result.status === "awaiting-user") {
|
|
265
|
+
notifyInfo(ctx, `UltraPlan ${stage} awaiting user`, "Continue with the next stage when ready.");
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
notifyError(ctx, `UltraPlan ${stage} ${result.status}`, result.error ?? result.blocker?.message ?? "");
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
async function pickInFlightSession(platform: Platform, ctx: any): Promise<string | null> {
|
|
272
|
+
const allSessionIds = readSessionsFromIndex(platform, ctx.cwd);
|
|
273
|
+
const inFlight = listInFlightAuthoringSessions(platform.paths, ctx.cwd, allSessionIds)
|
|
274
|
+
.filter((s) => !isSessionPromoted(platform, ctx.cwd, s.sessionId));
|
|
275
|
+
if (inFlight.length === 0) {
|
|
276
|
+
notifyWarning(ctx, "No in-flight authoring sessions", "Start one with /supi:ultraplan");
|
|
277
|
+
return null;
|
|
278
|
+
}
|
|
279
|
+
if (inFlight.length === 1) return inFlight[0]!.sessionId;
|
|
280
|
+
const choice = await ctx.ui.select(
|
|
281
|
+
"Pick an in-flight session",
|
|
282
|
+
inFlight.map((s) => ({ label: `${s.sessionId} (${s.stage})`, value: s.sessionId })),
|
|
283
|
+
);
|
|
284
|
+
return typeof choice === "string" ? choice : null;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// ---------------------------------------------------------------------------
|
|
288
|
+
// Resume + plan + quick handlers
|
|
289
|
+
// ---------------------------------------------------------------------------
|
|
290
|
+
|
|
291
|
+
export async function handleResume(platform: Platform, ctx: any, args: string): Promise<void> {
|
|
292
|
+
const arg = args.trim();
|
|
293
|
+
if (arg.length > 0) {
|
|
294
|
+
const dir = getUltraplanAuthoringDir(platform.paths, ctx.cwd, arg);
|
|
295
|
+
if (!fs.existsSync(dir)) {
|
|
296
|
+
notifyError(ctx, "No authoring session", `No authoring directory found for ${arg}`);
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
await driveAuthoringPipeline({ platform, ctx, sessionId: arg, seedPrompt: "", gates: "default" });
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
// No id arg: pick from in-flight list.
|
|
303
|
+
const sessionId = await pickInFlightSession(platform, ctx);
|
|
304
|
+
if (!sessionId) return;
|
|
305
|
+
await driveAuthoringPipeline({ platform, ctx, sessionId, seedPrompt: "", gates: "default" });
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
export async function handlePlan(platform: Platform, ctx: any, args: string): Promise<void> {
|
|
309
|
+
if (!ctx.hasUI) {
|
|
310
|
+
notifyWarning(ctx, "UltraPlan authoring requires interactive mode");
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
const tokens = args.trim().split(/\s+/).filter((t) => t.length > 0);
|
|
314
|
+
let gates: PipelineGateMode = "default";
|
|
315
|
+
const positional: string[] = [];
|
|
316
|
+
for (const tok of tokens) {
|
|
317
|
+
if (tok === "--auto") gates = "auto";
|
|
318
|
+
else if (tok === "--manual") gates = "manual";
|
|
319
|
+
else positional.push(tok);
|
|
320
|
+
}
|
|
321
|
+
let seed = positional.join(" ").trim();
|
|
322
|
+
if (seed.length === 0) {
|
|
323
|
+
seed = (await ctx.ui.input("What do you want to ship next?", { multiline: true })) ?? "";
|
|
324
|
+
}
|
|
325
|
+
if (seed.length === 0) return;
|
|
326
|
+
|
|
327
|
+
const sessionId = newAuthoringSessionId();
|
|
328
|
+
const manifestSave = saveUltraPlanManifest(
|
|
329
|
+
platform.paths,
|
|
330
|
+
ctx.cwd,
|
|
331
|
+
sessionId,
|
|
332
|
+
makeBootstrapManifest(sessionId, projectName(ctx.cwd)),
|
|
333
|
+
);
|
|
334
|
+
if (!manifestSave.ok) {
|
|
335
|
+
notifyError(ctx, "Failed to create authoring session", manifestSave.error.message);
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
await driveAuthoringPipeline({ platform, ctx, sessionId, seedPrompt: seed, gates });
|
|
339
|
+
}
|