Skip to content

Commit c6bb7ae

Browse files
committed
Merge remote-tracking branch 'origin/main' into fix/claude-adapter-live-catalog
Main moved root-request token usage into emitContextUsage, which still measured against the turn's model selection in the bundled catalog. It now takes the running process's compiled selection, as the compaction usage already does, so stream and assistant usage report the live catalog's window.
2 parents 48e6fb8 + d8e9fd2 commit c6bb7ae

604 files changed

Lines changed: 31032 additions & 10196 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.gitignore‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ dist-electron/
3333
.showcase/
3434
apps/mobile/.showcase/
3535
apps/mobile/.generated/
36+
apps/mobile/.android-cache/
3637
/.generated/
3738
artifacts/app-store/screenshots/
3839
.github/pr-assets/

‎apps/desktop/gnome-extension/metadata.json‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"uuid": "[email protected]",
33
"name": "T3 Code SnapShots",
44
"description": "Allows T3 Code to capture the focused window, identify it for optional accessibility text, and animate it into T3 Code. Disable this extension to revoke access.",
5-
"shell-version": ["45", "46", "47", "48", "49", "50"],
6-
"version": 2,
5+
"shell-version": ["45", "46", "47", "48", "49", "50", "51"],
6+
"version": 3,
77
"url": "https://github.com/pingdotgg/t3code"
88
}

‎apps/desktop/src/app/DesktopAppIdentity.test.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ const layerElectronApp = (calls: ElectronAppCalls) =>
4444
name: Effect.succeed("T3 Code"),
4545
systemLocale: Effect.succeed("en-US"),
4646
whenReady: Effect.void,
47+
requestSingleInstanceLock: Effect.succeed(true),
4748
quit: Effect.void,
4849
exit: () => Effect.void,
4950
relaunch: () => Effect.void,

‎apps/desktop/src/app/DesktopClerk.test.ts‎

Lines changed: 163 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,17 @@ import * as Effect from "effect/Effect";
1010
import * as Layer from "effect/Layer";
1111
import { beforeEach, vi } from "vite-plus/test";
1212

13-
const { createClerkBridgeMock, storageAdapter, storageMock } = vi.hoisted(() => ({
14-
createClerkBridgeMock: vi.fn(),
15-
storageAdapter: {
16-
getItem: vi.fn(),
17-
setItem: vi.fn(),
18-
removeItem: vi.fn(),
19-
},
20-
storageMock: vi.fn(),
21-
}));
13+
const { createClerkBridgeMock, requestSingleInstanceLockMock, storageAdapter, storageMock } =
14+
vi.hoisted(() => ({
15+
createClerkBridgeMock: vi.fn(),
16+
requestSingleInstanceLockMock: vi.fn(() => true),
17+
storageAdapter: {
18+
getItem: vi.fn(),
19+
setItem: vi.fn(),
20+
removeItem: vi.fn(),
21+
},
22+
storageMock: vi.fn(),
23+
}));
2224

2325
vi.mock("@clerk/electron", () => ({
2426
createClerkBridge: createClerkBridgeMock,
@@ -56,6 +58,7 @@ const layerDesktopClerk = (
5658
openSystemSettings: () => Effect.succeed(false),
5759
copyText: () => Effect.void,
5860
},
61+
listeners = new Map<string, (...args: unknown[]) => void>(),
5962
) => {
6063
const environment = DesktopEnvironment.DesktopEnvironment.of({
6164
stateDir: "/tmp/t3-state",
@@ -69,6 +72,24 @@ const layerDesktopClerk = (
6972
Effect.sync(() => {
7073
events.push(`setPath:${name}:${value}`);
7174
}),
75+
requestSingleInstanceLock: Effect.sync(() => {
76+
events.push("requestSingleInstanceLock");
77+
return requestSingleInstanceLockMock();
78+
}),
79+
quit: Effect.sync(() => {
80+
events.push("quit");
81+
}),
82+
on: (name: string, listener: (...args: unknown[]) => void) =>
83+
Effect.acquireRelease(
84+
Effect.sync(() => {
85+
events.push(`on:${name}`);
86+
listeners.set(name, listener);
87+
}),
88+
() =>
89+
Effect.sync(() => {
90+
listeners.delete(name);
91+
}),
92+
).pipe(Effect.asVoid),
7293
} as unknown as ElectronApp.ElectronApp["Service"];
7394

7495
return DesktopClerk.layer.pipe(
@@ -87,6 +108,7 @@ const layerDesktopClerk = (
87108
describe("DesktopClerk", () => {
88109
beforeEach(() => {
89110
createClerkBridgeMock.mockReset();
111+
requestSingleInstanceLockMock.mockReset().mockReturnValue(true);
90112
storageMock.mockReset();
91113
});
92114

@@ -106,22 +128,37 @@ describe("DesktopClerk", () => {
106128
[
107129
{
108130
storage: storageAdapter,
131+
manageSingleInstanceLock: false,
109132
passkeys: true,
110133
renderer: { scheme: "t3code-dev", host: "app" },
111134
},
112135
],
113136
]);
114137
assert.equal(cleanup.mock.calls.length, 1);
115-
// The bridge acquires Electron's single-instance lock at creation, and
116-
// the lock both lives in and creates the userData directory — so the
117-
// real path must be set before the bridge exists.
118-
assert.deepEqual(events, ["setPath:userData:/tmp/app-data/t3code-dev", "createClerkBridge"]);
138+
assert.deepEqual(events, [
139+
"setPath:userData:/tmp/app-data/t3code-dev",
140+
"requestSingleInstanceLock",
141+
"on:second-instance",
142+
"createClerkBridge",
143+
]);
119144
storageMock.mockClear();
120145
createClerkBridgeMock.mockClear();
121146
});
122147
});
123148

124149
it.each([
150+
{
151+
name: "packaged macOS",
152+
isDevelopment: false,
153+
platform: "darwin" as const,
154+
userData: "/tmp/app-data/t3code-v2",
155+
},
156+
{
157+
name: "packaged Linux",
158+
isDevelopment: false,
159+
platform: "linux" as const,
160+
userData: "/tmp/app-data/t3code-v2",
161+
},
125162
{
126163
name: "packaged Windows",
127164
isDevelopment: false,
@@ -152,7 +189,12 @@ describe("DesktopClerk", () => {
152189
),
153190
);
154191

155-
assert.deepEqual(events, [`setPath:userData:${userData}`, "createClerkBridge"]);
192+
assert.deepEqual(events, [
193+
`setPath:userData:${userData}`,
194+
"requestSingleInstanceLock",
195+
"on:second-instance",
196+
"createClerkBridge",
197+
]);
156198
},
157199
);
158200

@@ -204,63 +246,122 @@ describe("DesktopClerk", () => {
204246
});
205247
});
206248

207-
it.effect("registers the second-instance handler in the primary instance", () => {
208-
storageMock.mockReturnValue(storageAdapter);
209-
createClerkBridgeMock.mockReturnValue({ cleanup: vi.fn(), isPrimaryInstance: true });
210-
const quit = vi.fn();
211-
const registeredEvents: string[] = [];
212-
const electronApp = {
213-
quit: Effect.sync(quit),
214-
on: (eventName: string) =>
215-
Effect.sync(() => {
216-
registeredEvents.push(eventName);
217-
}),
218-
} as unknown as ElectronApp.ElectronApp["Service"];
219-
const electronWindow = {} as ElectronWindow.ElectronWindow["Service"];
249+
it.effect.each(["before configure", "after configure"] as const)(
250+
"reveals the running window when a second instance launches %s",
251+
(entry) => {
252+
storageMock.mockReturnValue(storageAdapter);
253+
createClerkBridgeMock.mockReturnValue({ cleanup: vi.fn(), isPrimaryInstance: true });
254+
const quit = vi.fn();
255+
const listeners = new Map<string, (...args: unknown[]) => void>();
256+
const revealed = Promise.withResolvers<unknown>();
257+
const window = { id: 1 };
258+
const electronApp = {
259+
quit: Effect.sync(quit),
260+
on: (eventName: string, listener: (...args: unknown[]) => void) =>
261+
Effect.sync(() => {
262+
listeners.set(eventName, listener);
263+
}),
264+
} as unknown as ElectronApp.ElectronApp["Service"];
265+
const electronWindow = {
266+
currentMainOrFirst: Effect.succeedSome(window),
267+
reveal: (value: unknown) => Effect.sync(() => revealed.resolve(value)),
268+
} as unknown as ElectronWindow.ElectronWindow["Service"];
220269

221-
return Effect.gen(function* () {
222-
const clerk = yield* DesktopClerk.DesktopClerk;
223-
const exit = yield* Effect.exit(Effect.scoped(clerk.configure));
270+
return Effect.gen(function* () {
271+
const clerk = yield* DesktopClerk.DesktopClerk;
272+
if (entry === "before configure") listeners.get("second-instance")?.({}, ["t3"]);
273+
yield* clerk.configure;
224274

225-
assert.isTrue(Exit.isSuccess(exit));
226-
assert.equal(quit.mock.calls.length, 0);
227-
assert.deepEqual(registeredEvents, ["open-url", "open-file", "second-instance"]);
228-
}).pipe(
229-
Effect.provide(layerDesktopClerk()),
230-
Effect.provideService(ElectronApp.ElectronApp, electronApp),
231-
Effect.provideService(ElectronWindow.ElectronWindow, electronWindow),
232-
Effect.provideService(DesktopWebLinks.DesktopWebLinks, ignoreWebLinks),
233-
);
234-
});
275+
assert.equal(quit.mock.calls.length, 0);
276+
if (entry === "after configure") listeners.get("second-instance")!({}, ["t3"]);
277+
assert.strictEqual(yield* Effect.promise(() => revealed.promise), window);
278+
}).pipe(
279+
Effect.scoped,
280+
Effect.provide(layerDesktopClerk(true, [], "darwin", undefined, undefined, listeners)),
281+
Effect.provideService(ElectronApp.ElectronApp, electronApp),
282+
Effect.provideService(ElectronWindow.ElectronWindow, electronWindow),
283+
Effect.provideService(DesktopWebLinks.DesktopWebLinks, ignoreWebLinks),
284+
);
285+
},
286+
);
235287

236-
it.effect("quits and interrupts startup in a secondary instance", () => {
288+
it.effect("delivers queued startup links and later links once in arrival order", () => {
237289
storageMock.mockReturnValue(storageAdapter);
238-
createClerkBridgeMock.mockReturnValue({ cleanup: vi.fn(), isPrimaryInstance: false });
239-
const quit = vi.fn();
240-
const registeredEvents: string[] = [];
290+
createClerkBridgeMock.mockReturnValue({ cleanup: vi.fn(), isPrimaryInstance: true });
291+
const listeners = new Map<string, (...args: unknown[]) => void>();
292+
const received: string[] = [];
293+
const first = "t3code://new?prompt=first";
294+
const second = "t3code://threads/env-1/thread-1";
295+
const later = "t3code://new?prompt=later";
296+
const delivered = Promise.withResolvers<void>();
241297
const electronApp = {
242-
quit: Effect.sync(quit),
243-
on: (eventName: string) =>
298+
on: (name: string, listener: (...args: unknown[]) => void) =>
244299
Effect.sync(() => {
245-
registeredEvents.push(eventName);
300+
listeners.set(name, listener);
246301
}),
247302
} as unknown as ElectronApp.ElectronApp["Service"];
248-
const electronWindow = {} as ElectronWindow.ElectronWindow["Service"];
249303

250304
return Effect.gen(function* () {
251305
const clerk = yield* DesktopClerk.DesktopClerk;
252-
const exit = yield* Effect.exit(Effect.scoped(clerk.configure));
306+
listeners.get("second-instance")?.({}, ["t3", first]);
307+
listeners.get("second-instance")?.({}, ["t3", second]);
308+
assert.deepEqual(received, []);
253309

254-
assert.isTrue(Exit.hasInterrupts(exit));
255-
assert.equal(quit.mock.calls.length, 1);
256-
assert.deepEqual(registeredEvents, []);
310+
yield* clerk.configure;
311+
listeners.get("second-instance")!({}, ["t3", later]);
312+
yield* Effect.promise(() => delivered.promise);
313+
314+
assert.deepEqual(received, [first, second, later]);
257315
}).pipe(
258-
Effect.provide(layerDesktopClerk()),
316+
Effect.scoped,
317+
Effect.provide(layerDesktopClerk(true, [], "darwin", undefined, undefined, listeners)),
259318
Effect.provideService(ElectronApp.ElectronApp, electronApp),
260-
Effect.provideService(ElectronWindow.ElectronWindow, electronWindow),
261-
Effect.provideService(DesktopWebLinks.DesktopWebLinks, ignoreWebLinks),
319+
Effect.provideService(
320+
ElectronWindow.ElectronWindow,
321+
{} as ElectronWindow.ElectronWindow["Service"],
322+
),
323+
Effect.provideService(
324+
DesktopWebLinks.DesktopWebLinks,
325+
DesktopWebLinks.DesktopWebLinks.of({
326+
receive: (url) =>
327+
Effect.sync(() => {
328+
received.push(url);
329+
if (url === later) delivered.resolve();
330+
}),
331+
setRendererReady: () => Effect.void,
332+
}),
333+
),
262334
);
263335
});
336+
337+
it.effect.each(["darwin", "win32", "linux"] as const)(
338+
"quits a second launch before initializing Clerk or the application runtime on %s",
339+
(platform) =>
340+
Effect.gen(function* () {
341+
requestSingleInstanceLockMock.mockReturnValueOnce(false);
342+
createClerkBridgeMock.mockReturnValue({ cleanup: vi.fn(), isPrimaryInstance: true });
343+
const events: string[] = [];
344+
const runtime = layerDesktopClerk(false, events, platform).pipe(
345+
Layer.flatMap(() =>
346+
Layer.effectDiscard(
347+
Effect.sync(() => {
348+
events.push("initializeApplicationRuntime");
349+
}),
350+
),
351+
),
352+
);
353+
const exit = yield* Effect.exit(Effect.scoped(Layer.build(runtime)));
354+
355+
assert.isTrue(Exit.hasInterrupts(exit));
356+
assert.deepEqual(events, [
357+
"setPath:userData:/tmp/app-data/t3code-v2",
358+
"requestSingleInstanceLock",
359+
"quit",
360+
]);
361+
assert.equal(createClerkBridgeMock.mock.calls.length, 0);
362+
assert.equal(storageMock.mock.calls.length, 0);
363+
}),
364+
);
264365
});
265366

266367
it.effect(
@@ -302,15 +403,15 @@ it.effect(
302403
assert.equal(event.preventDefault.mock.calls.length, 1);
303404
}).pipe(
304405
Effect.scoped,
305-
Effect.provide(layerDesktopClerk()),
406+
Effect.provide(layerDesktopClerk(true, [], "darwin", undefined, undefined, listeners)),
306407
Effect.provideService(ElectronApp.ElectronApp, electronApp),
307408
Effect.provideService(ElectronWindow.ElectronWindow, electronWindow),
308409
Effect.provideService(DesktopWebLinks.DesktopWebLinks, ignoreWebLinks),
309410
);
310411
},
311412
);
312413

313-
it.effect.each(["startup", "open-url"] as const)(
414+
it.effect.each(["startup", "open-url", "early-second-instance"] as const)(
314415
"receives hosted web sign-in through the desktop %s handler",
315416
(entry) =>
316417
Effect.gen(function* () {
@@ -369,6 +470,9 @@ it.effect.each(["startup", "open-url"] as const)(
369470
} as unknown as ElectronApp.ElectronApp["Service"];
370471
yield* Effect.gen(function* () {
371472
const clerk = yield* DesktopClerk.DesktopClerk;
473+
if (entry === "early-second-instance") {
474+
listeners.get("second-instance")?.({}, ["t3", link]);
475+
}
372476
yield* clerk.configure;
373477
if (entry === "open-url") {
374478
const event = { preventDefault: vi.fn() };
@@ -381,7 +485,7 @@ it.effect.each(["startup", "open-url"] as const)(
381485
assert.strictEqual(delivery?.flowId, request.flowId);
382486
assert.strictEqual(delivery?.returnUrl, request.returnUrl);
383487
}).pipe(
384-
Effect.provide(layerDesktopClerk(true, [], "darwin", undefined, shell)),
488+
Effect.provide(layerDesktopClerk(true, [], "darwin", undefined, shell, listeners)),
385489
Effect.provideService(HostProcess.Arguments, entry === "startup" ? ["t3", link] : ["t3"]),
386490
Effect.provideService(ElectronApp.ElectronApp, electronApp),
387491
Effect.provideService(
@@ -428,7 +532,7 @@ it.effect("hands web and app links to the renderer and leaves other links alone"
428532
"t3code://threads/env-1/thread-1",
429533
]);
430534
}).pipe(
431-
Effect.provide(layerDesktopClerk(true, [], "darwin")),
535+
Effect.provide(layerDesktopClerk(true, [], "darwin", undefined, undefined, listeners)),
432536
Effect.provideService(HostProcess.Arguments, ["t3"]),
433537
Effect.provideService(ElectronApp.ElectronApp, electronApp),
434538
Effect.provideService(

0 commit comments

Comments
 (0)