@codexhost/cli-darwin-x64 0.15.0 → 0.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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 });
@@ -15856,7 +15858,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15856
15858
  harnessId: harnessPluginIdSchema,
15857
15859
  model: harnessModelRefSchema.optional(),
15858
15860
  thinkingOptionId: harnessThinkingOptionIdSchema.optional(),
15859
- permissionModeId: harnessPermissionModeIdSchema.optional()
15861
+ permissionModeId: harnessPermissionModeIdSchema.optional(),
15862
+ /** A draft prewarm create: stays unsubmitted until the user's first Turn.
15863
+ * Desktop forwards only the Model of a main-process prewarm to thread/start. */
15864
+ prewarm: external_exports.literal(true).optional()
15860
15865
  }).strict();
15861
15866
  function encodeHarnessPluginRoute(route) {
15862
15867
  const parsed = harnessPluginRouteSchema.parse(route);
@@ -16348,8 +16353,24 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16348
16353
  if (!ownerWindow.document || !ownerWindow.location) return null;
16349
16354
  const page = new URL(ownerWindow.location.href);
16350
16355
  const urls = /* @__PURE__ */ new Set();
16351
- for (const link of ownerWindow.document.querySelectorAll('link[rel="modulepreload"][href]')) {
16352
- const url2 = new URL(link.getAttribute("href") ?? "", page);
16356
+ const catalog = Reflect.get(ownerWindow, "__codexhostLoadedModulesV1");
16357
+ let sources;
16358
+ if (catalog !== void 0) {
16359
+ if (typeof catalog !== "object" || catalog === null || !("complete" in catalog) || catalog.complete !== true || !("documentUrl" in catalog) || catalog.documentUrl !== page.href || !("urls" in catalog) || !Array.isArray(catalog.urls) || catalog.urls.length > 4096 || catalog.urls.some((url2) => typeof url2 !== "string"))
16360
+ throw new Error("Codex loaded module catalog is unavailable in this window");
16361
+ sources = catalog.urls;
16362
+ } else {
16363
+ sources = [...ownerWindow.document.querySelectorAll('link[rel="modulepreload"][href]')].map(
16364
+ (link) => link.getAttribute("href") ?? ""
16365
+ );
16366
+ }
16367
+ for (const source of sources) {
16368
+ let url2;
16369
+ try {
16370
+ url2 = new URL(source, page);
16371
+ } catch {
16372
+ continue;
16373
+ }
16353
16374
  if (url2.protocol === page.protocol && url2.host === page.host && url2.pathname.endsWith(".js") && !url2.search && !url2.hash)
16354
16375
  urls.add(url2.href);
16355
16376
  }
@@ -16367,6 +16388,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16367
16388
  for (const value of Object.values(module).filter(matchesServices)) matches.add(value);
16368
16389
  if (matches.size > 1) throw new Error("Codex native services are unavailable in this window");
16369
16390
  }
16391
+ if (catalog !== void 0 && Reflect.get(ownerWindow, "__codexhostLoadedModulesV1") !== catalog)
16392
+ throw new Error("Codex loaded module catalog changed during discovery. Try again once ready.");
16370
16393
  return [...matches][0] ?? null;
16371
16394
  }
16372
16395
 
@@ -17240,10 +17263,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17240
17263
  return [];
17241
17264
  seen.add(entry.node);
17242
17265
  if (entry.node === first || entry.node === alternate) {
17243
- const ancestors = [];
17266
+ const ancestors2 = [];
17244
17267
  for (let cursor = entry; cursor; cursor = cursor.parent)
17245
- ancestors.push(cursor.node);
17246
- return ancestors;
17268
+ ancestors2.push(cursor.node);
17269
+ return ancestors2;
17247
17270
  }
17248
17271
  const sibling = entry.parent && fiber(entry.node.sibling);
17249
17272
  if (sibling)
@@ -17255,6 +17278,594 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17255
17278
  return stack.length > 0 ? exhausted() : [];
17256
17279
  }
17257
17280
 
17281
+ // ../desktop-control/dist/renderer-native-schedule-sidebar.js
17282
+ var NATIVE_SCHEDULE_SIDEBAR_ROW_SELECTOR = 'aside [data-sidebar-cycle-item][role="button"][aria-labelledby]';
17283
+ function readNativeScheduleSidebarThread(element) {
17284
+ if (!element.matches(NATIVE_SCHEDULE_SIDEBAR_ROW_SELECTOR))
17285
+ return null;
17286
+ const keys = Object.keys(element).filter((key2) => key2.startsWith("__reactFiber$"));
17287
+ const key = keys[0];
17288
+ if (keys.length !== 1 || !key)
17289
+ return null;
17290
+ let scheduledContainer = false;
17291
+ const candidates = /* @__PURE__ */ new Set();
17292
+ let depth = 0;
17293
+ for (const fiber of committedReactAncestors(Reflect.get(element, key))) {
17294
+ if (++depth > 12)
17295
+ break;
17296
+ const props = fiber.memoizedProps;
17297
+ if (!props || typeof props !== "object")
17298
+ continue;
17299
+ if (Object.hasOwn(props, "data-selected-scheduled-task"))
17300
+ scheduledContainer = true;
17301
+ if (!scheduledContainer || !Object.hasOwn(props, "automation"))
17302
+ continue;
17303
+ const automation = props.automation;
17304
+ 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")
17305
+ return null;
17306
+ const parsed = hostThreadIdSchema.safeParse(automation.targetThreadId);
17307
+ if (!parsed.success)
17308
+ return null;
17309
+ candidates.add(parsed.data);
17310
+ }
17311
+ return candidates.size === 1 ? candidates.values().next().value ?? null : null;
17312
+ }
17313
+
17314
+ // ../desktop-control/dist/renderer-scoped-draft-model.js
17315
+ function findScopedDraftModelBinding(composer, draftId) {
17316
+ let element = composer.querySelector?.('[data-codex-composer], [contenteditable="true"][role="textbox"]') ?? composer;
17317
+ let fiber;
17318
+ while (element && !fiber) {
17319
+ const key = Object.getOwnPropertyNames(element).find((name) => name.startsWith("__reactFiber$"));
17320
+ if (key)
17321
+ fiber = Object.getOwnPropertyDescriptor(element, key)?.value;
17322
+ element = element.parentElement;
17323
+ }
17324
+ const rows = [];
17325
+ const groups = /* @__PURE__ */ new Map();
17326
+ const updates = /* @__PURE__ */ new Set();
17327
+ for (const ancestor of committedReactAncestors(fiber)) {
17328
+ const queue = ancestor.updateQueue;
17329
+ const data = (queue?.memoCache?.data ?? []).filter(Array.isArray);
17330
+ for (const row of data) {
17331
+ rows.push(row);
17332
+ groups.set(row, data);
17333
+ if (!Array.isArray(row) || row.length !== 14 || row[6] !== draftId || row[7] !== draftId)
17334
+ continue;
17335
+ const result = row[13];
17336
+ if (result?.isNewThreadDraft === true && row[11] === true && result.draftSettings === row[10] && result.updateDraftSettings === row[9] && row[9] === row[12] && typeof row[9] === "function")
17337
+ updates.add(row[9]);
17338
+ }
17339
+ }
17340
+ let update;
17341
+ const modes = /* @__PURE__ */ new Set();
17342
+ const creationModes = /* @__PURE__ */ new Set();
17343
+ for (const row of rows) {
17344
+ if (row.length !== 24 || row[7] !== null || row[10] !== true || !updates.has(row[13]))
17345
+ continue;
17346
+ const context = row[12];
17347
+ const result = row[23];
17348
+ 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]) {
17349
+ update ??= row[13];
17350
+ modes.add(context.usesAccountPreferences);
17351
+ const settings = result.modelSettings;
17352
+ const group = groups.get(row);
17353
+ const candidate = group?.[group.indexOf(row) - 1];
17354
+ const mode = candidate?.[44];
17355
+ const value = candidate?.[51];
17356
+ 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)
17357
+ creationModes.add(mode);
17358
+ }
17359
+ }
17360
+ const [usesAccountPreferences] = modes;
17361
+ return update && modes.size === 1 && usesAccountPreferences !== void 0 ? {
17362
+ update,
17363
+ usesAccountPreferences,
17364
+ ...creationModes.size ? { creationModes: [...creationModes] } : {}
17365
+ } : null;
17366
+ }
17367
+ function createScopedDraftModelWriter() {
17368
+ const captured = /* @__PURE__ */ new Map();
17369
+ const restore = (key) => {
17370
+ const entry = captured.get(key);
17371
+ if (!entry)
17372
+ return;
17373
+ entry.update((current) => {
17374
+ const settings = current.modelSettings;
17375
+ return settings?.model === entry.model && current.modelSettingsPersistAsDefault === false ? {
17376
+ ...current,
17377
+ modelSettings: entry.original.modelSettings,
17378
+ modelSettingsPersistAsDefault: entry.original.modelSettingsPersistAsDefault,
17379
+ isManuallyChanged: entry.original.isManuallyChanged
17380
+ } : current;
17381
+ });
17382
+ captured.delete(key);
17383
+ };
17384
+ return {
17385
+ has(key) {
17386
+ return captured.has(key);
17387
+ },
17388
+ apply(key, binding, model2) {
17389
+ if (model2 === null) {
17390
+ restore(key);
17391
+ return;
17392
+ }
17393
+ const { update, usesAccountPreferences } = binding;
17394
+ update((current) => {
17395
+ const previous = captured.get(key);
17396
+ captured.set(key, { update, original: previous?.original ?? current, model: model2 });
17397
+ const settings = current.modelSettings;
17398
+ if (settings?.model === model2 && settings.usesAccountPreferences === usesAccountPreferences && current.modelSettingsPersistAsDefault === false)
17399
+ return current;
17400
+ return {
17401
+ ...current,
17402
+ isManuallyChanged: true,
17403
+ modelSettingsPersistAsDefault: false,
17404
+ modelSettings: {
17405
+ ...settings,
17406
+ model: model2,
17407
+ reasoningEffort: settings?.reasoningEffort ?? null,
17408
+ profile: settings?.profile ?? null,
17409
+ usesAccountPreferences
17410
+ }
17411
+ };
17412
+ });
17413
+ },
17414
+ dispose() {
17415
+ for (const key of captured.keys())
17416
+ restore(key);
17417
+ }
17418
+ };
17419
+ }
17420
+
17421
+ // ../desktop-control/dist/renderer-native-schedule-form.js
17422
+ var record4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
17423
+ function ancestors(element) {
17424
+ if (!record4(element))
17425
+ return [];
17426
+ const key = Object.getOwnPropertyNames(element).find((name) => name.startsWith("__reactFiber$"));
17427
+ return committedReactAncestors(key ? Object.getOwnPropertyDescriptor(element, key)?.value : null);
17428
+ }
17429
+ function readNativeScheduleForm(form) {
17430
+ const candidates = ancestors(form).flatMap(({ memoizedProps: props2 }) => {
17431
+ 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")
17432
+ return [];
17433
+ return [props2];
17434
+ });
17435
+ const props = candidates[0];
17436
+ if (!props || candidates.some((other) => other.draft !== props.draft || other.onChange !== props.onChange || other.onSubmit !== props.onSubmit))
17437
+ return null;
17438
+ const draft = props.draft;
17439
+ const change = props.onChange;
17440
+ 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);
17441
+ return {
17442
+ selection: {
17443
+ model: draft.model,
17444
+ reasoningEffort: draft.reasoningEffort
17445
+ },
17446
+ supportsExternal,
17447
+ hasTarget: draft.targetThreadId != null,
17448
+ isSaving: props.isSaving,
17449
+ title: (typeof draft.name === "string" ? draft.name.trim() : "") || String(draft.prompt).trim().replace(/\s+/gu, " ").slice(0, 80),
17450
+ targetThreadId: typeof draft.targetThreadId === "string" ? draft.targetThreadId : null,
17451
+ setTargetThread(threadId, expectedModel) {
17452
+ if (!supportsExternal || props.isSaving || draft.targetThreadId != null || !threadId || !expectedModel.startsWith("codexhost/plugin-v1@"))
17453
+ return;
17454
+ change((current) => current.id == null && current.targetThreadId == null && current.kind === "heartbeat" && current.cloudTeam == null && current.model === expectedModel ? { ...current, targetThreadId: threadId } : current);
17455
+ },
17456
+ setModel(selection) {
17457
+ if (props.isSaving || draft.targetThreadId != null)
17458
+ return;
17459
+ change((current) => current.id == null && current.targetThreadId == null && current.kind === draft.kind ? { ...current, ...selection } : current);
17460
+ }
17461
+ };
17462
+ }
17463
+ function nativeScheduleModelRows(form) {
17464
+ const rows = /* @__PURE__ */ new Set();
17465
+ for (const button2 of form.querySelectorAll("button")) {
17466
+ let host = null;
17467
+ for (const fiber of ancestors(button2)) {
17468
+ const node = fiber.stateNode;
17469
+ if (node === form)
17470
+ break;
17471
+ 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))
17472
+ host = node;
17473
+ const props = fiber.memoizedProps;
17474
+ const label = record4(props) && record4(props.label) ? props.label.props : null;
17475
+ if (record4(label) && ["inbox.automations.model.label", "automations.configuration.effort"].includes(String(label.id))) {
17476
+ if (host)
17477
+ rows.add(host);
17478
+ break;
17479
+ }
17480
+ }
17481
+ }
17482
+ return [...rows];
17483
+ }
17484
+
17485
+ // ../desktop-control/dist/renderer-host-discovery.js
17486
+ function requestManagerFromHookState(value, hostId2) {
17487
+ const record10 = (candidate) => typeof candidate === "object" && candidate !== null;
17488
+ const manager = (candidate) => {
17489
+ if (!record10(candidate) || !record10(candidate.requestClient) || !record10(candidate.prewarmedThreadManager))
17490
+ return null;
17491
+ const bridge = candidate.requestClient;
17492
+ return typeof candidate.sendRequest === "function" && typeof bridge.sendRequest === "function" && typeof bridge.prewarmThreadStart === "function" && typeof bridge.enqueueRequest === "function" && typeof candidate.prewarmedThreadManager.discardAllPrewarmedThreads === "function" ? candidate : null;
17493
+ };
17494
+ if (!record10(value))
17495
+ return null;
17496
+ const direct = manager(value) ?? manager(value.manager);
17497
+ if (direct)
17498
+ return direct;
17499
+ if (!hostId2 || typeof value.addManager !== "function" || typeof value.getForHostId !== "function")
17500
+ return null;
17501
+ try {
17502
+ return manager(value.getForHostId(hostId2));
17503
+ } catch {
17504
+ return null;
17505
+ }
17506
+ }
17507
+ function discoverRendererHosts(root, ancestors2 = committedReactAncestors, managerFrom = requestManagerFromHookState) {
17508
+ const editors = [
17509
+ ...root.querySelectorAll('[data-codex-composer], [contenteditable="true"][role="textbox"]')
17510
+ ];
17511
+ const hostIds = /* @__PURE__ */ new Set();
17512
+ const managers = /* @__PURE__ */ new Set();
17513
+ const registries = /* @__PURE__ */ new Set();
17514
+ const fibers = /* @__PURE__ */ new Set();
17515
+ for (const editor of editors) {
17516
+ let element = editor;
17517
+ let fiber;
17518
+ while (element && !fiber) {
17519
+ const key = Object.getOwnPropertyNames(element).find((name) => name.startsWith("__reactFiber$"));
17520
+ if (key)
17521
+ fiber = Object.getOwnPropertyDescriptor(element, key)?.value;
17522
+ element = element.parentElement ?? null;
17523
+ }
17524
+ for (const current of ancestors2(fiber)) {
17525
+ fibers.add(current);
17526
+ const props = current.memoizedProps;
17527
+ for (const key of ["executionTargetHostId", "permissionsHostId"]) {
17528
+ const hostId2 = props?.[key];
17529
+ if (typeof hostId2 === "string" && hostId2)
17530
+ hostIds.add(hostId2);
17531
+ }
17532
+ }
17533
+ }
17534
+ for (const fiber of fibers) {
17535
+ let hook = fiber.memoizedState;
17536
+ for (let index = 0; hook && index < 120; index += 1) {
17537
+ const value = hook.memoizedState;
17538
+ const manager = managerFrom(value);
17539
+ if (manager)
17540
+ managers.add(manager);
17541
+ if (value && typeof value === "object" && "addManager" in value && typeof value.addManager === "function" && "getForHostId" in value && typeof value.getForHostId === "function") {
17542
+ registries.add(value);
17543
+ }
17544
+ hook = hook.next && typeof hook.next === "object" ? hook.next : null;
17545
+ }
17546
+ }
17547
+ return {
17548
+ editorCount: editors.length,
17549
+ hostIds: [...hostIds],
17550
+ managers: [...managers],
17551
+ registries: [...registries]
17552
+ };
17553
+ }
17554
+
17555
+ // ../desktop-control/dist/renderer-host-rpc-discovery.js
17556
+ function findRendererHostRpcFamily(store) {
17557
+ const record10 = (value) => typeof value === "object" && value !== null;
17558
+ const families = /* @__PURE__ */ new Set();
17559
+ for (const [definition, members] of store.familyBindings) {
17560
+ if (!record10(definition) || definition.kind !== "signal-family")
17561
+ continue;
17562
+ if (!record10(members) || typeof members.get !== "function")
17563
+ continue;
17564
+ for (const [hostId2, member] of members) {
17565
+ if (typeof hostId2 !== "string" || !record10(member))
17566
+ continue;
17567
+ const signal = member.value;
17568
+ if (!record10(signal) || typeof signal.get !== "function")
17569
+ continue;
17570
+ let value;
17571
+ try {
17572
+ value = signal.get();
17573
+ } catch {
17574
+ continue;
17575
+ }
17576
+ if (record10(value) && Object.keys(value).length === 2 && typeof value.status === "string" && record10(value.client) && value.client.hostId === hostId2 && "rpc" in value.client) {
17577
+ families.add(members);
17578
+ break;
17579
+ }
17580
+ }
17581
+ }
17582
+ if (families.size !== 1)
17583
+ return null;
17584
+ return { store, family: families.values().next().value };
17585
+ }
17586
+ function resolveRendererHostRpc(discovery, hostId2) {
17587
+ const record10 = (value2) => typeof value2 === "object" && value2 !== null;
17588
+ const signal = discovery.family.get(hostId2)?.value;
17589
+ if (!record10(signal) || typeof signal.get !== "function")
17590
+ return null;
17591
+ let value;
17592
+ try {
17593
+ value = signal.get();
17594
+ } catch {
17595
+ return null;
17596
+ }
17597
+ if (!record10(value) || value.status !== "ready" || !record10(value.client) || value.client.hostId !== hostId2)
17598
+ return null;
17599
+ const rpc = value.client.rpc;
17600
+ return typeof rpc === "function" || record10(rpc) ? rpc : null;
17601
+ }
17602
+
17603
+ // ../desktop-control/dist/renderer-schedule-workspace-rpc.js
17604
+ var record5 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
17605
+ function localAppScope(root) {
17606
+ const scopes = /* @__PURE__ */ new Map();
17607
+ const seen = /* @__PURE__ */ new Set();
17608
+ for (const main of root.querySelectorAll("main")) {
17609
+ const keys = Object.getOwnPropertyNames(main).filter((key2) => key2.startsWith("__reactFiber$"));
17610
+ const key = keys[0];
17611
+ if (keys.length !== 1 || !key)
17612
+ continue;
17613
+ for (const fiber of committedReactAncestors(Reflect.get(main, key))) {
17614
+ if (seen.has(fiber))
17615
+ break;
17616
+ seen.add(fiber);
17617
+ let hook = fiber.memoizedState;
17618
+ for (let n = 0; record5(hook) && "next" in hook && n < 150; n++, hook = hook.next) {
17619
+ const handle = record5(hook.memoizedState) ? hook.memoizedState.current : null;
17620
+ if (!record5(handle) || !record5(handle.node) || handle.node.parent != null || !("chain" in handle) || !("scope" in handle) || typeof handle.get !== "function" || typeof handle.set !== "function" || typeof handle.watch !== "function" || !(handle.node.familyBindings instanceof Map))
17621
+ continue;
17622
+ scopes.set(handle.node, { handle, store: handle.node });
17623
+ }
17624
+ }
17625
+ }
17626
+ const scope = scopes.values().next().value;
17627
+ if (scopes.size !== 1 || !scope)
17628
+ throw new Error("Native local app scope is missing or ambiguous");
17629
+ const discovery = findRendererHostRpcFamily(scope.store);
17630
+ const rpc = discovery && resolveRendererHostRpc(discovery, "local");
17631
+ if (!discovery || !rpc)
17632
+ throw new Error("Native local app RPC is unavailable");
17633
+ return { ...scope, discovery, rpc };
17634
+ }
17635
+ async function createRpcScheduleWorkspaceThread(root, routing, route, createThread, input, signal) {
17636
+ if (!route.policy.scopedCreation)
17637
+ throw new Error("Native local chat creation is unavailable");
17638
+ const scope = localAppScope(root);
17639
+ const assertConnection = () => {
17640
+ if (routing.forHost("local")?.manager !== route.manager || resolveRendererHostRpc(scope.discovery, "local") !== scope.rpc)
17641
+ throw new Error("The local connection changed. Reopen the task dialog.");
17642
+ };
17643
+ const assertCurrent = () => {
17644
+ signal.throwIfAborted();
17645
+ assertConnection();
17646
+ };
17647
+ const request = async (method, params) => {
17648
+ assertConnection();
17649
+ return route.manager.sendRequest(method, params);
17650
+ };
17651
+ const readEmpty = async (threadId) => {
17652
+ const read = await request("thread/read", { threadId, includeTurns: false });
17653
+ if (!record5(read) || !record5(read.thread) || read.thread.id !== threadId || !record5(read.thread.status))
17654
+ throw new Error("The created chat could not be read");
17655
+ const turns = await request("thread/turns/list", { threadId, cursor: null, limit: 1 });
17656
+ const queue = await request("thread/queue/list", { threadId, cursor: null, limit: 1 });
17657
+ if (!record5(turns) || !Array.isArray(turns.data) || !("nextCursor" in turns) || !record5(queue) || !Array.isArray(queue.data) || !("nextCursor" in queue))
17658
+ throw new Error("The created chat's history or queue could not be confirmed");
17659
+ return {
17660
+ thread: read.thread,
17661
+ empty: read.thread.status.type === "idle" && turns.data.length === 0 && turns.nextCursor === null && queue.data.length === 0 && queue.nextCursor === null
17662
+ };
17663
+ };
17664
+ assertCurrent();
17665
+ let createdId = null;
17666
+ let retained = false;
17667
+ let failed = false;
17668
+ let cleanup;
17669
+ const discard = () => {
17670
+ if (!createdId || retained)
17671
+ return Promise.resolve();
17672
+ const threadId = createdId;
17673
+ return cleanup ??= (async () => {
17674
+ const { empty } = await readEmpty(threadId);
17675
+ if (!empty || retained)
17676
+ return;
17677
+ await request("thread/archive", { threadId });
17678
+ })();
17679
+ };
17680
+ const discardAfterDismissal = () => {
17681
+ void discard().catch((error51) => {
17682
+ console.error("Could not discard the unsubmitted schedule chat. Check the chat list.", error51);
17683
+ });
17684
+ };
17685
+ signal.addEventListener("abort", discardAfterDismissal, { once: true });
17686
+ const remember = (result) => {
17687
+ if (!record5(result) || result.status !== "created")
17688
+ return;
17689
+ const id = hostThreadIdSchema.safeParse(result.conversationId);
17690
+ if (!id.success)
17691
+ return;
17692
+ if (createdId && createdId !== id.data)
17693
+ throw new Error("Chat creation returned conflicting identities");
17694
+ createdId = id.data;
17695
+ if (signal.aborted || failed)
17696
+ discardAfterDismissal();
17697
+ };
17698
+ try {
17699
+ const output = await createThread({
17700
+ scope: scope.handle,
17701
+ target: { type: "project", projectId: input.workspace.id, environment: { type: "local" } },
17702
+ model: input.model,
17703
+ title: input.title,
17704
+ prompt: "",
17705
+ startWithoutFirstTurn: true,
17706
+ assertRequestCurrent: assertCurrent,
17707
+ onSettled: remember
17708
+ });
17709
+ const result = record5(output) && output.kind === "creation" ? output.result : null;
17710
+ remember(result);
17711
+ assertCurrent();
17712
+ if (!record5(result) || result.status !== "created" || !createdId || !record5(result.firstTurn) || result.firstTurn.status !== "not-requested")
17713
+ throw new Error("Chat creation was not confirmed. Check the chat list before creating another task.");
17714
+ const { thread, empty } = await readEmpty(createdId);
17715
+ const inspection = threadInspectionSchema.parse(await request("codexhost/thread/inspect", { threadId: createdId }));
17716
+ assertCurrent();
17717
+ if (!empty || thread.cwd !== input.workspace.cwd || inspection.owner !== "external" || inspection.transportModelId !== input.model)
17718
+ throw new Error("The created chat's workspace, Model or empty state could not be confirmed");
17719
+ return {
17720
+ threadId: createdId,
17721
+ discard,
17722
+ retain() {
17723
+ retained = true;
17724
+ signal.removeEventListener("abort", discardAfterDismissal);
17725
+ }
17726
+ };
17727
+ } catch (error51) {
17728
+ failed = true;
17729
+ try {
17730
+ await discard();
17731
+ } catch (cleanupError) {
17732
+ throw new Error(`${error51 instanceof Error ? error51.message : String(error51)}; Chat cleanup failed: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. Check the chat list.`);
17733
+ }
17734
+ throw error51;
17735
+ }
17736
+ }
17737
+
17738
+ // ../desktop-control/dist/renderer-schedule-workspace.js
17739
+ var record6 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
17740
+ function readNativeScheduleWorkspaces(root) {
17741
+ const projects = /* @__PURE__ */ new Map();
17742
+ const ambiguous = /* @__PURE__ */ new Set();
17743
+ const seen = /* @__PURE__ */ new Set();
17744
+ const add = (value) => {
17745
+ if (!record6(value) || value.source !== "codex" || !record6(value.group))
17746
+ return;
17747
+ const group = value.group;
17748
+ 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"))
17749
+ return;
17750
+ const next = { id: group.projectId, label: group.label || group.path, cwd: group.path };
17751
+ const previous = projects.get(next.id);
17752
+ if (previous && previous.cwd !== next.cwd)
17753
+ ambiguous.add(next.id);
17754
+ else
17755
+ projects.set(next.id, next);
17756
+ };
17757
+ for (const element of root.querySelectorAll("aside [data-sidebar-cycle-item]")) {
17758
+ const keys = Object.getOwnPropertyNames(element).filter((key2) => key2.startsWith("__reactFiber$"));
17759
+ const key = keys[0];
17760
+ if (keys.length !== 1 || !key)
17761
+ continue;
17762
+ for (const fiber of committedReactAncestors(Reflect.get(element, key))) {
17763
+ if (seen.has(fiber))
17764
+ break;
17765
+ seen.add(fiber);
17766
+ const props = fiber.memoizedProps;
17767
+ if (!record6(props))
17768
+ continue;
17769
+ add(props.project);
17770
+ if (props.projectByKey instanceof Map)
17771
+ for (const project3 of props.projectByKey.values())
17772
+ add(project3);
17773
+ }
17774
+ }
17775
+ return [...projects.values()].filter(({ id }) => !ambiguous.has(id));
17776
+ }
17777
+ function isNativeProjectThreadCreator(value) {
17778
+ try {
17779
+ if (typeof value !== "function" || value.length !== 1)
17780
+ return false;
17781
+ const source = Function.prototype.toString.call(value);
17782
+ 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");
17783
+ } catch {
17784
+ return false;
17785
+ }
17786
+ }
17787
+ async function createNativeScheduleWorkspaceThread(root, routing, createThread, input, signal) {
17788
+ if (!decodeHarnessPluginRoute(input.model))
17789
+ throw new Error("An external Harness is required");
17790
+ const route = routing.forHost("local");
17791
+ if (route && Reflect.get(route.manager, "kind") === "main-process-rpc") {
17792
+ if (!readNativeScheduleWorkspaces(root).some(({ id, cwd }) => id === input.workspace.id && cwd === input.workspace.cwd))
17793
+ throw new Error("The selected workspace is no longer available");
17794
+ return createRpcScheduleWorkspaceThread(root, routing, route, createThread, input, signal);
17795
+ }
17796
+ const manager = route?.manager;
17797
+ if (!route?.policy.scopedCreation || !manager || typeof manager.getConversation !== "function" || typeof manager.archiveConversation !== "function")
17798
+ throw new Error("Native local chat creation is unavailable");
17799
+ const discovery = discoverRendererHosts({
17800
+ querySelectorAll: () => root.querySelectorAll("main")
17801
+ });
17802
+ const scopes = new Set(discovery.registries.flatMap((registry2) => {
17803
+ try {
17804
+ return registry2.getForHostId("local") === manager ? [Reflect.get(registry2, "scope")] : [];
17805
+ } catch {
17806
+ return [];
17807
+ }
17808
+ }));
17809
+ const scope = scopes.values().next().value;
17810
+ if (scopes.size !== 1 || !record6(scope) || typeof scope.get !== "function")
17811
+ throw new Error("Native local chat scope is missing or ambiguous");
17812
+ if (!readNativeScheduleWorkspaces(root).some(({ id, cwd }) => id === input.workspace.id && cwd === input.workspace.cwd))
17813
+ throw new Error("The selected workspace is no longer available");
17814
+ signal.throwIfAborted();
17815
+ let createdId = null;
17816
+ let released = false;
17817
+ const discard = () => {
17818
+ if (!createdId || released)
17819
+ return;
17820
+ const id = createdId;
17821
+ released = true;
17822
+ const conversation2 = manager.getConversation(id);
17823
+ if (!record6(conversation2) || !Array.isArray(conversation2.turns) || conversation2.turns.length || Array.isArray(conversation2.requests) && conversation2.requests.length > 0 || conversation2.pendingRequest != null)
17824
+ return;
17825
+ void Promise.resolve().then(() => manager.archiveConversation(id, {
17826
+ useAppServerPins: false,
17827
+ source: "automation_history"
17828
+ })).catch(() => void 0);
17829
+ };
17830
+ signal.addEventListener("abort", discard, { once: true });
17831
+ const remember = (result2) => {
17832
+ if (!record6(result2) || result2.status !== "created")
17833
+ return;
17834
+ const id = hostThreadIdSchema.safeParse(result2.conversationId);
17835
+ if (id.success)
17836
+ createdId = id.data;
17837
+ if (signal.aborted)
17838
+ discard();
17839
+ };
17840
+ const output = await createThread({
17841
+ scope,
17842
+ target: { type: "project", projectId: input.workspace.id, environment: { type: "local" } },
17843
+ model: input.model,
17844
+ title: input.title,
17845
+ prompt: "",
17846
+ startWithoutFirstTurn: true,
17847
+ onSettled: remember
17848
+ });
17849
+ const result = record6(output) && output.kind === "creation" ? output.result : null;
17850
+ remember(result);
17851
+ signal.throwIfAborted();
17852
+ if (!record6(result) || result.status !== "created" || !createdId || !record6(result.firstTurn) || result.firstTurn.status !== "not-requested")
17853
+ throw new Error("Chat creation was not confirmed. Check the chat list before creating another task.");
17854
+ if (routing.forHost("local")?.manager !== route.manager)
17855
+ throw new Error("The local connection changed. Reopen the task dialog.");
17856
+ const conversation = manager.getConversation(createdId);
17857
+ const mode = record6(conversation) ? conversation.latestCollaborationMode : null;
17858
+ if (!record6(conversation) || conversation.cwd !== input.workspace.cwd || !record6(mode) || !record6(mode.settings) || mode.settings.model !== input.model)
17859
+ throw new Error("The created chat's workspace or Model could not be confirmed");
17860
+ return {
17861
+ threadId: createdId,
17862
+ retain() {
17863
+ released = true;
17864
+ signal.removeEventListener("abort", discard);
17865
+ }
17866
+ };
17867
+ }
17868
+
17258
17869
  // src/renderer-composer-kind.ts
17259
17870
  function orbitComposerKind(composer) {
17260
17871
  let element = composer.querySelector('[contenteditable="true"], textarea, [role="textbox"]') ?? composer;
@@ -17534,6 +18145,16 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17534
18145
  ["path", { d: "M12 13.5V8" }]
17535
18146
  ];
17536
18147
 
18148
+ // ../../node_modules/lucide/dist/esm/icons/calendar-clock.mjs
18149
+ var CalendarClock = [
18150
+ ["path", { d: "M16 14v2.2l1.6 1" }],
18151
+ ["path", { d: "M16 2v3" }],
18152
+ ["path", { d: "M21 7.338V5a2 2 0 00-2-2H5a2 2 0 00-2 2v14a2 2 0 002 2h2.338" }],
18153
+ ["path", { d: "M3 9h5.859" }],
18154
+ ["path", { d: "M8 2v3" }],
18155
+ ["circle", { cx: "16", cy: "16", r: "6" }]
18156
+ ];
18157
+
17537
18158
  // ../../node_modules/lucide/dist/esm/icons/circle-check.mjs
17538
18159
  var CircleCheck = [
17539
18160
  ["circle", { cx: "12", cy: "12", r: "10" }],
@@ -17839,6 +18460,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17839
18460
  "routes",
17840
18461
  "gateway",
17841
18462
  "updates",
18463
+ "schedules",
17842
18464
  "about",
17843
18465
  "info",
17844
18466
  "external-link",
@@ -17890,6 +18512,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17890
18512
  routes: Route,
17891
18513
  gateway: Network,
17892
18514
  updates: CircleArrowUp,
18515
+ schedules: CalendarClock,
17893
18516
  about: Info,
17894
18517
  info: Info,
17895
18518
  "external-link": ExternalLink,
@@ -19680,7 +20303,6 @@ ${messages.harnessVersionLatest}: ${harnessVersionLabel(version2.state, messages
19680
20303
  updateLatestVersion: "Latest version",
19681
20304
  updateUpToDate: "You are up to date.",
19682
20305
  updateAvailable: "A new version is available.",
19683
- updateWindowsManualRequired: "Automatic updates are unavailable on Windows. Update manually below.",
19684
20306
  updateAndRestart: "Update",
19685
20307
  updateChecking: "Checking for updates...",
19686
20308
  updateDownloading: "Downloading update...",
@@ -19695,8 +20317,7 @@ ${messages.harnessVersionLatest}: ${harnessVersionLabel(version2.state, messages
19695
20317
  updateFailed: "Update failed.",
19696
20318
  updateRetry: "Retry",
19697
20319
  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.",
20320
+ updateWindowsInstallerDescription: "To update manually, download and run the installer for this system.",
19700
20321
  updateManualTitle: "Manual update",
19701
20322
  updateManualFallbackDescription: "The automatic update did not complete. Run this command in a terminal instead, then quit Codex and relaunch it with codexhost.",
19702
20323
  updateCopyCommand: "Copy",
@@ -19961,7 +20582,6 @@ ${messages.harnessVersionLatest}: ${harnessVersionLabel(version2.state, messages
19961
20582
  updateLatestVersion: "\u6700\u65B0\u7248\u672C",
19962
20583
  updateUpToDate: "\u5F53\u524D\u5DF2\u662F\u6700\u65B0\u7248\u672C\u3002",
19963
20584
  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
20585
  updateAndRestart: "\u66F4\u65B0",
19966
20586
  updateChecking: "\u6B63\u5728\u68C0\u67E5\u66F4\u65B0...",
19967
20587
  updateDownloading: "\u6B63\u5728\u4E0B\u8F7D\u66F4\u65B0...",
@@ -19976,8 +20596,7 @@ ${messages.harnessVersionLatest}: ${harnessVersionLabel(version2.state, messages
19976
20596
  updateFailed: "\u66F4\u65B0\u5931\u8D25\u3002",
19977
20597
  updateRetry: "\u91CD\u8BD5",
19978
20598
  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",
20599
+ 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
20600
  updateManualTitle: "\u624B\u52A8\u66F4\u65B0",
19982
20601
  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
20602
  updateCopyCommand: "\u590D\u5236",
@@ -24123,13 +24742,13 @@ Codex Fast mode prioritizes requests and may increase usage.`
24123
24742
  (name) => name.startsWith("__reactFiber$")
24124
24743
  );
24125
24744
  if (key) {
24126
- const ancestors = committedReactAncestors(
24745
+ const ancestors2 = committedReactAncestors(
24127
24746
  Object.getOwnPropertyDescriptor(element, key)?.value
24128
24747
  );
24129
24748
  const scopes = [];
24130
- ancestors.forEach(({ memoizedProps: props }, index) => {
24749
+ ancestors2.forEach(({ memoizedProps: props }, index) => {
24131
24750
  if (isRecord3(props) && "onLocalSubmitStart" in props && typeof props.submitDisabled === "boolean") {
24132
- scopes.push({ owner: ancestors[index], fibers: ancestors.slice(0, index + 1) });
24751
+ scopes.push({ owner: ancestors2[index], fibers: ancestors2.slice(0, index + 1) });
24133
24752
  }
24134
24753
  });
24135
24754
  const valid = scopes.filter((scope) => {
@@ -25386,10 +26005,72 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25386
26005
  };
25387
26006
  }
25388
26007
 
26008
+ // src/renderer-thread-reference-persistence.ts
26009
+ var record7 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
26010
+ var SYNC_TIMEOUT_MS = 2e3;
26011
+ function restoreRpcThreadReferenceCapability(client, messages, isCurrent) {
26012
+ if (!record7(messages) || !record7(messages.electronBridge)) return client;
26013
+ const bridge = messages.electronBridge;
26014
+ const send = bridge.sendMessageFromView;
26015
+ if (typeof send !== "function") return client;
26016
+ const inspect = client.inspectThread.bind(client);
26017
+ const checked = /* @__PURE__ */ new Set();
26018
+ const isMissing = (key) => new Promise((resolve) => {
26019
+ const finish = (missing) => {
26020
+ clearTimeout(timer);
26021
+ messages.removeEventListener("message", listener);
26022
+ resolve(missing);
26023
+ };
26024
+ const listener = (event) => {
26025
+ if (event.source != null && event.source !== messages) return;
26026
+ const message2 = event.data;
26027
+ if (!record7(message2) || message2.type !== "persisted-atom-sync" || !record7(message2.state))
26028
+ return;
26029
+ finish(!Object.hasOwn(message2.state, key));
26030
+ };
26031
+ const timer = setTimeout(() => finish(false), SYNC_TIMEOUT_MS);
26032
+ messages.addEventListener("message", listener);
26033
+ try {
26034
+ Promise.resolve(
26035
+ send.call(bridge, { type: "persisted-atom-sync-request", responsePriority: "critical" })
26036
+ ).catch(() => finish(false));
26037
+ } catch {
26038
+ finish(false);
26039
+ }
26040
+ });
26041
+ const inspectThread = async (input) => {
26042
+ if (!isCurrent() || checked.has(input.threadId)) return inspect(input);
26043
+ checked.add(input.threadId);
26044
+ const key = `thread-reference-capability:${input.threadId}`;
26045
+ if (!await isMissing(key) || !isCurrent()) return inspect(input);
26046
+ let proven = true;
26047
+ const result = await inspect({ ...input, includeReferenceCapability: true }).catch(() => {
26048
+ proven = false;
26049
+ return inspect(input);
26050
+ });
26051
+ if (proven && result.owner === "codex" && result.supportsThreadReferences === true && isCurrent() && await isMissing(key) && isCurrent()) {
26052
+ try {
26053
+ await send.call(bridge, {
26054
+ type: "persisted-atom-update",
26055
+ key,
26056
+ value: true,
26057
+ deleted: false
26058
+ });
26059
+ } catch {
26060
+ }
26061
+ }
26062
+ return result;
26063
+ };
26064
+ return Object.freeze({ ...client, inspectThread });
26065
+ }
26066
+
25389
26067
  // src/renderer-thread-reference-capability.ts
25390
- var record4 = (value) => typeof value === "object" && value !== null;
25391
- function restoreThreadReferenceCapability(client, manager, isCurrent) {
25392
- if (!record4(manager) || !record4(manager.storage)) return client;
26068
+ var record8 = (value) => typeof value === "object" && value !== null;
26069
+ function restoreThreadReferenceCapability(client, manager, isCurrent, messages = null) {
26070
+ if (record8(manager) && manager.kind === "main-process-rpc") {
26071
+ return restoreRpcThreadReferenceCapability(client, messages, isCurrent);
26072
+ }
26073
+ if (!record8(manager) || !record8(manager.storage)) return client;
25393
26074
  const storage = manager.storage;
25394
26075
  const read = storage.readValue;
25395
26076
  const write = storage.writeValue;
@@ -25424,14 +26105,14 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25424
26105
  }
25425
26106
 
25426
26107
  // src/renderer-thread-reference-context.ts
25427
- var record5 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
26108
+ var record9 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
25428
26109
  function createThreadReferenceContext(manager, hostId2, isCurrent) {
25429
26110
  const prepared = /* @__PURE__ */ new WeakMap();
25430
26111
  return (params) => {
25431
- if (hostId2 === "local" || !record5(manager) || typeof manager.getConversation !== "function" || !record5(params) || typeof params.threadId !== "string")
26112
+ if (hostId2 === "local" || !record9(manager) || typeof manager.getConversation !== "function" || !record9(params) || typeof params.threadId !== "string")
25432
26113
  return params;
25433
26114
  const conversation = manager.getConversation.call(manager, params.threadId);
25434
- if (!record5(conversation) || conversation.id !== params.threadId || conversation.modelProvider !== "codexhost")
26115
+ if (!record9(conversation) || conversation.id !== params.threadId || conversation.modelProvider !== "codexhost")
25435
26116
  return params;
25436
26117
  if (!isCurrent()) throw new Error("Thread reference connection is no longer available");
25437
26118
  const cached2 = prepared.get(params);
@@ -25537,7 +26218,8 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25537
26218
  const client = restoreThreadReferenceCapability(
25538
26219
  nativeClient,
25539
26220
  target,
25540
- () => !disposed && readRouting()?.forHost(route.hostId) === route
26221
+ () => !disposed && readRouting()?.forHost(route.hostId) === route,
26222
+ messages
25541
26223
  );
25542
26224
  entries.set(route.hostId, { route, client, cleanups });
25543
26225
  try {
@@ -25681,6 +26363,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25681
26363
  var SIDEBAR_THREAD_ID_ATTRIBUTE = "data-app-action-sidebar-thread-id";
25682
26364
  var SIDEBAR_THREAD_HOST_ID_ATTRIBUTE = "data-app-action-sidebar-thread-host-id";
25683
26365
  var SIDEBAR_AGENT_ICON_ATTRIBUTE = "data-codexhost-sidebar-agent-icon";
26366
+ var SIDEBAR_AGENT_ICON_ROW_SELECTOR = `${SIDEBAR_THREAD_ROW_SELECTOR}, ${NATIVE_SCHEDULE_SIDEBAR_ROW_SELECTOR}`;
25684
26367
  var OWNERSHIP_RETRY_DELAYS_MS = [100, 300, 800, 1500, 3e3];
25685
26368
  function isRecord10(value) {
25686
26369
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -25726,7 +26409,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25726
26409
  return candidates.size === 1 ? candidates.values().next().value ?? null : null;
25727
26410
  }
25728
26411
  function rendererAgentForThreadOwnership(ownership) {
25729
- if (ownership.owner === "codex") return null;
26412
+ if (ownership.owner === "codex") return "codex";
25730
26413
  return ownership.harnessId;
25731
26414
  }
25732
26415
  function sidebarAgentIconAnchor(titleTrigger, title) {
@@ -25744,22 +26427,30 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25744
26427
  this.element = element;
25745
26428
  }
25746
26429
  element;
26430
+ #scheduledThread;
25747
26431
  isConnected() {
25748
26432
  return this.element.isConnected;
25749
26433
  }
25750
26434
  hostId() {
25751
- return sidebarThreadAttributes(this.element)?.hostId ?? null;
26435
+ const attributes = sidebarThreadAttributes(this.element);
26436
+ this.#scheduledThread = attributes ? void 0 : readNativeScheduleSidebarThread(this.element);
26437
+ return attributes?.hostId ?? (this.#scheduledThread ? "local" : null);
25752
26438
  }
25753
26439
  threadId() {
25754
- return threadIdFromSidebarRowElement(this.element);
26440
+ const threadId = sidebarThreadAttributes(this.element) ? threadIdFromSidebarRowElement(this.element) : this.#scheduledThread !== void 0 ? this.#scheduledThread : readNativeScheduleSidebarThread(this.element);
26441
+ this.#scheduledThread = void 0;
26442
+ return threadId;
25755
26443
  }
25756
26444
  draftId() {
25757
26445
  return draftIdFromSidebarRowElement(this.element);
25758
26446
  }
25759
26447
  render(agent, plugin) {
25760
26448
  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]");
26449
+ const scheduled = !this.element.hasAttribute(SIDEBAR_THREAD_ROW_ATTRIBUTE) && this.element.matches(NATIVE_SCHEDULE_SIDEBAR_ROW_SELECTOR);
26450
+ const titleTrigger = scheduled ? this.element : this.element.querySelector("[data-thread-title-trigger]");
26451
+ const title = scheduled ? [...this.element.querySelectorAll("[data-thread-title][id]")].find(
26452
+ (node) => node.id === this.element.getAttribute("aria-labelledby")
26453
+ ) : titleTrigger?.querySelector("[data-thread-title]");
25763
26454
  if (!titleTrigger || !title) {
25764
26455
  this.clear();
25765
26456
  return;
@@ -25808,7 +26499,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25808
26499
  row = new BrowserSidebarAgentIconRow(element);
25809
26500
  this.#rowsByElement.set(element, row);
25810
26501
  }
25811
- if (element.isConnected && element.matches(SIDEBAR_THREAD_ROW_SELECTOR))
26502
+ if (element.isConnected && element.matches(SIDEBAR_AGENT_ICON_ROW_SELECTOR))
25812
26503
  this.#trackedRows.add(row);
25813
26504
  else this.#trackedRows.delete(row);
25814
26505
  return row;
@@ -25817,7 +26508,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25817
26508
  for (const row of this.#trackedRows) {
25818
26509
  if (!row.isConnected()) this.#trackedRows.delete(row);
25819
26510
  }
25820
- return [...this.root.querySelectorAll(SIDEBAR_THREAD_ROW_SELECTOR)].map(
26511
+ return [...this.root.querySelectorAll(SIDEBAR_AGENT_ICON_ROW_SELECTOR)].map(
25821
26512
  (element) => this.#row(element)
25822
26513
  );
25823
26514
  }
@@ -25826,13 +26517,14 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25826
26517
  const changed = /* @__PURE__ */ new Set();
25827
26518
  const collect = (node) => {
25828
26519
  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))
26520
+ if (node.matches(SIDEBAR_AGENT_ICON_ROW_SELECTOR))
26521
+ changed.add(this.#row(node));
26522
+ for (const element of node.querySelectorAll(SIDEBAR_AGENT_ICON_ROW_SELECTOR))
25831
26523
  changed.add(this.#row(element));
25832
26524
  };
25833
26525
  for (const mutation of mutations) {
25834
26526
  const target = mutation.target instanceof Element ? mutation.target : mutation.target.parentElement;
25835
- const row = target?.closest(SIDEBAR_THREAD_ROW_SELECTOR);
26527
+ const row = target?.closest(SIDEBAR_AGENT_ICON_ROW_SELECTOR);
25836
26528
  if (row) changed.add(this.#row(row));
25837
26529
  else if (target && this.#rowsByElement.has(target))
25838
26530
  changed.add(this.#row(target));
@@ -25846,7 +26538,10 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25846
26538
  attributeFilter: [
25847
26539
  SIDEBAR_THREAD_ROW_ATTRIBUTE,
25848
26540
  SIDEBAR_THREAD_ID_ATTRIBUTE,
25849
- SIDEBAR_THREAD_HOST_ID_ATTRIBUTE
26541
+ SIDEBAR_THREAD_HOST_ID_ATTRIBUTE,
26542
+ "data-sidebar-cycle-item",
26543
+ "aria-labelledby",
26544
+ "role"
25850
26545
  ],
25851
26546
  childList: true,
25852
26547
  subtree: true
@@ -25916,7 +26611,8 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25916
26611
  ownershipRetryTimers.delete(key);
25917
26612
  if (disposed) return;
25918
26613
  failed.delete(key);
25919
- ownershipByThread.delete(key);
26614
+ const cached2 = ownershipByThread.get(key);
26615
+ if (cached2) cached2.stale = true;
25920
26616
  scheduleScan(rowsByThread.get(key) ?? []);
25921
26617
  }, delay);
25922
26618
  ownershipRetryTimers.set(key, timer);
@@ -25929,7 +26625,10 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25929
26625
  if (disposed) return;
25930
26626
  for (const ownership of threads) {
25931
26627
  const key = ownershipKey(hostId2, ownership.threadId);
25932
- ownershipByThread.set(key, rendererAgentForThreadOwnership(ownership));
26628
+ ownershipByThread.set(key, {
26629
+ agent: rendererAgentForThreadOwnership(ownership),
26630
+ stale: false
26631
+ });
25933
26632
  failed.delete(key);
25934
26633
  if (ownership.owner === "codex") {
25935
26634
  provisionalCodex.add(key);
@@ -25962,6 +26661,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25962
26661
  const unresolvedByHost = /* @__PURE__ */ new Map();
25963
26662
  const pluginsByHost = /* @__PURE__ */ new Map();
25964
26663
  const getPlugin = (hostId2, agent) => {
26664
+ if (agent === "codex") return void 0;
25965
26665
  if (!pluginsByHost.has(hostId2)) pluginsByHost.set(hostId2, options.getPlugins?.(hostId2));
25966
26666
  return pluginsByHost.get(hostId2)?.find(({ id }) => id === agent);
25967
26667
  };
@@ -25987,11 +26687,10 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25987
26687
  if (localAgent !== null && localAgent !== void 0) {
25988
26688
  if (threadId.success) {
25989
26689
  const key2 = ownershipKey(hostId2, threadId.data);
25990
- ownershipByThread.set(key2, localAgent === "codex" ? null : localAgent);
26690
+ ownershipByThread.set(key2, { agent: localAgent, stale: false });
25991
26691
  clearOwnershipRetry(key2);
25992
26692
  }
25993
- if (localAgent === "codex") row.clear();
25994
- else row.render(localAgent, getPlugin(hostId2, localAgent));
26693
+ row.render(localAgent, getPlugin(hostId2, localAgent));
25995
26694
  continue;
25996
26695
  }
25997
26696
  if (!threadId.success) {
@@ -25999,13 +26698,11 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25999
26698
  continue;
26000
26699
  }
26001
26700
  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();
26701
+ const cached2 = ownershipByThread.get(key);
26702
+ if (cached2) {
26703
+ row.render(cached2.agent, getPlugin(hostId2, cached2.agent));
26704
+ if (!cached2.stale) continue;
26705
+ } else row.clear();
26009
26706
  if (!pending.has(key) && !failed.has(key)) {
26010
26707
  let unresolved = unresolvedByHost.get(hostId2);
26011
26708
  if (!unresolved) {
@@ -26045,7 +26742,10 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26045
26742
  for (const timer of ownershipRetryTimers.values()) clearTimeout(timer);
26046
26743
  ownershipRetryTimers.clear();
26047
26744
  ownershipRetryAttempts.clear();
26048
- for (const key of provisionalCodex) ownershipByThread.delete(key);
26745
+ for (const key of provisionalCodex) {
26746
+ const cached2 = ownershipByThread.get(key);
26747
+ if (cached2) cached2.stale = true;
26748
+ }
26049
26749
  provisionalCodex.clear();
26050
26750
  scheduleScan(dom.rows());
26051
26751
  },
@@ -26144,16 +26844,16 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26144
26844
  return isRecord11(value) ? value : null;
26145
26845
  }
26146
26846
  function directForkAncestors(first) {
26147
- const ancestors = [];
26847
+ const ancestors2 = [];
26148
26848
  const seen = /* @__PURE__ */ new Set();
26149
26849
  let fiber = first;
26150
- while (fiber && ancestors.length < FAST_FORK_OWNER_DEPTH) {
26850
+ while (fiber && ancestors2.length < FAST_FORK_OWNER_DEPTH) {
26151
26851
  if (seen.has(fiber)) return [];
26152
26852
  seen.add(fiber);
26153
- ancestors.push(fiber);
26853
+ ancestors2.push(fiber);
26154
26854
  fiber = isRecord11(fiber.return) ? fiber.return : null;
26155
26855
  }
26156
- return ancestors;
26856
+ return ancestors2;
26157
26857
  }
26158
26858
  function ownsOtherCallback(fiber, props) {
26159
26859
  if (typeof fiber.type === "string") return false;
@@ -26161,13 +26861,13 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26161
26861
  (name) => /^on[A-Z]/.test(name) && name !== "onClick" && name !== "onFork" && typeof props[name] === "function"
26162
26862
  );
26163
26863
  }
26164
- function forkTargetFromAncestors(button2, threadId, turnId, ancestors) {
26864
+ function forkTargetFromAncestors(button2, threadId, turnId, ancestors2) {
26165
26865
  const conversationIds = /* @__PURE__ */ new Set();
26166
26866
  const turnIds = /* @__PURE__ */ new Set();
26167
26867
  const hostIds = /* @__PURE__ */ new Set();
26168
26868
  const projectlessStates = /* @__PURE__ */ new Set();
26169
26869
  let hasForkCallback = false;
26170
- for (const fiber of ancestors) {
26870
+ for (const fiber of ancestors2) {
26171
26871
  const props = fiber.memoizedProps;
26172
26872
  if (!isRecord11(props)) continue;
26173
26873
  if (!hasForkCallback && typeof props.onFork !== "function" && ownsOtherCallback(fiber, props)) {
@@ -26704,6 +27404,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26704
27404
  }
26705
27405
  });
26706
27406
  const selectedPolicies = /* @__PURE__ */ new Map();
27407
+ const draftModels = createScopedDraftModelWriter();
26707
27408
  const handleRoutingPolicyChange = () => {
26708
27409
  currentRequestRoute();
26709
27410
  };
@@ -26724,7 +27425,16 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26724
27425
  const route = window.__codexhostHostRoutingV1?.forComposer(composer);
26725
27426
  if (!route) return false;
26726
27427
  try {
26727
- if (route.policy.select(carrier ?? null)) {
27428
+ const target = composer ? findComposerModelTarget(composer) : null;
27429
+ if (target?.[0] === "conversation") return true;
27430
+ if (target?.[0] !== "default" || typeof target[1] !== "string" || !composer)
27431
+ return agent === "codex";
27432
+ const binding = findScopedDraftModelBinding(composer, target[1]);
27433
+ const draftKey = target[1];
27434
+ if (!binding || !route.policy.scopedCreation)
27435
+ return agent === "codex" && !draftModels.has(draftKey);
27436
+ draftModels.apply(draftKey, binding, carrier ?? null);
27437
+ if (route.policy.select(carrier ?? null, draftKey, binding.creationModes)) {
26728
27438
  modelUpdates += 1;
26729
27439
  liveStatus.modelUpdates = modelUpdates;
26730
27440
  }
@@ -26742,6 +27452,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26742
27452
  dispose() {
26743
27453
  if (disposed) return;
26744
27454
  disposed = true;
27455
+ draftModels.dispose();
26745
27456
  window.removeEventListener(
26746
27457
  "codexhost:draft-prewarm-policy-changed",
26747
27458
  handleRoutingPolicyChange
@@ -27177,6 +27888,8 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
27177
27888
  cachedInputTokens: 0,
27178
27889
  cacheWriteInputTokens: 0,
27179
27890
  cacheKnownInputTokens: 0,
27891
+ cacheHitCachedInputTokens: 0,
27892
+ cacheHitInputTokens: 0,
27180
27893
  outputTokens: 0,
27181
27894
  reasoningOutputTokens: 0,
27182
27895
  costUsd: 0,
@@ -27190,6 +27903,8 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
27190
27903
  target.cachedInputTokens += source.cachedInputTokens;
27191
27904
  target.cacheWriteInputTokens += source.cacheWriteInputTokens;
27192
27905
  target.cacheKnownInputTokens += source.cacheKnownInputTokens;
27906
+ target.cacheHitCachedInputTokens += source.cacheHitCachedInputTokens;
27907
+ target.cacheHitInputTokens += source.cacheHitInputTokens;
27193
27908
  target.outputTokens += source.outputTokens;
27194
27909
  target.reasoningOutputTokens += source.reasoningOutputTokens;
27195
27910
  target.costUsd += source.costUsd;
@@ -27244,7 +27959,9 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
27244
27959
  };
27245
27960
  }
27246
27961
  function cacheHitRate(totals2) {
27247
- return totals2.cacheKnownInputTokens > 0 ? formatRendererCacheHitRate(totals2.cachedInputTokens / totals2.cacheKnownInputTokens * 100) : "\u2014";
27962
+ return totals2.cacheHitInputTokens > 0 ? formatRendererCacheHitRate(
27963
+ totals2.cacheHitCachedInputTokens / totals2.cacheHitInputTokens * 100
27964
+ ) : "\u2014";
27248
27965
  }
27249
27966
  function formatMeasure(measure, value, locale = "en") {
27250
27967
  return measure === "cost" ? money(value) : count2(value, locale);
@@ -29111,7 +29828,7 @@ ${messages.creditsCoverage}: ${value.reportedRequests} / ${row.requests}` : void
29111
29828
  {
29112
29829
  key: "hit",
29113
29830
  label: messages.cacheHit,
29114
- sort: (row) => row.cacheKnownInputTokens > 0 ? row.cachedInputTokens / row.cacheKnownInputTokens : -1,
29831
+ sort: (row) => row.cacheHitInputTokens > 0 ? row.cacheHitCachedInputTokens / row.cacheHitInputTokens : -1,
29115
29832
  cell: (row) => cacheHitRate(row)
29116
29833
  },
29117
29834
  {
@@ -32331,7 +33048,7 @@ ${detail}` : ""}`
32331
33048
  }
32332
33049
  function defaultImportName(source, existing) {
32333
33050
  const base = source.provider === "openai-codex" ? "codex" : "grok";
32334
- const used = new Set(existing.map((record6) => record6.name));
33051
+ const used = new Set(existing.map((record10) => record10.name));
32335
33052
  const valid = (name) => credentialImportNameSchema.safeParse(name).success;
32336
33053
  if (!used.has(base)) return base;
32337
33054
  const local = source.label.includes("@") ? source.label.split("@")[0] ?? "" : "";
@@ -32354,7 +33071,7 @@ ${detail}` : ""}`
32354
33071
  const shown = (text) => accountDisplayText(text, hideEmails);
32355
33072
  const targetButtons = /* @__PURE__ */ new Map();
32356
33073
  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);
33074
+ const sourceOf = (record10) => snapshot.sources.find((source) => source.id === record10.source.id);
32358
33075
  const piTarget = () => snapshot.targets.find((candidate) => candidate.harnessId === TARGET_HARNESS_ID);
32359
33076
  const compatibleSources = () => {
32360
33077
  const target = piTarget();
@@ -32392,7 +33109,7 @@ ${detail}` : ""}`
32392
33109
  sectionImport.addEventListener("click", () => {
32393
33110
  const sources = compatibleSources();
32394
33111
  const free = sources.find(
32395
- (source2) => !importedRecords().some((record6) => record6.source.id === source2.id)
33112
+ (source2) => !importedRecords().some((record10) => record10.source.id === source2.id)
32396
33113
  );
32397
33114
  const source = free ?? sources[0];
32398
33115
  if (source) openDialog("add", { source, choose: true }, SECTION_IMPORT_KEY);
@@ -32442,30 +33159,30 @@ ${detail}` : ""}`
32442
33159
  mark.append(createRendererAgentIcon(agent ?? "pi", 26, document2, pluginFor(agent ?? "pi")));
32443
33160
  return mark;
32444
33161
  };
32445
- const renderRow = (record6) => {
33162
+ const renderRow = (record10) => {
32446
33163
  const row = document2.createElement("div");
32447
33164
  row.className = "settings-pi-accounts__row";
32448
33165
  row.tabIndex = -1;
32449
- row.dataset.importName = record6.name;
32450
- row.setAttribute("aria-label", shown(record6.source.label));
32451
- const agent = record6.source.harnessId;
33166
+ row.dataset.importName = record10.name;
33167
+ row.setAttribute("aria-label", shown(record10.source.label));
33168
+ const agent = record10.source.harnessId;
32452
33169
  const mark = createMark(agent);
32453
33170
  const identity = document2.createElement("div");
32454
33171
  identity.className = "settings-pi-accounts__identity";
32455
33172
  const label = document2.createElement("strong");
32456
33173
  label.className = "settings-account-email";
32457
- label.textContent = shown(record6.source.label);
33174
+ label.textContent = shown(record10.source.label);
32458
33175
  label.title = label.textContent;
32459
33176
  label.translate = false;
32460
33177
  const meta3 = document2.createElement("div");
32461
33178
  meta3.className = "settings-account-metadata";
32462
- const source = sourceOf(record6);
33179
+ const source = sourceOf(record10);
32463
33180
  const parts = [
32464
33181
  metaPart(rendererAgentLabel(agent, pluginFor(agent)), "settings-pi-accounts__agent"),
32465
- metaPart(`${record6.name}/\u2026`, void 0, true),
33182
+ metaPart(`${record10.name}/\u2026`, void 0, true),
32466
33183
  metaPart(messages.copied)
32467
33184
  ];
32468
- const time3 = formatImportedAt(record6.importedAt);
33185
+ const time3 = formatImportedAt(record10.importedAt);
32469
33186
  if (time3) parts.push(metaPart(time3));
32470
33187
  parts.forEach((part, index) => {
32471
33188
  if (index > 0) {
@@ -32482,23 +33199,23 @@ ${detail}` : ""}`
32482
33199
  reimport.type = "button";
32483
33200
  reimport.className = "settings-account-action";
32484
33201
  reimport.textContent = messages.rowReimport;
32485
- reimport.setAttribute("aria-label", `${messages.reimport}: ${shown(record6.source.label)}`);
33202
+ reimport.setAttribute("aria-label", `${messages.reimport}: ${shown(record10.source.label)}`);
32486
33203
  reimport.disabled = busy || !source;
32487
33204
  reimport.title = messages.reimport;
32488
33205
  reimport.addEventListener("click", () => {
32489
- if (source) openDialog("reimport", { source, record: record6 }, `row:${record6.name}`);
33206
+ if (source) openDialog("reimport", { source, record: record10 }, `row:${record10.name}`);
32490
33207
  });
32491
33208
  const remove = document2.createElement("button");
32492
33209
  remove.type = "button";
32493
33210
  remove.className = "settings-account-action settings-pi-accounts__remove";
32494
33211
  remove.textContent = messages.rowRemove;
32495
- remove.setAttribute("aria-label", `${messages.remove}: ${shown(record6.source.label)}`);
33212
+ remove.setAttribute("aria-label", `${messages.remove}: ${shown(record10.source.label)}`);
32496
33213
  remove.disabled = busy;
32497
- remove.addEventListener("click", () => openDialog("remove", { record: record6 }, `row:${record6.name}`));
33214
+ remove.addEventListener("click", () => openDialog("remove", { record: record10 }, `row:${record10.name}`));
32498
33215
  if (source) actions.append(reimport);
32499
33216
  actions.append(remove);
32500
33217
  row.append(mark, identity, actions);
32501
- rows.set(record6.name, row);
33218
+ rows.set(record10.name, row);
32502
33219
  return row;
32503
33220
  };
32504
33221
  const loginTypeLabel = (type) => type === "oauth" ? messages.typeOauth : type === "api_key" ? messages.typeApiKey : messages.typeOther;
@@ -32651,7 +33368,7 @@ ${detail}` : ""}`
32651
33368
  const label = document2.createElement("strong");
32652
33369
  label.textContent = shown(choice.label);
32653
33370
  label.translate = false;
32654
- const existing = importedRecords().find((record6) => record6.source.id === choice.id);
33371
+ const existing = importedRecords().find((record10) => record10.source.id === choice.id);
32655
33372
  const agent = choice.harnessId;
32656
33373
  const detail = document2.createElement("span");
32657
33374
  detail.textContent = [
@@ -32692,7 +33409,7 @@ ${detail}` : ""}`
32692
33409
  const name = request.action === "list" ? void 0 : request.name;
32693
33410
  state = {
32694
33411
  source: state.source,
32695
- record: importedRecords().find((record6) => record6.name === name) ?? state.record
33412
+ record: importedRecords().find((record10) => record10.name === name) ?? state.record
32696
33413
  };
32697
33414
  show(next);
32698
33415
  } else {
@@ -32706,12 +33423,12 @@ ${detail}` : ""}`
32706
33423
  sourceRadios = [];
32707
33424
  body.replaceChildren();
32708
33425
  controls.replaceChildren();
32709
- const { source, record: record6 } = state;
33426
+ const { source, record: record10 } = state;
32710
33427
  const close = () => modal.close();
32711
33428
  if (mode === "add" || mode === "reimport") {
32712
33429
  title.textContent = mode === "add" ? messages.add : messages.reimport;
32713
33430
  modal.setAttribute("aria-label", title.textContent);
32714
- const active = source ?? record6?.source;
33431
+ const active = source ?? record10?.source;
32715
33432
  const choices = mode === "add" && state.choose ? compatibleSources() : [];
32716
33433
  if (choices.length > 1) body.append(sourcePicker(choices));
32717
33434
  else if (active) body.append(line(messages.source, shown(active.label)));
@@ -32720,8 +33437,8 @@ ${detail}` : ""}`
32720
33437
  input.maxLength = 48;
32721
33438
  input.autocomplete = "off";
32722
33439
  input.spellcheck = false;
32723
- input.value = record6?.name ?? (source ? defaultImportName(source, importedRecords()) : "codex");
32724
- input.readOnly = Boolean(record6);
33440
+ input.value = record10?.name ?? (source ? defaultImportName(source, importedRecords()) : "codex");
33441
+ input.readOnly = Boolean(record10);
32725
33442
  input.addEventListener("input", () => {
32726
33443
  nameEdited = true;
32727
33444
  });
@@ -32755,7 +33472,7 @@ ${detail}` : ""}`
32755
33472
  {
32756
33473
  action: mode === "reimport" ? "reimport" : "import",
32757
33474
  sourceId: source2.id,
32758
- name: record6?.name ?? input.value,
33475
+ name: record10?.name ?? input.value,
32759
33476
  confirmed: true
32760
33477
  },
32761
33478
  "done"
@@ -32765,16 +33482,16 @@ ${detail}` : ""}`
32765
33482
  )
32766
33483
  );
32767
33484
  (mode === "add" ? input : controls.children[0]).focus();
32768
- } else if (mode === "remove" && record6) {
33485
+ } else if (mode === "remove" && record10) {
32769
33486
  title.textContent = messages.remove;
32770
33487
  modal.setAttribute("aria-label", title.textContent);
32771
- body.append(note(messages.removeWarning.replace("{name}", record6.name)));
33488
+ body.append(note(messages.removeWarning.replace("{name}", record10.name)));
32772
33489
  const cancel = command(messages.cancel, close);
32773
33490
  controls.append(
32774
33491
  cancel,
32775
33492
  command(
32776
33493
  messages.remove,
32777
- () => submit({ action: "remove", name: record6.name, confirmed: true }, null),
33494
+ () => submit({ action: "remove", name: record10.name, confirmed: true }, null),
32778
33495
  "danger"
32779
33496
  )
32780
33497
  );
@@ -32782,7 +33499,7 @@ ${detail}` : ""}`
32782
33499
  } else {
32783
33500
  title.textContent = messages.doneTitle;
32784
33501
  modal.setAttribute("aria-label", title.textContent);
32785
- const name = record6?.name;
33502
+ const name = record10?.name;
32786
33503
  if (name) body.append(line(messages.entry, `${name}/\u2026`, true));
32787
33504
  body.append(note(messages.done));
32788
33505
  const done = command(messages.close, close, "primary");
@@ -32829,21 +33546,21 @@ ${detail}` : ""}`
32829
33546
  (candidate) => candidate.harnessId === TARGET_HARNESS_ID && source && candidate.providers.includes(source.provider)
32830
33547
  );
32831
33548
  if (!source || !target) return null;
32832
- const record6 = target.imports.find((candidate) => candidate.source.id === source.id);
33549
+ const record10 = target.imports.find((candidate) => candidate.source.id === source.id);
32833
33550
  const key = `${harnessId}:${accountLabel}:import`;
32834
33551
  const button2 = document2.createElement("button");
32835
33552
  button2.type = "button";
32836
33553
  button2.className = "settings-account-pi-import";
32837
33554
  button2.dataset.accountFocus = key;
32838
33555
  button2.disabled = busy;
32839
- const hint = record6 ? messages.importedHint.replace("{name}", record6.name) : messages.add;
33556
+ const hint = record10 ? messages.importedHint.replace("{name}", record10.name) : messages.add;
32840
33557
  button2.title = hint;
32841
33558
  button2.setAttribute("aria-label", hint);
32842
33559
  button2.append(createRendererAgentIcon("pi", 12, document2, pluginFor("pi")));
32843
- if (record6) {
33560
+ if (record10) {
32844
33561
  button2.dataset.state = "imported";
32845
33562
  const name = document2.createElement("code");
32846
- name.textContent = `${record6.name}/\u2026`;
33563
+ name.textContent = `${record10.name}/\u2026`;
32847
33564
  name.translate = false;
32848
33565
  button2.append(name, createRendererSettingsIcon("check", 12));
32849
33566
  } else {
@@ -32851,7 +33568,7 @@ ${detail}` : ""}`
32851
33568
  button2.append(messages.add);
32852
33569
  }
32853
33570
  button2.addEventListener("click", () => {
32854
- if (!record6) {
33571
+ if (!record10) {
32855
33572
  openDialog("add", { source }, key);
32856
33573
  return;
32857
33574
  }
@@ -32860,7 +33577,7 @@ ${detail}` : ""}`
32860
33577
  renderSection();
32861
33578
  sectionToggle.setAttribute("aria-expanded", "true");
32862
33579
  }
32863
- const row = rows.get(record6.name);
33580
+ const row = rows.get(record10.name);
32864
33581
  row?.scrollIntoView({ block: "nearest", behavior: "smooth" });
32865
33582
  row?.focus();
32866
33583
  });
@@ -33855,6 +34572,43 @@ ${detail}` : ""}`
33855
34572
  });
33856
34573
  }
33857
34574
 
34575
+ // src/settings/harness-schedules-page.ts
34576
+ function createHarnessSchedulesPage(messages, options) {
34577
+ const t = (zh, en) => messages.locale === "zh-CN" ? zh : en;
34578
+ return {
34579
+ id: "harness-schedules",
34580
+ label: t("\u5B9A\u65F6\u4EFB\u52A1", "Schedules"),
34581
+ icon: "schedules",
34582
+ mount(context) {
34583
+ const navigate = () => {
34584
+ context.content.replaceChildren();
34585
+ void context.runLatest((signal) => options.openSchedules(signal), {
34586
+ success() {
34587
+ },
34588
+ failure() {
34589
+ const document2 = context.content.ownerDocument;
34590
+ const status = document2.createElement("p");
34591
+ status.setAttribute("role", "status");
34592
+ status.className = "text-sm text-settings-muted";
34593
+ status.textContent = t(
34594
+ "\u65E0\u6CD5\u6253\u5F00\u5B98\u65B9\u5B9A\u65F6\u4EFB\u52A1\u9875\uFF0C\u8BF7\u91CD\u8BD5\u6216\u4ECE\u5B98\u65B9\u4FA7\u680F\u8FDB\u5165\u3002",
34595
+ "Could not open the official schedules page. Retry or use the Desktop sidebar."
34596
+ );
34597
+ const retry = document2.createElement("button");
34598
+ retry.type = "button";
34599
+ 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";
34600
+ retry.textContent = t("\u91CD\u8BD5", "Retry");
34601
+ retry.addEventListener("click", navigate);
34602
+ context.content.replaceChildren(status, retry);
34603
+ }
34604
+ });
34605
+ };
34606
+ navigate();
34607
+ return void 0;
34608
+ }
34609
+ };
34610
+ }
34611
+
33858
34612
  // src/settings/update-request.ts
33859
34613
  var RENDERER_UPDATE_REQUEST_TIMEOUT_MS = 15e3;
33860
34614
  var RendererUpdateRequestTimeoutError = class extends Error {
@@ -34182,8 +34936,8 @@ ${detail}` : ""}`
34182
34936
  const starBanner = updateStarBanner(document2, messages);
34183
34937
  context.content.append(heading, metadata, panel, controls, starBanner, notes);
34184
34938
  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;
34939
+ controls.className = fallback ? "settings-update-controls" : "settings-update-controls is-quiet";
34940
+ manualNpmDescription.textContent = fallback ? messages.updateManualFallbackDescription : messages.updateManualNpmDescription;
34187
34941
  manualNpmDescription.className = fallback ? "settings-update-manual-description is-fallback" : "settings-update-manual-description";
34188
34942
  };
34189
34943
  let pollTimer;
@@ -34333,14 +35087,14 @@ ${detail}` : ""}`
34333
35087
  panel.dataset.updateState = view;
34334
35088
  panel.replaceChildren();
34335
35089
  setManualFallback(Boolean(result.error) || actionableStatus !== null);
34336
- const inlineUpdate = !result.error && !windows && !actionableStatus && result.updateAvailable;
35090
+ const inlineUpdate = !result.error && !actionableStatus && result.updateAvailable;
34337
35091
  if (inlineUpdate) panel.dataset.inline = "";
34338
35092
  else delete panel.dataset.inline;
34339
35093
  panel.append(
34340
35094
  createPanelHead(
34341
35095
  document2,
34342
35096
  view,
34343
- actionableStatus ? statusMessage(actionableStatus, messages) ?? messages.updateFailed : result.error ? messages.updateFailed : result.updateAvailable ? windows ? messages.updateWindowsManualRequired : messages.updateAvailable : messages.updateUpToDate
35097
+ actionableStatus ? statusMessage(actionableStatus, messages) ?? messages.updateFailed : result.error ? messages.updateFailed : result.updateAvailable ? messages.updateAvailable : messages.updateUpToDate
34344
35098
  )
34345
35099
  );
34346
35100
  if (actionableStatus?.error) {
@@ -34356,7 +35110,7 @@ ${detail}` : ""}`
34356
35110
  panel.append(error51);
34357
35111
  }
34358
35112
  const buttons = [];
34359
- if (!windows && result.updateAvailable && result.installationAvailable) {
35113
+ if (result.updateAvailable && result.installationAvailable) {
34360
35114
  const update = document2.createElement("button");
34361
35115
  update.type = "button";
34362
35116
  update.className = "settings-command-button";
@@ -34405,11 +35159,12 @@ ${detail}` : ""}`
34405
35159
  }
34406
35160
  });
34407
35161
  }
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) {
35162
+ 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
35163
  return Object.freeze([
34410
35164
  createConnectionsSettingsPage(messages, getDiagnostics, void 0, getRemoteConnections),
34411
35165
  createRemoteConnectionsPage(messages, getRemoteConnections),
34412
35166
  createAccountsSettingsPage(messages, getAccountClient),
35167
+ ...harnessSchedules ? [createHarnessSchedulesPage(messages, harnessSchedules)] : [],
34413
35168
  createSessionImportSettingsPage(
34414
35169
  messages,
34415
35170
  getSessionImportClient,
@@ -39110,7 +39865,7 @@ th[aria-sort] .console-usage-sort__mark {
39110
39865
  `;
39111
39866
 
39112
39867
  // 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';
39868
+ 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
39869
 
39115
39870
  // src/settings/trigger.ts
39116
39871
  var SETTINGS_TRIGGER_ATTRIBUTE = "data-codexhost-settings-trigger";
@@ -39677,6 +40432,7 @@ ${usage_default}`;
39677
40432
  let disposed = false;
39678
40433
  const mount = () => {
39679
40434
  const messages = rendererSettingsMessages(locale);
40435
+ const schedules = options.harnessSchedules;
39680
40436
  const definitions = createDefaultRendererSettingsPages(
39681
40437
  messages,
39682
40438
  options.getUpdateClient ?? (() => null),
@@ -39693,7 +40449,13 @@ ${usage_default}`;
39693
40449
  options.getLoadedSessionsClient ?? (() => null),
39694
40450
  options.getRemoteConnections ?? (() => null),
39695
40451
  options.requestUsageStatistics,
39696
- options.usageStatisticsHosts
40452
+ options.usageStatisticsHosts,
40453
+ schedules ? {
40454
+ openSchedules: async (signal) => {
40455
+ await schedules.openSchedules(signal);
40456
+ if (!disposed && !signal.aborted) shell?.close();
40457
+ }
40458
+ } : void 0
39697
40459
  );
39698
40460
  const nextShell = installRendererSettingsShell(definitions, messages, ownerWindow.document, {
39699
40461
  onOpenChange(open) {
@@ -40427,6 +41189,815 @@ ${usage_default}`;
40427
41189
  return event.defaultPrevented;
40428
41190
  }
40429
41191
 
41192
+ // src/codex-schedule-navigation.ts
41193
+ function isNavigationBus(value) {
41194
+ if (typeof value !== "object" || value === null) return false;
41195
+ const bus = value;
41196
+ return bus.handlers instanceof Map && bus.handlers.has("navigate-to-route") && typeof bus.dispatchHostMessage === "function";
41197
+ }
41198
+ function hasArrived(ownerWindow) {
41199
+ const paths = ["/automations", "/scheduled"];
41200
+ const pages = ownerWindow.document.querySelectorAll('[data-app-shell-active-page="true"]');
41201
+ if (pages.length > 0) {
41202
+ const page = pages[0];
41203
+ if (pages.length !== 1 || !page) return false;
41204
+ const fiberKey = Object.keys(page).find((key) => key.startsWith("__reactFiber$"));
41205
+ if (!fiberKey) return false;
41206
+ for (const ancestor of committedReactAncestors(Reflect.get(page, fiberKey))) {
41207
+ const props = ancestor.memoizedProps;
41208
+ const value = props?.value;
41209
+ if (value?.navigationType === "POP" || value?.navigationType === "PUSH" || value?.navigationType === "REPLACE") {
41210
+ return typeof value.location?.pathname === "string" && paths.includes(value.location.pathname);
41211
+ }
41212
+ }
41213
+ return false;
41214
+ }
41215
+ return paths.includes(ownerWindow.location.pathname);
41216
+ }
41217
+ async function openCodexSchedules(signal, ownerWindow = window) {
41218
+ signal.throwIfAborted();
41219
+ const bus = await loadCodexNativeServices(ownerWindow, isNavigationBus);
41220
+ signal.throwIfAborted();
41221
+ if (!bus) throw new Error("Codex navigation is unavailable");
41222
+ await new Promise((resolve, reject) => {
41223
+ let settled = false;
41224
+ const finish = (error51) => {
41225
+ if (settled) return;
41226
+ settled = true;
41227
+ ownerWindow.clearInterval(poll);
41228
+ ownerWindow.clearTimeout(timeout);
41229
+ signal.removeEventListener("abort", onAbort);
41230
+ if (error51) reject(error51);
41231
+ else resolve();
41232
+ };
41233
+ const arrived = () => hasArrived(ownerWindow);
41234
+ const onAbort = () => finish(arrived() ? void 0 : signal.reason);
41235
+ const poll = ownerWindow.setInterval(() => {
41236
+ if (arrived()) finish();
41237
+ }, 25);
41238
+ const timeout = ownerWindow.setTimeout(
41239
+ () => finish(new Error("Codex did not open the requested page")),
41240
+ 5e3
41241
+ );
41242
+ signal.addEventListener("abort", onAbort, { once: true });
41243
+ try {
41244
+ bus.dispatchHostMessage({ type: "navigate-to-route", path: "/automations" });
41245
+ if (arrived()) finish();
41246
+ } catch (error51) {
41247
+ finish(error51);
41248
+ }
41249
+ });
41250
+ }
41251
+
41252
+ // src/renderer-native-schedule-picker.ts
41253
+ var schedulePickerStyles = `
41254
+ .picker { position:relative; display:flex; justify-content:flex-end; min-width:0; max-width:100%; }
41255
+ .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; }
41256
+ .trigger:hover:not(:disabled), .trigger[aria-expanded="true"] { color:var(--text); background:var(--hover); }
41257
+ .trigger:focus-visible { outline:2px solid var(--focus); outline-offset:1px; }
41258
+ .trigger:disabled { cursor:default; }
41259
+ .trigger > svg, .trigger > img, .trigger > span.icon, .item > svg, .item > img, .item > span.icon { flex:none; }
41260
+ .label { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
41261
+ .trigger[data-stale] .label { opacity:.6; }
41262
+ .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; }
41263
+ .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; }
41264
+ .trigger[aria-expanded="true"] .chevron { transform:translateY(2px) rotate(225deg); }
41265
+ .trigger[aria-busy="true"] .chevron { display:none; }
41266
+ .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; }
41267
+ .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; }
41268
+ .menu:not(:popover-open):not([data-open]) { display:none; }
41269
+ .item { display:flex; align-items:center; gap:10px; min-height:36px; padding:6px 8px; border-radius:8px; cursor:pointer; outline:none; }
41270
+ .item:hover:not([aria-disabled="true"]), .item:focus-visible { background:var(--hover); }
41271
+ .item:focus-visible { box-shadow:inset 0 0 0 2px var(--focus); }
41272
+ .item[aria-disabled="true"] { opacity:.45; cursor:default; }
41273
+ .item .label { flex:1; }
41274
+ .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; }
41275
+ .item[aria-selected="true"] .check { visibility:visible; }
41276
+ @keyframes shimmer { to { background-position:-100% 0; } }
41277
+ @keyframes spin { to { transform:rotate(360deg); } }
41278
+ @media(prefers-reduced-motion:reduce) { .spinner, .trigger[data-shimmer] .label { animation:none; } .trigger, .chevron { transition:none; } }
41279
+ `;
41280
+ function createSchedulePicker(document2, options) {
41281
+ const view = document2.defaultView ?? window;
41282
+ const root = document2.createElement("div");
41283
+ root.className = "picker";
41284
+ const trigger = document2.createElement("button");
41285
+ trigger.type = "button";
41286
+ trigger.className = "trigger";
41287
+ trigger.setAttribute("aria-label", options.label);
41288
+ trigger.setAttribute("aria-haspopup", "listbox");
41289
+ trigger.setAttribute("aria-expanded", "false");
41290
+ const menu = document2.createElement("div");
41291
+ menu.className = "menu";
41292
+ menu.setAttribute("role", "listbox");
41293
+ menu.setAttribute("aria-label", options.listLabel);
41294
+ const supportsPopover = typeof menu.showPopover === "function";
41295
+ if (supportsPopover) menu.setAttribute("popover", "manual");
41296
+ root.append(trigger, menu);
41297
+ let items = [];
41298
+ let stale = null;
41299
+ let value = "";
41300
+ let disabled = false;
41301
+ let busy = false;
41302
+ let placeholder = "";
41303
+ let shimmer = false;
41304
+ let isOpen = false;
41305
+ let isDisabled = () => false;
41306
+ const optionElements = /* @__PURE__ */ new Map();
41307
+ const selectedItem = () => items.find((item) => item.value === value) ?? stale;
41308
+ const cloneIcon = (item) => item.icon?.cloneNode(true) ?? null;
41309
+ const renderTrigger = () => {
41310
+ const item = selectedItem();
41311
+ const label = document2.createElement("span");
41312
+ label.className = "label";
41313
+ label.textContent = item?.label ?? placeholder;
41314
+ const icon2 = item ? cloneIcon(item) : null;
41315
+ const tail = document2.createElement("span");
41316
+ tail.className = busy ? "spinner" : "chevron";
41317
+ tail.setAttribute("aria-hidden", "true");
41318
+ trigger.replaceChildren(...icon2 ? [icon2] : [], label, tail);
41319
+ trigger.toggleAttribute("data-stale", Boolean(item && !items.includes(item)));
41320
+ trigger.toggleAttribute("data-shimmer", shimmer && !item);
41321
+ trigger.dataset.value = item ? value : "";
41322
+ trigger.setAttribute("aria-busy", String(busy));
41323
+ trigger.disabled = disabled;
41324
+ if (disabled && isOpen) close();
41325
+ };
41326
+ const renderItems = () => {
41327
+ optionElements.clear();
41328
+ const elements = items.map((item) => {
41329
+ const option = document2.createElement("div");
41330
+ option.className = "item";
41331
+ option.setAttribute("role", "option");
41332
+ option.tabIndex = -1;
41333
+ option.dataset.value = item.value;
41334
+ option.setAttribute("aria-selected", String(item.value === value));
41335
+ if (item.disabled || isDisabled(item.value)) option.setAttribute("aria-disabled", "true");
41336
+ const icon2 = cloneIcon(item);
41337
+ const label = document2.createElement("span");
41338
+ label.className = "label";
41339
+ label.textContent = item.label;
41340
+ const check2 = document2.createElement("span");
41341
+ check2.className = "check";
41342
+ check2.setAttribute("aria-hidden", "true");
41343
+ option.append(...icon2 ? [icon2] : [], label, check2);
41344
+ optionElements.set(item.value, option);
41345
+ return option;
41346
+ });
41347
+ menu.replaceChildren(...elements);
41348
+ };
41349
+ const enabledOptions = () => [...optionElements.values()].filter((el) => el.getAttribute("aria-disabled") !== "true");
41350
+ const focusOption = (el) => {
41351
+ el?.focus();
41352
+ el?.scrollIntoView({ block: "nearest" });
41353
+ };
41354
+ const position = () => {
41355
+ const rect = trigger.getBoundingClientRect();
41356
+ const margin = 8;
41357
+ menu.style.minWidth = `${Math.max(200, Math.min(rect.width, view.innerWidth - 2 * margin))}px`;
41358
+ menu.style.maxHeight = "";
41359
+ const height = menu.offsetHeight;
41360
+ const below = view.innerHeight - rect.bottom - margin - 4;
41361
+ const above = rect.top - margin - 4;
41362
+ const placeBelow = height <= below || below >= above;
41363
+ const room = Math.max(120, placeBelow ? below : above);
41364
+ menu.style.maxHeight = `${room}px`;
41365
+ const used = Math.min(height, room);
41366
+ menu.style.top = `${placeBelow ? rect.bottom + 4 : rect.top - 4 - used}px`;
41367
+ const width = menu.offsetWidth;
41368
+ const left = Math.min(Math.max(margin, rect.right - width), view.innerWidth - width - margin);
41369
+ menu.style.left = `${Math.max(margin, left)}px`;
41370
+ };
41371
+ const onWindowKey = (event) => {
41372
+ if (event.key !== "Escape") return;
41373
+ event.preventDefault();
41374
+ event.stopImmediatePropagation();
41375
+ close();
41376
+ trigger.focus();
41377
+ };
41378
+ const onOutside = (event) => {
41379
+ if (!event.composedPath().includes(root)) close();
41380
+ };
41381
+ const onDismiss = () => close();
41382
+ function open() {
41383
+ if (isOpen || disabled) return;
41384
+ options.onOpen?.();
41385
+ if (!items.length) return;
41386
+ isOpen = true;
41387
+ trigger.setAttribute("aria-expanded", "true");
41388
+ if (supportsPopover) menu.showPopover();
41389
+ else menu.setAttribute("data-open", "");
41390
+ position();
41391
+ focusOption(optionElements.get(value) ?? enabledOptions()[0]);
41392
+ view.addEventListener("keydown", onWindowKey, true);
41393
+ document2.addEventListener("pointerdown", onOutside, true);
41394
+ view.addEventListener("resize", onDismiss);
41395
+ view.addEventListener("blur", onDismiss);
41396
+ document2.addEventListener("scroll", onDismiss, true);
41397
+ }
41398
+ function close() {
41399
+ if (!isOpen) return;
41400
+ isOpen = false;
41401
+ trigger.setAttribute("aria-expanded", "false");
41402
+ if (supportsPopover && menu.matches(":popover-open")) menu.hidePopover();
41403
+ menu.removeAttribute("data-open");
41404
+ view.removeEventListener("keydown", onWindowKey, true);
41405
+ document2.removeEventListener("pointerdown", onOutside, true);
41406
+ view.removeEventListener("resize", onDismiss);
41407
+ view.removeEventListener("blur", onDismiss);
41408
+ document2.removeEventListener("scroll", onDismiss, true);
41409
+ }
41410
+ const choose = (el) => {
41411
+ if (el.getAttribute("aria-disabled") === "true") return;
41412
+ const next = el.dataset.value ?? "";
41413
+ close();
41414
+ trigger.focus();
41415
+ if (next === value) return;
41416
+ picker.value = next;
41417
+ options.onChange(next);
41418
+ };
41419
+ trigger.addEventListener("click", () => isOpen ? close() : open());
41420
+ trigger.addEventListener("keydown", (event) => {
41421
+ if (event.key !== "ArrowDown" && event.key !== "ArrowUp") return;
41422
+ event.preventDefault();
41423
+ open();
41424
+ });
41425
+ menu.addEventListener("click", (event) => {
41426
+ const el = event.target.closest('[role="option"]');
41427
+ if (el) choose(el);
41428
+ });
41429
+ menu.addEventListener("keydown", (event) => {
41430
+ const list = enabledOptions();
41431
+ const active = menu.getRootNode().activeElement;
41432
+ const at = active ? list.indexOf(active) : -1;
41433
+ if (event.key === "ArrowDown") focusOption(list[Math.min(list.length - 1, at + 1)]);
41434
+ else if (event.key === "ArrowUp") focusOption(list[Math.max(0, at - 1)]);
41435
+ else if (event.key === "Home") focusOption(list[0]);
41436
+ else if (event.key === "End") focusOption(list.at(-1));
41437
+ else if (event.key === "Enter" || event.key === " ") {
41438
+ if (active?.getAttribute("role") === "option") choose(active);
41439
+ } else if (event.key === "Tab") {
41440
+ close();
41441
+ trigger.focus();
41442
+ return;
41443
+ } else return;
41444
+ event.preventDefault();
41445
+ });
41446
+ const picker = {
41447
+ root,
41448
+ trigger,
41449
+ get value() {
41450
+ return value;
41451
+ },
41452
+ set value(next) {
41453
+ if (next === value) return;
41454
+ stale = null;
41455
+ value = next;
41456
+ for (const [key, el] of optionElements)
41457
+ el.setAttribute("aria-selected", String(key === next));
41458
+ renderTrigger();
41459
+ },
41460
+ get disabled() {
41461
+ return disabled;
41462
+ },
41463
+ set disabled(next) {
41464
+ if (next === disabled) return;
41465
+ disabled = next;
41466
+ renderTrigger();
41467
+ },
41468
+ get busy() {
41469
+ return busy;
41470
+ },
41471
+ set busy(next) {
41472
+ if (next === busy) return;
41473
+ busy = next;
41474
+ renderTrigger();
41475
+ },
41476
+ setItems(next) {
41477
+ const previous = selectedItem();
41478
+ stale = options.retainMissing && previous && !next.some((item) => item.value === value) ? { ...previous, disabled: true } : null;
41479
+ items = next;
41480
+ renderItems();
41481
+ renderTrigger();
41482
+ },
41483
+ setDisabledValues(next) {
41484
+ isDisabled = next;
41485
+ for (const item of items) {
41486
+ const el = optionElements.get(item.value);
41487
+ if (!el) continue;
41488
+ if (item.disabled || next(item.value)) el.setAttribute("aria-disabled", "true");
41489
+ else el.removeAttribute("aria-disabled");
41490
+ }
41491
+ },
41492
+ setPlaceholder(text, shimmerText = false) {
41493
+ if (text === placeholder && shimmerText === shimmer) return;
41494
+ placeholder = text;
41495
+ shimmer = shimmerText;
41496
+ renderTrigger();
41497
+ },
41498
+ close
41499
+ };
41500
+ renderTrigger();
41501
+ return picker;
41502
+ }
41503
+
41504
+ // src/renderer-native-schedule-controls.ts
41505
+ function restoreRow(row, appearance) {
41506
+ row.hidden = appearance.hidden;
41507
+ row.style.setProperty("display", appearance.display, appearance.priority);
41508
+ }
41509
+ function installRendererNativeScheduleControls(document2, options) {
41510
+ const view = document2.defaultView ?? window;
41511
+ const mounted = /* @__PURE__ */ new Map();
41512
+ let disposed = false;
41513
+ let frame = null;
41514
+ const text = (zh, en) => options.locale() === "zh-CN" ? zh : en;
41515
+ const schedule = () => {
41516
+ if (!disposed && frame === null) frame = view.requestAnimationFrame(scan);
41517
+ };
41518
+ function mount(form) {
41519
+ const root = document2.createElement("div");
41520
+ root.dataset.codexhostScheduleControls = "true";
41521
+ const shadow = root.attachShadow({ mode: "open" });
41522
+ const style = document2.createElement("style");
41523
+ style.textContent = `
41524
+ :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); }
41525
+ * { box-sizing:border-box; }
41526
+ fieldset { border:1px solid var(--border); border-radius:16px; padding:0 12px; margin:0; min-width:0; }
41527
+ .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; }
41528
+ .row + .row { border-top:1px solid var(--border); }
41529
+ .name { flex:none; }
41530
+ .value { display:flex; justify-content:flex-end; min-width:0; max-width:72%; }
41531
+ fieldset:disabled { opacity:.6; }
41532
+ ${schedulePickerStyles}
41533
+ .message { display:flex; align-items:baseline; gap:8px; margin:8px 4px 0; color:var(--muted); font-size:12px; line-height:1.5; }
41534
+ p { margin:0; min-width:0; overflow-wrap:anywhere; }
41535
+ button.retry { border:0; border-radius:4px; padding:2px 4px; color:inherit; background:transparent; font:inherit; text-decoration:underline; cursor:pointer; flex-shrink:0; }
41536
+ button.retry:focus-visible { outline:2px solid var(--focus); outline-offset:2px; }
41537
+ [hidden] { display:none!important; }
41538
+ `;
41539
+ const fields = document2.createElement("fieldset");
41540
+ const harness2 = createSchedulePicker(document2, {
41541
+ label: "Harness",
41542
+ listLabel: text("\u9009\u62E9 Harness", "Choose a Harness"),
41543
+ retainMissing: true,
41544
+ onChange: () => onHarness()
41545
+ });
41546
+ const model2 = createSchedulePicker(document2, {
41547
+ label: text("\u6A21\u578B", "Model"),
41548
+ listLabel: text("\u9009\u62E9\u6A21\u578B", "Choose a Model"),
41549
+ retainMissing: true,
41550
+ onChange: () => applyModel()
41551
+ });
41552
+ const workspace = createSchedulePicker(document2, {
41553
+ label: text("\u5DE5\u4F5C\u533A", "Workspace"),
41554
+ listLabel: text("\u9009\u62E9\u5DE5\u4F5C\u533A", "Choose a workspace"),
41555
+ retainMissing: true,
41556
+ onOpen: () => refreshWorkspaces(),
41557
+ onChange: () => {
41558
+ const next = workspaces.find(({ id }) => id === workspace.value) ?? null;
41559
+ if (next?.id === selectedWorkspace?.id && next?.cwd === selectedWorkspace?.cwd) return;
41560
+ selectedWorkspace = next;
41561
+ void loadModels({ preserveSelection: models.length > 0 });
41562
+ }
41563
+ });
41564
+ const label = (name, picker) => {
41565
+ const row = document2.createElement("div");
41566
+ row.className = "row";
41567
+ const title = document2.createElement("span");
41568
+ title.className = "name";
41569
+ title.textContent = name;
41570
+ const value = document2.createElement("div");
41571
+ value.className = "value";
41572
+ value.append(picker.root);
41573
+ row.append(title, value);
41574
+ fields.append(row);
41575
+ return row;
41576
+ };
41577
+ label("Harness", harness2);
41578
+ const modelRow = label(text("\u6A21\u578B", "Model"), model2);
41579
+ const workspaceRow = label(text("\u5DE5\u4F5C\u533A", "Workspace"), workspace);
41580
+ const status = document2.createElement("p");
41581
+ status.setAttribute("role", "status");
41582
+ const retry = document2.createElement("button");
41583
+ retry.type = "button";
41584
+ retry.className = "retry";
41585
+ retry.textContent = text("\u91CD\u8BD5", "Retry");
41586
+ retry.hidden = true;
41587
+ const messageRow = document2.createElement("div");
41588
+ messageRow.className = "message";
41589
+ messageRow.append(status, retry);
41590
+ shadow.append(style, fields, messageRow);
41591
+ const editor = form.querySelector('[contenteditable="true"][role="textbox"], textarea');
41592
+ const container = editor?.closest("fieldset")?.querySelector(":scope > div") ?? form;
41593
+ container.prepend(root);
41594
+ let retired = false;
41595
+ let client = options.getClient();
41596
+ let selectedHarness = "codex";
41597
+ let availablePlugins = [];
41598
+ let generation = 0;
41599
+ let loading = false;
41600
+ let confirming = false;
41601
+ let confirmationTimer;
41602
+ let error51 = "";
41603
+ let models = [];
41604
+ let workspaces = [];
41605
+ let selectedWorkspace = null;
41606
+ let workspaceCreation = null;
41607
+ let carrier = null;
41608
+ let original = null;
41609
+ let restoring = null;
41610
+ const hiddenRows = /* @__PURE__ */ new Map();
41611
+ const external = () => selectedHarness !== "codex";
41612
+ const available = () => options.getAvailablePlugins().some((plugin) => plugin.id === selectedHarness);
41613
+ const harnessItem = (id, name, plugin) => ({
41614
+ value: id,
41615
+ label: name,
41616
+ icon: createRendererAgentIcon(id, 18, document2, plugin)
41617
+ });
41618
+ harness2.setItems([harnessItem("codex", "Codex")]);
41619
+ harness2.value = "codex";
41620
+ const syncAvailablePlugins = () => {
41621
+ const next = options.getAvailablePlugins();
41622
+ if (next.length === availablePlugins.length && next.every(
41623
+ (plugin, index) => plugin.id === availablePlugins[index]?.id && plugin.name === availablePlugins[index]?.name
41624
+ ))
41625
+ return;
41626
+ availablePlugins = next;
41627
+ harness2.setItems([
41628
+ harnessItem("codex", "Codex"),
41629
+ ...next.map((plugin) => harnessItem(plugin.id, plugin.name, plugin))
41630
+ ]);
41631
+ harness2.value = selectedHarness;
41632
+ };
41633
+ function refreshWorkspaces() {
41634
+ workspaces = readNativeScheduleWorkspaces(document2);
41635
+ workspace.setItems([
41636
+ { value: "", label: text("\u81EA\u52A8\u5206\u914D", "Automatic") },
41637
+ ...workspaces.map(({ id, label: label2, cwd }) => ({ value: id, label: `${label2} \xB7 ${cwd}` }))
41638
+ ]);
41639
+ workspace.value = selectedWorkspace?.id ?? "";
41640
+ update();
41641
+ }
41642
+ const cancelConfirmation = () => {
41643
+ if (confirmationTimer !== void 0) view.clearTimeout(confirmationTimer);
41644
+ confirmationTimer = void 0;
41645
+ confirming = false;
41646
+ };
41647
+ const restoredSelection = (selection) => restoring && (restoring.model === null ? !selection.model?.startsWith("codexhost/") : selection.model === restoring.model && selection.reasoningEffort === restoring.reasoningEffort);
41648
+ const confirmSelection = () => {
41649
+ cancelConfirmation();
41650
+ confirming = true;
41651
+ const deadline = Date.now() + 5e3;
41652
+ const check2 = () => {
41653
+ if (retired) return;
41654
+ const binding = readNativeScheduleForm(form);
41655
+ const confirmed = binding && (external() ? binding.selection.model === carrier : !restoring || restoredSelection(binding.selection));
41656
+ if (!binding || !options.canRouteExternal() || client !== options.getClient() || confirmed || Date.now() >= deadline)
41657
+ cancelConfirmation();
41658
+ else confirmationTimer = view.setTimeout(check2, 50);
41659
+ update();
41660
+ };
41661
+ confirmationTimer = view.setTimeout(check2, 0);
41662
+ };
41663
+ const restore = () => {
41664
+ const binding = readNativeScheduleForm(form);
41665
+ if (original && carrier && (!binding || binding.selection.model === carrier || confirming)) {
41666
+ restoring = original;
41667
+ binding?.setModel(original);
41668
+ confirmSelection();
41669
+ }
41670
+ carrier = null;
41671
+ original = null;
41672
+ selectedWorkspace = null;
41673
+ workspace.value = "";
41674
+ };
41675
+ const applyModel = () => {
41676
+ const binding = readNativeScheduleForm(form);
41677
+ const selected = models.find((entry) => entry.ref.id === model2.value);
41678
+ if (!external() || workspaceCreation !== null || !binding?.supportsExternal || !available() || binding.hasTarget || binding.isSaving || !selected)
41679
+ return;
41680
+ original ??= restoring ?? binding.selection;
41681
+ restoring = null;
41682
+ carrier = encodeHarnessPluginRoute({
41683
+ harnessId: selectedHarness,
41684
+ model: selected.ref
41685
+ });
41686
+ binding.setModel({ model: carrier, reasoningEffort: null });
41687
+ confirmSelection();
41688
+ update();
41689
+ };
41690
+ const loadModels = async ({ preserveSelection = false } = {}) => {
41691
+ const request = ++generation;
41692
+ const previousModel = model2.value;
41693
+ if (!preserveSelection) {
41694
+ cancelConfirmation();
41695
+ models = [];
41696
+ model2.setItems([]);
41697
+ model2.value = "";
41698
+ model2.setPlaceholder(text("\u6B63\u5728\u52A0\u8F7D\u6A21\u578B\u2026", "Loading models\u2026"), true);
41699
+ }
41700
+ error51 = "";
41701
+ loading = true;
41702
+ update();
41703
+ const requestedHarness = selectedHarness;
41704
+ const selectedClient = client;
41705
+ try {
41706
+ if (!selectedClient) throw Error(text("\u672C\u5730\u8FDE\u63A5\u4E0D\u53EF\u7528\u3002", "Local connection unavailable."));
41707
+ const result = await selectedClient.inspectHarness({
41708
+ harnessId: requestedHarness,
41709
+ ...selectedWorkspace ? { cwd: selectedWorkspace.cwd } : {}
41710
+ });
41711
+ if (retired || request !== generation || selectedClient !== options.getClient()) return;
41712
+ if (result.status !== "ready")
41713
+ throw Error(text("\u6240\u9009 Harness \u4E0D\u53EF\u7528\u3002", "The selected Harness is unavailable."));
41714
+ const selectedModel = preserveSelection ? model2.value : previousModel;
41715
+ const next = result.catalog.models;
41716
+ const changed = next.length !== models.length || next.some(
41717
+ (entry, index) => entry.ref.id !== models[index]?.ref.id || entry.label !== models[index]?.label
41718
+ );
41719
+ models = next;
41720
+ if (changed || !preserveSelection)
41721
+ model2.setItems(models.map((entry) => ({ value: entry.ref.id, label: entry.label })));
41722
+ const defaultModel = result.catalog.defaultModel;
41723
+ 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 ?? "";
41724
+ model2.setPlaceholder("");
41725
+ if (!models.length) throw Error(text("\u6CA1\u6709\u53EF\u7528\u6A21\u578B\u3002", "No models are available."));
41726
+ if (!preserveSelection) applyModel();
41727
+ } catch (cause) {
41728
+ if (retired || request !== generation) return;
41729
+ error51 = cause instanceof Error ? cause.message : text("\u6A21\u578B\u8BFB\u53D6\u5931\u8D25\u3002", "Could not read models.");
41730
+ if (!preserveSelection) model2.setPlaceholder(text("\u6A21\u578B\u52A0\u8F7D\u5931\u8D25", "Models unavailable"));
41731
+ } finally {
41732
+ if (!retired && request === generation) {
41733
+ loading = false;
41734
+ update();
41735
+ }
41736
+ }
41737
+ };
41738
+ const onHarness = () => {
41739
+ const binding = readNativeScheduleForm(form);
41740
+ if (binding?.hasTarget || binding?.isSaving || workspaceCreation) return;
41741
+ selectedHarness = harness2.value;
41742
+ client = options.getClient();
41743
+ if (!external()) restore();
41744
+ generation++;
41745
+ models = [];
41746
+ model2.setItems([]);
41747
+ model2.value = "";
41748
+ model2.setPlaceholder("");
41749
+ error51 = "";
41750
+ loading = false;
41751
+ if (external()) {
41752
+ refreshWorkspaces();
41753
+ void loadModels();
41754
+ }
41755
+ update();
41756
+ };
41757
+ retry.addEventListener("click", () => {
41758
+ if (error51) void loadModels({ preserveSelection: models.length > 0 });
41759
+ else applyModel();
41760
+ });
41761
+ function blockedReason() {
41762
+ const binding = readNativeScheduleForm(form);
41763
+ if (!external()) {
41764
+ const restored = binding && restoredSelection(binding.selection);
41765
+ if (restoring && !restored)
41766
+ return text(
41767
+ "\u6B63\u5728\u6062\u590D Codex \u914D\u7F6E\uFF0C\u8BF7\u7A0D\u540E\u63D0\u4EA4\u3002",
41768
+ "Restoring Codex settings. Submit again once ready."
41769
+ );
41770
+ restoring = null;
41771
+ if (binding?.selection.model?.startsWith("codexhost/"))
41772
+ return text(
41773
+ "\u4EFB\u52A1\u4ECD\u643A\u5E26\u5916\u90E8 Model\uFF0C\u8BF7\u91CD\u65B0\u6253\u5F00\u5F39\u7A97\u3002",
41774
+ "The task still carries an external Model. Reopen the dialog."
41775
+ );
41776
+ return "";
41777
+ }
41778
+ if (!binding || !options.canRouteExternal() || client !== options.getClient())
41779
+ return text(
41780
+ "\u4EFB\u52A1\u63A5\u5165\u6216\u672C\u5730\u8FDE\u63A5\u4E0D\u53EF\u7528\uFF0C\u8BF7\u91CD\u65B0\u6253\u5F00\u5F39\u7A97\u3002",
41781
+ "Task binding or local connection unavailable. Reopen the dialog."
41782
+ );
41783
+ if (!available())
41784
+ return text(
41785
+ "\u6240\u9009 Harness \u5DF2\u4E0D\u5728\u672C\u5730\u53EF\u7528\u5217\u8868\u4E2D\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u3002",
41786
+ "The selected Harness is no longer available locally. Choose another Harness."
41787
+ );
41788
+ if (!binding.supportsExternal)
41789
+ return text(
41790
+ "\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",
41791
+ "External Harnesses require a personal local task in the same chat. Enable Run on this computer and disable Start each run in new chat."
41792
+ );
41793
+ if (workspaceCreation?.error) return workspaceCreation.error;
41794
+ if (workspaceCreation?.pending)
41795
+ return text("\u6B63\u5728\u521B\u5EFA\u5DE5\u4F5C\u533A\u4F1A\u8BDD\u2026", "Creating workspace chat\u2026");
41796
+ const chosen = selectedWorkspace;
41797
+ if (chosen && !binding.hasTarget && !workspaces.some(({ id, cwd }) => id === chosen.id && cwd === chosen.cwd))
41798
+ return text(
41799
+ "\u6240\u9009\u5DE5\u4F5C\u533A\u5DF2\u4E0D\u53EF\u7528\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u3002",
41800
+ "The selected workspace is no longer available. Choose another workspace."
41801
+ );
41802
+ if (error51) return error51;
41803
+ if (loading)
41804
+ return models.length > 0 ? text(
41805
+ "\u6B63\u5728\u786E\u8BA4\u5DE5\u4F5C\u533A\u7684\u6A21\u578B\u914D\u7F6E\uFF0C\u8BF7\u7A0D\u540E\u63D0\u4EA4\u3002",
41806
+ "Checking workspace models. Submit again once ready."
41807
+ ) : text("\u8BF7\u7B49\u5F85\u5E76\u9009\u62E9\u53EF\u7528\u7684 Model\u3002", "Wait for an available Model and select it.");
41808
+ if (!carrier || !models.some((entry) => entry.ref.id === model2.value))
41809
+ return text(
41810
+ "\u5F53\u524D\u6A21\u578B\u5728\u6B64\u5DE5\u4F5C\u533A\u4E0D\u53EF\u7528\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u6A21\u578B\u3002",
41811
+ "The selected Model is unavailable in this workspace. Choose another Model."
41812
+ );
41813
+ if (binding.selection.model !== carrier && confirming)
41814
+ return text("\u6B63\u5728\u5E94\u7528\u6A21\u578B\u2026", "Applying Model\u2026");
41815
+ if (binding.selection.model !== carrier)
41816
+ return text(
41817
+ "\u4EFB\u52A1\u7684 Model \u5C1A\u672A\u786E\u8BA4\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9 Model\u3002",
41818
+ "The task Model is not confirmed. Select the Model again."
41819
+ );
41820
+ return "";
41821
+ }
41822
+ function update() {
41823
+ if (retired) return;
41824
+ syncAvailablePlugins();
41825
+ const binding = readNativeScheduleForm(form);
41826
+ const active = external();
41827
+ modelRow.hidden = !active;
41828
+ workspaceRow.hidden = !active;
41829
+ fields.disabled = Boolean(binding?.isSaving || binding?.hasTarget || workspaceCreation);
41830
+ workspace.disabled = loading && models.length === 0 || confirming || !binding?.supportsExternal || !available();
41831
+ const modelBusy = loading && models.length === 0 || confirming && active;
41832
+ model2.disabled = modelBusy || models.length === 0 || !binding?.supportsExternal || !available();
41833
+ model2.busy = modelBusy;
41834
+ harness2.busy = confirming && !active;
41835
+ harness2.disabled = fields.disabled;
41836
+ const externalBlocked = !binding?.supportsExternal || !options.canRouteExternal();
41837
+ harness2.setDisabledValues(externalBlocked ? (id) => id !== "codex" : () => false);
41838
+ const blocked = blockedReason();
41839
+ const message2 = loading && models.length === 0 || confirming ? "" : active ? blocked : blocked || error51 || (!binding?.supportsExternal ? text(
41840
+ "\u5916\u90E8 Harness \u9700\u8981\u5728\u9AD8\u7EA7\u8BBE\u7F6E\u4E2D\u9009\u62E9\u672C\u5730\u3001\u56FA\u5B9A\u804A\u5929\u3002",
41841
+ "For external Harnesses, choose local execution in the same chat under Advanced."
41842
+ ) : "");
41843
+ if (status.textContent !== message2) status.textContent = message2;
41844
+ messageRow.hidden = !message2;
41845
+ 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();
41846
+ const rows = active ? new Set(nativeScheduleModelRows(form)) : /* @__PURE__ */ new Set();
41847
+ for (const [row, appearance] of hiddenRows) {
41848
+ if (rows.has(row)) continue;
41849
+ restoreRow(row, appearance);
41850
+ hiddenRows.delete(row);
41851
+ }
41852
+ for (const row of rows) {
41853
+ if (!hiddenRows.has(row))
41854
+ hiddenRows.set(row, {
41855
+ hidden: row.hidden,
41856
+ display: row.style.getPropertyValue("display"),
41857
+ priority: row.style.getPropertyPriority("display")
41858
+ });
41859
+ row.hidden = true;
41860
+ row.style.setProperty("display", "none", "important");
41861
+ }
41862
+ }
41863
+ async function prepareWorkspace(chosen, routeModel) {
41864
+ if (workspaceCreation) return;
41865
+ const attempt = {
41866
+ controller: new AbortController(),
41867
+ pending: true,
41868
+ error: "",
41869
+ thread: void 0
41870
+ };
41871
+ workspaceCreation = attempt;
41872
+ update();
41873
+ try {
41874
+ const binding = readNativeScheduleForm(form);
41875
+ if (!binding) throw Error("Task binding unavailable");
41876
+ attempt.thread = await options.createWorkspaceThread(
41877
+ { workspace: chosen, model: routeModel, title: binding.title },
41878
+ attempt.controller.signal
41879
+ );
41880
+ attempt.controller.signal.throwIfAborted();
41881
+ if (retired || !form.isConnected) throw Error("Task dialog closed");
41882
+ const current = readNativeScheduleForm(form);
41883
+ if (!current?.supportsExternal || current.selection.model !== routeModel || client !== options.getClient())
41884
+ throw Error("Task configuration or connection changed. Reopen the dialog.");
41885
+ current.setTargetThread(attempt.thread.threadId, routeModel);
41886
+ const deadline = Date.now() + 5e3;
41887
+ while (readNativeScheduleForm(form)?.targetThreadId !== attempt.thread.threadId) {
41888
+ attempt.controller.signal.throwIfAborted();
41889
+ if (Date.now() >= deadline)
41890
+ throw Error("The task's target chat was not confirmed. Reopen the dialog.");
41891
+ await new Promise((resolve) => view.setTimeout(resolve, 25));
41892
+ }
41893
+ attempt.controller.signal.throwIfAborted();
41894
+ attempt.pending = false;
41895
+ update();
41896
+ form.requestSubmit();
41897
+ } catch (cause) {
41898
+ let cleanupError = "";
41899
+ if (attempt.thread?.discard) {
41900
+ if (readNativeScheduleForm(form)?.targetThreadId === attempt.thread.threadId)
41901
+ attempt.thread.retain();
41902
+ else {
41903
+ try {
41904
+ await attempt.thread.discard();
41905
+ } catch (error52) {
41906
+ cleanupError = ` ${text("\u4F1A\u8BDD\u6E05\u7406\u5931\u8D25\uFF1A", "Chat cleanup failed:")} ${error52 instanceof Error ? error52.message : String(error52)}`;
41907
+ }
41908
+ }
41909
+ }
41910
+ attempt.error = `${cause instanceof Error ? cause.message : text("\u4F1A\u8BDD\u521B\u5EFA\u5931\u8D25\u3002", "Chat creation failed.")}${cleanupError} ${text("\u8BF7\u5148\u68C0\u67E5\u4F1A\u8BDD\u5217\u8868\uFF0C\u52FF\u91CD\u590D\u521B\u5EFA\u3002", "Check the chat list before creating another task.")}`;
41911
+ } finally {
41912
+ attempt.pending = false;
41913
+ if (!retired) update();
41914
+ }
41915
+ }
41916
+ const onSubmit = (event) => {
41917
+ if (external() && selectedWorkspace) refreshWorkspaces();
41918
+ const reason = blockedReason();
41919
+ if (!reason) {
41920
+ if (external() && selectedWorkspace) {
41921
+ const binding = readNativeScheduleForm(form);
41922
+ const button2 = form.querySelector('button[type="submit"]');
41923
+ if (!button2 || button2.matches(":disabled") || binding?.isSaving) {
41924
+ event.preventDefault();
41925
+ event.stopImmediatePropagation();
41926
+ return;
41927
+ }
41928
+ if (!binding?.hasTarget && carrier) {
41929
+ event.preventDefault();
41930
+ event.stopImmediatePropagation();
41931
+ void prepareWorkspace(selectedWorkspace, carrier);
41932
+ return;
41933
+ }
41934
+ workspaceCreation?.thread?.retain();
41935
+ }
41936
+ return;
41937
+ }
41938
+ event.preventDefault();
41939
+ event.stopImmediatePropagation();
41940
+ messageRow.hidden = loading && models.length === 0 || confirming;
41941
+ status.textContent = reason;
41942
+ };
41943
+ form.addEventListener("submit", onSubmit, true);
41944
+ update();
41945
+ return {
41946
+ root,
41947
+ update,
41948
+ dispose() {
41949
+ retired = true;
41950
+ generation++;
41951
+ if (form.isConnected) restore();
41952
+ cancelConfirmation();
41953
+ harness2.close();
41954
+ model2.close();
41955
+ workspace.close();
41956
+ if (form.isConnected && workspaceCreation?.thread && readNativeScheduleForm(form)?.targetThreadId === workspaceCreation.thread.threadId)
41957
+ workspaceCreation.thread.retain();
41958
+ workspaceCreation?.controller.abort();
41959
+ for (const [row, appearance] of hiddenRows) restoreRow(row, appearance);
41960
+ form.removeEventListener("submit", onSubmit, true);
41961
+ root.remove();
41962
+ }
41963
+ };
41964
+ }
41965
+ function scan() {
41966
+ frame = null;
41967
+ if (disposed) return;
41968
+ for (const [form, control] of mounted) {
41969
+ if (!form.isConnected || !control.root.isConnected) {
41970
+ control.dispose();
41971
+ mounted.delete(form);
41972
+ } else control.update();
41973
+ }
41974
+ for (const form of document2.querySelectorAll('form[data-density="form"]')) {
41975
+ if (!mounted.has(form) && readNativeScheduleForm(form)) mounted.set(form, mount(form));
41976
+ }
41977
+ }
41978
+ const unsubscribeAvailability = options.subscribeAvailability(schedule);
41979
+ const observer = new MutationObserver(schedule);
41980
+ observer.observe(document2.documentElement, { childList: true, subtree: true });
41981
+ document2.addEventListener("change", schedule, true);
41982
+ document2.addEventListener("click", schedule, true);
41983
+ view.addEventListener("codexhost:draft-prewarm-policy-changed", schedule);
41984
+ scan();
41985
+ return {
41986
+ refresh: schedule,
41987
+ dispose() {
41988
+ disposed = true;
41989
+ if (frame !== null) view.cancelAnimationFrame(frame);
41990
+ observer.disconnect();
41991
+ unsubscribeAvailability();
41992
+ document2.removeEventListener("change", schedule, true);
41993
+ document2.removeEventListener("click", schedule, true);
41994
+ view.removeEventListener("codexhost:draft-prewarm-policy-changed", schedule);
41995
+ for (const control of mounted.values()) control.dispose();
41996
+ mounted.clear();
41997
+ }
41998
+ };
41999
+ }
42000
+
40430
42001
  // src/renderer-binding-probe.ts
40431
42002
  var EMPTY_PLUGINS = [];
40432
42003
  function isRetryableHarnessAvailability(availability, error51) {
@@ -40804,6 +42375,9 @@ ${usage_default}`;
40804
42375
  disposed: () => disposed
40805
42376
  });
40806
42377
  const settingsLifecycle = installRendererSettingsLifecycle(window, {
42378
+ harnessSchedules: {
42379
+ openSchedules: (signal) => openCodexSchedules(signal)
42380
+ },
40807
42381
  getRemoteConnections: () => remoteConnections,
40808
42382
  getUpdateClient: () => modelControl,
40809
42383
  getAccountClient: () => modelControl,
@@ -42291,6 +43865,30 @@ ${usage_default}`;
42291
43865
  return () => connectionListeners.delete(listener);
42292
43866
  }
42293
43867
  };
43868
+ const nativeScheduleControls = installRendererNativeScheduleControls(document, {
43869
+ getClient: () => modelClientForHost("local"),
43870
+ getAvailablePlugins: () => {
43871
+ const client = modelClientForHost("local");
43872
+ const state = hostHarnessAvailabilityState("local");
43873
+ if (!client || state.directoryClient !== client) return [];
43874
+ return (state.plugins ?? []).filter((plugin) => plugin.kind !== "usage" && state.availability[plugin.id] === "ready").map((plugin) => pluginForHost("local", plugin.id) ?? plugin);
43875
+ },
43876
+ subscribeAvailability: (listener) => {
43877
+ connectionListeners.add(listener);
43878
+ return () => connectionListeners.delete(listener);
43879
+ },
43880
+ canRouteExternal: () => window.__codexhostHostRoutingV1?.forHost("local")?.policy.scopedCreation === true,
43881
+ async createWorkspaceThread(input, signal) {
43882
+ const routing = window.__codexhostHostRoutingV1;
43883
+ const manager = routing?.forHost("local")?.manager;
43884
+ const create = await loadCodexNativeServices(window, isNativeProjectThreadCreator);
43885
+ signal.throwIfAborted();
43886
+ if (!routing || !manager || routing.forHost("local")?.manager !== manager || !create)
43887
+ throw new Error("Native workspace chat creation is unavailable. Reopen the task dialog.");
43888
+ return createNativeScheduleWorkspaceThread(document, routing, create, input, signal);
43889
+ },
43890
+ locale: () => settingsLifecycle.locale
43891
+ });
42294
43892
  const mount = (composer) => {
42295
43893
  if (mountedByComposer.has(composer) || !composer.isConnected || hasNativeComposerRequest(composer) || orbitComposerKind(composer) !== "codex" || !composer.matches(CODEX_COMPOSER_SELECTOR)) {
42296
43894
  return;
@@ -42625,6 +44223,7 @@ ${usage_default}`;
42625
44223
  const onAdapterStatus = () => {
42626
44224
  publishConnectionStatus();
42627
44225
  if (shouldRefreshCodexAccountsForAdapterState(adapterStatus.state)) {
44226
+ reconcileHarnessAvailabilityHost();
42628
44227
  void loadCodexAccounts();
42629
44228
  sidebarAgentIcons.refresh();
42630
44229
  void refreshHarnessAvailabilityForHost("local");
@@ -42803,6 +44402,7 @@ ${usage_default}`;
42803
44402
  if (disposed || modelControl !== installedModelControl) return;
42804
44403
  try {
42805
44404
  settingsLifecycle.refresh();
44405
+ nativeScheduleControls.refresh();
42806
44406
  } catch {
42807
44407
  }
42808
44408
  });
@@ -42853,6 +44453,7 @@ ${usage_default}`;
42853
44453
  disposeReasoningSoftWrap();
42854
44454
  delegationMention?.dispose();
42855
44455
  sidebarAgentIcons.dispose();
44456
+ nativeScheduleControls.dispose();
42856
44457
  settingsLifecycle.dispose();
42857
44458
  document.removeEventListener("beforeinput", onBeforeInput, true);
42858
44459
  document.removeEventListener("submit", onSubmit, true);
@@ -42929,6 +44530,7 @@ lucide/dist/esm/icons/message-circle-question-mark.mjs:
42929
44530
  lucide/dist/esm/icons/pencil.mjs:
42930
44531
  lucide/dist/esm/icons/x.mjs:
42931
44532
  lucide/dist/esm/icons/boxes.mjs:
44533
+ lucide/dist/esm/icons/calendar-clock.mjs:
42932
44534
  lucide/dist/esm/icons/circle-check.mjs:
42933
44535
  lucide/dist/esm/icons/chevron-down.mjs:
42934
44536
  lucide/dist/esm/icons/chevron-left.mjs: