@cmmd-center/forge 0.10.11 → 0.10.13

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 (21) hide show
  1. package/dist/bin.cjs +93 -25
  2. package/dist/bin.mjs +107 -39
  3. package/dist/client/assets/{CanvasPanel-mbL7UwXT.js → CanvasPanel-Cogtmutb.js} +2 -2
  4. package/dist/client/assets/{CompositeItem-Dm91tFrl.js → CompositeItem-D6h2WFmU.js} +2 -2
  5. package/dist/client/assets/{DiffPanel-D5_mQprX.js → DiffPanel-DGiCJd76.js} +2 -2
  6. package/dist/client/assets/{DiffPanel.logic-C9mMwE_h.js → DiffPanel.logic-Dd5YF6k3.js} +2 -2
  7. package/dist/client/assets/{DiffPanelShell-B66p-lZ_.js → DiffPanelShell-C-nlQxal.js} +3 -3
  8. package/dist/client/assets/{DiffWorkerPoolProvider-NicytKOR.js → DiffWorkerPoolProvider-CfmtkBLg.js} +2 -2
  9. package/dist/client/assets/{PullRequestCodePanel-Bo4GJMN4.js → PullRequestCodePanel-xkECqRzW.js} +2 -2
  10. package/dist/client/assets/{Virtualizer-CwnDGyPn.js → Virtualizer-CVyQexgp.js} +2 -2
  11. package/dist/client/assets/{canvasStateStore-CqQQvGP5.js → canvasStateStore-DUZyBLSv.js} +2 -2
  12. package/dist/client/assets/{cmmdAuthRedirect-Dm6mOZMB.js → cmmdAuthRedirect-Bkc6Luqb.js} +2 -2
  13. package/dist/client/assets/{index-CRRrSW8u.js → index-BD9iZwyM.js} +59 -59
  14. package/dist/client/assets/src-BlF9iHm-.js +3 -0
  15. package/dist/client/assets/{toggle-dld7kzOP.js → toggle-CWmPePti.js} +2 -2
  16. package/dist/client/assets/{useTriggerFocusGuards-DPZ1smix.js → useTriggerFocusGuards-O7DUCec0.js} +2 -2
  17. package/dist/client/index.html +10 -10
  18. package/dist/forge-build.json +1 -1
  19. package/dist/{open-FIgTDosf.mjs → open-D8mGyWmt.mjs} +3 -3
  20. package/package.json +1 -1
  21. package/dist/client/assets/src-BOr7-dep.js +0 -3
package/dist/bin.cjs CHANGED
@@ -18674,16 +18674,81 @@ const CLAUDE_CODE_EFFORT_OPTIONS = [
18674
18674
  const CODEX_DEFAULT_MODEL = "gpt-6-astra";
18675
18675
  const CODEX_SPARK_MODEL = "gpt-5.3-codex-spark";
18676
18676
  const CLAUDE_DEFAULT_MODEL = "claude-fable-5-1";
18677
- const CodexModelOptions = require_Schema$1.Struct({
18677
+ /**
18678
+ * Generic option value carried by ACP-based provider adapters (cursor, opencode).
18679
+ * Used to pass per-turn options like reasoning effort or thinking toggles to
18680
+ * the agent without baking them into model-specific schemas.
18681
+ *
18682
+ * Mirrors t3code's @t3tools/contracts ProviderOptionSelection — required by
18683
+ * the ported ACP runtime (apps/server/src/provider/acp/*) so cursor + opencode
18684
+ * adapters can carry user-selected reasoning levels through the session.
18685
+ */
18686
+ const ProviderOptionSelectionValue = require_Schema$1.Union([TrimmedNonEmptyString, require_Schema$1.Boolean]);
18687
+ const ProviderOptionSelection = require_Schema$1.Struct({
18688
+ id: TrimmedNonEmptyString,
18689
+ value: ProviderOptionSelectionValue
18690
+ });
18691
+ /**
18692
+ * The object form on its own, exported so callers that need the individual
18693
+ * field schemas can reach them. The exported `CodexModelOptions` below is a
18694
+ * union and has no `.fields`.
18695
+ */
18696
+ const CodexModelOptionsObject = require_Schema$1.Struct({
18678
18697
  reasoningEffort: require_Schema$1.optional(require_Schema$1.Literals(CODEX_REASONING_EFFORT_OPTIONS)),
18679
18698
  fastMode: require_Schema$1.optional(require_Schema$1.Boolean)
18680
18699
  });
18681
- const ClaudeModelOptions = require_Schema$1.Struct({
18700
+ /** The object form on its own; see {@link CodexModelOptionsObject}. */
18701
+ const ClaudeModelOptionsObject = require_Schema$1.Struct({
18682
18702
  thinking: require_Schema$1.optional(require_Schema$1.Boolean),
18683
18703
  effort: require_Schema$1.optional(require_Schema$1.Literals(CLAUDE_CODE_EFFORT_OPTIONS)),
18684
18704
  fastMode: require_Schema$1.optional(require_Schema$1.Boolean),
18685
18705
  contextWindow: require_Schema$1.optional(require_Schema$1.String)
18686
18706
  });
18707
+ /**
18708
+ * `[{ id, value }]` folded into `{ [id]: value }`.
18709
+ *
18710
+ * Duplicate ids keep the last, which is what an object literal would have done
18711
+ * had the sender used one.
18712
+ */
18713
+ function selectionArrayToRecord(selections) {
18714
+ const record = {};
18715
+ for (const { id, value } of selections) record[id] = value;
18716
+ return record;
18717
+ }
18718
+ function recordToSelectionArray(value) {
18719
+ if (typeof value !== "object" || value === null) return [];
18720
+ return Object.entries(value).flatMap(([id, entry]) => typeof entry === "string" || typeof entry === "boolean" ? [{
18721
+ id,
18722
+ value: entry
18723
+ }] : []);
18724
+ }
18725
+ /**
18726
+ * Also accept the option array that t3code-derived clients send.
18727
+ *
18728
+ * Forge's own surfaces send `{ reasoningEffort: "high" }`. The vendored mobile
18729
+ * client encodes the same choice as `[{ id: "reasoningEffort", value: "high" }]`,
18730
+ * its canonical shape, and the two contract packages never compare notes. So a
18731
+ * person picking a reasoning effort on the phone produced a `startTurn` payload
18732
+ * the server refused outright with "Expected object, got [...]" — not a dropped
18733
+ * option, a turn that never ran at all.
18734
+ *
18735
+ * Tolerated here rather than changed in the vendored encoder: this accepts both
18736
+ * shapes from any client, while `@t3tools/contracts` keeps the canonical form
18737
+ * it shares with upstream. The array is normalised into the object the provider
18738
+ * adapters already read, so nothing downstream learns a second shape.
18739
+ *
18740
+ * The object member stays first because it is what every Forge surface sends.
18741
+ * `Schema.Struct` rejects an array outright rather than decoding it to an empty
18742
+ * object, so an array falls through to the member built for it.
18743
+ */
18744
+ const CodexModelOptions = require_Schema$1.Union([CodexModelOptionsObject, require_Schema$1.ArraySchema(ProviderOptionSelection).pipe(require_Schema$1.decodeTo(CodexModelOptionsObject, require_Schema$1.transformOrFail({
18745
+ decode: (selections) => require_Schema$1.succeed(selectionArrayToRecord(selections)),
18746
+ encode: (value) => require_Schema$1.succeed(recordToSelectionArray(value))
18747
+ })))]);
18748
+ const ClaudeModelOptions = require_Schema$1.Union([ClaudeModelOptionsObject, require_Schema$1.ArraySchema(ProviderOptionSelection).pipe(require_Schema$1.decodeTo(ClaudeModelOptionsObject, require_Schema$1.transformOrFail({
18749
+ decode: (selections) => require_Schema$1.succeed(selectionArrayToRecord(selections)),
18750
+ encode: (value) => require_Schema$1.succeed(recordToSelectionArray(value))
18751
+ })))]);
18687
18752
  require_Schema$1.Struct({
18688
18753
  codex: require_Schema$1.optional(CodexModelOptions),
18689
18754
  claudeAgent: require_Schema$1.optional(ClaudeModelOptions),
@@ -18710,20 +18775,6 @@ const ModelCapabilities = require_Schema$1.Struct({
18710
18775
  contextWindowOptions: require_Schema$1.ArraySchema(ContextWindowOption),
18711
18776
  promptInjectedEffortLevels: require_Schema$1.ArraySchema(TrimmedNonEmptyString)
18712
18777
  });
18713
- /**
18714
- * Generic option value carried by ACP-based provider adapters (cursor, opencode).
18715
- * Used to pass per-turn options like reasoning effort or thinking toggles to
18716
- * the agent without baking them into model-specific schemas.
18717
- *
18718
- * Mirrors t3code's @t3tools/contracts ProviderOptionSelection — required by
18719
- * the ported ACP runtime (apps/server/src/provider/acp/*) so cursor + opencode
18720
- * adapters can carry user-selected reasoning levels through the session.
18721
- */
18722
- const ProviderOptionSelectionValue = require_Schema$1.Union([TrimmedNonEmptyString, require_Schema$1.Boolean]);
18723
- const ProviderOptionSelection = require_Schema$1.Struct({
18724
- id: TrimmedNonEmptyString,
18725
- value: ProviderOptionSelectionValue
18726
- });
18727
18778
  function effortLabel(value) {
18728
18779
  switch (value) {
18729
18780
  case "xhigh": return "Extra High";
@@ -22376,14 +22427,14 @@ var ServerSettingsError = class extends require_Schema$1.TaggedErrorClass()("Ser
22376
22427
  ...DEFAULT_CLIENT_SETTINGS
22377
22428
  });
22378
22429
  const CodexModelOptionsPatch = require_Schema$1.Struct({
22379
- reasoningEffort: require_Schema$1.optionalKey(CodexModelOptions.fields.reasoningEffort),
22380
- fastMode: require_Schema$1.optionalKey(CodexModelOptions.fields.fastMode)
22430
+ reasoningEffort: require_Schema$1.optionalKey(CodexModelOptionsObject.fields.reasoningEffort),
22431
+ fastMode: require_Schema$1.optionalKey(CodexModelOptionsObject.fields.fastMode)
22381
22432
  });
22382
22433
  const ClaudeModelOptionsPatch = require_Schema$1.Struct({
22383
- thinking: require_Schema$1.optionalKey(ClaudeModelOptions.fields.thinking),
22384
- effort: require_Schema$1.optionalKey(ClaudeModelOptions.fields.effort),
22385
- fastMode: require_Schema$1.optionalKey(ClaudeModelOptions.fields.fastMode),
22386
- contextWindow: require_Schema$1.optionalKey(ClaudeModelOptions.fields.contextWindow)
22434
+ thinking: require_Schema$1.optionalKey(ClaudeModelOptionsObject.fields.thinking),
22435
+ effort: require_Schema$1.optionalKey(ClaudeModelOptionsObject.fields.effort),
22436
+ fastMode: require_Schema$1.optionalKey(ClaudeModelOptionsObject.fields.fastMode),
22437
+ contextWindow: require_Schema$1.optionalKey(ClaudeModelOptionsObject.fields.contextWindow)
22387
22438
  });
22388
22439
  const ModelSelectionPatch = require_Schema$1.Union([require_Schema$1.Struct({
22389
22440
  provider: require_Schema$1.optionalKey(require_Schema$1.Literal("codex")),
@@ -65724,7 +65775,7 @@ function normalizeNumberish(value) {
65724
65775
  }
65725
65776
  //#endregion
65726
65777
  //#region package.json
65727
- var version$1 = "0.10.11";
65778
+ var version$1 = "0.10.13";
65728
65779
  //#endregion
65729
65780
  //#region src/sentry.ts
65730
65781
  const SERVER_APP_NAME = "forge-server";
@@ -211001,6 +211052,7 @@ const DEFAULT_PUBLIC_PROVIDER_ERROR = "CMMD is temporarily unavailable. Check th
211001
211052
  function categorizePublicProviderError(message) {
211002
211053
  if (!message) return null;
211003
211054
  const m = message.toLowerCase();
211055
+ if (/\bforge_runtime_stopped\b/.test(m) || /\bthis turn was interrupted because the environment was stopped\b/.test(m)) return "This turn was interrupted because the environment was stopped. Start the environment and retry.";
211004
211056
  if (/\bforge_provider_model_not_allowed\b/.test(m) || /\bnot\s+scoped\s+to\s+the\s+requested\s+model\b/.test(m)) return "The workspace AI credential does not cover the model this turn asked for. Retry, or pick that model for the thread.";
211005
211057
  if (/\bmodel\b[\s\S]*\b(not\s+(found|available|supported)|does\s+not\s+exist|unsupported|invalid|unknown)\b/.test(m) || /\b(unsupported|unknown|invalid)\b[\s\S]*\bmodel\b/.test(m) || /\b(model_not_found|invalid_model|model_not_supported)\b/.test(m)) return "The selected model isn't available right now. Pick a different model and retry.";
211006
211058
  if (/\b(rate[\s-]?limit|too\s+many\s+requests|quota|insufficient_quota)\b/.test(m) || /\b429\b/.test(m)) return "The AI service is rate-limited or out of quota. Wait a moment and retry.";
@@ -293989,7 +294041,7 @@ function resolveBuildCommitFromEnv(env) {
293989
294041
  * environment descriptor down instead of reporting an honest "unknown".
293990
294042
  */
293991
294043
  function readBakedBuildCommit() {
293992
- return "1bdecd034b4ea69b2c72eaebd3134a3c4b916673";
294044
+ return "75c8e9532c9e35e71d4da1d8d45474fa2855ff1d";
293993
294045
  }
293994
294046
  async function resolveServerBuildCommit(input) {
293995
294047
  if (isFullCommitSha(input.baked)) return input.baked;
@@ -297070,6 +297122,19 @@ function toProjectorDecodeError(eventType) {
297070
297122
  });
297071
297123
  }
297072
297124
  //#endregion
297125
+ //#region src/orchestration/turnAccountSelection.ts
297126
+ /** A per-turn account choice remains local to the thread and cannot change its provider. */
297127
+ function turnAccountSelection(current, requested) {
297128
+ if (!requested || requested.provider !== current.provider) return void 0;
297129
+ if (requested.provider !== "codex" && requested.provider !== "claudeAgent") return void 0;
297130
+ const currentAccountId = "providerAccountId" in current ? current.providerAccountId : void 0;
297131
+ if (requested.providerAccountId === void 0 || requested.providerAccountId === currentAccountId) return void 0;
297132
+ return {
297133
+ ...current,
297134
+ providerAccountId: requested.providerAccountId
297135
+ };
297136
+ }
297137
+ //#endregion
297073
297138
  //#region src/orchestration/commandInvariants.ts
297074
297139
  function invariantError(commandType, detail) {
297075
297140
  return new OrchestrationCommandInvariantError({
@@ -297608,7 +297673,9 @@ const decideOrchestrationCommand = require_Schema$1.fn("decideOrchestrationComma
297608
297673
  createdAt: command.createdAt
297609
297674
  }
297610
297675
  };
297611
- if (!(targetThread.anchorKind !== nextAnchor.anchorKind || targetThread.anchorCmmdId !== nextAnchor.anchorCmmdId)) return [userMessageEvent, turnStartRequestedEvent];
297676
+ const shouldUpdateAnchor = targetThread.anchorKind !== nextAnchor.anchorKind || targetThread.anchorCmmdId !== nextAnchor.anchorCmmdId;
297677
+ const accountSelection = turnAccountSelection(targetThread.modelSelection, command.modelSelection);
297678
+ if (!shouldUpdateAnchor && !accountSelection) return [userMessageEvent, turnStartRequestedEvent];
297612
297679
  return [
297613
297680
  {
297614
297681
  ...withEventBase({
@@ -297622,6 +297689,7 @@ const decideOrchestrationCommand = require_Schema$1.fn("decideOrchestrationComma
297622
297689
  threadId: command.threadId,
297623
297690
  anchorKind: nextAnchor.anchorKind,
297624
297691
  anchorCmmdId: nextAnchor.anchorCmmdId,
297692
+ ...accountSelection ? { modelSelection: accountSelection } : {},
297625
297693
  updatedAt: command.createdAt
297626
297694
  }
297627
297695
  },
package/dist/bin.mjs CHANGED
@@ -22,7 +22,7 @@ import { createCipheriv, createDecipheriv, createHash, createHmac, createPublicK
22
22
  import * as FS$1 from "node:fs";
23
23
  import fs, { accessSync, chmodSync, constants, createReadStream, existsSync, mkdirSync, mkdtempSync, promises, readFile, readFileSync, readdir, readdirSync, realpathSync, rmSync, statSync, writeFileSync } from "node:fs";
24
24
  import * as NodeOS from "node:os";
25
- import os, { homedir, networkInterfaces, tmpdir } from "node:os";
25
+ import $U, { homedir, networkInterfaces, tmpdir } from "node:os";
26
26
  import * as Path$1 from "node:path";
27
27
  import path, { basename, delimiter, dirname, extname, isAbsolute, join, posix, relative, resolve, sep } from "node:path";
28
28
  import { pathToFileURL } from "node:url";
@@ -18601,16 +18601,71 @@ const CLAUDE_CODE_EFFORT_OPTIONS = [
18601
18601
  const CODEX_DEFAULT_MODEL = "gpt-6-astra";
18602
18602
  const CODEX_SPARK_MODEL = "gpt-5.3-codex-spark";
18603
18603
  const CLAUDE_DEFAULT_MODEL = "claude-fable-5-1";
18604
- const CodexModelOptions = Struct({
18604
+ const ProviderOptionSelection = Struct({
18605
+ id: TrimmedNonEmptyString,
18606
+ value: Union([TrimmedNonEmptyString, Boolean$1])
18607
+ });
18608
+ /**
18609
+ * The object form on its own, exported so callers that need the individual
18610
+ * field schemas can reach them. The exported `CodexModelOptions` below is a
18611
+ * union and has no `.fields`.
18612
+ */
18613
+ const CodexModelOptionsObject = Struct({
18605
18614
  reasoningEffort: optional$4(Literals(CODEX_REASONING_EFFORT_OPTIONS)),
18606
18615
  fastMode: optional$4(Boolean$1)
18607
18616
  });
18608
- const ClaudeModelOptions = Struct({
18617
+ /** The object form on its own; see {@link CodexModelOptionsObject}. */
18618
+ const ClaudeModelOptionsObject = Struct({
18609
18619
  thinking: optional$4(Boolean$1),
18610
18620
  effort: optional$4(Literals(CLAUDE_CODE_EFFORT_OPTIONS)),
18611
18621
  fastMode: optional$4(Boolean$1),
18612
18622
  contextWindow: optional$4(String$1)
18613
18623
  });
18624
+ /**
18625
+ * `[{ id, value }]` folded into `{ [id]: value }`.
18626
+ *
18627
+ * Duplicate ids keep the last, which is what an object literal would have done
18628
+ * had the sender used one.
18629
+ */
18630
+ function selectionArrayToRecord(selections) {
18631
+ const record = {};
18632
+ for (const { id, value } of selections) record[id] = value;
18633
+ return record;
18634
+ }
18635
+ function recordToSelectionArray(value) {
18636
+ if (typeof value !== "object" || value === null) return [];
18637
+ return Object.entries(value).flatMap(([id, entry]) => typeof entry === "string" || typeof entry === "boolean" ? [{
18638
+ id,
18639
+ value: entry
18640
+ }] : []);
18641
+ }
18642
+ /**
18643
+ * Also accept the option array that t3code-derived clients send.
18644
+ *
18645
+ * Forge's own surfaces send `{ reasoningEffort: "high" }`. The vendored mobile
18646
+ * client encodes the same choice as `[{ id: "reasoningEffort", value: "high" }]`,
18647
+ * its canonical shape, and the two contract packages never compare notes. So a
18648
+ * person picking a reasoning effort on the phone produced a `startTurn` payload
18649
+ * the server refused outright with "Expected object, got [...]" — not a dropped
18650
+ * option, a turn that never ran at all.
18651
+ *
18652
+ * Tolerated here rather than changed in the vendored encoder: this accepts both
18653
+ * shapes from any client, while `@t3tools/contracts` keeps the canonical form
18654
+ * it shares with upstream. The array is normalised into the object the provider
18655
+ * adapters already read, so nothing downstream learns a second shape.
18656
+ *
18657
+ * The object member stays first because it is what every Forge surface sends.
18658
+ * `Schema.Struct` rejects an array outright rather than decoding it to an empty
18659
+ * object, so an array falls through to the member built for it.
18660
+ */
18661
+ const CodexModelOptions = Union([CodexModelOptionsObject, ArraySchema(ProviderOptionSelection).pipe(decodeTo(CodexModelOptionsObject, transformOrFail({
18662
+ decode: (selections) => succeed(selectionArrayToRecord(selections)),
18663
+ encode: (value) => succeed(recordToSelectionArray(value))
18664
+ })))]);
18665
+ const ClaudeModelOptions = Union([ClaudeModelOptionsObject, ArraySchema(ProviderOptionSelection).pipe(decodeTo(ClaudeModelOptionsObject, transformOrFail({
18666
+ decode: (selections) => succeed(selectionArrayToRecord(selections)),
18667
+ encode: (value) => succeed(recordToSelectionArray(value))
18668
+ })))]);
18614
18669
  Struct({
18615
18670
  codex: optional$4(CodexModelOptions),
18616
18671
  claudeAgent: optional$4(ClaudeModelOptions),
@@ -18637,10 +18692,6 @@ const ModelCapabilities = Struct({
18637
18692
  contextWindowOptions: ArraySchema(ContextWindowOption),
18638
18693
  promptInjectedEffortLevels: ArraySchema(TrimmedNonEmptyString)
18639
18694
  });
18640
- const ProviderOptionSelection = Struct({
18641
- id: TrimmedNonEmptyString,
18642
- value: Union([TrimmedNonEmptyString, Boolean$1])
18643
- });
18644
18695
  function effortLabel(value) {
18645
18696
  switch (value) {
18646
18697
  case "xhigh": return "Extra High";
@@ -22201,14 +22252,14 @@ var ServerSettingsError = class extends TaggedErrorClass()("ServerSettingsError"
22201
22252
  ...DEFAULT_CLIENT_SETTINGS
22202
22253
  });
22203
22254
  const CodexModelOptionsPatch = Struct({
22204
- reasoningEffort: optionalKey(CodexModelOptions.fields.reasoningEffort),
22205
- fastMode: optionalKey(CodexModelOptions.fields.fastMode)
22255
+ reasoningEffort: optionalKey(CodexModelOptionsObject.fields.reasoningEffort),
22256
+ fastMode: optionalKey(CodexModelOptionsObject.fields.fastMode)
22206
22257
  });
22207
22258
  const ClaudeModelOptionsPatch = Struct({
22208
- thinking: optionalKey(ClaudeModelOptions.fields.thinking),
22209
- effort: optionalKey(ClaudeModelOptions.fields.effort),
22210
- fastMode: optionalKey(ClaudeModelOptions.fields.fastMode),
22211
- contextWindow: optionalKey(ClaudeModelOptions.fields.contextWindow)
22259
+ thinking: optionalKey(ClaudeModelOptionsObject.fields.thinking),
22260
+ effort: optionalKey(ClaudeModelOptionsObject.fields.effort),
22261
+ fastMode: optionalKey(ClaudeModelOptionsObject.fields.fastMode),
22262
+ contextWindow: optionalKey(ClaudeModelOptionsObject.fields.contextWindow)
22212
22263
  });
22213
22264
  const ModelSelectionPatch = Union([Struct({
22214
22265
  provider: optionalKey(Literal("codex")),
@@ -50056,7 +50107,7 @@ function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
50056
50107
  const min = forceColor || 0;
50057
50108
  if (env.TERM === "dumb") return min;
50058
50109
  if (process$1.platform === "win32") {
50059
- const osRelease = os.release().split(".");
50110
+ const osRelease = $U.release().split(".");
50060
50111
  if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) return Number(osRelease[2]) >= 14931 ? 3 : 2;
50061
50112
  return 1;
50062
50113
  }
@@ -52499,7 +52550,7 @@ var require_ProcessDetector = /* @__PURE__ */ __commonJSMin(((exports) => {
52499
52550
  exports.processDetector = void 0;
52500
52551
  const api_1 = (init_esm$1(), __toCommonJS(esm_exports$1));
52501
52552
  const semconv_1 = require_semconv$1();
52502
- const os$4 = __require("os");
52553
+ const os$3 = __require("os");
52503
52554
  /**
52504
52555
  * ProcessDetector will be used to detect the resources related current process running
52505
52556
  * and being instrumented from the NodeJS Process module.
@@ -52521,7 +52572,7 @@ var require_ProcessDetector = /* @__PURE__ */ __commonJSMin(((exports) => {
52521
52572
  };
52522
52573
  if (process.argv.length > 1) attributes[semconv_1.ATTR_PROCESS_COMMAND] = process.argv[1];
52523
52574
  try {
52524
- const userInfo = os$4.userInfo();
52575
+ const userInfo = os$3.userInfo();
52525
52576
  attributes[semconv_1.ATTR_PROCESS_OWNER] = userInfo.username;
52526
52577
  } catch (e) {
52527
52578
  api_1.diag.debug(`error obtaining process owner: ${e}`);
@@ -65444,7 +65495,7 @@ function normalizeNumberish(value) {
65444
65495
  }
65445
65496
  //#endregion
65446
65497
  //#region package.json
65447
- var version$1 = "0.10.11";
65498
+ var version$1 = "0.10.13";
65448
65499
  //#endregion
65449
65500
  //#region src/sentry.ts
65450
65501
  const SERVER_APP_NAME = "forge-server";
@@ -74181,7 +74232,7 @@ var require_node_gyp_build = /* @__PURE__ */ __commonJSMin(((exports, module) =>
74181
74232
  var fs$6 = __require("fs");
74182
74233
  var path$5 = __require("path");
74183
74234
  var url$1 = __require("url");
74184
- var os$3 = __require("os");
74235
+ var os$2 = __require("os");
74185
74236
  var runtimeRequire = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
74186
74237
  var vars = process.config && process.config.variables || {};
74187
74238
  var prebuildsOnly = !!process.env.PREBUILDS_ONLY;
@@ -74189,8 +74240,8 @@ var require_node_gyp_build = /* @__PURE__ */ __commonJSMin(((exports, module) =>
74189
74240
  var abi = versions.modules;
74190
74241
  if (versions.deno || process.isBun) abi = "unsupported";
74191
74242
  var runtime = isElectron() ? "electron" : isNwjs() ? "node-webkit" : "node";
74192
- var arch = process.env.npm_config_arch || os$3.arch();
74193
- var platform = process.env.npm_config_platform || os$3.platform();
74243
+ var arch = process.env.npm_config_arch || os$2.arch();
74244
+ var platform = process.env.npm_config_platform || os$2.platform();
74194
74245
  var libc = process.env.LIBC || (isMusl(platform) ? "musl" : "glibc");
74195
74246
  var armv = process.env.ARM_VERSION || (arch === "arm64" ? "8" : vars.arm_version) || "";
74196
74247
  var uv = (versions.uv || "").split(".")[0];
@@ -91920,7 +91971,7 @@ const launchDetached = (launch) => gen(function* () {
91920
91971
  });
91921
91972
  const OpenLive = effect(Open, gen(function* () {
91922
91973
  const open = yield* tryPromise({
91923
- try: () => import("./open-FIgTDosf.mjs"),
91974
+ try: () => import("./open-D8mGyWmt.mjs"),
91924
91975
  catch: (cause) => new OpenError$1({
91925
91976
  message: "failed to load browser opener",
91926
91977
  cause
@@ -188933,7 +188984,7 @@ var Vce = {
188933
188984
  function Ve() {
188934
188985
  return Vce;
188935
188986
  }
188936
- var Us = os.homedir(), lk = os.tmpdir(), { env: Vc } = process$1, Yce = (e) => {
188987
+ var Us = $U.homedir(), lk = $U.tmpdir(), { env: Vc } = process$1, Yce = (e) => {
188937
188988
  let t = path.join(Us, "Library");
188938
188989
  return {
188939
188990
  data: path.join(t, "Application Support", e),
@@ -199133,12 +199184,12 @@ function qZ(e, t) {
199133
199184
  }
199134
199185
  return n;
199135
199186
  }
199136
- var os$2 = "https://code.claude.com/docs/en", kKe = [
199187
+ var os$1 = "https://code.claude.com/docs/en", kKe = [
199137
199188
  {
199138
199189
  matches: (e) => e.path === "permissions.defaultMode" && e.code === "invalid_value",
199139
199190
  tip: {
199140
199191
  suggestion: "Valid modes: \"acceptEdits\" (ask before file changes), \"plan\" (analysis only), \"bypassPermissions\" (auto-accept all), or \"default\" (standard behavior)",
199141
- docLink: `${os$2}/iam#permission-modes`
199192
+ docLink: `${os$1}/iam#permission-modes`
199142
199193
  }
199143
199194
  },
199144
199195
  {
@@ -199153,7 +199204,7 @@ var os$2 = "https://code.claude.com/docs/en", kKe = [
199153
199204
  matches: (e) => e.path.startsWith("env.") && e.code === "invalid_type",
199154
199205
  tip: {
199155
199206
  suggestion: "Environment variables must be strings. Wrap numbers and booleans in quotes. Example: \"DEBUG\": \"true\", \"PORT\": \"3000\"",
199156
- docLink: `${os$2}/settings#environment-variables`
199207
+ docLink: `${os$1}/settings#environment-variables`
199157
199208
  }
199158
199209
  },
199159
199210
  {
@@ -199164,14 +199215,14 @@ var os$2 = "https://code.claude.com/docs/en", kKe = [
199164
199215
  matches: (e) => e.path.startsWith("hooks.") && e.code === "invalid_key",
199165
199216
  tip: {
199166
199217
  suggestion: "Not a recognized hook event. Common events: PreToolUse, PostToolUse, UserPromptSubmit, SessionStart, SessionEnd, Stop. Check spelling and capitalization.",
199167
- docLink: `${os$2}/hooks`
199218
+ docLink: `${os$1}/hooks`
199168
199219
  }
199169
199220
  },
199170
199221
  {
199171
199222
  matches: (e) => /\.hooks\.\d+\.command$/.test(e.path) && e.code === "invalid_type" && e.received === "undefined",
199172
199223
  tip: {
199173
199224
  suggestion: "Command hooks require `command`. For exec form (no shell), set `command` to the executable and `args` to its arguments: {\"type\": \"command\", \"command\": \"echo\", \"args\": [\"hi\"]}. For shell form, set `command` to the full shell string: {\"type\": \"command\", \"command\": \"echo hi\"}.",
199174
- docLink: `${os$2}/hooks#exec-form-and-shell-form`
199225
+ docLink: `${os$1}/hooks#exec-form-and-shell-form`
199175
199226
  }
199176
199227
  },
199177
199228
  {
@@ -199186,7 +199237,7 @@ var os$2 = "https://code.claude.com/docs/en", kKe = [
199186
199237
  matches: (e) => e.code === "unrecognized_keys",
199187
199238
  tip: {
199188
199239
  suggestion: "Check for typos or refer to the documentation for valid fields",
199189
- docLink: `${os$2}/settings`
199240
+ docLink: `${os$1}/settings`
199190
199241
  }
199191
199242
  },
199192
199243
  {
@@ -199201,13 +199252,13 @@ var os$2 = "https://code.claude.com/docs/en", kKe = [
199201
199252
  matches: (e) => e.path === "permissions.additionalDirectories" && e.code === "invalid_type",
199202
199253
  tip: {
199203
199254
  suggestion: "Must be an array of directory paths. Example: [\"~/projects\", \"/tmp/workspace\"]. You can also use --add-dir flag or /add-dir command",
199204
- docLink: `${os$2}/iam#working-directories`
199255
+ docLink: `${os$1}/iam#working-directories`
199205
199256
  }
199206
199257
  }
199207
199258
  ], AKe = {
199208
- permissions: `${os$2}/iam#configuring-permissions`,
199209
- env: `${os$2}/settings#environment-variables`,
199210
- hooks: `${os$2}/hooks`
199259
+ permissions: `${os$1}/iam#configuring-permissions`,
199260
+ env: `${os$1}/settings#environment-variables`,
199261
+ hooks: `${os$1}/hooks`
199211
199262
  };
199212
199263
  function GZ(e) {
199213
199264
  let t = kKe.find((r) => r.matches(e));
@@ -210594,6 +210645,7 @@ const DEFAULT_PUBLIC_PROVIDER_ERROR = "CMMD is temporarily unavailable. Check th
210594
210645
  function categorizePublicProviderError(message) {
210595
210646
  if (!message) return null;
210596
210647
  const m = message.toLowerCase();
210648
+ if (/\bforge_runtime_stopped\b/.test(m) || /\bthis turn was interrupted because the environment was stopped\b/.test(m)) return "This turn was interrupted because the environment was stopped. Start the environment and retry.";
210597
210649
  if (/\bforge_provider_model_not_allowed\b/.test(m) || /\bnot\s+scoped\s+to\s+the\s+requested\s+model\b/.test(m)) return "The workspace AI credential does not cover the model this turn asked for. Retry, or pick that model for the thread.";
210598
210650
  if (/\bmodel\b[\s\S]*\b(not\s+(found|available|supported)|does\s+not\s+exist|unsupported|invalid|unknown)\b/.test(m) || /\b(unsupported|unknown|invalid)\b[\s\S]*\bmodel\b/.test(m) || /\b(model_not_found|invalid_model|model_not_supported)\b/.test(m)) return "The selected model isn't available right now. Pick a different model and retry.";
210599
210651
  if (/\b(rate[\s-]?limit|too\s+many\s+requests|quota|insufficient_quota)\b/.test(m) || /\b429\b/.test(m)) return "The AI service is rate-limited or out of quota. Wait a moment and retry.";
@@ -265133,7 +265185,7 @@ var import_multicast_dns = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMi
265133
265185
  var dgram = __require("dgram");
265134
265186
  var thunky = require_thunky();
265135
265187
  var events = __require("events");
265136
- var os$1 = __require("os");
265188
+ var os = __require("os");
265137
265189
  var noop = function() {};
265138
265190
  module.exports = function(opts) {
265139
265191
  if (!opts) opts = {};
@@ -265264,14 +265316,14 @@ var import_multicast_dns = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMi
265264
265316
  return that;
265265
265317
  };
265266
265318
  function defaultInterface() {
265267
- var networks = os$1.networkInterfaces();
265319
+ var networks = os.networkInterfaces();
265268
265320
  var names = Object.keys(networks);
265269
265321
  for (var i = 0; i < names.length; i++) {
265270
265322
  var net = networks[names[i]];
265271
265323
  for (var j = 0; j < net.length; j++) {
265272
265324
  var iface = net[j];
265273
265325
  if (isIPv4(iface.family) && !iface.internal) {
265274
- if (os$1.platform() === "darwin" && names[i] === "en0") return iface.address;
265326
+ if (os.platform() === "darwin" && names[i] === "en0") return iface.address;
265275
265327
  return "0.0.0.0";
265276
265328
  }
265277
265329
  }
@@ -265279,7 +265331,7 @@ var import_multicast_dns = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMi
265279
265331
  return "127.0.0.1";
265280
265332
  }
265281
265333
  function allInterfaces() {
265282
- var networks = os$1.networkInterfaces();
265334
+ var networks = os.networkInterfaces();
265283
265335
  var names = Object.keys(networks);
265284
265336
  var res = [];
265285
265337
  for (var i = 0; i < names.length; i++) {
@@ -293441,7 +293493,7 @@ function resolveBuildCommitFromEnv(env) {
293441
293493
  * environment descriptor down instead of reporting an honest "unknown".
293442
293494
  */
293443
293495
  function readBakedBuildCommit() {
293444
- return "1bdecd034b4ea69b2c72eaebd3134a3c4b916673";
293496
+ return "75c8e9532c9e35e71d4da1d8d45474fa2855ff1d";
293445
293497
  }
293446
293498
  async function resolveServerBuildCommit(input) {
293447
293499
  if (isFullCommitSha(input.baked)) return input.baked;
@@ -296502,6 +296554,19 @@ function toProjectorDecodeError(eventType) {
296502
296554
  });
296503
296555
  }
296504
296556
  //#endregion
296557
+ //#region src/orchestration/turnAccountSelection.ts
296558
+ /** A per-turn account choice remains local to the thread and cannot change its provider. */
296559
+ function turnAccountSelection(current, requested) {
296560
+ if (!requested || requested.provider !== current.provider) return void 0;
296561
+ if (requested.provider !== "codex" && requested.provider !== "claudeAgent") return void 0;
296562
+ const currentAccountId = "providerAccountId" in current ? current.providerAccountId : void 0;
296563
+ if (requested.providerAccountId === void 0 || requested.providerAccountId === currentAccountId) return void 0;
296564
+ return {
296565
+ ...current,
296566
+ providerAccountId: requested.providerAccountId
296567
+ };
296568
+ }
296569
+ //#endregion
296505
296570
  //#region src/orchestration/commandInvariants.ts
296506
296571
  function invariantError(commandType, detail) {
296507
296572
  return new OrchestrationCommandInvariantError({
@@ -297040,7 +297105,9 @@ const decideOrchestrationCommand = fn$1("decideOrchestrationCommand")(function*
297040
297105
  createdAt: command.createdAt
297041
297106
  }
297042
297107
  };
297043
- if (!(targetThread.anchorKind !== nextAnchor.anchorKind || targetThread.anchorCmmdId !== nextAnchor.anchorCmmdId)) return [userMessageEvent, turnStartRequestedEvent];
297108
+ const shouldUpdateAnchor = targetThread.anchorKind !== nextAnchor.anchorKind || targetThread.anchorCmmdId !== nextAnchor.anchorCmmdId;
297109
+ const accountSelection = turnAccountSelection(targetThread.modelSelection, command.modelSelection);
297110
+ if (!shouldUpdateAnchor && !accountSelection) return [userMessageEvent, turnStartRequestedEvent];
297044
297111
  return [
297045
297112
  {
297046
297113
  ...withEventBase({
@@ -297054,6 +297121,7 @@ const decideOrchestrationCommand = fn$1("decideOrchestrationCommand")(function*
297054
297121
  threadId: command.threadId,
297055
297122
  anchorKind: nextAnchor.anchorKind,
297056
297123
  anchorCmmdId: nextAnchor.anchorCmmdId,
297124
+ ...accountSelection ? { modelSelection: accountSelection } : {},
297057
297125
  updatedAt: command.createdAt
297058
297126
  }
297059
297127
  },
@@ -317283,7 +317351,7 @@ const connectLoginCommand = make$34("login", {
317283
317351
  })).json();
317284
317352
  },
317285
317353
  openBrowser: async (url) => {
317286
- const open = (await import("./open-FIgTDosf.mjs")).default;
317354
+ const open = (await import("./open-D8mGyWmt.mjs")).default;
317287
317355
  await open(url);
317288
317356
  return true;
317289
317357
  },