@prestyj/cli 4.2.62 → 4.2.76
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/core/compaction/compactor.d.ts +3 -1
- package/dist/core/compaction/compactor.d.ts.map +1 -1
- package/dist/core/compaction/compactor.js +6 -3
- package/dist/core/compaction/compactor.js.map +1 -1
- package/dist/core/compaction/compactor.test.js +86 -10
- package/dist/core/compaction/compactor.test.js.map +1 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +13 -3
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/settings-manager.d.ts +1 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +2 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +15 -1
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/system-prompt.d.ts.map +1 -1
- package/dist/system-prompt.js +21 -3
- package/dist/system-prompt.js.map +1 -1
- package/dist/ui/App.d.ts.map +1 -1
- package/dist/ui/App.js +258 -70
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/buddy/Buddy.d.ts +15 -0
- package/dist/ui/buddy/Buddy.d.ts.map +1 -0
- package/dist/ui/buddy/Buddy.js +118 -0
- package/dist/ui/buddy/Buddy.js.map +1 -0
- package/dist/ui/buddy/gacha.d.ts +8 -0
- package/dist/ui/buddy/gacha.d.ts.map +1 -0
- package/dist/ui/buddy/gacha.js +94 -0
- package/dist/ui/buddy/gacha.js.map +1 -0
- package/dist/ui/buddy/species.d.ts +52 -0
- package/dist/ui/buddy/species.d.ts.map +1 -0
- package/dist/ui/buddy/species.js +257 -0
- package/dist/ui/buddy/species.js.map +1 -0
- package/dist/ui/components/ActivityIndicator.d.ts +8 -1
- package/dist/ui/components/ActivityIndicator.d.ts.map +1 -1
- package/dist/ui/components/ActivityIndicator.js +60 -8
- package/dist/ui/components/ActivityIndicator.js.map +1 -1
- package/dist/ui/components/AnimationContext.d.ts +5 -0
- package/dist/ui/components/AnimationContext.d.ts.map +1 -1
- package/dist/ui/components/AnimationContext.js +8 -1
- package/dist/ui/components/AnimationContext.js.map +1 -1
- package/dist/ui/components/AssistantMessage.d.ts.map +1 -1
- package/dist/ui/components/AssistantMessage.js +3 -2
- package/dist/ui/components/AssistantMessage.js.map +1 -1
- package/dist/ui/components/BackgroundTasksBar.js +2 -2
- package/dist/ui/components/BackgroundTasksBar.js.map +1 -1
- package/dist/ui/components/Footer.d.ts +3 -1
- package/dist/ui/components/Footer.d.ts.map +1 -1
- package/dist/ui/components/Footer.js +23 -48
- package/dist/ui/components/Footer.js.map +1 -1
- package/dist/ui/components/Markdown.d.ts +4 -0
- package/dist/ui/components/Markdown.d.ts.map +1 -1
- package/dist/ui/components/Markdown.js +109 -6
- package/dist/ui/components/Markdown.js.map +1 -1
- package/dist/ui/components/MessageResponse.d.ts +25 -0
- package/dist/ui/components/MessageResponse.d.ts.map +1 -0
- package/dist/ui/components/MessageResponse.js +42 -0
- package/dist/ui/components/MessageResponse.js.map +1 -0
- package/dist/ui/components/NoSelect.d.ts +20 -0
- package/dist/ui/components/NoSelect.d.ts.map +1 -0
- package/dist/ui/components/NoSelect.js +14 -0
- package/dist/ui/components/NoSelect.js.map +1 -0
- package/dist/ui/components/PlanProgress.d.ts +7 -0
- package/dist/ui/components/PlanProgress.d.ts.map +1 -0
- package/dist/ui/components/PlanProgress.js +30 -0
- package/dist/ui/components/PlanProgress.js.map +1 -0
- package/dist/ui/components/Ratchet.d.ts +20 -0
- package/dist/ui/components/Ratchet.d.ts.map +1 -0
- package/dist/ui/components/Ratchet.js +30 -0
- package/dist/ui/components/Ratchet.js.map +1 -0
- package/dist/ui/components/ServerToolExecution.d.ts.map +1 -1
- package/dist/ui/components/ServerToolExecution.js +5 -6
- package/dist/ui/components/ServerToolExecution.js.map +1 -1
- package/dist/ui/components/Spinner.d.ts +8 -2
- package/dist/ui/components/Spinner.d.ts.map +1 -1
- package/dist/ui/components/Spinner.js +51 -5
- package/dist/ui/components/Spinner.js.map +1 -1
- package/dist/ui/components/StreamingArea.d.ts.map +1 -1
- package/dist/ui/components/StreamingArea.js +7 -42
- package/dist/ui/components/StreamingArea.js.map +1 -1
- package/dist/ui/components/SubAgentPanel.d.ts.map +1 -1
- package/dist/ui/components/SubAgentPanel.js +4 -3
- package/dist/ui/components/SubAgentPanel.js.map +1 -1
- package/dist/ui/components/ToolExecution.d.ts.map +1 -1
- package/dist/ui/components/ToolExecution.js +38 -12
- package/dist/ui/components/ToolExecution.js.map +1 -1
- package/dist/ui/components/ToolGroupExecution.d.ts.map +1 -1
- package/dist/ui/components/ToolGroupExecution.js +21 -17
- package/dist/ui/components/ToolGroupExecution.js.map +1 -1
- package/dist/ui/components/ToolUseLoader.d.ts +19 -0
- package/dist/ui/components/ToolUseLoader.d.ts.map +1 -0
- package/dist/ui/components/ToolUseLoader.js +42 -0
- package/dist/ui/components/ToolUseLoader.js.map +1 -0
- package/dist/ui/constants/figures.d.ts +30 -0
- package/dist/ui/constants/figures.d.ts.map +1 -0
- package/dist/ui/constants/figures.js +41 -0
- package/dist/ui/constants/figures.js.map +1 -0
- package/dist/ui/hooks/useAgentLoop.d.ts +8 -0
- package/dist/ui/hooks/useAgentLoop.d.ts.map +1 -1
- package/dist/ui/hooks/useAgentLoop.js +31 -112
- package/dist/ui/hooks/useAgentLoop.js.map +1 -1
- package/dist/ui/hooks/useBlink.d.ts +11 -0
- package/dist/ui/hooks/useBlink.d.ts.map +1 -0
- package/dist/ui/hooks/useBlink.js +19 -0
- package/dist/ui/hooks/useBlink.js.map +1 -0
- package/dist/ui/hooks/useMinDisplayTime.d.ts +11 -0
- package/dist/ui/hooks/useMinDisplayTime.d.ts.map +1 -0
- package/dist/ui/hooks/useMinDisplayTime.js +34 -0
- package/dist/ui/hooks/useMinDisplayTime.js.map +1 -0
- package/dist/ui/hooks/useTerminalProgress.d.ts +2 -0
- package/dist/ui/hooks/useTerminalProgress.d.ts.map +1 -0
- package/dist/ui/hooks/useTerminalProgress.js +98 -0
- package/dist/ui/hooks/useTerminalProgress.js.map +1 -0
- package/dist/ui/spinner-frames.d.ts +1 -0
- package/dist/ui/spinner-frames.d.ts.map +1 -1
- package/dist/ui/spinner-frames.js +15 -5
- package/dist/ui/spinner-frames.js.map +1 -1
- package/dist/ui/theme/dark.json +2 -1
- package/dist/ui/theme/light.json +2 -1
- package/dist/ui/theme/theme.d.ts +1 -0
- package/dist/ui/theme/theme.d.ts.map +1 -1
- package/dist/ui/utils/markdown-cache.d.ts +12 -0
- package/dist/ui/utils/markdown-cache.d.ts.map +1 -0
- package/dist/ui/utils/markdown-cache.js +43 -0
- package/dist/ui/utils/markdown-cache.js.map +1 -0
- package/dist/ui/utils/word-diff.d.ts +11 -0
- package/dist/ui/utils/word-diff.d.ts.map +1 -0
- package/dist/ui/utils/word-diff.js +23 -0
- package/dist/ui/utils/word-diff.js.map +1 -0
- package/dist/utils/plan-steps.d.ts +41 -0
- package/dist/utils/plan-steps.d.ts.map +1 -0
- package/dist/utils/plan-steps.js +91 -0
- package/dist/utils/plan-steps.js.map +1 -0
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../src/system-prompt.ts"],"names":[],"mappings":"AAEA,OAAO,EAAyB,KAAK,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAIrE;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,KAAK,EAAE,EAChB,QAAQ,CAAC,EAAE,OAAO,EAClB,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../src/system-prompt.ts"],"names":[],"mappings":"AAEA,OAAO,EAAyB,KAAK,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAIrE;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,KAAK,EAAE,EAChB,QAAQ,CAAC,EAAE,OAAO,EAClB,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,CAAC,MAAM,CAAC,CAgMjB"}
|
package/dist/system-prompt.js
CHANGED
|
@@ -46,8 +46,21 @@ export async function buildSystemPrompt(cwd, skills, planMode, approvedPlanPath)
|
|
|
46
46
|
`### Rules\n` +
|
|
47
47
|
`- DO NOT use bash, edit, write (except to .ezcoder/plans/), or subagent — they are restricted\n` +
|
|
48
48
|
`- Be specific: list exact file paths, function names, line numbers\n` +
|
|
49
|
-
`-
|
|
50
|
-
|
|
49
|
+
`- Note risks and verification criteria\n\n` +
|
|
50
|
+
`### Plan Format\n` +
|
|
51
|
+
`Your plan can have any structure (phases, analysis, notes, etc.) but it MUST end ` +
|
|
52
|
+
`with a section titled exactly \`## Steps\` containing a single flat numbered list of ` +
|
|
53
|
+
`implementation steps. This section is parsed by the progress widget — it is the ONLY ` +
|
|
54
|
+
`source of truth for step tracking. Do NOT put numbered lists elsewhere in the plan. ` +
|
|
55
|
+
`Use bullets or sub-headings for other sections.\n\n` +
|
|
56
|
+
`Example:\n` +
|
|
57
|
+
"```\n" +
|
|
58
|
+
`## Steps\n` +
|
|
59
|
+
`1. Create protocol types package with shared interfaces\n` +
|
|
60
|
+
`2. Set up monorepo with pnpm workspaces\n` +
|
|
61
|
+
`3. Migrate Expo Router to file-based routing\n` +
|
|
62
|
+
`...\n` +
|
|
63
|
+
"```");
|
|
51
64
|
}
|
|
52
65
|
// 2c. Approved plan — injected when a plan has been approved for implementation
|
|
53
66
|
if (approvedPlanPath && !planMode) {
|
|
@@ -66,7 +79,12 @@ export async function buildSystemPrompt(cwd, skills, planMode, approvedPlanPath)
|
|
|
66
79
|
`### Rules\n` +
|
|
67
80
|
`- Follow the plan's step-by-step implementation order\n` +
|
|
68
81
|
`- Do not deviate from the plan without user confirmation\n` +
|
|
69
|
-
`- If you encounter issues not covered by the plan, ask the user`
|
|
82
|
+
`- If you encounter issues not covered by the plan, ask the user\n\n` +
|
|
83
|
+
`### Progress Tracking\n` +
|
|
84
|
+
`After completing each step from the plan's \`## Steps\` section, output \`[DONE:n]\` ` +
|
|
85
|
+
`(e.g. \`[DONE:1]\`, \`[DONE:2]\`) in your response to mark it as complete. ` +
|
|
86
|
+
`The step numbers correspond to the numbered list in the \`## Steps\` section. ` +
|
|
87
|
+
`This updates the progress widget shown to the user.`);
|
|
70
88
|
}
|
|
71
89
|
}
|
|
72
90
|
// 3. Code Quality
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-prompt.js","sourceRoot":"","sources":["../src/system-prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,qBAAqB,EAAc,MAAM,kBAAkB,CAAC;AAErE,MAAM,aAAa,GAAG,CAAC,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,gBAAgB,CAAC,CAAC;AAEnF;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,GAAW,EACX,MAAgB,EAChB,QAAkB,EAClB,gBAAyB;IAEzB,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,cAAc;IACd,QAAQ,CAAC,IAAI,CACX,+FAA+F;QAC7F,iFAAiF;QACjF,oCAAoC,CACvC,CAAC;IAEF,iBAAiB;IACjB,QAAQ,CAAC,IAAI,CACX,oBAAoB;QAClB,6BAA6B;QAC7B,2HAA2H;QAC3H,qDAAqD;QACrD,wFAAwF;QACxF,iGAAiG;QACjG,kEAAkE;QAClE,sBAAsB;QACtB,gGAAgG;QAChG,oEAAoE;QACpE,uEAAuE;QACvE,0DAA0D;QAC1D,4BAA4B;QAC5B,0EAA0E;QAC1E,mFAAmF;QACnF,gFAAgF;QAChF,6FAA6F;QAC7F,sEAAsE;QACtE,cAAc;QACd,uJAAuJ;QACvJ,iFAAiF;QACjF,8JAA8J,CACjK,CAAC;IAEF,gBAAgB;IAChB,IAAI,QAAQ,EAAE,CAAC;QACb,QAAQ,CAAC,IAAI,CACX,2BAA2B;YACzB,+FAA+F;YAC/F,gBAAgB;YAChB,mEAAmE;YACnE,mEAAmE;YACnE,iEAAiE;YACjE,kEAAkE;YAClE,aAAa;YACb,iGAAiG;YACjG,sEAAsE;YACtE,
|
|
1
|
+
{"version":3,"file":"system-prompt.js","sourceRoot":"","sources":["../src/system-prompt.ts"],"names":[],"mappings":"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"}
|
package/dist/ui/App.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/ui/App.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,EAA6B,MAAM,aAAa,CAAC;AAE/F,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGhD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAK3D,OAAO,EAAiB,KAAK,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAcjF,OAAO,KAAK,EAAE,cAAc,EAAqB,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/ui/App.tsx"],"names":[],"mappings":"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"}
|
package/dist/ui/App.js
CHANGED
|
@@ -29,6 +29,7 @@ import { BackgroundTasksBar } from "./components/BackgroundTasksBar.js";
|
|
|
29
29
|
import { useTheme } from "./theme/theme.js";
|
|
30
30
|
import { useAnimationTick, useAnimationActive, deriveFrame, } from "./components/AnimationContext.js";
|
|
31
31
|
import { useTerminalTitle } from "./hooks/useTerminalTitle.js";
|
|
32
|
+
import { useTerminalProgress } from "./hooks/useTerminalProgress.js";
|
|
32
33
|
import { getGitBranch } from "../utils/git.js";
|
|
33
34
|
import { getModel, getContextWindow } from "../core/model-registry.js";
|
|
34
35
|
import { SessionManager } from "../core/session-manager.js";
|
|
@@ -39,8 +40,10 @@ import { estimateConversationTokens } from "../core/compaction/token-estimator.j
|
|
|
39
40
|
import { PROMPT_COMMANDS, getPromptCommand } from "../core/prompt-commands.js";
|
|
40
41
|
import { loadCustomCommands } from "../core/custom-commands.js";
|
|
41
42
|
import { buildSystemPrompt } from "../system-prompt.js";
|
|
43
|
+
import { extractPlanSteps, findCompletedMarkers, markStepsCompleted, stripDoneMarkers, } from "../utils/plan-steps.js";
|
|
42
44
|
import { getMCPServers } from "../core/mcp/index.js";
|
|
43
45
|
import { trimFlushedItems, flushOnTurnText, flushOnTurnEnd } from "./live-item-flush.js";
|
|
46
|
+
import { Buddy } from "./buddy/Buddy.js";
|
|
44
47
|
// ── Provider Error Hints ──────────────────────────────────
|
|
45
48
|
/** Detect provider-side errors and return a user-facing hint. */
|
|
46
49
|
function getProviderErrorHint(message) {
|
|
@@ -102,6 +105,41 @@ function compactHistory(items) {
|
|
|
102
105
|
return compacted;
|
|
103
106
|
}
|
|
104
107
|
// flushOnTurnText, flushOnTurnEnd are imported from ./live-item-flush.ts
|
|
108
|
+
/** Check whether an item is still active (running spinner, pending result). */
|
|
109
|
+
function isActiveItem(item) {
|
|
110
|
+
switch (item.kind) {
|
|
111
|
+
case "tool_start":
|
|
112
|
+
case "server_tool_start":
|
|
113
|
+
case "compacting":
|
|
114
|
+
return true;
|
|
115
|
+
case "tool_group":
|
|
116
|
+
return item.tools.some((t) => t.status === "running");
|
|
117
|
+
case "subagent_group":
|
|
118
|
+
return item.agents.some((a) => a.status === "running");
|
|
119
|
+
default:
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Partition live items into completed (flushable to Static) and still-active.
|
|
125
|
+
* Completed items precede active ones — we flush the longest contiguous prefix
|
|
126
|
+
* of completed items to keep ordering stable.
|
|
127
|
+
*/
|
|
128
|
+
function partitionCompleted(items) {
|
|
129
|
+
// Find the first active item — everything before it is safe to flush
|
|
130
|
+
const firstActiveIdx = items.findIndex(isActiveItem);
|
|
131
|
+
if (firstActiveIdx === -1) {
|
|
132
|
+
// All items are completed
|
|
133
|
+
return { flushed: items, remaining: [] };
|
|
134
|
+
}
|
|
135
|
+
if (firstActiveIdx === 0) {
|
|
136
|
+
return { flushed: [], remaining: items };
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
flushed: items.slice(0, firstActiveIdx),
|
|
140
|
+
remaining: items.slice(firstActiveIdx),
|
|
141
|
+
};
|
|
142
|
+
}
|
|
105
143
|
// ── Duration summary ─────────────────────────────────────
|
|
106
144
|
function formatDuration(ms) {
|
|
107
145
|
const totalSec = Math.round(ms / 1000);
|
|
@@ -276,10 +314,16 @@ export function App(props) {
|
|
|
276
314
|
const messagesRef = useRef(props.messages);
|
|
277
315
|
const [planAutoExpand, setPlanAutoExpand] = useState(false);
|
|
278
316
|
const approvedPlanPathRef = useRef(undefined);
|
|
317
|
+
const planStepsRef = useRef([]);
|
|
318
|
+
const [planSteps, setPlanSteps] = useState([]);
|
|
279
319
|
const nextIdRef = useRef(0);
|
|
280
320
|
const sessionManagerRef = useRef(props.sessionsDir ? new SessionManager(props.sessionsDir) : null);
|
|
281
321
|
const sessionPathRef = useRef(props.sessionPath);
|
|
282
322
|
const persistedIndexRef = useRef(messagesRef.current.length);
|
|
323
|
+
/** Last actual API-reported input token count (from turn_end). */
|
|
324
|
+
const lastActualTokensRef = useRef(0);
|
|
325
|
+
/** Timestamp of last compaction — used for time-based cooldown. */
|
|
326
|
+
const lastCompactionTimeRef = useRef(0);
|
|
283
327
|
const getId = () => String(nextIdRef.current++);
|
|
284
328
|
// Two-phase flush: items waiting to be moved to Static history after the
|
|
285
329
|
// live area has been cleared and Ink has committed the smaller output.
|
|
@@ -379,13 +423,15 @@ export function App(props) {
|
|
|
379
423
|
persistedIndexRef.current = allMsgs.length;
|
|
380
424
|
}, []);
|
|
381
425
|
// ── Compaction ─────────────────────────────────────────
|
|
382
|
-
// Load settings for auto-compaction
|
|
426
|
+
// Load settings for auto-compaction + buddy
|
|
383
427
|
const settingsRef = useRef(null);
|
|
428
|
+
const [buddyEnabled, setBuddyEnabled] = useState(false);
|
|
384
429
|
useEffect(() => {
|
|
385
430
|
if (props.settingsFile) {
|
|
386
431
|
const sm = new SettingsManager(props.settingsFile);
|
|
387
432
|
sm.load().then(() => {
|
|
388
433
|
settingsRef.current = sm;
|
|
434
|
+
setBuddyEnabled(sm.get("buddyEnabled") ?? false);
|
|
389
435
|
});
|
|
390
436
|
}
|
|
391
437
|
}, [props.settingsFile]);
|
|
@@ -442,6 +488,11 @@ export function App(props) {
|
|
|
442
488
|
* transformContext callback for the agent loop.
|
|
443
489
|
* Called before each LLM call and on context overflow.
|
|
444
490
|
* Checks if auto-compaction is needed and runs it.
|
|
491
|
+
*
|
|
492
|
+
* Uses actual API-reported token counts (from previous turn_end) when
|
|
493
|
+
* available, falling back to the character-based estimate. A 30-second
|
|
494
|
+
* cooldown prevents repeated compaction — matching the pattern used by
|
|
495
|
+
* Mysti, openclaw, and other real-world agent frameworks.
|
|
445
496
|
*/
|
|
446
497
|
const transformContext = useCallback(async (messages, options) => {
|
|
447
498
|
const settings = settingsRef.current;
|
|
@@ -449,13 +500,26 @@ export function App(props) {
|
|
|
449
500
|
const threshold = settings?.get("compactThreshold") ?? 0.8;
|
|
450
501
|
// Force-compact on context overflow regardless of settings
|
|
451
502
|
if (options?.force) {
|
|
452
|
-
|
|
503
|
+
const result = await compactConversation(messages);
|
|
504
|
+
lastCompactionTimeRef.current = Date.now();
|
|
505
|
+
lastActualTokensRef.current = 0; // Reset stale pre-compaction count
|
|
506
|
+
return result;
|
|
453
507
|
}
|
|
454
508
|
if (!autoCompact)
|
|
455
509
|
return messages;
|
|
510
|
+
// Time-based cooldown: skip if compaction ran within the last 30 seconds
|
|
511
|
+
if (Date.now() - lastCompactionTimeRef.current < 30_000) {
|
|
512
|
+
log("INFO", "compaction", `Skipping compaction — cooldown active`);
|
|
513
|
+
return messages;
|
|
514
|
+
}
|
|
456
515
|
const contextWindow = getContextWindow(currentModel);
|
|
457
|
-
|
|
458
|
-
|
|
516
|
+
// Prefer actual API-reported tokens over char-based estimate
|
|
517
|
+
const actualTokens = lastActualTokensRef.current > 0 ? lastActualTokensRef.current : undefined;
|
|
518
|
+
if (shouldCompact(messages, contextWindow, threshold, actualTokens)) {
|
|
519
|
+
const result = await compactConversation(messages);
|
|
520
|
+
lastCompactionTimeRef.current = Date.now();
|
|
521
|
+
lastActualTokensRef.current = 0; // Reset stale pre-compaction count
|
|
522
|
+
return result;
|
|
459
523
|
}
|
|
460
524
|
return messages;
|
|
461
525
|
}, [currentModel, compactConversation]);
|
|
@@ -535,8 +599,33 @@ export function App(props) {
|
|
|
535
599
|
}, {
|
|
536
600
|
onComplete: useCallback(() => {
|
|
537
601
|
persistNewMessages();
|
|
538
|
-
|
|
602
|
+
// Auto-clear plan progress and approved plan when all steps are completed
|
|
603
|
+
const steps = planStepsRef.current;
|
|
604
|
+
if (steps.length > 0 && steps.every((s) => s.completed)) {
|
|
605
|
+
planStepsRef.current = [];
|
|
606
|
+
setPlanSteps([]);
|
|
607
|
+
approvedPlanPathRef.current = undefined;
|
|
608
|
+
// Rebuild system prompt to remove the completed plan from context
|
|
609
|
+
void (async () => {
|
|
610
|
+
const newPrompt = await buildSystemPrompt(props.cwd, props.skills, planMode, undefined);
|
|
611
|
+
if (messagesRef.current[0]?.role === "system") {
|
|
612
|
+
messagesRef.current[0] = { role: "system", content: newPrompt };
|
|
613
|
+
}
|
|
614
|
+
})();
|
|
615
|
+
}
|
|
616
|
+
}, [persistNewMessages, planMode, props.cwd, props.skills]),
|
|
539
617
|
onTurnText: useCallback((text, thinking, thinkingMs) => {
|
|
618
|
+
// Track [DONE:n] markers for plan step progress
|
|
619
|
+
if (planStepsRef.current.length > 0) {
|
|
620
|
+
const completed = findCompletedMarkers(text);
|
|
621
|
+
if (completed.size > 0) {
|
|
622
|
+
const updated = markStepsCompleted(planStepsRef.current, completed);
|
|
623
|
+
if (updated !== planStepsRef.current) {
|
|
624
|
+
planStepsRef.current = updated;
|
|
625
|
+
setPlanSteps(updated);
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
}
|
|
540
629
|
// Flush all completed items from the previous turn to Static history.
|
|
541
630
|
// This keeps liveItems bounded per-turn, preventing Ink's live area from
|
|
542
631
|
// growing unbounded, which makes Ink's live-area re-renders expensive.
|
|
@@ -545,11 +634,22 @@ export function App(props) {
|
|
|
545
634
|
if (flushed.length > 0) {
|
|
546
635
|
setHistory((h) => compactHistory([...h, ...trimFlushedItems(flushed)]));
|
|
547
636
|
}
|
|
548
|
-
|
|
637
|
+
const displayText = planStepsRef.current.length > 0 ? stripDoneMarkers(text) : text;
|
|
638
|
+
return [{ kind: "assistant", text: displayText, thinking, thinkingMs, id: getId() }];
|
|
549
639
|
});
|
|
550
640
|
}, []),
|
|
551
641
|
onToolStart: useCallback((toolCallId, name, args) => {
|
|
552
642
|
log("INFO", "tool", `Tool call started: ${name}`, { id: toolCallId });
|
|
643
|
+
// Flush completed items (assistant text, finished tools) to Static
|
|
644
|
+
// before adding tool UI. Keeping both in the live area makes it tall
|
|
645
|
+
// and causes Ink's cursor math to clip the top.
|
|
646
|
+
setLiveItems((prev) => {
|
|
647
|
+
const { flushed, remaining } = partitionCompleted(prev);
|
|
648
|
+
if (flushed.length > 0) {
|
|
649
|
+
setHistory((h) => compactHistory([...h, ...trimFlushedItems(flushed)]));
|
|
650
|
+
}
|
|
651
|
+
return remaining;
|
|
652
|
+
});
|
|
553
653
|
if (name === "subagent") {
|
|
554
654
|
// Create or update the sub-agent group item
|
|
555
655
|
const newAgent = {
|
|
@@ -656,7 +756,12 @@ export function App(props) {
|
|
|
656
756
|
};
|
|
657
757
|
const next = [...prev];
|
|
658
758
|
next[groupIdx] = { ...group, agents: updatedAgents };
|
|
659
|
-
|
|
759
|
+
// Flush completed items to Static to keep the live area small
|
|
760
|
+
const { flushed, remaining } = partitionCompleted(next);
|
|
761
|
+
if (flushed.length > 0) {
|
|
762
|
+
setHistory((h) => compactHistory([...h, ...trimFlushedItems(flushed)]));
|
|
763
|
+
}
|
|
764
|
+
return remaining;
|
|
660
765
|
});
|
|
661
766
|
}
|
|
662
767
|
else {
|
|
@@ -664,69 +769,87 @@ export function App(props) {
|
|
|
664
769
|
// Check if this tool is in a tool_group
|
|
665
770
|
const groupIdx = prev.findIndex((item) => item.kind === "tool_group" &&
|
|
666
771
|
item.tools.some((t) => t.toolCallId === toolCallId));
|
|
772
|
+
let updated;
|
|
667
773
|
if (groupIdx !== -1) {
|
|
668
774
|
const group = prev[groupIdx];
|
|
669
|
-
|
|
670
|
-
|
|
775
|
+
updated = [...prev];
|
|
776
|
+
updated[groupIdx] = {
|
|
671
777
|
...group,
|
|
672
778
|
tools: group.tools.map((t) => t.toolCallId === toolCallId
|
|
673
779
|
? { ...t, status: "done", result, isError }
|
|
674
780
|
: t),
|
|
675
781
|
};
|
|
676
|
-
return next;
|
|
677
782
|
}
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
783
|
+
else {
|
|
784
|
+
// Find the matching tool_start and replace it with tool_done
|
|
785
|
+
const startIdx = prev.findIndex((item) => item.kind === "tool_start" && item.toolCallId === toolCallId);
|
|
786
|
+
if (startIdx !== -1) {
|
|
787
|
+
const startItem = prev[startIdx];
|
|
788
|
+
const doneItem = {
|
|
789
|
+
kind: "tool_done",
|
|
790
|
+
name,
|
|
791
|
+
args: startItem.args,
|
|
792
|
+
result,
|
|
793
|
+
isError,
|
|
794
|
+
durationMs,
|
|
795
|
+
details,
|
|
796
|
+
id: startItem.id,
|
|
797
|
+
};
|
|
798
|
+
updated = [...prev];
|
|
799
|
+
updated[startIdx] = doneItem;
|
|
800
|
+
}
|
|
801
|
+
else {
|
|
802
|
+
// Fallback: just append
|
|
803
|
+
updated = [
|
|
804
|
+
...prev,
|
|
805
|
+
{
|
|
806
|
+
kind: "tool_done",
|
|
807
|
+
name,
|
|
808
|
+
args: {},
|
|
809
|
+
result,
|
|
810
|
+
isError,
|
|
811
|
+
durationMs,
|
|
812
|
+
details,
|
|
813
|
+
id: getId(),
|
|
814
|
+
},
|
|
815
|
+
];
|
|
816
|
+
}
|
|
695
817
|
}
|
|
696
|
-
//
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
args: {},
|
|
703
|
-
result,
|
|
704
|
-
isError,
|
|
705
|
-
durationMs,
|
|
706
|
-
details,
|
|
707
|
-
id: getId(),
|
|
708
|
-
},
|
|
709
|
-
];
|
|
818
|
+
// Flush completed items to Static to keep the live area small
|
|
819
|
+
const { flushed, remaining } = partitionCompleted(updated);
|
|
820
|
+
if (flushed.length > 0) {
|
|
821
|
+
setHistory((h) => compactHistory([...h, ...trimFlushedItems(flushed)]));
|
|
822
|
+
}
|
|
823
|
+
return remaining;
|
|
710
824
|
});
|
|
711
825
|
}
|
|
712
826
|
}, []),
|
|
713
827
|
onServerToolCall: useCallback((id, name, input) => {
|
|
714
828
|
log("INFO", "server_tool", `Server tool call: ${name}`, { id });
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
829
|
+
// Flush completed items (including assistant text) to Static before
|
|
830
|
+
// adding server tool UI — same rationale as onToolStart.
|
|
831
|
+
setLiveItems((prev) => {
|
|
832
|
+
const { flushed, remaining } = partitionCompleted(prev);
|
|
833
|
+
if (flushed.length > 0) {
|
|
834
|
+
setHistory((h) => compactHistory([...h, ...trimFlushedItems(flushed)]));
|
|
835
|
+
}
|
|
836
|
+
return [
|
|
837
|
+
...remaining,
|
|
838
|
+
{
|
|
839
|
+
kind: "server_tool_start",
|
|
840
|
+
serverToolCallId: id,
|
|
841
|
+
name,
|
|
842
|
+
input,
|
|
843
|
+
startedAt: Date.now(),
|
|
844
|
+
id: getId(),
|
|
845
|
+
},
|
|
846
|
+
];
|
|
847
|
+
});
|
|
726
848
|
}, []),
|
|
727
849
|
onServerToolResult: useCallback((toolUseId, resultType, data) => {
|
|
728
850
|
log("INFO", "server_tool", `Server tool result`, { toolUseId, resultType });
|
|
729
851
|
setLiveItems((prev) => {
|
|
852
|
+
let updated;
|
|
730
853
|
const startIdx = prev.findIndex((item) => item.kind === "server_tool_start" && item.serverToolCallId === toolUseId);
|
|
731
854
|
if (startIdx !== -1) {
|
|
732
855
|
const startItem = prev[startIdx];
|
|
@@ -739,22 +862,29 @@ export function App(props) {
|
|
|
739
862
|
durationMs: Date.now() - startItem.startedAt,
|
|
740
863
|
id: startItem.id,
|
|
741
864
|
};
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
return next;
|
|
865
|
+
updated = [...prev];
|
|
866
|
+
updated[startIdx] = doneItem;
|
|
745
867
|
}
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
868
|
+
else {
|
|
869
|
+
updated = [
|
|
870
|
+
...prev,
|
|
871
|
+
{
|
|
872
|
+
kind: "server_tool_done",
|
|
873
|
+
name: "unknown",
|
|
874
|
+
input: {},
|
|
875
|
+
resultType,
|
|
876
|
+
data,
|
|
877
|
+
durationMs: 0,
|
|
878
|
+
id: getId(),
|
|
879
|
+
},
|
|
880
|
+
];
|
|
881
|
+
}
|
|
882
|
+
// Flush completed items to Static
|
|
883
|
+
const { flushed, remaining } = partitionCompleted(updated);
|
|
884
|
+
if (flushed.length > 0) {
|
|
885
|
+
setHistory((h) => compactHistory([...h, ...trimFlushedItems(flushed)]));
|
|
886
|
+
}
|
|
887
|
+
return remaining;
|
|
758
888
|
});
|
|
759
889
|
}, []),
|
|
760
890
|
onTurnEnd: useCallback((turn, stopReason, usage) => {
|
|
@@ -765,6 +895,9 @@ export function App(props) {
|
|
|
765
895
|
...(usage.cacheRead != null && { cacheRead: String(usage.cacheRead) }),
|
|
766
896
|
...(usage.cacheWrite != null && { cacheWrite: String(usage.cacheWrite) }),
|
|
767
897
|
});
|
|
898
|
+
// Track actual token count for compaction decisions
|
|
899
|
+
lastActualTokensRef.current =
|
|
900
|
+
usage.inputTokens + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0);
|
|
768
901
|
// For tool-only turns (no text), flush completed items to Static so
|
|
769
902
|
// liveItems doesn't grow unbounded across consecutive tool-only turns.
|
|
770
903
|
setLiveItems((prev) => {
|
|
@@ -911,6 +1044,8 @@ export function App(props) {
|
|
|
911
1044
|
setTitleRunning(agentLoop.isRunning);
|
|
912
1045
|
setTitleToolNames(agentLoop.activeToolCalls.map((tc) => tc.name));
|
|
913
1046
|
}, [agentLoop.activityPhase, agentLoop.isRunning, activeToolNamesKey]);
|
|
1047
|
+
// Terminal progress bar (OSC 9;4) — pulsing bar in supported terminals
|
|
1048
|
+
useTerminalProgress(agentLoop.isRunning, agentLoop.activeToolCalls.length > 0);
|
|
914
1049
|
// Animated thinking border — derived from global animation tick
|
|
915
1050
|
useAnimationActive();
|
|
916
1051
|
const animTick = useAnimationTick();
|
|
@@ -952,7 +1087,14 @@ export function App(props) {
|
|
|
952
1087
|
setHistory([{ kind: "banner", id: "banner" }]);
|
|
953
1088
|
setLiveItems([]);
|
|
954
1089
|
setDoneStatus(null);
|
|
955
|
-
|
|
1090
|
+
approvedPlanPathRef.current = undefined;
|
|
1091
|
+
planStepsRef.current = [];
|
|
1092
|
+
setPlanSteps([]);
|
|
1093
|
+
// Rebuild system prompt without the approved plan
|
|
1094
|
+
void (async () => {
|
|
1095
|
+
const newPrompt = await buildSystemPrompt(props.cwd, props.skills, planMode, undefined);
|
|
1096
|
+
messagesRef.current = [{ role: "system", content: newPrompt }];
|
|
1097
|
+
})();
|
|
956
1098
|
agentLoop.reset();
|
|
957
1099
|
setLiveItems([{ kind: "info", text: "Session cleared.", id: getId() }]);
|
|
958
1100
|
return;
|
|
@@ -979,6 +1121,40 @@ export function App(props) {
|
|
|
979
1121
|
]);
|
|
980
1122
|
return;
|
|
981
1123
|
}
|
|
1124
|
+
// Handle /clearplan — dismiss the approved plan
|
|
1125
|
+
if (trimmed === "/clearplan") {
|
|
1126
|
+
approvedPlanPathRef.current = undefined;
|
|
1127
|
+
planStepsRef.current = [];
|
|
1128
|
+
setPlanSteps([]);
|
|
1129
|
+
// Rebuild system prompt without the plan
|
|
1130
|
+
void (async () => {
|
|
1131
|
+
const newPrompt = await buildSystemPrompt(props.cwd, props.skills, planMode, undefined);
|
|
1132
|
+
if (messagesRef.current[0]?.role === "system") {
|
|
1133
|
+
messagesRef.current[0] = { role: "system", content: newPrompt };
|
|
1134
|
+
}
|
|
1135
|
+
})();
|
|
1136
|
+
setLiveItems([{ kind: "info", text: "Approved plan dismissed.", id: getId() }]);
|
|
1137
|
+
return;
|
|
1138
|
+
}
|
|
1139
|
+
// Handle /buddy — toggle companion
|
|
1140
|
+
if (trimmed === "/buddy") {
|
|
1141
|
+
const next = !buddyEnabled;
|
|
1142
|
+
setBuddyEnabled(next);
|
|
1143
|
+
if (settingsRef.current) {
|
|
1144
|
+
settingsRef.current.set("buddyEnabled", next);
|
|
1145
|
+
}
|
|
1146
|
+
setLiveItems((items) => [
|
|
1147
|
+
...items,
|
|
1148
|
+
{
|
|
1149
|
+
kind: "info",
|
|
1150
|
+
text: next
|
|
1151
|
+
? "Buddy enabled! Your companion will appear near the prompt."
|
|
1152
|
+
: "Buddy disabled.",
|
|
1153
|
+
id: getId(),
|
|
1154
|
+
},
|
|
1155
|
+
]);
|
|
1156
|
+
return;
|
|
1157
|
+
}
|
|
982
1158
|
// Handle /plans — open plan pane
|
|
983
1159
|
if (trimmed === "/plans") {
|
|
984
1160
|
stdout?.write("\x1b[2J\x1b[3J\x1b[H");
|
|
@@ -1124,6 +1300,12 @@ export function App(props) {
|
|
|
1124
1300
|
};
|
|
1125
1301
|
setLastUserMessage(input);
|
|
1126
1302
|
setDoneStatus(null);
|
|
1303
|
+
// Clear stale plan progress if there's no active approved plan
|
|
1304
|
+
// (avoids lingering progress from a completed or abandoned plan run)
|
|
1305
|
+
if (planStepsRef.current.length > 0 && !approvedPlanPathRef.current) {
|
|
1306
|
+
planStepsRef.current = [];
|
|
1307
|
+
setPlanSteps([]);
|
|
1308
|
+
}
|
|
1127
1309
|
setLiveItems([userItem]);
|
|
1128
1310
|
// Run agent
|
|
1129
1311
|
try {
|
|
@@ -1372,6 +1554,12 @@ export function App(props) {
|
|
|
1372
1554
|
}, onApprove: (planPath) => {
|
|
1373
1555
|
// Store approved plan path — will be injected into the new system prompt
|
|
1374
1556
|
approvedPlanPathRef.current = planPath;
|
|
1557
|
+
// Extract plan steps for progress tracking
|
|
1558
|
+
void import("node:fs/promises").then(({ readFile }) => readFile(planPath, "utf-8").then((content) => {
|
|
1559
|
+
const steps = extractPlanSteps(content);
|
|
1560
|
+
planStepsRef.current = steps;
|
|
1561
|
+
setPlanSteps(steps);
|
|
1562
|
+
}));
|
|
1375
1563
|
// Clear session for a fresh context focused on the plan
|
|
1376
1564
|
stdout?.write("\x1b[2J\x1b[3J\x1b[H");
|
|
1377
1565
|
setHistory([{ kind: "banner", id: "banner" }]);
|
|
@@ -1418,7 +1606,7 @@ export function App(props) {
|
|
|
1418
1606
|
void agentLoop.run(msg);
|
|
1419
1607
|
} })) : (_jsxs(_Fragment, { children: [_jsxs(Box, { flexDirection: "column", flexGrow: 1, paddingRight: 1, children: [liveItems.map((item) => renderItem(item)), _jsx(StreamingArea, { isRunning: agentLoop.isRunning, streamingText: agentLoop.streamingText, streamingThinking: agentLoop.streamingThinking, showThinking: props.showThinking, thinkingMs: agentLoop.thinkingMs, planMode: planMode })] }), agentLoop.isRunning && agentLoop.activityPhase !== "idle" ? (_jsx(Box, { marginTop: 1, borderStyle: "round", borderColor: agentLoop.activityPhase === "thinking"
|
|
1420
1608
|
? THINKING_BORDER_COLORS[thinkingBorderFrame]
|
|
1421
|
-
: "transparent", paddingLeft: 1, paddingRight: 1, width: columns, children: _jsx(ActivityIndicator, { phase: agentLoop.activityPhase, elapsedMs: agentLoop.elapsedMs, thinkingMs: agentLoop.thinkingMs, isThinking: agentLoop.isThinking, tokenEstimate: agentLoop.streamedTokenEstimate, userMessage: lastUserMessage, activeToolNames: agentLoop.activeToolCalls.map((tc) => tc.name), planMode: planMode, retryInfo: agentLoop.retryInfo }) })) : (doneStatus && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: theme.success, children: ["✻ ", doneStatus.verb, " ", formatDuration(doneStatus.durationMs)] }) }))), agentLoop.queuedCount > 0 && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: theme.accent, children: ["⏳ ", agentLoop.queuedCount, " message", agentLoop.queuedCount > 1 ? "s" : "", " queued"] }) })), _jsx(InputArea, { onSubmit: handleSubmit, onAbort: handleAbort, disabled: agentLoop.isRunning, isActive: !taskBarFocused && !overlay, onDownAtEnd: handleFocusTaskBar, onShiftTab: handleToggleThinking, onToggleTasks: () => {
|
|
1609
|
+
: "transparent", paddingLeft: 1, paddingRight: 1, width: columns, children: _jsx(ActivityIndicator, { phase: agentLoop.activityPhase, elapsedMs: agentLoop.elapsedMs, thinkingMs: agentLoop.thinkingMs, isThinking: agentLoop.isThinking, tokenEstimate: agentLoop.streamedTokenEstimate, charCountRef: agentLoop.charCountRef, realTokensAccumRef: agentLoop.realTokensAccumRef, userMessage: lastUserMessage, activeToolNames: agentLoop.activeToolCalls.map((tc) => tc.name), planMode: planMode, retryInfo: agentLoop.retryInfo, planDone: planSteps.filter((s) => s.completed).length, planTotal: planSteps.length }) })) : (doneStatus && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: theme.success, children: ["✻ ", doneStatus.verb, " ", formatDuration(doneStatus.durationMs)] }) }))), agentLoop.queuedCount > 0 && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: theme.accent, children: ["⏳ ", agentLoop.queuedCount, " message", agentLoop.queuedCount > 1 ? "s" : "", " queued"] }) })), _jsx(InputArea, { onSubmit: handleSubmit, onAbort: handleAbort, disabled: agentLoop.isRunning, isActive: !taskBarFocused && !overlay, onDownAtEnd: handleFocusTaskBar, onShiftTab: handleToggleThinking, onToggleTasks: () => {
|
|
1422
1610
|
stdout?.write("\x1b[2J\x1b[3J\x1b[H");
|
|
1423
1611
|
setOverlay("tasks");
|
|
1424
1612
|
}, onToggleSkills: () => {
|
|
@@ -1437,6 +1625,6 @@ export function App(props) {
|
|
|
1437
1625
|
id: getId(),
|
|
1438
1626
|
},
|
|
1439
1627
|
]);
|
|
1440
|
-
}, cwd: props.cwd, commands: allCommands }), overlay === "model" ? (_jsx(ModelSelector, { onSelect: handleModelSelect, onCancel: () => setOverlay(null), loggedInProviders: props.loggedInProviders ?? [currentProvider], currentModel: currentModel, currentProvider: currentProvider })) : (_jsx(Footer, { model: currentModel, tokensIn: agentLoop.contextUsed, cwd: props.cwd, gitBranch: gitBranch, thinkingEnabled: thinkingEnabled, planMode: planMode })), bgTasks.length > 0 && (_jsx(BackgroundTasksBar, { tasks: bgTasks, focused: taskBarFocused, expanded: taskBarExpanded, selectedIndex: selectedTaskIndex, onExpand: handleTaskBarExpand, onCollapse: handleTaskBarCollapse, onKill: handleTaskKill, onExit: handleTaskBarExit, onNavigate: handleTaskNavigate }))] }))] }));
|
|
1628
|
+
}, cwd: props.cwd, commands: allCommands }), overlay === "model" ? (_jsx(ModelSelector, { onSelect: handleModelSelect, onCancel: () => setOverlay(null), loggedInProviders: props.loggedInProviders ?? [currentProvider], currentModel: currentModel, currentProvider: currentProvider })) : (_jsx(Footer, { model: currentModel, tokensIn: agentLoop.contextUsed, linesAdded: agentLoop.linesChanged.added, linesRemoved: agentLoop.linesChanged.removed, cwd: props.cwd, gitBranch: gitBranch, thinkingEnabled: thinkingEnabled, planMode: planMode })), buddyEnabled && _jsx(Buddy, { phase: agentLoop.activityPhase }), bgTasks.length > 0 && (_jsx(BackgroundTasksBar, { tasks: bgTasks, focused: taskBarFocused, expanded: taskBarExpanded, selectedIndex: selectedTaskIndex, onExpand: handleTaskBarExpand, onCollapse: handleTaskBarCollapse, onKill: handleTaskKill, onExit: handleTaskBarExit, onNavigate: handleTaskNavigate }))] }))] }));
|
|
1441
1629
|
}
|
|
1442
1630
|
//# sourceMappingURL=App.js.map
|