@appilots/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.
@@ -14,10 +14,20 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
14
14
  throw Error('Dynamic require of "' + x + '" is not supported');
15
15
  });
16
16
 
17
- // src/version.ts
18
- var SDK_VERSION = "0.1.0";
17
+ // ../shared/dist/chunk-43YQ52Q7.mjs
18
+ var SENSITIVE_FIELD_NAME_RE = /(\b|_|-)(password|senha|contrase[ñn]a|mot[\s_-]*de[\s_-]*passe|passwd|pwd|secret|token|api[\s_-]*key|access[\s_-]*key|private[\s_-]*key|cvv|cvc|cvn|cvc2|cid|pin(?:[\s_-]*code)?|otp|one[\s_-]*time[\s_-]*code|2fa|mfa|security[\s_-]*code|c[óo]digo[\s_-]*seguran[çc]a|c[óo]digo[\s_-]*verifica[çc][ãa]o|verification[\s_-]*code)(\b|_|-)/i;
19
+ function isSensitiveFieldName(id, label, placeholder, type) {
20
+ if (type === "password") return true;
21
+ for (const candidate of [id, label, placeholder]) {
22
+ if (typeof candidate === "string" && SENSITIVE_FIELD_NAME_RE.test(candidate)) {
23
+ return true;
24
+ }
25
+ }
26
+ return false;
27
+ }
19
28
 
20
- // src/services/AppilotsClient.ts
29
+ // ../client-core/dist/index.mjs
30
+ var SDK_VERSION = "0.1.0";
21
31
  var StreamTransportError = class extends Error {
22
32
  constructor(message) {
23
33
  super(message);
@@ -785,6 +795,591 @@ var AppilotsClient = class {
785
795
  };
786
796
  }
787
797
  };
798
+ var defaultLightTheme = {
799
+ colors: {
800
+ primary: "#6366f1",
801
+ secondary: "#8b5cf6",
802
+ background: "#ffffff",
803
+ surface: "#f3f4f6",
804
+ text: "#1f2937",
805
+ textSecondary: "#6b7280",
806
+ border: "#e5e7eb",
807
+ // NOTE (BACKLOG 4.2): success/warning/error used to have ZERO visual
808
+ // consumers — nothing read them, so ActionBreadcrumb's tones and the
809
+ // confirm card's destructive accents were hardcoded separately with
810
+ // their OWN hex values (#10B981/#EF4444/#9CA3AF-ish grays). Since no
811
+ // other UI in the SDK reads these three tokens, we picked these
812
+ // defaults to exactly match those pre-existing hardcoded values —
813
+ // wiring the tokens up to ActionBreadcrumb (see breadcrumbPresentation.ts)
814
+ // is now a no-op for anyone on the bundled default theme, while a
815
+ // custom theme's success/warning/error now actually do something.
816
+ success: "#10b981",
817
+ warning: "#9ca3af",
818
+ error: "#ef4444",
819
+ // Same value as `text` — split out so an app can diverge them, but
820
+ // any app that doesn't set these renders pixel-identical to before.
821
+ buttonText: "#1f2937",
822
+ bubbleText: "#1f2937",
823
+ userBubbleText: "#ffffff"
824
+ },
825
+ typography: {
826
+ fontFamily: "System",
827
+ fontSizeXs: 11,
828
+ fontSizeSm: 13,
829
+ fontSizeBase: 15,
830
+ fontSizeLg: 18
831
+ },
832
+ radii: {
833
+ sm: 8,
834
+ md: 12,
835
+ lg: 16
836
+ },
837
+ shadows: {
838
+ appearance: "light"
839
+ }
840
+ };
841
+ var defaultDarkTheme = {
842
+ colors: {
843
+ primary: "#818cf8",
844
+ secondary: "#a78bfa",
845
+ background: "#0f172a",
846
+ surface: "#1e293b",
847
+ text: "#f1f5f9",
848
+ textSecondary: "#94a3b8",
849
+ border: "#334155",
850
+ // Kept IDENTICAL to the light theme's success/warning/error (not the
851
+ // usual "lighter for dark bg" adjustment other tokens get) — the
852
+ // breadcrumb's tones were a fixed, theme-agnostic hardcoded palette
853
+ // before this token existed, rendering the SAME hex in light and dark
854
+ // mode. Diverging them here would change dark-mode breadcrumbs even
855
+ // though nothing in the token tree asked for that.
856
+ success: "#10b981",
857
+ warning: "#9ca3af",
858
+ error: "#ef4444",
859
+ buttonText: "#f1f5f9",
860
+ bubbleText: "#f1f5f9",
861
+ userBubbleText: "#ffffff"
862
+ },
863
+ typography: { ...defaultLightTheme.typography },
864
+ radii: { ...defaultLightTheme.radii },
865
+ shadows: { appearance: "dark" }
866
+ };
867
+ function mergeThemeTokens(base, partial) {
868
+ if (!partial) return base;
869
+ return {
870
+ colors: { ...base.colors, ...partial.colors ?? {} },
871
+ typography: { ...base.typography, ...partial.typography ?? {} },
872
+ radii: { ...base.radii, ...partial.radii ?? {} },
873
+ shadows: { ...base.shadows, ...partial.shadows ?? {} }
874
+ };
875
+ }
876
+ function resolveBaseTheme(mode, systemScheme) {
877
+ if (mode === "dark") return defaultDarkTheme;
878
+ if (mode === "light") return defaultLightTheme;
879
+ return systemScheme === "dark" ? defaultDarkTheme : defaultLightTheme;
880
+ }
881
+ var LIST_ITEM_TARGET_RE = /^list-\d+-item-\d+$/i;
882
+ 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;
883
+ function isListItemPressTarget(value) {
884
+ if (typeof value !== "string" || !value.trim()) return false;
885
+ return LIST_ITEM_TARGET_RE.test(value.trim());
886
+ }
887
+ function looksDestructiveActionLabel(value) {
888
+ if (typeof value !== "string" || !value.trim()) return false;
889
+ return DESTRUCTIVE_LABEL_RE.test(value.trim());
890
+ }
891
+ function actionPressTargetId(action) {
892
+ if (action.type !== "ui_interaction") return null;
893
+ const payload = action.payload;
894
+ const componentId = payload?.componentId;
895
+ if (typeof componentId === "string" && componentId.trim()) return componentId.trim();
896
+ const targetId = payload?.targetId;
897
+ if (typeof targetId === "string" && targetId.trim()) return targetId.trim();
898
+ return null;
899
+ }
900
+ function turnHasConfirmActions(actions) {
901
+ return actions.some((action) => action.type === "confirm");
902
+ }
903
+ function normalize(value) {
904
+ return value.normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[‘’]/g, "'").toLowerCase();
905
+ }
906
+ function detectLocaleFromUserTexts(texts) {
907
+ for (const raw of texts) {
908
+ const normalized = normalize(raw);
909
+ if (/[ãõáéíóúâêôç]/i.test(raw) || /\b(voce|voces|pra|assinatura|cancela|canela|segunda|certo|quais|tenho|pode|posso)\b/.test(
910
+ normalized
911
+ )) {
912
+ return "pt";
913
+ }
914
+ if (/[áéíóúñ¿¡]/i.test(raw) || /\b(cancela|segunda|suscripcion|puedo|cuales|hola)\b/.test(normalized)) {
915
+ return "es";
916
+ }
917
+ if (/[àâçéèêëîïôûùüÿœ]/i.test(raw) || /\b(annuler|deuxieme|abonnement|bonjour)\b/.test(normalized)) {
918
+ return "fr";
919
+ }
920
+ }
921
+ return "en";
922
+ }
923
+ var copy = {
924
+ pt: {
925
+ rateLimit: "O provedor de IA atingiu o limite de uso durante a automa\xE7\xE3o. Aguarde um momento e pe\xE7a para continuar, ou aumente o limite de tokens por minuto.",
926
+ invalidInput: "N\xE3o consegui continuar a automa\xE7\xE3o por um problema interno de sincroniza\xE7\xE3o. Pode tentar de novo ou fazer essa parte manualmente?",
927
+ generic: (detail) => `Perdi o fio da automa\xE7\xE3o (${detail}). Pode continuar manualmente ou me pedir de novo?`
928
+ },
929
+ es: {
930
+ rateLimit: "El proveedor de IA alcanz\xF3 su l\xEDmite de uso durante la automatizaci\xF3n. Espera un momento y p\xEDdeme continuar, o aumenta el l\xEDmite de tokens por minuto.",
931
+ invalidInput: "No pude continuar la automatizaci\xF3n por un problema interno de sincronizaci\xF3n. \xBFPuedes intentarlo de nuevo o hacer esta parte manualmente?",
932
+ generic: (detail) => `Perd\xED el hilo de la automatizaci\xF3n (${detail}). \xBFPuedes continuar manualmente o ped\xEDrmelo de nuevo?`
933
+ },
934
+ fr: {
935
+ rateLimit: "Le fournisseur d'IA a atteint sa limite d'utilisation pendant l'automatisation. Attendez un instant et demandez-moi de continuer, ou augmentez la limite de tokens par minute.",
936
+ invalidInput: "Je n'ai pas pu poursuivre l'automatisation \xE0 cause d'un probl\xE8me interne de synchronisation. Pouvez-vous r\xE9essayer ou faire cette \xE9tape manuellement ?",
937
+ generic: (detail) => `J'ai perdu le fil de l'automatisation (${detail}). Vous pouvez continuer manuellement ou me redemander ?`
938
+ },
939
+ en: {
940
+ rateLimit: "Your AI provider hit its rate limit during automation. Wait a moment and ask me to continue, or raise your TPM limit.",
941
+ invalidInput: "I could not continue the automation because of an internal sync issue. You can try again or take over manually.",
942
+ generic: (detail) => `I lost my footing during automation (${detail}). You can take over from here.`
943
+ }
944
+ };
945
+ function buildContinuationFailureMessage(rawError, recentUserTexts) {
946
+ const locale = detectLocaleFromUserTexts(recentUserTexts);
947
+ const strings = copy[locale] ?? copy.en;
948
+ if (/rate limit|tokens per min|tpm/i.test(rawError)) {
949
+ return strings.rateLimit;
950
+ }
951
+ if (/invalid input|validation_error|422/i.test(rawError)) {
952
+ return strings.invalidInput;
953
+ }
954
+ return strings.generic(rawError);
955
+ }
956
+ function metadataMatchesComponentId(metaId, componentId) {
957
+ const norm = (s) => s.toLowerCase().replace(/^el:(button|link|input|toggle|listitem)[:_-]/, "").replace(/^(btn-|btn_|button-|button_|link-|link_)/, "").trim();
958
+ const meta = norm(metaId);
959
+ const comp = norm(componentId);
960
+ if (!meta || !comp) return false;
961
+ return meta === comp;
962
+ }
963
+ function fingerprintAction(action, screen) {
964
+ const p = action.payload ?? {};
965
+ const scope = `@${screen ?? "?"}`;
966
+ switch (action.type) {
967
+ case "navigate":
968
+ return `navigate${scope}:${p.screenName ?? "?"}`;
969
+ case "form_fill": {
970
+ const fields = p.fields ?? [];
971
+ const ids = fields.map((f) => String(f?.fieldId ?? "?")).sort();
972
+ return `form_fill${scope}:${ids.join(",")}`;
973
+ }
974
+ case "ui_interaction":
975
+ return `ui_interaction${scope}:${p.action ?? "?"}:${p.componentId ?? p.targetId ?? "?"}`;
976
+ case "confirm":
977
+ return `confirm${scope}:${p.message ?? p.title ?? "?"}`;
978
+ default:
979
+ return `${action.type}${scope}:${JSON.stringify(p)}`;
980
+ }
981
+ }
982
+ function normalize2(s) {
983
+ return s.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]/g, "");
984
+ }
985
+ function matchScore(needle, hay) {
986
+ if (!needle || !hay) return 0;
987
+ if (needle === hay) return 100;
988
+ if (hay.startsWith(needle) || needle.startsWith(hay)) return 75;
989
+ if (hay.endsWith(needle) || needle.endsWith(hay)) return 60;
990
+ if (hay.includes(needle) || needle.includes(hay)) return 40;
991
+ return 0;
992
+ }
993
+ function isGenericSelectValue(value) {
994
+ if (value === void 0 || value === null || value === "") return true;
995
+ const normalized = normalize2(String(value));
996
+ if (!normalized) return true;
997
+ return /^(any|qualquer|random|aleatorio|aleatoria|auto|automatico|automatica|mock|mockado|mockada|mockados|mockadas|dummy|sample|exemplo|default|padrao|teste|test)$/.test(
998
+ normalized
999
+ );
1000
+ }
1001
+ var LIST_ORDINAL_RE = /^list-\d+-item-\d+$/i;
1002
+ function normalizeId(value) {
1003
+ return value.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase();
1004
+ }
1005
+ function isOptionalCosmeticTargetId(targetId) {
1006
+ if (typeof targetId !== "string" || !targetId.trim()) return false;
1007
+ const id = normalizeId(targetId);
1008
+ return /foto|photo|avatar|icone|icon|emoji|sheetaction|sheet-action|btn-foto/.test(id) || id.includes("photo-sheet");
1009
+ }
1010
+ function routeLooksLikeFormContext(route) {
1011
+ const haystack = normalizeId(route ?? "");
1012
+ return /create|edit|form|cadastr|register|novo|vehiclecreate|subscriptioncreate|vehicleedit|subscriptioncreate/.test(
1013
+ haystack
1014
+ );
1015
+ }
1016
+ function screenPathParts(screen) {
1017
+ if (!screen) return [];
1018
+ return screen.split("/").map((part) => part.trim()).filter(Boolean);
1019
+ }
1020
+ function isMisappliedListOrdinalOnForm(targetId, screen, activePath) {
1021
+ if (typeof targetId !== "string" || !LIST_ORDINAL_RE.test(targetId.trim())) {
1022
+ return false;
1023
+ }
1024
+ const routes = [...screenPathParts(screen), ...activePath ?? []];
1025
+ if (routes.length === 0) return routeLooksLikeFormContext(screen);
1026
+ return routes.some((route) => routeLooksLikeFormContext(route));
1027
+ }
1028
+ function isOptionalStepAutomationFailure(targetId, screen, activePath) {
1029
+ return isOptionalCosmeticTargetId(targetId) || isMisappliedListOrdinalOnForm(targetId, screen, activePath);
1030
+ }
1031
+ var OPTIONAL_STEP_AUTOMATION_HINT = "optional-step-automation-failed";
1032
+ var MAX_TRACE_ENTRIES = 200;
1033
+ var entries = [];
1034
+ var listeners = /* @__PURE__ */ new Set();
1035
+ var traceCounter = 0;
1036
+ function notify() {
1037
+ const snapshot = [...entries];
1038
+ listeners.forEach((listener) => listener(snapshot));
1039
+ }
1040
+ function append(entry) {
1041
+ entries.push(entry);
1042
+ if (entries.length > MAX_TRACE_ENTRIES) {
1043
+ entries.splice(0, entries.length - MAX_TRACE_ENTRIES);
1044
+ }
1045
+ notify();
1046
+ }
1047
+ function recordAppilotsDebugTrace(entry) {
1048
+ append({
1049
+ ...entry,
1050
+ id: entry.id ?? `trace_${++traceCounter}`
1051
+ });
1052
+ }
1053
+ function actionFromEvent(event) {
1054
+ const action = event.data?.action;
1055
+ if (action && typeof action === "object" && typeof action.id === "string") {
1056
+ return action;
1057
+ }
1058
+ return void 0;
1059
+ }
1060
+ function recordAppilotsEventTrace(event) {
1061
+ if (!event.type.startsWith("agent:action:")) return;
1062
+ const action = actionFromEvent(event);
1063
+ const actionId = action?.id || (typeof event.data?.actionId === "string" ? event.data.actionId : void 0);
1064
+ const actionType = action?.type || (typeof event.data?.actionType === "string" ? event.data.actionType : void 0);
1065
+ recordAppilotsDebugTrace({
1066
+ timestamp: event.timestamp,
1067
+ type: event.type,
1068
+ messageId: action?.messageId,
1069
+ actionId,
1070
+ actionType,
1071
+ status: event.type === "agent:action:start" ? "started" : event.type === "agent:action:complete" ? "completed" : "error",
1072
+ data: event.data
1073
+ });
1074
+ }
1075
+ function getAppilotsDebugTraces() {
1076
+ return [...entries];
1077
+ }
1078
+ function clearAppilotsDebugTraces() {
1079
+ entries.splice(0, entries.length);
1080
+ notify();
1081
+ }
1082
+ function subscribeAppilotsDebugTraces(listener) {
1083
+ listeners.add(listener);
1084
+ listener([...entries]);
1085
+ return () => {
1086
+ listeners.delete(listener);
1087
+ };
1088
+ }
1089
+ function describeAction(action) {
1090
+ const state = mapStatus(action.status);
1091
+ const label = labelFor(action, state);
1092
+ return { label, state };
1093
+ }
1094
+ function mapStatus(status) {
1095
+ switch (status) {
1096
+ case "pending":
1097
+ return "pending";
1098
+ case "executing":
1099
+ return "running";
1100
+ case "completed":
1101
+ return "success";
1102
+ case "failed":
1103
+ return "failed";
1104
+ default:
1105
+ return "pending";
1106
+ }
1107
+ }
1108
+ function labelFor(action, state) {
1109
+ if (state === "failed") {
1110
+ return failureLabel(action);
1111
+ }
1112
+ switch (action.type) {
1113
+ case "navigate":
1114
+ return navigateLabel(action, state);
1115
+ case "form_fill":
1116
+ return formFillLabel(action, state);
1117
+ case "ui_interaction":
1118
+ return uiInteractionLabel(action, state);
1119
+ case "scroll_list":
1120
+ return scrollListLabel(action, state);
1121
+ case "confirm":
1122
+ return confirmLabel(state);
1123
+ default:
1124
+ return genericLabel(action.type, state);
1125
+ }
1126
+ }
1127
+ function navigateLabel(action, state) {
1128
+ const screen = readString(action.payload, "screenName") || "a outra tela";
1129
+ switch (state) {
1130
+ case "pending":
1131
+ return `Vou navegar para ${screen}`;
1132
+ case "running":
1133
+ return `Navegando para ${screen}...`;
1134
+ case "success":
1135
+ return `Naveguei para ${screen}`;
1136
+ default:
1137
+ return `Navega\xE7\xE3o para ${screen}`;
1138
+ }
1139
+ }
1140
+ function formFillLabel(action, state) {
1141
+ const fields = readArray(action.payload, "fields");
1142
+ const summary = summariseFields(fields);
1143
+ switch (state) {
1144
+ case "pending":
1145
+ return summary ? `Vou preencher ${summary}` : "Vou preencher o formul\xE1rio";
1146
+ case "running":
1147
+ return summary ? `Preenchendo ${summary}...` : "Preenchendo formul\xE1rio...";
1148
+ case "success":
1149
+ return summary ? `Preenchi ${summary}` : "Preenchi o formul\xE1rio";
1150
+ default:
1151
+ return "Preenchimento do formul\xE1rio";
1152
+ }
1153
+ }
1154
+ function uiInteractionLabel(action, state) {
1155
+ const verbBase = uiVerb(readString(action.payload, "action"));
1156
+ const target = humanActionTarget(action.payload);
1157
+ const where = target ? ` em ${target}` : "";
1158
+ switch (state) {
1159
+ case "pending":
1160
+ return `Vou ${verbBase.infinitive}${where}`;
1161
+ case "running":
1162
+ return `${verbBase.gerund}${where}...`;
1163
+ case "success":
1164
+ return `${verbBase.past}${where}`;
1165
+ default:
1166
+ return `Intera\xE7\xE3o${where}`;
1167
+ }
1168
+ }
1169
+ function scrollListLabel(action, state) {
1170
+ const payload = action.payload;
1171
+ const toIndex = typeof payload?.toIndex === "number" ? payload.toIndex : void 0;
1172
+ const direction = payload?.direction === "up" ? "para cima" : "para baixo";
1173
+ const target = toIndex !== void 0 ? `at\xE9 o item ${toIndex}` : direction;
1174
+ switch (state) {
1175
+ case "pending":
1176
+ return `Vou rolar a lista ${target}`;
1177
+ case "running":
1178
+ return `Rolando a lista ${target}...`;
1179
+ case "success":
1180
+ return `Rolei a lista ${target}`;
1181
+ default:
1182
+ return "Rolagem da lista";
1183
+ }
1184
+ }
1185
+ function confirmLabel(state) {
1186
+ switch (state) {
1187
+ case "pending":
1188
+ case "running":
1189
+ return "Aguardando confirma\xE7\xE3o";
1190
+ case "success":
1191
+ return "Voc\xEA confirmou";
1192
+ case "failed":
1193
+ return "Confirma\xE7\xE3o cancelada";
1194
+ default:
1195
+ return "Confirma\xE7\xE3o";
1196
+ }
1197
+ }
1198
+ function genericLabel(type, state) {
1199
+ switch (state) {
1200
+ case "pending":
1201
+ return `Vou executar ${type}`;
1202
+ case "running":
1203
+ return `Executando ${type}...`;
1204
+ case "success":
1205
+ return `Executei ${type}`;
1206
+ default:
1207
+ return type;
1208
+ }
1209
+ }
1210
+ function failureLabel(action) {
1211
+ const cause = humanizeError(action.error);
1212
+ const head = failureHead(action);
1213
+ return cause ? `${head} (${cause})` : head;
1214
+ }
1215
+ function failureHead(action) {
1216
+ switch (action.type) {
1217
+ case "navigate": {
1218
+ const screen = readString(action.payload, "screenName") || "a tela";
1219
+ return `N\xE3o consegui navegar para ${screen}`;
1220
+ }
1221
+ case "form_fill":
1222
+ return "N\xE3o consegui preencher o formul\xE1rio";
1223
+ case "ui_interaction": {
1224
+ const verb = uiVerb(readString(action.payload, "action"));
1225
+ const target = humanComponentId(
1226
+ readString(action.payload, "componentId") || readString(action.payload, "targetId")
1227
+ );
1228
+ return target ? `N\xE3o consegui ${verb.infinitive} em ${target}` : `N\xE3o consegui ${verb.infinitive}`;
1229
+ }
1230
+ case "scroll_list":
1231
+ return "N\xE3o consegui rolar a lista";
1232
+ case "confirm":
1233
+ return "Voc\xEA cancelou";
1234
+ default:
1235
+ return `N\xE3o consegui executar ${action.type}`;
1236
+ }
1237
+ }
1238
+ var TECHNICAL_PATTERNS = [
1239
+ /\bat\s+\S+\s*\(/,
1240
+ // stack trace frame
1241
+ /TypeError|ReferenceError|SyntaxError|RangeError/i,
1242
+ /HTTP\s*[45]\d{2}/i,
1243
+ /^\s*\{[\s\S]*\}\s*$/,
1244
+ // JSON dump
1245
+ /undefined is not a function/i,
1246
+ /Cannot read propert/i
1247
+ ];
1248
+ var FRIENDLY_REWRITES = [
1249
+ [/rejected by user/i, "cancelado pelo usu\xE1rio"],
1250
+ [/component '([^']+)' not found/i, "componente $1 n\xE3o encontrado"],
1251
+ [/field '([^']+)' not found/i, "campo $1 n\xE3o encontrado"],
1252
+ [/screen '([^']+)' not registered/i, "tela $1 n\xE3o registrada"],
1253
+ [/permission denied/i, "sem permiss\xE3o"],
1254
+ [/timeout|timed out/i, "tempo esgotado"],
1255
+ [/network/i, "falha de rede"]
1256
+ ];
1257
+ var MAX_REASON_LEN = 80;
1258
+ function humanizeError(raw, _action) {
1259
+ if (!raw) return void 0;
1260
+ const trimmed = String(raw).trim();
1261
+ if (!trimmed) return void 0;
1262
+ for (const [pattern, replacement] of FRIENDLY_REWRITES) {
1263
+ if (pattern.test(trimmed)) {
1264
+ return finalize(trimmed.replace(pattern, replacement));
1265
+ }
1266
+ }
1267
+ if (TECHNICAL_PATTERNS.some((p) => p.test(trimmed))) {
1268
+ return "algo deu errado";
1269
+ }
1270
+ if (trimmed.length > MAX_REASON_LEN) {
1271
+ return "algo deu errado";
1272
+ }
1273
+ return finalize(trimmed);
1274
+ }
1275
+ function finalize(text) {
1276
+ let out = text.trim();
1277
+ if (out.length > MAX_REASON_LEN) out = out.slice(0, MAX_REASON_LEN - 1).trimEnd() + "\u2026";
1278
+ if (out.length > 0) out = out[0].toLowerCase() + out.slice(1);
1279
+ return out;
1280
+ }
1281
+ function uiVerb(raw) {
1282
+ switch ((raw ?? "press").toLowerCase()) {
1283
+ case "press":
1284
+ case "tap":
1285
+ case "click":
1286
+ return { infinitive: "clicar", gerund: "Clicando", past: "Cliquei" };
1287
+ case "longpress":
1288
+ case "long_press":
1289
+ return { infinitive: "pressionar", gerund: "Pressionando", past: "Pressionei" };
1290
+ case "scroll":
1291
+ case "scroll_to":
1292
+ return { infinitive: "rolar", gerund: "Rolando", past: "Rolei" };
1293
+ case "focus":
1294
+ return { infinitive: "focar", gerund: "Focando", past: "Foquei" };
1295
+ default:
1296
+ return { infinitive: "interagir", gerund: "Interagindo", past: "Interagi" };
1297
+ }
1298
+ }
1299
+ function summariseFields(fields) {
1300
+ if (!Array.isArray(fields) || fields.length === 0) return void 0;
1301
+ const parts = [];
1302
+ const visible = fields.slice(0, 3);
1303
+ for (const f of visible) {
1304
+ if (!f || typeof f !== "object") continue;
1305
+ const obj = f;
1306
+ const name = humanFieldName(obj.label, obj.fieldId);
1307
+ if (!name) continue;
1308
+ const fieldIdStr = typeof obj.fieldId === "string" ? obj.fieldId : void 0;
1309
+ const labelStr = typeof obj.label === "string" ? obj.label : void 0;
1310
+ const fieldTypeStr = typeof obj.fieldType === "string" ? obj.fieldType : void 0;
1311
+ const sensitive = isSensitiveFieldName(fieldIdStr, labelStr, void 0, fieldTypeStr);
1312
+ if (sensitive) {
1313
+ parts.push(`${name}=\u2022\u2022\u2022\u2022`);
1314
+ continue;
1315
+ }
1316
+ const value = formatFieldValue(obj.value);
1317
+ parts.push(value !== void 0 ? `${name}=${value}` : name);
1318
+ }
1319
+ if (parts.length === 0) return void 0;
1320
+ const extra = fields.length - parts.length;
1321
+ return extra > 0 ? `${parts.join(", ")} +${extra}` : parts.join(", ");
1322
+ }
1323
+ function formatFieldValue(value) {
1324
+ if (value === void 0 || value === null || value === "") return void 0;
1325
+ if (typeof value === "string") {
1326
+ const v = value.length > 18 ? `${value.slice(0, 17)}\u2026` : value;
1327
+ return `"${v}"`;
1328
+ }
1329
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
1330
+ return void 0;
1331
+ }
1332
+ function humanActionTarget(payload) {
1333
+ if (!payload || typeof payload !== "object") return "";
1334
+ const record = payload;
1335
+ const friendly = readFriendlyString(record, "label") || readFriendlyString(record, "actionDescription") || readFriendlyString(record, "title") || readFriendlyString(record, "name");
1336
+ if (friendly) return friendly;
1337
+ return humanComponentId(
1338
+ readString(payload, "componentId") || readString(payload, "targetId")
1339
+ );
1340
+ }
1341
+ function humanFieldName(label, fieldId) {
1342
+ if (typeof label === "string" && label.trim()) return label.trim();
1343
+ if (typeof fieldId !== "string" || isTechnicalIdentifier(fieldId)) return void 0;
1344
+ return humanComponentId(fieldId) || void 0;
1345
+ }
1346
+ function readFriendlyString(record, key) {
1347
+ const value = record[key];
1348
+ if (typeof value !== "string") return "";
1349
+ const trimmed = value.trim();
1350
+ if (!trimmed || isTechnicalIdentifier(trimmed)) return "";
1351
+ return trimmed;
1352
+ }
1353
+ function humanComponentId(id) {
1354
+ if (!id) return "";
1355
+ if (isTechnicalIdentifier(id)) return "";
1356
+ const cleaned = id.replace(/^(btn-|btn_|button-|component-)/i, "").replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[-_]+/g, " ").trim();
1357
+ if (!cleaned) return "";
1358
+ return cleaned[0].toUpperCase() + cleaned.slice(1);
1359
+ }
1360
+ function isTechnicalIdentifier(value) {
1361
+ const raw = value.trim();
1362
+ if (!raw) return false;
1363
+ if (/^el:/i.test(raw)) return true;
1364
+ if (/^list-\d+-item-\d+$/i.test(raw)) return true;
1365
+ if (/(testid|test-id|accessibilityid|accessibility-id|automationid|automation-id)/i.test(raw)) {
1366
+ return true;
1367
+ }
1368
+ if (/^[a-z]+:[^ ]+:[^ ]+/i.test(raw)) return true;
1369
+ if (/^[A-Za-z][\w-]*:[^\s]+$/i.test(raw)) return true;
1370
+ if (/^[a-z]+(?:[-_][a-z]+)*[-_][a-z0-9]{5,}$/i.test(raw)) return true;
1371
+ return false;
1372
+ }
1373
+ function readString(payload, key) {
1374
+ if (!payload || typeof payload !== "object") return "";
1375
+ const v = payload[key];
1376
+ return typeof v === "string" ? v : "";
1377
+ }
1378
+ function readArray(payload, key) {
1379
+ if (!payload || typeof payload !== "object") return [];
1380
+ const v = payload[key];
1381
+ return Array.isArray(v) ? v : [];
1382
+ }
788
1383
 
789
1384
  // src/registry/ComponentRegistry.ts
790
1385
  var ComponentRegistryImpl = class {
@@ -1018,7 +1613,7 @@ function getDefaultRegistry() {
1018
1613
  }
1019
1614
 
1020
1615
  // src/auto/idExtraction.ts
1021
- function normalizeId(raw) {
1616
+ function normalizeId2(raw) {
1022
1617
  return raw.toLowerCase().normalize("NFD").replace(/[̀-ͯ]/g, "").replace(/^(input-|btn-|toggle-|switch-)/, "").replace(/[^a-z0-9\s-_]/g, "").trim().replace(/[-_\s]+(.)/g, (_, c) => c.toUpperCase()).replace(/[-_\s]+$/, "");
1023
1618
  }
1024
1619
  function deriveSemanticInputId(props) {
@@ -1066,7 +1661,7 @@ function sectionListFlatIndex(sections, section, localIndex) {
1066
1661
  function extractId(props) {
1067
1662
  const raw = props?.testID ?? props?.nativeID ?? props?.id ?? props?.accessibilityLabel ?? props?.name ?? props?.placeholder ?? (typeof props?.autoComplete === "string" && props.autoComplete !== "off" ? props.autoComplete : void 0);
1068
1663
  if (raw && typeof raw === "string") {
1069
- const normalized = normalizeId(raw);
1664
+ const normalized = normalizeId2(raw);
1070
1665
  if (normalized && normalized.length > 0) {
1071
1666
  console.log(`[Appilots] extractId: raw="${raw}" \u2192 normalized="${normalized}"`);
1072
1667
  return normalized;
@@ -1217,7 +1812,7 @@ function componentDisplayName(type) {
1217
1812
  function extractListId(props, componentName) {
1218
1813
  const raw = props?.appilotsListId ?? props?.testID ?? props?.nativeID ?? props?.id ?? props?.accessibilityLabel ?? props?.name;
1219
1814
  if (typeof raw === "string" && raw.trim().length > 0) {
1220
- const normalized = normalizeId(raw);
1815
+ const normalized = normalizeId2(raw);
1221
1816
  if (normalized) return normalized;
1222
1817
  }
1223
1818
  _generatedListIdCounter += 1;
@@ -1647,65 +2242,6 @@ function getGlobalConfig() {
1647
2242
  return _globalConfig;
1648
2243
  }
1649
2244
 
1650
- // src/debug/actionTraceStore.ts
1651
- var MAX_TRACE_ENTRIES = 200;
1652
- var entries = [];
1653
- var listeners = /* @__PURE__ */ new Set();
1654
- var traceCounter = 0;
1655
- function notify() {
1656
- const snapshot = [...entries];
1657
- listeners.forEach((listener) => listener(snapshot));
1658
- }
1659
- function append(entry) {
1660
- entries.push(entry);
1661
- if (entries.length > MAX_TRACE_ENTRIES) {
1662
- entries.splice(0, entries.length - MAX_TRACE_ENTRIES);
1663
- }
1664
- notify();
1665
- }
1666
- function recordAppilotsDebugTrace(entry) {
1667
- append({
1668
- ...entry,
1669
- id: entry.id ?? `trace_${++traceCounter}`
1670
- });
1671
- }
1672
- function actionFromEvent(event) {
1673
- const action = event.data?.action;
1674
- if (action && typeof action === "object" && typeof action.id === "string") {
1675
- return action;
1676
- }
1677
- return void 0;
1678
- }
1679
- function recordAppilotsEventTrace(event) {
1680
- if (!event.type.startsWith("agent:action:")) return;
1681
- const action = actionFromEvent(event);
1682
- const actionId = action?.id || (typeof event.data?.actionId === "string" ? event.data.actionId : void 0);
1683
- const actionType = action?.type || (typeof event.data?.actionType === "string" ? event.data.actionType : void 0);
1684
- recordAppilotsDebugTrace({
1685
- timestamp: event.timestamp,
1686
- type: event.type,
1687
- messageId: action?.messageId,
1688
- actionId,
1689
- actionType,
1690
- status: event.type === "agent:action:start" ? "started" : event.type === "agent:action:complete" ? "completed" : "error",
1691
- data: event.data
1692
- });
1693
- }
1694
- function getAppilotsDebugTraces() {
1695
- return [...entries];
1696
- }
1697
- function clearAppilotsDebugTraces() {
1698
- entries.splice(0, entries.length);
1699
- notify();
1700
- }
1701
- function subscribeAppilotsDebugTraces(listener) {
1702
- listeners.add(listener);
1703
- listener([...entries]);
1704
- return () => {
1705
- listeners.delete(listener);
1706
- };
1707
- }
1708
-
1709
2245
  // src/introspection/fiberRoot.ts
1710
2246
  var _fiberRoot = null;
1711
2247
  function setFiberRoot(fiber) {
@@ -2354,19 +2890,26 @@ function clearScreenRegistry() {
2354
2890
  exports.AppilotsClient = AppilotsClient;
2355
2891
  exports.AppilotsProvider = AppilotsProvider;
2356
2892
  exports.AppilotsRegistryProvider = AppilotsRegistryProvider;
2893
+ exports.OPTIONAL_STEP_AUTOMATION_HINT = OPTIONAL_STEP_AUTOMATION_HINT;
2357
2894
  exports.SDK_VERSION = SDK_VERSION;
2358
2895
  exports.StreamAbortError = StreamAbortError;
2359
2896
  exports.StreamTransportError = StreamTransportError;
2360
2897
  exports._patchJsxRuntimes = _patchJsxRuntimes;
2898
+ exports.actionPressTargetId = actionPressTargetId;
2361
2899
  exports.appilotsDebugWarn = appilotsDebugWarn;
2900
+ exports.buildContinuationFailureMessage = buildContinuationFailureMessage;
2362
2901
  exports.clearAppilotsDebugTraces = clearAppilotsDebugTraces;
2363
2902
  exports.clearScreenRegistry = clearScreenRegistry;
2364
2903
  exports.componentRegistry = componentRegistry;
2365
2904
  exports.createComponentRegistry = createComponentRegistry;
2366
2905
  exports.createElementRegistry = createElementRegistry;
2367
2906
  exports.createListRegistry = createListRegistry;
2907
+ exports.defaultDarkTheme = defaultDarkTheme;
2908
+ exports.defaultLightTheme = defaultLightTheme;
2909
+ exports.describeAction = describeAction;
2368
2910
  exports.elementRegistry = elementRegistry;
2369
2911
  exports.enableAppilotsAutoTracking = enableAppilotsAutoTracking;
2912
+ exports.fingerprintAction = fingerprintAction;
2370
2913
  exports.getActiveRouteNames = getActiveRouteNames;
2371
2914
  exports.getAllScreens = getAllScreens;
2372
2915
  exports.getAppilotsDebugTraces = getAppilotsDebugTraces;
@@ -2378,17 +2921,28 @@ exports.getGlobalConfig = getGlobalConfig;
2378
2921
  exports.getNavigationRef = getNavigationRef;
2379
2922
  exports.getNavigationStateSnapshot = getNavigationStateSnapshot;
2380
2923
  exports.getScreenMetadata = getScreenMetadata;
2924
+ exports.humanizeError = humanizeError;
2381
2925
  exports.initAppilots = initAppilots;
2382
2926
  exports.isAutoTrackingEnabled = isAutoTrackingEnabled;
2927
+ exports.isGenericSelectValue = isGenericSelectValue;
2928
+ exports.isListItemPressTarget = isListItemPressTarget;
2929
+ exports.isOptionalStepAutomationFailure = isOptionalStepAutomationFailure;
2383
2930
  exports.listRegistry = listRegistry;
2931
+ exports.looksDestructiveActionLabel = looksDestructiveActionLabel;
2932
+ exports.matchScore = matchScore;
2933
+ exports.mergeThemeTokens = mergeThemeTokens;
2934
+ exports.metadataMatchesComponentId = metadataMatchesComponentId;
2935
+ exports.normalize2 = normalize2;
2384
2936
  exports.probeLoadingState = probeLoadingState;
2385
2937
  exports.recordAppilotsDebugTrace = recordAppilotsDebugTrace;
2386
2938
  exports.registerScreen = registerScreen;
2939
+ exports.resolveBaseTheme = resolveBaseTheme;
2387
2940
  exports.routesBelongToSameFeature = routesBelongToSameFeature;
2388
2941
  exports.screenDepartedBaseline = screenDepartedBaseline;
2389
2942
  exports.setCurrentScreen = setCurrentScreen;
2390
2943
  exports.setNavigationRef = setNavigationRef;
2391
2944
  exports.subscribeAppilotsDebugTraces = subscribeAppilotsDebugTraces;
2945
+ exports.turnHasConfirmActions = turnHasConfirmActions;
2392
2946
  exports.useAppilotsContext = useAppilotsContext;
2393
2947
  exports.useResolvedRegistry = useResolvedRegistry;
2394
2948
  exports.waitForLoadingSettle = waitForLoadingSettle;