| author | |
| committer | |
| log | 3583cd27dccda1b35fe80d9411a95a7217cc8176 |
| tree | c74afae1579278f99e783f3fe9f8f9396cd221ce |
| parent | 27732293373fbb081a966b437ae022afe77db16b |
| signature | Signed by PGP key B5690EEEBB952194 |
9 files changed, 9 insertions(+), 87 deletions(-)
apps/mobile/src/features/terminal/terminalLaunchContext.test.ts+1-9| ... | @@ -2,7 +2,6 @@ import { describe, expect, it } from "vite-plus/test"; | ... | @@ -2,7 +2,6 @@ import { describe, expect, it } from "vite-plus/test"; |
| 2 | import { EnvironmentId, ThreadId } from "@t3tools/contracts"; | 2 | import { EnvironmentId, ThreadId } from "@t3tools/contracts"; |
| 3 | 3 | ||
| 4 | import { | 4 | import { |
| 5 | peekPendingTerminalLaunch, | ||
| 6 | resolvePreferredThreadWorktreePath, | 5 | resolvePreferredThreadWorktreePath, |
| 7 | resolveTerminalOpenLocation, | 6 | resolveTerminalOpenLocation, |
| 8 | stagePendingTerminalLaunch, | 7 | stagePendingTerminalLaunch, |
| ... | @@ -82,19 +81,13 @@ describe("pending terminal launches", () => { | ... | @@ -82,19 +81,13 @@ describe("pending terminal launches", () => { |
| 82 | }, | 81 | }, |
| 83 | }); | 82 | }); |
| 84 | 83 | ||
| 85 | expect(peekPendingTerminalLaunch(target)).toEqual({ | ||
| 86 | cwd: "/repo/worktrees/feature", | ||
| 87 | worktreePath: "/repo/worktrees/feature", | ||
| 88 | env: { FOO: "bar" }, | ||
| 89 | initialInput: "pnpm dev\r", | ||
| 90 | }); | ||
| 91 | expect(takePendingTerminalLaunch(target)).toEqual({ | 84 | expect(takePendingTerminalLaunch(target)).toEqual({ |
| 92 | cwd: "/repo/worktrees/feature", | 85 | cwd: "/repo/worktrees/feature", |
| 93 | worktreePath: "/repo/worktrees/feature", | 86 | worktreePath: "/repo/worktrees/feature", |
| 94 | env: { FOO: "bar" }, | 87 | env: { FOO: "bar" }, |
| 95 | initialInput: "pnpm dev\r", | 88 | initialInput: "pnpm dev\r", |
| 96 | }); | 89 | }); |
| 97 | expect(peekPendingTerminalLaunch(target)).toBeNull(); | 90 | expect(takePendingTerminalLaunch(target)).toBeNull(); |
| 98 | }); | 91 | }); |
| 99 | 92 | ||
| 100 | it("keeps pending launches isolated per terminal target", () => { | 93 | it("keeps pending launches isolated per terminal target", () => { |
| ... | @@ -118,7 +111,6 @@ describe("pending terminal launches", () => { | ... | @@ -118,7 +111,6 @@ describe("pending terminal launches", () => { |
| 118 | }, | 111 | }, |
| 119 | }); | 112 | }); |
| 120 | 113 | ||
| 121 | expect(peekPendingTerminalLaunch(otherTarget)).toBeNull(); | ||
| 122 | expect(takePendingTerminalLaunch(otherTarget)).toBeNull(); | 114 | expect(takePendingTerminalLaunch(otherTarget)).toBeNull(); |
| 123 | expect(takePendingTerminalLaunch(primaryTarget)).toEqual({ | 115 | expect(takePendingTerminalLaunch(primaryTarget)).toEqual({ |
| 124 | cwd: "/repo/root", | 116 | cwd: "/repo/root", |
apps/mobile/src/features/terminal/terminalLaunchContext.ts-6| ... | @@ -36,12 +36,6 @@ export function stagePendingTerminalLaunch(input: { | ... | @@ -36,12 +36,6 @@ export function stagePendingTerminalLaunch(input: { |
| 36 | }); | 36 | }); |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | export function peekPendingTerminalLaunch( | ||
| 40 | target: PendingTerminalLaunchTarget, | ||
| 41 | ): PendingTerminalLaunch | null { | ||
| 42 | return pendingTerminalLaunches.get(pendingTerminalLaunchKey(target)) ?? null; | ||
| 43 | } | ||
| 44 | |||
| 45 | export function takePendingTerminalLaunch( | 39 | export function takePendingTerminalLaunch( |
| 46 | target: PendingTerminalLaunchTarget, | 40 | target: PendingTerminalLaunchTarget, |
| 47 | ): PendingTerminalLaunch | null { | 41 | ): PendingTerminalLaunch | null { |
apps/mobile/src/features/terminal/threadTerminalPanelModel.test.ts deleted-40| ... | @@ -1,40 +0,0 @@ | ||
| 1 | import { EnvironmentId, ThreadId } from "@t3tools/contracts"; | ||
| 2 | import { describe, expect, it } from "vite-plus/test"; | ||
| 3 | |||
| 4 | import { | ||
| 5 | buildThreadTerminalAttachInput, | ||
| 6 | threadTerminalSubscriptionKey, | ||
| 7 | type ThreadTerminalSubscriptionIdentity, | ||
| 8 | } from "./threadTerminalPanelModel"; | ||
| 9 | |||
| 10 | const identity: ThreadTerminalSubscriptionIdentity = { | ||
| 11 | environmentId: EnvironmentId.make("env-1"), | ||
| 12 | threadId: ThreadId.make("thread-1"), | ||
| 13 | terminalId: "default", | ||
| 14 | cwd: "/repo", | ||
| 15 | worktreePath: "/repo", | ||
| 16 | }; | ||
| 17 | |||
| 18 | describe("threadTerminalSubscriptionKey", () => { | ||
| 19 | it("does not include mutable terminal dimensions", () => { | ||
| 20 | const initialAttach = buildThreadTerminalAttachInput(identity, { cols: 80, rows: 24 }); | ||
| 21 | const resizedAttach = buildThreadTerminalAttachInput(identity, { cols: 132, rows: 40 }); | ||
| 22 | |||
| 23 | expect(initialAttach).not.toEqual(resizedAttach); | ||
| 24 | expect(threadTerminalSubscriptionKey({ ...identity, ...initialAttach })).toBe( | ||
| 25 | threadTerminalSubscriptionKey({ ...identity, ...resizedAttach }), | ||
| 26 | ); | ||
| 27 | }); | ||
| 28 | |||
| 29 | it.each([ | ||
| 30 | ["environment", { environmentId: EnvironmentId.make("env-2") }], | ||
| 31 | ["thread", { threadId: ThreadId.make("thread-2") }], | ||
| 32 | ["terminal", { terminalId: "term-2" }], | ||
| 33 | ["cwd", { cwd: "/repo/packages/app" }], | ||
| 34 | ["worktree", { worktreePath: "/repo/worktrees/feature" }], | ||
| 35 | ])("changes when the %s identity changes", (_label, update) => { | ||
| 36 | expect(threadTerminalSubscriptionKey({ ...identity, ...update })).not.toBe( | ||
| 37 | threadTerminalSubscriptionKey(identity), | ||
| 38 | ); | ||
| 39 | }); | ||
| 40 | }); | ||
apps/mobile/src/features/terminal/threadTerminalPanelModel.ts-12| ... | @@ -13,18 +13,6 @@ export interface TerminalGridSize { | ... | @@ -13,18 +13,6 @@ export interface TerminalGridSize { |
| 13 | readonly rows: number; | 13 | readonly rows: number; |
| 14 | } | 14 | } |
| 15 | 15 | ||
| 16 | export function threadTerminalSubscriptionKey( | ||
| 17 | identity: ThreadTerminalSubscriptionIdentity, | ||
| 18 | ): string { | ||
| 19 | return JSON.stringify([ | ||
| 20 | identity.environmentId, | ||
| 21 | identity.threadId, | ||
| 22 | identity.terminalId, | ||
| 23 | identity.cwd, | ||
| 24 | identity.worktreePath, | ||
| 25 | ]); | ||
| 26 | } | ||
| 27 | |||
| 28 | export function buildThreadTerminalAttachInput( | 16 | export function buildThreadTerminalAttachInput( |
| 29 | identity: ThreadTerminalSubscriptionIdentity, | 17 | identity: ThreadTerminalSubscriptionIdentity, |
| 30 | gridSize: TerminalGridSize, | 18 | gridSize: TerminalGridSize, |
apps/web/src/components/chat/MessagesTimeline.test.tsx+1-7| ... | @@ -134,7 +134,6 @@ function matchMedia() { | ... | @@ -134,7 +134,6 @@ function matchMedia() { |
| 134 | } | 134 | } |
| 135 | 135 | ||
| 136 | let MessagesTimeline: typeof import("./MessagesTimeline").MessagesTimeline; | 136 | let MessagesTimeline: typeof import("./MessagesTimeline").MessagesTimeline; |
| 137 | let toolCallExpandedBodyClassName: typeof import("./MessagesTimeline").toolCallExpandedBodyClassName; | ||
| 138 | 137 | ||
| 139 | beforeAll(async () => { | 138 | beforeAll(async () => { |
| 140 | const classList = { | 139 | const classList = { |
| ... | @@ -168,7 +167,7 @@ beforeAll(async () => { | ... | @@ -168,7 +167,7 @@ beforeAll(async () => { |
| 168 | }, | 167 | }, |
| 169 | }); | 168 | }); |
| 170 | 169 | ||
| 171 | ({ MessagesTimeline, toolCallExpandedBodyClassName } = await import("./MessagesTimeline")); | 170 | ({ MessagesTimeline } = await import("./MessagesTimeline")); |
| 172 | }, 30_000); | 171 | }, 30_000); |
| 173 | 172 | ||
| 174 | const ACTIVE_THREAD_ENVIRONMENT_ID = EnvironmentId.make("environment-local"); | 173 | const ACTIVE_THREAD_ENVIRONMENT_ID = EnvironmentId.make("environment-local"); |
| ... | @@ -238,11 +237,6 @@ function buildAssistantTimelineEntry(text: string) { | ... | @@ -238,11 +237,6 @@ function buildAssistantTimelineEntry(text: string) { |
| 238 | } | 237 | } |
| 239 | 238 | ||
| 240 | describe("MessagesTimeline", () => { | 239 | describe("MessagesTimeline", () => { |
| 241 | it("sizes expanded tool details with the configured code font size", () => { | ||
| 242 | expect(toolCallExpandedBodyClassName).toContain("var(--font-size-code"); | ||
| 243 | expect(toolCallExpandedBodyClassName).not.toContain("text-[11px]"); | ||
| 244 | }); | ||
| 245 | |||
| 246 | it("uses the larger leading inset only when the top fade is enabled", () => { | 240 | it("uses the larger leading inset only when the top fade is enabled", () => { |
| 247 | const timelineEntries = [buildUserTimelineEntry("Hello")]; | 241 | const timelineEntries = [buildUserTimelineEntry("Hello")]; |
| 248 | 242 |
apps/web/src/components/chat/MessagesTimeline.tsx+1-1| ... | @@ -2063,7 +2063,7 @@ function buildToolCallExpandedBody( | ... | @@ -2063,7 +2063,7 @@ function buildToolCallExpandedBody( |
| 2063 | return blocks.length > 0 ? blocks.join("\n\n") : null; | 2063 | return blocks.length > 0 ? blocks.join("\n\n") : null; |
| 2064 | } | 2064 | } |
| 2065 | 2065 | ||
| 2066 | export const toolCallExpandedBodyClassName = | 2066 | const toolCallExpandedBodyClassName = |
| 2067 | "max-h-64 cursor-text overflow-auto whitespace-pre-wrap break-words font-mono text-secondary-label text-[length:var(--font-size-code,0.6875rem)] leading-relaxed select-text"; | 2067 | "max-h-64 cursor-text overflow-auto whitespace-pre-wrap break-words font-mono text-secondary-label text-[length:var(--font-size-code,0.6875rem)] leading-relaxed select-text"; |
| 2068 | 2068 | ||
| 2069 | function workEntryIconName(workEntry: TimelineWorkEntry): WorkEntryIconName { | 2069 | function workEntryIconName(workEntry: TimelineWorkEntry): WorkEntryIconName { |
apps/web/src/components/composerFooterLayout.test.ts+5-8| ... | @@ -3,7 +3,6 @@ import { describe, expect, it } from "vite-plus/test"; | ... | @@ -3,7 +3,6 @@ import { describe, expect, it } from "vite-plus/test"; |
| 3 | import { | 3 | import { |
| 4 | COMPOSER_FOOTER_COMPACT_BREAKPOINT_PX, | 4 | COMPOSER_FOOTER_COMPACT_BREAKPOINT_PX, |
| 5 | COMPOSER_FOOTER_WIDE_ACTIONS_COMPACT_BREAKPOINT_PX, | 5 | COMPOSER_FOOTER_WIDE_ACTIONS_COMPACT_BREAKPOINT_PX, |
| 6 | COMPOSER_PRIMARY_ACTIONS_COMPACT_BREAKPOINT_PX, | ||
| 7 | shouldUseCompactComposerPrimaryActions, | 6 | shouldUseCompactComposerPrimaryActions, |
| 8 | shouldUseCompactComposerFooter, | 7 | shouldUseCompactComposerFooter, |
| 9 | } from "./composerFooterLayout"; | 8 | } from "./composerFooterLayout"; |
| ... | @@ -38,16 +37,14 @@ describe("shouldUseCompactComposerFooter", () => { | ... | @@ -38,16 +37,14 @@ describe("shouldUseCompactComposerFooter", () => { |
| 38 | 37 | ||
| 39 | describe("shouldUseCompactComposerPrimaryActions", () => { | 38 | describe("shouldUseCompactComposerPrimaryActions", () => { |
| 40 | it("matches the wide footer breakpoint", () => { | 39 | it("matches the wide footer breakpoint", () => { |
| 41 | expect(COMPOSER_PRIMARY_ACTIONS_COMPACT_BREAKPOINT_PX).toBe( | ||
| 42 | COMPOSER_FOOTER_WIDE_ACTIONS_COMPACT_BREAKPOINT_PX, | ||
| 43 | ); | ||
| 44 | expect( | 40 | expect( |
| 45 | shouldUseCompactComposerPrimaryActions(COMPOSER_PRIMARY_ACTIONS_COMPACT_BREAKPOINT_PX - 1, { | 41 | shouldUseCompactComposerPrimaryActions( |
| 46 | hasWideActions: true, | 42 | COMPOSER_FOOTER_WIDE_ACTIONS_COMPACT_BREAKPOINT_PX - 1, |
| 47 | }), | 43 | { hasWideActions: true }, |
| 44 | ), | ||
| 48 | ).toBe(true); | 45 | ).toBe(true); |
| 49 | expect( | 46 | expect( |
| 50 | shouldUseCompactComposerPrimaryActions(COMPOSER_PRIMARY_ACTIONS_COMPACT_BREAKPOINT_PX, { | 47 | shouldUseCompactComposerPrimaryActions(COMPOSER_FOOTER_WIDE_ACTIONS_COMPACT_BREAKPOINT_PX, { |
| 51 | hasWideActions: true, | 48 | hasWideActions: true, |
| 52 | }), | 49 | }), |
| 53 | ).toBe(false); | 50 | ).toBe(false); |
apps/web/src/components/composerFooterLayout.ts+1-3| ... | @@ -1,7 +1,5 @@ | ... | @@ -1,7 +1,5 @@ |
| 1 | export const COMPOSER_FOOTER_COMPACT_BREAKPOINT_PX = 620; | 1 | export const COMPOSER_FOOTER_COMPACT_BREAKPOINT_PX = 620; |
| 2 | export const COMPOSER_FOOTER_WIDE_ACTIONS_COMPACT_BREAKPOINT_PX = 780; | 2 | export const COMPOSER_FOOTER_WIDE_ACTIONS_COMPACT_BREAKPOINT_PX = 780; |
| 3 | export const COMPOSER_PRIMARY_ACTIONS_COMPACT_BREAKPOINT_PX = | ||
| 4 | COMPOSER_FOOTER_WIDE_ACTIONS_COMPACT_BREAKPOINT_PX; | ||
| 5 | 3 | ||
| 6 | export function shouldUseCompactComposerFooter( | 4 | export function shouldUseCompactComposerFooter( |
| 7 | width: number | null, | 5 | width: number | null, |
| ... | @@ -20,5 +18,5 @@ export function shouldUseCompactComposerPrimaryActions( | ... | @@ -20,5 +18,5 @@ export function shouldUseCompactComposerPrimaryActions( |
| 20 | if (!options?.hasWideActions) { | 18 | if (!options?.hasWideActions) { |
| 21 | return false; | 19 | return false; |
| 22 | } | 20 | } |
| 23 | return width !== null && width < COMPOSER_PRIMARY_ACTIONS_COMPACT_BREAKPOINT_PX; | 21 | return width !== null && width < COMPOSER_FOOTER_WIDE_ACTIONS_COMPACT_BREAKPOINT_PX; |
| 24 | } | 22 | } |
packages/shared/src/terminalLabels.test.ts-1| ... | @@ -34,7 +34,6 @@ describe("resolveTerminalSessionLabel", () => { | ... | @@ -34,7 +34,6 @@ describe("resolveTerminalSessionLabel", () => { |
| 34 | describe("nextTerminalId", () => { | 34 | describe("nextTerminalId", () => { |
| 35 | it("allocates term-1 when no terminals are listed yet", () => { | 35 | it("allocates term-1 when no terminals are listed yet", () => { |
| 36 | expect(nextTerminalId([])).toBe(DEFAULT_TERMINAL_ID); | 36 | expect(nextTerminalId([])).toBe(DEFAULT_TERMINAL_ID); |
| 37 | expect(nextTerminalId([])).toBe("term-1"); | ||
| 38 | }); | 37 | }); |
| 39 | 38 | ||
| 40 | it("allocates term-2 when only term-1 exists", () => { | 39 | it("allocates term-2 when only term-1 exists", () => { |