@codexhost/cli-darwin-x64 0.15.0 → 0.16.0

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.
@@ -14952,6 +14952,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
14952
14952
  cachedInputTokens: count,
14953
14953
  cacheWriteInputTokens: count,
14954
14954
  cacheKnownInputTokens: count,
14955
+ cacheHitCachedInputTokens: count,
14956
+ cacheHitInputTokens: count,
14955
14957
  outputTokens: count,
14956
14958
  reasoningOutputTokens: count,
14957
14959
  /** USD at the public price, summed over the priced requests only. */
@@ -15410,7 +15412,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15410
15412
  external_exports.null()
15411
15413
  ]);
15412
15414
  function hasNoCircularReferences(value) {
15413
- const ancestors = /* @__PURE__ */ new WeakSet();
15415
+ const ancestors2 = /* @__PURE__ */ new WeakSet();
15414
15416
  const stack = [{ value, leaving: false }];
15415
15417
  try {
15416
15418
  while (stack.length > 0) {
@@ -15418,14 +15420,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15418
15420
  if (!frame)
15419
15421
  break;
15420
15422
  if (frame.leaving) {
15421
- ancestors.delete(frame.value);
15423
+ ancestors2.delete(frame.value);
15422
15424
  continue;
15423
15425
  }
15424
15426
  if (typeof frame.value !== "object" || frame.value === null)
15425
15427
  continue;
15426
- if (ancestors.has(frame.value))
15428
+ if (ancestors2.has(frame.value))
15427
15429
  return false;
15428
- ancestors.add(frame.value);
15430
+ ancestors2.add(frame.value);
15429
15431
  stack.push({ value: frame.value, leaving: true });
15430
15432
  for (const child of Object.values(frame.value)) {
15431
15433
  stack.push({ value: child, leaving: false });
@@ -17240,10 +17242,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17240
17242
  return [];
17241
17243
  seen.add(entry.node);
17242
17244
  if (entry.node === first || entry.node === alternate) {
17243
- const ancestors = [];
17245
+ const ancestors2 = [];
17244
17246
  for (let cursor = entry; cursor; cursor = cursor.parent)
17245
- ancestors.push(cursor.node);
17246
- return ancestors;
17247
+ ancestors2.push(cursor.node);
17248
+ return ancestors2;
17247
17249
  }
17248
17250
  const sibling = entry.parent && fiber(entry.node.sibling);
17249
17251
  if (sibling)
@@ -17255,6 +17257,402 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17255
17257
  return stack.length > 0 ? exhausted() : [];
17256
17258
  }
17257
17259
 
17260
+ // ../desktop-control/dist/renderer-native-schedule-sidebar.js
17261
+ var NATIVE_SCHEDULE_SIDEBAR_ROW_SELECTOR = 'aside [data-sidebar-cycle-item][role="button"][aria-labelledby]';
17262
+ function readNativeScheduleSidebarThread(element) {
17263
+ if (!element.matches(NATIVE_SCHEDULE_SIDEBAR_ROW_SELECTOR))
17264
+ return null;
17265
+ const keys = Object.keys(element).filter((key2) => key2.startsWith("__reactFiber$"));
17266
+ const key = keys[0];
17267
+ if (keys.length !== 1 || !key)
17268
+ return null;
17269
+ let scheduledContainer = false;
17270
+ const candidates = /* @__PURE__ */ new Set();
17271
+ let depth = 0;
17272
+ for (const fiber of committedReactAncestors(Reflect.get(element, key))) {
17273
+ if (++depth > 12)
17274
+ break;
17275
+ const props = fiber.memoizedProps;
17276
+ if (!props || typeof props !== "object")
17277
+ continue;
17278
+ if (Object.hasOwn(props, "data-selected-scheduled-task"))
17279
+ scheduledContainer = true;
17280
+ if (!scheduledContainer || !Object.hasOwn(props, "automation"))
17281
+ continue;
17282
+ const automation = props.automation;
17283
+ if (!automation || typeof automation !== "object" || automation.kind !== "heartbeat" || typeof automation.id !== "string" || !automation.id || props.hostId != null && props.hostId !== "local" || automation.hostId != null && automation.hostId !== "local")
17284
+ return null;
17285
+ const parsed = hostThreadIdSchema.safeParse(automation.targetThreadId);
17286
+ if (!parsed.success)
17287
+ return null;
17288
+ candidates.add(parsed.data);
17289
+ }
17290
+ return candidates.size === 1 ? candidates.values().next().value ?? null : null;
17291
+ }
17292
+
17293
+ // ../desktop-control/dist/renderer-scoped-draft-model.js
17294
+ function findScopedDraftModelBinding(composer, draftId) {
17295
+ let element = composer.querySelector?.('[data-codex-composer], [contenteditable="true"][role="textbox"]') ?? composer;
17296
+ let fiber;
17297
+ while (element && !fiber) {
17298
+ const key = Object.getOwnPropertyNames(element).find((name) => name.startsWith("__reactFiber$"));
17299
+ if (key)
17300
+ fiber = Object.getOwnPropertyDescriptor(element, key)?.value;
17301
+ element = element.parentElement;
17302
+ }
17303
+ const rows = [];
17304
+ const groups = /* @__PURE__ */ new Map();
17305
+ const updates = /* @__PURE__ */ new Set();
17306
+ for (const ancestor of committedReactAncestors(fiber)) {
17307
+ const queue = ancestor.updateQueue;
17308
+ const data = (queue?.memoCache?.data ?? []).filter(Array.isArray);
17309
+ for (const row of data) {
17310
+ rows.push(row);
17311
+ groups.set(row, data);
17312
+ if (!Array.isArray(row) || row.length !== 14 || row[6] !== draftId || row[7] !== draftId)
17313
+ continue;
17314
+ const result = row[13];
17315
+ if (result?.isNewThreadDraft === true && row[11] === true && result.draftSettings === row[10] && result.updateDraftSettings === row[9] && row[9] === row[12] && typeof row[9] === "function")
17316
+ updates.add(row[9]);
17317
+ }
17318
+ }
17319
+ let update;
17320
+ const modes = /* @__PURE__ */ new Set();
17321
+ const creationModes = /* @__PURE__ */ new Set();
17322
+ for (const row of rows) {
17323
+ if (row.length !== 24 || row[7] !== null || row[10] !== true || !updates.has(row[13]))
17324
+ continue;
17325
+ const context = row[12];
17326
+ const result = row[23];
17327
+ if (context && context === row[21] && typeof context.usesAccountPreferences === "boolean" && result?.usesAccountPreferences === context.usesAccountPreferences && typeof row[14] === "function" && row[14] === row[20] && result.setModelAndReasoningEffort === row[14]) {
17328
+ update ??= row[13];
17329
+ modes.add(context.usesAccountPreferences);
17330
+ const settings = result.modelSettings;
17331
+ const group = groups.get(row);
17332
+ const candidate = group?.[group.indexOf(row) - 1];
17333
+ const mode = candidate?.[44];
17334
+ const value = candidate?.[51];
17335
+ if (candidate?.length === 52 && settings && candidate[39] === settings.model && candidate[40] === settings.reasoningEffort && mode && mode === candidate[49] && mode.settings === candidate[41] && mode.settings?.model === settings.model && value?.activeMode === mode)
17336
+ creationModes.add(mode);
17337
+ }
17338
+ }
17339
+ const [usesAccountPreferences] = modes;
17340
+ return update && modes.size === 1 && usesAccountPreferences !== void 0 ? {
17341
+ update,
17342
+ usesAccountPreferences,
17343
+ ...creationModes.size ? { creationModes: [...creationModes] } : {}
17344
+ } : null;
17345
+ }
17346
+ function createScopedDraftModelWriter() {
17347
+ const captured = /* @__PURE__ */ new Map();
17348
+ const restore = (key) => {
17349
+ const entry = captured.get(key);
17350
+ if (!entry)
17351
+ return;
17352
+ entry.update((current) => {
17353
+ const settings = current.modelSettings;
17354
+ return settings?.model === entry.model && current.modelSettingsPersistAsDefault === false ? {
17355
+ ...current,
17356
+ modelSettings: entry.original.modelSettings,
17357
+ modelSettingsPersistAsDefault: entry.original.modelSettingsPersistAsDefault,
17358
+ isManuallyChanged: entry.original.isManuallyChanged
17359
+ } : current;
17360
+ });
17361
+ captured.delete(key);
17362
+ };
17363
+ return {
17364
+ has(key) {
17365
+ return captured.has(key);
17366
+ },
17367
+ apply(key, binding, model2) {
17368
+ if (model2 === null) {
17369
+ restore(key);
17370
+ return;
17371
+ }
17372
+ const { update, usesAccountPreferences } = binding;
17373
+ update((current) => {
17374
+ const previous = captured.get(key);
17375
+ captured.set(key, { update, original: previous?.original ?? current, model: model2 });
17376
+ const settings = current.modelSettings;
17377
+ if (settings?.model === model2 && settings.usesAccountPreferences === usesAccountPreferences && current.modelSettingsPersistAsDefault === false)
17378
+ return current;
17379
+ return {
17380
+ ...current,
17381
+ isManuallyChanged: true,
17382
+ modelSettingsPersistAsDefault: false,
17383
+ modelSettings: {
17384
+ ...settings,
17385
+ model: model2,
17386
+ reasoningEffort: settings?.reasoningEffort ?? null,
17387
+ profile: settings?.profile ?? null,
17388
+ usesAccountPreferences
17389
+ }
17390
+ };
17391
+ });
17392
+ },
17393
+ dispose() {
17394
+ for (const key of captured.keys())
17395
+ restore(key);
17396
+ }
17397
+ };
17398
+ }
17399
+
17400
+ // ../desktop-control/dist/renderer-native-schedule-form.js
17401
+ var record4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
17402
+ function ancestors(element) {
17403
+ if (!record4(element))
17404
+ return [];
17405
+ const key = Object.getOwnPropertyNames(element).find((name) => name.startsWith("__reactFiber$"));
17406
+ return committedReactAncestors(key ? Object.getOwnPropertyDescriptor(element, key)?.value : null);
17407
+ }
17408
+ function readNativeScheduleForm(form) {
17409
+ const candidates = ancestors(form).flatMap(({ memoizedProps: props2 }) => {
17410
+ if (!record4(props2) || !record4(props2.setup) || props2.setup.triggerMode !== "create" || !record4(props2.draft) || !record4(props2.draft.scheduleConfig) || typeof props2.draft.scheduleDirty !== "boolean" || typeof props2.draft.prompt !== "string" || props2.draft.id != null || !["heartbeat", "cron"].includes(String(props2.draft.kind)) || !["local", "cloud"].includes(String(props2.executionLocation)) || typeof props2.onChange !== "function" || typeof props2.onSubmit !== "function" || typeof props2.isSaving !== "boolean" || props2.draft.model !== null && typeof props2.draft.model !== "string" || props2.draft.reasoningEffort !== null && typeof props2.draft.reasoningEffort !== "string")
17411
+ return [];
17412
+ return [props2];
17413
+ });
17414
+ const props = candidates[0];
17415
+ if (!props || candidates.some((other) => other.draft !== props.draft || other.onChange !== props.onChange || other.onSubmit !== props.onSubmit))
17416
+ return null;
17417
+ const draft = props.draft;
17418
+ const change = props.onChange;
17419
+ const supportsExternal = props.executionLocation === "local" && draft.kind === "heartbeat" && draft.cloudTeam == null && (!record4(props.creation) || props.creation.type === "task") && (!record4(draft.eventTrigger) || draft.eventTrigger.selected !== true) && (!Array.isArray(draft.webhookTriggers) || draft.webhookTriggers.length === 0);
17420
+ return {
17421
+ selection: {
17422
+ model: draft.model,
17423
+ reasoningEffort: draft.reasoningEffort
17424
+ },
17425
+ supportsExternal,
17426
+ hasTarget: draft.targetThreadId != null,
17427
+ isSaving: props.isSaving,
17428
+ title: (typeof draft.name === "string" ? draft.name.trim() : "") || String(draft.prompt).trim().replace(/\s+/gu, " ").slice(0, 80),
17429
+ targetThreadId: typeof draft.targetThreadId === "string" ? draft.targetThreadId : null,
17430
+ setTargetThread(threadId, expectedModel) {
17431
+ if (!supportsExternal || props.isSaving || draft.targetThreadId != null || !threadId || !expectedModel.startsWith("codexhost/plugin-v1@"))
17432
+ return;
17433
+ change((current) => current.id == null && current.targetThreadId == null && current.kind === "heartbeat" && current.cloudTeam == null && current.model === expectedModel ? { ...current, targetThreadId: threadId } : current);
17434
+ },
17435
+ setModel(selection) {
17436
+ if (props.isSaving || draft.targetThreadId != null)
17437
+ return;
17438
+ change((current) => current.id == null && current.targetThreadId == null && current.kind === draft.kind ? { ...current, ...selection } : current);
17439
+ }
17440
+ };
17441
+ }
17442
+ function nativeScheduleModelRows(form) {
17443
+ const rows = /* @__PURE__ */ new Set();
17444
+ for (const button2 of form.querySelectorAll("button")) {
17445
+ let host = null;
17446
+ for (const fiber of ancestors(button2)) {
17447
+ const node = fiber.stateNode;
17448
+ if (node === form)
17449
+ break;
17450
+ if (record4(node) && node.nodeType === 1 && typeof node.hidden === "boolean" && record4(node.style) && ["getPropertyValue", "getPropertyPriority", "setProperty"].every((method) => typeof node.style[method] === "function") && form.contains(node))
17451
+ host = node;
17452
+ const props = fiber.memoizedProps;
17453
+ const label = record4(props) && record4(props.label) ? props.label.props : null;
17454
+ if (record4(label) && ["inbox.automations.model.label", "automations.configuration.effort"].includes(String(label.id))) {
17455
+ if (host)
17456
+ rows.add(host);
17457
+ break;
17458
+ }
17459
+ }
17460
+ }
17461
+ return [...rows];
17462
+ }
17463
+
17464
+ // ../desktop-control/dist/renderer-host-discovery.js
17465
+ function requestManagerFromHookState(value, hostId2) {
17466
+ const record8 = (candidate) => typeof candidate === "object" && candidate !== null;
17467
+ const manager = (candidate) => {
17468
+ if (!record8(candidate) || !record8(candidate.requestClient) || !record8(candidate.prewarmedThreadManager))
17469
+ return null;
17470
+ const bridge = candidate.requestClient;
17471
+ return typeof candidate.sendRequest === "function" && typeof bridge.sendRequest === "function" && typeof bridge.prewarmThreadStart === "function" && typeof bridge.enqueueRequest === "function" && typeof candidate.prewarmedThreadManager.discardAllPrewarmedThreads === "function" ? candidate : null;
17472
+ };
17473
+ if (!record8(value))
17474
+ return null;
17475
+ const direct = manager(value) ?? manager(value.manager);
17476
+ if (direct)
17477
+ return direct;
17478
+ if (!hostId2 || typeof value.addManager !== "function" || typeof value.getForHostId !== "function")
17479
+ return null;
17480
+ try {
17481
+ return manager(value.getForHostId(hostId2));
17482
+ } catch {
17483
+ return null;
17484
+ }
17485
+ }
17486
+ function discoverRendererHosts(root, ancestors2 = committedReactAncestors, managerFrom = requestManagerFromHookState) {
17487
+ const editors = [
17488
+ ...root.querySelectorAll('[data-codex-composer], [contenteditable="true"][role="textbox"]')
17489
+ ];
17490
+ const hostIds = /* @__PURE__ */ new Set();
17491
+ const managers = /* @__PURE__ */ new Set();
17492
+ const registries = /* @__PURE__ */ new Set();
17493
+ const fibers = /* @__PURE__ */ new Set();
17494
+ for (const editor of editors) {
17495
+ let element = editor;
17496
+ let fiber;
17497
+ while (element && !fiber) {
17498
+ const key = Object.getOwnPropertyNames(element).find((name) => name.startsWith("__reactFiber$"));
17499
+ if (key)
17500
+ fiber = Object.getOwnPropertyDescriptor(element, key)?.value;
17501
+ element = element.parentElement ?? null;
17502
+ }
17503
+ for (const current of ancestors2(fiber)) {
17504
+ fibers.add(current);
17505
+ const props = current.memoizedProps;
17506
+ for (const key of ["executionTargetHostId", "permissionsHostId"]) {
17507
+ const hostId2 = props?.[key];
17508
+ if (typeof hostId2 === "string" && hostId2)
17509
+ hostIds.add(hostId2);
17510
+ }
17511
+ }
17512
+ }
17513
+ for (const fiber of fibers) {
17514
+ let hook = fiber.memoizedState;
17515
+ for (let index = 0; hook && index < 120; index += 1) {
17516
+ const value = hook.memoizedState;
17517
+ const manager = managerFrom(value);
17518
+ if (manager)
17519
+ managers.add(manager);
17520
+ if (value && typeof value === "object" && "addManager" in value && typeof value.addManager === "function" && "getForHostId" in value && typeof value.getForHostId === "function") {
17521
+ registries.add(value);
17522
+ }
17523
+ hook = hook.next && typeof hook.next === "object" ? hook.next : null;
17524
+ }
17525
+ }
17526
+ return {
17527
+ editorCount: editors.length,
17528
+ hostIds: [...hostIds],
17529
+ managers: [...managers],
17530
+ registries: [...registries]
17531
+ };
17532
+ }
17533
+
17534
+ // ../desktop-control/dist/renderer-schedule-workspace.js
17535
+ var record5 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
17536
+ function readNativeScheduleWorkspaces(root) {
17537
+ const projects = /* @__PURE__ */ new Map();
17538
+ const ambiguous = /* @__PURE__ */ new Set();
17539
+ const seen = /* @__PURE__ */ new Set();
17540
+ const add = (value) => {
17541
+ if (!record5(value) || value.source !== "codex" || !record5(value.group))
17542
+ return;
17543
+ const group = value.group;
17544
+ if (group.projectKind !== "local" || group.hostId != null && group.hostId !== "local" || typeof group.projectId !== "string" || !group.projectId || typeof group.label !== "string" || typeof group.path !== "string" || !Array.isArray(group.rootPaths) || !group.rootPaths.includes(group.path) || !/^(?:\/|[A-Za-z]:[\\/]|\\\\)/u.test(group.path) || group.path.includes("\0"))
17545
+ return;
17546
+ const next = { id: group.projectId, label: group.label || group.path, cwd: group.path };
17547
+ const previous = projects.get(next.id);
17548
+ if (previous && previous.cwd !== next.cwd)
17549
+ ambiguous.add(next.id);
17550
+ else
17551
+ projects.set(next.id, next);
17552
+ };
17553
+ for (const element of root.querySelectorAll("aside [data-sidebar-cycle-item]")) {
17554
+ const keys = Object.getOwnPropertyNames(element).filter((key2) => key2.startsWith("__reactFiber$"));
17555
+ const key = keys[0];
17556
+ if (keys.length !== 1 || !key)
17557
+ continue;
17558
+ for (const fiber of committedReactAncestors(Reflect.get(element, key))) {
17559
+ if (seen.has(fiber))
17560
+ break;
17561
+ seen.add(fiber);
17562
+ const props = fiber.memoizedProps;
17563
+ if (!record5(props))
17564
+ continue;
17565
+ add(props.project);
17566
+ if (props.projectByKey instanceof Map)
17567
+ for (const project3 of props.projectByKey.values())
17568
+ add(project3);
17569
+ }
17570
+ }
17571
+ return [...projects.values()].filter(({ id }) => !ambiguous.has(id));
17572
+ }
17573
+ function isNativeProjectThreadCreator(value) {
17574
+ if (typeof value !== "function" || value.length !== 1)
17575
+ return false;
17576
+ const source = Function.prototype.toString.call(value);
17577
+ return /^async function/u.test(source) && source.includes("startWithoutFirstTurn:") && source.includes("onSettled:") && source.includes("createThread config is not supported for delegated thread creation") && source.includes("createThread serviceName is only supported for local Electron root threads outside worktrees");
17578
+ }
17579
+ async function createNativeScheduleWorkspaceThread(root, routing, createThread, input, signal) {
17580
+ if (!decodeHarnessPluginRoute(input.model))
17581
+ throw new Error("An external Harness is required");
17582
+ const route = routing.forHost("local");
17583
+ const manager = route?.manager;
17584
+ if (!route?.policy.scopedCreation || !manager || typeof manager.getConversation !== "function" || typeof manager.archiveConversation !== "function")
17585
+ throw new Error("Native local chat creation is unavailable");
17586
+ const discovery = discoverRendererHosts({
17587
+ querySelectorAll: () => root.querySelectorAll("main")
17588
+ });
17589
+ const scopes = new Set(discovery.registries.flatMap((registry2) => {
17590
+ try {
17591
+ return registry2.getForHostId("local") === manager ? [Reflect.get(registry2, "scope")] : [];
17592
+ } catch {
17593
+ return [];
17594
+ }
17595
+ }));
17596
+ const scope = scopes.values().next().value;
17597
+ if (scopes.size !== 1 || !record5(scope) || typeof scope.get !== "function")
17598
+ throw new Error("Native local chat scope is missing or ambiguous");
17599
+ if (!readNativeScheduleWorkspaces(root).some(({ id, cwd }) => id === input.workspace.id && cwd === input.workspace.cwd))
17600
+ throw new Error("The selected workspace is no longer available");
17601
+ signal.throwIfAborted();
17602
+ let createdId = null;
17603
+ let released = false;
17604
+ const discard = () => {
17605
+ if (!createdId || released)
17606
+ return;
17607
+ const id = createdId;
17608
+ released = true;
17609
+ const conversation2 = manager.getConversation(id);
17610
+ if (!record5(conversation2) || !Array.isArray(conversation2.turns) || conversation2.turns.length || Array.isArray(conversation2.requests) && conversation2.requests.length > 0 || conversation2.pendingRequest != null)
17611
+ return;
17612
+ void Promise.resolve().then(() => manager.archiveConversation(id, {
17613
+ useAppServerPins: false,
17614
+ source: "automation_history"
17615
+ })).catch(() => void 0);
17616
+ };
17617
+ signal.addEventListener("abort", discard, { once: true });
17618
+ const remember = (result2) => {
17619
+ if (!record5(result2) || result2.status !== "created")
17620
+ return;
17621
+ const id = hostThreadIdSchema.safeParse(result2.conversationId);
17622
+ if (id.success)
17623
+ createdId = id.data;
17624
+ if (signal.aborted)
17625
+ discard();
17626
+ };
17627
+ const output = await createThread({
17628
+ scope,
17629
+ target: { type: "project", projectId: input.workspace.id, environment: { type: "local" } },
17630
+ model: input.model,
17631
+ title: input.title,
17632
+ prompt: "",
17633
+ startWithoutFirstTurn: true,
17634
+ onSettled: remember
17635
+ });
17636
+ const result = record5(output) && output.kind === "creation" ? output.result : null;
17637
+ remember(result);
17638
+ signal.throwIfAborted();
17639
+ if (!record5(result) || result.status !== "created" || !createdId || !record5(result.firstTurn) || result.firstTurn.status !== "not-requested")
17640
+ throw new Error("Chat creation was not confirmed. Check the chat list before creating another task.");
17641
+ if (routing.forHost("local")?.manager !== route.manager)
17642
+ throw new Error("The local connection changed. Reopen the task dialog.");
17643
+ const conversation = manager.getConversation(createdId);
17644
+ const mode = record5(conversation) ? conversation.latestCollaborationMode : null;
17645
+ if (!record5(conversation) || conversation.cwd !== input.workspace.cwd || !record5(mode) || !record5(mode.settings) || mode.settings.model !== input.model)
17646
+ throw new Error("The created chat's workspace or Model could not be confirmed");
17647
+ return {
17648
+ threadId: createdId,
17649
+ retain() {
17650
+ released = true;
17651
+ signal.removeEventListener("abort", discard);
17652
+ }
17653
+ };
17654
+ }
17655
+
17258
17656
  // src/renderer-composer-kind.ts
17259
17657
  function orbitComposerKind(composer) {
17260
17658
  let element = composer.querySelector('[contenteditable="true"], textarea, [role="textbox"]') ?? composer;
@@ -17534,6 +17932,16 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17534
17932
  ["path", { d: "M12 13.5V8" }]
17535
17933
  ];
17536
17934
 
17935
+ // ../../node_modules/lucide/dist/esm/icons/calendar-clock.mjs
17936
+ var CalendarClock = [
17937
+ ["path", { d: "M16 14v2.2l1.6 1" }],
17938
+ ["path", { d: "M16 2v3" }],
17939
+ ["path", { d: "M21 7.338V5a2 2 0 00-2-2H5a2 2 0 00-2 2v14a2 2 0 002 2h2.338" }],
17940
+ ["path", { d: "M3 9h5.859" }],
17941
+ ["path", { d: "M8 2v3" }],
17942
+ ["circle", { cx: "16", cy: "16", r: "6" }]
17943
+ ];
17944
+
17537
17945
  // ../../node_modules/lucide/dist/esm/icons/circle-check.mjs
17538
17946
  var CircleCheck = [
17539
17947
  ["circle", { cx: "12", cy: "12", r: "10" }],
@@ -17839,6 +18247,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17839
18247
  "routes",
17840
18248
  "gateway",
17841
18249
  "updates",
18250
+ "schedules",
17842
18251
  "about",
17843
18252
  "info",
17844
18253
  "external-link",
@@ -17890,6 +18299,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17890
18299
  routes: Route,
17891
18300
  gateway: Network,
17892
18301
  updates: CircleArrowUp,
18302
+ schedules: CalendarClock,
17893
18303
  about: Info,
17894
18304
  info: Info,
17895
18305
  "external-link": ExternalLink,
@@ -19680,7 +20090,6 @@ ${messages.harnessVersionLatest}: ${harnessVersionLabel(version2.state, messages
19680
20090
  updateLatestVersion: "Latest version",
19681
20091
  updateUpToDate: "You are up to date.",
19682
20092
  updateAvailable: "A new version is available.",
19683
- updateWindowsManualRequired: "Automatic updates are unavailable on Windows. Update manually below.",
19684
20093
  updateAndRestart: "Update",
19685
20094
  updateChecking: "Checking for updates...",
19686
20095
  updateDownloading: "Downloading update...",
@@ -19695,8 +20104,7 @@ ${messages.harnessVersionLatest}: ${harnessVersionLabel(version2.state, messages
19695
20104
  updateFailed: "Update failed.",
19696
20105
  updateRetry: "Retry",
19697
20106
  updateManualNpmDescription: "To update manually, quit codexhost and run this command:",
19698
- updateWindowsNpmDescription: "Automatic updates are unavailable on Windows. Quit codexhost and run this command in a terminal:",
19699
- updateWindowsInstallerDescription: "Automatic updates are unavailable on Windows. Download and run the installer for this system.",
20107
+ updateWindowsInstallerDescription: "To update manually, download and run the installer for this system.",
19700
20108
  updateManualTitle: "Manual update",
19701
20109
  updateManualFallbackDescription: "The automatic update did not complete. Run this command in a terminal instead, then quit Codex and relaunch it with codexhost.",
19702
20110
  updateCopyCommand: "Copy",
@@ -19961,7 +20369,6 @@ ${messages.harnessVersionLatest}: ${harnessVersionLabel(version2.state, messages
19961
20369
  updateLatestVersion: "\u6700\u65B0\u7248\u672C",
19962
20370
  updateUpToDate: "\u5F53\u524D\u5DF2\u662F\u6700\u65B0\u7248\u672C\u3002",
19963
20371
  updateAvailable: "\u6709\u65B0\u7248\u672C\u53EF\u7528\u3002",
19964
- updateWindowsManualRequired: "Windows \u6682\u4E0D\u652F\u6301\u81EA\u52A8\u66F4\u65B0\uFF0C\u8BF7\u5728\u4E0B\u65B9\u624B\u52A8\u66F4\u65B0\u3002",
19965
20372
  updateAndRestart: "\u66F4\u65B0",
19966
20373
  updateChecking: "\u6B63\u5728\u68C0\u67E5\u66F4\u65B0...",
19967
20374
  updateDownloading: "\u6B63\u5728\u4E0B\u8F7D\u66F4\u65B0...",
@@ -19976,8 +20383,7 @@ ${messages.harnessVersionLatest}: ${harnessVersionLabel(version2.state, messages
19976
20383
  updateFailed: "\u66F4\u65B0\u5931\u8D25\u3002",
19977
20384
  updateRetry: "\u91CD\u8BD5",
19978
20385
  updateManualNpmDescription: "\u5982\u9700\u624B\u52A8\u66F4\u65B0\uFF0C\u8BF7\u5728\u7EC8\u7AEF\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u3002\u66F4\u65B0\u5B8C\u6210\u540E\uFF0C\u8BF7\u9000\u51FA Codex \u5E76\u901A\u8FC7 codexhost \u91CD\u65B0\u542F\u52A8\u3002",
19979
- updateWindowsNpmDescription: "Windows \u6682\u4E0D\u652F\u6301\u81EA\u52A8\u66F4\u65B0\u3002\u8BF7\u9000\u51FA codexhost\uFF0C\u5728\u7EC8\u7AEF\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u5B8C\u6210\u66F4\u65B0\u3002",
19980
- updateWindowsInstallerDescription: "Windows \u6682\u4E0D\u652F\u6301\u81EA\u52A8\u66F4\u65B0\u3002\u8BF7\u4E0B\u8F7D\u5E76\u8FD0\u884C\u9002\u7528\u4E8E\u5F53\u524D\u7CFB\u7EDF\u7684\u5B89\u88C5\u5305\u3002",
20386
+ updateWindowsInstallerDescription: "\u5982\u9700\u624B\u52A8\u66F4\u65B0\uFF0C\u8BF7\u4E0B\u8F7D\u5E76\u8FD0\u884C\u9002\u7528\u4E8E\u5F53\u524D\u7CFB\u7EDF\u7684\u5B89\u88C5\u5305\u3002",
19981
20387
  updateManualTitle: "\u624B\u52A8\u66F4\u65B0",
19982
20388
  updateManualFallbackDescription: "\u81EA\u52A8\u66F4\u65B0\u672A\u80FD\u5B8C\u6210\uFF0C\u8BF7\u6539\u7528\u4E0B\u5217\u547D\u4EE4\u5728\u7EC8\u7AEF\u624B\u52A8\u66F4\u65B0\u3002\u5B8C\u6210\u540E\u8BF7\u9000\u51FA Codex \u5E76\u901A\u8FC7 codexhost \u91CD\u65B0\u542F\u52A8\u3002",
19983
20389
  updateCopyCommand: "\u590D\u5236",
@@ -24123,13 +24529,13 @@ Codex Fast mode prioritizes requests and may increase usage.`
24123
24529
  (name) => name.startsWith("__reactFiber$")
24124
24530
  );
24125
24531
  if (key) {
24126
- const ancestors = committedReactAncestors(
24532
+ const ancestors2 = committedReactAncestors(
24127
24533
  Object.getOwnPropertyDescriptor(element, key)?.value
24128
24534
  );
24129
24535
  const scopes = [];
24130
- ancestors.forEach(({ memoizedProps: props }, index) => {
24536
+ ancestors2.forEach(({ memoizedProps: props }, index) => {
24131
24537
  if (isRecord3(props) && "onLocalSubmitStart" in props && typeof props.submitDisabled === "boolean") {
24132
- scopes.push({ owner: ancestors[index], fibers: ancestors.slice(0, index + 1) });
24538
+ scopes.push({ owner: ancestors2[index], fibers: ancestors2.slice(0, index + 1) });
24133
24539
  }
24134
24540
  });
24135
24541
  const valid = scopes.filter((scope) => {
@@ -25387,9 +25793,9 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25387
25793
  }
25388
25794
 
25389
25795
  // src/renderer-thread-reference-capability.ts
25390
- var record4 = (value) => typeof value === "object" && value !== null;
25796
+ var record6 = (value) => typeof value === "object" && value !== null;
25391
25797
  function restoreThreadReferenceCapability(client, manager, isCurrent) {
25392
- if (!record4(manager) || !record4(manager.storage)) return client;
25798
+ if (!record6(manager) || !record6(manager.storage)) return client;
25393
25799
  const storage = manager.storage;
25394
25800
  const read = storage.readValue;
25395
25801
  const write = storage.writeValue;
@@ -25424,14 +25830,14 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25424
25830
  }
25425
25831
 
25426
25832
  // src/renderer-thread-reference-context.ts
25427
- var record5 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
25833
+ var record7 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
25428
25834
  function createThreadReferenceContext(manager, hostId2, isCurrent) {
25429
25835
  const prepared = /* @__PURE__ */ new WeakMap();
25430
25836
  return (params) => {
25431
- if (hostId2 === "local" || !record5(manager) || typeof manager.getConversation !== "function" || !record5(params) || typeof params.threadId !== "string")
25837
+ if (hostId2 === "local" || !record7(manager) || typeof manager.getConversation !== "function" || !record7(params) || typeof params.threadId !== "string")
25432
25838
  return params;
25433
25839
  const conversation = manager.getConversation.call(manager, params.threadId);
25434
- if (!record5(conversation) || conversation.id !== params.threadId || conversation.modelProvider !== "codexhost")
25840
+ if (!record7(conversation) || conversation.id !== params.threadId || conversation.modelProvider !== "codexhost")
25435
25841
  return params;
25436
25842
  if (!isCurrent()) throw new Error("Thread reference connection is no longer available");
25437
25843
  const cached2 = prepared.get(params);
@@ -25681,6 +26087,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25681
26087
  var SIDEBAR_THREAD_ID_ATTRIBUTE = "data-app-action-sidebar-thread-id";
25682
26088
  var SIDEBAR_THREAD_HOST_ID_ATTRIBUTE = "data-app-action-sidebar-thread-host-id";
25683
26089
  var SIDEBAR_AGENT_ICON_ATTRIBUTE = "data-codexhost-sidebar-agent-icon";
26090
+ var SIDEBAR_AGENT_ICON_ROW_SELECTOR = `${SIDEBAR_THREAD_ROW_SELECTOR}, ${NATIVE_SCHEDULE_SIDEBAR_ROW_SELECTOR}`;
25684
26091
  var OWNERSHIP_RETRY_DELAYS_MS = [100, 300, 800, 1500, 3e3];
25685
26092
  function isRecord10(value) {
25686
26093
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -25726,7 +26133,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25726
26133
  return candidates.size === 1 ? candidates.values().next().value ?? null : null;
25727
26134
  }
25728
26135
  function rendererAgentForThreadOwnership(ownership) {
25729
- if (ownership.owner === "codex") return null;
26136
+ if (ownership.owner === "codex") return "codex";
25730
26137
  return ownership.harnessId;
25731
26138
  }
25732
26139
  function sidebarAgentIconAnchor(titleTrigger, title) {
@@ -25744,22 +26151,30 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25744
26151
  this.element = element;
25745
26152
  }
25746
26153
  element;
26154
+ #scheduledThread;
25747
26155
  isConnected() {
25748
26156
  return this.element.isConnected;
25749
26157
  }
25750
26158
  hostId() {
25751
- return sidebarThreadAttributes(this.element)?.hostId ?? null;
26159
+ const attributes = sidebarThreadAttributes(this.element);
26160
+ this.#scheduledThread = attributes ? void 0 : readNativeScheduleSidebarThread(this.element);
26161
+ return attributes?.hostId ?? (this.#scheduledThread ? "local" : null);
25752
26162
  }
25753
26163
  threadId() {
25754
- return threadIdFromSidebarRowElement(this.element);
26164
+ const threadId = sidebarThreadAttributes(this.element) ? threadIdFromSidebarRowElement(this.element) : this.#scheduledThread !== void 0 ? this.#scheduledThread : readNativeScheduleSidebarThread(this.element);
26165
+ this.#scheduledThread = void 0;
26166
+ return threadId;
25755
26167
  }
25756
26168
  draftId() {
25757
26169
  return draftIdFromSidebarRowElement(this.element);
25758
26170
  }
25759
26171
  render(agent, plugin) {
25760
26172
  const presentation = JSON.stringify([agent, plugin?.name, plugin?.icon, plugin?.iconStyle]);
25761
- const titleTrigger = this.element.querySelector("[data-thread-title-trigger]");
25762
- const title = titleTrigger?.querySelector("[data-thread-title]");
26173
+ const scheduled = !this.element.hasAttribute(SIDEBAR_THREAD_ROW_ATTRIBUTE) && this.element.matches(NATIVE_SCHEDULE_SIDEBAR_ROW_SELECTOR);
26174
+ const titleTrigger = scheduled ? this.element : this.element.querySelector("[data-thread-title-trigger]");
26175
+ const title = scheduled ? [...this.element.querySelectorAll("[data-thread-title][id]")].find(
26176
+ (node) => node.id === this.element.getAttribute("aria-labelledby")
26177
+ ) : titleTrigger?.querySelector("[data-thread-title]");
25763
26178
  if (!titleTrigger || !title) {
25764
26179
  this.clear();
25765
26180
  return;
@@ -25808,7 +26223,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25808
26223
  row = new BrowserSidebarAgentIconRow(element);
25809
26224
  this.#rowsByElement.set(element, row);
25810
26225
  }
25811
- if (element.isConnected && element.matches(SIDEBAR_THREAD_ROW_SELECTOR))
26226
+ if (element.isConnected && element.matches(SIDEBAR_AGENT_ICON_ROW_SELECTOR))
25812
26227
  this.#trackedRows.add(row);
25813
26228
  else this.#trackedRows.delete(row);
25814
26229
  return row;
@@ -25817,7 +26232,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25817
26232
  for (const row of this.#trackedRows) {
25818
26233
  if (!row.isConnected()) this.#trackedRows.delete(row);
25819
26234
  }
25820
- return [...this.root.querySelectorAll(SIDEBAR_THREAD_ROW_SELECTOR)].map(
26235
+ return [...this.root.querySelectorAll(SIDEBAR_AGENT_ICON_ROW_SELECTOR)].map(
25821
26236
  (element) => this.#row(element)
25822
26237
  );
25823
26238
  }
@@ -25826,13 +26241,14 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25826
26241
  const changed = /* @__PURE__ */ new Set();
25827
26242
  const collect = (node) => {
25828
26243
  if (!(node instanceof Element)) return;
25829
- if (node.matches(SIDEBAR_THREAD_ROW_SELECTOR)) changed.add(this.#row(node));
25830
- for (const element of node.querySelectorAll(SIDEBAR_THREAD_ROW_SELECTOR))
26244
+ if (node.matches(SIDEBAR_AGENT_ICON_ROW_SELECTOR))
26245
+ changed.add(this.#row(node));
26246
+ for (const element of node.querySelectorAll(SIDEBAR_AGENT_ICON_ROW_SELECTOR))
25831
26247
  changed.add(this.#row(element));
25832
26248
  };
25833
26249
  for (const mutation of mutations) {
25834
26250
  const target = mutation.target instanceof Element ? mutation.target : mutation.target.parentElement;
25835
- const row = target?.closest(SIDEBAR_THREAD_ROW_SELECTOR);
26251
+ const row = target?.closest(SIDEBAR_AGENT_ICON_ROW_SELECTOR);
25836
26252
  if (row) changed.add(this.#row(row));
25837
26253
  else if (target && this.#rowsByElement.has(target))
25838
26254
  changed.add(this.#row(target));
@@ -25846,7 +26262,10 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25846
26262
  attributeFilter: [
25847
26263
  SIDEBAR_THREAD_ROW_ATTRIBUTE,
25848
26264
  SIDEBAR_THREAD_ID_ATTRIBUTE,
25849
- SIDEBAR_THREAD_HOST_ID_ATTRIBUTE
26265
+ SIDEBAR_THREAD_HOST_ID_ATTRIBUTE,
26266
+ "data-sidebar-cycle-item",
26267
+ "aria-labelledby",
26268
+ "role"
25850
26269
  ],
25851
26270
  childList: true,
25852
26271
  subtree: true
@@ -25916,7 +26335,8 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25916
26335
  ownershipRetryTimers.delete(key);
25917
26336
  if (disposed) return;
25918
26337
  failed.delete(key);
25919
- ownershipByThread.delete(key);
26338
+ const cached2 = ownershipByThread.get(key);
26339
+ if (cached2) cached2.stale = true;
25920
26340
  scheduleScan(rowsByThread.get(key) ?? []);
25921
26341
  }, delay);
25922
26342
  ownershipRetryTimers.set(key, timer);
@@ -25929,7 +26349,10 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25929
26349
  if (disposed) return;
25930
26350
  for (const ownership of threads) {
25931
26351
  const key = ownershipKey(hostId2, ownership.threadId);
25932
- ownershipByThread.set(key, rendererAgentForThreadOwnership(ownership));
26352
+ ownershipByThread.set(key, {
26353
+ agent: rendererAgentForThreadOwnership(ownership),
26354
+ stale: false
26355
+ });
25933
26356
  failed.delete(key);
25934
26357
  if (ownership.owner === "codex") {
25935
26358
  provisionalCodex.add(key);
@@ -25962,6 +26385,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25962
26385
  const unresolvedByHost = /* @__PURE__ */ new Map();
25963
26386
  const pluginsByHost = /* @__PURE__ */ new Map();
25964
26387
  const getPlugin = (hostId2, agent) => {
26388
+ if (agent === "codex") return void 0;
25965
26389
  if (!pluginsByHost.has(hostId2)) pluginsByHost.set(hostId2, options.getPlugins?.(hostId2));
25966
26390
  return pluginsByHost.get(hostId2)?.find(({ id }) => id === agent);
25967
26391
  };
@@ -25987,11 +26411,10 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25987
26411
  if (localAgent !== null && localAgent !== void 0) {
25988
26412
  if (threadId.success) {
25989
26413
  const key2 = ownershipKey(hostId2, threadId.data);
25990
- ownershipByThread.set(key2, localAgent === "codex" ? null : localAgent);
26414
+ ownershipByThread.set(key2, { agent: localAgent, stale: false });
25991
26415
  clearOwnershipRetry(key2);
25992
26416
  }
25993
- if (localAgent === "codex") row.clear();
25994
- else row.render(localAgent, getPlugin(hostId2, localAgent));
26417
+ row.render(localAgent, getPlugin(hostId2, localAgent));
25995
26418
  continue;
25996
26419
  }
25997
26420
  if (!threadId.success) {
@@ -25999,13 +26422,11 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25999
26422
  continue;
26000
26423
  }
26001
26424
  const key = ownershipKey(hostId2, threadId.data);
26002
- if (ownershipByThread.has(key)) {
26003
- const agent = ownershipByThread.get(key);
26004
- if (agent) row.render(agent, getPlugin(hostId2, agent));
26005
- else row.clear();
26006
- continue;
26007
- }
26008
- row.clear();
26425
+ const cached2 = ownershipByThread.get(key);
26426
+ if (cached2) {
26427
+ row.render(cached2.agent, getPlugin(hostId2, cached2.agent));
26428
+ if (!cached2.stale) continue;
26429
+ } else row.clear();
26009
26430
  if (!pending.has(key) && !failed.has(key)) {
26010
26431
  let unresolved = unresolvedByHost.get(hostId2);
26011
26432
  if (!unresolved) {
@@ -26045,7 +26466,10 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26045
26466
  for (const timer of ownershipRetryTimers.values()) clearTimeout(timer);
26046
26467
  ownershipRetryTimers.clear();
26047
26468
  ownershipRetryAttempts.clear();
26048
- for (const key of provisionalCodex) ownershipByThread.delete(key);
26469
+ for (const key of provisionalCodex) {
26470
+ const cached2 = ownershipByThread.get(key);
26471
+ if (cached2) cached2.stale = true;
26472
+ }
26049
26473
  provisionalCodex.clear();
26050
26474
  scheduleScan(dom.rows());
26051
26475
  },
@@ -26144,16 +26568,16 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26144
26568
  return isRecord11(value) ? value : null;
26145
26569
  }
26146
26570
  function directForkAncestors(first) {
26147
- const ancestors = [];
26571
+ const ancestors2 = [];
26148
26572
  const seen = /* @__PURE__ */ new Set();
26149
26573
  let fiber = first;
26150
- while (fiber && ancestors.length < FAST_FORK_OWNER_DEPTH) {
26574
+ while (fiber && ancestors2.length < FAST_FORK_OWNER_DEPTH) {
26151
26575
  if (seen.has(fiber)) return [];
26152
26576
  seen.add(fiber);
26153
- ancestors.push(fiber);
26577
+ ancestors2.push(fiber);
26154
26578
  fiber = isRecord11(fiber.return) ? fiber.return : null;
26155
26579
  }
26156
- return ancestors;
26580
+ return ancestors2;
26157
26581
  }
26158
26582
  function ownsOtherCallback(fiber, props) {
26159
26583
  if (typeof fiber.type === "string") return false;
@@ -26161,13 +26585,13 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26161
26585
  (name) => /^on[A-Z]/.test(name) && name !== "onClick" && name !== "onFork" && typeof props[name] === "function"
26162
26586
  );
26163
26587
  }
26164
- function forkTargetFromAncestors(button2, threadId, turnId, ancestors) {
26588
+ function forkTargetFromAncestors(button2, threadId, turnId, ancestors2) {
26165
26589
  const conversationIds = /* @__PURE__ */ new Set();
26166
26590
  const turnIds = /* @__PURE__ */ new Set();
26167
26591
  const hostIds = /* @__PURE__ */ new Set();
26168
26592
  const projectlessStates = /* @__PURE__ */ new Set();
26169
26593
  let hasForkCallback = false;
26170
- for (const fiber of ancestors) {
26594
+ for (const fiber of ancestors2) {
26171
26595
  const props = fiber.memoizedProps;
26172
26596
  if (!isRecord11(props)) continue;
26173
26597
  if (!hasForkCallback && typeof props.onFork !== "function" && ownsOtherCallback(fiber, props)) {
@@ -26704,6 +27128,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26704
27128
  }
26705
27129
  });
26706
27130
  const selectedPolicies = /* @__PURE__ */ new Map();
27131
+ const draftModels = createScopedDraftModelWriter();
26707
27132
  const handleRoutingPolicyChange = () => {
26708
27133
  currentRequestRoute();
26709
27134
  };
@@ -26724,7 +27149,16 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26724
27149
  const route = window.__codexhostHostRoutingV1?.forComposer(composer);
26725
27150
  if (!route) return false;
26726
27151
  try {
26727
- if (route.policy.select(carrier ?? null)) {
27152
+ const target = composer ? findComposerModelTarget(composer) : null;
27153
+ if (target?.[0] === "conversation") return true;
27154
+ if (target?.[0] !== "default" || typeof target[1] !== "string" || !composer)
27155
+ return agent === "codex";
27156
+ const binding = findScopedDraftModelBinding(composer, target[1]);
27157
+ const draftKey = target[1];
27158
+ if (!binding || !route.policy.scopedCreation)
27159
+ return agent === "codex" && !draftModels.has(draftKey);
27160
+ draftModels.apply(draftKey, binding, carrier ?? null);
27161
+ if (route.policy.select(carrier ?? null, draftKey, binding.creationModes)) {
26728
27162
  modelUpdates += 1;
26729
27163
  liveStatus.modelUpdates = modelUpdates;
26730
27164
  }
@@ -26742,6 +27176,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26742
27176
  dispose() {
26743
27177
  if (disposed) return;
26744
27178
  disposed = true;
27179
+ draftModels.dispose();
26745
27180
  window.removeEventListener(
26746
27181
  "codexhost:draft-prewarm-policy-changed",
26747
27182
  handleRoutingPolicyChange
@@ -27177,6 +27612,8 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
27177
27612
  cachedInputTokens: 0,
27178
27613
  cacheWriteInputTokens: 0,
27179
27614
  cacheKnownInputTokens: 0,
27615
+ cacheHitCachedInputTokens: 0,
27616
+ cacheHitInputTokens: 0,
27180
27617
  outputTokens: 0,
27181
27618
  reasoningOutputTokens: 0,
27182
27619
  costUsd: 0,
@@ -27190,6 +27627,8 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
27190
27627
  target.cachedInputTokens += source.cachedInputTokens;
27191
27628
  target.cacheWriteInputTokens += source.cacheWriteInputTokens;
27192
27629
  target.cacheKnownInputTokens += source.cacheKnownInputTokens;
27630
+ target.cacheHitCachedInputTokens += source.cacheHitCachedInputTokens;
27631
+ target.cacheHitInputTokens += source.cacheHitInputTokens;
27193
27632
  target.outputTokens += source.outputTokens;
27194
27633
  target.reasoningOutputTokens += source.reasoningOutputTokens;
27195
27634
  target.costUsd += source.costUsd;
@@ -27244,7 +27683,9 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
27244
27683
  };
27245
27684
  }
27246
27685
  function cacheHitRate(totals2) {
27247
- return totals2.cacheKnownInputTokens > 0 ? formatRendererCacheHitRate(totals2.cachedInputTokens / totals2.cacheKnownInputTokens * 100) : "\u2014";
27686
+ return totals2.cacheHitInputTokens > 0 ? formatRendererCacheHitRate(
27687
+ totals2.cacheHitCachedInputTokens / totals2.cacheHitInputTokens * 100
27688
+ ) : "\u2014";
27248
27689
  }
27249
27690
  function formatMeasure(measure, value, locale = "en") {
27250
27691
  return measure === "cost" ? money(value) : count2(value, locale);
@@ -29111,7 +29552,7 @@ ${messages.creditsCoverage}: ${value.reportedRequests} / ${row.requests}` : void
29111
29552
  {
29112
29553
  key: "hit",
29113
29554
  label: messages.cacheHit,
29114
- sort: (row) => row.cacheKnownInputTokens > 0 ? row.cachedInputTokens / row.cacheKnownInputTokens : -1,
29555
+ sort: (row) => row.cacheHitInputTokens > 0 ? row.cacheHitCachedInputTokens / row.cacheHitInputTokens : -1,
29115
29556
  cell: (row) => cacheHitRate(row)
29116
29557
  },
29117
29558
  {
@@ -32331,7 +32772,7 @@ ${detail}` : ""}`
32331
32772
  }
32332
32773
  function defaultImportName(source, existing) {
32333
32774
  const base = source.provider === "openai-codex" ? "codex" : "grok";
32334
- const used = new Set(existing.map((record6) => record6.name));
32775
+ const used = new Set(existing.map((record8) => record8.name));
32335
32776
  const valid = (name) => credentialImportNameSchema.safeParse(name).success;
32336
32777
  if (!used.has(base)) return base;
32337
32778
  const local = source.label.includes("@") ? source.label.split("@")[0] ?? "" : "";
@@ -32354,7 +32795,7 @@ ${detail}` : ""}`
32354
32795
  const shown = (text) => accountDisplayText(text, hideEmails);
32355
32796
  const targetButtons = /* @__PURE__ */ new Map();
32356
32797
  const importedRecords = () => snapshot.targets.find((target) => target.harnessId === TARGET_HARNESS_ID)?.imports ?? [];
32357
- const sourceOf = (record6) => snapshot.sources.find((source) => source.id === record6.source.id);
32798
+ const sourceOf = (record8) => snapshot.sources.find((source) => source.id === record8.source.id);
32358
32799
  const piTarget = () => snapshot.targets.find((candidate) => candidate.harnessId === TARGET_HARNESS_ID);
32359
32800
  const compatibleSources = () => {
32360
32801
  const target = piTarget();
@@ -32392,7 +32833,7 @@ ${detail}` : ""}`
32392
32833
  sectionImport.addEventListener("click", () => {
32393
32834
  const sources = compatibleSources();
32394
32835
  const free = sources.find(
32395
- (source2) => !importedRecords().some((record6) => record6.source.id === source2.id)
32836
+ (source2) => !importedRecords().some((record8) => record8.source.id === source2.id)
32396
32837
  );
32397
32838
  const source = free ?? sources[0];
32398
32839
  if (source) openDialog("add", { source, choose: true }, SECTION_IMPORT_KEY);
@@ -32442,30 +32883,30 @@ ${detail}` : ""}`
32442
32883
  mark.append(createRendererAgentIcon(agent ?? "pi", 26, document2, pluginFor(agent ?? "pi")));
32443
32884
  return mark;
32444
32885
  };
32445
- const renderRow = (record6) => {
32886
+ const renderRow = (record8) => {
32446
32887
  const row = document2.createElement("div");
32447
32888
  row.className = "settings-pi-accounts__row";
32448
32889
  row.tabIndex = -1;
32449
- row.dataset.importName = record6.name;
32450
- row.setAttribute("aria-label", shown(record6.source.label));
32451
- const agent = record6.source.harnessId;
32890
+ row.dataset.importName = record8.name;
32891
+ row.setAttribute("aria-label", shown(record8.source.label));
32892
+ const agent = record8.source.harnessId;
32452
32893
  const mark = createMark(agent);
32453
32894
  const identity = document2.createElement("div");
32454
32895
  identity.className = "settings-pi-accounts__identity";
32455
32896
  const label = document2.createElement("strong");
32456
32897
  label.className = "settings-account-email";
32457
- label.textContent = shown(record6.source.label);
32898
+ label.textContent = shown(record8.source.label);
32458
32899
  label.title = label.textContent;
32459
32900
  label.translate = false;
32460
32901
  const meta3 = document2.createElement("div");
32461
32902
  meta3.className = "settings-account-metadata";
32462
- const source = sourceOf(record6);
32903
+ const source = sourceOf(record8);
32463
32904
  const parts = [
32464
32905
  metaPart(rendererAgentLabel(agent, pluginFor(agent)), "settings-pi-accounts__agent"),
32465
- metaPart(`${record6.name}/\u2026`, void 0, true),
32906
+ metaPart(`${record8.name}/\u2026`, void 0, true),
32466
32907
  metaPart(messages.copied)
32467
32908
  ];
32468
- const time3 = formatImportedAt(record6.importedAt);
32909
+ const time3 = formatImportedAt(record8.importedAt);
32469
32910
  if (time3) parts.push(metaPart(time3));
32470
32911
  parts.forEach((part, index) => {
32471
32912
  if (index > 0) {
@@ -32482,23 +32923,23 @@ ${detail}` : ""}`
32482
32923
  reimport.type = "button";
32483
32924
  reimport.className = "settings-account-action";
32484
32925
  reimport.textContent = messages.rowReimport;
32485
- reimport.setAttribute("aria-label", `${messages.reimport}: ${shown(record6.source.label)}`);
32926
+ reimport.setAttribute("aria-label", `${messages.reimport}: ${shown(record8.source.label)}`);
32486
32927
  reimport.disabled = busy || !source;
32487
32928
  reimport.title = messages.reimport;
32488
32929
  reimport.addEventListener("click", () => {
32489
- if (source) openDialog("reimport", { source, record: record6 }, `row:${record6.name}`);
32930
+ if (source) openDialog("reimport", { source, record: record8 }, `row:${record8.name}`);
32490
32931
  });
32491
32932
  const remove = document2.createElement("button");
32492
32933
  remove.type = "button";
32493
32934
  remove.className = "settings-account-action settings-pi-accounts__remove";
32494
32935
  remove.textContent = messages.rowRemove;
32495
- remove.setAttribute("aria-label", `${messages.remove}: ${shown(record6.source.label)}`);
32936
+ remove.setAttribute("aria-label", `${messages.remove}: ${shown(record8.source.label)}`);
32496
32937
  remove.disabled = busy;
32497
- remove.addEventListener("click", () => openDialog("remove", { record: record6 }, `row:${record6.name}`));
32938
+ remove.addEventListener("click", () => openDialog("remove", { record: record8 }, `row:${record8.name}`));
32498
32939
  if (source) actions.append(reimport);
32499
32940
  actions.append(remove);
32500
32941
  row.append(mark, identity, actions);
32501
- rows.set(record6.name, row);
32942
+ rows.set(record8.name, row);
32502
32943
  return row;
32503
32944
  };
32504
32945
  const loginTypeLabel = (type) => type === "oauth" ? messages.typeOauth : type === "api_key" ? messages.typeApiKey : messages.typeOther;
@@ -32651,7 +33092,7 @@ ${detail}` : ""}`
32651
33092
  const label = document2.createElement("strong");
32652
33093
  label.textContent = shown(choice.label);
32653
33094
  label.translate = false;
32654
- const existing = importedRecords().find((record6) => record6.source.id === choice.id);
33095
+ const existing = importedRecords().find((record8) => record8.source.id === choice.id);
32655
33096
  const agent = choice.harnessId;
32656
33097
  const detail = document2.createElement("span");
32657
33098
  detail.textContent = [
@@ -32692,7 +33133,7 @@ ${detail}` : ""}`
32692
33133
  const name = request.action === "list" ? void 0 : request.name;
32693
33134
  state = {
32694
33135
  source: state.source,
32695
- record: importedRecords().find((record6) => record6.name === name) ?? state.record
33136
+ record: importedRecords().find((record8) => record8.name === name) ?? state.record
32696
33137
  };
32697
33138
  show(next);
32698
33139
  } else {
@@ -32706,12 +33147,12 @@ ${detail}` : ""}`
32706
33147
  sourceRadios = [];
32707
33148
  body.replaceChildren();
32708
33149
  controls.replaceChildren();
32709
- const { source, record: record6 } = state;
33150
+ const { source, record: record8 } = state;
32710
33151
  const close = () => modal.close();
32711
33152
  if (mode === "add" || mode === "reimport") {
32712
33153
  title.textContent = mode === "add" ? messages.add : messages.reimport;
32713
33154
  modal.setAttribute("aria-label", title.textContent);
32714
- const active = source ?? record6?.source;
33155
+ const active = source ?? record8?.source;
32715
33156
  const choices = mode === "add" && state.choose ? compatibleSources() : [];
32716
33157
  if (choices.length > 1) body.append(sourcePicker(choices));
32717
33158
  else if (active) body.append(line(messages.source, shown(active.label)));
@@ -32720,8 +33161,8 @@ ${detail}` : ""}`
32720
33161
  input.maxLength = 48;
32721
33162
  input.autocomplete = "off";
32722
33163
  input.spellcheck = false;
32723
- input.value = record6?.name ?? (source ? defaultImportName(source, importedRecords()) : "codex");
32724
- input.readOnly = Boolean(record6);
33164
+ input.value = record8?.name ?? (source ? defaultImportName(source, importedRecords()) : "codex");
33165
+ input.readOnly = Boolean(record8);
32725
33166
  input.addEventListener("input", () => {
32726
33167
  nameEdited = true;
32727
33168
  });
@@ -32755,7 +33196,7 @@ ${detail}` : ""}`
32755
33196
  {
32756
33197
  action: mode === "reimport" ? "reimport" : "import",
32757
33198
  sourceId: source2.id,
32758
- name: record6?.name ?? input.value,
33199
+ name: record8?.name ?? input.value,
32759
33200
  confirmed: true
32760
33201
  },
32761
33202
  "done"
@@ -32765,16 +33206,16 @@ ${detail}` : ""}`
32765
33206
  )
32766
33207
  );
32767
33208
  (mode === "add" ? input : controls.children[0]).focus();
32768
- } else if (mode === "remove" && record6) {
33209
+ } else if (mode === "remove" && record8) {
32769
33210
  title.textContent = messages.remove;
32770
33211
  modal.setAttribute("aria-label", title.textContent);
32771
- body.append(note(messages.removeWarning.replace("{name}", record6.name)));
33212
+ body.append(note(messages.removeWarning.replace("{name}", record8.name)));
32772
33213
  const cancel = command(messages.cancel, close);
32773
33214
  controls.append(
32774
33215
  cancel,
32775
33216
  command(
32776
33217
  messages.remove,
32777
- () => submit({ action: "remove", name: record6.name, confirmed: true }, null),
33218
+ () => submit({ action: "remove", name: record8.name, confirmed: true }, null),
32778
33219
  "danger"
32779
33220
  )
32780
33221
  );
@@ -32782,7 +33223,7 @@ ${detail}` : ""}`
32782
33223
  } else {
32783
33224
  title.textContent = messages.doneTitle;
32784
33225
  modal.setAttribute("aria-label", title.textContent);
32785
- const name = record6?.name;
33226
+ const name = record8?.name;
32786
33227
  if (name) body.append(line(messages.entry, `${name}/\u2026`, true));
32787
33228
  body.append(note(messages.done));
32788
33229
  const done = command(messages.close, close, "primary");
@@ -32829,21 +33270,21 @@ ${detail}` : ""}`
32829
33270
  (candidate) => candidate.harnessId === TARGET_HARNESS_ID && source && candidate.providers.includes(source.provider)
32830
33271
  );
32831
33272
  if (!source || !target) return null;
32832
- const record6 = target.imports.find((candidate) => candidate.source.id === source.id);
33273
+ const record8 = target.imports.find((candidate) => candidate.source.id === source.id);
32833
33274
  const key = `${harnessId}:${accountLabel}:import`;
32834
33275
  const button2 = document2.createElement("button");
32835
33276
  button2.type = "button";
32836
33277
  button2.className = "settings-account-pi-import";
32837
33278
  button2.dataset.accountFocus = key;
32838
33279
  button2.disabled = busy;
32839
- const hint = record6 ? messages.importedHint.replace("{name}", record6.name) : messages.add;
33280
+ const hint = record8 ? messages.importedHint.replace("{name}", record8.name) : messages.add;
32840
33281
  button2.title = hint;
32841
33282
  button2.setAttribute("aria-label", hint);
32842
33283
  button2.append(createRendererAgentIcon("pi", 12, document2, pluginFor("pi")));
32843
- if (record6) {
33284
+ if (record8) {
32844
33285
  button2.dataset.state = "imported";
32845
33286
  const name = document2.createElement("code");
32846
- name.textContent = `${record6.name}/\u2026`;
33287
+ name.textContent = `${record8.name}/\u2026`;
32847
33288
  name.translate = false;
32848
33289
  button2.append(name, createRendererSettingsIcon("check", 12));
32849
33290
  } else {
@@ -32851,7 +33292,7 @@ ${detail}` : ""}`
32851
33292
  button2.append(messages.add);
32852
33293
  }
32853
33294
  button2.addEventListener("click", () => {
32854
- if (!record6) {
33295
+ if (!record8) {
32855
33296
  openDialog("add", { source }, key);
32856
33297
  return;
32857
33298
  }
@@ -32860,7 +33301,7 @@ ${detail}` : ""}`
32860
33301
  renderSection();
32861
33302
  sectionToggle.setAttribute("aria-expanded", "true");
32862
33303
  }
32863
- const row = rows.get(record6.name);
33304
+ const row = rows.get(record8.name);
32864
33305
  row?.scrollIntoView({ block: "nearest", behavior: "smooth" });
32865
33306
  row?.focus();
32866
33307
  });
@@ -33855,6 +34296,43 @@ ${detail}` : ""}`
33855
34296
  });
33856
34297
  }
33857
34298
 
34299
+ // src/settings/harness-schedules-page.ts
34300
+ function createHarnessSchedulesPage(messages, options) {
34301
+ const t = (zh, en) => messages.locale === "zh-CN" ? zh : en;
34302
+ return {
34303
+ id: "harness-schedules",
34304
+ label: t("\u5B9A\u65F6\u4EFB\u52A1", "Schedules"),
34305
+ icon: "schedules",
34306
+ mount(context) {
34307
+ const navigate = () => {
34308
+ context.content.replaceChildren();
34309
+ void context.runLatest((signal) => options.openSchedules(signal), {
34310
+ success() {
34311
+ },
34312
+ failure() {
34313
+ const document2 = context.content.ownerDocument;
34314
+ const status = document2.createElement("p");
34315
+ status.setAttribute("role", "status");
34316
+ status.className = "text-sm text-settings-muted";
34317
+ status.textContent = t(
34318
+ "\u65E0\u6CD5\u6253\u5F00\u5B98\u65B9\u5B9A\u65F6\u4EFB\u52A1\u9875\uFF0C\u8BF7\u91CD\u8BD5\u6216\u4ECE\u5B98\u65B9\u4FA7\u680F\u8FDB\u5165\u3002",
34319
+ "Could not open the official schedules page. Retry or use the Desktop sidebar."
34320
+ );
34321
+ const retry = document2.createElement("button");
34322
+ retry.type = "button";
34323
+ retry.className = "rounded-lg px-3 py-2 text-sm text-settings-text hover:bg-settings-hover focus-visible:outline-2 focus-visible:outline-settings-focus";
34324
+ retry.textContent = t("\u91CD\u8BD5", "Retry");
34325
+ retry.addEventListener("click", navigate);
34326
+ context.content.replaceChildren(status, retry);
34327
+ }
34328
+ });
34329
+ };
34330
+ navigate();
34331
+ return void 0;
34332
+ }
34333
+ };
34334
+ }
34335
+
33858
34336
  // src/settings/update-request.ts
33859
34337
  var RENDERER_UPDATE_REQUEST_TIMEOUT_MS = 15e3;
33860
34338
  var RendererUpdateRequestTimeoutError = class extends Error {
@@ -34182,8 +34660,8 @@ ${detail}` : ""}`
34182
34660
  const starBanner = updateStarBanner(document2, messages);
34183
34661
  context.content.append(heading, metadata, panel, controls, starBanner, notes);
34184
34662
  const setManualFallback = (fallback) => {
34185
- controls.className = !fallback && !windows ? "settings-update-controls is-quiet" : "settings-update-controls";
34186
- manualNpmDescription.textContent = windows ? messages.updateWindowsNpmDescription : fallback ? messages.updateManualFallbackDescription : messages.updateManualNpmDescription;
34663
+ controls.className = fallback ? "settings-update-controls" : "settings-update-controls is-quiet";
34664
+ manualNpmDescription.textContent = fallback ? messages.updateManualFallbackDescription : messages.updateManualNpmDescription;
34187
34665
  manualNpmDescription.className = fallback ? "settings-update-manual-description is-fallback" : "settings-update-manual-description";
34188
34666
  };
34189
34667
  let pollTimer;
@@ -34333,14 +34811,14 @@ ${detail}` : ""}`
34333
34811
  panel.dataset.updateState = view;
34334
34812
  panel.replaceChildren();
34335
34813
  setManualFallback(Boolean(result.error) || actionableStatus !== null);
34336
- const inlineUpdate = !result.error && !windows && !actionableStatus && result.updateAvailable;
34814
+ const inlineUpdate = !result.error && !actionableStatus && result.updateAvailable;
34337
34815
  if (inlineUpdate) panel.dataset.inline = "";
34338
34816
  else delete panel.dataset.inline;
34339
34817
  panel.append(
34340
34818
  createPanelHead(
34341
34819
  document2,
34342
34820
  view,
34343
- actionableStatus ? statusMessage(actionableStatus, messages) ?? messages.updateFailed : result.error ? messages.updateFailed : result.updateAvailable ? windows ? messages.updateWindowsManualRequired : messages.updateAvailable : messages.updateUpToDate
34821
+ actionableStatus ? statusMessage(actionableStatus, messages) ?? messages.updateFailed : result.error ? messages.updateFailed : result.updateAvailable ? messages.updateAvailable : messages.updateUpToDate
34344
34822
  )
34345
34823
  );
34346
34824
  if (actionableStatus?.error) {
@@ -34356,7 +34834,7 @@ ${detail}` : ""}`
34356
34834
  panel.append(error51);
34357
34835
  }
34358
34836
  const buttons = [];
34359
- if (!windows && result.updateAvailable && result.installationAvailable) {
34837
+ if (result.updateAvailable && result.installationAvailable) {
34360
34838
  const update = document2.createElement("button");
34361
34839
  update.type = "button";
34362
34840
  update.className = "settings-command-button";
@@ -34405,11 +34883,12 @@ ${detail}` : ""}`
34405
34883
  }
34406
34884
  });
34407
34885
  }
34408
- function createDefaultRendererSettingsPages(messages = DEFAULT_RENDERER_SETTINGS_MESSAGES, getUpdateClient = () => null, getDiagnostics = () => null, getAccountClient = () => null, getSessionImportClient = () => null, openImportedThread = () => Promise.reject(new Error("Imported Thread navigation is unavailable")), getLoadedSessionsClient = () => null, getRemoteConnections = () => null, requestUsageStatistics = () => Promise.reject(new Error("Local Host connection is unavailable")), usageStatisticsHosts) {
34886
+ function createDefaultRendererSettingsPages(messages = DEFAULT_RENDERER_SETTINGS_MESSAGES, getUpdateClient = () => null, getDiagnostics = () => null, getAccountClient = () => null, getSessionImportClient = () => null, openImportedThread = () => Promise.reject(new Error("Imported Thread navigation is unavailable")), getLoadedSessionsClient = () => null, getRemoteConnections = () => null, requestUsageStatistics = () => Promise.reject(new Error("Local Host connection is unavailable")), usageStatisticsHosts, harnessSchedules) {
34409
34887
  return Object.freeze([
34410
34888
  createConnectionsSettingsPage(messages, getDiagnostics, void 0, getRemoteConnections),
34411
34889
  createRemoteConnectionsPage(messages, getRemoteConnections),
34412
34890
  createAccountsSettingsPage(messages, getAccountClient),
34891
+ ...harnessSchedules ? [createHarnessSchedulesPage(messages, harnessSchedules)] : [],
34413
34892
  createSessionImportSettingsPage(
34414
34893
  messages,
34415
34894
  getSessionImportClient,
@@ -39110,7 +39589,7 @@ th[aria-sort] .console-usage-sort__mark {
39110
39589
  `;
39111
39590
 
39112
39591
  // src/settings/tailwind.css
39113
- var tailwind_default = '@layer properties, theme, base, components, utilities;\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-content:"";--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0}}}@layer theme{:root,:host{--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.025em;--leading-relaxed:1.625;--radius-md:.375rem;--radius-lg:.5rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1)}}@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.top-full{top:100%}.left-0{left:0}.z-20{z-index:20}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.m-0{margin:0}.mx-2{margin-inline:calc(var(--spacing) * 2)}.mt-1{margin-top:var(--spacing)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-5{margin-top:calc(var(--spacing) * 5)}.mt-7{margin-top:calc(var(--spacing) * 7)}.mt-8{margin-top:calc(var(--spacing) * 8)}.mt-16{margin-top:calc(var(--spacing) * 16)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.ml-1{margin-left:var(--spacing)}.ml-\\[45px\\]{margin-left:45px}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.list-item{display:list-item}.table{display:table}.size-1\\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-8{height:calc(var(--spacing) * 8)}.min-h-6{min-height:calc(var(--spacing) * 6)}.min-h-\\[60px\\]{min-height:60px}.w-9{width:calc(var(--spacing) * 9)}.w-14{width:calc(var(--spacing) * 14)}.w-80{width:calc(var(--spacing) * 80)}.w-full{width:100%}.w-px{width:1px}.max-w-64{max-width:calc(var(--spacing) * 64)}.min-w-0{min-width:0}.flex-shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.cursor-help{cursor:help}.cursor-pointer{cursor:pointer}.resize{resize:both}.list-disc{list-style-type:disc}.appearance-none{appearance:none}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-0\\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}.overflow-x-auto{overflow-x:auto}.rounded-\\[10px\\]{border-radius:10px}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-settings-border{border-color:var(--settings-border)}.border-settings-divider{border-color:var(--settings-divider)}.bg-settings-panel{background-color:var(--settings-panel)}.bg-settings-subtle{background-color:var(--settings-subtle)}.bg-settings-surface{background-color:var(--settings-surface)}.bg-settings-surface-hover{background-color:var(--settings-surface-hover)}.bg-transparent{background-color:#0000}.p-0{padding:0}.p-4{padding:calc(var(--spacing) * 4)}.\\!px-0{padding-inline:0!important}.px-1{padding-inline:var(--spacing)}.px-2\\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pl-4{padding-left:calc(var(--spacing) * 4)}.\\!text-right{text-align:right!important}.text-left{text-align:left}.text-right{text-align:right}.align-top{vertical-align:top}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\\[11px\\]{font-size:11px}.text-\\[13px\\]{font-size:13px}.leading-5{--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5)}.leading-7{--tw-leading:calc(var(--spacing) * 7);line-height:calc(var(--spacing) * 7)}.leading-\\[18px\\]{--tw-leading:18px;line-height:18px}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.text-wrap{text-wrap:wrap}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-pre-wrap{white-space:pre-wrap}.text-settings-muted{color:var(--settings-muted)}.text-settings-subtle{color:var(--settings-subtle)}.text-settings-text{color:var(--settings-text)}.lowercase{text-transform:lowercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.opacity-0{opacity:0}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\\[0_10px_30px_rgb\\(0_0_0\\/0\\.22\\)\\]{--tw-shadow:0 10px 30px var(--tw-shadow-color,#00000038);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring,.ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-settings-border{--tw-ring-color:var(--settings-border)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-filter{-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.outline-none{--tw-outline-style:none;outline-style:none}.ring-inset{--tw-ring-inset:inset}.group-focus-within\\:visible:is(:where(.group):focus-within *){visibility:visible}.group-focus-within\\:opacity-100:is(:where(.group):focus-within *){opacity:1}@media (hover:hover){.group-hover\\:visible:is(:where(.group):hover *){visibility:visible}.group-hover\\:opacity-100:is(:where(.group):hover *){opacity:1}}.group-data-\\[state\\=failed\\]\\/status\\:bg-settings-danger:is(:where(.group\\/status)[data-state=failed] *){background-color:var(--settings-danger)}.group-data-\\[state\\=unavailable\\]\\/status\\:bg-settings-warning:is(:where(.group\\/status)[data-state=unavailable] *){background-color:var(--settings-warning)}.marker\\:text-settings-subtle ::marker{color:var(--settings-subtle)}.marker\\:text-settings-subtle::marker{color:var(--settings-subtle)}.marker\\:text-settings-subtle ::-webkit-details-marker{color:var(--settings-subtle)}.marker\\:text-settings-subtle::-webkit-details-marker{color:var(--settings-subtle)}.before\\:absolute:before{content:var(--tw-content);position:absolute}.before\\:top-0\\.5:before{content:var(--tw-content);top:calc(var(--spacing) * .5)}.before\\:left-0\\.5:before{content:var(--tw-content);left:calc(var(--spacing) * .5)}.before\\:size-4:before{content:var(--tw-content);width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.before\\:rounded-full:before{content:var(--tw-content);border-radius:3.40282e38px}.before\\:bg-white:before{content:var(--tw-content);background-color:#fff}.before\\:shadow-\\[0_1px_2px_rgb\\(0_0_0\\/0\\.3\\)\\]:before{content:var(--tw-content);--tw-shadow:0 1px 2px var(--tw-shadow-color,#0000004d);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.before\\:transition-transform:before{content:var(--tw-content);transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.first\\:border-t-0:first-child{border-top-style:var(--tw-border-style);border-top-width:0}.first-of-type\\:mt-0:first-of-type{margin-top:0}.checked\\:bg-settings-focus:checked{background-color:var(--settings-focus)}.checked\\:ring-transparent:checked{--tw-ring-color:transparent}.checked\\:before\\:translate-x-4:checked:before{content:var(--tw-content);--tw-translate-x:calc(var(--spacing) * 4);translate:var(--tw-translate-x) var(--tw-translate-y)}.focus-within\\:border-settings-focus:focus-within{border-color:var(--settings-focus)}@media (hover:hover){.hover\\:text-settings-text:hover{color:var(--settings-text)}}.focus-visible\\:text-settings-text:focus-visible{color:var(--settings-text)}.focus-visible\\:outline-2:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px}.focus-visible\\:outline-offset-2:focus-visible{outline-offset:2px}.focus-visible\\:outline-settings-focus:focus-visible{outline-color:var(--settings-focus)}.data-\\[invalid\\=true\\]\\:border-settings-danger[data-invalid=true]{border-color:var(--settings-danger)}.data-\\[invalid\\=true\\]\\:text-settings-danger[data-invalid=true],.data-\\[state\\=failed\\]\\:text-settings-danger[data-state=failed]{color:var(--settings-danger)}.data-\\[state\\=unavailable\\]\\:text-settings-warning[data-state=unavailable]{color:var(--settings-warning)}}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@layer properties{\n *, ::before, ::after, ::backdrop{--tw-border-style:solid;--tw-shadow:0 0 #0000;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-alpha:100%;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-offset-width:0;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-drop-shadow-alpha:100%;--tw-content:"";--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0}}\n';
39592
+ var tailwind_default = '@layer properties, theme, base, components, utilities;\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-content:"";--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0}}}@layer theme{:root,:host{--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.025em;--leading-relaxed:1.625;--radius-md:.375rem;--radius-lg:.5rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1)}}@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.top-full{top:100%}.left-0{left:0}.z-20{z-index:20}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.m-0{margin:0}.mx-2{margin-inline:calc(var(--spacing) * 2)}.mt-1{margin-top:var(--spacing)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-5{margin-top:calc(var(--spacing) * 5)}.mt-7{margin-top:calc(var(--spacing) * 7)}.mt-8{margin-top:calc(var(--spacing) * 8)}.mt-16{margin-top:calc(var(--spacing) * 16)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.ml-1{margin-left:var(--spacing)}.ml-\\[45px\\]{margin-left:45px}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.list-item{display:list-item}.table{display:table}.size-1\\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-8{height:calc(var(--spacing) * 8)}.min-h-6{min-height:calc(var(--spacing) * 6)}.min-h-\\[60px\\]{min-height:60px}.w-9{width:calc(var(--spacing) * 9)}.w-14{width:calc(var(--spacing) * 14)}.w-80{width:calc(var(--spacing) * 80)}.w-full{width:100%}.w-px{width:1px}.max-w-64{max-width:calc(var(--spacing) * 64)}.min-w-0{min-width:0}.flex-shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.cursor-help{cursor:help}.cursor-pointer{cursor:pointer}.resize{resize:both}.list-disc{list-style-type:disc}.appearance-none{appearance:none}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-0\\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}.overflow-x-auto{overflow-x:auto}.rounded-\\[10px\\]{border-radius:10px}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-settings-border{border-color:var(--settings-border)}.border-settings-divider{border-color:var(--settings-divider)}.bg-settings-panel{background-color:var(--settings-panel)}.bg-settings-subtle{background-color:var(--settings-subtle)}.bg-settings-surface{background-color:var(--settings-surface)}.bg-settings-surface-hover{background-color:var(--settings-surface-hover)}.bg-transparent{background-color:#0000}.p-0{padding:0}.p-4{padding:calc(var(--spacing) * 4)}.\\!px-0{padding-inline:0!important}.px-1{padding-inline:var(--spacing)}.px-2\\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pl-4{padding-left:calc(var(--spacing) * 4)}.\\!text-right{text-align:right!important}.text-left{text-align:left}.text-right{text-align:right}.align-top{vertical-align:top}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\\[11px\\]{font-size:11px}.text-\\[13px\\]{font-size:13px}.leading-5{--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5)}.leading-7{--tw-leading:calc(var(--spacing) * 7);line-height:calc(var(--spacing) * 7)}.leading-\\[18px\\]{--tw-leading:18px;line-height:18px}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.text-wrap{text-wrap:wrap}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-pre-wrap{white-space:pre-wrap}.text-settings-muted{color:var(--settings-muted)}.text-settings-subtle{color:var(--settings-subtle)}.text-settings-text{color:var(--settings-text)}.lowercase{text-transform:lowercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.opacity-0{opacity:0}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\\[0_10px_30px_rgb\\(0_0_0\\/0\\.22\\)\\]{--tw-shadow:0 10px 30px var(--tw-shadow-color,#00000038);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring,.ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-settings-border{--tw-ring-color:var(--settings-border)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-filter{-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.outline-none{--tw-outline-style:none;outline-style:none}.ring-inset{--tw-ring-inset:inset}.group-focus-within\\:visible:is(:where(.group):focus-within *){visibility:visible}.group-focus-within\\:opacity-100:is(:where(.group):focus-within *){opacity:1}@media (hover:hover){.group-hover\\:visible:is(:where(.group):hover *){visibility:visible}.group-hover\\:opacity-100:is(:where(.group):hover *){opacity:1}}.group-data-\\[state\\=failed\\]\\/status\\:bg-settings-danger:is(:where(.group\\/status)[data-state=failed] *){background-color:var(--settings-danger)}.group-data-\\[state\\=unavailable\\]\\/status\\:bg-settings-warning:is(:where(.group\\/status)[data-state=unavailable] *){background-color:var(--settings-warning)}.marker\\:text-settings-subtle ::marker{color:var(--settings-subtle)}.marker\\:text-settings-subtle::marker{color:var(--settings-subtle)}.marker\\:text-settings-subtle ::-webkit-details-marker{color:var(--settings-subtle)}.marker\\:text-settings-subtle::-webkit-details-marker{color:var(--settings-subtle)}.before\\:absolute:before{content:var(--tw-content);position:absolute}.before\\:top-0\\.5:before{content:var(--tw-content);top:calc(var(--spacing) * .5)}.before\\:left-0\\.5:before{content:var(--tw-content);left:calc(var(--spacing) * .5)}.before\\:size-4:before{content:var(--tw-content);width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.before\\:rounded-full:before{content:var(--tw-content);border-radius:3.40282e38px}.before\\:bg-white:before{content:var(--tw-content);background-color:#fff}.before\\:shadow-\\[0_1px_2px_rgb\\(0_0_0\\/0\\.3\\)\\]:before{content:var(--tw-content);--tw-shadow:0 1px 2px var(--tw-shadow-color,#0000004d);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.before\\:transition-transform:before{content:var(--tw-content);transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.first\\:border-t-0:first-child{border-top-style:var(--tw-border-style);border-top-width:0}.first-of-type\\:mt-0:first-of-type{margin-top:0}.checked\\:bg-settings-focus:checked{background-color:var(--settings-focus)}.checked\\:ring-transparent:checked{--tw-ring-color:transparent}.checked\\:before\\:translate-x-4:checked:before{content:var(--tw-content);--tw-translate-x:calc(var(--spacing) * 4);translate:var(--tw-translate-x) var(--tw-translate-y)}.focus-within\\:border-settings-focus:focus-within{border-color:var(--settings-focus)}@media (hover:hover){.hover\\:bg-settings-hover:hover{background-color:var(--settings-hover)}.hover\\:text-settings-text:hover{color:var(--settings-text)}}.focus-visible\\:text-settings-text:focus-visible{color:var(--settings-text)}.focus-visible\\:outline-2:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px}.focus-visible\\:outline-offset-2:focus-visible{outline-offset:2px}.focus-visible\\:outline-settings-focus:focus-visible{outline-color:var(--settings-focus)}.data-\\[invalid\\=true\\]\\:border-settings-danger[data-invalid=true]{border-color:var(--settings-danger)}.data-\\[invalid\\=true\\]\\:text-settings-danger[data-invalid=true],.data-\\[state\\=failed\\]\\:text-settings-danger[data-state=failed]{color:var(--settings-danger)}.data-\\[state\\=unavailable\\]\\:text-settings-warning[data-state=unavailable]{color:var(--settings-warning)}}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@layer properties{\n *, ::before, ::after, ::backdrop{--tw-border-style:solid;--tw-shadow:0 0 #0000;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-alpha:100%;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-offset-width:0;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-drop-shadow-alpha:100%;--tw-content:"";--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0}}\n';
39114
39593
 
39115
39594
  // src/settings/trigger.ts
39116
39595
  var SETTINGS_TRIGGER_ATTRIBUTE = "data-codexhost-settings-trigger";
@@ -39677,6 +40156,7 @@ ${usage_default}`;
39677
40156
  let disposed = false;
39678
40157
  const mount = () => {
39679
40158
  const messages = rendererSettingsMessages(locale);
40159
+ const schedules = options.harnessSchedules;
39680
40160
  const definitions = createDefaultRendererSettingsPages(
39681
40161
  messages,
39682
40162
  options.getUpdateClient ?? (() => null),
@@ -39693,7 +40173,13 @@ ${usage_default}`;
39693
40173
  options.getLoadedSessionsClient ?? (() => null),
39694
40174
  options.getRemoteConnections ?? (() => null),
39695
40175
  options.requestUsageStatistics,
39696
- options.usageStatisticsHosts
40176
+ options.usageStatisticsHosts,
40177
+ schedules ? {
40178
+ openSchedules: async (signal) => {
40179
+ await schedules.openSchedules(signal);
40180
+ if (!disposed && !signal.aborted) shell?.close();
40181
+ }
40182
+ } : void 0
39697
40183
  );
39698
40184
  const nextShell = installRendererSettingsShell(definitions, messages, ownerWindow.document, {
39699
40185
  onOpenChange(open) {
@@ -40427,6 +40913,803 @@ ${usage_default}`;
40427
40913
  return event.defaultPrevented;
40428
40914
  }
40429
40915
 
40916
+ // src/codex-schedule-navigation.ts
40917
+ function isNavigationBus(value) {
40918
+ if (typeof value !== "object" || value === null) return false;
40919
+ const bus = value;
40920
+ return bus.handlers instanceof Map && bus.handlers.has("navigate-to-route") && typeof bus.dispatchHostMessage === "function";
40921
+ }
40922
+ function hasArrived(ownerWindow) {
40923
+ const paths = ["/automations", "/scheduled"];
40924
+ const pages = ownerWindow.document.querySelectorAll('[data-app-shell-active-page="true"]');
40925
+ if (pages.length > 0) {
40926
+ const page = pages[0];
40927
+ if (pages.length !== 1 || !page) return false;
40928
+ const fiberKey = Object.keys(page).find((key) => key.startsWith("__reactFiber$"));
40929
+ if (!fiberKey) return false;
40930
+ for (const ancestor of committedReactAncestors(Reflect.get(page, fiberKey))) {
40931
+ const props = ancestor.memoizedProps;
40932
+ const value = props?.value;
40933
+ if (value?.navigationType === "POP" || value?.navigationType === "PUSH" || value?.navigationType === "REPLACE") {
40934
+ return typeof value.location?.pathname === "string" && paths.includes(value.location.pathname);
40935
+ }
40936
+ }
40937
+ return false;
40938
+ }
40939
+ return paths.includes(ownerWindow.location.pathname);
40940
+ }
40941
+ async function openCodexSchedules(signal, ownerWindow = window) {
40942
+ signal.throwIfAborted();
40943
+ const bus = await loadCodexNativeServices(ownerWindow, isNavigationBus);
40944
+ signal.throwIfAborted();
40945
+ if (!bus) throw new Error("Codex navigation is unavailable");
40946
+ await new Promise((resolve, reject) => {
40947
+ let settled = false;
40948
+ const finish = (error51) => {
40949
+ if (settled) return;
40950
+ settled = true;
40951
+ ownerWindow.clearInterval(poll);
40952
+ ownerWindow.clearTimeout(timeout);
40953
+ signal.removeEventListener("abort", onAbort);
40954
+ if (error51) reject(error51);
40955
+ else resolve();
40956
+ };
40957
+ const arrived = () => hasArrived(ownerWindow);
40958
+ const onAbort = () => finish(arrived() ? void 0 : signal.reason);
40959
+ const poll = ownerWindow.setInterval(() => {
40960
+ if (arrived()) finish();
40961
+ }, 25);
40962
+ const timeout = ownerWindow.setTimeout(
40963
+ () => finish(new Error("Codex did not open the requested page")),
40964
+ 5e3
40965
+ );
40966
+ signal.addEventListener("abort", onAbort, { once: true });
40967
+ try {
40968
+ bus.dispatchHostMessage({ type: "navigate-to-route", path: "/automations" });
40969
+ if (arrived()) finish();
40970
+ } catch (error51) {
40971
+ finish(error51);
40972
+ }
40973
+ });
40974
+ }
40975
+
40976
+ // src/renderer-native-schedule-picker.ts
40977
+ var schedulePickerStyles = `
40978
+ .picker { position:relative; display:flex; justify-content:flex-end; min-width:0; max-width:100%; }
40979
+ .trigger { display:flex; align-items:center; gap:8px; min-width:0; max-width:100%; height:32px; padding:0 8px 0 10px; border:0; border-radius:10px; color:var(--muted); background:transparent; font:inherit; text-align:right; cursor:pointer; transition:background-color .12s, color .12s; }
40980
+ .trigger:hover:not(:disabled), .trigger[aria-expanded="true"] { color:var(--text); background:var(--hover); }
40981
+ .trigger:focus-visible { outline:2px solid var(--focus); outline-offset:1px; }
40982
+ .trigger:disabled { cursor:default; }
40983
+ .trigger > svg, .trigger > img, .trigger > span.icon, .item > svg, .item > img, .item > span.icon { flex:none; }
40984
+ .label { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
40985
+ .trigger[data-stale] .label { opacity:.6; }
40986
+ .trigger[data-shimmer] .label { background:linear-gradient(90deg,var(--muted) 0%,var(--muted) 35%,color-mix(in srgb,var(--muted) 30%,transparent) 50%,var(--muted) 65%,var(--muted) 100%) 100% 0/250% 100%; -webkit-background-clip:text; background-clip:text; color:transparent; animation:shimmer 1.4s ease-in-out infinite; }
40987
+ .chevron { flex:none; width:6px; height:6px; margin:0 3px 2px 2px; border-right:1.5px solid; border-bottom:1.5px solid; transform:rotate(45deg); transition:transform .12s; }
40988
+ .trigger[aria-expanded="true"] .chevron { transform:translateY(2px) rotate(225deg); }
40989
+ .trigger[aria-busy="true"] .chevron { display:none; }
40990
+ .spinner { flex:none; width:12px; height:12px; margin:0 1px; border:1.5px solid color-mix(in srgb,currentColor 25%,transparent); border-top-color:currentColor; border-radius:50%; animation:spin .8s linear infinite; }
40991
+ .menu { position:fixed; inset:auto; margin:0; padding:4px; min-width:200px; max-width:calc(100vw - 16px); overflow:auto; overscroll-behavior:contain; border:1px solid var(--border); border-radius:12px; color:var(--text); background:var(--surface); box-shadow:0 8px 28px rgba(0,0,0,.22),0 1px 3px rgba(0,0,0,.12); font:inherit; }
40992
+ .menu:not(:popover-open):not([data-open]) { display:none; }
40993
+ .item { display:flex; align-items:center; gap:10px; min-height:36px; padding:6px 8px; border-radius:8px; cursor:pointer; outline:none; }
40994
+ .item:hover:not([aria-disabled="true"]), .item:focus-visible { background:var(--hover); }
40995
+ .item:focus-visible { box-shadow:inset 0 0 0 2px var(--focus); }
40996
+ .item[aria-disabled="true"] { opacity:.45; cursor:default; }
40997
+ .item .label { flex:1; }
40998
+ .check { flex:none; width:5px; height:9px; margin:0 6px 2px 4px; border-right:1.5px solid; border-bottom:1.5px solid; transform:rotate(45deg); visibility:hidden; }
40999
+ .item[aria-selected="true"] .check { visibility:visible; }
41000
+ @keyframes shimmer { to { background-position:-100% 0; } }
41001
+ @keyframes spin { to { transform:rotate(360deg); } }
41002
+ @media(prefers-reduced-motion:reduce) { .spinner, .trigger[data-shimmer] .label { animation:none; } .trigger, .chevron { transition:none; } }
41003
+ `;
41004
+ function createSchedulePicker(document2, options) {
41005
+ const view = document2.defaultView ?? window;
41006
+ const root = document2.createElement("div");
41007
+ root.className = "picker";
41008
+ const trigger = document2.createElement("button");
41009
+ trigger.type = "button";
41010
+ trigger.className = "trigger";
41011
+ trigger.setAttribute("aria-label", options.label);
41012
+ trigger.setAttribute("aria-haspopup", "listbox");
41013
+ trigger.setAttribute("aria-expanded", "false");
41014
+ const menu = document2.createElement("div");
41015
+ menu.className = "menu";
41016
+ menu.setAttribute("role", "listbox");
41017
+ menu.setAttribute("aria-label", options.listLabel);
41018
+ const supportsPopover = typeof menu.showPopover === "function";
41019
+ if (supportsPopover) menu.setAttribute("popover", "manual");
41020
+ root.append(trigger, menu);
41021
+ let items = [];
41022
+ let stale = null;
41023
+ let value = "";
41024
+ let disabled = false;
41025
+ let busy = false;
41026
+ let placeholder = "";
41027
+ let shimmer = false;
41028
+ let isOpen = false;
41029
+ let isDisabled = () => false;
41030
+ const optionElements = /* @__PURE__ */ new Map();
41031
+ const selectedItem = () => items.find((item) => item.value === value) ?? stale;
41032
+ const cloneIcon = (item) => item.icon?.cloneNode(true) ?? null;
41033
+ const renderTrigger = () => {
41034
+ const item = selectedItem();
41035
+ const label = document2.createElement("span");
41036
+ label.className = "label";
41037
+ label.textContent = item?.label ?? placeholder;
41038
+ const icon2 = item ? cloneIcon(item) : null;
41039
+ const tail = document2.createElement("span");
41040
+ tail.className = busy ? "spinner" : "chevron";
41041
+ tail.setAttribute("aria-hidden", "true");
41042
+ trigger.replaceChildren(...icon2 ? [icon2] : [], label, tail);
41043
+ trigger.toggleAttribute("data-stale", Boolean(item && !items.includes(item)));
41044
+ trigger.toggleAttribute("data-shimmer", shimmer && !item);
41045
+ trigger.dataset.value = item ? value : "";
41046
+ trigger.setAttribute("aria-busy", String(busy));
41047
+ trigger.disabled = disabled;
41048
+ if (disabled && isOpen) close();
41049
+ };
41050
+ const renderItems = () => {
41051
+ optionElements.clear();
41052
+ const elements = items.map((item) => {
41053
+ const option = document2.createElement("div");
41054
+ option.className = "item";
41055
+ option.setAttribute("role", "option");
41056
+ option.tabIndex = -1;
41057
+ option.dataset.value = item.value;
41058
+ option.setAttribute("aria-selected", String(item.value === value));
41059
+ if (item.disabled || isDisabled(item.value)) option.setAttribute("aria-disabled", "true");
41060
+ const icon2 = cloneIcon(item);
41061
+ const label = document2.createElement("span");
41062
+ label.className = "label";
41063
+ label.textContent = item.label;
41064
+ const check2 = document2.createElement("span");
41065
+ check2.className = "check";
41066
+ check2.setAttribute("aria-hidden", "true");
41067
+ option.append(...icon2 ? [icon2] : [], label, check2);
41068
+ optionElements.set(item.value, option);
41069
+ return option;
41070
+ });
41071
+ menu.replaceChildren(...elements);
41072
+ };
41073
+ const enabledOptions = () => [...optionElements.values()].filter((el) => el.getAttribute("aria-disabled") !== "true");
41074
+ const focusOption = (el) => {
41075
+ el?.focus();
41076
+ el?.scrollIntoView({ block: "nearest" });
41077
+ };
41078
+ const position = () => {
41079
+ const rect = trigger.getBoundingClientRect();
41080
+ const margin = 8;
41081
+ menu.style.minWidth = `${Math.max(200, Math.min(rect.width, view.innerWidth - 2 * margin))}px`;
41082
+ menu.style.maxHeight = "";
41083
+ const height = menu.offsetHeight;
41084
+ const below = view.innerHeight - rect.bottom - margin - 4;
41085
+ const above = rect.top - margin - 4;
41086
+ const placeBelow = height <= below || below >= above;
41087
+ const room = Math.max(120, placeBelow ? below : above);
41088
+ menu.style.maxHeight = `${room}px`;
41089
+ const used = Math.min(height, room);
41090
+ menu.style.top = `${placeBelow ? rect.bottom + 4 : rect.top - 4 - used}px`;
41091
+ const width = menu.offsetWidth;
41092
+ const left = Math.min(Math.max(margin, rect.right - width), view.innerWidth - width - margin);
41093
+ menu.style.left = `${Math.max(margin, left)}px`;
41094
+ };
41095
+ const onWindowKey = (event) => {
41096
+ if (event.key !== "Escape") return;
41097
+ event.preventDefault();
41098
+ event.stopImmediatePropagation();
41099
+ close();
41100
+ trigger.focus();
41101
+ };
41102
+ const onOutside = (event) => {
41103
+ if (!event.composedPath().includes(root)) close();
41104
+ };
41105
+ const onDismiss = () => close();
41106
+ function open() {
41107
+ if (isOpen || disabled) return;
41108
+ options.onOpen?.();
41109
+ if (!items.length) return;
41110
+ isOpen = true;
41111
+ trigger.setAttribute("aria-expanded", "true");
41112
+ if (supportsPopover) menu.showPopover();
41113
+ else menu.setAttribute("data-open", "");
41114
+ position();
41115
+ focusOption(optionElements.get(value) ?? enabledOptions()[0]);
41116
+ view.addEventListener("keydown", onWindowKey, true);
41117
+ document2.addEventListener("pointerdown", onOutside, true);
41118
+ view.addEventListener("resize", onDismiss);
41119
+ view.addEventListener("blur", onDismiss);
41120
+ document2.addEventListener("scroll", onDismiss, true);
41121
+ }
41122
+ function close() {
41123
+ if (!isOpen) return;
41124
+ isOpen = false;
41125
+ trigger.setAttribute("aria-expanded", "false");
41126
+ if (supportsPopover && menu.matches(":popover-open")) menu.hidePopover();
41127
+ menu.removeAttribute("data-open");
41128
+ view.removeEventListener("keydown", onWindowKey, true);
41129
+ document2.removeEventListener("pointerdown", onOutside, true);
41130
+ view.removeEventListener("resize", onDismiss);
41131
+ view.removeEventListener("blur", onDismiss);
41132
+ document2.removeEventListener("scroll", onDismiss, true);
41133
+ }
41134
+ const choose = (el) => {
41135
+ if (el.getAttribute("aria-disabled") === "true") return;
41136
+ const next = el.dataset.value ?? "";
41137
+ close();
41138
+ trigger.focus();
41139
+ if (next === value) return;
41140
+ picker.value = next;
41141
+ options.onChange(next);
41142
+ };
41143
+ trigger.addEventListener("click", () => isOpen ? close() : open());
41144
+ trigger.addEventListener("keydown", (event) => {
41145
+ if (event.key !== "ArrowDown" && event.key !== "ArrowUp") return;
41146
+ event.preventDefault();
41147
+ open();
41148
+ });
41149
+ menu.addEventListener("click", (event) => {
41150
+ const el = event.target.closest('[role="option"]');
41151
+ if (el) choose(el);
41152
+ });
41153
+ menu.addEventListener("keydown", (event) => {
41154
+ const list = enabledOptions();
41155
+ const active = menu.getRootNode().activeElement;
41156
+ const at = active ? list.indexOf(active) : -1;
41157
+ if (event.key === "ArrowDown") focusOption(list[Math.min(list.length - 1, at + 1)]);
41158
+ else if (event.key === "ArrowUp") focusOption(list[Math.max(0, at - 1)]);
41159
+ else if (event.key === "Home") focusOption(list[0]);
41160
+ else if (event.key === "End") focusOption(list.at(-1));
41161
+ else if (event.key === "Enter" || event.key === " ") {
41162
+ if (active?.getAttribute("role") === "option") choose(active);
41163
+ } else if (event.key === "Tab") {
41164
+ close();
41165
+ trigger.focus();
41166
+ return;
41167
+ } else return;
41168
+ event.preventDefault();
41169
+ });
41170
+ const picker = {
41171
+ root,
41172
+ trigger,
41173
+ get value() {
41174
+ return value;
41175
+ },
41176
+ set value(next) {
41177
+ if (next === value) return;
41178
+ stale = null;
41179
+ value = next;
41180
+ for (const [key, el] of optionElements)
41181
+ el.setAttribute("aria-selected", String(key === next));
41182
+ renderTrigger();
41183
+ },
41184
+ get disabled() {
41185
+ return disabled;
41186
+ },
41187
+ set disabled(next) {
41188
+ if (next === disabled) return;
41189
+ disabled = next;
41190
+ renderTrigger();
41191
+ },
41192
+ get busy() {
41193
+ return busy;
41194
+ },
41195
+ set busy(next) {
41196
+ if (next === busy) return;
41197
+ busy = next;
41198
+ renderTrigger();
41199
+ },
41200
+ setItems(next) {
41201
+ const previous = selectedItem();
41202
+ stale = options.retainMissing && previous && !next.some((item) => item.value === value) ? { ...previous, disabled: true } : null;
41203
+ items = next;
41204
+ renderItems();
41205
+ renderTrigger();
41206
+ },
41207
+ setDisabledValues(next) {
41208
+ isDisabled = next;
41209
+ for (const item of items) {
41210
+ const el = optionElements.get(item.value);
41211
+ if (!el) continue;
41212
+ if (item.disabled || next(item.value)) el.setAttribute("aria-disabled", "true");
41213
+ else el.removeAttribute("aria-disabled");
41214
+ }
41215
+ },
41216
+ setPlaceholder(text, shimmerText = false) {
41217
+ if (text === placeholder && shimmerText === shimmer) return;
41218
+ placeholder = text;
41219
+ shimmer = shimmerText;
41220
+ renderTrigger();
41221
+ },
41222
+ close
41223
+ };
41224
+ renderTrigger();
41225
+ return picker;
41226
+ }
41227
+
41228
+ // src/renderer-native-schedule-controls.ts
41229
+ function restoreRow(row, appearance) {
41230
+ row.hidden = appearance.hidden;
41231
+ row.style.setProperty("display", appearance.display, appearance.priority);
41232
+ }
41233
+ function installRendererNativeScheduleControls(document2, options) {
41234
+ const view = document2.defaultView ?? window;
41235
+ const mounted = /* @__PURE__ */ new Map();
41236
+ let disposed = false;
41237
+ let frame = null;
41238
+ const text = (zh, en) => options.locale() === "zh-CN" ? zh : en;
41239
+ const schedule = () => {
41240
+ if (!disposed && frame === null) frame = view.requestAnimationFrame(scan);
41241
+ };
41242
+ function mount(form) {
41243
+ const root = document2.createElement("div");
41244
+ root.dataset.codexhostScheduleControls = "true";
41245
+ const shadow = root.attachShadow({ mode: "open" });
41246
+ const style = document2.createElement("style");
41247
+ style.textContent = `
41248
+ :host { display:block; contain:inline-size; margin:0 0 16px; color:inherit; font:inherit; --text:var(--color-text-primary,CanvasText); --muted:var(--color-text-secondary,light-dark(#6b6b6b,#b5b5b5)); --border:var(--color-border-default,light-dark(#e1e1e1,#454545)); --hover:var(--color-token-list-hover-background,light-dark(rgba(0,0,0,.05),rgba(255,255,255,.08))); --surface:var(--color-token-dropdown-background,var(--color-background-surface,Canvas)); --focus:var(--color-text-info,#387aff); }
41249
+ * { box-sizing:border-box; }
41250
+ fieldset { border:1px solid var(--border); border-radius:16px; padding:0 12px; margin:0; min-width:0; }
41251
+ .row { display:flex; align-items:center; justify-content:space-between; gap:16px; min-width:0; min-height:52px; padding:8px 0 8px 4px; font:inherit; }
41252
+ .row + .row { border-top:1px solid var(--border); }
41253
+ .name { flex:none; }
41254
+ .value { display:flex; justify-content:flex-end; min-width:0; max-width:72%; }
41255
+ fieldset:disabled { opacity:.6; }
41256
+ ${schedulePickerStyles}
41257
+ .message { display:flex; align-items:baseline; gap:8px; margin:8px 4px 0; color:var(--muted); font-size:12px; line-height:1.5; }
41258
+ p { margin:0; min-width:0; overflow-wrap:anywhere; }
41259
+ button.retry { border:0; border-radius:4px; padding:2px 4px; color:inherit; background:transparent; font:inherit; text-decoration:underline; cursor:pointer; flex-shrink:0; }
41260
+ button.retry:focus-visible { outline:2px solid var(--focus); outline-offset:2px; }
41261
+ [hidden] { display:none!important; }
41262
+ `;
41263
+ const fields = document2.createElement("fieldset");
41264
+ const harness2 = createSchedulePicker(document2, {
41265
+ label: "Harness",
41266
+ listLabel: text("\u9009\u62E9 Harness", "Choose a Harness"),
41267
+ retainMissing: true,
41268
+ onChange: () => onHarness()
41269
+ });
41270
+ const model2 = createSchedulePicker(document2, {
41271
+ label: text("\u6A21\u578B", "Model"),
41272
+ listLabel: text("\u9009\u62E9\u6A21\u578B", "Choose a Model"),
41273
+ retainMissing: true,
41274
+ onChange: () => applyModel()
41275
+ });
41276
+ const workspace = createSchedulePicker(document2, {
41277
+ label: text("\u5DE5\u4F5C\u533A", "Workspace"),
41278
+ listLabel: text("\u9009\u62E9\u5DE5\u4F5C\u533A", "Choose a workspace"),
41279
+ retainMissing: true,
41280
+ onOpen: () => refreshWorkspaces(),
41281
+ onChange: () => {
41282
+ const next = workspaces.find(({ id }) => id === workspace.value) ?? null;
41283
+ if (next?.id === selectedWorkspace?.id && next?.cwd === selectedWorkspace?.cwd) return;
41284
+ selectedWorkspace = next;
41285
+ void loadModels({ preserveSelection: models.length > 0 });
41286
+ }
41287
+ });
41288
+ const label = (name, picker) => {
41289
+ const row = document2.createElement("div");
41290
+ row.className = "row";
41291
+ const title = document2.createElement("span");
41292
+ title.className = "name";
41293
+ title.textContent = name;
41294
+ const value = document2.createElement("div");
41295
+ value.className = "value";
41296
+ value.append(picker.root);
41297
+ row.append(title, value);
41298
+ fields.append(row);
41299
+ return row;
41300
+ };
41301
+ label("Harness", harness2);
41302
+ const modelRow = label(text("\u6A21\u578B", "Model"), model2);
41303
+ const workspaceRow = label(text("\u5DE5\u4F5C\u533A", "Workspace"), workspace);
41304
+ const status = document2.createElement("p");
41305
+ status.setAttribute("role", "status");
41306
+ const retry = document2.createElement("button");
41307
+ retry.type = "button";
41308
+ retry.className = "retry";
41309
+ retry.textContent = text("\u91CD\u8BD5", "Retry");
41310
+ retry.hidden = true;
41311
+ const messageRow = document2.createElement("div");
41312
+ messageRow.className = "message";
41313
+ messageRow.append(status, retry);
41314
+ shadow.append(style, fields, messageRow);
41315
+ const editor = form.querySelector('[contenteditable="true"][role="textbox"], textarea');
41316
+ const container = editor?.closest("fieldset")?.querySelector(":scope > div") ?? form;
41317
+ container.prepend(root);
41318
+ let retired = false;
41319
+ let client = options.getClient();
41320
+ let selectedHarness = "codex";
41321
+ let availablePlugins = [];
41322
+ let generation = 0;
41323
+ let loading = false;
41324
+ let confirming = false;
41325
+ let confirmationTimer;
41326
+ let error51 = "";
41327
+ let models = [];
41328
+ let workspaces = [];
41329
+ let selectedWorkspace = null;
41330
+ let workspaceCreation = null;
41331
+ let carrier = null;
41332
+ let original = null;
41333
+ let restoring = null;
41334
+ const hiddenRows = /* @__PURE__ */ new Map();
41335
+ const external = () => selectedHarness !== "codex";
41336
+ const available = () => options.getAvailablePlugins().some((plugin) => plugin.id === selectedHarness);
41337
+ const harnessItem = (id, name, plugin) => ({
41338
+ value: id,
41339
+ label: name,
41340
+ icon: createRendererAgentIcon(id, 18, document2, plugin)
41341
+ });
41342
+ harness2.setItems([harnessItem("codex", "Codex")]);
41343
+ harness2.value = "codex";
41344
+ const syncAvailablePlugins = () => {
41345
+ const next = options.getAvailablePlugins();
41346
+ if (next.length === availablePlugins.length && next.every(
41347
+ (plugin, index) => plugin.id === availablePlugins[index]?.id && plugin.name === availablePlugins[index]?.name
41348
+ ))
41349
+ return;
41350
+ availablePlugins = next;
41351
+ harness2.setItems([
41352
+ harnessItem("codex", "Codex"),
41353
+ ...next.map((plugin) => harnessItem(plugin.id, plugin.name, plugin))
41354
+ ]);
41355
+ harness2.value = selectedHarness;
41356
+ };
41357
+ function refreshWorkspaces() {
41358
+ workspaces = readNativeScheduleWorkspaces(document2);
41359
+ workspace.setItems([
41360
+ { value: "", label: text("\u81EA\u52A8\u5206\u914D", "Automatic") },
41361
+ ...workspaces.map(({ id, label: label2, cwd }) => ({ value: id, label: `${label2} \xB7 ${cwd}` }))
41362
+ ]);
41363
+ workspace.value = selectedWorkspace?.id ?? "";
41364
+ update();
41365
+ }
41366
+ const cancelConfirmation = () => {
41367
+ if (confirmationTimer !== void 0) view.clearTimeout(confirmationTimer);
41368
+ confirmationTimer = void 0;
41369
+ confirming = false;
41370
+ };
41371
+ const restoredSelection = (selection) => restoring && (restoring.model === null ? !selection.model?.startsWith("codexhost/") : selection.model === restoring.model && selection.reasoningEffort === restoring.reasoningEffort);
41372
+ const confirmSelection = () => {
41373
+ cancelConfirmation();
41374
+ confirming = true;
41375
+ const deadline = Date.now() + 5e3;
41376
+ const check2 = () => {
41377
+ if (retired) return;
41378
+ const binding = readNativeScheduleForm(form);
41379
+ const confirmed = binding && (external() ? binding.selection.model === carrier : !restoring || restoredSelection(binding.selection));
41380
+ if (!binding || !options.canRouteExternal() || client !== options.getClient() || confirmed || Date.now() >= deadline)
41381
+ cancelConfirmation();
41382
+ else confirmationTimer = view.setTimeout(check2, 50);
41383
+ update();
41384
+ };
41385
+ confirmationTimer = view.setTimeout(check2, 0);
41386
+ };
41387
+ const restore = () => {
41388
+ const binding = readNativeScheduleForm(form);
41389
+ if (original && carrier && (!binding || binding.selection.model === carrier || confirming)) {
41390
+ restoring = original;
41391
+ binding?.setModel(original);
41392
+ confirmSelection();
41393
+ }
41394
+ carrier = null;
41395
+ original = null;
41396
+ selectedWorkspace = null;
41397
+ workspace.value = "";
41398
+ };
41399
+ const applyModel = () => {
41400
+ const binding = readNativeScheduleForm(form);
41401
+ const selected = models.find((entry) => entry.ref.id === model2.value);
41402
+ if (!external() || workspaceCreation !== null || !binding?.supportsExternal || !available() || binding.hasTarget || binding.isSaving || !selected)
41403
+ return;
41404
+ original ??= restoring ?? binding.selection;
41405
+ restoring = null;
41406
+ carrier = encodeHarnessPluginRoute({
41407
+ harnessId: selectedHarness,
41408
+ model: selected.ref
41409
+ });
41410
+ binding.setModel({ model: carrier, reasoningEffort: null });
41411
+ confirmSelection();
41412
+ update();
41413
+ };
41414
+ const loadModels = async ({ preserveSelection = false } = {}) => {
41415
+ const request = ++generation;
41416
+ const previousModel = model2.value;
41417
+ if (!preserveSelection) {
41418
+ cancelConfirmation();
41419
+ models = [];
41420
+ model2.setItems([]);
41421
+ model2.value = "";
41422
+ model2.setPlaceholder(text("\u6B63\u5728\u52A0\u8F7D\u6A21\u578B\u2026", "Loading models\u2026"), true);
41423
+ }
41424
+ error51 = "";
41425
+ loading = true;
41426
+ update();
41427
+ const requestedHarness = selectedHarness;
41428
+ const selectedClient = client;
41429
+ try {
41430
+ if (!selectedClient) throw Error(text("\u672C\u5730\u8FDE\u63A5\u4E0D\u53EF\u7528\u3002", "Local connection unavailable."));
41431
+ const result = await selectedClient.inspectHarness({
41432
+ harnessId: requestedHarness,
41433
+ ...selectedWorkspace ? { cwd: selectedWorkspace.cwd } : {}
41434
+ });
41435
+ if (retired || request !== generation || selectedClient !== options.getClient()) return;
41436
+ if (result.status !== "ready")
41437
+ throw Error(text("\u6240\u9009 Harness \u4E0D\u53EF\u7528\u3002", "The selected Harness is unavailable."));
41438
+ const selectedModel = preserveSelection ? model2.value : previousModel;
41439
+ const next = result.catalog.models;
41440
+ const changed = next.length !== models.length || next.some(
41441
+ (entry, index) => entry.ref.id !== models[index]?.ref.id || entry.label !== models[index]?.label
41442
+ );
41443
+ models = next;
41444
+ if (changed || !preserveSelection)
41445
+ model2.setItems(models.map((entry) => ({ value: entry.ref.id, label: entry.label })));
41446
+ const defaultModel = result.catalog.defaultModel;
41447
+ model2.value = preserveSelection || models.some((entry) => entry.ref.id === selectedModel) ? selectedModel : defaultModel && models.some((entry) => entry.ref.id === defaultModel.id) ? defaultModel.id : models[0]?.ref.id ?? "";
41448
+ model2.setPlaceholder("");
41449
+ if (!models.length) throw Error(text("\u6CA1\u6709\u53EF\u7528\u6A21\u578B\u3002", "No models are available."));
41450
+ if (!preserveSelection) applyModel();
41451
+ } catch (cause) {
41452
+ if (retired || request !== generation) return;
41453
+ error51 = cause instanceof Error ? cause.message : text("\u6A21\u578B\u8BFB\u53D6\u5931\u8D25\u3002", "Could not read models.");
41454
+ if (!preserveSelection) model2.setPlaceholder(text("\u6A21\u578B\u52A0\u8F7D\u5931\u8D25", "Models unavailable"));
41455
+ } finally {
41456
+ if (!retired && request === generation) {
41457
+ loading = false;
41458
+ update();
41459
+ }
41460
+ }
41461
+ };
41462
+ const onHarness = () => {
41463
+ const binding = readNativeScheduleForm(form);
41464
+ if (binding?.hasTarget || binding?.isSaving || workspaceCreation) return;
41465
+ selectedHarness = harness2.value;
41466
+ client = options.getClient();
41467
+ if (!external()) restore();
41468
+ generation++;
41469
+ models = [];
41470
+ model2.setItems([]);
41471
+ model2.value = "";
41472
+ model2.setPlaceholder("");
41473
+ error51 = "";
41474
+ loading = false;
41475
+ if (external()) {
41476
+ refreshWorkspaces();
41477
+ void loadModels();
41478
+ }
41479
+ update();
41480
+ };
41481
+ retry.addEventListener("click", () => {
41482
+ if (error51) void loadModels({ preserveSelection: models.length > 0 });
41483
+ else applyModel();
41484
+ });
41485
+ function blockedReason() {
41486
+ const binding = readNativeScheduleForm(form);
41487
+ if (!external()) {
41488
+ const restored = binding && restoredSelection(binding.selection);
41489
+ if (restoring && !restored)
41490
+ return text(
41491
+ "\u6B63\u5728\u6062\u590D Codex \u914D\u7F6E\uFF0C\u8BF7\u7A0D\u540E\u63D0\u4EA4\u3002",
41492
+ "Restoring Codex settings. Submit again once ready."
41493
+ );
41494
+ restoring = null;
41495
+ if (binding?.selection.model?.startsWith("codexhost/"))
41496
+ return text(
41497
+ "\u4EFB\u52A1\u4ECD\u643A\u5E26\u5916\u90E8 Model\uFF0C\u8BF7\u91CD\u65B0\u6253\u5F00\u5F39\u7A97\u3002",
41498
+ "The task still carries an external Model. Reopen the dialog."
41499
+ );
41500
+ return "";
41501
+ }
41502
+ if (!binding || !options.canRouteExternal() || client !== options.getClient())
41503
+ return text(
41504
+ "\u4EFB\u52A1\u63A5\u5165\u6216\u672C\u5730\u8FDE\u63A5\u4E0D\u53EF\u7528\uFF0C\u8BF7\u91CD\u65B0\u6253\u5F00\u5F39\u7A97\u3002",
41505
+ "Task binding or local connection unavailable. Reopen the dialog."
41506
+ );
41507
+ if (!available())
41508
+ return text(
41509
+ "\u6240\u9009 Harness \u5DF2\u4E0D\u5728\u672C\u5730\u53EF\u7528\u5217\u8868\u4E2D\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u3002",
41510
+ "The selected Harness is no longer available locally. Choose another Harness."
41511
+ );
41512
+ if (!binding.supportsExternal)
41513
+ return text(
41514
+ "\u5916\u90E8 Harness \u4EC5\u652F\u6301\u672C\u5730\u56FA\u5B9A\u804A\u5929\uFF1A\u8BF7\u542F\u7528\u201C\u5728\u6B64\u7535\u8111\u4E0A\u8FD0\u884C\u201D\uFF0C\u5173\u95ED\u201C\u6BCF\u6B21\u8FD0\u884C\u90FD\u5F00\u542F\u65B0\u804A\u5929\u201D\uFF0C\u5E76\u9009\u62E9\u4E2A\u4EBA\u5B9A\u65F6\u4EFB\u52A1\u3002",
41515
+ "External Harnesses require a personal local task in the same chat. Enable Run on this computer and disable Start each run in new chat."
41516
+ );
41517
+ if (workspaceCreation?.error) return workspaceCreation.error;
41518
+ if (workspaceCreation?.pending)
41519
+ return text("\u6B63\u5728\u521B\u5EFA\u5DE5\u4F5C\u533A\u4F1A\u8BDD\u2026", "Creating workspace chat\u2026");
41520
+ const chosen = selectedWorkspace;
41521
+ if (chosen && !binding.hasTarget && !workspaces.some(({ id, cwd }) => id === chosen.id && cwd === chosen.cwd))
41522
+ return text(
41523
+ "\u6240\u9009\u5DE5\u4F5C\u533A\u5DF2\u4E0D\u53EF\u7528\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u3002",
41524
+ "The selected workspace is no longer available. Choose another workspace."
41525
+ );
41526
+ if (error51) return error51;
41527
+ if (loading)
41528
+ return models.length > 0 ? text(
41529
+ "\u6B63\u5728\u786E\u8BA4\u5DE5\u4F5C\u533A\u7684\u6A21\u578B\u914D\u7F6E\uFF0C\u8BF7\u7A0D\u540E\u63D0\u4EA4\u3002",
41530
+ "Checking workspace models. Submit again once ready."
41531
+ ) : text("\u8BF7\u7B49\u5F85\u5E76\u9009\u62E9\u53EF\u7528\u7684 Model\u3002", "Wait for an available Model and select it.");
41532
+ if (!carrier || !models.some((entry) => entry.ref.id === model2.value))
41533
+ return text(
41534
+ "\u5F53\u524D\u6A21\u578B\u5728\u6B64\u5DE5\u4F5C\u533A\u4E0D\u53EF\u7528\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u6A21\u578B\u3002",
41535
+ "The selected Model is unavailable in this workspace. Choose another Model."
41536
+ );
41537
+ if (binding.selection.model !== carrier && confirming)
41538
+ return text("\u6B63\u5728\u5E94\u7528\u6A21\u578B\u2026", "Applying Model\u2026");
41539
+ if (binding.selection.model !== carrier)
41540
+ return text(
41541
+ "\u4EFB\u52A1\u7684 Model \u5C1A\u672A\u786E\u8BA4\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9 Model\u3002",
41542
+ "The task Model is not confirmed. Select the Model again."
41543
+ );
41544
+ return "";
41545
+ }
41546
+ function update() {
41547
+ if (retired) return;
41548
+ syncAvailablePlugins();
41549
+ const binding = readNativeScheduleForm(form);
41550
+ const active = external();
41551
+ modelRow.hidden = !active;
41552
+ workspaceRow.hidden = !active;
41553
+ fields.disabled = Boolean(binding?.isSaving || binding?.hasTarget || workspaceCreation);
41554
+ workspace.disabled = loading && models.length === 0 || confirming || !binding?.supportsExternal || !available();
41555
+ const modelBusy = loading && models.length === 0 || confirming && active;
41556
+ model2.disabled = modelBusy || models.length === 0 || !binding?.supportsExternal || !available();
41557
+ model2.busy = modelBusy;
41558
+ harness2.busy = confirming && !active;
41559
+ harness2.disabled = fields.disabled;
41560
+ const externalBlocked = !binding?.supportsExternal || !options.canRouteExternal();
41561
+ harness2.setDisabledValues(externalBlocked ? (id) => id !== "codex" : () => false);
41562
+ const blocked = blockedReason();
41563
+ const message2 = loading && models.length === 0 || confirming ? "" : active ? blocked : blocked || error51 || (!binding?.supportsExternal ? text(
41564
+ "\u5916\u90E8 Harness \u9700\u8981\u5728\u9AD8\u7EA7\u8BBE\u7F6E\u4E2D\u9009\u62E9\u672C\u5730\u3001\u56FA\u5B9A\u804A\u5929\u3002",
41565
+ "For external Harnesses, choose local execution in the same chat under Advanced."
41566
+ ) : "");
41567
+ if (status.textContent !== message2) status.textContent = message2;
41568
+ messageRow.hidden = !message2;
41569
+ retry.hidden = !active || loading || confirming || Boolean(workspaceCreation) || !error51 && models.length > 0 && !models.some((entry) => entry.ref.id === model2.value) || !message2 || !binding?.supportsExternal || Boolean(binding.hasTarget || binding.isSaving) || client !== options.getClient() || !options.canRouteExternal() || !available();
41570
+ const rows = active ? new Set(nativeScheduleModelRows(form)) : /* @__PURE__ */ new Set();
41571
+ for (const [row, appearance] of hiddenRows) {
41572
+ if (rows.has(row)) continue;
41573
+ restoreRow(row, appearance);
41574
+ hiddenRows.delete(row);
41575
+ }
41576
+ for (const row of rows) {
41577
+ if (!hiddenRows.has(row))
41578
+ hiddenRows.set(row, {
41579
+ hidden: row.hidden,
41580
+ display: row.style.getPropertyValue("display"),
41581
+ priority: row.style.getPropertyPriority("display")
41582
+ });
41583
+ row.hidden = true;
41584
+ row.style.setProperty("display", "none", "important");
41585
+ }
41586
+ }
41587
+ async function prepareWorkspace(chosen, routeModel) {
41588
+ if (workspaceCreation) return;
41589
+ const attempt = {
41590
+ controller: new AbortController(),
41591
+ pending: true,
41592
+ error: "",
41593
+ thread: void 0
41594
+ };
41595
+ workspaceCreation = attempt;
41596
+ update();
41597
+ try {
41598
+ const binding = readNativeScheduleForm(form);
41599
+ if (!binding) throw Error("Task binding unavailable");
41600
+ attempt.thread = await options.createWorkspaceThread(
41601
+ { workspace: chosen, model: routeModel, title: binding.title },
41602
+ attempt.controller.signal
41603
+ );
41604
+ attempt.controller.signal.throwIfAborted();
41605
+ if (retired || !form.isConnected) throw Error("Task dialog closed");
41606
+ const current = readNativeScheduleForm(form);
41607
+ if (!current?.supportsExternal || current.selection.model !== routeModel || client !== options.getClient())
41608
+ throw Error("Task configuration or connection changed. Reopen the dialog.");
41609
+ current.setTargetThread(attempt.thread.threadId, routeModel);
41610
+ const deadline = Date.now() + 5e3;
41611
+ while (readNativeScheduleForm(form)?.targetThreadId !== attempt.thread.threadId) {
41612
+ attempt.controller.signal.throwIfAborted();
41613
+ if (Date.now() >= deadline)
41614
+ throw Error("The task's target chat was not confirmed. Reopen the dialog.");
41615
+ await new Promise((resolve) => view.setTimeout(resolve, 25));
41616
+ }
41617
+ attempt.controller.signal.throwIfAborted();
41618
+ attempt.pending = false;
41619
+ update();
41620
+ form.requestSubmit();
41621
+ } catch (cause) {
41622
+ attempt.error = `${cause instanceof Error ? cause.message : text("\u4F1A\u8BDD\u521B\u5EFA\u5931\u8D25\u3002", "Chat creation failed.")} ${text("\u8BF7\u5148\u68C0\u67E5\u4F1A\u8BDD\u5217\u8868\uFF0C\u52FF\u91CD\u590D\u521B\u5EFA\u3002", "Check the chat list before creating another task.")}`;
41623
+ } finally {
41624
+ attempt.pending = false;
41625
+ if (!retired) update();
41626
+ }
41627
+ }
41628
+ const onSubmit = (event) => {
41629
+ if (external() && selectedWorkspace) refreshWorkspaces();
41630
+ const reason = blockedReason();
41631
+ if (!reason) {
41632
+ if (external() && selectedWorkspace) {
41633
+ const binding = readNativeScheduleForm(form);
41634
+ const button2 = form.querySelector('button[type="submit"]');
41635
+ if (!button2 || button2.matches(":disabled") || binding?.isSaving) {
41636
+ event.preventDefault();
41637
+ event.stopImmediatePropagation();
41638
+ return;
41639
+ }
41640
+ if (!binding?.hasTarget && carrier) {
41641
+ event.preventDefault();
41642
+ event.stopImmediatePropagation();
41643
+ void prepareWorkspace(selectedWorkspace, carrier);
41644
+ return;
41645
+ }
41646
+ workspaceCreation?.thread?.retain();
41647
+ }
41648
+ return;
41649
+ }
41650
+ event.preventDefault();
41651
+ event.stopImmediatePropagation();
41652
+ messageRow.hidden = loading && models.length === 0 || confirming;
41653
+ status.textContent = reason;
41654
+ };
41655
+ form.addEventListener("submit", onSubmit, true);
41656
+ update();
41657
+ return {
41658
+ root,
41659
+ update,
41660
+ dispose() {
41661
+ retired = true;
41662
+ generation++;
41663
+ if (form.isConnected) restore();
41664
+ cancelConfirmation();
41665
+ harness2.close();
41666
+ model2.close();
41667
+ workspace.close();
41668
+ if (form.isConnected && workspaceCreation?.thread && readNativeScheduleForm(form)?.targetThreadId === workspaceCreation.thread.threadId)
41669
+ workspaceCreation.thread.retain();
41670
+ workspaceCreation?.controller.abort();
41671
+ for (const [row, appearance] of hiddenRows) restoreRow(row, appearance);
41672
+ form.removeEventListener("submit", onSubmit, true);
41673
+ root.remove();
41674
+ }
41675
+ };
41676
+ }
41677
+ function scan() {
41678
+ frame = null;
41679
+ if (disposed) return;
41680
+ for (const [form, control] of mounted) {
41681
+ if (!form.isConnected || !control.root.isConnected) {
41682
+ control.dispose();
41683
+ mounted.delete(form);
41684
+ } else control.update();
41685
+ }
41686
+ for (const form of document2.querySelectorAll('form[data-density="form"]')) {
41687
+ if (!mounted.has(form) && readNativeScheduleForm(form)) mounted.set(form, mount(form));
41688
+ }
41689
+ }
41690
+ const unsubscribeAvailability = options.subscribeAvailability(schedule);
41691
+ const observer = new MutationObserver(schedule);
41692
+ observer.observe(document2.documentElement, { childList: true, subtree: true });
41693
+ document2.addEventListener("change", schedule, true);
41694
+ document2.addEventListener("click", schedule, true);
41695
+ view.addEventListener("codexhost:draft-prewarm-policy-changed", schedule);
41696
+ scan();
41697
+ return {
41698
+ refresh: schedule,
41699
+ dispose() {
41700
+ disposed = true;
41701
+ if (frame !== null) view.cancelAnimationFrame(frame);
41702
+ observer.disconnect();
41703
+ unsubscribeAvailability();
41704
+ document2.removeEventListener("change", schedule, true);
41705
+ document2.removeEventListener("click", schedule, true);
41706
+ view.removeEventListener("codexhost:draft-prewarm-policy-changed", schedule);
41707
+ for (const control of mounted.values()) control.dispose();
41708
+ mounted.clear();
41709
+ }
41710
+ };
41711
+ }
41712
+
40430
41713
  // src/renderer-binding-probe.ts
40431
41714
  var EMPTY_PLUGINS = [];
40432
41715
  function isRetryableHarnessAvailability(availability, error51) {
@@ -40804,6 +42087,9 @@ ${usage_default}`;
40804
42087
  disposed: () => disposed
40805
42088
  });
40806
42089
  const settingsLifecycle = installRendererSettingsLifecycle(window, {
42090
+ harnessSchedules: {
42091
+ openSchedules: (signal) => openCodexSchedules(signal)
42092
+ },
40807
42093
  getRemoteConnections: () => remoteConnections,
40808
42094
  getUpdateClient: () => modelControl,
40809
42095
  getAccountClient: () => modelControl,
@@ -42291,6 +43577,30 @@ ${usage_default}`;
42291
43577
  return () => connectionListeners.delete(listener);
42292
43578
  }
42293
43579
  };
43580
+ const nativeScheduleControls = installRendererNativeScheduleControls(document, {
43581
+ getClient: () => modelClientForHost("local"),
43582
+ getAvailablePlugins: () => {
43583
+ const client = modelClientForHost("local");
43584
+ const state = hostHarnessAvailabilityState("local");
43585
+ if (!client || state.directoryClient !== client) return [];
43586
+ return (state.plugins ?? []).filter((plugin) => plugin.kind !== "usage" && state.availability[plugin.id] === "ready").map((plugin) => pluginForHost("local", plugin.id) ?? plugin);
43587
+ },
43588
+ subscribeAvailability: (listener) => {
43589
+ connectionListeners.add(listener);
43590
+ return () => connectionListeners.delete(listener);
43591
+ },
43592
+ canRouteExternal: () => window.__codexhostHostRoutingV1?.forHost("local")?.policy.scopedCreation === true,
43593
+ async createWorkspaceThread(input, signal) {
43594
+ const routing = window.__codexhostHostRoutingV1;
43595
+ const manager = routing?.forHost("local")?.manager;
43596
+ const create = await loadCodexNativeServices(window, isNativeProjectThreadCreator);
43597
+ signal.throwIfAborted();
43598
+ if (!routing || !manager || routing.forHost("local")?.manager !== manager || !create)
43599
+ throw new Error("Native workspace chat creation is unavailable. Reopen the task dialog.");
43600
+ return createNativeScheduleWorkspaceThread(document, routing, create, input, signal);
43601
+ },
43602
+ locale: () => settingsLifecycle.locale
43603
+ });
42294
43604
  const mount = (composer) => {
42295
43605
  if (mountedByComposer.has(composer) || !composer.isConnected || hasNativeComposerRequest(composer) || orbitComposerKind(composer) !== "codex" || !composer.matches(CODEX_COMPOSER_SELECTOR)) {
42296
43606
  return;
@@ -42625,6 +43935,7 @@ ${usage_default}`;
42625
43935
  const onAdapterStatus = () => {
42626
43936
  publishConnectionStatus();
42627
43937
  if (shouldRefreshCodexAccountsForAdapterState(adapterStatus.state)) {
43938
+ reconcileHarnessAvailabilityHost();
42628
43939
  void loadCodexAccounts();
42629
43940
  sidebarAgentIcons.refresh();
42630
43941
  void refreshHarnessAvailabilityForHost("local");
@@ -42803,6 +44114,7 @@ ${usage_default}`;
42803
44114
  if (disposed || modelControl !== installedModelControl) return;
42804
44115
  try {
42805
44116
  settingsLifecycle.refresh();
44117
+ nativeScheduleControls.refresh();
42806
44118
  } catch {
42807
44119
  }
42808
44120
  });
@@ -42853,6 +44165,7 @@ ${usage_default}`;
42853
44165
  disposeReasoningSoftWrap();
42854
44166
  delegationMention?.dispose();
42855
44167
  sidebarAgentIcons.dispose();
44168
+ nativeScheduleControls.dispose();
42856
44169
  settingsLifecycle.dispose();
42857
44170
  document.removeEventListener("beforeinput", onBeforeInput, true);
42858
44171
  document.removeEventListener("submit", onSubmit, true);
@@ -42929,6 +44242,7 @@ lucide/dist/esm/icons/message-circle-question-mark.mjs:
42929
44242
  lucide/dist/esm/icons/pencil.mjs:
42930
44243
  lucide/dist/esm/icons/x.mjs:
42931
44244
  lucide/dist/esm/icons/boxes.mjs:
44245
+ lucide/dist/esm/icons/calendar-clock.mjs:
42932
44246
  lucide/dist/esm/icons/circle-check.mjs:
42933
44247
  lucide/dist/esm/icons/chevron-down.mjs:
42934
44248
  lucide/dist/esm/icons/chevron-left.mjs: