@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.
Files changed (221) hide show
  1. package/dist/agent/agents.js +4 -4
  2. package/dist/agent/index.js +24 -148
  3. package/dist/cli.js +25 -220
  4. package/dist/commands/serve.js +1 -1
  5. package/dist/extensions/spectral-vision-fallback.js +225 -0
  6. package/dist/mcp/agent-dir.js +1 -1
  7. package/dist/mcp/config.js +3 -3
  8. package/dist/mcp/sampling-handler.js +1 -1
  9. package/dist/mcp/server-manager.js +5 -1
  10. package/dist/memory/commands/status.js +6 -6
  11. package/dist/memory/commands/view.js +16 -14
  12. package/dist/memory/compaction.js +33 -5
  13. package/dist/memory/config.js +3 -3
  14. package/dist/memory/debug-log.js +1 -1
  15. package/dist/memory/observer.js +2 -2
  16. package/dist/memory/prompts.js +5 -5
  17. package/dist/memory/tokens.js +1 -1
  18. package/dist/memory/tools/read-project-observations.js +2 -2
  19. package/dist/memory/tools/recall-observation.js +4 -4
  20. package/dist/relay/auto-research.js +23 -23
  21. package/dist/relay/dispatcher.js +28 -2
  22. package/dist/relay/models-fetch.js +15 -3
  23. package/dist/{pi → sdk}/coding-agent/cli/args.js +4 -4
  24. package/dist/{pi → sdk}/coding-agent/config.js +9 -20
  25. package/dist/{pi → sdk}/coding-agent/core/agent-session.js +5 -17
  26. package/dist/{pi → sdk}/coding-agent/core/compaction/compaction.js +161 -5
  27. package/dist/{pi → sdk}/coding-agent/core/extensions/loader.js +0 -6
  28. package/dist/{pi → sdk}/coding-agent/core/extensions/runner.js +7 -1
  29. package/dist/{pi → sdk}/coding-agent/core/keybindings.js +129 -2
  30. package/dist/{pi → sdk}/coding-agent/core/model-registry.js +11 -4
  31. package/dist/{pi → sdk}/coding-agent/core/package-manager.js +5 -5
  32. package/dist/{pi → sdk}/coding-agent/core/sdk.js +1 -1
  33. package/dist/{pi → sdk}/coding-agent/core/session-manager.js +4 -4
  34. package/dist/{pi → sdk}/coding-agent/core/settings-manager.js +20 -0
  35. package/dist/{pi → sdk}/coding-agent/core/telemetry.js +1 -1
  36. package/dist/{pi → sdk}/coding-agent/core/tools/bash.js +17 -63
  37. package/dist/{pi → sdk}/coding-agent/core/tools/edit.js +4 -141
  38. package/dist/{pi → sdk}/coding-agent/core/tools/find.js +0 -11
  39. package/dist/{pi → sdk}/coding-agent/core/tools/grep.js +0 -11
  40. package/dist/{pi → sdk}/coding-agent/core/tools/ls.js +0 -11
  41. package/dist/{pi → sdk}/coding-agent/core/tools/read.js +0 -12
  42. package/dist/{pi → sdk}/coding-agent/core/tools/render-utils.js +1 -14
  43. package/dist/{pi → sdk}/coding-agent/core/tools/write.js +2 -97
  44. package/dist/{pi → sdk}/coding-agent/migrations.js +3 -3
  45. package/dist/{pi → sdk}/coding-agent/modes/interactive/components/keybinding-hints.js +1 -1
  46. package/dist/sdk/coding-agent/modes/interactive/components/visual-truncate.js +26 -0
  47. package/dist/{pi → sdk}/coding-agent/modes/interactive/theme/theme.js +1 -2
  48. package/dist/{pi → sdk}/coding-agent/utils/tools-manager.js +1 -1
  49. package/dist/{pi → sdk}/coding-agent/utils/version-check.js +2 -2
  50. package/dist/{pi → sdk}/coding-agent/utils/windows-self-update.js +1 -1
  51. package/dist/server/{pi-bridge.js → agent-bridge.js} +158 -89
  52. package/dist/server/handlers/sessions.js +21 -0
  53. package/dist/server/session-stream.js +12 -6
  54. package/package.json +6 -3
  55. package/dist/pi/coding-agent/core/export-html/ansi-to-html.js +0 -248
  56. package/dist/pi/coding-agent/core/export-html/index.js +0 -225
  57. package/dist/pi/coding-agent/core/export-html/tool-renderer.js +0 -107
  58. package/dist/pi/coding-agent/modes/interactive/components/visual-truncate.js +0 -32
  59. package/dist/pi/tui/autocomplete.js +0 -631
  60. package/dist/pi/tui/components/box.js +0 -103
  61. package/dist/pi/tui/components/cancellable-loader.js +0 -34
  62. package/dist/pi/tui/components/editor.js +0 -1915
  63. package/dist/pi/tui/components/image.js +0 -88
  64. package/dist/pi/tui/components/input.js +0 -425
  65. package/dist/pi/tui/components/loader.js +0 -68
  66. package/dist/pi/tui/components/markdown.js +0 -633
  67. package/dist/pi/tui/components/select-list.js +0 -158
  68. package/dist/pi/tui/components/settings-list.js +0 -184
  69. package/dist/pi/tui/components/spacer.js +0 -22
  70. package/dist/pi/tui/components/text.js +0 -88
  71. package/dist/pi/tui/components/truncated-text.js +0 -50
  72. package/dist/pi/tui/editor-component.js +0 -1
  73. package/dist/pi/tui/fuzzy.js +0 -109
  74. package/dist/pi/tui/index.js +0 -31
  75. package/dist/pi/tui/keybindings.js +0 -173
  76. package/dist/pi/tui/keys.js +0 -1172
  77. package/dist/pi/tui/kill-ring.js +0 -43
  78. package/dist/pi/tui/stdin-buffer.js +0 -360
  79. package/dist/pi/tui/terminal-image.js +0 -335
  80. package/dist/pi/tui/terminal.js +0 -324
  81. package/dist/pi/tui/tui.js +0 -1076
  82. package/dist/pi/tui/undo-stack.js +0 -24
  83. package/dist/pi/tui/utils.js +0 -1016
  84. /package/dist/{pi → sdk}/agent-core/agent-loop.js +0 -0
  85. /package/dist/{pi → sdk}/agent-core/agent.js +0 -0
  86. /package/dist/{pi → sdk}/agent-core/harness/agent-harness.js +0 -0
  87. /package/dist/{pi → sdk}/agent-core/harness/compaction/branch-summarization.js +0 -0
  88. /package/dist/{pi → sdk}/agent-core/harness/compaction/compaction.js +0 -0
  89. /package/dist/{pi → sdk}/agent-core/harness/compaction/utils.js +0 -0
  90. /package/dist/{pi → sdk}/agent-core/harness/env/nodejs.js +0 -0
  91. /package/dist/{pi → sdk}/agent-core/harness/messages.js +0 -0
  92. /package/dist/{pi → sdk}/agent-core/harness/prompt-templates.js +0 -0
  93. /package/dist/{pi → sdk}/agent-core/harness/session/jsonl-repo.js +0 -0
  94. /package/dist/{pi → sdk}/agent-core/harness/session/jsonl-storage.js +0 -0
  95. /package/dist/{pi → sdk}/agent-core/harness/session/memory-repo.js +0 -0
  96. /package/dist/{pi → sdk}/agent-core/harness/session/memory-storage.js +0 -0
  97. /package/dist/{pi → sdk}/agent-core/harness/session/repo-utils.js +0 -0
  98. /package/dist/{pi → sdk}/agent-core/harness/session/session.js +0 -0
  99. /package/dist/{pi → sdk}/agent-core/harness/session/uuid.js +0 -0
  100. /package/dist/{pi → sdk}/agent-core/harness/skills.js +0 -0
  101. /package/dist/{pi → sdk}/agent-core/harness/system-prompt.js +0 -0
  102. /package/dist/{pi → sdk}/agent-core/harness/types.js +0 -0
  103. /package/dist/{pi → sdk}/agent-core/harness/utils/shell-output.js +0 -0
  104. /package/dist/{pi → sdk}/agent-core/harness/utils/truncate.js +0 -0
  105. /package/dist/{pi → sdk}/agent-core/index.js +0 -0
  106. /package/dist/{pi → sdk}/agent-core/node.js +0 -0
  107. /package/dist/{pi → sdk}/agent-core/proxy.js +0 -0
  108. /package/dist/{pi → sdk}/agent-core/types.js +0 -0
  109. /package/dist/{pi → sdk}/ai/api-registry.js +0 -0
  110. /package/dist/{pi → sdk}/ai/cli.js +0 -0
  111. /package/dist/{pi → sdk}/ai/env-api-keys.js +0 -0
  112. /package/dist/{pi → sdk}/ai/image-models.generated.js +0 -0
  113. /package/dist/{pi → sdk}/ai/image-models.js +0 -0
  114. /package/dist/{pi → sdk}/ai/images-api-registry.js +0 -0
  115. /package/dist/{pi → sdk}/ai/images.js +0 -0
  116. /package/dist/{pi → sdk}/ai/index.js +0 -0
  117. /package/dist/{pi → sdk}/ai/models.generated.js +0 -0
  118. /package/dist/{pi → sdk}/ai/models.js +0 -0
  119. /package/dist/{pi → sdk}/ai/oauth.js +0 -0
  120. /package/dist/{pi → sdk}/ai/providers/anthropic.js +0 -0
  121. /package/dist/{pi → sdk}/ai/providers/faux.js +0 -0
  122. /package/dist/{pi → sdk}/ai/providers/github-copilot-headers.js +0 -0
  123. /package/dist/{pi → sdk}/ai/providers/openai-completions.js +0 -0
  124. /package/dist/{pi → sdk}/ai/providers/openai-prompt-cache.js +0 -0
  125. /package/dist/{pi → sdk}/ai/providers/register-builtins.js +0 -0
  126. /package/dist/{pi → sdk}/ai/providers/simple-options.js +0 -0
  127. /package/dist/{pi → sdk}/ai/providers/transform-messages.js +0 -0
  128. /package/dist/{pi → sdk}/ai/session-resources.js +0 -0
  129. /package/dist/{pi → sdk}/ai/stream.js +0 -0
  130. /package/dist/{pi → sdk}/ai/types.js +0 -0
  131. /package/dist/{pi → sdk}/ai/utils/diagnostics.js +0 -0
  132. /package/dist/{pi → sdk}/ai/utils/event-stream.js +0 -0
  133. /package/dist/{pi → sdk}/ai/utils/hash.js +0 -0
  134. /package/dist/{pi → sdk}/ai/utils/headers.js +0 -0
  135. /package/dist/{pi → sdk}/ai/utils/json-parse.js +0 -0
  136. /package/dist/{pi → sdk}/ai/utils/node-http-proxy.js +0 -0
  137. /package/dist/{pi → sdk}/ai/utils/oauth/anthropic.js +0 -0
  138. /package/dist/{pi → sdk}/ai/utils/oauth/device-code.js +0 -0
  139. /package/dist/{pi → sdk}/ai/utils/oauth/github-copilot.js +0 -0
  140. /package/dist/{pi → sdk}/ai/utils/oauth/index.js +0 -0
  141. /package/dist/{pi → sdk}/ai/utils/oauth/oauth-page.js +0 -0
  142. /package/dist/{pi → sdk}/ai/utils/oauth/openai-codex.js +0 -0
  143. /package/dist/{pi → sdk}/ai/utils/oauth/pkce.js +0 -0
  144. /package/dist/{pi → sdk}/ai/utils/oauth/types.js +0 -0
  145. /package/dist/{pi → sdk}/ai/utils/overflow.js +0 -0
  146. /package/dist/{pi → sdk}/ai/utils/sanitize-unicode.js +0 -0
  147. /package/dist/{pi → sdk}/ai/utils/typebox-helpers.js +0 -0
  148. /package/dist/{pi → sdk}/ai/utils/validation.js +0 -0
  149. /package/dist/{pi → sdk}/coding-agent/bun/cli.js +0 -0
  150. /package/dist/{pi → sdk}/coding-agent/bun/restore-sandbox-env.js +0 -0
  151. /package/dist/{pi → sdk}/coding-agent/cli/file-processor.js +0 -0
  152. /package/dist/{pi → sdk}/coding-agent/cli/initial-message.js +0 -0
  153. /package/dist/{pi → sdk}/coding-agent/cli.js +0 -0
  154. /package/dist/{pi → sdk}/coding-agent/core/agent-session-runtime.js +0 -0
  155. /package/dist/{pi → sdk}/coding-agent/core/agent-session-services.js +0 -0
  156. /package/dist/{pi → sdk}/coding-agent/core/auth-guidance.js +0 -0
  157. /package/dist/{pi → sdk}/coding-agent/core/auth-storage.js +0 -0
  158. /package/dist/{pi → sdk}/coding-agent/core/bash-executor.js +0 -0
  159. /package/dist/{pi → sdk}/coding-agent/core/compaction/branch-summarization.js +0 -0
  160. /package/dist/{pi → sdk}/coding-agent/core/compaction/index.js +0 -0
  161. /package/dist/{pi → sdk}/coding-agent/core/compaction/utils.js +0 -0
  162. /package/dist/{pi → sdk}/coding-agent/core/defaults.js +0 -0
  163. /package/dist/{pi → sdk}/coding-agent/core/diagnostics.js +0 -0
  164. /package/dist/{pi → sdk}/coding-agent/core/event-bus.js +0 -0
  165. /package/dist/{pi → sdk}/coding-agent/core/exec.js +0 -0
  166. /package/dist/{pi → sdk}/coding-agent/core/extensions/index.js +0 -0
  167. /package/dist/{pi → sdk}/coding-agent/core/extensions/types.js +0 -0
  168. /package/dist/{pi → sdk}/coding-agent/core/extensions/wrapper.js +0 -0
  169. /package/dist/{pi → sdk}/coding-agent/core/footer-data-provider.js +0 -0
  170. /package/dist/{pi → sdk}/coding-agent/core/http-dispatcher.js +0 -0
  171. /package/dist/{pi → sdk}/coding-agent/core/index.js +0 -0
  172. /package/dist/{pi → sdk}/coding-agent/core/messages.js +0 -0
  173. /package/dist/{pi → sdk}/coding-agent/core/model-resolver.js +0 -0
  174. /package/dist/{pi → sdk}/coding-agent/core/output-guard.js +0 -0
  175. /package/dist/{pi → sdk}/coding-agent/core/prompt-templates.js +0 -0
  176. /package/dist/{pi → sdk}/coding-agent/core/provider-display-names.js +0 -0
  177. /package/dist/{pi → sdk}/coding-agent/core/resolve-config-value.js +0 -0
  178. /package/dist/{pi → sdk}/coding-agent/core/resource-loader.js +0 -0
  179. /package/dist/{pi → sdk}/coding-agent/core/session-cwd.js +0 -0
  180. /package/dist/{pi → sdk}/coding-agent/core/skills.js +0 -0
  181. /package/dist/{pi → sdk}/coding-agent/core/slash-commands.js +0 -0
  182. /package/dist/{pi → sdk}/coding-agent/core/source-info.js +0 -0
  183. /package/dist/{pi → sdk}/coding-agent/core/system-prompt.js +0 -0
  184. /package/dist/{pi → sdk}/coding-agent/core/timings.js +0 -0
  185. /package/dist/{pi → sdk}/coding-agent/core/tools/edit-diff.js +0 -0
  186. /package/dist/{pi → sdk}/coding-agent/core/tools/file-mutation-queue.js +0 -0
  187. /package/dist/{pi → sdk}/coding-agent/core/tools/index.js +0 -0
  188. /package/dist/{pi → sdk}/coding-agent/core/tools/output-accumulator.js +0 -0
  189. /package/dist/{pi → sdk}/coding-agent/core/tools/path-utils.js +0 -0
  190. /package/dist/{pi → sdk}/coding-agent/core/tools/tool-definition-wrapper.js +0 -0
  191. /package/dist/{pi → sdk}/coding-agent/core/tools/truncate.js +0 -0
  192. /package/dist/{pi → sdk}/coding-agent/index.js +0 -0
  193. /package/dist/{pi → sdk}/coding-agent/main.js +0 -0
  194. /package/dist/{pi → sdk}/coding-agent/modes/index.js +0 -0
  195. /package/dist/{pi → sdk}/coding-agent/modes/interactive/components/diff.js +0 -0
  196. /package/dist/{pi → sdk}/coding-agent/modes/interactive/interactive-mode.js +0 -0
  197. /package/dist/{pi → sdk}/coding-agent/modes/print-mode.js +0 -0
  198. /package/dist/{pi → sdk}/coding-agent/modes/rpc/jsonl.js +0 -0
  199. /package/dist/{pi → sdk}/coding-agent/modes/rpc/rpc-client.js +0 -0
  200. /package/dist/{pi → sdk}/coding-agent/modes/rpc/rpc-mode.js +0 -0
  201. /package/dist/{pi → sdk}/coding-agent/modes/rpc/rpc-types.js +0 -0
  202. /package/dist/{pi → sdk}/coding-agent/utils/ansi.js +0 -0
  203. /package/dist/{pi → sdk}/coding-agent/utils/changelog.js +0 -0
  204. /package/dist/{pi → sdk}/coding-agent/utils/child-process.js +0 -0
  205. /package/dist/{pi → sdk}/coding-agent/utils/clipboard-image.js +0 -0
  206. /package/dist/{pi → sdk}/coding-agent/utils/clipboard-native.js +0 -0
  207. /package/dist/{pi → sdk}/coding-agent/utils/clipboard.js +0 -0
  208. /package/dist/{pi → sdk}/coding-agent/utils/exif-orientation.js +0 -0
  209. /package/dist/{pi → sdk}/coding-agent/utils/frontmatter.js +0 -0
  210. /package/dist/{pi → sdk}/coding-agent/utils/fs-watch.js +0 -0
  211. /package/dist/{pi → sdk}/coding-agent/utils/git.js +0 -0
  212. /package/dist/{pi → sdk}/coding-agent/utils/html.js +0 -0
  213. /package/dist/{pi → sdk}/coding-agent/utils/image-convert.js +0 -0
  214. /package/dist/{pi → sdk}/coding-agent/utils/image-resize.js +0 -0
  215. /package/dist/{pi → sdk}/coding-agent/utils/mime.js +0 -0
  216. /package/dist/{pi → sdk}/coding-agent/utils/paths.js +0 -0
  217. /package/dist/{pi → sdk}/coding-agent/utils/photon.js +0 -0
  218. /package/dist/{pi → sdk}/coding-agent/utils/pi-user-agent.js +0 -0
  219. /package/dist/{pi → sdk}/coding-agent/utils/shell.js +0 -0
  220. /package/dist/{pi → sdk}/coding-agent/utils/sleep.js +0 -0
  221. /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, showImages) {
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, cache) {
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
- ? (cache?.highlightedLines ?? highlightCode(replaceTabs(normalizeDisplayText(fileContent)), lang))
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 ~/.pi/agent/*.jsonl to proper session directories.
67
+ * Migrate sessions from ~/.spectral/agent/*.jsonl to proper session directories.
68
68
  *
69
- * Bug in v0.30.0: Sessions were saved to ~/.pi/agent/ instead of
70
- * ~/.pi/agent/sessions/<encoded-cwd>/. This migration moves them
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 "../../../../tui/index.js";
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 ?? (getCapabilities().trueColor ? "truecolor" : "256color");
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.PI_OFFLINE;
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://pi.dev/api/latest-version";
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.PI_SKIP_VERSION_CHECK || process.env.PI_OFFLINE)
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 = ".pi-native-quarantine";
5
+ const QUARANTINE_DIR_NAME = ".spectral-native-quarantine";
6
6
  function normalizePath(path) {
7
7
  return toNamespacedPath(resolve(path));
8
8
  }