@oh-my-pi/pi-coding-agent 17.2.11 → 17.2.12

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 (152) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/{CHANGELOG-d9xenpn9.md → CHANGELOG-k9ghy5sn.md} +13 -0
  3. package/dist/cli.js +10795 -10791
  4. package/dist/types/advisor/runtime.d.ts +1 -1
  5. package/dist/types/config/custom-models.d.ts +31 -0
  6. package/dist/types/config/model-config-values.d.ts +19 -0
  7. package/dist/types/config/model-patch.d.ts +93 -0
  8. package/dist/types/config/model-provider-discovery.d.ts +51 -0
  9. package/dist/types/config/model-registry.d.ts +5 -52
  10. package/dist/types/config/settings.d.ts +5 -3
  11. package/dist/types/debug/raw-sse-buffer.d.ts +9 -0
  12. package/dist/types/discovery/agent-plugin-format.d.ts +6 -13
  13. package/dist/types/discovery/contained-path.d.ts +2 -3
  14. package/dist/types/eval/executor-base.d.ts +8 -2
  15. package/dist/types/eval/kernel-session-registry.d.ts +60 -0
  16. package/dist/types/export/share.d.ts +1 -1
  17. package/dist/types/lsp/diagnostics.d.ts +96 -0
  18. package/dist/types/lsp/index.d.ts +7 -128
  19. package/dist/types/lsp/servers.d.ts +72 -0
  20. package/dist/types/lsp/tool.d.ts +42 -0
  21. package/dist/types/lsp/workspace-diagnostics.d.ts +12 -0
  22. package/dist/types/lsp/writethrough.d.ts +33 -0
  23. package/dist/types/mcp/transports/header-policy.d.ts +2 -1
  24. package/dist/types/modes/components/agent-hub-projection.d.ts +2 -7
  25. package/dist/types/modes/components/agent-hub-renderer.d.ts +0 -7
  26. package/dist/types/modes/theme/color.d.ts +19 -0
  27. package/dist/types/modes/theme/loader.d.ts +19 -0
  28. package/dist/types/modes/theme/schema.d.ts +175 -0
  29. package/dist/types/modes/theme/symbols.d.ts +28 -0
  30. package/dist/types/modes/theme/theme-class.d.ts +244 -0
  31. package/dist/types/modes/theme/theme.d.ts +9 -280
  32. package/dist/types/modes/theme/tui-adapters.d.ts +13 -0
  33. package/dist/types/registry/agent-registry.d.ts +1 -3
  34. package/dist/types/secrets/index.d.ts +3 -1
  35. package/dist/types/secrets/message-transform.d.ts +40 -0
  36. package/dist/types/secrets/obfuscator.d.ts +0 -108
  37. package/dist/types/secrets/placeholder-scan.d.ts +95 -0
  38. package/dist/types/secrets/placeholder.d.ts +94 -0
  39. package/dist/types/secrets/replacement.d.ts +82 -0
  40. package/dist/types/session/agent-session-types.d.ts +6 -0
  41. package/dist/types/session/agent-session.d.ts +1 -1
  42. package/dist/types/session/session-handoff.d.ts +3 -3
  43. package/dist/types/session/session-manager.d.ts +32 -0
  44. package/dist/types/session/session-provider-boundary.d.ts +1 -1
  45. package/dist/types/session/turn-recovery.d.ts +2 -2
  46. package/dist/types/slash-commands/builtin-collaboration.d.ts +2 -0
  47. package/dist/types/slash-commands/builtin-completions.d.ts +36 -0
  48. package/dist/types/slash-commands/builtin-control.d.ts +2 -0
  49. package/dist/types/slash-commands/builtin-lifecycle.d.ts +3 -0
  50. package/dist/types/slash-commands/builtin-marketplace.d.ts +11 -0
  51. package/dist/types/slash-commands/builtin-modes.d.ts +5 -0
  52. package/dist/types/slash-commands/builtin-registry.d.ts +1 -1
  53. package/dist/types/slash-commands/builtin-session.d.ts +2 -0
  54. package/dist/types/tools/gh-common.d.ts +69 -0
  55. package/dist/types/tools/gh-pr-checkout.d.ts +84 -0
  56. package/dist/types/tools/gh-pr-diff.d.ts +102 -0
  57. package/dist/types/tools/gh-run-watch.d.ts +78 -0
  58. package/dist/types/tools/gh-search.d.ts +61 -0
  59. package/dist/types/tools/gh-types.d.ts +340 -0
  60. package/dist/types/tools/gh-view.d.ts +88 -0
  61. package/dist/types/tools/gh.d.ts +4 -201
  62. package/dist/types/tools/read-archive.d.ts +16 -0
  63. package/dist/types/tools/read-format.d.ts +104 -0
  64. package/dist/types/tools/read-path-resolution.d.ts +19 -0
  65. package/dist/types/tools/read-pdf-images.d.ts +12 -0
  66. package/dist/types/tools/read-renderer.d.ts +24 -0
  67. package/dist/types/tools/read-selector.d.ts +27 -0
  68. package/dist/types/tools/read-sqlite.d.ts +16 -0
  69. package/dist/types/tools/read-summary.d.ts +19 -0
  70. package/dist/types/tools/read.d.ts +1 -23
  71. package/dist/types/tools/shell-tokenize.d.ts +2 -1
  72. package/dist/types/utils/changelog.d.ts +0 -5
  73. package/package.json +13 -13
  74. package/src/advisor/runtime.ts +12 -7
  75. package/src/config/custom-models.ts +188 -0
  76. package/src/config/model-config-values.ts +128 -0
  77. package/src/config/model-patch.ts +252 -0
  78. package/src/config/model-provider-discovery.ts +132 -0
  79. package/src/config/model-registry.ts +64 -704
  80. package/src/config/settings.ts +7 -3
  81. package/src/debug/raw-sse-buffer.ts +20 -0
  82. package/src/discovery/agent-plugin-format.ts +7 -7
  83. package/src/discovery/contained-path.ts +2 -5
  84. package/src/edit/hashline/diff.ts +5 -1
  85. package/src/eval/executor-base.ts +39 -6
  86. package/src/eval/jl/executor.ts +82 -371
  87. package/src/eval/kernel-session-registry.ts +398 -0
  88. package/src/eval/py/executor.ts +53 -261
  89. package/src/eval/rb/executor.ts +36 -279
  90. package/src/export/share.ts +2 -1
  91. package/src/lsp/diagnostics.ts +516 -0
  92. package/src/lsp/index.ts +20 -2819
  93. package/src/lsp/servers.ts +296 -0
  94. package/src/lsp/tool.ts +1352 -0
  95. package/src/lsp/workspace-diagnostics.ts +170 -0
  96. package/src/lsp/writethrough.ts +561 -0
  97. package/src/mcp/transports/header-policy.ts +1 -1
  98. package/src/modes/components/agent-hub-projection.ts +2 -2
  99. package/src/modes/components/agent-hub-renderer.ts +3 -7
  100. package/src/modes/controllers/command-controller.ts +4 -1
  101. package/src/modes/theme/color.ts +133 -0
  102. package/src/modes/theme/loader.ts +178 -0
  103. package/src/modes/theme/schema.ts +263 -0
  104. package/src/modes/theme/symbols.ts +1000 -0
  105. package/src/modes/theme/theme-class.ts +611 -0
  106. package/src/modes/theme/theme.ts +27 -2453
  107. package/src/modes/theme/tui-adapters.ts +279 -0
  108. package/src/registry/agent-registry.ts +2 -2
  109. package/src/secrets/index.ts +6 -12
  110. package/src/secrets/message-transform.ts +287 -0
  111. package/src/secrets/obfuscator.ts +39 -1303
  112. package/src/secrets/placeholder-scan.ts +506 -0
  113. package/src/secrets/placeholder.ts +309 -0
  114. package/src/secrets/replacement.ts +216 -0
  115. package/src/session/agent-session-types.ts +6 -0
  116. package/src/session/agent-session.ts +113 -7
  117. package/src/session/indexed-session-storage.ts +7 -2
  118. package/src/session/session-advisors.ts +32 -34
  119. package/src/session/session-handoff.ts +39 -20
  120. package/src/session/session-manager.ts +67 -3
  121. package/src/session/session-provider-boundary.ts +3 -6
  122. package/src/session/turn-recovery.ts +21 -12
  123. package/src/slash-commands/builtin-collaboration.ts +504 -0
  124. package/src/slash-commands/builtin-completions.ts +291 -0
  125. package/src/slash-commands/builtin-control.ts +78 -0
  126. package/src/slash-commands/builtin-lifecycle.ts +506 -0
  127. package/src/slash-commands/builtin-marketplace.ts +567 -0
  128. package/src/slash-commands/builtin-modes.ts +518 -0
  129. package/src/slash-commands/builtin-registry.ts +21 -3000
  130. package/src/slash-commands/builtin-session.ts +592 -0
  131. package/src/task/executor.ts +17 -14
  132. package/src/tools/gh-common.ts +288 -0
  133. package/src/tools/gh-pr-checkout.ts +679 -0
  134. package/src/tools/gh-pr-diff.ts +473 -0
  135. package/src/tools/gh-run-watch.ts +1015 -0
  136. package/src/tools/gh-search.ts +500 -0
  137. package/src/tools/gh-types.ts +379 -0
  138. package/src/tools/gh-view.ts +612 -0
  139. package/src/tools/gh.ts +109 -3821
  140. package/src/tools/read-archive.ts +209 -0
  141. package/src/tools/read-format.ts +593 -0
  142. package/src/tools/read-path-resolution.ts +36 -0
  143. package/src/tools/read-pdf-images.ts +250 -0
  144. package/src/tools/read-renderer.ts +289 -0
  145. package/src/tools/read-selector.ts +84 -0
  146. package/src/tools/read-sqlite.ts +215 -0
  147. package/src/tools/read-summary.ts +199 -0
  148. package/src/tools/read.ts +77 -1820
  149. package/src/tools/shell-tokenize.ts +1 -1
  150. package/src/utils/changelog.ts +1 -1
  151. package/src/utils/title-generator.ts +3 -1
  152. package/src/web/search/providers/zai.ts +12 -3
@@ -0,0 +1,209 @@
1
+ import type { AgentToolResult } from "@oh-my-pi/pi-agent-core";
2
+ import type { TextContent } from "@oh-my-pi/pi-ai";
3
+ import type { ToolSession } from "../sdk";
4
+ import { truncateHead } from "../session/streaming-output";
5
+ import { type ArchiveReader, formatArchiveEntryLines, openArchive, parseArchivePathCandidates } from "../utils/zip";
6
+ import { applyListLimit } from "./list-limit";
7
+ import { resolveReadPath } from "./path-utils";
8
+ import type { ReadToolDetails } from "./read";
9
+ import {
10
+ buildInMemoryMultiRangeResult,
11
+ buildInMemoryTextResult,
12
+ decodeUtf8Text,
13
+ markMarkdownContentType,
14
+ prependSuffixResolutionNotice,
15
+ } from "./read-format";
16
+ import {
17
+ findSuffixMatchCached,
18
+ isNotFoundError,
19
+ isRemoteMountPath,
20
+ type SuffixMatchCache,
21
+ } from "./read-path-resolution";
22
+ import { isMultiRange, isRawSelector, type ParsedSelector, parseSel, selToOffsetLimit } from "./read-selector";
23
+ import { formatBytes } from "./render-utils";
24
+ import { ToolError, throwIfAborted } from "./tool-errors";
25
+ import { toolResult } from "./tool-result";
26
+
27
+ interface ResolvedArchiveReadPath {
28
+ absolutePath: string;
29
+ archiveSubPath: string;
30
+ suffixResolution?: { from: string; to: string };
31
+ }
32
+ export async function resolveArchiveReadPath(
33
+ session: ToolSession,
34
+ readPath: string,
35
+ suffixCache: SuffixMatchCache,
36
+ signal?: AbortSignal,
37
+ ): Promise<ResolvedArchiveReadPath | null> {
38
+ const candidates = parseArchivePathCandidates(readPath);
39
+ for (const candidate of candidates) {
40
+ let absolutePath = resolveReadPath(candidate.archivePath, session.cwd);
41
+ let suffixResolution: { from: string; to: string } | undefined;
42
+
43
+ try {
44
+ const stat = await Bun.file(absolutePath).stat();
45
+ if (stat.isDirectory()) continue;
46
+ return {
47
+ absolutePath,
48
+ archiveSubPath: candidate.archivePath === readPath ? "" : candidate.subPath,
49
+ suffixResolution,
50
+ };
51
+ } catch (error) {
52
+ if (!isNotFoundError(error) || isRemoteMountPath(absolutePath)) continue;
53
+
54
+ const suffixMatch = await findSuffixMatchCached(session, suffixCache, candidate.archivePath, signal);
55
+ if (!suffixMatch) continue;
56
+
57
+ try {
58
+ const retryStat = await Bun.file(suffixMatch.absolutePath).stat();
59
+ if (retryStat.isDirectory()) continue;
60
+
61
+ absolutePath = suffixMatch.absolutePath;
62
+ suffixResolution = { from: candidate.archivePath, to: suffixMatch.displayPath };
63
+ return {
64
+ absolutePath,
65
+ archiveSubPath: candidate.archivePath === readPath ? "" : candidate.subPath,
66
+ suffixResolution,
67
+ };
68
+ } catch (retryError) {
69
+ if (!isNotFoundError(retryError)) {
70
+ throw retryError;
71
+ }
72
+ }
73
+ }
74
+ }
75
+
76
+ return null;
77
+ }
78
+ async function readArchiveDirectory(
79
+ archive: ArchiveReader,
80
+ archivePath: string,
81
+ subPath: string,
82
+ offset: number | undefined,
83
+ limit: number | undefined,
84
+ details: ReadToolDetails,
85
+ signal?: AbortSignal,
86
+ ): Promise<AgentToolResult<ReadToolDetails>> {
87
+ const DEFAULT_LIMIT = 500;
88
+ const effectiveLimit = limit ?? DEFAULT_LIMIT;
89
+ const allEntries = archive.listDirectory(subPath);
90
+ // `offset` is 1-indexed (line-selector semantics): `a.zip:dir:50` starts
91
+ // the listing at the 50th entry instead of being silently ignored.
92
+ const entries = offset !== undefined && offset > 1 ? allEntries.slice(offset - 1) : allEntries;
93
+
94
+ const listLimit = applyListLimit(entries, { limit: effectiveLimit });
95
+ const limitedEntries = listLimit.items;
96
+ const limitMeta = listLimit.meta;
97
+
98
+ for (let index = 0; index < limitedEntries.length; index++) {
99
+ throwIfAborted(signal);
100
+ }
101
+ const results = formatArchiveEntryLines(limitedEntries);
102
+
103
+ const output = results.length > 0 ? results.join("\n") : "(empty archive directory)";
104
+ const text = prependSuffixResolutionNotice(output, details.suffixResolution);
105
+ const truncation = truncateHead(text, { maxLines: Number.MAX_SAFE_INTEGER });
106
+ const directoryDetails: ReadToolDetails = { ...details, isDirectory: true };
107
+ const resultBuilder = toolResult<ReadToolDetails>(directoryDetails).text(truncation.content);
108
+ resultBuilder.sourcePath(archivePath).limits({ resultLimit: limitMeta.resultLimit?.reached });
109
+ if (truncation.truncated) {
110
+ directoryDetails.truncation = truncation;
111
+ resultBuilder.truncation(truncation, { direction: "head" });
112
+ }
113
+ return resultBuilder.done();
114
+ }
115
+
116
+ export async function readArchive(
117
+ session: ToolSession,
118
+ readPath: string,
119
+ parsedSel: ParsedSelector,
120
+ resolvedArchivePath: ResolvedArchiveReadPath,
121
+ signal?: AbortSignal,
122
+ ): Promise<AgentToolResult<ReadToolDetails>> {
123
+ throwIfAborted(signal);
124
+ const archive = await openArchive(resolvedArchivePath.absolutePath);
125
+ throwIfAborted(signal);
126
+
127
+ const details: ReadToolDetails = markMarkdownContentType(
128
+ session,
129
+ {
130
+ resolvedPath: resolvedArchivePath.absolutePath,
131
+ suffixResolution: resolvedArchivePath.suffixResolution,
132
+ },
133
+ resolvedArchivePath.archiveSubPath,
134
+ );
135
+
136
+ let archiveSubPath = resolvedArchivePath.archiveSubPath;
137
+ let sel = parsedSel;
138
+ let node = archive.getNode(archiveSubPath);
139
+ if (!node && archiveSubPath) {
140
+ // `archive.zip:500` / `archive.zip:raw`: the whole subPath is a
141
+ // selector on the archive root, not a member name. Member names take
142
+ // precedence (getNode above); fall back to root + selector.
143
+ const wholeSel = parseSel(archiveSubPath);
144
+ if (wholeSel.kind !== "none") {
145
+ node = archive.getNode("");
146
+ archiveSubPath = "";
147
+ sel = wholeSel;
148
+ }
149
+ }
150
+ if (!node) {
151
+ throw new ToolError(`Path '${readPath}' not found inside archive`);
152
+ }
153
+
154
+ if (node.isDirectory) {
155
+ if (isMultiRange(sel)) {
156
+ throw new ToolError("Multi-range line selectors are not supported for archive directory listings.");
157
+ }
158
+ const { offset, limit } = selToOffsetLimit(sel);
159
+ return readArchiveDirectory(
160
+ archive,
161
+ resolvedArchivePath.absolutePath,
162
+ archiveSubPath,
163
+ offset,
164
+ limit,
165
+ details,
166
+ signal,
167
+ );
168
+ }
169
+
170
+ const entry = await archive.readFile(archiveSubPath);
171
+ const text = decodeUtf8Text(entry.bytes);
172
+ if (text === null) {
173
+ return toolResult<ReadToolDetails>(details)
174
+ .text(
175
+ prependSuffixResolutionNotice(
176
+ `[Cannot read binary archive entry '${entry.path}' (${formatBytes(entry.size)})]`,
177
+ resolvedArchivePath.suffixResolution,
178
+ ),
179
+ )
180
+ .sourcePath(resolvedArchivePath.absolutePath)
181
+ .done();
182
+ }
183
+
184
+ // Archive members are immutable: there is no edit path for bytes inside
185
+ // an archive, and a hashline tag keyed to the archive file would invite
186
+ // (and fail) edits while clobbering sibling members' snapshots.
187
+ const raw = isRawSelector(sel);
188
+ const result =
189
+ isMultiRange(sel) && sel.kind === "lines"
190
+ ? buildInMemoryMultiRangeResult(session, text, sel.ranges, {
191
+ details,
192
+ sourcePath: resolvedArchivePath.absolutePath,
193
+ entityLabel: "archive entry",
194
+ raw,
195
+ immutable: true,
196
+ })
197
+ : buildInMemoryTextResult(session, text, selToOffsetLimit(sel).offset, selToOffsetLimit(sel).limit, {
198
+ details,
199
+ sourcePath: resolvedArchivePath.absolutePath,
200
+ entityLabel: "archive entry",
201
+ raw,
202
+ immutable: true,
203
+ });
204
+ const firstText = result.content.find((content): content is TextContent => content.type === "text");
205
+ if (firstText) {
206
+ firstText.text = prependSuffixResolutionNotice(firstText.text, resolvedArchivePath.suffixResolution);
207
+ }
208
+ return result;
209
+ }