@cmmd-center/forge 0.10.4 → 0.10.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/dist/bin.cjs +106 -37
  2. package/dist/bin.mjs +129 -60
  3. package/dist/client/assets/{CanvasPanel-BYsK8tAq.js → CanvasPanel-Dr4I7MnM.js} +2 -2
  4. package/dist/client/assets/{CompositeItem-khilqBJh.js → CompositeItem-Cj6_oAlz.js} +2 -2
  5. package/dist/client/assets/{DiffPanel-CrG7-Qe5.js → DiffPanel-njtnlFro.js} +3 -3
  6. package/dist/client/assets/{DiffPanel.logic--xX71t7M.js → DiffPanel.logic-BiWRNb4k.js} +2 -2
  7. package/dist/client/assets/{DiffPanelShell-CSeG4SSQ.js → DiffPanelShell-AKUK0L-g.js} +33 -33
  8. package/dist/client/assets/{DiffWorkerPoolProvider-C1s-wxqS.js → DiffWorkerPoolProvider-DWrja16U.js} +51 -51
  9. package/dist/client/assets/PullRequestCodePanel-CAaq9dk8.js +5 -0
  10. package/dist/client/assets/{Virtualizer-BaEpKPBi.js → Virtualizer-BXpiamky.js} +2 -2
  11. package/dist/client/assets/{canvasStateStore-CVTcDwc2.js → canvasStateStore-DncdOQ4J.js} +2 -2
  12. package/dist/client/assets/{cmmdAuthRedirect-B6WFFIw6.js → cmmdAuthRedirect-DWiMDVzN.js} +2 -2
  13. package/dist/client/assets/index-DBIIL0ML.js +151 -0
  14. package/dist/client/assets/index-T36rURmx.css +1 -0
  15. package/dist/client/assets/src-CtyKlVph.js +3 -0
  16. package/dist/client/assets/{toggle-DnYrc2U3.js → toggle-pTm2fPLg.js} +2 -2
  17. package/dist/client/assets/{useTriggerFocusGuards-CVcUEajo.js → useTriggerFocusGuards-B4Ejoaox.js} +2 -2
  18. package/dist/client/index.html +11 -11
  19. package/dist/forge-build.json +1 -1
  20. package/dist/{open-FIgTDosf.mjs → open-D8mGyWmt.mjs} +3 -3
  21. package/package.json +1 -1
  22. package/dist/client/assets/PullRequestCodePanel-CDmYMNEt.js +0 -5
  23. package/dist/client/assets/index-DB-C-45R.css +0 -1
  24. package/dist/client/assets/index-zQmFiQS7.js +0 -151
  25. package/dist/client/assets/src-BSCF6BY3.js +0 -3
package/dist/bin.cjs CHANGED
@@ -16544,7 +16544,7 @@ function makeNetServiceShape(createServer = node_net.createServer) {
16544
16544
  }
16545
16545
  //#endregion
16546
16546
  //#region ../../packages/shared/src/releaseInfo.generated.ts
16547
- const FORGE_RELEASE_VERSION = "0.10.3";
16547
+ const FORGE_RELEASE_VERSION = "0.10.4";
16548
16548
  //#endregion
16549
16549
  //#region ../../packages/shared/src/hostProcess.ts
16550
16550
  /**
@@ -18213,6 +18213,7 @@ const ExecutionEnvironmentDescriptor = require_Schema$1.Struct({
18213
18213
  platform: ExecutionEnvironmentPlatform,
18214
18214
  serverVersion: TrimmedNonEmptyString,
18215
18215
  buildCommit: require_Schema$1.optional(TrimmedNonEmptyString),
18216
+ deviceRuntimeId: require_Schema$1.optional(TrimmedNonEmptyString),
18216
18217
  capabilities: ExecutionEnvironmentCapabilities
18217
18218
  });
18218
18219
  require_Schema$1.Literals([
@@ -22079,6 +22080,7 @@ const ClientSettingsSchema = require_Schema$1.Struct({
22079
22080
  confirmThreadArchive: require_Schema$1.Boolean.pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed(true))),
22080
22081
  confirmThreadDelete: require_Schema$1.Boolean.pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed(true))),
22081
22082
  showInteractionModeToggle: require_Schema$1.Boolean.pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed(false))),
22083
+ composerCollapseOnBlur: require_Schema$1.Boolean.pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed(true))),
22082
22084
  diffWordWrap: require_Schema$1.Boolean.pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed(true))),
22083
22085
  previewAutoOpen: require_Schema$1.Boolean.pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed(false))),
22084
22086
  previewRememberLastUrl: require_Schema$1.Boolean.pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed(true))),
@@ -26338,7 +26340,7 @@ function acceptCmmdProjectPatchField(field, raw) {
26338
26340
  //#region ../../packages/contracts/src/cloud.ts
26339
26341
  /**
26340
26342
  * One entry returned by `GET /api/cloud/available-folders` — a candidate
26341
- * subdirectory of the managed runtime's `cloudProjectsRoot` (typically `/data/Projects`)
26343
+ * subdirectory of the managed runtime's `cloudProjectsRoot` (typically `/projects`)
26342
26344
  * that the SPA can offer in the cloud-mode "Register existing folder" picker.
26343
26345
  */
26344
26346
  const CloudAvailableFolder = require_Schema$1.Struct({
@@ -65376,7 +65378,7 @@ function normalizeNumberish(value) {
65376
65378
  }
65377
65379
  //#endregion
65378
65380
  //#region package.json
65379
- var version$1 = "0.10.4";
65381
+ var version$1 = "0.10.6";
65380
65382
  //#endregion
65381
65383
  //#region src/sentry.ts
65382
65384
  const SERVER_APP_NAME = "forge-server";
@@ -68161,6 +68163,15 @@ function parsePersistedServerObservabilitySettings(raw) {
68161
68163
  * @module ServerConfig
68162
68164
  */
68163
68165
  const DEFAULT_PORT = 13773;
68166
+ /**
68167
+ * Where a managed cloud runtime keeps the user's checkouts when
68168
+ * FORGE_CLOUD_PROJECTS_ROOT is not set. CMMD seeds every sprite checkout under
68169
+ * /projects (forge-guest-layout.ts on the CMMD side) and passes that value in
68170
+ * the Service env, so this default only matters for a server started without
68171
+ * it. It used to be a path under the Fly-era mounted volume; on a sprite the
68172
+ * two repos disagreed and every local-checkout turn was refused (FOR-36484).
68173
+ */
68174
+ const DEFAULT_CLOUD_PROJECTS_ROOT = "/projects";
68164
68175
  const RuntimeMode = require_Schema$1.Literals(["web", "desktop"]);
68165
68176
  require_Schema$1.Literals(["browser", "headless"]);
68166
68177
  const deriveServerPaths = require_Schema$1.fn(function* (baseDir, _devUrl, _mode) {
@@ -68286,7 +68297,7 @@ var ServerConfig = class ServerConfig extends require_Schema$1.Service()("forge/
68286
68297
  forgeCodexHomePath: void 0,
68287
68298
  forgeClaudeConfigPath: void 0,
68288
68299
  forgeApexBaseUrl: void 0,
68289
- cloudProjectsRoot: "/data/Projects",
68300
+ cloudProjectsRoot: DEFAULT_CLOUD_PROJECTS_ROOT,
68290
68301
  ...overrides
68291
68302
  };
68292
68303
  }));
@@ -97489,7 +97500,7 @@ const resolveAutoBootstrapWelcomeTargets = require_Schema$1.gen(function* () {
97489
97500
  /**
97490
97501
  * Cloud-mode project recovery — runs only on cloud execution runtimes.
97491
97502
  * Scans `cloudProjectsRoot` (default
97492
- * /data/Projects) for git-repo subdirectories and registers any not yet in
97503
+ * /projects) for git-repo subdirectories and registers any not yet in
97493
97504
  * the orchestration engine. This is the cloud-mode replacement for the
97494
97505
  * gated `autoBootstrapProjectFromCwd` path: managed runtimes whose volume
97495
97506
  * already holds cloned repos surface them in the sidebar after restart.
@@ -149778,13 +149789,40 @@ var CodexAppServerManager = class extends node_events.EventEmitter {
149778
149789
  if (!providerConversationId) return;
149779
149790
  return context.collabReceiverTurns.get(providerConversationId);
149780
149791
  }
149792
+ /**
149793
+ * The child threads one thread item says the turn spawned.
149794
+ *
149795
+ * Two item shapes name a child, and which one arrives depends on the Codex
149796
+ * build. `CollabAgentToolCallThreadItem` lists `receiverThreadIds`, which
149797
+ * "in case of spawn operation ... corresponds to the newly spawned agent".
149798
+ * `SubAgentActivityThreadItem` names a single `agentThreadId` and is what a
149799
+ * `spawn_agent` call reports on codex-cli 0.152/0.153: measured on the
149800
+ * packaged desktop on 2026-09-06, the spawn arrived as `SubAgentActivity`
149801
+ * (`kind: started`) and the only collab tool call that followed was the
149802
+ * `wait`, whose `receiverThreadIds` was empty. Reading only the collab item
149803
+ * left the child unmapped, so its spend was published as a second turn row
149804
+ * under the child's own turn id instead of a subagent row under the parent's.
149805
+ *
149806
+ * `SubAgentActivityThreadItem` has no `model` field, so a `completed` report
149807
+ * for a child a collab call already named must not blank the model out; the
149808
+ * caller's `model ?? known` merge is what keeps it.
149809
+ */
149810
+ readSpawnedThreadIds(item, itemType) {
149811
+ if (itemType === "subAgentActivity") {
149812
+ const agentThreadId = this.readString(item, "agentThreadId");
149813
+ return agentThreadId ? [agentThreadId] : [];
149814
+ }
149815
+ if (itemType !== "collabAgentToolCall") return [];
149816
+ return this.readArray(item, "receiverThreadIds")?.map((value) => typeof value === "string" ? value : null).filter((value) => value !== null) ?? [];
149817
+ }
149781
149818
  rememberCollabReceiverTurns(context, params, parentTurnId) {
149782
149819
  if (!parentTurnId) return;
149783
149820
  const payload = this.readObject(params);
149784
149821
  const item = this.readObject(payload, "item") ?? payload;
149785
- if ((this.readString(item, "type") ?? this.readString(item, "kind")) !== "collabAgentToolCall") return;
149822
+ const itemType = this.readString(item, "type") ?? this.readString(item, "kind");
149823
+ const receiverThreadIds = this.readSpawnedThreadIds(item, itemType);
149824
+ if (receiverThreadIds.length === 0) return;
149786
149825
  const model = this.readString(item, "model");
149787
- const receiverThreadIds = this.readArray(item, "receiverThreadIds")?.map((value) => typeof value === "string" ? value : null).filter((value) => value !== null) ?? [];
149788
149826
  for (const receiverThreadId of receiverThreadIds) {
149789
149827
  const known = context.collabReceiverTurns.get(receiverThreadId)?.model;
149790
149828
  const resolved = model ?? known;
@@ -149800,8 +149838,8 @@ var CodexAppServerManager = class extends node_events.EventEmitter {
149800
149838
  * Codex reports a child thread's tokens on the parent's own connection:
149801
149839
  * `ThreadTokenUsageUpdatedNotification` requires `threadId` and `turnId` and
149802
149840
  * names the child thread for a child, and `Thread.parentThreadId` is "only
149803
- * set if this thread is a subagent" (codex 0.144.6 app-server protocol
149804
- * schema). Every other child notification is suppressed so it cannot replace
149841
+ * set if this thread is a subagent" (still true of the codex-cli 0.153
149842
+ * app-server protocol schema). Every other child notification is suppressed so it cannot replace
149805
149843
  * the parent turn; this one is not, because the tokens belong on the ledger.
149806
149844
  * The method is Forge's own rather than the protocol's, because the payload
149807
149845
  * carries what the Usage row needs rather than what the notification held.
@@ -207597,11 +207635,14 @@ function mapCodexThreadTokenUsageEvent(event, canonicalThreadId, payload) {
207597
207635
  *
207598
207636
  * The source is the live app-server protocol, not a rollout read: Codex sends
207599
207637
  * `thread/tokenUsage/updated` for a child thread on the parent's own
207600
- * connection (0.144.6 schema: `ThreadTokenUsageUpdatedNotification` requires
207601
- * `threadId` and `turnId`, `Thread.parentThreadId` is set only for a subagent,
207602
- * and `CollabAgentToolCallThreadItem` names `receiverThreadIds` and the
207603
- * spawned agent's `model`), and `codexAppServerManager` already tracked those
207604
- * child threads to route their notifications onto the parent turn.
207638
+ * connection (`ThreadTokenUsageUpdatedNotification` requires `threadId` and
207639
+ * `turnId`, and `Thread.parentThreadId` is set only for a subagent), and
207640
+ * `codexAppServerManager` already tracked those child threads to route their
207641
+ * notifications onto the parent turn. It learns a child from whichever item
207642
+ * the running Codex build uses to announce a spawn: the
207643
+ * `receiverThreadIds` of a `CollabAgentToolCallThreadItem`, which also names
207644
+ * the spawned agent's `model`, or the `agentThreadId` of a
207645
+ * `SubAgentActivityThreadItem`, which names no model.
207605
207646
  *
207606
207647
  * The row carries no context-meter snapshot and no `turnUsage`: the parent's
207607
207648
  * own row is never re-summed with its children. It carries the call's delta
@@ -208488,7 +208529,8 @@ const CODE_BY_UPSTREAM_REASON$1 = {
208488
208529
  credential_expired_refreshing: "CREDENTIAL_EXPIRED_REFRESHING",
208489
208530
  credential_reconnect_required: "CREDENTIAL_RECONNECT_REQUIRED",
208490
208531
  credential_not_connected: "CREDENTIAL_RECONNECT_REQUIRED",
208491
- credential_generation_not_applied: "CREDENTIAL_GENERATION_NOT_APPLIED"
208532
+ credential_generation_not_applied: "CREDENTIAL_GENERATION_NOT_APPLIED",
208533
+ runtime_unavailable: "RUNTIME_UNAVAILABLE"
208492
208534
  };
208493
208535
  const CLAUDE_NATIVE_CREDENTIAL_UNUSABLE_COPY = "The delivered Claude credential is unavailable or unusable in this runtime.";
208494
208536
  /**
@@ -208551,10 +208593,17 @@ function claudeNativeCredentialUnusableMessage() {
208551
208593
  * CMMD writes this marker when it activates a personal Claude subscription
208552
208594
  * inside a running sprite. Activation always happens after boot, so a
208553
208595
  * boot-time env var alone cannot reflect it (FOR-36249).
208596
+ *
208597
+ * CMMD names the file in the Service env (FORGE_PERSONAL_CLAUDE_MARKER_PATH).
208598
+ * Without that, the marker sits directly under FORGE_HOME, which is the same
208599
+ * guest home CMMD derives every sprite path from. A server with neither has no
208600
+ * sprite home to look in, and a desktop never has a marker, so it reads none.
208554
208601
  */
208555
- const PERSONAL_CLAUDE_IN_VM_MARKER_PATH = "/data/.forge-personal-claude-in-vm";
208602
+ const PERSONAL_CLAUDE_IN_VM_MARKER_NAME = ".forge-personal-claude-in-vm";
208556
208603
  function markerPath(env) {
208557
- return env.FORGE_PERSONAL_CLAUDE_MARKER_PATH || PERSONAL_CLAUDE_IN_VM_MARKER_PATH;
208604
+ if (env.FORGE_PERSONAL_CLAUDE_MARKER_PATH) return env.FORGE_PERSONAL_CLAUDE_MARKER_PATH;
208605
+ if (env.FORGE_HOME) return (0, node_path.join)(env.FORGE_HOME, PERSONAL_CLAUDE_IN_VM_MARKER_NAME);
208606
+ return null;
208558
208607
  }
208559
208608
  /**
208560
208609
  * True when this runtime should offer the personal Claude subscription lane.
@@ -208567,8 +208616,10 @@ function markerPath(env) {
208567
208616
  */
208568
208617
  function personalClaudeInVmEnabled(env = process.env) {
208569
208618
  if (env.FORGE_PERSONAL_CLAUDE_IN_VM === "true") return true;
208619
+ const marker = markerPath(env);
208620
+ if (!marker) return false;
208570
208621
  try {
208571
- return (0, node_fs.existsSync)(markerPath(env));
208622
+ return (0, node_fs.existsSync)(marker);
208572
208623
  } catch {
208573
208624
  return false;
208574
208625
  }
@@ -227179,7 +227230,8 @@ const CLAUDE_READINESS_COPY = {
227179
227230
  failed: "Claude native runtime setup could not be applied. Reconnect Claude in Settings.",
227180
227231
  invalid: "Claude native runtime readiness is no longer valid. Reconnect Claude in Settings.",
227181
227232
  unavailable: "Claude native runtime readiness could not be verified.",
227182
- generationMismatch: "Claude native runtime generation does not match CMMD readiness."
227233
+ generationMismatch: "Claude native runtime generation does not match CMMD readiness.",
227234
+ environmentUnavailable: "This Environment is not running, so Claude cannot run on it. Restart the Environment, then try again."
227183
227235
  };
227184
227236
  var ClaudeRuntimeReadinessError = class extends Error {
227185
227237
  constructor(safeIssue, retryable = false, retryProfile = "default") {
@@ -227249,6 +227301,7 @@ async function withReadinessRetry(attempt) {
227249
227301
  */
227250
227302
  function readinessReasonIssue(readiness) {
227251
227303
  const code = claudeReadinessReasonCode(readiness.reason);
227304
+ if (code === "RUNTIME_UNAVAILABLE") return CLAUDE_READINESS_COPY.environmentUnavailable;
227252
227305
  if (code === "CREDENTIAL_RECONNECT_REQUIRED") return CLAUDE_READINESS_COPY.invalid;
227253
227306
  if (code === "CREDENTIAL_GENERATION_NOT_APPLIED") return CLAUDE_READINESS_COPY.applying;
227254
227307
  if (code !== "CREDENTIAL_EXPIRED_REFRESHING") return null;
@@ -227259,6 +227312,10 @@ function readinessReasonIssue(readiness) {
227259
227312
  function isCredentialRefreshInFlight(readiness) {
227260
227313
  return claudeReadinessReasonCode(readiness.reason) === "CREDENTIAL_EXPIRED_REFRESHING";
227261
227314
  }
227315
+ /** True when CMMD says the runtime itself cannot take a delivery (CMMD-36473). */
227316
+ function isRuntimeUnavailable(readiness) {
227317
+ return claudeReadinessReasonCode(readiness.reason) === "RUNTIME_UNAVAILABLE";
227318
+ }
227262
227319
  function readinessFailureIssue(readiness) {
227263
227320
  const reasonIssue = readinessReasonIssue(readiness);
227264
227321
  if (reasonIssue !== null) return reasonIssue;
@@ -227298,11 +227355,12 @@ function verifiedClaudeDeliveryBinding(readiness, authority) {
227298
227355
  function appliedClaudeGeneration(readiness) {
227299
227356
  if (readiness.connected !== true || readiness.deliveryStatus !== "applied" || readiness.nativeExecutable !== true || typeof readiness.generationId !== "string" || readiness.generationId.trim().length === 0) {
227300
227357
  const refreshing = isCredentialRefreshInFlight(readiness);
227301
- throw new ClaudeRuntimeReadinessError(readinessFailureIssue(readiness), refreshing || [
227358
+ const retryable = !isRuntimeUnavailable(readiness) && (refreshing || [
227302
227359
  "pending",
227303
227360
  "claimed",
227304
227361
  "activating"
227305
- ].includes(readiness.deliveryStatus), refreshing ? "credentialRefresh" : "default");
227362
+ ].includes(readiness.deliveryStatus));
227363
+ throw new ClaudeRuntimeReadinessError(readinessFailureIssue(readiness), retryable, refreshing ? "credentialRefresh" : "default");
227306
227364
  }
227307
227365
  return readiness.generationId;
227308
227366
  }
@@ -228460,15 +228518,15 @@ const collectOutput = require_Schema$1.fn("collectOutput")(function* (input, str
228460
228518
  /**
228461
228519
  * Adds a `safe.directory` exception to a git child environment.
228462
228520
  *
228463
- * Forge runs git against workspaces on a mounted volume (`/data/Projects/...` on
228464
- * Fly). A volume mount replaces the build-time ownership of its mountpoint, so a
228521
+ * Forge runs git against workspaces on a mounted volume (`<cloudProjectsRoot>/...`
228522
+ * on Fly). A volume mount replaces the build-time ownership of its mountpoint, so a
228465
228523
  * repository there can be owned by a uid other than the server's, and git then
228466
228524
  * refuses EVERY command against it with "detected dubious ownership" — the
228467
228525
  * FORGE-2T failure in `CheckpointStore.captureCheckpoint`.
228468
228526
  *
228469
228527
  * The exception has to be `*`, verified against git 2.43:
228470
228528
  * - git compares `safe.directory` entries literally, so a prefix such as
228471
- * `/data/Projects/*` does not match the repository at all.
228529
+ * `/projects/*` does not match the repository at all.
228472
228530
  * - the value must name the DISCOVERED REPOSITORY ROOT, which is an ancestor of
228473
228531
  * `cwd` whenever a command runs from a subdirectory. Resolving that root means
228474
228532
  * asking git, which is the command being refused.
@@ -291410,7 +291468,7 @@ const ServerLoggerLive = require_Schema$1.gen(function* () {
291410
291468
  * Observed live on a Forge Cloud sprite (2026-07-25): the browser opens
291411
291469
  * `wss://<sprite>.sprites.app/ws?routeKey=…&runtimeTicket=<JWT>`, and the HTTP
291412
291470
  * instrumentation records `url.full` / `url.query` verbatim. The ticket then
291413
- * lands in `/data/userdata/logs/server.trace.ndjson` at mode 644 — readable by
291471
+ * lands in `<FORGE_HOME>/userdata/logs/server.trace.ndjson` at mode 644 — readable by
291414
291472
  * the same user the agent runs as — and the URL also crosses fly.io's edge,
291415
291473
  * where infrastructure we do not control may log it.
291416
291474
  *
@@ -291707,7 +291765,7 @@ function resolveBuildCommitFromEnv(env) {
291707
291765
  * environment descriptor down instead of reporting an honest "unknown".
291708
291766
  */
291709
291767
  function readBakedBuildCommit() {
291710
- return "986939d02dd54d5adfd34ed23f2d67fece201f9a";
291768
+ return "5f0060a9696edd41f61f06cbf24450a5994fed33";
291711
291769
  }
291712
291770
  async function resolveServerBuildCommit(input) {
291713
291771
  if (isFullCommitSha(input.baked)) return input.baked;
@@ -291796,6 +291854,25 @@ function runtimeTopology(serverConfig) {
291796
291854
  if (serverConfig.mode === "desktop") return "desktop-local";
291797
291855
  return "local-web";
291798
291856
  }
291857
+ /**
291858
+ * The CMMD device runtime id to publish on this server's descriptor.
291859
+ *
291860
+ * A client cannot work this out for itself. Its only other source is page
291861
+ * storage, which holds this machine's id when the page runs inside the desktop
291862
+ * shell and a freshly minted browser id otherwise, so opening the same local
291863
+ * server at `127.0.0.1` in Safari made the desktop look like a remote runtime
291864
+ * (FOR-36439). The server was told the id at boot, so the server says it.
291865
+ *
291866
+ * The cloud shell is excluded on purpose. It is a control plane, not an
291867
+ * execution runtime, and its own provider list is empty; publishing a runtime
291868
+ * id there would let the SPA resolve some target as "the server I am talking
291869
+ * to" and read models off a surface that runs nothing. Everything else with no
291870
+ * registration (dev checkouts, plain `forge serve`) already answers undefined.
291871
+ */
291872
+ function resolveDescriptorDeviceRuntimeId(config) {
291873
+ if (config.forgeCloudShellMode === true) return void 0;
291874
+ return resolveRuntimeReplicationRuntimeId(config);
291875
+ }
291799
291876
  function executionEnvironmentCapabilities(serverConfig) {
291800
291877
  const isCloudShell = serverConfig.forgeCloudShellMode === true;
291801
291878
  const isRuntime = serverConfig.forgeCmmdRuntimeMode === true && !isCloudShell;
@@ -291870,6 +291947,7 @@ const makeServerEnvironment = require_Schema$1.fn("makeServerEnvironment")(funct
291870
291947
  env: process.env,
291871
291948
  readGitCommit: resolveForgeGitCommit
291872
291949
  }));
291950
+ const deviceRuntimeId = resolveDescriptorDeviceRuntimeId(serverConfig);
291873
291951
  const buildDescriptor = require_Schema$1.gen(function* () {
291874
291952
  const displayNameOverride = yield* require_HttpServer.get$1(displayNameOverrideRef);
291875
291953
  const os = platformOs();
@@ -291882,6 +291960,7 @@ const makeServerEnvironment = require_Schema$1.fn("makeServerEnvironment")(funct
291882
291960
  },
291883
291961
  serverVersion: version$1,
291884
291962
  ...buildCommit !== void 0 ? { buildCommit } : {},
291963
+ ...deviceRuntimeId !== void 0 ? { deviceRuntimeId } : {},
291885
291964
  capabilities: {
291886
291965
  ...executionEnvironmentCapabilities(serverConfig),
291887
291966
  posthogPublicKey: posthog.posthogPublicKey,
@@ -299738,16 +299817,6 @@ function describeDispatchCause(cause) {
299738
299817
  if (deepest === void 0 || deepest.length <= DISPATCH_CAUSE_DETAIL_LIMIT) return deepest;
299739
299818
  return `${deepest.slice(0, DISPATCH_CAUSE_DETAIL_LIMIT)}...`;
299740
299819
  }
299741
- /**
299742
- * Where automation-created projects live when the caller does not say.
299743
- *
299744
- * This is the documented default of the `cloudProjectsRoot` setting
299745
- * (FORGE_CLOUD_PROJECTS_ROOT, see cli.ts) and exists only for direct callers
299746
- * such as tests. Every HTTP route passes the CONFIGURED value instead: reading
299747
- * the default here is what made a runtime configured with any other root create
299748
- * its automation projects in a directory nothing else read.
299749
- */
299750
- const DEFAULT_CLOUD_PROJECTS_ROOT = "/data/Projects";
299751
299820
  const respondToOrchestrationHttpError = (error) => require_Schema$1.gen(function* () {
299752
299821
  if (error._tag === "OrchestrationGetSnapshotError") {
299753
299822
  yield* require_Schema$1.logError("orchestration http route failed", {
@@ -314725,7 +314794,7 @@ const resolveServerConfig = (flags, cliLogLevel, options) => require_Schema$1.ge
314725
314794
  forgeCodexHomePath: env.forgeCodexHomePath,
314726
314795
  forgeClaudeConfigPath: env.forgeClaudeConfigPath,
314727
314796
  forgeApexBaseUrl: env.forgeApexBaseUrl,
314728
- cloudProjectsRoot: env.cloudProjectsRoot ?? "/data/Projects"
314797
+ cloudProjectsRoot: env.cloudProjectsRoot ?? "/projects"
314729
314798
  };
314730
314799
  if (config.forgeCloudShellMode === true && (!config.forgeCloudOwnerAssertionPublicKey?.trim() || !config.forgeCloudOwnerAssertionKeyId?.trim())) return yield* require_Schema$1.die(/* @__PURE__ */ new Error("FORGE_CMMD_CLOUD_OWNER_ASSERTION_PUBLIC_KEY and FORGE_CMMD_CLOUD_OWNER_ASSERTION_KEY_ID are required in cloud-shell mode; runtime ticket keys are not accepted for Cloud owner assertions."));
314731
314800
  if (config.forgeCloudShellMode === true && !isEd25519PublicKey(config.forgeCloudOwnerAssertionPublicKey ?? "")) return yield* require_Schema$1.die(/* @__PURE__ */ new Error("FORGE_CMMD_CLOUD_OWNER_ASSERTION_PUBLIC_KEY must be a valid Ed25519 public key in cloud-shell mode."));