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.
Files changed (128) hide show
  1. package/README.md +90 -0
  2. package/bin/opencode-pair-autonomy.js +20 -0
  3. package/dist/__tests__/comment-guard.test.d.ts +1 -0
  4. package/dist/__tests__/config.test.d.ts +1 -0
  5. package/dist/__tests__/learning.test.d.ts +1 -0
  6. package/dist/__tests__/plan-mode.test.d.ts +1 -0
  7. package/dist/agents.d.ts +2 -0
  8. package/dist/cli.d.ts +1 -0
  9. package/dist/cli.js +15351 -0
  10. package/dist/commands.d.ts +2 -0
  11. package/dist/config.d.ts +3 -0
  12. package/dist/hooks/comment-guard.d.ts +15 -0
  13. package/dist/hooks/file-edited.d.ts +7 -0
  14. package/dist/hooks/index.d.ts +46 -0
  15. package/dist/hooks/post-tool-use.d.ts +5 -0
  16. package/dist/hooks/pre-compact.d.ts +4 -0
  17. package/dist/hooks/pre-tool-use.d.ts +5 -0
  18. package/dist/hooks/prompt-refiner.d.ts +38 -0
  19. package/dist/hooks/runtime.d.ts +91 -0
  20. package/dist/hooks/sdk.d.ts +6 -0
  21. package/dist/hooks/session-end.d.ts +4 -0
  22. package/dist/hooks/session-start.d.ts +19 -0
  23. package/dist/hooks/stop.d.ts +5 -0
  24. package/dist/i18n/index.d.ts +15 -0
  25. package/dist/index.d.ts +3 -0
  26. package/dist/index.js +17823 -0
  27. package/dist/installer.d.ts +12 -0
  28. package/dist/learning/analyzer.d.ts +15 -0
  29. package/dist/learning/store.d.ts +4 -0
  30. package/dist/learning/types.d.ts +32 -0
  31. package/dist/mcp.d.ts +4 -0
  32. package/dist/project-facts.d.ts +8 -0
  33. package/dist/prompts/coordinator.d.ts +2 -0
  34. package/dist/prompts/shared.d.ts +5 -0
  35. package/dist/prompts/workers.d.ts +8 -0
  36. package/dist/types.d.ts +81 -0
  37. package/dist/utils.d.ts +6 -0
  38. package/examples/opencode-pair-autonomy.jsonc +35 -0
  39. package/examples/opencode.jsonc +17 -0
  40. package/package.json +103 -0
  41. package/vendor/mcp/pg-mcp/README.md +91 -0
  42. package/vendor/mcp/pg-mcp/config.example.json +26 -0
  43. package/vendor/mcp/pg-mcp/config.json +15 -0
  44. package/vendor/mcp/pg-mcp/package-lock.json +1288 -0
  45. package/vendor/mcp/pg-mcp/package.json +18 -0
  46. package/vendor/mcp/pg-mcp/src/config.js +71 -0
  47. package/vendor/mcp/pg-mcp/src/db.js +85 -0
  48. package/vendor/mcp/pg-mcp/src/index.js +203 -0
  49. package/vendor/mcp/pg-mcp/src/sqlGuard.js +75 -0
  50. package/vendor/mcp/pg-mcp/src/tools.js +89 -0
  51. package/vendor/mcp/ssh-mcp/README.md +46 -0
  52. package/vendor/mcp/ssh-mcp/config.example.json +23 -0
  53. package/vendor/mcp/ssh-mcp/config.json +6 -0
  54. package/vendor/mcp/ssh-mcp/package-lock.json +1142 -0
  55. package/vendor/mcp/ssh-mcp/package.json +18 -0
  56. package/vendor/mcp/ssh-mcp/src/config.js +140 -0
  57. package/vendor/mcp/ssh-mcp/src/index.js +130 -0
  58. package/vendor/mcp/ssh-mcp/src/ssh.js +163 -0
  59. package/vendor/mcp/sudo-mcp/README.md +51 -0
  60. package/vendor/mcp/sudo-mcp/config.example.json +28 -0
  61. package/vendor/mcp/sudo-mcp/config.json +28 -0
  62. package/vendor/mcp/sudo-mcp/package-lock.json +1145 -0
  63. package/vendor/mcp/sudo-mcp/package.json +18 -0
  64. package/vendor/mcp/sudo-mcp/src/config.js +57 -0
  65. package/vendor/mcp/sudo-mcp/src/index.js +267 -0
  66. package/vendor/mcp/sudo-mcp/src/runner.js +168 -0
  67. package/vendor/mcp/web-agent-mcp/package-lock.json +2886 -0
  68. package/vendor/mcp/web-agent-mcp/package.json +28 -0
  69. package/vendor/mcp/web-agent-mcp/src/adapters/cloakbrowser/adapter.ts +335 -0
  70. package/vendor/mcp/web-agent-mcp/src/adapters/cloakbrowser/auth-heuristics.ts +324 -0
  71. package/vendor/mcp/web-agent-mcp/src/adapters/cloakbrowser/launcher.ts +1340 -0
  72. package/vendor/mcp/web-agent-mcp/src/config/env.ts +107 -0
  73. package/vendor/mcp/web-agent-mcp/src/core/action-flow.ts +82 -0
  74. package/vendor/mcp/web-agent-mcp/src/core/artifact-store.ts +109 -0
  75. package/vendor/mcp/web-agent-mcp/src/core/errors.ts +108 -0
  76. package/vendor/mcp/web-agent-mcp/src/core/observation-flow.ts +38 -0
  77. package/vendor/mcp/web-agent-mcp/src/core/policy-engine.ts +113 -0
  78. package/vendor/mcp/web-agent-mcp/src/core/retry-policy.ts +42 -0
  79. package/vendor/mcp/web-agent-mcp/src/core/session-manager.ts +670 -0
  80. package/vendor/mcp/web-agent-mcp/src/core/session-restart-policy.ts +34 -0
  81. package/vendor/mcp/web-agent-mcp/src/core/task-history.ts +97 -0
  82. package/vendor/mcp/web-agent-mcp/src/index.ts +3 -0
  83. package/vendor/mcp/web-agent-mcp/src/schemas/act.ts +167 -0
  84. package/vendor/mcp/web-agent-mcp/src/schemas/common.ts +56 -0
  85. package/vendor/mcp/web-agent-mcp/src/schemas/observe.ts +214 -0
  86. package/vendor/mcp/web-agent-mcp/src/schemas/page.ts +21 -0
  87. package/vendor/mcp/web-agent-mcp/src/schemas/policy.ts +42 -0
  88. package/vendor/mcp/web-agent-mcp/src/schemas/runtime.ts +21 -0
  89. package/vendor/mcp/web-agent-mcp/src/schemas/session.ts +63 -0
  90. package/vendor/mcp/web-agent-mcp/src/server.ts +75 -0
  91. package/vendor/mcp/web-agent-mcp/src/tools/act/click.ts +68 -0
  92. package/vendor/mcp/web-agent-mcp/src/tools/act/drag.ts +57 -0
  93. package/vendor/mcp/web-agent-mcp/src/tools/act/enter-code.ts +78 -0
  94. package/vendor/mcp/web-agent-mcp/src/tools/act/fill.ts +65 -0
  95. package/vendor/mcp/web-agent-mcp/src/tools/act/pinch.ts +58 -0
  96. package/vendor/mcp/web-agent-mcp/src/tools/act/press.ts +67 -0
  97. package/vendor/mcp/web-agent-mcp/src/tools/act/shared.ts +73 -0
  98. package/vendor/mcp/web-agent-mcp/src/tools/act/swipe.ts +59 -0
  99. package/vendor/mcp/web-agent-mcp/src/tools/act/wait-for.ts +56 -0
  100. package/vendor/mcp/web-agent-mcp/src/tools/act/wheel.ts +59 -0
  101. package/vendor/mcp/web-agent-mcp/src/tools/observe/a11y.ts +60 -0
  102. package/vendor/mcp/web-agent-mcp/src/tools/observe/auth-state.ts +92 -0
  103. package/vendor/mcp/web-agent-mcp/src/tools/observe/boxes.ts +66 -0
  104. package/vendor/mcp/web-agent-mcp/src/tools/observe/console.ts +67 -0
  105. package/vendor/mcp/web-agent-mcp/src/tools/observe/dom.ts +60 -0
  106. package/vendor/mcp/web-agent-mcp/src/tools/observe/network.ts +67 -0
  107. package/vendor/mcp/web-agent-mcp/src/tools/observe/page-state.ts +93 -0
  108. package/vendor/mcp/web-agent-mcp/src/tools/observe/screenshot.ts +73 -0
  109. package/vendor/mcp/web-agent-mcp/src/tools/observe/text.ts +70 -0
  110. package/vendor/mcp/web-agent-mcp/src/tools/observe/wait-for-network.ts +70 -0
  111. package/vendor/mcp/web-agent-mcp/src/tools/page/navigate.ts +59 -0
  112. package/vendor/mcp/web-agent-mcp/src/tools/policy/recommend-observation.ts +40 -0
  113. package/vendor/mcp/web-agent-mcp/src/tools/register-tools.ts +55 -0
  114. package/vendor/mcp/web-agent-mcp/src/tools/runtime/evaluate-js.ts +83 -0
  115. package/vendor/mcp/web-agent-mcp/src/tools/session/close.ts +41 -0
  116. package/vendor/mcp/web-agent-mcp/src/tools/session/create.ts +86 -0
  117. package/vendor/mcp/web-agent-mcp/src/tools/session/restart.ts +72 -0
  118. package/vendor/mcp/web-agent-mcp/src/utils/fs.ts +28 -0
  119. package/vendor/mcp/web-agent-mcp/src/utils/ids.ts +9 -0
  120. package/vendor/mcp/web-agent-mcp/src/utils/time.ts +7 -0
  121. package/vendor/mcp/web-agent-mcp/tsconfig.json +22 -0
  122. package/vendor/skills/editorial-technical-ui/SKILL.md +84 -0
  123. package/vendor/skills/figma-console/SKILL.md +839 -0
  124. package/vendor/skills/go-fiber-postgres/SKILL.md +31 -0
  125. package/vendor/skills/opencode-plugin-dev/SKILL.md +31 -0
  126. package/vendor/skills/rust-media-desktop/SKILL.md +30 -0
  127. package/vendor/skills/vue-vite-ui/SKILL.md +31 -0
  128. 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,7 @@
1
+ export function nowIso() {
2
+ return new Date().toISOString();
3
+ }
4
+
5
+ export function elapsedMs(startedAt: number) {
6
+ return Date.now() - startedAt;
7
+ }
@@ -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
+ }