@cmmd-center/forge 0.10.0 → 0.10.1

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.
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 $U, { homedir, networkInterfaces, tmpdir } from "node:os";
25
+ import os, { 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";
@@ -49564,7 +49564,7 @@ function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
49564
49564
  const min = forceColor || 0;
49565
49565
  if (env.TERM === "dumb") return min;
49566
49566
  if (process$1.platform === "win32") {
49567
- const osRelease = $U.release().split(".");
49567
+ const osRelease = os.release().split(".");
49568
49568
  if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) return Number(osRelease[2]) >= 14931 ? 3 : 2;
49569
49569
  return 1;
49570
49570
  }
@@ -52007,7 +52007,7 @@ var require_ProcessDetector = /* @__PURE__ */ __commonJSMin(((exports) => {
52007
52007
  exports.processDetector = void 0;
52008
52008
  const api_1 = (init_esm$1(), __toCommonJS(esm_exports$1));
52009
52009
  const semconv_1 = require_semconv$1();
52010
- const os$3 = __require("os");
52010
+ const os$4 = __require("os");
52011
52011
  /**
52012
52012
  * ProcessDetector will be used to detect the resources related current process running
52013
52013
  * and being instrumented from the NodeJS Process module.
@@ -52029,7 +52029,7 @@ var require_ProcessDetector = /* @__PURE__ */ __commonJSMin(((exports) => {
52029
52029
  };
52030
52030
  if (process.argv.length > 1) attributes[semconv_1.ATTR_PROCESS_COMMAND] = process.argv[1];
52031
52031
  try {
52032
- const userInfo = os$3.userInfo();
52032
+ const userInfo = os$4.userInfo();
52033
52033
  attributes[semconv_1.ATTR_PROCESS_OWNER] = userInfo.username;
52034
52034
  } catch (e) {
52035
52035
  api_1.diag.debug(`error obtaining process owner: ${e}`);
@@ -64952,7 +64952,7 @@ function normalizeNumberish(value) {
64952
64952
  }
64953
64953
  //#endregion
64954
64954
  //#region package.json
64955
- var version$1 = "0.10.0";
64955
+ var version$1 = "0.10.1";
64956
64956
  //#endregion
64957
64957
  //#region src/sentry.ts
64958
64958
  const SERVER_APP_NAME = "forge-server";
@@ -68099,6 +68099,13 @@ const resolveBaseDir = fn$1(function* (raw) {
68099
68099
  if (!raw || raw.trim().length === 0) return join(NodeOS.homedir(), ".forge");
68100
68100
  return resolve(yield* expandHomePath$1(raw.trim()));
68101
68101
  });
68102
+ function bunHttpServerOptions(config) {
68103
+ return {
68104
+ port: config.port,
68105
+ ...config.host ? { hostname: config.host } : {},
68106
+ idleTimeout: 120
68107
+ };
68108
+ }
68102
68109
  //#endregion
68103
68110
  //#region ../../packages/shared/src/loopback.ts
68104
68111
  const LOOPBACK_HOSTNAMES$1 = new Set([
@@ -73583,7 +73590,7 @@ var require_node_gyp_build = /* @__PURE__ */ __commonJSMin(((exports, module) =>
73583
73590
  var fs$6 = __require("fs");
73584
73591
  var path$5 = __require("path");
73585
73592
  var url$1 = __require("url");
73586
- var os$2 = __require("os");
73593
+ var os$3 = __require("os");
73587
73594
  var runtimeRequire = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
73588
73595
  var vars = process.config && process.config.variables || {};
73589
73596
  var prebuildsOnly = !!process.env.PREBUILDS_ONLY;
@@ -73591,8 +73598,8 @@ var require_node_gyp_build = /* @__PURE__ */ __commonJSMin(((exports, module) =>
73591
73598
  var abi = versions.modules;
73592
73599
  if (versions.deno || process.isBun) abi = "unsupported";
73593
73600
  var runtime = isElectron() ? "electron" : isNwjs() ? "node-webkit" : "node";
73594
- var arch = process.env.npm_config_arch || os$2.arch();
73595
- var platform = process.env.npm_config_platform || os$2.platform();
73601
+ var arch = process.env.npm_config_arch || os$3.arch();
73602
+ var platform = process.env.npm_config_platform || os$3.platform();
73596
73603
  var libc = process.env.LIBC || (isMusl(platform) ? "musl" : "glibc");
73597
73604
  var armv = process.env.ARM_VERSION || (arch === "arm64" ? "8" : vars.arm_version) || "";
73598
73605
  var uv = (versions.uv || "").split(".")[0];
@@ -91250,7 +91257,7 @@ const launchDetached = (launch) => gen(function* () {
91250
91257
  });
91251
91258
  const OpenLive = effect(Open, gen(function* () {
91252
91259
  const open = yield* tryPromise({
91253
- try: () => import("./open-D8mGyWmt.mjs"),
91260
+ try: () => import("./open-FIgTDosf.mjs"),
91254
91261
  catch: (cause) => new OpenError$1({
91255
91262
  message: "failed to load browser opener",
91256
91263
  cause
@@ -97564,6 +97571,31 @@ function mapClaudeRateLimitInfo(info) {
97564
97571
  }
97565
97572
  };
97566
97573
  }
97574
+ const SEVEN_DAY_MODEL_PREFIX = "seven_day_";
97575
+ const SEVEN_DAY_OVERAGE_SUFFIX = "overage_included";
97576
+ function capitalizeModelSuffix(suffix) {
97577
+ return suffix.length === 0 ? suffix : suffix.charAt(0).toUpperCase() + suffix.slice(1);
97578
+ }
97579
+ /**
97580
+ * Maps a per-model weekly SDKRateLimitInfo (`seven_day_<model>`, e.g.
97581
+ * `seven_day_opus`) into a `ProviderUsageModelWindow`. `seven_day_overage_included`
97582
+ * is not a per-model window (it reports overage-inclusive quota, not a
97583
+ * specific model) and stays ignored here, same as plain `overage`.
97584
+ */
97585
+ function mapClaudeModelRateLimitInfo(info) {
97586
+ if (typeof info.utilization !== "number" || typeof info.resetsAt !== "number" || !info.status) return null;
97587
+ if (!info.rateLimitType?.startsWith(SEVEN_DAY_MODEL_PREFIX)) return null;
97588
+ const suffix = info.rateLimitType.slice(10);
97589
+ if (suffix.length === 0 || suffix === SEVEN_DAY_OVERAGE_SUFFIX) return null;
97590
+ return {
97591
+ model: capitalizeModelSuffix(suffix),
97592
+ window: {
97593
+ usedPercent: Math.round(info.utilization * 100),
97594
+ resetsAt: (/* @__PURE__ */ new Date(info.resetsAt * 1e3)).toISOString(),
97595
+ status: info.status
97596
+ }
97597
+ };
97598
+ }
97567
97599
  const cachedSnapshots = /* @__PURE__ */ new Map();
97568
97600
  let localClaudeGenerationHash = null;
97569
97601
  function setLocalClaudeUsageGeneration(generationId) {
@@ -97573,22 +97605,71 @@ function currentClaudeUsageGenerationHash() {
97573
97605
  const value = process.env.FORGE_PERSONAL_CLAUDE_GENERATION_HASH?.trim() ?? "";
97574
97606
  return /^[a-f0-9]{64}$/.test(value) ? value : localClaudeGenerationHash;
97575
97607
  }
97576
- /** Merges a single-window update into the cached snapshot without clobbering the other window. */
97577
- function recordClaudeRateLimitTelemetry(info, generationHash = currentClaudeUsageGenerationHash(), providerAccountId) {
97578
- const mapped = mapClaudeRateLimitInfo(info);
97579
- if (!mapped || generationHash === null) return;
97580
- const observedAt = (/* @__PURE__ */ new Date()).toISOString();
97581
- const cacheKey = providerAccountId ? `${providerAccountId}:${generationHash}` : generationHash;
97582
- const previous = cachedSnapshots.get(cacheKey);
97583
- const fiveHourObservedAt = mapped.kind === "fiveHour" ? observedAt : previous?.fiveHourObservedAt ?? null;
97584
- const sevenDayObservedAt = mapped.kind === "sevenDay" ? observedAt : previous?.sevenDayObservedAt ?? null;
97585
- cachedSnapshots.set(cacheKey, {
97586
- fiveHour: mapped.kind === "fiveHour" ? mapped.window : previous?.fiveHour ?? null,
97587
- sevenDay: mapped.kind === "sevenDay" ? mapped.window : previous?.sevenDay ?? null,
97608
+ function cacheKeyFor(generationHash, providerAccountId) {
97609
+ return providerAccountId ? `${providerAccountId}:${generationHash}` : generationHash;
97610
+ }
97611
+ /**
97612
+ * `observedAt` here is a placeholder, not an observation — it becomes
97613
+ * meaningful only once a standard (five_hour/seven_day) window actually
97614
+ * lands via `withStandardWindow`, which recomputes it from the retained
97615
+ * windows' own observation times. A per-model-only cache (no standard window
97616
+ * yet) still carries this placeholder, so callers should treat `observedAt`
97617
+ * as trustworthy only once `fiveHour` or `sevenDay` is non-null.
97618
+ */
97619
+ function emptyCachedSnapshot(observedAt) {
97620
+ return {
97621
+ fiveHour: null,
97622
+ sevenDay: null,
97623
+ modelWindowsByModel: {},
97624
+ observedAt,
97625
+ fiveHourObservedAt: null,
97626
+ sevenDayObservedAt: null
97627
+ };
97628
+ }
97629
+ /** Oldest observation among the retained standard windows, so one fresh event cannot mask stale data. */
97630
+ function oldestObservedAt(fiveHourObservedAt, sevenDayObservedAt) {
97631
+ return [fiveHourObservedAt, sevenDayObservedAt].filter((value) => value !== null).toSorted()[0];
97632
+ }
97633
+ function withStandardWindow(previous, mapped, observedAt) {
97634
+ const isFiveHour = mapped.kind === "fiveHour";
97635
+ const fiveHourObservedAt = isFiveHour ? observedAt : previous.fiveHourObservedAt;
97636
+ const sevenDayObservedAt = isFiveHour ? previous.sevenDayObservedAt : observedAt;
97637
+ return {
97638
+ ...previous,
97639
+ fiveHour: isFiveHour ? mapped.window : previous.fiveHour,
97640
+ sevenDay: isFiveHour ? previous.sevenDay : mapped.window,
97588
97641
  fiveHourObservedAt,
97589
97642
  sevenDayObservedAt,
97590
- observedAt: [fiveHourObservedAt, sevenDayObservedAt].filter((value) => value !== null).toSorted()[0]
97591
- });
97643
+ observedAt: oldestObservedAt(fiveHourObservedAt, sevenDayObservedAt)
97644
+ };
97645
+ }
97646
+ function withModelWindow(previous, mapped) {
97647
+ return {
97648
+ ...previous,
97649
+ modelWindowsByModel: {
97650
+ ...previous.modelWindowsByModel,
97651
+ [mapped.model]: mapped.window
97652
+ }
97653
+ };
97654
+ }
97655
+ /**
97656
+ * Merges a single-window update into the cached snapshot without clobbering
97657
+ * the other windows. A per-model weekly report (`seven_day_<model>`) merges
97658
+ * into `modelWindowsByModel` keyed by model, leaving every other model and
97659
+ * the plain five_hour/seven_day windows untouched.
97660
+ */
97661
+ function recordClaudeRateLimitTelemetry(info, generationHash = currentClaudeUsageGenerationHash(), providerAccountId) {
97662
+ if (generationHash === null) return;
97663
+ const cacheKey = cacheKeyFor(generationHash, providerAccountId);
97664
+ const observedAt = (/* @__PURE__ */ new Date()).toISOString();
97665
+ const previous = cachedSnapshots.get(cacheKey) ?? emptyCachedSnapshot(observedAt);
97666
+ const standard = mapClaudeRateLimitInfo(info);
97667
+ if (standard) {
97668
+ cachedSnapshots.set(cacheKey, withStandardWindow(previous, standard, observedAt));
97669
+ return;
97670
+ }
97671
+ const model = mapClaudeModelRateLimitInfo(info);
97672
+ if (model) cachedSnapshots.set(cacheKey, withModelWindow(previous, model));
97592
97673
  }
97593
97674
  //#endregion
97594
97675
  //#region src/providerAuth/ClaudeDeviceAuth.ts
@@ -97792,6 +97873,44 @@ function parseUsageLine(output, label, now) {
97792
97873
  status: usageStatus(usedPercent)
97793
97874
  };
97794
97875
  }
97876
+ const MODEL_WEEK_LINE = /^Current week \(([^)]+)\): (\d+(?:\.\d+)?)% used(?: · resets (.+))?$/gm;
97877
+ const ALL_MODELS_LABEL = "all models";
97878
+ /** Matches CMMD's own bound in `personal-claude-usage.ts` — a model name past
97879
+ * this is treated as noise, not a real per-model window. */
97880
+ const MAX_MODEL_NAME_LENGTH = 64;
97881
+ /** Matches CMMD's own cap in `personal-claude-usage.ts`. */
97882
+ const MAX_MODEL_WINDOWS = 32;
97883
+ /**
97884
+ * Parses every "Current week (<Model>)" line except the "(all models)" row
97885
+ * already handled by `parseUsageLine`. The exclusion is case-insensitive to
97886
+ * match CMMD's own parser. A per-model line usually carries no reset suffix
97887
+ * of its own — Claude Code shows the same weekly reset as the all-models row
97888
+ * — so a missing suffix falls back to `sevenDayResetsAt`. A malformed line
97889
+ * (bad percent, unparsable reset, an implausibly long model name) is
97890
+ * skipped, not fatal: the two required lines are what fail closed, not these
97891
+ * optional extras. The result is capped at CMMD's own `modelWindows` bound so
97892
+ * an unexpectedly large or noisy `/usage` output can't grow the publish body
97893
+ * without limit.
97894
+ */
97895
+ function parseModelUsageLines(output, sevenDayResetsAt, now) {
97896
+ const windows = [];
97897
+ for (const match of output.matchAll(MODEL_WEEK_LINE)) {
97898
+ const model = match[1];
97899
+ if (model.toLowerCase() === ALL_MODELS_LABEL) continue;
97900
+ if (model.length > MAX_MODEL_NAME_LENGTH) continue;
97901
+ const usedPercent = Number(match[2]);
97902
+ if (!Number.isFinite(usedPercent) || usedPercent < 0 || usedPercent > 100) continue;
97903
+ const resetsAt = match[3] ? parseResetAt(match[3], now) : sevenDayResetsAt;
97904
+ if (resetsAt === null) continue;
97905
+ windows.push({
97906
+ model,
97907
+ usedPercent,
97908
+ resetsAt,
97909
+ status: usageStatus(usedPercent)
97910
+ });
97911
+ }
97912
+ return windows.slice(0, MAX_MODEL_WINDOWS);
97913
+ }
97795
97914
  async function fetchClaudeUsageViaOfficialClient(input) {
97796
97915
  const raw = await (input.run ?? runClaudeUsageCommand)(input.binaryPath, USAGE_ARGS, input.claudeConfigDir);
97797
97916
  const parsed = JSON.parse(raw);
@@ -97803,7 +97922,8 @@ async function fetchClaudeUsageViaOfficialClient(input) {
97803
97922
  if (fiveHour === null || sevenDay === null) throw new Error("Claude client usage output shape changed.");
97804
97923
  return {
97805
97924
  fiveHour,
97806
- sevenDay
97925
+ sevenDay,
97926
+ modelWindows: parseModelUsageLines(parsed.result, sevenDay.resetsAt, now)
97807
97927
  };
97808
97928
  }
97809
97929
  //#endregion
@@ -98001,27 +98121,61 @@ const logUsagePublishFailure = (failure, path) => failure === null ? void_$1 : l
98001
98121
  stack: failure.cause instanceof Error ? failure.cause.stack : void 0,
98002
98122
  path
98003
98123
  });
98124
+ /**
98125
+ * True only when CMMD's own telemetry schema is the reason the publish
98126
+ * failed, and only for a body that actually carried the field it can't
98127
+ * parse — never for a 400 caused by something else in the same body.
98128
+ */
98129
+ function isModelWindowsRejection(cause, body) {
98130
+ return cause instanceof CmmdProxyRequestError && cause.status === 400 && "modelWindows" in body;
98131
+ }
98132
+ /**
98133
+ * Sends the usage-publish body, tolerant of a CMMD deployment that has not
98134
+ * yet rolled out per-model windows. CMMD's telemetry schema is `.strict()`,
98135
+ * so an unrecognized `modelWindows` key fails the WHOLE body with a 400 —
98136
+ * losing fiveHour/sevenDay too, not just the field it can't parse yet. Retry
98137
+ * exactly once with that key omitted rather than losing the publish
98138
+ * outright; deploy CMMD first so this retry becomes unnecessary. A second
98139
+ * failure (still 400, or anything else) propagates like any other publish
98140
+ * failure — this is a rollout accommodation, not a general retry policy.
98141
+ */
98142
+ async function publishUsageBody(jwt, path, body) {
98143
+ try {
98144
+ await cmmdGateway.request({
98145
+ method: "POST",
98146
+ jwt,
98147
+ path,
98148
+ body
98149
+ });
98150
+ } catch (cause) {
98151
+ if (!isModelWindowsRejection(cause, body)) throw cause;
98152
+ const { modelWindows: _modelWindows, ...bodyWithoutModelWindows } = body;
98153
+ console.info("[cmmd-claude-cred-sync] usage publish retried without modelWindows — CMMD predates per-model rate-limit windows", { path });
98154
+ await cmmdGateway.request({
98155
+ method: "POST",
98156
+ jwt,
98157
+ path,
98158
+ body: bodyWithoutModelWindows
98159
+ });
98160
+ }
98161
+ }
98004
98162
  async function publishClaudeUsageAfterSync(input) {
98005
98163
  try {
98006
98164
  const usage = await input.loadUsage({
98007
98165
  binaryPath: resolveClaudeBinaryPath("claude"),
98008
98166
  ...input.homePath ? { claudeConfigDir: input.homePath } : {}
98009
98167
  });
98010
- await cmmdGateway.request({
98011
- method: "POST",
98012
- jwt: input.auth.jwt,
98013
- path: input.auth.path === AUTH_RUNTIME_CLAUDE_CREDENTIAL_PATH ? AUTH_RUNTIME_CLAUDE_USAGE_PATH : USER_CLAUDE_USAGE_PATH,
98014
- body: {
98015
- providerAccountId: input.providerAccountId,
98016
- credentialGenerationId: input.credentialGenerationId,
98017
- accountEmail: input.accountEmail,
98018
- accountDisplayName: input.accountDisplayName,
98019
- planType: input.planType,
98020
- source: "active_poll",
98021
- fiveHour: usage.fiveHour,
98022
- sevenDay: usage.sevenDay,
98023
- observedAt: (/* @__PURE__ */ new Date()).toISOString()
98024
- }
98168
+ await publishUsageBody(input.auth.jwt, input.auth.path === AUTH_RUNTIME_CLAUDE_CREDENTIAL_PATH ? AUTH_RUNTIME_CLAUDE_USAGE_PATH : USER_CLAUDE_USAGE_PATH, {
98169
+ providerAccountId: input.providerAccountId,
98170
+ credentialGenerationId: input.credentialGenerationId,
98171
+ accountEmail: input.accountEmail,
98172
+ accountDisplayName: input.accountDisplayName,
98173
+ planType: input.planType,
98174
+ source: "active_poll",
98175
+ fiveHour: usage.fiveHour,
98176
+ sevenDay: usage.sevenDay,
98177
+ modelWindows: usage.modelWindows,
98178
+ observedAt: (/* @__PURE__ */ new Date()).toISOString()
98025
98179
  });
98026
98180
  return null;
98027
98181
  } catch (cause) {
@@ -185223,7 +185377,7 @@ var Vce = {
185223
185377
  function Ve() {
185224
185378
  return Vce;
185225
185379
  }
185226
- var Us = $U.homedir(), lk = $U.tmpdir(), { env: Vc } = process$1, Yce = (e) => {
185380
+ var Us = os.homedir(), lk = os.tmpdir(), { env: Vc } = process$1, Yce = (e) => {
185227
185381
  let t = path.join(Us, "Library");
185228
185382
  return {
185229
185383
  data: path.join(t, "Application Support", e),
@@ -195423,12 +195577,12 @@ function qZ(e, t) {
195423
195577
  }
195424
195578
  return n;
195425
195579
  }
195426
- var os$1 = "https://code.claude.com/docs/en", kKe = [
195580
+ var os$2 = "https://code.claude.com/docs/en", kKe = [
195427
195581
  {
195428
195582
  matches: (e) => e.path === "permissions.defaultMode" && e.code === "invalid_value",
195429
195583
  tip: {
195430
195584
  suggestion: "Valid modes: \"acceptEdits\" (ask before file changes), \"plan\" (analysis only), \"bypassPermissions\" (auto-accept all), or \"default\" (standard behavior)",
195431
- docLink: `${os$1}/iam#permission-modes`
195585
+ docLink: `${os$2}/iam#permission-modes`
195432
195586
  }
195433
195587
  },
195434
195588
  {
@@ -195443,7 +195597,7 @@ var os$1 = "https://code.claude.com/docs/en", kKe = [
195443
195597
  matches: (e) => e.path.startsWith("env.") && e.code === "invalid_type",
195444
195598
  tip: {
195445
195599
  suggestion: "Environment variables must be strings. Wrap numbers and booleans in quotes. Example: \"DEBUG\": \"true\", \"PORT\": \"3000\"",
195446
- docLink: `${os$1}/settings#environment-variables`
195600
+ docLink: `${os$2}/settings#environment-variables`
195447
195601
  }
195448
195602
  },
195449
195603
  {
@@ -195454,14 +195608,14 @@ var os$1 = "https://code.claude.com/docs/en", kKe = [
195454
195608
  matches: (e) => e.path.startsWith("hooks.") && e.code === "invalid_key",
195455
195609
  tip: {
195456
195610
  suggestion: "Not a recognized hook event. Common events: PreToolUse, PostToolUse, UserPromptSubmit, SessionStart, SessionEnd, Stop. Check spelling and capitalization.",
195457
- docLink: `${os$1}/hooks`
195611
+ docLink: `${os$2}/hooks`
195458
195612
  }
195459
195613
  },
195460
195614
  {
195461
195615
  matches: (e) => /\.hooks\.\d+\.command$/.test(e.path) && e.code === "invalid_type" && e.received === "undefined",
195462
195616
  tip: {
195463
195617
  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\"}.",
195464
- docLink: `${os$1}/hooks#exec-form-and-shell-form`
195618
+ docLink: `${os$2}/hooks#exec-form-and-shell-form`
195465
195619
  }
195466
195620
  },
195467
195621
  {
@@ -195476,7 +195630,7 @@ var os$1 = "https://code.claude.com/docs/en", kKe = [
195476
195630
  matches: (e) => e.code === "unrecognized_keys",
195477
195631
  tip: {
195478
195632
  suggestion: "Check for typos or refer to the documentation for valid fields",
195479
- docLink: `${os$1}/settings`
195633
+ docLink: `${os$2}/settings`
195480
195634
  }
195481
195635
  },
195482
195636
  {
@@ -195491,13 +195645,13 @@ var os$1 = "https://code.claude.com/docs/en", kKe = [
195491
195645
  matches: (e) => e.path === "permissions.additionalDirectories" && e.code === "invalid_type",
195492
195646
  tip: {
195493
195647
  suggestion: "Must be an array of directory paths. Example: [\"~/projects\", \"/tmp/workspace\"]. You can also use --add-dir flag or /add-dir command",
195494
- docLink: `${os$1}/iam#working-directories`
195648
+ docLink: `${os$2}/iam#working-directories`
195495
195649
  }
195496
195650
  }
195497
195651
  ], AKe = {
195498
- permissions: `${os$1}/iam#configuring-permissions`,
195499
- env: `${os$1}/settings#environment-variables`,
195500
- hooks: `${os$1}/hooks`
195652
+ permissions: `${os$2}/iam#configuring-permissions`,
195653
+ env: `${os$2}/settings#environment-variables`,
195654
+ hooks: `${os$2}/hooks`
195501
195655
  };
195502
195656
  function GZ(e) {
195503
195657
  let t = kKe.find((r) => r.matches(e));
@@ -259809,7 +259963,7 @@ var import_multicast_dns = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMi
259809
259963
  var dgram = __require("dgram");
259810
259964
  var thunky = require_thunky();
259811
259965
  var events = __require("events");
259812
- var os = __require("os");
259966
+ var os$1 = __require("os");
259813
259967
  var noop = function() {};
259814
259968
  module.exports = function(opts) {
259815
259969
  if (!opts) opts = {};
@@ -259940,14 +260094,14 @@ var import_multicast_dns = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMi
259940
260094
  return that;
259941
260095
  };
259942
260096
  function defaultInterface() {
259943
- var networks = os.networkInterfaces();
260097
+ var networks = os$1.networkInterfaces();
259944
260098
  var names = Object.keys(networks);
259945
260099
  for (var i = 0; i < names.length; i++) {
259946
260100
  var net = networks[names[i]];
259947
260101
  for (var j = 0; j < net.length; j++) {
259948
260102
  var iface = net[j];
259949
260103
  if (isIPv4(iface.family) && !iface.internal) {
259950
- if (os.platform() === "darwin" && names[i] === "en0") return iface.address;
260104
+ if (os$1.platform() === "darwin" && names[i] === "en0") return iface.address;
259951
260105
  return "0.0.0.0";
259952
260106
  }
259953
260107
  }
@@ -259955,7 +260109,7 @@ var import_multicast_dns = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMi
259955
260109
  return "127.0.0.1";
259956
260110
  }
259957
260111
  function allInterfaces() {
259958
- var networks = os.networkInterfaces();
260112
+ var networks = os$1.networkInterfaces();
259959
260113
  var names = Object.keys(networks);
259960
260114
  var res = [];
259961
260115
  for (var i = 0; i < names.length; i++) {
@@ -288374,7 +288528,7 @@ function resolveBuildCommitFromEnv(env) {
288374
288528
  * environment descriptor down instead of reporting an honest "unknown".
288375
288529
  */
288376
288530
  function readBakedBuildCommit() {
288377
- return "4f80a79430e58ba6f2e487d692fdefeb66e8486f";
288531
+ return "abd184dd1d3a4d5156ad021326b71afb06430b1b";
288378
288532
  }
288379
288533
  async function resolveServerBuildCommit(input) {
288380
288534
  if (isFullCommitSha(input.baked)) return input.baked;
@@ -309993,6 +310147,7 @@ const claudeUsageHandler = (dependencies) => gen(function* () {
309993
310147
  response = jsonUnsafe({
309994
310148
  fiveHour: usage.fiveHour,
309995
310149
  sevenDay: usage.sevenDay,
310150
+ modelWindows: usage.modelWindows,
309996
310151
  observedAt: observedAt.toISOString(),
309997
310152
  receipt: {
309998
310153
  orgId: claims.orgId,
@@ -310282,10 +310437,7 @@ const PtyAdapterLive = unwrap(gen(function* () {
310282
310437
  }));
310283
310438
  const HttpServerLive = unwrap(gen(function* () {
310284
310439
  const config = yield* ServerConfig;
310285
- if (typeof Bun !== "undefined") return (yield* promise(() => import("./BunHttpServer-G-hOZ_UH.mjs"))).layer({
310286
- port: config.port,
310287
- ...config.host ? { hostname: config.host } : {}
310288
- });
310440
+ if (typeof Bun !== "undefined") return (yield* promise(() => import("./BunHttpServer-G-hOZ_UH.mjs"))).layer(bunHttpServerOptions(config));
310289
310441
  const [NodeHttpServer, NodeHttp] = yield* all([promise(() => import("./NodeHttpServer-soWs9SdF.mjs")), promise(() => import("node:http"))]);
310290
310442
  return NodeHttpServer.layer(NodeHttp.createServer, {
310291
310443
  host: config.host,
@@ -311292,7 +311444,7 @@ const connectLoginCommand = make$33("login", {
311292
311444
  })).json();
311293
311445
  },
311294
311446
  openBrowser: async (url) => {
311295
- const open = (await import("./open-D8mGyWmt.mjs")).default;
311447
+ const open = (await import("./open-FIgTDosf.mjs")).default;
311296
311448
  await open(url);
311297
311449
  return true;
311298
311450
  },