@oh-my-pi/pi-coding-agent 14.6.2 → 14.6.3
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/CHANGELOG.md +71 -2
- package/README.md +21 -0
- package/package.json +23 -7
- package/src/cli/grievances-cli.ts +89 -4
- package/src/commands/grievances.ts +33 -7
- package/src/config/prompt-templates.ts +14 -7
- package/src/config/settings-schema.ts +585 -100
- package/src/config/settings.ts +42 -0
- package/src/discovery/helpers.ts +13 -6
- package/src/edit/index.ts +3 -3
- package/src/edit/line-hash.ts +73 -25
- package/src/edit/modes/hashline.lark +10 -3
- package/src/edit/modes/hashline.ts +104 -38
- package/src/edit/renderer.ts +3 -3
- package/src/hindsight/backend.ts +444 -0
- package/src/hindsight/bank.ts +131 -0
- package/src/hindsight/client.ts +445 -0
- package/src/hindsight/config.ts +165 -0
- package/src/hindsight/content.ts +205 -0
- package/src/hindsight/index.ts +6 -0
- package/src/hindsight/retain-queue.ts +166 -0
- package/src/hindsight/transcript.ts +71 -0
- package/src/main.ts +7 -10
- package/src/memories/index.ts +1 -1
- package/src/memory-backend/index.ts +4 -0
- package/src/memory-backend/local-backend.ts +30 -0
- package/src/memory-backend/off-backend.ts +16 -0
- package/src/memory-backend/resolve.ts +24 -0
- package/src/memory-backend/types.ts +69 -0
- package/src/modes/components/settings-defs.ts +50 -451
- package/src/modes/components/settings-selector.ts +2 -2
- package/src/modes/components/status-line/presets.ts +1 -1
- package/src/modes/controllers/command-controller.ts +6 -5
- package/src/modes/controllers/event-controller.ts +12 -0
- package/src/modes/controllers/selector-controller.ts +3 -12
- package/src/modes/theme/theme.ts +4 -0
- package/src/prompts/tools/github.md +3 -0
- package/src/prompts/tools/hashline.md +20 -16
- package/src/prompts/tools/read.md +10 -6
- package/src/prompts/tools/recall.md +5 -0
- package/src/prompts/tools/reflect.md +5 -0
- package/src/prompts/tools/retain.md +5 -0
- package/src/prompts/tools/search.md +1 -1
- package/src/sdk.ts +12 -9
- package/src/session/agent-session.ts +75 -3
- package/src/slash-commands/builtin-registry.ts +2 -12
- package/src/tools/ast-edit.ts +14 -5
- package/src/tools/ast-grep.ts +12 -3
- package/src/tools/find.ts +47 -7
- package/src/tools/gh-renderer.ts +10 -1
- package/src/tools/gh.ts +233 -5
- package/src/tools/hindsight-recall.ts +70 -0
- package/src/tools/hindsight-reflect.ts +57 -0
- package/src/tools/hindsight-retain.ts +63 -0
- package/src/tools/index.ts +17 -0
- package/src/tools/path-utils.ts +55 -0
- package/src/tools/read.ts +1 -1
- package/src/tools/search.ts +45 -8
package/src/tools/search.ts
CHANGED
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
hasGlobPathChars,
|
|
23
23
|
normalizePathLikeInput,
|
|
24
24
|
parseSearchPath,
|
|
25
|
+
partitionExistingPaths,
|
|
25
26
|
resolveExplicitSearchPaths,
|
|
26
27
|
resolveToCwd,
|
|
27
28
|
} from "./path-utils";
|
|
@@ -68,6 +69,10 @@ export interface SearchToolDetails {
|
|
|
68
69
|
* `result.text` lines but uses a `│` gutter and `*` to mark match lines (vs space for
|
|
69
70
|
* context). The TUI uses this directly so it never parses model-facing hashline anchors. */
|
|
70
71
|
displayContent?: string;
|
|
72
|
+
/** User-supplied paths whose base directory was missing on disk. The tool
|
|
73
|
+
* skipped these and continued with the surviving entries; surfaced as a
|
|
74
|
+
* non-fatal warning in the renderer and in the model-facing text. */
|
|
75
|
+
missingPaths?: string[];
|
|
71
76
|
}
|
|
72
77
|
|
|
73
78
|
type SearchParams = Static<typeof searchSchema>;
|
|
@@ -82,7 +87,7 @@ export class SearchTool implements AgentTool<typeof searchSchema, SearchToolDeta
|
|
|
82
87
|
constructor(private readonly session: ToolSession) {
|
|
83
88
|
const displayMode = resolveFileDisplayMode(session);
|
|
84
89
|
this.description = prompt.render(searchDescription, {
|
|
85
|
-
|
|
90
|
+
IS_HL_MODE: displayMode.hashLines,
|
|
86
91
|
IS_LINE_NUMBER_MODE: !displayMode.hashLines && displayMode.lineNumbers,
|
|
87
92
|
});
|
|
88
93
|
}
|
|
@@ -140,13 +145,26 @@ export class SearchTool implements AgentTool<typeof searchSchema, SearchToolDeta
|
|
|
140
145
|
}
|
|
141
146
|
resolvedPathInputs.push(resource.sourcePath);
|
|
142
147
|
}
|
|
143
|
-
|
|
144
|
-
|
|
148
|
+
// Tolerate missing entries in a multi-path call: skip ones whose base
|
|
149
|
+
// directory is gone, and only error if every entry is missing. Single
|
|
150
|
+
// missing path keeps the original ENOENT semantics.
|
|
151
|
+
let missingPaths: string[] = [];
|
|
152
|
+
let effectivePaths = resolvedPathInputs;
|
|
153
|
+
if (resolvedPathInputs.length > 1) {
|
|
154
|
+
const partition = await partitionExistingPaths(resolvedPathInputs, this.session.cwd, parseSearchPath);
|
|
155
|
+
if (partition.valid.length === 0) {
|
|
156
|
+
throw new ToolError(`Path not found: ${partition.missing.join(", ")}`);
|
|
157
|
+
}
|
|
158
|
+
effectivePaths = partition.valid;
|
|
159
|
+
missingPaths = partition.missing;
|
|
160
|
+
}
|
|
161
|
+
if (effectivePaths.length === 1) {
|
|
162
|
+
const parsedPath = parseSearchPath(effectivePaths[0] ?? ".");
|
|
145
163
|
searchPath = resolveToCwd(parsedPath.basePath, this.session.cwd);
|
|
146
164
|
globFilter = parsedPath.glob;
|
|
147
165
|
scopePath = formatScopePath(searchPath);
|
|
148
166
|
} else {
|
|
149
|
-
const multiSearchPath = await resolveExplicitSearchPaths(
|
|
167
|
+
const multiSearchPath = await resolveExplicitSearchPaths(effectivePaths, this.session.cwd, globFilter);
|
|
150
168
|
if (!multiSearchPath) {
|
|
151
169
|
throw new ToolError("`paths` must contain at least one path or glob");
|
|
152
170
|
}
|
|
@@ -285,6 +303,8 @@ export class SearchTool implements AgentTool<typeof searchSchema, SearchToolDeta
|
|
|
285
303
|
const limitMessage = `Result limit reached; narrow paths or use skip=${nextSkip}.`;
|
|
286
304
|
const { record: recordFile, list: fileList } = createFileRecorder();
|
|
287
305
|
const fileMatchCounts = new Map<string, number>();
|
|
306
|
+
const missingPathsNote =
|
|
307
|
+
missingPaths.length > 0 ? `Skipped missing paths: ${missingPaths.join(", ")}` : undefined;
|
|
288
308
|
if (selectedMatches.length === 0) {
|
|
289
309
|
const details: SearchToolDetails = {
|
|
290
310
|
scopePath,
|
|
@@ -292,8 +312,10 @@ export class SearchTool implements AgentTool<typeof searchSchema, SearchToolDeta
|
|
|
292
312
|
fileCount: 0,
|
|
293
313
|
files: [],
|
|
294
314
|
truncated: false,
|
|
315
|
+
missingPaths: missingPaths.length > 0 ? missingPaths : undefined,
|
|
295
316
|
};
|
|
296
|
-
|
|
317
|
+
const text = missingPathsNote ? `No matches found\n${missingPathsNote}` : "No matches found";
|
|
318
|
+
return toolResult(details).text(text).done();
|
|
297
319
|
}
|
|
298
320
|
const outputLines: string[] = [];
|
|
299
321
|
let linesTruncated = false;
|
|
@@ -365,6 +387,9 @@ export class SearchTool implements AgentTool<typeof searchSchema, SearchToolDeta
|
|
|
365
387
|
if (matchLimitReached || result.limitReached) {
|
|
366
388
|
outputLines.push("", limitMessage);
|
|
367
389
|
}
|
|
390
|
+
if (missingPathsNote) {
|
|
391
|
+
outputLines.push("", missingPathsNote);
|
|
392
|
+
}
|
|
368
393
|
const rawOutput = outputLines.join("\n");
|
|
369
394
|
const truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });
|
|
370
395
|
const output = truncation.content;
|
|
@@ -382,6 +407,7 @@ export class SearchTool implements AgentTool<typeof searchSchema, SearchToolDeta
|
|
|
382
407
|
matchLimitReached: matchLimitReached ? effectiveLimit : undefined,
|
|
383
408
|
resultLimitReached: result.limitReached ? internalLimit : undefined,
|
|
384
409
|
displayContent: displayLines.join("\n"),
|
|
410
|
+
missingPaths: missingPaths.length > 0 ? missingPaths : undefined,
|
|
385
411
|
};
|
|
386
412
|
if (truncation.truncated) details.truncation = truncation;
|
|
387
413
|
if (linesTruncated) details.linesTruncated = true;
|
|
@@ -487,12 +513,20 @@ export const searchToolRenderer = {
|
|
|
487
513
|
details?.truncated || truncation || limits?.matchLimit || limits?.resultLimit || limits?.columnTruncated,
|
|
488
514
|
);
|
|
489
515
|
|
|
516
|
+
const missingPathsList = details?.missingPaths ?? [];
|
|
517
|
+
const missingNote =
|
|
518
|
+
missingPathsList.length > 0
|
|
519
|
+
? uiTheme.fg("warning", `skipped missing: ${missingPathsList.join(", ")}`)
|
|
520
|
+
: undefined;
|
|
521
|
+
|
|
490
522
|
if (matchCount === 0) {
|
|
491
523
|
const header = renderStatusLine(
|
|
492
524
|
{ icon: "warning", title: "Search", description: args?.pattern, meta: ["0 matches"] },
|
|
493
525
|
uiTheme,
|
|
494
526
|
);
|
|
495
|
-
|
|
527
|
+
const lines = [header, formatEmptyMessage("No matches found", uiTheme)];
|
|
528
|
+
if (missingNote) lines.push(missingNote);
|
|
529
|
+
return new Text(lines.join("\n"), 0, 0);
|
|
496
530
|
}
|
|
497
531
|
|
|
498
532
|
const summaryParts = [formatCount("match", matchCount), formatCount("file", fileCount)];
|
|
@@ -538,8 +572,11 @@ export const searchToolRenderer = {
|
|
|
538
572
|
if (limits?.columnTruncated) truncationReasons.push(`line length ${limits.columnTruncated.maxColumn}`);
|
|
539
573
|
if (truncation?.artifactId) truncationReasons.push(formatFullOutputReference(truncation.artifactId));
|
|
540
574
|
|
|
541
|
-
const extraLines =
|
|
542
|
-
|
|
575
|
+
const extraLines: string[] = [];
|
|
576
|
+
if (truncationReasons.length > 0) {
|
|
577
|
+
extraLines.push(uiTheme.fg("warning", `truncated: ${truncationReasons.join(", ")}`));
|
|
578
|
+
}
|
|
579
|
+
if (missingNote) extraLines.push(missingNote);
|
|
543
580
|
|
|
544
581
|
let cached: RenderCache | undefined;
|
|
545
582
|
return {
|