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,75 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
+
import { pathToFileURL } from "node:url";
|
|
4
|
+
import { realpathSync } from "node:fs";
|
|
5
|
+
import { loadEnv } from "./config/env.js";
|
|
6
|
+
import { createCloakBrowserAdapter } from "./adapters/cloakbrowser/launcher.js";
|
|
7
|
+
import { ArtifactStore } from "./core/artifact-store.js";
|
|
8
|
+
import { SessionManager } from "./core/session-manager.js";
|
|
9
|
+
import { TaskHistoryStore } from "./core/task-history.js";
|
|
10
|
+
import { registerTools } from "./tools/register-tools.js";
|
|
11
|
+
|
|
12
|
+
export type RuntimeServices = {
|
|
13
|
+
env: ReturnType<typeof loadEnv>;
|
|
14
|
+
artifacts: ArtifactStore;
|
|
15
|
+
history: TaskHistoryStore;
|
|
16
|
+
sessions: SessionManager;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export function createRuntimeServices() {
|
|
20
|
+
const env = loadEnv();
|
|
21
|
+
const artifacts = new ArtifactStore(env);
|
|
22
|
+
const history = new TaskHistoryStore(env);
|
|
23
|
+
const adapter = createCloakBrowserAdapter(env);
|
|
24
|
+
const sessions = new SessionManager({ env, adapter });
|
|
25
|
+
|
|
26
|
+
return { env, artifacts, history, sessions } satisfies RuntimeServices;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function createServer(services = createRuntimeServices()) {
|
|
30
|
+
const server = new McpServer(
|
|
31
|
+
{
|
|
32
|
+
name: services.env.serverName,
|
|
33
|
+
version: services.env.serverVersion,
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
capabilities: {
|
|
37
|
+
logging: {},
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
registerTools(server, services);
|
|
43
|
+
return server;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export async function startStdioServer() {
|
|
47
|
+
const server = createServer();
|
|
48
|
+
const transport = new StdioServerTransport();
|
|
49
|
+
await server.connect(transport);
|
|
50
|
+
console.error("web-agent-mcp running on stdio");
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async function main() {
|
|
54
|
+
await startStdioServer();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function isMainModule(): boolean {
|
|
58
|
+
if (!process.argv[1]) return false;
|
|
59
|
+
const argv1Url = pathToFileURL(process.argv[1]).href;
|
|
60
|
+
if (import.meta.url === argv1Url) return true;
|
|
61
|
+
try {
|
|
62
|
+
return (
|
|
63
|
+
import.meta.url === pathToFileURL(realpathSync(process.argv[1])).href
|
|
64
|
+
);
|
|
65
|
+
} catch {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (isMainModule()) {
|
|
71
|
+
main().catch((error) => {
|
|
72
|
+
console.error("Fatal error in main():", error);
|
|
73
|
+
process.exit(1);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import type { RuntimeServices } from "../../server.js";
|
|
4
|
+
import { actionResultSchema, clickInputSchema } from "../../schemas/act.js";
|
|
5
|
+
import {
|
|
6
|
+
createActionFailureResponse,
|
|
7
|
+
createActionSuccessResult,
|
|
8
|
+
} from "./shared.js";
|
|
9
|
+
|
|
10
|
+
export function registerClickTool(
|
|
11
|
+
server: McpServer,
|
|
12
|
+
services: RuntimeServices,
|
|
13
|
+
) {
|
|
14
|
+
server.registerTool(
|
|
15
|
+
"act.click",
|
|
16
|
+
{
|
|
17
|
+
title: "Click Element",
|
|
18
|
+
description: "Click an element using a CSS selector.",
|
|
19
|
+
inputSchema: clickInputSchema,
|
|
20
|
+
outputSchema: actionResultSchema,
|
|
21
|
+
annotations: {
|
|
22
|
+
readOnlyHint: false,
|
|
23
|
+
destructiveHint: false,
|
|
24
|
+
idempotentHint: false,
|
|
25
|
+
openWorldHint: true,
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
async (input: z.infer<typeof clickInputSchema>) => {
|
|
29
|
+
try {
|
|
30
|
+
const action = await services.history.startAction("act.click", input, {
|
|
31
|
+
session_id: input.session_id,
|
|
32
|
+
page_id: input.page_id,
|
|
33
|
+
});
|
|
34
|
+
const { session, page, result } = await services.sessions.click(
|
|
35
|
+
input.session_id,
|
|
36
|
+
input.page_id,
|
|
37
|
+
{
|
|
38
|
+
selector: input.selector,
|
|
39
|
+
frameSelector: input.frame_selector,
|
|
40
|
+
button: input.button,
|
|
41
|
+
clickCount: input.click_count,
|
|
42
|
+
timeoutMs: input.timeout_ms,
|
|
43
|
+
},
|
|
44
|
+
);
|
|
45
|
+
const data = { verificationHint: result.verificationHint };
|
|
46
|
+
services.sessions.recordSuccess(session.sessionId);
|
|
47
|
+
await services.history.finishAction(action, "succeeded", data);
|
|
48
|
+
return createActionSuccessResult({
|
|
49
|
+
actionId: action.action_id,
|
|
50
|
+
sessionId: session.sessionId,
|
|
51
|
+
pageId: page.pageId,
|
|
52
|
+
appliedMode: "semantic",
|
|
53
|
+
verificationHint: result.verificationHint,
|
|
54
|
+
targetSelectorKnown: true,
|
|
55
|
+
});
|
|
56
|
+
} catch (error) {
|
|
57
|
+
return createActionFailureResponse({
|
|
58
|
+
services,
|
|
59
|
+
error,
|
|
60
|
+
sessionId: input.session_id,
|
|
61
|
+
pageId: input.page_id,
|
|
62
|
+
appliedMode: "semantic",
|
|
63
|
+
targetSelectorKnown: true,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
);
|
|
68
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import type { RuntimeServices } from "../../server.js";
|
|
4
|
+
import { actionResultSchema, dragInputSchema } from "../../schemas/act.js";
|
|
5
|
+
import { createActionFailureResponse, createActionSuccessResult } from "./shared.js";
|
|
6
|
+
|
|
7
|
+
export function registerDragTool(server: McpServer, services: RuntimeServices) {
|
|
8
|
+
server.registerTool(
|
|
9
|
+
"act.drag",
|
|
10
|
+
{
|
|
11
|
+
title: "Drag Between Elements",
|
|
12
|
+
description: "Drag from one selector to another using mouse input.",
|
|
13
|
+
inputSchema: dragInputSchema,
|
|
14
|
+
outputSchema: actionResultSchema,
|
|
15
|
+
annotations: {
|
|
16
|
+
readOnlyHint: false,
|
|
17
|
+
destructiveHint: false,
|
|
18
|
+
idempotentHint: false,
|
|
19
|
+
openWorldHint: true
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
async (input: z.infer<typeof dragInputSchema>) => {
|
|
23
|
+
try {
|
|
24
|
+
const action = await services.history.startAction("act.drag", input, {
|
|
25
|
+
session_id: input.session_id,
|
|
26
|
+
page_id: input.page_id
|
|
27
|
+
});
|
|
28
|
+
const { session, page, result } = await services.sessions.drag(input.session_id, input.page_id, {
|
|
29
|
+
fromSelector: input.from_selector,
|
|
30
|
+
toSelector: input.to_selector,
|
|
31
|
+
steps: input.steps,
|
|
32
|
+
timeoutMs: input.timeout_ms
|
|
33
|
+
});
|
|
34
|
+
const data = { verificationHint: result.verificationHint };
|
|
35
|
+
services.sessions.recordSuccess(session.sessionId);
|
|
36
|
+
await services.history.finishAction(action, "succeeded", data);
|
|
37
|
+
return createActionSuccessResult({
|
|
38
|
+
actionId: action.action_id,
|
|
39
|
+
sessionId: session.sessionId,
|
|
40
|
+
pageId: page.pageId,
|
|
41
|
+
appliedMode: "physical",
|
|
42
|
+
verificationHint: result.verificationHint,
|
|
43
|
+
targetSelectorKnown: true
|
|
44
|
+
});
|
|
45
|
+
} catch (error) {
|
|
46
|
+
return createActionFailureResponse({
|
|
47
|
+
services,
|
|
48
|
+
error,
|
|
49
|
+
sessionId: input.session_id,
|
|
50
|
+
pageId: input.page_id,
|
|
51
|
+
appliedMode: "physical",
|
|
52
|
+
targetSelectorKnown: true
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import type { RuntimeServices } from "../../server.js";
|
|
4
|
+
import { actionResultSchema, enterCodeInputSchema } from "../../schemas/act.js";
|
|
5
|
+
import {
|
|
6
|
+
createActionFailureResponse,
|
|
7
|
+
createActionSuccessResult,
|
|
8
|
+
} from "./shared.js";
|
|
9
|
+
|
|
10
|
+
export function registerEnterCodeTool(
|
|
11
|
+
server: McpServer,
|
|
12
|
+
services: RuntimeServices,
|
|
13
|
+
) {
|
|
14
|
+
server.registerTool(
|
|
15
|
+
"act.enter_code",
|
|
16
|
+
{
|
|
17
|
+
title: "Enter Verification Code",
|
|
18
|
+
description:
|
|
19
|
+
"Fill a one-time code into a focused, single, or segmented input flow.",
|
|
20
|
+
inputSchema: enterCodeInputSchema,
|
|
21
|
+
outputSchema: actionResultSchema,
|
|
22
|
+
annotations: {
|
|
23
|
+
readOnlyHint: false,
|
|
24
|
+
destructiveHint: false,
|
|
25
|
+
idempotentHint: false,
|
|
26
|
+
openWorldHint: true,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
async (input: z.infer<typeof enterCodeInputSchema>) => {
|
|
30
|
+
const action = await services.history.startAction(
|
|
31
|
+
"act.enter_code",
|
|
32
|
+
input,
|
|
33
|
+
{
|
|
34
|
+
session_id: input.session_id,
|
|
35
|
+
page_id: input.page_id,
|
|
36
|
+
},
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
const { session, page, result } = await services.sessions.enterCode(
|
|
41
|
+
input.session_id,
|
|
42
|
+
input.page_id,
|
|
43
|
+
{
|
|
44
|
+
code: input.code,
|
|
45
|
+
selector: input.selector,
|
|
46
|
+
frameSelector: input.frame_selector,
|
|
47
|
+
submit: input.submit,
|
|
48
|
+
timeoutMs: input.timeout_ms,
|
|
49
|
+
},
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
services.sessions.recordSuccess(session.sessionId);
|
|
53
|
+
await services.history.finishAction(action, "succeeded", {
|
|
54
|
+
verificationHint: result.verificationHint,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
return createActionSuccessResult({
|
|
58
|
+
actionId: action.action_id,
|
|
59
|
+
sessionId: session.sessionId,
|
|
60
|
+
pageId: page.pageId,
|
|
61
|
+
appliedMode: "semantic",
|
|
62
|
+
verificationHint: result.verificationHint,
|
|
63
|
+
targetSelectorKnown: Boolean(input.selector),
|
|
64
|
+
});
|
|
65
|
+
} catch (error) {
|
|
66
|
+
return createActionFailureResponse({
|
|
67
|
+
services,
|
|
68
|
+
error,
|
|
69
|
+
actionId: action.action_id,
|
|
70
|
+
sessionId: input.session_id,
|
|
71
|
+
pageId: input.page_id,
|
|
72
|
+
appliedMode: "semantic",
|
|
73
|
+
targetSelectorKnown: Boolean(input.selector),
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
);
|
|
78
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import type { RuntimeServices } from "../../server.js";
|
|
4
|
+
import { actionResultSchema, fillInputSchema } from "../../schemas/act.js";
|
|
5
|
+
import {
|
|
6
|
+
createActionFailureResponse,
|
|
7
|
+
createActionSuccessResult,
|
|
8
|
+
} from "./shared.js";
|
|
9
|
+
|
|
10
|
+
export function registerFillTool(server: McpServer, services: RuntimeServices) {
|
|
11
|
+
server.registerTool(
|
|
12
|
+
"act.fill",
|
|
13
|
+
{
|
|
14
|
+
title: "Fill Input",
|
|
15
|
+
description: "Fill a form input using a CSS selector.",
|
|
16
|
+
inputSchema: fillInputSchema,
|
|
17
|
+
outputSchema: actionResultSchema,
|
|
18
|
+
annotations: {
|
|
19
|
+
readOnlyHint: false,
|
|
20
|
+
destructiveHint: false,
|
|
21
|
+
idempotentHint: false,
|
|
22
|
+
openWorldHint: true,
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
async (input: z.infer<typeof fillInputSchema>) => {
|
|
26
|
+
try {
|
|
27
|
+
const action = await services.history.startAction("act.fill", input, {
|
|
28
|
+
session_id: input.session_id,
|
|
29
|
+
page_id: input.page_id,
|
|
30
|
+
});
|
|
31
|
+
const { session, page, result } = await services.sessions.fill(
|
|
32
|
+
input.session_id,
|
|
33
|
+
input.page_id,
|
|
34
|
+
{
|
|
35
|
+
selector: input.selector,
|
|
36
|
+
frameSelector: input.frame_selector,
|
|
37
|
+
value: input.value,
|
|
38
|
+
clearFirst: input.clear_first,
|
|
39
|
+
timeoutMs: input.timeout_ms,
|
|
40
|
+
},
|
|
41
|
+
);
|
|
42
|
+
const data = { verificationHint: result.verificationHint };
|
|
43
|
+
services.sessions.recordSuccess(session.sessionId);
|
|
44
|
+
await services.history.finishAction(action, "succeeded", data);
|
|
45
|
+
return createActionSuccessResult({
|
|
46
|
+
actionId: action.action_id,
|
|
47
|
+
sessionId: session.sessionId,
|
|
48
|
+
pageId: page.pageId,
|
|
49
|
+
appliedMode: "semantic",
|
|
50
|
+
verificationHint: result.verificationHint,
|
|
51
|
+
targetSelectorKnown: true,
|
|
52
|
+
});
|
|
53
|
+
} catch (error) {
|
|
54
|
+
return createActionFailureResponse({
|
|
55
|
+
services,
|
|
56
|
+
error,
|
|
57
|
+
sessionId: input.session_id,
|
|
58
|
+
pageId: input.page_id,
|
|
59
|
+
appliedMode: "semantic",
|
|
60
|
+
targetSelectorKnown: true,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
);
|
|
65
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import type { RuntimeServices } from "../../server.js";
|
|
4
|
+
import { actionResultSchema, pinchInputSchema } from "../../schemas/act.js";
|
|
5
|
+
import { createActionFailureResponse, createActionSuccessResult } from "./shared.js";
|
|
6
|
+
|
|
7
|
+
export function registerPinchTool(server: McpServer, services: RuntimeServices) {
|
|
8
|
+
server.registerTool(
|
|
9
|
+
"act.pinch",
|
|
10
|
+
{
|
|
11
|
+
title: "Pinch Gesture",
|
|
12
|
+
description: "Perform a touch-style pinch gesture on a selector center or explicit coordinates.",
|
|
13
|
+
inputSchema: pinchInputSchema,
|
|
14
|
+
outputSchema: actionResultSchema,
|
|
15
|
+
annotations: {
|
|
16
|
+
readOnlyHint: false,
|
|
17
|
+
destructiveHint: false,
|
|
18
|
+
idempotentHint: false,
|
|
19
|
+
openWorldHint: true
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
async (input: z.infer<typeof pinchInputSchema>) => {
|
|
23
|
+
try {
|
|
24
|
+
const action = await services.history.startAction("act.pinch", input, {
|
|
25
|
+
session_id: input.session_id,
|
|
26
|
+
page_id: input.page_id
|
|
27
|
+
});
|
|
28
|
+
const { session, page, result } = await services.sessions.pinch(input.session_id, input.page_id, {
|
|
29
|
+
selector: input.selector,
|
|
30
|
+
centerX: input.center_x,
|
|
31
|
+
centerY: input.center_y,
|
|
32
|
+
scaleFactor: input.scale_factor,
|
|
33
|
+
speed: input.speed
|
|
34
|
+
});
|
|
35
|
+
const data = { verificationHint: result.verificationHint };
|
|
36
|
+
services.sessions.recordSuccess(session.sessionId);
|
|
37
|
+
await services.history.finishAction(action, "succeeded", data);
|
|
38
|
+
return createActionSuccessResult({
|
|
39
|
+
actionId: action.action_id,
|
|
40
|
+
sessionId: session.sessionId,
|
|
41
|
+
pageId: page.pageId,
|
|
42
|
+
appliedMode: "physical",
|
|
43
|
+
verificationHint: result.verificationHint,
|
|
44
|
+
targetSelectorKnown: Boolean(input.selector)
|
|
45
|
+
});
|
|
46
|
+
} catch (error) {
|
|
47
|
+
return createActionFailureResponse({
|
|
48
|
+
services,
|
|
49
|
+
error,
|
|
50
|
+
sessionId: input.session_id,
|
|
51
|
+
pageId: input.page_id,
|
|
52
|
+
appliedMode: "physical",
|
|
53
|
+
targetSelectorKnown: Boolean(input.selector)
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
);
|
|
58
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import type { RuntimeServices } from "../../server.js";
|
|
4
|
+
import { actionResultSchema, pressInputSchema } from "../../schemas/act.js";
|
|
5
|
+
import {
|
|
6
|
+
createActionFailureResponse,
|
|
7
|
+
createActionSuccessResult,
|
|
8
|
+
} from "./shared.js";
|
|
9
|
+
|
|
10
|
+
export function registerPressTool(
|
|
11
|
+
server: McpServer,
|
|
12
|
+
services: RuntimeServices,
|
|
13
|
+
) {
|
|
14
|
+
server.registerTool(
|
|
15
|
+
"act.press",
|
|
16
|
+
{
|
|
17
|
+
title: "Press Key",
|
|
18
|
+
description: "Press a keyboard key on the page or a targeted selector.",
|
|
19
|
+
inputSchema: pressInputSchema,
|
|
20
|
+
outputSchema: actionResultSchema,
|
|
21
|
+
annotations: {
|
|
22
|
+
readOnlyHint: false,
|
|
23
|
+
destructiveHint: false,
|
|
24
|
+
idempotentHint: false,
|
|
25
|
+
openWorldHint: true,
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
async (input: z.infer<typeof pressInputSchema>) => {
|
|
29
|
+
try {
|
|
30
|
+
const action = await services.history.startAction("act.press", input, {
|
|
31
|
+
session_id: input.session_id,
|
|
32
|
+
page_id: input.page_id,
|
|
33
|
+
});
|
|
34
|
+
const { session, page, result } = await services.sessions.press(
|
|
35
|
+
input.session_id,
|
|
36
|
+
input.page_id,
|
|
37
|
+
{
|
|
38
|
+
key: input.key,
|
|
39
|
+
selector: input.selector,
|
|
40
|
+
frameSelector: input.frame_selector,
|
|
41
|
+
timeoutMs: input.timeout_ms,
|
|
42
|
+
},
|
|
43
|
+
);
|
|
44
|
+
const data = { verificationHint: result.verificationHint };
|
|
45
|
+
services.sessions.recordSuccess(session.sessionId);
|
|
46
|
+
await services.history.finishAction(action, "succeeded", data);
|
|
47
|
+
return createActionSuccessResult({
|
|
48
|
+
actionId: action.action_id,
|
|
49
|
+
sessionId: session.sessionId,
|
|
50
|
+
pageId: page.pageId,
|
|
51
|
+
appliedMode: "semantic",
|
|
52
|
+
verificationHint: result.verificationHint,
|
|
53
|
+
targetSelectorKnown: Boolean(input.selector),
|
|
54
|
+
});
|
|
55
|
+
} catch (error) {
|
|
56
|
+
return createActionFailureResponse({
|
|
57
|
+
services,
|
|
58
|
+
error,
|
|
59
|
+
sessionId: input.session_id,
|
|
60
|
+
pageId: input.page_id,
|
|
61
|
+
appliedMode: "semantic",
|
|
62
|
+
targetSelectorKnown: Boolean(input.selector),
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
);
|
|
67
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { createFailureResult } from "../../core/errors.js";
|
|
2
|
+
import { buildActionFailurePayload, buildActionSuccessPayload } from "../../core/action-flow.js";
|
|
3
|
+
import { createToolSuccess } from "../../schemas/common.js";
|
|
4
|
+
import type { RuntimeServices } from "../../server.js";
|
|
5
|
+
|
|
6
|
+
export function createActionSuccessResult(input: {
|
|
7
|
+
actionId: string;
|
|
8
|
+
sessionId: string;
|
|
9
|
+
pageId: string;
|
|
10
|
+
appliedMode: "semantic" | "physical";
|
|
11
|
+
verificationHint?: string;
|
|
12
|
+
targetSelectorKnown: boolean;
|
|
13
|
+
}) {
|
|
14
|
+
return createToolSuccess({
|
|
15
|
+
ok: true,
|
|
16
|
+
code: "OK",
|
|
17
|
+
action_id: input.actionId,
|
|
18
|
+
session_id: input.sessionId,
|
|
19
|
+
page_id: input.pageId,
|
|
20
|
+
data: buildActionSuccessPayload({
|
|
21
|
+
actionId: input.actionId,
|
|
22
|
+
appliedMode: input.appliedMode,
|
|
23
|
+
verificationHint: input.verificationHint,
|
|
24
|
+
targetSelectorKnown: input.targetSelectorKnown
|
|
25
|
+
})
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function createActionFailureResponse(input: {
|
|
30
|
+
services: RuntimeServices;
|
|
31
|
+
error: unknown;
|
|
32
|
+
actionId?: string;
|
|
33
|
+
sessionId: string;
|
|
34
|
+
pageId?: string;
|
|
35
|
+
appliedMode: "semantic" | "physical";
|
|
36
|
+
targetSelectorKnown: boolean;
|
|
37
|
+
}) {
|
|
38
|
+
let sessionHealth:
|
|
39
|
+
| {
|
|
40
|
+
consecutiveErrors: number;
|
|
41
|
+
maxConsecutiveErrors: number;
|
|
42
|
+
cooldownMs: number;
|
|
43
|
+
lastRestartAt?: string;
|
|
44
|
+
now: string;
|
|
45
|
+
}
|
|
46
|
+
| undefined;
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
const session = input.services.sessions.recordFailure(input.sessionId);
|
|
50
|
+
sessionHealth = {
|
|
51
|
+
consecutiveErrors: session.consecutiveErrors,
|
|
52
|
+
maxConsecutiveErrors: input.services.env.sessionMaxConsecutiveErrors,
|
|
53
|
+
cooldownMs: input.services.env.sessionRestartCooldownMs,
|
|
54
|
+
lastRestartAt: session.lastRestartAt,
|
|
55
|
+
now: new Date().toISOString()
|
|
56
|
+
};
|
|
57
|
+
} catch {
|
|
58
|
+
sessionHealth = undefined;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return createFailureResult(input.error, {
|
|
62
|
+
action_id: input.actionId,
|
|
63
|
+
session_id: input.sessionId,
|
|
64
|
+
page_id: input.pageId,
|
|
65
|
+
data: buildActionFailurePayload({
|
|
66
|
+
error: input.error,
|
|
67
|
+
actionId: input.actionId,
|
|
68
|
+
appliedMode: input.appliedMode,
|
|
69
|
+
targetSelectorKnown: input.targetSelectorKnown,
|
|
70
|
+
sessionHealth
|
|
71
|
+
})
|
|
72
|
+
});
|
|
73
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import type { RuntimeServices } from "../../server.js";
|
|
4
|
+
import { actionResultSchema, swipeInputSchema } from "../../schemas/act.js";
|
|
5
|
+
import { createActionFailureResponse, createActionSuccessResult } from "./shared.js";
|
|
6
|
+
|
|
7
|
+
export function registerSwipeTool(server: McpServer, services: RuntimeServices) {
|
|
8
|
+
server.registerTool(
|
|
9
|
+
"act.swipe",
|
|
10
|
+
{
|
|
11
|
+
title: "Swipe Gesture",
|
|
12
|
+
description: "Perform a touch-style swipe from a selector center or explicit coordinates.",
|
|
13
|
+
inputSchema: swipeInputSchema,
|
|
14
|
+
outputSchema: actionResultSchema,
|
|
15
|
+
annotations: {
|
|
16
|
+
readOnlyHint: false,
|
|
17
|
+
destructiveHint: false,
|
|
18
|
+
idempotentHint: false,
|
|
19
|
+
openWorldHint: true
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
async (input: z.infer<typeof swipeInputSchema>) => {
|
|
23
|
+
try {
|
|
24
|
+
const action = await services.history.startAction("act.swipe", input, {
|
|
25
|
+
session_id: input.session_id,
|
|
26
|
+
page_id: input.page_id
|
|
27
|
+
});
|
|
28
|
+
const { session, page, result } = await services.sessions.swipe(input.session_id, input.page_id, {
|
|
29
|
+
selector: input.selector,
|
|
30
|
+
startX: input.start_x,
|
|
31
|
+
startY: input.start_y,
|
|
32
|
+
deltaX: input.delta_x,
|
|
33
|
+
deltaY: input.delta_y,
|
|
34
|
+
speed: input.speed
|
|
35
|
+
});
|
|
36
|
+
const data = { verificationHint: result.verificationHint };
|
|
37
|
+
services.sessions.recordSuccess(session.sessionId);
|
|
38
|
+
await services.history.finishAction(action, "succeeded", data);
|
|
39
|
+
return createActionSuccessResult({
|
|
40
|
+
actionId: action.action_id,
|
|
41
|
+
sessionId: session.sessionId,
|
|
42
|
+
pageId: page.pageId,
|
|
43
|
+
appliedMode: "physical",
|
|
44
|
+
verificationHint: result.verificationHint,
|
|
45
|
+
targetSelectorKnown: Boolean(input.selector)
|
|
46
|
+
});
|
|
47
|
+
} catch (error) {
|
|
48
|
+
return createActionFailureResponse({
|
|
49
|
+
services,
|
|
50
|
+
error,
|
|
51
|
+
sessionId: input.session_id,
|
|
52
|
+
pageId: input.page_id,
|
|
53
|
+
appliedMode: "physical",
|
|
54
|
+
targetSelectorKnown: Boolean(input.selector)
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
);
|
|
59
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import type { RuntimeServices } from "../../server.js";
|
|
4
|
+
import { actionResultSchema, waitForInputSchema } from "../../schemas/act.js";
|
|
5
|
+
import { createActionFailureResponse, createActionSuccessResult } from "./shared.js";
|
|
6
|
+
|
|
7
|
+
export function registerWaitForTool(server: McpServer, services: RuntimeServices) {
|
|
8
|
+
server.registerTool(
|
|
9
|
+
"act.wait_for",
|
|
10
|
+
{
|
|
11
|
+
title: "Wait For Condition",
|
|
12
|
+
description: "Wait for a selector or text to appear on the current page.",
|
|
13
|
+
inputSchema: waitForInputSchema,
|
|
14
|
+
outputSchema: actionResultSchema,
|
|
15
|
+
annotations: {
|
|
16
|
+
readOnlyHint: true,
|
|
17
|
+
destructiveHint: false,
|
|
18
|
+
idempotentHint: false,
|
|
19
|
+
openWorldHint: true
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
async (input: z.infer<typeof waitForInputSchema>) => {
|
|
23
|
+
try {
|
|
24
|
+
const action = await services.history.startAction("act.wait_for", input, {
|
|
25
|
+
session_id: input.session_id,
|
|
26
|
+
page_id: input.page_id
|
|
27
|
+
});
|
|
28
|
+
const { session, page, result } = await services.sessions.waitFor(input.session_id, input.page_id, {
|
|
29
|
+
selector: input.selector,
|
|
30
|
+
text: input.text,
|
|
31
|
+
timeoutMs: input.timeout_ms
|
|
32
|
+
});
|
|
33
|
+
const data = { verificationHint: result.verificationHint };
|
|
34
|
+
services.sessions.recordSuccess(session.sessionId);
|
|
35
|
+
await services.history.finishAction(action, "succeeded", data);
|
|
36
|
+
return createActionSuccessResult({
|
|
37
|
+
actionId: action.action_id,
|
|
38
|
+
sessionId: session.sessionId,
|
|
39
|
+
pageId: page.pageId,
|
|
40
|
+
appliedMode: "semantic",
|
|
41
|
+
verificationHint: result.verificationHint,
|
|
42
|
+
targetSelectorKnown: Boolean(input.selector)
|
|
43
|
+
});
|
|
44
|
+
} catch (error) {
|
|
45
|
+
return createActionFailureResponse({
|
|
46
|
+
services,
|
|
47
|
+
error,
|
|
48
|
+
sessionId: input.session_id,
|
|
49
|
+
pageId: input.page_id,
|
|
50
|
+
appliedMode: "semantic",
|
|
51
|
+
targetSelectorKnown: Boolean(input.selector)
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
);
|
|
56
|
+
}
|