@entelligentsia/forgecli 1.0.21 → 1.0.25
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/CHANGELOG.md +88 -0
- package/dist/CHANGELOG-forge-plugin.md +118 -0
- package/dist/extensions/forgecli/forge-tools.d.ts +1 -0
- package/dist/extensions/forgecli/forge-tools.js +73 -0
- package/dist/extensions/forgecli/forge-tools.js.map +1 -1
- package/dist/extensions/forgecli/lib/forge-root.d.ts +5 -0
- package/dist/extensions/forgecli/lib/forge-root.js +14 -1
- package/dist/extensions/forgecli/lib/forge-root.js.map +1 -1
- package/dist/extensions/forgecli/orchestrators/fix-bug.d.ts +1 -0
- package/dist/extensions/forgecli/orchestrators/fix-bug.js +26 -0
- package/dist/extensions/forgecli/orchestrators/fix-bug.js.map +1 -1
- package/dist/extensions/forgecli/orchestrators/run-sprint.js +49 -0
- package/dist/extensions/forgecli/orchestrators/run-sprint.js.map +1 -1
- package/dist/forge-payload/.base-pack/workflows/_fragments/event-emission-schema.md +4 -0
- package/dist/forge-payload/.base-pack/workflows/_fragments/event-vocabulary.md +88 -0
- package/dist/forge-payload/.base-pack/workflows/commit_task.md +41 -38
- package/dist/forge-payload/.base-pack/workflows/implement_plan.md +3 -3
- package/dist/forge-payload/.base-pack/workflows-js/wfl-fix-bug.js +42 -6
- package/dist/forge-payload/.base-pack/workflows-js/wfl-run-task.js +32 -1
- package/dist/forge-payload/.claude-plugin/plugin.json +1 -1
- package/dist/forge-payload/.schemas/enum-catalog.json +2 -2
- package/dist/forge-payload/.schemas/event.schema.json +8 -3
- package/dist/forge-payload/.schemas/migrations.json +56 -0
- package/dist/forge-payload/integrity.json +3 -3
- package/dist/forge-payload/meta/store-schema/event.schema.md +7 -0
- package/dist/forge-payload/meta/workflows/_fragments/event-emission-schema.md +4 -0
- package/dist/forge-payload/meta/workflows/_fragments/event-vocabulary.md +88 -0
- package/dist/forge-payload/meta/workflows/meta-commit.md +46 -43
- package/dist/forge-payload/meta/workflows/meta-fix-bug.md +7 -2
- package/dist/forge-payload/meta/workflows/meta-implement.md +3 -3
- package/dist/forge-payload/meta/workflows/meta-orchestrate.md +4 -1
- package/dist/forge-payload/schemas/enum-catalog.json +2 -2
- package/dist/forge-payload/schemas/event.schema.json +8 -3
- package/dist/forge-payload/schemas/structure-manifest.json +4 -2
- package/dist/forge-payload/tools/commit-task.cjs +218 -0
- package/dist/forge-payload/tools/store-cli.cjs +6 -1
- package/node_modules/@mariozechner/clipboard/package.json +2 -1
- package/node_modules/@mariozechner/clipboard-linux-x64-musl/README.md +3 -0
- package/node_modules/@mariozechner/clipboard-linux-x64-musl/package.json +25 -0
- package/package.json +2 -2
- package/dist/extensions/forgecli/add-pipeline.d.ts +0 -19
- package/dist/extensions/forgecli/add-pipeline.js +0 -143
- package/dist/extensions/forgecli/add-pipeline.js.map +0 -1
- package/dist/extensions/forgecli/add-task.d.ts +0 -20
- package/dist/extensions/forgecli/add-task.js +0 -154
- package/dist/extensions/forgecli/add-task.js.map +0 -1
- package/dist/extensions/forgecli/approve.d.ts +0 -22
- package/dist/extensions/forgecli/approve.js +0 -152
- package/dist/extensions/forgecli/approve.js.map +0 -1
- package/dist/extensions/forgecli/banner.d.ts +0 -10
- package/dist/extensions/forgecli/banner.js +0 -36
- package/dist/extensions/forgecli/banner.js.map +0 -1
- package/dist/extensions/forgecli/calibrate.d.ts +0 -64
- package/dist/extensions/forgecli/calibrate.js +0 -481
- package/dist/extensions/forgecli/calibrate.js.map +0 -1
- package/dist/extensions/forgecli/collate.d.ts +0 -22
- package/dist/extensions/forgecli/collate.js +0 -134
- package/dist/extensions/forgecli/collate.js.map +0 -1
- package/dist/extensions/forgecli/commit.d.ts +0 -22
- package/dist/extensions/forgecli/commit.js +0 -152
- package/dist/extensions/forgecli/commit.js.map +0 -1
- package/dist/extensions/forgecli/config-command.d.ts +0 -8
- package/dist/extensions/forgecli/config-command.js +0 -67
- package/dist/extensions/forgecli/config-command.js.map +0 -1
- package/dist/extensions/forgecli/config-layer.d.ts +0 -53
- package/dist/extensions/forgecli/config-layer.js +0 -72
- package/dist/extensions/forgecli/config-layer.js.map +0 -1
- package/dist/extensions/forgecli/config-writer.d.ts +0 -16
- package/dist/extensions/forgecli/config-writer.js +0 -69
- package/dist/extensions/forgecli/config-writer.js.map +0 -1
- package/dist/extensions/forgecli/enhance.d.ts +0 -27
- package/dist/extensions/forgecli/enhance.js +0 -199
- package/dist/extensions/forgecli/enhance.js.map +0 -1
- package/dist/extensions/forgecli/fix-bug.d.ts +0 -85
- package/dist/extensions/forgecli/fix-bug.js +0 -1580
- package/dist/extensions/forgecli/fix-bug.js.map +0 -1
- package/dist/extensions/forgecli/forge-header.d.ts +0 -12
- package/dist/extensions/forgecli/forge-header.js +0 -114
- package/dist/extensions/forgecli/forge-header.js.map +0 -1
- package/dist/extensions/forgecli/forge-init.d.ts +0 -26
- package/dist/extensions/forgecli/forge-init.js +0 -514
- package/dist/extensions/forgecli/forge-init.js.map +0 -1
- package/dist/extensions/forgecli/forge-root.d.ts +0 -10
- package/dist/extensions/forgecli/forge-root.js +0 -62
- package/dist/extensions/forgecli/forge-root.js.map +0 -1
- package/dist/extensions/forgecli/forge-update-command.d.ts +0 -100
- package/dist/extensions/forgecli/forge-update-command.js +0 -435
- package/dist/extensions/forgecli/forge-update-command.js.map +0 -1
- package/dist/extensions/forgecli/friction-emit.d.ts +0 -99
- package/dist/extensions/forgecli/friction-emit.js +0 -245
- package/dist/extensions/forgecli/friction-emit.js.map +0 -1
- package/dist/extensions/forgecli/implement.d.ts +0 -22
- package/dist/extensions/forgecli/implement.js +0 -170
- package/dist/extensions/forgecli/implement.js.map +0 -1
- package/dist/extensions/forgecli/init-context.d.ts +0 -99
- package/dist/extensions/forgecli/init-context.js +0 -178
- package/dist/extensions/forgecli/init-context.js.map +0 -1
- package/dist/extensions/forgecli/init-progress.d.ts +0 -39
- package/dist/extensions/forgecli/init-progress.js +0 -117
- package/dist/extensions/forgecli/init-progress.js.map +0 -1
- package/dist/extensions/forgecli/input-router.d.ts +0 -33
- package/dist/extensions/forgecli/input-router.js +0 -136
- package/dist/extensions/forgecli/input-router.js.map +0 -1
- package/dist/extensions/forgecli/lib/halt-advisor.d.ts +0 -59
- package/dist/extensions/forgecli/lib/halt-advisor.js +0 -113
- package/dist/extensions/forgecli/lib/halt-advisor.js.map +0 -1
- package/dist/extensions/forgecli/lib/orchestrator-preflight.d.ts +0 -46
- package/dist/extensions/forgecli/lib/orchestrator-preflight.js +0 -64
- package/dist/extensions/forgecli/lib/orchestrator-preflight.js.map +0 -1
- package/dist/extensions/forgecli/materialize.d.ts +0 -16
- package/dist/extensions/forgecli/materialize.js +0 -195
- package/dist/extensions/forgecli/materialize.js.map +0 -1
- package/dist/extensions/forgecli/migrate.d.ts +0 -22
- package/dist/extensions/forgecli/migrate.js +0 -260
- package/dist/extensions/forgecli/migrate.js.map +0 -1
- package/dist/extensions/forgecli/migration-engine.d.ts +0 -117
- package/dist/extensions/forgecli/migration-engine.js +0 -563
- package/dist/extensions/forgecli/migration-engine.js.map +0 -1
- package/dist/extensions/forgecli/model-registry.d.ts +0 -61
- package/dist/extensions/forgecli/model-registry.js +0 -127
- package/dist/extensions/forgecli/model-registry.js.map +0 -1
- package/dist/extensions/forgecli/model-resolver.d.ts +0 -32
- package/dist/extensions/forgecli/model-resolver.js +0 -65
- package/dist/extensions/forgecli/model-resolver.js.map +0 -1
- package/dist/extensions/forgecli/model-validator.d.ts +0 -29
- package/dist/extensions/forgecli/model-validator.js +0 -107
- package/dist/extensions/forgecli/model-validator.js.map +0 -1
- package/dist/extensions/forgecli/orchestrator-status-bar.d.ts +0 -26
- package/dist/extensions/forgecli/orchestrator-status-bar.js +0 -213
- package/dist/extensions/forgecli/orchestrator-status-bar.js.map +0 -1
- package/dist/extensions/forgecli/plan.d.ts +0 -22
- package/dist/extensions/forgecli/plan.js +0 -167
- package/dist/extensions/forgecli/plan.js.map +0 -1
- package/dist/extensions/forgecli/quiz-agent.d.ts +0 -17
- package/dist/extensions/forgecli/quiz-agent.js +0 -98
- package/dist/extensions/forgecli/quiz-agent.js.map +0 -1
- package/dist/extensions/forgecli/read-command.d.ts +0 -2
- package/dist/extensions/forgecli/read-command.js +0 -100
- package/dist/extensions/forgecli/read-command.js.map +0 -1
- package/dist/extensions/forgecli/regenerate.d.ts +0 -40
- package/dist/extensions/forgecli/regenerate.js +0 -438
- package/dist/extensions/forgecli/regenerate.js.map +0 -1
- package/dist/extensions/forgecli/remove-command.d.ts +0 -17
- package/dist/extensions/forgecli/remove-command.js +0 -124
- package/dist/extensions/forgecli/remove-command.js.map +0 -1
- package/dist/extensions/forgecli/report-bug.d.ts +0 -25
- package/dist/extensions/forgecli/report-bug.js +0 -159
- package/dist/extensions/forgecli/report-bug.js.map +0 -1
- package/dist/extensions/forgecli/retrospective.d.ts +0 -20
- package/dist/extensions/forgecli/retrospective.js +0 -126
- package/dist/extensions/forgecli/retrospective.js.map +0 -1
- package/dist/extensions/forgecli/review-code.d.ts +0 -35
- package/dist/extensions/forgecli/review-code.js +0 -196
- package/dist/extensions/forgecli/review-code.js.map +0 -1
- package/dist/extensions/forgecli/review-plan.d.ts +0 -35
- package/dist/extensions/forgecli/review-plan.js +0 -200
- package/dist/extensions/forgecli/review-plan.js.map +0 -1
- package/dist/extensions/forgecli/run-sprint.d.ts +0 -27
- package/dist/extensions/forgecli/run-sprint.js +0 -716
- package/dist/extensions/forgecli/run-sprint.js.map +0 -1
- package/dist/extensions/forgecli/run-task.d.ts +0 -204
- package/dist/extensions/forgecli/run-task.js +0 -1403
- package/dist/extensions/forgecli/run-task.js.map +0 -1
- package/dist/extensions/forgecli/skill-curation-flag.d.ts +0 -21
- package/dist/extensions/forgecli/skill-curation-flag.js +0 -71
- package/dist/extensions/forgecli/skill-curation-flag.js.map +0 -1
- package/dist/extensions/forgecli/skill-curator-subagent.d.ts +0 -102
- package/dist/extensions/forgecli/skill-curator-subagent.js +0 -339
- package/dist/extensions/forgecli/skill-curator-subagent.js.map +0 -1
- package/dist/extensions/forgecli/skill-retriever.d.ts +0 -84
- package/dist/extensions/forgecli/skill-retriever.js +0 -246
- package/dist/extensions/forgecli/skill-retriever.js.map +0 -1
- package/dist/extensions/forgecli/skill-usage-tracker.d.ts +0 -91
- package/dist/extensions/forgecli/skill-usage-tracker.js +0 -224
- package/dist/extensions/forgecli/skill-usage-tracker.js.map +0 -1
- package/dist/extensions/forgecli/sprint-intake.d.ts +0 -10
- package/dist/extensions/forgecli/sprint-intake.js +0 -91
- package/dist/extensions/forgecli/sprint-intake.js.map +0 -1
- package/dist/extensions/forgecli/sprint-plan.d.ts +0 -14
- package/dist/extensions/forgecli/sprint-plan.js +0 -122
- package/dist/extensions/forgecli/sprint-plan.js.map +0 -1
- package/dist/extensions/forgecli/status-command.d.ts +0 -19
- package/dist/extensions/forgecli/status-command.js +0 -140
- package/dist/extensions/forgecli/status-command.js.map +0 -1
- package/dist/extensions/forgecli/store-error-remediation.d.ts +0 -65
- package/dist/extensions/forgecli/store-error-remediation.js +0 -307
- package/dist/extensions/forgecli/store-error-remediation.js.map +0 -1
- package/dist/extensions/forgecli/store-query.d.ts +0 -22
- package/dist/extensions/forgecli/store-query.js +0 -107
- package/dist/extensions/forgecli/store-query.js.map +0 -1
- package/dist/extensions/forgecli/store-repair.d.ts +0 -17
- package/dist/extensions/forgecli/store-repair.js +0 -123
- package/dist/extensions/forgecli/store-repair.js.map +0 -1
- package/dist/extensions/forgecli/store-resolver.d.ts +0 -56
- package/dist/extensions/forgecli/store-resolver.js +0 -263
- package/dist/extensions/forgecli/store-resolver.js.map +0 -1
- package/dist/extensions/forgecli/store-validator.d.ts +0 -16
- package/dist/extensions/forgecli/store-validator.js +0 -32
- package/dist/extensions/forgecli/store-validator.js.map +0 -1
- package/dist/extensions/forgecli/test-orchestrate.d.ts +0 -2
- package/dist/extensions/forgecli/test-orchestrate.js +0 -182
- package/dist/extensions/forgecli/test-orchestrate.js.map +0 -1
- package/dist/extensions/forgecli/thread-switcher.d.ts +0 -5
- package/dist/extensions/forgecli/thread-switcher.js +0 -189
- package/dist/extensions/forgecli/thread-switcher.js.map +0 -1
- package/dist/extensions/forgecli/transition-guard.d.ts +0 -20
- package/dist/extensions/forgecli/transition-guard.js +0 -89
- package/dist/extensions/forgecli/transition-guard.js.map +0 -1
- package/dist/extensions/forgecli/update-check.d.ts +0 -37
- package/dist/extensions/forgecli/update-check.js +0 -185
- package/dist/extensions/forgecli/update-check.js.map +0 -1
- package/dist/extensions/forgecli/update-tools.d.ts +0 -23
- package/dist/extensions/forgecli/update-tools.js +0 -135
- package/dist/extensions/forgecli/update-tools.js.map +0 -1
- package/dist/extensions/forgecli/validate.d.ts +0 -22
- package/dist/extensions/forgecli/validate.js +0 -152
- package/dist/extensions/forgecli/validate.js.map +0 -1
- package/dist/extensions/forgecli/viewport-events.d.ts +0 -78
- package/dist/extensions/forgecli/viewport-events.js +0 -243
- package/dist/extensions/forgecli/viewport-events.js.map +0 -1
- package/dist/extensions/forgecli/viewport-renderer.d.ts +0 -83
- package/dist/extensions/forgecli/viewport-renderer.js +0 -233
- package/dist/extensions/forgecli/viewport-renderer.js.map +0 -1
- package/dist/extensions/forgecli/viewport-theme.d.ts +0 -11
- package/dist/extensions/forgecli/viewport-theme.js +0 -128
- package/dist/extensions/forgecli/viewport-theme.js.map +0 -1
- package/dist/extensions/forgecli/whats-new-widget.d.ts +0 -26
- package/dist/extensions/forgecli/whats-new-widget.js +0 -376
- package/dist/extensions/forgecli/whats-new-widget.js.map +0 -1
- package/dist/extensions/forgecli/whats-new.d.ts +0 -120
- package/dist/extensions/forgecli/whats-new.js +0 -470
- package/dist/extensions/forgecli/whats-new.js.map +0 -1
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
// test-orchestrate.ts — /test-orchestrate slash command for subagent harness e2e.
|
|
2
|
-
//
|
|
3
|
-
// Spawns a forge subagent via runForgeSubagent() and delegates the user-provided
|
|
4
|
-
// prompt to it. Multi-turn allowed (subagent loops until no more tool calls).
|
|
5
|
-
// Streams live updates back to UI via setStatus + ctx.ui.notify.
|
|
6
|
-
//
|
|
7
|
-
// Usage:
|
|
8
|
-
// /test-orchestrate <prompt>
|
|
9
|
-
// /test-orchestrate @path/to/prompt-file.md
|
|
10
|
-
//
|
|
11
|
-
// Persona: inline minimal generic-assistant persona. Replace with
|
|
12
|
-
// loadForgePersona("engineer", cwd) once persona frontmatter is backfilled.
|
|
13
|
-
import * as fs from "node:fs";
|
|
14
|
-
import * as path from "node:path";
|
|
15
|
-
import { getFinalOutput, loadForgePersona, runForgeSubagent } from "./forge-subagent.js";
|
|
16
|
-
const STATUS_KEY = "test-orchestrate";
|
|
17
|
-
const GENERIC_PERSONA = {
|
|
18
|
-
name: "test-scribe",
|
|
19
|
-
description: "Generic assistant for /test-orchestrate harness",
|
|
20
|
-
systemPrompt: [
|
|
21
|
-
"You are a test subagent invoked through the Forge subagent harness.",
|
|
22
|
-
"Use the available tools (read, write, edit, bash) as needed to fulfill the user's request.",
|
|
23
|
-
"Be terse. Show evidence (file paths, command output) over narration.",
|
|
24
|
-
"If the task asks for a file, write it. If it asks for analysis, summarize in <200 words.",
|
|
25
|
-
].join(" "),
|
|
26
|
-
filePath: "<inline>",
|
|
27
|
-
};
|
|
28
|
-
function parseArgs(args, cwd) {
|
|
29
|
-
const trimmed = args.trim();
|
|
30
|
-
if (!trimmed) {
|
|
31
|
-
return { mode: "text", text: "", persona: GENERIC_PERSONA, cwd };
|
|
32
|
-
}
|
|
33
|
-
// @path/to/file → read file as task body
|
|
34
|
-
if (trimmed.startsWith("@")) {
|
|
35
|
-
const rel = trimmed.slice(1);
|
|
36
|
-
const abs = path.isAbsolute(rel) ? rel : path.resolve(cwd, rel);
|
|
37
|
-
const text = fs.readFileSync(abs, "utf-8");
|
|
38
|
-
return { mode: "file", text, persona: GENERIC_PERSONA, cwd };
|
|
39
|
-
}
|
|
40
|
-
// --persona <name> <task>
|
|
41
|
-
const personaMatch = trimmed.match(/^--persona\s+(\S+)\s+(.+)$/s);
|
|
42
|
-
if (personaMatch) {
|
|
43
|
-
const personaName = personaMatch[1];
|
|
44
|
-
const text = personaMatch[2];
|
|
45
|
-
const persona = loadForgePersona(personaName, cwd);
|
|
46
|
-
return { mode: "persona-file", text, persona, cwd };
|
|
47
|
-
}
|
|
48
|
-
return { mode: "text", text: trimmed, persona: GENERIC_PERSONA, cwd };
|
|
49
|
-
}
|
|
50
|
-
export function registerTestOrchestrate(pi) {
|
|
51
|
-
pi.registerCommand("test-orchestrate", {
|
|
52
|
-
description: "Spawn a forge subagent via the SDK harness and delegate a prompt. " +
|
|
53
|
-
"Usage: /test-orchestrate <prompt> | @<file> | --persona <name> <prompt>",
|
|
54
|
-
async handler(args, ctx) {
|
|
55
|
-
const cwd = process.cwd();
|
|
56
|
-
let parsed;
|
|
57
|
-
try {
|
|
58
|
-
parsed = parseArgs(args, cwd);
|
|
59
|
-
}
|
|
60
|
-
catch (err) {
|
|
61
|
-
const e = err;
|
|
62
|
-
ctx.ui.notify(`× /test-orchestrate — ${e.message ?? "arg parse failed"}`, "error");
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
if (!parsed.text.trim()) {
|
|
66
|
-
ctx.ui.notify("× /test-orchestrate — prompt required (usage: /test-orchestrate <prompt> | @<file> | --persona <name> <prompt>)", "error");
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
const ac = new AbortController();
|
|
70
|
-
ctx.ui.setStatus?.(STATUS_KEY, `subagent: ${parsed.persona.name} starting…`);
|
|
71
|
-
// Rolling tail of recent events for the live monitor widget.
|
|
72
|
-
const TAIL_MAX = 12;
|
|
73
|
-
const TEXT_WINDOW = 80; // chars of streaming text shown
|
|
74
|
-
const tail = [];
|
|
75
|
-
let turn = 0;
|
|
76
|
-
let lastToolName = "";
|
|
77
|
-
let textBuffer = ""; // accumulator for current message_update text_delta
|
|
78
|
-
const refreshWidget = () => {
|
|
79
|
-
const header = `▶ subagent ${parsed.persona.name} · turn ${turn}`;
|
|
80
|
-
const lines = [header, ...tail.slice(-TAIL_MAX)];
|
|
81
|
-
if (textBuffer) {
|
|
82
|
-
const tailText = textBuffer.slice(-TEXT_WINDOW).replace(/\n/g, " ⏎ ");
|
|
83
|
-
lines.push(`▌ ${tailText}`);
|
|
84
|
-
}
|
|
85
|
-
ctx.ui.setWidget?.(STATUS_KEY, lines);
|
|
86
|
-
};
|
|
87
|
-
const push = (line) => {
|
|
88
|
-
tail.push(line);
|
|
89
|
-
if (tail.length > TAIL_MAX * 2)
|
|
90
|
-
tail.splice(0, tail.length - TAIL_MAX);
|
|
91
|
-
refreshWidget();
|
|
92
|
-
};
|
|
93
|
-
try {
|
|
94
|
-
const result = await runForgeSubagent({
|
|
95
|
-
persona: parsed.persona,
|
|
96
|
-
task: parsed.text,
|
|
97
|
-
cwd,
|
|
98
|
-
signal: ac.signal,
|
|
99
|
-
modelRegistry: ctx.modelRegistry,
|
|
100
|
-
onEvent: (event) => {
|
|
101
|
-
switch (event.type) {
|
|
102
|
-
case "agent_start":
|
|
103
|
-
push("◉ agent_start");
|
|
104
|
-
break;
|
|
105
|
-
case "message_start":
|
|
106
|
-
textBuffer = "";
|
|
107
|
-
push("▸ message_start");
|
|
108
|
-
break;
|
|
109
|
-
case "message_update": {
|
|
110
|
-
const ame = event.assistantMessageEvent;
|
|
111
|
-
if (ame?.type === "text_delta" && typeof ame.delta === "string") {
|
|
112
|
-
textBuffer += ame.delta;
|
|
113
|
-
refreshWidget();
|
|
114
|
-
}
|
|
115
|
-
else if (ame?.type === "thinking_delta") {
|
|
116
|
-
push("💭 thinking…");
|
|
117
|
-
}
|
|
118
|
-
break;
|
|
119
|
-
}
|
|
120
|
-
case "tool_execution_start":
|
|
121
|
-
lastToolName = event.toolName;
|
|
122
|
-
push(`🔧 tool_call · ${lastToolName}`);
|
|
123
|
-
ctx.ui.setStatus?.(STATUS_KEY, `subagent: ${parsed.persona.name} · turn ${turn} · tool: ${lastToolName}`);
|
|
124
|
-
break;
|
|
125
|
-
case "tool_execution_update":
|
|
126
|
-
refreshWidget();
|
|
127
|
-
break;
|
|
128
|
-
case "tool_execution_end": {
|
|
129
|
-
const verdict = event.isError ? "✗" : "✓";
|
|
130
|
-
push(`${verdict} tool_end · ${lastToolName}`);
|
|
131
|
-
break;
|
|
132
|
-
}
|
|
133
|
-
case "message_end":
|
|
134
|
-
push("◼ message_end");
|
|
135
|
-
break;
|
|
136
|
-
case "turn_end": {
|
|
137
|
-
turn++;
|
|
138
|
-
const u = event.message?.usage;
|
|
139
|
-
const usageStr = u
|
|
140
|
-
? ` · ↑${u.input ?? 0} ↓${u.output ?? 0}` +
|
|
141
|
-
(u.cost?.total ? ` $${u.cost.total.toFixed(4)}` : "")
|
|
142
|
-
: "";
|
|
143
|
-
push(`── turn ${turn}${usageStr} ──`);
|
|
144
|
-
textBuffer = "";
|
|
145
|
-
break;
|
|
146
|
-
}
|
|
147
|
-
case "agent_end":
|
|
148
|
-
push("◉ agent_end");
|
|
149
|
-
break;
|
|
150
|
-
}
|
|
151
|
-
},
|
|
152
|
-
});
|
|
153
|
-
ctx.ui.setStatus?.(STATUS_KEY, undefined);
|
|
154
|
-
ctx.ui.setWidget?.(STATUS_KEY, undefined);
|
|
155
|
-
if (result.exitCode !== 0) {
|
|
156
|
-
ctx.ui.notify(`× /test-orchestrate — subagent exited ${result.exitCode}` +
|
|
157
|
-
(result.errorMessage ? `: ${result.errorMessage}` : "") +
|
|
158
|
-
(result.stopReason ? ` [${result.stopReason}]` : ""), "error");
|
|
159
|
-
return;
|
|
160
|
-
}
|
|
161
|
-
const finalOutput = getFinalOutput(result.messages);
|
|
162
|
-
const usage = result.usage;
|
|
163
|
-
const summary = [
|
|
164
|
-
`〇 /test-orchestrate — ${parsed.persona.name} done.`,
|
|
165
|
-
`Turns: ${usage.turns} ↑${usage.input} ↓${usage.output} R${usage.cacheRead} W${usage.cacheWrite} $${usage.cost.toFixed(4)}`,
|
|
166
|
-
`Model: ${result.model ?? "unknown"}`,
|
|
167
|
-
"",
|
|
168
|
-
"── Output ──",
|
|
169
|
-
finalOutput || "(no assistant text returned)",
|
|
170
|
-
].join("\n");
|
|
171
|
-
ctx.ui.notify(summary, "info");
|
|
172
|
-
}
|
|
173
|
-
catch (err) {
|
|
174
|
-
const e = err;
|
|
175
|
-
ctx.ui.setStatus?.(STATUS_KEY, undefined);
|
|
176
|
-
ctx.ui.setWidget?.(STATUS_KEY, undefined);
|
|
177
|
-
ctx.ui.notify(`× /test-orchestrate — harness error: ${e.message ?? "unknown"}`, "error");
|
|
178
|
-
}
|
|
179
|
-
},
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
//# sourceMappingURL=test-orchestrate.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"test-orchestrate.js","sourceRoot":"","sources":["../../../src/extensions/forgecli/test-orchestrate.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
/** Open the dashboard overlay. Shared by /forge:threads, /forge:dashboard,
|
|
3
|
-
* and the status bar Enter action. */
|
|
4
|
-
export declare function openDashboardTui(ctx: ExtensionContext): void;
|
|
5
|
-
export declare function registerThreadSwitcher(pi: ExtensionAPI): void;
|
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
// thread-switcher.ts — orchestrator status bar + dashboard overlay for forge.
|
|
2
|
-
//
|
|
3
|
-
// Two elements:
|
|
4
|
-
// 1. OrchestratorStatusBar (belowEditor widget): a one-line summary of
|
|
5
|
-
// running orchestrations — label, current phase, status glyph, spinner,
|
|
6
|
-
// turn preview, token meter. Press ↓ to open the dashboard overlay.
|
|
7
|
-
// Hidden when no orchestration is running.
|
|
8
|
-
//
|
|
9
|
-
// 2. Dashboard overlay (/forge:dashboard command or ↓ from status bar):
|
|
10
|
-
// full-screen two-panel tree browser + detail view. See dashboard/.
|
|
11
|
-
//
|
|
12
|
-
// The chip strip and TailViewComponent have been retired — the dashboard
|
|
13
|
-
// replaces them for all orchestration visualization. The main viewport
|
|
14
|
-
// stays clean for user prompts and new tasks.
|
|
15
|
-
import { getInputRouter } from "./input-router.js";
|
|
16
|
-
import { matchesKey, Key } from "@earendil-works/pi-tui";
|
|
17
|
-
import { getOrchestratorTree } from "./orchestrator-tree.js";
|
|
18
|
-
import { DashboardComponent, DashboardController } from "./dashboard/component.js";
|
|
19
|
-
import { OrchestratorStatusBar } from "./orchestrator-status-bar.js";
|
|
20
|
-
import { getSessionRegistry, } from "./session-registry.js";
|
|
21
|
-
import { fmtModelLabel, fmtTokenFooter } from "./viewport-renderer.js";
|
|
22
|
-
import { paintFooterLine } from "./viewport-theme.js";
|
|
23
|
-
const STATUS_BAR_WIDGET_KEY = "forge:orchestrator-status-bar";
|
|
24
|
-
const FOOTER_WIDGET_KEY = "forge:viewport-footer";
|
|
25
|
-
// ── Aggregate token footer ──────────────────────────────────────────────────
|
|
26
|
-
// Mirrors the per-phase footer rendered inside TailView when a subagent chip
|
|
27
|
-
// was focused. Now shown at the bottom of the main viewport whenever an
|
|
28
|
-
// orchestration is active.
|
|
29
|
-
class ViewportFooterComponent {
|
|
30
|
-
registry;
|
|
31
|
-
theme;
|
|
32
|
-
getOrchestratorModel;
|
|
33
|
-
invalidationCb;
|
|
34
|
-
constructor(registry, theme, getOrchestratorModel) {
|
|
35
|
-
this.registry = registry;
|
|
36
|
-
this.theme = theme;
|
|
37
|
-
this.getOrchestratorModel = getOrchestratorModel;
|
|
38
|
-
const onChange = () => this.invalidationCb?.();
|
|
39
|
-
registry.on("change", onChange);
|
|
40
|
-
registry.on("tail", onChange);
|
|
41
|
-
registry.on("turn", onChange);
|
|
42
|
-
this.dispose = () => {
|
|
43
|
-
registry.off("change", onChange);
|
|
44
|
-
registry.off("tail", onChange);
|
|
45
|
-
registry.off("turn", onChange);
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
render(width) {
|
|
49
|
-
const sessions = this.registry.listSessions();
|
|
50
|
-
const hasActive = sessions.some((s) => s.status === "running" || s.status === "cancelling");
|
|
51
|
-
if (!hasActive)
|
|
52
|
-
return [];
|
|
53
|
-
const tokens = fmtTokenFooter(this.registry.getAggregateUsage(), this.registry.getAggregateCompression());
|
|
54
|
-
const orchModel = fmtModelLabel(this.getOrchestratorModel?.());
|
|
55
|
-
if (!tokens && !orchModel)
|
|
56
|
-
return [];
|
|
57
|
-
const left = orchModel ? `⌂ ${orchModel}` : "";
|
|
58
|
-
const right = tokens ? `Σ ${tokens}` : "";
|
|
59
|
-
const text = left && right ? `${left} ${right}` : left || right;
|
|
60
|
-
return [paintFooterLine(text, width, this.theme)];
|
|
61
|
-
}
|
|
62
|
-
invalidate() { }
|
|
63
|
-
setInvalidationCallback(cb) {
|
|
64
|
-
this.invalidationCb = cb;
|
|
65
|
-
}
|
|
66
|
-
dispose;
|
|
67
|
-
}
|
|
68
|
-
// ── Registration ─────────────────────────────────────────────────────────────
|
|
69
|
-
function isDownArrow(data) {
|
|
70
|
-
return data === "\x1b[B" || data === "\x1bOB";
|
|
71
|
-
}
|
|
72
|
-
let statusBarRef;
|
|
73
|
-
let statusBarTui;
|
|
74
|
-
// Module-level tree reference so openDashboardTui can access the singleton
|
|
75
|
-
// without being nested inside registerThreadSwitcher.
|
|
76
|
-
let treeRef;
|
|
77
|
-
/** Open the dashboard overlay. Shared by /forge:threads, /forge:dashboard,
|
|
78
|
-
* and the status bar Enter action. */
|
|
79
|
-
export function openDashboardTui(ctx) {
|
|
80
|
-
const tree = treeRef ?? getOrchestratorTree();
|
|
81
|
-
if (!treeRef)
|
|
82
|
-
treeRef = tree;
|
|
83
|
-
const controller = new DashboardController(tree);
|
|
84
|
-
const router = getInputRouter();
|
|
85
|
-
router.pushOverlay();
|
|
86
|
-
ctx.ui.custom((tui, theme, _kb, done) => {
|
|
87
|
-
const component = new DashboardComponent(controller, tui, theme, done);
|
|
88
|
-
return component;
|
|
89
|
-
}, {
|
|
90
|
-
overlay: true,
|
|
91
|
-
overlayOptions: {
|
|
92
|
-
width: "100%",
|
|
93
|
-
anchor: "center",
|
|
94
|
-
margin: 0,
|
|
95
|
-
},
|
|
96
|
-
}).finally(() => {
|
|
97
|
-
router.popOverlay();
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
export function registerThreadSwitcher(pi) {
|
|
101
|
-
const registry = getSessionRegistry();
|
|
102
|
-
const tree = getOrchestratorTree();
|
|
103
|
-
treeRef = tree;
|
|
104
|
-
let mounted = false;
|
|
105
|
-
let currentCtx;
|
|
106
|
-
function mount(ctx) {
|
|
107
|
-
currentCtx = ctx;
|
|
108
|
-
if (mounted)
|
|
109
|
-
return;
|
|
110
|
-
// ── Orchestrator status bar (belowEditor) ────────────────────────
|
|
111
|
-
ctx.ui.setWidget(STATUS_BAR_WIDGET_KEY, (tui, theme) => {
|
|
112
|
-
statusBarTui = tui;
|
|
113
|
-
const bar = new OrchestratorStatusBar(tree, theme);
|
|
114
|
-
bar.setInvalidationCallback(() => tui.requestRender());
|
|
115
|
-
bar.setOnAction(() => {
|
|
116
|
-
// Enter on focused status bar → open dashboard.
|
|
117
|
-
const live = currentCtx;
|
|
118
|
-
if (live)
|
|
119
|
-
openDashboardTui(live);
|
|
120
|
-
});
|
|
121
|
-
statusBarRef = bar;
|
|
122
|
-
return bar;
|
|
123
|
-
}, { placement: "belowEditor" });
|
|
124
|
-
// ── Aggregate token footer (aboveEditor) ─────────────────────────
|
|
125
|
-
ctx.ui.setWidget(FOOTER_WIDGET_KEY, (tui, theme) => {
|
|
126
|
-
const getOrchestratorModel = () => {
|
|
127
|
-
try {
|
|
128
|
-
const m = ctx.model;
|
|
129
|
-
if (!m)
|
|
130
|
-
return undefined;
|
|
131
|
-
return { provider: m.provider, model: m.id };
|
|
132
|
-
}
|
|
133
|
-
catch {
|
|
134
|
-
return undefined;
|
|
135
|
-
}
|
|
136
|
-
};
|
|
137
|
-
const footer = new ViewportFooterComponent(registry, theme, getOrchestratorModel);
|
|
138
|
-
footer.setInvalidationCallback(() => tui.requestRender());
|
|
139
|
-
return footer;
|
|
140
|
-
}, { placement: "aboveEditor" });
|
|
141
|
-
// ── Input routing: ↓ focuses status bar; Enter opens dashboard ────────
|
|
142
|
-
getInputRouter().register((data) => {
|
|
143
|
-
if (!statusBarRef || !statusBarTui)
|
|
144
|
-
return undefined;
|
|
145
|
-
// Allow ↓ navigation whenever orchestration roots are visible —
|
|
146
|
-
// this includes completed/failed/escalated roots so the user
|
|
147
|
-
// can review results even after execution ends.
|
|
148
|
-
const activeRoots = tree.getActiveRoots();
|
|
149
|
-
if (activeRoots.length === 0)
|
|
150
|
-
return undefined;
|
|
151
|
-
// ↓ focuses the status bar (makes it active).
|
|
152
|
-
if (isDownArrow(data)) {
|
|
153
|
-
statusBarRef.setActive(true);
|
|
154
|
-
return { consume: true };
|
|
155
|
-
}
|
|
156
|
-
// When the status bar is focused, ↑ / Esc return focus to the prompt.
|
|
157
|
-
if (statusBarRef.isActive() && (matchesKey(data, Key.up) || matchesKey(data, Key.escape))) {
|
|
158
|
-
statusBarRef.setActive(false);
|
|
159
|
-
return { consume: true };
|
|
160
|
-
}
|
|
161
|
-
// When the status bar is focused, Enter opens the dashboard.
|
|
162
|
-
if (statusBarRef.isActive() && matchesKey(data, Key.enter)) {
|
|
163
|
-
statusBarRef.setActive(false);
|
|
164
|
-
const live = currentCtx;
|
|
165
|
-
if (live)
|
|
166
|
-
openDashboardTui(live);
|
|
167
|
-
return { consume: true };
|
|
168
|
-
}
|
|
169
|
-
return undefined;
|
|
170
|
-
}, { name: "orchestrator-status-bar", skipWhenOverlayActive: true });
|
|
171
|
-
mounted = true;
|
|
172
|
-
}
|
|
173
|
-
pi.registerCommand("forge:threads", {
|
|
174
|
-
description: "Open the Forge orchestrator dashboard. " +
|
|
175
|
-
"Shows a two-panel view of sprint/task/phase tree with status, " +
|
|
176
|
-
"metrics, and live activity. You can also press ↓ from the prompt " +
|
|
177
|
-
"when an orchestration is running.",
|
|
178
|
-
async handler(_args, ctx) {
|
|
179
|
-
mount(ctx);
|
|
180
|
-
openDashboardTui(ctx);
|
|
181
|
-
},
|
|
182
|
-
});
|
|
183
|
-
// Mount at session_start so the status bar + ↓ listener are live from
|
|
184
|
-
// the first keystroke. mount() is idempotent.
|
|
185
|
-
pi.on("session_start", async (_event, ctx) => {
|
|
186
|
-
mount(ctx);
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
//# sourceMappingURL=thread-switcher.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"thread-switcher.js","sourceRoot":"","sources":["../../../src/extensions/forgecli/thread-switcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
export interface TransitionGuardResult {
|
|
2
|
-
allowed: boolean;
|
|
3
|
-
reason: string;
|
|
4
|
-
}
|
|
5
|
-
export interface TransitionGuardInput {
|
|
6
|
-
entity: string;
|
|
7
|
-
entityId: string;
|
|
8
|
-
toStatus: string;
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Check whether a status transition is legal.
|
|
12
|
-
*
|
|
13
|
-
* Fail-open: if the current status cannot be read, returns
|
|
14
|
-
* `{ allowed: true, reason: "lookup-failed" }`. The caller
|
|
15
|
-
* should audit-log this outcome but MUST NOT block the operation.
|
|
16
|
-
*
|
|
17
|
-
* @param input Entity, entity ID, and target status.
|
|
18
|
-
* @param forgeRoot Absolute path to the Forge plugin root.
|
|
19
|
-
*/
|
|
20
|
-
export declare function checkTransition(input: TransitionGuardInput, forgeRoot: string): TransitionGuardResult;
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
// Status-transition guard — FORGE-S18-T03
|
|
2
|
-
//
|
|
3
|
-
// Checks whether a proposed status transition is legal for a given entity.
|
|
4
|
-
//
|
|
5
|
-
// The guard reads the current status from disk via `store-cli read` (spawnSync).
|
|
6
|
-
// Fail-open: if the current-status lookup fails for any reason, the guard returns
|
|
7
|
-
// { allowed: true } and sets reason="lookup-failed". The caller (hook-dispatcher)
|
|
8
|
-
// logs this as "lookup-failed" under FORGE_HOOK_AUDIT=1 but never blocks the
|
|
9
|
-
// operation — a lookup failure must not block a valid operation.
|
|
10
|
-
//
|
|
11
|
-
// FORGE-S25-T17: spawnSync replaced with spawnStoreCliRead from lib/spawn-store-cli.ts.
|
|
12
|
-
// FORGE-S25-T27: inline TASK/SPRINT/BUG_TRANSITIONS tables replaced with catalog-loader
|
|
13
|
-
// constants derived from T26 enum-catalog.json + transitions/*.json. Tables now match
|
|
14
|
-
// the T25 ADR-canonical FSM (doc/decisions/state-machine-reconciliation.md):
|
|
15
|
-
// - terminal states (committed, blocked, escalated, abandoned) are truly terminal (Set [])
|
|
16
|
-
// - plan-revision-required and code-revision-required reachable from more states
|
|
17
|
-
// Closes finding N-E-2 (forge-cli side), round-2-validation.md findings 36, 40.
|
|
18
|
-
import * as path from "node:path";
|
|
19
|
-
import { BUG_TRANSITIONS, SPRINT_TRANSITIONS, TASK_TRANSITIONS } from "./lib/catalog-loader.js";
|
|
20
|
-
import { spawnStoreCliRead } from "./lib/spawn-store-cli.js";
|
|
21
|
-
// ── Legal transition tables ───────────────────────────────────────────────────
|
|
22
|
-
//
|
|
23
|
-
// Loaded from enum-catalog.json / transitions/*.json (T25 ADR-canonical).
|
|
24
|
-
// Source: build-enum-catalog.cjs (FORGE-S25-T26) → bundled by build-payload.cjs (FORGE-S25-T27).
|
|
25
|
-
// Do NOT inline transition tables here — edit forge/forge/tools/build-enum-catalog.cjs instead.
|
|
26
|
-
const ENTITY_TABLES = {
|
|
27
|
-
task: TASK_TRANSITIONS,
|
|
28
|
-
sprint: SPRINT_TRANSITIONS,
|
|
29
|
-
bug: BUG_TRANSITIONS,
|
|
30
|
-
};
|
|
31
|
-
function legalNextStates(entity, fromStatus) {
|
|
32
|
-
const table = ENTITY_TABLES[entity];
|
|
33
|
-
if (!table)
|
|
34
|
-
return [];
|
|
35
|
-
const allowed = table[fromStatus];
|
|
36
|
-
return allowed ? [...allowed] : [];
|
|
37
|
-
}
|
|
38
|
-
// ── Current-status lookup (fail-open) ────────────────────────────────────────
|
|
39
|
-
/**
|
|
40
|
-
* Read the current status of an entity from the store via `store-cli read`.
|
|
41
|
-
* Returns the status string on success, or null on any failure (fail-open).
|
|
42
|
-
*/
|
|
43
|
-
function readCurrentStatus(entity, entityId, forgeRoot) {
|
|
44
|
-
const storeCliPath = path.join(forgeRoot, "tools", "store-cli.cjs");
|
|
45
|
-
// Use the shared wrapper from lib/spawn-store-cli.ts (FORGE-S25-T17).
|
|
46
|
-
// Fail-open: spawnStoreCliRead returns null on any error — matches prior behaviour.
|
|
47
|
-
const record = spawnStoreCliRead(storeCliPath, entity, entityId, forgeRoot);
|
|
48
|
-
if (record === null)
|
|
49
|
-
return null;
|
|
50
|
-
const status = record["status"];
|
|
51
|
-
return typeof status === "string" ? status : null;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Check whether a status transition is legal.
|
|
55
|
-
*
|
|
56
|
-
* Fail-open: if the current status cannot be read, returns
|
|
57
|
-
* `{ allowed: true, reason: "lookup-failed" }`. The caller
|
|
58
|
-
* should audit-log this outcome but MUST NOT block the operation.
|
|
59
|
-
*
|
|
60
|
-
* @param input Entity, entity ID, and target status.
|
|
61
|
-
* @param forgeRoot Absolute path to the Forge plugin root.
|
|
62
|
-
*/
|
|
63
|
-
export function checkTransition(input, forgeRoot) {
|
|
64
|
-
const { entity, entityId, toStatus } = input;
|
|
65
|
-
// Lookup current status — fail-open on any error.
|
|
66
|
-
const fromStatus = readCurrentStatus(entity, entityId, forgeRoot);
|
|
67
|
-
if (fromStatus === null) {
|
|
68
|
-
return {
|
|
69
|
-
allowed: true,
|
|
70
|
-
reason: "lookup-failed",
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
const table = ENTITY_TABLES[entity];
|
|
74
|
-
if (!table) {
|
|
75
|
-
// Unknown entity type — allow through (future-proofing).
|
|
76
|
-
return { allowed: true, reason: "" };
|
|
77
|
-
}
|
|
78
|
-
const allowed = table[fromStatus]?.has(toStatus) ?? false;
|
|
79
|
-
if (allowed) {
|
|
80
|
-
return { allowed: true, reason: "" };
|
|
81
|
-
}
|
|
82
|
-
const legal = legalNextStates(entity, fromStatus);
|
|
83
|
-
const legalStr = legal.length > 0 ? legal.join(", ") : "(none)";
|
|
84
|
-
return {
|
|
85
|
-
allowed: false,
|
|
86
|
-
reason: `${fromStatus} → ${toStatus} is not a legal transition for ${entity}. Legal next states from ${fromStatus}: ${legalStr}.`,
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
//# sourceMappingURL=transition-guard.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"transition-guard.js","sourceRoot":"","sources":["../../../src/extensions/forgecli/transition-guard.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,EAAE;AACF,2EAA2E;AAC3E,EAAE;AACF,iFAAiF;AACjF,kFAAkF;AAClF,kFAAkF;AAClF,6EAA6E;AAC7E,iEAAiE;AACjE,EAAE;AACF,wFAAwF;AACxF,wFAAwF;AACxF,wFAAwF;AACxF,+EAA+E;AAC/E,+FAA+F;AAC/F,qFAAqF;AACrF,kFAAkF;AAElF,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChG,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAO7D,iFAAiF;AACjF,EAAE;AACF,0EAA0E;AAC1E,iGAAiG;AACjG,gGAAgG;AAEhG,MAAM,aAAa,GAAgD;IAClE,IAAI,EAAE,gBAAgB;IACtB,MAAM,EAAE,kBAAkB;IAC1B,GAAG,EAAE,eAAe;CACpB,CAAC;AAEF,SAAS,eAAe,CAAC,MAAc,EAAE,UAAkB;IAC1D,MAAM,KAAK,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACpC,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IACtB,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC;IAClC,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACpC,CAAC;AAED,gFAAgF;AAEhF;;;GAGG;AACH,SAAS,iBAAiB,CAAC,MAAc,EAAE,QAAgB,EAAE,SAAiB;IAC7E,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,eAAe,CAAC,CAAC;IACpE,sEAAsE;IACtE,oFAAoF;IACpF,MAAM,MAAM,GAAG,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;IAC5E,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACjC,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAChC,OAAO,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACnD,CAAC;AAUD;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe,CAAC,KAA2B,EAAE,SAAiB;IAC7E,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IAE7C,kDAAkD;IAClD,MAAM,UAAU,GAAG,iBAAiB,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;IAClE,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QACzB,OAAO;YACN,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,eAAe;SACvB,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACpC,IAAI,CAAC,KAAK,EAAE,CAAC;QACZ,yDAAyD;QACzD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IACtC,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC;IAC1D,IAAI,OAAO,EAAE,CAAC;QACb,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IACtC,CAAC;IAED,MAAM,KAAK,GAAG,eAAe,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAClD,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IAChE,OAAO;QACN,OAAO,EAAE,KAAK;QACd,MAAM,EAAE,GAAG,UAAU,MAAM,QAAQ,kCAAkC,MAAM,4BAA4B,UAAU,KAAK,QAAQ,GAAG;KACjI,CAAC;AACH,CAAC"}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
export declare const CACHE_TTL_MS: number;
|
|
2
|
-
export interface UpdateCheckOptions {
|
|
3
|
-
notify(message: string, level: "info" | "warning" | "error"): void;
|
|
4
|
-
currentCliVersion: string;
|
|
5
|
-
currentBundledForgeVersion: string;
|
|
6
|
-
now?: () => number;
|
|
7
|
-
fetchImpl?: typeof fetch;
|
|
8
|
-
cacheDir?: string;
|
|
9
|
-
}
|
|
10
|
-
export interface UpdateBannerCache {
|
|
11
|
-
lastProbeAt: number;
|
|
12
|
-
latestNpmVersion: string | null;
|
|
13
|
-
latestForgeVersion: string | null;
|
|
14
|
-
dismissedNpmVersions: string[];
|
|
15
|
-
dismissedForgeVersions: string[];
|
|
16
|
-
}
|
|
17
|
-
declare function cachePath(cacheDir: string): string;
|
|
18
|
-
declare function readCache(cacheDir: string): Promise<UpdateBannerCache | null>;
|
|
19
|
-
declare function writeCache(cacheDir: string, cache: UpdateBannerCache): Promise<void>;
|
|
20
|
-
declare function semverGt(a: string, b: string): boolean;
|
|
21
|
-
declare function composeBanner(npm: {
|
|
22
|
-
current: string;
|
|
23
|
-
latest: string;
|
|
24
|
-
} | null, forge: {
|
|
25
|
-
current: string;
|
|
26
|
-
latest: string;
|
|
27
|
-
} | null): string | null;
|
|
28
|
-
export declare function triggerUpdateCheck(opts: UpdateCheckOptions): Promise<void>;
|
|
29
|
-
export declare const __test__: {
|
|
30
|
-
CACHE_TTL_MS: number;
|
|
31
|
-
cachePath: typeof cachePath;
|
|
32
|
-
readCache: typeof readCache;
|
|
33
|
-
writeCache: typeof writeCache;
|
|
34
|
-
semverGt: typeof semverGt;
|
|
35
|
-
composeBanner: typeof composeBanner;
|
|
36
|
-
};
|
|
37
|
-
export {};
|