@oh-my-pi/pi-coding-agent 16.1.9 → 16.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/dist/cli.js +3455 -3430
  3. package/dist/types/config/settings-schema.d.ts +10 -0
  4. package/dist/types/edit/streaming.d.ts +5 -5
  5. package/dist/types/export/html/index.d.ts +31 -2
  6. package/dist/types/export/html/web-palette.d.ts +117 -0
  7. package/dist/types/hindsight/content.d.ts +7 -0
  8. package/dist/types/hindsight/transcript.d.ts +1 -1
  9. package/dist/types/modes/components/hook-editor.d.ts +2 -1
  10. package/dist/types/modes/controllers/selector-controller.d.ts +0 -1
  11. package/dist/types/modes/interactive-mode.d.ts +5 -0
  12. package/dist/types/modes/types.d.ts +17 -0
  13. package/dist/types/modes/utils/keybinding-matchers.d.ts +13 -0
  14. package/dist/types/sdk.d.ts +1 -0
  15. package/dist/types/session/agent-session.d.ts +4 -0
  16. package/dist/types/session/session-context.d.ts +2 -0
  17. package/dist/types/session/session-entries.d.ts +6 -0
  18. package/dist/types/session/session-manager.d.ts +2 -1
  19. package/dist/types/system-prompt.d.ts +2 -0
  20. package/dist/types/tools/acp-bridge.d.ts +29 -0
  21. package/dist/types/tools/browser/aria/aria-snapshot.d.ts +39 -0
  22. package/dist/types/tools/browser/cmux/cmux-tab.d.ts +10 -0
  23. package/dist/types/tools/browser/tab-worker.d.ts +20 -0
  24. package/dist/types/tools/browser.d.ts +1 -0
  25. package/dist/types/tools/find.d.ts +1 -2
  26. package/dist/types/tools/write.d.ts +1 -2
  27. package/dist/types/utils/image-loading.d.ts +4 -3
  28. package/dist/types/utils/jj.d.ts +25 -0
  29. package/dist/types/utils/title-generator.d.ts +0 -2
  30. package/package.json +12 -12
  31. package/scripts/generate-aria-snapshot.ts +134 -0
  32. package/scripts/generate-share-viewer.ts +4 -2
  33. package/src/autoresearch/git.ts +12 -0
  34. package/src/config/settings-schema.ts +12 -0
  35. package/src/discovery/opencode.ts +47 -4
  36. package/src/edit/hashline/filesystem.ts +8 -0
  37. package/src/edit/modes/patch.ts +18 -2
  38. package/src/edit/modes/replace.ts +13 -10
  39. package/src/edit/streaming.ts +5 -5
  40. package/src/export/html/index.ts +50 -8
  41. package/src/export/html/web-palette.ts +142 -0
  42. package/src/hindsight/backend.ts +4 -4
  43. package/src/hindsight/content.ts +17 -1
  44. package/src/hindsight/transcript.ts +2 -2
  45. package/src/internal-urls/docs-index.generated.txt +1 -1
  46. package/src/modes/components/agent-dashboard.ts +8 -8
  47. package/src/modes/components/hook-editor.ts +13 -10
  48. package/src/modes/components/session-selector.ts +3 -0
  49. package/src/modes/controllers/event-controller.ts +29 -5
  50. package/src/modes/controllers/extension-ui-controller.ts +6 -2
  51. package/src/modes/controllers/selector-controller.ts +3 -5
  52. package/src/modes/interactive-mode.ts +69 -29
  53. package/src/modes/theme/dark.json +1 -1
  54. package/src/modes/types.ts +18 -0
  55. package/src/modes/utils/keybinding-matchers.ts +36 -1
  56. package/src/modes/utils/ui-helpers.ts +1 -0
  57. package/src/prompts/system/project-prompt.md +2 -0
  58. package/src/prompts/system/system-prompt.md +0 -1
  59. package/src/prompts/tools/browser.md +5 -2
  60. package/src/sdk.ts +20 -2
  61. package/src/session/agent-session.ts +38 -14
  62. package/src/session/session-context.ts +5 -0
  63. package/src/session/session-entries.ts +6 -0
  64. package/src/session/session-manager.ts +3 -1
  65. package/src/system-prompt.ts +15 -3
  66. package/src/task/worktree.ts +12 -4
  67. package/src/thinking.ts +1 -1
  68. package/src/tools/acp-bridge.ts +66 -0
  69. package/src/tools/bash.ts +3 -3
  70. package/src/tools/browser/aria/aria-snapshot.bundle.txt +7 -0
  71. package/src/tools/browser/aria/aria-snapshot.ts +103 -0
  72. package/src/tools/browser/cmux/cmux-tab.ts +73 -1
  73. package/src/tools/browser/tab-worker.ts +242 -47
  74. package/src/tools/browser.ts +5 -0
  75. package/src/tools/find.ts +1 -2
  76. package/src/tools/index.ts +1 -1
  77. package/src/tools/write.ts +3 -27
  78. package/src/utils/git.ts +3 -2
  79. package/src/utils/image-loading.ts +6 -3
  80. package/src/utils/jj.ts +47 -0
  81. package/src/utils/title-generator.ts +31 -99
@@ -210,7 +210,7 @@ import { resolveMemoryBackend } from "../memory-backend";
210
210
  import { shutdownMnemopiEmbedClient } from "../mnemopi/embed-client";
211
211
  import { getMnemopiSessionState, type MnemopiSessionState, setMnemopiSessionState } from "../mnemopi/state";
212
212
  import { containsOrchestrate, ORCHESTRATE_NOTICE } from "../modes/orchestrate";
213
- import { getCurrentThemeName, theme } from "../modes/theme/theme";
213
+ import { theme } from "../modes/theme/theme";
214
214
  import { parseTurnBudget } from "../modes/turn-budget";
215
215
  import { containsUltrathink, ULTRATHINK_NOTICE } from "../modes/ultrathink";
216
216
  import { computeNonMessageBreakdown, computeNonMessageTokens } from "../modes/utils/context-usage";
@@ -477,6 +477,8 @@ export interface AgentSessionConfig {
477
477
  modelRegistry: ModelRegistry;
478
478
  /** Tool registry for LSP and settings */
479
479
  toolRegistry?: Map<string, AgentTool>;
480
+ /** Tool names whose current registry entry is still the built-in implementation. */
481
+ builtInToolNames?: Iterable<string>;
480
482
  /** Current session pre-LLM message transform pipeline */
481
483
  transformContext?: (messages: AgentMessage[], signal?: AbortSignal) => AgentMessage[] | Promise<AgentMessage[]>;
482
484
  /** Provider payload hook used by the active session request path */
@@ -1290,6 +1292,7 @@ export class AgentSession {
1290
1292
  // Generic tool discovery (covers built-in + MCP + extension when tools.discoveryMode === "all")
1291
1293
  #discoverableToolSearchIndex: DiscoverableToolSearchIndex | null = null;
1292
1294
  #selectedDiscoveredToolNames = new Set<string>();
1295
+ #builtInToolNames = new Set<string>();
1293
1296
  #rpcHostToolNames = new Set<string>();
1294
1297
  #defaultSelectedMCPServerNames = new Set<string>();
1295
1298
  #defaultSelectedMCPToolNames = new Set<string>();
@@ -1566,6 +1569,7 @@ export class AgentSession {
1566
1569
  this.#pruneToolDescriptions = config.pruneToolDescriptions === true;
1567
1570
  this.#validateRetryFallbackChains();
1568
1571
  this.#toolRegistry = config.toolRegistry ?? new Map();
1572
+ this.#builtInToolNames = new Set(config.builtInToolNames ?? []);
1569
1573
  this.#requestedToolNames = config.requestedToolNames;
1570
1574
  this.#transformContext = config.transformContext ?? (messages => messages);
1571
1575
  this.#onPayload = config.onPayload;
@@ -4496,6 +4500,11 @@ export class AgentSession {
4496
4500
  return this.#toolRegistry.get(name);
4497
4501
  }
4498
4502
 
4503
+ /** True when the current registry entry for `name` came from a built-in factory. */
4504
+ hasBuiltInTool(name: string): boolean {
4505
+ return this.#builtInToolNames.has(name);
4506
+ }
4507
+
4499
4508
  /**
4500
4509
  * Get all configured tool names (built-in via --tools or default, plus custom tools).
4501
4510
  */
@@ -6835,7 +6844,7 @@ export class AgentSession {
6835
6844
  this.#pendingNextTurnMessages = [];
6836
6845
  this.#scheduledHiddenNextTurnGeneration = undefined;
6837
6846
 
6838
- this.sessionManager.appendThinkingLevelChange(this.thinkingLevel);
6847
+ this.sessionManager.appendThinkingLevelChange(this.thinkingLevel, this.configuredThinkingLevel());
6839
6848
  this.sessionManager.appendServiceTierChange(this.serviceTier ?? null);
6840
6849
  if (nextDiscoverySessionToolNames) {
6841
6850
  await this.#applyActiveToolsByName(nextDiscoverySessionToolNames, { persistMCPSelection: false });
@@ -7234,16 +7243,20 @@ export class AgentSession {
7234
7243
  return;
7235
7244
  }
7236
7245
 
7246
+ const wasAuto = this.#autoThinking;
7237
7247
  this.#autoThinking = false;
7238
7248
  this.#autoResolvedLevel = undefined;
7239
7249
  const effectiveLevel = resolveThinkingLevelForModel(this.model, level);
7240
- const isChanging = effectiveLevel !== this.#thinkingLevel;
7250
+ // Leaving auto must persist even when the resolved effort is unchanged (e.g.
7251
+ // auto resolved to medium, then the user pins medium): otherwise the latest
7252
+ // session entry keeps `configured: "auto"` and resume re-enables auto.
7253
+ const isChanging = wasAuto || effectiveLevel !== this.#thinkingLevel;
7241
7254
 
7242
7255
  this.#thinkingLevel = effectiveLevel;
7243
7256
  this.#applyThinkingLevelToAgent(effectiveLevel);
7244
7257
 
7245
7258
  if (isChanging) {
7246
- this.sessionManager.appendThinkingLevelChange(effectiveLevel);
7259
+ this.sessionManager.appendThinkingLevelChange(effectiveLevel, effectiveLevel);
7247
7260
  if (persist && effectiveLevel !== undefined && effectiveLevel !== ThinkingLevel.Off) {
7248
7261
  this.settings.set("defaultThinkingLevel", effectiveLevel);
7249
7262
  }
@@ -7332,7 +7345,7 @@ export class AgentSession {
7332
7345
  this.#thinkingLevel = effort;
7333
7346
  this.#applyThinkingLevelToAgent(effort);
7334
7347
  if (shouldPersistResolution) {
7335
- this.sessionManager.appendThinkingLevelChange(effort);
7348
+ this.sessionManager.appendThinkingLevelChange(effort, AUTO_THINKING);
7336
7349
  }
7337
7350
  this.#emit({
7338
7351
  type: "thinking_level_changed",
@@ -11608,18 +11621,26 @@ export class AgentSession {
11608
11621
  .some(entry => entry.type === "service_tier_change");
11609
11622
  const defaultThinkingLevel = parseConfiguredThinkingLevel(this.settings.get("defaultThinkingLevel"));
11610
11623
  const configuredServiceTier = this.settings.get("serviceTier");
11611
- // Session log entries store only concrete levels. When `auto` has resolved
11612
- // for a turn, the persisted context may already carry that concrete level
11613
- // even if the branch scan races a just-flushed thinking entry under isolated
11614
- // parallel test workers. Prefer the concrete context value in that case;
11615
- // otherwise keep the configured `auto` selector so fresh sessions still
11616
- // classify their first turn.
11624
+ // Restore the thinking selector. Each change persists the configured
11625
+ // selector (`auto` or a concrete level), so prefer it: an `auto` session
11626
+ // resumes in auto mode (reclassifying the next turn) instead of freezing at
11627
+ // the last resolved level. Entries written before the `configured` field
11628
+ // existed fall back to the concrete level (legacy pin-on-resume behavior).
11629
+ // With no thinking entry, fall back to the global default so fresh sessions
11630
+ // still classify their first turn.
11631
+ const restoredConfigured = sessionContext.configuredThinkingLevel;
11617
11632
  const restoredThinkingLevel: ConfiguredThinkingLevel | undefined =
11618
11633
  hasThinkingEntry || (defaultThinkingLevel === AUTO_THINKING && sessionContext.thinkingLevel !== "off")
11619
- ? (sessionContext.thinkingLevel as ThinkingLevel | undefined)
11634
+ ? restoredConfigured === AUTO_THINKING
11635
+ ? AUTO_THINKING
11636
+ : (sessionContext.thinkingLevel as ThinkingLevel | undefined)
11620
11637
  : defaultThinkingLevel;
11621
11638
  if (restoredThinkingLevel === AUTO_THINKING) {
11622
11639
  this.#autoThinking = true;
11640
+ // Resume in auto (pending) like a fresh auto session: the next user
11641
+ // turn reclassifies. We intentionally do not seed the last resolved
11642
+ // effort, so the cold (--continue) and in-app switch paths display
11643
+ // identically as `auto` until then.
11623
11644
  this.#autoResolvedLevel = undefined;
11624
11645
  this.#thinkingLevel = resolveProvisionalAutoLevel(this.model);
11625
11646
  } else {
@@ -12513,9 +12534,12 @@ export class AgentSession {
12513
12534
  * @returns Path to exported file
12514
12535
  */
12515
12536
  async exportToHtml(outputPath?: string): Promise<string> {
12516
- const themeName = getCurrentThemeName();
12537
+ // Public HTML export ships in the omp brand palette (collab-web
12538
+ // pink/purple), matching my.omp.sh — not the host's terminal theme.
12539
+ // Callers who want a themed export can pass `palette: "theme"` with
12540
+ // `themeName` directly to `exportSessionToHtml`.
12517
12541
  const { exportSessionToHtml } = await import("../export/html");
12518
- return exportSessionToHtml(this.sessionManager, this.state, { outputPath, themeName });
12542
+ return exportSessionToHtml(this.sessionManager, this.state, { outputPath, palette: "web" });
12519
12543
  }
12520
12544
 
12521
12545
  // =========================================================================
@@ -7,6 +7,8 @@ import { type CompactionEntry, EPHEMERAL_MODEL_CHANGE_ROLE, type SessionEntry }
7
7
  export interface SessionContext {
8
8
  messages: AgentMessage[];
9
9
  thinkingLevel?: string;
10
+ /** Configured thinking selector (`"auto"` or a concrete level) from the latest change. */
11
+ configuredThinkingLevel?: string;
10
12
  serviceTier?: ServiceTier;
11
13
  /** Model roles: { default: "provider/modelId", small: "provider/modelId", ... } */
12
14
  models: Record<string, string>;
@@ -134,6 +136,7 @@ export function buildSessionContext(
134
136
 
135
137
  // Extract settings and find compaction
136
138
  let thinkingLevel: string | undefined = "off";
139
+ let configuredThinkingLevel: string | undefined;
137
140
  let serviceTier: ServiceTier | undefined;
138
141
  const models: Record<string, string> = {};
139
142
  let compaction: CompactionEntry | null = null;
@@ -154,6 +157,7 @@ export function buildSessionContext(
154
157
  for (const entry of path) {
155
158
  if (entry.type === "thinking_level_change") {
156
159
  thinkingLevel = entry.thinkingLevel ?? "off";
160
+ configuredThinkingLevel = entry.configured ?? entry.thinkingLevel ?? undefined;
157
161
  } else if (entry.type === "model_change") {
158
162
  // New format: { model: "provider/id", role?: string }
159
163
  if (entry.model) {
@@ -388,6 +392,7 @@ export function buildSessionContext(
388
392
  messages,
389
393
  cacheMissExplainedAt: options?.transcript ? cacheMissExplainedAt : undefined,
390
394
  thinkingLevel,
395
+ configuredThinkingLevel,
391
396
  serviceTier,
392
397
  models,
393
398
  injectedTtsrRules,
@@ -37,6 +37,12 @@ export interface SessionMessageEntry extends SessionEntryBase {
37
37
  export interface ThinkingLevelChangeEntry extends SessionEntryBase {
38
38
  type: "thinking_level_change";
39
39
  thinkingLevel?: string | null;
40
+ /**
41
+ * The user-configured selector at the time of this change: `"auto"` when auto
42
+ * mode was active, otherwise the concrete level. Absent on entries written
43
+ * before auto-mode persistence existed; readers fall back to `thinkingLevel`.
44
+ */
45
+ configured?: string | null;
40
46
  }
41
47
 
42
48
  export interface ModelChangeEntry extends SessionEntryBase {
@@ -1158,11 +1158,13 @@ export class SessionManager {
1158
1158
  return entry.id;
1159
1159
  }
1160
1160
 
1161
- appendThinkingLevelChange(thinkingLevel?: string): string {
1161
+ /** Append a thinking level change as child of current leaf, then advance leaf. Returns entry id. */
1162
+ appendThinkingLevelChange(thinkingLevel?: string, configured?: string): string {
1162
1163
  const entry: ThinkingLevelChangeEntry = {
1163
1164
  type: "thinking_level_change",
1164
1165
  ...this.#freshEntryFields(),
1165
1166
  thinkingLevel: thinkingLevel ?? null,
1167
+ configured: configured ?? null,
1166
1168
  };
1167
1169
  this.#recordEntry(entry);
1168
1170
  return entry.id;
@@ -421,6 +421,8 @@ export interface BuildSystemPromptOptions {
421
421
  model?: string;
422
422
  /** Personality preset rendered into the default system prompt. "none" omits the block. Default: "default" */
423
423
  personality?: Personality;
424
+ /** Whether to include the workspace directory tree in the system prompt. Default: false */
425
+ includeWorkspaceTree?: boolean;
424
426
  }
425
427
 
426
428
  /** Result of building provider-facing system prompt messages. */
@@ -461,6 +463,7 @@ export async function buildSystemPrompt(options: BuildSystemPromptOptions = {}):
461
463
  memoryRootEnabled = false,
462
464
  model,
463
465
  personality = "default",
466
+ includeWorkspaceTree = false,
464
467
  } = options;
465
468
  const inlineToolDescriptors = providedInlineToolDescriptors ?? false;
466
469
  const resolvedCwd = cwd ?? getProjectDir();
@@ -523,9 +526,17 @@ export async function buildSystemPrompt(options: BuildSystemPromptOptions = {}):
523
526
  const workspaceTreePromise =
524
527
  providedWorkspaceTree !== undefined
525
528
  ? Promise.resolve(providedWorkspaceTree)
526
- : logger.time("buildWorkspaceTree", () =>
527
- buildWorkspaceTree(resolvedCwd, { timeoutMs: SYSTEM_PROMPT_PREP_TIMEOUT_MS }),
528
- );
529
+ : includeWorkspaceTree
530
+ ? logger.time("buildWorkspaceTree", () =>
531
+ buildWorkspaceTree(resolvedCwd, { timeoutMs: SYSTEM_PROMPT_PREP_TIMEOUT_MS }),
532
+ )
533
+ : Promise.resolve({
534
+ rootPath: resolvedCwd,
535
+ rendered: "",
536
+ truncated: false,
537
+ totalLines: 0,
538
+ agentsMdFiles: [],
539
+ });
529
540
  const skillsPromise: Promise<Skill[]> =
530
541
  providedSkills !== undefined
531
542
  ? Promise.resolve(providedSkills)
@@ -670,6 +681,7 @@ export async function buildSystemPrompt(options: BuildSystemPromptOptions = {}):
670
681
  secretsEnabled,
671
682
  hasMemoryRoot: memoryRootEnabled,
672
683
  hasObsidian: hasObsidian(),
684
+ includeWorkspaceTree,
673
685
  };
674
686
  const rendered = prompt.render(resolvedCustomPrompt ? customSystemPromptTemplate : systemPromptTemplate, data);
675
687
  const systemPrompt = [rendered];
@@ -5,6 +5,7 @@ import * as path from "node:path";
5
5
  import * as natives from "@oh-my-pi/pi-natives";
6
6
  import { getWorktreeDir, hashPath, logger, Snowflake } from "@oh-my-pi/pi-utils";
7
7
  import * as git from "../utils/git";
8
+ import * as jj from "../utils/jj";
8
9
  import { mapWithConcurrencyLimit } from "./parallel";
9
10
 
10
11
  const { IsoBackendKind } = natives;
@@ -28,12 +29,19 @@ export interface WorktreeBaseline {
28
29
  }
29
30
 
30
31
  export async function getRepoRoot(cwd: string): Promise<string> {
31
- const repoRoot = await git.repo.root(cwd);
32
- if (!repoRoot) {
33
- throw new Error("Git repository not found for isolated task execution.");
32
+ // Pure-jj check runs first so a jj workspace nested under an unrelated
33
+ // outer Git checkout is rejected at its own root rather than silently
34
+ // mutating the surrounding Git tree behind jj's back.
35
+ if (await jj.isPureJjRepo(cwd)) {
36
+ throw new Error(
37
+ "Isolated task execution requires a Git checkout, but this workspace is pure Jujutsu (`.jj/` without a colocated `.git/`). Run `jj git init --colocate` to add a Git checkout, or set `task.isolation.mode: none` to disable task isolation.",
38
+ );
34
39
  }
35
40
 
36
- return repoRoot;
41
+ const repoRoot = await git.repo.root(cwd);
42
+ if (repoRoot) return repoRoot;
43
+
44
+ throw new Error("Git repository not found for isolated task execution.");
37
45
  }
38
46
 
39
47
  const GIT_NO_INDEX_NULL_PATH = process.platform === "win32" ? "NUL" : "/dev/null";
package/src/thinking.ts CHANGED
@@ -32,7 +32,7 @@ const THINKING_LEVEL_METADATA: Record<ThinkingLevel, ThinkingLevelMetadata> = {
32
32
  [ThinkingLevel.High]: { value: ThinkingLevel.High, label: "high", description: "Deep reasoning (~16k tokens)" },
33
33
  [ThinkingLevel.XHigh]: {
34
34
  value: ThinkingLevel.XHigh,
35
- label: "max",
35
+ label: "xhigh",
36
36
  description: "Maximum reasoning (~32k tokens)",
37
37
  },
38
38
  };
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Shared ACP client bridge routing for file-write sites.
3
+ *
4
+ * When an ACP client (e.g. Zed) advertises the `fs.writeTextFile` capability,
5
+ * all write-mode tools must route through it so the editor's open buffer is
6
+ * updated immediately. Internal artifacts ('/Users/theo/.omp/agent/sessions/-Projects-oh-my-pi/2026-06-10T09-11-41-506Z_019eb0cd-3ec2-7000-92aa-1b82aa4d78f0/local' plan files, other scheme
7
+ * URLs) are always written directly to disk — those are OMP-owned and should
8
+ * never be pushed into the editor.
9
+ */
10
+ import type { ToolSession } from ".";
11
+ import { invalidateFsScanAfterWrite } from "./fs-cache-invalidation";
12
+ import { isInternalUrlPath } from "./path-utils";
13
+ import { resolvePlanPath } from "./plan-mode-guard";
14
+ import { ToolError } from "./tool-errors";
15
+
16
+ /**
17
+ * Return `true` when an ACP client bridge write is appropriate for this path.
18
+ *
19
+ * Returns `false` for internal-URL paths (e.g. `'/Users/theo/.omp/agent/sessions/-Projects-oh-my-pi/2026-06-10T09-11-41-506Z_019eb0cd-3ec2-7000-92aa-1b82aa4d78f0/local/PLAN.md'`) and for the
20
+ * active plan file while plan mode is enabled — both are OMP-internal artifacts
21
+ * that must stay off the editor's buffer.
22
+ */
23
+ export function shouldRouteWriteThroughBridge(
24
+ session: ToolSession,
25
+ requestedPath: string,
26
+ absolutePath: string,
27
+ ): boolean {
28
+ if (isInternalUrlPath(requestedPath)) return false;
29
+
30
+ const state = session.getPlanModeState?.();
31
+ if (!state?.enabled || !isInternalUrlPath(state.planFilePath)) return true;
32
+
33
+ return absolutePath !== resolvePlanPath(session, state.planFilePath);
34
+ }
35
+
36
+ /**
37
+ * Try to route a file write through the ACP client bridge.
38
+ *
39
+ * Performs the full guard check, bridge call (wrapped in {@link ToolError}),
40
+ * FS-scan cache invalidation, and session mutation-version bump.
41
+ *
42
+ * Returns `true` when the bridge was used and the caller must skip the
43
+ * writethrough path. Returns `false` when the bridge is unavailable or the
44
+ * path should not be routed through it.
45
+ */
46
+ export async function routeWriteThroughBridge(
47
+ session: ToolSession,
48
+ requestedPath: string,
49
+ absolutePath: string,
50
+ content: string,
51
+ ): Promise<boolean> {
52
+ if (!shouldRouteWriteThroughBridge(session, requestedPath, absolutePath)) return false;
53
+
54
+ const bridge = session.getClientBridge?.();
55
+ if (!bridge?.capabilities.writeTextFile || !bridge.writeTextFile) return false;
56
+
57
+ try {
58
+ await bridge.writeTextFile({ path: absolutePath, content });
59
+ } catch (error) {
60
+ throw new ToolError(error instanceof Error ? error.message : String(error));
61
+ }
62
+
63
+ invalidateFsScanAfterWrite(absolutePath);
64
+ session.bumpFileMutationVersion?.(absolutePath);
65
+ return true;
66
+ }
package/src/tools/bash.ts CHANGED
@@ -1132,9 +1132,9 @@ function getPartialJson<TArgs>(args: TArgs | undefined): string | undefined {
1132
1132
  }
1133
1133
 
1134
1134
  export function getBashEnvForDisplay(args: BashRenderArgs): Record<string, string> | undefined {
1135
- // During streaming, partial-json parsing often does not surface env values until the object closes.
1136
- // Recover them from the raw JSON buffer so the pending bash preview can show `NAME="..." cmd` immediately,
1137
- // instead of rendering only the command and making the env assignment appear at the very end.
1135
+ // The parsed args don't always mirror the exact current stream prefix, so recover
1136
+ // env from the raw JSON buffer to surface `NAME="..." cmd` in the preview as it
1137
+ // streams rather than only once the args object finishes.
1138
1138
  const partialEnv = extractPartialBashEnv(args.__partialJson);
1139
1139
  if (partialEnv && args.env) return { ...partialEnv, ...args.env };
1140
1140
  return args.env ?? partialEnv;
@@ -0,0 +1,7 @@
1
+ // @generated by scripts/generate-aria-snapshot.ts from Playwright v1.61.0
2
+ // Bundled from Playwright's injected ARIA-snapshot sources (Apache-2.0, (c) Microsoft).
3
+ // Do not edit by hand. Regenerate with: bun scripts/generate-aria-snapshot.ts
4
+ var{defineProperty:M_,getOwnPropertyNames:WX,getOwnPropertyDescriptor:LX}=Object,zX=Object.prototype.hasOwnProperty;function MX(_){return this[_]}var jX=(_)=>{var J=(k_??=new WeakMap).get(_),Z;if(J)return J;if(J=M_({},"__esModule",{value:!0}),_&&typeof _==="object"||typeof _==="function"){for(var $ of WX(_))if(!zX.call(J,$))M_(J,$,{get:MX.bind(_,$),enumerable:!(Z=LX(_,$))||Z.enumerable})}return k_.set(_,J),J},k_;var FX=(_)=>_;function BX(_,J){this[_]=FX.bind(null,J)}var IX=(_,J)=>{for(var Z in J)M_(_,Z,{get:J[Z],enumerable:!0,configurable:!0,set:BX.bind(J,Z)})};var YZ={};IX(YZ,{resolveAriaRef:()=>$Z,ariaSnapshot:()=>ZZ});module.exports=jX(YZ);function h_(_,J){if(_.role!==J.role||_.name!==J.name)return!1;if(!VX(_,J)||d(_)!==d(J))return!1;let Z=Object.keys(_.props),$=Object.keys(J.props);return Z.length===$.length&&Z.every((X)=>_.props[X]===J.props[X])}function d(_){return _.box.cursor==="pointer"}function VX(_,J){return _.active===J.active&&_.checked===J.checked&&_.disabled===J.disabled&&_.expanded===J.expanded&&_.invalid===J.invalid&&_.selected===J.selected&&_.level===J.level&&_.pressed===J.pressed}var u_;function j_(_){let J=u_?.get(_);if(J===void 0)J=_.replace(/[\u200b\u00ad]/g,"").trim().replace(/\s+/g," "),u_?.set(_,J);return J}function F_(_){return _.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function p_(_,J){let Z=_.length,$=J.length,X=0,Q=0,U=Array(Z+1).fill(null).map(()=>Array($+1).fill(0));for(let W=1;W<=Z;W++)for(let Y=1;Y<=$;Y++)if(_[W-1]===J[Y-1]){if(U[W][Y]=U[W-1][Y-1]+1,U[W][Y]>X)X=U[W][Y],Q=W}return _.slice(Q-X,Q)}var HZ=new RegExp("([\\u001B\\u009B][[\\]()#?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)|(?:(?:\\d{0,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~])))","g");function c_(_){if(!m_(_))return _;return"'"+_.replace(/'/g,"''")+"'"}function e(_){if(!m_(_))return _;return'"'+_.replace(/[\\"\x00-\x1f\x7f-\x9f]/g,(J)=>{switch(J){case"\\":return"\\\\";case'"':return"\\\"";case"\b":return"\\b";case"\f":return"\\f";case`
5
+ `:return"\\n";case"\r":return"\\r";case"\t":return"\\t";default:return"\\x"+J.charCodeAt(0).toString(16).padStart(2,"0")}})+'"'}function m_(_){if(_.length===0)return!0;if(/^\s|\s$/.test(_))return!0;if(/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\x9f]/.test(_))return!0;if(/^-/.test(_))return!0;if(/[\n:](\s|$)/.test(_))return!0;if(/\s#/.test(_))return!0;if(/[\n\r]/.test(_))return!0;if(/^[&*\],?!>|@"'#%]/.test(_))return!0;if(/[{}`]/.test(_))return!0;if(/^\[/.test(_))return!0;if(!isNaN(Number(_))||["y","n","yes","no","true","false","on","off","null"].includes(_.toLowerCase()))return!0;return!1}var DX={};function h(_){if(_.parentElement)return _.parentElement;if(!_.parentNode)return;if(_.parentNode.nodeType===11&&_.parentNode.host)return _.parentNode.host}function d_(_){let J=_;while(J.parentNode)J=J.parentNode;if(J.nodeType===11||J.nodeType===9)return J}function OX(_){while(_.parentElement)_=_.parentElement;return h(_)}function s(_,J,Z){while(_){let $=_.closest(J);if(Z&&$!==Z&&$?.contains(Z))return;if($)return $;_=OX(_)}}function b(_,J){let Z=J==="::before"?R_:J==="::after"?D_:V_;if(Z&&Z.has(_))return Z.get(_);let $=_.ownerDocument&&_.ownerDocument.defaultView?_.ownerDocument.defaultView.getComputedStyle(_,J):void 0;return Z?.set(_,$),$}function B_(_,J){if(J=J??b(_),!J)return!0;if(Element.prototype.checkVisibility&&DX.browserNameForWorkarounds!=="webkit"){if(!_.checkVisibility())return!1}else{let Z=_.closest("details,summary");if(Z!==_&&Z?.nodeName==="DETAILS"&&!Z.open)return!1}if(J.visibility!=="visible")return!1;return!0}function i(_){let J=b(_);if(!J)return{visible:!0,inline:!1};let Z=J.cursor;if(J.display==="contents"){for(let X=_.firstChild;X;X=X.nextSibling){if(X.nodeType===1&&__(X))return{visible:!0,inline:!1,cursor:Z};if(X.nodeType===3&&I_(X))return{visible:!0,inline:!0,cursor:Z}}return{visible:!1,inline:!1,cursor:Z}}if(!B_(_,J))return{cursor:Z,visible:!1,inline:!1};let $=_.getBoundingClientRect();return{cursor:Z,visible:$.width>0&&$.height>0,inline:J.display==="inline"}}function __(_){return i(_).visible}function I_(_){let J=_.ownerDocument.createRange();J.selectNode(_);let Z=J.getBoundingClientRect();return Z.width>0&&Z.height>0}function V(_){let J=_.tagName;if(typeof J==="string")return J.toUpperCase();if(_ instanceof HTMLFormElement)return"FORM";return _.tagName.toUpperCase()}var V_,R_,D_,s_=0;function i_(){++s_,V_??=new Map,R_??=new Map,D_??=new Map}function l_(){if(!--s_)V_=void 0,R_=void 0,D_=void 0}var R=function(_,J,Z){return _>=J&&_<=Z};function A(_){return R(_,48,57)}function r_(_){return A(_)||R(_,65,70)||R(_,97,102)}function wX(_){return R(_,65,90)}function AX(_){return R(_,97,122)}function EX(_){return wX(_)||AX(_)}function PX(_){return _>=128}function J_(_){return EX(_)||PX(_)||_===95}function a_(_){return J_(_)||A(_)||_===45}function fX(_){return R(_,0,8)||_===11||R(_,14,31)||_===127}function u(_){return _===10}function T(_){return u(_)||_===9||_===32}var CX=1114111;class Z_ extends Error{constructor(_){super(_);this.name="InvalidCharacterError"}}function bX(_){let J=[];for(let Z=0;Z<_.length;Z++){let $=_.charCodeAt(Z);if($===13&&_.charCodeAt(Z+1)===10)$=10,Z++;if($===13||$===12)$=10;if($===0)$=65533;if(R($,55296,56319)&&R(_.charCodeAt(Z+1),56320,57343)){let X=$-55296,Q=_.charCodeAt(Z+1)-56320;$=Math.pow(2,16)+X*Math.pow(2,10)+Q,Z++}J.push($)}return J}function D(_){if(_<=65535)return String.fromCharCode(_);_-=Math.pow(2,16);let J=Math.floor(_/Math.pow(2,10))+55296,Z=_%Math.pow(2,10)+56320;return String.fromCharCode(J)+String.fromCharCode(Z)}function n_(_){let J=bX(_),Z=-1,$=[],X,Q=0,U=0,W=0,Y=function(){Q+=1,W=U,U=0},K={line:Q,column:U},z=function(G){if(G>=J.length)return-1;return J[G]},q=function(G){if(G===void 0)G=1;if(G>3)throw"Spec Error: no more than three codepoints of lookahead.";return z(Z+G)},L=function(G){if(G===void 0)G=1;if(Z+=G,X=z(Z),u(X))Y();else U+=G;return!0},I=function(){if(Z-=1,u(X))Q-=1,U=W;else U-=1;return K.line=Q,K.column=U,!0},H=function(G){if(G===void 0)G=X;return G===-1},F=function(){},j=function(){},w=function(){if(E(),L(),T(X)){while(T(q()))L();return new $_}else if(X===34)return K_();else if(X===35)if(a_(q())||k(q(1),q(2))){let G=new jJ("");if(o(q(1),q(2),q(3)))G.type="id";return G.value=t(),G}else return new O(X);else if(X===36)if(q()===61)return L(),new KJ;else return new O(X);else if(X===39)return K_();else if(X===40)return new HJ;else if(X===41)return new Y_;else if(X===42)if(q()===61)return L(),new WJ;else return new O(X);else if(X===43)if(W_())return I(),S();else return new O(X);else if(X===44)return new XJ;else if(X===45)if(W_())return I(),S();else if(q(1)===45&&q(2)===62)return L(2),new e_;else if(QX())return I(),m();else return new O(X);else if(X===46)if(W_())return I(),S();else return new O(X);else if(X===58)return new _J;else if(X===59)return new JJ;else if(X===60)if(q(1)===33&&q(2)===45&&q(3)===45)return L(3),new t_;else return new O(X);else if(X===64)if(o(q(1),q(2),q(3)))return new MJ(t());else return new O(X);else if(X===91)return new YJ;else if(X===92)if(n())return I(),m();else return j(),new O(X);else if(X===93)return new QJ;else if(X===94)if(q()===61)return L(),new UJ;else return new O(X);else if(X===123)return new ZJ;else if(X===124)if(q()===61)return L(),new GJ;else if(q()===124)return L(),new LJ;else return new O(X);else if(X===125)return new $J;else if(X===126)if(q()===61)return L(),new qJ;else return new O(X);else if(A(X))return I(),S();else if(J_(X))return I(),m();else if(H())return new zJ;else return new O(X)},E=function(){while(q(1)===47&&q(2)===42){L(2);while(!0)if(L(),X===42&&q()===47){L();break}else if(H()){j();return}}},S=function(){let G=qX();if(o(q(1),q(2),q(3))){let M=new VJ;return M.value=G.value,M.repr=G.repr,M.type=G.type,M.unit=t(),M}else if(q()===37){L();let M=new IJ;return M.value=G.value,M.repr=G.repr,M}else{let M=new BJ;return M.value=G.value,M.repr=G.repr,M.type=G.type,M}},m=function(){let G=t();if(G.toLowerCase()==="url"&&q()===40){L();while(T(q(1))&&T(q(2)))L();if(q()===34||q()===39)return new p(G);else if(T(q())&&(q(2)===34||q(2)===39))return new p(G);else return a()}else if(q()===40)return L(),new p(G);else return new Q_(G)},K_=function(G){if(G===void 0)G=X;let M="";while(L())if(X===G||H())return new H_(M);else if(u(X))return j(),I(),new o_;else if(X===92)if(H(q()))F();else if(u(q()))L();else M+=D(C());else M+=D(X);throw Error("Internal error")},a=function(){let G=new FJ("");while(T(q()))L();if(H(q()))return G;while(L())if(X===41||H())return G;else if(T(X)){while(T(q()))L();if(q()===41||H(q()))return L(),G;else return L_(),new X_}else if(X===34||X===39||X===40||fX(X))return j(),L_(),new X_;else if(X===92)if(n())G.value+=D(C());else return j(),L_(),new X_;else G.value+=D(X);throw Error("Internal error")},C=function(){if(L(),r_(X)){let G=[X];for(let P=0;P<5;P++)if(r_(q()))L(),G.push(X);else break;if(T(q()))L();let M=parseInt(G.map(function(P){return String.fromCharCode(P)}).join(""),16);if(M>CX)M=65533;return M}else if(H())return 65533;else return X},k=function(G,M){if(G!==92)return!1;if(u(M))return!1;return!0},n=function(){return k(X,q())},o=function(G,M,P){if(G===45)return J_(M)||M===45||k(M,P);else if(J_(G))return!0;else if(G===92)return k(G,M);else return!1},QX=function(){return o(X,q(1),q(2))},HX=function(G,M,P){if(G===43||G===45){if(A(M))return!0;if(M===46&&A(P))return!0;return!1}else if(G===46){if(A(M))return!0;return!1}else if(A(G))return!0;else return!1},W_=function(){return HX(X,q(1),q(2))},t=function(){let G="";while(L())if(a_(X))G+=D(X);else if(n())G+=D(C());else return I(),G;throw Error("Internal parse error")},qX=function(){let G="",M="integer";if(q()===43||q()===45)L(),G+=D(X);while(A(q()))L(),G+=D(X);if(q(1)===46&&A(q(2))){L(),G+=D(X),L(),G+=D(X),M="number";while(A(q()))L(),G+=D(X)}let P=q(1),z_=q(2),UX=q(3);if((P===69||P===101)&&A(z_)){L(),G+=D(X),L(),G+=D(X),M="number";while(A(q()))L(),G+=D(X)}else if((P===69||P===101)&&(z_===43||z_===45)&&A(UX)){L(),G+=D(X),L(),G+=D(X),L(),G+=D(X),M="number";while(A(q()))L(),G+=D(X)}let KX=GX(G);return{type:M,value:KX,repr:G}},GX=function(G){return+G},L_=function(){while(L())if(X===41||H())return;else if(n())C(),F();else F()},N_=0;while(!H(q()))if($.push(w()),N_++,N_>J.length*2)throw Error("I'm infinite-looping!");return $}class B{tokenType="";value;toJSON(){return{token:this.tokenType}}toString(){return this.tokenType}toSource(){return""+this}}class o_ extends B{tokenType="BADSTRING"}class X_ extends B{tokenType="BADURL"}class $_ extends B{tokenType="WHITESPACE";toString(){return"WS"}toSource(){return" "}}class t_ extends B{tokenType="CDO";toSource(){return"<!--"}}class e_ extends B{tokenType="CDC";toSource(){return"-->"}}class _J extends B{tokenType=":"}class JJ extends B{tokenType=";"}class XJ extends B{tokenType=","}class g extends B{value="";mirror=""}class ZJ extends g{tokenType="{";constructor(){super();this.value="{",this.mirror="}"}}class $J extends g{tokenType="}";constructor(){super();this.value="}",this.mirror="{"}}class YJ extends g{tokenType="[";constructor(){super();this.value="[",this.mirror="]"}}class QJ extends g{tokenType="]";constructor(){super();this.value="]",this.mirror="["}}class HJ extends g{tokenType="(";constructor(){super();this.value="(",this.mirror=")"}}class Y_ extends g{tokenType=")";constructor(){super();this.value=")",this.mirror="("}}class qJ extends B{tokenType="~="}class GJ extends B{tokenType="|="}class UJ extends B{tokenType="^="}class KJ extends B{tokenType="$="}class WJ extends B{tokenType="*="}class LJ extends B{tokenType="||"}class zJ extends B{tokenType="EOF";toSource(){return""}}class O extends B{tokenType="DELIM";value="";constructor(_){super();this.value=D(_)}toString(){return"DELIM("+this.value+")"}toJSON(){let _=this.constructor.prototype.constructor.prototype.toJSON.call(this);return _.value=this.value,_}toSource(){if(this.value==="\\")return"\\\n";else return this.value}}class N extends B{value="";ASCIIMatch(_){return this.value.toLowerCase()===_.toLowerCase()}toJSON(){let _=this.constructor.prototype.constructor.prototype.toJSON.call(this);return _.value=this.value,_}}class Q_ extends N{constructor(_){super();this.value=_}tokenType="IDENT";toString(){return"IDENT("+this.value+")"}toSource(){return l(this.value)}}class p extends N{tokenType="FUNCTION";mirror;constructor(_){super();this.value=_,this.mirror=")"}toString(){return"FUNCTION("+this.value+")"}toSource(){return l(this.value)+"("}}class MJ extends N{tokenType="AT-KEYWORD";constructor(_){super();this.value=_}toString(){return"AT("+this.value+")"}toSource(){return"@"+l(this.value)}}class jJ extends N{tokenType="HASH";type;constructor(_){super();this.value=_,this.type="unrestricted"}toString(){return"HASH("+this.value+")"}toJSON(){let _=this.constructor.prototype.constructor.prototype.toJSON.call(this);return _.value=this.value,_.type=this.type,_}toSource(){if(this.type==="id")return"#"+l(this.value);else return"#"+yX(this.value)}}class H_ extends N{tokenType="STRING";constructor(_){super();this.value=_}toString(){return'"'+RJ(this.value)+'"'}}class FJ extends N{tokenType="URL";constructor(_){super();this.value=_}toString(){return"URL("+this.value+")"}toSource(){return'url("'+RJ(this.value)+'")'}}class BJ extends B{tokenType="NUMBER";type;repr;constructor(){super();this.type="integer",this.repr=""}toString(){if(this.type==="integer")return"INT("+this.value+")";return"NUMBER("+this.value+")"}toJSON(){let _=super.toJSON();return _.value=this.value,_.type=this.type,_.repr=this.repr,_}toSource(){return this.repr}}class IJ extends B{tokenType="PERCENTAGE";repr;constructor(){super();this.repr=""}toString(){return"PERCENTAGE("+this.value+")"}toJSON(){let _=this.constructor.prototype.constructor.prototype.toJSON.call(this);return _.value=this.value,_.repr=this.repr,_}toSource(){return this.repr+"%"}}class VJ extends B{tokenType="DIMENSION";type;repr;unit;constructor(){super();this.type="integer",this.repr="",this.unit=""}toString(){return"DIM("+this.value+","+this.unit+")"}toJSON(){let _=this.constructor.prototype.constructor.prototype.toJSON.call(this);return _.value=this.value,_.type=this.type,_.repr=this.repr,_.unit=this.unit,_}toSource(){let _=this.repr,J=l(this.unit);if(J[0].toLowerCase()==="e"&&(J[1]==="-"||R(J.charCodeAt(1),48,57)))J="\\65 "+J.slice(1,J.length);return _+J}}function l(_){_=""+_;let J="",Z=_.charCodeAt(0);for(let $=0;$<_.length;$++){let X=_.charCodeAt($);if(X===0)throw new Z_("Invalid character: the input contains U+0000.");if(R(X,1,31)||X===127||$===0&&R(X,48,57)||$===1&&R(X,48,57)&&Z===45)J+="\\"+X.toString(16)+" ";else if(X>=128||X===45||X===95||R(X,48,57)||R(X,65,90)||R(X,97,122))J+=_[$];else J+="\\"+_[$]}return J}function yX(_){_=""+_;let J="";for(let Z=0;Z<_.length;Z++){let $=_.charCodeAt(Z);if($===0)throw new Z_("Invalid character: the input contains U+0000.");if($>=128||$===45||$===95||R($,48,57)||R($,65,90)||R($,97,122))J+=_[Z];else J+="\\"+$.toString(16)+" "}return J}function RJ(_){_=""+_;let J="";for(let Z=0;Z<_.length;Z++){let $=_.charCodeAt(Z);if($===0)throw new Z_("Invalid character: the input contains U+0000.");if(R($,1,31)||$===127)J+="\\"+$.toString(16)+" ";else if($===34||$===92)J+="\\"+_[Z];else J+=_[Z]}return J}function DJ(_){return _.hasAttribute("aria-label")||_.hasAttribute("aria-labelledby")}var OJ="article:not([role]), aside:not([role]), main:not([role]), nav:not([role]), section:not([role]), [role=article], [role=complementary], [role=main], [role=navigation], [role=region]",TX=[["aria-atomic",void 0],["aria-busy",void 0],["aria-controls",void 0],["aria-current",void 0],["aria-describedby",void 0],["aria-details",void 0],["aria-dropeffect",void 0],["aria-flowto",void 0],["aria-grabbed",void 0],["aria-hidden",void 0],["aria-keyshortcuts",void 0],["aria-label",["caption","code","deletion","emphasis","generic","insertion","paragraph","presentation","strong","subscript","superscript"]],["aria-labelledby",["caption","code","deletion","emphasis","generic","insertion","paragraph","presentation","strong","subscript","superscript"]],["aria-live",void 0],["aria-owns",void 0],["aria-relevant",void 0],["aria-roledescription",["generic"]]];function fJ(_,J){return TX.some(([Z,$])=>{return!$?.includes(J||"")&&_.hasAttribute(Z)})}function CJ(_){return!Number.isNaN(Number(String(_.getAttribute("tabindex"))))}function xX(_){return!mJ(_)&&(vX(_)||CJ(_))}function vX(_){let J=V(_);if(["BUTTON","DETAILS","SELECT","TEXTAREA"].includes(J))return!0;if(J==="A"||J==="AREA")return _.hasAttribute("href");if(J==="INPUT")return!_.hidden;return!1}var gX={A:(_)=>{return _.hasAttribute("href")?"link":null},AREA:(_)=>{return _.hasAttribute("href")?"link":null},ARTICLE:()=>"article",ASIDE:()=>"complementary",BLOCKQUOTE:()=>"blockquote",BUTTON:()=>"button",CAPTION:()=>"caption",CODE:()=>"code",DATALIST:()=>"listbox",DD:()=>"definition",DEL:()=>"deletion",DETAILS:()=>"group",DFN:()=>"term",DIALOG:()=>"dialog",DT:()=>"term",EM:()=>"emphasis",FIELDSET:()=>"group",FIGURE:()=>"figure",FOOTER:(_)=>s(_,OJ)?null:"contentinfo",FORM:(_)=>DJ(_)?"form":null,H1:()=>"heading",H2:()=>"heading",H3:()=>"heading",H4:()=>"heading",H5:()=>"heading",H6:()=>"heading",HEADER:(_)=>s(_,OJ)?null:"banner",HR:()=>"separator",HTML:()=>"document",IMG:(_)=>_.getAttribute("alt")===""&&!_.getAttribute("title")&&!fJ(_)&&!CJ(_)?"presentation":"img",INPUT:(_)=>{let J=_.type.toLowerCase();if(J==="search")return _.hasAttribute("list")?"combobox":"searchbox";if(["email","tel","text","url",""].includes(J)){let Z=G_(_,_.getAttribute("list"))[0];return Z&&V(Z)==="DATALIST"?"combobox":"textbox"}if(J==="hidden")return null;if(J==="file")return"button";return lX[J]||"textbox"},INS:()=>"insertion",LI:()=>"listitem",MAIN:()=>"main",MARK:()=>"mark",MATH:()=>"math",MENU:()=>"list",METER:()=>"meter",NAV:()=>"navigation",OL:()=>"list",OPTGROUP:()=>"group",OPTION:()=>"option",OUTPUT:()=>"status",P:()=>"paragraph",PROGRESS:()=>"progressbar",SEARCH:()=>"search",SECTION:(_)=>DJ(_)?"region":null,SELECT:(_)=>_.hasAttribute("multiple")||_.size>1?"listbox":"combobox",STRONG:()=>"strong",SUB:()=>"subscript",SUP:()=>"superscript",SVG:()=>"img",TABLE:()=>"table",TBODY:()=>"rowgroup",TD:(_)=>{let J=s(_,"table"),Z=J?O_(J):"";return Z==="grid"||Z==="treegrid"?"gridcell":"cell"},TEXTAREA:()=>"textbox",TFOOT:()=>"rowgroup",TH:(_)=>{let J=_.getAttribute("scope");if(J==="col"||J==="colgroup")return"columnheader";if(J==="row"||J==="rowgroup")return"rowheader";let{nextElementSibling:Z,previousElementSibling:$}=_,X=!!_.parentElement&&V(_.parentElement)==="TR"?_.parentElement:void 0;if(!Z&&!$){if(X){let Q=s(X,"table");if(Q&&Q.rows.length<=1)return null}return"columnheader"}if(wJ(Z)&&wJ($))return"columnheader";if(AJ(Z)||AJ($))return"rowheader";return"columnheader"},THEAD:()=>"rowgroup",TIME:()=>"time",TR:()=>"row",UL:()=>"list"};function wJ(_){return!!_&&V(_)==="TH"}function AJ(_){if(!_||V(_)!=="TD")return!1;return!!(_.textContent?.trim()||_.children.length>0)}var NX={DD:["DL","DIV"],DIV:["DL"],DT:["DL","DIV"],LI:["OL","UL"],TBODY:["TABLE"],TD:["TR"],TFOOT:["TABLE"],TH:["TR"],THEAD:["TABLE"],TR:["THEAD","TBODY","TFOOT","TABLE"]};function EJ(_){let J=gX[V(_)]?.(_)||"";if(!J)return null;let Z=_;while(Z){let $=h(Z),X=NX[V(Z)];if(!X||!$||!X.includes(V($)))break;let Q=O_($);if((Q==="none"||Q==="presentation")&&!bJ($,Q))return Q;Z=$}return J}var kX=["alert","alertdialog","application","article","banner","blockquote","button","caption","cell","checkbox","code","columnheader","combobox","complementary","contentinfo","definition","deletion","dialog","directory","document","emphasis","feed","figure","form","generic","grid","gridcell","group","heading","img","insertion","link","list","listbox","listitem","log","main","mark","marquee","math","meter","menu","menubar","menuitem","menuitemcheckbox","menuitemradio","navigation","none","note","option","paragraph","presentation","progressbar","radio","radiogroup","region","row","rowgroup","rowheader","scrollbar","search","searchbox","separator","slider","spinbutton","status","strong","subscript","superscript","switch","tab","table","tablist","tabpanel","term","textbox","time","timer","toolbar","tooltip","tree","treegrid","treeitem"];function O_(_){return(_.getAttribute("role")||"").split(" ").map((Z)=>Z.trim()).find((Z)=>kX.includes(Z))||null}function bJ(_,J){return fJ(_,J)||xX(_)}function f(_){let J=O_(_);if(!J)return EJ(_);if(J==="none"||J==="presentation"){let Z=EJ(_);if(bJ(_,Z))return Z}return J}function yJ(_){return _===null?void 0:_.toLowerCase()==="true"}function SJ(_){return["STYLE","SCRIPT","NOSCRIPT","TEMPLATE"].includes(V(_))}function y(_){if(SJ(_))return!0;let J=b(_),Z=_.nodeName==="SLOT";if(J?.display==="contents"&&!Z){for(let X=_.firstChild;X;X=X.nextSibling){if(X.nodeType===1&&!y(X))return!1;if(X.nodeType===3&&I_(X))return!1}return!0}if(!(_.nodeName==="OPTION"&&!!_.closest("select"))&&!Z&&!B_(_,J))return!0;return TJ(_)}function TJ(_){let J=q_?.get(_);if(J===void 0){if(J=!1,_.parentElement&&_.parentElement.shadowRoot&&!_.assignedSlot)J=!0;if(!J){let Z=b(_);J=!Z||Z.display==="none"||yJ(_.getAttribute("aria-hidden"))===!0}if(!J){let Z=h(_);if(Z)J=TJ(Z)}q_?.set(_,J)}return J}function G_(_,J){if(!J)return[];let Z=d_(_);if(!Z)return[];try{let $=J.split(" ").filter((Q)=>!!Q),X=[];for(let Q of $){let U=Z.querySelector("#"+CSS.escape(Q));if(U&&!X.includes(U))X.push(U)}return X}catch($){return[]}}function x(_){return _.trim()}function hX(_){return _.split(" ").map((J)=>J.replace(/\r\n/g,`
6
+ `).replace(/[\u200b\u00ad]/g,"").replace(/\s\s*/g," ")).join(" ").trim()}function PJ(_,J){let Z=[..._.querySelectorAll(J)];for(let $ of G_(_,_.getAttribute("aria-owns"))){if($.matches(J))Z.push($);Z.push(...$.querySelectorAll(J))}return Z}function c(_,J){let Z=J==="::before"?T_:J==="::after"?x_:S_;if(Z?.has(_))return Z?.get(_);let $=b(_,J),X;if($){let Q=$.content;if(Q&&Q!=="none"&&Q!=="normal"){if($.display!=="none"&&$.visibility!=="hidden")X=uX(_,Q,!!J)}}if(J&&X!==void 0){if(($?.display||"inline")!=="inline")X=" "+X+" "}if(Z)Z.set(_,X);return X}function uX(_,J,Z){if(!J||J==="none"||J==="normal")return;try{let $=n_(J).filter((W)=>!(W instanceof $_)),X=$.findIndex((W)=>W instanceof O&&W.value==="/");if(X!==-1)$=$.slice(X+1);else if(!Z)return;let Q=[],U=0;while(U<$.length)if($[U]instanceof H_)Q.push($[U].value),U++;else if(U+2<$.length&&$[U]instanceof p&&$[U].value==="attr"&&$[U+1]instanceof Q_&&$[U+2]instanceof Y_){let W=$[U+1].value;Q.push(_.getAttribute(W)||""),U+=3}else return;return Q.join("")}catch{}}function pX(_){let J=_.getAttribute("aria-labelledby");if(J===null)return null;let Z=G_(_,J);return Z.length?Z:null}function cX(_,J){let Z=["button","cell","checkbox","columnheader","gridcell","heading","link","menuitem","menuitemcheckbox","menuitemradio","option","radio","row","rowheader","switch","tab","tooltip","treeitem"].includes(_),$=J&&["","caption","code","contentinfo","definition","deletion","emphasis","insertion","list","listitem","mark","none","paragraph","presentation","region","row","rowgroup","section","strong","subscript","superscript","table","term","time"].includes(_);return Z||$}function xJ(_,J){let Z=J?y_:b_,$=Z?.get(_);if($===void 0){if($="",!["caption","code","definition","deletion","emphasis","generic","insertion","mark","paragraph","presentation","strong","subscript","suggestion","superscript","term","time"].includes(f(_)||""))$=hX(v(_,{includeHidden:J,visitedElements:new Set,embeddedInTargetElement:"self"}));Z?.set(_,$)}return $}var vJ=["application","checkbox","columnheader","combobox","gridcell","listbox","radiogroup","rowheader","searchbox","slider","spinbutton","switch","textbox","tree"];function gJ(_){let J=_.getAttribute("aria-invalid");if(!J||J.trim()===""||J.toLocaleLowerCase()==="false")return"false";if(J==="true"||J==="grammar"||J==="spelling")return J;return"true"}function v(_,J){if(J.visitedElements.has(_))return"";let Z={...J,embeddedInTargetElement:J.embeddedInTargetElement==="self"?"descendant":J.embeddedInTargetElement};if(!J.includeHidden){let Y=!!J.embeddedInLabelledBy?.hidden||!!J.embeddedInDescribedBy?.hidden||!!J.embeddedInNativeTextAlternative?.hidden||!!J.embeddedInLabel?.hidden;if(SJ(_)||!Y&&y(_))return J.visitedElements.add(_),""}let $=pX(_);if(!J.embeddedInLabelledBy){let Y=($||[]).map((K)=>v(K,{...J,embeddedInLabelledBy:{element:K,hidden:y(K)},embeddedInDescribedBy:void 0,embeddedInTargetElement:void 0,embeddedInLabel:void 0,embeddedInNativeTextAlternative:void 0})).join(" ");if(Y)return Y}let X=f(_)||"",Q=V(_);if(!!J.embeddedInLabel||!!J.embeddedInLabelledBy||J.embeddedInTargetElement==="descendant"){let Y=[..._.labels||[]].includes(_),K=($||[]).includes(_);if(!Y&&!K){if(X==="textbox"){if(J.visitedElements.add(_),Q==="INPUT"||Q==="TEXTAREA")return _.value;return _.textContent||""}if(["combobox","listbox"].includes(X)){J.visitedElements.add(_);let z;if(Q==="SELECT"){if(z=[..._.selectedOptions],!z.length&&_.options.length)z.push(_.options[0])}else{let q=X==="combobox"?PJ(_,"*").find((L)=>f(L)==="listbox"):_;z=q?PJ(q,'[aria-selected="true"]').filter((L)=>f(L)==="option"):[]}if(!z.length&&Q==="INPUT")return _.value;return z.map((q)=>v(q,Z)).join(" ")}if(["progressbar","scrollbar","slider","spinbutton","meter"].includes(X)){if(J.visitedElements.add(_),_.hasAttribute("aria-valuetext"))return _.getAttribute("aria-valuetext")||"";if(_.hasAttribute("aria-valuenow"))return _.getAttribute("aria-valuenow")||"";return _.getAttribute("value")||""}if(["menu"].includes(X))return J.visitedElements.add(_),""}}let U=_.getAttribute("aria-label")||"";if(x(U))return J.visitedElements.add(_),U;if(!["presentation","none"].includes(X)){if(Q==="INPUT"&&["button","submit","reset"].includes(_.type)){J.visitedElements.add(_);let Y=_.value||"";if(x(Y))return Y;if(_.type==="submit")return"Submit";if(_.type==="reset")return"Reset";return _.getAttribute("title")||""}if(Q==="INPUT"&&_.type==="file"){J.visitedElements.add(_);let Y=_.labels||[];if(Y.length&&!J.embeddedInLabelledBy)return r(Y,J);return"Choose File"}if(Q==="INPUT"&&_.type==="image"){J.visitedElements.add(_);let Y=_.labels||[];if(Y.length&&!J.embeddedInLabelledBy)return r(Y,J);let K=_.getAttribute("alt")||"";if(x(K))return K;let z=_.getAttribute("title")||"";if(x(z))return z;return"Submit"}if(!$&&Q==="BUTTON"){J.visitedElements.add(_);let Y=_.labels||[];if(Y.length)return r(Y,J)}if(!$&&Q==="OUTPUT"){J.visitedElements.add(_);let Y=_.labels||[];if(Y.length)return r(Y,J);return _.getAttribute("title")||""}if(!$&&(Q==="TEXTAREA"||Q==="SELECT"||Q==="INPUT")){J.visitedElements.add(_);let Y=_.labels||[];if(Y.length)return r(Y,J);let K=Q==="INPUT"&&["text","password","search","tel","email","url"].includes(_.type)||Q==="TEXTAREA",z=_.getAttribute("placeholder")||"",q=_.getAttribute("title")||"";if(!K||q)return q;return z}if(!$&&Q==="FIELDSET"){J.visitedElements.add(_);for(let K=_.firstElementChild;K;K=K.nextElementSibling)if(V(K)==="LEGEND")return v(K,{...Z,embeddedInNativeTextAlternative:{element:K,hidden:y(K)}});return _.getAttribute("title")||""}if(!$&&Q==="FIGURE"){J.visitedElements.add(_);for(let K=_.firstElementChild;K;K=K.nextElementSibling)if(V(K)==="FIGCAPTION")return v(K,{...Z,embeddedInNativeTextAlternative:{element:K,hidden:y(K)}});return _.getAttribute("title")||""}if(Q==="IMG"){J.visitedElements.add(_);let Y=_.getAttribute("alt")||"";if(x(Y))return Y;return _.getAttribute("title")||""}if(Q==="TABLE"){J.visitedElements.add(_);for(let K=_.firstElementChild;K;K=K.nextElementSibling)if(V(K)==="CAPTION")return v(K,{...Z,embeddedInNativeTextAlternative:{element:K,hidden:y(K)}});let Y=_.getAttribute("summary")||"";if(Y)return Y}if(Q==="AREA"){J.visitedElements.add(_);let Y=_.getAttribute("alt")||"";if(x(Y))return Y;return _.getAttribute("title")||""}if(Q==="SVG"||_.ownerSVGElement){J.visitedElements.add(_);for(let Y=_.firstElementChild;Y;Y=Y.nextElementSibling)if(V(Y)==="TITLE"&&Y.ownerSVGElement)return v(Y,{...Z,embeddedInLabelledBy:{element:Y,hidden:y(Y)}})}if(_.ownerSVGElement&&Q==="A"){let Y=_.getAttribute("xlink:title")||"";if(x(Y))return J.visitedElements.add(_),Y}}let W=Q==="SUMMARY"&&!["presentation","none"].includes(X);if(cX(X,J.embeddedInTargetElement==="descendant")||W||!!J.embeddedInLabelledBy||!!J.embeddedInDescribedBy||!!J.embeddedInLabel||!!J.embeddedInNativeTextAlternative){J.visitedElements.add(_);let Y=mX(_,Z);if(J.embeddedInTargetElement==="self"?x(Y):Y)return Y}if(!["presentation","none"].includes(X)||Q==="IFRAME"){J.visitedElements.add(_);let Y=_.getAttribute("title")||"";if(x(Y))return Y}return J.visitedElements.add(_),""}function mX(_,J){let Z=[],$=(Q,U)=>{if(U&&Q.assignedSlot)return;if(Q.nodeType===1){let W=b(Q)?.display||"inline",Y=v(Q,J);if(W!=="inline"||Q.nodeName==="BR")Y=" "+Y+" ";Z.push(Y)}else if(Q.nodeType===3)Z.push(Q.textContent||"")};Z.push(c(_,"::before")||"");let X=c(_);if(X!==void 0)Z.push(X);else{let Q=_.nodeName==="SLOT"?_.assignedNodes():[];if(Q.length)for(let U of Q)$(U,!1);else{for(let U=_.firstChild;U;U=U.nextSibling)$(U,!0);if(_.shadowRoot)for(let U=_.shadowRoot.firstChild;U;U=U.nextSibling)$(U,!0);for(let U of G_(_,_.getAttribute("aria-owns")))$(U,!0)}}return Z.push(c(_,"::after")||""),Z.join("")}var w_=["gridcell","option","row","tab","rowheader","columnheader","treeitem"];function NJ(_){if(V(_)==="OPTION")return _.selected;if(w_.includes(f(_)||""))return yJ(_.getAttribute("aria-selected"))===!0;return!1}var A_=["checkbox","menuitemcheckbox","option","radio","switch","menuitemradio","treeitem"];function kJ(_){let J=dX(_,!0);return J==="error"?!1:J}function dX(_,J){let Z=V(_);if(J&&Z==="INPUT"&&_.indeterminate)return"mixed";if(Z==="INPUT"&&["checkbox","radio"].includes(_.type))return _.checked;if(A_.includes(f(_)||"")){let $=_.getAttribute("aria-checked");if($==="true")return!0;if(J&&$==="mixed")return"mixed";return!1}return"error"}var E_=["button"];function hJ(_){if(E_.includes(f(_)||"")){let J=_.getAttribute("aria-pressed");if(J==="true")return!0;if(J==="mixed")return"mixed"}return!1}var P_=["application","button","checkbox","combobox","gridcell","link","listbox","menuitem","row","rowheader","tab","treeitem","columnheader","menuitemcheckbox","menuitemradio","rowheader","switch"];function uJ(_){if(V(_)==="DETAILS")return _.open;if(P_.includes(f(_)||"")){let J=_.getAttribute("aria-expanded");if(J===null)return;if(J==="true")return!0;return!1}return}var f_=["heading","listitem","row","treeitem"];function pJ(_){let J={H1:1,H2:2,H3:3,H4:4,H5:5,H6:6}[V(_)];if(J)return J;if(f_.includes(f(_)||"")){let Z=_.getAttribute("aria-level"),$=Z===null?Number.NaN:Number(Z);if(Number.isInteger($)&&$>=1)return $}return 0}var C_=["application","button","composite","gridcell","group","input","link","menuitem","scrollbar","separator","tab","checkbox","columnheader","combobox","grid","listbox","menu","menubar","menuitemcheckbox","menuitemradio","option","radio","radiogroup","row","rowheader","searchbox","select","slider","spinbutton","switch","tablist","textbox","toolbar","tree","treegrid","treeitem"];function cJ(_){return mJ(_)||dJ(_)}function mJ(_){return["BUTTON","INPUT","SELECT","TEXTAREA","OPTION","OPTGROUP"].includes(V(_))&&(_.hasAttribute("disabled")||sX(_)||iX(_))}function sX(_){return V(_)==="OPTION"&&!!_.closest("OPTGROUP[DISABLED]")}function iX(_){let J=_?.closest("FIELDSET[DISABLED]");if(!J)return!1;let Z=J.querySelector(":scope > LEGEND");return!Z||!Z.contains(_)}function dJ(_,J=!1){if(!_)return!1;if(J||C_.includes(f(_)||"")){let Z=(_.getAttribute("aria-disabled")||"").toLowerCase();if(Z==="true")return!0;if(Z==="false")return!1;return dJ(h(_),!0)}return!1}function r(_,J){return[..._].map((Z)=>v(Z,{...J,embeddedInLabel:{element:Z,hidden:y(Z)},embeddedInNativeTextAlternative:void 0,embeddedInLabelledBy:void 0,embeddedInDescribedBy:void 0,embeddedInTargetElement:void 0})).filter((Z)=>!!Z).join(" ")}function sJ(_){let J=v_,Z=_,$,X=[];for(;Z;Z=h(Z)){let Q=J.get(Z);if(Q!==void 0){$=Q;break}X.push(Z);let U=b(Z);if(!U){$=!0;break}let W=U.pointerEvents;if(W){$=W!=="none";break}}if($===void 0)$=!0;for(let Q of X)J.set(Q,$);return $}var b_,y_,iJ,lJ,rJ,q_,S_,T_,x_,v_,aJ=0;function nJ(){i_(),++aJ,b_??=new Map,y_??=new Map,iJ??=new Map,lJ??=new Map,rJ??=new Map,q_??=new Map,S_??=new Map,T_??=new Map,x_??=new Map,v_??=new Map}function oJ(){if(!--aJ)b_=void 0,y_=void 0,iJ=void 0,lJ=void 0,rJ=void 0,q_=void 0,S_=void 0,T_=void 0,x_=void 0,v_=void 0;l_()}var lX={button:"button",checkbox:"checkbox",image:"button",number:"spinbutton",radio:"radio",range:"slider",reset:"button",submit:"button"};var aX=0;function eJ(_){let J=_.boxes;if(_.mode==="ai")return{visibility:"ariaOrVisible",refs:"interactable",refPrefix:_.refPrefix,includeGenericRole:!0,renderActive:!_.doNotRenderActive,renderCursorPointer:!0,renderBoxes:J};if(_.mode==="autoexpect")return{visibility:"ariaAndVisible",refs:"none",renderBoxes:J};if(_.mode==="codegen")return{visibility:"aria",refs:"none",renderStringsAsRegex:!0,renderBoxes:J};return{visibility:"aria",refs:"none",renderBoxes:J}}function _X(_,J){let Z=eJ(J),$=new Set,X={root:{role:"fragment",name:"",children:[],props:{},box:i(_),receivesPointerEvents:!0},elements:new Map,refs:new Map,iframeRefs:[]};g_(X.root,_);let Q=(W,Y,K)=>{if($.has(Y))return;if($.add(Y),Y.nodeType===Node.TEXT_NODE&&Y.nodeValue){if(!K)return;let F=Y.nodeValue;if(W.role!=="textbox"&&F)W.children.push(Y.nodeValue||"");return}if(Y.nodeType!==Node.ELEMENT_NODE)return;let z=Y,q=!y(z),L=q;if(Z.visibility==="ariaOrVisible")L=q||__(z);if(Z.visibility==="ariaAndVisible")L=q&&__(z);if(Z.visibility==="aria"&&!L)return;let I=[];if(z.hasAttribute("aria-owns")){let F=z.getAttribute("aria-owns").split(/\s+/);for(let j of F){let w=_.ownerDocument.getElementById(j);if(w)I.push(w)}}let H=L?nX(z,Z):null;if(H){if(H.ref){if(X.elements.set(H.ref,z),X.refs.set(z,H.ref),H.role==="iframe")X.iframeRefs.push(H.ref)}W.children.push(H)}U(H||W,z,I,L)};function U(W,Y,K,z){let L=(b(Y)?.display||"inline")!=="inline"||Y.nodeName==="BR"?" ":"";if(L)W.children.push(L);W.children.push(c(Y,"::before")||"");let I=Y.nodeName==="SLOT"?Y.assignedNodes():[];if(I.length)for(let H of I)Q(W,H,z);else{for(let H=Y.firstChild;H;H=H.nextSibling)if(!H.assignedSlot)Q(W,H,z);if(Y.shadowRoot)for(let H=Y.shadowRoot.firstChild;H;H=H.nextSibling)Q(W,H,z)}for(let H of K)Q(W,H,z);if(W.children.push(c(Y,"::after")||""),L)W.children.push(L);if(W.children.length===1&&W.name===W.children[0])W.children=[];if(W.role==="link"&&Y.hasAttribute("href")){let H=Y.getAttribute("href");W.props.url=H}if(W.role==="textbox"&&Y.hasAttribute("placeholder")&&Y.getAttribute("placeholder")!==W.name){let H=Y.getAttribute("placeholder");W.props.placeholder=H}}nJ();try{Q(X.root,_,!0)}finally{oJ()}return tX(X.root),oX(X.root),X}function tJ(_,J){if(J.refs==="none")return;if(J.refs==="interactable"&&(!_.box.visible||!_.receivesPointerEvents))return;let Z=$X(_),$=Z._ariaRef;if(!$||$.role!==_.role||$.name!==_.name)$={role:_.role,name:_.name,ref:(J.refPrefix??"")+"e"+ ++aX},Z._ariaRef=$;_.ref=$.ref}function nX(_,J){let Z=_.ownerDocument.activeElement===_;if(_.nodeName==="IFRAME"){let K={role:"iframe",name:"",children:[],props:{},box:i(_),receivesPointerEvents:!0,active:Z};return g_(K,_),tJ(K,J),K}let $=J.includeGenericRole?"generic":null,X=f(_)??$;if(!X||X==="presentation"||X==="none")return null;let Q=j_(xJ(_,!1)||""),U=sJ(_),W=i(_);if(X==="generic"&&W.inline&&_.childNodes.length===1&&_.childNodes[0].nodeType===Node.TEXT_NODE)return null;let Y={role:X,name:Q,children:[],props:{},box:W,receivesPointerEvents:U,active:Z};if(g_(Y,_),tJ(Y,J),A_.includes(X))Y.checked=kJ(_);if(C_.includes(X))Y.disabled=cJ(_);if(P_.includes(X))Y.expanded=uJ(_);if(vJ.includes(X)){let K=gJ(_);Y.invalid=K==="false"?!1:K==="true"?!0:K}if(f_.includes(X))Y.level=pJ(_);if(E_.includes(X))Y.pressed=hJ(_);if(w_.includes(X))Y.selected=NJ(_);if(_ instanceof HTMLInputElement||_ instanceof HTMLTextAreaElement){if(_.type!=="checkbox"&&_.type!=="radio"&&_.type!=="file")Y.children=[_.value]}return Y}function oX(_){let J=(Z)=>{let $=[];for(let Q of Z.children||[]){if(typeof Q==="string"){$.push(Q);continue}let U=J(Q);$.push(...U)}if(Z.role==="generic"&&!Z.name&&$.length<=1&&$.every((Q)=>typeof Q!=="string"&&!!Q.ref))return $;return Z.children=$,[Z]};J(_)}function tX(_){let J=($,X)=>{if(!$.length)return;let Q=j_($.join(""));if(Q)X.push(Q);$.length=0},Z=($)=>{let X=[],Q=[];for(let U of $.children||[])if(typeof U==="string")Q.push(U);else J(Q,X),Z(U),X.push(U);if(J(Q,X),$.children=X.length?X:[],$.children.length===1&&$.children[0]===$.name)$.children=[]};Z(_)}var jZ=Symbol("cachedRegex");function JX(_,J=new Map){if(_?.ref)J.set(_.ref,_);for(let Z of _?.children||[])if(typeof Z!=="string")JX(Z,J);return J}function eX(_,J){let Z=JX(J?.root),$=new Map,X=(Q,U)=>{let W=Q.children.length===U?.children.length&&h_(Q,U),Y=W;for(let K=0;K<Q.children.length;K++){let z=Q.children[K],q=U?.children[K];if(typeof z==="string")W&&=z===q,Y&&=z===q;else{let L=typeof q!=="string"?q:void 0;if(z.ref)L=Z.get(z.ref);let I=X(z,L);if(!L||!I&&!z.ref||L!==q)Y=!1;W&&=I&&L===q}}return $.set(Q,W?"same":Y?"skip":"changed"),W};return X(_.root,Z.get(J?.root?.ref)),$}function _Z(_,J){let Z=[],$=(X)=>{let Q=J.get(X);if(Q==="same");else if(Q==="skip"){for(let U of X.children)if(typeof U!=="string")$(U)}else Z.push(X)};for(let X of _)if(typeof X==="string")Z.push(X);else $(X);return Z}function U_(_){return" ".repeat(_)}function XX(_,J,Z){let $=eJ(J),X=[],Q={},U=$.renderStringsAsRegex?XZ:()=>!0,W=$.renderStringsAsRegex?JZ:(H)=>H,Y=_.root.role==="fragment"?_.root.children:[_.root],K=eX(_,Z);if(Z)Y=_Z(Y,K);let z=(H,F)=>{if(J.depth&&F>J.depth)return;let j=e(W(H));if(j)X.push(U_(F)+"- text: "+j)},q=(H,F)=>{let j=H.role;if(H.name&&H.name.length<=900){let w=W(H.name);if(w){let E=w.startsWith("/")&&w.endsWith("/")?w:JSON.stringify(w);j+=" "+E}}if(H.checked==="mixed")j+=" [checked=mixed]";if(H.checked===!0)j+=" [checked]";if(H.disabled)j+=" [disabled]";if(H.expanded)j+=" [expanded]";if(H.active&&$.renderActive)j+=" [active]";if(H.invalid==="grammar"||H.invalid==="spelling")j+=` [invalid=${H.invalid}]`;if(H.invalid===!0)j+=" [invalid]";if(H.level)j+=` [level=${H.level}]`;if(H.pressed==="mixed")j+=" [pressed=mixed]";if(H.pressed===!0)j+=" [pressed]";if(H.selected===!0)j+=" [selected]";if(H.ref){if(j+=` [ref=${H.ref}]`,F&&d(H))j+=" [cursor=pointer]"}if($.renderBoxes){let w=$X(H);if(w){let E=w.getBoundingClientRect();j+=` [box=${Math.round(E.x)},${Math.round(E.y)},${Math.round(E.width)},${Math.round(E.height)}]`}}return j},L=(H)=>{return H?.children.length===1&&typeof H.children[0]==="string"&&!Object.keys(H.props).length?H.children[0]:void 0},I=(H,F,j)=>{if(J.depth&&F>J.depth)return;if(H.role==="iframe"&&H.ref)Q[H.ref]=F;if(K.get(H)==="same"&&H.ref){X.push(U_(F)+`- ref=${H.ref} [unchanged]`);return}let w=!!Z&&!F,E=U_(F)+"- "+(w?"<changed> ":"")+c_(q(H,j)),S=L(H),m=!!J.depth&&F===J.depth;if(!S&&(!H.children.length||m)&&!Object.keys(H.props).length)X.push(E);else if(S!==void 0)if(U(H,S))X.push(E+": "+e(W(S)));else X.push(E);else{X.push(E+":");for(let[C,k]of Object.entries(H.props))X.push(U_(F+1)+"- /"+C+": "+e(k));let a=!!H.ref&&j&&d(H);for(let C of H.children)if(typeof C==="string")z(U(H,C)?C:"",F+1);else I(C,F+1,j&&!a)}};for(let H of Y)if(typeof H==="string")z(H,0);else I(H,0,!!$.renderCursorPointer);return{text:X.join(`
7
+ `),iframeDepths:Q}}function JZ(_){let J=[{regex:/\b[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\b/,replacement:"[0-9a-fA-F-]+"},{regex:/\b[\d,.]+[bkmBKM]+\b/,replacement:"[\\d,.]+[bkmBKM]+"},{regex:/\b\d+[hmsp]+\b/,replacement:"\\d+[hmsp]+"},{regex:/\b[\d,.]+[hmsp]+\b/,replacement:"[\\d,.]+[hmsp]+"},{regex:/\b\d+,\d+\b/,replacement:"\\d+,\\d+"},{regex:/\b\d+\.\d{2,}\b/,replacement:"\\d+\\.\\d+"},{regex:/\b\d{2,}\.\d+\b/,replacement:"\\d+\\.\\d+"},{regex:/\b\d{2,}\b/,replacement:"\\d+"}],Z="",$=0,X=new RegExp(J.map((Q)=>"("+Q.regex.source+")").join("|"),"g");if(_.replace(X,(Q,...U)=>{let W=U[U.length-2],Y=U.slice(0,-2);Z+=F_(_.slice($,W));for(let K=0;K<Y.length;K++)if(Y[K]){let{replacement:z}=J[K];Z+=z;break}return $=W+Q.length,Q}),!Z)return _;return Z+=F_(_.slice($)),String(new RegExp(Z))}function XZ(_,J){if(!J.length)return!1;if(!_.name)return!0;let Z=J.length<=200&&_.name.length<=200?p_(J,_.name):"",$=J;while(Z&&$.includes(Z))$=$.replace(Z,"");return $.trim().length/J.length>0.1}var ZX=Symbol("element");function $X(_){return _[ZX]}function g_(_,J){_[ZX]=J}function YX(_){let J=(Z)=>{for(let $ of Array.from(Z.querySelectorAll("*"))){_($);let X=$.shadowRoot;if(X)J(X)}};J(document)}function ZZ(_,J={}){YX((Q)=>{if(Q._ariaRef)delete Q._ariaRef});let Z=_??document.body??document.documentElement,$={mode:"ai",depth:J.depth,boxes:J.boxes},X=_X(Z,$);return XX(X,$).text}function $Z(_){let J=null;return YX((Z)=>{if(!J&&Z._ariaRef?.ref===_)J=Z}),J}
@@ -0,0 +1,103 @@
1
+ import type { ElementHandle, JSHandle, Page } from "puppeteer-core";
2
+ import ariaBundle from "./aria-snapshot.bundle.txt" with { type: "text" };
3
+ // `aria-snapshot.bundle.txt` is a generated, committed artifact: Playwright's
4
+ // injected ARIA-snapshot sources (pinned, Apache-2.0) bundled to a CJS module.
5
+ // The upstream sources are NOT vendored — regenerate the bundle with:
6
+ // bun scripts/generate-aria-snapshot.ts
7
+ // (fetches the pinned tag, bundles in a temp dir, rewrites the .txt artifact.)
8
+
9
+ export interface AriaSnapshotOptions {
10
+ /** Maximum tree depth to render. */
11
+ depth?: number;
12
+ /** Append `[box=x,y,w,h]` bounding boxes to each node. */
13
+ boxes?: boolean;
14
+ }
15
+
16
+ /**
17
+ * Page-side evaluators built ONCE here in the worker — never inside the page, so
18
+ * page CSP never applies. They run the generated Playwright ARIA-snapshot bundle
19
+ * (CJS, see scripts/generate-aria-snapshot.ts) in a throwaway module scope.
20
+ *
21
+ * Puppeteer serializes these functions to a CDP `Runtime.evaluate` in the page's
22
+ * MAIN world (the only world where the bundle's `_ariaRef` ref expandos live —
23
+ * isolated-world locators/query-handlers cannot see them). Nothing is installed
24
+ * on `window`; the only footprint is the `_ariaRef` markers the snapshot writes,
25
+ * which are the price of actionable `[ref=eN]` ids.
26
+ */
27
+ function buildEvaluator(params: string, call: string): (...args: unknown[]) => unknown {
28
+ return new Function(
29
+ ...params.split(",").map(p => p.trim()),
30
+ `var module = { exports: {} };\n${ariaBundle}\nreturn module.exports.${call};`,
31
+ ) as unknown as (...args: unknown[]) => unknown;
32
+ }
33
+
34
+ // Handles (root) must stay top-level args: Puppeteer only unwraps JSHandles
35
+ // passed positionally to page.evaluate, never ones nested inside an object.
36
+ const evaluateAriaSnapshot = buildEvaluator("root, request", "ariaSnapshot(root, request)");
37
+ const evaluateResolveRef = buildEvaluator("ref", "resolveAriaRef(ref)");
38
+
39
+ /**
40
+ * Capture a Playwright-format ARIA snapshot of `root` (or the whole document when
41
+ * null). Always runs in `ai` mode so every node carries a `[ref=eN]` id; resolve
42
+ * those to elements with {@link resolveAriaRefHandle}. Ids are renumbered from e1
43
+ * on each call and remain valid until the next snapshot.
44
+ */
45
+ export async function captureAriaSnapshot(
46
+ page: Page,
47
+ root: ElementHandle | null,
48
+ options: AriaSnapshotOptions = {},
49
+ ): Promise<string> {
50
+ const request = { depth: options.depth, boxes: options.boxes };
51
+ return (await page.evaluate(evaluateAriaSnapshot as never, root as never, request as never)) as string;
52
+ }
53
+
54
+ /**
55
+ * Resolve a `[ref=eN]` id from the latest snapshot to a live `ElementHandle`, or
56
+ * null when the ref no longer matches any element. Runs in the main world so it
57
+ * sees the `_ariaRef` expandos the snapshot wrote.
58
+ */
59
+ export async function resolveAriaRefHandle(page: Page, ref: string): Promise<ElementHandle | null> {
60
+ const handle = (await page.evaluateHandle(evaluateResolveRef as never, ref as never)) as JSHandle;
61
+ const element = handle.asElement();
62
+ if (!element) {
63
+ await handle.dispose().catch(() => undefined);
64
+ return null;
65
+ }
66
+ return element as ElementHandle;
67
+ }
68
+
69
+ const ARIA_REF_PREFIXES = ["aria-ref=", "aria-ref/", "ariaref/"];
70
+
71
+ /**
72
+ * Recognize the explicit `[ref=eN]` selector forms and return the bare ref id,
73
+ * else null. Accepts `aria-ref=e5` (Playwright-MCP style), `aria-ref/e5`, and
74
+ * `ariaref/e5` — lets `tab.click("aria-ref=e5")` etc. act on snapshot refs. A
75
+ * bare `e5` is intentionally NOT a ref selector: the cmux backend already uses
76
+ * bare `eN`/`@eN` for its own observe ids, so requiring the prefix keeps action
77
+ * selectors meaning the same thing on both backends. (`tab.ref("e5")` still
78
+ * accepts a bare id directly.)
79
+ */
80
+ export function parseAriaRefSelector(selector: string): string | null {
81
+ const trimmed = selector.trim();
82
+ for (const prefix of ARIA_REF_PREFIXES) {
83
+ if (trimmed.startsWith(prefix)) {
84
+ const id = trimmed.slice(prefix.length).trim();
85
+ return /^e\d+$/.test(id) ? id : null;
86
+ }
87
+ }
88
+ return null;
89
+ }
90
+
91
+ /**
92
+ * Build a self-contained expression script that runs the vendored bundle in the
93
+ * page and returns the ARIA snapshot YAML. Used by the cmux backend, whose
94
+ * `browser.eval` RPC takes a script string and returns the completion value (it
95
+ * has no ElementHandle to pass in). The script resolves `selector` via
96
+ * `document.querySelector` in-page (CSS selectors only) or falls back to the
97
+ * whole document. Like the puppeteer path it installs nothing on `window`.
98
+ */
99
+ export function buildAriaSnapshotScript(selector: string | undefined, options: AriaSnapshotOptions = {}): string {
100
+ const request = { depth: options.depth, boxes: options.boxes };
101
+ const sel = selector ? JSON.stringify(selector) : "null";
102
+ return `(function(){var module={exports:{}};\n${ariaBundle}\nvar __sel=${sel};var __root=__sel?document.querySelector(__sel):null;if(__sel&&!__root)throw new Error("tab.ariaSnapshot: selector "+__sel+" matched no element");return module.exports.ariaSnapshot(__root,${JSON.stringify(request)});})()`;
103
+ }