@prestyj/cli 5.6.0 → 5.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app-sidecar.js +127 -39
- package/dist/app-sidecar.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +15 -0
- package/dist/cli.js.map +1 -1
- package/dist/core/agent-session-review-coverage.test.d.ts +2 -0
- package/dist/core/agent-session-review-coverage.test.d.ts.map +1 -0
- package/dist/core/agent-session-review-coverage.test.js +57 -0
- package/dist/core/agent-session-review-coverage.test.js.map +1 -0
- package/dist/core/agent-session.d.ts +11 -4
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +133 -22
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/compactor.test.js +1 -1
- package/dist/core/compaction/compactor.test.js.map +1 -1
- package/dist/core/event-bus.d.ts +2 -0
- package/dist/core/event-bus.d.ts.map +1 -1
- package/dist/core/event-bus.js.map +1 -1
- package/dist/core/ideal-review.d.ts +27 -0
- package/dist/core/ideal-review.d.ts.map +1 -1
- package/dist/core/ideal-review.js +64 -0
- package/dist/core/ideal-review.js.map +1 -1
- package/dist/core/ideal-review.test.js +34 -1
- package/dist/core/ideal-review.test.js.map +1 -1
- package/dist/core/lsp/client.d.ts +3 -0
- package/dist/core/lsp/client.d.ts.map +1 -1
- package/dist/core/lsp/client.js +20 -0
- package/dist/core/lsp/client.js.map +1 -1
- package/dist/core/lsp/manager.d.ts +32 -9
- package/dist/core/lsp/manager.d.ts.map +1 -1
- package/dist/core/lsp/manager.js +89 -37
- package/dist/core/lsp/manager.js.map +1 -1
- package/dist/core/lsp/manager.test.js +56 -4
- package/dist/core/lsp/manager.test.js.map +1 -1
- package/dist/core/run-lifecycle.d.ts +40 -0
- package/dist/core/run-lifecycle.d.ts.map +1 -0
- package/dist/core/run-lifecycle.js +95 -0
- package/dist/core/run-lifecycle.js.map +1 -0
- package/dist/core/run-lifecycle.test.d.ts +2 -0
- package/dist/core/run-lifecycle.test.d.ts.map +1 -0
- package/dist/core/run-lifecycle.test.js +64 -0
- package/dist/core/run-lifecycle.test.js.map +1 -0
- package/dist/core/session-manager.d.ts +25 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +66 -1
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-manager.test.js +80 -2
- package/dist/core/session-manager.test.js.map +1 -1
- package/dist/core/subagent-manager.d.ts +40 -3
- package/dist/core/subagent-manager.d.ts.map +1 -1
- package/dist/core/subagent-manager.js +342 -30
- package/dist/core/subagent-manager.js.map +1 -1
- package/dist/core/subagent-manager.test.js +189 -3
- package/dist/core/subagent-manager.test.js.map +1 -1
- package/dist/core/subagent-store.d.ts +20 -0
- package/dist/core/subagent-store.d.ts.map +1 -0
- package/dist/core/subagent-store.js +177 -0
- package/dist/core/subagent-store.js.map +1 -0
- package/dist/core/subagent-store.test.d.ts +2 -0
- package/dist/core/subagent-store.test.d.ts.map +1 -0
- package/dist/core/subagent-store.test.js +94 -0
- package/dist/core/subagent-store.test.js.map +1 -0
- package/dist/modes/agent-home-mode.d.ts.map +1 -1
- package/dist/modes/agent-home-mode.js +10 -3
- package/dist/modes/agent-home-mode.js.map +1 -1
- package/dist/modes/serve-mode.d.ts.map +1 -1
- package/dist/modes/serve-mode.js +10 -3
- package/dist/modes/serve-mode.js.map +1 -1
- package/dist/modes/subagent-worker-mode.d.ts +2 -0
- package/dist/modes/subagent-worker-mode.d.ts.map +1 -1
- package/dist/modes/subagent-worker-mode.js +13 -3
- package/dist/modes/subagent-worker-mode.js.map +1 -1
- package/dist/tools/goals.d.ts +3 -3
- package/dist/tools/tasks.d.ts +2 -2
- package/dist/tools/web-fetch.d.ts +1 -1
- package/dist/ui/App.d.ts +7 -1
- package/dist/ui/App.d.ts.map +1 -1
- package/dist/ui/App.js +63 -17
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/components/Footer.d.ts +1 -0
- package/dist/ui/components/Footer.d.ts.map +1 -1
- package/dist/ui/components/Footer.js +3 -3
- package/dist/ui/components/Footer.js.map +1 -1
- package/dist/ui/components/Footer.test.d.ts +2 -0
- package/dist/ui/components/Footer.test.d.ts.map +1 -0
- package/dist/ui/components/Footer.test.js +16 -0
- package/dist/ui/components/Footer.test.js.map +1 -0
- package/dist/ui/hooks/useAgentLoop.d.ts +8 -3
- package/dist/ui/hooks/useAgentLoop.d.ts.map +1 -1
- package/dist/ui/hooks/useAgentLoop.js +63 -7
- package/dist/ui/hooks/useAgentLoop.js.map +1 -1
- package/dist/ui/hooks/useSessionPersistence.d.ts +4 -2
- package/dist/ui/hooks/useSessionPersistence.d.ts.map +1 -1
- package/dist/ui/hooks/useSessionPersistence.js +7 -1
- package/dist/ui/hooks/useSessionPersistence.js.map +1 -1
- package/dist/ui/render.d.ts +7 -0
- package/dist/ui/render.d.ts.map +1 -1
- package/dist/ui/render.js +4 -0
- package/dist/ui/render.js.map +1 -1
- package/package.json +5 -5
package/dist/ui/App.js
CHANGED
|
@@ -13,6 +13,7 @@ import { useTaskBarStore, useTaskBarPolling, focusTaskBar, exitTaskBar, expandTa
|
|
|
13
13
|
import { playNotificationSound } from "../utils/sound.js";
|
|
14
14
|
import {} from "@prestyj/ai";
|
|
15
15
|
import { downscaleForPreview, extractMediaPaths } from "../utils/image.js";
|
|
16
|
+
import { buildSubAgentCompletionFollowUp, } from "../core/subagent-manager.js";
|
|
16
17
|
import { useAgentLoop } from "./hooks/useAgentLoop.js";
|
|
17
18
|
import { useTranscriptHistory } from "./hooks/useTranscriptHistory.js";
|
|
18
19
|
import { createWebSearchTool } from "../tools/web-search.js";
|
|
@@ -395,6 +396,7 @@ export function App(props) {
|
|
|
395
396
|
const sessionManagerRef = useRef(props.sessionsDir ? new SessionManager(props.sessionsDir) : null);
|
|
396
397
|
const sessionPathRef = useRef(props.sessionStore?.sessionPath ?? props.sessionPath);
|
|
397
398
|
const persistedIndexRef = useRef(messagesRef.current.length);
|
|
399
|
+
const turnMetricsRef = useRef(props.sessionStore?.turnMetrics ?? []);
|
|
398
400
|
const sessionStatsRef = useRef(props.sessionStore?.sessionStats ??
|
|
399
401
|
createSessionStats({ sessionId: props.sessionStore?.sessionId ?? props.sessionId }));
|
|
400
402
|
const [idealReviewEnabled, setIdealReviewEnabled] = useState(props.sessionStore?.idealReviewEnabled ?? props.idealReviewEnabled ?? true);
|
|
@@ -609,9 +611,9 @@ export function App(props) {
|
|
|
609
611
|
.map((key) => props.credentialsByProvider?.[key])
|
|
610
612
|
.find((c) => c !== undefined);
|
|
611
613
|
const activeApiKey = currentCreds?.accessToken ?? props.apiKey;
|
|
612
|
-
const activeAccountId = currentCreds
|
|
613
|
-
const activeProjectId = currentCreds
|
|
614
|
-
const activeBaseUrl = currentProvider === "gemini" ? undefined :
|
|
614
|
+
const activeAccountId = currentCreds ? currentCreds.accountId : props.accountId;
|
|
615
|
+
const activeProjectId = currentCreds ? currentCreds.projectId : props.projectId;
|
|
616
|
+
const activeBaseUrl = currentProvider === "gemini" ? undefined : currentCreds ? currentCreds.baseUrl : props.baseUrl;
|
|
615
617
|
const contextWindowOptions = useMemo(() => ({ provider: currentProvider, accountId: activeAccountId }), [currentProvider, activeAccountId]);
|
|
616
618
|
// Load git branch — re-runs whenever the displayed cwd changes (e.g. when
|
|
617
619
|
// a pixel fix moves the agent into a different project root).
|
|
@@ -790,16 +792,19 @@ export function App(props) {
|
|
|
790
792
|
useEffect(() => {
|
|
791
793
|
void applyLanguageDetectionRef.current("initial");
|
|
792
794
|
}, []);
|
|
795
|
+
const rebindSubagentsAfterCompaction = useCallback((sessionId) => props.subAgentManager?.rebindParentSession(sessionId) ?? Promise.resolve(), [props.subAgentManager]);
|
|
793
796
|
const { persistCompactedSession, persistNewMessages } = useSessionPersistence({
|
|
794
797
|
sessionManagerRef,
|
|
795
798
|
sessionPathRef,
|
|
796
799
|
sessionStatsRef,
|
|
797
800
|
persistedIndexRef,
|
|
798
801
|
messagesRef,
|
|
802
|
+
turnMetricsRef,
|
|
799
803
|
cwdRef,
|
|
800
804
|
currentProvider,
|
|
801
805
|
currentModel,
|
|
802
806
|
sessionStore,
|
|
807
|
+
onCompactedSession: rebindSubagentsAfterCompaction,
|
|
803
808
|
});
|
|
804
809
|
/**
|
|
805
810
|
* Run the language detector against the current cwd. If the detected set is a
|
|
@@ -904,6 +909,8 @@ export function App(props) {
|
|
|
904
909
|
projectId: activeProjectId,
|
|
905
910
|
resolveCredentials,
|
|
906
911
|
transformContext,
|
|
912
|
+
lspManager: props.lspManager,
|
|
913
|
+
reviewCoverageTracker: props.reviewCoverageTracker,
|
|
907
914
|
getIdealReviewMessage: (stats, touchedFiles) => {
|
|
908
915
|
if (!idealReviewEnabledRef.current)
|
|
909
916
|
return null;
|
|
@@ -1490,14 +1497,37 @@ export function App(props) {
|
|
|
1490
1497
|
return remaining;
|
|
1491
1498
|
});
|
|
1492
1499
|
}, [queueFlush]),
|
|
1493
|
-
onTurnEnd: useCallback((turn, stopReason, usage) => {
|
|
1500
|
+
onTurnEnd: useCallback((turn, stopReason, usage, timing) => {
|
|
1494
1501
|
recordTurnEnd(sessionStatsRef.current, usage);
|
|
1502
|
+
const metric = {
|
|
1503
|
+
version: 1,
|
|
1504
|
+
turn,
|
|
1505
|
+
provider: currentProvider,
|
|
1506
|
+
model: currentModel,
|
|
1507
|
+
stopReason,
|
|
1508
|
+
usage: { ...usage },
|
|
1509
|
+
timing: { ...timing },
|
|
1510
|
+
cost: {
|
|
1511
|
+
status: "unavailable",
|
|
1512
|
+
reason: "No authoritative effective-dated provider pricing is available",
|
|
1513
|
+
},
|
|
1514
|
+
};
|
|
1515
|
+
turnMetricsRef.current.push(metric);
|
|
1516
|
+
if (sessionStore)
|
|
1517
|
+
sessionStore.turnMetrics = [...turnMetricsRef.current];
|
|
1518
|
+
const metricSessionPath = sessionPathRef.current;
|
|
1519
|
+
const metricManager = sessionManagerRef.current;
|
|
1520
|
+
if (metricSessionPath && metricManager) {
|
|
1521
|
+
void metricManager.appendTurnMetric(metricSessionPath, metric);
|
|
1522
|
+
}
|
|
1495
1523
|
log("INFO", "turn", `Turn ${turn} ended`, {
|
|
1496
1524
|
stopReason,
|
|
1497
1525
|
inputTokens: String(usage.inputTokens),
|
|
1498
1526
|
outputTokens: String(usage.outputTokens),
|
|
1499
1527
|
...(usage.cacheRead != null && { cacheRead: String(usage.cacheRead) }),
|
|
1500
1528
|
...(usage.cacheWrite != null && { cacheWrite: String(usage.cacheWrite) }),
|
|
1529
|
+
providerDurationMs: String(timing.providerDurationMs),
|
|
1530
|
+
...(timing.ttftMs != null && { ttftMs: String(timing.ttftMs) }),
|
|
1501
1531
|
});
|
|
1502
1532
|
// Track actual token count for compaction decisions.
|
|
1503
1533
|
// Anthropic has separate input/output limits — only count input.
|
|
@@ -1515,7 +1545,7 @@ export function App(props) {
|
|
|
1515
1545
|
}
|
|
1516
1546
|
return remaining;
|
|
1517
1547
|
});
|
|
1518
|
-
}, [queueFlush]),
|
|
1548
|
+
}, [currentModel, currentProvider, queueFlush, sessionStore]),
|
|
1519
1549
|
onDone: useCallback((durationMs, toolsUsed, runStats) => {
|
|
1520
1550
|
log("INFO", "agent", `Agent done`, {
|
|
1521
1551
|
duration: `${durationMs}ms`,
|
|
@@ -1688,6 +1718,9 @@ export function App(props) {
|
|
|
1688
1718
|
// natural completion boundary regardless. The stuck-guard caps
|
|
1689
1719
|
// nudges per step so a genuinely blocked agent surfaces.
|
|
1690
1720
|
getFollowUpMessages: useCallback(() => {
|
|
1721
|
+
const childCompletionFollowUp = buildSubAgentCompletionFollowUp(props.subAgentManager);
|
|
1722
|
+
if (childCompletionFollowUp)
|
|
1723
|
+
return childCompletionFollowUp;
|
|
1691
1724
|
const steps = planStepsRef.current;
|
|
1692
1725
|
if (steps.length === 0 || !approvedPlanPathRef.current)
|
|
1693
1726
|
return null;
|
|
@@ -1711,7 +1744,7 @@ export function App(props) {
|
|
|
1711
1744
|
`or you genuinely need user input.`,
|
|
1712
1745
|
},
|
|
1713
1746
|
];
|
|
1714
|
-
}, []),
|
|
1747
|
+
}, [props.subAgentManager]),
|
|
1715
1748
|
onRetry: useCallback(() => {
|
|
1716
1749
|
// Roll back any pending progressive flushes from the aborted attempt.
|
|
1717
1750
|
// Without this, a stall retry regenerates the preamble and the old
|
|
@@ -2786,6 +2819,10 @@ export function App(props) {
|
|
|
2786
2819
|
try {
|
|
2787
2820
|
const session = await sm.create(taskCwd, currentProvider, currentModel);
|
|
2788
2821
|
newSessionPath = session.path;
|
|
2822
|
+
sessionStatsRef.current.sessionId = session.id;
|
|
2823
|
+
if (props.sessionStore)
|
|
2824
|
+
props.sessionStore.sessionId = session.id;
|
|
2825
|
+
await props.subAgentManager?.resetParentSession(session.id);
|
|
2789
2826
|
log("INFO", "tasks", "New session for task", { path: session.path });
|
|
2790
2827
|
}
|
|
2791
2828
|
catch {
|
|
@@ -2811,22 +2848,27 @@ export function App(props) {
|
|
|
2811
2848
|
agentLoop.reset();
|
|
2812
2849
|
persistedIndexRef.current = messagesRef.current.length;
|
|
2813
2850
|
const sm = sessionManagerRef.current;
|
|
2814
|
-
if (sm) {
|
|
2815
|
-
void sm.create(taskCwd, currentProvider, currentModel).then((session) => {
|
|
2816
|
-
sessionPathRef.current = session.path;
|
|
2817
|
-
log("INFO", "tasks", "New session for task", { path: session.path });
|
|
2818
|
-
});
|
|
2819
|
-
}
|
|
2820
2851
|
const taskItem = { kind: "task", title, id: getId() };
|
|
2821
2852
|
setLastUserMessage(title);
|
|
2822
2853
|
setDoneStatus(null);
|
|
2823
2854
|
setLiveItems([taskItem]);
|
|
2824
|
-
void
|
|
2825
|
-
|
|
2826
|
-
|
|
2855
|
+
void (async () => {
|
|
2856
|
+
try {
|
|
2857
|
+
if (sm) {
|
|
2858
|
+
const session = await sm.create(taskCwd, currentProvider, currentModel);
|
|
2859
|
+
sessionPathRef.current = session.path;
|
|
2860
|
+
sessionStatsRef.current.sessionId = session.id;
|
|
2861
|
+
await props.subAgentManager?.resetParentSession(session.id);
|
|
2862
|
+
log("INFO", "tasks", "New session for task", { path: session.path });
|
|
2863
|
+
}
|
|
2864
|
+
await agentLoop.run(fullPrompt);
|
|
2827
2865
|
}
|
|
2828
|
-
|
|
2829
|
-
|
|
2866
|
+
catch (err) {
|
|
2867
|
+
if (agentLoop.isRunning)
|
|
2868
|
+
agentLoop.reset();
|
|
2869
|
+
setLiveItems((prev) => [...prev, toErrorItem(err, getId())]);
|
|
2870
|
+
}
|
|
2871
|
+
})();
|
|
2830
2872
|
}, [agentLoop, currentModel, currentProvider, props]);
|
|
2831
2873
|
// Keep the ref in sync so stale closures (task picker, onDone run-all) can
|
|
2832
2874
|
// start a task without being recreated each render.
|
|
@@ -3408,6 +3450,10 @@ export function App(props) {
|
|
|
3408
3450
|
if (sm) {
|
|
3409
3451
|
const s = await sm.create(props.cwd, currentProvider, currentModel);
|
|
3410
3452
|
newSessionPath = s.path;
|
|
3453
|
+
sessionStatsRef.current.sessionId = s.id;
|
|
3454
|
+
if (props.sessionStore)
|
|
3455
|
+
props.sessionStore.sessionId = s.id;
|
|
3456
|
+
await props.subAgentManager?.resetParentSession(s.id);
|
|
3411
3457
|
}
|
|
3412
3458
|
if (props.resetUI && props.sessionStore) {
|
|
3413
3459
|
// Clear the overlay so the new mount lands on the chat,
|