@mercuryo-ai/magicpay-cli 0.1.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.
Files changed (144) hide show
  1. package/README.md +56 -0
  2. package/dist/agentbrowse-assistive.d.ts +2 -0
  3. package/dist/agentbrowse-assistive.d.ts.map +1 -0
  4. package/dist/agentbrowse-assistive.js +66 -0
  5. package/dist/assistive-llm-client.d.ts +13 -0
  6. package/dist/assistive-llm-client.d.ts.map +1 -0
  7. package/dist/assistive-llm-client.js +152 -0
  8. package/dist/browser-bridge/act.d.ts +5 -0
  9. package/dist/browser-bridge/act.d.ts.map +1 -0
  10. package/dist/browser-bridge/act.js +8 -0
  11. package/dist/browser-bridge/observe.d.ts +5 -0
  12. package/dist/browser-bridge/observe.d.ts.map +1 -0
  13. package/dist/browser-bridge/observe.js +53 -0
  14. package/dist/browser-home.d.ts +7 -0
  15. package/dist/browser-home.d.ts.map +1 -0
  16. package/dist/browser-home.js +34 -0
  17. package/dist/commands/act.d.ts +5 -0
  18. package/dist/commands/act.d.ts.map +1 -0
  19. package/dist/commands/act.js +8 -0
  20. package/dist/commands/attach.d.ts +4 -0
  21. package/dist/commands/attach.d.ts.map +1 -0
  22. package/dist/commands/attach.js +10 -0
  23. package/dist/commands/browser-status.d.ts +5 -0
  24. package/dist/commands/browser-status.d.ts.map +1 -0
  25. package/dist/commands/browser-status.js +5 -0
  26. package/dist/commands/close.d.ts +4 -0
  27. package/dist/commands/close.d.ts.map +1 -0
  28. package/dist/commands/close.js +11 -0
  29. package/dist/commands/end-session.d.ts +22 -0
  30. package/dist/commands/end-session.d.ts.map +1 -0
  31. package/dist/commands/end-session.js +104 -0
  32. package/dist/commands/extract.d.ts +4 -0
  33. package/dist/commands/extract.d.ts.map +1 -0
  34. package/dist/commands/extract.js +14 -0
  35. package/dist/commands/fill-secret.d.ts +10 -0
  36. package/dist/commands/fill-secret.d.ts.map +1 -0
  37. package/dist/commands/fill-secret.js +483 -0
  38. package/dist/commands/find-form.d.ts +57 -0
  39. package/dist/commands/find-form.d.ts.map +1 -0
  40. package/dist/commands/find-form.js +138 -0
  41. package/dist/commands/get-secrets-catalog.d.ts +13 -0
  42. package/dist/commands/get-secrets-catalog.d.ts.map +1 -0
  43. package/dist/commands/get-secrets-catalog.js +103 -0
  44. package/dist/commands/init.d.ts +10 -0
  45. package/dist/commands/init.d.ts.map +1 -0
  46. package/dist/commands/init.js +28 -0
  47. package/dist/commands/launch.d.ts +4 -0
  48. package/dist/commands/launch.d.ts.map +1 -0
  49. package/dist/commands/launch.js +10 -0
  50. package/dist/commands/mock-approve-secret.d.ts +21 -0
  51. package/dist/commands/mock-approve-secret.d.ts.map +1 -0
  52. package/dist/commands/mock-approve-secret.js +69 -0
  53. package/dist/commands/mock-deny-secret.d.ts +21 -0
  54. package/dist/commands/mock-deny-secret.d.ts.map +1 -0
  55. package/dist/commands/mock-deny-secret.js +69 -0
  56. package/dist/commands/navigate.d.ts +4 -0
  57. package/dist/commands/navigate.d.ts.map +1 -0
  58. package/dist/commands/navigate.js +9 -0
  59. package/dist/commands/observe.d.ts +5 -0
  60. package/dist/commands/observe.d.ts.map +1 -0
  61. package/dist/commands/observe.js +53 -0
  62. package/dist/commands/poll-secret.d.ts +13 -0
  63. package/dist/commands/poll-secret.d.ts.map +1 -0
  64. package/dist/commands/poll-secret.js +87 -0
  65. package/dist/commands/request-secret.d.ts +15 -0
  66. package/dist/commands/request-secret.d.ts.map +1 -0
  67. package/dist/commands/request-secret.js +235 -0
  68. package/dist/commands/screenshot.d.ts +4 -0
  69. package/dist/commands/screenshot.d.ts.map +1 -0
  70. package/dist/commands/screenshot.js +11 -0
  71. package/dist/commands/solve-captcha.d.ts +19 -0
  72. package/dist/commands/solve-captcha.d.ts.map +1 -0
  73. package/dist/commands/solve-captcha.js +63 -0
  74. package/dist/commands/start-session.d.ts +28 -0
  75. package/dist/commands/start-session.d.ts.map +1 -0
  76. package/dist/commands/start-session.js +298 -0
  77. package/dist/commands/status.d.ts +27 -0
  78. package/dist/commands/status.d.ts.map +1 -0
  79. package/dist/commands/status.js +51 -0
  80. package/dist/commands/submit-form.d.ts +36 -0
  81. package/dist/commands/submit-form.d.ts.map +1 -0
  82. package/dist/commands/submit-form.js +242 -0
  83. package/dist/config.d.ts +2 -0
  84. package/dist/config.d.ts.map +1 -0
  85. package/dist/config.js +1 -0
  86. package/dist/fillable-form-state.d.ts +5 -0
  87. package/dist/fillable-form-state.d.ts.map +1 -0
  88. package/dist/fillable-form-state.js +22 -0
  89. package/dist/gateway.d.ts +10 -0
  90. package/dist/gateway.d.ts.map +1 -0
  91. package/dist/gateway.js +49 -0
  92. package/dist/generated/build-config.d.ts +2 -0
  93. package/dist/generated/build-config.d.ts.map +1 -0
  94. package/dist/generated/build-config.js +2 -0
  95. package/dist/index.d.ts +4 -0
  96. package/dist/index.d.ts.map +1 -0
  97. package/dist/index.js +398 -0
  98. package/dist/mock-secret-cabinet.d.ts +37 -0
  99. package/dist/mock-secret-cabinet.d.ts.map +1 -0
  100. package/dist/mock-secret-cabinet.js +321 -0
  101. package/dist/mock-secret-store.d.ts +12 -0
  102. package/dist/mock-secret-store.d.ts.map +1 -0
  103. package/dist/mock-secret-store.js +108 -0
  104. package/dist/mock-stored-secrets.json +180 -0
  105. package/dist/otel-exporter.d.ts +58 -0
  106. package/dist/otel-exporter.d.ts.map +1 -0
  107. package/dist/otel-exporter.js +241 -0
  108. package/dist/otel-projector.d.ts +59 -0
  109. package/dist/otel-projector.d.ts.map +1 -0
  110. package/dist/otel-projector.js +325 -0
  111. package/dist/output.d.ts +10 -0
  112. package/dist/output.d.ts.map +1 -0
  113. package/dist/output.js +29 -0
  114. package/dist/package-version.d.ts +2 -0
  115. package/dist/package-version.d.ts.map +1 -0
  116. package/dist/package-version.js +14 -0
  117. package/dist/protected-exposure.d.ts +4 -0
  118. package/dist/protected-exposure.d.ts.map +1 -0
  119. package/dist/protected-exposure.js +17 -0
  120. package/dist/request-output.d.ts +4 -0
  121. package/dist/request-output.d.ts.map +1 -0
  122. package/dist/request-output.js +27 -0
  123. package/dist/run-store.d.ts +130 -0
  124. package/dist/run-store.d.ts.map +1 -0
  125. package/dist/run-store.js +245 -0
  126. package/dist/secret-backend.d.ts +28 -0
  127. package/dist/secret-backend.d.ts.map +1 -0
  128. package/dist/secret-backend.js +335 -0
  129. package/dist/secret-state.d.ts +7 -0
  130. package/dist/secret-state.d.ts.map +1 -0
  131. package/dist/secret-state.js +26 -0
  132. package/dist/session-backend.d.ts +34 -0
  133. package/dist/session-backend.d.ts.map +1 -0
  134. package/dist/session-backend.js +36 -0
  135. package/dist/update-check.d.ts +13 -0
  136. package/dist/update-check.d.ts.map +1 -0
  137. package/dist/update-check.js +175 -0
  138. package/dist/workflow-session-completion.d.ts +32 -0
  139. package/dist/workflow-session-completion.d.ts.map +1 -0
  140. package/dist/workflow-session-completion.js +149 -0
  141. package/dist/workflow-state.d.ts +2 -0
  142. package/dist/workflow-state.d.ts.map +1 -0
  143. package/dist/workflow-state.js +1 -0
  144. package/package.json +67 -0
@@ -0,0 +1,87 @@
1
+ import { describeSecretRequestStatus } from '@mercuryo-ai/magicpay-sdk/core';
2
+ import { exportRunStepToOtlpHttpJsonBestEffort } from '../otel-exporter.js';
3
+ import { serializeSecretRequest } from '../request-output.js';
4
+ import { finishRunStep, startRunStep } from '../run-store.js';
5
+ import { getMagicPayClient } from '../secret-backend.js';
6
+ import { saveSecretRequestSnapshot } from '../secret-state.js';
7
+ import { saveMagicPaySession } from '../workflow-state.js';
8
+ export async function pollSecret(session, requestId) {
9
+ const step = session.activeRunId
10
+ ? startRunStep({
11
+ runId: session.activeRunId,
12
+ command: 'poll-secret',
13
+ input: {
14
+ requestId,
15
+ },
16
+ refs: {
17
+ requestId,
18
+ },
19
+ })
20
+ : null;
21
+ const finalizeStep = async (result) => {
22
+ if (step) {
23
+ finishRunStep({
24
+ runId: step.runId,
25
+ stepId: step.stepId,
26
+ success: result.success,
27
+ ...('outcomeType' in result && typeof result.outcomeType === 'string'
28
+ ? { outcomeType: result.outcomeType }
29
+ : {}),
30
+ ...('message' in result && typeof result.message === 'string'
31
+ ? { message: result.message }
32
+ : {}),
33
+ ...('reason' in result && typeof result.reason === 'string'
34
+ ? { reason: result.reason }
35
+ : {}),
36
+ });
37
+ await exportRunStepToOtlpHttpJsonBestEffort(step.runId, step.stepId);
38
+ }
39
+ return result;
40
+ };
41
+ if (!session.intentSessionId) {
42
+ return finalizeStep({
43
+ success: false,
44
+ error: 'workflow_session_required',
45
+ outcomeType: 'blocked',
46
+ message: 'Protected secret request polling failed because no active workflow session is bound to this browser.',
47
+ reason: 'Run `magicpay start-session` first so MagicPay has a workflow session for protected requests.',
48
+ requestId,
49
+ });
50
+ }
51
+ const client = getMagicPayClient();
52
+ const result = await client.secrets.poll(session.intentSessionId, requestId);
53
+ if (!result.success) {
54
+ if (result.kind === 'other') {
55
+ return finalizeStep({
56
+ success: false,
57
+ error: 'secret_request_lookup_failed',
58
+ outcomeType: 'blocked',
59
+ message: 'Protected secret request polling failed because MagicPay did not return a usable request state.',
60
+ reason: result.reason,
61
+ requestId,
62
+ });
63
+ }
64
+ return finalizeStep({
65
+ success: false,
66
+ error: 'secret_request_not_found',
67
+ outcomeType: 'blocked',
68
+ message: 'Protected secret request lookup failed because the requested request does not exist.',
69
+ reason: result.reason,
70
+ requestId,
71
+ });
72
+ }
73
+ const snapshot = saveSecretRequestSnapshot(session, result.result.snapshot);
74
+ session.currentRequestId = result.result.session.currentRequestId ?? undefined;
75
+ session.lastKnownStatus = result.result.session.status;
76
+ session.lastEventSeq = result.result.session.lastEventSeq;
77
+ saveMagicPaySession(session);
78
+ const statusContract = describeSecretRequestStatus(snapshot.status, snapshot.requestType);
79
+ return finalizeStep({
80
+ success: true,
81
+ ...serializeSecretRequest(snapshot),
82
+ ...(statusContract.outcomeType ? { outcomeType: statusContract.outcomeType } : {}),
83
+ message: statusContract.message,
84
+ reason: statusContract.reason,
85
+ ...(statusContract.nextAction ? { nextAction: statusContract.nextAction } : {}),
86
+ });
87
+ }
@@ -0,0 +1,15 @@
1
+ import { type MagicPaySession } from '../workflow-state.js';
2
+ export type RequestSecretResult = ({
3
+ success: true;
4
+ } & Record<string, unknown>) | {
5
+ success: false;
6
+ error: 'workflow_session_required' | 'unknown_fill_ref' | 'fillable_form_absent' | 'secret_request_host_resolution_failed' | 'stored_secret_not_available_for_fill_ref';
7
+ outcomeType: 'blocked';
8
+ message: string;
9
+ reason: string;
10
+ fillRef?: string;
11
+ storedSecretRef?: string;
12
+ fillableFormPresence?: 'present' | 'unknown' | 'absent';
13
+ };
14
+ export declare function requestSecret(session: MagicPaySession, fillRef: string, storedSecretRef: string, merchantName: string): Promise<RequestSecretResult>;
15
+ //# sourceMappingURL=request-secret.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-secret.d.ts","sourceRoot":"","sources":["../../src/commands/request-secret.ts"],"names":[],"mappings":"AAcA,OAAO,EAAuB,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEjF,MAAM,MAAM,mBAAmB,GAC3B,CAAC;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAC7C;IACE,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EACD,2BAA2B,GAC3B,kBAAkB,GAClB,sBAAsB,GACtB,uCAAuC,GACvC,0CAA0C,CAAC;IAC/C,WAAW,EAAE,SAAS,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oBAAoB,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;CACzD,CAAC;AAmEN,wBAAsB,aAAa,CACjC,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,MAAM,EACf,eAAe,EAAE,MAAM,EACvB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,mBAAmB,CAAC,CAkM9B"}
@@ -0,0 +1,235 @@
1
+ import { buildRequestInputForObservedForm } from '@mercuryo-ai/magicpay-sdk/agentbrowse';
2
+ import { describeSecretRequestStatus, resolveSecretCatalogContext, } from '@mercuryo-ai/magicpay-sdk/core';
3
+ import { exportRunStepToOtlpHttpJsonBestEffort } from '../otel-exporter.js';
4
+ import { getFillableForm } from '../fillable-form-state.js';
5
+ import { serializeSecretRequest } from '../request-output.js';
6
+ import { finishRunStep, startRunStep } from '../run-store.js';
7
+ import { getMagicPayClient } from '../secret-backend.js';
8
+ import { saveSecretCatalog, saveSecretRequestSnapshot } from '../secret-state.js';
9
+ import { saveMagicPaySession } from '../workflow-state.js';
10
+ function fillableFormPresencePayload(fillableForm) {
11
+ return {
12
+ fillableFormPresence: fillableForm.presence ?? 'present',
13
+ };
14
+ }
15
+ function formatUnknownError(error) {
16
+ if (error instanceof Error) {
17
+ return error.message;
18
+ }
19
+ if (typeof error === 'string') {
20
+ return error;
21
+ }
22
+ if (error && typeof error === 'object') {
23
+ try {
24
+ return JSON.stringify(error);
25
+ }
26
+ catch {
27
+ return Object.prototype.toString.call(error);
28
+ }
29
+ }
30
+ return String(error);
31
+ }
32
+ async function ensureCatalogForForm(session, fillableForm) {
33
+ const pageState = session.runtime?.pages?.[fillableForm.pageRef];
34
+ const pageUrl = pageState?.url;
35
+ if (!pageUrl) {
36
+ return {
37
+ catalog: null,
38
+ host: null,
39
+ };
40
+ }
41
+ const { host, catalog: cached } = resolveSecretCatalogContext(session.secretCatalogByHost, pageUrl);
42
+ if (cached) {
43
+ return {
44
+ catalog: cached,
45
+ host,
46
+ };
47
+ }
48
+ if (!session.intentSessionId) {
49
+ return {
50
+ catalog: null,
51
+ host,
52
+ };
53
+ }
54
+ const snapshot = await getMagicPayClient().secrets.fetchCatalog(session.intentSessionId, pageUrl);
55
+ saveSecretCatalog(session, snapshot);
56
+ saveMagicPaySession(session);
57
+ return {
58
+ catalog: snapshot,
59
+ host,
60
+ };
61
+ }
62
+ export async function requestSecret(session, fillRef, storedSecretRef, merchantName) {
63
+ const step = session.activeRunId
64
+ ? startRunStep({
65
+ runId: session.activeRunId,
66
+ command: 'request-secret',
67
+ input: {
68
+ fillRef,
69
+ storedSecretRef,
70
+ merchantName,
71
+ },
72
+ refs: {
73
+ pageRef: session.runtime?.currentPageRef,
74
+ fillRef,
75
+ },
76
+ })
77
+ : null;
78
+ const finalizeStep = async (result) => {
79
+ if (step) {
80
+ finishRunStep({
81
+ runId: step.runId,
82
+ stepId: step.stepId,
83
+ success: result.success,
84
+ ...('outcomeType' in result && typeof result.outcomeType === 'string'
85
+ ? { outcomeType: result.outcomeType }
86
+ : {}),
87
+ ...('message' in result && typeof result.message === 'string'
88
+ ? { message: result.message }
89
+ : {}),
90
+ ...('reason' in result && typeof result.reason === 'string'
91
+ ? { reason: result.reason }
92
+ : {}),
93
+ });
94
+ await exportRunStepToOtlpHttpJsonBestEffort(step.runId, step.stepId);
95
+ }
96
+ return result;
97
+ };
98
+ try {
99
+ if (!session.intentSessionId) {
100
+ return finalizeStep({
101
+ success: false,
102
+ error: 'workflow_session_required',
103
+ outcomeType: 'blocked',
104
+ message: 'Protected secret request was not created because no active workflow session is bound to this browser.',
105
+ reason: 'Run `magicpay start-session` first so MagicPay has a workflow session for protected requests.',
106
+ fillRef,
107
+ storedSecretRef,
108
+ });
109
+ }
110
+ const fillableForm = getFillableForm(session, fillRef);
111
+ if (!fillableForm) {
112
+ return finalizeStep({
113
+ success: false,
114
+ error: 'unknown_fill_ref',
115
+ outcomeType: 'blocked',
116
+ message: 'Protected secret request was not created because the requested fill reference is unknown.',
117
+ reason: 'The provided fillRef does not match any currently observed protected fill target.',
118
+ fillRef,
119
+ storedSecretRef,
120
+ });
121
+ }
122
+ if (fillableForm.presence === 'absent') {
123
+ return finalizeStep({
124
+ success: false,
125
+ error: 'fillable_form_absent',
126
+ outcomeType: 'blocked',
127
+ message: 'Protected secret request was not created because the requested fill target is no longer present on the page.',
128
+ reason: 'MagicPay CLI already observed this protected fill target as absent, so a new observe pass is required before requesting a secret.',
129
+ fillRef,
130
+ storedSecretRef,
131
+ ...fillableFormPresencePayload(fillableForm),
132
+ });
133
+ }
134
+ let catalogHost = null;
135
+ let catalog = null;
136
+ try {
137
+ const resolved = await ensureCatalogForForm(session, fillableForm);
138
+ catalog = resolved.catalog;
139
+ catalogHost = resolved.host;
140
+ }
141
+ catch {
142
+ catalog = null;
143
+ catalogHost = null;
144
+ }
145
+ if (!catalogHost) {
146
+ return finalizeStep({
147
+ success: false,
148
+ error: 'secret_request_host_resolution_failed',
149
+ outcomeType: 'blocked',
150
+ message: 'Protected secret request was not created because MagicPay CLI could not determine the current site host.',
151
+ reason: 'The current page URL did not resolve to a usable host for secret request creation.',
152
+ fillRef,
153
+ storedSecretRef,
154
+ ...fillableFormPresencePayload(fillableForm),
155
+ });
156
+ }
157
+ const pageState = session.runtime?.pages?.[fillableForm.pageRef];
158
+ const client = getMagicPayClient();
159
+ const requestInput = buildRequestInputForObservedForm({
160
+ sessionId: session.intentSessionId,
161
+ merchantName,
162
+ fillableForm,
163
+ storedSecretRef,
164
+ catalog,
165
+ urlOrHost: pageState?.url ?? catalogHost,
166
+ page: {
167
+ ref: fillableForm.pageRef,
168
+ ...(pageState?.url ? { url: pageState.url } : {}),
169
+ ...(pageState?.title ? { title: pageState.title } : {}),
170
+ },
171
+ });
172
+ if (!requestInput.success) {
173
+ if (requestInput.kind === 'host_resolution_failed') {
174
+ return finalizeStep({
175
+ success: false,
176
+ error: 'secret_request_host_resolution_failed',
177
+ outcomeType: 'blocked',
178
+ message: 'Protected secret request was not created because MagicPay CLI could not determine the current site host.',
179
+ reason: requestInput.reason,
180
+ fillRef,
181
+ storedSecretRef,
182
+ ...fillableFormPresencePayload(fillableForm),
183
+ });
184
+ }
185
+ return finalizeStep({
186
+ success: false,
187
+ error: 'stored_secret_not_available_for_fill_ref',
188
+ outcomeType: 'blocked',
189
+ message: 'Protected secret request was not created because this stored secret is not available for the requested fill target.',
190
+ reason: 'The provided storedSecretRef is not a candidate for the requested protected fill target.',
191
+ fillRef,
192
+ storedSecretRef,
193
+ ...fillableFormPresencePayload(fillableForm),
194
+ });
195
+ }
196
+ const created = await client.secrets.createRequest(requestInput.input);
197
+ if (requestInput.catalog && requestInput.catalog !== catalog) {
198
+ saveSecretCatalog(session, requestInput.catalog);
199
+ }
200
+ const snapshot = saveSecretRequestSnapshot(session, created.snapshot);
201
+ session.currentRequestId = created.session.currentRequestId ?? undefined;
202
+ session.lastKnownStatus = created.session.status;
203
+ session.lastEventSeq = created.session.lastEventSeq;
204
+ saveMagicPaySession(session);
205
+ const statusContract = describeSecretRequestStatus(snapshot.status, snapshot.requestType);
206
+ const reasonPrefix = created.reused
207
+ ? 'MagicPay CLI reused an existing secret request for this fill target.'
208
+ : 'MagicPay CLI created a new secret request for this fill target.';
209
+ return finalizeStep({
210
+ success: true,
211
+ ...fillableFormPresencePayload(fillableForm),
212
+ ...serializeSecretRequest(snapshot),
213
+ reused: created.reused,
214
+ ...(created.duplicate ? { duplicate: true } : {}),
215
+ ...(statusContract.outcomeType ? { outcomeType: statusContract.outcomeType } : {}),
216
+ message: statusContract.message,
217
+ reason: `${reasonPrefix} ${statusContract.reason}`,
218
+ ...(statusContract.nextAction ? { nextAction: statusContract.nextAction } : {}),
219
+ });
220
+ }
221
+ catch (error) {
222
+ if (step) {
223
+ finishRunStep({
224
+ runId: step.runId,
225
+ stepId: step.stepId,
226
+ success: false,
227
+ outcomeType: 'secret_request_failed',
228
+ message: 'Protected secret request failed.',
229
+ reason: formatUnknownError(error),
230
+ });
231
+ await exportRunStepToOtlpHttpJsonBestEffort(step.runId, step.stepId);
232
+ }
233
+ throw error;
234
+ }
235
+ }
@@ -0,0 +1,4 @@
1
+ import { type BrowserSessionState, type ScreenshotResult } from '@mercuryo-ai/agentbrowse';
2
+ export type { ScreenshotResult };
3
+ export declare function screenshot(session: BrowserSessionState, filePath?: string): Promise<ScreenshotResult>;
4
+ //# sourceMappingURL=screenshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../../src/commands/screenshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACtB,MAAM,0BAA0B,CAAC;AAGlC,YAAY,EAAE,gBAAgB,EAAE,CAAC;AAEjC,wBAAsB,UAAU,CAC9B,OAAO,EAAE,mBAAmB,EAC5B,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,gBAAgB,CAAC,CAQ3B"}
@@ -0,0 +1,11 @@
1
+ import { screenshot as screenshotPrimitive, } from '@mercuryo-ai/agentbrowse';
2
+ import { saveMagicPaySession } from '../workflow-state.js';
3
+ export async function screenshot(session, filePath) {
4
+ const initialPageRef = session.runtime?.currentPageRef;
5
+ const result = await screenshotPrimitive(session, filePath);
6
+ const currentPageRef = session.runtime?.currentPageRef;
7
+ if (result.success || currentPageRef !== initialPageRef) {
8
+ saveMagicPaySession(session);
9
+ }
10
+ return result;
11
+ }
@@ -0,0 +1,19 @@
1
+ export type SolveCaptchaSuccess = {
2
+ success: true;
3
+ solved: number;
4
+ verified: number;
5
+ unresolved: number;
6
+ unresolvedCaptchas: string[];
7
+ detected: number;
8
+ timedOut: boolean;
9
+ };
10
+ export type SolveCaptchaFailure = {
11
+ success: false;
12
+ error: 'captcha_session_required' | 'captcha_not_supported' | 'captcha_solve_failed';
13
+ outcomeType: 'blocked' | 'unsupported' | 'failed';
14
+ message: string;
15
+ reason: string;
16
+ };
17
+ export type SolveCaptchaResult = SolveCaptchaSuccess | SolveCaptchaFailure;
18
+ export declare function solveCaptcha(timeoutSeconds?: number): Promise<SolveCaptchaResult>;
19
+ //# sourceMappingURL=solve-captcha.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solve-captcha.d.ts","sourceRoot":"","sources":["../../src/commands/solve-captcha.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,IAAI,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,0BAA0B,GAAG,uBAAuB,GAAG,sBAAsB,CAAC;IACrF,WAAW,EAAE,SAAS,GAAG,aAAa,GAAG,QAAQ,CAAC;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,mBAAmB,GAAG,mBAAmB,CAAC;AAmC3E,wBAAsB,YAAY,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA0DvF"}
@@ -0,0 +1,63 @@
1
+ import { supportsCaptchaSolve, } from '@mercuryo-ai/agentbrowse';
2
+ import { solveCaptchasByCdp } from '@mercuryo-ai/captcha-solver';
3
+ import { resolveMagicPayGatewayConfig } from '../gateway.js';
4
+ import { writeInfo } from '../output.js';
5
+ import { loadMagicPayBrowserSession } from '../workflow-state.js';
6
+ const DEFAULT_TIMEOUT_SECONDS = 90;
7
+ const MAX_SOLVE_TIMEOUT_MS = 120_000;
8
+ function buildFailure(error, outcomeType, message, reason) {
9
+ return {
10
+ success: false,
11
+ error,
12
+ outcomeType,
13
+ message,
14
+ reason,
15
+ };
16
+ }
17
+ function resolveSharedProxy(transport) {
18
+ return transport?.proxyMode === 'proxy' ? transport.proxy : undefined;
19
+ }
20
+ function buildSuccess(result) {
21
+ return {
22
+ success: true,
23
+ solved: result.solved,
24
+ verified: result.verified,
25
+ unresolved: result.unresolved,
26
+ unresolvedCaptchas: result.unresolvedCaptchas,
27
+ detected: result.detected,
28
+ timedOut: result.timedOut,
29
+ };
30
+ }
31
+ export async function solveCaptcha(timeoutSeconds) {
32
+ const session = loadMagicPayBrowserSession();
33
+ if (!session) {
34
+ return buildFailure('captcha_session_required', 'blocked', 'Captcha solving requires an active browser session.', 'Start a browser session with `magicpay launch` or `magicpay attach <cdp-url>` before running `magicpay solve-captcha`.');
35
+ }
36
+ if (!supportsCaptchaSolve(session)) {
37
+ return buildFailure('captcha_not_supported', 'unsupported', 'The current browser session does not support captcha solving.', 'This session was started without captcha-solving capability.');
38
+ }
39
+ const timeoutMs = Math.max(1, timeoutSeconds ?? DEFAULT_TIMEOUT_SECONDS) * 1000;
40
+ const sharedProxy = resolveSharedProxy(session.transport);
41
+ let gateway;
42
+ try {
43
+ gateway = resolveMagicPayGatewayConfig();
44
+ }
45
+ catch (error) {
46
+ return buildFailure('captcha_solve_failed', 'failed', 'Captcha solving failed.', error instanceof Error ? error.message : String(error));
47
+ }
48
+ writeInfo(`[captcha] solve-captcha started (timeout ${Math.ceil(timeoutMs / 1000)}s, endpoint ${session.cdpUrl})`);
49
+ try {
50
+ const result = await solveCaptchasByCdp(session.cdpUrl, gateway.apiKey, {
51
+ timeoutMs,
52
+ solveTimeoutMs: Math.min(timeoutMs, MAX_SOLVE_TIMEOUT_MS),
53
+ apiUrl: gateway.apiUrl,
54
+ proxy: sharedProxy,
55
+ sharedTransport: Boolean(sharedProxy),
56
+ onProgress: (message) => writeInfo(message),
57
+ });
58
+ return buildSuccess(result);
59
+ }
60
+ catch (error) {
61
+ return buildFailure('captcha_solve_failed', 'failed', 'Captcha solving failed.', error instanceof Error ? error.message : String(error));
62
+ }
63
+ }
@@ -0,0 +1,28 @@
1
+ export type StartSessionSuccessResult = {
2
+ success: true;
3
+ runId: string;
4
+ startedAt: string;
5
+ browserSessionId: string;
6
+ intentSessionId: string;
7
+ lastEventSeq: number;
8
+ status: string;
9
+ currentRequestId: string | null;
10
+ replacedPreviousRun: boolean;
11
+ profile?: string;
12
+ pageRef?: string;
13
+ url?: string;
14
+ title?: string;
15
+ };
16
+ export type StartSessionFailureResult = {
17
+ success: false;
18
+ error: 'browser_session_unavailable' | 'backend_session_start_failed' | 'workflow_session_complete_failed';
19
+ outcomeType: 'blocked' | 'failed';
20
+ message: 'Session start failed.';
21
+ reason: string;
22
+ };
23
+ export type StartSessionResult = StartSessionSuccessResult | StartSessionFailureResult;
24
+ export interface StartSessionOptions {
25
+ merchantName?: string;
26
+ }
27
+ export declare function startSession(requestedName?: string, options?: StartSessionOptions): Promise<StartSessionResult>;
28
+ //# sourceMappingURL=start-session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start-session.d.ts","sourceRoot":"","sources":["../../src/commands/start-session.ts"],"names":[],"mappings":"AAmBA,MAAM,MAAM,yBAAyB,GAAG;IACtC,OAAO,EAAE,IAAI,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,mBAAmB,EAAE,OAAO,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EACD,6BAA6B,GAC7B,8BAA8B,GAC9B,kCAAkC,CAAC;IACvC,WAAW,EAAE,SAAS,GAAG,QAAQ,CAAC;IAClC,OAAO,EAAE,uBAAuB,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,yBAAyB,GAAG,yBAAyB,CAAC;AAIvF,MAAM,WAAW,mBAAmB;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AA6LD,wBAAsB,YAAY,CAChC,aAAa,CAAC,EAAE,MAAM,EACtB,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,kBAAkB,CAAC,CA0K7B"}