codexuse-cli 3.7.0 → 3.7.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.
@@ -7,7 +7,7 @@ import { execFileSync, spawn, spawnSync } from "node:child_process";
7
7
  import * as Crypto from "node:crypto";
8
8
  import crypto$1, { createHash, randomBytes, randomUUID } from "node:crypto";
9
9
  import * as NFS from "node:fs";
10
- import fs, { accessSync, constants, createReadStream, existsSync, promises, readFileSync, realpathSync, statSync } from "node:fs";
10
+ import fs, { accessSync, constants, existsSync, promises, readFileSync, realpathSync, statSync } from "node:fs";
11
11
  import * as OS from "node:os";
12
12
  import os from "node:os";
13
13
  import * as Path from "node:path";
@@ -19195,6 +19195,9 @@ const GeneralChatEnsureResult = Struct({
19195
19195
  created: Boolean$2
19196
19196
  });
19197
19197
  //#endregion
19198
+ //#region ../../packages/t3-contracts/src/agentChat.ts
19199
+ const AgentChatConfig = GeneralChatConfig;
19200
+ //#endregion
19198
19201
  //#region ../../packages/t3-contracts/src/server.ts
19199
19202
  const KeybindingsMalformedConfigIssue = Struct({
19200
19203
  kind: Literal("keybindings.malformed-config"),
@@ -19239,6 +19242,7 @@ const ServerConfig = Struct({
19239
19242
  providers: ServerProviderStatuses,
19240
19243
  availableEditors: Array$1(EditorId),
19241
19244
  projectPolicy: ServerProjectPolicy,
19245
+ agentChat: AgentChatConfig,
19242
19246
  generalChat: GeneralChatConfig
19243
19247
  });
19244
19248
  const ServerUpsertKeybindingResult = Struct({
@@ -19250,6 +19254,7 @@ const ServerConfigUpdatedPayload = Struct({
19250
19254
  issues: ServerConfigIssues,
19251
19255
  providers: ServerProviderStatuses,
19252
19256
  projectPolicy: ServerProjectPolicy,
19257
+ agentChat: AgentChatConfig,
19253
19258
  generalChat: GeneralChatConfig
19254
19259
  });
19255
19260
  const ServerProviderUpdatedPayload = Struct({ providers: ServerProviderStatuses });
@@ -19262,6 +19267,7 @@ const WS_METHODS = {
19262
19267
  projectsEnsure: "projects.ensure",
19263
19268
  projectsSearchEntries: "projects.searchEntries",
19264
19269
  projectsWriteFile: "projects.writeFile",
19270
+ agentChatEnsure: "agentChat.ensure",
19265
19271
  generalChatEnsure: "generalChat.ensure",
19266
19272
  filesystemBrowse: "filesystem.browse",
19267
19273
  shellOpenInEditor: "shell.openInEditor",
@@ -19323,7 +19329,6 @@ const WS_METHODS = {
19323
19329
  cliStatus: "cli.status",
19324
19330
  cliCheckFreshness: "cli.checkFreshness",
19325
19331
  cliUpdateGlobal: "cli.updateGlobal",
19326
- analyticsGetData: "analytics.getData",
19327
19332
  accountPoolGetStatus: "accountPool.getStatus",
19328
19333
  accountPoolListProfiles: "accountPool.listProfiles",
19329
19334
  accountPoolListSessions: "accountPool.listSessions",
@@ -19363,6 +19368,7 @@ const WebSocketRequestBody = Union([
19363
19368
  tagRequestBody(WS_METHODS.projectsEnsure, ProjectEnsureInput),
19364
19369
  tagRequestBody(WS_METHODS.projectsSearchEntries, ProjectSearchEntriesInput),
19365
19370
  tagRequestBody(WS_METHODS.projectsWriteFile, ProjectWriteFileInput),
19371
+ tagRequestBody(WS_METHODS.agentChatEnsure, Struct({})),
19366
19372
  tagRequestBody(WS_METHODS.generalChatEnsure, Struct({})),
19367
19373
  tagRequestBody(WS_METHODS.filesystemBrowse, FilesystemBrowseInput),
19368
19374
  tagRequestBody(WS_METHODS.shellOpenInEditor, OpenInEditorInput),
@@ -19466,8 +19472,7 @@ const WebSocketRequestBody = Union([
19466
19472
  tagRequestBody(WS_METHODS.cliInfo, Struct({})),
19467
19473
  tagRequestBody(WS_METHODS.cliStatus, Struct({})),
19468
19474
  tagRequestBody(WS_METHODS.cliCheckFreshness, Struct({})),
19469
- tagRequestBody(WS_METHODS.cliUpdateGlobal, Struct({})),
19470
- tagRequestBody(WS_METHODS.analyticsGetData, Struct({ query: optional$2(Unknown) }))
19475
+ tagRequestBody(WS_METHODS.cliUpdateGlobal, Struct({}))
19471
19476
  ]);
19472
19477
  const WebSocketRequest = Struct({
19473
19478
  id: TrimmedNonEmptyString,
@@ -28693,7 +28698,7 @@ const SQLITE_BUSY_MAX_ATTEMPTS = 3;
28693
28698
  const SQLITE_BUSY_RETRY_DELAY_MS = 100;
28694
28699
  const writeQueueByDbPath = /* @__PURE__ */ new Map();
28695
28700
  const initializedDbPaths = /* @__PURE__ */ new Set();
28696
- function isRecord$10(value) {
28701
+ function isRecord$8(value) {
28697
28702
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
28698
28703
  }
28699
28704
  function clone$1(value) {
@@ -28797,7 +28802,7 @@ function resolveAppStorageDbPath(userDataDir) {
28797
28802
  async function readDocument(dbPath, namespace, normalize) {
28798
28803
  return withDatabase(dbPath, (db) => {
28799
28804
  const row = db.prepare(`SELECT value_json AS valueJson FROM ${APP_STORAGE_TABLE} WHERE namespace = ?`).get(namespace);
28800
- const parsed = isRecord$10(row) ? safeParseJson(row.valueJson) : null;
28805
+ const parsed = isRecord$8(row) ? safeParseJson(row.valueJson) : null;
28801
28806
  if (parsed === null) return null;
28802
28807
  return normalize(parsed);
28803
28808
  });
@@ -28828,7 +28833,7 @@ async function updateDocument(input) {
28828
28833
  beginImmediate(db);
28829
28834
  try {
28830
28835
  const row = db.prepare(`SELECT value_json AS valueJson FROM ${APP_STORAGE_TABLE} WHERE namespace = ?`).get(input.namespace);
28831
- const current = isRecord$10(row) ? input.normalize(safeParseJson(row.valueJson) ?? input.fallback()) : input.fallback();
28836
+ const current = isRecord$8(row) ? input.normalize(safeParseJson(row.valueJson) ?? input.fallback()) : input.fallback();
28832
28837
  const next = input.normalize(input.transform(clone$1(current)));
28833
28838
  db.prepare(`
28834
28839
  INSERT INTO ${APP_STORAGE_TABLE} (namespace, value_json, updated_at)
@@ -28855,7 +28860,7 @@ let configuredUserDataDir = null;
28855
28860
  let appStateCache = null;
28856
28861
  let writeLock = Promise.resolve();
28857
28862
  const writeLockContext = new AsyncLocalStorage();
28858
- function isRecord$9(value) {
28863
+ function isRecord$7(value) {
28859
28864
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
28860
28865
  }
28861
28866
  function clone(value) {
@@ -28933,8 +28938,7 @@ function createDefaultAppState() {
28933
28938
  welcomeResumeStep: null,
28934
28939
  milestones: {
28935
28940
  firstProfileAdded: false,
28936
- secondProfileAdded: false,
28937
- analyticsViewed: false
28941
+ secondProfileAdded: false
28938
28942
  },
28939
28943
  sessionCount: 0,
28940
28944
  nudgeCooldowns: {},
@@ -28983,7 +28987,7 @@ function asString$8(value) {
28983
28987
  }
28984
28988
  function normalizeAppState(raw) {
28985
28989
  const defaults = createDefaultAppState();
28986
- if (!isRecord$9(raw)) return defaults;
28990
+ if (!isRecord$7(raw)) return defaults;
28987
28991
  const merged = clone(deepMerge(defaults, raw));
28988
28992
  merged.schemaVersion = 1;
28989
28993
  if (typeof merged.autoRoll.enabled !== "boolean") merged.autoRoll.enabled = false;
@@ -29022,12 +29026,12 @@ function normalizeAppState(raw) {
29022
29026
  const allowedPreferenceKeys = new Set(Object.keys(defaults.preferences));
29023
29027
  for (const key of Object.keys(merged.preferences)) if (!allowedPreferenceKeys.has(key)) delete merged.preferences[key];
29024
29028
  }
29025
- if (!isRecord$9(merged.runtimeSettings)) merged.runtimeSettings = {};
29026
- if (!isRecord$9(merged.ui)) merged.ui = clone(defaults.ui);
29029
+ if (!isRecord$7(merged.runtimeSettings)) merged.runtimeSettings = {};
29030
+ if (!isRecord$7(merged.ui)) merged.ui = clone(defaults.ui);
29027
29031
  merged.ui.themeMode = merged.ui.themeMode === "light" || merged.ui.themeMode === "dark" ? merged.ui.themeMode : null;
29028
- if (!isRecord$9(merged.ui.layout)) merged.ui.layout = clone(defaults.ui.layout);
29032
+ if (!isRecord$7(merged.ui.layout)) merged.ui.layout = clone(defaults.ui.layout);
29029
29033
  if (typeof merged.ui.layout.sidebarCollapsed !== "boolean") merged.ui.layout.sidebarCollapsed = null;
29030
- if (!isRecord$9(merged.ui.profiles)) merged.ui.profiles = clone(defaults.ui.profiles);
29034
+ if (!isRecord$7(merged.ui.profiles)) merged.ui.profiles = clone(defaults.ui.profiles);
29031
29035
  merged.ui.profiles.viewMode = merged.ui.profiles.viewMode === "cards" || merged.ui.profiles.viewMode === "compact" ? merged.ui.profiles.viewMode : null;
29032
29036
  merged.ui.profiles.sortBy = asString$8(merged.ui.profiles.sortBy);
29033
29037
  merged.ui.profiles.groupBy = asString$8(merged.ui.profiles.groupBy);
@@ -29035,35 +29039,34 @@ function normalizeAppState(raw) {
29035
29039
  merged.ui.profiles.healthFilter = asString$8(merged.ui.profiles.healthFilter);
29036
29040
  merged.ui.profiles.customGroupFilter = asString$8(merged.ui.profiles.customGroupFilter);
29037
29041
  if (typeof merged.ui.profiles.toolbarOpen !== "boolean") merged.ui.profiles.toolbarOpen = null;
29038
- if (!isRecord$9(merged.ui.profiles.collapsedSections)) merged.ui.profiles.collapsedSections = {};
29042
+ if (!isRecord$7(merged.ui.profiles.collapsedSections)) merged.ui.profiles.collapsedSections = {};
29039
29043
  else merged.ui.profiles.collapsedSections = Object.fromEntries(Object.entries(merged.ui.profiles.collapsedSections).flatMap(([key, value]) => {
29040
29044
  const normalizedKey = asString$8(key);
29041
29045
  if (!normalizedKey || typeof value !== "boolean") return [];
29042
29046
  return [[normalizedKey, value]];
29043
29047
  }));
29044
- if (!isRecord$9(merged.ui.onboarding)) merged.ui.onboarding = clone(defaults.ui.onboarding);
29048
+ if (!isRecord$7(merged.ui.onboarding)) merged.ui.onboarding = clone(defaults.ui.onboarding);
29045
29049
  if (typeof merged.ui.onboarding.welcomeCompleted !== "boolean") merged.ui.onboarding.welcomeCompleted = false;
29046
29050
  if (!Number.isFinite(merged.ui.onboarding.welcomeCompletedAt)) merged.ui.onboarding.welcomeCompletedAt = null;
29047
29051
  merged.ui.onboarding.welcomeResumeStep = merged.ui.onboarding.welcomeResumeStep === 2 ? 2 : null;
29048
- if (!isRecord$9(merged.ui.onboarding.milestones)) merged.ui.onboarding.milestones = clone(defaults.ui.onboarding.milestones);
29052
+ if (!isRecord$7(merged.ui.onboarding.milestones)) merged.ui.onboarding.milestones = clone(defaults.ui.onboarding.milestones);
29049
29053
  if (typeof merged.ui.onboarding.milestones.firstProfileAdded !== "boolean") merged.ui.onboarding.milestones.firstProfileAdded = false;
29050
29054
  if (typeof merged.ui.onboarding.milestones.secondProfileAdded !== "boolean") merged.ui.onboarding.milestones.secondProfileAdded = false;
29051
- if (typeof merged.ui.onboarding.milestones.analyticsViewed !== "boolean") merged.ui.onboarding.milestones.analyticsViewed = false;
29052
29055
  if (!Number.isFinite(merged.ui.onboarding.sessionCount)) merged.ui.onboarding.sessionCount = 0;
29053
- if (!isRecord$9(merged.ui.onboarding.nudgeCooldowns)) merged.ui.onboarding.nudgeCooldowns = {};
29056
+ if (!isRecord$7(merged.ui.onboarding.nudgeCooldowns)) merged.ui.onboarding.nudgeCooldowns = {};
29054
29057
  else merged.ui.onboarding.nudgeCooldowns = Object.fromEntries(Object.entries(merged.ui.onboarding.nudgeCooldowns).flatMap(([key, value]) => {
29055
29058
  const normalizedKey = asString$8(key);
29056
29059
  if (!normalizedKey || !Number.isFinite(value)) return [];
29057
29060
  return [[normalizedKey, Number(value)]];
29058
29061
  }));
29059
- if (!isRecord$9(merged.ui.onboarding.nudgeDismissCount)) merged.ui.onboarding.nudgeDismissCount = {};
29062
+ if (!isRecord$7(merged.ui.onboarding.nudgeDismissCount)) merged.ui.onboarding.nudgeDismissCount = {};
29060
29063
  else merged.ui.onboarding.nudgeDismissCount = Object.fromEntries(Object.entries(merged.ui.onboarding.nudgeDismissCount).flatMap(([key, value]) => {
29061
29064
  const normalizedKey = asString$8(key);
29062
29065
  if (!normalizedKey || !Number.isFinite(value)) return [];
29063
29066
  return [[normalizedKey, Number(value)]];
29064
29067
  }));
29065
29068
  if (typeof merged.ui.onboarding.proUnlockedCelebrated !== "boolean") merged.ui.onboarding.proUnlockedCelebrated = false;
29066
- if (!isRecord$9(merged.ui.projectThreadSelections)) merged.ui.projectThreadSelections = {};
29069
+ if (!isRecord$7(merged.ui.projectThreadSelections)) merged.ui.projectThreadSelections = {};
29067
29070
  else merged.ui.projectThreadSelections = Object.fromEntries(Object.entries(merged.ui.projectThreadSelections).flatMap(([projectId, threadId]) => {
29068
29071
  const normalizedProjectId = asString$8(projectId);
29069
29072
  if (!normalizedProjectId) return [];
@@ -29075,8 +29078,8 @@ function normalizeAppState(raw) {
29075
29078
  const allowedUiKeys = new Set(Object.keys(defaults.ui));
29076
29079
  for (const key of Object.keys(merged.ui)) if (!allowedUiKeys.has(key)) delete merged.ui[key];
29077
29080
  }
29078
- if (!isRecord$9(merged.profileDashboard)) merged.profileDashboard = clone(defaults.profileDashboard);
29079
- if (!isRecord$9(merged.profileDashboard.customGroupsByAccountKey)) merged.profileDashboard.customGroupsByAccountKey = {};
29081
+ if (!isRecord$7(merged.profileDashboard)) merged.profileDashboard = clone(defaults.profileDashboard);
29082
+ if (!isRecord$7(merged.profileDashboard.customGroupsByAccountKey)) merged.profileDashboard.customGroupsByAccountKey = {};
29080
29083
  else merged.profileDashboard.customGroupsByAccountKey = Object.fromEntries(Object.entries(merged.profileDashboard.customGroupsByAccountKey).flatMap(([key, value]) => {
29081
29084
  const normalizedKey = asString$8(key);
29082
29085
  const normalizedValue = asString$8(value);
@@ -29087,30 +29090,30 @@ function normalizeAppState(raw) {
29087
29090
  const allowedProfileDashboardKeys = new Set(Object.keys(defaults.profileDashboard));
29088
29091
  for (const key of Object.keys(merged.profileDashboard)) if (!allowedProfileDashboardKeys.has(key)) delete merged.profileDashboard[key];
29089
29092
  }
29090
- const legacyProjectSettingsByPath = isRecord$9(raw.projectSettingsByPath) ? raw.projectSettingsByPath : null;
29091
- if (!isRecord$9(merged.workspaceSettingsByPath)) merged.workspaceSettingsByPath = {};
29093
+ const legacyProjectSettingsByPath = isRecord$7(raw.projectSettingsByPath) ? raw.projectSettingsByPath : null;
29094
+ if (!isRecord$7(merged.workspaceSettingsByPath)) merged.workspaceSettingsByPath = {};
29092
29095
  if (legacyProjectSettingsByPath) merged.workspaceSettingsByPath = {
29093
29096
  ...legacyProjectSettingsByPath,
29094
29097
  ...merged.workspaceSettingsByPath
29095
29098
  };
29096
29099
  delete merged.projectSettingsByPath;
29097
- if (!isRecord$9(merged.conversationCategoriesByCwd)) merged.conversationCategoriesByCwd = {};
29098
- if (!isRecord$9(merged.conversationCategoryAssignmentsByCwd)) merged.conversationCategoryAssignmentsByCwd = {};
29099
- if (!isRecord$9(merged.git)) merged.git = clone(defaults.git);
29100
+ if (!isRecord$7(merged.conversationCategoriesByCwd)) merged.conversationCategoriesByCwd = {};
29101
+ if (!isRecord$7(merged.conversationCategoryAssignmentsByCwd)) merged.conversationCategoryAssignmentsByCwd = {};
29102
+ if (!isRecord$7(merged.git)) merged.git = clone(defaults.git);
29100
29103
  merged.git.commitMessagePrompt = normalizeCommitMessagePrompt(merged.git.commitMessagePrompt) ?? DEFAULT_COMMIT_MESSAGE_PROMPT;
29101
29104
  {
29102
29105
  const allowedGitKeys = new Set(Object.keys(defaults.git));
29103
29106
  for (const key of Object.keys(merged.git)) if (!allowedGitKeys.has(key)) delete merged.git[key];
29104
29107
  }
29105
- if (!isRecord$9(merged.skills)) merged.skills = clone(defaults.skills);
29108
+ if (!isRecord$7(merged.skills)) merged.skills = clone(defaults.skills);
29106
29109
  if (!Array.isArray(merged.skills.sources)) merged.skills.sources = [];
29107
- if (!isRecord$9(merged.skills.installsBySlug)) merged.skills.installsBySlug = {};
29108
- if (!isRecord$9(merged.sync)) merged.sync = clone(defaults.sync);
29110
+ if (!isRecord$7(merged.skills.installsBySlug)) merged.skills.installsBySlug = {};
29111
+ if (!isRecord$7(merged.sync)) merged.sync = clone(defaults.sync);
29109
29112
  merged.sync.lastPushAt = asString$8(merged.sync.lastPushAt);
29110
29113
  merged.sync.lastPullAt = asString$8(merged.sync.lastPullAt);
29111
29114
  merged.sync.lastError = asString$8(merged.sync.lastError);
29112
29115
  merged.sync.remoteUpdatedAt = asString$8(merged.sync.remoteUpdatedAt);
29113
- if (!isRecord$9(merged.analytics)) merged.analytics = isRecord$9(merged.telemetry) ? clone(merged.telemetry) : clone(defaults.analytics);
29116
+ if (!isRecord$7(merged.analytics)) merged.analytics = isRecord$7(merged.telemetry) ? clone(merged.telemetry) : clone(defaults.analytics);
29114
29117
  merged.analytics.anonymousId = asString$8(merged.analytics.anonymousId);
29115
29118
  if (!merged.analytics.anonymousId) {
29116
29119
  const legacyInstallId = asString$8(merged.telemetry?.installId);
@@ -29120,8 +29123,8 @@ function normalizeAppState(raw) {
29120
29123
  merged.analytics.lastFlushAt = asString$8(merged.analytics.lastFlushAt);
29121
29124
  merged.analytics.lastError = asString$8(merged.analytics.lastError);
29122
29125
  if ("telemetry" in merged) delete merged.telemetry;
29123
- if (!isRecord$9(merged.profilesByName)) merged.profilesByName = {};
29124
- if (!isRecord$9(merged.migration)) merged.migration = clone(defaults.migration);
29126
+ if (!isRecord$7(merged.profilesByName)) merged.profilesByName = {};
29127
+ if (!isRecord$7(merged.migration)) merged.migration = clone(defaults.migration);
29125
29128
  if (![
29126
29129
  "pending",
29127
29130
  "pending_local_storage",
@@ -29134,7 +29137,7 @@ function normalizeAppState(raw) {
29134
29137
  return merged;
29135
29138
  }
29136
29139
  function deepMerge(base, patch) {
29137
- if (!isRecord$9(base) || !isRecord$9(patch)) return clone(patch ?? base);
29140
+ if (!isRecord$7(base) || !isRecord$7(patch)) return clone(patch ?? base);
29138
29141
  const next = { ...base };
29139
29142
  for (const [key, patchValue] of Object.entries(patch)) {
29140
29143
  if (patchValue === void 0) continue;
@@ -29143,7 +29146,7 @@ function deepMerge(base, patch) {
29143
29146
  next[key] = clone(patchValue);
29144
29147
  continue;
29145
29148
  }
29146
- if (isRecord$9(currentValue) && isRecord$9(patchValue)) {
29149
+ if (isRecord$7(currentValue) && isRecord$7(patchValue)) {
29147
29150
  next[key] = deepMerge(currentValue, patchValue);
29148
29151
  continue;
29149
29152
  }
@@ -29215,10 +29218,46 @@ async function patchAppState(patch) {
29215
29218
  });
29216
29219
  }
29217
29220
  //#endregion
29221
+ //#region ../../packages/runtime-app-state/src/app/agentChatWorkspace.ts
29222
+ const AGENT_CHAT_WORKSPACE_DIRNAME = "agent-chat-workspace";
29223
+ const AGENT_CHAT_PROJECT_TITLE = "Agent";
29224
+ const AGENT_CHAT_AGENTS_FILENAME = "AGENTS.md";
29225
+ const IS_CASE_INSENSITIVE_PLATFORM$2 = process.platform === "darwin" || process.platform === "win32";
29226
+ function stripTrailingSeparators$2(input) {
29227
+ const trimmed = input.trim();
29228
+ if (trimmed.length === 0) return trimmed;
29229
+ const root = path.parse(trimmed).root;
29230
+ let next = trimmed;
29231
+ while (next.length > root.length && /[\\/]+$/.test(next)) next = next.slice(0, -1);
29232
+ return next;
29233
+ }
29234
+ function canonicalizeWorkspaceRoot$1(input) {
29235
+ const resolved = path.resolve(input.trim());
29236
+ return stripTrailingSeparators$2((() => {
29237
+ try {
29238
+ return realpathSync.native(resolved);
29239
+ } catch {
29240
+ return resolved;
29241
+ }
29242
+ })());
29243
+ }
29244
+ function workspaceRootKey$1(input) {
29245
+ const canonical = canonicalizeWorkspaceRoot$1(input).replaceAll("\\", "/");
29246
+ return IS_CASE_INSENSITIVE_PLATFORM$2 ? canonical.toLowerCase() : canonical;
29247
+ }
29248
+ function resolveAgentChatWorkspaceRoot() {
29249
+ return canonicalizeWorkspaceRoot$1(path.join(getUserDataDir(), AGENT_CHAT_WORKSPACE_DIRNAME));
29250
+ }
29251
+ function resolveAgentChatAgentsPath() {
29252
+ return path.join(resolveAgentChatWorkspaceRoot(), AGENT_CHAT_AGENTS_FILENAME);
29253
+ }
29254
+ function isAgentChatWorkspaceRoot(workspaceRoot) {
29255
+ return workspaceRootKey$1(workspaceRoot) === workspaceRootKey$1(resolveAgentChatWorkspaceRoot());
29256
+ }
29257
+ //#endregion
29218
29258
  //#region ../../packages/runtime-app-state/src/app/generalChatWorkspace.ts
29219
29259
  const GENERAL_CHAT_WORKSPACE_DIRNAME = "general-chat-workspace";
29220
29260
  const GENERAL_CHAT_PROJECT_TITLE = "General Chat";
29221
- const GENERAL_CHAT_ANALYTICS_BUCKET = "General Chat";
29222
29261
  const GENERAL_CHAT_AGENTS_FILENAME = "AGENTS.md";
29223
29262
  const IS_CASE_INSENSITIVE_PLATFORM$1 = process.platform === "darwin" || process.platform === "win32";
29224
29263
  function stripTrailingSeparators$1(input) {
@@ -29296,7 +29335,7 @@ function asString$7(value) {
29296
29335
  const trimmed = value.trim();
29297
29336
  return trimmed.length > 0 ? trimmed : null;
29298
29337
  }
29299
- function isRecord$8(value) {
29338
+ function isRecord$6(value) {
29300
29339
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
29301
29340
  }
29302
29341
  function parseAutoRoll(raw) {
@@ -29308,7 +29347,7 @@ function parseAutoRoll(raw) {
29308
29347
  }
29309
29348
  }
29310
29349
  function parseStoredLicense(raw) {
29311
- if (!isRecord$8(raw)) return null;
29350
+ if (!isRecord$6(raw)) return null;
29312
29351
  const statusCandidate = asString$7(raw.status);
29313
29352
  const status = [
29314
29353
  "inactive",
@@ -29391,7 +29430,7 @@ async function readCodexSettingsJsonRaw() {
29391
29430
  };
29392
29431
  }
29393
29432
  async function writeCodexSettingsJsonRaw(payload) {
29394
- if (!isRecord$8(payload)) return;
29433
+ if (!isRecord$6(payload)) return;
29395
29434
  const autoRoll = parseAutoRoll(payload.autoRoll ?? payload.auto_roll);
29396
29435
  const license = parseStoredLicense(payload.license);
29397
29436
  await patchAppState({
@@ -29423,11 +29462,11 @@ async function writeCodexSettingsJsonRaw(payload) {
29423
29462
  folderHistory: Array.isArray(payload.folderHistory) ? payload.folderHistory : void 0,
29424
29463
  pinnedPaths: Array.isArray(payload.pinnedPaths) ? payload.pinnedPaths : void 0
29425
29464
  },
29426
- workspaceSettingsByPath: isRecord$8(payload.workspaceSettingsByPath) ? payload.workspaceSettingsByPath : isRecord$8(payload.projectSettingsByPath) ? payload.projectSettingsByPath : void 0,
29427
- conversationCategoriesByCwd: isRecord$8(payload.categoriesByCwd) ? payload.categoriesByCwd : void 0,
29428
- conversationCategoryAssignmentsByCwd: isRecord$8(payload.conversationCategoryByCwd) ? payload.conversationCategoryByCwd : void 0,
29429
- git: isRecord$8(payload.git) ? payload.git : void 0,
29430
- sync: isRecord$8(payload.sync) ? payload.sync : void 0
29465
+ workspaceSettingsByPath: isRecord$6(payload.workspaceSettingsByPath) ? payload.workspaceSettingsByPath : isRecord$6(payload.projectSettingsByPath) ? payload.projectSettingsByPath : void 0,
29466
+ conversationCategoriesByCwd: isRecord$6(payload.categoriesByCwd) ? payload.categoriesByCwd : void 0,
29467
+ conversationCategoryAssignmentsByCwd: isRecord$6(payload.conversationCategoryByCwd) ? payload.conversationCategoryByCwd : void 0,
29468
+ git: isRecord$6(payload.git) ? payload.git : void 0,
29469
+ sync: isRecord$6(payload.sync) ? payload.sync : void 0
29431
29470
  });
29432
29471
  }
29433
29472
  //#endregion
@@ -29824,7 +29863,7 @@ function findActiveProjectByCanonicalRoot(projects, workspaceRoot) {
29824
29863
  function countActiveUniqueProjects(projects) {
29825
29864
  const seen = /* @__PURE__ */ new Set();
29826
29865
  for (const project of projects) {
29827
- if (project.deletedAt !== null || isGeneralChatWorkspaceRoot(project.workspaceRoot)) continue;
29866
+ if (project.deletedAt !== null || isGeneralChatWorkspaceRoot(project.workspaceRoot) || isAgentChatWorkspaceRoot(project.workspaceRoot)) continue;
29828
29867
  seen.add(projectRootKey(project.workspaceRoot));
29829
29868
  }
29830
29869
  return seen.size;
@@ -30228,7 +30267,7 @@ function logInfo(...args) {
30228
30267
  }
30229
30268
  //#endregion
30230
30269
  //#region ../../packages/runtime-codex/src/codex/app-server.ts
30231
- function isRecord$7(value) {
30270
+ function isRecord$5(value) {
30232
30271
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
30233
30272
  }
30234
30273
  function asTrimmedString$2(value) {
@@ -30257,10 +30296,10 @@ function isInlineImageValue(value) {
30257
30296
  return normalized.startsWith("data:") || normalized.startsWith("http://") || normalized.startsWith("https://");
30258
30297
  }
30259
30298
  function normalizeSendUserMessageItem(value) {
30260
- if (!isRecord$7(value)) return null;
30299
+ if (!isRecord$5(value)) return null;
30261
30300
  const type = asString$6(value.type).trim();
30262
30301
  if (!type) return null;
30263
- const data = isRecord$7(value.data) ? value.data : {};
30302
+ const data = isRecord$5(value.data) ? value.data : {};
30264
30303
  if (type === "text") {
30265
30304
  const text = asString$6(data.text ?? value.text);
30266
30305
  if (!text.trim()) return null;
@@ -30295,7 +30334,7 @@ function normalizeTurnInputParams(params) {
30295
30334
  if (expectedTurnId && !asString$6(params.expectedTurnId).trim()) normalized.expectedTurnId = expectedTurnId;
30296
30335
  const turnId = asString$6(params.turnId ?? params.turn_id ?? expectedTurnId).trim();
30297
30336
  if (turnId && !asString$6(params.turnId).trim()) normalized.turnId = turnId;
30298
- const providedInput = Array.isArray(params.input) ? params.input.filter((entry) => isRecord$7(entry)) : [];
30337
+ const providedInput = Array.isArray(params.input) ? params.input.filter((entry) => isRecord$5(entry)) : [];
30299
30338
  if (providedInput.length > 0) {
30300
30339
  normalized.input = providedInput;
30301
30340
  return normalized;
@@ -30304,7 +30343,7 @@ function normalizeTurnInputParams(params) {
30304
30343
  if (providedItems.length > 0) {
30305
30344
  const input = providedItems.flatMap((item) => {
30306
30345
  const type = asString$6(item.type).trim();
30307
- const data = isRecord$7(item.data) ? item.data : item;
30346
+ const data = isRecord$5(item.data) ? item.data : item;
30308
30347
  if (type === "text") {
30309
30348
  const text = asString$6(data.text).trim();
30310
30349
  return text ? [{
@@ -30347,7 +30386,7 @@ function pickMethodKind(method, params) {
30347
30386
  const normalized = method.toLowerCase();
30348
30387
  if (normalized.includes("requestapproval")) return "approval";
30349
30388
  if (normalized.includes("requestuserinput")) return "user_input";
30350
- if (isRecord$7(params)) {
30389
+ if (isRecord$5(params)) {
30351
30390
  if ("file_changes" in params || "fileChanges" in params || "grant_root" in params || "grantRoot" in params) return "patch";
30352
30391
  if ("command" in params || "parsed_cmd" in params || "parsedCmd" in params || "cwd" in params) return "exec";
30353
30392
  }
@@ -30549,7 +30588,7 @@ var CodexAppServer = class extends EventEmitter {
30549
30588
  try {
30550
30589
  const response = await this.request("addConversationListener", listenerParams);
30551
30590
  this.addConversationListenerSupported = true;
30552
- return isRecord$7(response) ? response : null;
30591
+ return isRecord$5(response) ? response : null;
30553
30592
  } catch (error) {
30554
30593
  if (isMethodUnavailableError(error, "addConversationListener")) {
30555
30594
  this.addConversationListenerSupported = false;
@@ -30564,7 +30603,7 @@ var CodexAppServer = class extends EventEmitter {
30564
30603
  try {
30565
30604
  const response = await this.request("addConversationListener", listenerParams);
30566
30605
  this.addConversationListenerSupported = true;
30567
- return isRecord$7(response) ? response : null;
30606
+ return isRecord$5(response) ? response : null;
30568
30607
  } catch (resumeError) {
30569
30608
  if (isMethodUnavailableError(resumeError, "addConversationListener")) {
30570
30609
  this.addConversationListenerSupported = false;
@@ -30774,7 +30813,7 @@ var CodexAppServer = class extends EventEmitter {
30774
30813
  listPendingUserInputRequests() {
30775
30814
  return [...this.pendingServerRequests.values()].filter((request) => request.kind === "user_input").map((request) => {
30776
30815
  const workspaceId = asTrimmedString$2(request.params.workspace_id ?? request.params.workspaceId);
30777
- const params = isRecord$7(request.params.params) ? request.params.params : request.params;
30816
+ const params = isRecord$5(request.params.params) ? request.params.params : request.params;
30778
30817
  if (!workspaceId) return null;
30779
30818
  return {
30780
30819
  workspace_id: workspaceId,
@@ -30887,7 +30926,7 @@ var CodexAppServer = class extends EventEmitter {
30887
30926
  this.logParseFailure(line, parseError);
30888
30927
  return true;
30889
30928
  }
30890
- if (!isRecord$7(parsed)) {
30929
+ if (!isRecord$5(parsed)) {
30891
30930
  logWarn("[app-server] unexpected JSON message", parsed);
30892
30931
  return true;
30893
30932
  }
@@ -30976,9 +31015,9 @@ var CodexAppServer = class extends EventEmitter {
30976
31015
  id: request.id,
30977
31016
  kind,
30978
31017
  method: request.method,
30979
- params: isRecord$7(request.params) ? request.params : {}
31018
+ params: isRecord$5(request.params) ? request.params : {}
30980
31019
  });
30981
- const params = isRecord$7(request.params) ? request.params : {};
31020
+ const params = isRecord$5(request.params) ? request.params : {};
30982
31021
  if (kind === "exec") this.emit("codex:exec-command-request", {
30983
31022
  requestToken: token,
30984
31023
  params
@@ -31365,14 +31404,14 @@ async function listParityWorkspaces() {
31365
31404
  //#region src/externalThreadOverrides.ts
31366
31405
  const EXTERNAL_THREAD_OVERRIDES_DOCUMENT = "desktop.external-thread-overrides.v1";
31367
31406
  const EXTERNAL_THREAD_OVERRIDES_VERSION = 1;
31368
- function asRecord$4(value) {
31407
+ function asRecord$3(value) {
31369
31408
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
31370
31409
  }
31371
31410
  function normalizeOptionalTitle(value) {
31372
31411
  return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
31373
31412
  }
31374
31413
  function sanitizeOverride(value) {
31375
- const record = asRecord$4(value);
31414
+ const record = asRecord$3(value);
31376
31415
  if (!record) return null;
31377
31416
  const suppressed = record.suppressed === true ? true : void 0;
31378
31417
  const localTitle = normalizeOptionalTitle(record.localTitle);
@@ -31413,8 +31452,8 @@ function resolveOverridesDbPath(stateDir) {
31413
31452
  }
31414
31453
  async function readExternalThreadOverrides(stateDir) {
31415
31454
  return await readDocument(resolveOverridesDbPath(stateDir), EXTERNAL_THREAD_OVERRIDES_DOCUMENT, (value) => {
31416
- const record = asRecord$4(value);
31417
- const threadsRecord = asRecord$4(record?.threads) ?? {};
31455
+ const record = asRecord$3(value);
31456
+ const threadsRecord = asRecord$3(record?.threads) ?? {};
31418
31457
  const threads = {};
31419
31458
  for (const [threadId, entry] of Object.entries(threadsRecord)) {
31420
31459
  const sanitized = sanitizeOverride(entry);
@@ -31550,7 +31589,7 @@ let externalCodexThreadSyncWatcherSettleTimer = null;
31550
31589
  let externalCodexThreadSyncWatcherPendingTrigger = null;
31551
31590
  const externalSyncAppServerLeaseCount = /* @__PURE__ */ new Map();
31552
31591
  let externalCodexThreadSyncRefreshQueue = null;
31553
- function asRecord$3(value) {
31592
+ function asRecord$2(value) {
31554
31593
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
31555
31594
  }
31556
31595
  function clearSharedExternalSyncAppServerIdleTimer() {
@@ -31818,9 +31857,9 @@ async function readImportedVisibleMessageTimeline(thread) {
31818
31857
  } catch {
31819
31858
  continue;
31820
31859
  }
31821
- const record = asRecord$3(entry);
31860
+ const record = asRecord$2(entry);
31822
31861
  if (!record || asTrimmedString$1(record.type) !== "event_msg") continue;
31823
- const payload = asRecord$3(record.payload);
31862
+ const payload = asRecord$2(record.payload);
31824
31863
  if (!payload) continue;
31825
31864
  const timestamp = firstNonEmptyString(record.timestamp, payload.timestamp, payload.createdAt, payload.created_at);
31826
31865
  if (!timestamp || !Number.isFinite(Date.parse(timestamp))) continue;
@@ -31847,16 +31886,16 @@ function takeImportedVisibleMessageTimestamp(timeline, role) {
31847
31886
  return nextTimestamp;
31848
31887
  }
31849
31888
  function listThreadSummariesFromResponse(payload) {
31850
- const root = asRecord$3(payload);
31851
- const result = asRecord$3(root?.result) ?? root;
31889
+ const root = asRecord$2(payload);
31890
+ const result = asRecord$2(root?.result) ?? root;
31852
31891
  return {
31853
- threads: (Array.isArray(result?.data) ? result.data : []).map((entry) => asRecord$3(entry)).filter((entry) => Boolean(asTrimmedString$1(entry?.id))),
31892
+ threads: (Array.isArray(result?.data) ? result.data : []).map((entry) => asRecord$2(entry)).filter((entry) => Boolean(asTrimmedString$1(entry?.id))),
31854
31893
  nextCursor: firstNonEmptyString(result?.nextCursor, result?.next_cursor)
31855
31894
  };
31856
31895
  }
31857
31896
  function extractLegacyThread(payload) {
31858
- const root = asRecord$3(payload);
31859
- const thread = asRecord$3((asRecord$3(root?.result) ?? root)?.thread) ?? asRecord$3(root?.thread);
31897
+ const root = asRecord$2(payload);
31898
+ const thread = asRecord$2((asRecord$2(root?.result) ?? root)?.thread) ?? asRecord$2(root?.thread);
31860
31899
  return thread && asTrimmedString$1(thread.id) ? thread : null;
31861
31900
  }
31862
31901
  function normalizeProjectScriptIcon(value) {
@@ -31973,19 +32012,19 @@ const MODEL_KEYS = [
31973
32012
  "model_name"
31974
32013
  ];
31975
32014
  function extractModelFromRecord(record) {
31976
- const payload = asRecord$3(record.payload);
32015
+ const payload = asRecord$2(record.payload);
31977
32016
  const containers = [
31978
32017
  record,
31979
32018
  payload,
31980
- asRecord$3(payload?.info),
31981
- asRecord$3(record.info),
31982
- asRecord$3(record.metadata),
31983
- asRecord$3(record.context),
31984
- asRecord$3(record.turnContext),
31985
- asRecord$3(record.turn_context),
31986
- asRecord$3(record.params),
31987
- asRecord$3(record.settings),
31988
- asRecord$3(record.config)
32019
+ asRecord$2(payload?.info),
32020
+ asRecord$2(record.info),
32021
+ asRecord$2(record.metadata),
32022
+ asRecord$2(record.context),
32023
+ asRecord$2(record.turnContext),
32024
+ asRecord$2(record.turn_context),
32025
+ asRecord$2(record.params),
32026
+ asRecord$2(record.settings),
32027
+ asRecord$2(record.config)
31989
32028
  ].filter((value) => value !== null);
31990
32029
  for (const container of containers) {
31991
32030
  const value = pickString(container, MODEL_KEYS);
@@ -31996,13 +32035,13 @@ function extractModelFromRecord(record) {
31996
32035
  function resolveImportedModel(thread) {
31997
32036
  const turns = Array.isArray(thread.turns) ? thread.turns : [];
31998
32037
  for (let turnIndex = turns.length - 1; turnIndex >= 0; turnIndex -= 1) {
31999
- const turn = asRecord$3(turns[turnIndex]);
32038
+ const turn = asRecord$2(turns[turnIndex]);
32000
32039
  if (!turn) continue;
32001
32040
  const turnLevel = extractModelFromRecord(turn);
32002
32041
  if (turnLevel) return turnLevel;
32003
32042
  const items = Array.isArray(turn.items) ? turn.items : [];
32004
32043
  for (let itemIndex = items.length - 1; itemIndex >= 0; itemIndex -= 1) {
32005
- const item = asRecord$3(items[itemIndex]);
32044
+ const item = asRecord$2(items[itemIndex]);
32006
32045
  if (!item) continue;
32007
32046
  const model = extractModelFromRecord(item);
32008
32047
  if (model) return model;
@@ -32017,7 +32056,7 @@ function resolveThreadTitle(thread) {
32017
32056
  return firstNonEmptyString(thread.name, thread.preview, thread.title)?.split(/\r?\n/, 1)[0]?.trim()?.slice(0, 140) || "Imported thread";
32018
32057
  }
32019
32058
  function readLegacyContentRecord(value) {
32020
- return asRecord$3(value);
32059
+ return asRecord$2(value);
32021
32060
  }
32022
32061
  function readLegacyContentText(item) {
32023
32062
  const data = readLegacyContentRecord(item.data);
@@ -32109,7 +32148,7 @@ async function parseUserMessageContent(input) {
32109
32148
  const attachments = [];
32110
32149
  let imageIndex = 0;
32111
32150
  for (const entry of content) {
32112
- const item = asRecord$3(entry);
32151
+ const item = asRecord$2(entry);
32113
32152
  if (!item) continue;
32114
32153
  const type = asTrimmedString$1(item.type);
32115
32154
  if (type === "text") {
@@ -32180,13 +32219,13 @@ async function buildThreadImportArtifacts(input) {
32180
32219
  let latestArtifactUpdatedAt = createdAt;
32181
32220
  let latestUpdatedAt = summaryUpdatedAt;
32182
32221
  for (const [turnIndex, turnEntry] of turns.entries()) {
32183
- const turn = asRecord$3(turnEntry);
32222
+ const turn = asRecord$2(turnEntry);
32184
32223
  if (!turn) continue;
32185
32224
  const turnIdRaw = firstNonEmptyString(turn.id, turn.turnId, turn.turn_id);
32186
32225
  const turnId = turnIdRaw ? TurnId.makeUnsafe(turnIdRaw) : null;
32187
32226
  const items = Array.isArray(turn.items) ? turn.items : [];
32188
32227
  for (const [itemIndex, itemEntry] of items.entries()) {
32189
- const item = asRecord$3(itemEntry);
32228
+ const item = asRecord$2(itemEntry);
32190
32229
  if (!item) continue;
32191
32230
  const itemId = firstNonEmptyString(item.id) ?? `${turnIndex + 1}-${itemIndex + 1}`;
32192
32231
  const type = asTrimmedString$1(item.type);
@@ -32409,7 +32448,7 @@ async function isDirectory(targetPath) {
32409
32448
  async function readImportMarker(stateDir) {
32410
32449
  const dbPath = resolveStateDbPath(stateDir);
32411
32450
  const stored = await readDocument(dbPath, EXTERNAL_SYNC_MARKER_DOCUMENT, (value) => {
32412
- const version = asFiniteNumber(asRecord$3(value)?.version);
32451
+ const version = asFiniteNumber(asRecord$2(value)?.version);
32413
32452
  if (version === null || version <= 0) return null;
32414
32453
  return { version };
32415
32454
  });
@@ -32417,7 +32456,7 @@ async function readImportMarker(stateDir) {
32417
32456
  const markerPath = path.join(stateDir, EXTERNAL_SYNC_MARKER_FILE);
32418
32457
  try {
32419
32458
  const raw = await fs$1.readFile(markerPath, "utf8");
32420
- const version = asFiniteNumber(asRecord$3(JSON.parse(raw))?.version);
32459
+ const version = asFiniteNumber(asRecord$2(JSON.parse(raw))?.version);
32421
32460
  if (version === null || version <= 0) return null;
32422
32461
  const marker = { version };
32423
32462
  await writeDocument(dbPath, EXTERNAL_SYNC_MARKER_DOCUMENT, marker);
@@ -32497,7 +32536,7 @@ function hasImportedThreadArtifacts(state) {
32497
32536
  return state.messageIds.size > 0 || state.activityIds.size > 0 || state.planIds.size > 0;
32498
32537
  }
32499
32538
  function readProviderThreadIdFromResumeCursor(resumeCursor) {
32500
- const cursor = asRecord$3(resumeCursor);
32539
+ const cursor = asRecord$2(resumeCursor);
32501
32540
  return firstNonEmptyString(cursor?.threadId, cursor?.thread_id, cursor?.conversationId, cursor?.conversation_id) ?? null;
32502
32541
  }
32503
32542
  function resolveLegacyThreadReadIds(input) {
@@ -32949,7 +32988,7 @@ const runExternalCodexThreadSync = gen(function* () {
32949
32988
  }
32950
32989
  const syncTargets = [];
32951
32990
  for (const project of readModel.projects) {
32952
- if (project.deletedAt !== null || isGeneralChatWorkspaceRoot(project.workspaceRoot)) continue;
32991
+ if (project.deletedAt !== null || isGeneralChatWorkspaceRoot(project.workspaceRoot) || isAgentChatWorkspaceRoot(project.workspaceRoot)) continue;
32953
32992
  const workspaceRoot = project.workspaceRoot;
32954
32993
  const rootKey = projectRootKey(workspaceRoot);
32955
32994
  if (projectIdByRootKey.has(rootKey)) continue;
@@ -36909,12 +36948,12 @@ function decodeProviderKind(providerName, operation) {
36909
36948
  detail: `Unknown persisted provider '${providerName}'.`
36910
36949
  }));
36911
36950
  }
36912
- function isRecord$6(value) {
36951
+ function isRecord$4(value) {
36913
36952
  return value !== null && typeof value === "object" && !Array.isArray(value);
36914
36953
  }
36915
36954
  function mergeRuntimePayload(existing, next) {
36916
36955
  if (next === void 0) return existing ?? null;
36917
- if (isRecord$6(existing) && isRecord$6(next)) return {
36956
+ if (isRecord$4(existing) && isRecord$4(next)) return {
36918
36957
  ...existing,
36919
36958
  ...next
36920
36959
  };
@@ -41217,7 +41256,7 @@ const LEGACY_APP_SETTINGS_KEYS = new Set([
41217
41256
  "activeRemoteBackendId",
41218
41257
  "keepDaemonRunningAfterAppClose"
41219
41258
  ]);
41220
- function asRecord$2(value) {
41259
+ function asRecord$1(value) {
41221
41260
  return value && typeof value === "object" ? value : {};
41222
41261
  }
41223
41262
  function stripLegacyAppSettingsKeys(settings) {
@@ -41231,10 +41270,10 @@ function stripLegacyAppSettingsKeys(settings) {
41231
41270
  return changed ? next : settings;
41232
41271
  }
41233
41272
  async function readAppSettings() {
41234
- return stripLegacyAppSettingsKeys(asRecord$2((await getAppState()).runtimeSettings));
41273
+ return stripLegacyAppSettingsKeys(asRecord$1((await getAppState()).runtimeSettings));
41235
41274
  }
41236
41275
  async function writeAppSettings(settings, onUpdated) {
41237
- const nextSettings = stripLegacyAppSettingsKeys(asRecord$2(settings));
41276
+ const nextSettings = stripLegacyAppSettingsKeys(asRecord$1(settings));
41238
41277
  await updateAppState((current) => ({
41239
41278
  ...current,
41240
41279
  runtimeSettings: nextSettings
@@ -42879,7 +42918,7 @@ const FALLBACK_FEATURE_KEYS = [
42879
42918
  ];
42880
42919
  let metadataCache = null;
42881
42920
  let metadataCacheAt = 0;
42882
- function isRecord$5(value) {
42921
+ function isRecord$3(value) {
42883
42922
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
42884
42923
  }
42885
42924
  function uniqueSorted(values) {
@@ -42950,14 +42989,14 @@ function parseFeatureCatalog(output) {
42950
42989
  }
42951
42990
  function parseSchemaKeys(schemaRaw) {
42952
42991
  const parsed = JSON.parse(schemaRaw);
42953
- if (!isRecord$5(parsed)) return {
42992
+ if (!isRecord$3(parsed)) return {
42954
42993
  topLevelKeys: FALLBACK_SCHEMA_TOP_LEVEL_KEYS,
42955
42994
  featureKeys: FALLBACK_FEATURE_KEYS
42956
42995
  };
42957
- const properties = isRecord$5(parsed.properties) ? parsed.properties : {};
42996
+ const properties = isRecord$3(parsed.properties) ? parsed.properties : {};
42958
42997
  const topLevelKeys = uniqueSorted(Object.keys(properties));
42959
- const features = isRecord$5(properties.features) ? properties.features : {};
42960
- const featureProperties = isRecord$5(features.properties) ? features.properties : {};
42998
+ const features = isRecord$3(properties.features) ? properties.features : {};
42999
+ const featureProperties = isRecord$3(features.properties) ? features.properties : {};
42961
43000
  const featureKeys = uniqueSorted(Object.keys(featureProperties));
42962
43001
  return {
42963
43002
  topLevelKeys: topLevelKeys.length > 0 ? topLevelKeys : FALLBACK_SCHEMA_TOP_LEVEL_KEYS,
@@ -45880,7 +45919,7 @@ var AccountPoolTurnFailure = class extends Error {
45880
45919
  this.providerThreadId = input.providerThreadId;
45881
45920
  }
45882
45921
  };
45883
- function isRecord$4(value) {
45922
+ function isRecord$2(value) {
45884
45923
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
45885
45924
  }
45886
45925
  function asString$1(value) {
@@ -46014,7 +46053,7 @@ function createDefaultStore() {
46014
46053
  };
46015
46054
  }
46016
46055
  function normalizeApiKeyRecord(id, value) {
46017
- const record = isRecord$4(value) ? value : null;
46056
+ const record = isRecord$2(value) ? value : null;
46018
46057
  const tokenHash = asString$1(record?.tokenHash);
46019
46058
  const tokenPreview = asString$1(record?.tokenPreview);
46020
46059
  const createdAt = normalizeIsoString(record?.createdAt);
@@ -46029,7 +46068,7 @@ function normalizeApiKeyRecord(id, value) {
46029
46068
  };
46030
46069
  }
46031
46070
  function normalizeLegacySessionRecord(id, value) {
46032
- const record = isRecord$4(value) ? value : null;
46071
+ const record = isRecord$2(value) ? value : null;
46033
46072
  const profileName = asString$1(record?.profileName);
46034
46073
  const threadId = asString$1(record?.threadId);
46035
46074
  const createdAt = normalizeIsoString(record?.createdAt);
@@ -46053,19 +46092,19 @@ function normalizeLegacySessionRecord(id, value) {
46053
46092
  };
46054
46093
  }
46055
46094
  function normalizeLegacyStore(value) {
46056
- const record = isRecord$4(value) ? value : null;
46095
+ const record = isRecord$2(value) ? value : null;
46057
46096
  const apiKeysById = {};
46058
- for (const [id, keyValue] of Object.entries(isRecord$4(record?.apiKeysById) ? record.apiKeysById : {})) {
46097
+ for (const [id, keyValue] of Object.entries(isRecord$2(record?.apiKeysById) ? record.apiKeysById : {})) {
46059
46098
  const normalized = normalizeApiKeyRecord(id, keyValue);
46060
46099
  if (normalized) apiKeysById[id] = normalized;
46061
46100
  }
46062
46101
  const sessionsById = {};
46063
- for (const [id, sessionValue] of Object.entries(isRecord$4(record?.sessionsById) ? record.sessionsById : {})) {
46102
+ for (const [id, sessionValue] of Object.entries(isRecord$2(record?.sessionsById) ? record.sessionsById : {})) {
46064
46103
  const normalized = normalizeLegacySessionRecord(id, sessionValue);
46065
46104
  if (normalized) sessionsById[id] = normalized;
46066
46105
  }
46067
46106
  const responseIndex = {};
46068
- for (const [responseId, sessionId] of Object.entries(isRecord$4(record?.responseIndex) ? record.responseIndex : {})) {
46107
+ for (const [responseId, sessionId] of Object.entries(isRecord$2(record?.responseIndex) ? record.responseIndex : {})) {
46069
46108
  const normalizedSessionId = asString$1(sessionId);
46070
46109
  if (normalizedSessionId) responseIndex[responseId] = normalizedSessionId;
46071
46110
  }
@@ -46078,7 +46117,7 @@ function normalizeLegacyStore(value) {
46078
46117
  };
46079
46118
  }
46080
46119
  function normalizeTranscriptEntry(value) {
46081
- const record = isRecord$4(value) ? value : null;
46120
+ const record = isRecord$2(value) ? value : null;
46082
46121
  const role = asString$1(record?.role);
46083
46122
  const createdAt = normalizeIsoString(record?.createdAt);
46084
46123
  if (role !== "user" && role !== "assistant" || !createdAt) return null;
@@ -46090,7 +46129,7 @@ function normalizeTranscriptEntry(value) {
46090
46129
  };
46091
46130
  }
46092
46131
  function normalizeSessionRecord(id, value) {
46093
- const record = isRecord$4(value) ? value : null;
46132
+ const record = isRecord$2(value) ? value : null;
46094
46133
  const activeSegmentId = asString$1(record?.activeSegmentId);
46095
46134
  const createdAt = normalizeIsoString(record?.createdAt);
46096
46135
  const lastUsedAt = normalizeIsoString(record?.lastUsedAt);
@@ -46127,7 +46166,7 @@ function normalizeSessionRecord(id, value) {
46127
46166
  };
46128
46167
  }
46129
46168
  function normalizeSegmentRecord(id, value) {
46130
- const record = isRecord$4(value) ? value : null;
46169
+ const record = isRecord$2(value) ? value : null;
46131
46170
  const sessionId = asString$1(record?.sessionId);
46132
46171
  const profileName = asString$1(record?.profileName);
46133
46172
  const threadId = asString$1(record?.threadId);
@@ -46148,7 +46187,7 @@ function normalizeSegmentRecord(id, value) {
46148
46187
  };
46149
46188
  }
46150
46189
  function normalizeProfileStateRecord(value) {
46151
- const record = isRecord$4(value) ? value : null;
46190
+ const record = isRecord$2(value) ? value : null;
46152
46191
  return {
46153
46192
  cooldownUntil: normalizeIsoString(record?.cooldownUntil),
46154
46193
  lastFailureClass: normalizeFailureClass(record?.lastFailureClass),
@@ -46157,7 +46196,7 @@ function normalizeProfileStateRecord(value) {
46157
46196
  };
46158
46197
  }
46159
46198
  function normalizeResponseIndexRecord(value) {
46160
- const record = isRecord$4(value) ? value : null;
46199
+ const record = isRecord$2(value) ? value : null;
46161
46200
  const sessionId = asString$1(record?.sessionId);
46162
46201
  const segmentId = asString$1(record?.segmentId);
46163
46202
  const createdAt = normalizeIsoString(record?.createdAt) ?? (/* @__PURE__ */ new Date(0)).toISOString();
@@ -46169,30 +46208,30 @@ function normalizeResponseIndexRecord(value) {
46169
46208
  };
46170
46209
  }
46171
46210
  function normalizeStore(value) {
46172
- const record = isRecord$4(value) ? value : null;
46211
+ const record = isRecord$2(value) ? value : null;
46173
46212
  const apiKeysById = {};
46174
- for (const [id, keyValue] of Object.entries(isRecord$4(record?.apiKeysById) ? record.apiKeysById : {})) {
46213
+ for (const [id, keyValue] of Object.entries(isRecord$2(record?.apiKeysById) ? record.apiKeysById : {})) {
46175
46214
  const normalized = normalizeApiKeyRecord(id, keyValue);
46176
46215
  if (normalized) apiKeysById[id] = normalized;
46177
46216
  }
46178
46217
  const sessionsById = {};
46179
- for (const [id, sessionValue] of Object.entries(isRecord$4(record?.sessionsById) ? record.sessionsById : {})) {
46218
+ for (const [id, sessionValue] of Object.entries(isRecord$2(record?.sessionsById) ? record.sessionsById : {})) {
46180
46219
  const normalized = normalizeSessionRecord(id, sessionValue);
46181
46220
  if (normalized) sessionsById[id] = normalized;
46182
46221
  }
46183
46222
  const segmentsById = {};
46184
- for (const [id, segmentValue] of Object.entries(isRecord$4(record?.segmentsById) ? record.segmentsById : {})) {
46223
+ for (const [id, segmentValue] of Object.entries(isRecord$2(record?.segmentsById) ? record.segmentsById : {})) {
46185
46224
  const normalized = normalizeSegmentRecord(id, segmentValue);
46186
46225
  if (normalized) segmentsById[id] = normalized;
46187
46226
  }
46188
46227
  const profilesByName = {};
46189
- for (const [name, profileValue] of Object.entries(isRecord$4(record?.profilesByName) ? record.profilesByName : {})) {
46228
+ for (const [name, profileValue] of Object.entries(isRecord$2(record?.profilesByName) ? record.profilesByName : {})) {
46190
46229
  const normalizedName = asString$1(name);
46191
46230
  if (!normalizedName) continue;
46192
46231
  profilesByName[normalizedName] = normalizeProfileStateRecord(profileValue);
46193
46232
  }
46194
46233
  const responseIndex = {};
46195
- for (const [responseId, responseValue] of Object.entries(isRecord$4(record?.responseIndex) ? record.responseIndex : {})) {
46234
+ for (const [responseId, responseValue] of Object.entries(isRecord$2(record?.responseIndex) ? record.responseIndex : {})) {
46196
46235
  const normalized = normalizeResponseIndexRecord(responseValue);
46197
46236
  if (normalized) responseIndex[responseId] = normalized;
46198
46237
  }
@@ -46317,7 +46356,7 @@ function extractTextAndImages(value) {
46317
46356
  text: value.trim() || null,
46318
46357
  images: []
46319
46358
  };
46320
- const record = isRecord$4(value) ? value : null;
46359
+ const record = isRecord$2(value) ? value : null;
46321
46360
  const arrayValue = Array.isArray(value) ? value : Array.isArray(record?.content) ? record?.content : null;
46322
46361
  const directText = asString$1(record?.text) ?? asString$1(record?.content);
46323
46362
  const directImage = asString$1(record?.image_url) ?? asString$1(record?.url) ?? asString$1(record?.imageUrl);
@@ -46332,7 +46371,7 @@ function extractTextAndImages(value) {
46332
46371
  if (entry.trim().length > 0) texts.push(entry.trim());
46333
46372
  continue;
46334
46373
  }
46335
- const part = isRecord$4(entry) ? entry : null;
46374
+ const part = isRecord$2(entry) ? entry : null;
46336
46375
  if (!part) continue;
46337
46376
  const partType = asString$1(part.type) ?? "text";
46338
46377
  const text = asString$1(part.text) ?? asString$1(part.content) ?? asString$1(part.value);
@@ -46353,7 +46392,7 @@ function assistantLabel(value) {
46353
46392
  return normalized && normalized.length > 0 ? normalized : null;
46354
46393
  }
46355
46394
  function isAssistantLikeRecord(value) {
46356
- const record = isRecord$4(value) ? value : null;
46395
+ const record = isRecord$2(value) ? value : null;
46357
46396
  if (!record) return false;
46358
46397
  return [
46359
46398
  assistantLabel(record.role),
@@ -46366,7 +46405,7 @@ function collectTextFragments(value, depth = 0) {
46366
46405
  if (depth > 6) return [];
46367
46406
  if (typeof value === "string") return value.length > 0 ? [value] : [];
46368
46407
  if (Array.isArray(value)) return value.flatMap((entry) => collectTextFragments(entry, depth + 1));
46369
- const record = isRecord$4(value) ? value : null;
46408
+ const record = isRecord$2(value) ? value : null;
46370
46409
  if (!record) return [];
46371
46410
  return [
46372
46411
  asString$1(record.text),
@@ -46395,7 +46434,7 @@ function extractAssistantTextSnapshot(value, depth = 0) {
46395
46434
  }
46396
46435
  return null;
46397
46436
  }
46398
- const record = isRecord$4(value) ? value : null;
46437
+ const record = isRecord$2(value) ? value : null;
46399
46438
  if (!record) return null;
46400
46439
  const nestedMatch = extractAssistantTextSnapshot(record.turn, depth + 1) ?? extractAssistantTextSnapshot(record.response, depth + 1) ?? extractAssistantTextSnapshot(record.result, depth + 1) ?? extractAssistantTextSnapshot(record.item, depth + 1) ?? extractAssistantTextSnapshot(record.items, depth + 1) ?? extractAssistantTextSnapshot(record.messages, depth + 1) ?? extractAssistantTextSnapshot(record.output, depth + 1) ?? extractAssistantTextSnapshot(record.content, depth + 1);
46401
46440
  if (nestedMatch) return nestedMatch;
@@ -46414,7 +46453,7 @@ function prepareTurnInput(body, fallbackModel) {
46414
46453
  looseText = [looseText, entry.trim()].filter(Boolean).join("\n\n") || null;
46415
46454
  continue;
46416
46455
  }
46417
- const record = isRecord$4(entry) ? entry : null;
46456
+ const record = isRecord$2(entry) ? entry : null;
46418
46457
  if (!record) continue;
46419
46458
  const entryRole = asString$1(record.role);
46420
46459
  const entryType = asString$1(record.type);
@@ -46431,7 +46470,7 @@ function prepareTurnInput(body, fallbackModel) {
46431
46470
  if (text) looseText = [looseText, text].filter(Boolean).join("\n\n") || null;
46432
46471
  looseImages.push(...images);
46433
46472
  }
46434
- else if (isRecord$4(input)) {
46473
+ else if (isRecord$2(input)) {
46435
46474
  const { text, images } = extractTextAndImages(input);
46436
46475
  looseText = text;
46437
46476
  looseImages.push(...images);
@@ -46460,7 +46499,7 @@ function prepareTurnInput(body, fallbackModel) {
46460
46499
  if (transcriptParts.length > 0) promptParts.push(`Conversation so far:\n${transcriptParts.join("\n\n")}`);
46461
46500
  if (finalPrompt) promptParts.push(finalPrompt);
46462
46501
  const normalizedModel = normalizeModelSlug(asString$1(body.model) ?? fallbackModel, "codex") ?? fallbackModel;
46463
- const effort = asString$1((isRecord$4(body.reasoning) ? body.reasoning : null)?.effort) ?? asString$1(body.effort) ?? void 0;
46502
+ const effort = asString$1((isRecord$2(body.reasoning) ? body.reasoning : null)?.effort) ?? asString$1(body.effort) ?? void 0;
46464
46503
  return {
46465
46504
  prompt: promptParts.join("\n\n").trim() || null,
46466
46505
  attachments: [...looseImages, ...finalUserImages].map((url) => ({
@@ -46477,7 +46516,7 @@ function prepareTurnInput(body, fallbackModel) {
46477
46516
  }
46478
46517
  function resolveResponseContinuationKey(body, headers) {
46479
46518
  const previousResponseId = asString$1(body.previous_response_id);
46480
- const conversation = asString$1(body.conversation) ?? (isRecord$4(body.conversation) ? asString$1(body.conversation.id) : null);
46519
+ const conversation = asString$1(body.conversation) ?? (isRecord$2(body.conversation) ? asString$1(body.conversation.id) : null);
46481
46520
  if (conversation && previousResponseId) throw new AccountPoolRequestError({
46482
46521
  statusCode: 400,
46483
46522
  code: "invalid_request_error",
@@ -46556,7 +46595,7 @@ async function readJsonRequestBody(req) {
46556
46595
  const raw = Buffer.concat(chunks).toString("utf8").trim();
46557
46596
  if (!raw) return {};
46558
46597
  const parsed = JSON.parse(raw);
46559
- if (!isRecord$4(parsed)) throw new Error("Expected a JSON object request body.");
46598
+ if (!isRecord$2(parsed)) throw new Error("Expected a JSON object request body.");
46560
46599
  return parsed;
46561
46600
  }
46562
46601
  function stringifyFailureReason(failureClass, message) {
@@ -47713,17 +47752,17 @@ var LocalAccountPool = class LocalAccountPool {
47713
47752
  if (snapshotText) this.applyObserverTextSnapshot(observer, snapshotText);
47714
47753
  }
47715
47754
  if (event.method === "turn/completed") {
47716
- const payload = isRecord$4(event.payload) ? event.payload : null;
47717
- const turn = isRecord$4(payload?.turn) ? payload?.turn : payload;
47755
+ const payload = isRecord$2(event.payload) ? event.payload : null;
47756
+ const turn = isRecord$2(payload?.turn) ? payload?.turn : payload;
47718
47757
  const turnStatus = asString$1(turn?.status);
47719
- const errorMessage = asString$1(isRecord$4(turn?.error) ? turn.error.message : void 0) ?? asString$1(payload?.message);
47758
+ const errorMessage = asString$1(isRecord$2(turn?.error) ? turn.error.message : void 0) ?? asString$1(payload?.message);
47720
47759
  if (turnStatus === "failed" || errorMessage) {
47721
47760
  observer.done = true;
47722
47761
  observer.reject(new Error(errorMessage ?? "Provider turn failed."));
47723
47762
  this.turnObservers.delete(event.threadId);
47724
47763
  return;
47725
47764
  }
47726
- const usage = isRecord$4(turn?.usage) ? turn?.usage : void 0;
47765
+ const usage = isRecord$2(turn?.usage) ? turn?.usage : void 0;
47727
47766
  const snapshotText = observer.text.length > 0 ? null : extractAssistantTextSnapshot(event.payload);
47728
47767
  if (snapshotText) this.applyObserverTextSnapshot(observer, snapshotText);
47729
47768
  observer.usage = usage;
@@ -47765,15 +47804,15 @@ var LocalAccountPool = class LocalAccountPool {
47765
47804
  else observer.pendingDeltas.push(snapshotText);
47766
47805
  }
47767
47806
  extractEventErrorMessage(payload) {
47768
- if (!isRecord$4(payload)) return null;
47769
- return asString$1((isRecord$4(payload.error) ? payload.error : payload).message) ?? null;
47807
+ if (!isRecord$2(payload)) return null;
47808
+ return asString$1((isRecord$2(payload.error) ? payload.error : payload).message) ?? null;
47770
47809
  }
47771
47810
  readLiveProviderThreadId(threadId) {
47772
47811
  const active = this.manager.listSessions().find((session) => session.threadId === ThreadId.makeUnsafe(threadId));
47773
47812
  return this.readResumeCursorThreadId(active?.resumeCursor);
47774
47813
  }
47775
47814
  readResumeCursorThreadId(resumeCursor) {
47776
- if (!isRecord$4(resumeCursor)) return null;
47815
+ if (!isRecord$2(resumeCursor)) return null;
47777
47816
  return asString$1(resumeCursor.threadId);
47778
47817
  }
47779
47818
  async closeLiveSegment(segmentId) {
@@ -48673,7 +48712,7 @@ const LEGACY_SKILLS_DIR = "skills";
48673
48712
  const LEGACY_SKILLS_REPOS_FILE = "repos.json";
48674
48713
  const LEGACY_SKILL_MANIFEST = ".codexuse-skill.json";
48675
48714
  const LEGACY_LICENSE_SECRET_FILE = "license.secret";
48676
- function isRecord$3(value) {
48715
+ function isRecord$1(value) {
48677
48716
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
48678
48717
  }
48679
48718
  function isMissingPathError(error) {
@@ -48710,7 +48749,7 @@ function mergeLegacyLocalStoragePatch(payload) {
48710
48749
  else skippedKeys.add(key);
48711
48750
  };
48712
48751
  const settingsStorage = payload["settings-storage"];
48713
- if (isRecord$3(settingsStorage)) {
48752
+ if (isRecord$1(settingsStorage)) {
48714
48753
  const nextExcludeFolders = Array.isArray(settingsStorage.excludeFolders) ? settingsStorage.excludeFolders.filter((item) => typeof item === "string") : void 0;
48715
48754
  const nextBeep = typeof settingsStorage.enableTaskCompleteBeep === "boolean" ? settingsStorage.enableTaskCompleteBeep : void 0;
48716
48755
  const nextSleep = typeof settingsStorage.preventSleepDuringTasks === "boolean" ? settingsStorage.preventSleepDuringTasks : void 0;
@@ -48724,13 +48763,13 @@ function mergeLegacyLocalStoragePatch(payload) {
48724
48763
  markSkippedIfPresent("provider", hasKey("provider"));
48725
48764
  markSkippedIfPresent("sandbox-storage", hasKey("sandbox-storage"));
48726
48765
  const projectSettings = payload["project-settings-storage"];
48727
- if (isRecord$3(projectSettings) && isRecord$3(projectSettings.settingsByPath)) {
48766
+ if (isRecord$1(projectSettings) && isRecord$1(projectSettings.settingsByPath)) {
48728
48767
  patch.workspaceSettingsByPath = projectSettings.settingsByPath;
48729
48768
  markSkippedIfPresent("project-settings-storage", true);
48730
48769
  } else markSkippedIfPresent("project-settings-storage", false);
48731
48770
  const folder = payload["folder-storage"];
48732
- if (isRecord$3(folder)) {
48733
- const folderHistory = Array.isArray(folder.folderHistory) ? folder.folderHistory.filter(isRecord$3) : void 0;
48771
+ if (isRecord$1(folder)) {
48772
+ const folderHistory = Array.isArray(folder.folderHistory) ? folder.folderHistory.filter(isRecord$1) : void 0;
48734
48773
  const pinnedPaths = Array.isArray(folder.pinnedPaths) ? folder.pinnedPaths.filter((item) => typeof item === "string") : void 0;
48735
48774
  patch.preferences = {
48736
48775
  ...patch.preferences ?? {},
@@ -48741,12 +48780,12 @@ function mergeLegacyLocalStoragePatch(payload) {
48741
48780
  } else markSkippedIfPresent("folder-storage", false);
48742
48781
  const categories = payload["conversation-categories-storage"];
48743
48782
  let consumedCategories = false;
48744
- if (isRecord$3(categories)) {
48745
- if (isRecord$3(categories.categoriesByCwd)) {
48783
+ if (isRecord$1(categories)) {
48784
+ if (isRecord$1(categories.categoriesByCwd)) {
48746
48785
  patch.conversationCategoriesByCwd = categories.categoriesByCwd;
48747
48786
  consumedCategories = true;
48748
48787
  }
48749
- if (isRecord$3(categories.conversationCategoryByCwd)) {
48788
+ if (isRecord$1(categories.conversationCategoryByCwd)) {
48750
48789
  patch.conversationCategoryAssignmentsByCwd = categories.conversationCategoryByCwd;
48751
48790
  consumedCategories = true;
48752
48791
  }
@@ -48827,7 +48866,7 @@ async function importLegacyLocalStorageOnce(payload) {
48827
48866
  importedKeys: [],
48828
48867
  skippedKeys: []
48829
48868
  };
48830
- if (!payload || !isRecord$3(payload)) return {
48869
+ if (!payload || !isRecord$1(payload)) return {
48831
48870
  completed: true,
48832
48871
  importedKeys: [],
48833
48872
  skippedKeys: []
@@ -48890,992 +48929,6 @@ async function importLegacyLocalStorageOnce(payload) {
48890
48929
  };
48891
48930
  }
48892
48931
  //#endregion
48893
- //#region ../../packages/runtime-integrations/src/analytics/store.ts
48894
- const USAGE_FILE_INDEX_NAME = "desktop.analytics.usage-file-index";
48895
- const QUERY_SNAPSHOT_NAME = "desktop.analytics.query-snapshots";
48896
- function resolveUsageFileIndexPath() {
48897
- return USAGE_FILE_INDEX_NAME;
48898
- }
48899
- function resolveQuerySnapshotPath() {
48900
- return QUERY_SNAPSHOT_NAME;
48901
- }
48902
- async function readJsonFile(filePath) {
48903
- return readDocument(resolveAppStorageDbPath(getUserDataDir()), filePath, (value) => value);
48904
- }
48905
- async function writeJsonFileAtomic(filePath, value) {
48906
- await writeDocument(resolveAppStorageDbPath(getUserDataDir()), filePath, value);
48907
- }
48908
- //#endregion
48909
- //#region ../../packages/runtime-codex/src/codex/paths.ts
48910
- function getCodexRoot() {
48911
- const home = process.env.HOME || process.env.USERPROFILE;
48912
- if (!home) throw new Error("HOME is not set");
48913
- return path.join(home, ".codex");
48914
- }
48915
- function getSessionsDir() {
48916
- return path.join(getCodexRoot(), "sessions");
48917
- }
48918
- //#endregion
48919
- //#region ../../packages/runtime-integrations/src/analytics/usage-parse.ts
48920
- const ZERO_USAGE = {
48921
- input_tokens: 0,
48922
- output_tokens: 0,
48923
- reasoning_output_tokens: 0,
48924
- cached_input_tokens: 0,
48925
- total_tokens: 0
48926
- };
48927
- const MAX_ACTIVITY_GAP_MS = 120 * 1e3;
48928
- function asRecord$1(value) {
48929
- return value && typeof value === "object" && !Array.isArray(value) ? value : null;
48930
- }
48931
- function normalizeNumber(value) {
48932
- if (typeof value === "number" && Number.isFinite(value)) return value;
48933
- if (typeof value === "string" && value.trim() !== "") {
48934
- const parsed = Number(value);
48935
- return Number.isFinite(parsed) ? parsed : 0;
48936
- }
48937
- return 0;
48938
- }
48939
- function normalizeUsage(raw) {
48940
- const inputTokens = normalizeNumber(raw.input_tokens ?? raw.inputTokens ?? raw.prompt_tokens ?? raw.promptTokens);
48941
- const outputTokens = normalizeNumber(raw.output_tokens ?? raw.outputTokens ?? raw.completion_tokens ?? raw.completionTokens);
48942
- const reasoningOutputTokens = normalizeNumber(raw.reasoning_output_tokens ?? raw.reasoningOutputTokens);
48943
- const cachedInputTokens = normalizeNumber(raw.cached_input_tokens ?? raw.cachedInputTokens ?? raw.cache_read_input_tokens ?? raw.cacheReadInputTokens ?? raw.cache_creation_input_tokens ?? raw.cacheCreationInputTokens);
48944
- const totalTokens = normalizeNumber(raw.total_tokens ?? raw.totalTokens);
48945
- return {
48946
- input_tokens: inputTokens,
48947
- output_tokens: outputTokens,
48948
- reasoning_output_tokens: reasoningOutputTokens,
48949
- cached_input_tokens: cachedInputTokens,
48950
- total_tokens: totalTokens > 0 ? totalTokens : inputTokens + outputTokens + reasoningOutputTokens
48951
- };
48952
- }
48953
- function hasUsage(usage) {
48954
- return usage.input_tokens > 0 || usage.output_tokens > 0 || usage.reasoning_output_tokens > 0 || usage.cached_input_tokens > 0 || usage.total_tokens > 0;
48955
- }
48956
- function parseFilenameMetadata(filePath) {
48957
- const name = path.basename(filePath);
48958
- const tsMatch = /(\d{4}-\d{2}-\d{2})T(\d{2})-(\d{2})-(\d{2})/.exec(name);
48959
- const sessionMatch = /([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})(?:\.jsonl)?$/.exec(name);
48960
- if (!tsMatch || !sessionMatch) return null;
48961
- const [, date, hour, min, sec] = tsMatch;
48962
- const sessionId = sessionMatch[1].toLowerCase();
48963
- const timestamp = `${date}T${hour}:${min}:${sec}Z`;
48964
- const timestampMs = Date.parse(timestamp);
48965
- if (Number.isNaN(timestampMs)) return null;
48966
- return {
48967
- sessionId,
48968
- timestamp,
48969
- timestampMs
48970
- };
48971
- }
48972
- function readTimestampMs(entry) {
48973
- const raw = entry.timestamp;
48974
- if (typeof raw === "string") {
48975
- const parsed = Date.parse(raw);
48976
- return Number.isFinite(parsed) ? parsed : null;
48977
- }
48978
- const numeric = normalizeNumber(raw);
48979
- if (!Number.isFinite(numeric) || numeric <= 0) return null;
48980
- return numeric < 0xe8d4a51000 ? numeric * 1e3 : numeric;
48981
- }
48982
- function findUsageMap(info, keys) {
48983
- for (const key of keys) {
48984
- const value = asRecord$1(info[key]);
48985
- if (value) return value;
48986
- }
48987
- return null;
48988
- }
48989
- function extractProjectPath(entry) {
48990
- const cwd = asRecord$1(entry.payload)?.cwd;
48991
- return typeof cwd === "string" && cwd.trim() ? cwd.trim() : null;
48992
- }
48993
- function extractModelFromTurnContext(entry) {
48994
- const payload = asRecord$1(entry.payload);
48995
- if (!payload) return null;
48996
- const direct = payload.model;
48997
- if (typeof direct === "string" && direct.trim()) return direct.trim().replace(/^models\//i, "");
48998
- const nested = asRecord$1(payload.info)?.model;
48999
- if (typeof nested === "string" && nested.trim()) return nested.trim().replace(/^models\//i, "");
49000
- return null;
49001
- }
49002
- function extractModelFromTokenCount(entry) {
49003
- const payload = asRecord$1(entry.payload);
49004
- const info = asRecord$1(payload?.info);
49005
- const candidates = [
49006
- info?.model,
49007
- info?.model_name,
49008
- payload?.model,
49009
- entry.model
49010
- ];
49011
- for (const candidate of candidates) if (typeof candidate === "string" && candidate.trim()) return candidate.trim().replace(/^models\//i, "");
49012
- return null;
49013
- }
49014
- async function readUsageFromFile(filePath) {
49015
- const stream = createReadStream(filePath, { encoding: "utf8" });
49016
- const rl = readline.createInterface({
49017
- input: stream,
49018
- crlfDelay: Infinity
49019
- });
49020
- let projectPath = null;
49021
- let model = null;
49022
- let usageSnapshot = null;
49023
- let latestTimestampMs = null;
49024
- let agentTimeMs = 0;
49025
- let agentRuns = 0;
49026
- let lastActivityMs = null;
49027
- const seenRunTimestamps = /* @__PURE__ */ new Set();
49028
- const trackActivity = (timestampMs) => {
49029
- if (typeof timestampMs !== "number" || !Number.isFinite(timestampMs)) return;
49030
- if (lastActivityMs !== null) {
49031
- const gapMs = timestampMs - lastActivityMs;
49032
- if (gapMs > 0 && gapMs <= MAX_ACTIVITY_GAP_MS) agentTimeMs += gapMs;
49033
- }
49034
- lastActivityMs = timestampMs;
49035
- if (!latestTimestampMs || timestampMs > latestTimestampMs) latestTimestampMs = timestampMs;
49036
- };
49037
- try {
49038
- for await (const line of rl) {
49039
- if (!line || line.length > 512e3) continue;
49040
- let entry = null;
49041
- try {
49042
- entry = JSON.parse(line);
49043
- } catch {
49044
- continue;
49045
- }
49046
- const entryType = typeof entry.type === "string" ? entry.type : "";
49047
- if (!projectPath && (entryType === "session_meta" || entryType === "turn_context")) projectPath = extractProjectPath(entry);
49048
- if (!model && entryType === "turn_context") model = extractModelFromTurnContext(entry);
49049
- const timestampMs = readTimestampMs(entry);
49050
- if (entryType === "response_item") {
49051
- if (asRecord$1(entry.payload)?.role === "assistant") {
49052
- if (typeof timestampMs === "number" && Number.isFinite(timestampMs) && !seenRunTimestamps.has(timestampMs)) {
49053
- seenRunTimestamps.add(timestampMs);
49054
- agentRuns += 1;
49055
- }
49056
- trackActivity(timestampMs);
49057
- }
49058
- continue;
49059
- }
49060
- if (entryType !== "event_msg" && entryType !== "") continue;
49061
- const payload = asRecord$1(entry.payload);
49062
- if (!payload) continue;
49063
- if (payload.type === "agent_message") {
49064
- if (typeof timestampMs === "number" && Number.isFinite(timestampMs) && !seenRunTimestamps.has(timestampMs)) {
49065
- seenRunTimestamps.add(timestampMs);
49066
- agentRuns += 1;
49067
- }
49068
- trackActivity(timestampMs);
49069
- continue;
49070
- }
49071
- if (payload.type === "agent_reasoning") {
49072
- trackActivity(timestampMs);
49073
- continue;
49074
- }
49075
- if (payload.type !== "token_count") continue;
49076
- trackActivity(timestampMs);
49077
- const info = asRecord$1(payload.info);
49078
- if (!info) continue;
49079
- const totalUsageMap = findUsageMap(info, [
49080
- "total_token_usage",
49081
- "totalTokenUsage",
49082
- "total"
49083
- ]);
49084
- if (totalUsageMap) usageSnapshot = normalizeUsage(totalUsageMap);
49085
- else {
49086
- const lastUsageMap = findUsageMap(info, [
49087
- "last_token_usage",
49088
- "lastTokenUsage",
49089
- "last"
49090
- ]);
49091
- if (lastUsageMap) usageSnapshot = normalizeUsage(lastUsageMap);
49092
- }
49093
- if (!usageSnapshot || !hasUsage(usageSnapshot)) continue;
49094
- if (!model) model = extractModelFromTokenCount(entry);
49095
- }
49096
- } finally {
49097
- rl.close();
49098
- stream.close();
49099
- }
49100
- const usage = usageSnapshot ?? ZERO_USAGE;
49101
- if (!hasUsage(usage) && agentTimeMs <= 0 && agentRuns <= 0) return null;
49102
- return {
49103
- projectPath,
49104
- model,
49105
- usage,
49106
- timestampMs: latestTimestampMs,
49107
- agentTimeMs,
49108
- agentRuns
49109
- };
49110
- }
49111
- //#endregion
49112
- //#region ../../packages/runtime-integrations/src/analytics/usage.ts
49113
- const CACHE_TTL_MS = 3e5;
49114
- const RANGE_SAFETY_BUFFER_MS = 1440 * 60 * 1e3;
49115
- const USAGE_FILE_INDEX_VERSION = 1;
49116
- const cacheByKey = /* @__PURE__ */ new Map();
49117
- const scanPromises = /* @__PURE__ */ new Map();
49118
- function computeValidDirSet(fromTime, toTime) {
49119
- if (fromTime === void 0 && toTime === void 0) return null;
49120
- const from = fromTime !== void 0 ? new Date(fromTime) : /* @__PURE__ */ new Date(0);
49121
- const to = toTime !== void 0 ? new Date(toTime) : /* @__PURE__ */ new Date();
49122
- from.setUTCDate(from.getUTCDate() - 1);
49123
- to.setUTCDate(to.getUTCDate() + 1);
49124
- const years = /* @__PURE__ */ new Set();
49125
- const months = /* @__PURE__ */ new Set();
49126
- const days = /* @__PURE__ */ new Set();
49127
- const cursor = new Date(Date.UTC(from.getUTCFullYear(), from.getUTCMonth(), from.getUTCDate()));
49128
- const end = to.getTime();
49129
- while (cursor.getTime() <= end) {
49130
- const y = String(cursor.getUTCFullYear());
49131
- const m = String(cursor.getUTCMonth() + 1).padStart(2, "0");
49132
- const d = String(cursor.getUTCDate()).padStart(2, "0");
49133
- years.add(y);
49134
- months.add(`${y}/${m}`);
49135
- days.add(`${y}/${m}/${d}`);
49136
- cursor.setUTCDate(cursor.getUTCDate() + 1);
49137
- }
49138
- return {
49139
- years,
49140
- months,
49141
- days
49142
- };
49143
- }
49144
- async function listSessionFiles(rootDir, fromTime, toTime) {
49145
- const validDirs = computeValidDirSet(fromTime, toTime);
49146
- const results = [];
49147
- const scannedDayDirs = /* @__PURE__ */ new Set();
49148
- let yearEntries = [];
49149
- try {
49150
- yearEntries = await promises.readdir(rootDir, { withFileTypes: true });
49151
- } catch {
49152
- return {
49153
- files: results,
49154
- scannedDayDirs
49155
- };
49156
- }
49157
- for (const yearEntry of yearEntries) {
49158
- if (!yearEntry.isDirectory()) continue;
49159
- if (validDirs && !validDirs.years.has(yearEntry.name)) continue;
49160
- const yearPath = path.join(rootDir, yearEntry.name);
49161
- let monthEntries = [];
49162
- try {
49163
- monthEntries = await promises.readdir(yearPath, { withFileTypes: true });
49164
- } catch {
49165
- continue;
49166
- }
49167
- for (const monthEntry of monthEntries) {
49168
- if (!monthEntry.isDirectory()) continue;
49169
- if (validDirs && !validDirs.months.has(`${yearEntry.name}/${monthEntry.name}`)) continue;
49170
- const monthPath = path.join(yearPath, monthEntry.name);
49171
- let dayEntries = [];
49172
- try {
49173
- dayEntries = await promises.readdir(monthPath, { withFileTypes: true });
49174
- } catch {
49175
- continue;
49176
- }
49177
- for (const dayEntry of dayEntries) {
49178
- if (!dayEntry.isDirectory()) continue;
49179
- if (validDirs && !validDirs.days.has(`${yearEntry.name}/${monthEntry.name}/${dayEntry.name}`)) continue;
49180
- const dayPath = path.join(monthPath, dayEntry.name);
49181
- scannedDayDirs.add(dayPath);
49182
- let fileEntries = [];
49183
- try {
49184
- fileEntries = await promises.readdir(dayPath, { withFileTypes: true });
49185
- } catch {
49186
- continue;
49187
- }
49188
- for (const fileEntry of fileEntries) {
49189
- if (!fileEntry.isFile() || !fileEntry.name.endsWith(".jsonl")) continue;
49190
- const filePath = path.join(dayPath, fileEntry.name);
49191
- try {
49192
- const stats = await promises.stat(filePath);
49193
- results.push({
49194
- filePath,
49195
- size: stats.size,
49196
- mtimeMs: stats.mtimeMs
49197
- });
49198
- } catch {
49199
- continue;
49200
- }
49201
- }
49202
- }
49203
- }
49204
- }
49205
- return {
49206
- files: results,
49207
- scannedDayDirs
49208
- };
49209
- }
49210
- function toIsoTimestamp(timestampMs) {
49211
- return new Date(timestampMs).toISOString();
49212
- }
49213
- function compareByTimestampDesc(a, b) {
49214
- const aMs = Date.parse(a.timestamp);
49215
- const bMs = Date.parse(b.timestamp);
49216
- const aValue = Number.isFinite(aMs) ? aMs : 0;
49217
- const bValue = Number.isFinite(bMs) ? bMs : 0;
49218
- if (aValue === bValue) return a.sessionId.localeCompare(b.sessionId);
49219
- return bValue - aValue;
49220
- }
49221
- function normalizeRangeTime(value) {
49222
- if (typeof value !== "number" || !Number.isFinite(value)) return;
49223
- return Math.floor(value);
49224
- }
49225
- function normalizeWorkspacePath$1(value) {
49226
- if (typeof value !== "string" || !value.trim()) return null;
49227
- let normalized = path.normalize(path.resolve(value.trim()));
49228
- const root = path.parse(normalized).root;
49229
- if (normalized !== root) normalized = normalized.replace(/[\\/]+$/, "");
49230
- if (process.platform === "win32") normalized = normalized.toLowerCase();
49231
- return normalized;
49232
- }
49233
- function pathMatchesWorkspace(projectPath, normalizedWorkspacePath) {
49234
- if (!normalizedWorkspacePath) return true;
49235
- const normalizedProjectPath = normalizeWorkspacePath$1(projectPath);
49236
- if (!normalizedProjectPath) return false;
49237
- if (normalizedProjectPath === normalizedWorkspacePath) return true;
49238
- const relativePath = path.relative(normalizedWorkspacePath, normalizedProjectPath);
49239
- return relativePath.length > 0 && !relativePath.startsWith("..") && !path.isAbsolute(relativePath);
49240
- }
49241
- function shouldSkipByRange(timestampMs, options) {
49242
- const fromTime = normalizeRangeTime(options?.fromTime);
49243
- const toTime = normalizeRangeTime(options?.toTime);
49244
- if (fromTime !== void 0 && timestampMs < fromTime - RANGE_SAFETY_BUFFER_MS) return true;
49245
- if (toTime !== void 0 && timestampMs > toTime + RANGE_SAFETY_BUFFER_MS) return true;
49246
- return false;
49247
- }
49248
- function buildCacheKey(options) {
49249
- const fromTime = normalizeRangeTime(options?.fromTime);
49250
- const toTime = normalizeRangeTime(options?.toTime);
49251
- const workspacePath = normalizeWorkspacePath$1(options?.workspacePath);
49252
- return `${fromTime ?? "none"}:${toTime ?? "none"}:${workspacePath ?? "all"}`;
49253
- }
49254
- function isRecord$2(value) {
49255
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
49256
- }
49257
- function toNumber(value) {
49258
- if (typeof value === "number" && Number.isFinite(value)) return value;
49259
- if (typeof value === "string" && value.trim()) {
49260
- const parsed = Number(value);
49261
- return Number.isFinite(parsed) ? parsed : null;
49262
- }
49263
- return null;
49264
- }
49265
- function asTokenUsage(value) {
49266
- if (!isRecord$2(value)) return null;
49267
- const input_tokens = toNumber(value.input_tokens) ?? 0;
49268
- const output_tokens = toNumber(value.output_tokens) ?? 0;
49269
- const reasoning_output_tokens = toNumber(value.reasoning_output_tokens) ?? 0;
49270
- return {
49271
- input_tokens,
49272
- output_tokens,
49273
- reasoning_output_tokens,
49274
- cached_input_tokens: toNumber(value.cached_input_tokens) ?? 0,
49275
- total_tokens: toNumber(value.total_tokens) ?? input_tokens + output_tokens + reasoning_output_tokens
49276
- };
49277
- }
49278
- function asUsageRecord(value) {
49279
- if (!isRecord$2(value)) return null;
49280
- const sessionId = typeof value.sessionId === "string" ? value.sessionId.trim() : "";
49281
- const rolloutPath = typeof value.rolloutPath === "string" ? value.rolloutPath.trim() : "";
49282
- const timestamp = typeof value.timestamp === "string" ? value.timestamp.trim() : "";
49283
- if (!sessionId || !rolloutPath || !timestamp) return null;
49284
- const usage = asTokenUsage(value.usage);
49285
- if (!usage) return null;
49286
- return {
49287
- sessionId,
49288
- rolloutPath,
49289
- projectPath: typeof value.projectPath === "string" && value.projectPath.trim() ? value.projectPath.trim() : null,
49290
- model: typeof value.model === "string" && value.model.trim() ? value.model.trim() : null,
49291
- usage,
49292
- timestamp,
49293
- agentTimeMs: toNumber(value.agentTimeMs) ?? 0,
49294
- agentRuns: toNumber(value.agentRuns) ?? 0
49295
- };
49296
- }
49297
- function asUsageFileIndexEntry(value) {
49298
- if (!isRecord$2(value)) return null;
49299
- const filePath = typeof value.filePath === "string" ? value.filePath.trim() : "";
49300
- if (!filePath) return null;
49301
- const size = toNumber(value.size);
49302
- const mtimeMs = toNumber(value.mtimeMs);
49303
- if (size === null || mtimeMs === null) return null;
49304
- const record = value.record === null ? null : asUsageRecord(value.record);
49305
- if (value.record !== null && !record) return null;
49306
- return {
49307
- filePath,
49308
- size,
49309
- mtimeMs,
49310
- record
49311
- };
49312
- }
49313
- async function readUsageFileIndex() {
49314
- const raw = await readJsonFile(resolveUsageFileIndexPath());
49315
- if (!raw || raw.version !== USAGE_FILE_INDEX_VERSION || !Array.isArray(raw.entries)) return /* @__PURE__ */ new Map();
49316
- const byPath = /* @__PURE__ */ new Map();
49317
- for (const entry of raw.entries) {
49318
- const normalized = asUsageFileIndexEntry(entry);
49319
- if (!normalized) continue;
49320
- byPath.set(normalized.filePath, normalized);
49321
- }
49322
- return byPath;
49323
- }
49324
- async function writeUsageFileIndex(indexByPath) {
49325
- await writeJsonFileAtomic(resolveUsageFileIndexPath(), {
49326
- version: USAGE_FILE_INDEX_VERSION,
49327
- updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
49328
- entries: Array.from(indexByPath.values())
49329
- });
49330
- }
49331
- function isPathInsideDir(filePath, dirPath) {
49332
- if (filePath === dirPath) return true;
49333
- const relativePath = path.relative(dirPath, filePath);
49334
- return relativePath.length > 0 && !relativePath.startsWith("..") && !path.isAbsolute(relativePath);
49335
- }
49336
- function pruneDeletedEntries(indexByPath, scannedDayDirs, scannedPaths) {
49337
- if (scannedDayDirs.size === 0) return;
49338
- const dayDirs = Array.from(scannedDayDirs.values());
49339
- for (const filePath of Array.from(indexByPath.keys())) {
49340
- if (!dayDirs.some((dayDir) => isPathInsideDir(filePath, dayDir))) continue;
49341
- if (!scannedPaths.has(filePath)) indexByPath.delete(filePath);
49342
- }
49343
- }
49344
- async function scanUsageRecords(options) {
49345
- const startedAt = Date.now();
49346
- const { files, scannedDayDirs } = await listSessionFiles(getSessionsDir(), normalizeRangeTime(options?.fromTime), normalizeRangeTime(options?.toTime));
49347
- const indexByPath = await readUsageFileIndex();
49348
- const nextIndexByPath = new Map(indexByPath);
49349
- const latestBySessionId = /* @__PURE__ */ new Map();
49350
- const normalizedWorkspacePath = normalizeWorkspacePath$1(options?.workspacePath);
49351
- const scannedPaths = /* @__PURE__ */ new Set();
49352
- let parsedFiles = 0;
49353
- let reusedFiles = 0;
49354
- for (const file of files) {
49355
- const filePath = file.filePath;
49356
- scannedPaths.add(filePath);
49357
- const metadata = parseFilenameMetadata(filePath);
49358
- if (!metadata || shouldSkipByRange(metadata.timestampMs, options)) continue;
49359
- const existing = indexByPath.get(filePath);
49360
- const canReuse = existing && existing.mtimeMs === file.mtimeMs && existing.size === file.size;
49361
- let record = null;
49362
- if (canReuse) {
49363
- reusedFiles += 1;
49364
- record = existing.record;
49365
- nextIndexByPath.set(filePath, existing);
49366
- } else {
49367
- parsedFiles += 1;
49368
- const usageData = await readUsageFromFile(filePath);
49369
- if (usageData) {
49370
- const effectiveTimestampMs = typeof usageData.timestampMs === "number" && Number.isFinite(usageData.timestampMs) ? usageData.timestampMs : metadata.timestampMs;
49371
- record = {
49372
- sessionId: metadata.sessionId,
49373
- rolloutPath: filePath,
49374
- projectPath: usageData.projectPath,
49375
- model: usageData.model,
49376
- usage: usageData.usage,
49377
- timestamp: toIsoTimestamp(effectiveTimestampMs),
49378
- agentTimeMs: usageData.agentTimeMs,
49379
- agentRuns: usageData.agentRuns
49380
- };
49381
- }
49382
- nextIndexByPath.set(filePath, {
49383
- filePath,
49384
- size: file.size,
49385
- mtimeMs: file.mtimeMs,
49386
- record
49387
- });
49388
- }
49389
- if (!record || !pathMatchesWorkspace(record.projectPath, normalizedWorkspacePath)) continue;
49390
- const existingRecord = latestBySessionId.get(record.sessionId);
49391
- if (!existingRecord) {
49392
- latestBySessionId.set(record.sessionId, record);
49393
- continue;
49394
- }
49395
- const existingTs = Date.parse(existingRecord.timestamp);
49396
- const nextTs = Date.parse(record.timestamp);
49397
- const existingMs = Number.isFinite(existingTs) ? existingTs : 0;
49398
- if ((Number.isFinite(nextTs) ? nextTs : 0) >= existingMs) latestBySessionId.set(record.sessionId, record);
49399
- }
49400
- pruneDeletedEntries(nextIndexByPath, scannedDayDirs, scannedPaths);
49401
- try {
49402
- await writeUsageFileIndex(nextIndexByPath);
49403
- } catch (error) {
49404
- if (process.env.NODE_ENV !== "production") console.warn("[analytics] failed to persist usage-file-index", error);
49405
- }
49406
- return {
49407
- records: Array.from(latestBySessionId.values()).sort(compareByTimestampDesc),
49408
- meta: {
49409
- source: "fresh",
49410
- parsedFiles,
49411
- reusedFiles,
49412
- scanMs: Date.now() - startedAt
49413
- }
49414
- };
49415
- }
49416
- function cloneUsageReadResult(result, sourceOverride) {
49417
- return {
49418
- records: result.records.slice(),
49419
- meta: {
49420
- source: sourceOverride ?? result.meta.source,
49421
- parsedFiles: result.meta.parsedFiles,
49422
- reusedFiles: result.meta.reusedFiles,
49423
- scanMs: result.meta.scanMs
49424
- }
49425
- };
49426
- }
49427
- async function loadCachedOrScan(options) {
49428
- const key = buildCacheKey(options);
49429
- const forceRefresh = Boolean(options?.forceRefresh);
49430
- if (forceRefresh) cacheByKey.delete(key);
49431
- const now = Date.now();
49432
- if (!forceRefresh) {
49433
- const cached = cacheByKey.get(key);
49434
- if (cached && now - cached.cachedAt < CACHE_TTL_MS) return cloneUsageReadResult(cached.result, "memory");
49435
- }
49436
- if (!forceRefresh) {
49437
- const inFlight = scanPromises.get(key);
49438
- if (inFlight) return inFlight;
49439
- }
49440
- const scanPromise = scanUsageRecords(options).then((result) => {
49441
- cacheByKey.set(key, {
49442
- cachedAt: Date.now(),
49443
- result: cloneUsageReadResult(result)
49444
- });
49445
- return result;
49446
- }).finally(() => {
49447
- scanPromises.delete(key);
49448
- });
49449
- scanPromises.set(key, scanPromise);
49450
- return scanPromise;
49451
- }
49452
- async function readTokenUsageDetailed(options) {
49453
- return loadCachedOrScan(options);
49454
- }
49455
- //#endregion
49456
- //#region ../../packages/runtime-integrations/src/analytics/service.ts
49457
- const MODEL_COSTS = {
49458
- "gpt-5.3-codex": {
49459
- input: 2.5,
49460
- output: 10,
49461
- cache_write: 1.25,
49462
- cache_read: .125
49463
- },
49464
- "gpt-5.2-codex": {
49465
- input: 2.5,
49466
- output: 10,
49467
- cache_write: 1.25,
49468
- cache_read: .125
49469
- },
49470
- "gpt-5-codex": {
49471
- input: 2.5,
49472
- output: 10,
49473
- cache_write: 1.25,
49474
- cache_read: .125
49475
- },
49476
- "gpt-5": {
49477
- input: 2.5,
49478
- output: 10,
49479
- cache_write: 1.25,
49480
- cache_read: .125
49481
- }
49482
- };
49483
- const DEFAULT_MODEL = "gpt-5.3-codex";
49484
- const QUERY_SNAPSHOT_VERSION = 1;
49485
- const QUERY_SNAPSHOT_TTL_MS = 6e4;
49486
- const QUERY_SNAPSHOT_MAX_ENTRIES = 60;
49487
- const MAX_TIMELINE_POINTS = 30;
49488
- const MAX_MODELS = 10;
49489
- const MAX_PROJECTS = 10;
49490
- const OTHER_MODEL_KEY = "Other";
49491
- const OTHER_PROJECT_KEY = "Other";
49492
- function calculateTokenCost(usage, model) {
49493
- const costs = MODEL_COSTS[model] ?? MODEL_COSTS[DEFAULT_MODEL];
49494
- const inputCost = (usage.input_tokens - (usage.cached_input_tokens || 0)) / 1e6 * costs.input;
49495
- const outputCost = usage.output_tokens / 1e6 * costs.output;
49496
- const cacheWriteCost = usage.cached_input_tokens / 1e6 * costs.cache_write;
49497
- return inputCost + outputCost + cacheWriteCost + 0;
49498
- }
49499
- function buildDailyUsage(metrics) {
49500
- const dailyMap = /* @__PURE__ */ new Map();
49501
- for (const metric of metrics) {
49502
- const date = metric.timestamp.toISOString().slice(0, 10);
49503
- const entry = dailyMap.get(date) ?? {
49504
- date,
49505
- totalTokens: 0,
49506
- inputTokens: 0,
49507
- outputTokens: 0,
49508
- cacheCreationTokens: 0,
49509
- cacheReadTokens: 0,
49510
- totalCost: 0,
49511
- sessionCount: 0,
49512
- agentTimeMs: 0,
49513
- agentRuns: 0,
49514
- models: []
49515
- };
49516
- entry.totalTokens += metric.totalTokens;
49517
- entry.inputTokens += metric.inputTokens;
49518
- entry.outputTokens += metric.outputTokens + metric.reasoningOutputTokens;
49519
- entry.cacheCreationTokens += metric.cachedInputTokens;
49520
- entry.totalCost += metric.estimatedCost;
49521
- entry.sessionCount += 1;
49522
- entry.agentTimeMs += metric.agentTimeMs;
49523
- entry.agentRuns += metric.agentRuns;
49524
- if (!entry.models.includes(metric.model)) entry.models.push(metric.model);
49525
- dailyMap.set(date, entry);
49526
- }
49527
- return Array.from(dailyMap.values()).sort((a, b) => a.date.localeCompare(b.date));
49528
- }
49529
- function buildHourlyUsage(metrics) {
49530
- const hourlyMap = /* @__PURE__ */ new Map();
49531
- for (const metric of metrics) {
49532
- const key = `${metric.timestamp.toISOString().slice(0, 10)} ${metric.timestamp.getHours().toString().padStart(2, "0")}:00`;
49533
- const entry = hourlyMap.get(key) ?? {
49534
- hour: key,
49535
- totalTokens: 0,
49536
- inputTokens: 0,
49537
- outputTokens: 0,
49538
- totalCost: 0,
49539
- sessionCount: 0
49540
- };
49541
- entry.totalTokens += metric.totalTokens;
49542
- entry.inputTokens += metric.inputTokens;
49543
- entry.outputTokens += metric.outputTokens + metric.reasoningOutputTokens;
49544
- entry.totalCost += metric.estimatedCost;
49545
- entry.sessionCount += 1;
49546
- hourlyMap.set(key, entry);
49547
- }
49548
- return Array.from(hourlyMap.values()).sort((a, b) => a.hour.localeCompare(b.hour));
49549
- }
49550
- function buildModelUsage(metrics) {
49551
- const modelMap = /* @__PURE__ */ new Map();
49552
- const totalTokens = metrics.reduce((sum, metric) => sum + metric.totalTokens, 0);
49553
- for (const metric of metrics) {
49554
- const entry = modelMap.get(metric.model) ?? {
49555
- model: metric.model,
49556
- tokens: 0,
49557
- inputTokens: 0,
49558
- outputTokens: 0,
49559
- cost: 0,
49560
- percentage: 0,
49561
- sessionCount: 0
49562
- };
49563
- entry.tokens += metric.totalTokens;
49564
- entry.inputTokens += metric.inputTokens;
49565
- entry.outputTokens += metric.outputTokens + metric.reasoningOutputTokens;
49566
- entry.cost += metric.estimatedCost;
49567
- entry.sessionCount += 1;
49568
- modelMap.set(metric.model, entry);
49569
- }
49570
- return Array.from(modelMap.values()).map((entry) => ({
49571
- ...entry,
49572
- percentage: totalTokens > 0 ? entry.tokens / totalTokens * 100 : 0
49573
- })).sort((a, b) => b.tokens - a.tokens);
49574
- }
49575
- function limitModelUsage(data, maxModels = MAX_MODELS) {
49576
- if (data.length <= maxModels) return data;
49577
- const top = data.slice(0, maxModels);
49578
- const rest = data.slice(maxModels);
49579
- if (rest.length === 0) return top;
49580
- const other = rest.reduce((acc, item) => {
49581
- acc.tokens += item.tokens;
49582
- acc.inputTokens += item.inputTokens;
49583
- acc.outputTokens += item.outputTokens;
49584
- acc.cost += item.cost;
49585
- acc.sessionCount += item.sessionCount;
49586
- return acc;
49587
- }, {
49588
- model: OTHER_MODEL_KEY,
49589
- tokens: 0,
49590
- inputTokens: 0,
49591
- outputTokens: 0,
49592
- cost: 0,
49593
- percentage: 0,
49594
- sessionCount: 0
49595
- });
49596
- const total = top.reduce((sum, item) => sum + item.tokens, 0) + other.tokens;
49597
- return [...top.map((item) => ({
49598
- ...item,
49599
- percentage: total > 0 ? item.tokens / total * 100 : 0
49600
- })), {
49601
- ...other,
49602
- percentage: total > 0 ? other.tokens / total * 100 : 0
49603
- }];
49604
- }
49605
- function buildProjectBreakdown(metrics) {
49606
- const projectMap = /* @__PURE__ */ new Map();
49607
- for (const metric of metrics) {
49608
- const rawProjectPath = metric.projectPath?.trim() || null;
49609
- const key = rawProjectPath && isGeneralChatWorkspaceRoot(rawProjectPath) ? GENERAL_CHAT_ANALYTICS_BUCKET : rawProjectPath || "Unknown";
49610
- const entry = projectMap.get(key) ?? {
49611
- sessions: 0,
49612
- cost: 0,
49613
- tokens: 0
49614
- };
49615
- entry.sessions += 1;
49616
- entry.cost += metric.estimatedCost;
49617
- entry.tokens += metric.totalTokens;
49618
- projectMap.set(key, entry);
49619
- }
49620
- return Object.fromEntries(projectMap.entries());
49621
- }
49622
- function limitProjectBreakdown(projectBreakdown, maxProjects = MAX_PROJECTS) {
49623
- const sorted = Object.entries(projectBreakdown).sort((a, b) => b[1].cost - a[1].cost);
49624
- if (sorted.length <= maxProjects) return Object.fromEntries(sorted);
49625
- const top = sorted.slice(0, maxProjects);
49626
- const other = sorted.slice(maxProjects).reduce((acc, entry) => {
49627
- acc.sessions += entry[1].sessions;
49628
- acc.cost += entry[1].cost;
49629
- acc.tokens += entry[1].tokens;
49630
- return acc;
49631
- }, {
49632
- sessions: 0,
49633
- cost: 0,
49634
- tokens: 0
49635
- });
49636
- if (other.sessions > 0 || other.cost > 0 || other.tokens > 0) top.push([OTHER_PROJECT_KEY, other]);
49637
- return Object.fromEntries(top);
49638
- }
49639
- function limitTimelinePoints(data, maxPoints = MAX_TIMELINE_POINTS) {
49640
- if (data.length <= maxPoints) return data;
49641
- return data.slice(-maxPoints);
49642
- }
49643
- function normalizeWorkspacePath(value) {
49644
- if (typeof value !== "string" || !value.trim()) return null;
49645
- let normalized = path.normalize(path.resolve(value.trim()));
49646
- const root = path.parse(normalized).root;
49647
- if (normalized !== root) normalized = normalized.replace(/[\\/]+$/, "");
49648
- if (process.platform === "win32") normalized = normalized.toLowerCase();
49649
- return normalized;
49650
- }
49651
- function resolveLocalTimeZone() {
49652
- try {
49653
- const zone = Intl.DateTimeFormat().resolvedOptions().timeZone;
49654
- if (zone && typeof zone === "string" && zone.trim()) return zone.trim();
49655
- } catch {}
49656
- return "local";
49657
- }
49658
- function normalizeDateInput(value) {
49659
- if (value instanceof Date) return Number.isFinite(value.getTime()) ? value : void 0;
49660
- if (typeof value === "number" && Number.isFinite(value)) {
49661
- const timestamp = Math.abs(value) < 0xe8d4a51000 ? value * 1e3 : value;
49662
- const normalized = new Date(Math.trunc(timestamp));
49663
- return Number.isFinite(normalized.getTime()) ? normalized : void 0;
49664
- }
49665
- if (typeof value === "string") {
49666
- const trimmed = value.trim();
49667
- if (!trimmed) return;
49668
- const numeric = Number(trimmed);
49669
- if (Number.isFinite(numeric)) return normalizeDateInput(numeric);
49670
- const parsed = Date.parse(trimmed);
49671
- if (Number.isFinite(parsed)) return new Date(parsed);
49672
- }
49673
- }
49674
- function normalizeDateRange(dateRange) {
49675
- if (!dateRange) return;
49676
- const from = normalizeDateInput(dateRange.from);
49677
- const to = normalizeDateInput(dateRange.to);
49678
- return from || to ? {
49679
- from,
49680
- to
49681
- } : {};
49682
- }
49683
- function buildSnapshotKey(options) {
49684
- const dateRange = normalizeDateRange(options.dateRange);
49685
- return `${dateRange?.from?.getTime() ?? 0}:${dateRange?.to?.getTime() ?? 0}:${normalizeWorkspacePath(options.workspacePath) ?? "all"}:${resolveLocalTimeZone()}`;
49686
- }
49687
- function isRecord$1(value) {
49688
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
49689
- }
49690
- function normalizeQuerySnapshotEntry(value) {
49691
- if (!isRecord$1(value)) return null;
49692
- const key = typeof value.key === "string" ? value.key.trim() : "";
49693
- const cachedAt = typeof value.cachedAt === "number" ? value.cachedAt : Number(value.cachedAt);
49694
- const generatedAt = typeof value.generatedAt === "string" ? value.generatedAt : "";
49695
- const data = value.data;
49696
- if (!key || !Number.isFinite(cachedAt) || !generatedAt || !data) return null;
49697
- return {
49698
- key,
49699
- cachedAt,
49700
- generatedAt,
49701
- data,
49702
- parsedFiles: typeof value.parsedFiles === "number" && Number.isFinite(value.parsedFiles) ? value.parsedFiles : 0,
49703
- reusedFiles: typeof value.reusedFiles === "number" && Number.isFinite(value.reusedFiles) ? value.reusedFiles : 0,
49704
- scanMs: typeof value.scanMs === "number" && Number.isFinite(value.scanMs) ? value.scanMs : 0
49705
- };
49706
- }
49707
- async function readQuerySnapshotStore() {
49708
- const raw = await readJsonFile(resolveQuerySnapshotPath());
49709
- if (!raw || raw.version !== QUERY_SNAPSHOT_VERSION || !Array.isArray(raw.entries)) return {
49710
- version: QUERY_SNAPSHOT_VERSION,
49711
- entries: [],
49712
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
49713
- };
49714
- const entries = [];
49715
- for (const entry of raw.entries) {
49716
- const normalized = normalizeQuerySnapshotEntry(entry);
49717
- if (normalized) entries.push(normalized);
49718
- }
49719
- return {
49720
- version: QUERY_SNAPSHOT_VERSION,
49721
- entries,
49722
- updatedAt: typeof raw.updatedAt === "string" && raw.updatedAt ? raw.updatedAt : (/* @__PURE__ */ new Date()).toISOString()
49723
- };
49724
- }
49725
- async function writeQuerySnapshotStore(store) {
49726
- await writeJsonFileAtomic(resolveQuerySnapshotPath(), store);
49727
- }
49728
- async function readSnapshotByKey(key) {
49729
- return (await readQuerySnapshotStore()).entries.find((entry) => entry.key === key) ?? null;
49730
- }
49731
- async function upsertSnapshotEntry(entry) {
49732
- const filtered = (await readQuerySnapshotStore()).entries.filter((candidate) => candidate.key !== entry.key);
49733
- filtered.unshift(entry);
49734
- if (filtered.length > QUERY_SNAPSHOT_MAX_ENTRIES) filtered.length = QUERY_SNAPSHOT_MAX_ENTRIES;
49735
- await writeQuerySnapshotStore({
49736
- version: QUERY_SNAPSHOT_VERSION,
49737
- entries: filtered,
49738
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
49739
- });
49740
- }
49741
- function createResultMetaFromSnapshot(snapshot) {
49742
- return {
49743
- source: "persisted",
49744
- stale: Date.now() - snapshot.cachedAt > QUERY_SNAPSHOT_TTL_MS,
49745
- generatedAt: snapshot.generatedAt,
49746
- parsedFiles: snapshot.parsedFiles,
49747
- reusedFiles: snapshot.reusedFiles,
49748
- scanMs: snapshot.scanMs
49749
- };
49750
- }
49751
- function resolveDateRange(options) {
49752
- if (!options) return {};
49753
- if ("dateRange" in options || "mergeProfiles" in options || "includeUnattributedSessions" in options || "forceRefresh" in options || "workspacePath" in options || "loadMode" in options) {
49754
- const query = options;
49755
- return {
49756
- ...query,
49757
- dateRange: normalizeDateRange(query.dateRange)
49758
- };
49759
- }
49760
- return { dateRange: normalizeDateRange(options) };
49761
- }
49762
- async function loadAnalyticsData(dateRangeOrOptions) {
49763
- const startedAt = Date.now();
49764
- const options = resolveDateRange(dateRangeOrOptions);
49765
- const loadMode = options.loadMode ?? "cacheFirst";
49766
- const shouldReadPersisted = loadMode === "cacheFirst" && !options.forceRefresh;
49767
- const snapshotKey = buildSnapshotKey(options);
49768
- const persisted = shouldReadPersisted ? await readSnapshotByKey(snapshotKey) : null;
49769
- if (persisted) return {
49770
- data: persisted.data,
49771
- meta: createResultMetaFromSnapshot(persisted)
49772
- };
49773
- const { dateRange, workspacePath } = options;
49774
- const fromTime = dateRange?.from?.getTime() ?? 0;
49775
- const toTime = dateRange?.to?.getTime() ?? Date.now();
49776
- const usageResult = await readTokenUsageDetailed({
49777
- fromTime,
49778
- toTime,
49779
- forceRefresh: Boolean(options.forceRefresh || loadMode === "freshOnly"),
49780
- workspacePath
49781
- });
49782
- const records = usageResult.records;
49783
- const metrics = [];
49784
- for (const record of records) {
49785
- const ts = Date.parse(record.timestamp);
49786
- if (Number.isNaN(ts)) continue;
49787
- if (ts < fromTime || ts > toTime) continue;
49788
- const model = record.model ?? DEFAULT_MODEL;
49789
- metrics.push({
49790
- sessionId: record.sessionId,
49791
- timestamp: new Date(ts),
49792
- projectPath: record.projectPath,
49793
- model,
49794
- inputTokens: record.usage.input_tokens,
49795
- outputTokens: record.usage.output_tokens,
49796
- reasoningOutputTokens: record.usage.reasoning_output_tokens,
49797
- cachedInputTokens: record.usage.cached_input_tokens,
49798
- totalTokens: record.usage.total_tokens,
49799
- agentTimeMs: record.agentTimeMs,
49800
- agentRuns: record.agentRuns,
49801
- estimatedCost: calculateTokenCost(record.usage, model)
49802
- });
49803
- }
49804
- const totalCost = metrics.reduce((sum, m) => sum + m.estimatedCost, 0);
49805
- const totalSessions = metrics.length;
49806
- const totalTokens = metrics.reduce((sum, m) => sum + m.totalTokens, 0);
49807
- const avgCostPerSession = totalSessions > 0 ? totalCost / totalSessions : 0;
49808
- const avgTokensPerSession = totalSessions > 0 ? totalTokens / totalSessions : 0;
49809
- const totalInputTokens = metrics.reduce((sum, m) => sum + m.inputTokens, 0);
49810
- const totalOutputTokens = metrics.reduce((sum, m) => sum + m.outputTokens + m.reasoningOutputTokens, 0);
49811
- const totalReasoningTokens = metrics.reduce((sum, m) => sum + m.reasoningOutputTokens, 0);
49812
- const totalCachedInputTokens = metrics.reduce((sum, m) => sum + m.cachedInputTokens, 0);
49813
- const totalCacheCreationTokens = metrics.reduce((sum, m) => sum + m.cachedInputTokens, 0);
49814
- const totalCacheReadTokens = 0;
49815
- const totalAgentTimeMs = metrics.reduce((sum, m) => sum + m.agentTimeMs, 0);
49816
- const totalAgentRuns = metrics.reduce((sum, m) => sum + m.agentRuns, 0);
49817
- const dailyUsage = limitTimelinePoints(buildDailyUsage(metrics));
49818
- const hourlyUsage = limitTimelinePoints(buildHourlyUsage(metrics));
49819
- const modelUsage = limitModelUsage(buildModelUsage(metrics));
49820
- const projectBreakdown = limitProjectBreakdown(buildProjectBreakdown(metrics));
49821
- const cacheEfficiencyBase = totalInputTokens + totalCacheCreationTokens;
49822
- const data = {
49823
- summary: {
49824
- totalTokens,
49825
- totalInputTokens,
49826
- totalOutputTokens,
49827
- totalCacheCreationTokens,
49828
- totalCacheReadTokens,
49829
- totalReasoningTokens,
49830
- totalCachedInputTokens,
49831
- totalAgentTimeMs,
49832
- totalAgentRuns,
49833
- totalCost,
49834
- totalSessions,
49835
- avgCostPerSession,
49836
- avgTokensPerSession,
49837
- cacheEfficiency: cacheEfficiencyBase > 0 ? totalCacheCreationTokens / cacheEfficiencyBase * 100 : 0,
49838
- cacheSavings: 0,
49839
- dailyAvgCost: dailyUsage.length > 0 ? totalCost / dailyUsage.length : 0,
49840
- models: modelUsage.map((entry) => entry.model)
49841
- },
49842
- dailyUsage,
49843
- hourlyUsage,
49844
- modelUsage,
49845
- projectBreakdown
49846
- };
49847
- const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
49848
- const result = {
49849
- data,
49850
- meta: {
49851
- source: usageResult.meta.source === "memory" ? "memory" : "fresh",
49852
- stale: false,
49853
- generatedAt,
49854
- parsedFiles: usageResult.meta.parsedFiles,
49855
- reusedFiles: usageResult.meta.reusedFiles,
49856
- scanMs: usageResult.meta.scanMs
49857
- }
49858
- };
49859
- try {
49860
- await upsertSnapshotEntry({
49861
- key: snapshotKey,
49862
- cachedAt: Date.now(),
49863
- generatedAt,
49864
- data,
49865
- parsedFiles: result.meta.parsedFiles,
49866
- reusedFiles: result.meta.reusedFiles,
49867
- scanMs: result.meta.scanMs
49868
- });
49869
- } catch (error) {
49870
- if (process.env.NODE_ENV !== "production") console.warn("[analytics] failed to persist query snapshot", error);
49871
- }
49872
- if (process.env.NODE_ENV !== "production") {
49873
- const elapsedMs = Date.now() - startedAt;
49874
- console.warn(`[analytics] loadAnalyticsData totalMs=${elapsedMs} records=${records.length} source=${result.meta.source} parsedFiles=${result.meta.parsedFiles} reusedFiles=${result.meta.reusedFiles}`);
49875
- }
49876
- return result;
49877
- }
49878
- //#endregion
49879
48932
  //#region ../../packages/runtime-integrations/src/agents/service.ts
49880
48933
  const AGENTS_FILENAME = "AGENTS.md";
49881
48934
  function resolveGlobalPath(options) {
@@ -50742,6 +49795,35 @@ async function inspectCodexRuntime(input) {
50742
49795
  };
50743
49796
  }
50744
49797
  //#endregion
49798
+ //#region src/agentChat.ts
49799
+ const AGENT_CHAT_AGENTS_CONTENT = `# AGENTS.md — Agent
49800
+
49801
+ You are the assistant for CodexUse's Agent surface.
49802
+
49803
+ Default behavior:
49804
+ - Act like a capable local agent, not a casual chat-only assistant.
49805
+ - Use the machine deliberately when the user asks you to inspect files, run commands, edit code, or complete workspace tasks.
49806
+ - Treat this workspace as internal app scaffolding; the real task may still involve other folders on the machine.
49807
+ - Prefer concrete execution over abstract discussion when the user asks for action.
49808
+ - Before destructive, irreversible, security-sensitive, or high-impact machine actions, pause and get confirmation.
49809
+ - Explain when you are about to leave discussion-only mode and start taking actions on the machine.
49810
+ - Keep changes scoped to the user's request, and avoid unrelated file churn.
49811
+ `;
49812
+ function getAgentChatConfig() {
49813
+ return { workspaceRoot: resolveAgentChatWorkspaceRoot() };
49814
+ }
49815
+ async function ensureAgentChatWorkspaceArtifacts() {
49816
+ const workspaceRoot = resolveAgentChatWorkspaceRoot();
49817
+ const agentsPath = resolveAgentChatAgentsPath();
49818
+ await promises.mkdir(workspaceRoot, { recursive: true });
49819
+ try {
49820
+ await promises.access(agentsPath);
49821
+ } catch {
49822
+ await promises.writeFile(agentsPath, AGENT_CHAT_AGENTS_CONTENT, "utf8");
49823
+ }
49824
+ return workspaceRoot;
49825
+ }
49826
+ //#endregion
50745
49827
  //#region src/generalChat.ts
50746
49828
  const GENERAL_CHAT_AGENTS_CONTENT = `# AGENTS.md — General Chat
50747
49829
 
@@ -52780,6 +51862,7 @@ const createServer = fn(function* () {
52780
51862
  clients,
52781
51863
  logOutgoingPush
52782
51864
  });
51865
+ const agentChatConfig = getAgentChatConfig();
52783
51866
  const generalChatConfig = getGeneralChatConfig();
52784
51867
  yield* readiness.markPushBusReady;
52785
51868
  yield* keybindingsManager.start.pipe(mapError((cause) => new ServerLifecycleError({
@@ -53171,6 +52254,7 @@ const createServer = fn(function* () {
53171
52254
  issues: [],
53172
52255
  providers: providerStatuses,
53173
52256
  projectPolicy,
52257
+ agentChat: agentChatConfig,
53174
52258
  generalChat: generalChatConfig
53175
52259
  });
53176
52260
  })).pipe(forkIn(subscriptionsScope));
@@ -53183,6 +52267,7 @@ const createServer = fn(function* () {
53183
52267
  issues: event.issues,
53184
52268
  providers: providerStatuses,
53185
52269
  projectPolicy,
52270
+ agentChat: agentChatConfig,
53186
52271
  generalChat: generalChatConfig
53187
52272
  });
53188
52273
  })).pipe(forkIn(subscriptionsScope));
@@ -53525,6 +52610,37 @@ const createServer = fn(function* () {
53525
52610
  created: true
53526
52611
  };
53527
52612
  }
52613
+ case WS_METHODS.agentChatEnsure: {
52614
+ const workspaceRoot = yield* tryPromise({
52615
+ try: () => ensureAgentChatWorkspaceArtifacts(),
52616
+ catch: (cause) => new RouteRequestError({ message: `Failed to prepare Agent workspace: ${String(cause)}` })
52617
+ });
52618
+ const existingProject = findActiveProjectByCanonicalRoot((yield* projectionReadModelQuery.getSnapshot()).projects, workspaceRoot);
52619
+ if (existingProject) return {
52620
+ projectId: existingProject.id,
52621
+ workspaceRoot: existingProject.workspaceRoot,
52622
+ created: false
52623
+ };
52624
+ const createdAt = (/* @__PURE__ */ new Date()).toISOString();
52625
+ const projectId = ProjectId.makeUnsafe(crypto.randomUUID());
52626
+ yield* orchestrationEngine.dispatch({
52627
+ type: "project.create",
52628
+ commandId: CommandId.makeUnsafe(crypto.randomUUID()),
52629
+ projectId,
52630
+ title: AGENT_CHAT_PROJECT_TITLE,
52631
+ workspaceRoot,
52632
+ defaultModelSelection: {
52633
+ provider: "codex",
52634
+ model: DEFAULT_MODEL_BY_PROVIDER.codex
52635
+ },
52636
+ createdAt
52637
+ });
52638
+ return {
52639
+ projectId,
52640
+ workspaceRoot,
52641
+ created: true
52642
+ };
52643
+ }
53528
52644
  case WS_METHODS.generalChatEnsure: {
53529
52645
  const workspaceRoot = yield* tryPromise({
53530
52646
  try: () => ensureGeneralChatWorkspaceArtifacts(),
@@ -53670,6 +52786,7 @@ const createServer = fn(function* () {
53670
52786
  providers,
53671
52787
  availableEditors,
53672
52788
  projectPolicy,
52789
+ agentChat: agentChatConfig,
53673
52790
  generalChat: generalChatConfig
53674
52791
  };
53675
52792
  }
@@ -54058,10 +53175,6 @@ const createServer = fn(function* () {
54058
53175
  });
54059
53176
  return result;
54060
53177
  }
54061
- case WS_METHODS.analyticsGetData: {
54062
- const body = stripRequestTag(request.body);
54063
- return yield* promise(() => loadAnalyticsData(body.query ?? void 0));
54064
- }
54065
53178
  default: return yield* new RouteRequestError({ message: `Unknown method: ${String(request.body._tag)}` });
54066
53179
  }
54067
53180
  });
@@ -55672,7 +54785,9 @@ const layer = /* @__PURE__ */ layerMergedServices(/* @__PURE__ */ succeed(fetch$
55672
54785
  //#endregion
55673
54786
  //#region src/index.ts
55674
54787
  const RuntimeLayer = empty$6.pipe(provideMerge(CliConfig.layer), provideMerge(ServerLive), provideMerge(OpenLive), provideMerge(NetService.layer), provideMerge(layer$2), provideMerge(layer));
55675
- run$1(t3Cli, { version }).pipe(provide(RuntimeLayer), runMain);
54788
+ const program = run$1(t3Cli, { version });
54789
+ const runnableProgram = provide(program, RuntimeLayer);
54790
+ runMain(runnableProgram);
55676
54791
  //#endregion
55677
54792
  export { make$13 as n, get$1 as t };
55678
54793