@appilots/web-sdk 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4509,18 +4509,27 @@ var WRITE_SUCCESS = {
4509
4509
  "a\\s+[e\xE9]t[e\xE9]\\s+(?:enregistr|cr[e\xE9]|ajout|sauvegard)[e\xE9]e?"
4510
4510
  ]
4511
4511
  };
4512
+ var SENTENCE_START = "(?:^|[.!?:;*\\n]\\s*)";
4512
4513
  var COMPLETION_CLAIM = {
4513
4514
  pt: [
4514
4515
  "j[a\xE1]\\s+(?:cadastrei|registrei|salvei|criei)",
4515
4516
  "conclu[i\xED]\\s+o\\s+cadastro",
4516
- "cadastro\\s+(?:foi\\s+)?(?:conclu[i\xED]do|realizado|feito)"
4517
+ "cadastro\\s+(?:foi\\s+)?(?:conclu[i\xED]do|realizado|feito)",
4518
+ `${SENTENCE_START}(?:eu\\s+)?(?:cadastrei|registrei|salvei|criei|adicionei|enviei)\\b`
4517
4519
  ],
4518
4520
  en: [
4519
4521
  "i(?:'|\u2019)?ve\\s+(?:registered|saved|created|added)",
4520
- "i\\s+have\\s+(?:registered|saved|created|added)"
4522
+ "i\\s+have\\s+(?:registered|saved|created|added)",
4523
+ `${SENTENCE_START}i\\s+(?:registered|saved|created|added|submitted)\\b`
4521
4524
  ],
4522
- es: ["ya\\s+(?:lo\\s+|la\\s+)?(?:registr[e\xE9]|guard[e\xE9]|cre[e\xE9])"],
4523
- fr: ["j(?:e\\s+l(?:'|\u2019)ai|(?:'|\u2019)ai)\\s+(?:enregistr|cr[e\xE9]|ajout|sauvegard)[e\xE9]"]
4525
+ es: [
4526
+ "ya\\s+(?:lo\\s+|la\\s+)?(?:registr[e\xE9]|guard[e\xE9]|cre[e\xE9])",
4527
+ `${SENTENCE_START}(?:ya\\s+)?he\\s+(?:registrado|guardado|creado|enviado|a[\xF1n]adido)\\b`
4528
+ ],
4529
+ fr: [
4530
+ "j(?:e\\s+l(?:'|\u2019)ai|(?:'|\u2019)ai)\\s+(?:enregistr|cr[e\xE9]|ajout|sauvegard)[e\xE9]",
4531
+ `${SENTENCE_START}c(?:'|\u2019)est\\s+(?:enregistr|cr[e\xE9]|ajout|sauvegard)[e\xE9]`
4532
+ ]
4524
4533
  };
4525
4534
  var SUBMIT_CONTROL = {
4526
4535
  pt: ["cadastrar", "registrar", "salvar", "enviar", "confirmar"],
@@ -4638,6 +4647,7 @@ var AppilotsClient = class {
4638
4647
  mcpVersion;
4639
4648
  introspectionReporter;
4640
4649
  user;
4650
+ plainLanguage;
4641
4651
  sessionId = null;
4642
4652
  mission = null;
4643
4653
  missionDispatchPaused = false;
@@ -4656,6 +4666,7 @@ var AppilotsClient = class {
4656
4666
  this.mcpVersion = options.mcpVersion;
4657
4667
  this.introspectionReporter = options.introspectionReporter;
4658
4668
  this.user = options.user;
4669
+ this.plainLanguage = options.plainLanguage;
4659
4670
  this.headers = {
4660
4671
  "Content-Type": "application/json",
4661
4672
  // Version telemetry: lets the server correlate behavior per SDK
@@ -4805,6 +4816,19 @@ var AppilotsClient = class {
4805
4816
  return {};
4806
4817
  }
4807
4818
  }
4819
+ /**
4820
+ * Per-session plain-language override — e.g. from the signed-in user's
4821
+ * accessibility profile. `undefined` hands the decision back to the
4822
+ * project setting. Applies from the next request on.
4823
+ */
4824
+ setPlainLanguage(value) {
4825
+ this.plainLanguage = value;
4826
+ }
4827
+ /** Every relay-bound context carries the reply-style preference. */
4828
+ withPreferences(context) {
4829
+ if (this.plainLanguage === void 0) return context;
4830
+ return { ...context ?? {}, plainLanguage: this.plainLanguage };
4831
+ }
4808
4832
  // ── Messages ──────────────────────────────────────────────────
4809
4833
  async sendMessage(content, context) {
4810
4834
  if (this.sessionStorage && !this.sessionId) await this.loadStoredSession();
@@ -4818,7 +4842,7 @@ var AppilotsClient = class {
4818
4842
  body: JSON.stringify({
4819
4843
  content,
4820
4844
  sessionId: this.sessionId,
4821
- context,
4845
+ context: this.withPreferences(context),
4822
4846
  // Optional MCP version bundled with this app build. Server
4823
4847
  // compares vs the active MCP doc to detect stale uploads.
4824
4848
  ...this.mcpVersion ? { mcpVersion: this.mcpVersion } : {},
@@ -5083,7 +5107,7 @@ var AppilotsClient = class {
5083
5107
  JSON.stringify({
5084
5108
  content,
5085
5109
  sessionId: this.sessionId,
5086
- context,
5110
+ context: this.withPreferences(context),
5087
5111
  ...this.mcpVersion ? { mcpVersion: this.mcpVersion } : {},
5088
5112
  ...this.introspectionFragment()
5089
5113
  })
@@ -5102,7 +5126,9 @@ var AppilotsClient = class {
5102
5126
  body: JSON.stringify({
5103
5127
  sessionId: this.sessionId,
5104
5128
  results,
5105
- context: this.mission ? { ...context, missionProtocol: 1, missionId: this.mission.scope.id } : context,
5129
+ context: this.withPreferences(
5130
+ this.mission ? { ...context, missionProtocol: 1, missionId: this.mission.scope.id } : context
5131
+ ),
5106
5132
  hop
5107
5133
  })
5108
5134
  },
@@ -5190,7 +5216,7 @@ var AppilotsClient = class {
5190
5216
  body: JSON.stringify({
5191
5217
  command,
5192
5218
  missionId: this.mission.scope.id,
5193
- context
5219
+ context: this.withPreferences(context)
5194
5220
  })
5195
5221
  });
5196
5222
  if (command === "resume") this.missionDispatchPaused = false;
@@ -5577,6 +5603,11 @@ var AppilotsClient = class {
5577
5603
  };
5578
5604
  }
5579
5605
  };
5606
+ function isSpeechHost(value) {
5607
+ if (!value || typeof value !== "object") return false;
5608
+ const candidate = value;
5609
+ return typeof candidate.start === "function" && typeof candidate.stop === "function" && typeof candidate.cancel === "function";
5610
+ }
5580
5611
  var DESTRUCTIVE_LABEL_RE = /\b(cancelar?\w*|cancel(?:ar|led|ation|amento)?|delete\w*|exclu\w*|delet\w*|remov\w*|remove|apag\w*|destroy\w*|unsubscribe\w*)\b/i;
5581
5612
  function looksDestructiveActionLabel(value) {
5582
5613
  if (typeof value !== "string" || !value.trim()) return false;
@@ -6718,6 +6749,10 @@ function actionHasCompletedConfirmGate(action, actions) {
6718
6749
  return payload.destructive === true || payload.severity === "danger";
6719
6750
  });
6720
6751
  }
6752
+ function confirmExpiresAt(confirm) {
6753
+ const scope = readPayload(confirm).missionApproval;
6754
+ return typeof scope?.expiresAt === "number" ? scope.expiresAt : void 0;
6755
+ }
6721
6756
  var ActionQueueMachine = class {
6722
6757
  deps;
6723
6758
  options;
@@ -7223,6 +7258,20 @@ var ActionQueueMachine = class {
7223
7258
  return this.state.actions.filter((a) => a.status === "completed" || a.status === "failed");
7224
7259
  }
7225
7260
  };
7261
+ var STILL_WORKING_FIRST_MS = 1e4;
7262
+ var STILL_WORKING_EVERY_MS = 2e4;
7263
+ function startStillWorkingTimer(onTick) {
7264
+ let elapsedMs = STILL_WORKING_FIRST_MS;
7265
+ let timer = setTimeout(function tick() {
7266
+ onTick(Math.round(elapsedMs / 1e3));
7267
+ elapsedMs += STILL_WORKING_EVERY_MS;
7268
+ timer = setTimeout(tick, STILL_WORKING_EVERY_MS);
7269
+ }, STILL_WORKING_FIRST_MS);
7270
+ return () => clearTimeout(timer);
7271
+ }
7272
+ function normalize3(s) {
7273
+ return s.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]/g, "");
7274
+ }
7226
7275
  function matchScore(needle, hay) {
7227
7276
  if (!needle || !hay) return 0;
7228
7277
  if (needle === hay) return 100;
@@ -7923,7 +7972,7 @@ function parseInlineMarkdown(text) {
7923
7972
  }
7924
7973
 
7925
7974
  // src/version.ts
7926
- var SDK_VERSION2 = "0.2.0";
7975
+ var SDK_VERSION2 = "0.3.0";
7927
7976
 
7928
7977
  // src/introspection/locators.ts
7929
7978
  var APPILOTS_ID_ATTR = "data-appilots-id";
@@ -9318,7 +9367,9 @@ function stripComponentPrefix(componentId) {
9318
9367
  /^(?:button|btn|switch|toggle|slider|input|field|link)[-_](.+)$/i
9319
9368
  );
9320
9369
  if (kebab?.[1]) return kebab[1];
9321
- const camel = componentId.match(/^(?:button|btn|switch|toggle|slider|input|field|link)([A-Z].*)$/);
9370
+ const camel = componentId.match(
9371
+ /^(?:button|btn|switch|toggle|slider|input|field|link)([A-Z].*)$/
9372
+ );
9322
9373
  if (camel?.[1]) return camel[1].charAt(0).toLowerCase() + camel[1].slice(1);
9323
9374
  return null;
9324
9375
  }
@@ -9346,7 +9397,8 @@ function matchesKind(el, kind) {
9346
9397
  return !["checkbox", "radio", "button", "submit", "reset", "image"].includes(type);
9347
9398
  }
9348
9399
  if (kind === "toggle") {
9349
- if (tag === "input" && (el.getAttribute("type") ?? "").toLowerCase() === "checkbox") return true;
9400
+ if (tag === "input" && (el.getAttribute("type") ?? "").toLowerCase() === "checkbox")
9401
+ return true;
9350
9402
  const role2 = (el.getAttribute("role") ?? "").toLowerCase();
9351
9403
  return role2 === "switch" || role2 === "checkbox";
9352
9404
  }
@@ -9365,7 +9417,9 @@ function findListItemElements(listIndex, options = {}) {
9365
9417
  const root = rootOf(options);
9366
9418
  if (typeof root.querySelectorAll !== "function") return void 0;
9367
9419
  const containers = Array.from(
9368
- root.querySelectorAll(`[${APPILOTS_LIST_ID_ATTR}], ul, ol, table, [role="list"], [role="listbox"], [role="grid"]`)
9420
+ root.querySelectorAll(
9421
+ `[${APPILOTS_LIST_ID_ATTR}], ul, ol, table, [role="list"], [role="listbox"], [role="grid"]`
9422
+ )
9369
9423
  ).filter((el) => !hidesSubtree(el));
9370
9424
  const container = containers[listIndex];
9371
9425
  if (!container) return void 0;
@@ -9460,6 +9514,14 @@ function resolveTargetElement(rawId, options = {}) {
9460
9514
  return { element: el, via: "exact-id" };
9461
9515
  }
9462
9516
  }
9517
+ const folded = normalize3(id);
9518
+ if (folded) {
9519
+ for (const el of candidates) {
9520
+ if (idCandidatesFor(el).some((candidate) => normalize3(candidate) === folded)) {
9521
+ return { element: el, via: "exact-id" };
9522
+ }
9523
+ }
9524
+ }
9463
9525
  const stripped = stripComponentPrefix(id);
9464
9526
  if (stripped) {
9465
9527
  const strippedLower = stripped.toLowerCase();
@@ -9474,9 +9536,10 @@ function resolveTargetElement(rawId, options = {}) {
9474
9536
  let best;
9475
9537
  let tied = false;
9476
9538
  for (const el of candidates) {
9539
+ if (isSensitiveField(el, bestId(el), accessibleName(el))) continue;
9477
9540
  let score = 0;
9478
9541
  for (const candidate of idCandidatesFor(el)) {
9479
- score = Math.max(score, matchScore(id, candidate));
9542
+ score = Math.max(score, matchScore(folded, normalize3(candidate)));
9480
9543
  }
9481
9544
  if (score < MIN_FUZZY_SCORE) continue;
9482
9545
  if (!best || score > best.score) {
@@ -9506,7 +9569,9 @@ function isOccludedByModal(el, options = {}) {
9506
9569
  const root = rootOf(options);
9507
9570
  if (typeof root.querySelectorAll !== "function") return false;
9508
9571
  const modals = Array.from(
9509
- root.querySelectorAll('[aria-modal="true"], [role="dialog"], [role="alertdialog"], dialog[open]')
9572
+ root.querySelectorAll(
9573
+ '[aria-modal="true"], [role="dialog"], [role="alertdialog"], dialog[open]'
9574
+ )
9510
9575
  ).filter((modal) => !hidesSubtree(modal) && isVisible(modal));
9511
9576
  if (modals.length === 0) return false;
9512
9577
  return !modals.some((modal) => modal === el || modal.contains(el));
@@ -9515,7 +9580,9 @@ function modalCandidateLabels(options = {}, limit = 8) {
9515
9580
  const root = rootOf(options);
9516
9581
  if (typeof root.querySelectorAll !== "function") return [];
9517
9582
  const modal = Array.from(
9518
- root.querySelectorAll('[aria-modal="true"], [role="dialog"], [role="alertdialog"], dialog[open]')
9583
+ root.querySelectorAll(
9584
+ '[aria-modal="true"], [role="dialog"], [role="alertdialog"], dialog[open]'
9585
+ )
9519
9586
  ).find((candidate) => !hidesSubtree(candidate));
9520
9587
  if (!modal) return [];
9521
9588
  const out = [];
@@ -9550,6 +9617,21 @@ function readVisibleValidation(context) {
9550
9617
  const snapshot = captureSnapshot({ root: rootElement(context) });
9551
9618
  return snapshot.texts.find((text) => FORM_VALIDATION_TEXT_RE2.test(text));
9552
9619
  }
9620
+ var SUBMIT_SETTLE_MAX_MS = 6e3;
9621
+ function readAlertTexts(context) {
9622
+ const root = rootElement(context) ?? (typeof document !== "undefined" ? document.body : void 0);
9623
+ if (!root) return [];
9624
+ return Array.from(root.querySelectorAll('[role="alert"], [aria-live="assertive"]')).filter((el) => !hidesSubtree(el)).map((el) => (el.textContent ?? "").trim()).filter(Boolean);
9625
+ }
9626
+ async function waitForSubmitSettle(submit, context) {
9627
+ const busy = () => submit.isConnected && (submit.disabled || submit.getAttribute("aria-disabled") === "true") || captureSnapshot({ root: rootElement(context) }).loading;
9628
+ const started = Date.now();
9629
+ while (busy()) {
9630
+ if (context.signal?.aborted || Date.now() - started >= SUBMIT_SETTLE_MAX_MS) return !busy();
9631
+ await sleep2(100);
9632
+ }
9633
+ return true;
9634
+ }
9553
9635
  function rootElement(context) {
9554
9636
  const root = context.root;
9555
9637
  if (!root) return void 0;
@@ -9755,6 +9837,18 @@ async function formFillHandler(payload, context, permissions) {
9755
9837
  setToggleValue(el, value2);
9756
9838
  continue;
9757
9839
  }
9840
+ if (el.tagName.toLowerCase() === "input" && el.type === "file") {
9841
+ failures.push({
9842
+ fieldId: field.fieldId,
9843
+ error: `Field "${field.fieldId}" is a file picker; only the user can attach a file`,
9844
+ diagnose: diagnose(context, "validation", {
9845
+ fieldId: field.fieldId,
9846
+ recoverable: false,
9847
+ requiresUserInput: true
9848
+ })
9849
+ });
9850
+ continue;
9851
+ }
9758
9852
  const value = field.value == null ? "" : String(field.value);
9759
9853
  const written = setControlValue(el, value);
9760
9854
  if (!written) {
@@ -9822,6 +9916,7 @@ async function formFillHandler(payload, context, permissions) {
9822
9916
  context
9823
9917
  );
9824
9918
  if (blocked) return { success: false, ...blocked };
9919
+ const alertsBefore = new Set(readAlertTexts(context));
9825
9920
  clickElement(submit);
9826
9921
  await sleep2(120);
9827
9922
  if (context.signal?.aborted) return { success: false, error: "Session ended" };
@@ -9834,6 +9929,30 @@ async function formFillHandler(payload, context, permissions) {
9834
9929
  effect: "partial"
9835
9930
  };
9836
9931
  }
9932
+ const settled = await waitForSubmitSettle(submit, context);
9933
+ if (context.signal?.aborted) return { success: false, error: "Session ended" };
9934
+ if (!settled) {
9935
+ return {
9936
+ success: false,
9937
+ error: `Submit still in progress after ${SUBMIT_SETTLE_MAX_MS / 1e3}s \u2014 outcome unknown, do not report it as saved`,
9938
+ diagnose: diagnose(context, "screen-timeout", { recoverable: false }),
9939
+ effect: "unknown"
9940
+ };
9941
+ }
9942
+ const lateValidation = readVisibleValidation(context);
9943
+ const rejection = lateValidation ?? readAlertTexts(context).find((text) => !alertsBefore.has(text));
9944
+ if (rejection) {
9945
+ return {
9946
+ success: false,
9947
+ error: `Submit was rejected: ${rejection}`,
9948
+ diagnose: lateValidation ? diagnose(context, "validation", { visibleMessage: rejection, recoverable: true }) : (
9949
+ // Server-side failure (5xx, expired session, timeout): retrying
9950
+ // blindly can double-submit or loop, so hand it to the user.
9951
+ diagnose(context, "unknown", { visibleMessage: rejection, recoverable: false })
9952
+ ),
9953
+ effect: "partial"
9954
+ };
9955
+ }
9837
9956
  return { success: true, effect: "completed" };
9838
9957
  }
9839
9958
  return { success: true, effect: "changed" };
@@ -10152,6 +10271,14 @@ async function withSuppressedConfirm(context, fn) {
10152
10271
  }
10153
10272
 
10154
10273
  // src/runtime/AppilotsWebRuntime.ts
10274
+ function browserLocale() {
10275
+ if (typeof navigator === "undefined") return void 0;
10276
+ for (const language of navigator.languages ?? [navigator.language]) {
10277
+ const locale = normalizeAppilotsLocale(language);
10278
+ if (locale) return locale;
10279
+ }
10280
+ return void 0;
10281
+ }
10155
10282
  var POST_ACTION_LOADING_MAX_MS = 6e3;
10156
10283
  var AppilotsWebRuntime = class {
10157
10284
  client;
@@ -10177,13 +10304,15 @@ var AppilotsWebRuntime = class {
10177
10304
  apiKey: options.apiKey,
10178
10305
  apiBaseUrl: options.apiBaseUrl,
10179
10306
  debug: options.debug,
10307
+ timeout: options.timeout,
10180
10308
  appVersion: options.appVersion,
10181
10309
  mcpVersion: options.mcpVersion,
10182
10310
  // This package's own version, so the server can tell a web
10183
10311
  // client apart from an RN one by more than the platform field
10184
10312
  // (issue #312).
10185
10313
  sdkVersion: SDK_VERSION2,
10186
- user: options.user
10314
+ user: options.user,
10315
+ plainLanguage: options.plainLanguage
10187
10316
  });
10188
10317
  this.navigation = new WebNavigationAdapter({
10189
10318
  routes: options.routes,
@@ -10249,6 +10378,8 @@ var AppilotsWebRuntime = class {
10249
10378
  buildContext(extras = {}) {
10250
10379
  if (extras.newMission === true) this.deltaTracker.reset();
10251
10380
  const context = { platform: "web" };
10381
+ const deviceLocale = browserLocale();
10382
+ if (deviceLocale) context.deviceLocale = deviceLocale;
10252
10383
  const screen = this.navigation.getCurrentScreen();
10253
10384
  if (screen) context.currentScreen = screen;
10254
10385
  const navigationState = this.navigation.getNavigationState();
@@ -10379,4 +10510,106 @@ var AppilotsWebRuntime = class {
10379
10510
  }
10380
10511
  };
10381
10512
 
10382
- export { APPILOTS_CHAT_ATTR, APPILOTS_ID_ATTR, APPILOTS_ITEM_COUNT_ATTR, APPILOTS_ITEM_INDEX_ATTR, APPILOTS_ITEM_KEY_ATTR, APPILOTS_LIST_ID_ATTR, APPILOTS_LIST_ITEM_ATTR, APPILOTS_SENSITIVE_ATTR, APPILOTS_SKIP_ATTR, ActionQueueMachine, AppilotsClient, AppilotsWebRuntime, ChatSessionMachine, RateLimitedError, SDK_VERSION2 as SDK_VERSION, WebNavigationAdapter, accessibleName, bestId, buildPath, candidateIds, captureSnapshot, clickElement, describeAction, elementRole, executeAction, findListItemElements, findScrollContainer, focusElement, getRegisteredElement, hidesSubtree, humanizeError, isOccludedByModal, isVisible, longPressElement, matchRoute, modalCandidateLabels, normalizeLabelToId, parseInlineMarkdown, parseMarkdownBlocks, parseSyntheticListItemId, primaryControlOf, probeLoadingState, readControlValue, readOwnText, readScrollMetrics, readToggleValue, registeredElements, resolveListItem, resolveTargetElement, routesBelongToSameFeature2 as routesBelongToSameFeature, screenDepartedBaseline, scrollIntoView, scrollToOffset, setControlValue, setToggleValue, stripComponentPrefix, waitForLoadingSettle, waitForScreenSettle, walkDom };
10513
+ // src/speech/webSpeechHost.ts
10514
+ var MAX_SILENT_RESTARTS = 5;
10515
+ function recognitionCtor() {
10516
+ const g = globalThis;
10517
+ return g.SpeechRecognition ?? g.webkitSpeechRecognition ?? null;
10518
+ }
10519
+ function isWebSpeechSupported() {
10520
+ return recognitionCtor() !== null;
10521
+ }
10522
+ function createWebSpeechHost() {
10523
+ const Ctor = recognitionCtor();
10524
+ if (!Ctor) return null;
10525
+ let live = null;
10526
+ let committed = "";
10527
+ let current = "";
10528
+ let silentRestarts = 0;
10529
+ let pendingStop = null;
10530
+ const partialListeners = /* @__PURE__ */ new Set();
10531
+ const endListeners = /* @__PURE__ */ new Set();
10532
+ const text = () => `${committed} ${current}`.replace(/\s+/g, " ").trim();
10533
+ const ended = (error) => endListeners.forEach((l) => l(error));
10534
+ const open = (locale) => new Promise((resolve, reject) => {
10535
+ const r = new Ctor();
10536
+ live = r;
10537
+ r.lang = locale;
10538
+ r.continuous = true;
10539
+ r.interimResults = true;
10540
+ let started = false;
10541
+ let failure;
10542
+ r.onstart = () => {
10543
+ started = true;
10544
+ resolve();
10545
+ };
10546
+ r.onresult = ({ results }) => {
10547
+ if (live !== r) return;
10548
+ let next = "";
10549
+ for (let i = 0; i < results.length; i++) next += results[i]?.[0]?.transcript ?? "";
10550
+ current = next;
10551
+ silentRestarts = 0;
10552
+ const t = text();
10553
+ partialListeners.forEach((l) => l(t));
10554
+ };
10555
+ r.onerror = ({ error }) => {
10556
+ if (error !== "no-speech") failure = error;
10557
+ };
10558
+ r.onend = () => {
10559
+ if (live !== r) return;
10560
+ if (pendingStop) {
10561
+ const done = pendingStop;
10562
+ pendingStop = null;
10563
+ live = null;
10564
+ done(text());
10565
+ return;
10566
+ }
10567
+ live = null;
10568
+ if (!started) {
10569
+ reject(new Error(failure ?? "speech recognition did not start"));
10570
+ return;
10571
+ }
10572
+ if (failure) return ended(new Error(failure));
10573
+ if (silentRestarts >= MAX_SILENT_RESTARTS) return ended();
10574
+ silentRestarts++;
10575
+ committed = text();
10576
+ current = "";
10577
+ open(locale).catch(ended);
10578
+ };
10579
+ r.start();
10580
+ });
10581
+ return {
10582
+ start({ locale }) {
10583
+ live?.abort();
10584
+ committed = "";
10585
+ current = "";
10586
+ silentRestarts = 0;
10587
+ pendingStop = null;
10588
+ return open(locale);
10589
+ },
10590
+ stop() {
10591
+ const r = live;
10592
+ if (!r) return Promise.resolve(text());
10593
+ return new Promise((resolve) => {
10594
+ pendingStop = resolve;
10595
+ r.stop();
10596
+ });
10597
+ },
10598
+ async cancel() {
10599
+ const r = live;
10600
+ live = null;
10601
+ pendingStop = null;
10602
+ r?.abort();
10603
+ },
10604
+ onPartial(listener) {
10605
+ partialListeners.add(listener);
10606
+ return () => partialListeners.delete(listener);
10607
+ },
10608
+ onEnd(listener) {
10609
+ endListeners.add(listener);
10610
+ return () => endListeners.delete(listener);
10611
+ }
10612
+ };
10613
+ }
10614
+
10615
+ export { APPILOTS_CHAT_ATTR, APPILOTS_ID_ATTR, APPILOTS_ITEM_COUNT_ATTR, APPILOTS_ITEM_INDEX_ATTR, APPILOTS_ITEM_KEY_ATTR, APPILOTS_LIST_ID_ATTR, APPILOTS_LIST_ITEM_ATTR, APPILOTS_SENSITIVE_ATTR, APPILOTS_SKIP_ATTR, ActionQueueMachine, AppilotsClient, AppilotsWebRuntime, ChatSessionMachine, RateLimitedError, SDK_VERSION2 as SDK_VERSION, WebNavigationAdapter, accessibleName, appilotsDebugWarn, bestId, buildPath, candidateIds, captureSnapshot, clickElement, confirmExpiresAt, createWebSpeechHost, describeAction, elementRole, executeAction, findListItemElements, findScrollContainer, focusElement, getRegisteredElement, hidesSubtree, humanizeError, isOccludedByModal, isSpeechHost, isVisible, isWebSpeechSupported, longPressElement, matchRoute, modalCandidateLabels, normalizeLabelToId, parseInlineMarkdown, parseMarkdownBlocks, parseSyntheticListItemId, primaryControlOf, probeLoadingState, readControlValue, readOwnText, readScrollMetrics, readToggleValue, registeredElements, resolveListItem, resolveTargetElement, routesBelongToSameFeature2 as routesBelongToSameFeature, screenDepartedBaseline, scrollIntoView, scrollToOffset, setControlValue, setToggleValue, startStillWorkingTimer, stripComponentPrefix, waitForLoadingSettle, waitForScreenSettle, walkDom };
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as ControlEvidence, A as AgentAction, a as AppilotsLocale, b as AgentPermissions, c as AppilotsEvent, W as WebNavigationAdapter, S as ScreenActionMetadataLike, d as ActionExecutionResult } from './AppilotsWebRuntime-DZF26UyU.mjs';
2
- export { e as ActionDiagnose, f as ActionQueueMachine, g as AgentActionType, h as AppilotsClient, i as AppilotsEventHandler, j as AppilotsWebRuntime, k as AppilotsWebRuntimeOptions, l as ChatMessage, m as ChatSessionMachine, n as ChatSessionOptions, o as ChatSessionState, E as EscalationState, p as EscalationStrings, R as RateLimitedError, q as WebNavigationAdapterOptions, r as WebNavigationState, s as WebRoute, t as WebScreenMetadata, u as buildPath, v as matchRoute } from './AppilotsWebRuntime-DZF26UyU.mjs';
1
+ import { C as ControlEvidence, A as AgentAction, a as AppilotsLocale, b as AgentPermissions, c as AppilotsEvent, W as WebNavigationAdapter, S as ScreenActionMetadataLike, d as ActionExecutionResult } from './webSpeechHost-CrTKADeb.mjs';
2
+ export { e as ActionDiagnose, f as ActionQueueMachine, g as AgentActionType, h as AppilotsClient, i as AppilotsEventHandler, j as AppilotsWebRuntime, k as AppilotsWebRuntimeOptions, l as ChatMessage, m as ChatSessionMachine, n as ChatSessionOptions, o as ChatSessionState, E as EscalationState, p as EscalationStrings, R as RateLimitedError, q as SpeechHost, r as SpeechStartOptions, s as SpeechState, t as WebNavigationAdapterOptions, u as WebNavigationState, v as WebRoute, w as WebScreenMetadata, x as buildPath, y as createWebSpeechHost, z as isSpeechHost, B as isWebSpeechSupported, D as matchRoute } from './webSpeechHost-CrTKADeb.mjs';
3
3
 
4
4
  type ActionPresentationState = 'pending' | 'running' | 'success' | 'failed';
5
5
 
@@ -1005,6 +1005,6 @@ declare function scrollToOffset(container: Element, offset: number): boolean;
1005
1005
  * (`X-Appilots-Sdk-Version`). Kept identical to package.json by the
1006
1006
  * release flow; `version.test.ts` fails if the two ever disagree.
1007
1007
  */
1008
- declare const SDK_VERSION = "0.2.0";
1008
+ declare const SDK_VERSION = "0.3.0";
1009
1009
 
1010
1010
  export { APPILOTS_CHAT_ATTR, APPILOTS_ID_ATTR, APPILOTS_ITEM_COUNT_ATTR, APPILOTS_ITEM_INDEX_ATTR, APPILOTS_ITEM_KEY_ATTR, APPILOTS_LIST_ID_ATTR, APPILOTS_LIST_ITEM_ATTR, APPILOTS_SENSITIVE_ATTR, APPILOTS_SKIP_ATTR, ActionExecutionResult, AgentAction, AgentPermissions, AppilotsEvent, type LoadingProbeResult, type LoadingSettleOptions, type LoadingSettleResult, type ResolveOptions, type ResolvedTarget, SDK_VERSION, type ScreenSettleOptions, type ScreenSettleResult, type ScreenSnapshot, type ScrollMetrics, type SettleProbes, type WalkDomOptions, type WebExecutorContext, WebNavigationAdapter, accessibleName, bestId, candidateIds, captureSnapshot, clickElement, describeAction, elementRole, executeAction, findListItemElements, findScrollContainer, focusElement, getRegisteredElement, hidesSubtree, humanizeError, isOccludedByModal, isVisible, longPressElement, modalCandidateLabels, normalizeLabelToId, parseSyntheticListItemId, primaryControlOf, probeLoadingState, readControlValue, readOwnText, readScrollMetrics, readToggleValue, registeredElements, resolveListItem, resolveTargetElement, routesBelongToSameFeature, screenDepartedBaseline, scrollIntoView, scrollToOffset, setControlValue, setToggleValue, stripComponentPrefix, waitForLoadingSettle, waitForScreenSettle, walkDom };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as ControlEvidence, A as AgentAction, a as AppilotsLocale, b as AgentPermissions, c as AppilotsEvent, W as WebNavigationAdapter, S as ScreenActionMetadataLike, d as ActionExecutionResult } from './AppilotsWebRuntime-DZF26UyU.js';
2
- export { e as ActionDiagnose, f as ActionQueueMachine, g as AgentActionType, h as AppilotsClient, i as AppilotsEventHandler, j as AppilotsWebRuntime, k as AppilotsWebRuntimeOptions, l as ChatMessage, m as ChatSessionMachine, n as ChatSessionOptions, o as ChatSessionState, E as EscalationState, p as EscalationStrings, R as RateLimitedError, q as WebNavigationAdapterOptions, r as WebNavigationState, s as WebRoute, t as WebScreenMetadata, u as buildPath, v as matchRoute } from './AppilotsWebRuntime-DZF26UyU.js';
1
+ import { C as ControlEvidence, A as AgentAction, a as AppilotsLocale, b as AgentPermissions, c as AppilotsEvent, W as WebNavigationAdapter, S as ScreenActionMetadataLike, d as ActionExecutionResult } from './webSpeechHost-CrTKADeb.js';
2
+ export { e as ActionDiagnose, f as ActionQueueMachine, g as AgentActionType, h as AppilotsClient, i as AppilotsEventHandler, j as AppilotsWebRuntime, k as AppilotsWebRuntimeOptions, l as ChatMessage, m as ChatSessionMachine, n as ChatSessionOptions, o as ChatSessionState, E as EscalationState, p as EscalationStrings, R as RateLimitedError, q as SpeechHost, r as SpeechStartOptions, s as SpeechState, t as WebNavigationAdapterOptions, u as WebNavigationState, v as WebRoute, w as WebScreenMetadata, x as buildPath, y as createWebSpeechHost, z as isSpeechHost, B as isWebSpeechSupported, D as matchRoute } from './webSpeechHost-CrTKADeb.js';
3
3
 
4
4
  type ActionPresentationState = 'pending' | 'running' | 'success' | 'failed';
5
5
 
@@ -1005,6 +1005,6 @@ declare function scrollToOffset(container: Element, offset: number): boolean;
1005
1005
  * (`X-Appilots-Sdk-Version`). Kept identical to package.json by the
1006
1006
  * release flow; `version.test.ts` fails if the two ever disagree.
1007
1007
  */
1008
- declare const SDK_VERSION = "0.2.0";
1008
+ declare const SDK_VERSION = "0.3.0";
1009
1009
 
1010
1010
  export { APPILOTS_CHAT_ATTR, APPILOTS_ID_ATTR, APPILOTS_ITEM_COUNT_ATTR, APPILOTS_ITEM_INDEX_ATTR, APPILOTS_ITEM_KEY_ATTR, APPILOTS_LIST_ID_ATTR, APPILOTS_LIST_ITEM_ATTR, APPILOTS_SENSITIVE_ATTR, APPILOTS_SKIP_ATTR, ActionExecutionResult, AgentAction, AgentPermissions, AppilotsEvent, type LoadingProbeResult, type LoadingSettleOptions, type LoadingSettleResult, type ResolveOptions, type ResolvedTarget, SDK_VERSION, type ScreenSettleOptions, type ScreenSettleResult, type ScreenSnapshot, type ScrollMetrics, type SettleProbes, type WalkDomOptions, type WebExecutorContext, WebNavigationAdapter, accessibleName, bestId, candidateIds, captureSnapshot, clickElement, describeAction, elementRole, executeAction, findListItemElements, findScrollContainer, focusElement, getRegisteredElement, hidesSubtree, humanizeError, isOccludedByModal, isVisible, longPressElement, modalCandidateLabels, normalizeLabelToId, parseSyntheticListItemId, primaryControlOf, probeLoadingState, readControlValue, readOwnText, readScrollMetrics, readToggleValue, registeredElements, resolveListItem, resolveTargetElement, routesBelongToSameFeature, screenDepartedBaseline, scrollIntoView, scrollToOffset, setControlValue, setToggleValue, stripComponentPrefix, waitForLoadingSettle, waitForScreenSettle, walkDom };