Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
127 commits
Select commit Hold shift + click to select a range
4338377
feat(web): "failed to start" screen helps users recover and report th…
t3dotgg Oct 26, 2026
69f85ef
chore(task-cache): name native client downloads so agent-device can i…
juliusmarminge Oct 26, 2026
03851b8
fix(web): keep large thread counts from shrinking labels (#25355)
Yash-Singh1 Oct 26, 2026
cbd72e5
fix(task-cache): avoid cross-request admission waiters (#25353)
juliusmarminge Oct 26, 2026
3d5364f
fix(task-cache): name Android native client downloads .apk
juliusmarminge Oct 26, 2026
10629af
fix(server): select the active iPhone Duo display for screenshots (#2…
shivamhwp Oct 26, 2026
3ed0688
fix(server): remove one-child-per-model instruction (#25359)
Yash-Singh1 Oct 26, 2026
3e70f55
fix(dev): skip auto-seeding large databases (#25365)
Yash-Singh1 Oct 26, 2026
2763bbe
fix(server): preview snapshots preserve blurred backdrops (#24618)
juliusmarminge Oct 26, 2026
5a38e6b
fix(web): model picker no longer jumps when switching providers (#25358)
t3dotgg Oct 26, 2026
9eac774
test(mobile): run React hooks with the release compiler (#24274)
juliusmarminge Oct 26, 2026
bfc7177
fix(mobile): pause videos outside visible thread and PR content (#24268)
juliusmarminge Oct 26, 2026
572cf74
fix(server): retry stalled MCP registration for resumed Claude turns …
Yash-Singh1 Oct 26, 2026
1ecb1a0
fix(mobile): avoid crashes opening wrapped source links (#25156)
juliusmarminge Oct 26, 2026
fb8fc1f
refactor(web): disconnect and reconnect delays read a shared deadline…
juliusmarminge Oct 26, 2026
d171a88
feat(mobile): run the chrome e2e across poses on the device pool
juliusmarminge Oct 26, 2026
72dde22
chore(lint): enforce effectFnOpportunity (#25099)
juliusmarminge Oct 26, 2026
e1c750e
fix(web): composer body ref stops re-attaching on every render (#25409)
juliusmarminge Oct 26, 2026
0a20d7e
fix(web): switching threads no longer delays the next thread's visit …
juliusmarminge Oct 26, 2026
91f47a1
fix(mobile): mobile:install builds on a cache miss for pooled devices…
juliusmarminge Oct 26, 2026
cc93cc5
revert(web): composer body ref goes back to the #25079 ref callback (…
juliusmarminge Oct 26, 2026
184d915
feat(mobile): thread rows drop the branch and lead with the title (#2…
juliusmarminge Oct 26, 2026
a240408
refactor(web): file breadcrumb menus refetch on a new workspace chang…
juliusmarminge Oct 26, 2026
1316d48
fix(web): citations to older responses load their history instead of …
juliusmarminge Oct 26, 2026
6ea3414
refactor(client): composers share one workspace snapshot refresh per …
juliusmarminge Oct 26, 2026
6ffde5b
refactor(mobile): composer pastes and picks are cancelled by their dr…
juliusmarminge Oct 26, 2026
911091b
chore(mobile): e2e poses for current devices, Duo and landscape fixes
juliusmarminge Oct 26, 2026
3433ba1
fix(mobile): select the correct draft after adding a project (#24269)
juliusmarminge Oct 26, 2026
6a1c8d1
fix(mobile): mobile:install no longer requires --prepare
juliusmarminge Oct 26, 2026
3e47c1c
fix(mobile): e2e landscape poses rotate for real on tablets and folds
juliusmarminge Oct 26, 2026
cc0b86d
fix(server): goals stop the running turn, clear while working, no ech…
t3dotgg Oct 26, 2026
0712398
refactor(web): pull request list remembers each answer for the next s…
juliusmarminge Oct 26, 2026
3f3c1b9
refactor(web): HTML previews handle frame messages in one listener (#…
juliusmarminge Oct 26, 2026
2acc7b5
refactor(web): review guide runs are watched from their answers, not …
juliusmarminge Oct 26, 2026
9d7997a
refactor(web): resize drags, panel shells and the browser host own th…
juliusmarminge Oct 26, 2026
3cb16cf
fix(web): find shows its match after a thread switch, and the timelin…
juliusmarminge Oct 26, 2026
59a3f52
fix(mobile): a new thread's first send no longer sticks on Starting (…
juliusmarminge Oct 26, 2026
d5a791b
fix(client): drafts for answered questions are cleared even when thei…
juliusmarminge Oct 26, 2026
28df7a2
refactor(web): terminal output no longer re-renders the drawer, theme…
juliusmarminge Oct 26, 2026
f0dd86f
fix(web): stable callbacks refresh before layout effects read them (#…
juliusmarminge Oct 26, 2026
7d3208c
test(web): say why the useStableCallback test renders without a route…
juliusmarminge Oct 26, 2026
e5ea25d
fix(mobile): queued edits end when their run starts, wherever you are…
juliusmarminge Oct 26, 2026
148d2fd
refactor(web): root theme, toast and chrome sync start with the app (…
juliusmarminge Oct 26, 2026
a936f05
refactor(web): root theme, toast and chrome sync start with the app (…
juliusmarminge Oct 26, 2026
d6fb62a
fix(mobile): editing a queued message while a question is open no lon…
juliusmarminge Oct 26, 2026
f05c38f
fix(web): browser viewport resizes work without an open preview panel…
juliusmarminge Oct 26, 2026
d81757e
test(web): attachment preview omission tests no longer time out on CI…
juliusmarminge Oct 26, 2026
87ea18c
fix(mobile): describe when composer view commands can reject (#25516)
juliusmarminge Oct 26, 2026
7c6e85c
fix(web): browser history and titles show up again (#25491)
juliusmarminge Oct 26, 2026
3f94487
fix(web): switching back to a thread no longer restores its tab's old…
juliusmarminge Oct 26, 2026
e6ec114
refactor(web): pull request page reacts to turns and sweep Escape wit…
juliusmarminge Oct 26, 2026
b424c6e
fix(web): an armed pull request confirm no longer outlives its button…
juliusmarminge Oct 26, 2026
210b2e7
fix(mobile): keep expanding composer text above its toolbar (#25396)
saphid Oct 26, 2026
1c1050e
fix(server): release completed PR sync sweep data from the read cache…
juliusmarminge Oct 26, 2026
e762f09
fix(mobile): drop the unused useLayoutEffect import that fails lint o…
juliusmarminge Oct 26, 2026
374e57d
refactor(web): provider settings and Codex setup run as explicit flow…
juliusmarminge Oct 26, 2026
8e1bb03
test(web): attachment preview omission cases check the prepared docum…
juliusmarminge Oct 26, 2026
c4d5950
refactor(mobile): pull request screens use a file-jump store and hand…
juliusmarminge Oct 26, 2026
4e42eaf
fix(mobile): label the pull request toast action View (#25581)
PixPMusic Oct 26, 2026
220eb73
refactor(mobile): media previews share file leases and close on blur …
juliusmarminge Oct 26, 2026
b6994c5
fix(shared): pin T3 Connect cloudflared to 2026.10.4, which drops the…
Project516 Oct 26, 2026
278588a
fix(web): skill chips in chat open the same details popover as the co…
flamboh Oct 26, 2026
dd5b540
refactor(web): chat route shortcuts register once instead of rebuildi…
juliusmarminge Oct 26, 2026
fe507c5
fix(clients): queued messages can't be edited while a question is ope…
juliusmarminge Oct 26, 2026
0899305
docs: add an FAQ that answers what people ask every day (#25451)
t3dotgg Oct 26, 2026
560ddb1
feat(web): warn before adding a second Claude or Codex account (#25475)
t3dotgg Oct 26, 2026
0790e38
fix(server): expire new-model badges after seven days (#25609)
Yash-Singh1 Oct 26, 2026
451bb45
refactor(web): running timers share one clock instead of an interval …
juliusmarminge Oct 26, 2026
4034b5f
fix(web): simplify the created pull request success row (#25613)
Yash-Singh1 Oct 26, 2026
5effca1
fix(web): thread jump hints wait for their delay on every hold (#25636)
juliusmarminge Oct 26, 2026
a54ba53
fix(mobile): open threads from the local cache instead of "Thread una…
juliusmarminge Oct 26, 2026
e2d3ded
fix(infra): task-cache telemetry no longer strands an event queued du…
juliusmarminge Oct 26, 2026
0c901ed
refactor(web): video previews attach listeners on their element and s…
juliusmarminge Oct 26, 2026
3de3eee
refactor(mobile): voice input session owns recording, metering and ke…
juliusmarminge Oct 26, 2026
6838e31
fix(web): screen readers can wrap to the first and last message of a …
shivamhwp Oct 26, 2026
024e593
fix(client-runtime): a slow host no longer shows settings as read-onl…
yordis Oct 26, 2026
a4fbea8
refactor(mobile): thread rows share one clock and cache SVGs instead …
juliusmarminge Oct 26, 2026
0604547
fix(server): a thread whose worktree was deleted recovers on the next…
yordis Oct 26, 2026
977a188
refactor(mobile): pull request list records answers where they land (…
juliusmarminge Oct 26, 2026
abf8f43
fix(mobile): keep floating status within the composer width (#25671)
PixPMusic Oct 26, 2026
9db433f
refactor(web): settings group by concern, with General split into foc…
juliusmarminge Oct 26, 2026
576a40f
fix(server): telemetry keeps a failed batch for 30 minutes, not 1.5 (…
t3dotgg Oct 26, 2026
78e93fd
fix(mobile): a caret move in one composer no longer moves another dra…
juliusmarminge Oct 26, 2026
d73fd12
test(web): attachment preview Word and large-text tests no longer fla…
juliusmarminge Oct 26, 2026
82dc892
feat(evals): shared evals package and an eval for T3 tool-use mistake…
t3dotgg Oct 26, 2026
0b0417a
refactor(web): Cmd+O presses the Open in editor button instead of a p…
juliusmarminge Oct 26, 2026
a7caea3
fix(mobile): queued messages are delivered by an app service, not a r…
juliusmarminge Oct 26, 2026
08bd2ec
test(web): PDF viewer behavior is covered by fast tests (#25699)
juliusmarminge Oct 27, 2026
0623d09
refactor(mobile): drop the unreachable pending-task editor from new-t…
juliusmarminge Oct 27, 2026
bd3287b
feat(web): thread state lives at the end of the timeline, not stacked…
t3dotgg Oct 27, 2026
5432d8e
refactor(web): drafts promote from the draft store, not from route ef…
juliusmarminge Oct 27, 2026
9bc0c33
refactor(mobile): settings use web's pages and groups (#25686)
juliusmarminge Oct 27, 2026
a2398c2
refactor(mobile): thread inspector mode is derived, not synced (#25682)
juliusmarminge Oct 27, 2026
68339a0
refactor(mobile): pull request list, filters and viewed files without…
juliusmarminge Oct 27, 2026
becf853
fix(web): PDF search finds phrases that wrap across lines (#25702)
juliusmarminge Oct 27, 2026
ed44f25
feat(server): cut T3's MCP tool schemas by a third and merge 18 tools…
t3dotgg Oct 27, 2026
354f6c8
fix(mobile): pull request rows refresh their diff stats after a new p…
juliusmarminge Oct 27, 2026
daa720a
fix(workflows): keep completed workflows reachable (#24587)
Bil0000 Oct 27, 2026
10a82e8
fix(web): devices agents open in background threads now show up (#25714)
juliusmarminge Oct 27, 2026
71ba6b3
refactor(web): optimistic chat messages leave without a timer (#25710)
juliusmarminge Oct 27, 2026
323d961
feat(acp): ACP session notices show as notices, not reply text (#25704)
juliusmarminge Oct 27, 2026
5127de8
fix(mobile): scale and align thread list icons (#25668)
PixPMusic Oct 27, 2026
3b48b52
refactor(mobile): new-task branch defaults are derived, not written a…
juliusmarminge Oct 27, 2026
6df241d
feat(provider): add Vercel fx as a provider (#18277)
agadzik Oct 27, 2026
417bc79
fix(mobile): usage chart bars round at the top instead of the bottom …
adityavardhansharma Oct 27, 2026
d145077
fix(mobile): a draft route's branch checkout runs once, even across a…
juliusmarminge Oct 27, 2026
65b4a69
fix(web): thread details popover closes when the card moves inline (#…
juliusmarminge Oct 27, 2026
f6a9315
refactor(web): diff and file reveals are requests, and workspace edit…
juliusmarminge Oct 27, 2026
3425671
feat(web): Add provider leads with first-class providers (#25753)
juliusmarminge Oct 27, 2026
5811d5c
refactor(mobile): app-lifetime services install once, and the usage w…
juliusmarminge Oct 27, 2026
8e86eb2
fix(client-runtime): searches and refreshes no longer wait on an unre…
juliusmarminge Oct 27, 2026
5d91ab1
refactor(web): command palette state lives in a store, git and branch…
juliusmarminge Oct 27, 2026
e0d068c
fix(mobile): restore Android chat content corners (#23989)
PixPMusic Oct 27, 2026
d2c4403
fix(server): agents show trends and comparisons as inline charts agai…
t3dotgg Oct 27, 2026
689763a
fix(mobile): isolate file tree state by workspace (#24270)
juliusmarminge Oct 27, 2026
83838af
fix(mobile): finished subagents stay reachable from the Agents pill (…
saphid Oct 27, 2026
e689dad
fix(mobile): keep segmented controls readable on cards and screens (#…
PixPMusic Oct 27, 2026
b1619f3
fix(web): cancelling update everything no longer flashes the update b…
t3dotgg Oct 27, 2026
44dae85
fix(mobile): lists end at the search field, and HTML previews start b…
juliusmarminge Oct 27, 2026
850d1e7
fix(provider-cursor): bump @cursor/sdk to 1.0.38 so long-context tier…
gcrft123 Oct 27, 2026
c294d63
fix(server): Sonnet also answers trend and comparison data with inlin…
t3dotgg Oct 27, 2026
fe867b8
fix(server): Claude MCP timeouts preserve the native session (#25660)
juliusmarminge Oct 27, 2026
32bf48f
fix(server): preserve settled runs during delegated acknowledgements …
juliusmarminge Oct 27, 2026
5522180
fix(mobile): align the iPad composer with workspace navigation (#24942)
PixPMusic Oct 27, 2026
a9b513b
chore(evals): store eval cases as .ndjson so review tools skip them (…
juliusmarminge Oct 27, 2026
394929a
test(server): CI fails when agent context grows past main (#25785)
t3dotgg Oct 27, 2026
2b8d341
Merge upstream/main into fork (2026-10-27)
riccardovandra Oct 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 2 additions & 0 deletions .github/scripts/ci-changes.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ const RUST = /^native\/(resource-monitor|kde-snap-shot|hyprland-snap-shot)\//;

// These tests read other packages without declaring dependencies.
const TEST_ONLY_DEPS = {
// Evals import the server's source to test its real model-facing text.
"@t3tools/evals": ["t3"],
"@t3tools/provider-pi": ["@t3tools/client-runtime"],
"@t3tools/scripts": [
"@t3tools/desktop",
Expand Down
55 changes: 55 additions & 0 deletions .github/workflows/agent-context-budget.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Agent Context Budget

# Fails when a PR raises a value in agentContextBudget.json above main's. AgentContextBudget.test.ts
# keeps that file equal to the measured context, so the context cannot grow by editing the file.
# To accept growth on purpose, a maintainer adds the agent-context-increase label.
on:
pull_request:
types: [opened, synchronize, reopened, labeled, unlabeled]

permissions:
contents: read

concurrency:
group: agent-context-budget-${{ github.event.pull_request.number }}
cancel-in-progress: true

jobs:
budget:
name: Agent context budget
runs-on: ubuntu-24.04
timeout-minutes: 5
env:
BUDGET: apps/server/src/provider/agentContextBudget.json
ALLOW_INCREASE: ${{ contains(github.event.pull_request.labels.*.name, 'agent-context-increase') }}
steps:
- name: Checkout
uses: actions/checkout@v6
with:
sparse-checkout: apps/server/src/provider/agentContextBudget.json
sparse-checkout-cone-mode: false

- name: Compare with main
run: |
git fetch --quiet --depth=1 origin main
if ! git cat-file -e "FETCH_HEAD:$BUDGET" 2>/dev/null; then
echo "main has no agent context budget yet."
exit 0
fi
git show "FETCH_HEAD:$BUDGET" > "$RUNNER_TEMP/main.json"
grown=$(jq -r --slurpfile main "$RUNNER_TEMP/main.json" '
to_entries[]
| select($main[0][.key] != null and .value > $main[0][.key])
| "\(.key): \($main[0][.key]) -> \(.value) (+\(.value - $main[0][.key]))"
' "$BUDGET")
if [ -z "$grown" ]; then
echo "Agent context is not larger than main."
exit 0
fi
printf 'Agent context grew compared to main:\n%s\n' "$grown"
if [ "$ALLOW_INCREASE" = "true" ]; then
echo "Accepted by the agent-context-increase label."
exit 0
fi
echo "::error file=$BUDGET::Agent context grew compared to main. Cut the added text, or ask a maintainer to add the agent-context-increase label."
exit 1
6 changes: 5 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ The most common defect in this repo is a change that works on the path you teste

An empty database is a bad test. Seed your worktree's `.t3` with a copy of real data instead of pointing at live state:

- The first `vp run dev` in a worktree does this for you when its database is missing. `--no-seed` or `T3CODE_DEV_SEED=0` skips it.
- The first `vp run dev` in a worktree does this for you when its database is missing and the source is at most 500 MiB. Larger sources warn and dev starts with an empty database. `--no-seed` or `T3CODE_DEV_SEED=0` skips seeding. Manual migration still accepts larger sources and may use substantial disk space before pruning.
- Run `vp run migrate-dev-db` with your dev server stopped to refresh. It rebuilds `<worktree>/.t3/userdata/statev2.sqlite` from a read-only snapshot of `~/.t3/userdata/statev2.sqlite`, the developer's real data. It keeps recent projects and their stopped threads, and drops scheduled tasks, pending work, and auth sessions, so your dev server never runs the developer's agents. Raise `--projects` and `--threads-per-project` for more data.
- Refresh `statev2.sqlite`, not `state.sqlite`. The server copies the V1 `state.sqlite` only when `statev2.sqlite` is missing.
- Bring `secrets` and `settings.json` only if the flow under test needs them.
Expand Down Expand Up @@ -136,6 +136,10 @@ An empty database is a bad test. Seed your worktree's `.t3` with a copy of real

For authorized mobile verification, a missing or outdated native client is an install step, not a blocker. Run `vp run mobile:install <ios|android> [device-id]` on the device host before starting Metro; it targets the only booted simulator or connected Android device when the id is omitted. It installs the dev client for this checkout's native fingerprint from the shared cache in seconds and builds only when no machine has built it yet, so prefer it over `expo run:*`, `xcodebuild`, or `gradlew`, which rebuild from scratch. Its stdout is one JSON line; build output goes to the log it names. See `test-t3-mobile` for the full workflow.

## Evals

`evals/` checks how real models behave with T3 Code's model-facing text: agent instructions, MCP tool descriptions and schemas, and generated titles. Before you change that text, read [evals/README.md](evals/README.md) and run the evals it names. When you fix a model behavior bug, add a case that fails before the fix.

## Pull requests

- Never make a PR unless the developer explicitly asks you to do so.
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ We are (mostly) not accepting contributions yet. Small fixes may be considered.

Full docs live in [docs/](./docs). There's no docs site yet.

- [FAQ](./docs/user/faq.md)
- [Install and first run](./docs/user/install.md)
- [Permission modes](./docs/user/permission-modes.md)
- [Keyboard shortcuts](./docs/user/keybindings.md)
Expand Down
5 changes: 4 additions & 1 deletion apps/desktop/src/app/DesktopAppActivation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,10 @@ export const make = Effect.gen(function* () {
webContents.send(DESKTOP_APP_ACTIVATION_REQUEST_CHANNEL, request);
});
}),
complete: (response) => Effect.sync(() => broker.complete(response)),
// The IPC handler owns the activation-completion span.
complete: Effect.fnUntraced(function* (response) {
return yield* Effect.sync(() => broker.complete(response));
}),
});
});

Expand Down
169 changes: 86 additions & 83 deletions apps/desktop/src/app/DesktopObservability.ts
Original file line number Diff line number Diff line change
Expand Up @@ -459,90 +459,91 @@ const makeBackendOutputLogShape = (
): Effect.Effect<DesktopBackendOutputLogShape> =>
Option.match(sink, {
onNone: () => Effect.succeed(DesktopBackendOutputLogNoop),
onSome: (logFile) =>
Effect.gen(function* () {
const sessionRef = yield* Ref.make(Option.none<BackendOutputSession>());
const writeFailure = Effect.fn("desktop.observability.backendOutput.writeFailure")(
function* (session: BackendOutputSession, details: string) {
yield* writeBackendChildLogRecord(logFile, {
message: "backend child process failure output start",
level: "ERROR",
annotations: {
component: "desktop-backend-child",
runId: session.runId,
instanceId: id,
phase: "START",
details: session.startDetails,
},
});
for (const output of session.chunks) {
yield* writeBackendChildLogRecord(logFile, {
message: "backend child process output",
level: output.streamName === "stderr" ? "ERROR" : "INFO",
annotations: {
component: "desktop-backend-child",
runId: session.runId,
instanceId: id,
stream: output.streamName,
text: textDecoder.decode(output.chunk.subarray(output.offset)),
},
});
}
yield* writeBackendChildLogRecord(logFile, {
message: "backend child process failure output end",
level: "ERROR",
annotations: {
component: "desktop-backend-child",
runId: session.runId,
instanceId: id,
phase: "END",
details: sanitizeLogValue(details),
},
});
// The enclosing operation owns the span for this inline handler.
onSome: Effect.fnUntraced(function* (logFile) {
const sessionRef = yield* Ref.make(Option.none<BackendOutputSession>());
const writeFailure = Effect.fn("desktop.observability.backendOutput.writeFailure")(function* (
session: BackendOutputSession,
details: string,
) {
yield* writeBackendChildLogRecord(logFile, {
message: "backend child process failure output start",
level: "ERROR",
annotations: {
component: "desktop-backend-child",
runId: session.runId,
instanceId: id,
phase: "START",
details: session.startDetails,
},
);
return {
beginSession: Effect.fn("desktop.observability.backendOutput.beginSession")(function* ({
details,
}) {
const runId = yield* currentDesktopRunId;
yield* Ref.set(
sessionRef,
Option.some({
runId,
startDetails: sanitizeLogValue(details),
chunks: [],
byteLength: 0,
}),
);
}),
writeOutputChunk: Effect.fnUntraced(function* (streamName, chunk) {
if (environment.isDevelopment) {
yield* writeDevelopmentConsoleOutput(streamName, chunk);
}
yield* Ref.update(
sessionRef,
Option.map((session) => appendBoundedOutputChunk(session, streamName, chunk)),
);
}),
persistFailureSnapshot: Effect.fn(
"desktop.observability.backendOutput.persistFailureSnapshot",
)(function* ({ details }) {
const session = yield* Ref.get(sessionRef);
if (Option.isSome(session)) {
yield* writeFailure(session.value, details);
}
}),
persistFailure: Effect.fn("desktop.observability.backendOutput.persistFailure")(
function* ({ details }) {
const session = yield* Ref.modify(sessionRef, (current) => [current, Option.none()]);
if (Option.isNone(session)) return;
yield* writeFailure(session.value, details);
});
for (const output of session.chunks) {
yield* writeBackendChildLogRecord(logFile, {
message: "backend child process output",
level: output.streamName === "stderr" ? "ERROR" : "INFO",
annotations: {
component: "desktop-backend-child",
runId: session.runId,
instanceId: id,
stream: output.streamName,
text: textDecoder.decode(output.chunk.subarray(output.offset)),
},
),
discardSession: Ref.set(sessionRef, Option.none()),
} satisfies DesktopBackendOutputLogShape;
}),
});
}
yield* writeBackendChildLogRecord(logFile, {
message: "backend child process failure output end",
level: "ERROR",
annotations: {
component: "desktop-backend-child",
runId: session.runId,
instanceId: id,
phase: "END",
details: sanitizeLogValue(details),
},
});
});
return {
beginSession: Effect.fn("desktop.observability.backendOutput.beginSession")(function* ({
details,
}) {
const runId = yield* currentDesktopRunId;
yield* Ref.set(
sessionRef,
Option.some({
runId,
startDetails: sanitizeLogValue(details),
chunks: [],
byteLength: 0,
}),
);
}),
writeOutputChunk: Effect.fnUntraced(function* (streamName, chunk) {
if (environment.isDevelopment) {
yield* writeDevelopmentConsoleOutput(streamName, chunk);
}
yield* Ref.update(
sessionRef,
Option.map((session) => appendBoundedOutputChunk(session, streamName, chunk)),
);
}),
persistFailureSnapshot: Effect.fn(
"desktop.observability.backendOutput.persistFailureSnapshot",
)(function* ({ details }) {
const session = yield* Ref.get(sessionRef);
if (Option.isSome(session)) {
yield* writeFailure(session.value, details);
}
}),
persistFailure: Effect.fn("desktop.observability.backendOutput.persistFailure")(function* ({
details,
}) {
const session = yield* Ref.modify(sessionRef, (current) => [current, Option.none()]);
if (Option.isNone(session)) return;
yield* writeFailure(session.value, details);
}),
discardSession: Ref.set(sessionRef, Option.none()),
} satisfies DesktopBackendOutputLogShape;
}),
});

const layerBackendOutputLogFactory = Layer.effect(
Expand Down Expand Up @@ -589,7 +590,9 @@ const layerBackendOutputLogFactory = Layer.effect(
});

return DesktopBackendOutputLogFactory.of({
forInstance: (id) => makeForId(id),
forInstance: Effect.fn("DesktopBackendOutputLogFactory.forInstance")(function (id) {
return makeForId(id);
}),
});
}),
);
Expand Down
15 changes: 7 additions & 8 deletions apps/desktop/src/app/DesktopWebLinks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,15 @@ const make = Effect.gen(function* () {
});

return DesktopWebLinks.of({
receive: (url) =>
Effect.suspend(() => {
receive: Effect.fn("DesktopWebLinks.receive")(function (url) {
return Effect.suspend(() => {
pending.push(url);
return flush;
}).pipe(Effect.withSpan("DesktopWebLinks.receive")),
setRendererReady: (ready) =>
(ready ? startListening : Effect.sync(stopListening)).pipe(
Effect.andThen(flush),
Effect.withSpan("DesktopWebLinks.setRendererReady"),
),
});
}),
setRendererReady: Effect.fn("DesktopWebLinks.setRendererReady")(function (ready) {
return ready ? startListening : Effect.sync(stopListening);
}, Effect.andThen(flush)),
});
});

Expand Down
Loading
Loading