@kenkaiiii/ggcoder 4.3.230 → 4.3.232
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/cli.d.ts.map +1 -1
- package/dist/cli.js +3 -0
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +7 -1
- package/dist/config.js.map +1 -1
- package/dist/config.test.d.ts +2 -0
- package/dist/config.test.d.ts.map +1 -0
- package/dist/config.test.js +29 -0
- package/dist/config.test.js.map +1 -0
- package/dist/core/goal-controller.d.ts +27 -6
- package/dist/core/goal-controller.d.ts.map +1 -1
- package/dist/core/goal-controller.js +246 -141
- package/dist/core/goal-controller.js.map +1 -1
- package/dist/core/goal-controller.test.js +210 -79
- package/dist/core/goal-controller.test.js.map +1 -1
- package/dist/core/goal-engine.d.ts +61 -0
- package/dist/core/goal-engine.d.ts.map +1 -0
- package/dist/core/goal-engine.js +123 -0
- package/dist/core/goal-engine.js.map +1 -0
- package/dist/core/goal-engine.test.d.ts +2 -0
- package/dist/core/goal-engine.test.d.ts.map +1 -0
- package/dist/core/goal-engine.test.js +295 -0
- package/dist/core/goal-engine.test.js.map +1 -0
- package/dist/core/goal-integration.d.ts +80 -0
- package/dist/core/goal-integration.d.ts.map +1 -0
- package/dist/core/goal-integration.js +296 -0
- package/dist/core/goal-integration.js.map +1 -0
- package/dist/core/goal-integration.test.d.ts +2 -0
- package/dist/core/goal-integration.test.d.ts.map +1 -0
- package/dist/core/goal-integration.test.js +369 -0
- package/dist/core/goal-integration.test.js.map +1 -0
- package/dist/core/goal-prerequisites.test.js +37 -1
- package/dist/core/goal-prerequisites.test.js.map +1 -1
- package/dist/core/goal-store.d.ts +80 -1
- package/dist/core/goal-store.d.ts.map +1 -1
- package/dist/core/goal-store.js +232 -65
- package/dist/core/goal-store.js.map +1 -1
- package/dist/core/goal-store.test.js +111 -2
- package/dist/core/goal-store.test.js.map +1 -1
- package/dist/core/goal-worker.d.ts.map +1 -1
- package/dist/core/goal-worker.js +55 -4
- package/dist/core/goal-worker.js.map +1 -1
- package/dist/core/goal-worker.test.js +75 -6
- package/dist/core/goal-worker.test.js.map +1 -1
- package/dist/core/goal-worktree.d.ts +55 -1
- package/dist/core/goal-worktree.d.ts.map +1 -1
- package/dist/core/goal-worktree.js +164 -1
- package/dist/core/goal-worktree.js.map +1 -1
- package/dist/core/goal-worktree.test.js +226 -4
- package/dist/core/goal-worktree.test.js.map +1 -1
- package/dist/core/ideal-review.d.ts +20 -0
- package/dist/core/ideal-review.d.ts.map +1 -0
- package/dist/core/ideal-review.js +55 -0
- package/dist/core/ideal-review.js.map +1 -0
- package/dist/core/ideal-review.test.d.ts +2 -0
- package/dist/core/ideal-review.test.d.ts.map +1 -0
- package/dist/core/ideal-review.test.js +59 -0
- package/dist/core/ideal-review.test.js.map +1 -0
- 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/system-prompt.d.ts.map +1 -1
- package/dist/system-prompt.js +9 -6
- package/dist/system-prompt.js.map +1 -1
- package/dist/system-prompt.test.js +1 -1
- package/dist/system-prompt.test.js.map +1 -1
- package/dist/tools/edit-diff.d.ts +17 -4
- package/dist/tools/edit-diff.d.ts.map +1 -1
- package/dist/tools/edit-diff.js +78 -16
- package/dist/tools/edit-diff.js.map +1 -1
- package/dist/tools/edit-diff.test.js +31 -1
- package/dist/tools/edit-diff.test.js.map +1 -1
- package/dist/tools/edit-robustness.test.d.ts +2 -0
- package/dist/tools/edit-robustness.test.d.ts.map +1 -0
- package/dist/tools/edit-robustness.test.js +415 -0
- package/dist/tools/edit-robustness.test.js.map +1 -0
- package/dist/tools/edit.d.ts.map +1 -1
- package/dist/tools/edit.js +15 -16
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/edit.test.js +23 -12
- package/dist/tools/edit.test.js.map +1 -1
- package/dist/tools/goals.d.ts +9 -1
- package/dist/tools/goals.d.ts.map +1 -1
- package/dist/tools/goals.js +78 -25
- package/dist/tools/goals.js.map +1 -1
- package/dist/tools/goals.test.js +142 -11
- package/dist/tools/goals.test.js.map +1 -1
- package/dist/tools/html-extract.d.ts +58 -0
- package/dist/tools/html-extract.d.ts.map +1 -0
- package/dist/tools/html-extract.js +130 -0
- package/dist/tools/html-extract.js.map +1 -0
- package/dist/tools/html-extract.test.d.ts +2 -0
- package/dist/tools/html-extract.test.d.ts.map +1 -0
- package/dist/tools/html-extract.test.js +60 -0
- package/dist/tools/html-extract.test.js.map +1 -0
- package/dist/tools/pdf-extract.d.ts +18 -0
- package/dist/tools/pdf-extract.d.ts.map +1 -0
- package/dist/tools/pdf-extract.js +43 -0
- package/dist/tools/pdf-extract.js.map +1 -0
- package/dist/tools/pdf-extract.test.d.ts +2 -0
- package/dist/tools/pdf-extract.test.d.ts.map +1 -0
- package/dist/tools/pdf-extract.test.js +15 -0
- package/dist/tools/pdf-extract.test.js.map +1 -0
- package/dist/tools/prompt-hints.d.ts.map +1 -1
- package/dist/tools/prompt-hints.js +2 -1
- package/dist/tools/prompt-hints.js.map +1 -1
- package/dist/tools/web-fetch.d.ts +16 -1
- package/dist/tools/web-fetch.d.ts.map +1 -1
- package/dist/tools/web-fetch.js +357 -45
- package/dist/tools/web-fetch.js.map +1 -1
- package/dist/tools/web-fetch.test.js +263 -2
- package/dist/tools/web-fetch.test.js.map +1 -1
- package/dist/tools/web-search.d.ts +14 -0
- package/dist/tools/web-search.d.ts.map +1 -1
- package/dist/tools/web-search.js +321 -35
- package/dist/tools/web-search.js.map +1 -1
- package/dist/tools/web-search.test.js +144 -1
- package/dist/tools/web-search.test.js.map +1 -1
- package/dist/ui/App.d.ts +11 -1
- package/dist/ui/App.d.ts.map +1 -1
- package/dist/ui/App.js +132 -17
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/app-items.d.ts +14 -1
- package/dist/ui/app-items.d.ts.map +1 -1
- package/dist/ui/app-items.js +2 -0
- package/dist/ui/app-items.js.map +1 -1
- package/dist/ui/components/ChatLayout.d.ts +8 -1
- package/dist/ui/components/ChatLayout.d.ts.map +1 -1
- package/dist/ui/components/ChatLayout.js +4 -1
- package/dist/ui/components/ChatLayout.js.map +1 -1
- package/dist/ui/components/ChatScreen.d.ts +14 -1
- package/dist/ui/components/ChatScreen.d.ts.map +1 -1
- package/dist/ui/components/ChatScreen.js +3 -2
- package/dist/ui/components/ChatScreen.js.map +1 -1
- package/dist/ui/components/IdealHookMessage.d.ts +12 -0
- package/dist/ui/components/IdealHookMessage.d.ts.map +1 -0
- package/dist/ui/components/IdealHookMessage.js +24 -0
- package/dist/ui/components/IdealHookMessage.js.map +1 -0
- package/dist/ui/components/InputArea.d.ts +13 -1
- package/dist/ui/components/InputArea.d.ts.map +1 -1
- package/dist/ui/components/InputArea.js +96 -12
- package/dist/ui/components/InputArea.js.map +1 -1
- package/dist/ui/components/TranscriptViewport.d.ts +34 -0
- package/dist/ui/components/TranscriptViewport.d.ts.map +1 -0
- package/dist/ui/components/TranscriptViewport.js +45 -0
- package/dist/ui/components/TranscriptViewport.js.map +1 -0
- package/dist/ui/footer-jump-regression.test.d.ts +2 -0
- package/dist/ui/footer-jump-regression.test.d.ts.map +1 -0
- package/dist/ui/footer-jump-regression.test.js +167 -0
- package/dist/ui/footer-jump-regression.test.js.map +1 -0
- package/dist/ui/goal-events.d.ts +1 -1
- package/dist/ui/goal-events.d.ts.map +1 -1
- package/dist/ui/goal-events.js +2 -2
- package/dist/ui/goal-events.js.map +1 -1
- package/dist/ui/goal-events.test.js +2 -2
- package/dist/ui/goal-events.test.js.map +1 -1
- package/dist/ui/goal-lifecycle-orchestration.test.js +13 -97
- package/dist/ui/goal-lifecycle-orchestration.test.js.map +1 -1
- package/dist/ui/goal-progress.d.ts.map +1 -1
- package/dist/ui/goal-progress.js +0 -1
- package/dist/ui/goal-progress.js.map +1 -1
- package/dist/ui/goal-run-helpers.d.ts +0 -4
- package/dist/ui/goal-run-helpers.d.ts.map +1 -1
- package/dist/ui/goal-run-helpers.js +2 -21
- package/dist/ui/goal-run-helpers.js.map +1 -1
- package/dist/ui/hooks/useAgentLoop.d.ts +2 -0
- package/dist/ui/hooks/useAgentLoop.d.ts.map +1 -1
- package/dist/ui/hooks/useAgentLoop.js +45 -1
- package/dist/ui/hooks/useAgentLoop.js.map +1 -1
- package/dist/ui/hooks/useChatLayoutMeasurements.d.ts +8 -0
- package/dist/ui/hooks/useChatLayoutMeasurements.d.ts.map +1 -1
- package/dist/ui/hooks/useChatLayoutMeasurements.js +2 -0
- package/dist/ui/hooks/useChatLayoutMeasurements.js.map +1 -1
- package/dist/ui/hooks/useGoalOrchestration.d.ts +2 -1
- package/dist/ui/hooks/useGoalOrchestration.d.ts.map +1 -1
- package/dist/ui/hooks/useGoalOrchestration.js +198 -80
- package/dist/ui/hooks/useGoalOrchestration.js.map +1 -1
- package/dist/ui/hooks/useTerminalSize.d.ts +8 -1
- package/dist/ui/hooks/useTerminalSize.d.ts.map +1 -1
- package/dist/ui/hooks/useTerminalSize.js +12 -2
- package/dist/ui/hooks/useTerminalSize.js.map +1 -1
- package/dist/ui/hooks/useTranscriptHistory.d.ts +1 -1
- package/dist/ui/hooks/useTranscriptHistory.d.ts.map +1 -1
- package/dist/ui/hooks/useTranscriptHistory.js +23 -9
- package/dist/ui/hooks/useTranscriptHistory.js.map +1 -1
- package/dist/ui/hooks/useTranscriptHistory.test.d.ts +2 -0
- package/dist/ui/hooks/useTranscriptHistory.test.d.ts.map +1 -0
- package/dist/ui/hooks/useTranscriptHistory.test.js +61 -0
- package/dist/ui/hooks/useTranscriptHistory.test.js.map +1 -0
- package/dist/ui/hooks/useTranscriptScroll.d.ts +30 -0
- package/dist/ui/hooks/useTranscriptScroll.d.ts.map +1 -0
- package/dist/ui/hooks/useTranscriptScroll.js +44 -0
- package/dist/ui/hooks/useTranscriptScroll.js.map +1 -0
- package/dist/ui/hooks/useTranscriptScroll.test.d.ts +2 -0
- package/dist/ui/hooks/useTranscriptScroll.test.d.ts.map +1 -0
- package/dist/ui/hooks/useTranscriptScroll.test.js +119 -0
- package/dist/ui/hooks/useTranscriptScroll.test.js.map +1 -0
- package/dist/ui/live-area-clamp.test.js +11 -2
- package/dist/ui/live-area-clamp.test.js.map +1 -1
- package/dist/ui/render.d.ts +11 -0
- package/dist/ui/render.d.ts.map +1 -1
- package/dist/ui/render.js +71 -7
- package/dist/ui/render.js.map +1 -1
- package/dist/ui/stores/transcript-scroll-store.d.ts +27 -0
- package/dist/ui/stores/transcript-scroll-store.d.ts.map +1 -0
- package/dist/ui/stores/transcript-scroll-store.js +73 -0
- package/dist/ui/stores/transcript-scroll-store.js.map +1 -0
- package/dist/ui/stores/transcript-scroll-store.test.d.ts +2 -0
- package/dist/ui/stores/transcript-scroll-store.test.d.ts.map +1 -0
- package/dist/ui/stores/transcript-scroll-store.test.js +73 -0
- package/dist/ui/stores/transcript-scroll-store.test.js.map +1 -0
- package/dist/ui/terminal-history.d.ts.map +1 -1
- package/dist/ui/terminal-history.js +8 -0
- package/dist/ui/terminal-history.js.map +1 -1
- package/dist/ui/testing/screen-recorder.d.ts +29 -0
- package/dist/ui/testing/screen-recorder.d.ts.map +1 -0
- package/dist/ui/testing/screen-recorder.js +179 -0
- package/dist/ui/testing/screen-recorder.js.map +1 -0
- package/dist/ui/transcript/TranscriptRenderer.d.ts.map +1 -1
- package/dist/ui/transcript/TranscriptRenderer.js +4 -1
- package/dist/ui/transcript/TranscriptRenderer.js.map +1 -1
- package/dist/ui/transcript/spacing.d.ts +3 -2
- package/dist/ui/transcript/spacing.d.ts.map +1 -1
- package/dist/ui/transcript/spacing.js +8 -0
- package/dist/ui/transcript/spacing.js.map +1 -1
- package/dist/ui/transcript/spacing.test.js +31 -0
- package/dist/ui/transcript/spacing.test.js.map +1 -1
- package/dist/ui/transcript/transcript-lines.d.ts +32 -0
- package/dist/ui/transcript/transcript-lines.d.ts.map +1 -0
- package/dist/ui/transcript/transcript-lines.js +82 -0
- package/dist/ui/transcript/transcript-lines.js.map +1 -0
- package/dist/ui/transcript/transcript-lines.test.d.ts +2 -0
- package/dist/ui/transcript/transcript-lines.test.d.ts.map +1 -0
- package/dist/ui/transcript/transcript-lines.test.js +76 -0
- package/dist/ui/transcript/transcript-lines.test.js.map +1 -0
- package/dist/ui/transcript-viewport-pinning.test.d.ts +2 -0
- package/dist/ui/transcript-viewport-pinning.test.d.ts.map +1 -0
- package/dist/ui/transcript-viewport-pinning.test.js +148 -0
- package/dist/ui/transcript-viewport-pinning.test.js.map +1 -0
- package/dist/ui/tui-history-parity.test.js +8 -0
- package/dist/ui/tui-history-parity.test.js.map +1 -1
- package/dist/ui/tui-simulation.test.d.ts +2 -0
- package/dist/ui/tui-simulation.test.d.ts.map +1 -0
- package/dist/ui/tui-simulation.test.js +138 -0
- package/dist/ui/tui-simulation.test.js.map +1 -0
- package/dist/ui/tui-terminal-recorder.test.d.ts +2 -0
- package/dist/ui/tui-terminal-recorder.test.d.ts.map +1 -0
- package/dist/ui/tui-terminal-recorder.test.js +134 -0
- package/dist/ui/tui-terminal-recorder.test.js.map +1 -0
- package/dist/utils/format.js +7 -0
- package/dist/utils/format.js.map +1 -1
- package/package.json +12 -6
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
2
|
-
import { createWebSearchTool, isAdSearchResultUrl } from "./web-search.js";
|
|
2
|
+
import { canonicalSearchResultUrl, createWebSearchTool, isAdSearchResultUrl, normalizeDomain, } from "./web-search.js";
|
|
3
3
|
const originalFetch = globalThis.fetch;
|
|
4
4
|
function context() {
|
|
5
5
|
return { signal: new AbortController().signal, toolCallId: "test" };
|
|
@@ -8,6 +8,16 @@ afterEach(() => {
|
|
|
8
8
|
globalThis.fetch = originalFetch;
|
|
9
9
|
vi.restoreAllMocks();
|
|
10
10
|
});
|
|
11
|
+
describe("canonicalSearchResultUrl", () => {
|
|
12
|
+
it("strips tracking params and fragments while sorting remaining params", () => {
|
|
13
|
+
expect(canonicalSearchResultUrl("https://example.com/docs?utm_source=x&b=2&a=1&fbclid=abc#section")).toBe("https://example.com/docs?a=1&b=2");
|
|
14
|
+
});
|
|
15
|
+
it("unwraps nested redirect params safely", () => {
|
|
16
|
+
expect(canonicalSearchResultUrl("/l/?url=https%3A%2F%2Fexample.com%2Fguide%3Futm_medium%3Dcpc%26x%3D1")).toBe("https://example.com/guide?x=1");
|
|
17
|
+
expect(canonicalSearchResultUrl("https://duckduckgo.com/y.js?u3=https%3A%2F%2Fwww.bing.com%2Faclick%3Fld%3Dabc")).toBeNull();
|
|
18
|
+
expect(canonicalSearchResultUrl("javascript:alert(1)")).toBeNull();
|
|
19
|
+
});
|
|
20
|
+
});
|
|
11
21
|
describe("isAdSearchResultUrl", () => {
|
|
12
22
|
it("blocks DuckDuckGo ad redirects", () => {
|
|
13
23
|
const url = "https://duckduckgo.com/y.js?ad_domain=nordvpn.com&ad_provider=bingv7aa&ad_type=txad&u3=https%3A%2F%2Fwww.bing.com%2Faclick%3Fld%3Dabc";
|
|
@@ -17,11 +27,32 @@ describe("isAdSearchResultUrl", () => {
|
|
|
17
27
|
expect(isAdSearchResultUrl("https://www.bing.com/aclick?ld=abc&msclkid=123")).toBe(true);
|
|
18
28
|
expect(isAdSearchResultUrl("https://www.google.com/aclk?sa=l&adurl=https%3A%2F%2Fexample.com")).toBe(true);
|
|
19
29
|
});
|
|
30
|
+
it("blocks affiliate and ad network hosts", () => {
|
|
31
|
+
expect(isAdSearchResultUrl("https://awin1.com/cread.php?awinmid=1")).toBe(true);
|
|
32
|
+
expect(isAdSearchResultUrl("https://ads.linkedin.com/click?id=1")).toBe(true);
|
|
33
|
+
});
|
|
20
34
|
it("allows ordinary organic result URLs", () => {
|
|
21
35
|
expect(isAdSearchResultUrl("https://developer.mozilla.org/en-US/docs/Web/API/fetch")).toBe(false);
|
|
22
36
|
expect(isAdSearchResultUrl("/l/?uddg=https%3A%2F%2Fwww.typescriptlang.org%2Fdocs%2F")).toBe(false);
|
|
23
37
|
});
|
|
24
38
|
});
|
|
39
|
+
describe("normalizeDomain", () => {
|
|
40
|
+
it("lowercases and strips scheme and wildcard prefixes", () => {
|
|
41
|
+
expect(normalizeDomain("https://Docs.Python.ORG")).toBe("docs.python.org");
|
|
42
|
+
expect(normalizeDomain("*.example.com")).toBe("example.com");
|
|
43
|
+
expect(normalizeDomain(" github.com ")).toBe("github.com");
|
|
44
|
+
});
|
|
45
|
+
it("converts Unicode homographs to punycode", () => {
|
|
46
|
+
// "аррӏе" uses Cyrillic look-alikes; hostname normalizes to xn-- punycode.
|
|
47
|
+
const result = normalizeDomain("аррӏе.com");
|
|
48
|
+
expect(result).toMatch(/^xn--/);
|
|
49
|
+
expect(result).not.toBe("apple.com");
|
|
50
|
+
});
|
|
51
|
+
it("returns null for un-parseable input", () => {
|
|
52
|
+
expect(normalizeDomain("")).toBeNull();
|
|
53
|
+
expect(normalizeDomain(" ")).toBeNull();
|
|
54
|
+
});
|
|
55
|
+
});
|
|
25
56
|
describe("createWebSearchTool", () => {
|
|
26
57
|
it("filters ad results from live parser output before returning organic results", async () => {
|
|
27
58
|
const html = `
|
|
@@ -95,6 +126,118 @@ describe("createWebSearchTool", () => {
|
|
|
95
126
|
expect(result).toContain("from Brave");
|
|
96
127
|
expect(result).not.toContain("Cheap laptops for sale");
|
|
97
128
|
});
|
|
129
|
+
it("applies time_range and include_domains to the request", async () => {
|
|
130
|
+
let capturedUrl = "";
|
|
131
|
+
globalThis.fetch = vi.fn(async (input) => {
|
|
132
|
+
capturedUrl = String(input);
|
|
133
|
+
// Return organic result only on the Google branch.
|
|
134
|
+
if (capturedUrl.includes("google.com")) {
|
|
135
|
+
return new Response(`<div class="g"><a href="https://docs.python.org/3/"><h3>Python Docs</h3></a><div class="VwiC3b">Official Python documentation.</div></div>`, { status: 200 });
|
|
136
|
+
}
|
|
137
|
+
return new Response("<html></html>", { status: 200 });
|
|
138
|
+
});
|
|
139
|
+
const result = await createWebSearchTool().execute({
|
|
140
|
+
query: "asyncio",
|
|
141
|
+
include_domains: ["docs.python.org"],
|
|
142
|
+
time_range: "week",
|
|
143
|
+
max_results: 5,
|
|
144
|
+
}, context());
|
|
145
|
+
// Last captured URL is the Google branch with recency + site scoping.
|
|
146
|
+
expect(capturedUrl).toContain("tbs=qdr:w");
|
|
147
|
+
expect(decodeURIComponent(capturedUrl)).toContain("site:docs.python.org");
|
|
148
|
+
expect(result).toContain("Python Docs");
|
|
149
|
+
expect(result).toContain("past week");
|
|
150
|
+
});
|
|
151
|
+
it("drops results from excluded domains client-side", async () => {
|
|
152
|
+
const html = `
|
|
153
|
+
<a class="result__a" href="/l/?uddg=https%3A%2F%2Fw3schools.com%2Ffetch">W3Schools Fetch</a>
|
|
154
|
+
<a class="result__snippet">Tutorial content.</a>
|
|
155
|
+
<a class="result__a" href="/l/?uddg=https%3A%2F%2Fdeveloper.mozilla.org%2Fen-US%2Fdocs%2FWeb%2FAPI%2FFetch_API">Fetch API - MDN</a>
|
|
156
|
+
<a class="result__snippet">MDN reference.</a>
|
|
157
|
+
`;
|
|
158
|
+
globalThis.fetch = vi.fn(async () => new Response(html, { status: 200 }));
|
|
159
|
+
const result = await createWebSearchTool().execute({ query: "fetch api", exclude_domains: ["w3schools.com"], max_results: 5 }, context());
|
|
160
|
+
expect(result).toContain("Fetch API - MDN");
|
|
161
|
+
expect(result).not.toContain("W3Schools");
|
|
162
|
+
expect(result).toContain("-site:w3schools.com");
|
|
163
|
+
});
|
|
164
|
+
it("filters coupon spam for non-commerce queries but keeps it for commerce queries", async () => {
|
|
165
|
+
const html = `
|
|
166
|
+
<a class="result__a" href="https://coupon.example.com/typescript">TypeScript coupon code</a>
|
|
167
|
+
<a class="result__snippet">Exclusive deal and discount code for docs.</a>
|
|
168
|
+
<a class="result__a" href="https://www.typescriptlang.org/docs/">TypeScript Documentation</a>
|
|
169
|
+
<a class="result__snippet">Official TypeScript docs.</a>
|
|
170
|
+
`;
|
|
171
|
+
globalThis.fetch = vi.fn(async () => new Response(html, { status: 200 }));
|
|
172
|
+
const docsResult = await createWebSearchTool().execute({ query: "typescript docs", max_results: 5 }, context());
|
|
173
|
+
expect(docsResult).toContain("TypeScript Documentation");
|
|
174
|
+
expect(docsResult).not.toContain("TypeScript coupon code");
|
|
175
|
+
expect(docsResult).toContain("filtered 1 spam result");
|
|
176
|
+
globalThis.fetch = vi.fn(async () => new Response(html, { status: 200 }));
|
|
177
|
+
const commerceResult = await createWebSearchTool().execute({ query: "best typescript coupon", max_results: 5 }, context());
|
|
178
|
+
expect(commerceResult).toContain("TypeScript coupon code");
|
|
179
|
+
});
|
|
180
|
+
it("collapses duplicate canonical URLs and reports duplicate count", async () => {
|
|
181
|
+
const html = `
|
|
182
|
+
<a class="result__a" href="https://example.com/docs?utm_source=a&b=2&a=1#top">Docs first</a>
|
|
183
|
+
<a class="result__snippet">First snippet.</a>
|
|
184
|
+
<a class="result__a" href="https://example.com/docs?a=1&b=2">Docs duplicate</a>
|
|
185
|
+
<a class="result__snippet">Duplicate snippet.</a>
|
|
186
|
+
`;
|
|
187
|
+
globalThis.fetch = vi.fn(async () => new Response(html, { status: 200 }));
|
|
188
|
+
const result = await createWebSearchTool().execute({ query: "example docs", max_results: 5 }, context());
|
|
189
|
+
expect(result).toContain("Docs first");
|
|
190
|
+
expect(result).not.toContain("Docs duplicate");
|
|
191
|
+
expect(result).toContain("1 duplicate");
|
|
192
|
+
});
|
|
193
|
+
it("skips sponsored parser blocks and returns organic results", async () => {
|
|
194
|
+
const html = `
|
|
195
|
+
<li class="b_algo b_ad">
|
|
196
|
+
<h2><a href="https://example-ad.com/offer">Sponsored offer</a></h2>
|
|
197
|
+
<div class="b_adlabel">Ad</div><p>Buy now.</p>
|
|
198
|
+
</li>
|
|
199
|
+
<li class="b_algo">
|
|
200
|
+
<h2><a href="https://developer.mozilla.org/docs/Web/API/Fetch_API">Fetch API - MDN</a></h2>
|
|
201
|
+
<div class="b_caption"><p>Useful organic snippet.</p></div>
|
|
202
|
+
</li>
|
|
203
|
+
`;
|
|
204
|
+
globalThis.fetch = vi
|
|
205
|
+
.fn()
|
|
206
|
+
.mockResolvedValueOnce(new Response("<html></html>", { status: 200 }))
|
|
207
|
+
.mockResolvedValueOnce(new Response("<html></html>", { status: 200 }))
|
|
208
|
+
.mockResolvedValueOnce(new Response("<html></html>", { status: 200 }))
|
|
209
|
+
.mockResolvedValueOnce(new Response(html, { status: 200 }));
|
|
210
|
+
const result = await createWebSearchTool().execute({ query: "fetch api mdn", max_results: 5 }, context());
|
|
211
|
+
expect(result).toContain("Fetch API - MDN");
|
|
212
|
+
expect(result).not.toContain("Sponsored offer");
|
|
213
|
+
expect(result).toContain("from Bing");
|
|
214
|
+
});
|
|
215
|
+
it("reports filtered ad counts only when non-zero", async () => {
|
|
216
|
+
const html = `
|
|
217
|
+
<a class="result__a" href="https://googleadservices.com/pagead/aclk">Cloud hosting</a>
|
|
218
|
+
<a class="result__snippet">Fast platform overview.</a>
|
|
219
|
+
<a class="result__a" href="https://example.com/docs">Docs</a>
|
|
220
|
+
<a class="result__snippet">Organic docs.</a>
|
|
221
|
+
`;
|
|
222
|
+
globalThis.fetch = vi.fn(async () => new Response(html, { status: 200 }));
|
|
223
|
+
const filtered = await createWebSearchTool().execute({ query: "example docs", max_results: 5 }, context());
|
|
224
|
+
expect(filtered).toContain("filtered 1 ad");
|
|
225
|
+
globalThis.fetch = vi.fn(async () => new Response(`<a class="result__a" href="https://example.com/docs">Docs</a><a class="result__snippet">Organic docs.</a>`, { status: 200 }));
|
|
226
|
+
const clean = await createWebSearchTool().execute({ query: "example docs", max_results: 5 }, context());
|
|
227
|
+
expect(clean).not.toContain("filtered");
|
|
228
|
+
});
|
|
229
|
+
it("rejects setting both include_domains and exclude_domains via the schema", () => {
|
|
230
|
+
const tool = createWebSearchTool();
|
|
231
|
+
const parsed = tool.parameters.safeParse({
|
|
232
|
+
query: "x",
|
|
233
|
+
include_domains: ["a.com"],
|
|
234
|
+
exclude_domains: ["b.com"],
|
|
235
|
+
});
|
|
236
|
+
expect(parsed.success).toBe(false);
|
|
237
|
+
if (!parsed.success) {
|
|
238
|
+
expect(parsed.error.issues.some((i) => /mutually exclusive/i.test(i.message))).toBe(true);
|
|
239
|
+
}
|
|
240
|
+
});
|
|
98
241
|
it("uses Bing as a fallback and unwraps Bing redirect URLs", async () => {
|
|
99
242
|
const blockedHtml = "<html>captcha blocked challenge-form</html>";
|
|
100
243
|
const bingURL = `https://www.bing.com/ck/a?u=a1${Buffer.from("https://www.typescriptlang.org/docs/", "utf8").toString("base64url")}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-search.test.js","sourceRoot":"","sources":["../../src/tools/web-search.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAE3E,MAAM,aAAa,GAAG,UAAU,CAAC,KAAK,CAAC;AAEvC,SAAS,OAAO;IACd,OAAO,EAAE,MAAM,EAAE,IAAI,eAAe,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;AACtE,CAAC;AAED,SAAS,CAAC,GAAG,EAAE;IACb,UAAU,CAAC,KAAK,GAAG,aAAa,CAAC;IACjC,EAAE,CAAC,eAAe,EAAE,CAAC;AACvB,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,GAAG,GACP,uIAAuI,CAAC;QAE1I,MAAM,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,CAAC,mBAAmB,CAAC,gDAAgD,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzF,MAAM,CACJ,mBAAmB,CAAC,kEAAkE,CAAC,CACxF,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,CAAC,mBAAmB,CAAC,wDAAwD,CAAC,CAAC,CAAC,IAAI,CACxF,KAAK,CACN,CAAC;QACF,MAAM,CAAC,mBAAmB,CAAC,yDAAyD,CAAC,CAAC,CAAC,IAAI,CACzF,KAAK,CACN,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,6EAA6E,EAAE,KAAK,IAAI,EAAE;QAC3F,MAAM,IAAI,GAAG;;;;;KAKZ,CAAC;QACF,UAAU,CAAC,KAAK,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAiB,CAAC;QAE1F,MAAM,MAAM,GAAG,MAAM,mBAAmB,EAAE,CAAC,OAAO,CAChD,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC,EAAE,EACtC,OAAO,EAAE,CACV,CAAC;QAEF,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,4DAA4D,CAAC,CAAC;QACvF,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;QACxE,MAAM,IAAI,GAAG;;;;;;;KAOZ,CAAC;QACF,UAAU,CAAC,KAAK,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAiB,CAAC;QAE1F,MAAM,MAAM,GAAG,MAAM,mBAAmB,EAAE,CAAC,OAAO,CAChD,EAAE,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,CAAC,EAAE,EAC5C,OAAO,EAAE,CACV,CAAC;QAEF,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,0BAA0B,CAAC,CAAC;QACrD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,sCAAsC,CAAC,CAAC;QACjE,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,wCAAwC,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;QAC5E,MAAM,SAAS,GAAG,eAAe,CAAC;QAClC,MAAM,UAAU,GAAG;;;;;KAKlB,CAAC;QACF,UAAU,CAAC,KAAK,GAAG,EAAE;aAClB,EAAE,EAAE;aACJ,qBAAqB,CAAC,IAAI,QAAQ,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;aAC/D,qBAAqB,CAAC,IAAI,QAAQ,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;aAC/D,qBAAqB,CAAC,IAAI,QAAQ,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;aAC/D,qBAAqB,CAAC,IAAI,QAAQ,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;aAC/D,qBAAqB,CAAC,IAAI,QAAQ,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAiB,CAAC;QAEpF,MAAM,MAAM,GAAG,MAAM,mBAAmB,EAAE,CAAC,OAAO,CAChD,EAAE,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,CAAC,EAAE,EAC1C,OAAO,EAAE,CACV,CAAC;QAEF,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,4DAA4D,CAAC,CAAC;QACvF,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,6DAA6D,CAAC,CAAC;QACxF,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,KAAK,IAAI,EAAE;QAC9E,MAAM,UAAU,GAAG;;;KAGlB,CAAC;QACF,MAAM,SAAS,GAAG;;;;;KAKjB,CAAC;QACF,UAAU,CAAC,KAAK,GAAG,EAAE;aAClB,EAAE,EAAE;aACJ,qBAAqB,CAAC,IAAI,QAAQ,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;aAChE,qBAAqB,CAAC,IAAI,QAAQ,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;aAChE,qBAAqB,CAAC,IAAI,QAAQ,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAiB,CAAC;QAEnF,MAAM,MAAM,GAAG,MAAM,mBAAmB,EAAE,CAAC,OAAO,CAChD,EAAE,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,EAAE,EACzC,OAAO,EAAE,CACV,CAAC;QAEF,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QAC3C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,6BAA6B,CAAC,CAAC;QACxD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACtE,MAAM,WAAW,GAAG,6CAA6C,CAAC;QAClE,MAAM,OAAO,GAAG,iCAAiC,MAAM,CAAC,IAAI,CAC1D,sCAAsC,EACtC,MAAM,CACP,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QAC1B,MAAM,QAAQ,GAAG;;uBAEE,OAAO;;;KAGzB,CAAC;QACF,UAAU,CAAC,KAAK,GAAG,EAAE;aAClB,EAAE,EAAE;aACJ,qBAAqB,CAAC,IAAI,QAAQ,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;aACjE,qBAAqB,CAAC,IAAI,QAAQ,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;aACjE,qBAAqB,CAAC,IAAI,QAAQ,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;aACjE,qBAAqB,CAAC,IAAI,QAAQ,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAiB,CAAC;QAElF,MAAM,MAAM,GAAG,MAAM,mBAAmB,EAAE,CAAC,OAAO,CAChD,EAAE,KAAK,EAAE,mCAAmC,EAAE,WAAW,EAAE,CAAC,EAAE,EAC9D,OAAO,EAAE,CACV,CAAC;QAEF,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,0BAA0B,CAAC,CAAC;QACrD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,sCAAsC,CAAC,CAAC;QACjE,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"web-search.test.js","sourceRoot":"","sources":["../../src/tools/web-search.test.ts"],"names":[],"mappings":"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"}
|
package/dist/ui/App.d.ts
CHANGED
|
@@ -20,7 +20,7 @@ export { getNextThinkingLevel } from "./thinking-level.js";
|
|
|
20
20
|
export { appendGoalProgressDraft, completedItemsWithDurableGoalTerminalProgress, formatGoalTerminalProgress, getGoalContinuationChoiceKey, routeGoalSyntheticEvent, truncateGoalProgressText, } from "./goal-progress.js";
|
|
21
21
|
export { getChatControlsLayoutDecision, getDoneFlushDecision, getGoalActivationPaneTransition, getGoalSetupFinishedPaneTransition, getGoalSetupPaneTransitionAfterRun, getScrollStabilizationDecision, getStaticHistoryKey, hasParagraphBreakLiveUserMessage, isTallLiveUserMessage, nextGoalModeAfterAgentDone, shouldHideHistoryForOverlayView, shouldHideStaticItemsForOverlayView, shouldResetUIForGoalSetupPaneTransition, shouldStabilizeOverlayPaneRerender, shouldTopSpaceAfterPrintedAgentBoundary, shouldTopSpaceAssistantAfterToolBoundary, shouldTopSpaceStreamingAssistant, } from "./layout-decisions.js";
|
|
22
22
|
export { getNextGeneratedItemId, isActiveItem, partitionCompleted, pinStreamingTextBeforeToolBoundary, } from "./item-helpers.js";
|
|
23
|
-
export {
|
|
23
|
+
export { buildGoalUserPauseRun, goalRunNeedsExplicitContinuationAfterWorker, shouldKeepGoalRunTrackedAfterDecision, shouldRunGoalTaskInMainCheckout, } from "./goal-run-helpers.js";
|
|
24
24
|
export interface AppProps {
|
|
25
25
|
provider: Provider;
|
|
26
26
|
model: string;
|
|
@@ -36,6 +36,7 @@ export interface AppProps {
|
|
|
36
36
|
cwd: string;
|
|
37
37
|
version: string;
|
|
38
38
|
showTokenUsage?: boolean;
|
|
39
|
+
idealReviewEnabled?: boolean;
|
|
39
40
|
onSlashCommand?: (input: string) => Promise<string | null>;
|
|
40
41
|
loggedInProviders?: Provider[];
|
|
41
42
|
credentialsByProvider?: Record<string, {
|
|
@@ -72,6 +73,14 @@ export interface AppProps {
|
|
|
72
73
|
onExitPlan?: (planPath: string) => Promise<string>;
|
|
73
74
|
};
|
|
74
75
|
terminalHistoryPrinter?: TerminalHistoryPrinter;
|
|
76
|
+
/**
|
|
77
|
+
* When true, the UI runs in the alternate-screen fullscreen viewport: the
|
|
78
|
+
* transcript is rendered inside Ink as a bounded, app-scrolled region above a
|
|
79
|
+
* pinned controls region, and nothing is written to native scrollback. This
|
|
80
|
+
* is what keeps the footer a truly fixed bottom region. Defaults off (legacy
|
|
81
|
+
* scrollback path) for non-TTY / CI / print modes.
|
|
82
|
+
*/
|
|
83
|
+
fullscreen?: boolean;
|
|
75
84
|
/**
|
|
76
85
|
* Wired by `renderApp`. Tears down the current Ink instance and renders
|
|
77
86
|
* a fresh one. Patching Ink's internal frame tracking in place is
|
|
@@ -148,6 +157,7 @@ export interface AppProps {
|
|
|
148
157
|
goalMode?: GoalMode;
|
|
149
158
|
planMode?: boolean;
|
|
150
159
|
sessionStats?: SessionStats;
|
|
160
|
+
idealReviewEnabled?: boolean;
|
|
151
161
|
};
|
|
152
162
|
}
|
|
153
163
|
export declare function App(props: AppProps): import("react/jsx-runtime").JSX.Element;
|
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":"AAuBA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,KAAK,aAAa,EAEnB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAUrD,OAAO,EAIL,KAAK,eAAe,EACrB,MAAM,+BAA+B,CAAC;AAGvC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAwBjE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAkB,eAAe,EAAe,MAAM,6BAA6B,CAAC;AAEhG,OAAO,EAML,KAAK,QAAQ,EACd,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAQ3D,OAAO,EAKL,KAAK,aAAa,EAClB,KAAK,OAAO,EACb,MAAM,uBAAuB,CAAC;AAI/B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,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
|
@@ -48,22 +48,27 @@ import { isGoalSyntheticEvent, parseGoalSyntheticEvent } from "./goal-events.js"
|
|
|
48
48
|
import { buildUserContentWithAttachments } from "./prompt-routing.js";
|
|
49
49
|
import { submitPromptCommand } from "./submit-prompt-command.js";
|
|
50
50
|
import { handleUiSlashCommand } from "./submit-slash-commands.js";
|
|
51
|
+
import { buildIdealReviewMessage, evaluateIdealReview } from "../core/ideal-review.js";
|
|
51
52
|
import { getNextThinkingLevel, isThinkingLevelSupported } from "./thinking-level.js";
|
|
52
53
|
import { appendGoalProgressDraft, completedItemsWithDurableGoalTerminalProgress, } from "./goal-progress.js";
|
|
53
54
|
import { getDoneFlushDecision, nextGoalModeAfterAgentDone, shouldTopSpaceAfterPrintedAgentBoundary, shouldTopSpaceStreamingAssistant, } from "./layout-decisions.js";
|
|
54
55
|
import { isTranscriptSpacingItem } from "./transcript/spacing.js";
|
|
56
|
+
import { buildTranscriptLines } from "./transcript/transcript-lines.js";
|
|
57
|
+
import { useTranscriptScroll } from "./hooks/useTranscriptScroll.js";
|
|
58
|
+
import { scrollTranscriptByLines } from "./stores/transcript-scroll-store.js";
|
|
55
59
|
import { renderTranscriptItem } from "./transcript/TranscriptRenderer.js";
|
|
56
60
|
import { formatDuration } from "./duration-format.js";
|
|
57
61
|
import { pickDurationVerb } from "./duration-summary.js";
|
|
58
62
|
import { toErrorItem } from "./error-item.js";
|
|
59
63
|
import { addLinesChanged, buildSessionSummary, createSessionStats, recordServerToolCall, recordToolEnd, recordTurnEnd, } from "./session-summary.js";
|
|
60
64
|
import { compactHistory, getNextGeneratedItemId, isActiveItem, isSameAssistantText, normalizeAssistantText, partitionCompleted, pinStreamingTextBeforeToolBoundary, removeItemsWithIds, uniqueItemsById, } from "./item-helpers.js";
|
|
65
|
+
import { IDEAL_HOOK_NOTICE_TEXT } from "./app-items.js";
|
|
61
66
|
export { buildGoalSetupPromptFromPlanner, buildUserContentWithAttachments, collectAssistantTextSince, isGoalPromptCommandName, routePromptCommandInput, runGoalPromptSetupSequence, } from "./prompt-routing.js";
|
|
62
67
|
export { getNextThinkingLevel } from "./thinking-level.js";
|
|
63
68
|
export { appendGoalProgressDraft, completedItemsWithDurableGoalTerminalProgress, formatGoalTerminalProgress, getGoalContinuationChoiceKey, routeGoalSyntheticEvent, truncateGoalProgressText, } from "./goal-progress.js";
|
|
64
69
|
export { getChatControlsLayoutDecision, getDoneFlushDecision, getGoalActivationPaneTransition, getGoalSetupFinishedPaneTransition, getGoalSetupPaneTransitionAfterRun, getScrollStabilizationDecision, getStaticHistoryKey, hasParagraphBreakLiveUserMessage, isTallLiveUserMessage, nextGoalModeAfterAgentDone, shouldHideHistoryForOverlayView, shouldHideStaticItemsForOverlayView, shouldResetUIForGoalSetupPaneTransition, shouldStabilizeOverlayPaneRerender, shouldTopSpaceAfterPrintedAgentBoundary, shouldTopSpaceAssistantAfterToolBoundary, shouldTopSpaceStreamingAssistant, } from "./layout-decisions.js";
|
|
65
70
|
export { getNextGeneratedItemId, isActiveItem, partitionCompleted, pinStreamingTextBeforeToolBoundary, } from "./item-helpers.js";
|
|
66
|
-
export {
|
|
71
|
+
export { buildGoalUserPauseRun, goalRunNeedsExplicitContinuationAfterWorker, shouldKeepGoalRunTrackedAfterDecision, shouldRunGoalTaskInMainCheckout, } from "./goal-run-helpers.js";
|
|
67
72
|
/** Tools that get aggregated into a single compact group when possible. */
|
|
68
73
|
const AGGREGATABLE_TOOLS = new Set([
|
|
69
74
|
"read",
|
|
@@ -100,6 +105,9 @@ export function App(props) {
|
|
|
100
105
|
const { columns, rows } = useTerminalSize();
|
|
101
106
|
// Hoisted before terminal title hook so it can reference them
|
|
102
107
|
const [lastUserMessage, setLastUserMessage] = useState("");
|
|
108
|
+
// Bumped on every prompt submit; the fullscreen transcript scroll controller
|
|
109
|
+
// watches this to snap back to the bottom so the newest output is visible.
|
|
110
|
+
const [scrollResetToken, setScrollResetToken] = useState(0);
|
|
103
111
|
const [exitPending, setExitPending] = useState(false);
|
|
104
112
|
const [quittingSummary, setQuittingSummary] = useState(null);
|
|
105
113
|
// Terminal title — updated later after agentLoop is created
|
|
@@ -204,6 +212,8 @@ export function App(props) {
|
|
|
204
212
|
const persistedIndexRef = useRef(messagesRef.current.length);
|
|
205
213
|
const sessionStatsRef = useRef(props.sessionStore?.sessionStats ??
|
|
206
214
|
createSessionStats({ sessionId: props.sessionStore?.sessionId ?? props.sessionId }));
|
|
215
|
+
const [idealReviewEnabled, setIdealReviewEnabled] = useState(props.sessionStore?.idealReviewEnabled ?? props.idealReviewEnabled ?? true);
|
|
216
|
+
const idealReviewEnabledRef = useRef(idealReviewEnabled);
|
|
207
217
|
/** Last actual API-reported input token count (from turn_end). */
|
|
208
218
|
const lastActualTokensRef = useRef(0);
|
|
209
219
|
/** Timestamp (ms) when lastActualTokensRef was last updated by turn_end. */
|
|
@@ -235,6 +245,11 @@ export function App(props) {
|
|
|
235
245
|
const appendGoalProgress = useCallback((item) => {
|
|
236
246
|
setLiveItems((prev) => appendGoalProgressDraft(prev, item, getId));
|
|
237
247
|
}, []);
|
|
248
|
+
useEffect(() => {
|
|
249
|
+
idealReviewEnabledRef.current = idealReviewEnabled;
|
|
250
|
+
if (props.sessionStore)
|
|
251
|
+
props.sessionStore.idealReviewEnabled = idealReviewEnabled;
|
|
252
|
+
}, [idealReviewEnabled, props.sessionStore]);
|
|
238
253
|
const goalNumberForRun = useCallback((runId) => Math.max(1, goalStatusEntries.findIndex((entry) => entry.runId === runId) + 1), [goalStatusEntries]);
|
|
239
254
|
const clearGoalStatusEntry = useCallback((runId) => {
|
|
240
255
|
setGoalStatusEntries((prev) => {
|
|
@@ -271,7 +286,12 @@ export function App(props) {
|
|
|
271
286
|
queuedGoalSyntheticEventsRef,
|
|
272
287
|
});
|
|
273
288
|
const { pendingHistoryFlushRef, streamedAssistantFlushRef, queueFlush, finalizeSubmittedUserItem, clearPendingHistory, } = useTranscriptHistory({
|
|
274
|
-
|
|
289
|
+
// In fullscreen alt-screen mode the transcript renders inside Ink (the
|
|
290
|
+
// viewport), so we must NOT write completed rows to native scrollback —
|
|
291
|
+
// doing so would scroll the live frame. Dropping the printer keeps history
|
|
292
|
+
// accumulating in React state (still flushed + persisted) without any
|
|
293
|
+
// stdout writes. The legacy scrollback path keeps the printer.
|
|
294
|
+
terminalHistoryPrinter: props.fullscreen ? undefined : props.terminalHistoryPrinter,
|
|
275
295
|
terminalHistoryContext: {
|
|
276
296
|
theme,
|
|
277
297
|
columns,
|
|
@@ -636,6 +656,22 @@ export function App(props) {
|
|
|
636
656
|
projectId: activeProjectId,
|
|
637
657
|
resolveCredentials,
|
|
638
658
|
transformContext,
|
|
659
|
+
getIdealReviewMessage: (stats) => {
|
|
660
|
+
if (!idealReviewEnabledRef.current)
|
|
661
|
+
return null;
|
|
662
|
+
const decision = evaluateIdealReview(stats);
|
|
663
|
+
if (!decision.shouldReview)
|
|
664
|
+
return null;
|
|
665
|
+
log("INFO", "ideal", "Injecting ideal review before final response", {
|
|
666
|
+
score: String(decision.score),
|
|
667
|
+
reasons: decision.reasons.join(", "),
|
|
668
|
+
});
|
|
669
|
+
setLiveItems((prev) => [
|
|
670
|
+
...prev,
|
|
671
|
+
{ kind: "ideal_hook", text: IDEAL_HOOK_NOTICE_TEXT, id: getId() },
|
|
672
|
+
]);
|
|
673
|
+
return buildIdealReviewMessage(decision.reasons);
|
|
674
|
+
},
|
|
639
675
|
}, {
|
|
640
676
|
onComplete: useCallback(() => {
|
|
641
677
|
persistNewMessages();
|
|
@@ -1155,15 +1191,14 @@ export function App(props) {
|
|
|
1155
1191
|
setDoneStatus({ durationMs, toolsUsed, verb: pickDurationVerb(toolsUsed) });
|
|
1156
1192
|
playNotificationSound();
|
|
1157
1193
|
}
|
|
1158
|
-
//
|
|
1159
|
-
//
|
|
1160
|
-
//
|
|
1161
|
-
//
|
|
1162
|
-
//
|
|
1163
|
-
//
|
|
1164
|
-
//
|
|
1165
|
-
|
|
1166
|
-
if (doneDecision.flushLiveItems) {
|
|
1194
|
+
// Keep the final assistant response mounted in the live frame after a
|
|
1195
|
+
// normal chat turn finishes. Moving a large final response to terminal
|
|
1196
|
+
// history at this moment writes many scrollback rows while the footer is
|
|
1197
|
+
// still mounted, which visibly pushes the input/footer upward. The final
|
|
1198
|
+
// response is flushed on the next submit before the new prompt is shown.
|
|
1199
|
+
// Non-chat overlay transitions still flush so setup/plan/goal output
|
|
1200
|
+
// does not vanish during remounts.
|
|
1201
|
+
if (doneDecision.flushLiveItems && !doneDecision.showDoneStatus) {
|
|
1167
1202
|
setLiveItems((prev) => {
|
|
1168
1203
|
if (prev.length > 0)
|
|
1169
1204
|
queueFlush(prev);
|
|
@@ -1506,6 +1541,26 @@ export function App(props) {
|
|
|
1506
1541
|
// has not grown.
|
|
1507
1542
|
await applyLanguageDetectionRef.current("input");
|
|
1508
1543
|
}
|
|
1544
|
+
if (trimmed === "/ideal-on" || trimmed === "/ideal-off") {
|
|
1545
|
+
const next = trimmed === "/ideal-on";
|
|
1546
|
+
setIdealReviewEnabled(next);
|
|
1547
|
+
if (props.settingsFile) {
|
|
1548
|
+
const sm = new SettingsManager(props.settingsFile);
|
|
1549
|
+
await sm.load();
|
|
1550
|
+
await sm.set("idealReviewEnabled", next);
|
|
1551
|
+
}
|
|
1552
|
+
setLiveItems((prev) => [
|
|
1553
|
+
...prev,
|
|
1554
|
+
{
|
|
1555
|
+
kind: "info",
|
|
1556
|
+
text: next
|
|
1557
|
+
? "Ideal review enabled. Use /ideal-off to disable it."
|
|
1558
|
+
: "Ideal review disabled. Use /ideal-on to enable it.",
|
|
1559
|
+
id: getId(),
|
|
1560
|
+
},
|
|
1561
|
+
]);
|
|
1562
|
+
return;
|
|
1563
|
+
}
|
|
1509
1564
|
// /rewind — open the checkpoint picker (needs React state + the store).
|
|
1510
1565
|
if (trimmed === "/rewind") {
|
|
1511
1566
|
const store = props.checkpointStore;
|
|
@@ -1684,6 +1739,7 @@ export function App(props) {
|
|
|
1684
1739
|
id: getId(),
|
|
1685
1740
|
};
|
|
1686
1741
|
setLastUserMessage(input);
|
|
1742
|
+
setScrollResetToken((token) => token + 1);
|
|
1687
1743
|
setDoneStatus(null);
|
|
1688
1744
|
// Clear stale plan progress if there's no active approved plan
|
|
1689
1745
|
// (avoids lingering progress from a completed or abandoned plan run)
|
|
@@ -1691,7 +1747,7 @@ export function App(props) {
|
|
|
1691
1747
|
planStepsRef.current = [];
|
|
1692
1748
|
setPlanSteps([]);
|
|
1693
1749
|
}
|
|
1694
|
-
finalizeSubmittedUserItem(userItem);
|
|
1750
|
+
finalizeSubmittedUserItem(userItem, liveItems);
|
|
1695
1751
|
// Open a per-turn checkpoint capturing the conversation position right
|
|
1696
1752
|
// before this exchange, so /rewind can restore pre-turn code/chat state.
|
|
1697
1753
|
if (props.checkpointStore) {
|
|
@@ -1724,6 +1780,7 @@ export function App(props) {
|
|
|
1724
1780
|
compactConversation,
|
|
1725
1781
|
currentModel,
|
|
1726
1782
|
finalizeSubmittedUserItem,
|
|
1783
|
+
liveItems,
|
|
1727
1784
|
props.cwd,
|
|
1728
1785
|
props.onSlashCommand,
|
|
1729
1786
|
props.resetUI,
|
|
@@ -1915,6 +1972,14 @@ export function App(props) {
|
|
|
1915
1972
|
{ name: "compact", aliases: ["c"], description: "Compact context", sectionTitle: "built-in" },
|
|
1916
1973
|
{ name: "clear", aliases: [], description: "Clear session", sectionTitle: "built-in" },
|
|
1917
1974
|
{ name: "theme", aliases: ["t"], description: "Switch theme", sectionTitle: "built-in" },
|
|
1975
|
+
{
|
|
1976
|
+
name: idealReviewEnabled ? "ideal-off" : "ideal-on",
|
|
1977
|
+
aliases: [],
|
|
1978
|
+
description: idealReviewEnabled
|
|
1979
|
+
? "Disable pre-final ideal review"
|
|
1980
|
+
: "Enable pre-final ideal review",
|
|
1981
|
+
sectionTitle: "built-in",
|
|
1982
|
+
},
|
|
1918
1983
|
{
|
|
1919
1984
|
name: "rewind",
|
|
1920
1985
|
aliases: [],
|
|
@@ -1936,13 +2001,13 @@ export function App(props) {
|
|
|
1936
2001
|
sectionTitle: "built-in",
|
|
1937
2002
|
},
|
|
1938
2003
|
];
|
|
1939
|
-
}, [customCommands]);
|
|
2004
|
+
}, [customCommands, idealReviewEnabled]);
|
|
1940
2005
|
const renderItem = (item, index, items) => renderTranscriptItem({
|
|
1941
2006
|
item,
|
|
1942
2007
|
index,
|
|
1943
2008
|
items,
|
|
1944
|
-
pendingHistoryFlushLastItem: pendingHistoryFlushRef.current.at(-1),
|
|
1945
|
-
historyLastItem: history.at(-1),
|
|
2009
|
+
pendingHistoryFlushLastItem: index === 0 ? pendingHistoryFlushRef.current.at(-1) : undefined,
|
|
2010
|
+
historyLastItem: index === 0 ? history.at(-1) : undefined,
|
|
1946
2011
|
version: props.version,
|
|
1947
2012
|
currentModel,
|
|
1948
2013
|
currentProvider,
|
|
@@ -2052,7 +2117,7 @@ export function App(props) {
|
|
|
2052
2117
|
});
|
|
2053
2118
|
const isSkillsView = overlay === "skills";
|
|
2054
2119
|
const isPlanView = overlay === "plan";
|
|
2055
|
-
const { footerStatusLayout, activityVisible, stallStatusVisible, statusSlotVisible, mainControlsRef, measuredLiveAreaRows, } = useChatLayoutMeasurements({
|
|
2120
|
+
const { footerStatusLayout, activityVisible, stallStatusVisible, statusSlotVisible, mainControlsRef, measuredLiveAreaRows, viewportRows, } = useChatLayoutMeasurements({
|
|
2056
2121
|
rows,
|
|
2057
2122
|
columns,
|
|
2058
2123
|
backgroundTaskCount: bgTasks.length,
|
|
@@ -2129,6 +2194,54 @@ export function App(props) {
|
|
|
2129
2194
|
// mid-stream, the live remainder is the next paragraph — re-insert the blank
|
|
2130
2195
|
// line that separated them so the live tail lines up with the flushed history.
|
|
2131
2196
|
const streamingContinuesFlushed = streamedAssistantFlushRef.current.flushedChars > 0;
|
|
2197
|
+
// ── Fullscreen alt-screen transcript ───────────────────
|
|
2198
|
+
// Flatten history + live items + in-flight streaming into the flat ANSI line
|
|
2199
|
+
// buffer the viewport renders. Reuses the same serializer the legacy
|
|
2200
|
+
// scrollback printer used, so the transcript looks identical. Only computed
|
|
2201
|
+
// when fullscreen is active (the legacy path renders items through Ink).
|
|
2202
|
+
const transcriptContext = useMemo(() => ({
|
|
2203
|
+
theme,
|
|
2204
|
+
columns,
|
|
2205
|
+
version: props.version,
|
|
2206
|
+
model: currentModel,
|
|
2207
|
+
provider: currentProvider,
|
|
2208
|
+
cwd: displayedCwd,
|
|
2209
|
+
}), [theme, columns, props.version, currentModel, currentProvider, displayedCwd]);
|
|
2210
|
+
const transcriptLines = useMemo(() => {
|
|
2211
|
+
if (!props.fullscreen)
|
|
2212
|
+
return [];
|
|
2213
|
+
const items = [...history, ...uniqueItemsById(liveItems)];
|
|
2214
|
+
const hasStreaming = visibleStreamingText.length > 0 || agentLoop.streamingThinking.length > 0;
|
|
2215
|
+
if (hasStreaming) {
|
|
2216
|
+
items.push({
|
|
2217
|
+
kind: "assistant",
|
|
2218
|
+
text: visibleStreamingText,
|
|
2219
|
+
thinking: agentLoop.streamingThinking,
|
|
2220
|
+
thinkingMs: agentLoop.thinkingMs,
|
|
2221
|
+
continuation: streamingContinuesFlushed,
|
|
2222
|
+
id: "__streaming__",
|
|
2223
|
+
});
|
|
2224
|
+
}
|
|
2225
|
+
return buildTranscriptLines(items, transcriptContext);
|
|
2226
|
+
}, [
|
|
2227
|
+
props.fullscreen,
|
|
2228
|
+
history,
|
|
2229
|
+
liveItems,
|
|
2230
|
+
visibleStreamingText,
|
|
2231
|
+
agentLoop.streamingThinking,
|
|
2232
|
+
agentLoop.thinkingMs,
|
|
2233
|
+
streamingContinuesFlushed,
|
|
2234
|
+
transcriptContext,
|
|
2235
|
+
]);
|
|
2236
|
+
// Keyboard + bounds controller. The offset itself lives in the external
|
|
2237
|
+
// transcript-scroll store; the viewport subscribes to it directly so scroll
|
|
2238
|
+
// re-renders only the viewport, not this whole component.
|
|
2239
|
+
useTranscriptScroll({
|
|
2240
|
+
totalLines: transcriptLines.length,
|
|
2241
|
+
viewportRows,
|
|
2242
|
+
active: !!props.fullscreen && !overlay && !taskBarFocused,
|
|
2243
|
+
resetToken: scrollResetToken,
|
|
2244
|
+
});
|
|
2132
2245
|
const visibleQueuedCount = liveItems.filter((item) => item.kind === "queued").length;
|
|
2133
2246
|
const hiddenQueuedCount = Math.max(0, agentLoop.queuedCount - visibleQueuedCount);
|
|
2134
2247
|
const shouldTopSpaceQueueIndicator = hiddenQueuedCount > 0 &&
|
|
@@ -2427,7 +2540,7 @@ export function App(props) {
|
|
|
2427
2540
|
if (quittingSummary) {
|
|
2428
2541
|
return (_jsx(Box, { flexDirection: "column", width: columns, flexShrink: 0, flexGrow: 0, children: _jsx(SessionSummaryDisplay, { summary: quittingSummary }) }));
|
|
2429
2542
|
}
|
|
2430
|
-
return (_jsx(Box, { flexDirection: "column", width: columns, flexShrink: 0, flexGrow: 0, children: rewindCheckpoints ? (_jsx(RewindOverlay, { checkpoints: rewindCheckpoints, onRestore: handleRewindRestore, onCancel: handleRewindCancel })) : fullScreenOverlay ? (_jsx(FullScreenOverlayRouter, { overlay: fullScreenOverlay, version: props.version, cwd: props.cwd, agentRunning: agentLoop.isRunning, planAutoExpand: planAutoExpand, onClosePixel: handleCloseRemountableOverlay, onPixelFixOne: handlePixelFixOne, onPixelFixAll: handlePixelFixAll, onCloseSkills: handleCloseRemountableOverlay, onClosePlan: handleClosePlanOverlay, onApprovePlan: handleApprovePlan, onRejectPlan: handleRejectPlan })) : (_jsx(ChatScreen, { columns: columns, liveItems: uniqueItemsById(liveItems), renderItem: renderItem, isRunning: agentLoop.isRunning, visibleStreamingText: visibleStreamingText, streamingThinking: agentLoop.streamingThinking, thinkingMs: agentLoop.thinkingMs, reserveStreamingSpacing: shouldReserveStreamingSpacing, renderMarkdown: renderMarkdown, measuredLiveAreaRows: measuredLiveAreaRows, assistantMarginTop: shouldTopSpaceStreamingText || streamingContinuesFlushed ? 1 : 0, streamingContinuation: streamingContinuesFlushed, controlsRef: mainControlsRef, hiddenQueuedCount: hiddenQueuedCount, queueIndicatorMarginTop: shouldTopSpaceQueueIndicator ? 2 : 1, theme: theme, statusSlotVisible: statusSlotVisible, activityVisible: activityVisible, stallStatusVisible: stallStatusVisible, doneStatus: doneStatus, activityPhase: agentLoop.activityPhase, elapsedMs: agentLoop.elapsedMs, runStartRef: agentLoop.runStartRef, isThinking: agentLoop.isThinking, thinkingLevel: thinkingLevel, tokenEstimate: agentLoop.streamedTokenEstimate, charCountRef: agentLoop.charCountRef, realTokensAccumRef: agentLoop.realTokensAccumRef, lastUserMessage: lastUserMessage, activeToolNames: agentLoop.activeToolCalls.map((tc) => tc.name), retryInfo: agentLoop.retryInfo, planDone: planSteps.filter((s) => s.completed).length, planTotal: planSteps.length, formatDuration: formatDuration, inputControls: {
|
|
2543
|
+
return (_jsx(Box, { flexDirection: "column", width: columns, flexShrink: 0, flexGrow: 0, children: rewindCheckpoints ? (_jsx(RewindOverlay, { checkpoints: rewindCheckpoints, onRestore: handleRewindRestore, onCancel: handleRewindCancel })) : fullScreenOverlay ? (_jsx(FullScreenOverlayRouter, { overlay: fullScreenOverlay, version: props.version, cwd: props.cwd, agentRunning: agentLoop.isRunning, planAutoExpand: planAutoExpand, onClosePixel: handleCloseRemountableOverlay, onPixelFixOne: handlePixelFixOne, onPixelFixAll: handlePixelFixAll, onCloseSkills: handleCloseRemountableOverlay, onClosePlan: handleClosePlanOverlay, onApprovePlan: handleApprovePlan, onRejectPlan: handleRejectPlan })) : (_jsx(ChatScreen, { columns: columns, liveItems: uniqueItemsById(liveItems), renderItem: renderItem, isRunning: agentLoop.isRunning, visibleStreamingText: visibleStreamingText, streamingThinking: agentLoop.streamingThinking, thinkingMs: agentLoop.thinkingMs, reserveStreamingSpacing: shouldReserveStreamingSpacing, renderMarkdown: renderMarkdown, measuredLiveAreaRows: measuredLiveAreaRows, fullscreen: props.fullscreen, rows: rows, transcriptLines: transcriptLines, viewportRows: viewportRows, assistantMarginTop: shouldTopSpaceStreamingText || streamingContinuesFlushed ? 1 : 0, streamingContinuation: streamingContinuesFlushed, controlsRef: mainControlsRef, hiddenQueuedCount: hiddenQueuedCount, queueIndicatorMarginTop: shouldTopSpaceQueueIndicator ? 2 : 1, theme: theme, statusSlotVisible: statusSlotVisible, activityVisible: activityVisible, stallStatusVisible: stallStatusVisible, doneStatus: doneStatus, activityPhase: agentLoop.activityPhase, elapsedMs: agentLoop.elapsedMs, runStartRef: agentLoop.runStartRef, isThinking: agentLoop.isThinking, thinkingLevel: thinkingLevel, tokenEstimate: agentLoop.streamedTokenEstimate, charCountRef: agentLoop.charCountRef, realTokensAccumRef: agentLoop.realTokensAccumRef, lastUserMessage: lastUserMessage, activeToolNames: agentLoop.activeToolCalls.map((tc) => tc.name), retryInfo: agentLoop.retryInfo, planDone: planSteps.filter((s) => s.completed).length, planTotal: planSteps.length, formatDuration: formatDuration, inputControls: {
|
|
2431
2544
|
onSubmit: handleSubmit,
|
|
2432
2545
|
onAbort: handleAbort,
|
|
2433
2546
|
injectText: composerInject,
|
|
@@ -2441,6 +2554,8 @@ export function App(props) {
|
|
|
2441
2554
|
onToggleMarkdown: () => setRenderMarkdown((prev) => !prev),
|
|
2442
2555
|
cwd: props.cwd,
|
|
2443
2556
|
commands: allCommands,
|
|
2557
|
+
mouseScroll: props.fullscreen,
|
|
2558
|
+
onScroll: scrollTranscriptByLines,
|
|
2444
2559
|
}, taskPicker: {
|
|
2445
2560
|
open: taskPicker.open,
|
|
2446
2561
|
tasks: taskPicker.tasks,
|