lsd-pi 1.3.2 → 1.3.7

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 (205) hide show
  1. package/dist/cli.js +2 -1
  2. package/dist/lsd-settings-manager.d.ts +2 -0
  3. package/dist/lsd-settings-manager.js +5 -0
  4. package/dist/resource-loader.js +33 -3
  5. package/dist/resources/extensions/browser-tools/tools/codegen.js +5 -5
  6. package/dist/resources/extensions/browser-tools/tools/navigation.js +107 -178
  7. package/dist/resources/extensions/browser-tools/tools/network-mock.js +112 -167
  8. package/dist/resources/extensions/browser-tools/tools/pages.js +182 -234
  9. package/dist/resources/extensions/browser-tools/tools/refs.js +202 -461
  10. package/dist/resources/extensions/browser-tools/tools/session.js +176 -323
  11. package/dist/resources/extensions/browser-tools/tools/state-persistence.js +91 -154
  12. package/dist/resources/extensions/browser-tools/utils.js +1 -1
  13. package/dist/resources/extensions/cache-timer/index.js +3 -2
  14. package/dist/resources/extensions/slash-commands/extension-manifest.json +2 -2
  15. package/dist/resources/extensions/slash-commands/fast.js +73 -0
  16. package/dist/resources/extensions/slash-commands/index.js +2 -0
  17. package/dist/resources/extensions/slash-commands/plan.js +37 -12
  18. package/dist/resources/extensions/subagent/background-job-manager.js +13 -0
  19. package/dist/resources/extensions/subagent/in-process-runner.js +387 -0
  20. package/dist/resources/extensions/subagent/index.js +278 -626
  21. package/dist/resources/extensions/subagent/legacy-runner.js +503 -0
  22. package/dist/resources/extensions/voice/index.js +96 -36
  23. package/dist/resources/extensions/voice/push-to-talk.js +26 -0
  24. package/dist/welcome-screen.js +2 -2
  25. package/package.json +1 -1
  26. package/packages/pi-agent-core/dist/agent.d.ts +19 -0
  27. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  28. package/packages/pi-agent-core/dist/agent.js +16 -0
  29. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  30. package/packages/pi-agent-core/src/agent.ts +32 -2
  31. package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts +34 -1
  32. package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
  33. package/packages/pi-ai/dist/providers/openai-codex-responses.js +32 -4
  34. package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  35. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js +127 -16
  36. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js.map +1 -1
  37. package/packages/pi-ai/dist/providers/openai-responses.d.ts +8 -1
  38. package/packages/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
  39. package/packages/pi-ai/dist/providers/openai-responses.fast-mode.test.d.ts +2 -0
  40. package/packages/pi-ai/dist/providers/openai-responses.fast-mode.test.d.ts.map +1 -0
  41. package/packages/pi-ai/dist/providers/openai-responses.fast-mode.test.js +67 -0
  42. package/packages/pi-ai/dist/providers/openai-responses.fast-mode.test.js.map +1 -0
  43. package/packages/pi-ai/dist/providers/openai-responses.js +21 -3
  44. package/packages/pi-ai/dist/providers/openai-responses.js.map +1 -1
  45. package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  46. package/packages/pi-ai/dist/providers/simple-options.js +2 -0
  47. package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
  48. package/packages/pi-ai/dist/types.d.ts +5 -0
  49. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  50. package/packages/pi-ai/dist/types.js.map +1 -1
  51. package/packages/pi-ai/src/providers/openai-codex-responses.test.ts +143 -20
  52. package/packages/pi-ai/src/providers/openai-codex-responses.ts +47 -4
  53. package/packages/pi-ai/src/providers/openai-responses.fast-mode.test.ts +73 -0
  54. package/packages/pi-ai/src/providers/openai-responses.ts +26 -3
  55. package/packages/pi-ai/src/providers/simple-options.ts +2 -0
  56. package/packages/pi-ai/src/types.ts +5 -0
  57. package/packages/pi-coding-agent/dist/core/keybindings.d.ts +1 -1
  58. package/packages/pi-coding-agent/dist/core/keybindings.d.ts.map +1 -1
  59. package/packages/pi-coding-agent/dist/core/keybindings.js +2 -0
  60. package/packages/pi-coding-agent/dist/core/keybindings.js.map +1 -1
  61. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  62. package/packages/pi-coding-agent/dist/core/sdk.js +4 -2
  63. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  64. package/packages/pi-coding-agent/dist/core/settings-manager.collapse-tool-calls.test.d.ts +2 -0
  65. package/packages/pi-coding-agent/dist/core/settings-manager.collapse-tool-calls.test.d.ts.map +1 -0
  66. package/packages/pi-coding-agent/dist/core/settings-manager.collapse-tool-calls.test.js +35 -0
  67. package/packages/pi-coding-agent/dist/core/settings-manager.collapse-tool-calls.test.js.map +1 -0
  68. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +12 -0
  69. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  70. package/packages/pi-coding-agent/dist/core/settings-manager.fast-mode.test.d.ts +2 -0
  71. package/packages/pi-coding-agent/dist/core/settings-manager.fast-mode.test.d.ts.map +1 -0
  72. package/packages/pi-coding-agent/dist/core/settings-manager.fast-mode.test.js +35 -0
  73. package/packages/pi-coding-agent/dist/core/settings-manager.fast-mode.test.js.map +1 -0
  74. package/packages/pi-coding-agent/dist/core/settings-manager.js +24 -0
  75. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  76. package/packages/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
  77. package/packages/pi-coding-agent/dist/core/slash-commands.js +1 -0
  78. package/packages/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
  79. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  80. package/packages/pi-coding-agent/dist/core/system-prompt.js +6 -1
  81. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  82. package/packages/pi-coding-agent/dist/core/tool-priority.d.ts +4 -0
  83. package/packages/pi-coding-agent/dist/core/tool-priority.d.ts.map +1 -0
  84. package/packages/pi-coding-agent/dist/core/tool-priority.js +18 -0
  85. package/packages/pi-coding-agent/dist/core/tool-priority.js.map +1 -0
  86. package/packages/pi-coding-agent/dist/core/tool-priority.test.d.ts +2 -0
  87. package/packages/pi-coding-agent/dist/core/tool-priority.test.d.ts.map +1 -0
  88. package/packages/pi-coding-agent/dist/core/tool-priority.test.js +27 -0
  89. package/packages/pi-coding-agent/dist/core/tool-priority.test.js.map +1 -0
  90. package/packages/pi-coding-agent/dist/core/tools/edit-diff.d.ts +5 -0
  91. package/packages/pi-coding-agent/dist/core/tools/edit-diff.d.ts.map +1 -1
  92. package/packages/pi-coding-agent/dist/core/tools/edit-diff.js +21 -0
  93. package/packages/pi-coding-agent/dist/core/tools/edit-diff.js.map +1 -1
  94. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js +16 -1
  95. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js.map +1 -1
  96. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-summary-line.test.d.ts +2 -0
  97. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-summary-line.test.d.ts.map +1 -0
  98. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-summary-line.test.js +34 -0
  99. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-summary-line.test.js.map +1 -0
  100. package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.d.ts +45 -0
  101. package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.d.ts.map +1 -0
  102. package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.js +314 -0
  103. package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.js.map +1 -0
  104. package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.test.d.ts +2 -0
  105. package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.test.d.ts.map +1 -0
  106. package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.test.js +122 -0
  107. package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.test.js.map +1 -0
  108. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.d.ts +7 -5
  109. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.d.ts.map +1 -1
  110. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js +86 -28
  111. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js.map +1 -1
  112. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts +4 -0
  113. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  114. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +23 -10
  115. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  116. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +8 -0
  117. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  118. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +52 -6
  119. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
  120. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +19 -0
  121. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  122. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +127 -14
  123. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  124. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.d.ts +14 -0
  125. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.d.ts.map +1 -0
  126. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.js +93 -0
  127. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.js.map +1 -0
  128. package/packages/pi-coding-agent/dist/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.d.ts +2 -0
  129. package/packages/pi-coding-agent/dist/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.d.ts.map +1 -0
  130. package/packages/pi-coding-agent/dist/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.js +328 -0
  131. package/packages/pi-coding-agent/dist/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.js.map +1 -0
  132. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  133. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +123 -0
  134. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  135. package/packages/pi-coding-agent/dist/modes/interactive/controllers/extension-ui-controller.js +1 -1
  136. package/packages/pi-coding-agent/dist/modes/interactive/controllers/extension-ui-controller.js.map +1 -1
  137. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  138. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +7 -0
  139. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  140. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +4 -0
  141. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  142. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  143. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +9 -1
  144. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  145. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +103 -23
  146. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  147. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -1
  148. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +41 -0
  149. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
  150. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +4 -4
  151. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  152. package/packages/pi-coding-agent/package.json +1 -1
  153. package/packages/pi-coding-agent/src/core/keybindings.ts +4 -1
  154. package/packages/pi-coding-agent/src/core/sdk.ts +4 -2
  155. package/packages/pi-coding-agent/src/core/settings-manager.collapse-tool-calls.test.ts +46 -0
  156. package/packages/pi-coding-agent/src/core/settings-manager.fast-mode.test.ts +46 -0
  157. package/packages/pi-coding-agent/src/core/settings-manager.ts +36 -0
  158. package/packages/pi-coding-agent/src/core/slash-commands.ts +1 -0
  159. package/packages/pi-coding-agent/src/core/system-prompt.ts +6 -1
  160. package/packages/pi-coding-agent/src/core/tool-priority.test.ts +30 -0
  161. package/packages/pi-coding-agent/src/core/tool-priority.ts +17 -0
  162. package/packages/pi-coding-agent/src/core/tools/edit-diff.test.ts +20 -0
  163. package/packages/pi-coding-agent/src/core/tools/edit-diff.ts +26 -0
  164. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-summary-line.test.ts +41 -0
  165. package/packages/pi-coding-agent/src/modes/interactive/components/btw-overlay.test.ts +172 -0
  166. package/packages/pi-coding-agent/src/modes/interactive/components/btw-overlay.ts +402 -0
  167. package/packages/pi-coding-agent/src/modes/interactive/components/diff.ts +105 -28
  168. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +21 -6
  169. package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +63 -6
  170. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +1262 -1138
  171. package/packages/pi-coding-agent/src/modes/interactive/components/tool-summary-line.ts +120 -0
  172. package/packages/pi-coding-agent/src/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.ts +396 -0
  173. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +530 -398
  174. package/packages/pi-coding-agent/src/modes/interactive/controllers/extension-ui-controller.ts +1 -1
  175. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +7 -0
  176. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +4 -0
  177. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +109 -23
  178. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +60 -1
  179. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +4 -4
  180. package/packages/pi-tui/dist/components/editor.js +3 -3
  181. package/packages/pi-tui/dist/components/editor.js.map +1 -1
  182. package/packages/pi-tui/src/components/editor.ts +3 -3
  183. package/pkg/dist/modes/interactive/theme/themes.js +4 -4
  184. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  185. package/pkg/package.json +1 -1
  186. package/src/resources/extensions/browser-tools/tools/codegen.ts +5 -5
  187. package/src/resources/extensions/browser-tools/tools/navigation.ts +118 -196
  188. package/src/resources/extensions/browser-tools/tools/network-mock.ts +114 -205
  189. package/src/resources/extensions/browser-tools/tools/pages.ts +183 -237
  190. package/src/resources/extensions/browser-tools/tools/refs.ts +193 -507
  191. package/src/resources/extensions/browser-tools/tools/session.ts +182 -321
  192. package/src/resources/extensions/browser-tools/tools/state-persistence.ts +94 -172
  193. package/src/resources/extensions/browser-tools/utils.ts +1 -1
  194. package/src/resources/extensions/cache-timer/index.ts +3 -2
  195. package/src/resources/extensions/slash-commands/extension-manifest.json +2 -2
  196. package/src/resources/extensions/slash-commands/fast.ts +89 -0
  197. package/src/resources/extensions/slash-commands/index.ts +2 -0
  198. package/src/resources/extensions/slash-commands/plan.ts +42 -12
  199. package/src/resources/extensions/subagent/background-job-manager.ts +28 -0
  200. package/src/resources/extensions/subagent/in-process-runner.ts +534 -0
  201. package/src/resources/extensions/subagent/index.ts +489 -799
  202. package/src/resources/extensions/subagent/legacy-runner.ts +607 -0
  203. package/src/resources/extensions/voice/index.ts +308 -238
  204. package/src/resources/extensions/voice/push-to-talk.ts +42 -0
  205. package/src/resources/extensions/voice/tests/push-to-talk.test.ts +109 -0
@@ -3,7 +3,8 @@ import { Type } from "@sinclair/typebox";
3
3
  import type { ToolDeps } from "../state.js";
4
4
 
5
5
  /**
6
- * Network interception & mocking tools — mock API responses, block URLs, simulate errors.
6
+ * Consolidated network interception tools — mock API responses, block URLs, manage routes.
7
+ * Merged from: browser_mock_route, browser_block_urls, browser_clear_routes.
7
8
  */
8
9
 
9
10
  interface ActiveRoute {
@@ -20,108 +21,45 @@ const activeRoutes: ActiveRoute[] = [];
20
21
  const routeCleanups: Map<number, () => Promise<void>> = new Map();
21
22
 
22
23
  export function registerNetworkMockTools(pi: ExtensionAPI, deps: ToolDeps): void {
23
- // -------------------------------------------------------------------------
24
- // browser_mock_route
25
- // -------------------------------------------------------------------------
26
24
  pi.registerTool({
27
- name: "browser_mock_route",
28
- label: "Browser Mock Route",
25
+ name: "browser_network",
26
+ label: "Browser Network",
29
27
  description:
30
- "Intercept network requests matching a URL pattern and respond with custom status, body, and headers. " +
31
- "Supports simulating slow responses via delay parameter. " +
32
- "Routes survive page navigation within the same context. Use browser_clear_routes to remove all mocks.",
28
+ "Manage browser network interception: mock API responses, block URL patterns, or clear active routes. " +
29
+ "Routes survive page navigation within the same context.",
33
30
  parameters: Type.Object({
34
- url: Type.String({
35
- description: "URL pattern to intercept. Supports glob patterns (e.g., '**/api/users*') or exact URLs.",
36
- }),
37
- status: Type.Optional(
38
- Type.Number({ description: "HTTP status code for the mock response (default: 200)." }),
39
- ),
40
- body: Type.Optional(
41
- Type.String({ description: "Response body string. For JSON responses, pass a JSON string." }),
42
- ),
43
- contentType: Type.Optional(
44
- Type.String({ description: "Content-Type header (default: 'application/json' if body looks like JSON, else 'text/plain')." }),
45
- ),
46
- headers: Type.Optional(
47
- Type.Record(Type.String(), Type.String(), {
48
- description: "Additional response headers as key-value pairs.",
49
- }),
50
- ),
51
- delay: Type.Optional(
52
- Type.Number({ description: "Delay in milliseconds before sending the response. Simulates slow responses." }),
53
- ),
31
+ action: Type.Union([
32
+ Type.Literal("mock"),
33
+ Type.Literal("block"),
34
+ Type.Literal("clear"),
35
+ ], { description: "'mock' intercept and respond, 'block' abort matching requests, 'clear' — remove all active routes" }),
36
+ url: Type.Optional(Type.String({
37
+ description: "URL pattern to intercept (glob or exact). Required for mock/block.",
38
+ })),
39
+ status: Type.Optional(Type.Number({ description: "HTTP status code for mock response (default: 200)." })),
40
+ body: Type.Optional(Type.String({ description: "Response body string for mock." })),
41
+ contentType: Type.Optional(Type.String({ description: "Content-Type header for mock." })),
42
+ headers: Type.Optional(Type.Record(Type.String(), Type.String(), {
43
+ description: "Additional response headers for mock.",
44
+ })),
45
+ delay: Type.Optional(Type.Number({ description: "Delay in ms before sending mock response." })),
46
+ patterns: Type.Optional(Type.Array(Type.String(), {
47
+ description: "URL patterns to block (for block action). Glob syntax.",
48
+ })),
54
49
  }),
55
50
 
56
51
  async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
57
52
  try {
58
- const { page: p } = await deps.ensureBrowser();
59
- const routeId = nextRouteId++;
60
-
61
- const status = params.status ?? 200;
62
- const body = params.body ?? "";
63
- const delay = params.delay ?? 0;
64
-
65
- // Auto-detect content type
66
- let contentType = params.contentType;
67
- if (!contentType) {
68
- try {
69
- JSON.parse(body);
70
- contentType = "application/json";
71
- } catch {
72
- contentType = "text/plain";
73
- }
53
+ if (params.action === "mock") {
54
+ return await handleMock(deps, params);
55
+ } else if (params.action === "block") {
56
+ return await handleBlock(deps, params);
57
+ } else {
58
+ return await handleClear(deps);
74
59
  }
75
-
76
- const headers: Record<string, string> = {
77
- "content-type": contentType,
78
- "access-control-allow-origin": "*",
79
- ...(params.headers ?? {}),
80
- };
81
-
82
- const handler = async (route: any) => {
83
- if (delay > 0) {
84
- await new Promise((resolve) => setTimeout(resolve, delay));
85
- }
86
- await route.fulfill({
87
- status,
88
- body,
89
- headers,
90
- });
91
- };
92
-
93
- await p.route(params.url, handler);
94
-
95
- const cleanup = async () => {
96
- try {
97
- await p.unroute(params.url, handler);
98
- } catch {
99
- // Page may be closed
100
- }
101
- };
102
-
103
- const routeInfo: ActiveRoute = {
104
- id: routeId,
105
- pattern: params.url,
106
- type: "mock",
107
- status,
108
- delay: delay > 0 ? delay : undefined,
109
- description: `Mock ${params.url} → ${status}${delay > 0 ? ` (${delay}ms delay)` : ""}`,
110
- };
111
-
112
- activeRoutes.push(routeInfo);
113
- routeCleanups.set(routeId, cleanup);
114
-
115
- return {
116
- content: [{
117
- type: "text",
118
- text: `Route mocked: ${routeInfo.description}\nRoute ID: ${routeId}\nActive routes: ${activeRoutes.length}`,
119
- }],
120
- details: { routeId, ...routeInfo, activeRouteCount: activeRoutes.length },
121
- };
122
60
  } catch (err: any) {
123
61
  return {
124
- content: [{ type: "text", text: `Mock route failed: ${err.message}` }],
62
+ content: [{ type: "text" as const, text: `Network action '${params.action}' failed: ${err.message}` }],
125
63
  details: { error: err.message },
126
64
  isError: true,
127
65
  };
@@ -129,116 +67,87 @@ export function registerNetworkMockTools(pi: ExtensionAPI, deps: ToolDeps): void
129
67
  },
130
68
  });
131
69
 
132
- // -------------------------------------------------------------------------
133
- // browser_block_urls
134
- // -------------------------------------------------------------------------
135
- pi.registerTool({
136
- name: "browser_block_urls",
137
- label: "Browser Block URLs",
138
- description:
139
- "Block network requests matching URL patterns. Useful for blocking analytics, ads, or third-party scripts. " +
140
- "Accepts glob patterns. Routes survive page navigation.",
141
- parameters: Type.Object({
142
- patterns: Type.Array(Type.String(), {
143
- description: "URL patterns to block (glob syntax, e.g., ['**/analytics*', '**/ads*']).",
144
- }),
145
- }),
146
-
147
- async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
148
- try {
149
- const { page: p } = await deps.ensureBrowser();
150
- const results: ActiveRoute[] = [];
151
-
152
- for (const pattern of params.patterns) {
153
- const routeId = nextRouteId++;
154
-
155
- const handler = async (route: any) => {
156
- await route.abort("blockedbyclient");
157
- };
158
-
159
- await p.route(pattern, handler);
160
-
161
- const cleanup = async () => {
162
- try {
163
- await p.unroute(pattern, handler);
164
- } catch { /* cleanup route may already be removed or page closed */ }
165
- };
166
-
167
- const routeInfo: ActiveRoute = {
168
- id: routeId,
169
- pattern,
170
- type: "block",
171
- description: `Block ${pattern}`,
172
- };
173
-
174
- activeRoutes.push(routeInfo);
175
- routeCleanups.set(routeId, cleanup);
176
- results.push(routeInfo);
177
- }
178
-
179
- return {
180
- content: [{
181
- type: "text",
182
- text: `Blocked ${results.length} URL pattern(s):\n${results.map((r) => ` - ${r.description} (ID: ${r.id})`).join("\n")}\nActive routes: ${activeRoutes.length}`,
183
- }],
184
- details: { blocked: results, activeRouteCount: activeRoutes.length },
185
- };
186
- } catch (err: any) {
187
- return {
188
- content: [{ type: "text", text: `Block URLs failed: ${err.message}` }],
189
- details: { error: err.message },
190
- isError: true,
191
- };
192
- }
193
- },
194
- });
195
-
196
- // -------------------------------------------------------------------------
197
- // browser_clear_routes
198
- // -------------------------------------------------------------------------
199
- pi.registerTool({
200
- name: "browser_clear_routes",
201
- label: "Browser Clear Routes",
202
- description:
203
- "Remove all active route mocks and URL blocks. Also lists currently active routes if called with no routes active.",
204
- parameters: Type.Object({}),
205
-
206
- async execute(_toolCallId, _params, _signal, _onUpdate, _ctx) {
207
- try {
208
- await deps.ensureBrowser();
209
- const count = activeRoutes.length;
210
-
211
- if (count === 0) {
212
- return {
213
- content: [{ type: "text", text: "No active routes to clear." }],
214
- details: { cleared: 0 },
215
- };
216
- }
217
-
218
- const routeDescriptions = activeRoutes.map((r) => r.description);
219
-
220
- // Clean up all routes
221
- for (const [id, cleanup] of routeCleanups) {
222
- await cleanup();
223
- }
224
-
225
- activeRoutes.length = 0;
226
- routeCleanups.clear();
227
-
228
- return {
229
- content: [{
230
- type: "text",
231
- text: `Cleared ${count} route(s):\n${routeDescriptions.map((d) => ` - ${d}`).join("\n")}`,
232
- }],
233
- details: { cleared: count, routes: routeDescriptions },
234
- };
235
- } catch (err: any) {
236
- return {
237
- content: [{ type: "text", text: `Clear routes failed: ${err.message}` }],
238
- details: { error: err.message },
239
- isError: true,
240
- };
241
- }
242
- },
243
- });
70
+ async function handleMock(deps: ToolDeps, params: any) {
71
+ if (!params.url) {
72
+ return { content: [{ type: "text" as const, text: "Mock requires a 'url' parameter." }], details: { error: "missing_url" }, isError: true };
73
+ }
74
+ const { page: p } = await deps.ensureBrowser();
75
+ const routeId = nextRouteId++;
76
+ const status = params.status ?? 200;
77
+ const body = params.body ?? "";
78
+ const delay = params.delay ?? 0;
79
+
80
+ let contentType = params.contentType;
81
+ if (!contentType) {
82
+ try { JSON.parse(body); contentType = "application/json"; } catch { contentType = "text/plain"; }
83
+ }
84
+
85
+ const respHeaders: Record<string, string> = {
86
+ "content-type": contentType,
87
+ "access-control-allow-origin": "*",
88
+ ...(params.headers ?? {}),
89
+ };
90
+
91
+ const handler = async (route: any) => {
92
+ if (delay > 0) await new Promise((r) => setTimeout(r, delay));
93
+ await route.fulfill({ status, body, headers: respHeaders });
94
+ };
95
+
96
+ await p.route(params.url, handler);
97
+ const cleanup = async () => { try { await p.unroute(params.url, handler); } catch { /* page may be closed */ } };
98
+
99
+ const routeInfo: ActiveRoute = {
100
+ id: routeId, pattern: params.url, type: "mock", status,
101
+ delay: delay > 0 ? delay : undefined,
102
+ description: `Mock ${params.url} ${status}${delay > 0 ? ` (${delay}ms delay)` : ""}`,
103
+ };
104
+ activeRoutes.push(routeInfo);
105
+ routeCleanups.set(routeId, cleanup);
106
+
107
+ return {
108
+ content: [{ type: "text" as const, text: `Route mocked: ${routeInfo.description}\nRoute ID: ${routeId}\nActive routes: ${activeRoutes.length}` }],
109
+ details: { routeId, ...routeInfo, activeRouteCount: activeRoutes.length },
110
+ };
111
+ }
112
+
113
+ async function handleBlock(deps: ToolDeps, params: any) {
114
+ const patterns = params.patterns ?? (params.url ? [params.url] : []);
115
+ if (patterns.length === 0) {
116
+ return { content: [{ type: "text" as const, text: "Block requires 'patterns' or 'url' parameter." }], details: { error: "missing_patterns" }, isError: true };
117
+ }
118
+ const { page: p } = await deps.ensureBrowser();
119
+ const results: ActiveRoute[] = [];
120
+
121
+ for (const pattern of patterns) {
122
+ const routeId = nextRouteId++;
123
+ const handler = async (route: any) => { await route.abort("blockedbyclient"); };
124
+ await p.route(pattern, handler);
125
+ const cleanup = async () => { try { await p.unroute(pattern, handler); } catch { /* cleanup */ } };
126
+ const routeInfo: ActiveRoute = { id: routeId, pattern, type: "block", description: `Block ${pattern}` };
127
+ activeRoutes.push(routeInfo);
128
+ routeCleanups.set(routeId, cleanup);
129
+ results.push(routeInfo);
130
+ }
131
+
132
+ return {
133
+ content: [{ type: "text" as const, text: `Blocked ${results.length} URL pattern(s):\n${results.map((r) => ` - ${r.description} (ID: ${r.id})`).join("\n")}\nActive routes: ${activeRoutes.length}` }],
134
+ details: { blocked: results, activeRouteCount: activeRoutes.length },
135
+ };
136
+ }
137
+
138
+ async function handleClear(_deps: ToolDeps) {
139
+ await _deps.ensureBrowser();
140
+ const count = activeRoutes.length;
141
+ if (count === 0) {
142
+ return { content: [{ type: "text" as const, text: "No active routes to clear." }], details: { cleared: 0 } };
143
+ }
144
+ const descriptions = activeRoutes.map((r) => r.description);
145
+ for (const [, cleanup] of routeCleanups) await cleanup();
146
+ activeRoutes.length = 0;
147
+ routeCleanups.clear();
148
+ return {
149
+ content: [{ type: "text" as const, text: `Cleared ${count} route(s):\n${descriptions.map((d) => ` - ${d}`).join("\n")}` }],
150
+ details: { cleared: count, routes: descriptions },
151
+ };
152
+ }
244
153
  }