Repository navigation
feat(server): send telemetry through ingest.t3.codes - #15028
Conversation
ApprovabilityVerdict: Needs Human Approval Macroscope's review found this PR requires human approval — This changes the default destination and delivery behavior for production telemetry, routing existing events through a new external ingest service and adding release-channel metadata. The product-wide default change and resulting data-flow impact warrant human review. You can add or adjust custom eligibility rules. Learn more. |
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: Scenario and decoded snapshot size10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
a4916a4 to
6345297
Compare
The server now sends analytics batches to ingest.t3.codes, which keeps a copy of every event and forwards events to PostHog. T3CODE_POSTHOG_HOST still overrides the host. - The background flush runs every 10s instead of every 1s. The shutdown flush and the retry backoff are unchanged. - A batch the endpoint rejects (400, 401, 413) is dropped at once with one warning. 408, 429, and 5xx answers are still retried. - Every event carries telemetryChannel (stable, nightly, preview, or dev). Release builds of pingdotgg/t3code stamp it at build time; all other builds report dev. It is separate from the sign-in page build channel. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
6345297 to
c7ba221
Compare
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
## What's Changed * perf(mobile): settings screens compile with the React Compiler by @juliusmarminge in pingdotgg/t3code#21119 * perf(mobile): files, review and remaining settings screens compile with the React Compiler by @juliusmarminge in pingdotgg/t3code#21124 * perf(mobile): home, workspace layout and overlay pieces compile with the React Compiler by @juliusmarminge in pingdotgg/t3code#21133 * perf(mobile): pull request screens compile with the React Compiler by @juliusmarminge in pingdotgg/t3code#21136 * perf(mobile): composer, connections, add project and shared state compile with the React Compiler by @juliusmarminge in pingdotgg/t3code#21137 * perf(mobile): new task flow, git sheets, thread settings and work log compile with the React Compiler by @juliusmarminge in pingdotgg/t3code#21141 * perf(mobile): thread composer, route screen and queue control compile with the React Compiler by @juliusmarminge in pingdotgg/t3code#21142 * perf(mobile): thread detail screen and navigation sidebar compile with the React Compiler by @juliusmarminge in pingdotgg/t3code#21145 * perf(mobile): thread rows no longer re-render the list when another thread streams by @juliusmarminge in pingdotgg/t3code#21255 * perf(mobile): composer draft no longer re-renders the thread screen when typing by @juliusmarminge in pingdotgg/t3code#21261 * perf(mobile): ThreadFeed compiles with the React Compiler by @juliusmarminge in pingdotgg/t3code#21268 * feat(server): send telemetry through ingest.t3.codes by @t3dotgg in pingdotgg/t3code#15028 * fix(devices): Android fold controls work over T3 Connect by @t3dotgg in pingdotgg/t3code#21156 * test(web): burst-merged jsdom tests run in a real browser by @juliusmarminge in pingdotgg/t3code#21318 * fix(web): keep the composer chin below the input by @t3dotgg in pingdotgg/t3code#21345 **Full Changelog**: pingdotgg/t3code@v0.1.1-nightly.20261018.3331...v0.1.1-nightly.20261018.3335 Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.1.1-nightly.20261018.3335
## What's Changed * perf(mobile): settings screens compile with the React Compiler by @juliusmarminge in pingdotgg/t3code#21119 * perf(mobile): files, review and remaining settings screens compile with the React Compiler by @juliusmarminge in pingdotgg/t3code#21124 * perf(mobile): home, workspace layout and overlay pieces compile with the React Compiler by @juliusmarminge in pingdotgg/t3code#21133 * perf(mobile): pull request screens compile with the React Compiler by @juliusmarminge in pingdotgg/t3code#21136 * perf(mobile): composer, connections, add project and shared state compile with the React Compiler by @juliusmarminge in pingdotgg/t3code#21137 * perf(mobile): new task flow, git sheets, thread settings and work log compile with the React Compiler by @juliusmarminge in pingdotgg/t3code#21141 * perf(mobile): thread composer, route screen and queue control compile with the React Compiler by @juliusmarminge in pingdotgg/t3code#21142 * perf(mobile): thread detail screen and navigation sidebar compile with the React Compiler by @juliusmarminge in pingdotgg/t3code#21145 * perf(mobile): thread rows no longer re-render the list when another thread streams by @juliusmarminge in pingdotgg/t3code#21255 * perf(mobile): composer draft no longer re-renders the thread screen when typing by @juliusmarminge in pingdotgg/t3code#21261 * perf(mobile): ThreadFeed compiles with the React Compiler by @juliusmarminge in pingdotgg/t3code#21268 * feat(server): send telemetry through ingest.t3.codes by @t3dotgg in pingdotgg/t3code#15028 * fix(devices): Android fold controls work over T3 Connect by @t3dotgg in pingdotgg/t3code#21156 * test(web): burst-merged jsdom tests run in a real browser by @juliusmarminge in pingdotgg/t3code#21318 * fix(web): keep the composer chin below the input by @t3dotgg in pingdotgg/t3code#21345 **Full Changelog**: pingdotgg/t3code@v0.1.1-nightly.20261018.3331...v0.1.1-nightly.20261018.3335 Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.1.1-nightly.20261018.3335
Merges `pingdotgg/t3code` up to `ab6be13d43`, from base `5c5dcbc60b`: 589 commits. Branched from `main` (`7e132898fa`), with no other merge PR open. Most of the range is the rest of upstream's move to the React Compiler, plus its apps/web DOM tests moving to vitest browser mode (`*.browser.test.tsx`, run in real Chromium). Upstream removed jsdom and `react-test-renderer`. ## How the conflicts were resolved All 27 conflicted files were resolved by the verdict `preflight.mjs` printed for each. The tracker entry in `docs/fork/upstream-merge-log.md` has the details. **Tests** - Seven upstream tests became browser tests. The fork's mocks were re-ported into the new files, and the inventory was re-pointed at them. - The fork's framed-preview tests moved to the fork-only `PreviewView.frame.browser.test.tsx`. A browser-mode mock binds its exports once, at load, so one file can't run both with and without the desktop bridge. - Three fork-only tests (ThreadForkDialog, MoatlessArtifactChip, MobileSidebarDrawer) depended on `react-test-renderer` and on test helpers upstream deleted. They are rewritten as browser tests. **ChatView** - Upstream moved the rewind dialog into `chat/ChatOverlayHosts.tsx`, and the `checkpointFileRestore` gate moved with it. - The ThreadDetailsPanel script props were re-applied in upstream's inline JSX. **Lockfile and package.json** - `pnpm-lock.yaml` was re-derived with `install.mjs`. - `apps/web/package.json` keeps the `moatless-api` workspace link and the `tsc --noEmit` typecheck script. **Converged** - Upstream now renders Mermaid itself (`chat/MermaidDiagram.tsx`). The fork's `fork/mermaidDiagram*` files, their inventory entries and the Mermaid Diagram Delta section are deleted. **Fixed along the way** - The provider list's own "Add provider" button had no gate, on `main` too. It is now behind `providerConfiguration`, like the title button. - Upstream's React Compiler lint rules flagged 64 errors in fork-owned files, and the compiler-coverage test found 2 bailouts (`finally` inside a hook). All are fixed. - Most were `useMemo`/`useCallback` removals. - The only behaviour change: sandbox "elapsed" times are now measured from the status query's `dataUpdatedAt` instead of a `Date.now()` read during render. ## Verification `verify.mjs --sequential`: duplicate-adds, tripwires, resolution-check, unsupported-methods (ADD 0 / DROP 0 / KEEP 2), lockfile, fmt, lint, typecheck and build are all green. The `test` step is red only on the five files that failed alone on 2026-10-17 too, on the same machine-only causes: - `shared` `AgentScope` - `ssh` `tunnel` - `provider-opencode` `OpenCodeServerLedger` - `t3` `AcpAdapterV2` - `t3` `OrchestratorReplayFixtures` `@t3tools/web` failed in the full run, and re-ran green after the fixes: 565 files, 8497 tests. The failure that wasn't a compiler bailout, `WorkflowOpeningBlock.browser.test.tsx`, is upstream's file unchanged, and it passed alone. ## Feature classification ### Usable as-is - **Reasoning-effort stepping**: new `composer.increaseEffort` and `composer.decreaseEffort` commands. They have no default binding, and keybinding editing stays behind `serverAdministration`. - **Transcript and markdown fixes**: - Windows paths and terminal links (pingdotgg#21069, pingdotgg#21199, pingdotgg#19627) - Math in Mermaid diagrams (pingdotgg#16198) - Code-block highlight jump (pingdotgg#20923) - Copied task lists (pingdotgg#14778) - Table expand button (pingdotgg#19782) - **Message-list fixes**: - Huge-thread scroll loop (pingdotgg#21269) - Answered questions stay visible (pingdotgg#21086) - "Failed" status for failed runs (pingdotgg#20996) - Resumed-subagent rows (pingdotgg#18099) - Background-agent count (pingdotgg#20785) - A single completion sound (pingdotgg#17540) - **Composer fixes**: - Spacing and centring (pingdotgg#21345, pingdotgg#12952, pingdotgg#17820, pingdotgg#21241) - Quotes (pingdotgg#20350, pingdotgg#19450) - Send shortcut on follow-ups (pingdotgg#20929) - `/tmp/x` no longer opens the slash menu (pingdotgg#19671) - Failed attachments don't block send (pingdotgg#20737) - HEIC attachments (pingdotgg#10429) - Long approval commands wrap (pingdotgg#17802) - Android Backspace (pingdotgg#18063) - **Thread drag and drop into chat** (pingdotgg#19697, pingdotgg#20024). - **Diff, file and pull request panel fixes**: pingdotgg#20297, pingdotgg#20333, pingdotgg#19089, pingdotgg#18288, pingdotgg#17132, pingdotgg#21048, pingdotgg#17554, pingdotgg#19945, pingdotgg#15341, pingdotgg#21245, pingdotgg#21147. - **Sidebar and breadcrumb fixes**: middle truncation (pingdotgg#18858, pingdotgg#17208), "No project" scratch breadcrumb (pingdotgg#19721), and snoozed threads waking in an open chat (pingdotgg#21019). - **Settings and miscellaneous UI fixes**: - Model picker lists every custom model (pingdotgg#14961) - Font picker (pingdotgg#9814) - Settings search highlight (pingdotgg#20764) - Usage popover (pingdotgg#19808, pingdotgg#16936) - Web app manifest name (pingdotgg#19175) - Dark-mode switches (pingdotgg#14984) - **Phone browser**: tapping away from the model picker no longer presses what is under it (3f2dbd7). - **client-runtime**: queries stay pending during a connection hand-off (pingdotgg#18155), and a dropped session is not shown as a failed connection (pingdotgg#18469). - **React Compiler and render-performance work**: about 190 commits. - **Workflow thread view**: `WorkflowOpeningBlock` shows a workflow's phases and agents (pingdotgg#20857). It renders only when `workflowScript` is set, which Moatless never sends; see the backend list. ### Unsupported in Moatless / needs implementation - **`t3 doctor`, server telemetry and the Node CLI** (pingdotgg#20948, pingdotgg#15028, pingdotgg#15921, pingdotgg#15913): upstream's server only, with no client surface. - **SSH device hosts and T3 Connect/relay fixes** (pingdotgg#20377, pingdotgg#17440, pingdotgg#18832, pingdotgg#19444, pingdotgg#18621, pingdotgg#17743, pingdotgg#18838): behind `FEATURES.connections` or `FEATURES.deviceHub`. - **Tailscale HTTPS row** (pingdotgg#21057): behind `FEATURES.connections`. - **Remote server self-update and how-to-update messages** (pingdotgg#18980, pingdotgg#18110): behind `FEATURES.serverUpdateBanner`. - **Masking of secret settings fields** (pingdotgg#20446): the form is behind `FEATURES.providerConfiguration`, because Moatless does not dispatch `server.updateSettings`. - **Desktop updater, desktop preview and local-machine fixes** (pingdotgg#21210, pingdotgg#20994, pingdotgg#16026, pingdotgg#18549, pingdotgg#19846, pingdotgg#20206, pingdotgg#20277): desktop bridge only, or behind `FEATURES.openInEditor`. ### Backend behavior to consider reproducing in Moatless Added to [gaps: runtime fixes](docs/fork/gaps.md#runtime-fixes-upstream-made-to-its-own-server). - **`workflowScript: true` on a conversation message whose body is a provider-native workflow script.** Without it the timeline shows the raw script. - **`endedWatch` on an ended pull request watch**, so watching again doesn't repeat news the thread already got (pingdotgg#21155). - **`pullRequests` on orchestrator MCP thread list and read results** (pingdotgg#17454). Related: `t3_thread_send` now says why a message was refused (pingdotgg#21027). - **`vcs.createWorktree` always sends `path: null`** and expects the server to place the worktree. Moatless doesn't dispatch this method; it is under `projectManagement`. - **Run lifecycle**: - Refuse `thread.create` for an id that already exists (pingdotgg#19704). - Cancel a preparing run on archive (pingdotgg#20073). - A parent Stop clears orphaned delegated follow-ups (pingdotgg#20310). - Queued messages land in order after a resume (pingdotgg#17773). - **Workflow members stream thinking and tool calls into their own threads** (pingdotgg#20786). - **Pull request link handling**: canonicalise legacy links (pingdotgg#19129), don't inherit watches into forks (pingdotgg#16623), and settle threads after their pull request merges (pingdotgg#18232, pingdotgg#19937). No new RPC methods. `vcs.createWorktree` is the only change to `rpc.ts`. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- Moatless task: https://moatless.soaplabstest.com/tasks/5bcfa708-8eac-41b0-a580-c885a620afb5
Problem
The server sends analytics straight to PostHog, so we keep no copy of the raw events and cannot choose what PostHog gets. Events also do not say which release channel sent them. The existing build channel cannot do this job: it calls stable "latest", calls preview "nightly", and labels local builds "latest".
Change
T3CODE_POSTHOG_HOSTis nowhttps://ingest.t3.codes. That endpoint takes the same/batch/body, archives every event, and forwards a filtered set to PostHog. The env override still works.api_keydoes not send batch after batch.__T3CODE_TELEMETRY_CHANNEL__, sent on every event astelemetryChannelnext tot3CodeVersion. It defaults todev, and a value other thanstable,nightly,preview, ordevfails the build. The sign-in page constant__T3CODE_BUILD_CHANNEL__is unchanged.T3CODE_TELEMETRY_CHANNELonly whengithub.repository == 'pingdotgg/t3code'. Other repositories getdev.release.ymlbuild_bundle(server bundle that desktop reuses)needs.preflight.outputs.release_channelstable,nightly, orpreviewrelease-desktop.ymlCLI single-executable (bundles the server again)inputs.release_channeldesktop-macos-preview.yml(PR mac previews)release_channel: previewpreviewThe preflight step already writes exactly
stable(tag pushes and manual stable),nightly(schedule and manual nightly), orpreview(manual preview) asrelease_channel, so the value passes through as is. Nothing else bundles the server: desktop packaging runs with--skip-buildon thejs-bundleartifact, the Windows app embeds the Linux CLI archive, npm repacks the CLI archives, and AUR repacks the released AppImage.docs/user/telemetry.mdsays where data goes. The Delivery section ofdocs/internals/product-analytics.mdnames the endpoint and notes that it rejects events without a uuid.ingest.t3.codesis live. It forwards every T3 Code event to PostHog (MODE=full, no filters), so PostHog keeps getting the same events after this ships.Scope and approval
Theo asked for this as part of moving T3 Code analytics to a T3-owned store, with PostHog fed from it. The client change is limited to the existing telemetry service: where batches go, which failures retry, and one new property. Theo reviews before merge.
Verification
Rebased onto
mainagain on Oct 10. The only conflicts came from the HostProcess refactor (#17628, #17641):HostProcessPlatformandHostProcessArchitectureare nowHostProcess.PlatformandHostProcess.Architecture. The PR logic is unchanged.vp test run src/telemetry/AnalyticsService.test.tsinapps/server: 6 passed. New cases: 400, 401, and 413 send the batch once; a connection reset, 408, 429, and 503 send it 5 times with the same uuids;telemetryChannelisdevby default and is the build-time value when one is set.T3CODE_TELEMETRY_CHANNEL=nightly vp packinapps/server: the bundle containsconst telemetryChannel = "nightly";and thehttps://ingest.t3.codesdefault.T3CODE_TELEMETRY_CHANNEL=latest vp packstops with the validation error.tsc --noEmitinapps/server: passes.vp linton the changed TS files: one warning, unusedlayerTestinAnalyticsService.ts, which is already on main.vp fmt --checkon the changed files: clean.concurrency.queue, shellcheck style) are unchanged.Not checked: a real release run, and a live send from a T3 Code build to
ingest.t3.codes.Made by Claude Opus 5.5 in Claude Code.
🤖 Generated with Claude Code