authorgravatar for me@t3.ggTheo Browne <me@t3.gg> 2026-10-14 02:57:52-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-10-14 02:57:52-07:00
logffceb61fcbbdc7ac5268812a1cc5dfedd7a6f7b9
tree0e9dd26b9523d782cf8bd866f276b75ea9049ca8
parent0ae1091d019484d474fce0fe0a89195a82134041
signature Signed by PGP key B5690EEEBB952194

fix(cli): t3 triage reports the server's version, not its own, as the user's build (#19359)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

7 files changed, 168 insertions(+), 35 deletions(-)

.github/ISSUE_TEMPLATE/via-triage.yml+1-1
...@@ -37,7 +37,7 @@ body:...@@ -37,7 +37,7 @@ body:
37 id: version37 id: version
38 attributes:38 attributes:
39 label: Version39 label: Version
40 description: Installed t3 version or commit.40 description: Version the bug happened on (not the `t3 triage` CLI version), or unknown.
41 placeholder: 0.0.3341 placeholder: 0.0.33
42 validations:42 validations:
43 required: true43 required: true
.github/triage/PLAYBOOK.md+24-8
...@@ -6,7 +6,7 @@ crashes, auth failures, broken setups, slow launches, or anything else. Your job...@@ -6,7 +6,7 @@ crashes, auth failures, broken setups, slow launches, or anything else. Your job
6find out what went wrong, unblock the user if you can, and turn what you learned into6find out what went wrong, unblock the user if you can, and turn what you learned into
7a well written GitHub issue when one is warranted.7a well written GitHub issue when one is warranted.
88
9A triage context file with machine facts (version, OS, paths, server liveness) was9A triage context file with machine facts (versions, OS, paths, server liveness) was
10provided alongside this playbook. Everything machine-specific lives there, not here.10provided alongside this playbook. Everything machine-specific lives there, not here.
1111
12## 1. Ask what went wrong12## 1. Ask what went wrong
...@@ -18,9 +18,15 @@ valuable thing you can extract from this conversation....@@ -18,9 +18,15 @@ valuable thing you can extract from this conversation.
1818
19## 2. Read the machine facts19## 2. Read the machine facts
2020
21Read the triage context file before investigating. It tells you the installed21Read the triage context file before investigating. It tells you the OS, whether
22version, the OS, whether the server process is currently running, and the exact22the server process is currently running, and the exact paths for state, logs, and
23paths for state, logs, and the database.23the database.
24
25Its triage CLI version (called "Installed version" in older context files) is only
26the version of the `t3` that ran `t3 triage`. It is often not the build the bug
27happened on: `npx t3 triage` runs whatever `t3` npm resolves, while the user may
28run the desktop app, the background service, or a nightly. The server process line
29gives the local server's version when the server recorded one.
2430
25## 3. Check for a newer playbook31## 3. Check for a newer playbook
2632
...@@ -30,8 +36,16 @@ instead of this one. The user may be on an old release with an old copy....@@ -30,8 +36,16 @@ instead of this one. The user may be on an old release with an old copy.
3036
31## 4. Get the source37## 4. Get the source
3238
33Clone the repo at the tag matching the user's installed version, into the source39Before cloning, ask the user which version, device, and surface the bug happened
34cache directory named in the context file, one subdirectory per commit hash:40on. The bug may have happened on another machine, a remote server, the mobile app,
41or an older build they have since updated. Check their answer against local facts
42where they apply: the server version in the context file, or `serverVersion` from
43`<origin>/.well-known/t3/environment` when a local server is running. If neither
44the user nor the machine can tell you the version, say it is unknown. Do not guess.
45
46Clone the repo at the release tag for that version (`v` followed by the version,
47such as `v0.0.42`), into the source cache directory named in the context file,
48one subdirectory per commit hash:
3549
36 git clone --depth 1 --filter=blob:none --branch <release-tag> \50 git clone --depth 1 --filter=blob:none --branch <release-tag> \
37 https://github.com/pingdotgg/t3code <source-cache-dir>/<hash>51 https://github.com/pingdotgg/t3code <source-cache-dir>/<hash>
...@@ -82,8 +96,8 @@ comes from this repo's `main` branch....@@ -82,8 +96,8 @@ comes from this repo's `main` branch.
8296
83Search existing issues in pingdotgg/t3code (use `gh`, or the public GitHub search97Search existing issues in pingdotgg/t3code (use `gh`, or the public GitHub search
84API if `gh` is missing or not logged in). Then check whether the problem is already98API if `gh` is missing or not logged in). Then check whether the problem is already
85fixed in a release newer than the user's version: compare versions, read release99fixed in a release newer than the version the bug happened on: compare versions,
86notes and recent commits touching the relevant code.100read release notes and recent commits touching the relevant code.
87101
88If the user is behind and the fix likely shipped, say so plainly and give them the102If the user is behind and the fix likely shipped, say so plainly and give them the
89exact update command for how they run the CLI (the context file records how it was103exact update command for how they run the CLI (the context file records how it was
...@@ -105,6 +119,8 @@ of `main` for that work, never the tag-pinned diagnosis clone....@@ -105,6 +119,8 @@ of `main` for that work, never the tag-pinned diagnosis clone.
105- Match the structure of the `via-triage` issue template119- Match the structure of the `via-triage` issue template
106 (`.github/ISSUE_TEMPLATE/via-triage.yml` in the repo): what happened, diagnosis,120 (`.github/ISSUE_TEMPLATE/via-triage.yml` in the repo): what happened, diagnosis,
107 repro steps, environment, evidence, related issues.121 repro steps, environment, evidence, related issues.
122- Under Version, give the version the bug happened on from step 4, or say it is
123 unknown. Name the triage CLI version only as the CLI's.
108- Label it `via-triage`. Use a plain, specific title with no prefix.124- Label it `via-triage`. Use a plain, specific title with no prefix.
109- Show the user the complete final issue text and get an explicit yes before125- Show the user the complete final issue text and get an explicit yes before
110 posting. Never post without it.126 posting. Never post without it.
apps/server/src/cli/triage.test.ts created+62
...@@ -0,0 +1,62 @@
1import * as NodeServices from "@effect/platform-node/NodeServices";
2import { assert, it } from "@effect/vitest";
3import * as Effect from "effect/Effect";
4import * as FileSystem from "effect/FileSystem";
5import * as Path from "effect/Path";
6
7import packageJson from "../../package.json" with { type: "json" };
8import {
9 makePersistedServerRuntimeState,
10 persistServerRuntimeState,
11} from "../serverRuntimeState.ts";
12import { describeServerProcess } from "./triage.ts";
13
14it.effect("reports the version the running server recorded, not the CLI's", () =>
15 Effect.gen(function* () {
16 const fs = yield* FileSystem.FileSystem;
17 const path = yield* Path.Path;
18 const statePath = path.join(
19 yield* fs.makeTempDirectoryScoped({ prefix: "t3-triage-" }),
20 "server-runtime.json",
21 );
22 // The test process stands in for the server, so its pid is alive.
23 const state = yield* makePersistedServerRuntimeState({
24 config: { host: undefined, devUrl: undefined },
25 port: 3773,
26 });
27 yield* persistServerRuntimeState({ path: statePath, state });
28
29 assert.equal(
30 yield* describeServerProcess(statePath),
31 `running (pid ${String(process.pid)}, http://127.0.0.1:3773, version ${packageJson.version})`,
32 );
33 }).pipe(Effect.provide(NodeServices.layer)),
34);
35
36it.effect("says the server version is unknown when the state file has none", () =>
37 Effect.gen(function* () {
38 const fs = yield* FileSystem.FileSystem;
39 const path = yield* Path.Path;
40 const statePath = path.join(
41 yield* fs.makeTempDirectoryScoped({ prefix: "t3-triage-" }),
42 "server-runtime.json",
43 );
44 // A server from before versions were recorded, such as the 0.0.43 desktop
45 // app in #13337.
46 yield* fs.writeFileString(
47 statePath,
48 JSON.stringify({
49 version: 1,
50 pid: process.pid,
51 port: 3773,
52 origin: "http://127.0.0.1:3773",
53 startedAt: "2026-09-24T00:08:56.777Z",
54 }),
55 );
56
57 assert.equal(
58 yield* describeServerProcess(statePath),
59 `running (pid ${String(process.pid)}, http://127.0.0.1:3773, version not recorded)`,
60 );
61 }).pipe(Effect.provide(NodeServices.layer)),
62);
apps/server/src/cli/triage.ts+13-10
...@@ -2,7 +2,7 @@...@@ -2,7 +2,7 @@
2 * `t3 triage` - hand a misbehaving install to the user's own coding agent.2 * `t3 triage` - hand a misbehaving install to the user's own coding agent.
3 *3 *
4 * The command is deliberately thin: it writes a `context.md` with machine facts4 * The command is deliberately thin: it writes a `context.md` with machine facts
5 * (version, paths, server liveness), then launches claude or codex5 * (versions, paths, server liveness), then launches claude or codex
6 * interactively, seeded with the playbook from `triagePrompt.ts`. The agent6 * interactively, seeded with the playbook from `triagePrompt.ts`. The agent
7 * asks the user what went wrong, investigates, and files the issue; the7 * asks the user what went wrong, investigates, and files the issue; the
8 * harness's own permission prompts gate anything it wants to run. With no8 * harness's own permission prompts gate anything it wants to run. With no
...@@ -77,8 +77,11 @@ export class TriageAgentSpawnError extends Schema.TaggedError<TriageAgentSpawnEr...@@ -77,8 +77,11 @@ export class TriageAgentSpawnError extends Schema.TaggedError<TriageAgentSpawnEr
77 }77 }
78}78}
7979
80/** One human-readable line about the local server, for `context.md`. */80/**
81const describeServerProcess = Effect.fn("triage.describeServerProcess")(function* (81 * One human-readable line about the local server, for `context.md`. Includes
82 * the version the server recorded, which can differ from this CLI's version.
83 */
84export const describeServerProcess = Effect.fn("triage.describeServerProcess")(function* (
82 serverRuntimeStatePath: string,85 serverRuntimeStatePath: string,
83) {86) {
84 // readPersistedServerRuntimeState swallows read/decode failures itself and87 // readPersistedServerRuntimeState swallows read/decode failures itself and
...@@ -87,10 +90,14 @@ const describeServerProcess = Effect.fn("triage.describeServerProcess")(function...@@ -87,10 +90,14 @@ const describeServerProcess = Effect.fn("triage.describeServerProcess")(function
87 if (Option.isNone(state)) {90 if (Option.isNone(state)) {
88 return "not running (no server-runtime.json; the server may never have started here)";91 return "not running (no server-runtime.json; the server may never have started here)";
89 }92 }
93 const version =
94 state.value.serverVersion === undefined
95 ? "version not recorded"
96 : `version ${state.value.serverVersion}`;
90 if (!isProcessAlive(state.value.pid)) {97 if (!isProcessAlive(state.value.pid)) {
91 return `not running (state file is stale: pid ${String(state.value.pid)} is dead; last origin ${state.value.origin})`;98 return `not running (state file is stale: pid ${String(state.value.pid)} is dead; last origin ${state.value.origin}, ${version})`;
92 }99 }
93 return `running (pid ${String(state.value.pid)}, ${state.value.origin})`;100 return `running (pid ${String(state.value.pid)}, ${state.value.origin}, ${version})`;
94});101});
95102
96const pickAgent = (agents: ReadonlyArray<TriageAgent>) =>103const pickAgent = (agents: ReadonlyArray<TriageAgent>) =>
...@@ -183,16 +190,12 @@ export const triageCommand = Command.make("triage", {...@@ -183,16 +190,12 @@ export const triageCommand = Command.make("triage", {
183 );190 );
184 yield* fs.makeDirectory(scratchDir, { recursive: true });191 yield* fs.makeDirectory(scratchDir, { recursive: true });
185192
186 const version = packageJson.version;
187 const contextFilePath = path.join(scratchDir, "context.md");193 const contextFilePath = path.join(scratchDir, "context.md");
188 yield* fs.writeFileString(194 yield* fs.writeFileString(
189 contextFilePath,195 contextFilePath,
190 buildTriageContext({196 buildTriageContext({
191 generatedAt: DateTime.formatIso(now),197 generatedAt: DateTime.formatIso(now),
192 version,198 cliVersion: packageJson.version,
193 releaseTag: /^[^-+]+-(?:nightly|preview)\./.test(version)
194 ? `v${version} (prerelease build; if this tag does not exist, clone main)`
195 : `v${version}`,
196 os: `${yield* HostProcess.Platform} ${yield* HostProcess.Architecture} (${NodeOS.release()})`,199 os: `${yield* HostProcess.Platform} ${yield* HostProcess.Architecture} (${NodeOS.release()})`,
197 nodeVersion: process.version,200 nodeVersion: process.version,
198 launchedAs: yield* resolveCliCommand("triage"),201 launchedAs: yield* resolveCliCommand("triage"),
apps/server/src/cli/triagePrompt.test.ts+32-3
...@@ -41,8 +41,7 @@ it("launch prompt stays a single argv-safe line naming the prompt file", () => {...@@ -41,8 +41,7 @@ it("launch prompt stays a single argv-safe line naming the prompt file", () => {
41it("context file carries every path the playbook depends on", () => {41it("context file carries every path the playbook depends on", () => {
42 const context = buildTriageContext({42 const context = buildTriageContext({
43 generatedAt: "2026-08-13T00:00:00.000Z",43 generatedAt: "2026-08-13T00:00:00.000Z",
44 version: "0.0.33",44 cliVersion: "0.0.33",
45 releaseTag: "v0.0.33",
46 os: "linux x64 (7.0.0)",45 os: "linux x64 (7.0.0)",
47 nodeVersion: "v24.0.0",46 nodeVersion: "v24.0.0",
48 launchedAs: "npx t3 triage",47 launchedAs: "npx t3 triage",
...@@ -70,5 +69,35 @@ it("context file carries every path the playbook depends on", () => {...@@ -70,5 +69,35 @@ it("context file carries every path the playbook depends on", () => {
70 assert.include(context, "/home/u/.t3/userdata/secrets");69 assert.include(context, "/home/u/.t3/userdata/secrets");
71 assert.include(context, "/home/u/.t3/source");70 assert.include(context, "/home/u/.t3/source");
72 assert.include(context, "npx t3 triage");71 assert.include(context, "npx t3 triage");
73 assert.include(context, "v0.0.33");72});
73
74it("context file labels the CLI version as the CLI's, not the user's build", () => {
75 // `npx t3 triage` can resolve a different `t3` than the app the bug
76 // happened on (#13337), so the agent must not read it as the user's version.
77 const context = buildTriageContext({
78 generatedAt: "2026-09-24T00:00:00.000Z",
79 cliVersion: "0.0.42",
80 os: "linux x64 (7.2.0)",
81 nodeVersion: "v26.8.2",
82 launchedAs: "npx t3 triage",
83 server: "running (pid 42, http://127.0.0.1:3773, version 0.0.43-nightly.20260923.2173)",
84 paths: {
85 stateDir: "/home/u/.t3/userdata",
86 dbPath: "/home/u/.t3/userdata/state.sqlite",
87 settingsPath: "/home/u/.t3/userdata/settings.json",
88 logsDir: "/home/u/.t3/userdata/logs",
89 serviceLogPath: "/home/u/.t3/userdata/logs/boot-service.log",
90 desktopBackendLogGlob: "/home/u/.t3/userdata/logs/server-child*.log*",
91 serverTracePath: "/home/u/.t3/userdata/logs/server.trace.ndjson",
92 providerEventLogPath: "/home/u/.t3/userdata/logs/provider/events.log",
93 terminalLogsDir: "/home/u/.t3/userdata/logs/terminals",
94 providerStatusCacheDir: "/home/u/.t3/caches",
95 secretsDir: "/home/u/.t3/userdata/secrets",
96 sourceCacheDir: "/home/u/.t3/source",
97 },
98 });
99 assert.notInclude(context, "Installed version");
100 assert.notInclude(context, "Release tag");
101 assert.include(context, "- Triage CLI version: 0.0.42 (");
102 assert.include(context, "version 0.0.43-nightly.20260923.2173");
74});103});
apps/server/src/cli/triagePrompt.ts+27-13
...@@ -18,7 +18,7 @@ crashes, auth failures, broken setups, slow launches, or anything else. Your job...@@ -18,7 +18,7 @@ crashes, auth failures, broken setups, slow launches, or anything else. Your job
18find out what went wrong, unblock the user if you can, and turn what you learned into18find out what went wrong, unblock the user if you can, and turn what you learned into
19a well written GitHub issue when one is warranted.19a well written GitHub issue when one is warranted.
2020
21A triage context file with machine facts (version, OS, paths, server liveness) was21A triage context file with machine facts (versions, OS, paths, server liveness) was
22provided alongside this playbook. Everything machine-specific lives there, not here.22provided alongside this playbook. Everything machine-specific lives there, not here.
2323
24## 1. Ask what went wrong24## 1. Ask what went wrong
...@@ -30,9 +30,15 @@ valuable thing you can extract from this conversation....@@ -30,9 +30,15 @@ valuable thing you can extract from this conversation.
3030
31## 2. Read the machine facts31## 2. Read the machine facts
3232
33Read the triage context file before investigating. It tells you the installed33Read the triage context file before investigating. It tells you the OS, whether
34version, the OS, whether the server process is currently running, and the exact34the server process is currently running, and the exact paths for state, logs, and
35paths for state, logs, and the database.35the database.
36
37Its triage CLI version (called "Installed version" in older context files) is only
38the version of the \`t3\` that ran \`t3 triage\`. It is often not the build the bug
39happened on: \`npx t3 triage\` runs whatever \`t3\` npm resolves, while the user may
40run the desktop app, the background service, or a nightly. The server process line
41gives the local server's version when the server recorded one.
3642
37## 3. Check for a newer playbook43## 3. Check for a newer playbook
3844
...@@ -42,8 +48,16 @@ instead of this one. The user may be on an old release with an old copy....@@ -42,8 +48,16 @@ instead of this one. The user may be on an old release with an old copy.
4248
43## 4. Get the source49## 4. Get the source
4450
45Clone the repo at the tag matching the user's installed version, into the source51Before cloning, ask the user which version, device, and surface the bug happened
46cache directory named in the context file, one subdirectory per commit hash:52on. The bug may have happened on another machine, a remote server, the mobile app,
53or an older build they have since updated. Check their answer against local facts
54where they apply: the server version in the context file, or \`serverVersion\` from
55\`<origin>/.well-known/t3/environment\` when a local server is running. If neither
56the user nor the machine can tell you the version, say it is unknown. Do not guess.
57
58Clone the repo at the release tag for that version (\`v\` followed by the version,
59such as \`v0.0.42\`), into the source cache directory named in the context file,
60one subdirectory per commit hash:
4761
48 git clone --depth 1 --filter=blob:none --branch <release-tag> \\62 git clone --depth 1 --filter=blob:none --branch <release-tag> \\
49 https://github.com/pingdotgg/t3code <source-cache-dir>/<hash>63 https://github.com/pingdotgg/t3code <source-cache-dir>/<hash>
...@@ -94,8 +108,8 @@ comes from this repo's \`main\` branch....@@ -94,8 +108,8 @@ comes from this repo's \`main\` branch.
94108
95Search existing issues in pingdotgg/t3code (use \`gh\`, or the public GitHub search109Search existing issues in pingdotgg/t3code (use \`gh\`, or the public GitHub search
96API if \`gh\` is missing or not logged in). Then check whether the problem is already110API if \`gh\` is missing or not logged in). Then check whether the problem is already
97fixed in a release newer than the user's version: compare versions, read release111fixed in a release newer than the version the bug happened on: compare versions,
98notes and recent commits touching the relevant code.112read release notes and recent commits touching the relevant code.
99113
100If the user is behind and the fix likely shipped, say so plainly and give them the114If the user is behind and the fix likely shipped, say so plainly and give them the
101exact update command for how they run the CLI (the context file records how it was115exact update command for how they run the CLI (the context file records how it was
...@@ -117,6 +131,8 @@ of \`main\` for that work, never the tag-pinned diagnosis clone....@@ -117,6 +131,8 @@ of \`main\` for that work, never the tag-pinned diagnosis clone.
117- Match the structure of the \`via-triage\` issue template131- Match the structure of the \`via-triage\` issue template
118 (\`.github/ISSUE_TEMPLATE/via-triage.yml\` in the repo): what happened, diagnosis,132 (\`.github/ISSUE_TEMPLATE/via-triage.yml\` in the repo): what happened, diagnosis,
119 repro steps, environment, evidence, related issues.133 repro steps, environment, evidence, related issues.
134- Under Version, give the version the bug happened on from step 4, or say it is
135 unknown. Name the triage CLI version only as the CLI's.
120- Label it \`via-triage\`. Use a plain, specific title with no prefix.136- Label it \`via-triage\`. Use a plain, specific title with no prefix.
121- Show the user the complete final issue text and get an explicit yes before137- Show the user the complete final issue text and get an explicit yes before
122 posting. Never post without it.138 posting. Never post without it.
...@@ -153,7 +169,7 @@ export const buildTriageLaunchPrompt = (promptFilePath: string) =>...@@ -153,7 +169,7 @@ export const buildTriageLaunchPrompt = (promptFilePath: string) =>
153export const buildTriageSeedPrompt = (contextFilePath: string) => `A T3 Code user is \169export const buildTriageSeedPrompt = (contextFilePath: string) => `A T3 Code user is \
154having a problem with their install and started this session with \`t3 triage\`.170having a problem with their install and started this session with \`t3 triage\`.
155171
156Machine facts (version, OS, paths, server liveness) are in the triage context file:172Machine facts (versions, OS, paths, server liveness) are in the triage context file:
157173
158 ${contextFilePath}174 ${contextFilePath}
159175
...@@ -166,8 +182,7 @@ ${TRIAGE_PLAYBOOK}`;...@@ -166,8 +182,7 @@ ${TRIAGE_PLAYBOOK}`;
166/** Machine facts for one triage run, pre-formatted so the template stays plain. */182/** Machine facts for one triage run, pre-formatted so the template stays plain. */
167export interface TriageContextInput {183export interface TriageContextInput {
168 readonly generatedAt: string;184 readonly generatedAt: string;
169 readonly version: string;185 readonly cliVersion: string;
170 readonly releaseTag: string;
171 readonly os: string;186 readonly os: string;
172 readonly nodeVersion: string;187 readonly nodeVersion: string;
173 readonly launchedAs: string;188 readonly launchedAs: string;
...@@ -193,8 +208,7 @@ export const buildTriageContext = (input: TriageContextInput) => `# T3 Code tria...@@ -193,8 +208,7 @@ export const buildTriageContext = (input: TriageContextInput) => `# T3 Code tria
193208
194Generated by \`t3 triage\` at ${input.generatedAt}.209Generated by \`t3 triage\` at ${input.generatedAt}.
195210
196- Installed version: ${input.version}211- Triage CLI version: ${input.cliVersion} (the \`t3\` that ran this command; the bug may have happened on another build)
197- Release tag for this version: ${input.releaseTag}
198- OS: ${input.os}212- OS: ${input.os}
199- Node: ${input.nodeVersion}213- Node: ${input.nodeVersion}
200- CLI launched as: ${input.launchedAs}214- CLI launched as: ${input.launchedAs}
apps/server/src/serverRuntimeState.ts+9
...@@ -5,10 +5,12 @@ import * as Option from "effect/Option";...@@ -5,10 +5,12 @@ import * as Option from "effect/Option";
5import * as Schema from "effect/Schema";5import * as Schema from "effect/Schema";
66
7import { writeFileStringAtomically } from "@t3tools/shared/atomicWrite";7import { writeFileStringAtomically } from "@t3tools/shared/atomicWrite";
8import packageJson from "../package.json" with { type: "json" };
8import type * as ServerConfig from "./config.ts";9import type * as ServerConfig from "./config.ts";
9import { formatHostForUrl, isWildcardHost } from "./startupAccess.ts";10import { formatHostForUrl, isWildcardHost } from "./startupAccess.ts";
1011
11export const PersistedServerRuntimeState = Schema.Struct({12export const PersistedServerRuntimeState = Schema.Struct({
13 // Schema version of this file, not the server build. See `serverVersion`.
12 version: Schema.Literal(1),14 version: Schema.Literal(1),
13 pid: Schema.Int,15 pid: Schema.Int,
14 ownerId: Schema.optional(Schema.String),16 ownerId: Schema.optional(Schema.String),
...@@ -25,6 +27,12 @@ export const PersistedServerRuntimeState = Schema.Struct({...@@ -25,6 +27,12 @@ export const PersistedServerRuntimeState = Schema.Struct({
25 * the difference between "restart the service" and "stop your terminal".27 * the difference between "restart the service" and "stop your terminal".
26 */28 */
27 serviceManaged: Schema.optional(Schema.Boolean),29 serviceManaged: Schema.optional(Schema.Boolean),
30 /**
31 * The server build that wrote this record. `t3 triage` reports it because
32 * the CLI that runs triage can be a different build. Missing on records
33 * written by older servers.
34 */
35 serverVersion: Schema.optional(Schema.String),
28});36});
29export type PersistedServerRuntimeState = typeof PersistedServerRuntimeState.Type;37export type PersistedServerRuntimeState = typeof PersistedServerRuntimeState.Type;
3038
...@@ -68,6 +76,7 @@ export const makePersistedServerRuntimeState = (input: {...@@ -68,6 +76,7 @@ export const makePersistedServerRuntimeState = (input: {
68 ...(input.config.devUrl ? { devUrl: input.config.devUrl.toString() } : {}),76 ...(input.config.devUrl ? { devUrl: input.config.devUrl.toString() } : {}),
69 startedAt: DateTime.formatIso(now),77 startedAt: DateTime.formatIso(now),
70 ...(input.serviceManaged ? { serviceManaged: true } : {}),78 ...(input.serviceManaged ? { serviceManaged: true } : {}),
79 serverVersion: packageJson.version,
71 }));80 }));
7281
73export const persistServerRuntimeState = (input: {82export const persistServerRuntimeState = (input: {