@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 @@
1
+ {"version":3,"file":"fillable-form-state.d.ts","sourceRoot":"","sources":["../src/fillable-form-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAsBjF,wBAAgB,eAAe,CAC7B,OAAO,EAAE,mBAAmB,EAC5B,OAAO,EAAE,MAAM,GACd,iBAAiB,GAAG,IAAI,CAG1B;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,mBAAmB,GAAG,iBAAiB,EAAE,CAGnF"}
@@ -0,0 +1,22 @@
1
+ function normalizeFillableForm(session, form) {
2
+ const pageScopeEpoch = session.runtime?.pages?.[form.pageRef]?.scopeEpoch ?? 0;
3
+ const scopeEpoch = form.scopeEpoch ?? pageScopeEpoch;
4
+ const presence = form.presence === 'absent'
5
+ ? 'absent'
6
+ : form.presence === 'unknown' || scopeEpoch < pageScopeEpoch
7
+ ? 'unknown'
8
+ : 'present';
9
+ return {
10
+ ...form,
11
+ scopeEpoch,
12
+ presence,
13
+ };
14
+ }
15
+ export function getFillableForm(session, fillRef) {
16
+ const form = session.runtime?.fillableForms?.[fillRef];
17
+ return form ? normalizeFillableForm(session, form) : null;
18
+ }
19
+ export function listFillableForms(session) {
20
+ const forms = Object.values(session.runtime?.fillableForms ?? {});
21
+ return forms.map((form) => normalizeFillableForm(session, form));
22
+ }
@@ -0,0 +1,10 @@
1
+ import { buildMagicPayAgentMeUrl, MagicPayRequestError, type AgentBackendProfile, type MagicPayGatewayConfig } from '@mercuryo-ai/magicpay-sdk/gateway';
2
+ export declare function tryResolveMagicPayGatewayConfig(): MagicPayGatewayConfig | null;
3
+ export declare function resolveMagicPayGatewayConfig(): MagicPayGatewayConfig;
4
+ export declare function buildMagicPayTelemetryTracesUrl(apiUrl: string): string;
5
+ export { buildMagicPayAgentMeUrl, MagicPayRequestError };
6
+ export type { AgentBackendProfile, MagicPayGatewayConfig };
7
+ export declare function getAuthenticatedAgent(options?: {
8
+ fetchImpl?: typeof fetch;
9
+ }): Promise<AgentBackendProfile>;
10
+ //# sourceMappingURL=gateway.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../src/gateway.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAE3B,MAAM,mCAAmC,CAAC;AA6B3C,wBAAgB,+BAA+B,IAAI,qBAAqB,GAAG,IAAI,CAiB9E;AAED,wBAAgB,4BAA4B,IAAI,qBAAqB,CAMpE;AAED,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED,OAAO,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,CAAC;AACzD,YAAY,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,CAAC;AAE3D,wBAAsB,qBAAqB,CACzC,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CAAO,GACzC,OAAO,CAAC,mBAAmB,CAAC,CAE9B"}
@@ -0,0 +1,49 @@
1
+ import { buildMagicPayAgentMeUrl, MagicPayRequestError, getAuthenticatedAgent as getAuthenticatedAgentFromSdk, } from '@mercuryo-ai/magicpay-sdk/gateway';
2
+ import { readConfig } from './config.js';
3
+ import { DEFAULT_MAGICPAY_API_URL } from './generated/build-config.js';
4
+ function trimOrUndefined(value) {
5
+ if (!value) {
6
+ return undefined;
7
+ }
8
+ const trimmed = value.trim();
9
+ if (trimmed.length === 0 ||
10
+ trimmed.toLowerCase() === 'undefined' ||
11
+ trimmed.toLowerCase() === 'null') {
12
+ return undefined;
13
+ }
14
+ return trimmed;
15
+ }
16
+ function normalizeApiUrl(value) {
17
+ return value.replace(/\/$/, '');
18
+ }
19
+ function appendApiPath(apiUrl, suffix) {
20
+ return `${normalizeApiUrl(apiUrl)}${suffix.startsWith('/') ? suffix : `/${suffix}`}`;
21
+ }
22
+ export function tryResolveMagicPayGatewayConfig() {
23
+ const config = readConfig();
24
+ const apiKey = trimOrUndefined(process.env.MAGICPAY_API_KEY) || trimOrUndefined(config.gateway?.apiKey);
25
+ const apiUrl = trimOrUndefined(process.env.MAGICPAY_API_URL) ||
26
+ trimOrUndefined(config.gateway?.apiUrl) ||
27
+ DEFAULT_MAGICPAY_API_URL;
28
+ if (!apiKey) {
29
+ return null;
30
+ }
31
+ return {
32
+ apiKey,
33
+ apiUrl: normalizeApiUrl(apiUrl),
34
+ };
35
+ }
36
+ export function resolveMagicPayGatewayConfig() {
37
+ const gateway = tryResolveMagicPayGatewayConfig();
38
+ if (!gateway) {
39
+ throw new Error('MagicPay API key is required.');
40
+ }
41
+ return gateway;
42
+ }
43
+ export function buildMagicPayTelemetryTracesUrl(apiUrl) {
44
+ return appendApiPath(apiUrl, '/observability/telemetry/traces');
45
+ }
46
+ export { buildMagicPayAgentMeUrl, MagicPayRequestError };
47
+ export async function getAuthenticatedAgent(options = {}) {
48
+ return getAuthenticatedAgentFromSdk(resolveMagicPayGatewayConfig(), options);
49
+ }
@@ -0,0 +1,2 @@
1
+ export declare const DEFAULT_MAGICPAY_API_URL = "https://agents-api.mercuryo.io/functions/v1/api";
2
+ //# sourceMappingURL=build-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-config.d.ts","sourceRoot":"","sources":["../../src/generated/build-config.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,wBAAwB,oDAAoD,CAAC"}
@@ -0,0 +1,2 @@
1
+ // Generated build config. Local development keeps the dev API by default.
2
+ export const DEFAULT_MAGICPAY_API_URL = 'https://agents-api.mercuryo.io/functions/v1/api';
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ export declare function main(argv?: string[]): Promise<void>;
3
+ export declare function isDirectExecution(metaUrl: string, argv?: string[]): boolean;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AA0VA,wBAAsB,IAAI,CAAC,IAAI,GAAE,MAAM,EAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4HvE;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,EAAiB,GAAG,OAAO,CAWzF"}
package/dist/index.js ADDED
@@ -0,0 +1,398 @@
1
+ #!/usr/bin/env node
2
+ import { config as loadEnv } from 'dotenv';
3
+ import { realpathSync } from 'node:fs';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { attach } from './commands/attach.js';
6
+ import { endSession } from './commands/end-session.js';
7
+ import { fillSecret } from './commands/fill-secret.js';
8
+ import { findForm } from './commands/find-form.js';
9
+ import { getSecretsCatalog } from './commands/get-secrets-catalog.js';
10
+ import { init } from './commands/init.js';
11
+ import { mockApproveSecret } from './commands/mock-approve-secret.js';
12
+ import { mockDenySecret } from './commands/mock-deny-secret.js';
13
+ import { pollSecret } from './commands/poll-secret.js';
14
+ import { requestSecret } from './commands/request-secret.js';
15
+ import { startSession } from './commands/start-session.js';
16
+ import { status } from './commands/status.js';
17
+ import { submitForm } from './commands/submit-form.js';
18
+ import { info, outputError, outputJSON, fatal } from './output.js';
19
+ import { readCurrentPackageVersion } from './package-version.js';
20
+ import { loadMagicPayBrowserSession, loadMagicPaySession, } from './workflow-state.js';
21
+ loadEnv();
22
+ const KNOWN_COMMANDS = new Set([
23
+ 'init',
24
+ 'status',
25
+ 'attach',
26
+ 'start-session',
27
+ 'end-session',
28
+ 'find-form',
29
+ 'get-secrets-catalog',
30
+ 'request-secret',
31
+ 'mock-approve-secret',
32
+ 'mock-deny-secret',
33
+ 'poll-secret',
34
+ 'fill-secret',
35
+ 'submit-form',
36
+ ]);
37
+ function usageText() {
38
+ return `Usage: magicpay <command> [args] [options]
39
+
40
+ Commands:
41
+ init <apiKey> [--api-url <url>] Configure MagicPay gateway access for the payment CLI
42
+ status Check gateway health and authenticated agent identity
43
+ attach <cdp-url> [options] Attach the payment CLI to an already prepared browser over CDP
44
+ start-session [name] [--merchant-name <name>]
45
+ Start workflow session on the attached browser
46
+ end-session Complete the active workflow session without closing the browser
47
+ find-form [--purpose <kind>] Find the supported protected form on the current page
48
+ get-secrets-catalog [url] Refresh stored-secret metadata for a URL or current page
49
+ request-secret <fillRef> <storedSecretRef> --merchant-name <name>
50
+ Create or reuse a session-bound secret request for one fill target
51
+ mock-approve-secret <requestId> Approve a pending mock secret request locally (mock-only)
52
+ mock-deny-secret <requestId> Deny a pending mock secret request locally (mock-only)
53
+ poll-secret <requestId> Poll one secret request state without blocking
54
+ fill-secret <fillRef> <requestId>
55
+ Claim an approved secret request, fill protected fields, and auto-submit when a live submit control is available
56
+ submit-form <fillRef> Submit the selected protected form without exposing generic act
57
+
58
+ Options:
59
+ --api-url <url> Override persisted MagicPay API base URL for init
60
+ --provider <name> Optional provider label for attach (for example "browserbase")
61
+ --purpose <kind> Protected form purpose: auto, login, identity, payment_card
62
+ --help Show this help message
63
+ --version Show installed CLI version
64
+
65
+ Environment:
66
+ MAGICPAY_API_KEY Optional runtime override; use init for persisted config
67
+ MAGICPAY_API_URL Optional API base URL override
68
+ MAGICPAY_ENABLE_MOCK_SECRETS Enable local mock secret storage for dev/regression flows
69
+ MAGICPAY_MOCK_SECRET_STORE_PATH Optional override for mock stored-secret catalog path`;
70
+ }
71
+ function ensureMagicpayCommandName() {
72
+ process.env.MAGICPAY_COMMAND = process.env.MAGICPAY_COMMAND?.trim() || 'magicpay';
73
+ }
74
+ function getCommand(argv = process.argv) {
75
+ const rawArgs = argv.slice(2);
76
+ if (rawArgs.length === 0 || rawArgs[0] === '--help') {
77
+ info(usageText());
78
+ }
79
+ if (rawArgs[0] === '--version') {
80
+ info(readCurrentPackageVersion());
81
+ }
82
+ const command = rawArgs[0];
83
+ return {
84
+ command,
85
+ args: rawArgs.slice(1),
86
+ };
87
+ }
88
+ function getFlag(args, flag) {
89
+ const idx = args.indexOf(flag);
90
+ if (idx === -1 || idx + 1 >= args.length) {
91
+ return undefined;
92
+ }
93
+ return args[idx + 1];
94
+ }
95
+ function getPositional(args, valueFlags = []) {
96
+ const valueFlagSet = new Set(valueFlags);
97
+ for (let i = 0; i < args.length; i += 1) {
98
+ const arg = args[i];
99
+ if (arg.startsWith('--')) {
100
+ if (valueFlagSet.has(arg)) {
101
+ i += 1;
102
+ }
103
+ continue;
104
+ }
105
+ return arg;
106
+ }
107
+ return undefined;
108
+ }
109
+ function getPositionals(args, valueFlags = []) {
110
+ const valueFlagSet = new Set(valueFlags);
111
+ const values = [];
112
+ for (let i = 0; i < args.length; i += 1) {
113
+ const arg = args[i];
114
+ if (arg.startsWith('--')) {
115
+ if (valueFlagSet.has(arg)) {
116
+ i += 1;
117
+ }
118
+ continue;
119
+ }
120
+ values.push(arg);
121
+ }
122
+ return values;
123
+ }
124
+ function parseInitArgs(args) {
125
+ const apiKey = getPositional(args, ['--api-url']);
126
+ if (!apiKey) {
127
+ outputError('Usage: magicpay init <apiKey> [--api-url <url>]');
128
+ }
129
+ const apiUrl = getFlag(args, '--api-url');
130
+ const allowedFlags = new Set(['--api-url']);
131
+ for (let i = 0; i < args.length; i += 1) {
132
+ const arg = args[i];
133
+ if (!arg.startsWith('--')) {
134
+ continue;
135
+ }
136
+ if (!allowedFlags.has(arg)) {
137
+ outputError(`Unknown init option: ${arg}`);
138
+ }
139
+ i += 1;
140
+ }
141
+ return {
142
+ apiKey: apiKey,
143
+ apiUrl,
144
+ };
145
+ }
146
+ function parseStartSessionArgs(args) {
147
+ const nameParts = [];
148
+ let merchantName;
149
+ for (let i = 0; i < args.length; i += 1) {
150
+ const arg = args[i];
151
+ if (arg === '--merchant-name') {
152
+ const value = args[i + 1];
153
+ if (!value || value.startsWith('--')) {
154
+ outputError('Usage: magicpay start-session [name] [--merchant-name <name>]');
155
+ }
156
+ merchantName = value;
157
+ i += 1;
158
+ continue;
159
+ }
160
+ if (arg.startsWith('--')) {
161
+ outputError('Usage: magicpay start-session [name] [--merchant-name <name>]');
162
+ }
163
+ nameParts.push(arg);
164
+ }
165
+ return {
166
+ name: nameParts.join(' ').trim() || undefined,
167
+ merchantName,
168
+ };
169
+ }
170
+ function parseRequestSecretArgs(args) {
171
+ const positionals = getPositionals(args, ['--merchant-name']);
172
+ const [fillRef, storedSecretRef] = positionals;
173
+ const merchantName = getFlag(args, '--merchant-name');
174
+ if (!fillRef || !storedSecretRef || !merchantName) {
175
+ outputError('Usage: magicpay request-secret <fillRef> <storedSecretRef> --merchant-name <name>');
176
+ }
177
+ return {
178
+ fillRef: fillRef,
179
+ storedSecretRef: storedSecretRef,
180
+ merchantName: merchantName,
181
+ };
182
+ }
183
+ function parseAttachArgs(args) {
184
+ let cdpUrl;
185
+ let provider;
186
+ for (let i = 0; i < args.length; i += 1) {
187
+ const arg = args[i];
188
+ if (arg === '--provider') {
189
+ const value = args[i + 1];
190
+ if (!value || value.startsWith('--')) {
191
+ outputError('Usage: magicpay attach <cdp-url> [--provider <name>]');
192
+ }
193
+ provider = value;
194
+ i += 1;
195
+ continue;
196
+ }
197
+ if (arg.startsWith('--')) {
198
+ outputError(`Unknown attach option: ${arg}`);
199
+ }
200
+ if (cdpUrl) {
201
+ outputError('Usage: magicpay attach <cdp-url> [--provider <name>]');
202
+ }
203
+ cdpUrl = arg;
204
+ }
205
+ if (!cdpUrl) {
206
+ outputError('Usage: magicpay attach <cdp-url> [--provider <name>]');
207
+ }
208
+ return {
209
+ cdpUrl: cdpUrl,
210
+ ...(provider ? { provider } : {}),
211
+ };
212
+ }
213
+ function parseFindFormArgs(args) {
214
+ const allowedPurposes = new Set(['auto', 'login', 'identity', 'payment_card']);
215
+ let purpose = 'auto';
216
+ for (let i = 0; i < args.length; i += 1) {
217
+ const arg = args[i];
218
+ if (arg === '--purpose') {
219
+ const value = args[i + 1];
220
+ if (!value || value.startsWith('--')) {
221
+ outputError('Usage: magicpay find-form [--purpose <auto|login|identity|payment_card>]');
222
+ }
223
+ if (!allowedPurposes.has(value)) {
224
+ outputError('Usage: magicpay find-form [--purpose <auto|login|identity|payment_card>]');
225
+ }
226
+ purpose = value;
227
+ i += 1;
228
+ continue;
229
+ }
230
+ if (arg.startsWith('--')) {
231
+ outputError(`Unknown find-form option: ${arg}`);
232
+ }
233
+ outputError('Usage: magicpay find-form [--purpose <auto|login|identity|payment_card>]');
234
+ }
235
+ return { purpose };
236
+ }
237
+ function requireLaunchedBrowserSessionRecord(command) {
238
+ const session = loadMagicPaySession() ?? loadMagicPayBrowserSession();
239
+ if (session) {
240
+ return session;
241
+ }
242
+ return outputJSON({
243
+ success: false,
244
+ error: 'browser_session_required',
245
+ outcomeType: 'blocked',
246
+ message: `The \`${command}\` command requires an active browser session.`,
247
+ reason: 'No persisted browser session was found. Run `magicpay attach <cdp-url>` first.',
248
+ });
249
+ }
250
+ function requireWorkflowSessionRecord(command) {
251
+ const session = loadMagicPaySession();
252
+ if (!session) {
253
+ return outputJSON({
254
+ success: false,
255
+ error: 'browser_session_required',
256
+ outcomeType: 'blocked',
257
+ message: `The \`${command}\` command requires an active browser session.`,
258
+ reason: 'No persisted browser session was found. Run `magicpay attach <cdp-url>` first.',
259
+ });
260
+ }
261
+ if (session.intentSessionId && session.activeRunId) {
262
+ return session;
263
+ }
264
+ if (!session.intentSessionId) {
265
+ return outputJSON({
266
+ success: false,
267
+ error: 'workflow_session_required',
268
+ outcomeType: 'blocked',
269
+ message: `The \`${command}\` command requires an active workflow session.`,
270
+ reason: 'A browser session is loaded, but no workflow session is active for it. Run `magicpay start-session` first.',
271
+ });
272
+ }
273
+ return outputJSON({
274
+ success: false,
275
+ error: 'workflow_session_required',
276
+ outcomeType: 'blocked',
277
+ message: `The \`${command}\` command requires an active workflow session.`,
278
+ reason: 'The current workflow session is missing its local run binding. Run `magicpay start-session` again to re-bind the current browser session.',
279
+ });
280
+ }
281
+ export async function main(argv = process.argv) {
282
+ ensureMagicpayCommandName();
283
+ const parsed = getCommand(argv);
284
+ if (!parsed) {
285
+ process.exit(1);
286
+ }
287
+ const { command, args } = parsed;
288
+ if (!KNOWN_COMMANDS.has(command)) {
289
+ outputError(`Unknown command: ${command}\n\n${usageText()}`);
290
+ }
291
+ switch (command) {
292
+ case 'init': {
293
+ const initArgs = parseInitArgs(args);
294
+ outputJSON(init(initArgs.apiKey, initArgs.apiUrl));
295
+ return;
296
+ }
297
+ case 'status': {
298
+ outputJSON(await status());
299
+ return;
300
+ }
301
+ case 'attach': {
302
+ const attachArgs = parseAttachArgs(args);
303
+ outputJSON(await attach(attachArgs.cdpUrl, {
304
+ ...(attachArgs.provider ? { provider: attachArgs.provider } : {}),
305
+ }));
306
+ return;
307
+ }
308
+ case 'start-session': {
309
+ const startSessionArgs = parseStartSessionArgs(args);
310
+ outputJSON(await startSession(startSessionArgs.name, {
311
+ merchantName: startSessionArgs.merchantName,
312
+ }));
313
+ return;
314
+ }
315
+ case 'end-session': {
316
+ outputJSON(await endSession(requireWorkflowSessionRecord(command)));
317
+ return;
318
+ }
319
+ case 'find-form': {
320
+ const findFormArgs = parseFindFormArgs(args);
321
+ outputJSON(await findForm(requireLaunchedBrowserSessionRecord(command), {
322
+ purpose: findFormArgs.purpose,
323
+ }));
324
+ return;
325
+ }
326
+ case 'get-secrets-catalog': {
327
+ outputJSON(await getSecretsCatalog(requireWorkflowSessionRecord(command), getPositional(args)));
328
+ return;
329
+ }
330
+ case 'request-secret': {
331
+ const requestSecretArgs = parseRequestSecretArgs(args);
332
+ outputJSON(await requestSecret(requireWorkflowSessionRecord(command), requestSecretArgs.fillRef, requestSecretArgs.storedSecretRef, requestSecretArgs.merchantName));
333
+ return;
334
+ }
335
+ case 'mock-approve-secret': {
336
+ const requestId = getPositional(args);
337
+ if (!requestId) {
338
+ outputError('Usage: magicpay mock-approve-secret <requestId>');
339
+ }
340
+ outputJSON(await mockApproveSecret(requestId));
341
+ return;
342
+ }
343
+ case 'mock-deny-secret': {
344
+ const requestId = getPositional(args);
345
+ if (!requestId) {
346
+ outputError('Usage: magicpay mock-deny-secret <requestId>');
347
+ }
348
+ outputJSON(await mockDenySecret(requestId));
349
+ return;
350
+ }
351
+ case 'poll-secret': {
352
+ const requestId = getPositional(args);
353
+ if (!requestId) {
354
+ outputError('Usage: magicpay poll-secret <requestId>');
355
+ }
356
+ outputJSON(await pollSecret(requireWorkflowSessionRecord(command), requestId));
357
+ return;
358
+ }
359
+ case 'fill-secret': {
360
+ const positionals = getPositionals(args);
361
+ const [fillRef, requestId] = positionals;
362
+ if (!fillRef || !requestId) {
363
+ outputError('Usage: magicpay fill-secret <fillRef> <requestId>');
364
+ }
365
+ outputJSON(await fillSecret(requireWorkflowSessionRecord(command), fillRef, requestId));
366
+ return;
367
+ }
368
+ case 'submit-form': {
369
+ const fillRef = getPositional(args);
370
+ if (!fillRef) {
371
+ outputError('Usage: magicpay submit-form <fillRef>');
372
+ }
373
+ outputJSON(await submitForm(requireLaunchedBrowserSessionRecord(command), fillRef));
374
+ return;
375
+ }
376
+ }
377
+ }
378
+ export function isDirectExecution(metaUrl, argv = process.argv) {
379
+ const entry = argv[1];
380
+ if (!entry) {
381
+ return false;
382
+ }
383
+ try {
384
+ return realpathSync(entry) === realpathSync(fileURLToPath(metaUrl));
385
+ }
386
+ catch {
387
+ return false;
388
+ }
389
+ }
390
+ if (isDirectExecution(import.meta.url)) {
391
+ main()
392
+ .then(() => {
393
+ process.exit(0);
394
+ })
395
+ .catch((err) => {
396
+ fatal(err instanceof Error ? err.message : String(err));
397
+ });
398
+ }
@@ -0,0 +1,37 @@
1
+ import type { ClaimSecretRequestResult, CreateSecretRequestInput, CreateSecretRequestResult, SecretRequestHintField, SecretRequestPollOutcome, SecretRequestSnapshot } from '@mercuryo-ai/magicpay-sdk';
2
+ type MockClaimRecord = {
3
+ claimId: string;
4
+ issuedAt: string;
5
+ };
6
+ export interface MockSecretRequestRecord extends SecretRequestSnapshot {
7
+ sessionId: string;
8
+ purpose: string;
9
+ fields: SecretRequestHintField[];
10
+ claims: MockClaimRecord[];
11
+ approvedAt?: string;
12
+ }
13
+ type MockSecretRequestStore = {
14
+ version: 2;
15
+ nextRequest: number;
16
+ requests: Record<string, MockSecretRequestRecord>;
17
+ };
18
+ type LifecycleOptions = {
19
+ now?: string;
20
+ };
21
+ declare function readMockStore(): MockSecretRequestStore;
22
+ declare function defaultExpiry(createdAt: string): string;
23
+ export declare function setMockSecretRequestStorePathForTests(storePath?: string): void;
24
+ export declare function createOrReuseMockSecretRequest(input: CreateSecretRequestInput, options?: LifecycleOptions): CreateSecretRequestResult;
25
+ export declare function pollMockSecretRequest(sessionId: string, requestId: string, options?: LifecycleOptions): SecretRequestPollOutcome;
26
+ export declare function approveMockSecretRequest(requestId: string, options?: LifecycleOptions): MockSecretRequestRecord;
27
+ export declare function denyMockSecretRequest(requestId: string, options?: LifecycleOptions): MockSecretRequestRecord;
28
+ export declare function claimMockSecretRequest(sessionId: string, requestId: string, claimId: string, options: LifecycleOptions & {
29
+ resolveValues: (storedSecretRef: string) => Record<string, string> | null;
30
+ }): ClaimSecretRequestResult;
31
+ export declare function resetMockSecretRequestStore(): void;
32
+ export declare const __testMockSecretCabinet: {
33
+ defaultExpiry: typeof defaultExpiry;
34
+ readMockStore: typeof readMockStore;
35
+ };
36
+ export {};
37
+ //# sourceMappingURL=mock-secret-cabinet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-secret-cabinet.d.ts","sourceRoot":"","sources":["../src/mock-secret-cabinet.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,wBAAwB,EACxB,wBAAwB,EACxB,yBAAyB,EACzB,sBAAsB,EACtB,wBAAwB,EAExB,qBAAqB,EAItB,MAAM,2BAA2B,CAAC;AAMnC,KAAK,eAAe,GAAG;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,WAAW,uBAAwB,SAAQ,qBAAqB;IACpE,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,sBAAsB,EAAE,CAAC;IACjC,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,KAAK,sBAAsB,GAAG;IAC5B,OAAO,EAAE,CAAC,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;CACnD,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAyBF,iBAAS,aAAa,IAAI,sBAAsB,CAwB/C;AAWD,iBAAS,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEhD;AA8ID,wBAAgB,qCAAqC,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAE9E;AAED,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,wBAAwB,EAC/B,OAAO,GAAE,gBAAqB,GAC7B,yBAAyB,CA8D3B;AAED,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,gBAAqB,GAC7B,wBAAwB,CAsB1B;AAqCD,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,gBAAqB,GAC7B,uBAAuB,CAEzB;AAED,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,gBAAqB,GAC7B,uBAAuB,CAEzB;AAED,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,gBAAgB,GAAG;IAC1B,aAAa,EAAE,CAAC,eAAe,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;CAC3E,GACA,wBAAwB,CAiD1B;AAED,wBAAgB,2BAA2B,IAAI,IAAI,CAKlD;AAED,eAAO,MAAM,uBAAuB;;;CAGnC,CAAC"}