@upbeat-works/fisgon 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/LICENSE.md +10 -0
- package/README.md +150 -0
- package/dist/adapters/drizzle.d.ts +17 -0
- package/dist/adapters/drizzle.d.ts.map +1 -0
- package/dist/adapters/drizzle.js +83 -0
- package/dist/adapters/drizzle.js.map +1 -0
- package/dist/adapters/prisma.d.ts +16 -0
- package/dist/adapters/prisma.d.ts.map +1 -0
- package/dist/adapters/prisma.js +69 -0
- package/dist/adapters/prisma.js.map +1 -0
- package/dist/agent/ai.d.ts +3 -0
- package/dist/agent/ai.d.ts.map +1 -0
- package/dist/agent/ai.js +19 -0
- package/dist/agent/ai.js.map +1 -0
- package/dist/agent/browser-bridge.d.ts +42 -0
- package/dist/agent/browser-bridge.d.ts.map +1 -0
- package/dist/agent/browser-bridge.js +2 -0
- package/dist/agent/browser-bridge.js.map +1 -0
- package/dist/agent/index.d.ts +66 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +572 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/llm-driver.d.ts +30 -0
- package/dist/agent/llm-driver.d.ts.map +1 -0
- package/dist/agent/llm-driver.js +239 -0
- package/dist/agent/llm-driver.js.map +1 -0
- package/dist/agent/session-state.d.ts +28 -0
- package/dist/agent/session-state.d.ts.map +1 -0
- package/dist/agent/session-state.js +6 -0
- package/dist/agent/session-state.js.map +1 -0
- package/dist/agent/worker.d.ts +6 -0
- package/dist/agent/worker.d.ts.map +1 -0
- package/dist/agent/worker.js +12 -0
- package/dist/agent/worker.js.map +1 -0
- package/dist/cli/browser-handler.d.ts +30 -0
- package/dist/cli/browser-handler.d.ts.map +1 -0
- package/dist/cli/browser-handler.js +89 -0
- package/dist/cli/browser-handler.js.map +1 -0
- package/dist/cli/browser-setup.d.ts +11 -0
- package/dist/cli/browser-setup.d.ts.map +1 -0
- package/dist/cli/browser-setup.js +25 -0
- package/dist/cli/browser-setup.js.map +1 -0
- package/dist/cli/commands/actions.d.ts +3 -0
- package/dist/cli/commands/actions.d.ts.map +1 -0
- package/dist/cli/commands/actions.js +28 -0
- package/dist/cli/commands/actions.js.map +1 -0
- package/dist/cli/commands/do.d.ts +3 -0
- package/dist/cli/commands/do.d.ts.map +1 -0
- package/dist/cli/commands/do.js +138 -0
- package/dist/cli/commands/do.js.map +1 -0
- package/dist/cli/commands/events.d.ts +3 -0
- package/dist/cli/commands/events.d.ts.map +1 -0
- package/dist/cli/commands/events.js +36 -0
- package/dist/cli/commands/events.js.map +1 -0
- package/dist/cli/commands/interact.d.ts +3 -0
- package/dist/cli/commands/interact.d.ts.map +1 -0
- package/dist/cli/commands/interact.js +54 -0
- package/dist/cli/commands/interact.js.map +1 -0
- package/dist/cli/commands/navigate.d.ts +3 -0
- package/dist/cli/commands/navigate.d.ts.map +1 -0
- package/dist/cli/commands/navigate.js +34 -0
- package/dist/cli/commands/navigate.js.map +1 -0
- package/dist/cli/commands/open.d.ts +3 -0
- package/dist/cli/commands/open.d.ts.map +1 -0
- package/dist/cli/commands/open.js +29 -0
- package/dist/cli/commands/open.js.map +1 -0
- package/dist/cli/commands/run.d.ts +3 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +209 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/start.d.ts +3 -0
- package/dist/cli/commands/start.d.ts.map +1 -0
- package/dist/cli/commands/start.js +169 -0
- package/dist/cli/commands/start.js.map +1 -0
- package/dist/cli/commands/stop.d.ts +3 -0
- package/dist/cli/commands/stop.d.ts.map +1 -0
- package/dist/cli/commands/stop.js +37 -0
- package/dist/cli/commands/stop.js.map +1 -0
- package/dist/cli/commands/tick.d.ts +3 -0
- package/dist/cli/commands/tick.d.ts.map +1 -0
- package/dist/cli/commands/tick.js +34 -0
- package/dist/cli/commands/tick.js.map +1 -0
- package/dist/cli/config.d.ts +3 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +20 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/connection.d.ts +18 -0
- package/dist/cli/connection.d.ts.map +1 -0
- package/dist/cli/connection.js +79 -0
- package/dist/cli/connection.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +29 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/session-file.d.ts +9 -0
- package/dist/cli/session-file.d.ts.map +1 -0
- package/dist/cli/session-file.js +23 -0
- package/dist/cli/session-file.js.map +1 -0
- package/dist/cli/task-runner.d.ts +20 -0
- package/dist/cli/task-runner.d.ts.map +1 -0
- package/dist/cli/task-runner.js +318 -0
- package/dist/cli/task-runner.js.map +1 -0
- package/dist/core/task-file.d.ts +32 -0
- package/dist/core/task-file.d.ts.map +1 -0
- package/dist/core/task-file.js +51 -0
- package/dist/core/task-file.js.map +1 -0
- package/dist/core/tick-detector.d.ts +24 -0
- package/dist/core/tick-detector.d.ts.map +1 -0
- package/dist/core/tick-detector.js +71 -0
- package/dist/core/tick-detector.js.map +1 -0
- package/dist/core/types.d.ts +74 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +4 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/probes/action-scanner.d.ts +2 -0
- package/dist/probes/action-scanner.d.ts.map +1 -0
- package/dist/probes/action-scanner.js +9 -0
- package/dist/probes/action-scanner.js.map +1 -0
- package/dist/probes/fetch-probe.d.ts +2 -0
- package/dist/probes/fetch-probe.d.ts.map +1 -0
- package/dist/probes/fetch-probe.js +9 -0
- package/dist/probes/fetch-probe.js.map +1 -0
- package/dist/probes/inject.d.ts +3 -0
- package/dist/probes/inject.d.ts.map +1 -0
- package/dist/probes/inject.js +24 -0
- package/dist/probes/inject.js.map +1 -0
- package/dist/probes/navigation-probe.d.ts +2 -0
- package/dist/probes/navigation-probe.d.ts.map +1 -0
- package/dist/probes/navigation-probe.js +9 -0
- package/dist/probes/navigation-probe.js.map +1 -0
- package/dist/probes/scripts/action-scanner.js +62 -0
- package/dist/probes/scripts/fetch.js +61 -0
- package/dist/probes/scripts/navigation.js +55 -0
- package/dist/probes/scripts/scripts/action-scanner.js +62 -0
- package/dist/probes/scripts/scripts/fetch.js +61 -0
- package/dist/probes/scripts/scripts/navigation.js +55 -0
- package/dist/probes/scripts/scripts/ws-bootstrap.js +35 -0
- package/dist/probes/scripts/ws-bootstrap.js +35 -0
- package/dist/server/create-probe.d.ts +8 -0
- package/dist/server/create-probe.d.ts.map +1 -0
- package/dist/server/create-probe.js +73 -0
- package/dist/server/create-probe.js.map +1 -0
- package/dist/server/sql-parser.d.ts +6 -0
- package/dist/server/sql-parser.d.ts.map +1 -0
- package/dist/server/sql-parser.js +40 -0
- package/dist/server/sql-parser.js.map +1 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +2 -0
- package/dist/server.js.map +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { generateText, Output, tool, stepCountIs } from 'ai';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { model, structuredModel } from './ai.js';
|
|
4
|
+
const SYSTEM_PROMPT = `You are a browser automation agent. You control a real browser and can observe both client-side and server-side events.
|
|
5
|
+
|
|
6
|
+
Your tools give you full control over browser navigation and interaction. Use them to accomplish the user's instruction.
|
|
7
|
+
|
|
8
|
+
## How events work
|
|
9
|
+
|
|
10
|
+
Every action in the browser generates events from two sources:
|
|
11
|
+
- **Browser probes**: fetch requests/responses, navigation changes
|
|
12
|
+
- **Server probes**: SQL queries, custom application events (e.g. email content, background jobs)
|
|
13
|
+
|
|
14
|
+
After performing an action (clicking submit, navigating), call \`wait_for_tick\` to see what happened. A "tick" is a group of events collected until silence (no new events for ~500ms). The tick contains ALL events — both browser-side and server-side.
|
|
15
|
+
|
|
16
|
+
## Strategy
|
|
17
|
+
|
|
18
|
+
You are a USER of the application. Navigate it the way a user would — by looking at the page and clicking links, buttons, and menus.
|
|
19
|
+
|
|
20
|
+
1. Use \`get_actions\` to discover what's on the current page (links, buttons, forms, nav items)
|
|
21
|
+
2. Use \`open_action\` to inspect an element's HTML if you need more detail
|
|
22
|
+
3. Use \`interact\` to click links, fill forms, press buttons — it returns the resulting events automatically
|
|
23
|
+
4. Use \`navigate\` ONLY for exact URLs you already know (e.g. a callback URL from an email event). Never guess URLs.
|
|
24
|
+
5. Use \`wait_for_tick\` only when you need to wait for delayed events (e.g. after a page load that triggers background work)
|
|
25
|
+
6. Use \`get_events\` to review the full event history if needed
|
|
26
|
+
|
|
27
|
+
**Always start by calling \`get_actions\` to see what's available on the page**, then follow links/buttons to reach your destination. Do NOT construct or guess URLs — find them in the UI.
|
|
28
|
+
|
|
29
|
+
## Important
|
|
30
|
+
|
|
31
|
+
- Discover elements with \`get_actions\` — do NOT guess CSS selectors or URLs
|
|
32
|
+
- Both \`interact\` and \`navigate\` return the tick with all events — no need to call \`wait_for_tick\` after them
|
|
33
|
+
- Server events can reveal things not visible in the browser: magic link URLs in emails, session tokens, SQL operations
|
|
34
|
+
- If a login flow sends a magic link email, the email content appears as a server probe event — extract the URL and navigate to it
|
|
35
|
+
- Keep going until the instruction is fully accomplished, then respond with a summary of what you did`;
|
|
36
|
+
function createTools(ctx) {
|
|
37
|
+
return {
|
|
38
|
+
navigate: tool({
|
|
39
|
+
description: 'Navigate the browser to a URL. Returns the tick with all events (browser + server) that fired during page load.',
|
|
40
|
+
inputSchema: z.object({
|
|
41
|
+
url: z.string().describe('The URL to navigate to'),
|
|
42
|
+
}),
|
|
43
|
+
execute: async ({ url }) => {
|
|
44
|
+
await ctx.sendBrowserCommand({ type: 'browser-navigate', url });
|
|
45
|
+
return ctx.waitForTick(10000);
|
|
46
|
+
},
|
|
47
|
+
}),
|
|
48
|
+
get_actions: tool({
|
|
49
|
+
description: 'List available actions (forms, links, buttons) on the current page.',
|
|
50
|
+
inputSchema: z.object({}),
|
|
51
|
+
execute: async () => {
|
|
52
|
+
return (await ctx.sendBrowserCommand({
|
|
53
|
+
type: 'browser-actions',
|
|
54
|
+
}));
|
|
55
|
+
},
|
|
56
|
+
}),
|
|
57
|
+
open_action: tool({
|
|
58
|
+
description: 'Get the raw innerHTML of an action element. Use this to understand form fields, link targets, etc.',
|
|
59
|
+
inputSchema: z.object({
|
|
60
|
+
actionId: z
|
|
61
|
+
.string()
|
|
62
|
+
.describe('The action ID from get_actions results'),
|
|
63
|
+
}),
|
|
64
|
+
execute: async ({ actionId }) => {
|
|
65
|
+
return (await ctx.sendBrowserCommand({
|
|
66
|
+
type: 'browser-open',
|
|
67
|
+
actionId,
|
|
68
|
+
}));
|
|
69
|
+
},
|
|
70
|
+
}),
|
|
71
|
+
interact: tool({
|
|
72
|
+
description: 'Type text, click, or select an option in the browser. Use CSS selectors from open_action results. Returns the tick with all events that fired as a result.',
|
|
73
|
+
inputSchema: z.object({
|
|
74
|
+
action: z.enum(['type', 'click', 'select']).describe('The interaction type'),
|
|
75
|
+
selector: z.string().describe('CSS selector for the target element'),
|
|
76
|
+
value: z
|
|
77
|
+
.string()
|
|
78
|
+
.optional()
|
|
79
|
+
.describe('Value to type or select (required for type/select)'),
|
|
80
|
+
}),
|
|
81
|
+
execute: async ({ action, selector, value }) => {
|
|
82
|
+
let command;
|
|
83
|
+
if (action === 'type') {
|
|
84
|
+
command = { action: 'type', selector, value: value ?? '' };
|
|
85
|
+
}
|
|
86
|
+
else if (action === 'select') {
|
|
87
|
+
command = { action: 'select', selector, value: value ?? '' };
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
command = { action: 'click', selector };
|
|
91
|
+
}
|
|
92
|
+
await ctx.sendBrowserCommand({
|
|
93
|
+
type: 'browser-interact',
|
|
94
|
+
command,
|
|
95
|
+
});
|
|
96
|
+
return ctx.waitForTick(10000);
|
|
97
|
+
},
|
|
98
|
+
}),
|
|
99
|
+
wait_for_tick: tool({
|
|
100
|
+
description: 'Wait for the next tick (silence = all events settled). Returns all events including server-side probe data (SQL queries, custom events like email content).',
|
|
101
|
+
inputSchema: z.object({
|
|
102
|
+
timeout: z
|
|
103
|
+
.number()
|
|
104
|
+
.optional()
|
|
105
|
+
.describe('Timeout in ms (default 10000)'),
|
|
106
|
+
}),
|
|
107
|
+
execute: async ({ timeout }) => {
|
|
108
|
+
return ctx.waitForTick(timeout ?? 10000);
|
|
109
|
+
},
|
|
110
|
+
}),
|
|
111
|
+
get_events: tool({
|
|
112
|
+
description: 'Get all events captured so far in this session. Use to review what has happened.',
|
|
113
|
+
inputSchema: z.object({}),
|
|
114
|
+
execute: async () => {
|
|
115
|
+
return ctx.getEvents();
|
|
116
|
+
},
|
|
117
|
+
}),
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
export async function runTask(ctx, instruction) {
|
|
121
|
+
const appContext = [`App URL: ${ctx.appUrl}`];
|
|
122
|
+
if (ctx.loginUrl)
|
|
123
|
+
appContext.push(`Login URL: ${ctx.loginUrl}`);
|
|
124
|
+
if (ctx.currentUrl)
|
|
125
|
+
appContext.push(`Current browser URL: ${ctx.currentUrl} — the browser is already here, do NOT navigate away unless the instruction requires it`);
|
|
126
|
+
let stepNumber = 0;
|
|
127
|
+
const result = await generateText({
|
|
128
|
+
model,
|
|
129
|
+
system: SYSTEM_PROMPT + `\n\n## App context\n\n${appContext.join('\n')}`,
|
|
130
|
+
prompt: instruction,
|
|
131
|
+
tools: createTools(ctx),
|
|
132
|
+
stopWhen: stepCountIs(30),
|
|
133
|
+
onStepFinish(step) {
|
|
134
|
+
stepNumber++;
|
|
135
|
+
ctx.onStepLog?.({
|
|
136
|
+
step: stepNumber,
|
|
137
|
+
toolCalls: step.toolCalls.map((tc, i) => ({
|
|
138
|
+
name: tc.toolName,
|
|
139
|
+
args: tc.input,
|
|
140
|
+
result: step.toolResults[i]?.output,
|
|
141
|
+
})),
|
|
142
|
+
text: step.text || undefined,
|
|
143
|
+
});
|
|
144
|
+
},
|
|
145
|
+
});
|
|
146
|
+
return result.text;
|
|
147
|
+
}
|
|
148
|
+
const DISTILL_PROMPT = `You are analyzing a browser automation trace. Given the full sequence of tool calls and their results, distill it into a clean, minimal task file that can be replayed deterministically.
|
|
149
|
+
|
|
150
|
+
## Rules
|
|
151
|
+
|
|
152
|
+
1. **Only keep steps that change state**: \`navigate\`, \`interact\`, and \`wait_for_tick\`.
|
|
153
|
+
- REMOVE all \`get_actions\`, \`open_action\`, and \`get_events\` calls — they are read-only discovery steps the LLM used to explore the page. They are not needed for replay.
|
|
154
|
+
2. **Keep every interact step that matters** — clicks that switch views, type into fields, or submit forms. Look at the trace carefully: if a click changed the page (the next get_actions returned different results), it must be included.
|
|
155
|
+
3. **Remove missteps**: failed clicks (errors in result), redundant retries, and steps that didn't contribute to the goal.
|
|
156
|
+
4. **Use stable CSS selectors** — never use \`data-fisgon\` attributes (they are dynamically assigned and change between sessions). Never use \`:contains()\` (not valid CSS). Prefer: \`button[type="submit"]\`, \`input[name="email"]\`, \`a[href="..."]\`, \`role\` attributes, or \`nth-of-type\`. For text matching use Playwright's \`:has-text("...")\` pseudo-selector (e.g. \`button:has-text("Log In")\`).
|
|
157
|
+
5. **Parameterize dynamic values**: emails, passwords, URLs that vary. Replace with \`{{paramName}}\` placeholders and list defaults in \`params\`.
|
|
158
|
+
6. **Extract dynamic values** from step results: for values that are only known at runtime (like magic link URLs from email events), add \`extract\` on the step that produces them. The extract object maps variable names to expressions. Example: \`{"callbackUrl": "events[source=email].data.text | match(/http\\\\S+callback\\\\S+/)"}\`. The variable can then be used as \`{{callbackUrl}}\` in later steps.
|
|
159
|
+
7. **Add validation** based on the final state (typically url_contains).
|
|
160
|
+
|
|
161
|
+
## Output schema
|
|
162
|
+
|
|
163
|
+
- name: short kebab-case identifier
|
|
164
|
+
- description: what this task does
|
|
165
|
+
- params: object of param names to default values (null if none)
|
|
166
|
+
- steps: array of {tool, args, extract} — only navigate, interact, wait_for_tick
|
|
167
|
+
- validate: {url_contains, url_matches, event_exists} (null fields for unused)
|
|
168
|
+
|
|
169
|
+
Tool args:
|
|
170
|
+
- interact: {action: "click"|"type"|"select", selector: string, value?: string}
|
|
171
|
+
- navigate: {url: string}
|
|
172
|
+
- wait_for_tick: {timeout?: string}`;
|
|
173
|
+
const taskFileSchema = z.object({
|
|
174
|
+
name: z.string(),
|
|
175
|
+
description: z.string(),
|
|
176
|
+
params: z.record(z.string()).nullable(),
|
|
177
|
+
steps: z.array(z.object({
|
|
178
|
+
tool: z.string(),
|
|
179
|
+
args: z.record(z.string()).nullable(),
|
|
180
|
+
extract: z.record(z.string()).nullable(),
|
|
181
|
+
})),
|
|
182
|
+
validate: z.object({
|
|
183
|
+
url_contains: z.string().nullable(),
|
|
184
|
+
url_matches: z.string().nullable(),
|
|
185
|
+
event_exists: z.object({
|
|
186
|
+
source: z.string(),
|
|
187
|
+
type: z.string(),
|
|
188
|
+
}).nullable(),
|
|
189
|
+
}).nullable(),
|
|
190
|
+
});
|
|
191
|
+
const matchTasksSchema = z.object({
|
|
192
|
+
tasks: z.array(z.string()).nullable(),
|
|
193
|
+
remaining: z.string().nullable(),
|
|
194
|
+
});
|
|
195
|
+
export async function matchTasks(instruction, tasks) {
|
|
196
|
+
const catalog = tasks.map((t) => `- ${t.name}: ${t.description}`).join('\n');
|
|
197
|
+
const result = await generateText({
|
|
198
|
+
model: structuredModel,
|
|
199
|
+
output: Output.object({ schema: matchTasksSchema }),
|
|
200
|
+
system: `You are a task planner. Given a user instruction and a catalog of saved tasks, determine which saved tasks (if any) should be run to fulfill the instruction, and what (if anything) remains after those tasks.
|
|
201
|
+
|
|
202
|
+
Rules:
|
|
203
|
+
- Only match tasks that clearly correspond to part of the instruction
|
|
204
|
+
- Return task names in the order they should be executed
|
|
205
|
+
- If no tasks match, return tasks: null
|
|
206
|
+
- If the matched tasks fully cover the instruction, return remaining: null
|
|
207
|
+
- If there is leftover work after the matched tasks, describe it in remaining as a concise instruction for a browser automation agent
|
|
208
|
+
- Do NOT invent tasks — only return names from the catalog`,
|
|
209
|
+
prompt: `Instruction: ${instruction}
|
|
210
|
+
|
|
211
|
+
Task catalog:
|
|
212
|
+
${catalog}`,
|
|
213
|
+
});
|
|
214
|
+
const output = result.output;
|
|
215
|
+
return {
|
|
216
|
+
tasks: output.tasks,
|
|
217
|
+
remaining: output.remaining,
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
export async function distillSteps(stepLogs, instruction, finalUrl) {
|
|
221
|
+
const trace = stepLogs.map((log) => log.toolCalls.map((tc) => ({
|
|
222
|
+
tool: tc.name,
|
|
223
|
+
args: tc.args,
|
|
224
|
+
result: tc.result,
|
|
225
|
+
}))).flat();
|
|
226
|
+
const result = await generateText({
|
|
227
|
+
model: structuredModel,
|
|
228
|
+
output: Output.object({ schema: taskFileSchema }),
|
|
229
|
+
system: DISTILL_PROMPT,
|
|
230
|
+
prompt: [
|
|
231
|
+
`Instruction: ${instruction}`,
|
|
232
|
+
`Final browser URL: ${finalUrl}`,
|
|
233
|
+
`\nFull trace (${trace.length} tool calls):`,
|
|
234
|
+
JSON.stringify(trace, null, 2),
|
|
235
|
+
].join('\n'),
|
|
236
|
+
});
|
|
237
|
+
return result.output;
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=llm-driver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-driver.js","sourceRoot":"","sources":["../../src/agent/llm-driver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,IAAI,CAAA;AAC5D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAwBhD,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sGA+BgF,CAAA;AAEtG,SAAS,WAAW,CAAC,GAAgB;IACpC,OAAO;QACN,QAAQ,EAAE,IAAI,CAAwB;YACrC,WAAW,EACV,iHAAiH;YAClH,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;gBACrB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;aAClD,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;gBAC1B,MAAM,GAAG,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,GAAG,EAAE,CAAC,CAAA;gBAC/D,OAAO,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;YAC9B,CAAC;SACD,CAAC;QAEF,WAAW,EAAE,IAAI,CAAkC;YAClD,WAAW,EACV,qEAAqE;YACtE,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;YACzB,OAAO,EAAE,KAAK,IAAI,EAAE;gBACnB,OAAO,CAAC,MAAM,GAAG,CAAC,kBAAkB,CAAC;oBACpC,IAAI,EAAE,iBAAiB;iBACvB,CAAC,CAAa,CAAA;YAChB,CAAC;SACD,CAAC;QAEF,WAAW,EAAE,IAAI,CAA+B;YAC/C,WAAW,EACV,oGAAoG;YACrG,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;gBACrB,QAAQ,EAAE,CAAC;qBACT,MAAM,EAAE;qBACR,QAAQ,CAAC,wCAAwC,CAAC;aACpD,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;gBAC/B,OAAO,CAAC,MAAM,GAAG,CAAC,kBAAkB,CAAC;oBACpC,IAAI,EAAE,cAAc;oBACpB,QAAQ;iBACR,CAAC,CAAW,CAAA;YACd,CAAC;SACD,CAAC;QAEF,QAAQ,EAAE,IAAI,CAAkF;YAC/F,WAAW,EACV,4JAA4J;YAC7J,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;gBACrB,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,sBAAsB,CAAC;gBAC5E,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC;gBACpE,KAAK,EAAE,CAAC;qBACN,MAAM,EAAE;qBACR,QAAQ,EAAE;qBACV,QAAQ,CAAC,oDAAoD,CAAC;aAChE,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE;gBAC9C,IAAI,OAAwB,CAAA;gBAC5B,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;oBACvB,OAAO,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,IAAI,EAAE,EAAE,CAAA;gBAC3D,CAAC;qBAAM,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;oBAChC,OAAO,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,IAAI,EAAE,EAAE,CAAA;gBAC7D,CAAC;qBAAM,CAAC;oBACP,OAAO,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAA;gBACxC,CAAC;gBACD,MAAM,GAAG,CAAC,kBAAkB,CAAC;oBAC5B,IAAI,EAAE,kBAAkB;oBACxB,OAAO;iBACP,CAAC,CAAA;gBACF,OAAO,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;YAC9B,CAAC;SACD,CAAC;QAEF,aAAa,EAAE,IAAI,CAA6B;YAC/C,WAAW,EACV,6JAA6J;YAC9J,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;gBACrB,OAAO,EAAE,CAAC;qBACR,MAAM,EAAE;qBACR,QAAQ,EAAE;qBACV,QAAQ,CAAC,+BAA+B,CAAC;aAC3C,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;gBAC9B,OAAO,GAAG,CAAC,WAAW,CAAC,OAAO,IAAI,KAAK,CAAC,CAAA;YACzC,CAAC;SACD,CAAC;QAEF,UAAU,EAAE,IAAI,CAAsC;YACrD,WAAW,EACV,kFAAkF;YACnF,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;YACzB,OAAO,EAAE,KAAK,IAAI,EAAE;gBACnB,OAAO,GAAG,CAAC,SAAS,EAAE,CAAA;YACvB,CAAC;SACD,CAAC;KACF,CAAA;AACF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAC5B,GAAgB,EAChB,WAAmB;IAEnB,MAAM,UAAU,GAAG,CAAC,YAAY,GAAG,CAAC,MAAM,EAAE,CAAC,CAAA;IAC7C,IAAI,GAAG,CAAC,QAAQ;QAAE,UAAU,CAAC,IAAI,CAAC,cAAc,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAA;IAC/D,IAAI,GAAG,CAAC,UAAU;QAAE,UAAU,CAAC,IAAI,CAAC,wBAAwB,GAAG,CAAC,UAAU,yFAAyF,CAAC,CAAA;IAEpK,IAAI,UAAU,GAAG,CAAC,CAAA;IAClB,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC;QACjC,KAAK;QACL,MAAM,EAAE,aAAa,GAAG,yBAAyB,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QACxE,MAAM,EAAE,WAAW;QACnB,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC;QACvB,QAAQ,EAAE,WAAW,CAAC,EAAE,CAAC;QACzB,YAAY,CAAC,IAAI;YAChB,UAAU,EAAE,CAAA;YACZ,GAAG,CAAC,SAAS,EAAE,CAAC;gBACf,IAAI,EAAE,UAAU;gBAChB,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;oBACzC,IAAI,EAAE,EAAE,CAAC,QAAQ;oBACjB,IAAI,EAAE,EAAE,CAAC,KAAgC;oBACzC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,MAAM;iBACnC,CAAC,CAAC;gBACH,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,SAAS;aAC5B,CAAC,CAAA;QACH,CAAC;KACD,CAAC,CAAA;IAEF,OAAO,MAAM,CAAC,IAAI,CAAA;AACnB,CAAC;AAED,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;oCAwBa,CAAA;AAEpC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACvC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;QACvB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;QAChB,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;QACrC,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;KACxC,CAAC,CAAC;IACH,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC;QAClB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QACnC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAClC,YAAY,EAAE,CAAC,CAAC,MAAM,CAAC;YACtB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;YAClB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;SAChB,CAAC,CAAC,QAAQ,EAAE;KACb,CAAC,CAAC,QAAQ,EAAE;CACb,CAAC,CAAA;AAEF,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACrC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAChC,CAAC,CAAA;AAEF,MAAM,CAAC,KAAK,UAAU,UAAU,CAC/B,WAAmB,EACnB,KAAmD;IAEnD,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAE5E,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC;QACjC,KAAK,EAAE,eAAe;QACtB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC;QACnD,MAAM,EAAE;;;;;;;;2DAQiD;QACzD,MAAM,EAAE,gBAAgB,WAAW;;;EAGnC,OAAO,EAAE;KACT,CAAC,CAAA;IAEF,MAAM,MAAM,GAAG,MAAM,CAAC,MAA8D,CAAA;IACpF,OAAO;QACN,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,SAAS,EAAE,MAAM,CAAC,SAAS;KAC3B,CAAA;AACF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CACjC,QAAmB,EACnB,WAAmB,EACnB,QAAgB;IAEhB,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAClC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAC1B,IAAI,EAAE,EAAE,CAAC,IAAI;QACb,IAAI,EAAE,EAAE,CAAC,IAAI;QACb,MAAM,EAAE,EAAE,CAAC,MAAM;KACjB,CAAC,CAAC,CACH,CAAC,IAAI,EAAE,CAAA;IAER,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC;QACjC,KAAK,EAAE,eAAe;QACtB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;QACjD,MAAM,EAAE,cAAc;QACtB,MAAM,EAAE;YACP,gBAAgB,WAAW,EAAE;YAC7B,sBAAsB,QAAQ,EAAE;YAChC,iBAAiB,KAAK,CAAC,MAAM,eAAe;YAC5C,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;SAC9B,CAAC,IAAI,CAAC,IAAI,CAAC;KACZ,CAAC,CAAA;IAEF,OAAO,MAAM,CAAC,MAAkB,CAAA;AACjC,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export type SessionRow = {
|
|
2
|
+
id: string;
|
|
3
|
+
status: string;
|
|
4
|
+
browser_mode: string;
|
|
5
|
+
config: string;
|
|
6
|
+
created_at: number;
|
|
7
|
+
updated_at: number;
|
|
8
|
+
};
|
|
9
|
+
export type EventRow = {
|
|
10
|
+
id: number;
|
|
11
|
+
session_id: string;
|
|
12
|
+
tick_id: number | null;
|
|
13
|
+
source: string;
|
|
14
|
+
type: string;
|
|
15
|
+
timestamp: number;
|
|
16
|
+
data: string;
|
|
17
|
+
};
|
|
18
|
+
export type TickRow = {
|
|
19
|
+
id: number;
|
|
20
|
+
session_id: string;
|
|
21
|
+
started_at: number;
|
|
22
|
+
duration: number;
|
|
23
|
+
};
|
|
24
|
+
export type AgentState = {
|
|
25
|
+
activeSessionIds: string[];
|
|
26
|
+
};
|
|
27
|
+
export declare const initialAgentState: AgentState;
|
|
28
|
+
//# sourceMappingURL=session-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-state.d.ts","sourceRoot":"","sources":["../../src/agent/session-state.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,UAAU,GAAG;IACxB,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG;IACtB,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;CACZ,CAAA;AAED,MAAM,MAAM,OAAO,GAAG;IACrB,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;CAChB,CAAA;AAID,MAAM,MAAM,UAAU,GAAG;IACxB,gBAAgB,EAAE,MAAM,EAAE,CAAA;CAC1B,CAAA;AAED,eAAO,MAAM,iBAAiB,EAAE,UAE/B,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-state.js","sourceRoot":"","sources":["../../src/agent/session-state.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,+EAA+E;AAkC/E,MAAM,CAAC,MAAM,iBAAiB,GAAe;IAC5C,gBAAgB,EAAE,EAAE;CACpB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/agent/worker.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;;mBAGjB,OAAO,OAAO,UAAU,CAAC,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC;;AADvE,wBAQC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { routeAgentRequest } from 'agents';
|
|
2
|
+
export { FisgonAgent } from './index.js';
|
|
3
|
+
export default {
|
|
4
|
+
async fetch(request, env) {
|
|
5
|
+
// Route WebSocket and HTTP requests to the FisgonAgent Durable Object
|
|
6
|
+
const response = await routeAgentRequest(request, env);
|
|
7
|
+
if (response)
|
|
8
|
+
return response;
|
|
9
|
+
return new Response('Fisgon Agent — connect via WebSocket', { status: 200 });
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../../src/agent/worker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAA;AAE1C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAExC,eAAe;IACb,KAAK,CAAC,KAAK,CAAC,OAAgB,EAAE,GAAmB;QAC/C,sEAAsE;QACtE,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;QACtD,IAAI,QAAQ;YAAE,OAAO,QAAQ,CAAA;QAE7B,OAAO,IAAI,QAAQ,CAAC,sCAAsC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;IAC9E,CAAC;CACF,CAAA"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export type PlaywrightPage = {
|
|
2
|
+
goto(url: string, options?: {
|
|
3
|
+
waitUntil?: string;
|
|
4
|
+
}): Promise<unknown>;
|
|
5
|
+
evaluate<T>(fn: string | (() => T)): Promise<T>;
|
|
6
|
+
addInitScript(script: string): Promise<void>;
|
|
7
|
+
fill(selector: string, value: string): Promise<void>;
|
|
8
|
+
click(selector: string): Promise<void>;
|
|
9
|
+
selectOption(selector: string, value: string): Promise<unknown>;
|
|
10
|
+
waitForLoadState(state?: string): Promise<void>;
|
|
11
|
+
context(): {
|
|
12
|
+
addCookies(cookies: Array<{
|
|
13
|
+
name: string;
|
|
14
|
+
value: string;
|
|
15
|
+
domain: string;
|
|
16
|
+
path: string;
|
|
17
|
+
}>): Promise<void>;
|
|
18
|
+
};
|
|
19
|
+
close(): Promise<void>;
|
|
20
|
+
};
|
|
21
|
+
export type PlaywrightBrowser = {
|
|
22
|
+
newPage(): Promise<PlaywrightPage>;
|
|
23
|
+
close(): Promise<void>;
|
|
24
|
+
};
|
|
25
|
+
type Sendable = {
|
|
26
|
+
send(data: string): void;
|
|
27
|
+
};
|
|
28
|
+
export declare function createBrowserHandler(sender: Sendable, page: PlaywrightPage): (raw: unknown) => Promise<void>;
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=browser-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-handler.d.ts","sourceRoot":"","sources":["../../src/cli/browser-handler.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,cAAc,GAAG;IAC5B,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACrE,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;IAC/C,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5C,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACpD,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACtC,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAC/D,gBAAgB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/C,OAAO,IAAI;QACV,UAAU,CACT,OAAO,EAAE,KAAK,CAAC;YACd,IAAI,EAAE,MAAM,CAAA;YACZ,KAAK,EAAE,MAAM,CAAA;YACb,MAAM,EAAE,MAAM,CAAA;YACd,IAAI,EAAE,MAAM,CAAA;SACZ,CAAC,GACA,OAAO,CAAC,IAAI,CAAC,CAAA;KAChB,CAAA;IACD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACtB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC/B,OAAO,IAAI,OAAO,CAAC,cAAc,CAAC,CAAA;IAClC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACtB,CAAA;AAED,KAAK,QAAQ,GAAG;IACf,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CACxB,CAAA;AAmBD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,cAAc,IAC5D,KAAK,OAAO,mBAwF1B"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// Browser command handler for the CLI process.
|
|
2
|
+
// When the agent needs to control the browser, it sends commands to the CLI,
|
|
3
|
+
// which owns the Playwright browser instance.
|
|
4
|
+
import { createActionScannerScript } from '../probes/action-scanner.js';
|
|
5
|
+
function isBrowserCommand(msg) {
|
|
6
|
+
return (typeof msg === 'object' &&
|
|
7
|
+
msg !== null &&
|
|
8
|
+
'type' in msg &&
|
|
9
|
+
'commandId' in msg &&
|
|
10
|
+
typeof msg.type === 'string' &&
|
|
11
|
+
typeof msg.commandId === 'string');
|
|
12
|
+
}
|
|
13
|
+
export function createBrowserHandler(sender, page) {
|
|
14
|
+
return async (raw) => {
|
|
15
|
+
if (!isBrowserCommand(raw))
|
|
16
|
+
return;
|
|
17
|
+
const command = raw;
|
|
18
|
+
const { commandId } = command;
|
|
19
|
+
try {
|
|
20
|
+
let data = undefined;
|
|
21
|
+
switch (command.type) {
|
|
22
|
+
case 'browser-navigate': {
|
|
23
|
+
await page.goto(command.url, {
|
|
24
|
+
waitUntil: 'networkidle',
|
|
25
|
+
});
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
case 'browser-evaluate': {
|
|
29
|
+
data = await page.evaluate(command.script);
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
case 'browser-actions': {
|
|
33
|
+
data = await page.evaluate(createActionScannerScript());
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
case 'browser-open': {
|
|
37
|
+
const actionId = command.actionId;
|
|
38
|
+
data = await page.evaluate(`document.querySelector('[data-fisgon="${actionId}"]')?.innerHTML ?? ''`);
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
case 'browser-interact': {
|
|
42
|
+
const cmd = command.command;
|
|
43
|
+
switch (cmd.action) {
|
|
44
|
+
case 'type':
|
|
45
|
+
await page.fill(cmd.selector, cmd.value);
|
|
46
|
+
break;
|
|
47
|
+
case 'click':
|
|
48
|
+
await page.click(cmd.selector);
|
|
49
|
+
break;
|
|
50
|
+
case 'select':
|
|
51
|
+
await page.selectOption(cmd.selector, cmd.value);
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
case 'browser-set-cookie': {
|
|
57
|
+
await page.context().addCookies([
|
|
58
|
+
{
|
|
59
|
+
name: command.name,
|
|
60
|
+
value: command.value,
|
|
61
|
+
domain: command.domain,
|
|
62
|
+
path: '/',
|
|
63
|
+
},
|
|
64
|
+
]);
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
case 'browser-close': {
|
|
68
|
+
await page.close();
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
sender.send(JSON.stringify({
|
|
73
|
+
type: 'browser-result',
|
|
74
|
+
commandId,
|
|
75
|
+
success: true,
|
|
76
|
+
data,
|
|
77
|
+
}));
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
sender.send(JSON.stringify({
|
|
81
|
+
type: 'browser-result',
|
|
82
|
+
commandId,
|
|
83
|
+
success: false,
|
|
84
|
+
error: String(err),
|
|
85
|
+
}));
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=browser-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-handler.js","sourceRoot":"","sources":["../../src/cli/browser-handler.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,6EAA6E;AAC7E,8CAA8C;AAG9C,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAA;AAsCvE,SAAS,gBAAgB,CAAC,GAAY;IACrC,OAAO,CACN,OAAO,GAAG,KAAK,QAAQ;QACvB,GAAG,KAAK,IAAI;QACZ,MAAM,IAAI,GAAG;QACb,WAAW,IAAI,GAAG;QAClB,OAAQ,GAAsB,CAAC,IAAI,KAAK,QAAQ;QAChD,OAAQ,GAAsB,CAAC,SAAS,KAAK,QAAQ,CACrD,CAAA;AACF,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAgB,EAAE,IAAoB;IAC1E,OAAO,KAAK,EAAE,GAAY,EAAE,EAAE;QAC7B,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC;YAAE,OAAM;QAElC,MAAM,OAAO,GAAG,GAAG,CAAA;QACnB,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAA;QAE7B,IAAI,CAAC;YACJ,IAAI,IAAI,GAAY,SAAS,CAAA;YAE7B,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;gBACtB,KAAK,kBAAkB,CAAC,CAAC,CAAC;oBACzB,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAa,EAAE;wBACtC,SAAS,EAAE,aAAa;qBACxB,CAAC,CAAA;oBACF,MAAK;gBACN,CAAC;gBAED,KAAK,kBAAkB,CAAC,CAAC,CAAC;oBACzB,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAgB,CAAC,CAAA;oBACpD,MAAK;gBACN,CAAC;gBAED,KAAK,iBAAiB,CAAC,CAAC,CAAC;oBACxB,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,yBAAyB,EAAE,CAAC,CAAA;oBACvD,MAAK;gBACN,CAAC;gBAED,KAAK,cAAc,CAAC,CAAC,CAAC;oBACrB,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAkB,CAAA;oBAC3C,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CACzB,yCAAyC,QAAQ,uBAAuB,CACxE,CAAA;oBACD,MAAK;gBACN,CAAC;gBAED,KAAK,kBAAkB,CAAC,CAAC,CAAC;oBACzB,MAAM,GAAG,GAAG,OAAO,CAAC,OAA0B,CAAA;oBAC9C,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC;wBACpB,KAAK,MAAM;4BACV,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,KAAK,CAAC,CAAA;4BACxC,MAAK;wBACN,KAAK,OAAO;4BACX,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;4BAC9B,MAAK;wBACN,KAAK,QAAQ;4BACZ,MAAM,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,KAAK,CAAC,CAAA;4BAChD,MAAK;oBACP,CAAC;oBACD,MAAK;gBACN,CAAC;gBAED,KAAK,oBAAoB,CAAC,CAAC,CAAC;oBAC3B,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,UAAU,CAAC;wBAC/B;4BACC,IAAI,EAAE,OAAO,CAAC,IAAc;4BAC5B,KAAK,EAAE,OAAO,CAAC,KAAe;4BAC9B,MAAM,EAAE,OAAO,CAAC,MAAgB;4BAChC,IAAI,EAAE,GAAG;yBACT;qBACD,CAAC,CAAA;oBACF,MAAK;gBACN,CAAC;gBAED,KAAK,eAAe,CAAC,CAAC,CAAC;oBACtB,MAAM,IAAI,CAAC,KAAK,EAAE,CAAA;oBAClB,MAAK;gBACN,CAAC;YACF,CAAC;YAED,MAAM,CAAC,IAAI,CACV,IAAI,CAAC,SAAS,CAAC;gBACd,IAAI,EAAE,gBAAgB;gBACtB,SAAS;gBACT,OAAO,EAAE,IAAI;gBACb,IAAI;aACJ,CAAC,CACF,CAAA;QACF,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,CAAC,IAAI,CACV,IAAI,CAAC,SAAS,CAAC;gBACd,IAAI,EAAE,gBAAgB;gBACtB,SAAS;gBACT,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC;aAClB,CAAC,CACF,CAAA;QACF,CAAC;IACF,CAAC,CAAA;AACF,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type FisgonConfig } from '../core/types.js';
|
|
2
|
+
import { type PlaywrightBrowser, type PlaywrightPage } from './browser-handler.js';
|
|
3
|
+
export type BrowserSession = {
|
|
4
|
+
browser: PlaywrightBrowser;
|
|
5
|
+
page: PlaywrightPage;
|
|
6
|
+
cleanup: () => Promise<void>;
|
|
7
|
+
};
|
|
8
|
+
export declare function launchBrowser(config: FisgonConfig, sessionId: string, options?: {
|
|
9
|
+
headless?: boolean;
|
|
10
|
+
}): Promise<BrowserSession>;
|
|
11
|
+
//# sourceMappingURL=browser-setup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-setup.d.ts","sourceRoot":"","sources":["../../src/cli/browser-setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAEpD,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAElF,MAAM,MAAM,cAAc,GAAG;IAC5B,OAAO,EAAE,iBAAiB,CAAA;IAC1B,IAAI,EAAE,cAAc,CAAA;IACpB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC5B,CAAA;AAED,wBAAsB,aAAa,CAClC,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GAC9B,OAAO,CAAC,cAAc,CAAC,CA+BzB"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { createInjectableScript } from '../probes/inject.js';
|
|
2
|
+
export async function launchBrowser(config, sessionId, options) {
|
|
3
|
+
const pw = (await import('playwright'));
|
|
4
|
+
const headless = options?.headless ?? false;
|
|
5
|
+
const browser = await pw.chromium.launch({ headless });
|
|
6
|
+
const page = await browser.newPage();
|
|
7
|
+
const targetUrl = new URL(config.url);
|
|
8
|
+
// Set fisgon cookie so server probes can identify this session
|
|
9
|
+
await page.context().addCookies([
|
|
10
|
+
{
|
|
11
|
+
name: 'fisgon',
|
|
12
|
+
value: sessionId,
|
|
13
|
+
domain: targetUrl.hostname,
|
|
14
|
+
path: '/',
|
|
15
|
+
},
|
|
16
|
+
]);
|
|
17
|
+
// Inject browser probes (fetch, navigation, WS bootstrap)
|
|
18
|
+
const probeScript = createInjectableScript(config, sessionId);
|
|
19
|
+
await page.addInitScript(probeScript);
|
|
20
|
+
const cleanup = async () => {
|
|
21
|
+
await browser.close();
|
|
22
|
+
};
|
|
23
|
+
return { browser, page, cleanup };
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=browser-setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-setup.js","sourceRoot":"","sources":["../../src/cli/browser-setup.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AAS5D,MAAM,CAAC,KAAK,UAAU,aAAa,CAClC,MAAoB,EACpB,SAAiB,EACjB,OAAgC;IAEhC,MAAM,EAAE,GAAG,CAAC,MAAM,MAAM,CAAC,YAAY,CAAC,CAIrC,CAAA;IAED,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,KAAK,CAAA;IAC3C,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAA;IACtD,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAA;IACpC,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IAErC,+DAA+D;IAC/D,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,UAAU,CAAC;QAC/B;YACC,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,SAAS;YAChB,MAAM,EAAE,SAAS,CAAC,QAAQ;YAC1B,IAAI,EAAE,GAAG;SACT;KACD,CAAC,CAAA;IAEF,0DAA0D;IAC1D,MAAM,WAAW,GAAG,sBAAsB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IAC7D,MAAM,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,CAAA;IAErC,MAAM,OAAO,GAAG,KAAK,IAAI,EAAE;QAC1B,MAAM,OAAO,CAAC,KAAK,EAAE,CAAA;IACtB,CAAC,CAAA;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;AAClC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/actions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAMnC,eAAO,MAAM,cAAc,SA4BxB,CAAA"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { connectToAgent } from '../connection.js';
|
|
3
|
+
import { getRunningSession } from '../session-file.js';
|
|
4
|
+
export const actionsCommand = new Command('actions')
|
|
5
|
+
.description('List available actions on the current page')
|
|
6
|
+
.action(async () => {
|
|
7
|
+
const session = getRunningSession();
|
|
8
|
+
if (!session) {
|
|
9
|
+
console.error('No running Fisgon session. Run `fisgon start` first.');
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
const conn = await connectToAgent({
|
|
14
|
+
port: session.port,
|
|
15
|
+
agent: session.agent,
|
|
16
|
+
env: session.env,
|
|
17
|
+
sessionId: session.sessionId,
|
|
18
|
+
});
|
|
19
|
+
const result = await conn.call('getActions', [session.sessionId]);
|
|
20
|
+
console.log(JSON.stringify(result.actions, null, 2));
|
|
21
|
+
conn.close();
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
console.error('Actions failed:', err);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
//# sourceMappingURL=actions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../../../src/cli/commands/actions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAGnC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAEtD,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,OAAO,CAAC,SAAS,CAAC;KAClD,WAAW,CAAC,4CAA4C,CAAC;KACzD,MAAM,CAAC,KAAK,IAAI,EAAE;IAClB,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAA;IACnC,IAAI,CAAC,OAAO,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,sDAAsD,CAAC,CAAA;QACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAChB,CAAC;IAED,IAAI,CAAC;QACJ,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC;YACjC,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,SAAS,EAAE,OAAO,CAAC,SAAS;SAC5B,CAAC,CAAA;QACF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAC7B,YAAY,EACZ,CAAC,OAAO,CAAC,SAAS,CAAC,CACnB,CAAA;QAED,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;QAEpD,IAAI,CAAC,KAAK,EAAE,CAAA;IACb,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAA;QACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAChB,CAAC;AACF,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"do.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/do.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAyBnC,eAAO,MAAM,SAAS,SAuJnB,CAAA"}
|