march-cli 0.1.21 → 0.1.23
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 +88 -0
- package/README.zh.md +88 -0
- package/bin/march.mjs +13 -13
- package/package.json +43 -43
- package/src/agent/command-exec-tool.mjs +172 -168
- package/src/agent/context-stats-tool.mjs +57 -57
- package/src/agent/editing/diff-apply.mjs +28 -28
- package/src/agent/editing/diff-format.mjs +57 -57
- package/src/agent/editing/lsp-report.mjs +69 -69
- package/src/agent/file-edit-tool.mjs +262 -262
- package/src/agent/file-tools/read-file-tool.mjs +112 -112
- package/src/agent/file-tools/read-image-tool.mjs +76 -76
- package/src/agent/model-payload-dumper.mjs +208 -208
- package/src/agent/pi-session/pi-session-sidecar-failure.mjs +10 -10
- package/src/agent/provider/payload-messages.mjs +138 -138
- package/src/agent/runner/codex-large-context-guard.mjs +87 -87
- package/src/agent/runner/codex-transport-compression.mjs +180 -180
- package/src/agent/runner/codex-transport-debug.mjs +113 -113
- package/src/agent/runner/codex-websocket-event-debug.mjs +130 -130
- package/src/agent/runner/fast-model.mjs +36 -36
- package/src/agent/runner/runner-cleanup.mjs +12 -12
- package/src/agent/runner/runner-init.mjs +15 -15
- package/src/agent/runner/runner-session-state.mjs +40 -40
- package/src/agent/runner/runner-utils.mjs +24 -24
- package/src/agent/runner.mjs +299 -299
- package/src/agent/runtime/ipc/ipc-peer.mjs +99 -99
- package/src/agent/runtime/ipc/process-ipc-transport.mjs +16 -16
- package/src/agent/runtime/remote-runner-client.mjs +73 -73
- package/src/agent/runtime/remote-ui-client.mjs +20 -20
- package/src/agent/runtime/runner-ipc-target.mjs +125 -125
- package/src/agent/runtime/runner-process-client.mjs +47 -47
- package/src/agent/runtime/runner-process-entry.mjs +11 -11
- package/src/agent/runtime/runner-process-factory.mjs +108 -108
- package/src/agent/runtime/runner-runtime-host.mjs +79 -79
- package/src/agent/runtime/runtime-factory.mjs +42 -42
- package/src/agent/runtime/runtime-host.mjs +34 -34
- package/src/agent/runtime/ui-event-bridge.mjs +95 -95
- package/src/agent/screen-tools/list-windows-tool.mjs +39 -39
- package/src/agent/screen-tools/screen-tool.mjs +49 -49
- package/src/agent/screen-tools/windows-screen.mjs +133 -133
- package/src/agent/session/session-auto-name.mjs +41 -41
- package/src/agent/session/session-binding.mjs +12 -12
- package/src/agent/session/session-options.mjs +47 -47
- package/src/agent/tool-names.mjs +1 -1
- package/src/agent/tool-result.mjs +3 -3
- package/src/agent/tool-summary.mjs +112 -112
- package/src/agent/tools.mjs +58 -58
- package/src/agent/turn/turn-events.mjs +111 -111
- package/src/agent/turn/turn-logging.mjs +30 -30
- package/src/agent/turn/turn-runner.mjs +196 -196
- package/src/agent/vision-capability.mjs +14 -14
- package/src/auth/login-command.mjs +90 -90
- package/src/auth/storage.mjs +34 -34
- package/src/cli/args.mjs +79 -79
- package/src/cli/commands/copy-command.mjs +87 -87
- package/src/cli/commands/export-command.mjs +206 -206
- package/src/cli/commands/extensions-command.mjs +53 -53
- package/src/cli/commands/help-command.mjs +7 -7
- package/src/cli/commands/model-command.mjs +141 -141
- package/src/cli/commands/paste-image-command.mjs +43 -43
- package/src/cli/commands/provider-command.mjs +59 -59
- package/src/cli/commands/status-command.mjs +194 -194
- package/src/cli/commands/thinking-command.mjs +87 -87
- package/src/cli/fallback-ui.mjs +156 -156
- package/src/cli/input/attachment-tokens.mjs +20 -20
- package/src/cli/input/autocomplete.mjs +74 -106
- package/src/cli/input/external-editor.mjs +39 -39
- package/src/cli/input/file-search/index.mjs +160 -0
- package/src/cli/input/history-store.mjs +35 -35
- package/src/cli/input/image-clipboard.mjs +55 -55
- package/src/cli/input/keybinding-dispatch.mjs +76 -76
- package/src/cli/input/keybindings.mjs +96 -96
- package/src/cli/input/mode-state.mjs +43 -43
- package/src/cli/input/prompt-templates.mjs +84 -84
- package/src/cli/input/select-with-keyboard.mjs +86 -86
- package/src/cli/permissions.mjs +103 -103
- package/src/cli/repl-commands.mjs +86 -86
- package/src/cli/repl-loop.mjs +183 -183
- package/src/cli/selector-list.mjs +21 -21
- package/src/cli/session/pi-session-switch-command.mjs +41 -41
- package/src/cli/session/session-command.mjs +23 -23
- package/src/cli/session/session-list-command.mjs +68 -68
- package/src/cli/session/session-name-command.mjs +26 -26
- package/src/cli/session/session-source-command.mjs +89 -89
- package/src/cli/session/session-switch-command.mjs +1 -1
- package/src/cli/shell/shell-command.mjs +55 -55
- package/src/cli/shell/shell-drawer-controls.mjs +33 -33
- package/src/cli/shell/shell-drawer.mjs +192 -192
- package/src/cli/shell/shell-split-layout.mjs +70 -70
- package/src/cli/slash-commands.mjs +192 -192
- package/src/cli/startup/create-runtime-runner.mjs +61 -61
- package/src/cli/startup/runtime-close.mjs +23 -23
- package/src/cli/startup/startup-banner.mjs +71 -71
- package/src/cli/startup/startup-session.mjs +51 -51
- package/src/cli/status-line-updater.mjs +75 -75
- package/src/cli/tool-output.mjs +9 -9
- package/src/cli/tui/editor/external-editor-runner.mjs +24 -24
- package/src/cli/tui/input/mouse-selection-controller.mjs +91 -91
- package/src/cli/tui/input/mouse-tracking.mjs +20 -20
- package/src/cli/tui/layout/main-pane-layout.mjs +47 -47
- package/src/cli/tui/layout/safe-render-boundary.mjs +46 -46
- package/src/cli/tui/markdown-renderer.mjs +285 -285
- package/src/cli/tui/output/scroll-state.mjs +79 -79
- package/src/cli/tui/output/text-line-renderer.mjs +50 -50
- package/src/cli/tui/output/tool-card-renderer.mjs +59 -59
- package/src/cli/tui/output/visible-lines.mjs +8 -8
- package/src/cli/tui/output-buffer.mjs +293 -293
- package/src/cli/tui/permission-request-ui.mjs +18 -18
- package/src/cli/tui/recall-rendering.mjs +25 -25
- package/src/cli/tui/render/render-scheduler.mjs +26 -26
- package/src/cli/tui/render/stream-delta-buffer.mjs +46 -46
- package/src/cli/tui/select/editor-select-list.mjs +111 -111
- package/src/cli/tui/selection-screen.mjs +269 -269
- package/src/cli/tui/status/retry-status.mjs +72 -72
- package/src/cli/tui/status/spinner-status.mjs +42 -42
- package/src/cli/tui/status/status-bar.mjs +225 -225
- package/src/cli/tui/syntax/highlighting.mjs +260 -260
- package/src/cli/tui/syntax/languages.mjs +91 -91
- package/src/cli/tui/syntax/tree-sitter/bash.highlights.scm +261 -261
- package/src/cli/tui/syntax/tree-sitter/c.highlights.scm +341 -341
- package/src/cli/tui/syntax/tree-sitter/cpp.highlights.scm +268 -268
- package/src/cli/tui/syntax/tree-sitter/csharp.highlights.scm +577 -577
- package/src/cli/tui/syntax/tree-sitter/css.highlights.scm +109 -109
- package/src/cli/tui/syntax/tree-sitter/diff.highlights.scm +49 -49
- package/src/cli/tui/syntax/tree-sitter/go.highlights.scm +254 -254
- package/src/cli/tui/syntax/tree-sitter/html.highlights.scm +13 -13
- package/src/cli/tui/syntax/tree-sitter/java.highlights.scm +330 -330
- package/src/cli/tui/syntax/tree-sitter/json.highlights.scm +38 -38
- package/src/cli/tui/syntax/tree-sitter/php.highlights.scm +203 -203
- package/src/cli/tui/syntax/tree-sitter/python.highlights.scm +137 -137
- package/src/cli/tui/syntax/tree-sitter/ruby.highlights.scm +309 -309
- package/src/cli/tui/syntax/tree-sitter/rust.highlights.scm +531 -531
- package/src/cli/tui/syntax/tree-sitter/toml.highlights.scm +39 -39
- package/src/cli/tui/syntax/tree-sitter/tsx.highlights.scm +35 -35
- package/src/cli/tui/syntax/tree-sitter/typescript.highlights.scm +35 -35
- package/src/cli/tui/syntax/tree-sitter/yaml.highlights.scm +99 -99
- package/src/cli/tui/tool-rendering.mjs +87 -87
- package/src/cli/tui/tui-diff-rendering.mjs +157 -157
- package/src/cli/tui/tui-handlers.mjs +111 -111
- package/src/cli/tui/tui-input-controller.mjs +61 -61
- package/src/cli/tui/ui-theme.mjs +157 -157
- package/src/cli/ui.mjs +297 -297
- package/src/config/config-json.mjs +84 -84
- package/src/config/dotenv.mjs +20 -20
- package/src/config/features.mjs +75 -75
- package/src/config/loader.mjs +143 -143
- package/src/config/settings-command.mjs +97 -97
- package/src/context/engine.mjs +198 -198
- package/src/context/injections.mjs +26 -26
- package/src/context/profiles.mjs +39 -39
- package/src/context/project-context.mjs +20 -20
- package/src/context/session-status.mjs +17 -17
- package/src/context/shell-layers.mjs +23 -23
- package/src/context/system-core/base.md +61 -53
- package/src/context/system-core/prompts/deepseek-v4-pro.md +3 -3
- package/src/context/system-core/prompts/default.md +3 -3
- package/src/context/system-core.mjs +35 -35
- package/src/debug/logger.mjs +141 -141
- package/src/debug/model-context-dumper.mjs +52 -52
- package/src/extensions/discovery.mjs +40 -40
- package/src/extensions/lifecycle-adapter.mjs +210 -210
- package/src/extensions/lifecycle-manifest.mjs +69 -69
- package/src/image-gen/index.mjs +7 -7
- package/src/image-gen/provider.mjs +231 -231
- package/src/image-gen/tool.mjs +84 -84
- package/src/lsp/client.mjs +257 -257
- package/src/lsp/diagnostic-store.mjs +42 -42
- package/src/lsp/diagnostics-format.mjs +72 -72
- package/src/lsp/managed-node-server.mjs +99 -99
- package/src/lsp/path-match.mjs +10 -10
- package/src/lsp/server-definitions.mjs +188 -188
- package/src/lsp/servers.mjs +165 -165
- package/src/lsp/service.mjs +110 -110
- package/src/lsp/status-message.mjs +9 -9
- package/src/lsp/typescript-project-resolver.mjs +186 -186
- package/src/main.mjs +299 -299
- package/src/mcp/client.mjs +195 -195
- package/src/mcp/config.mjs +130 -130
- package/src/mcp/index.mjs +48 -48
- package/src/mcp/tools.mjs +98 -98
- package/src/memory/markdown/markdown-delete.mjs +23 -23
- package/src/memory/markdown/markdown-format.mjs +128 -128
- package/src/memory/markdown/markdown-recall.mjs +28 -28
- package/src/memory/markdown/ripgrep.mjs +16 -16
- package/src/memory/markdown/sqlite-index.mjs +87 -87
- package/src/memory/markdown-store.mjs +286 -286
- package/src/memory/markdown-tools.mjs +103 -103
- package/src/network/environment.mjs +131 -131
- package/src/notification/desktop-notifier.mjs +262 -262
- package/src/platform/open-file.mjs +28 -28
- package/src/platform/spawn-command.mjs +27 -27
- package/src/provider/accept-command.mjs +89 -89
- package/src/provider/command.mjs +21 -21
- package/src/provider/config-command.mjs +129 -129
- package/src/provider/custom-provider.mjs +113 -113
- package/src/provider/hosted-tools.mjs +111 -111
- package/src/provider/presets.mjs +72 -72
- package/src/provider/share-command.mjs +79 -79
- package/src/provider/share-payload.mjs +52 -52
- package/src/session/attachment-display.mjs +16 -16
- package/src/session/attachment-references.mjs +65 -65
- package/src/session/attachments.mjs +140 -140
- package/src/session/persist.mjs +1 -1
- package/src/session/pi-manager.mjs +34 -34
- package/src/session/session-utils.mjs +16 -16
- package/src/session/sidecar-sync.mjs +19 -19
- package/src/session/sidecar.mjs +69 -69
- package/src/session/transcript.mjs +83 -83
- package/src/session/tree.mjs +42 -42
- package/src/shell/cli-runtime.mjs +11 -11
- package/src/shell/hints.mjs +12 -12
- package/src/shell/node-pty-adapter.mjs +81 -81
- package/src/shell/runtime-state.mjs +126 -126
- package/src/shell/runtime.mjs +252 -252
- package/src/shell/screen-buffer.mjs +136 -136
- package/src/shell/tool-read.mjs +74 -74
- package/src/shell/tools.mjs +299 -299
- package/src/supergrok/actions/image-generate.mjs +60 -60
- package/src/supergrok/actions/search.mjs +78 -78
- package/src/supergrok/auth.mjs +36 -36
- package/src/supergrok/constants.mjs +18 -18
- package/src/supergrok/oauth-provider.mjs +278 -278
- package/src/supergrok/provider.mjs +35 -35
- package/src/supergrok/response.mjs +76 -76
- package/src/supergrok/tool.mjs +61 -61
- package/src/text/ansi.mjs +3 -3
- package/src/web/config-command.mjs +43 -43
- package/src/web/fetch.mjs +78 -78
- package/src/web/presets.mjs +16 -16
- package/src/web/search.mjs +83 -83
- package/src/web/tools.mjs +107 -107
- package/src/memory/database.mjs +0 -219
- package/src/memory/glossary.mjs +0 -124
- package/src/memory/graph/graph-cascades.mjs +0 -109
- package/src/memory/graph/graph-diagnostics.mjs +0 -73
- package/src/memory/graph/graph-path-removal.mjs +0 -50
- package/src/memory/graph/graph-path-utils.mjs +0 -17
- package/src/memory/graph/graph-primitives.mjs +0 -103
- package/src/memory/graph/graph-read.mjs +0 -159
- package/src/memory/graph.mjs +0 -282
- package/src/memory/search.mjs +0 -142
- package/src/memory/snapshot.mjs +0 -86
- package/src/memory/system-views.mjs +0 -120
- package/src/memory/tools.mjs +0 -282
|
@@ -1,57 +1,57 @@
|
|
|
1
|
-
import { defineTool } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
import { Type } from "typebox";
|
|
3
|
-
import { toolText } from "./tool-result.mjs";
|
|
4
|
-
|
|
5
|
-
export function createContextStatsTool({ engine }) {
|
|
6
|
-
return defineTool({
|
|
7
|
-
name: "context_stats",
|
|
8
|
-
label: "Context Stats",
|
|
9
|
-
description: "Show size statistics for the current March context layers without returning the full prompt text.",
|
|
10
|
-
parameters: Type.Object({}),
|
|
11
|
-
execute: async () => toolText(formatContextStats(engine), buildContextStats(engine)),
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function buildContextStats(engine) {
|
|
16
|
-
const layers = engine.buildContextLayers("");
|
|
17
|
-
const contextText = layers.map((layer) => layer.text).join("\n\n");
|
|
18
|
-
const layerStats = layers.map((layer) => ({
|
|
19
|
-
name: layer.name,
|
|
20
|
-
chars: layer.text.length,
|
|
21
|
-
estimatedTokens: estimateTokens(layer.text.length),
|
|
22
|
-
}));
|
|
23
|
-
return {
|
|
24
|
-
totalChars: contextText.length,
|
|
25
|
-
estimatedTokens: estimateTokens(contextText.length),
|
|
26
|
-
layers: layerStats,
|
|
27
|
-
runtime: {
|
|
28
|
-
turns: engine.turns?.length ?? 0,
|
|
29
|
-
toolDefs: engine.toolDefs?.length ?? 0,
|
|
30
|
-
},
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function formatContextStats(engine) {
|
|
35
|
-
const stats = buildContextStats(engine);
|
|
36
|
-
const lines = [
|
|
37
|
-
"Context stats:",
|
|
38
|
-
`total_chars: ${stats.totalChars}`,
|
|
39
|
-
`estimated_tokens: ${stats.estimatedTokens}`,
|
|
40
|
-
"",
|
|
41
|
-
"Layers:",
|
|
42
|
-
];
|
|
43
|
-
for (const layer of stats.layers) {
|
|
44
|
-
lines.push(`- ${layer.name}: ${layer.chars} chars, ~${layer.estimatedTokens} tokens`);
|
|
45
|
-
}
|
|
46
|
-
lines.push(
|
|
47
|
-
"",
|
|
48
|
-
"Runtime:",
|
|
49
|
-
`- turns: ${stats.runtime.turns}`,
|
|
50
|
-
`- tool_defs: ${stats.runtime.toolDefs}`,
|
|
51
|
-
);
|
|
52
|
-
return lines.join("\n");
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function estimateTokens(chars) {
|
|
56
|
-
return Math.ceil(chars / 4);
|
|
57
|
-
}
|
|
1
|
+
import { defineTool } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { Type } from "typebox";
|
|
3
|
+
import { toolText } from "./tool-result.mjs";
|
|
4
|
+
|
|
5
|
+
export function createContextStatsTool({ engine }) {
|
|
6
|
+
return defineTool({
|
|
7
|
+
name: "context_stats",
|
|
8
|
+
label: "Context Stats",
|
|
9
|
+
description: "Show size statistics for the current March context layers without returning the full prompt text.",
|
|
10
|
+
parameters: Type.Object({}),
|
|
11
|
+
execute: async () => toolText(formatContextStats(engine), buildContextStats(engine)),
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function buildContextStats(engine) {
|
|
16
|
+
const layers = engine.buildContextLayers("");
|
|
17
|
+
const contextText = layers.map((layer) => layer.text).join("\n\n");
|
|
18
|
+
const layerStats = layers.map((layer) => ({
|
|
19
|
+
name: layer.name,
|
|
20
|
+
chars: layer.text.length,
|
|
21
|
+
estimatedTokens: estimateTokens(layer.text.length),
|
|
22
|
+
}));
|
|
23
|
+
return {
|
|
24
|
+
totalChars: contextText.length,
|
|
25
|
+
estimatedTokens: estimateTokens(contextText.length),
|
|
26
|
+
layers: layerStats,
|
|
27
|
+
runtime: {
|
|
28
|
+
turns: engine.turns?.length ?? 0,
|
|
29
|
+
toolDefs: engine.toolDefs?.length ?? 0,
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function formatContextStats(engine) {
|
|
35
|
+
const stats = buildContextStats(engine);
|
|
36
|
+
const lines = [
|
|
37
|
+
"Context stats:",
|
|
38
|
+
`total_chars: ${stats.totalChars}`,
|
|
39
|
+
`estimated_tokens: ${stats.estimatedTokens}`,
|
|
40
|
+
"",
|
|
41
|
+
"Layers:",
|
|
42
|
+
];
|
|
43
|
+
for (const layer of stats.layers) {
|
|
44
|
+
lines.push(`- ${layer.name}: ${layer.chars} chars, ~${layer.estimatedTokens} tokens`);
|
|
45
|
+
}
|
|
46
|
+
lines.push(
|
|
47
|
+
"",
|
|
48
|
+
"Runtime:",
|
|
49
|
+
`- turns: ${stats.runtime.turns}`,
|
|
50
|
+
`- tool_defs: ${stats.runtime.toolDefs}`,
|
|
51
|
+
);
|
|
52
|
+
return lines.join("\n");
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function estimateTokens(chars) {
|
|
56
|
+
return Math.ceil(chars / 4);
|
|
57
|
+
}
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Apply unified-diff-like patches to in-memory text content.
|
|
3
|
-
* Used by file-edit-tool for dry-run validation and safe application.
|
|
4
|
-
*/
|
|
5
|
-
export function applyReplaceTextPatch(text, oldText, newText) {
|
|
6
|
-
const idx = text.indexOf(oldText);
|
|
7
|
-
if (idx === -1) {
|
|
8
|
-
return { ok: false, error: `Text not found in content` };
|
|
9
|
-
}
|
|
10
|
-
const before = text.slice(0, idx);
|
|
11
|
-
const after = text.slice(idx + oldText.length);
|
|
12
|
-
return { ok: true, result: before + newText + after };
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function applyReplaceRangePatch(text, startLine, endLine, newText) {
|
|
16
|
-
const lines = text.split("\n");
|
|
17
|
-
if (startLine < 1 || startLine > lines.length) {
|
|
18
|
-
return { ok: false, error: `startLine ${startLine} out of range (1-${lines.length})` };
|
|
19
|
-
}
|
|
20
|
-
if (endLine < startLine || endLine > lines.length) {
|
|
21
|
-
return { ok: false, error: `endLine ${endLine} out of range (${startLine}-${lines.length})` };
|
|
22
|
-
}
|
|
23
|
-
const zeroBasedStart = startLine - 1;
|
|
24
|
-
const before = lines.slice(0, zeroBasedStart);
|
|
25
|
-
const after = lines.slice(endLine);
|
|
26
|
-
const newLines = newText === "" ? [] : newText.split("\n");
|
|
27
|
-
return { ok: true, result: [...before, ...newLines, ...after].join("\n") };
|
|
28
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Apply unified-diff-like patches to in-memory text content.
|
|
3
|
+
* Used by file-edit-tool for dry-run validation and safe application.
|
|
4
|
+
*/
|
|
5
|
+
export function applyReplaceTextPatch(text, oldText, newText) {
|
|
6
|
+
const idx = text.indexOf(oldText);
|
|
7
|
+
if (idx === -1) {
|
|
8
|
+
return { ok: false, error: `Text not found in content` };
|
|
9
|
+
}
|
|
10
|
+
const before = text.slice(0, idx);
|
|
11
|
+
const after = text.slice(idx + oldText.length);
|
|
12
|
+
return { ok: true, result: before + newText + after };
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function applyReplaceRangePatch(text, startLine, endLine, newText) {
|
|
16
|
+
const lines = text.split("\n");
|
|
17
|
+
if (startLine < 1 || startLine > lines.length) {
|
|
18
|
+
return { ok: false, error: `startLine ${startLine} out of range (1-${lines.length})` };
|
|
19
|
+
}
|
|
20
|
+
if (endLine < startLine || endLine > lines.length) {
|
|
21
|
+
return { ok: false, error: `endLine ${endLine} out of range (${startLine}-${lines.length})` };
|
|
22
|
+
}
|
|
23
|
+
const zeroBasedStart = startLine - 1;
|
|
24
|
+
const before = lines.slice(0, zeroBasedStart);
|
|
25
|
+
const after = lines.slice(endLine);
|
|
26
|
+
const newLines = newText === "" ? [] : newText.split("\n");
|
|
27
|
+
return { ok: true, result: [...before, ...newLines, ...after].join("\n") };
|
|
28
|
+
}
|
|
@@ -1,57 +1,57 @@
|
|
|
1
|
-
export function formatDiff(oldText, newText, { startLine = 1 } = {}) {
|
|
2
|
-
if (oldText === "") return newText === "" ? [] : newText.split("\n").map((text, i) => ({ type: "add", text, lineNum: startLine + i }));
|
|
3
|
-
if (newText === "") return oldText.split("\n").map((text, i) => ({ type: "del", text, lineNum: startLine + i }));
|
|
4
|
-
const oldLines = oldText.split("\n");
|
|
5
|
-
const newLines = newText.split("\n");
|
|
6
|
-
|
|
7
|
-
let prefix = 0;
|
|
8
|
-
while (prefix < oldLines.length && prefix < newLines.length && oldLines[prefix] === newLines[prefix]) prefix++;
|
|
9
|
-
|
|
10
|
-
let suffix = 0;
|
|
11
|
-
while (
|
|
12
|
-
suffix < oldLines.length - prefix &&
|
|
13
|
-
suffix < newLines.length - prefix &&
|
|
14
|
-
oldLines[oldLines.length - 1 - suffix] === newLines[newLines.length - 1 - suffix]
|
|
15
|
-
) {
|
|
16
|
-
suffix++;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const ctx = 3;
|
|
20
|
-
const result = [];
|
|
21
|
-
const ctxStart = Math.max(0, prefix - ctx);
|
|
22
|
-
for (let i = ctxStart; i < prefix; i++) result.push({ type: "ctx", text: oldLines[i], lineNum: startLine + i });
|
|
23
|
-
|
|
24
|
-
const oldEnd = oldLines.length - suffix;
|
|
25
|
-
for (let i = prefix; i < oldEnd; i++) result.push({ type: "del", text: oldLines[i], lineNum: startLine + i });
|
|
26
|
-
|
|
27
|
-
const newEnd = newLines.length - suffix;
|
|
28
|
-
for (let i = prefix; i < newEnd; i++) result.push({ type: "add", text: newLines[i], lineNum: startLine + i });
|
|
29
|
-
|
|
30
|
-
const postStart = oldLines.length - suffix;
|
|
31
|
-
const postEnd = Math.min(oldLines.length, postStart + ctx);
|
|
32
|
-
for (let i = postStart; i < postEnd; i++) result.push({ type: "ctx", text: oldLines[i], lineNum: startLine + i });
|
|
33
|
-
return result;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export function countDiffChanges(diffLines) {
|
|
37
|
-
let adds = 0, dels = 0;
|
|
38
|
-
for (const line of diffLines) {
|
|
39
|
-
if (line.type === "add") adds++;
|
|
40
|
-
if (line.type === "del") dels++;
|
|
41
|
-
}
|
|
42
|
-
return { adds, dels };
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export function formatAppliedDiff(edits) {
|
|
46
|
-
const lines = ["[diff]"];
|
|
47
|
-
for (const edit of edits) {
|
|
48
|
-
const oldLineCount = edit.oldText.split("\n").length;
|
|
49
|
-
lines.push(`@@ lines ${edit.startLine}-${edit.startLine + oldLineCount - 1} @@`);
|
|
50
|
-
for (const line of formatDiff(edit.oldText, edit.newText, { startLine: edit.startLine })) {
|
|
51
|
-
if (line.type === "ctx") lines.push(` ${line.lineNum}: ${line.text}`);
|
|
52
|
-
if (line.type === "del") lines.push(`-${line.lineNum}: ${line.text}`);
|
|
53
|
-
if (line.type === "add") lines.push(`+${line.lineNum}: ${line.text}`);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
return lines.join("\n");
|
|
57
|
-
}
|
|
1
|
+
export function formatDiff(oldText, newText, { startLine = 1 } = {}) {
|
|
2
|
+
if (oldText === "") return newText === "" ? [] : newText.split("\n").map((text, i) => ({ type: "add", text, lineNum: startLine + i }));
|
|
3
|
+
if (newText === "") return oldText.split("\n").map((text, i) => ({ type: "del", text, lineNum: startLine + i }));
|
|
4
|
+
const oldLines = oldText.split("\n");
|
|
5
|
+
const newLines = newText.split("\n");
|
|
6
|
+
|
|
7
|
+
let prefix = 0;
|
|
8
|
+
while (prefix < oldLines.length && prefix < newLines.length && oldLines[prefix] === newLines[prefix]) prefix++;
|
|
9
|
+
|
|
10
|
+
let suffix = 0;
|
|
11
|
+
while (
|
|
12
|
+
suffix < oldLines.length - prefix &&
|
|
13
|
+
suffix < newLines.length - prefix &&
|
|
14
|
+
oldLines[oldLines.length - 1 - suffix] === newLines[newLines.length - 1 - suffix]
|
|
15
|
+
) {
|
|
16
|
+
suffix++;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const ctx = 3;
|
|
20
|
+
const result = [];
|
|
21
|
+
const ctxStart = Math.max(0, prefix - ctx);
|
|
22
|
+
for (let i = ctxStart; i < prefix; i++) result.push({ type: "ctx", text: oldLines[i], lineNum: startLine + i });
|
|
23
|
+
|
|
24
|
+
const oldEnd = oldLines.length - suffix;
|
|
25
|
+
for (let i = prefix; i < oldEnd; i++) result.push({ type: "del", text: oldLines[i], lineNum: startLine + i });
|
|
26
|
+
|
|
27
|
+
const newEnd = newLines.length - suffix;
|
|
28
|
+
for (let i = prefix; i < newEnd; i++) result.push({ type: "add", text: newLines[i], lineNum: startLine + i });
|
|
29
|
+
|
|
30
|
+
const postStart = oldLines.length - suffix;
|
|
31
|
+
const postEnd = Math.min(oldLines.length, postStart + ctx);
|
|
32
|
+
for (let i = postStart; i < postEnd; i++) result.push({ type: "ctx", text: oldLines[i], lineNum: startLine + i });
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function countDiffChanges(diffLines) {
|
|
37
|
+
let adds = 0, dels = 0;
|
|
38
|
+
for (const line of diffLines) {
|
|
39
|
+
if (line.type === "add") adds++;
|
|
40
|
+
if (line.type === "del") dels++;
|
|
41
|
+
}
|
|
42
|
+
return { adds, dels };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function formatAppliedDiff(edits) {
|
|
46
|
+
const lines = ["[diff]"];
|
|
47
|
+
for (const edit of edits) {
|
|
48
|
+
const oldLineCount = edit.oldText.split("\n").length;
|
|
49
|
+
lines.push(`@@ lines ${edit.startLine}-${edit.startLine + oldLineCount - 1} @@`);
|
|
50
|
+
for (const line of formatDiff(edit.oldText, edit.newText, { startLine: edit.startLine })) {
|
|
51
|
+
if (line.type === "ctx") lines.push(` ${line.lineNum}: ${line.text}`);
|
|
52
|
+
if (line.type === "del") lines.push(`-${line.lineNum}: ${line.text}`);
|
|
53
|
+
if (line.type === "add") lines.push(`+${line.lineNum}: ${line.text}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return lines.join("\n");
|
|
57
|
+
}
|
|
@@ -1,69 +1,69 @@
|
|
|
1
|
-
import { formatLspDiagnosticsForPath } from "../../lsp/diagnostics-format.mjs";
|
|
2
|
-
import { sameLspPath } from "../../lsp/path-match.mjs";
|
|
3
|
-
|
|
4
|
-
export async function waitForLspReport({ lspService, path, lspResult, since = Date.now(), timeoutMs = 3000, intervalMs = 150 }) {
|
|
5
|
-
const immediate = formatLspResultMessage(lspResult);
|
|
6
|
-
if (!lspService?.snapshot || !path || lspResult?.status === "unsupported") return immediate;
|
|
7
|
-
if (lspResult?.status === "unavailable" || lspResult?.status === "failed") return immediate;
|
|
8
|
-
|
|
9
|
-
const deadline = Date.now() + timeoutMs;
|
|
10
|
-
for (;;) {
|
|
11
|
-
const snapshot = lspService.snapshot();
|
|
12
|
-
const diagnostics = formatCurrentLspDiagnosticsForPath({ snapshot, path, since });
|
|
13
|
-
if (diagnostics) return diagnostics;
|
|
14
|
-
if (hasCurrentDiagnosticPublish({ snapshot, path, since })) return formatNoLspDiagnostics({ snapshot });
|
|
15
|
-
|
|
16
|
-
const remaining = deadline - Date.now();
|
|
17
|
-
if (remaining <= 0) return formatLatestLspMessage({ snapshot, lspResult });
|
|
18
|
-
await sleep(Math.min(intervalMs, remaining));
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function formatLspResultMessage(result, { timedOut = false } = {}) {
|
|
23
|
-
if (!result || result.status === "unsupported") return "";
|
|
24
|
-
if (result.status === "unavailable" || result.status === "failed") {
|
|
25
|
-
return `<lsp status="${result.status}" server="${result.id ?? "unknown"}">${result.reason ?? "unavailable"}</lsp>`;
|
|
26
|
-
}
|
|
27
|
-
if (result.status === "starting") {
|
|
28
|
-
const detail = timedOut ? "diagnostics still pending; server continues in background" : "diagnostics pending";
|
|
29
|
-
return `<lsp status="starting" server="${result.id}">${detail}</lsp>`;
|
|
30
|
-
}
|
|
31
|
-
return "";
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function formatCurrentLspDiagnosticsForPath({ snapshot, path, since }) {
|
|
35
|
-
const diagnostics = formatLspDiagnosticsForPath({ snapshot, path });
|
|
36
|
-
if (!diagnostics) return "";
|
|
37
|
-
if (!Array.isArray(snapshot?.files)) return diagnostics;
|
|
38
|
-
return hasCurrentDiagnosticPublish({ snapshot, path, since }) ? diagnostics : "";
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function hasCurrentDiagnosticPublish({ snapshot, path, since }) {
|
|
42
|
-
return (snapshot?.files ?? []).some((file) => sameLspPath(file.path, path) && (file.updatedAt ?? 0) >= since);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function formatNoLspDiagnostics({ snapshot }) {
|
|
46
|
-
const lines = ["[diagnostics]", "source: lsp"];
|
|
47
|
-
if (snapshot?.status) lines.push(`status: ${snapshot.status}`);
|
|
48
|
-
lines.push("summary: 0 diagnostics");
|
|
49
|
-
return lines.join("\n");
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function formatLatestLspMessage({ snapshot, lspResult }) {
|
|
53
|
-
const server = latestServerForResult(snapshot, lspResult);
|
|
54
|
-
if (server?.status === "failed" || server?.status === "unavailable") {
|
|
55
|
-
return formatLspResultMessage({ ...lspResult, ...server });
|
|
56
|
-
}
|
|
57
|
-
if (server?.status === "idle" || server?.status === "ready") return formatNoLspDiagnostics({ snapshot });
|
|
58
|
-
return formatLspResultMessage(lspResult, { timedOut: lspResult?.status === "starting" });
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function latestServerForResult(snapshot, lspResult) {
|
|
62
|
-
const servers = snapshot?.servers ?? [];
|
|
63
|
-
return servers.find((server) => server.id === lspResult?.id && server.root === lspResult?.root)
|
|
64
|
-
?? servers.find((server) => server.id === lspResult?.id);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function sleep(ms) {
|
|
68
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
69
|
-
}
|
|
1
|
+
import { formatLspDiagnosticsForPath } from "../../lsp/diagnostics-format.mjs";
|
|
2
|
+
import { sameLspPath } from "../../lsp/path-match.mjs";
|
|
3
|
+
|
|
4
|
+
export async function waitForLspReport({ lspService, path, lspResult, since = Date.now(), timeoutMs = 3000, intervalMs = 150 }) {
|
|
5
|
+
const immediate = formatLspResultMessage(lspResult);
|
|
6
|
+
if (!lspService?.snapshot || !path || lspResult?.status === "unsupported") return immediate;
|
|
7
|
+
if (lspResult?.status === "unavailable" || lspResult?.status === "failed") return immediate;
|
|
8
|
+
|
|
9
|
+
const deadline = Date.now() + timeoutMs;
|
|
10
|
+
for (;;) {
|
|
11
|
+
const snapshot = lspService.snapshot();
|
|
12
|
+
const diagnostics = formatCurrentLspDiagnosticsForPath({ snapshot, path, since });
|
|
13
|
+
if (diagnostics) return diagnostics;
|
|
14
|
+
if (hasCurrentDiagnosticPublish({ snapshot, path, since })) return formatNoLspDiagnostics({ snapshot });
|
|
15
|
+
|
|
16
|
+
const remaining = deadline - Date.now();
|
|
17
|
+
if (remaining <= 0) return formatLatestLspMessage({ snapshot, lspResult });
|
|
18
|
+
await sleep(Math.min(intervalMs, remaining));
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function formatLspResultMessage(result, { timedOut = false } = {}) {
|
|
23
|
+
if (!result || result.status === "unsupported") return "";
|
|
24
|
+
if (result.status === "unavailable" || result.status === "failed") {
|
|
25
|
+
return `<lsp status="${result.status}" server="${result.id ?? "unknown"}">${result.reason ?? "unavailable"}</lsp>`;
|
|
26
|
+
}
|
|
27
|
+
if (result.status === "starting") {
|
|
28
|
+
const detail = timedOut ? "diagnostics still pending; server continues in background" : "diagnostics pending";
|
|
29
|
+
return `<lsp status="starting" server="${result.id}">${detail}</lsp>`;
|
|
30
|
+
}
|
|
31
|
+
return "";
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function formatCurrentLspDiagnosticsForPath({ snapshot, path, since }) {
|
|
35
|
+
const diagnostics = formatLspDiagnosticsForPath({ snapshot, path });
|
|
36
|
+
if (!diagnostics) return "";
|
|
37
|
+
if (!Array.isArray(snapshot?.files)) return diagnostics;
|
|
38
|
+
return hasCurrentDiagnosticPublish({ snapshot, path, since }) ? diagnostics : "";
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function hasCurrentDiagnosticPublish({ snapshot, path, since }) {
|
|
42
|
+
return (snapshot?.files ?? []).some((file) => sameLspPath(file.path, path) && (file.updatedAt ?? 0) >= since);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function formatNoLspDiagnostics({ snapshot }) {
|
|
46
|
+
const lines = ["[diagnostics]", "source: lsp"];
|
|
47
|
+
if (snapshot?.status) lines.push(`status: ${snapshot.status}`);
|
|
48
|
+
lines.push("summary: 0 diagnostics");
|
|
49
|
+
return lines.join("\n");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function formatLatestLspMessage({ snapshot, lspResult }) {
|
|
53
|
+
const server = latestServerForResult(snapshot, lspResult);
|
|
54
|
+
if (server?.status === "failed" || server?.status === "unavailable") {
|
|
55
|
+
return formatLspResultMessage({ ...lspResult, ...server });
|
|
56
|
+
}
|
|
57
|
+
if (server?.status === "idle" || server?.status === "ready") return formatNoLspDiagnostics({ snapshot });
|
|
58
|
+
return formatLspResultMessage(lspResult, { timedOut: lspResult?.status === "starting" });
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function latestServerForResult(snapshot, lspResult) {
|
|
62
|
+
const servers = snapshot?.servers ?? [];
|
|
63
|
+
return servers.find((server) => server.id === lspResult?.id && server.root === lspResult?.root)
|
|
64
|
+
?? servers.find((server) => server.id === lspResult?.id);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function sleep(ms) {
|
|
68
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
69
|
+
}
|