@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.
- package/README.md +56 -0
- package/dist/agentbrowse-assistive.d.ts +2 -0
- package/dist/agentbrowse-assistive.d.ts.map +1 -0
- package/dist/agentbrowse-assistive.js +66 -0
- package/dist/assistive-llm-client.d.ts +13 -0
- package/dist/assistive-llm-client.d.ts.map +1 -0
- package/dist/assistive-llm-client.js +152 -0
- package/dist/browser-bridge/act.d.ts +5 -0
- package/dist/browser-bridge/act.d.ts.map +1 -0
- package/dist/browser-bridge/act.js +8 -0
- package/dist/browser-bridge/observe.d.ts +5 -0
- package/dist/browser-bridge/observe.d.ts.map +1 -0
- package/dist/browser-bridge/observe.js +53 -0
- package/dist/browser-home.d.ts +7 -0
- package/dist/browser-home.d.ts.map +1 -0
- package/dist/browser-home.js +34 -0
- package/dist/commands/act.d.ts +5 -0
- package/dist/commands/act.d.ts.map +1 -0
- package/dist/commands/act.js +8 -0
- package/dist/commands/attach.d.ts +4 -0
- package/dist/commands/attach.d.ts.map +1 -0
- package/dist/commands/attach.js +10 -0
- package/dist/commands/browser-status.d.ts +5 -0
- package/dist/commands/browser-status.d.ts.map +1 -0
- package/dist/commands/browser-status.js +5 -0
- package/dist/commands/close.d.ts +4 -0
- package/dist/commands/close.d.ts.map +1 -0
- package/dist/commands/close.js +11 -0
- package/dist/commands/end-session.d.ts +22 -0
- package/dist/commands/end-session.d.ts.map +1 -0
- package/dist/commands/end-session.js +104 -0
- package/dist/commands/extract.d.ts +4 -0
- package/dist/commands/extract.d.ts.map +1 -0
- package/dist/commands/extract.js +14 -0
- package/dist/commands/fill-secret.d.ts +10 -0
- package/dist/commands/fill-secret.d.ts.map +1 -0
- package/dist/commands/fill-secret.js +483 -0
- package/dist/commands/find-form.d.ts +57 -0
- package/dist/commands/find-form.d.ts.map +1 -0
- package/dist/commands/find-form.js +138 -0
- package/dist/commands/get-secrets-catalog.d.ts +13 -0
- package/dist/commands/get-secrets-catalog.d.ts.map +1 -0
- package/dist/commands/get-secrets-catalog.js +103 -0
- package/dist/commands/init.d.ts +10 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +28 -0
- package/dist/commands/launch.d.ts +4 -0
- package/dist/commands/launch.d.ts.map +1 -0
- package/dist/commands/launch.js +10 -0
- package/dist/commands/mock-approve-secret.d.ts +21 -0
- package/dist/commands/mock-approve-secret.d.ts.map +1 -0
- package/dist/commands/mock-approve-secret.js +69 -0
- package/dist/commands/mock-deny-secret.d.ts +21 -0
- package/dist/commands/mock-deny-secret.d.ts.map +1 -0
- package/dist/commands/mock-deny-secret.js +69 -0
- package/dist/commands/navigate.d.ts +4 -0
- package/dist/commands/navigate.d.ts.map +1 -0
- package/dist/commands/navigate.js +9 -0
- package/dist/commands/observe.d.ts +5 -0
- package/dist/commands/observe.d.ts.map +1 -0
- package/dist/commands/observe.js +53 -0
- package/dist/commands/poll-secret.d.ts +13 -0
- package/dist/commands/poll-secret.d.ts.map +1 -0
- package/dist/commands/poll-secret.js +87 -0
- package/dist/commands/request-secret.d.ts +15 -0
- package/dist/commands/request-secret.d.ts.map +1 -0
- package/dist/commands/request-secret.js +235 -0
- package/dist/commands/screenshot.d.ts +4 -0
- package/dist/commands/screenshot.d.ts.map +1 -0
- package/dist/commands/screenshot.js +11 -0
- package/dist/commands/solve-captcha.d.ts +19 -0
- package/dist/commands/solve-captcha.d.ts.map +1 -0
- package/dist/commands/solve-captcha.js +63 -0
- package/dist/commands/start-session.d.ts +28 -0
- package/dist/commands/start-session.d.ts.map +1 -0
- package/dist/commands/start-session.js +298 -0
- package/dist/commands/status.d.ts +27 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +51 -0
- package/dist/commands/submit-form.d.ts +36 -0
- package/dist/commands/submit-form.d.ts.map +1 -0
- package/dist/commands/submit-form.js +242 -0
- package/dist/config.d.ts +2 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +1 -0
- package/dist/fillable-form-state.d.ts +5 -0
- package/dist/fillable-form-state.d.ts.map +1 -0
- package/dist/fillable-form-state.js +22 -0
- package/dist/gateway.d.ts +10 -0
- package/dist/gateway.d.ts.map +1 -0
- package/dist/gateway.js +49 -0
- package/dist/generated/build-config.d.ts +2 -0
- package/dist/generated/build-config.d.ts.map +1 -0
- package/dist/generated/build-config.js +2 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +398 -0
- package/dist/mock-secret-cabinet.d.ts +37 -0
- package/dist/mock-secret-cabinet.d.ts.map +1 -0
- package/dist/mock-secret-cabinet.js +321 -0
- package/dist/mock-secret-store.d.ts +12 -0
- package/dist/mock-secret-store.d.ts.map +1 -0
- package/dist/mock-secret-store.js +108 -0
- package/dist/mock-stored-secrets.json +180 -0
- package/dist/otel-exporter.d.ts +58 -0
- package/dist/otel-exporter.d.ts.map +1 -0
- package/dist/otel-exporter.js +241 -0
- package/dist/otel-projector.d.ts +59 -0
- package/dist/otel-projector.d.ts.map +1 -0
- package/dist/otel-projector.js +325 -0
- package/dist/output.d.ts +10 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +29 -0
- package/dist/package-version.d.ts +2 -0
- package/dist/package-version.d.ts.map +1 -0
- package/dist/package-version.js +14 -0
- package/dist/protected-exposure.d.ts +4 -0
- package/dist/protected-exposure.d.ts.map +1 -0
- package/dist/protected-exposure.js +17 -0
- package/dist/request-output.d.ts +4 -0
- package/dist/request-output.d.ts.map +1 -0
- package/dist/request-output.js +27 -0
- package/dist/run-store.d.ts +130 -0
- package/dist/run-store.d.ts.map +1 -0
- package/dist/run-store.js +245 -0
- package/dist/secret-backend.d.ts +28 -0
- package/dist/secret-backend.d.ts.map +1 -0
- package/dist/secret-backend.js +335 -0
- package/dist/secret-state.d.ts +7 -0
- package/dist/secret-state.d.ts.map +1 -0
- package/dist/secret-state.js +26 -0
- package/dist/session-backend.d.ts +34 -0
- package/dist/session-backend.d.ts.map +1 -0
- package/dist/session-backend.js +36 -0
- package/dist/update-check.d.ts +13 -0
- package/dist/update-check.d.ts.map +1 -0
- package/dist/update-check.js +175 -0
- package/dist/workflow-session-completion.d.ts +32 -0
- package/dist/workflow-session-completion.d.ts.map +1 -0
- package/dist/workflow-session-completion.js +149 -0
- package/dist/workflow-state.d.ts +2 -0
- package/dist/workflow-state.d.ts.map +1 -0
- package/dist/workflow-state.js +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { enrichObservedFormsForUrl } from '@mercuryo-ai/magicpay-sdk/agentbrowse';
|
|
2
|
+
import { observe } from '../browser-bridge/observe.js';
|
|
3
|
+
import { listFillableForms } from '../fillable-form-state.js';
|
|
4
|
+
import { getResolvedSubmitTarget, } from './submit-form.js';
|
|
5
|
+
function normalizePurpose(purpose) {
|
|
6
|
+
return purpose ?? 'auto';
|
|
7
|
+
}
|
|
8
|
+
function readHost(url) {
|
|
9
|
+
if (!url) {
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
return new URL(url).host;
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function readString(value) {
|
|
20
|
+
return typeof value === 'string' ? value : undefined;
|
|
21
|
+
}
|
|
22
|
+
function toFindFormView(session, url) {
|
|
23
|
+
const runtimeForms = listFillableForms(session).filter((form) => form.presence !== 'absent');
|
|
24
|
+
const catalogByHost = 'secretCatalogByHost' in session &&
|
|
25
|
+
session.secretCatalogByHost &&
|
|
26
|
+
typeof session.secretCatalogByHost === 'object'
|
|
27
|
+
? session.secretCatalogByHost
|
|
28
|
+
: undefined;
|
|
29
|
+
const forms = url
|
|
30
|
+
? enrichObservedFormsForUrl(runtimeForms, catalogByHost, url)
|
|
31
|
+
: runtimeForms.map((form) => ({
|
|
32
|
+
...form,
|
|
33
|
+
storedSecretCandidates: [],
|
|
34
|
+
}));
|
|
35
|
+
return forms.map((form) => {
|
|
36
|
+
const submitTarget = getResolvedSubmitTarget(session, form.fillRef);
|
|
37
|
+
return {
|
|
38
|
+
...(submitTarget ? { submit: submitTarget } : {}),
|
|
39
|
+
fillRef: form.fillRef,
|
|
40
|
+
...(form.scopeRef ? { scopeRef: form.scopeRef } : {}),
|
|
41
|
+
purpose: form.purpose,
|
|
42
|
+
presence: form.presence === 'unknown' ? 'unknown' : 'present',
|
|
43
|
+
observedAt: form.observedAt,
|
|
44
|
+
fields: form.fields.map((field) => ({
|
|
45
|
+
fieldKey: field.fieldKey,
|
|
46
|
+
targetRef: field.targetRef,
|
|
47
|
+
...(field.label ? { label: field.label } : {}),
|
|
48
|
+
...(typeof field.required === 'boolean' ? { required: field.required } : {}),
|
|
49
|
+
...(field.valueHint ? { valueHint: field.valueHint } : {}),
|
|
50
|
+
})),
|
|
51
|
+
storedSecretCandidates: form.storedSecretCandidates.map((candidate) => ({
|
|
52
|
+
storedSecretRef: candidate.storedSecretRef,
|
|
53
|
+
kind: candidate.kind,
|
|
54
|
+
scope: candidate.scope,
|
|
55
|
+
displayName: candidate.displayName,
|
|
56
|
+
matchConfidence: candidate.matchConfidence,
|
|
57
|
+
intentRequired: candidate.intentRequired,
|
|
58
|
+
})),
|
|
59
|
+
};
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
function selectionReasonFor(purpose) {
|
|
63
|
+
return purpose === 'auto'
|
|
64
|
+
? 'single_supported_form_on_page'
|
|
65
|
+
: 'single_matching_form_for_requested_purpose';
|
|
66
|
+
}
|
|
67
|
+
export async function findForm(session, options = {}) {
|
|
68
|
+
const requestedPurpose = normalizePurpose(options.purpose);
|
|
69
|
+
const observed = await observe(session);
|
|
70
|
+
const observedPageRef = readString('pageRef' in observed ? observed.pageRef : undefined);
|
|
71
|
+
const observedUrl = readString('url' in observed ? observed.url : undefined);
|
|
72
|
+
const observedTitle = readString('title' in observed ? observed.title : undefined);
|
|
73
|
+
if (!observed.success) {
|
|
74
|
+
return {
|
|
75
|
+
success: false,
|
|
76
|
+
outcomeType: 'blocked',
|
|
77
|
+
error: observed.error === 'browser_connection_failed'
|
|
78
|
+
? 'browser_connection_failed'
|
|
79
|
+
: 'page_resolution_failed',
|
|
80
|
+
message: 'Protected form discovery could not inspect the current page.',
|
|
81
|
+
reason: observed.reason,
|
|
82
|
+
...(observedPageRef ? { pageRef: observedPageRef } : {}),
|
|
83
|
+
nextAction: observed.error === 'browser_connection_failed' ? 'attach' : 'ask-user',
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
const forms = toFindFormView(session, observedUrl);
|
|
87
|
+
const matchingForms = requestedPurpose === 'auto'
|
|
88
|
+
? forms
|
|
89
|
+
: forms.filter((form) => form.purpose === requestedPurpose);
|
|
90
|
+
if (matchingForms.length === 0) {
|
|
91
|
+
return {
|
|
92
|
+
success: false,
|
|
93
|
+
outcomeType: 'blocked',
|
|
94
|
+
error: 'protected_form_not_found',
|
|
95
|
+
message: 'No supported protected form was found on the current page.',
|
|
96
|
+
reason: requestedPurpose === 'auto'
|
|
97
|
+
? 'MagicPay did not detect a supported login, identity, or payment-card form on the current page.'
|
|
98
|
+
: `MagicPay did not detect a supported ${requestedPurpose} form on the current page.`,
|
|
99
|
+
...(observedPageRef ? { pageRef: observedPageRef } : {}),
|
|
100
|
+
...(observedUrl ? { url: observedUrl } : {}),
|
|
101
|
+
...(observedTitle ? { title: observedTitle } : {}),
|
|
102
|
+
purpose: requestedPurpose,
|
|
103
|
+
nextAction: 'ask-user',
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
if (matchingForms.length > 1) {
|
|
107
|
+
return {
|
|
108
|
+
success: false,
|
|
109
|
+
outcomeType: 'blocked',
|
|
110
|
+
error: 'protected_form_ambiguous',
|
|
111
|
+
message: 'Multiple supported protected forms were found, so MagicPay will not guess.',
|
|
112
|
+
reason: requestedPurpose === 'auto'
|
|
113
|
+
? 'More than one supported protected form is currently present on the page.'
|
|
114
|
+
: `More than one supported ${requestedPurpose} form is currently present on the page.`,
|
|
115
|
+
...(observedPageRef ? { pageRef: observedPageRef } : {}),
|
|
116
|
+
...(observedUrl ? { url: observedUrl } : {}),
|
|
117
|
+
...(observedTitle ? { title: observedTitle } : {}),
|
|
118
|
+
purpose: requestedPurpose,
|
|
119
|
+
forms: matchingForms,
|
|
120
|
+
nextAction: 'ask-user',
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
const selectedForm = matchingForms[0];
|
|
124
|
+
return {
|
|
125
|
+
success: true,
|
|
126
|
+
outcomeType: 'form_found',
|
|
127
|
+
pageRef: observedPageRef ?? session.runtime?.currentPageRef ?? 'p0',
|
|
128
|
+
url: observedUrl ?? '',
|
|
129
|
+
title: observedTitle ?? '',
|
|
130
|
+
...(readHost(observedUrl) ? { host: readHost(observedUrl) } : {}),
|
|
131
|
+
purpose: requestedPurpose === 'auto' ? selectedForm.purpose : requestedPurpose,
|
|
132
|
+
formCount: matchingForms.length,
|
|
133
|
+
selectedFillRef: selectedForm.fillRef,
|
|
134
|
+
selectionReason: selectionReasonFor(requestedPurpose),
|
|
135
|
+
nextAction: 'request-secret',
|
|
136
|
+
forms: matchingForms,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { SecretCatalog } from '@mercuryo-ai/magicpay-sdk';
|
|
2
|
+
import type { MagicPaySession } from '../workflow-state.js';
|
|
3
|
+
export type GetSecretsCatalogResult = ({
|
|
4
|
+
success: true;
|
|
5
|
+
} & SecretCatalog) | {
|
|
6
|
+
success: false;
|
|
7
|
+
error: 'workflow_session_required' | 'secret_sync_missing_url';
|
|
8
|
+
outcomeType: 'blocked';
|
|
9
|
+
message: string;
|
|
10
|
+
reason: string;
|
|
11
|
+
};
|
|
12
|
+
export declare function getSecretsCatalog(session: MagicPaySession, urlOrHost?: string): Promise<GetSecretsCatalogResult>;
|
|
13
|
+
//# sourceMappingURL=get-secrets-catalog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-secrets-catalog.d.ts","sourceRoot":"","sources":["../../src/commands/get-secrets-catalog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAM5D,MAAM,MAAM,uBAAuB,GAC/B,CAAC;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GAAG,aAAa,CAAC,GACnC;IACE,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,2BAA2B,GAAG,yBAAyB,CAAC;IAC/D,WAAW,EAAE,SAAS,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAyBN,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,eAAe,EACxB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,uBAAuB,CAAC,CAmFlC"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { exportRunStepToOtlpHttpJsonBestEffort } from '../otel-exporter.js';
|
|
2
|
+
import { finishRunStep, startRunStep } from '../run-store.js';
|
|
3
|
+
import { getSecretBackend } from '../secret-backend.js';
|
|
4
|
+
import { saveSecretCatalog } from '../secret-state.js';
|
|
5
|
+
import { saveMagicPaySession } from '../workflow-state.js';
|
|
6
|
+
function getCurrentSessionPageUrl(session) {
|
|
7
|
+
const pageRef = session.runtime?.currentPageRef ?? 'p0';
|
|
8
|
+
return session.runtime?.pages?.[pageRef]?.url ?? null;
|
|
9
|
+
}
|
|
10
|
+
function formatUnknownError(error) {
|
|
11
|
+
if (error instanceof Error) {
|
|
12
|
+
return error.message;
|
|
13
|
+
}
|
|
14
|
+
if (typeof error === 'string') {
|
|
15
|
+
return error;
|
|
16
|
+
}
|
|
17
|
+
if (error && typeof error === 'object') {
|
|
18
|
+
try {
|
|
19
|
+
return JSON.stringify(error);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return Object.prototype.toString.call(error);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return String(error);
|
|
26
|
+
}
|
|
27
|
+
export async function getSecretsCatalog(session, urlOrHost) {
|
|
28
|
+
const pageRef = session.runtime?.currentPageRef ?? 'p0';
|
|
29
|
+
const step = session.activeRunId
|
|
30
|
+
? startRunStep({
|
|
31
|
+
runId: session.activeRunId,
|
|
32
|
+
command: 'get-secrets-catalog',
|
|
33
|
+
input: {
|
|
34
|
+
urlOrHost: urlOrHost ?? null,
|
|
35
|
+
},
|
|
36
|
+
refs: {
|
|
37
|
+
pageRef,
|
|
38
|
+
},
|
|
39
|
+
})
|
|
40
|
+
: null;
|
|
41
|
+
const finalizeStep = async (result) => {
|
|
42
|
+
if (step) {
|
|
43
|
+
finishRunStep({
|
|
44
|
+
runId: step.runId,
|
|
45
|
+
stepId: step.stepId,
|
|
46
|
+
success: result.success,
|
|
47
|
+
...('outcomeType' in result && result.outcomeType
|
|
48
|
+
? { outcomeType: result.outcomeType }
|
|
49
|
+
: {}),
|
|
50
|
+
...('message' in result && typeof result.message === 'string'
|
|
51
|
+
? { message: result.message }
|
|
52
|
+
: {}),
|
|
53
|
+
...('reason' in result && typeof result.reason === 'string'
|
|
54
|
+
? { reason: result.reason }
|
|
55
|
+
: {}),
|
|
56
|
+
});
|
|
57
|
+
await exportRunStepToOtlpHttpJsonBestEffort(step.runId, step.stepId);
|
|
58
|
+
}
|
|
59
|
+
return result;
|
|
60
|
+
};
|
|
61
|
+
try {
|
|
62
|
+
if (!session.intentSessionId) {
|
|
63
|
+
return finalizeStep({
|
|
64
|
+
success: false,
|
|
65
|
+
error: 'workflow_session_required',
|
|
66
|
+
outcomeType: 'blocked',
|
|
67
|
+
message: 'Stored-secret sync could not start because no active workflow session is bound to this browser.',
|
|
68
|
+
reason: 'Run `magicpay start-session` first so MagicPay can scope catalog access to the current workflow session.',
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
const syncInput = urlOrHost ?? getCurrentSessionPageUrl(session);
|
|
72
|
+
if (!syncInput) {
|
|
73
|
+
return finalizeStep({
|
|
74
|
+
success: false,
|
|
75
|
+
error: 'secret_sync_missing_url',
|
|
76
|
+
outcomeType: 'blocked',
|
|
77
|
+
message: 'Stored-secret sync could not start because there is no current URL.',
|
|
78
|
+
reason: 'Provide a URL explicitly or create page context first by navigating or observing.',
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
const snapshot = await getSecretBackend().fetchSecretCatalog(session.intentSessionId, syncInput);
|
|
82
|
+
saveSecretCatalog(session, snapshot);
|
|
83
|
+
saveMagicPaySession(session);
|
|
84
|
+
return finalizeStep({
|
|
85
|
+
success: true,
|
|
86
|
+
...snapshot,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
if (step) {
|
|
91
|
+
finishRunStep({
|
|
92
|
+
runId: step.runId,
|
|
93
|
+
stepId: step.stepId,
|
|
94
|
+
success: false,
|
|
95
|
+
outcomeType: 'secret_sync_failed',
|
|
96
|
+
message: 'Stored-secret sync failed.',
|
|
97
|
+
reason: formatUnknownError(error),
|
|
98
|
+
});
|
|
99
|
+
await exportRunStepToOtlpHttpJsonBestEffort(step.runId, step.stepId);
|
|
100
|
+
}
|
|
101
|
+
throw error;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,IAAI,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE;QACP,gBAAgB,EAAE,IAAI,CAAC;QACvB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAMD,wBAAgB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,UAAU,CAwBhE"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { getConfigPath, readConfig, writeConfig } from '../config.js';
|
|
2
|
+
import { DEFAULT_MAGICPAY_API_URL } from '../generated/build-config.js';
|
|
3
|
+
function normalizeApiUrl(value) {
|
|
4
|
+
return value.replace(/\/$/, '');
|
|
5
|
+
}
|
|
6
|
+
export function init(apiKey, apiUrl) {
|
|
7
|
+
const config = readConfig();
|
|
8
|
+
const normalizedApiKey = apiKey.trim();
|
|
9
|
+
const normalizedApiUrl = apiUrl?.trim()
|
|
10
|
+
? normalizeApiUrl(apiUrl.trim())
|
|
11
|
+
: DEFAULT_MAGICPAY_API_URL;
|
|
12
|
+
writeConfig({
|
|
13
|
+
...config,
|
|
14
|
+
gateway: {
|
|
15
|
+
...(config.gateway ?? {}),
|
|
16
|
+
apiKey: normalizedApiKey,
|
|
17
|
+
apiUrl: normalizedApiUrl,
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
return {
|
|
21
|
+
success: true,
|
|
22
|
+
configPath: getConfigPath(),
|
|
23
|
+
gateway: {
|
|
24
|
+
apiKeyConfigured: true,
|
|
25
|
+
apiUrl: normalizedApiUrl,
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launch.d.ts","sourceRoot":"","sources":["../../src/commands/launch.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,YAAY,EAClB,MAAM,0BAA0B,CAAC;AAQlC,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,CAAC;AAE5C,wBAAsB,MAAM,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAOzF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { close as closeBrowser, launch as launchBrowser, } from '@mercuryo-ai/agentbrowse';
|
|
2
|
+
import { loadMagicPayBrowserSession, loadMagicPaySession, saveMagicPaySession, } from '../workflow-state.js';
|
|
3
|
+
export async function launch(url, options) {
|
|
4
|
+
await closeBrowser(loadMagicPaySession() ?? loadMagicPayBrowserSession());
|
|
5
|
+
const result = await launchBrowser(url, options);
|
|
6
|
+
if (result.success) {
|
|
7
|
+
saveMagicPaySession(result.session);
|
|
8
|
+
}
|
|
9
|
+
return result;
|
|
10
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type MockApproveSecretResult = {
|
|
2
|
+
success: true;
|
|
3
|
+
requestId: string;
|
|
4
|
+
sessionId: string;
|
|
5
|
+
status: 'fulfilled';
|
|
6
|
+
updatedAt: string;
|
|
7
|
+
resolvedAt?: string;
|
|
8
|
+
expiresAt?: string;
|
|
9
|
+
message: string;
|
|
10
|
+
reason: string;
|
|
11
|
+
} | {
|
|
12
|
+
success: false;
|
|
13
|
+
error: 'mock_secret_backend_disabled' | 'secret_request_not_found' | 'secret_request_expired' | 'secret_request_not_pending' | 'mock_secret_request_approval_failed';
|
|
14
|
+
outcomeType: 'blocked' | 'failed';
|
|
15
|
+
message: string;
|
|
16
|
+
reason: string;
|
|
17
|
+
requestId: string;
|
|
18
|
+
requestStatus?: string;
|
|
19
|
+
};
|
|
20
|
+
export declare function mockApproveSecret(requestId: string): Promise<MockApproveSecretResult>;
|
|
21
|
+
//# sourceMappingURL=mock-approve-secret.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock-approve-secret.d.ts","sourceRoot":"","sources":["../../src/commands/mock-approve-secret.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,uBAAuB,GAC/B;IACE,OAAO,EAAE,IAAI,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,WAAW,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,GACD;IACE,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EACD,8BAA8B,GAC9B,0BAA0B,GAC1B,wBAAwB,GACxB,4BAA4B,GAC5B,qCAAqC,CAAC;IAC1C,WAAW,EAAE,SAAS,GAAG,QAAQ,CAAC;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEN,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAsE3F"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { approveMockSecretRequest, SecretBackendDisabledError, } from '../secret-backend.js';
|
|
2
|
+
export async function mockApproveSecret(requestId) {
|
|
3
|
+
try {
|
|
4
|
+
const result = approveMockSecretRequest(requestId);
|
|
5
|
+
return {
|
|
6
|
+
success: true,
|
|
7
|
+
requestId: result.requestId,
|
|
8
|
+
sessionId: result.sessionId,
|
|
9
|
+
status: 'fulfilled',
|
|
10
|
+
updatedAt: result.updatedAt,
|
|
11
|
+
...(result.resolvedAt ? { resolvedAt: result.resolvedAt } : {}),
|
|
12
|
+
...(result.expiresAt ? { expiresAt: result.expiresAt } : {}),
|
|
13
|
+
message: 'Mock secret request is approved and ready to fill.',
|
|
14
|
+
reason: 'MagicPay CLI marked the local mock secret request as fulfilled.',
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
if (error instanceof SecretBackendDisabledError) {
|
|
19
|
+
return {
|
|
20
|
+
success: false,
|
|
21
|
+
error: 'mock_secret_backend_disabled',
|
|
22
|
+
outcomeType: 'blocked',
|
|
23
|
+
message: 'Mock secret approval is unavailable.',
|
|
24
|
+
reason: error.message,
|
|
25
|
+
requestId,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
29
|
+
if (reason === 'secret_request_not_found') {
|
|
30
|
+
return {
|
|
31
|
+
success: false,
|
|
32
|
+
error: 'secret_request_not_found',
|
|
33
|
+
outcomeType: 'blocked',
|
|
34
|
+
message: 'Mock secret approval failed because the request does not exist.',
|
|
35
|
+
reason: 'MagicPay mock storage did not find a secret request for the provided request ID.',
|
|
36
|
+
requestId,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
if (reason === 'secret_request_expired') {
|
|
40
|
+
return {
|
|
41
|
+
success: false,
|
|
42
|
+
error: 'secret_request_expired',
|
|
43
|
+
outcomeType: 'blocked',
|
|
44
|
+
message: 'Mock secret approval failed because the request already expired.',
|
|
45
|
+
reason: 'MagicPay mock storage already considers this secret request expired.',
|
|
46
|
+
requestId,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
if (reason.startsWith('secret_request_not_pending:')) {
|
|
50
|
+
return {
|
|
51
|
+
success: false,
|
|
52
|
+
error: 'secret_request_not_pending',
|
|
53
|
+
outcomeType: 'blocked',
|
|
54
|
+
message: 'Mock secret approval failed because the request is no longer pending.',
|
|
55
|
+
reason: 'MagicPay mock storage can only approve pending secret requests.',
|
|
56
|
+
requestId,
|
|
57
|
+
requestStatus: reason.slice('secret_request_not_pending:'.length),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
success: false,
|
|
62
|
+
error: 'mock_secret_request_approval_failed',
|
|
63
|
+
outcomeType: 'failed',
|
|
64
|
+
message: 'Mock secret approval failed.',
|
|
65
|
+
reason,
|
|
66
|
+
requestId,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type MockDenySecretResult = {
|
|
2
|
+
success: true;
|
|
3
|
+
requestId: string;
|
|
4
|
+
sessionId: string;
|
|
5
|
+
status: 'denied';
|
|
6
|
+
updatedAt: string;
|
|
7
|
+
resolvedAt?: string;
|
|
8
|
+
expiresAt?: string;
|
|
9
|
+
message: string;
|
|
10
|
+
reason: string;
|
|
11
|
+
} | {
|
|
12
|
+
success: false;
|
|
13
|
+
error: 'mock_secret_backend_disabled' | 'secret_request_not_found' | 'secret_request_expired' | 'secret_request_not_pending' | 'mock_secret_request_denial_failed';
|
|
14
|
+
outcomeType: 'blocked' | 'failed';
|
|
15
|
+
message: string;
|
|
16
|
+
reason: string;
|
|
17
|
+
requestId: string;
|
|
18
|
+
requestStatus?: string;
|
|
19
|
+
};
|
|
20
|
+
export declare function mockDenySecret(requestId: string): Promise<MockDenySecretResult>;
|
|
21
|
+
//# sourceMappingURL=mock-deny-secret.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock-deny-secret.d.ts","sourceRoot":"","sources":["../../src/commands/mock-deny-secret.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,oBAAoB,GAC5B;IACE,OAAO,EAAE,IAAI,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,QAAQ,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,GACD;IACE,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EACD,8BAA8B,GAC9B,0BAA0B,GAC1B,wBAAwB,GACxB,4BAA4B,GAC5B,mCAAmC,CAAC;IACxC,WAAW,EAAE,SAAS,GAAG,QAAQ,CAAC;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEN,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAsErF"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { denyMockSecretRequest, SecretBackendDisabledError, } from '../secret-backend.js';
|
|
2
|
+
export async function mockDenySecret(requestId) {
|
|
3
|
+
try {
|
|
4
|
+
const result = denyMockSecretRequest(requestId);
|
|
5
|
+
return {
|
|
6
|
+
success: true,
|
|
7
|
+
requestId: result.requestId,
|
|
8
|
+
sessionId: result.sessionId,
|
|
9
|
+
status: 'denied',
|
|
10
|
+
updatedAt: result.updatedAt,
|
|
11
|
+
...(result.resolvedAt ? { resolvedAt: result.resolvedAt } : {}),
|
|
12
|
+
...(result.expiresAt ? { expiresAt: result.expiresAt } : {}),
|
|
13
|
+
message: 'Mock secret request is denied and cannot be used.',
|
|
14
|
+
reason: 'MagicPay CLI marked the local mock secret request as denied.',
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
if (error instanceof SecretBackendDisabledError) {
|
|
19
|
+
return {
|
|
20
|
+
success: false,
|
|
21
|
+
error: 'mock_secret_backend_disabled',
|
|
22
|
+
outcomeType: 'blocked',
|
|
23
|
+
message: 'Mock secret denial is unavailable.',
|
|
24
|
+
reason: error.message,
|
|
25
|
+
requestId,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
29
|
+
if (reason === 'secret_request_not_found') {
|
|
30
|
+
return {
|
|
31
|
+
success: false,
|
|
32
|
+
error: 'secret_request_not_found',
|
|
33
|
+
outcomeType: 'blocked',
|
|
34
|
+
message: 'Mock secret denial failed because the request does not exist.',
|
|
35
|
+
reason: 'MagicPay mock storage did not find a secret request for the provided request ID.',
|
|
36
|
+
requestId,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
if (reason === 'secret_request_expired') {
|
|
40
|
+
return {
|
|
41
|
+
success: false,
|
|
42
|
+
error: 'secret_request_expired',
|
|
43
|
+
outcomeType: 'blocked',
|
|
44
|
+
message: 'Mock secret denial failed because the request already expired.',
|
|
45
|
+
reason: 'MagicPay mock storage already considers this secret request expired.',
|
|
46
|
+
requestId,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
if (reason.startsWith('secret_request_not_pending:')) {
|
|
50
|
+
return {
|
|
51
|
+
success: false,
|
|
52
|
+
error: 'secret_request_not_pending',
|
|
53
|
+
outcomeType: 'blocked',
|
|
54
|
+
message: 'Mock secret denial failed because the request is no longer pending.',
|
|
55
|
+
reason: 'MagicPay mock storage can only deny pending secret requests.',
|
|
56
|
+
requestId,
|
|
57
|
+
requestStatus: reason.slice('secret_request_not_pending:'.length),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
success: false,
|
|
62
|
+
error: 'mock_secret_request_denial_failed',
|
|
63
|
+
outcomeType: 'failed',
|
|
64
|
+
message: 'Mock secret denial failed.',
|
|
65
|
+
reason,
|
|
66
|
+
requestId,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigate.d.ts","sourceRoot":"","sources":["../../src/commands/navigate.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACpB,MAAM,0BAA0B,CAAC;AAGlC,YAAY,EAAE,cAAc,EAAE,CAAC;AAE/B,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,mBAAmB,EAC5B,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,cAAc,CAAC,CAMzB"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { navigate as navigatePrimitive, } from '@mercuryo-ai/agentbrowse';
|
|
2
|
+
import { saveMagicPaySession } from '../workflow-state.js';
|
|
3
|
+
export async function navigate(session, url) {
|
|
4
|
+
const result = await navigatePrimitive(session, url);
|
|
5
|
+
if (result.success) {
|
|
6
|
+
saveMagicPaySession(session);
|
|
7
|
+
}
|
|
8
|
+
return result;
|
|
9
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type BrowserSessionState, type ObserveResult } from '@mercuryo-ai/agentbrowse';
|
|
2
|
+
import { type MagicPaySession } from '../workflow-state.js';
|
|
3
|
+
export type { ObserveResult };
|
|
4
|
+
export declare function observe(session: BrowserSessionState | MagicPaySession, instruction?: string): Promise<ObserveResult>;
|
|
5
|
+
//# sourceMappingURL=observe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observe.d.ts","sourceRoot":"","sources":["../../src/commands/observe.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,mBAAmB,EAExB,KAAK,aAAa,EACnB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAuB,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEjF,YAAY,EAAE,aAAa,EAAE,CAAC;AAmC9B,wBAAsB,OAAO,CAC3B,OAAO,EAAE,mBAAmB,GAAG,eAAe,EAC9C,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,aAAa,CAAC,CAyBxB"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { observe as observePrimitive, } from '@mercuryo-ai/agentbrowse';
|
|
2
|
+
import { enrichObservedFormsForUrl } from '@mercuryo-ai/magicpay-sdk/agentbrowse';
|
|
3
|
+
import { listFillableForms } from '../fillable-form-state.js';
|
|
4
|
+
import { saveMagicPaySession } from '../workflow-state.js';
|
|
5
|
+
async function ensureAssistiveRuntime() {
|
|
6
|
+
const { ensureMagicPayAgentbrowseAssistiveRuntime } = await import('../agentbrowse-assistive.js');
|
|
7
|
+
ensureMagicPayAgentbrowseAssistiveRuntime();
|
|
8
|
+
}
|
|
9
|
+
function toObservedFillableForms(forms) {
|
|
10
|
+
return forms
|
|
11
|
+
.filter((form) => form.presence !== 'absent')
|
|
12
|
+
.map((form) => ({
|
|
13
|
+
fillRef: form.fillRef,
|
|
14
|
+
scopeRef: form.scopeRef,
|
|
15
|
+
purpose: form.purpose,
|
|
16
|
+
presence: form.presence === 'unknown' ? 'unknown' : 'present',
|
|
17
|
+
fields: form.fields.map((field) => ({
|
|
18
|
+
fieldKey: field.fieldKey,
|
|
19
|
+
targetRef: field.targetRef,
|
|
20
|
+
label: field.label,
|
|
21
|
+
required: field.required,
|
|
22
|
+
valueHint: field.valueHint,
|
|
23
|
+
})),
|
|
24
|
+
storedSecretCandidates: form.storedSecretCandidates.map((candidate) => ({
|
|
25
|
+
storedSecretRef: candidate.storedSecretRef,
|
|
26
|
+
kind: candidate.kind,
|
|
27
|
+
scope: candidate.scope,
|
|
28
|
+
displayName: candidate.displayName,
|
|
29
|
+
matchConfidence: candidate.matchConfidence,
|
|
30
|
+
intentRequired: candidate.intentRequired,
|
|
31
|
+
})),
|
|
32
|
+
}));
|
|
33
|
+
}
|
|
34
|
+
export async function observe(session, instruction) {
|
|
35
|
+
await ensureAssistiveRuntime();
|
|
36
|
+
const result = await observePrimitive(session, instruction);
|
|
37
|
+
if (result.success) {
|
|
38
|
+
saveMagicPaySession(session);
|
|
39
|
+
}
|
|
40
|
+
if (!result.success || !Array.isArray(result.fillableForms) || !result.url) {
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
const runtimeFillableForms = listFillableForms(session);
|
|
45
|
+
return {
|
|
46
|
+
...result,
|
|
47
|
+
fillableForms: toObservedFillableForms(enrichObservedFormsForUrl(runtimeFillableForms, 'secretCatalogByHost' in session ? session.secretCatalogByHost : undefined, result.url)),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type MagicPaySession } from '../workflow-state.js';
|
|
2
|
+
export type PollSecretResult = ({
|
|
3
|
+
success: true;
|
|
4
|
+
} & Record<string, unknown>) | {
|
|
5
|
+
success: false;
|
|
6
|
+
error: 'workflow_session_required' | 'secret_request_not_found' | 'secret_request_lookup_failed';
|
|
7
|
+
outcomeType: 'blocked';
|
|
8
|
+
message: string;
|
|
9
|
+
reason: string;
|
|
10
|
+
requestId: string;
|
|
11
|
+
};
|
|
12
|
+
export declare function pollSecret(session: MagicPaySession, requestId: string): Promise<PollSecretResult>;
|
|
13
|
+
//# sourceMappingURL=poll-secret.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"poll-secret.d.ts","sourceRoot":"","sources":["../../src/commands/poll-secret.ts"],"names":[],"mappings":"AAMA,OAAO,EAAuB,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEjF,MAAM,MAAM,gBAAgB,GACxB,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,0BAA0B,GAC1B,8BAA8B,CAAC;IACnC,WAAW,EAAE,SAAS,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEN,wBAAsB,UAAU,CAC9B,OAAO,EAAE,eAAe,EACxB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,gBAAgB,CAAC,CA0F3B"}
|