@oh-my-pi/pi-coding-agent 14.0.3 → 14.0.5

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 (43) hide show
  1. package/CHANGELOG.md +63 -1
  2. package/package.json +11 -8
  3. package/src/config/model-registry.ts +3 -2
  4. package/src/config/model-resolver.ts +33 -25
  5. package/src/config/settings.ts +9 -2
  6. package/src/dap/session.ts +31 -39
  7. package/src/debug/log-formatting.ts +2 -2
  8. package/src/edit/index.ts +2 -0
  9. package/src/edit/modes/chunk.ts +45 -16
  10. package/src/edit/modes/hashline.ts +2 -2
  11. package/src/ipy/executor.ts +3 -7
  12. package/src/ipy/kernel.ts +3 -3
  13. package/src/lsp/client.ts +4 -2
  14. package/src/lsp/index.ts +4 -9
  15. package/src/lsp/lspmux.ts +2 -2
  16. package/src/lsp/utils.ts +27 -143
  17. package/src/modes/components/diff.ts +1 -1
  18. package/src/modes/controllers/event-controller.ts +438 -426
  19. package/src/modes/theme/mermaid-cache.ts +5 -7
  20. package/src/modes/theme/theme.ts +2 -161
  21. package/src/priority.json +8 -0
  22. package/src/prompts/agents/designer.md +1 -2
  23. package/src/prompts/system/system-prompt.md +40 -2
  24. package/src/prompts/tools/chunk-edit.md +66 -38
  25. package/src/prompts/tools/read-chunk.md +10 -1
  26. package/src/sdk.ts +2 -1
  27. package/src/session/agent-session.ts +10 -0
  28. package/src/session/compaction/compaction.ts +1 -1
  29. package/src/tools/ast-edit.ts +2 -2
  30. package/src/tools/browser.ts +84 -21
  31. package/src/tools/fetch.ts +1 -1
  32. package/src/tools/find.ts +40 -94
  33. package/src/tools/gemini-image.ts +1 -0
  34. package/src/tools/index.ts +2 -3
  35. package/src/tools/read.ts +2 -0
  36. package/src/tools/render-utils.ts +1 -1
  37. package/src/tools/report-tool-issue.ts +2 -2
  38. package/src/utils/edit-mode.ts +2 -2
  39. package/src/utils/image-resize.ts +73 -37
  40. package/src/utils/lang-from-path.ts +239 -0
  41. package/src/utils/sixel.ts +2 -2
  42. package/src/web/scrapers/types.ts +50 -32
  43. package/src/web/search/providers/codex.ts +21 -2
package/src/lsp/client.ts CHANGED
@@ -638,15 +638,17 @@ export async function refreshFile(client: LspClient, filePath: string, signal?:
638
638
  const uri = fileToUri(filePath);
639
639
  const lockKey = `${client.name}:${uri}`;
640
640
 
641
- // Check if another operation is in progress
642
641
  const existingLock = fileOperationLocks.get(lockKey);
643
642
  if (existingLock) {
644
643
  await untilAborted(signal, () => existingLock);
645
644
  }
646
645
 
647
- // Lock and refresh file
648
646
  const refreshPromise = (async () => {
649
647
  throwIfAborted(signal);
648
+ // Drop cached diagnostics for this URI before asking the server to recompute.
649
+ // Otherwise an unrelated publishDiagnostics notification can advance the global
650
+ // diagnostics version and cause waiters to accept stale unversioned diagnostics.
651
+ client.diagnostics.delete(uri);
650
652
  const info = client.openFiles.get(uri);
651
653
 
652
654
  if (!info) {
package/src/lsp/index.ts CHANGED
@@ -47,7 +47,6 @@ import {
47
47
  } from "./types";
48
48
  import {
49
49
  applyCodeAction,
50
- collectGlobMatches,
51
50
  dedupeWorkspaceSymbols,
52
51
  extractHoverText,
53
52
  fileToUri,
@@ -60,8 +59,8 @@ import {
60
59
  formatLocation,
61
60
  formatSymbolInformation,
62
61
  formatWorkspaceEdit,
63
- hasGlobPattern,
64
62
  readLocationContext,
63
+ resolveDiagnosticTargets,
65
64
  resolveSymbolColumn,
66
65
  sortDiagnostics,
67
66
  symbolKindToIcon,
@@ -1172,13 +1171,9 @@ export class LspTool implements AgentTool<typeof lspSchema, LspToolDetails, Them
1172
1171
 
1173
1172
  let targets: string[];
1174
1173
  let truncatedGlobTargets = false;
1175
- if (hasGlobPattern(file)) {
1176
- const globMatches = await collectGlobMatches(file, this.session.cwd, MAX_GLOB_DIAGNOSTIC_TARGETS);
1177
- targets = globMatches.matches;
1178
- truncatedGlobTargets = globMatches.truncated;
1179
- } else {
1180
- targets = [file];
1181
- }
1174
+ const resolvedTargets = await resolveDiagnosticTargets(file, this.session.cwd, MAX_GLOB_DIAGNOSTIC_TARGETS);
1175
+ targets = resolvedTargets.matches;
1176
+ truncatedGlobTargets = resolvedTargets.truncated;
1182
1177
 
1183
1178
  if (targets.length === 0) {
1184
1179
  return {
package/src/lsp/lspmux.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as os from "node:os";
2
2
  import * as path from "node:path";
3
- import { $env, $which, logger } from "@oh-my-pi/pi-utils";
3
+ import { $flag, $which, logger } from "@oh-my-pi/pi-utils";
4
4
  import { TOML } from "bun";
5
5
 
6
6
  /**
@@ -135,7 +135,7 @@ export async function detectLspmux(): Promise<LspmuxState> {
135
135
  return cachedState;
136
136
  }
137
137
 
138
- if ($env.PI_DISABLE_LSPMUX === "1") {
138
+ if ($flag("PI_DISABLE_LSPMUX")) {
139
139
  cachedState = { available: false, running: false, binaryPath: null, config: null };
140
140
  cacheTimestamp = now;
141
141
  return cachedState;
package/src/lsp/utils.ts CHANGED
@@ -1,8 +1,10 @@
1
1
  export { truncate } from "@oh-my-pi/pi-utils";
2
2
 
3
+ import * as fs from "node:fs/promises";
3
4
  import path from "node:path";
4
5
  import { isEnoent } from "@oh-my-pi/pi-utils";
5
6
  import { type Theme, theme } from "../modes/theme/theme";
7
+ import { resolveToCwd } from "../tools/path-utils";
6
8
  import type {
7
9
  CodeAction,
8
10
  Command,
@@ -16,149 +18,7 @@ import type {
16
18
  WorkspaceEdit,
17
19
  } from "./types";
18
20
 
19
- // =============================================================================
20
- // Language Detection
21
- // =============================================================================
22
-
23
- const LANGUAGE_MAP: Record<string, string> = {
24
- // TypeScript/JavaScript
25
- ".ts": "typescript",
26
- ".tsx": "typescriptreact",
27
- ".js": "javascript",
28
- ".jsx": "javascriptreact",
29
- ".mjs": "javascript",
30
- ".cjs": "javascript",
31
- ".mts": "typescript",
32
- ".cts": "typescript",
33
-
34
- // Systems languages
35
- ".rs": "rust",
36
- ".go": "go",
37
- ".c": "c",
38
- ".h": "c",
39
- ".cpp": "cpp",
40
- ".cc": "cpp",
41
- ".cxx": "cpp",
42
- ".hpp": "cpp",
43
- ".hxx": "cpp",
44
- ".zig": "zig",
45
-
46
- // Scripting languages
47
- ".py": "python",
48
- ".rb": "ruby",
49
- ".lua": "lua",
50
- ".sh": "shellscript",
51
- ".bash": "shellscript",
52
- ".zsh": "shellscript",
53
- ".fish": "fish",
54
- ".pl": "perl",
55
- ".pm": "perl",
56
- ".php": "php",
57
-
58
- // JVM languages
59
- ".java": "java",
60
- ".kt": "kotlin",
61
- ".kts": "kotlin",
62
- ".scala": "scala",
63
- ".groovy": "groovy",
64
- ".clj": "clojure",
65
-
66
- // .NET languages
67
- ".cs": "csharp",
68
- ".fs": "fsharp",
69
- ".vb": "vb",
70
-
71
- // Web
72
- ".html": "html",
73
- ".htm": "html",
74
- ".css": "css",
75
- ".scss": "scss",
76
- ".sass": "sass",
77
- ".less": "less",
78
- ".vue": "vue",
79
- ".svelte": "svelte",
80
- ".astro": "astro",
81
-
82
- // Data formats
83
- ".json": "json",
84
- ".jsonc": "jsonc",
85
- ".yaml": "yaml",
86
- ".yml": "yaml",
87
- ".toml": "toml",
88
- ".xml": "xml",
89
- ".ini": "ini",
90
-
91
- // Documentation
92
- ".md": "markdown",
93
- ".markdown": "markdown",
94
- ".rst": "restructuredtext",
95
- ".adoc": "asciidoc",
96
- ".tex": "latex",
97
-
98
- // Other
99
- ".sql": "sql",
100
- ".graphql": "graphql",
101
- ".gql": "graphql",
102
- ".proto": "protobuf",
103
- ".dockerfile": "dockerfile",
104
- ".tf": "terraform",
105
- ".hcl": "hcl",
106
- ".nix": "nix",
107
- ".ex": "elixir",
108
- ".exs": "elixir",
109
- ".erl": "erlang",
110
- ".hrl": "erlang",
111
- ".hs": "haskell",
112
- ".ml": "ocaml",
113
- ".mli": "ocaml",
114
- ".swift": "swift",
115
- ".r": "r",
116
- ".R": "r",
117
- ".jl": "julia",
118
- ".dart": "dart",
119
- ".elm": "elm",
120
- ".v": "v",
121
- ".nim": "nim",
122
- ".cr": "crystal",
123
- ".d": "d",
124
- ".pas": "pascal",
125
- ".pp": "pascal",
126
- ".lisp": "lisp",
127
- ".lsp": "lisp",
128
- ".rkt": "racket",
129
- ".scm": "scheme",
130
- ".ps1": "powershell",
131
- ".psm1": "powershell",
132
- ".bat": "bat",
133
- ".cmd": "bat",
134
- ".tla": "tlaplus",
135
- ".tlaplus": "tlaplus",
136
- };
137
-
138
- /**
139
- * Detect language ID from file path.
140
- * Returns the LSP language identifier for the file type.
141
- */
142
- export function detectLanguageId(filePath: string): string {
143
- const ext = path.extname(filePath).toLowerCase();
144
- const basename = path.basename(filePath).toLowerCase();
145
-
146
- // Handle special filenames
147
- if (basename === "dockerfile" || basename.startsWith("dockerfile.") || basename === "containerfile") {
148
- return "dockerfile";
149
- }
150
- if (basename === "makefile" || basename === "gnumakefile") {
151
- return "makefile";
152
- }
153
- if (basename === "justfile") {
154
- return "just";
155
- }
156
- if (basename === "cmakelists.txt" || ext === ".cmake") {
157
- return "cmake";
158
- }
159
-
160
- return LANGUAGE_MAP[ext] ?? "plaintext";
161
- }
21
+ export { detectLanguageId } from "../utils/lang-from-path";
162
22
 
163
23
  // =============================================================================
164
24
  // URI Handling (Cross-Platform)
@@ -692,6 +552,30 @@ export async function collectGlobMatches(
692
552
  }
693
553
  return { matches, truncated: false };
694
554
  }
555
+
556
+ export async function resolveDiagnosticTargets(
557
+ file: string,
558
+ cwd: string,
559
+ maxMatches: number,
560
+ ): Promise<{ matches: string[]; truncated: boolean }> {
561
+ if (!hasGlobPattern(file)) {
562
+ return { matches: [file], truncated: false };
563
+ }
564
+
565
+ const resolved = resolveToCwd(file, cwd);
566
+ try {
567
+ const stat = await fs.stat(resolved);
568
+ if (stat.isFile()) {
569
+ return { matches: [file], truncated: false };
570
+ }
571
+ } catch (error) {
572
+ if (!isEnoent(error)) {
573
+ throw error;
574
+ }
575
+ }
576
+
577
+ return collectGlobMatches(file, cwd, maxMatches);
578
+ }
695
579
  // =============================================================================
696
580
  // Hover Content Extraction
697
581
  // =============================================================================
@@ -1,4 +1,4 @@
1
- import { getIndentation } from "@oh-my-pi/pi-natives";
1
+ import { getIndentation } from "@oh-my-pi/pi-utils";
2
2
  import * as Diff from "diff";
3
3
  import { theme } from "../../modes/theme/theme";
4
4
  import { replaceTabs } from "../../tools/render-utils";