march-cli 0.1.9 → 0.1.11

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 (36) hide show
  1. package/package.json +1 -1
  2. package/src/agent/editing/lsp-report.mjs +69 -0
  3. package/src/agent/file-edit-tool.mjs +10 -24
  4. package/src/agent/model-payload-dumper.mjs +11 -4
  5. package/src/agent/runner/runner-utils.mjs +18 -0
  6. package/src/agent/runner.mjs +26 -27
  7. package/src/agent/runtime/runner-runtime-host.mjs +2 -0
  8. package/src/agent/turn/turn-logging.mjs +30 -0
  9. package/src/agent/turn/turn-runner.mjs +40 -0
  10. package/src/cli/commands/status-command.mjs +4 -16
  11. package/src/cli/permissions.mjs +1 -1
  12. package/src/cli/shell/shell-drawer.mjs +1 -1
  13. package/src/cli/startup/runtime-close.mjs +23 -0
  14. package/src/cli/tui/output/visible-lines.mjs +8 -0
  15. package/src/cli/tui/output-buffer.mjs +30 -21
  16. package/src/cli/tui/render/stream-delta-buffer.mjs +46 -0
  17. package/src/cli/tui/selection-screen.mjs +12 -4
  18. package/src/cli/tui/tool-rendering.mjs +1 -1
  19. package/src/cli/ui.mjs +16 -17
  20. package/src/config/loader.mjs +28 -1
  21. package/src/context/system-core/base.md +1 -1
  22. package/src/debug/logger.mjs +141 -0
  23. package/src/lsp/client.mjs +2 -2
  24. package/src/lsp/diagnostic-store.mjs +5 -2
  25. package/src/lsp/diagnostics-format.mjs +3 -1
  26. package/src/lsp/managed-node-server.mjs +94 -0
  27. package/src/lsp/path-match.mjs +10 -0
  28. package/src/lsp/servers.mjs +56 -13
  29. package/src/lsp/service.mjs +6 -6
  30. package/src/lsp/status-message.mjs +1 -0
  31. package/src/lsp/typescript-project-resolver.mjs +186 -0
  32. package/src/main.mjs +17 -24
  33. package/src/platform/spawn-command.mjs +27 -0
  34. package/src/provider/hosted-tools.mjs +111 -0
  35. package/src/shell/runtime.mjs +9 -1
  36. package/src/web/tools.mjs +2 -2
@@ -0,0 +1,111 @@
1
+ const OPENAI_PROVIDERS = new Set(["openai"]);
2
+ const OPENAI_CODEX_PROVIDERS = new Set(["openai-codex"]);
3
+ const AZURE_OPENAI_PROVIDERS = new Set(["azure-openai-responses"]);
4
+ const ANTHROPIC_PROVIDERS = new Set(["anthropic"]);
5
+ const GOOGLE_PROVIDERS = new Set(["google", "google-vertex"]);
6
+ const XAI_PROVIDERS = new Set(["xai", "supergrok-oauth", "xai-oauth"]);
7
+
8
+ export function injectHostedTools(payload, model, config = {}) {
9
+ const capabilities = resolveHostedToolCapabilities(model).filter((tool) => isToolEnabled(tool, config));
10
+ if (capabilities.length === 0) return payload;
11
+ return injectPayloadHostedTools(payload, capabilities);
12
+ }
13
+
14
+ export function resolveHostedTools(model, config = {}) {
15
+ return resolveHostedToolCapabilities(model).filter((tool) => isToolEnabled(tool, config)).map(createHostedTool);
16
+ }
17
+
18
+ export function resolveHostedToolCapabilities(model) {
19
+ if (!model || typeof model !== "object") return [];
20
+ if (OPENAI_PROVIDERS.has(model.provider) && isOpenAiResponsesApi(model.api)) return ["openai.webSearch"];
21
+ if (OPENAI_CODEX_PROVIDERS.has(model.provider) && model.api === "openai-codex-responses") {
22
+ return ["openaiCodex.webSearch"];
23
+ }
24
+ if (AZURE_OPENAI_PROVIDERS.has(model.provider) && model.api === "azure-openai-responses") {
25
+ return ["azureOpenai.webSearch"];
26
+ }
27
+ if (ANTHROPIC_PROVIDERS.has(model.provider) && model.api === "anthropic-messages") return ["anthropic.webSearch"];
28
+ if (GOOGLE_PROVIDERS.has(model.provider) && isGoogleApi(model.api)) return ["google.webSearch"];
29
+ if (XAI_PROVIDERS.has(model.provider) && model.api === "openai-responses") return ["xai.webSearch", "xai.xSearch"];
30
+ return [];
31
+ }
32
+
33
+ function isToolEnabled(tool, config) {
34
+ const [provider, name] = tool.split(".");
35
+ const value = config?.[provider]?.[name] ?? "auto";
36
+ return value !== false;
37
+ }
38
+
39
+ function createHostedTool(tool) {
40
+ if (tool === "openai.webSearch" || tool === "azureOpenai.webSearch") return { type: "web_search_preview" };
41
+ if (tool === "openaiCodex.webSearch") return { type: "web_search" };
42
+ if (tool === "anthropic.webSearch") return { type: "web_search_20250305", name: "web_search" };
43
+ if (tool === "google.webSearch") return { googleSearch: {} };
44
+ if (tool === "xai.webSearch") return { type: "web_search", enable_image_understanding: true };
45
+ if (tool === "xai.xSearch") {
46
+ return { type: "x_search", enable_image_understanding: true, enable_video_understanding: true };
47
+ }
48
+ throw new Error(`Unsupported hosted tool capability: ${tool}`);
49
+ }
50
+
51
+ function isOpenAiResponsesApi(api) {
52
+ return api === "openai-responses";
53
+ }
54
+
55
+ function isGoogleApi(api) {
56
+ return api === "google-generative-ai" || api === "google-vertex";
57
+ }
58
+
59
+ function injectPayloadHostedTools(payload, capabilities) {
60
+ if (!payload || typeof payload !== "object") return payload;
61
+ if (payload.body && typeof payload.body === "object") {
62
+ return { ...payload, body: injectPayloadHostedTools(payload.body, capabilities) };
63
+ }
64
+ if (typeof payload.body === "string") return injectStringBodyHostedTools(payload, capabilities);
65
+ return capabilities.reduce((next, capability) => injectPayloadHostedTool(next, capability), payload);
66
+ }
67
+
68
+ function injectPayloadHostedTool(payload, capability) {
69
+ if (capability.startsWith("google.")) return appendGoogleTool(payload, createHostedTool(capability));
70
+ return appendTopLevelTool(payload, createHostedTool(capability));
71
+ }
72
+
73
+ function injectStringBodyHostedTools(payload, capabilities) {
74
+ try {
75
+ const body = JSON.parse(payload.body);
76
+ return { ...payload, body: JSON.stringify(injectPayloadHostedTools(body, capabilities)) };
77
+ } catch {
78
+ return payload;
79
+ }
80
+ }
81
+
82
+ function appendTopLevelTool(payload, tool) {
83
+ if (!Array.isArray(payload.tools)) return { ...payload, tools: [tool] };
84
+ return { ...payload, tools: mergeTools(payload.tools, [tool], getToolKey) };
85
+ }
86
+
87
+ function appendGoogleTool(payload, tool) {
88
+ const config = payload.config && typeof payload.config === "object" ? payload.config : {};
89
+ const tools = Array.isArray(config.tools) ? config.tools : [];
90
+ return {
91
+ ...payload,
92
+ config: {
93
+ ...config,
94
+ tools: mergeTools(tools, [tool], getGoogleToolKey),
95
+ },
96
+ };
97
+ }
98
+
99
+ function mergeTools(existing, added, keyForTool) {
100
+ const keys = new Set(existing.map(keyForTool).filter(Boolean));
101
+ return [...existing, ...added.filter((tool) => !keys.has(keyForTool(tool)))];
102
+ }
103
+
104
+ function getToolKey(tool) {
105
+ return tool?.type ?? tool?.name;
106
+ }
107
+
108
+ function getGoogleToolKey(tool) {
109
+ if (tool?.googleSearch) return "googleSearch";
110
+ return tool?.functionDeclarations ? "functionDeclarations" : getToolKey(tool);
111
+ }
@@ -10,7 +10,6 @@ import {
10
10
  normalizeSize,
11
11
  publicShell,
12
12
  requireShell,
13
- stripAnsi,
14
13
  touch,
15
14
  uniqueName,
16
15
  } from "./runtime-state.mjs";
@@ -194,6 +193,14 @@ export function createShellRuntime({
194
193
  };
195
194
  }
196
195
 
196
+ function snapshotShellScreen(id) {
197
+ const shell = requireShell(shells, id);
198
+ return {
199
+ shell: publicShell(shell),
200
+ screen: shell.screen?.snapshot?.() ?? null,
201
+ };
202
+ }
203
+
197
204
  function clearShell(id) {
198
205
  const shell = requireShell(shells, id);
199
206
  shell.rawChunks = [];
@@ -238,6 +245,7 @@ export function createShellRuntime({
238
245
  getShell,
239
246
  searchShell,
240
247
  snapshotShell,
248
+ snapshotShellScreen,
241
249
  clearShell,
242
250
  dispose,
243
251
  };
package/src/web/tools.mjs CHANGED
@@ -6,8 +6,8 @@ import { fetchWebPage } from "./fetch.mjs";
6
6
 
7
7
  export function createWebTools({ tavilyKey, braveKey } = {}) {
8
8
  const webSearchTool = defineTool({
9
- name: "web_search",
10
- label: "Web Search",
9
+ name: "external_web_search",
10
+ label: "External Web Search",
11
11
  description:
12
12
  "Search the web for current information on any topic. " +
13
13
  "Requires TAVILY_API_KEY or BRAVE_API_KEY; if neither is configured, use web_fetch when you already know the URL. " +