@aexol/spectral 0.7.7 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/agents.js +4 -4
- package/dist/agent/index.js +24 -148
- package/dist/cli.js +25 -220
- package/dist/commands/serve.js +1 -1
- package/dist/extensions/spectral-vision-fallback.js +225 -0
- package/dist/mcp/agent-dir.js +1 -1
- package/dist/mcp/config.js +3 -3
- package/dist/mcp/sampling-handler.js +1 -1
- package/dist/mcp/server-manager.js +5 -1
- package/dist/memory/commands/status.js +6 -6
- package/dist/memory/commands/view.js +16 -14
- package/dist/memory/compaction.js +33 -5
- package/dist/memory/config.js +3 -3
- package/dist/memory/debug-log.js +1 -1
- package/dist/memory/observer.js +2 -2
- package/dist/memory/prompts.js +5 -5
- package/dist/memory/tokens.js +1 -1
- package/dist/memory/tools/read-project-observations.js +2 -2
- package/dist/memory/tools/recall-observation.js +4 -4
- package/dist/relay/auto-research.js +23 -23
- package/dist/relay/dispatcher.js +28 -2
- package/dist/relay/models-fetch.js +15 -3
- package/dist/{pi → sdk}/coding-agent/cli/args.js +4 -4
- package/dist/{pi → sdk}/coding-agent/config.js +9 -20
- package/dist/{pi → sdk}/coding-agent/core/agent-session.js +5 -17
- package/dist/{pi → sdk}/coding-agent/core/compaction/compaction.js +161 -5
- package/dist/{pi → sdk}/coding-agent/core/extensions/loader.js +0 -6
- package/dist/{pi → sdk}/coding-agent/core/extensions/runner.js +7 -1
- package/dist/{pi → sdk}/coding-agent/core/keybindings.js +129 -2
- package/dist/{pi → sdk}/coding-agent/core/model-registry.js +11 -4
- package/dist/{pi → sdk}/coding-agent/core/package-manager.js +5 -5
- package/dist/{pi → sdk}/coding-agent/core/sdk.js +1 -1
- package/dist/{pi → sdk}/coding-agent/core/session-manager.js +4 -4
- package/dist/{pi → sdk}/coding-agent/core/settings-manager.js +20 -0
- package/dist/{pi → sdk}/coding-agent/core/telemetry.js +1 -1
- package/dist/{pi → sdk}/coding-agent/core/tools/bash.js +17 -63
- package/dist/{pi → sdk}/coding-agent/core/tools/edit.js +4 -141
- package/dist/{pi → sdk}/coding-agent/core/tools/find.js +0 -11
- package/dist/{pi → sdk}/coding-agent/core/tools/grep.js +0 -11
- package/dist/{pi → sdk}/coding-agent/core/tools/ls.js +0 -11
- package/dist/{pi → sdk}/coding-agent/core/tools/read.js +0 -12
- package/dist/{pi → sdk}/coding-agent/core/tools/render-utils.js +1 -14
- package/dist/{pi → sdk}/coding-agent/core/tools/write.js +2 -97
- package/dist/{pi → sdk}/coding-agent/migrations.js +3 -3
- package/dist/{pi → sdk}/coding-agent/modes/interactive/components/keybinding-hints.js +1 -1
- package/dist/sdk/coding-agent/modes/interactive/components/visual-truncate.js +26 -0
- package/dist/{pi → sdk}/coding-agent/modes/interactive/theme/theme.js +1 -2
- package/dist/{pi → sdk}/coding-agent/utils/tools-manager.js +1 -1
- package/dist/{pi → sdk}/coding-agent/utils/version-check.js +2 -2
- package/dist/{pi → sdk}/coding-agent/utils/windows-self-update.js +1 -1
- package/dist/server/{pi-bridge.js → agent-bridge.js} +158 -89
- package/dist/server/handlers/sessions.js +21 -0
- package/dist/server/session-stream.js +12 -6
- package/package.json +6 -3
- package/dist/pi/coding-agent/core/export-html/ansi-to-html.js +0 -248
- package/dist/pi/coding-agent/core/export-html/index.js +0 -225
- package/dist/pi/coding-agent/core/export-html/tool-renderer.js +0 -107
- package/dist/pi/coding-agent/modes/interactive/components/visual-truncate.js +0 -32
- package/dist/pi/tui/autocomplete.js +0 -631
- package/dist/pi/tui/components/box.js +0 -103
- package/dist/pi/tui/components/cancellable-loader.js +0 -34
- package/dist/pi/tui/components/editor.js +0 -1915
- package/dist/pi/tui/components/image.js +0 -88
- package/dist/pi/tui/components/input.js +0 -425
- package/dist/pi/tui/components/loader.js +0 -68
- package/dist/pi/tui/components/markdown.js +0 -633
- package/dist/pi/tui/components/select-list.js +0 -158
- package/dist/pi/tui/components/settings-list.js +0 -184
- package/dist/pi/tui/components/spacer.js +0 -22
- package/dist/pi/tui/components/text.js +0 -88
- package/dist/pi/tui/components/truncated-text.js +0 -50
- package/dist/pi/tui/editor-component.js +0 -1
- package/dist/pi/tui/fuzzy.js +0 -109
- package/dist/pi/tui/index.js +0 -31
- package/dist/pi/tui/keybindings.js +0 -173
- package/dist/pi/tui/keys.js +0 -1172
- package/dist/pi/tui/kill-ring.js +0 -43
- package/dist/pi/tui/stdin-buffer.js +0 -360
- package/dist/pi/tui/terminal-image.js +0 -335
- package/dist/pi/tui/terminal.js +0 -324
- package/dist/pi/tui/tui.js +0 -1076
- package/dist/pi/tui/undo-stack.js +0 -24
- package/dist/pi/tui/utils.js +0 -1016
- /package/dist/{pi → sdk}/agent-core/agent-loop.js +0 -0
- /package/dist/{pi → sdk}/agent-core/agent.js +0 -0
- /package/dist/{pi → sdk}/agent-core/harness/agent-harness.js +0 -0
- /package/dist/{pi → sdk}/agent-core/harness/compaction/branch-summarization.js +0 -0
- /package/dist/{pi → sdk}/agent-core/harness/compaction/compaction.js +0 -0
- /package/dist/{pi → sdk}/agent-core/harness/compaction/utils.js +0 -0
- /package/dist/{pi → sdk}/agent-core/harness/env/nodejs.js +0 -0
- /package/dist/{pi → sdk}/agent-core/harness/messages.js +0 -0
- /package/dist/{pi → sdk}/agent-core/harness/prompt-templates.js +0 -0
- /package/dist/{pi → sdk}/agent-core/harness/session/jsonl-repo.js +0 -0
- /package/dist/{pi → sdk}/agent-core/harness/session/jsonl-storage.js +0 -0
- /package/dist/{pi → sdk}/agent-core/harness/session/memory-repo.js +0 -0
- /package/dist/{pi → sdk}/agent-core/harness/session/memory-storage.js +0 -0
- /package/dist/{pi → sdk}/agent-core/harness/session/repo-utils.js +0 -0
- /package/dist/{pi → sdk}/agent-core/harness/session/session.js +0 -0
- /package/dist/{pi → sdk}/agent-core/harness/session/uuid.js +0 -0
- /package/dist/{pi → sdk}/agent-core/harness/skills.js +0 -0
- /package/dist/{pi → sdk}/agent-core/harness/system-prompt.js +0 -0
- /package/dist/{pi → sdk}/agent-core/harness/types.js +0 -0
- /package/dist/{pi → sdk}/agent-core/harness/utils/shell-output.js +0 -0
- /package/dist/{pi → sdk}/agent-core/harness/utils/truncate.js +0 -0
- /package/dist/{pi → sdk}/agent-core/index.js +0 -0
- /package/dist/{pi → sdk}/agent-core/node.js +0 -0
- /package/dist/{pi → sdk}/agent-core/proxy.js +0 -0
- /package/dist/{pi → sdk}/agent-core/types.js +0 -0
- /package/dist/{pi → sdk}/ai/api-registry.js +0 -0
- /package/dist/{pi → sdk}/ai/cli.js +0 -0
- /package/dist/{pi → sdk}/ai/env-api-keys.js +0 -0
- /package/dist/{pi → sdk}/ai/image-models.generated.js +0 -0
- /package/dist/{pi → sdk}/ai/image-models.js +0 -0
- /package/dist/{pi → sdk}/ai/images-api-registry.js +0 -0
- /package/dist/{pi → sdk}/ai/images.js +0 -0
- /package/dist/{pi → sdk}/ai/index.js +0 -0
- /package/dist/{pi → sdk}/ai/models.generated.js +0 -0
- /package/dist/{pi → sdk}/ai/models.js +0 -0
- /package/dist/{pi → sdk}/ai/oauth.js +0 -0
- /package/dist/{pi → sdk}/ai/providers/anthropic.js +0 -0
- /package/dist/{pi → sdk}/ai/providers/faux.js +0 -0
- /package/dist/{pi → sdk}/ai/providers/github-copilot-headers.js +0 -0
- /package/dist/{pi → sdk}/ai/providers/openai-completions.js +0 -0
- /package/dist/{pi → sdk}/ai/providers/openai-prompt-cache.js +0 -0
- /package/dist/{pi → sdk}/ai/providers/register-builtins.js +0 -0
- /package/dist/{pi → sdk}/ai/providers/simple-options.js +0 -0
- /package/dist/{pi → sdk}/ai/providers/transform-messages.js +0 -0
- /package/dist/{pi → sdk}/ai/session-resources.js +0 -0
- /package/dist/{pi → sdk}/ai/stream.js +0 -0
- /package/dist/{pi → sdk}/ai/types.js +0 -0
- /package/dist/{pi → sdk}/ai/utils/diagnostics.js +0 -0
- /package/dist/{pi → sdk}/ai/utils/event-stream.js +0 -0
- /package/dist/{pi → sdk}/ai/utils/hash.js +0 -0
- /package/dist/{pi → sdk}/ai/utils/headers.js +0 -0
- /package/dist/{pi → sdk}/ai/utils/json-parse.js +0 -0
- /package/dist/{pi → sdk}/ai/utils/node-http-proxy.js +0 -0
- /package/dist/{pi → sdk}/ai/utils/oauth/anthropic.js +0 -0
- /package/dist/{pi → sdk}/ai/utils/oauth/device-code.js +0 -0
- /package/dist/{pi → sdk}/ai/utils/oauth/github-copilot.js +0 -0
- /package/dist/{pi → sdk}/ai/utils/oauth/index.js +0 -0
- /package/dist/{pi → sdk}/ai/utils/oauth/oauth-page.js +0 -0
- /package/dist/{pi → sdk}/ai/utils/oauth/openai-codex.js +0 -0
- /package/dist/{pi → sdk}/ai/utils/oauth/pkce.js +0 -0
- /package/dist/{pi → sdk}/ai/utils/oauth/types.js +0 -0
- /package/dist/{pi → sdk}/ai/utils/overflow.js +0 -0
- /package/dist/{pi → sdk}/ai/utils/sanitize-unicode.js +0 -0
- /package/dist/{pi → sdk}/ai/utils/typebox-helpers.js +0 -0
- /package/dist/{pi → sdk}/ai/utils/validation.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/bun/cli.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/bun/restore-sandbox-env.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/cli/file-processor.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/cli/initial-message.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/cli.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/agent-session-runtime.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/agent-session-services.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/auth-guidance.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/auth-storage.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/bash-executor.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/compaction/branch-summarization.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/compaction/index.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/compaction/utils.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/defaults.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/diagnostics.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/event-bus.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/exec.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/extensions/index.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/extensions/types.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/extensions/wrapper.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/footer-data-provider.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/http-dispatcher.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/index.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/messages.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/model-resolver.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/output-guard.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/prompt-templates.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/provider-display-names.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/resolve-config-value.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/resource-loader.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/session-cwd.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/skills.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/slash-commands.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/source-info.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/system-prompt.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/timings.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/tools/edit-diff.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/tools/file-mutation-queue.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/tools/index.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/tools/output-accumulator.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/tools/path-utils.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/tools/tool-definition-wrapper.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/core/tools/truncate.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/index.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/main.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/modes/index.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/modes/interactive/components/diff.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/modes/interactive/interactive-mode.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/modes/print-mode.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/modes/rpc/jsonl.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/modes/rpc/rpc-client.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/modes/rpc/rpc-mode.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/modes/rpc/rpc-types.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/utils/ansi.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/utils/changelog.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/utils/child-process.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/utils/clipboard-image.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/utils/clipboard-native.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/utils/clipboard.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/utils/exif-orientation.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/utils/frontmatter.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/utils/fs-watch.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/utils/git.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/utils/html.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/utils/image-convert.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/utils/image-resize.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/utils/mime.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/utils/paths.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/utils/photon.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/utils/pi-user-agent.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/utils/shell.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/utils/sleep.js +0 -0
- /package/dist/{pi → sdk}/coding-agent/utils/syntax-highlight.js +0 -0
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { createInterface } from "node:readline";
|
|
2
|
-
import { Text } from "../../../tui/index.js";
|
|
3
2
|
import { spawn } from "child_process";
|
|
4
3
|
import { existsSync } from "fs";
|
|
5
4
|
import path from "path";
|
|
@@ -280,16 +279,6 @@ export function createFindToolDefinition(cwd, options) {
|
|
|
280
279
|
})();
|
|
281
280
|
});
|
|
282
281
|
},
|
|
283
|
-
renderCall(args, theme, context) {
|
|
284
|
-
const text = context.lastComponent ?? new Text("", 0, 0);
|
|
285
|
-
text.setText(formatFindCall(args, theme));
|
|
286
|
-
return text;
|
|
287
|
-
},
|
|
288
|
-
renderResult(result, options, theme, context) {
|
|
289
|
-
const text = context.lastComponent ?? new Text("", 0, 0);
|
|
290
|
-
text.setText(formatFindResult(result, options, theme, context.showImages));
|
|
291
|
-
return text;
|
|
292
|
-
},
|
|
293
282
|
};
|
|
294
283
|
}
|
|
295
284
|
export function createFindTool(cwd, options) {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { createInterface } from "node:readline";
|
|
2
|
-
import { Text } from "../../../tui/index.js";
|
|
3
2
|
import { spawn } from "child_process";
|
|
4
3
|
import { readFileSync, statSync } from "fs";
|
|
5
4
|
import path from "path";
|
|
@@ -286,16 +285,6 @@ export function createGrepToolDefinition(cwd, options) {
|
|
|
286
285
|
})();
|
|
287
286
|
});
|
|
288
287
|
},
|
|
289
|
-
renderCall(args, theme, context) {
|
|
290
|
-
const text = context.lastComponent ?? new Text("", 0, 0);
|
|
291
|
-
text.setText(formatGrepCall(args, theme));
|
|
292
|
-
return text;
|
|
293
|
-
},
|
|
294
|
-
renderResult(result, options, theme, context) {
|
|
295
|
-
const text = context.lastComponent ?? new Text("", 0, 0);
|
|
296
|
-
text.setText(formatGrepResult(result, options, theme, context.showImages));
|
|
297
|
-
return text;
|
|
298
|
-
},
|
|
299
288
|
};
|
|
300
289
|
}
|
|
301
290
|
export function createGrepTool(cwd, options) {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Text } from "../../../tui/index.js";
|
|
2
1
|
import { existsSync, readdirSync, statSync } from "fs";
|
|
3
2
|
import nodePath from "path";
|
|
4
3
|
import { Type } from "typebox";
|
|
@@ -151,16 +150,6 @@ export function createLsToolDefinition(cwd, options) {
|
|
|
151
150
|
})();
|
|
152
151
|
});
|
|
153
152
|
},
|
|
154
|
-
renderCall(args, theme, context) {
|
|
155
|
-
const text = context.lastComponent ?? new Text("", 0, 0);
|
|
156
|
-
text.setText(formatLsCall(args, theme));
|
|
157
|
-
return text;
|
|
158
|
-
},
|
|
159
|
-
renderResult(result, options, theme, context) {
|
|
160
|
-
const text = context.lastComponent ?? new Text("", 0, 0);
|
|
161
|
-
text.setText(formatLsResult(result, options, theme, context.showImages));
|
|
162
|
-
return text;
|
|
163
|
-
},
|
|
164
153
|
};
|
|
165
154
|
}
|
|
166
155
|
export function createLsTool(cwd, options) {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { basename, dirname, isAbsolute, relative, resolve as resolvePath, sep } from "node:path";
|
|
2
|
-
import { Text } from "../../../tui/index.js";
|
|
3
2
|
import { constants } from "fs";
|
|
4
3
|
import { access as fsAccess, readFile as fsReadFile } from "fs/promises";
|
|
5
4
|
import { Type } from "typebox";
|
|
@@ -270,17 +269,6 @@ export function createReadToolDefinition(cwd, options) {
|
|
|
270
269
|
})();
|
|
271
270
|
});
|
|
272
271
|
},
|
|
273
|
-
renderCall(args, theme, context) {
|
|
274
|
-
const text = context.lastComponent ?? new Text("", 0, 0);
|
|
275
|
-
const classification = !context.expanded ? getCompactReadClassification(args, context.cwd) : undefined;
|
|
276
|
-
text.setText(classification ? formatCompactReadCall(classification, args, theme) : formatReadCall(args, theme));
|
|
277
|
-
return text;
|
|
278
|
-
},
|
|
279
|
-
renderResult(result, options, theme, context) {
|
|
280
|
-
const text = context.lastComponent ?? new Text("", 0, 0);
|
|
281
|
-
text.setText(formatReadResult(context.args, result, options, theme, context.showImages, context.cwd, context.isError));
|
|
282
|
-
return text;
|
|
283
|
-
},
|
|
284
272
|
};
|
|
285
273
|
}
|
|
286
274
|
export function createReadTool(cwd, options) {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import * as os from "node:os";
|
|
2
|
-
import { getCapabilities, getImageDimensions, imageFallback } from "../../../tui/index.js";
|
|
3
2
|
import { stripAnsi } from "../../utils/ansi.js";
|
|
4
3
|
import { sanitizeBinaryOutput } from "../../utils/shell.js";
|
|
5
4
|
export function shortenPath(path) {
|
|
@@ -24,23 +23,11 @@ export function replaceTabs(text) {
|
|
|
24
23
|
export function normalizeDisplayText(text) {
|
|
25
24
|
return text.replace(/\r/g, "");
|
|
26
25
|
}
|
|
27
|
-
export function getTextOutput(result,
|
|
26
|
+
export function getTextOutput(result, _showImages) {
|
|
28
27
|
if (!result)
|
|
29
28
|
return "";
|
|
30
29
|
const textBlocks = result.content.filter((c) => c.type === "text");
|
|
31
|
-
const imageBlocks = result.content.filter((c) => c.type === "image");
|
|
32
30
|
let output = textBlocks.map((c) => sanitizeBinaryOutput(stripAnsi(c.text || "")).replace(/\r/g, "")).join("\n");
|
|
33
|
-
const caps = getCapabilities();
|
|
34
|
-
if (imageBlocks.length > 0 && (!caps.images || !showImages)) {
|
|
35
|
-
const imageIndicators = imageBlocks
|
|
36
|
-
.map((img) => {
|
|
37
|
-
const mimeType = img.mimeType ?? "image/unknown";
|
|
38
|
-
const dims = img.data && img.mimeType ? (getImageDimensions(img.data, img.mimeType) ?? undefined) : undefined;
|
|
39
|
-
return imageFallback(mimeType, dims);
|
|
40
|
-
})
|
|
41
|
-
.join("\n");
|
|
42
|
-
output = output ? `${output}\n${imageIndicators}` : imageIndicators;
|
|
43
|
-
}
|
|
44
31
|
return output;
|
|
45
32
|
}
|
|
46
33
|
export function invalidArgText(theme) {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Container, Text } from "../../../tui/index.js";
|
|
2
1
|
import { mkdir as fsMkdir, writeFile as fsWriteFile } from "fs/promises";
|
|
3
2
|
import { dirname } from "path";
|
|
4
3
|
import { Type } from "typebox";
|
|
@@ -16,73 +15,6 @@ const defaultWriteOperations = {
|
|
|
16
15
|
writeFile: (path, content) => fsWriteFile(path, content, "utf-8"),
|
|
17
16
|
mkdir: (dir) => fsMkdir(dir, { recursive: true }).then(() => { }),
|
|
18
17
|
};
|
|
19
|
-
class WriteCallRenderComponent extends Text {
|
|
20
|
-
cache;
|
|
21
|
-
constructor() {
|
|
22
|
-
super("", 0, 0);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
const WRITE_PARTIAL_FULL_HIGHLIGHT_LINES = 50;
|
|
26
|
-
function highlightSingleLine(line, lang) {
|
|
27
|
-
const highlighted = highlightCode(line, lang);
|
|
28
|
-
return highlighted[0] ?? "";
|
|
29
|
-
}
|
|
30
|
-
function refreshWriteHighlightPrefix(cache) {
|
|
31
|
-
const prefixCount = Math.min(WRITE_PARTIAL_FULL_HIGHLIGHT_LINES, cache.normalizedLines.length);
|
|
32
|
-
if (prefixCount === 0)
|
|
33
|
-
return;
|
|
34
|
-
const prefixSource = cache.normalizedLines.slice(0, prefixCount).join("\n");
|
|
35
|
-
const prefixHighlighted = highlightCode(prefixSource, cache.lang);
|
|
36
|
-
for (let i = 0; i < prefixCount; i++) {
|
|
37
|
-
cache.highlightedLines[i] =
|
|
38
|
-
prefixHighlighted[i] ?? highlightSingleLine(cache.normalizedLines[i] ?? "", cache.lang);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
function rebuildWriteHighlightCacheFull(rawPath, fileContent) {
|
|
42
|
-
const lang = rawPath ? getLanguageFromPath(rawPath) : undefined;
|
|
43
|
-
if (!lang)
|
|
44
|
-
return undefined;
|
|
45
|
-
const displayContent = normalizeDisplayText(fileContent);
|
|
46
|
-
const normalized = replaceTabs(displayContent);
|
|
47
|
-
return {
|
|
48
|
-
rawPath,
|
|
49
|
-
lang,
|
|
50
|
-
rawContent: fileContent,
|
|
51
|
-
normalizedLines: normalized.split("\n"),
|
|
52
|
-
highlightedLines: highlightCode(normalized, lang),
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
function updateWriteHighlightCacheIncremental(cache, rawPath, fileContent) {
|
|
56
|
-
const lang = rawPath ? getLanguageFromPath(rawPath) : undefined;
|
|
57
|
-
if (!lang)
|
|
58
|
-
return undefined;
|
|
59
|
-
if (!cache)
|
|
60
|
-
return rebuildWriteHighlightCacheFull(rawPath, fileContent);
|
|
61
|
-
if (cache.lang !== lang || cache.rawPath !== rawPath)
|
|
62
|
-
return rebuildWriteHighlightCacheFull(rawPath, fileContent);
|
|
63
|
-
if (!fileContent.startsWith(cache.rawContent))
|
|
64
|
-
return rebuildWriteHighlightCacheFull(rawPath, fileContent);
|
|
65
|
-
if (fileContent.length === cache.rawContent.length)
|
|
66
|
-
return cache;
|
|
67
|
-
const deltaRaw = fileContent.slice(cache.rawContent.length);
|
|
68
|
-
const deltaDisplay = normalizeDisplayText(deltaRaw);
|
|
69
|
-
const deltaNormalized = replaceTabs(deltaDisplay);
|
|
70
|
-
cache.rawContent = fileContent;
|
|
71
|
-
if (cache.normalizedLines.length === 0) {
|
|
72
|
-
cache.normalizedLines.push("");
|
|
73
|
-
cache.highlightedLines.push("");
|
|
74
|
-
}
|
|
75
|
-
const segments = deltaNormalized.split("\n");
|
|
76
|
-
const lastIndex = cache.normalizedLines.length - 1;
|
|
77
|
-
cache.normalizedLines[lastIndex] += segments[0];
|
|
78
|
-
cache.highlightedLines[lastIndex] = highlightSingleLine(cache.normalizedLines[lastIndex], cache.lang);
|
|
79
|
-
for (let i = 1; i < segments.length; i++) {
|
|
80
|
-
cache.normalizedLines.push(segments[i]);
|
|
81
|
-
cache.highlightedLines.push(highlightSingleLine(segments[i], cache.lang));
|
|
82
|
-
}
|
|
83
|
-
refreshWriteHighlightPrefix(cache);
|
|
84
|
-
return cache;
|
|
85
|
-
}
|
|
86
18
|
function trimTrailingEmptyLines(lines) {
|
|
87
19
|
let end = lines.length;
|
|
88
20
|
while (end > 0 && lines[end - 1] === "") {
|
|
@@ -90,7 +22,7 @@ function trimTrailingEmptyLines(lines) {
|
|
|
90
22
|
}
|
|
91
23
|
return lines.slice(0, end);
|
|
92
24
|
}
|
|
93
|
-
function formatWriteCall(args, options, theme
|
|
25
|
+
function formatWriteCall(args, options, theme) {
|
|
94
26
|
const rawPath = str(args?.file_path ?? args?.path);
|
|
95
27
|
const fileContent = str(args?.content);
|
|
96
28
|
const path = rawPath !== null ? shortenPath(rawPath) : null;
|
|
@@ -102,7 +34,7 @@ function formatWriteCall(args, options, theme, cache) {
|
|
|
102
34
|
else if (fileContent) {
|
|
103
35
|
const lang = rawPath ? getLanguageFromPath(rawPath) : undefined;
|
|
104
36
|
const renderedLines = lang
|
|
105
|
-
?
|
|
37
|
+
? highlightCode(replaceTabs(normalizeDisplayText(fileContent)), lang)
|
|
106
38
|
: normalizeDisplayText(fileContent).split("\n");
|
|
107
39
|
const lines = trimTrailingEmptyLines(renderedLines);
|
|
108
40
|
const totalLines = lines.length;
|
|
@@ -178,33 +110,6 @@ export function createWriteToolDefinition(cwd, options) {
|
|
|
178
110
|
})();
|
|
179
111
|
}));
|
|
180
112
|
},
|
|
181
|
-
renderCall(args, theme, context) {
|
|
182
|
-
const renderArgs = args;
|
|
183
|
-
const rawPath = str(renderArgs?.file_path ?? renderArgs?.path);
|
|
184
|
-
const fileContent = str(renderArgs?.content);
|
|
185
|
-
const component = context.lastComponent ?? new WriteCallRenderComponent();
|
|
186
|
-
if (fileContent !== null) {
|
|
187
|
-
component.cache = context.argsComplete
|
|
188
|
-
? rebuildWriteHighlightCacheFull(rawPath, fileContent)
|
|
189
|
-
: updateWriteHighlightCacheIncremental(component.cache, rawPath, fileContent);
|
|
190
|
-
}
|
|
191
|
-
else {
|
|
192
|
-
component.cache = undefined;
|
|
193
|
-
}
|
|
194
|
-
component.setText(formatWriteCall(renderArgs, { expanded: context.expanded, isPartial: context.isPartial }, theme, component.cache));
|
|
195
|
-
return component;
|
|
196
|
-
},
|
|
197
|
-
renderResult(result, _options, theme, context) {
|
|
198
|
-
const output = formatWriteResult({ ...result, isError: context.isError }, theme);
|
|
199
|
-
if (!output) {
|
|
200
|
-
const component = context.lastComponent ?? new Container();
|
|
201
|
-
component.clear();
|
|
202
|
-
return component;
|
|
203
|
-
}
|
|
204
|
-
const text = context.lastComponent ?? new Text("", 0, 0);
|
|
205
|
-
text.setText(output);
|
|
206
|
-
return text;
|
|
207
|
-
},
|
|
208
113
|
};
|
|
209
114
|
}
|
|
210
115
|
export function createWriteTool(cwd, options) {
|
|
@@ -64,10 +64,10 @@ export function migrateAuthToAuthJson() {
|
|
|
64
64
|
return providers;
|
|
65
65
|
}
|
|
66
66
|
/**
|
|
67
|
-
* Migrate sessions from ~/.
|
|
67
|
+
* Migrate sessions from ~/.spectral/agent/*.jsonl to proper session directories.
|
|
68
68
|
*
|
|
69
|
-
* Bug in v0.30.0: Sessions were saved to ~/.
|
|
70
|
-
* ~/.
|
|
69
|
+
* Bug in v0.30.0: Sessions were saved to ~/.spectral/agent/ instead of
|
|
70
|
+
* ~/.spectral/agent/sessions/<encoded-cwd>/. This migration moves them
|
|
71
71
|
* to the correct location based on the cwd in their session header.
|
|
72
72
|
*
|
|
73
73
|
* See: https://github.com/earendil-works/pi-mono/issues/320
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Utilities for formatting keybinding hints in the UI.
|
|
3
3
|
*/
|
|
4
|
-
import { getKeybindings } from "
|
|
4
|
+
import { getKeybindings } from "../../../core/keybindings.js";
|
|
5
5
|
import { theme } from "../theme/theme.js";
|
|
6
6
|
function formatKeyPart(part, options) {
|
|
7
7
|
const displayPart = process.platform === "darwin" && part.toLowerCase() === "alt" ? "option" : part;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared utility for truncating text to visual lines.
|
|
3
|
+
* Simplified for headless mode — returns lines directly without Text component.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Truncate text to a maximum number of visual lines (from the end).
|
|
7
|
+
*
|
|
8
|
+
* @param text - The text content (may contain newlines)
|
|
9
|
+
* @param maxVisualLines - Maximum number of visual lines to show
|
|
10
|
+
* @param _width - Ignored in headless mode
|
|
11
|
+
* @param _paddingX - Ignored in headless mode
|
|
12
|
+
* @returns The truncated visual lines and count of skipped lines
|
|
13
|
+
*/
|
|
14
|
+
export function truncateToVisualLines(text, maxVisualLines, _width, _paddingX = 0) {
|
|
15
|
+
if (!text) {
|
|
16
|
+
return { visualLines: [], skippedCount: 0 };
|
|
17
|
+
}
|
|
18
|
+
const allVisualLines = text.split("\n");
|
|
19
|
+
if (allVisualLines.length <= maxVisualLines) {
|
|
20
|
+
return { visualLines: allVisualLines, skippedCount: 0 };
|
|
21
|
+
}
|
|
22
|
+
// Take the last N visual lines
|
|
23
|
+
const truncatedLines = allVisualLines.slice(-maxVisualLines);
|
|
24
|
+
const skippedCount = allVisualLines.length - maxVisualLines;
|
|
25
|
+
return { visualLines: truncatedLines, skippedCount };
|
|
26
|
+
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
|
-
import { getCapabilities, } from "../../../../tui/index.js";
|
|
4
3
|
import chalk from "chalk";
|
|
5
4
|
import { Type } from "typebox";
|
|
6
5
|
import { Compile } from "typebox/compile";
|
|
@@ -443,7 +442,7 @@ function loadThemeJson(name) {
|
|
|
443
442
|
return parseThemeJsonContent(name, content);
|
|
444
443
|
}
|
|
445
444
|
function createTheme(themeJson, mode, sourcePath) {
|
|
446
|
-
const colorMode = mode ??
|
|
445
|
+
const colorMode = mode ?? "256color";
|
|
447
446
|
const resolvedColors = resolveThemeColors(themeJson.colors, themeJson.vars);
|
|
448
447
|
const fgColors = {};
|
|
449
448
|
const bgColors = {};
|
|
@@ -10,7 +10,7 @@ const TOOLS_DIR = getBinDir();
|
|
|
10
10
|
const NETWORK_TIMEOUT_MS = 10_000;
|
|
11
11
|
const DOWNLOAD_TIMEOUT_MS = 120_000;
|
|
12
12
|
function isOfflineModeEnabled() {
|
|
13
|
-
const value = process.env.
|
|
13
|
+
const value = process.env.SPECTRAL_OFFLINE;
|
|
14
14
|
if (!value)
|
|
15
15
|
return false;
|
|
16
16
|
return value === "1" || value.toLowerCase() === "true" || value.toLowerCase() === "yes";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getPiUserAgent } from "./pi-user-agent.js";
|
|
2
|
-
const LATEST_VERSION_URL = "https://
|
|
2
|
+
const LATEST_VERSION_URL = "https://spectral.dev/api/latest-version";
|
|
3
3
|
const DEFAULT_VERSION_CHECK_TIMEOUT_MS = 10000;
|
|
4
4
|
function parsePackageVersion(version) {
|
|
5
5
|
const match = version.trim().match(/^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+.*)?$/);
|
|
@@ -41,7 +41,7 @@ export function isNewerPackageVersion(candidateVersion, currentVersion) {
|
|
|
41
41
|
return candidateVersion.trim() !== currentVersion.trim();
|
|
42
42
|
}
|
|
43
43
|
export async function getLatestPiRelease(currentVersion, options = {}) {
|
|
44
|
-
if (process.env.
|
|
44
|
+
if (process.env.SPECTRAL_SKIP_VERSION_CHECK || process.env.SPECTRAL_OFFLINE)
|
|
45
45
|
return undefined;
|
|
46
46
|
const response = await fetch(LATEST_VERSION_URL, {
|
|
47
47
|
headers: {
|
|
@@ -2,7 +2,7 @@ import { randomUUID } from "node:crypto";
|
|
|
2
2
|
import { copyFileSync, existsSync, mkdirSync, renameSync, rmSync } from "node:fs";
|
|
3
3
|
import { basename, dirname, join, relative, resolve, toNamespacedPath } from "node:path";
|
|
4
4
|
import { getCwdRelativePath } from "./paths.js";
|
|
5
|
-
const QUARANTINE_DIR_NAME = ".
|
|
5
|
+
const QUARANTINE_DIR_NAME = ".spectral-native-quarantine";
|
|
6
6
|
function normalizePath(path) {
|
|
7
7
|
return toNamespacedPath(resolve(path));
|
|
8
8
|
}
|