@nexface/tools 0.1.14 → 0.1.15-alpha.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.
Files changed (84) hide show
  1. package/dist/browser/actions.js +10 -34
  2. package/dist/browser/actions.js.map +1 -0
  3. package/dist/browser/controller.js +74 -53
  4. package/dist/browser/controller.js.map +1 -0
  5. package/dist/browser/diagnostics.js +3 -8
  6. package/dist/browser/diagnostics.js.map +1 -0
  7. package/dist/browser/dom.js +28 -12
  8. package/dist/browser/dom.js.map +1 -0
  9. package/dist/browser/feedback.js +5 -6
  10. package/dist/browser/feedback.js.map +1 -0
  11. package/dist/browser/focus.js +1 -0
  12. package/dist/browser/focus.js.map +1 -0
  13. package/dist/browser/locator.js +9 -3
  14. package/dist/browser/locator.js.map +1 -0
  15. package/dist/browser/prompt.generated.js +1 -0
  16. package/dist/browser/prompt.generated.js.map +1 -0
  17. package/dist/browser/prompt.js +1 -0
  18. package/dist/browser/prompt.js.map +1 -0
  19. package/dist/browser/snapshot.js +22 -10
  20. package/dist/browser/snapshot.js.map +1 -0
  21. package/dist/browser/toolset.js +36 -42
  22. package/dist/browser/toolset.js.map +1 -0
  23. package/dist/browser/types.d.ts +1 -1
  24. package/dist/browser/types.js +1 -0
  25. package/dist/browser/types.js.map +1 -0
  26. package/dist/browser/worker-runner.js +1 -0
  27. package/dist/browser/worker-runner.js.map +1 -0
  28. package/dist/definition.d.ts +3 -1
  29. package/dist/definition.js +2 -2
  30. package/dist/definition.js.map +1 -0
  31. package/dist/index.browser.js +1 -0
  32. package/dist/index.browser.js.map +1 -0
  33. package/dist/index.js +1 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/internal-react.d.ts +1 -1
  36. package/dist/internal-react.js +4 -3
  37. package/dist/internal-react.js.map +1 -0
  38. package/dist/internal-types.js +1 -0
  39. package/dist/internal-types.js.map +1 -0
  40. package/dist/navigation.js +1 -0
  41. package/dist/navigation.js.map +1 -0
  42. package/dist/operation-lock.js +2 -36
  43. package/dist/operation-lock.js.map +1 -0
  44. package/dist/operation-runtime.js +13 -41
  45. package/dist/operation-runtime.js.map +1 -0
  46. package/dist/operation-surface.js +41 -118
  47. package/dist/operation-surface.js.map +1 -0
  48. package/dist/operation-types.js +1 -0
  49. package/dist/operation-types.js.map +1 -0
  50. package/dist/operation-view.d.ts +1 -1
  51. package/dist/operation-view.js +60 -120
  52. package/dist/operation-view.js.map +1 -0
  53. package/dist/react.js +12 -9
  54. package/dist/react.js.map +1 -0
  55. package/dist/registration.d.ts +3 -0
  56. package/dist/registration.js +7 -5
  57. package/dist/registration.js.map +1 -0
  58. package/dist/runtime.d.ts +17 -6
  59. package/dist/runtime.js +59 -105
  60. package/dist/runtime.js.map +1 -0
  61. package/dist/shared/definition.js +1 -0
  62. package/dist/shared/definition.js.map +1 -0
  63. package/dist/shared/errors.d.ts +1 -1
  64. package/dist/shared/errors.js +1 -0
  65. package/dist/shared/errors.js.map +1 -0
  66. package/dist/shared/page-protocol.js +1 -0
  67. package/dist/shared/page-protocol.js.map +1 -0
  68. package/dist/shared/page-tools.js +1 -0
  69. package/dist/shared/page-tools.js.map +1 -0
  70. package/dist/shared/runtime-controller.d.ts +0 -1
  71. package/dist/shared/runtime-controller.js +1 -0
  72. package/dist/shared/runtime-controller.js.map +1 -0
  73. package/dist/shared/runtime-execution.js +1 -0
  74. package/dist/shared/runtime-execution.js.map +1 -0
  75. package/dist/shared/schema.js +19 -45
  76. package/dist/shared/schema.js.map +1 -0
  77. package/dist/styles.css +109 -879
  78. package/dist/types.js +1 -0
  79. package/dist/types.js.map +1 -0
  80. package/dist/webmcp.js +12 -38
  81. package/dist/webmcp.js.map +1 -0
  82. package/package.json +2 -6
  83. package/dist/tool-search.d.ts +0 -11
  84. package/dist/tool-search.js +0 -117
@@ -27,7 +27,11 @@ const DEFAULT_SNAPSHOT_LIMITS = {
27
27
  fullMaxVisitedNodes: 40_000,
28
28
  };
29
29
  function isIgnoredMutationNode(node) {
30
- const element = node instanceof Element ? node : node instanceof Text ? node.parentElement : null;
30
+ const element = node instanceof Element
31
+ ? node
32
+ : node instanceof Text
33
+ ? node.parentElement
34
+ : null;
31
35
  return Boolean(element?.closest("[data-nexface-ignore]"));
32
36
  }
33
37
  function isRelevantMutation(record) {
@@ -36,7 +40,8 @@ function isRelevantMutation(record) {
36
40
  if (record.type !== "childList")
37
41
  return true;
38
42
  const changedNodes = [...record.addedNodes, ...record.removedNodes];
39
- return changedNodes.length === 0 || changedNodes.some((node) => !isIgnoredMutationNode(node));
43
+ return (changedNodes.length === 0
44
+ || changedNodes.some((node) => !isIgnoredMutationNode(node)));
40
45
  }
41
46
  let activeHistoryPatch;
42
47
  function subscribeHistoryChanges(subscriber) {
@@ -218,12 +223,12 @@ function validateInput(definition, input) {
218
223
  }
219
224
  }
220
225
  export function browserToolsAvailable() {
221
- return (typeof window !== "undefined" &&
222
- typeof document !== "undefined" &&
223
- typeof Worker !== "undefined" &&
224
- typeof Blob !== "undefined" &&
225
- typeof URL?.createObjectURL === "function" &&
226
- typeof MutationObserver !== "undefined");
226
+ return (typeof window !== "undefined"
227
+ && typeof document !== "undefined"
228
+ && typeof Worker !== "undefined"
229
+ && typeof Blob !== "undefined"
230
+ && typeof URL?.createObjectURL === "function"
231
+ && typeof MutationObserver !== "undefined");
227
232
  }
228
233
  export function createBrowserToolset(options = {}) {
229
234
  if (!browserToolsAvailable()) {
@@ -231,14 +236,19 @@ export function createBrowserToolset(options = {}) {
231
236
  }
232
237
  const limits = {
233
238
  ...DEFAULT_EXECUTION_LIMITS,
234
- maxDurationMs: options.limits?.maxDurationMs ?? DEFAULT_EXECUTION_LIMITS.maxDurationMs,
235
- maxResultChars: options.limits?.maxResultChars ?? DEFAULT_EXECUTION_LIMITS.maxResultChars,
236
- singleActionTimeoutMs: options.limits?.singleActionTimeoutMs ?? DEFAULT_EXECUTION_LIMITS.singleActionTimeoutMs,
239
+ maxDurationMs: options.limits?.maxDurationMs
240
+ ?? DEFAULT_EXECUTION_LIMITS.maxDurationMs,
241
+ maxResultChars: options.limits?.maxResultChars
242
+ ?? DEFAULT_EXECUTION_LIMITS.maxResultChars,
243
+ singleActionTimeoutMs: options.limits?.singleActionTimeoutMs
244
+ ?? DEFAULT_EXECUTION_LIMITS.singleActionTimeoutMs,
237
245
  };
238
246
  const snapshotLimits = {
239
247
  ...DEFAULT_SNAPSHOT_LIMITS,
240
- viewportMaxChars: options.snapshotLimits?.viewportMaxChars ?? DEFAULT_SNAPSHOT_LIMITS.viewportMaxChars,
241
- fullMaxChars: options.snapshotLimits?.fullMaxChars ?? DEFAULT_SNAPSHOT_LIMITS.fullMaxChars,
248
+ viewportMaxChars: options.snapshotLimits?.viewportMaxChars
249
+ ?? DEFAULT_SNAPSHOT_LIMITS.viewportMaxChars,
250
+ fullMaxChars: options.snapshotLimits?.fullMaxChars
251
+ ?? DEFAULT_SNAPSHOT_LIMITS.fullMaxChars,
242
252
  };
243
253
  const feedback = new ActionFeedback();
244
254
  const controller = new PageController(limits, feedback);
@@ -275,8 +285,7 @@ export function createBrowserToolset(options = {}) {
275
285
  const scope = normalizedInput.scope;
276
286
  const deadline = performance.now() + limits.maxDurationMs;
277
287
  signal.throwIfAborted();
278
- return (await observe(scope, { deadline, signal }, pageDecision ? "actions" : "text"))
279
- .snapshot;
288
+ return (await observe(scope, { deadline, signal }, pageDecision ? "actions" : "text")).snapshot;
280
289
  },
281
290
  };
282
291
  const executeObserved = async (signal, execute, cancel, mode = "code", onFeedback, assertActive) => {
@@ -307,8 +316,7 @@ export function createBrowserToolset(options = {}) {
307
316
  }
308
317
  result = await measurePagePhase("execution", () => execute(activeRegistry, workerBudget));
309
318
  signal.throwIfAborted();
310
- if (result.error &&
311
- ["EXECUTION_TIMEOUT", "WORKER_ERROR", "EXECUTION_OUTCOME_UNKNOWN"].includes(result.error.code)) {
319
+ if (result.error && ["EXECUTION_TIMEOUT", "WORKER_ERROR", "EXECUTION_OUTCOME_UNKNOWN"].includes(result.error.code)) {
312
320
  result.error.code = "EXECUTION_OUTCOME_UNKNOWN";
313
321
  }
314
322
  if (!result.ok && result.completedActions.length === 0) {
@@ -317,7 +325,9 @@ export function createBrowserToolset(options = {}) {
317
325
  try {
318
326
  const settled = await measurePagePhase("settle", () => tracker.waitForSettle({ deadline, signal }));
319
327
  signal.throwIfAborted();
320
- if (settled.timedOut && settled.urlChanged && !settled.mutationObservedAfterUrlChange) {
328
+ if (settled.timedOut
329
+ && settled.urlChanged
330
+ && !settled.mutationObservedAfterUrlChange) {
321
331
  result.snapshotUnavailable = true;
322
332
  return expireRefs(result);
323
333
  }
@@ -372,9 +382,7 @@ export function createBrowserToolset(options = {}) {
372
382
  if (!bundle || bundle.snapshot.snapshotId !== input.snapshotId)
373
383
  return undefined;
374
384
  const selected = bundle.actions?.get(input.actionId);
375
- if (!selected ||
376
- selected.command.method === "scrollBy" ||
377
- selected.command.method === "waitForTimeout")
385
+ if (!selected || selected.command.method === "scrollBy" || selected.command.method === "waitForTimeout")
378
386
  return undefined;
379
387
  const target = selected.command.target;
380
388
  const element = target?.type === "ref" ? bundle.registry.refs.get(target.ref)?.element : undefined;
@@ -388,21 +396,14 @@ export function createBrowserToolset(options = {}) {
388
396
  const selected = bundle.actions.get(input.actionId);
389
397
  if (!selected)
390
398
  throw new AgentToolError("INVALID_INPUT", "Action is not a candidate of this observation.");
391
- if (selected.command.method === "fill"
392
- ? typeof input.text !== "string" || !input.text.trim()
393
- : input.text !== undefined) {
399
+ if (selected.command.method === "fill" ? typeof input.text !== "string" || !input.text.trim() : input.text !== undefined) {
394
400
  throw new AgentToolError("INVALID_INPUT", "Only fill actions require a non-empty text value.");
395
401
  }
396
402
  if (selected.command.method === "selectOption") {
397
403
  const target = selected.command.target;
398
404
  const element = target.type === "ref" ? bundle.registry.refs.get(target.ref)?.element : undefined;
399
- const options = element instanceof HTMLSelectElement
400
- ? [...element.options].filter((option) => option.value === selected.command.args[0])
401
- : [];
402
- if (options.length !== 1 ||
403
- options[0].disabled ||
404
- options[0].closest("optgroup[disabled]") ||
405
- options[0].label.slice(0, 500) !== selected.candidate.option) {
405
+ const options = element instanceof HTMLSelectElement ? [...element.options].filter((option) => option.value === selected.command.args[0]) : [];
406
+ if (options.length !== 1 || options[0].disabled || options[0].closest("optgroup[disabled]") || options[0].label.slice(0, 500) !== selected.candidate.option) {
406
407
  throw new AgentToolError("INVALID_INPUT", "The observed option changed or is no longer available. Observe again.");
407
408
  }
408
409
  }
@@ -412,9 +413,7 @@ export function createBrowserToolset(options = {}) {
412
413
  let timer;
413
414
  try {
414
415
  const command = {
415
- ...selected.command,
416
- executionId,
417
- commandSeq: 1,
416
+ ...selected.command, executionId, commandSeq: 1,
418
417
  args: selected.command.method === "fill" ? [input.text] : selected.command.args,
419
418
  };
420
419
  const response = await Promise.race([
@@ -422,8 +421,7 @@ export function createBrowserToolset(options = {}) {
422
421
  if (selected.optionElement) {
423
422
  const target = selected.command.target;
424
423
  const element = target.type === "ref" ? registry.refs.get(target.ref)?.element : undefined;
425
- if (!selected.optionElement.isConnected ||
426
- selected.optionElement.closest("select") !== element) {
424
+ if (!selected.optionElement.isConnected || selected.optionElement.closest("select") !== element) {
427
425
  throw new AgentToolError("INVALID_INPUT", "The observed option was replaced. Observe again.");
428
426
  }
429
427
  }
@@ -436,12 +434,7 @@ export function createBrowserToolset(options = {}) {
436
434
  }),
437
435
  ]);
438
436
  const receipt = controller.completeExecution(executionId);
439
- return {
440
- executionId,
441
- ...receipt,
442
- ok: response.ok,
443
- ...(response.error ? { error: response.error } : {}),
444
- };
437
+ return { executionId, ...receipt, ok: response.ok, ...(response.error ? { error: response.error } : {}) };
445
438
  }
446
439
  finally {
447
440
  clearTimeout(timer);
@@ -456,3 +449,4 @@ export function createBrowserToolset(options = {}) {
456
449
  handlers: new Map(toolHandlers.map((tool) => [tool.definition.name, tool])),
457
450
  };
458
451
  }
452
+ //# sourceMappingURL=toolset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolset.js","sourceRoot":"","sources":["../../src/browser/toolset.ts"],"names":[],"mappings":"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","sourcesContent":["import { measurePagePhase } from \"./diagnostics.js\";\nimport { AgentToolError } from \"../runtime.js\";\nimport { validateAgentToolInput } from \"../shared/schema.js\";\nimport type { AgentToolDefinition } from \"../types.js\";\nimport { getSnapshotTool, executeActionTool, applyActionTool } from \"../shared/page-tools.js\";\nexport { getSnapshotTool, executeActionTool, applyActionTool } from \"../shared/page-tools.js\";\n\nimport { PageController } from \"./controller.js\";\nimport { ActionFeedback, type PageFeedbackListener } from \"./feedback.js\";\nimport { createSnapshot } from \"./snapshot.js\";\nimport type {\n ExecutionLimits,\n ExecutionResult,\n SnapshotBundle,\n SnapshotLimits,\n SnapshotScope,\n SnapshotFormat,\n PageCommand,\n} from \"./types.js\";\nimport { WorkerRunner } from \"./worker-runner.js\";\n\nexport const DEFAULT_EXECUTION_LIMITS: ExecutionLimits = {\n maxArgumentChars: 8_000,\n maxCodeLength: 12_000,\n maxDurationMs: 20_000,\n maxPageCalls: 30,\n maxResultChars: 64_000,\n singleActionTimeoutMs: 5_000,\n};\n\nconst MINIMUM_OBSERVATION_MS = 500;\nconst ACTION_OBSERVATION_MS = 150;\nconst QUIET_WINDOW_MS = 250;\nconst MAXIMUM_SETTLE_MS = 2_000;\nconst PAGE_POLL_INTERVAL_MS = 50;\n\nconst DEFAULT_SNAPSHOT_LIMITS: SnapshotLimits = {\n viewportMaxChars: 24_000,\n viewportMaxVisitedNodes: 12_000,\n fullMaxChars: 60_000,\n fullMaxVisitedNodes: 40_000,\n};\n\nexport interface PageAutomationOptions {\n limits?: {\n maxDurationMs?: number;\n maxResultChars?: number;\n singleActionTimeoutMs?: number;\n };\n snapshotLimits?: {\n viewportMaxChars?: number;\n fullMaxChars?: number;\n };\n}\n\nexport interface BrowserToolHandler {\n resolveTarget?(input: Record<string, unknown>): HTMLElement | undefined;\n definition: AgentToolDefinition<Record<string, unknown>, unknown>;\n execute(\n input: Record<string, unknown>,\n context: { signal: AbortSignal; onFeedback?: PageFeedbackListener; assertActive?: () => void; pageDecision?: boolean },\n ): Promise<unknown>;\n}\n\nexport interface BrowserToolset {\n definitions: AgentToolDefinition<Record<string, unknown>, unknown>[];\n handlers: Map<string, BrowserToolHandler>;\n}\n\nfunction isIgnoredMutationNode(node: Node | null): boolean {\n const element =\n node instanceof Element\n ? node\n : node instanceof Text\n ? node.parentElement\n : null;\n return Boolean(element?.closest(\"[data-nexface-ignore]\"));\n}\n\nfunction isRelevantMutation(record: MutationRecord): boolean {\n if (isIgnoredMutationNode(record.target)) return false;\n if (record.type !== \"childList\") return true;\n const changedNodes = [...record.addedNodes, ...record.removedNodes];\n return (\n changedNodes.length === 0\n || changedNodes.some((node) => !isIgnoredMutationNode(node))\n );\n}\n\nexport interface PageTransitionSettleResult {\n timedOut: boolean;\n urlChanged: boolean;\n mutationObservedAfterUrlChange: boolean;\n}\n\nexport interface PageTransitionTracker {\n waitForSettle(options: {\n deadline: number;\n signal: AbortSignal;\n }): Promise<PageTransitionSettleResult>;\n dispose(): void;\n}\n\ninterface HistoryChangeSubscriber {\n beforeChange(): void;\n afterChange(): void;\n}\n\ninterface HistoryPatch {\n subscribers: Set<HistoryChangeSubscriber>;\n originalPushState: History[\"pushState\"];\n originalReplaceState: History[\"replaceState\"];\n wrappedPushState: History[\"pushState\"];\n wrappedReplaceState: History[\"replaceState\"];\n onUrlEvent: () => void;\n}\n\nlet activeHistoryPatch: HistoryPatch | undefined;\n\nfunction subscribeHistoryChanges(\n subscriber: HistoryChangeSubscriber,\n): () => void {\n if (!activeHistoryPatch) {\n const subscribers = new Set<HistoryChangeSubscriber>();\n const originalPushState = history.pushState;\n const originalReplaceState = history.replaceState;\n const beforeChange = (): void => {\n for (const entry of [...subscribers]) entry.beforeChange();\n };\n const afterChange = (): void => {\n for (const entry of [...subscribers]) entry.afterChange();\n };\n const wrappedPushState: History[\"pushState\"] = function(\n this: History,\n data,\n unused,\n url,\n ): void {\n beforeChange();\n originalPushState.call(this, data, unused, url);\n afterChange();\n };\n const wrappedReplaceState: History[\"replaceState\"] = function(\n this: History,\n data,\n unused,\n url,\n ): void {\n beforeChange();\n originalReplaceState.call(this, data, unused, url);\n afterChange();\n };\n const onUrlEvent = (): void => {\n beforeChange();\n afterChange();\n };\n activeHistoryPatch = {\n subscribers,\n originalPushState,\n originalReplaceState,\n wrappedPushState,\n wrappedReplaceState,\n onUrlEvent,\n };\n history.pushState = wrappedPushState;\n history.replaceState = wrappedReplaceState;\n window.addEventListener(\"popstate\", onUrlEvent);\n window.addEventListener(\"hashchange\", onUrlEvent);\n }\n\n const patch = activeHistoryPatch;\n patch.subscribers.add(subscriber);\n let unsubscribed = false;\n return () => {\n if (unsubscribed) return;\n unsubscribed = true;\n patch.subscribers.delete(subscriber);\n if (patch.subscribers.size > 0 || activeHistoryPatch !== patch) return;\n if (history.pushState === patch.wrappedPushState) {\n history.pushState = patch.originalPushState;\n }\n if (history.replaceState === patch.wrappedReplaceState) {\n history.replaceState = patch.originalReplaceState;\n }\n window.removeEventListener(\"popstate\", patch.onUrlEvent);\n window.removeEventListener(\"hashchange\", patch.onUrlEvent);\n activeHistoryPatch = undefined;\n };\n}\n\nexport function startPageTransitionTracker(mode: \"code\" | \"action\" = \"code\"): PageTransitionTracker {\n const minimumObservationMs = mode === \"action\" ? ACTION_OBSERVATION_MS : MINIMUM_OBSERVATION_MS;\n const quietWindowMs = mode === \"action\" ? ACTION_OBSERVATION_MS : QUIET_WINDOW_MS;\n const initialUrl = location.href;\n let currentUrl = initialUrl;\n let urlChangedAt: number | undefined;\n let didUrlChange = false;\n let mutationObservedAfterUrlChange = false;\n let lastRelevantMutationAt = performance.now();\n let disposed = false;\n\n const syncUrl = (now: number): void => {\n const nextUrl = location.href;\n if (nextUrl === currentUrl) return;\n currentUrl = nextUrl;\n didUrlChange = true;\n urlChangedAt = now;\n mutationObservedAfterUrlChange = false;\n lastRelevantMutationAt = now;\n };\n\n let observer: MutationObserver;\n const recordMutations = (\n records: MutationRecord[],\n now: number,\n ): void => {\n if (!records.some(isRelevantMutation)) return;\n lastRelevantMutationAt = now;\n if (didUrlChange) mutationObservedAfterUrlChange = true;\n };\n const flushBeforeUrlChange = (): void => {\n recordMutations(observer.takeRecords(), performance.now());\n };\n\n observer = new MutationObserver((records) => {\n const now = performance.now();\n if (location.href !== currentUrl) {\n recordMutations(records, now);\n syncUrl(now);\n return;\n }\n recordMutations(records, now);\n });\n observer.observe(document.body, {\n attributes: true,\n childList: true,\n characterData: true,\n subtree: true,\n });\n\n const unsubscribeHistory = subscribeHistoryChanges({\n beforeChange: flushBeforeUrlChange,\n afterChange: () => syncUrl(performance.now()),\n });\n\n return {\n waitForSettle({ deadline, signal }) {\n signal.throwIfAborted();\n const startedAt = performance.now();\n syncUrl(startedAt);\n const settleDeadline = Math.min(\n deadline,\n startedAt + MAXIMUM_SETTLE_MS,\n );\n\n return new Promise((resolve, reject) => {\n let timer = 0;\n let settled = false;\n const cleanup = (): void => {\n window.clearInterval(timer);\n signal.removeEventListener(\"abort\", onAbort);\n };\n const finish = (timedOut: boolean): void => {\n if (settled) return;\n settled = true;\n cleanup();\n resolve({\n timedOut,\n urlChanged: didUrlChange,\n mutationObservedAfterUrlChange,\n });\n };\n const onAbort = (): void => {\n if (settled) return;\n settled = true;\n cleanup();\n reject(\n signal.reason instanceof Error\n ? signal.reason\n : new DOMException(\"Execution cancelled.\", \"AbortError\"),\n );\n };\n const check = (): void => {\n const now = performance.now();\n syncUrl(now);\n const minimumStartedAt = Math.max(\n startedAt,\n urlChangedAt ?? startedAt,\n );\n const reachedMinimum =\n now - minimumStartedAt >= minimumObservationMs;\n const isQuiet = now - lastRelevantMutationAt >= quietWindowMs;\n const urlReady =\n !didUrlChange || mutationObservedAfterUrlChange;\n if (reachedMinimum && isQuiet && urlReady) {\n finish(false);\n return;\n }\n if (now >= settleDeadline) finish(true);\n };\n\n signal.addEventListener(\"abort\", onAbort, { once: true });\n timer = window.setInterval(check, PAGE_POLL_INTERVAL_MS);\n check();\n });\n },\n dispose() {\n if (disposed) return;\n disposed = true;\n observer.disconnect();\n unsubscribeHistory();\n },\n };\n}\n\nfunction validateInput(\n definition: AgentToolDefinition,\n input: Record<string, unknown>,\n): void {\n const errors = validateAgentToolInput(definition.inputSchema, input);\n if (errors.length > 0) {\n throw new AgentToolError(\"INVALID_INPUT\", errors.join(\" \"), { errors });\n }\n}\n\nexport function browserToolsAvailable(): boolean {\n return (\n typeof window !== \"undefined\"\n && typeof document !== \"undefined\"\n && typeof Worker !== \"undefined\"\n && typeof Blob !== \"undefined\"\n && typeof URL?.createObjectURL === \"function\"\n && typeof MutationObserver !== \"undefined\"\n );\n}\n\nexport function createBrowserToolset(\n options: PageAutomationOptions = {},\n): BrowserToolset {\n if (!browserToolsAvailable()) {\n throw new AgentToolError(\n \"BROWSER_TOOLS_UNAVAILABLE\",\n \"Page automation requires document, Worker, Blob URL, and MutationObserver support.\",\n );\n }\n\n const limits: ExecutionLimits = {\n ...DEFAULT_EXECUTION_LIMITS,\n maxDurationMs: options.limits?.maxDurationMs\n ?? DEFAULT_EXECUTION_LIMITS.maxDurationMs,\n maxResultChars: options.limits?.maxResultChars\n ?? DEFAULT_EXECUTION_LIMITS.maxResultChars,\n singleActionTimeoutMs: options.limits?.singleActionTimeoutMs\n ?? DEFAULT_EXECUTION_LIMITS.singleActionTimeoutMs,\n };\n const snapshotLimits = {\n ...DEFAULT_SNAPSHOT_LIMITS,\n viewportMaxChars: options.snapshotLimits?.viewportMaxChars\n ?? DEFAULT_SNAPSHOT_LIMITS.viewportMaxChars,\n fullMaxChars: options.snapshotLimits?.fullMaxChars\n ?? DEFAULT_SNAPSHOT_LIMITS.fullMaxChars,\n };\n const feedback = new ActionFeedback();\n const controller = new PageController(limits, feedback);\n const runner = new WorkerRunner(controller, limits);\n let bundle: SnapshotBundle | undefined;\n\n const activate = (next: SnapshotBundle): SnapshotBundle => {\n bundle = next;\n return next;\n };\n\n const clearBundle = (): void => {\n bundle = undefined;\n };\n\n const expireRefs = (result: ExecutionResult): ExecutionResult => {\n clearBundle();\n result.refsExpired = true;\n return result;\n };\n\n const observe = async (\n scope: SnapshotScope,\n execution?: { deadline: number; signal: AbortSignal },\n format: SnapshotFormat = \"text\",\n ): Promise<SnapshotBundle> => {\n const next = await measurePagePhase(\"observation\", () => createSnapshot(scope, snapshotLimits, execution, format));\n execution?.signal.throwIfAborted();\n if (execution && performance.now() >= execution.deadline) {\n throw new DOMException(\n \"Snapshot collection exceeded the page automation deadline.\",\n \"TimeoutError\",\n );\n }\n return activate(next);\n };\n\n const getSnapshot: BrowserToolHandler = {\n definition: getSnapshotTool,\n async execute(input, { signal, pageDecision }) {\n const normalizedInput = {\n ...input,\n scope: input.scope ?? \"viewport\",\n };\n validateInput(getSnapshotTool, normalizedInput);\n const scope = normalizedInput.scope as SnapshotScope;\n const deadline = performance.now() + limits.maxDurationMs;\n signal.throwIfAborted();\n return (await observe(scope, { deadline, signal }, pageDecision ? \"actions\" : \"text\")).snapshot;\n },\n };\n\n const executeObserved = async (\n signal: AbortSignal,\n execute: (registry: SnapshotBundle[\"registry\"], budget: number) => Promise<ExecutionResult>,\n cancel: () => void,\n mode: \"code\" | \"action\" = \"code\",\n onFeedback?: PageFeedbackListener,\n assertActive?: () => void,\n ): Promise<ExecutionResult> => {\n if (!bundle) throw new AgentToolError(\"BROWSER_SNAPSHOT_REQUIRED\", \"A current page observation is required.\");\n const format: SnapshotFormat = mode === \"action\" ? \"actions\" : \"text\";\n const deadline = performance.now() + limits.maxDurationMs;\n signal.throwIfAborted();\n\n const onAbort = (): void => cancel();\n signal.addEventListener(\"abort\", onAbort, { once: true });\n const tracker = startPageTransitionTracker(mode);\n feedback.listener = onFeedback;\n feedback.assertActive = assertActive;\n let result: ExecutionResult;\n try {\n const activeRegistry = bundle.registry;\n const workerBudget = Math.max(0, deadline - performance.now());\n if (workerBudget <= 0) {\n return {\n executionId: \"deadline-exceeded\",\n ok: false,\n completedActions: [],\n error: {\n code: \"EXECUTION_TIMEOUT\",\n message: `Execution exceeded ${limits.maxDurationMs}ms.`,\n },\n } satisfies ExecutionResult;\n }\n result = await measurePagePhase(\"execution\", () => execute(activeRegistry, workerBudget));\n signal.throwIfAborted();\n if (result.error && [\"EXECUTION_TIMEOUT\", \"WORKER_ERROR\", \"EXECUTION_OUTCOME_UNKNOWN\"].includes(result.error.code)) {\n result.error.code = \"EXECUTION_OUTCOME_UNKNOWN\";\n }\n if (!result.ok && result.completedActions.length === 0) {\n return expireRefs(result);\n }\n try {\n const settled = await measurePagePhase(\"settle\", () => tracker.waitForSettle({ deadline, signal }));\n signal.throwIfAborted();\n if (\n settled.timedOut\n && settled.urlChanged\n && !settled.mutationObservedAfterUrlChange\n ) {\n result.snapshotUnavailable = true;\n return expireRefs(result);\n }\n const remainingBudget = deadline - performance.now();\n if (remainingBudget <= 0) {\n result.snapshotUnavailable = true;\n return expireRefs(result);\n }\n if (settled.timedOut) {\n const diagnostic = await measurePagePhase(\"observation\", () => createSnapshot(\n \"viewport\",\n snapshotLimits,\n { deadline, signal },\n format,\n ));\n result.snapshot = diagnostic.snapshot;\n result.postSnapshotTimedOut = true;\n return expireRefs(result);\n }\n const refreshed = await observe(\"viewport\", { deadline, signal }, format);\n signal.throwIfAborted();\n result.snapshot = refreshed.snapshot;\n } catch (error) {\n if (signal.aborted) {\n clearBundle();\n throw signal.reason;\n }\n result.snapshotUnavailable = true;\n expireRefs(result);\n }\n return result;\n } catch (error) {\n clearBundle();\n if (signal.aborted) throw signal.reason;\n throw new AgentToolError(\n \"EXECUTION_OUTCOME_UNKNOWN\",\n error instanceof Error ? error.message : \"Browser execution failed.\",\n { refsExpired: true },\n );\n } finally {\n feedback.listener = undefined;\n feedback.assertActive = undefined;\n tracker.dispose();\n signal.removeEventListener(\"abort\", onAbort);\n }\n };\n\n const executeCode: BrowserToolHandler = {\n definition: executeActionTool,\n async execute(input, { signal, onFeedback, assertActive }) {\n validateInput(executeActionTool, input);\n return executeObserved(signal, (registry, budget) => runner.execute(input.code as string, registry, budget), () => runner.cancel(), \"code\", onFeedback, assertActive);\n },\n };\n\n const applyAction: BrowserToolHandler = {\n definition: applyActionTool,\n resolveTarget(input) {\n if (!bundle || bundle.snapshot.snapshotId !== input.snapshotId) return undefined;\n const selected = bundle.actions?.get(input.actionId as string);\n if (!selected || selected.command.method === \"scrollBy\" || selected.command.method === \"waitForTimeout\") return undefined;\n const target = selected.command.target;\n const element = target?.type === \"ref\" ? bundle.registry.refs.get(target.ref)?.element : undefined;\n return element instanceof HTMLElement && element.isConnected ? element : undefined;\n },\n async execute(input, { signal, onFeedback, assertActive }) {\n validateInput(applyActionTool, input);\n if (!bundle || bundle.snapshot.snapshotId !== input.snapshotId || !bundle.actions) {\n throw new AgentToolError(\"BROWSER_SNAPSHOT_REQUIRED\", \"The actions observation is missing or expired.\");\n }\n const selected = bundle.actions.get(input.actionId as string);\n if (!selected) throw new AgentToolError(\"INVALID_INPUT\", \"Action is not a candidate of this observation.\");\n if (selected.command.method === \"fill\" ? typeof input.text !== \"string\" || !input.text.trim() : input.text !== undefined) {\n throw new AgentToolError(\"INVALID_INPUT\", \"Only fill actions require a non-empty text value.\");\n }\n if (selected.command.method === \"selectOption\") {\n const target = selected.command.target;\n const element = target.type === \"ref\" ? bundle.registry.refs.get(target.ref)?.element : undefined;\n const options = element instanceof HTMLSelectElement ? [...element.options].filter((option) => option.value === selected.command.args[0]) : [];\n if (options.length !== 1 || options[0]!.disabled || options[0]!.closest(\"optgroup[disabled]\") || options[0]!.label.slice(0, 500) !== selected.candidate.option) {\n throw new AgentToolError(\"INVALID_INPUT\", \"The observed option changed or is no longer available. Observe again.\");\n }\n }\n const executionId = crypto.randomUUID();\n return executeObserved(signal, async (registry, budget) => {\n controller.beginExecution(executionId, registry);\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n const command: PageCommand = {\n ...selected.command, executionId, commandSeq: 1,\n args: selected.command.method === \"fill\" ? [input.text] : selected.command.args,\n };\n const response = await Promise.race([\n controller.execute(command, async () => {\n if (selected.optionElement) {\n const target = selected.command.target;\n const element = target.type === \"ref\" ? registry.refs.get(target.ref)?.element : undefined;\n if (!selected.optionElement.isConnected || selected.optionElement.closest(\"select\") !== element) {\n throw new AgentToolError(\"INVALID_INPUT\", \"The observed option was replaced. Observe again.\");\n }\n }\n }),\n new Promise<never>((_, reject) => {\n timer = setTimeout(() => {\n controller.cancelExecution(executionId);\n reject(new Error(\"Page action exceeded its execution budget.\"));\n }, budget);\n }),\n ]);\n const receipt = controller.completeExecution(executionId);\n return { executionId, ...receipt, ok: response.ok, ...(response.error ? { error: response.error } : {}) };\n } finally {\n clearTimeout(timer);\n controller.completeExecution(executionId);\n }\n }, () => controller.cancelExecution(executionId), \"action\", onFeedback, assertActive);\n },\n };\n\n const toolHandlers = [getSnapshot, executeCode, applyAction];\n return {\n definitions: toolHandlers.map(({ definition }) => definition),\n handlers: new Map(toolHandlers.map((tool) => [tool.definition.name, tool])),\n };\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import type { ObservedAction } from "./actions.js";
2
2
  import type { PageSnapshot } from "../shared/page-protocol.js";
3
- export type { SnapshotScope, SnapshotFormat, SemanticState, PageActionCandidate, PageSnapshot, } from "../shared/page-protocol.js";
3
+ export type { SnapshotScope, SnapshotFormat, SemanticState, PageActionCandidate, PageSnapshot } from "../shared/page-protocol.js";
4
4
  export interface RefTarget {
5
5
  element: Element;
6
6
  identity: string;
@@ -1 +1,2 @@
1
1
  export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/browser/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ObservedAction } from \"./actions.js\";\n\nimport type { PageSnapshot } from \"../shared/page-protocol.js\";\nexport type { SnapshotScope, SnapshotFormat, SemanticState, PageActionCandidate, PageSnapshot } from \"../shared/page-protocol.js\";\n\nexport interface RefTarget {\n element: Element;\n identity: string;\n kind?: \"element\" | \"scrollable\";\n}\n\nexport interface SnapshotRegistry {\n snapshotId: string;\n refs: Map<string, RefTarget>;\n}\n\nexport interface SnapshotBundle {\n snapshot: PageSnapshot;\n registry: SnapshotRegistry;\n actions?: Map<string, ObservedAction>;\n}\n\nexport interface RegexValue {\n source: string;\n flags: string;\n}\n\nexport type TextMatcher = string | RegexValue;\n\nexport type LocatorStep =\n | {\n kind: \"role\";\n role: string;\n options?: { name?: TextMatcher; exact?: boolean };\n }\n | {\n kind: \"text\";\n text: TextMatcher;\n options?: { exact?: boolean };\n }\n | {\n kind: \"label\";\n text: TextMatcher;\n options?: { exact?: boolean };\n }\n | {\n kind: \"filter\";\n hasText: TextMatcher;\n };\n\nexport interface LocatorDescriptor {\n steps: LocatorStep[];\n}\n\nexport type LocatorMethod =\n | \"click\"\n | \"fill\"\n | \"press\"\n | \"check\"\n | \"uncheck\"\n | \"selectOption\"\n | \"setOptionSelected\"\n | \"hover\"\n | \"focus\"\n | \"blur\"\n | \"scrollBy\"\n | \"scrollTo\"\n | \"scrollIntoView\"\n | \"exists\"\n | \"text\"\n | \"waitFor\";\n\nexport type PageMethod = \"scrollBy\" | \"waitForTimeout\" | \"waitForURL\";\n\nexport type PageCommandTarget =\n | { type: \"page\" }\n | { type: \"ref\"; ref: string }\n | { type: \"locator\"; locator: LocatorDescriptor };\n\nexport interface PageCommand {\n executionId: string;\n commandSeq: number;\n target: PageCommandTarget;\n method: LocatorMethod | PageMethod;\n args: unknown[];\n}\n\nexport interface CommandError {\n code:\n | \"NOT_FOUND\"\n | \"AMBIGUOUS_TARGET\"\n | \"REF_ACTION_FAILED\"\n | \"NOT_VISIBLE\"\n | \"ELEMENT_COVERED\"\n | \"ELEMENT_DISABLED\"\n | \"NOT_EDITABLE\"\n | \"ACTION_TIMEOUT\"\n | \"EXECUTION_CANCELLED\"\n | \"EXECUTION_OUTCOME_UNKNOWN\"\n | \"INVALID_COMMAND\"\n | \"RESULT_TOO_LARGE\"\n | \"UNSUPPORTED_OPERATION\";\n message: string;\n candidates?: string[];\n}\n\nexport type JSONValue =\n | null\n | boolean\n | number\n | string\n | JSONValue[]\n | { [key: string]: JSONValue };\n\nexport interface CompletedAction {\n callIndex: number;\n method: LocatorMethod | PageMethod;\n target?: string;\n}\n\nexport interface FailedCall {\n callIndex: number;\n method: LocatorMethod | PageMethod;\n target?: string;\n}\n\nexport interface ExecutionResult {\n executionId: string;\n ok: boolean;\n value?: JSONValue;\n completedActions: CompletedAction[];\n failedCall?: FailedCall;\n error?: {\n code: string;\n message: string;\n statement?: string;\n };\n snapshot?: PageSnapshot;\n snapshotUnavailable?: boolean;\n postSnapshotTimedOut?: boolean;\n refsExpired?: boolean;\n}\n\nexport interface ExecutionLimits {\n maxArgumentChars: number;\n maxCodeLength: number;\n maxDurationMs: number;\n maxPageCalls: number;\n maxResultChars: number;\n singleActionTimeoutMs: number;\n}\n\nexport interface SnapshotLimits {\n fullMaxChars: number;\n fullMaxVisitedNodes: number;\n viewportMaxChars: number;\n viewportMaxVisitedNodes: number;\n}\n"]}
@@ -397,3 +397,4 @@ export class WorkerRunner {
397
397
  active.cancel();
398
398
  }
399
399
  }
400
+ //# sourceMappingURL=worker-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-runner.js","sourceRoot":"","sources":["../../src/browser/worker-runner.ts"],"names":[],"mappings":"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","sourcesContent":["import { PageController } from \"./controller.js\";\nimport type {\n ExecutionLimits,\n ExecutionResult,\n JSONValue,\n PageCommand,\n SnapshotRegistry,\n} from \"./types.js\";\n\ninterface WorkerCommandMessage {\n type: \"command\";\n requestId: number;\n command: PageCommand;\n}\n\ninterface WorkerDoneMessage {\n type: \"done\";\n hasValue: boolean;\n value?: unknown;\n}\n\ninterface WorkerErrorMessage {\n type: \"error\";\n error: { code: string; message: string; statement?: string };\n}\n\ntype WorkerMessage =\n | WorkerCommandMessage\n | WorkerDoneMessage\n | WorkerErrorMessage;\n\nexport function createWorkerRuntimeSource(\n executionId: string,\n code: string,\n): string {\n return `\nconst executionId = ${JSON.stringify(executionId)};\nlet requestId = 0;\nlet commandSeq = 0;\nconst pending = new Map();\n\nself.onmessage = (event) => {\n const message = event.data;\n if (message.type !== \"response\") return;\n const entry = pending.get(message.requestId);\n if (!entry) return;\n pending.delete(message.requestId);\n if (message.response.ok) entry.resolve(message.response.value);\n else {\n const error = new Error(message.response.error?.message || \"Page command failed\");\n error.code = message.response.error?.code || \"PAGE_COMMAND_FAILED\";\n error.candidates = message.response.error?.candidates;\n entry.reject(error);\n }\n};\n\nfunction normalizeRPCValue(value) {\n if (value instanceof RegExp) {\n return { source: value.source, flags: value.flags };\n }\n if (\n value === null ||\n typeof value === \"string\" ||\n typeof value === \"boolean\" ||\n (typeof value === \"number\" && Number.isFinite(value))\n ) {\n return value;\n }\n if (Array.isArray(value)) return value.map(normalizeRPCValue);\n if (value && typeof value === \"object\") {\n const prototype = Object.getPrototypeOf(value);\n if (prototype !== Object.prototype && prototype !== null) {\n throw new Error(\"Page API arguments must be plain JSON values or RegExp.\");\n }\n return Object.fromEntries(\n Object.entries(value).map(([key, item]) => [key, normalizeRPCValue(item)])\n );\n }\n throw new Error(\"Page API arguments contain an unsupported value.\");\n}\n\nfunction normalizeResult(value, seen = new Set()) {\n if (\n value === null ||\n typeof value === \"string\" ||\n typeof value === \"boolean\" ||\n (typeof value === \"number\" && Number.isFinite(value))\n ) {\n return value;\n }\n if (Array.isArray(value)) {\n if (seen.has(value)) throw new Error(\"nxf_executeAction returned a cyclic value.\");\n seen.add(value);\n const result = value.map((item) => normalizeResult(item, seen));\n seen.delete(value);\n return result;\n }\n if (value && typeof value === \"object\") {\n const prototype = Object.getPrototypeOf(value);\n if (prototype !== Object.prototype && prototype !== null) {\n throw new Error(\"nxf_executeAction must return JSON-serializable data.\");\n }\n if (seen.has(value)) throw new Error(\"nxf_executeAction returned a cyclic value.\");\n seen.add(value);\n const result = Object.fromEntries(\n Object.entries(value).map(([key, item]) => [key, normalizeResult(item, seen)])\n );\n seen.delete(value);\n return result;\n }\n throw new Error(\"nxf_executeAction must return JSON-serializable data.\");\n}\n\nfunction rpc(target, method, args) {\n if (pending.size > 0) {\n const error = new Error(\"Page API operations must be awaited sequentially.\");\n error.code = \"CONCURRENT_PAGE_OPERATION\";\n throw error;\n }\n const id = ++requestId;\n const command = {\n executionId,\n commandSeq: ++commandSeq,\n target: normalizeRPCValue(target),\n method,\n args: normalizeRPCValue(args)\n };\n self.postMessage({ type: \"command\", requestId: id, command });\n return new Promise((resolve, reject) =>\n pending.set(id, { resolve, reject })\n );\n}\n\nclass Locator {\n constructor(steps) { this.steps = steps; }\n getByRole(role, options = {}) {\n return new Locator([...this.steps, { kind: \"role\", role, options }]);\n }\n getByText(text, options = {}) {\n return new Locator([...this.steps, { kind: \"text\", text, options }]);\n }\n getByLabel(text, options = {}) {\n return new Locator([...this.steps, { kind: \"label\", text, options }]);\n }\n filter(options) {\n return new Locator([...this.steps, { kind: \"filter\", hasText: options.hasText }]);\n }\n call(method, ...args) {\n return rpc(\n { type: \"locator\", locator: { steps: this.steps } },\n method,\n args\n );\n }\n click() { return this.call(\"click\"); }\n fill(value) { return this.call(\"fill\", value); }\n press(key) { return this.call(\"press\", key); }\n check() { return this.call(\"check\"); }\n uncheck() { return this.call(\"uncheck\"); }\n selectOption(value) { return this.call(\"selectOption\", value); }\n hover() { return this.call(\"hover\"); }\n focus() { return this.call(\"focus\"); }\n blur() { return this.call(\"blur\"); }\n scrollBy(value) { return this.call(\"scrollBy\", value); }\n scrollTo(value) { return this.call(\"scrollTo\", value); }\n scrollIntoView() { return this.call(\"scrollIntoView\"); }\n exists() { return this.call(\"exists\"); }\n text() { return this.call(\"text\"); }\n waitFor(options = {}) { return this.call(\"waitFor\", options); }\n}\n\nconst uiTarget = Object.freeze({\n ref: (ref) => {\n if (typeof ref !== \"string\" || !/^@\\\\d+$/.test(ref)) {\n throw new Error(\"ui.ref(ref) requires a Snapshot ref such as @12.\");\n }\n return new LocatorProxy({ type: \"ref\", ref });\n },\n getByRole: (role, options = {}) =>\n new Locator([{ kind: \"role\", role, options }]),\n getByText: (text, options = {}) =>\n new Locator([{ kind: \"text\", text, options }]),\n getByLabel: (text, options = {}) =>\n new Locator([{ kind: \"label\", text, options }]),\n scrollBy: (value) => rpc({ type: \"page\" }, \"scrollBy\", [value]),\n waitForTimeout: (ms) => rpc({ type: \"page\" }, \"waitForTimeout\", [ms]),\n waitForURL: (url, options = {}) =>\n rpc({ type: \"page\" }, \"waitForURL\", [url, options])\n});\nconst ui = new Proxy(uiTarget, {\n get(target, property, receiver) {\n if (typeof property !== \"string\" || Object.hasOwn(target, property)) {\n return Reflect.get(target, property, receiver);\n }\n const error = new Error(\n 'UI API method \"' + property + '\" is not available. Supported methods: '\n + Object.keys(uiTarget).join(\", \") + \".\"\n );\n error.code = \"UI_API_NOT_AVAILABLE\";\n throw error;\n }\n});\n\nfunction LocatorProxy(target) {\n this.target = target;\n}\nLocatorProxy.prototype.call = function(method, ...args) {\n return rpc(this.target, method, args);\n};\nfor (const method of [\n \"click\",\n \"check\",\n \"uncheck\",\n \"hover\",\n \"focus\",\n \"blur\",\n \"scrollIntoView\",\n \"exists\",\n \"text\"\n]) {\n LocatorProxy.prototype[method] = function() {\n return this.call(method);\n };\n}\nLocatorProxy.prototype.fill = function(value) { return this.call(\"fill\", value); };\nLocatorProxy.prototype.press = function(key) { return this.call(\"press\", key); };\nLocatorProxy.prototype.selectOption = function(value) {\n return this.call(\"selectOption\", value);\n};\nLocatorProxy.prototype.scrollBy = function(value) {\n return this.call(\"scrollBy\", value);\n};\nLocatorProxy.prototype.scrollTo = function(value) {\n return this.call(\"scrollTo\", value);\n};\nLocatorProxy.prototype.waitFor = function(options = {}) {\n return this.call(\"waitFor\", options);\n};\n\n(async () => {\n try {\n const rawResult = await (async () => {\n${code}\n })();\n if (pending.size > 0) {\n const error = new Error(\"Every Page API operation must be awaited before nxf_executeAction returns.\");\n error.code = \"UNAWAITED_PAGE_OPERATION\";\n throw error;\n }\n const hasValue = rawResult !== undefined;\n const value = hasValue ? normalizeResult(rawResult) : undefined;\n self.postMessage({ type: \"done\", hasValue, value });\n } catch (error) {\n self.postMessage({\n type: \"error\",\n error: {\n code: error?.code || \"CODE_EXECUTION_FAILED\",\n message: error?.message || String(error),\n statement: error?.statement || error?.stack?.split(\"\\\\n\")[1]?.trim()\n }\n });\n }\n})();`;\n}\n\nfunction validateJSONValue(\n value: unknown,\n maxChars: number,\n): JSONValue {\n const serialized = JSON.stringify(value);\n if (serialized === undefined) {\n throw new Error(\"nxf_executeAction returned a non-JSON value.\");\n }\n if (serialized.length > maxChars) {\n throw new Error(\n `nxf_executeAction result exceeds ${maxChars} serialized characters.`,\n );\n }\n return JSON.parse(serialized) as JSONValue;\n}\n\nexport class WorkerRunner {\n private active:\n | {\n executionId: string;\n worker: Worker;\n objectUrl: string;\n settled: boolean;\n cancel: () => void;\n }\n | undefined;\n\n constructor(\n private readonly controller: PageController,\n private readonly limits: ExecutionLimits,\n ) {}\n\n async execute(\n code: string,\n registry: SnapshotRegistry,\n maxDurationMs = this.limits.maxDurationMs,\n ): Promise<ExecutionResult> {\n if (code.length > this.limits.maxCodeLength) {\n return {\n executionId: \"rejected\",\n ok: false,\n completedActions: [],\n error: {\n code: \"CODE_TOO_LONG\",\n message: `Code exceeds ${this.limits.maxCodeLength} characters.`,\n },\n };\n }\n\n if (this.active && !this.active.settled) {\n return {\n executionId: \"rejected\",\n ok: false,\n completedActions: [],\n error: {\n code: \"EXECUTION_IN_PROGRESS\",\n message: \"Another nxf_executeAction call is still running.\",\n },\n };\n }\n\n const executionId = crypto.randomUUID();\n const source = createWorkerRuntimeSource(executionId, code);\n const blob = new Blob([source], {\n type: \"text/javascript\",\n });\n const objectUrl = URL.createObjectURL(blob);\n const worker = new Worker(objectUrl, {\n name: `nexface-${executionId}`,\n });\n this.controller.beginExecution(executionId, registry);\n\n return new Promise<ExecutionResult>((resolve) => {\n const active: NonNullable<WorkerRunner[\"active\"]> = {\n executionId,\n worker,\n objectUrl,\n settled: false,\n cancel: () => {},\n };\n this.active = active;\n\n const settle = (\n partial: Omit<\n ExecutionResult,\n \"executionId\" | \"completedActions\" | \"failedCall\"\n >,\n ): void => {\n if (active.settled) return;\n active.settled = true;\n window.clearTimeout(timer);\n worker.terminate();\n URL.revokeObjectURL(objectUrl);\n const receipt = this.controller.completeExecution(executionId);\n if (this.active === active) this.active = undefined;\n resolve({\n executionId,\n ...partial,\n completedActions: receipt.completedActions,\n ...(receipt.failedCall ? { failedCall: receipt.failedCall } : {}),\n });\n };\n\n active.cancel = () => {\n this.controller.cancelExecution(executionId);\n settle({\n ok: false,\n error: {\n code: \"EXECUTION_CANCELLED\",\n message: \"Execution was cancelled.\",\n },\n });\n };\n\n const timer = window.setTimeout(() => {\n this.controller.cancelExecution(executionId);\n settle({\n ok: false,\n error: {\n code: \"EXECUTION_TIMEOUT\",\n message: `Execution exceeded ${maxDurationMs}ms.`,\n },\n });\n }, maxDurationMs);\n\n worker.onmessage = async (event: MessageEvent<WorkerMessage>) => {\n const message = event.data;\n if (message.type === \"command\") {\n let response = await this.controller.execute(message.command);\n if (response.ok && response.value !== undefined) {\n try {\n response = {\n ...response,\n value: validateJSONValue(\n response.value,\n this.limits.maxResultChars,\n ),\n };\n } catch (error) {\n response = {\n ok: false,\n error: {\n code: \"RESULT_TOO_LARGE\",\n message: error instanceof Error ? error.message : String(error),\n },\n };\n }\n }\n if (!active.settled) {\n worker.postMessage({\n type: \"response\",\n requestId: message.requestId,\n response,\n });\n }\n return;\n }\n if (message.type === \"done\") {\n if (!message.hasValue) {\n settle({ ok: true });\n return;\n }\n try {\n settle({\n ok: true,\n value: validateJSONValue(\n message.value,\n this.limits.maxResultChars,\n ),\n });\n } catch (error) {\n settle({\n ok: false,\n error: {\n code: \"RESULT_INVALID\",\n message:\n error instanceof Error ? error.message : String(error),\n },\n });\n }\n return;\n }\n settle({ ok: false, error: message.error });\n };\n\n worker.onerror = (event) => {\n settle({\n ok: false,\n error: {\n code: \"WORKER_ERROR\",\n message: event.message || \"Worker execution failed.\",\n },\n });\n };\n });\n }\n\n cancel(): void {\n const active = this.active;\n if (!active || active.settled) return;\n active.cancel();\n }\n}\n"]}
@@ -8,5 +8,7 @@ export declare function isValidAgentContextName(name: string): boolean;
8
8
  export declare function defineAgentTool<TResult = unknown>(metadata: AgentToolMetadataInput): AgentToolDefinition<Record<string, never>, TResult>;
9
9
  export declare function defineAgentTool<TInput = never, TResult = unknown, const TSchema extends AgentToolInputSchema = AgentToolInputSchema>(metadata: AgentToolMetadataInput & {
10
10
  inputSchema: TSchema;
11
- }): AgentToolDefinition<[TInput] extends [never] ? InferJsonSchema<TSchema> : TInput, TResult>;
11
+ }): AgentToolDefinition<[
12
+ TInput
13
+ ] extends [never] ? InferJsonSchema<TSchema> : TInput, TResult>;
12
14
  export {};
@@ -6,8 +6,7 @@ const emptyInputSchema = Object.freeze({
6
6
  });
7
7
  const agentNamePattern = /^[A-Za-z0-9_-]{1,64}$/;
8
8
  const reservedContextNames = new Set([
9
- "nxf_applyAction",
10
- "nxf_delegatePageTask",
9
+ "nxf_applyAction", "nxf_delegatePageTask",
11
10
  "nxf_callAppTool",
12
11
  "nxf_finish",
13
12
  "nxf_getSnapshot",
@@ -34,3 +33,4 @@ export function defineAgentTool(metadata) {
34
33
  inputSchema: metadata.inputSchema === undefined ? emptyInputSchema : metadata.inputSchema,
35
34
  });
36
35
  }
36
+ //# sourceMappingURL=definition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definition.js","sourceRoot":"","sources":["../src/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAOnE,MAAM,gBAAgB,GAAyB,MAAM,CAAC,MAAM,CAAC;IAC3D,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;IAC7B,oBAAoB,EAAE,KAAK;CAC5B,CAAC,CAAC;AAQH,MAAM,gBAAgB,GAAG,uBAAuB,CAAC;AAEjD,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC;IACnC,iBAAiB,EAAE,sBAAsB;IACzC,iBAAiB;IACjB,YAAY;IACZ,iBAAiB;IACjB,mBAAmB;CACpB,CAAC,CAAC;AAEH,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IAChC,GAAG,oBAAoB;IACvB,eAAe;IACf,oBAAoB;IACpB,kBAAkB;CACnB,CAAC,CAAC;AAEH,MAAM,UAAU,uBAAuB,CAAC,IAAY;IAClD,OAAO,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACxE,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC9B,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QAChE,MAAM,IAAI,KAAK,CAAC,wCAAwC,IAAI,GAAG,CAAC,CAAC;IACnE,CAAC;AACH,CAAC;AAeD,MAAM,UAAU,eAAe,CAC7B,QAAyE;IAEzE,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC1B,OAAO,yBAAyB,CAAC;QAC/B,GAAG,QAAQ;QACX,WAAW,EAAE,QAAQ,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW;KAC1F,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { createAgentToolDefinition } from \"./shared/definition.js\";\nimport type {\n AgentToolDefinition,\n AgentToolInputSchema,\n InferJsonSchema,\n} from \"./types.js\";\n\nconst emptyInputSchema: AgentToolInputSchema = Object.freeze({\n type: \"object\",\n properties: Object.freeze({}),\n additionalProperties: false,\n});\n\ninterface AgentToolMetadataInput {\n name: string;\n description: string;\n effect?: \"read\" | \"action\" | \"navigate\";\n}\n\nconst agentNamePattern = /^[A-Za-z0-9_-]{1,64}$/;\n\nconst reservedContextNames = new Set([\n \"nxf_applyAction\", \"nxf_delegatePageTask\",\n \"nxf_callAppTool\",\n \"nxf_finish\",\n \"nxf_getSnapshot\",\n \"nxf_executeAction\",\n]);\n\nconst reservedToolNames = new Set([\n ...reservedContextNames,\n \"nxf_loadSkill\",\n \"nxf_beginOperation\",\n \"nxf_endOperation\",\n]);\n\nexport function isValidAgentContextName(name: string): boolean {\n return agentNamePattern.test(name) && !reservedContextNames.has(name);\n}\n\nfunction assertName(name: string): void {\n if (!agentNamePattern.test(name) || reservedToolNames.has(name)) {\n throw new Error(`Invalid or reserved agent tool name: ${name}.`);\n }\n}\n\nexport function defineAgentTool<TResult = unknown>(\n metadata: AgentToolMetadataInput,\n): AgentToolDefinition<Record<string, never>, TResult>;\nexport function defineAgentTool<\n TInput = never,\n TResult = unknown,\n const TSchema extends AgentToolInputSchema = AgentToolInputSchema,\n>(\n metadata: AgentToolMetadataInput & { inputSchema: TSchema },\n): AgentToolDefinition<\n [TInput] extends [never] ? InferJsonSchema<TSchema> : TInput,\n TResult\n>;\nexport function defineAgentTool(\n metadata: AgentToolMetadataInput & { inputSchema?: AgentToolInputSchema },\n): AgentToolDefinition {\n assertName(metadata.name);\n return createAgentToolDefinition({\n ...metadata,\n inputSchema: metadata.inputSchema === undefined ? emptyInputSchema : metadata.inputSchema,\n });\n}\n"]}
@@ -1,3 +1,4 @@
1
1
  import "./styles.css";
2
2
  export * from "./index.js";
3
3
  export { registerAgentTool } from "./registration.js";
4
+ //# sourceMappingURL=index.browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.browser.js","sourceRoot":"","sources":["../src/index.browser.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AAEtB,cAAc,YAAY,CAAC;AAE3B,OAAO,EAAE,iBAAiB,EAA4B,MAAM,mBAAmB,CAAC","sourcesContent":["import \"./styles.css\";\n\nexport * from \"./index.js\";\n\nexport { registerAgentTool, type RegisteredAgentTool } from \"./registration.js\";\n"]}
package/dist/index.js CHANGED
@@ -4,3 +4,4 @@ export { AgentOperationSurface } from "./operation-surface.js";
4
4
  export { createToolRuntime, isToolRuntimeError, } from "./runtime.js";
5
5
  export { AgentContext, ToolsProvider, AgentUIAction, useAgentContext, useAgentNavigation, useAgentTool, } from "./react.js";
6
6
  export { registerAgentTool } from "./registration.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAmC,MAAM,wBAAwB,CAAC;AAChG,OAAO,EACL,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,YAAY,EACZ,aAAa,EACb,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,YAAY,GACb,MAAM,YAAY,CAAC;AAqCpB,OAAO,EAAE,iBAAiB,EAA4B,MAAM,mBAAmB,CAAC","sourcesContent":["export { defineAgentTool } from \"./definition.js\";\nexport { defineAgentNavigation } from \"./navigation.js\";\nexport { AgentOperationSurface, type AgentOperationSurfaceProps } from \"./operation-surface.js\";\nexport {\n createToolRuntime,\n isToolRuntimeError,\n} from \"./runtime.js\";\nexport {\n AgentContext,\n ToolsProvider,\n AgentUIAction,\n useAgentContext,\n useAgentNavigation,\n useAgentTool,\n} from \"./react.js\";\nexport type {\n AgentNavigation,\n AgentNavigationConfig,\n AgentNavigationExecutors,\n AgentNavigationRouteConfig,\n} from \"./navigation.js\";\nexport type {\n AgentToolBinding,\n AgentToolChatConfirmationConfig,\n AgentToolPageConfirmationConfig,\n AgentUIActionChildProps,\n AgentUIActionEvent,\n AgentUIActionProps,\n UseAgentToolDefaultOptions,\n UseAgentToolPageConfirmationOptions,\n} from \"./react.js\";\nexport type {\n AgentToolConfirmationConfig,\n RuntimeAgentTool,\n ToolRuntime,\n ToolOperation,\n ToolRuntimeOptions,\n ToolRuntimeToolChangeEvent,\n} from \"./runtime.js\";\nexport type {\n AgentContextEntry,\n AgentContextValue,\n AgentToolDefinition,\n AgentToolEffect,\n AgentToolExecutionContext,\n AgentToolExecutor,\n AgentToolInputSchema,\n InferJsonSchema,\n JsonSchema,\n} from \"./types.js\";\n\nexport { registerAgentTool, type RegisteredAgentTool } from \"./registration.js\";\n"]}
@@ -3,7 +3,7 @@ import { type ToolRuntime, type InternalToolRuntime } from "./runtime.js";
3
3
  export interface InternalToolRuntimeHostProps {
4
4
  children: ReactNode;
5
5
  }
6
- export declare function InternalToolRuntimeHost({ children }: InternalToolRuntimeHostProps): ReactElement;
6
+ export declare function InternalToolRuntimeHost({ children, }: InternalToolRuntimeHostProps): ReactElement;
7
7
  export declare function InternalToolRuntimeScope({ children, runtime, }: {
8
8
  children: ReactNode;
9
9
  runtime: ToolRuntime;
@@ -1,10 +1,10 @@
1
1
  import * as React from "react";
2
- import { createContext, useContext, useMemo } from "react";
2
+ import { createContext, useContext, useMemo, } from "react";
3
3
  import { createToolRuntime, getInternalToolRuntime, } from "./runtime.js";
4
4
  const InternalToolRuntimeContext = createContext(null);
5
- export function InternalToolRuntimeHost({ children }) {
5
+ export function InternalToolRuntimeHost({ children, }) {
6
6
  const runtime = useMemo(() => createToolRuntime(), []);
7
- return React.createElement(InternalToolRuntimeScope, { runtime: runtime }, children);
7
+ return (React.createElement(InternalToolRuntimeScope, { runtime: runtime }, children));
8
8
  }
9
9
  export function InternalToolRuntimeScope({ children, runtime, }) {
10
10
  const internalRuntime = getInternalToolRuntime(runtime);
@@ -20,3 +20,4 @@ export function useInternalToolRuntime() {
20
20
  export function useOptionalInternalToolRuntime() {
21
21
  return useContext(InternalToolRuntimeContext);
22
22
  }
23
+ //# sourceMappingURL=internal-react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internal-react.js","sourceRoot":"","sources":["../src/internal-react.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EACL,aAAa,EACb,UAAU,EACV,OAAO,GAGR,MAAM,OAAO,CAAC;AAEf,OAAO,EACL,iBAAiB,EACjB,sBAAsB,GAGvB,MAAM,cAAc,CAAC;AAEtB,MAAM,0BAA0B,GAC9B,aAAa,CAA6B,IAAI,CAAC,CAAC;AAMlD,MAAM,UAAU,uBAAuB,CAAC,EACtC,QAAQ,GACqB;IAC7B,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,iBAAiB,EAAE,EAAE,EAAE,CAAC,CAAC;IACvD,OAAO,CACL,oBAAC,wBAAwB,IAAC,OAAO,EAAE,OAAO,IACvC,QAAQ,CACgB,CAC5B,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,EACvC,QAAQ,EACR,OAAO,GAIR;IACC,MAAM,eAAe,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;IACxD,OAAO,CACL,oBAAC,0BAA0B,CAAC,QAAQ,IAAC,KAAK,EAAE,eAAe,IACxD,QAAQ,CAC2B,CACvC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,sBAAsB;IACpC,MAAM,OAAO,GAAG,UAAU,CAAC,0BAA0B,CAAC,CAAC;IACvD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,8EAA8E,CAC/E,CAAC;IACJ,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,8BAA8B;IAG5C,OAAO,UAAU,CAAC,0BAA0B,CAAC,CAAC;AAChD,CAAC","sourcesContent":["import * as React from \"react\";\nimport {\n createContext,\n useContext,\n useMemo,\n type ReactNode,\n type ReactElement,\n} from \"react\";\n\nimport {\n createToolRuntime,\n getInternalToolRuntime,\n type ToolRuntime,\n type InternalToolRuntime,\n} from \"./runtime.js\";\n\nconst InternalToolRuntimeContext =\n createContext<InternalToolRuntime | null>(null);\n\nexport interface InternalToolRuntimeHostProps {\n children: ReactNode;\n}\n\nexport function InternalToolRuntimeHost({\n children,\n}: InternalToolRuntimeHostProps): ReactElement {\n const runtime = useMemo(() => createToolRuntime(), []);\n return (\n <InternalToolRuntimeScope runtime={runtime}>\n {children}\n </InternalToolRuntimeScope>\n );\n}\n\nexport function InternalToolRuntimeScope({\n children,\n runtime,\n}: {\n children: ReactNode;\n runtime: ToolRuntime;\n}): ReactElement {\n const internalRuntime = getInternalToolRuntime(runtime);\n return (\n <InternalToolRuntimeContext.Provider value={internalRuntime}>\n {children}\n </InternalToolRuntimeContext.Provider>\n );\n}\n\nexport function useInternalToolRuntime(): InternalToolRuntime {\n const runtime = useContext(InternalToolRuntimeContext);\n if (!runtime) {\n throw new Error(\n \"Nexface components must be rendered inside ToolsProvider or NexfaceProvider.\",\n );\n }\n return runtime;\n}\n\nexport function useOptionalInternalToolRuntime():\n | InternalToolRuntime\n | null {\n return useContext(InternalToolRuntimeContext);\n}\n"]}
@@ -1 +1,2 @@
1
1
  export {};
2
+ //# sourceMappingURL=internal-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internal-types.js","sourceRoot":"","sources":["../src/internal-types.ts"],"names":[],"mappings":"","sourcesContent":["import type { RuntimeAgentTool } from \"./runtime.js\";\n\n/**\n * @experimental Status of an experimental execution notification.\n * @beta\n */\nexport type AgentToolExecutionStatus = \"running\" | \"success\" | \"error\";\n\n/**\n * @experimental Payload inferred by experimental execution listeners; not a named public export.\n * @beta\n */\nexport interface AgentToolExecutionEvent {\n tool: RuntimeAgentTool<any, any>;\n cancelled?: boolean;\n progressLabel?: string;\n id: string;\n operationId?: string;\n name: string;\n status: AgentToolExecutionStatus;\n startedAt: number;\n finishedAt?: number;\n input: unknown;\n result?: unknown;\n error?: unknown;\n}\n"]}
@@ -37,3 +37,4 @@ export function getAgentNavigationEntries(navigation) {
37
37
  }
38
38
  return entries;
39
39
  }
40
+ //# sourceMappingURL=navigation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigation.js","sourceRoot":"","sources":["../src/navigation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AA6BlD,MAAM,wBAAwB,GAAG,UAAU,CAAC;AA4B5C,MAAM,iBAAiB,GAAG,IAAI,OAAO,EAGlC,CAAC;AAEJ,MAAM,UAAU,qBAAqB,CAGnC,MAOC;IAED,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QACjE,MAAM,IAAI,GAAG,GAAG,wBAAwB,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QACxD,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW;YAClC,CAAC,CAAC,eAAe,CAAiC;gBAC9C,IAAI;gBACJ,MAAM,EAAE,UAAU;gBAClB,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,WAAW,EAAE,KAAK,CAAC,WAAW;aAC/B,CAAC;YACJ,CAAC,CAAC,eAAe,CAAwB;gBACrC,IAAI;gBACJ,MAAM,EAAE,UAAU;gBAClB,WAAW,EAAE,KAAK,CAAC,WAAW;aAC/B,CAAC,CAAC;QACP,IAAI,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,mCAAmC,UAAU,CAAC,IAAI,GAAG,CAAC,CAAC;QACzE,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC3B,OAAO,MAAM,CAAC,MAAM,CAAC;YACnB,GAAG;YACH,UAAU;SACX,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,CAAwC,CAAC;IAC5E,iBAAiB,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IAC1D,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,yBAAyB,CACvC,UAAgC;IAEhC,MAAM,OAAO,GAAG,iBAAiB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAClD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC","sourcesContent":["import { defineAgentTool } from \"./definition.js\";\nimport type {\n AgentToolDefinition,\n AgentToolExecutionContext,\n AgentToolInputSchema,\n InferJsonSchema,\n} from \"./types.js\";\n\nexport interface AgentNavigationResult {\n status: \"navigated\";\n}\n\ndeclare const agentNavigationBrand: unique symbol;\n\nexport interface AgentNavigationRouteConfig {\n name: string;\n description: string;\n inputSchema?: AgentToolInputSchema;\n}\n\nexport interface AgentNavigation<\n TRoutes extends Record<string, AgentNavigationRouteConfig> = Record<\n string,\n AgentNavigationRouteConfig\n >,\n> {\n readonly [agentNavigationBrand]: TRoutes;\n}\n\nconst navigationToolNamePrefix = \"nxf_nav_\";\n\nexport interface AgentNavigationConfig<\n TRoutes extends Record<string, AgentNavigationRouteConfig>,\n> {\n routes: TRoutes;\n}\n\nexport type AgentNavigationExecutors<\n TNavigation extends AgentNavigation,\n> = TNavigation extends AgentNavigation<infer TRoutes>\n ? {\n [TKey in keyof TRoutes]: (\n input: TRoutes[TKey] extends {\n readonly inputSchema: infer TSchema extends AgentToolInputSchema;\n }\n ? InferJsonSchema<TSchema>\n : Record<string, never>,\n context: AgentToolExecutionContext,\n ) => void | Promise<void>;\n }\n : never;\n\ninterface InternalAgentNavigationRoute {\n key: string;\n definition: AgentToolDefinition<any, AgentNavigationResult>;\n}\n\nconst navigationEntries = new WeakMap<\n AgentNavigation<any>,\n readonly InternalAgentNavigationRoute[]\n>();\n\nexport function defineAgentNavigation<\n const TRoutes extends Record<string, AgentNavigationRouteConfig>,\n>(\n config: AgentNavigationConfig<TRoutes> & {\n routes: {\n [TKey in keyof TRoutes]: Record<\n Exclude<keyof TRoutes[TKey], keyof AgentNavigationRouteConfig>,\n never\n >;\n };\n },\n): AgentNavigation<TRoutes> {\n const names = new Set<string>();\n const entries = Object.entries(config.routes).map(([key, route]) => {\n const name = `${navigationToolNamePrefix}${route.name}`;\n const definition = route.inputSchema\n ? defineAgentTool<unknown, AgentNavigationResult>({\n name,\n effect: \"navigate\",\n description: route.description,\n inputSchema: route.inputSchema,\n })\n : defineAgentTool<AgentNavigationResult>({\n name,\n effect: \"navigate\",\n description: route.description,\n });\n if (names.has(definition.name)) {\n throw new Error(`Duplicate navigation tool name: ${definition.name}.`);\n }\n names.add(definition.name);\n return Object.freeze({\n key,\n definition,\n });\n });\n const navigation = Object.freeze({}) as unknown as AgentNavigation<TRoutes>;\n navigationEntries.set(navigation, Object.freeze(entries));\n return navigation;\n}\n\nexport function getAgentNavigationEntries(\n navigation: AgentNavigation<any>,\n): readonly InternalAgentNavigationRoute[] {\n const entries = navigationEntries.get(navigation);\n if (!entries) {\n throw new Error(\"Navigation must be created by defineAgentNavigation().\");\n }\n return entries;\n}\n"]}
@@ -30,42 +30,7 @@ export function lockOperationSurface(surface, redirectFocus) {
30
30
  event.stopImmediatePropagation();
31
31
  };
32
32
  // Wheel and touch defaults are blocked here: React delegates them passively.
33
- const events = [
34
- "focus",
35
- "focusin",
36
- "mouseenter",
37
- "mouseleave",
38
- "pointerenter",
39
- "pointerleave",
40
- "pointerdown",
41
- "pointerup",
42
- "pointermove",
43
- "pointerover",
44
- "pointerout",
45
- "mousedown",
46
- "mouseup",
47
- "mousemove",
48
- "mouseover",
49
- "mouseout",
50
- "click",
51
- "dblclick",
52
- "auxclick",
53
- "contextmenu",
54
- "keydown",
55
- "keyup",
56
- "beforeinput",
57
- "paste",
58
- "cut",
59
- "drop",
60
- "dragstart",
61
- "touchstart",
62
- "touchmove",
63
- "touchend",
64
- "touchcancel",
65
- "wheel",
66
- "submit",
67
- "reset",
68
- ];
33
+ const events = ["focus", "focusin", "mouseenter", "mouseleave", "pointerenter", "pointerleave", "pointerdown", "pointerup", "pointermove", "pointerover", "pointerout", "mousedown", "mouseup", "mousemove", "mouseover", "mouseout", "click", "dblclick", "auxclick", "contextmenu", "keydown", "keyup", "beforeinput", "paste", "cut", "drop", "dragstart", "touchstart", "touchmove", "touchend", "touchcancel", "wheel", "submit", "reset"];
69
34
  lockedSurfaces.add(surface);
70
35
  surface.setAttribute("aria-busy", "true");
71
36
  for (const name of events)
@@ -80,3 +45,4 @@ export function lockOperationSurface(surface, redirectFocus) {
80
45
  surface.setAttribute("aria-busy", previousBusy);
81
46
  };
82
47
  }
48
+ //# sourceMappingURL=operation-lock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operation-lock.js","sourceRoot":"","sources":["../src/operation-lock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAErE,MAAM,cAAc,GAAG,IAAI,OAAO,EAAe,CAAC;AAElD,MAAM,UAAU,wBAAwB,CAAC,OAAoB;IAC3D,OAAO,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AACrC,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,oBAAoB,CAAC,OAAoB,EAAE,aAA0B;IACnF,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,CAAC,KAAY,EAAE,EAAE;QAC7B,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,iBAAiB,EAAE;YAAE,OAAO;QACvF,IAAI,CAAC,KAAK,CAAC,SAAS;YAAE,OAAO;QAC7B,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YACvD,IAAI,YAAY,EAAE;gBAAE,OAAO;YAC3B,KAAK,CAAC,wBAAwB,EAAE,CAAC;YACjC,IAAI,KAAK,CAAC,MAAM,YAAY,WAAW;gBAAE,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YAC7D,aAAa,EAAE,EAAE,CAAC;YAClB,OAAO;QACT,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAK,KAAuB,CAAC,GAAG,KAAK,KAAK,EAAE,CAAC;YACvE,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,KAAK,CAAC,wBAAwB,EAAE,CAAC;YACjC,aAAa,EAAE,EAAE,CAAC;YAClB,OAAO;QACT,CAAC;QACD,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,KAAK,CAAC,wBAAwB,EAAE,CAAC;IACnC,CAAC,CAAC;IACF,6EAA6E;IAC7E,MAAM,MAAM,GAAG,CAAC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAChb,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC5B,OAAO,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAC1C,KAAK,MAAM,IAAI,IAAI,MAAM;QAAE,OAAO,CAAC,gBAAgB,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IACpG,OAAO,GAAG,EAAE;QACV,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC/B,KAAK,MAAM,IAAI,IAAI,MAAM;YAAE,OAAO,CAAC,mBAAmB,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAC1E,IAAI,YAAY,KAAK,IAAI;YAAE,OAAO,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;;YAC3D,OAAO,CAAC,YAAY,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IACvD,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import { isAgentActivation, isAgentFocus } from \"./browser/focus.js\";\n\nconst lockedSurfaces = new WeakSet<HTMLElement>();\n\nexport function isOperationSurfaceLocked(surface: HTMLElement): boolean {\n return lockedSurfaces.has(surface);\n}\n\n/** Block user input inside the surface without hiding DOM from page tools. */\nexport function lockOperationSurface(surface: HTMLElement, redirectFocus?: () => void): () => void {\n const previousBusy = surface.getAttribute(\"aria-busy\");\n const block = (event: Event) => {\n if ((event.type === \"submit\" || event.type === \"reset\") && isAgentActivation()) return;\n if (!event.isTrusted) return;\n if (event.type === \"focus\" || event.type === \"focusin\") {\n if (isAgentFocus()) return;\n event.stopImmediatePropagation();\n if (event.target instanceof HTMLElement) event.target.blur();\n redirectFocus?.();\n return;\n }\n if (event.type === \"keydown\" && (event as KeyboardEvent).key === \"Tab\") {\n event.preventDefault();\n event.stopImmediatePropagation();\n redirectFocus?.();\n return;\n }\n event.preventDefault();\n event.stopImmediatePropagation();\n };\n // Wheel and touch defaults are blocked here: React delegates them passively.\n const events = [\"focus\", \"focusin\", \"mouseenter\", \"mouseleave\", \"pointerenter\", \"pointerleave\", \"pointerdown\", \"pointerup\", \"pointermove\", \"pointerover\", \"pointerout\", \"mousedown\", \"mouseup\", \"mousemove\", \"mouseover\", \"mouseout\", \"click\", \"dblclick\", \"auxclick\", \"contextmenu\", \"keydown\", \"keyup\", \"beforeinput\", \"paste\", \"cut\", \"drop\", \"dragstart\", \"touchstart\", \"touchmove\", \"touchend\", \"touchcancel\", \"wheel\", \"submit\", \"reset\"];\n lockedSurfaces.add(surface);\n surface.setAttribute(\"aria-busy\", \"true\");\n for (const name of events) surface.addEventListener(name, block, { capture: true, passive: false });\n return () => {\n lockedSurfaces.delete(surface);\n for (const name of events) surface.removeEventListener(name, block, true);\n if (previousBusy === null) surface.removeAttribute(\"aria-busy\");\n else surface.setAttribute(\"aria-busy\", previousBusy);\n };\n}\n"]}