opencode-pair-autonomy 1.0.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 +90 -0
- package/bin/opencode-pair-autonomy.js +20 -0
- package/dist/__tests__/comment-guard.test.d.ts +1 -0
- package/dist/__tests__/config.test.d.ts +1 -0
- package/dist/__tests__/learning.test.d.ts +1 -0
- package/dist/__tests__/plan-mode.test.d.ts +1 -0
- package/dist/agents.d.ts +2 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +15351 -0
- package/dist/commands.d.ts +2 -0
- package/dist/config.d.ts +3 -0
- package/dist/hooks/comment-guard.d.ts +15 -0
- package/dist/hooks/file-edited.d.ts +7 -0
- package/dist/hooks/index.d.ts +46 -0
- package/dist/hooks/post-tool-use.d.ts +5 -0
- package/dist/hooks/pre-compact.d.ts +4 -0
- package/dist/hooks/pre-tool-use.d.ts +5 -0
- package/dist/hooks/prompt-refiner.d.ts +38 -0
- package/dist/hooks/runtime.d.ts +91 -0
- package/dist/hooks/sdk.d.ts +6 -0
- package/dist/hooks/session-end.d.ts +4 -0
- package/dist/hooks/session-start.d.ts +19 -0
- package/dist/hooks/stop.d.ts +5 -0
- package/dist/i18n/index.d.ts +15 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +17823 -0
- package/dist/installer.d.ts +12 -0
- package/dist/learning/analyzer.d.ts +15 -0
- package/dist/learning/store.d.ts +4 -0
- package/dist/learning/types.d.ts +32 -0
- package/dist/mcp.d.ts +4 -0
- package/dist/project-facts.d.ts +8 -0
- package/dist/prompts/coordinator.d.ts +2 -0
- package/dist/prompts/shared.d.ts +5 -0
- package/dist/prompts/workers.d.ts +8 -0
- package/dist/types.d.ts +81 -0
- package/dist/utils.d.ts +6 -0
- package/examples/opencode-pair-autonomy.jsonc +35 -0
- package/examples/opencode.jsonc +17 -0
- package/package.json +103 -0
- package/vendor/mcp/pg-mcp/README.md +91 -0
- package/vendor/mcp/pg-mcp/config.example.json +26 -0
- package/vendor/mcp/pg-mcp/config.json +15 -0
- package/vendor/mcp/pg-mcp/package-lock.json +1288 -0
- package/vendor/mcp/pg-mcp/package.json +18 -0
- package/vendor/mcp/pg-mcp/src/config.js +71 -0
- package/vendor/mcp/pg-mcp/src/db.js +85 -0
- package/vendor/mcp/pg-mcp/src/index.js +203 -0
- package/vendor/mcp/pg-mcp/src/sqlGuard.js +75 -0
- package/vendor/mcp/pg-mcp/src/tools.js +89 -0
- package/vendor/mcp/ssh-mcp/README.md +46 -0
- package/vendor/mcp/ssh-mcp/config.example.json +23 -0
- package/vendor/mcp/ssh-mcp/config.json +6 -0
- package/vendor/mcp/ssh-mcp/package-lock.json +1142 -0
- package/vendor/mcp/ssh-mcp/package.json +18 -0
- package/vendor/mcp/ssh-mcp/src/config.js +140 -0
- package/vendor/mcp/ssh-mcp/src/index.js +130 -0
- package/vendor/mcp/ssh-mcp/src/ssh.js +163 -0
- package/vendor/mcp/sudo-mcp/README.md +51 -0
- package/vendor/mcp/sudo-mcp/config.example.json +28 -0
- package/vendor/mcp/sudo-mcp/config.json +28 -0
- package/vendor/mcp/sudo-mcp/package-lock.json +1145 -0
- package/vendor/mcp/sudo-mcp/package.json +18 -0
- package/vendor/mcp/sudo-mcp/src/config.js +57 -0
- package/vendor/mcp/sudo-mcp/src/index.js +267 -0
- package/vendor/mcp/sudo-mcp/src/runner.js +168 -0
- package/vendor/mcp/web-agent-mcp/package-lock.json +2886 -0
- package/vendor/mcp/web-agent-mcp/package.json +28 -0
- package/vendor/mcp/web-agent-mcp/src/adapters/cloakbrowser/adapter.ts +335 -0
- package/vendor/mcp/web-agent-mcp/src/adapters/cloakbrowser/auth-heuristics.ts +324 -0
- package/vendor/mcp/web-agent-mcp/src/adapters/cloakbrowser/launcher.ts +1340 -0
- package/vendor/mcp/web-agent-mcp/src/config/env.ts +107 -0
- package/vendor/mcp/web-agent-mcp/src/core/action-flow.ts +82 -0
- package/vendor/mcp/web-agent-mcp/src/core/artifact-store.ts +109 -0
- package/vendor/mcp/web-agent-mcp/src/core/errors.ts +108 -0
- package/vendor/mcp/web-agent-mcp/src/core/observation-flow.ts +38 -0
- package/vendor/mcp/web-agent-mcp/src/core/policy-engine.ts +113 -0
- package/vendor/mcp/web-agent-mcp/src/core/retry-policy.ts +42 -0
- package/vendor/mcp/web-agent-mcp/src/core/session-manager.ts +670 -0
- package/vendor/mcp/web-agent-mcp/src/core/session-restart-policy.ts +34 -0
- package/vendor/mcp/web-agent-mcp/src/core/task-history.ts +97 -0
- package/vendor/mcp/web-agent-mcp/src/index.ts +3 -0
- package/vendor/mcp/web-agent-mcp/src/schemas/act.ts +167 -0
- package/vendor/mcp/web-agent-mcp/src/schemas/common.ts +56 -0
- package/vendor/mcp/web-agent-mcp/src/schemas/observe.ts +214 -0
- package/vendor/mcp/web-agent-mcp/src/schemas/page.ts +21 -0
- package/vendor/mcp/web-agent-mcp/src/schemas/policy.ts +42 -0
- package/vendor/mcp/web-agent-mcp/src/schemas/runtime.ts +21 -0
- package/vendor/mcp/web-agent-mcp/src/schemas/session.ts +63 -0
- package/vendor/mcp/web-agent-mcp/src/server.ts +75 -0
- package/vendor/mcp/web-agent-mcp/src/tools/act/click.ts +68 -0
- package/vendor/mcp/web-agent-mcp/src/tools/act/drag.ts +57 -0
- package/vendor/mcp/web-agent-mcp/src/tools/act/enter-code.ts +78 -0
- package/vendor/mcp/web-agent-mcp/src/tools/act/fill.ts +65 -0
- package/vendor/mcp/web-agent-mcp/src/tools/act/pinch.ts +58 -0
- package/vendor/mcp/web-agent-mcp/src/tools/act/press.ts +67 -0
- package/vendor/mcp/web-agent-mcp/src/tools/act/shared.ts +73 -0
- package/vendor/mcp/web-agent-mcp/src/tools/act/swipe.ts +59 -0
- package/vendor/mcp/web-agent-mcp/src/tools/act/wait-for.ts +56 -0
- package/vendor/mcp/web-agent-mcp/src/tools/act/wheel.ts +59 -0
- package/vendor/mcp/web-agent-mcp/src/tools/observe/a11y.ts +60 -0
- package/vendor/mcp/web-agent-mcp/src/tools/observe/auth-state.ts +92 -0
- package/vendor/mcp/web-agent-mcp/src/tools/observe/boxes.ts +66 -0
- package/vendor/mcp/web-agent-mcp/src/tools/observe/console.ts +67 -0
- package/vendor/mcp/web-agent-mcp/src/tools/observe/dom.ts +60 -0
- package/vendor/mcp/web-agent-mcp/src/tools/observe/network.ts +67 -0
- package/vendor/mcp/web-agent-mcp/src/tools/observe/page-state.ts +93 -0
- package/vendor/mcp/web-agent-mcp/src/tools/observe/screenshot.ts +73 -0
- package/vendor/mcp/web-agent-mcp/src/tools/observe/text.ts +70 -0
- package/vendor/mcp/web-agent-mcp/src/tools/observe/wait-for-network.ts +70 -0
- package/vendor/mcp/web-agent-mcp/src/tools/page/navigate.ts +59 -0
- package/vendor/mcp/web-agent-mcp/src/tools/policy/recommend-observation.ts +40 -0
- package/vendor/mcp/web-agent-mcp/src/tools/register-tools.ts +55 -0
- package/vendor/mcp/web-agent-mcp/src/tools/runtime/evaluate-js.ts +83 -0
- package/vendor/mcp/web-agent-mcp/src/tools/session/close.ts +41 -0
- package/vendor/mcp/web-agent-mcp/src/tools/session/create.ts +86 -0
- package/vendor/mcp/web-agent-mcp/src/tools/session/restart.ts +72 -0
- package/vendor/mcp/web-agent-mcp/src/utils/fs.ts +28 -0
- package/vendor/mcp/web-agent-mcp/src/utils/ids.ts +9 -0
- package/vendor/mcp/web-agent-mcp/src/utils/time.ts +7 -0
- package/vendor/mcp/web-agent-mcp/tsconfig.json +22 -0
- package/vendor/skills/editorial-technical-ui/SKILL.md +84 -0
- package/vendor/skills/figma-console/SKILL.md +839 -0
- package/vendor/skills/go-fiber-postgres/SKILL.md +31 -0
- package/vendor/skills/opencode-plugin-dev/SKILL.md +31 -0
- package/vendor/skills/rust-media-desktop/SKILL.md +30 -0
- package/vendor/skills/vue-vite-ui/SKILL.md +31 -0
- package/vendor/skills/web-agent-browser/SKILL.md +140 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { buildFollowUpByGoal } from "../../core/observation-flow.js";
|
|
4
|
+
import type { RuntimeServices } from "../../server.js";
|
|
5
|
+
import { createFailureResult } from "../../core/errors.js";
|
|
6
|
+
import { createToolSuccess } from "../../schemas/common.js";
|
|
7
|
+
import { observeSessionInputSchema, observeTextOutputSchema } from "../../schemas/observe.js";
|
|
8
|
+
|
|
9
|
+
const observeTextInputSchema = observeSessionInputSchema.extend({
|
|
10
|
+
format: z.enum(["text", "markdown"]).default("text")
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
export function registerObserveTextTool(server: McpServer, services: RuntimeServices) {
|
|
14
|
+
server.registerTool(
|
|
15
|
+
"observe.text",
|
|
16
|
+
{
|
|
17
|
+
title: "Observe Text",
|
|
18
|
+
description: "Return extracted page text as a cheap observation artifact.",
|
|
19
|
+
inputSchema: observeTextInputSchema,
|
|
20
|
+
outputSchema: observeTextOutputSchema,
|
|
21
|
+
annotations: {
|
|
22
|
+
readOnlyHint: true,
|
|
23
|
+
destructiveHint: false,
|
|
24
|
+
idempotentHint: false,
|
|
25
|
+
openWorldHint: false
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
async (input: z.infer<typeof observeTextInputSchema>) => {
|
|
29
|
+
try {
|
|
30
|
+
const action = await services.history.startAction("observe.text", input, {
|
|
31
|
+
session_id: input.session_id,
|
|
32
|
+
page_id: input.page_id
|
|
33
|
+
});
|
|
34
|
+
const { session, page, result } = await services.sessions.observeText(
|
|
35
|
+
input.session_id,
|
|
36
|
+
input.page_id,
|
|
37
|
+
input.format
|
|
38
|
+
);
|
|
39
|
+
const artifact = await services.artifacts.writeText(input.format, result.content, {
|
|
40
|
+
session_id: session.sessionId,
|
|
41
|
+
page_id: page.pageId,
|
|
42
|
+
action_id: action.action_id,
|
|
43
|
+
url: result.url,
|
|
44
|
+
title: result.title,
|
|
45
|
+
meta: { requested_format: input.format, truncated: result.truncated }
|
|
46
|
+
});
|
|
47
|
+
const data = {
|
|
48
|
+
artifact_id: artifact.artifact_id,
|
|
49
|
+
format: input.format,
|
|
50
|
+
content: result.content,
|
|
51
|
+
truncated: result.truncated,
|
|
52
|
+
url: result.url,
|
|
53
|
+
title: result.title,
|
|
54
|
+
follow_up_by_goal: buildFollowUpByGoal({
|
|
55
|
+
pageStateKnown: true,
|
|
56
|
+
targetSelectorKnown: false,
|
|
57
|
+
recentFailure: "none"
|
|
58
|
+
})
|
|
59
|
+
};
|
|
60
|
+
await services.history.finishAction(action, "succeeded", {
|
|
61
|
+
artifact_id: artifact.artifact_id,
|
|
62
|
+
truncated: result.truncated
|
|
63
|
+
});
|
|
64
|
+
return createToolSuccess({ ok: true, code: "OK", action_id: action.action_id, session_id: session.sessionId, page_id: page.pageId, artifact_ids: [artifact.artifact_id], data });
|
|
65
|
+
} catch (error) {
|
|
66
|
+
return createFailureResult(error);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { createFailureResult } from "../../core/errors.js";
|
|
4
|
+
import {
|
|
5
|
+
waitForNetworkInputSchema,
|
|
6
|
+
waitForNetworkOutputSchema
|
|
7
|
+
} from "../../schemas/observe.js";
|
|
8
|
+
import { createToolSuccess } from "../../schemas/common.js";
|
|
9
|
+
import type { RuntimeServices } from "../../server.js";
|
|
10
|
+
|
|
11
|
+
export function registerWaitForNetworkTool(server: McpServer, services: RuntimeServices) {
|
|
12
|
+
server.registerTool(
|
|
13
|
+
"observe.wait_for_network",
|
|
14
|
+
{
|
|
15
|
+
title: "Wait For Network",
|
|
16
|
+
description: "Wait for a matching network response or failure in the active page session.",
|
|
17
|
+
inputSchema: waitForNetworkInputSchema,
|
|
18
|
+
outputSchema: waitForNetworkOutputSchema,
|
|
19
|
+
annotations: {
|
|
20
|
+
readOnlyHint: true,
|
|
21
|
+
destructiveHint: false,
|
|
22
|
+
idempotentHint: false,
|
|
23
|
+
openWorldHint: true
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
async (input: z.infer<typeof waitForNetworkInputSchema>) => {
|
|
27
|
+
try {
|
|
28
|
+
const action = await services.history.startAction("observe.wait_for_network", input, {
|
|
29
|
+
session_id: input.session_id,
|
|
30
|
+
page_id: input.page_id
|
|
31
|
+
});
|
|
32
|
+
const { session, page, result } = await services.sessions.waitForNetwork(
|
|
33
|
+
input.session_id,
|
|
34
|
+
input.page_id,
|
|
35
|
+
{
|
|
36
|
+
urlPattern: input.url_pattern,
|
|
37
|
+
useRegex: input.use_regex,
|
|
38
|
+
status: input.status,
|
|
39
|
+
outcome: input.outcome,
|
|
40
|
+
timeoutMs: input.timeout_ms,
|
|
41
|
+
pollIntervalMs: input.poll_interval_ms
|
|
42
|
+
}
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
const data = {
|
|
46
|
+
entry: result.entry,
|
|
47
|
+
elapsed_ms: result.elapsedMs
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
await services.history.finishAction(action, "succeeded", {
|
|
51
|
+
elapsed_ms: result.elapsedMs,
|
|
52
|
+
matched_url: result.entry.url,
|
|
53
|
+
status: result.entry.status,
|
|
54
|
+
outcome: result.entry.outcome
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
return createToolSuccess({
|
|
58
|
+
ok: true,
|
|
59
|
+
code: "OK",
|
|
60
|
+
action_id: action.action_id,
|
|
61
|
+
session_id: session.sessionId,
|
|
62
|
+
page_id: page.pageId,
|
|
63
|
+
data
|
|
64
|
+
});
|
|
65
|
+
} catch (error) {
|
|
66
|
+
return createFailureResult(error);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { buildFollowUpByGoal } from "../../core/observation-flow.js";
|
|
4
|
+
import type { RuntimeServices } from "../../server.js";
|
|
5
|
+
import { createId } from "../../utils/ids.js";
|
|
6
|
+
import { createFailureResult } from "../../core/errors.js";
|
|
7
|
+
import { createToolSuccess } from "../../schemas/common.js";
|
|
8
|
+
import { navigatePageInputSchema, navigatePageOutputSchema } from "../../schemas/page.js";
|
|
9
|
+
|
|
10
|
+
export function registerNavigatePageTool(server: McpServer, services: RuntimeServices) {
|
|
11
|
+
server.registerTool(
|
|
12
|
+
"page.navigate",
|
|
13
|
+
{
|
|
14
|
+
title: "Navigate Page",
|
|
15
|
+
description: "Navigate the active page to a URL and return lightweight metadata.",
|
|
16
|
+
inputSchema: navigatePageInputSchema,
|
|
17
|
+
outputSchema: navigatePageOutputSchema,
|
|
18
|
+
annotations: {
|
|
19
|
+
readOnlyHint: false,
|
|
20
|
+
destructiveHint: false,
|
|
21
|
+
idempotentHint: false,
|
|
22
|
+
openWorldHint: true
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
async (input: z.infer<typeof navigatePageInputSchema>) => {
|
|
26
|
+
try {
|
|
27
|
+
const action = await services.history.startAction("page.navigate", input, {
|
|
28
|
+
session_id: input.session_id,
|
|
29
|
+
page_id: input.page_id
|
|
30
|
+
});
|
|
31
|
+
const { session, page, result } = await services.sessions.navigate(
|
|
32
|
+
input.session_id,
|
|
33
|
+
input.page_id,
|
|
34
|
+
input.url,
|
|
35
|
+
input.wait_until
|
|
36
|
+
);
|
|
37
|
+
const response = {
|
|
38
|
+
page_id: page.pageId,
|
|
39
|
+
requested_url: result.requestedUrl,
|
|
40
|
+
final_url: result.finalUrl,
|
|
41
|
+
title: result.title,
|
|
42
|
+
navigation_id: createId("action"),
|
|
43
|
+
timings: {
|
|
44
|
+
elapsed_ms: result.elapsedMs
|
|
45
|
+
},
|
|
46
|
+
follow_up_by_goal: buildFollowUpByGoal({
|
|
47
|
+
pageStateKnown: false,
|
|
48
|
+
targetSelectorKnown: false,
|
|
49
|
+
recentFailure: "none"
|
|
50
|
+
})
|
|
51
|
+
};
|
|
52
|
+
await services.history.finishAction(action, "succeeded", response);
|
|
53
|
+
return createToolSuccess({ ok: true, code: "OK", action_id: action.action_id, session_id: session.sessionId, page_id: page.pageId, data: response });
|
|
54
|
+
} catch (error) {
|
|
55
|
+
return createFailureResult(error);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
);
|
|
59
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { recommendObservation } from "../../core/policy-engine.js";
|
|
4
|
+
import { toPolicyEnvelope } from "../../core/observation-flow.js";
|
|
5
|
+
import { createFailureResult } from "../../core/errors.js";
|
|
6
|
+
import { createToolSuccess } from "../../schemas/common.js";
|
|
7
|
+
import {
|
|
8
|
+
recommendObservationInputSchema,
|
|
9
|
+
recommendObservationOutputSchema
|
|
10
|
+
} from "../../schemas/policy.js";
|
|
11
|
+
|
|
12
|
+
export function registerRecommendObservationTool(server: McpServer) {
|
|
13
|
+
server.registerTool(
|
|
14
|
+
"policy.recommend_observation",
|
|
15
|
+
{
|
|
16
|
+
title: "Recommend Observation",
|
|
17
|
+
description: "Recommend the cheapest next observation tool before an interaction or verification step.",
|
|
18
|
+
inputSchema: recommendObservationInputSchema,
|
|
19
|
+
outputSchema: recommendObservationOutputSchema,
|
|
20
|
+
annotations: {
|
|
21
|
+
readOnlyHint: true,
|
|
22
|
+
destructiveHint: false,
|
|
23
|
+
idempotentHint: true,
|
|
24
|
+
openWorldHint: false
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
async (input: z.infer<typeof recommendObservationInputSchema>) => {
|
|
28
|
+
try {
|
|
29
|
+
const result = recommendObservation(input);
|
|
30
|
+
return createToolSuccess({
|
|
31
|
+
ok: true,
|
|
32
|
+
code: "OK",
|
|
33
|
+
data: toPolicyEnvelope(result)
|
|
34
|
+
});
|
|
35
|
+
} catch (error) {
|
|
36
|
+
return createFailureResult(error);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
);
|
|
40
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import type { RuntimeServices } from "../server.js";
|
|
3
|
+
import { registerClickTool } from "./act/click.js";
|
|
4
|
+
import { registerDragTool } from "./act/drag.js";
|
|
5
|
+
import { registerEnterCodeTool } from "./act/enter-code.js";
|
|
6
|
+
import { registerFillTool } from "./act/fill.js";
|
|
7
|
+
import { registerPinchTool } from "./act/pinch.js";
|
|
8
|
+
import { registerPressTool } from "./act/press.js";
|
|
9
|
+
import { registerSwipeTool } from "./act/swipe.js";
|
|
10
|
+
import { registerWaitForTool } from "./act/wait-for.js";
|
|
11
|
+
import { registerWheelTool } from "./act/wheel.js";
|
|
12
|
+
import { registerNavigatePageTool } from "./page/navigate.js";
|
|
13
|
+
import { registerObserveA11yTool } from "./observe/a11y.js";
|
|
14
|
+
import { registerObserveAuthStateTool } from "./observe/auth-state.js";
|
|
15
|
+
import { registerObserveBoxesTool } from "./observe/boxes.js";
|
|
16
|
+
import { registerObserveConsoleTool } from "./observe/console.js";
|
|
17
|
+
import { registerObserveDomTool } from "./observe/dom.js";
|
|
18
|
+
import { registerObserveNetworkTool } from "./observe/network.js";
|
|
19
|
+
import { registerObservePageStateTool } from "./observe/page-state.js";
|
|
20
|
+
import { registerObserveScreenshotTool } from "./observe/screenshot.js";
|
|
21
|
+
import { registerObserveTextTool } from "./observe/text.js";
|
|
22
|
+
import { registerWaitForNetworkTool } from "./observe/wait-for-network.js";
|
|
23
|
+
import { registerRecommendObservationTool } from "./policy/recommend-observation.js";
|
|
24
|
+
import { registerEvaluateJsTool } from "./runtime/evaluate-js.js";
|
|
25
|
+
import { registerCloseSessionTool } from "./session/close.js";
|
|
26
|
+
import { registerCreateSessionTool } from "./session/create.js";
|
|
27
|
+
import { registerRestartSessionTool } from "./session/restart.js";
|
|
28
|
+
|
|
29
|
+
export function registerTools(server: McpServer, services: RuntimeServices) {
|
|
30
|
+
registerCreateSessionTool(server, services);
|
|
31
|
+
registerCloseSessionTool(server, services);
|
|
32
|
+
registerRestartSessionTool(server, services);
|
|
33
|
+
registerNavigatePageTool(server, services);
|
|
34
|
+
registerClickTool(server, services);
|
|
35
|
+
registerDragTool(server, services);
|
|
36
|
+
registerEnterCodeTool(server, services);
|
|
37
|
+
registerFillTool(server, services);
|
|
38
|
+
registerPinchTool(server, services);
|
|
39
|
+
registerPressTool(server, services);
|
|
40
|
+
registerSwipeTool(server, services);
|
|
41
|
+
registerWaitForTool(server, services);
|
|
42
|
+
registerWheelTool(server, services);
|
|
43
|
+
registerObserveA11yTool(server, services);
|
|
44
|
+
registerObserveAuthStateTool(server, services);
|
|
45
|
+
registerObserveBoxesTool(server, services);
|
|
46
|
+
registerObserveConsoleTool(server, services);
|
|
47
|
+
registerObserveDomTool(server, services);
|
|
48
|
+
registerObserveNetworkTool(server, services);
|
|
49
|
+
registerObservePageStateTool(server, services);
|
|
50
|
+
registerObserveTextTool(server, services);
|
|
51
|
+
registerObserveScreenshotTool(server, services);
|
|
52
|
+
registerWaitForNetworkTool(server, services);
|
|
53
|
+
registerRecommendObservationTool(server);
|
|
54
|
+
registerEvaluateJsTool(server, services);
|
|
55
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import type { RuntimeServices } from "../../server.js";
|
|
4
|
+
import { createFailureResult } from "../../core/errors.js";
|
|
5
|
+
import { createToolSuccess } from "../../schemas/common.js";
|
|
6
|
+
import { evaluateJsInputSchema, evaluateJsOutputSchema } from "../../schemas/runtime.js";
|
|
7
|
+
|
|
8
|
+
const INLINE_LIMIT = 8000;
|
|
9
|
+
|
|
10
|
+
export function registerEvaluateJsTool(server: McpServer, services: RuntimeServices) {
|
|
11
|
+
server.registerTool(
|
|
12
|
+
"runtime.evaluate_js",
|
|
13
|
+
{
|
|
14
|
+
title: "Evaluate Runtime JavaScript",
|
|
15
|
+
description: "Evaluate a JavaScript expression in the current page context and persist the result as an artifact.",
|
|
16
|
+
inputSchema: evaluateJsInputSchema,
|
|
17
|
+
outputSchema: evaluateJsOutputSchema,
|
|
18
|
+
annotations: {
|
|
19
|
+
readOnlyHint: false,
|
|
20
|
+
destructiveHint: false,
|
|
21
|
+
idempotentHint: false,
|
|
22
|
+
openWorldHint: true
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
async (input: z.infer<typeof evaluateJsInputSchema>) => {
|
|
26
|
+
try {
|
|
27
|
+
const action = await services.history.startAction("runtime.evaluate_js", input, {
|
|
28
|
+
session_id: input.session_id,
|
|
29
|
+
page_id: input.page_id
|
|
30
|
+
});
|
|
31
|
+
const { session, page, result } = await services.sessions.evaluateJs(
|
|
32
|
+
input.session_id,
|
|
33
|
+
input.page_id,
|
|
34
|
+
{
|
|
35
|
+
expression: input.expression,
|
|
36
|
+
awaitPromise: input.await_promise
|
|
37
|
+
}
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
const serialized = JSON.stringify(result.value, null, 2);
|
|
41
|
+
const artifact = await services.artifacts.writeText("eval", serialized, {
|
|
42
|
+
session_id: session.sessionId,
|
|
43
|
+
page_id: page.pageId,
|
|
44
|
+
action_id: action.action_id,
|
|
45
|
+
url: result.url,
|
|
46
|
+
title: result.title,
|
|
47
|
+
meta: {
|
|
48
|
+
await_promise: input.await_promise,
|
|
49
|
+
inline: serialized.length <= INLINE_LIMIT
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const data = {
|
|
54
|
+
artifact_id: artifact.artifact_id,
|
|
55
|
+
value: serialized.length <= INLINE_LIMIT ? result.value : undefined,
|
|
56
|
+
preview: serialized.length <= INLINE_LIMIT ? undefined : `${serialized.slice(0, INLINE_LIMIT)}...`,
|
|
57
|
+
truncated: serialized.length > INLINE_LIMIT,
|
|
58
|
+
url: result.url,
|
|
59
|
+
title: result.title,
|
|
60
|
+
bytes: artifact.bytes,
|
|
61
|
+
storage_path: artifact.storage_path
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
await services.history.finishAction(action, "succeeded", {
|
|
65
|
+
artifact_id: artifact.artifact_id,
|
|
66
|
+
truncated: data.truncated
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
return createToolSuccess({
|
|
70
|
+
ok: true,
|
|
71
|
+
code: "OK",
|
|
72
|
+
action_id: action.action_id,
|
|
73
|
+
session_id: session.sessionId,
|
|
74
|
+
page_id: page.pageId,
|
|
75
|
+
artifact_ids: [artifact.artifact_id],
|
|
76
|
+
data
|
|
77
|
+
});
|
|
78
|
+
} catch (error) {
|
|
79
|
+
return createFailureResult(error);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
);
|
|
83
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import type { RuntimeServices } from "../../server.js";
|
|
4
|
+
import { createFailureResult } from "../../core/errors.js";
|
|
5
|
+
import { createToolSuccess } from "../../schemas/common.js";
|
|
6
|
+
import { closeSessionInputSchema, sessionCloseOutputSchema } from "../../schemas/session.js";
|
|
7
|
+
|
|
8
|
+
export function registerCloseSessionTool(server: McpServer, services: RuntimeServices) {
|
|
9
|
+
server.registerTool(
|
|
10
|
+
"session.close",
|
|
11
|
+
{
|
|
12
|
+
title: "Close Session",
|
|
13
|
+
description: "Close a browser session and release its runtime resources.",
|
|
14
|
+
inputSchema: closeSessionInputSchema,
|
|
15
|
+
outputSchema: sessionCloseOutputSchema,
|
|
16
|
+
annotations: {
|
|
17
|
+
readOnlyHint: false,
|
|
18
|
+
destructiveHint: true,
|
|
19
|
+
idempotentHint: false,
|
|
20
|
+
openWorldHint: false
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
async (input: z.infer<typeof closeSessionInputSchema>) => {
|
|
24
|
+
try {
|
|
25
|
+
const action = await services.history.startAction("session.close", input, {
|
|
26
|
+
session_id: input.session_id
|
|
27
|
+
});
|
|
28
|
+
const session = await services.sessions.closeSession(input.session_id);
|
|
29
|
+
const data = {
|
|
30
|
+
session_id: session.sessionId,
|
|
31
|
+
closed: true,
|
|
32
|
+
status: session.status
|
|
33
|
+
};
|
|
34
|
+
await services.history.finishAction(action, "succeeded", data);
|
|
35
|
+
return createToolSuccess({ ok: true, code: "OK", action_id: action.action_id, session_id: session.sessionId, data });
|
|
36
|
+
} catch (error) {
|
|
37
|
+
return createFailureResult(error);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
);
|
|
41
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import type { RuntimeServices } from "../../server.js";
|
|
4
|
+
import { createFailureResult } from "../../core/errors.js";
|
|
5
|
+
import { createToolSuccess } from "../../schemas/common.js";
|
|
6
|
+
import {
|
|
7
|
+
createSessionInputSchema,
|
|
8
|
+
sessionOutputSchema,
|
|
9
|
+
} from "../../schemas/session.js";
|
|
10
|
+
|
|
11
|
+
export function registerCreateSessionTool(
|
|
12
|
+
server: McpServer,
|
|
13
|
+
services: RuntimeServices,
|
|
14
|
+
) {
|
|
15
|
+
server.registerTool(
|
|
16
|
+
"session.create",
|
|
17
|
+
{
|
|
18
|
+
title: "Create Session",
|
|
19
|
+
description: "Launch a browser session and create the initial page.",
|
|
20
|
+
inputSchema: createSessionInputSchema,
|
|
21
|
+
outputSchema: sessionOutputSchema,
|
|
22
|
+
annotations: {
|
|
23
|
+
readOnlyHint: false,
|
|
24
|
+
destructiveHint: false,
|
|
25
|
+
idempotentHint: false,
|
|
26
|
+
openWorldHint: false,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
async (input: z.infer<typeof createSessionInputSchema>) => {
|
|
30
|
+
try {
|
|
31
|
+
const action = await services.history.startAction(
|
|
32
|
+
"session.create",
|
|
33
|
+
input,
|
|
34
|
+
);
|
|
35
|
+
const profileMode = input.profile_mode ?? "persistent";
|
|
36
|
+
const session = await services.sessions.createSession({
|
|
37
|
+
profileMode,
|
|
38
|
+
locale: input.locale,
|
|
39
|
+
timezoneId: input.timezone_id,
|
|
40
|
+
userDataDir: input.user_data_dir,
|
|
41
|
+
profileDirectory: input.profile_directory,
|
|
42
|
+
humanize: input.humanize,
|
|
43
|
+
launchArgs: input.launch_args,
|
|
44
|
+
viewport: input.viewport,
|
|
45
|
+
});
|
|
46
|
+
const data = {
|
|
47
|
+
session_id: session.sessionId,
|
|
48
|
+
context_id: session.contextId,
|
|
49
|
+
page_id: session.primaryPageId,
|
|
50
|
+
status: session.status,
|
|
51
|
+
profile_mode: session.profileMode,
|
|
52
|
+
locale: session.locale,
|
|
53
|
+
timezone_id: session.timezoneId,
|
|
54
|
+
user_data_dir: session.userDataDir,
|
|
55
|
+
profile_directory: session.profileDirectory,
|
|
56
|
+
humanize: session.humanize,
|
|
57
|
+
launch_args: session.launchArgs,
|
|
58
|
+
viewport: session.viewport,
|
|
59
|
+
created_at: session.createdAt,
|
|
60
|
+
health: {
|
|
61
|
+
consecutive_errors: session.consecutiveErrors,
|
|
62
|
+
last_error_at: session.lastErrorAt,
|
|
63
|
+
restart_recommended: false,
|
|
64
|
+
},
|
|
65
|
+
capabilities: {
|
|
66
|
+
observe: true,
|
|
67
|
+
screenshot: true,
|
|
68
|
+
evaluate: true,
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
services.sessions.recordSuccess(session.sessionId);
|
|
72
|
+
await services.history.finishAction(action, "succeeded", data);
|
|
73
|
+
return createToolSuccess({
|
|
74
|
+
ok: true,
|
|
75
|
+
code: "OK",
|
|
76
|
+
action_id: action.action_id,
|
|
77
|
+
session_id: session.sessionId,
|
|
78
|
+
page_id: session.primaryPageId,
|
|
79
|
+
data,
|
|
80
|
+
});
|
|
81
|
+
} catch (error) {
|
|
82
|
+
return createFailureResult(error);
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
);
|
|
86
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import type { RuntimeServices } from "../../server.js";
|
|
4
|
+
import { createFailureResult } from "../../core/errors.js";
|
|
5
|
+
import { createToolSuccess } from "../../schemas/common.js";
|
|
6
|
+
import {
|
|
7
|
+
restartSessionInputSchema,
|
|
8
|
+
sessionRestartOutputSchema
|
|
9
|
+
} from "../../schemas/session.js";
|
|
10
|
+
|
|
11
|
+
export function registerRestartSessionTool(server: McpServer, services: RuntimeServices) {
|
|
12
|
+
server.registerTool(
|
|
13
|
+
"session.restart",
|
|
14
|
+
{
|
|
15
|
+
title: "Restart Session",
|
|
16
|
+
description: "Restart a browser session while preserving its launch profile settings.",
|
|
17
|
+
inputSchema: restartSessionInputSchema,
|
|
18
|
+
outputSchema: sessionRestartOutputSchema,
|
|
19
|
+
annotations: {
|
|
20
|
+
readOnlyHint: false,
|
|
21
|
+
destructiveHint: false,
|
|
22
|
+
idempotentHint: false,
|
|
23
|
+
openWorldHint: false
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
async (input: z.infer<typeof restartSessionInputSchema>) => {
|
|
27
|
+
try {
|
|
28
|
+
const action = await services.history.startAction("session.restart", input, {
|
|
29
|
+
session_id: input.session_id
|
|
30
|
+
});
|
|
31
|
+
const session = await services.sessions.restartSession(input.session_id);
|
|
32
|
+
const health = services.sessions.getSessionHealth(session.sessionId);
|
|
33
|
+
const data = {
|
|
34
|
+
session_id: session.sessionId,
|
|
35
|
+
context_id: session.contextId,
|
|
36
|
+
page_id: session.primaryPageId,
|
|
37
|
+
status: session.status,
|
|
38
|
+
profile_mode: session.profileMode,
|
|
39
|
+
locale: session.locale,
|
|
40
|
+
timezone_id: session.timezoneId,
|
|
41
|
+
user_data_dir: session.userDataDir,
|
|
42
|
+
profile_directory: session.profileDirectory,
|
|
43
|
+
humanize: session.humanize,
|
|
44
|
+
launch_args: session.launchArgs,
|
|
45
|
+
viewport: session.viewport,
|
|
46
|
+
created_at: session.createdAt,
|
|
47
|
+
health: {
|
|
48
|
+
consecutive_errors: health.consecutiveErrors,
|
|
49
|
+
last_error_at: health.lastErrorAt,
|
|
50
|
+
restart_recommended: health.restartRecommended
|
|
51
|
+
},
|
|
52
|
+
capabilities: {
|
|
53
|
+
observe: true,
|
|
54
|
+
screenshot: true,
|
|
55
|
+
evaluate: true
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
await services.history.finishAction(action, "succeeded", data);
|
|
59
|
+
return createToolSuccess({
|
|
60
|
+
ok: true,
|
|
61
|
+
code: "OK",
|
|
62
|
+
action_id: action.action_id,
|
|
63
|
+
session_id: session.sessionId,
|
|
64
|
+
page_id: session.primaryPageId,
|
|
65
|
+
data
|
|
66
|
+
});
|
|
67
|
+
} catch (error) {
|
|
68
|
+
return createFailureResult(error);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
);
|
|
72
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
|
|
4
|
+
export async function ensureDir(dirPath: string) {
|
|
5
|
+
await fs.mkdir(dirPath, { recursive: true });
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export async function appendJsonLine(filePath: string, value: unknown) {
|
|
9
|
+
await ensureDir(path.dirname(filePath));
|
|
10
|
+
await fs.appendFile(filePath, `${JSON.stringify(value)}\n`, "utf8");
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export async function readJsonFile<T>(filePath: string, fallback: T): Promise<T> {
|
|
14
|
+
try {
|
|
15
|
+
const raw = await fs.readFile(filePath, "utf8");
|
|
16
|
+
return JSON.parse(raw) as T;
|
|
17
|
+
} catch (error) {
|
|
18
|
+
if ((error as NodeJS.ErrnoException).code === "ENOENT") {
|
|
19
|
+
return fallback;
|
|
20
|
+
}
|
|
21
|
+
throw error;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export async function writeJsonFile(filePath: string, value: unknown) {
|
|
26
|
+
await ensureDir(path.dirname(filePath));
|
|
27
|
+
await fs.writeFile(filePath, `${JSON.stringify(value, null, 2)}\n`, "utf8");
|
|
28
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
type IdPrefix = "session" | "context" | "page" | "task" | "action" | "artifact";
|
|
2
|
+
|
|
3
|
+
function randomPart() {
|
|
4
|
+
return Math.random().toString(36).slice(2, 10);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function createId(prefix: IdPrefix) {
|
|
8
|
+
return `${prefix}_${Date.now().toString(36)}_${randomPart()}`;
|
|
9
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"strict": true,
|
|
7
|
+
"rootDir": ".",
|
|
8
|
+
"outDir": "dist",
|
|
9
|
+
"declaration": true,
|
|
10
|
+
"sourceMap": true,
|
|
11
|
+
"esModuleInterop": true,
|
|
12
|
+
"forceConsistentCasingInFileNames": true,
|
|
13
|
+
"skipLibCheck": true,
|
|
14
|
+
"resolveJsonModule": true,
|
|
15
|
+
"verbatimModuleSyntax": true,
|
|
16
|
+
"noUncheckedIndexedAccess": true,
|
|
17
|
+
"noImplicitOverride": true,
|
|
18
|
+
"types": ["node", "vitest/globals"]
|
|
19
|
+
},
|
|
20
|
+
"include": ["src/**/*.ts", "tests/**/*.ts"],
|
|
21
|
+
"exclude": ["dist", "node_modules"]
|
|
22
|
+
}
|