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