Skip to content

Commit c8d0247

Browse files
Merge upstream pingdotgg/t3code main into fork main
Resolves conflicts keeping both fork and upstream intent: - Provider config RPCs keep the fork's published providers (account pools) and gain upstream's on-demand workspace snapshots - Settings search keeps fork peer-link/provider-pool gates and adds upstream's redesign gate - Mobile subagent rows and agents sheet open in upstream's inspector while keeping fork remote-environment targets - Mobile thread header keeps conversation summaries inside upstream's inspector presentation - Fork effects are baselined in scripts/effect-budget.json, as upstream did for effects merged after the budget - Upstream tests supply fork-only fields (markLimited, environmentContexts, published provider registry methods) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 parents 41e63e0 + b76a110 commit c8d0247

232 files changed

Lines changed: 10207 additions & 1554 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.

‎.github/workflows/web-preview.yml‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ jobs:
8282
--archive=tgz \
8383
--yes \
8484
--token "$VERCEL_TOKEN" \
85-
--scope "$vercel_scope"
85+
--scope "$vercel_scope" \
86+
--build-env "VITE_RELEASE_CHANNEL=preview"
8687
)"
8788
printf '%s\n' "$deployment_output"
8889
# Vercel can print lockfile warnings to stdout before the deployment URL.

‎.gitignore‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ apps/mobile/.generated/
3636
apps/mobile/.android-cache/
3737
/.generated/
3838
artifacts/app-store/screenshots/
39+
artifacts/mobile-e2e/
3940
.github/pr-assets/
4041
native/**/target/
4142
native/project-memory/build/

‎AGENTS.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ Architecture and its constraints: `docs/internals/overview.md`. Glossary: `docs/
194194
options, and pass combinators as additional function-builder arguments.
195195
- Inferred types over annotations. `any` is the enemy.
196196
- Default to no comment. Write one only for a constraint, an external quirk, or an invariant the code can't show, in one line where you can and four at most. Don't restate names or signatures, narrate steps, record history, or explain the fix you just made; the PR carries that. `t3code/no-low-value-comments` enforces the length cap and the mechanical cases.
197+
- React effects are a last resort: derive in render, act in handlers, reset with `key`, or use a ref callback or store. The `t3code/react-effect-budget` lint rule holds each file to its entry in `scripts/effect-budget.json`; raise an entry only in the PR that needs the effect, and lower it when you remove one.
197198
- Our users drive agents all day and notice a dropped frame, a lying spinner, and a stale label. No continuously repainting animations; they peg the GPU on high-refresh displays.
198199
- If a rule here fights the task in front of you, say so loudly and get a human sign-off before breaking it.
199200

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,4 +342,36 @@ describe("DesktopObservability", () => {
342342
Effect.provide(Layer.mergeAll(NodeServices.layer, layerCollector(requests), layerEmptyEnv)),
343343
);
344344
});
345+
346+
it.effect("describes the Node runtime and the desktop mode under semantic or t3code keys", () => {
347+
const requests: Array<ExportedRequest> = [];
348+
return Effect.gen(function* () {
349+
const fileSystem = yield* FileSystem.FileSystem;
350+
const baseDir = yield* fileSystem.makeTempDirectoryScoped({
351+
prefix: "t3-desktop-observability-test-",
352+
});
353+
const layerEnvironment = layerEnvironmentFor(baseDir);
354+
yield* writeObservabilitySettings(layerEnvironment, {
355+
otlpLogsUrl: "https://settings.example.com/v1/logs",
356+
});
357+
358+
yield* Effect.scoped(
359+
Effect.logInfo("desktop resource under test").pipe(
360+
Effect.provide(DesktopObservability.layer.pipe(Layer.provideMerge(layerEnvironment))),
361+
),
362+
);
363+
364+
const body = requests.map((request) => request.body).join("\n");
365+
assert.include(body, '"key":"process.runtime.name","value":{"stringValue":"nodejs"}');
366+
assert.include(
367+
body,
368+
`"key":"process.runtime.version","value":{"stringValue":"${process.versions.node}"}`,
369+
);
370+
assert.include(body, '"key":"t3code.desktop.mode","value":{"stringValue":"development"}');
371+
assert.notInclude(body, "service.mode");
372+
}).pipe(
373+
Effect.scoped,
374+
Effect.provide(Layer.mergeAll(NodeServices.layer, layerCollector(requests), layerEmptyEnv)),
375+
);
376+
});
345377
});

‎apps/desktop/src/app/DesktopObservability.ts‎

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@ import { PRIMARY_LOCAL_ENVIRONMENT_ID } from "@t3tools/contracts";
22
import {
33
makeLocalFileTracer,
44
makeTraceSink,
5+
nodeProcessRuntimeAttributes,
6+
processServiceInstanceId,
57
type SignalExport,
68
} from "@t3tools/shared/observability";
79
import * as HostProcess from "@t3tools/shared/HostProcess";
810
import * as SharedObservability from "@t3tools/shared/observability";
911
import * as OtelEnvironment from "@t3tools/shared/otelEnvironment";
12+
import { releaseChannelOf, releaseResourceAttributes } from "@t3tools/shared/releaseResource";
1013
import {
1114
parsePersistedServerObservabilitySettings,
1215
type PersistedServerObservabilitySettings,
@@ -595,15 +598,24 @@ const layerTelemetry = Layer.unwrap(
595598
Effect.gen(function* () {
596599
const environment = yield* DesktopEnvironment.DesktopEnvironment;
597600
const endpoints = yield* resolveOtlpEndpoints;
601+
// Unpackaged runs launch a script, so Electron reports its own version.
602+
const serviceVersion = environment.isPackaged
603+
? environment.appVersion
604+
: desktopPackageJson.version;
598605
const resource = {
599606
serviceName: "t3code-desktop",
600-
// Unpackaged runs launch a script, so Electron reports its own version.
601-
serviceVersion: environment.isPackaged ? environment.appVersion : desktopPackageJson.version,
607+
serviceVersion,
602608
attributes: {
603609
"service.namespace": "t3code",
604610
"service.runtime": "desktop",
605-
"service.mode": environment.isDevelopment ? "development" : "packaged",
611+
"t3code.desktop.mode": environment.isDevelopment ? "development" : "packaged",
612+
"service.instance.id": processServiceInstanceId(endpoints.resourceAttributes),
613+
...releaseResourceAttributes(
614+
environment.isDevelopment ? "dev" : releaseChannelOf(serviceVersion),
615+
endpoints.resourceAttributes,
616+
),
606617
"host.name": endpoints.resourceAttributes["host.name"] || (yield* HostProcess.Hostname),
618+
...nodeProcessRuntimeAttributes(),
607619
},
608620
};
609621

‎apps/desktop/src/backend/DesktopBackendConfiguration.test.ts‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,7 @@ describe("DesktopBackendConfiguration", () => {
678678
),
679679
);
680680

681-
it.effect("resolveWsl carries the kill switch into the distro", () =>
681+
it.effect("resolveWsl carries the kill switch and resource attributes into the distro", () =>
682682
Effect.gen(function* () {
683683
const fileSystem = yield* FileSystem.FileSystem;
684684
const baseDir = yield* fileSystem.makeTempDirectoryScoped({
@@ -688,10 +688,12 @@ describe("DesktopBackendConfiguration", () => {
688688
const previousWslEnv = process.env.WSLENV;
689689
const previousDisabled = process.env.OTEL_SDK_DISABLED;
690690
const previousTelemetry = process.env.T3CODE_TELEMETRY_ENABLED;
691+
const previousResourceAttributes = process.env.OTEL_RESOURCE_ATTRIBUTES;
691692
try {
692693
delete process.env.WSLENV;
693694
process.env.OTEL_SDK_DISABLED = "true";
694695
process.env.T3CODE_TELEMETRY_ENABLED = "false";
696+
process.env.OTEL_RESOURCE_ATTRIBUTES = "deployment.environment.name=staging";
695697

696698
yield* Effect.gen(function* () {
697699
const configuration = yield* DesktopBackendConfiguration.DesktopBackendConfiguration;
@@ -701,6 +703,8 @@ describe("DesktopBackendConfiguration", () => {
701703
assert.include((config.env.WSLENV ?? "").split(":"), "OTEL_SDK_DISABLED");
702704
assert.equal(config.env.T3CODE_TELEMETRY_ENABLED, "false");
703705
assert.include((config.env.WSLENV ?? "").split(":"), "T3CODE_TELEMETRY_ENABLED");
706+
assert.equal(config.env.OTEL_RESOURCE_ATTRIBUTES, "deployment.environment.name=staging");
707+
assert.include((config.env.WSLENV ?? "").split(":"), "OTEL_RESOURCE_ATTRIBUTES");
704708
}).pipe(
705709
Effect.provide(
706710
layerBackendConfiguration().pipe(
@@ -722,6 +726,7 @@ describe("DesktopBackendConfiguration", () => {
722726
restoreEnv("WSLENV", previousWslEnv);
723727
restoreEnv("OTEL_SDK_DISABLED", previousDisabled);
724728
restoreEnv("T3CODE_TELEMETRY_ENABLED", previousTelemetry);
729+
restoreEnv("OTEL_RESOURCE_ATTRIBUTES", previousResourceAttributes);
725730
}
726731
}).pipe(Effect.scoped, Effect.provide(NodeServices.layer)),
727732
);

‎apps/desktop/src/backend/DesktopBackendConfiguration.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ const WSL_FORWARDED_ENV_NAMES = [
110110
"OTEL_TRACES_EXPORTER",
111111
"OTEL_METRICS_EXPORTER",
112112
"OTEL_LOGS_EXPORTER",
113+
"OTEL_RESOURCE_ATTRIBUTES",
113114
] as const;
114115

115116
const WSL_SERVER_SYSTEM_PATH = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";

‎apps/mobile/src/Stack.tsx‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,10 @@ import { ConversationSummariesRouteScreen } from "./features/conversation-summar
6666
import { ThreadAgentsSheet } from "./features/threads/ThreadAgentsSheet";
6767
import { ThreadBackgroundWorkSheet } from "./features/threads/ThreadBackgroundWorkSheet";
6868
import { ThreadQueueSheet } from "./features/threads/ThreadQueueControl";
69-
import { ThreadRouteScreen } from "./features/threads/ThreadRouteScreen";
69+
import {
70+
FullscreenThreadRouteScreen,
71+
ThreadRouteScreen,
72+
} from "./features/threads/ThreadRouteScreen";
7073
import { McpAppFullscreenScreen } from "./features/threads/McpAppFullscreenScreen";
7174
import { ConnectionsRouteScreen } from "./features/connection/ConnectionsRouteScreen";
7275
import { ConnectionsNewRouteScreen } from "./features/connection/ConnectionsNewRouteScreen";
@@ -820,6 +823,13 @@ const RootStackConfig = createWorkspaceStackNavigator({
820823
linking: `${THREAD_LINKING_PREFIX}/terminal`,
821824
options: SOLID_HEADER_OPTIONS,
822825
}),
826+
ThreadInspectorFullscreen: createNativeStackScreen({
827+
screen: FullscreenThreadRouteScreen,
828+
options: {
829+
...THREAD_HEADER_OPTIONS,
830+
presentation: "fullScreenModal",
831+
},
832+
}),
823833
ThreadDevicePreview: createNativeStackScreen({
824834
screen: DevicePreviewRouteScreen,
825835
linking: `${THREAD_LINKING_PREFIX}/devices`,

0 commit comments

Comments
 (0)