@nuanu-ai/agentbrowse 0.2.7 → 0.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. package/README.md +36 -8
  2. package/dist/agentpay-stagehand-llm.d.ts.map +1 -1
  3. package/dist/agentpay-stagehand-llm.js +5 -1
  4. package/dist/commands/act.d.ts +6 -2
  5. package/dist/commands/act.d.ts.map +1 -1
  6. package/dist/commands/act.js +840 -55
  7. package/dist/commands/act.test-harness.d.ts +19 -0
  8. package/dist/commands/act.test-harness.d.ts.map +1 -0
  9. package/dist/commands/act.test-harness.js +245 -0
  10. package/dist/commands/action-acceptance.d.ts +90 -0
  11. package/dist/commands/action-acceptance.d.ts.map +1 -0
  12. package/dist/commands/action-acceptance.js +1411 -0
  13. package/dist/commands/action-artifacts.d.ts +33 -0
  14. package/dist/commands/action-artifacts.d.ts.map +1 -0
  15. package/dist/commands/action-artifacts.js +104 -0
  16. package/dist/commands/action-execution-guards.d.ts +5 -0
  17. package/dist/commands/action-execution-guards.d.ts.map +1 -0
  18. package/dist/commands/action-execution-guards.js +3 -0
  19. package/dist/commands/action-executor-helpers.d.ts +21 -0
  20. package/dist/commands/action-executor-helpers.d.ts.map +1 -0
  21. package/dist/commands/action-executor-helpers.js +242 -0
  22. package/dist/commands/action-executor.d.ts +12 -0
  23. package/dist/commands/action-executor.d.ts.map +1 -0
  24. package/dist/commands/action-executor.js +45 -0
  25. package/dist/commands/action-fallbacks.d.ts +6 -0
  26. package/dist/commands/action-fallbacks.d.ts.map +1 -0
  27. package/dist/commands/action-fallbacks.js +43 -0
  28. package/dist/commands/action-value-projection.d.ts +32 -0
  29. package/dist/commands/action-value-projection.d.ts.map +1 -0
  30. package/dist/commands/action-value-projection.js +151 -0
  31. package/dist/commands/browse-actions.d.ts +4 -0
  32. package/dist/commands/browse-actions.d.ts.map +1 -0
  33. package/dist/commands/browse-actions.js +4 -0
  34. package/dist/commands/captcha-solve.d.ts.map +1 -1
  35. package/dist/commands/captcha-solve.js +13 -3
  36. package/dist/commands/click-action-executor.d.ts +10 -0
  37. package/dist/commands/click-action-executor.d.ts.map +1 -0
  38. package/dist/commands/click-action-executor.js +68 -0
  39. package/dist/commands/create-intent.d.ts +6 -0
  40. package/dist/commands/create-intent.d.ts.map +1 -0
  41. package/dist/commands/create-intent.js +75 -0
  42. package/dist/commands/datepicker-action-executor.d.ts +12 -0
  43. package/dist/commands/datepicker-action-executor.d.ts.map +1 -0
  44. package/dist/commands/datepicker-action-executor.js +218 -0
  45. package/dist/commands/descriptor-validation.d.ts +27 -0
  46. package/dist/commands/descriptor-validation.d.ts.map +1 -0
  47. package/dist/commands/descriptor-validation.js +333 -0
  48. package/dist/commands/extract-scope-resolution.d.ts +20 -0
  49. package/dist/commands/extract-scope-resolution.d.ts.map +1 -0
  50. package/dist/commands/extract-scope-resolution.js +100 -0
  51. package/dist/commands/extract-stagehand-executor.d.ts +17 -0
  52. package/dist/commands/extract-stagehand-executor.d.ts.map +1 -0
  53. package/dist/commands/extract-stagehand-executor.js +18 -0
  54. package/dist/commands/extract.d.ts +3 -2
  55. package/dist/commands/extract.d.ts.map +1 -1
  56. package/dist/commands/extract.js +256 -39
  57. package/dist/commands/fill-secret.d.ts +7 -0
  58. package/dist/commands/fill-secret.d.ts.map +1 -0
  59. package/dist/commands/fill-secret.js +371 -0
  60. package/dist/commands/get-secrets-catalog.d.ts +6 -0
  61. package/dist/commands/get-secrets-catalog.d.ts.map +1 -0
  62. package/dist/commands/get-secrets-catalog.js +23 -0
  63. package/dist/commands/launch.d.ts.map +1 -1
  64. package/dist/commands/launch.js +41 -7
  65. package/dist/commands/navigate.d.ts +2 -1
  66. package/dist/commands/navigate.d.ts.map +1 -1
  67. package/dist/commands/navigate.js +49 -12
  68. package/dist/commands/observe-inventory.d.ts +109 -0
  69. package/dist/commands/observe-inventory.d.ts.map +1 -0
  70. package/dist/commands/observe-inventory.js +2837 -0
  71. package/dist/commands/observe-persistence.d.ts +14 -0
  72. package/dist/commands/observe-persistence.d.ts.map +1 -0
  73. package/dist/commands/observe-persistence.js +170 -0
  74. package/dist/commands/observe-projection.d.ts +84 -0
  75. package/dist/commands/observe-projection.d.ts.map +1 -0
  76. package/dist/commands/observe-projection.js +140 -0
  77. package/dist/commands/observe-protected.d.ts +5 -0
  78. package/dist/commands/observe-protected.d.ts.map +1 -0
  79. package/dist/commands/observe-protected.js +18 -0
  80. package/dist/commands/observe-semantics.d.ts +10 -0
  81. package/dist/commands/observe-semantics.d.ts.map +1 -0
  82. package/dist/commands/observe-semantics.js +338 -0
  83. package/dist/commands/observe-stagehand.d.ts +48 -0
  84. package/dist/commands/observe-stagehand.d.ts.map +1 -0
  85. package/dist/commands/observe-stagehand.js +105 -0
  86. package/dist/commands/observe-surfaces.d.ts +9 -0
  87. package/dist/commands/observe-surfaces.d.ts.map +1 -0
  88. package/dist/commands/observe-surfaces.js +195 -0
  89. package/dist/commands/observe.d.ts +47 -1
  90. package/dist/commands/observe.d.ts.map +1 -1
  91. package/dist/commands/observe.js +173 -20
  92. package/dist/commands/observe.test-harness.d.ts +67 -0
  93. package/dist/commands/observe.test-harness.d.ts.map +1 -0
  94. package/dist/commands/observe.test-harness.js +107 -0
  95. package/dist/commands/poll-intent.d.ts +6 -0
  96. package/dist/commands/poll-intent.d.ts.map +1 -0
  97. package/dist/commands/poll-intent.js +57 -0
  98. package/dist/commands/screenshot.d.ts +2 -1
  99. package/dist/commands/screenshot.d.ts.map +1 -1
  100. package/dist/commands/screenshot.js +44 -12
  101. package/dist/commands/select-action-executor.d.ts +10 -0
  102. package/dist/commands/select-action-executor.d.ts.map +1 -0
  103. package/dist/commands/select-action-executor.js +91 -0
  104. package/dist/commands/semantic-observe.d.ts +24 -0
  105. package/dist/commands/semantic-observe.d.ts.map +1 -0
  106. package/dist/commands/semantic-observe.js +344 -0
  107. package/dist/commands/status.d.ts.map +1 -1
  108. package/dist/commands/status.js +75 -2
  109. package/dist/commands/structured-grid-action-executor.d.ts +3 -0
  110. package/dist/commands/structured-grid-action-executor.d.ts.map +1 -0
  111. package/dist/commands/structured-grid-action-executor.js +4 -0
  112. package/dist/commands/target-resolution.d.ts +4 -0
  113. package/dist/commands/target-resolution.d.ts.map +1 -0
  114. package/dist/commands/target-resolution.js +33 -0
  115. package/dist/commands/text-input-action-executor.d.ts +5 -0
  116. package/dist/commands/text-input-action-executor.d.ts.map +1 -0
  117. package/dist/commands/text-input-action-executor.js +116 -0
  118. package/dist/commands/user-actionable.d.ts +4 -0
  119. package/dist/commands/user-actionable.d.ts.map +1 -0
  120. package/dist/commands/user-actionable.js +95 -0
  121. package/dist/control-semantics.d.ts +29 -0
  122. package/dist/control-semantics.d.ts.map +1 -0
  123. package/dist/control-semantics.js +299 -0
  124. package/dist/index.d.ts.map +1 -1
  125. package/dist/index.js +95 -32
  126. package/dist/output.d.ts +14 -2
  127. package/dist/output.d.ts.map +1 -1
  128. package/dist/output.js +17 -29
  129. package/dist/playwright-runtime.d.ts +35 -0
  130. package/dist/playwright-runtime.d.ts.map +1 -0
  131. package/dist/playwright-runtime.js +224 -0
  132. package/dist/runtime-resolution.d.ts +9 -0
  133. package/dist/runtime-resolution.d.ts.map +1 -0
  134. package/dist/runtime-resolution.js +19 -0
  135. package/dist/runtime-state.d.ts +217 -0
  136. package/dist/runtime-state.d.ts.map +1 -0
  137. package/dist/runtime-state.js +629 -0
  138. package/dist/secrets/backend.d.ts +32 -0
  139. package/dist/secrets/backend.d.ts.map +1 -0
  140. package/dist/secrets/backend.js +169 -0
  141. package/dist/secrets/catalog-applicability.d.ts +5 -0
  142. package/dist/secrets/catalog-applicability.d.ts.map +1 -0
  143. package/dist/secrets/catalog-applicability.js +59 -0
  144. package/dist/secrets/catalog-sync.d.ts +14 -0
  145. package/dist/secrets/catalog-sync.d.ts.map +1 -0
  146. package/dist/secrets/catalog-sync.js +35 -0
  147. package/dist/secrets/field-policy.d.ts +3 -0
  148. package/dist/secrets/field-policy.d.ts.map +1 -0
  149. package/dist/secrets/field-policy.js +3 -0
  150. package/dist/secrets/fill-ordering.d.ts +11 -0
  151. package/dist/secrets/fill-ordering.d.ts.map +1 -0
  152. package/dist/secrets/fill-ordering.js +44 -0
  153. package/dist/secrets/form-matcher.d.ts +60 -0
  154. package/dist/secrets/form-matcher.d.ts.map +1 -0
  155. package/dist/secrets/form-matcher.js +596 -0
  156. package/dist/secrets/intent-output.d.ts +11 -0
  157. package/dist/secrets/intent-output.d.ts.map +1 -0
  158. package/dist/secrets/intent-output.js +64 -0
  159. package/dist/secrets/mock-agentpay-backend.d.ts +13 -0
  160. package/dist/secrets/mock-agentpay-backend.d.ts.map +1 -0
  161. package/dist/secrets/mock-agentpay-backend.js +87 -0
  162. package/dist/secrets/mock-agentpay-cabinet.d.ts +43 -0
  163. package/dist/secrets/mock-agentpay-cabinet.d.ts.map +1 -0
  164. package/dist/secrets/mock-agentpay-cabinet.js +195 -0
  165. package/dist/secrets/protected-artifact-guard.d.ts +25 -0
  166. package/dist/secrets/protected-artifact-guard.d.ts.map +1 -0
  167. package/dist/secrets/protected-artifact-guard.js +26 -0
  168. package/dist/secrets/protected-bindings.d.ts +10 -0
  169. package/dist/secrets/protected-bindings.d.ts.map +1 -0
  170. package/dist/secrets/protected-bindings.js +17 -0
  171. package/dist/secrets/protected-field-values.d.ts +13 -0
  172. package/dist/secrets/protected-field-values.d.ts.map +1 -0
  173. package/dist/secrets/protected-field-values.js +100 -0
  174. package/dist/secrets/protected-fill.d.ts +47 -0
  175. package/dist/secrets/protected-fill.d.ts.map +1 -0
  176. package/dist/secrets/protected-fill.js +512 -0
  177. package/dist/secrets/types.d.ts +84 -0
  178. package/dist/secrets/types.d.ts.map +1 -0
  179. package/dist/secrets/types.js +27 -0
  180. package/dist/session.d.ts +22 -0
  181. package/dist/session.d.ts.map +1 -1
  182. package/dist/session.js +74 -2
  183. package/dist/solver/browser-launcher.d.ts.map +1 -1
  184. package/dist/solver/browser-launcher.js +6 -3
  185. package/dist/stagehand-runtime.d.ts +4 -0
  186. package/dist/stagehand-runtime.d.ts.map +1 -0
  187. package/dist/stagehand-runtime.js +10 -0
  188. package/dist/stagehand.d.ts +0 -5
  189. package/dist/stagehand.d.ts.map +1 -1
  190. package/dist/stagehand.js +0 -6
  191. package/package.json +5 -2
@@ -0,0 +1,87 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { homedir } from 'node:os';
3
+ import { join, resolve } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { normalizeCatalogLookupValue, storedSecretAppliesToHost, } from './catalog-applicability.js';
6
+ const DEFAULT_MOCK_SECRET_STORE_PATH = fileURLToPath(new URL('./mock-agentpay-stored-secrets.json', import.meta.url));
7
+ const USER_MOCK_SECRET_STORE_PATH = join(homedir(), '.agentpay', 'mock-stored-secrets.json');
8
+ let testMockSecretStorePath;
9
+ export function setMockSecretStorePathForTests(storePath) {
10
+ testMockSecretStorePath = storePath ? resolve(storePath) : undefined;
11
+ }
12
+ function loadMockStoredSecretRecords() {
13
+ const storePath = testMockSecretStorePath
14
+ ? testMockSecretStorePath
15
+ : existsSync(USER_MOCK_SECRET_STORE_PATH)
16
+ ? USER_MOCK_SECRET_STORE_PATH
17
+ : DEFAULT_MOCK_SECRET_STORE_PATH;
18
+ return JSON.parse(readFileSync(storePath, 'utf-8'));
19
+ }
20
+ export function normalizeMerchantKey(value) {
21
+ return normalizeCatalogLookupValue(value);
22
+ }
23
+ export function resolveHostFromInput(value) {
24
+ const trimmed = value.trim();
25
+ if (trimmed.length === 0) {
26
+ throw new Error('mock_secret_catalog_host_required');
27
+ }
28
+ try {
29
+ const parsed = new URL(trimmed);
30
+ if (!parsed.hostname) {
31
+ throw new Error('missing_hostname');
32
+ }
33
+ return normalizeCatalogLookupValue(parsed.hostname);
34
+ }
35
+ catch {
36
+ return normalizeCatalogLookupValue(trimmed);
37
+ }
38
+ }
39
+ function preferenceScore(metadata, merchantKey) {
40
+ return metadata.preferredForMerchantKeys?.some((candidate) => normalizeCatalogLookupValue(candidate) === merchantKey)
41
+ ? 1
42
+ : 0;
43
+ }
44
+ function stripValues(record) {
45
+ return {
46
+ ...record.metadata,
47
+ fieldKeys: [...record.metadata.fieldKeys],
48
+ fieldPolicies: record.metadata.fieldPolicies
49
+ ? { ...record.metadata.fieldPolicies }
50
+ : undefined,
51
+ preferredForMerchantKeys: record.metadata.preferredForMerchantKeys
52
+ ? [...record.metadata.preferredForMerchantKeys]
53
+ : undefined,
54
+ };
55
+ }
56
+ export function listMockStoredSecretsForHost(hostOrUrl, options = {}) {
57
+ const host = resolveHostFromInput(hostOrUrl);
58
+ const merchantKey = normalizeMerchantKey(options.merchantKey ?? host);
59
+ return loadMockStoredSecretRecords()
60
+ .filter((record) => storedSecretAppliesToHost(record.metadata, host))
61
+ .sort((left, right) => {
62
+ const preferenceDelta = preferenceScore(right.metadata, merchantKey) - preferenceScore(left.metadata, merchantKey);
63
+ if (preferenceDelta !== 0) {
64
+ return preferenceDelta;
65
+ }
66
+ return left.metadata.displayName.localeCompare(right.metadata.displayName);
67
+ })
68
+ .map(stripValues);
69
+ }
70
+ export function syncMockSecretCatalog(hostOrUrl, options = {}) {
71
+ const host = resolveHostFromInput(hostOrUrl);
72
+ return {
73
+ source: 'mock',
74
+ host,
75
+ syncedAt: options.syncedAt ?? new Date().toISOString(),
76
+ storedSecrets: listMockStoredSecretsForHost(host, {
77
+ merchantKey: options.merchantKey ?? host,
78
+ }),
79
+ };
80
+ }
81
+ export function resolveMockStoredSecretValues(storedSecretRef) {
82
+ const match = loadMockStoredSecretRecords().find((record) => record.metadata.storedSecretRef === storedSecretRef);
83
+ if (!match) {
84
+ return null;
85
+ }
86
+ return { ...match.values };
87
+ }
@@ -0,0 +1,43 @@
1
+ import type { SecretIntentSnapshot } from './types.js';
2
+ export interface MockSecretIntentRecord extends SecretIntentSnapshot {
3
+ approvalChannel: 'agentpay-cabinet';
4
+ host: string;
5
+ pageRef: string;
6
+ pollCount: number;
7
+ }
8
+ interface MockSecretIntentStore {
9
+ version: 1;
10
+ nextIntent: number;
11
+ intents: Record<string, MockSecretIntentRecord>;
12
+ }
13
+ interface IntentLifecycleOptions {
14
+ now?: string;
15
+ }
16
+ export interface CreateMockSecretIntentInput extends IntentLifecycleOptions {
17
+ fillRef: string;
18
+ storedSecretRef: string;
19
+ host: string;
20
+ pageRef: string;
21
+ scopeRef?: string;
22
+ expiresAt?: string;
23
+ }
24
+ export interface CreateMockSecretIntentResult {
25
+ intent: MockSecretIntentRecord;
26
+ reused: boolean;
27
+ }
28
+ declare function readMockStore(): MockSecretIntentStore;
29
+ declare function defaultExpiry(createdAt: string): string;
30
+ declare function progressIntentStatus(record: MockSecretIntentRecord, now: string): MockSecretIntentRecord;
31
+ export declare function createOrReuseMockSecretIntent(input: CreateMockSecretIntentInput): CreateMockSecretIntentResult;
32
+ export declare function getMockSecretIntent(intentId: string, options?: IntentLifecycleOptions): MockSecretIntentRecord | null;
33
+ export declare function approveMockSecretIntent(intentId: string, options?: IntentLifecycleOptions): MockSecretIntentRecord;
34
+ export declare function denyMockSecretIntent(intentId: string, options?: IntentLifecycleOptions): MockSecretIntentRecord;
35
+ export declare function markMockSecretIntentCompleted(intentId: string, options?: IntentLifecycleOptions): MockSecretIntentRecord;
36
+ export declare function resetMockSecretIntentStore(): void;
37
+ export declare const __testMockCabinet: {
38
+ defaultExpiry: typeof defaultExpiry;
39
+ progressIntentStatus: typeof progressIntentStatus;
40
+ readMockStore: typeof readMockStore;
41
+ };
42
+ export {};
43
+ //# sourceMappingURL=mock-agentpay-cabinet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-agentpay-cabinet.d.ts","sourceRoot":"","sources":["../../src/secrets/mock-agentpay-cabinet.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAsB,MAAM,YAAY,CAAC;AAO3E,MAAM,WAAW,sBAAuB,SAAQ,oBAAoB;IAClE,eAAe,EAAE,kBAAkB,CAAC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,qBAAqB;IAC7B,OAAO,EAAE,CAAC,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;CACjD;AAED,UAAU,sBAAsB;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,2BAA4B,SAAQ,sBAAsB;IACzE,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,4BAA4B;IAC3C,MAAM,EAAE,sBAAsB,CAAC;IAC/B,MAAM,EAAE,OAAO,CAAC;CACjB;AAQD,iBAAS,aAAa,IAAI,qBAAqB,CAuB9C;AAWD,iBAAS,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEhD;AAUD,iBAAS,oBAAoB,CAC3B,MAAM,EAAE,sBAAsB,EAC9B,GAAG,EAAE,MAAM,GACV,sBAAsB,CAmCxB;AAUD,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,2BAA2B,GACjC,4BAA4B,CAuC9B;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,sBAA2B,GACnC,sBAAsB,GAAG,IAAI,CAW/B;AAqCD,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,sBAA2B,GACnC,sBAAsB,CAExB;AAED,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,sBAA2B,GACnC,sBAAsB,CAExB;AAED,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,sBAA2B,GACnC,sBAAsB,CAexB;AAED,wBAAgB,0BAA0B,IAAI,IAAI,CAIjD;AAED,eAAO,MAAM,iBAAiB;;;;CAI7B,CAAC"}
@@ -0,0 +1,195 @@
1
+ import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';
2
+ import { homedir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ const MOCK_CABINET_DIR = join(homedir(), '.agentpay');
5
+ const MOCK_CABINET_PATH = join(MOCK_CABINET_DIR, 'mock-secret-intents.json');
6
+ const APPROVAL_CHANNEL = 'agentpay-cabinet';
7
+ const TERMINAL_INTENT_STATUSES = new Set(['approved', 'denied', 'timed_out', 'completed']);
8
+ function ensureMockCabinetDir() {
9
+ if (!existsSync(MOCK_CABINET_DIR)) {
10
+ mkdirSync(MOCK_CABINET_DIR, { recursive: true });
11
+ }
12
+ }
13
+ function readMockStore() {
14
+ if (!existsSync(MOCK_CABINET_PATH)) {
15
+ return {
16
+ version: 1,
17
+ nextIntent: 1,
18
+ intents: {},
19
+ };
20
+ }
21
+ try {
22
+ const raw = JSON.parse(readFileSync(MOCK_CABINET_PATH, 'utf-8'));
23
+ return {
24
+ version: 1,
25
+ nextIntent: Number.isFinite(raw.nextIntent) ? Number(raw.nextIntent) : 1,
26
+ intents: raw.intents ?? {},
27
+ };
28
+ }
29
+ catch {
30
+ return {
31
+ version: 1,
32
+ nextIntent: 1,
33
+ intents: {},
34
+ };
35
+ }
36
+ }
37
+ function writeMockStore(store) {
38
+ ensureMockCabinetDir();
39
+ writeFileSync(MOCK_CABINET_PATH, JSON.stringify(store, null, 2));
40
+ }
41
+ function nowIso(value) {
42
+ return value ?? new Date().toISOString();
43
+ }
44
+ function defaultExpiry(createdAt) {
45
+ return new Date(new Date(createdAt).getTime() + 15 * 60_000).toISOString();
46
+ }
47
+ function isExpired(record, now) {
48
+ if (!record.expiresAt || TERMINAL_INTENT_STATUSES.has(record.status)) {
49
+ return false;
50
+ }
51
+ return new Date(record.expiresAt).getTime() <= new Date(now).getTime();
52
+ }
53
+ function progressIntentStatus(record, now) {
54
+ if (isExpired(record, now)) {
55
+ return {
56
+ ...record,
57
+ status: 'timed_out',
58
+ };
59
+ }
60
+ switch (record.status) {
61
+ case 'pending':
62
+ return {
63
+ ...record,
64
+ status: 'checking',
65
+ pollCount: record.pollCount + 1,
66
+ };
67
+ case 'checking':
68
+ return {
69
+ ...record,
70
+ status: 'notify',
71
+ pollCount: record.pollCount + 1,
72
+ };
73
+ case 'notify':
74
+ return {
75
+ ...record,
76
+ status: 'confirmation',
77
+ pollCount: record.pollCount + 1,
78
+ };
79
+ case 'confirmation':
80
+ return {
81
+ ...record,
82
+ pollCount: record.pollCount + 1,
83
+ };
84
+ default:
85
+ return record;
86
+ }
87
+ }
88
+ function isActiveIntentStatus(status) {
89
+ return !TERMINAL_INTENT_STATUSES.has(status);
90
+ }
91
+ function nextIntentId(store) {
92
+ return `si_mock_${store.nextIntent++}`;
93
+ }
94
+ export function createOrReuseMockSecretIntent(input) {
95
+ const store = readMockStore();
96
+ const createdAt = nowIso(input.now);
97
+ const existing = Object.values(store.intents).find((intent) => intent.fillRef === input.fillRef &&
98
+ intent.storedSecretRef === input.storedSecretRef &&
99
+ isActiveIntentStatus(intent.status));
100
+ if (existing) {
101
+ return {
102
+ intent: existing,
103
+ reused: true,
104
+ };
105
+ }
106
+ const intentId = nextIntentId(store);
107
+ const intent = {
108
+ intentId,
109
+ fillRef: input.fillRef,
110
+ storedSecretRef: input.storedSecretRef,
111
+ status: 'pending',
112
+ approvalChannel: APPROVAL_CHANNEL,
113
+ host: input.host,
114
+ pageRef: input.pageRef,
115
+ scopeRef: input.scopeRef,
116
+ createdAt,
117
+ expiresAt: input.expiresAt ?? defaultExpiry(createdAt),
118
+ pollCount: 0,
119
+ };
120
+ store.intents[intentId] = intent;
121
+ writeMockStore(store);
122
+ return {
123
+ intent,
124
+ reused: false,
125
+ };
126
+ }
127
+ export function getMockSecretIntent(intentId, options = {}) {
128
+ const store = readMockStore();
129
+ const current = store.intents[intentId];
130
+ if (!current) {
131
+ return null;
132
+ }
133
+ const next = progressIntentStatus(current, nowIso(options.now));
134
+ store.intents[intentId] = next;
135
+ writeMockStore(store);
136
+ return next;
137
+ }
138
+ function transitionIntentDecision(intentId, status, options = {}) {
139
+ const store = readMockStore();
140
+ const current = store.intents[intentId];
141
+ if (!current) {
142
+ throw new Error('secret_intent_not_found');
143
+ }
144
+ if (isExpired(current, nowIso(options.now))) {
145
+ const timedOut = {
146
+ ...current,
147
+ status: 'timed_out',
148
+ };
149
+ store.intents[intentId] = timedOut;
150
+ writeMockStore(store);
151
+ throw new Error('secret_intent_timed_out');
152
+ }
153
+ if (!(current.status === 'notify' || current.status === 'confirmation')) {
154
+ throw new Error(`secret_intent_not_awaiting_decision:${current.status}`);
155
+ }
156
+ const decided = {
157
+ ...current,
158
+ status,
159
+ approvedAt: status === 'approved' ? nowIso(options.now) : current.approvedAt,
160
+ };
161
+ store.intents[intentId] = decided;
162
+ writeMockStore(store);
163
+ return decided;
164
+ }
165
+ export function approveMockSecretIntent(intentId, options = {}) {
166
+ return transitionIntentDecision(intentId, 'approved', options);
167
+ }
168
+ export function denyMockSecretIntent(intentId, options = {}) {
169
+ return transitionIntentDecision(intentId, 'denied', options);
170
+ }
171
+ export function markMockSecretIntentCompleted(intentId, options = {}) {
172
+ const store = readMockStore();
173
+ const current = store.intents[intentId];
174
+ if (!current) {
175
+ throw new Error('secret_intent_not_found');
176
+ }
177
+ const completed = {
178
+ ...current,
179
+ status: 'completed',
180
+ completedAt: nowIso(options.now),
181
+ };
182
+ store.intents[intentId] = completed;
183
+ writeMockStore(store);
184
+ return completed;
185
+ }
186
+ export function resetMockSecretIntentStore() {
187
+ if (existsSync(MOCK_CABINET_PATH)) {
188
+ unlinkSync(MOCK_CABINET_PATH);
189
+ }
190
+ }
191
+ export const __testMockCabinet = {
192
+ defaultExpiry,
193
+ progressIntentStatus,
194
+ readMockStore,
195
+ };
@@ -0,0 +1,25 @@
1
+ import type { ProtectedExposureState } from '../runtime-state.js';
2
+ export interface ProtectedArtifactsSuppressed {
3
+ suppressed: true;
4
+ outcomeType: 'protected_exposure_active';
5
+ reason: string;
6
+ pageRef: string;
7
+ fillRef: string;
8
+ intentId: string;
9
+ activatedAt: string;
10
+ exposureReason: ProtectedExposureState['reason'];
11
+ message: string;
12
+ }
13
+ export declare function buildProtectedArtifactsSuppressed(exposure: ProtectedExposureState): ProtectedArtifactsSuppressed;
14
+ export declare function buildProtectedScreenshotBlockedResult(exposure: ProtectedExposureState): {
15
+ error: string;
16
+ outcomeType: string;
17
+ reason: string;
18
+ pageRef: string;
19
+ fillRef: string;
20
+ intentId: string;
21
+ activatedAt: string;
22
+ exposureReason: "protected_fill_success" | "protected_fill_binding_stale" | "protected_fill_validation_failed" | "protected_fill_unexpected_error";
23
+ message: string;
24
+ };
25
+ //# sourceMappingURL=protected-artifact-guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protected-artifact-guard.d.ts","sourceRoot":"","sources":["../../src/secrets/protected-artifact-guard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAElE,MAAM,WAAW,4BAA4B;IAC3C,UAAU,EAAE,IAAI,CAAC;IACjB,WAAW,EAAE,2BAA2B,CAAC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,sBAAsB,CAAC,QAAQ,CAAC,CAAC;IACjD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,iCAAiC,CAC/C,QAAQ,EAAE,sBAAsB,GAC/B,4BAA4B,CAc9B;AAED,wBAAgB,qCAAqC,CAAC,QAAQ,EAAE,sBAAsB;;;;;;;;;;EAcrF"}
@@ -0,0 +1,26 @@
1
+ export function buildProtectedArtifactsSuppressed(exposure) {
2
+ return {
3
+ suppressed: true,
4
+ outcomeType: 'protected_exposure_active',
5
+ reason: 'Failure artifacts were suppressed because protected values may still be visible on the page.',
6
+ pageRef: exposure.pageRef,
7
+ fillRef: exposure.fillRef,
8
+ intentId: exposure.intentId,
9
+ activatedAt: exposure.activatedAt,
10
+ exposureReason: exposure.reason,
11
+ message: 'Failure artifacts were suppressed because protected values may still be visible on the page.',
12
+ };
13
+ }
14
+ export function buildProtectedScreenshotBlockedResult(exposure) {
15
+ return {
16
+ error: 'protected_screenshot_blocked',
17
+ outcomeType: 'protected_exposure_active',
18
+ reason: 'Screenshot capture is currently restricted because protected values may still be visible on the page.',
19
+ pageRef: exposure.pageRef,
20
+ fillRef: exposure.fillRef,
21
+ intentId: exposure.intentId,
22
+ activatedAt: exposure.activatedAt,
23
+ exposureReason: exposure.reason,
24
+ message: 'Screenshot capture is blocked because protected values may still be visible on the page.',
25
+ };
26
+ }
@@ -0,0 +1,10 @@
1
+ import { z } from 'zod';
2
+ import { type ProtectedBindingValueHint } from './types.js';
3
+ export declare const protectedBindingValueHintSchema: z.ZodEnum<["direct", "full_name.given", "full_name.family"]>;
4
+ export declare function normalizeProtectedBindingValueHint(fieldKey: string, valueHint?: string | null): ProtectedBindingValueHint;
5
+ export declare function protectedBindingKey(binding: {
6
+ targetRef: string;
7
+ fieldKey: string;
8
+ valueHint?: string | null;
9
+ }): string;
10
+ //# sourceMappingURL=protected-bindings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protected-bindings.d.ts","sourceRoot":"","sources":["../../src/secrets/protected-bindings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,+BAA+B,8DAAwC,CAAC;AAErF,wBAAgB,kCAAkC,CAChD,QAAQ,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GACxB,yBAAyB,CAS3B;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE;IACP,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,GACA,MAAM,CAMR"}
@@ -0,0 +1,17 @@
1
+ import { z } from 'zod';
2
+ import { PROTECTED_BINDING_VALUE_HINTS, } from './types.js';
3
+ export const protectedBindingValueHintSchema = z.enum(PROTECTED_BINDING_VALUE_HINTS);
4
+ export function normalizeProtectedBindingValueHint(fieldKey, valueHint) {
5
+ if (fieldKey === 'full_name' &&
6
+ (valueHint === 'full_name.given' || valueHint === 'full_name.family')) {
7
+ return valueHint;
8
+ }
9
+ return 'direct';
10
+ }
11
+ export function protectedBindingKey(binding) {
12
+ return [
13
+ binding.targetRef,
14
+ binding.fieldKey,
15
+ normalizeProtectedBindingValueHint(binding.fieldKey, binding.valueHint),
16
+ ].join(':');
17
+ }
@@ -0,0 +1,13 @@
1
+ import type { Page } from 'playwright-core';
2
+ import type { TargetDescriptor } from '../runtime-state.js';
3
+ import type { FillableFormFieldBinding, StoredSecretFieldPolicies } from './types.js';
4
+ export declare function resolveAssistedProtectedFieldValues(params: {
5
+ page: Page;
6
+ bindings: ReadonlyArray<{
7
+ binding: FillableFormFieldBinding;
8
+ target: TargetDescriptor | null;
9
+ }>;
10
+ protectedValues: Record<string, string>;
11
+ fieldPolicies?: StoredSecretFieldPolicies;
12
+ }): Promise<Map<string, string>>;
13
+ //# sourceMappingURL=protected-field-values.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protected-field-values.d.ts","sourceRoot":"","sources":["../../src/secrets/protected-field-values.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAG5C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAM5D,OAAO,KAAK,EACV,wBAAwB,EACxB,yBAAyB,EAC1B,MAAM,YAAY,CAAC;AA0CpB,wBAAsB,mCAAmC,CAAC,MAAM,EAAE;IAChE,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,aAAa,CAAC;QACtB,OAAO,EAAE,wBAAwB,CAAC;QAClC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAAC;KACjC,CAAC,CAAC;IACH,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,aAAa,CAAC,EAAE,yBAAyB,CAAC;CAC3C,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAiE/B"}
@@ -0,0 +1,100 @@
1
+ import { z } from 'zod';
2
+ import { AgentpayStagehandLlmClient } from '../agentpay-stagehand-llm.js';
3
+ import { tryResolveAgentpayGatewayConfig } from '../agentpay-gateway.js';
4
+ import { resolveProtectedFieldPolicy } from './field-policy.js';
5
+ import { protectedBindingKey, protectedBindingValueHintSchema, } from './protected-bindings.js';
6
+ const protectedFieldValuesSchema = z.object({
7
+ values: z
8
+ .array(z.object({
9
+ targetRef: z.string(),
10
+ fieldKey: z.string(),
11
+ valueHint: protectedBindingValueHintSchema.optional(),
12
+ value: z.string(),
13
+ confidence: z.enum(['high', 'medium', 'low']),
14
+ }))
15
+ .max(24),
16
+ });
17
+ function buildBindingSummary(binding, target) {
18
+ const parts = [
19
+ `targetRef=${JSON.stringify(binding.targetRef)}`,
20
+ `fieldKey=${JSON.stringify(binding.fieldKey)}`,
21
+ `valueHint=${JSON.stringify(binding.valueHint ?? 'direct')}`,
22
+ ];
23
+ if (target?.label)
24
+ parts.push(`label=${JSON.stringify(target.label)}`);
25
+ if (target?.displayLabel)
26
+ parts.push(`displayLabel=${JSON.stringify(target.displayLabel)}`);
27
+ if (target?.kind)
28
+ parts.push(`kind=${JSON.stringify(target.kind)}`);
29
+ if (target?.semantics?.role)
30
+ parts.push(`role=${JSON.stringify(target.semantics.role)}`);
31
+ if (target?.controlFamily)
32
+ parts.push(`controlFamily=${JSON.stringify(target.controlFamily)}`);
33
+ if (target?.context?.hintText)
34
+ parts.push(`hintText=${JSON.stringify(target.context.hintText)}`);
35
+ if (target?.context?.group?.label) {
36
+ parts.push(`groupLabel=${JSON.stringify(target.context.group.label)}`);
37
+ }
38
+ if (target?.context?.container?.label) {
39
+ parts.push(`containerLabel=${JSON.stringify(target.context.container.label)}`);
40
+ }
41
+ return parts.join(' | ');
42
+ }
43
+ export async function resolveAssistedProtectedFieldValues(params) {
44
+ const assistedBindings = params.bindings.filter(({ binding }) => {
45
+ return resolveProtectedFieldPolicy(params.fieldPolicies, binding.fieldKey) === 'llm_assisted';
46
+ });
47
+ if (assistedBindings.length === 0) {
48
+ return new Map();
49
+ }
50
+ const gateway = tryResolveAgentpayGatewayConfig();
51
+ if (!gateway) {
52
+ throw new Error('protected_field_value_resolver_gateway_missing');
53
+ }
54
+ const client = new AgentpayStagehandLlmClient(gateway);
55
+ const pageLocale = await params.page
56
+ .evaluate(() => document.documentElement.lang || document.body?.lang || '')
57
+ .catch(() => '');
58
+ const prompt = [
59
+ 'You are resolving UI-ready values for already matched protected fields.',
60
+ 'Do not invent new bindings. Use only the provided targetRef values.',
61
+ 'Return one resolved value per binding.',
62
+ 'Use page language, target labels, and field hints to adapt the stored value to the visible UI representation.',
63
+ 'Examples:',
64
+ '- full_name + valueHint=full_name.given -> return only the given/first-name part',
65
+ '- full_name + valueHint=full_name.family -> return only the family/last-name part',
66
+ '- nationality or issuing_country may require a localized UI value such as Россия for RU',
67
+ 'If unsure, return confidence=low for that binding.',
68
+ '',
69
+ `pageLocale=${JSON.stringify(pageLocale)}`,
70
+ 'Bindings:',
71
+ ...assistedBindings.map(({ binding, target }) => {
72
+ const storedValue = params.protectedValues[binding.fieldKey] ?? '';
73
+ return `${buildBindingSummary(binding, target)} | storedValue=${JSON.stringify(storedValue)}`;
74
+ }),
75
+ ].join('\n');
76
+ const result = await client.createChatCompletion({
77
+ logger: () => { },
78
+ options: {
79
+ messages: [{ role: 'user', content: prompt }],
80
+ response_model: {
81
+ name: 'ProtectedFieldValues',
82
+ schema: protectedFieldValuesSchema,
83
+ },
84
+ },
85
+ });
86
+ const allowedKeys = new Set(assistedBindings.map(({ binding }) => protectedBindingKey(binding)));
87
+ const resolvedValues = new Map();
88
+ for (const entry of result.data.values) {
89
+ const key = protectedBindingKey(entry);
90
+ if (!allowedKeys.has(key) || entry.confidence === 'low') {
91
+ continue;
92
+ }
93
+ const value = entry.value.trim();
94
+ if (!value) {
95
+ continue;
96
+ }
97
+ resolvedValues.set(key, value);
98
+ }
99
+ return resolvedValues;
100
+ }
@@ -0,0 +1,47 @@
1
+ import type { Page } from 'playwright-core';
2
+ import type { BrowseSession } from '../session.js';
3
+ import { type TargetDescriptor } from '../runtime-state.js';
4
+ import type { PersistedFillableForm, StoredSecretFieldPolicies, StoredSecretFieldKey } from './types.js';
5
+ type ProtectedFillAction = 'fill' | 'select' | 'type';
6
+ export interface ProtectedFilledField {
7
+ fieldKey: StoredSecretFieldKey;
8
+ targetRef: string;
9
+ }
10
+ export interface ProtectedFieldError extends ProtectedFilledField {
11
+ reason: 'client_validation_rejected' | 'value_not_applied';
12
+ validationTextRedacted?: true;
13
+ }
14
+ type ProtectedBindingStaleReason = 'target_missing' | 'target_not_live' | 'page_signature_mismatch' | 'dom_signature_mismatch' | 'locator_resolution_failed' | 'target_blocked';
15
+ export type ProtectedFillExecutionResult = {
16
+ kind: 'success';
17
+ filledFields: ProtectedFilledField[];
18
+ } | {
19
+ kind: 'binding_stale';
20
+ targetRef: string;
21
+ fieldKeys: StoredSecretFieldKey[];
22
+ reason: ProtectedBindingStaleReason;
23
+ attempts: string[];
24
+ } | {
25
+ kind: 'validation_failed';
26
+ filledFields: ProtectedFilledField[];
27
+ fieldErrors: ProtectedFieldError[];
28
+ } | {
29
+ kind: 'unexpected_error';
30
+ reason: 'missing_protected_value' | 'unsupported_protected_field_group' | 'deterministic_only_resolution_failed' | 'assisted_value_resolution_failed' | 'action_failed';
31
+ };
32
+ declare function actionForTarget(target: TargetDescriptor): ProtectedFillAction;
33
+ declare function formatCardExpiry(month: string, year: string): string;
34
+ export declare function executeProtectedFill(params: {
35
+ session: BrowseSession;
36
+ page: Page;
37
+ fillableForm: PersistedFillableForm;
38
+ protectedValues: Record<string, string>;
39
+ fieldPolicies?: StoredSecretFieldPolicies;
40
+ }): Promise<ProtectedFillExecutionResult>;
41
+ export declare const __testProtectedFill: {
42
+ actionForTarget: typeof actionForTarget;
43
+ formatCardExpiry: typeof formatCardExpiry;
44
+ resolveBindingValue: (fieldKeys: ReadonlyArray<StoredSecretFieldKey>, protectedValues: Record<string, string>) => string;
45
+ };
46
+ export {};
47
+ //# sourceMappingURL=protected-fill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protected-fill.d.ts","sourceRoot":"","sources":["../../src/secrets/protected-fill.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAyB,KAAK,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAanF,OAAO,KAAK,EAEV,qBAAqB,EACrB,yBAAyB,EACzB,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAGpB,KAAK,mBAAmB,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEtD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAoB,SAAQ,oBAAoB;IAC/D,MAAM,EAAE,4BAA4B,GAAG,mBAAmB,CAAC;IAC3D,sBAAsB,CAAC,EAAE,IAAI,CAAC;CAC/B;AAED,KAAK,2BAA2B,GAC5B,gBAAgB,GAChB,iBAAiB,GACjB,yBAAyB,GACzB,wBAAwB,GACxB,2BAA2B,GAC3B,gBAAgB,CAAC;AAarB,MAAM,MAAM,4BAA4B,GACpC;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,YAAY,EAAE,oBAAoB,EAAE,CAAC;CACtC,GACC;IACA,IAAI,EAAE,eAAe,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,oBAAoB,EAAE,CAAC;IAClC,MAAM,EAAE,2BAA2B,CAAC;IACpC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,GACD;IACE,IAAI,EAAE,mBAAmB,CAAC;IAC1B,YAAY,EAAE,oBAAoB,EAAE,CAAC;IACrC,WAAW,EAAE,mBAAmB,EAAE,CAAC;CACpC,GACD;IACE,IAAI,EAAE,kBAAkB,CAAC;IACzB,MAAM,EACF,yBAAyB,GACzB,mCAAmC,GACnC,sCAAsC,GACtC,kCAAkC,GAClC,eAAe,CAAC;CACrB,CAAC;AAwHN,iBAAS,eAAe,CAAC,MAAM,EAAE,gBAAgB,GAAG,mBAAmB,CActE;AAED,iBAAS,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAI7D;AAkVD,wBAAsB,oBAAoB,CAAC,MAAM,EAAE;IACjD,OAAO,EAAE,aAAa,CAAC;IACvB,IAAI,EAAE,IAAI,CAAC;IACX,YAAY,EAAE,qBAAqB,CAAC;IACpC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,aAAa,CAAC,EAAE,yBAAyB,CAAC;CAC3C,GAAG,OAAO,CAAC,4BAA4B,CAAC,CA4KxC;AAED,eAAO,MAAM,mBAAmB;;;qCAIjB,aAAa,CAAC,oBAAoB,CAAC,mBAC7B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;CAY1C,CAAC"}