@mariozechner/pi-coding-agent 0.61.1 → 0.63.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/CHANGELOG.md +107 -0
- package/README.md +2 -2
- package/dist/cli/file-processor.d.ts.map +1 -1
- package/dist/cli/file-processor.js +4 -0
- package/dist/cli/file-processor.js.map +1 -1
- package/dist/core/agent-session.d.ts +15 -6
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +94 -90
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts +3 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +5 -2
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts +2 -0
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +2 -2
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +2 -2
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +9 -9
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/export-html/index.d.ts +2 -2
- package/dist/core/export-html/index.d.ts.map +1 -1
- package/dist/core/export-html/index.js +7 -6
- package/dist/core/export-html/index.js.map +1 -1
- package/dist/core/export-html/tool-renderer.d.ts +2 -2
- package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
- package/dist/core/export-html/tool-renderer.js +41 -16
- package/dist/core/export-html/tool-renderer.js.map +1 -1
- package/dist/core/extensions/index.d.ts +3 -2
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +12 -2
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +4 -7
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +27 -38
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +44 -9
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/extensions/wrapper.d.ts.map +1 -1
- package/dist/core/extensions/wrapper.js +2 -8
- package/dist/core/extensions/wrapper.js.map +1 -1
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/model-registry.d.ts +18 -2
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +83 -69
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +4 -4
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/output-guard.d.ts +6 -0
- package/dist/core/output-guard.d.ts.map +1 -0
- package/dist/core/output-guard.js +59 -0
- package/dist/core/output-guard.js.map +1 -0
- package/dist/core/package-manager.d.ts +1 -0
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +77 -10
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/prompt-templates.d.ts +2 -1
- package/dist/core/prompt-templates.d.ts.map +1 -1
- package/dist/core/prompt-templates.js +30 -32
- package/dist/core/prompt-templates.js.map +1 -1
- package/dist/core/resolve-config-value.d.ts +6 -0
- package/dist/core/resolve-config-value.d.ts.map +1 -1
- package/dist/core/resolve-config-value.js +37 -5
- package/dist/core/resolve-config-value.js.map +1 -1
- package/dist/core/resource-loader.d.ts +6 -5
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +136 -108
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sdk.d.ts +2 -2
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +13 -22
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/settings-manager.d.ts +2 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +3 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts +2 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +25 -1
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts +2 -3
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/source-info.d.ts +18 -0
- package/dist/core/source-info.d.ts.map +1 -0
- package/dist/core/source-info.js +19 -0
- package/dist/core/source-info.js.map +1 -0
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +3 -38
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/timings.d.ts +1 -0
- package/dist/core/timings.d.ts.map +1 -1
- package/dist/core/timings.js +6 -0
- package/dist/core/timings.js.map +1 -1
- package/dist/core/tools/bash.d.ts +19 -9
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +151 -59
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts +23 -1
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +100 -32
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts +30 -6
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +172 -59
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/core/tools/file-mutation-queue.js +4 -4
- package/dist/core/tools/file-mutation-queue.js.map +1 -1
- package/dist/core/tools/find.d.ts +11 -4
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +76 -27
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts +15 -4
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +83 -29
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/index.d.ts +67 -21
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +50 -26
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/ls.d.ts +9 -3
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +67 -13
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/read.d.ts +10 -3
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +110 -51
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/render-utils.d.ts +21 -0
- package/dist/core/tools/render-utils.d.ts.map +1 -0
- package/dist/core/tools/render-utils.js +49 -0
- package/dist/core/tools/render-utils.js.map +1 -0
- package/dist/core/tools/tool-definition-wrapper.d.ts +14 -0
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -0
- package/dist/core/tools/tool-definition-wrapper.js +30 -0
- package/dist/core/tools/tool-definition-wrapper.js.map +1 -0
- package/dist/core/tools/write.d.ts +9 -3
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +162 -27
- package/dist/core/tools/write.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +56 -18
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts +0 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +18 -5
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +15 -40
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +126 -679
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +4 -11
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +146 -93
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts +3 -0
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +14 -0
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/print-mode.d.ts +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +84 -78
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +27 -20
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +3 -4
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/utils/image-resize.d.ts +5 -5
- package/dist/utils/image-resize.d.ts.map +1 -1
- package/dist/utils/image-resize.js +45 -94
- package/dist/utils/image-resize.js.map +1 -1
- package/docs/development.md +3 -1
- package/docs/extensions.md +74 -33
- package/docs/models.md +6 -0
- package/docs/rpc.md +11 -2
- package/docs/settings.md +12 -0
- package/docs/tui.md +2 -2
- package/examples/extensions/built-in-tool-renderer.ts +8 -8
- package/examples/extensions/commands.ts +3 -3
- package/examples/extensions/custom-compaction.ts +17 -4
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/custom-provider-qwen-cli/package.json +1 -1
- package/examples/extensions/handoff.ts +5 -2
- package/examples/extensions/minimal-mode.ts +14 -14
- package/examples/extensions/qna.ts +5 -2
- package/examples/extensions/question.ts +2 -2
- package/examples/extensions/questionnaire.ts +2 -2
- package/examples/extensions/subagent/index.ts +2 -2
- package/examples/extensions/summarize.ts +15 -4
- package/examples/extensions/todo.ts +2 -2
- package/examples/extensions/truncated-tool.ts +2 -2
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/sdk/04-skills.ts +8 -2
- package/examples/sdk/08-prompt-templates.ts +2 -1
- package/examples/sdk/12-full-control.ts +0 -1
- package/package.json +5 -4
|
@@ -20,6 +20,7 @@ import { BUILTIN_SLASH_COMMANDS } from "../../core/slash-commands.js";
|
|
|
20
20
|
import { getChangelogPath, getNewEntries, parseChangelog } from "../../utils/changelog.js";
|
|
21
21
|
import { copyToClipboard } from "../../utils/clipboard.js";
|
|
22
22
|
import { extensionForImageMimeType, readClipboardImage } from "../../utils/clipboard-image.js";
|
|
23
|
+
import { parseGitUrl } from "../../utils/git.js";
|
|
23
24
|
import { ensureTool } from "../../utils/tools-manager.js";
|
|
24
25
|
import { ArminComponent } from "./components/armin.js";
|
|
25
26
|
import { AssistantMessageComponent } from "./components/assistant-message.js";
|
|
@@ -168,6 +169,48 @@ export class InteractiveMode {
|
|
|
168
169
|
setRegisteredThemes(this.session.resourceLoader.getThemes().themes);
|
|
169
170
|
initTheme(this.settingsManager.getTheme(), true);
|
|
170
171
|
}
|
|
172
|
+
getAutocompleteSourceTag(sourceInfo) {
|
|
173
|
+
if (!sourceInfo) {
|
|
174
|
+
return undefined;
|
|
175
|
+
}
|
|
176
|
+
const scopePrefix = sourceInfo.scope === "user" ? "u" : sourceInfo.scope === "project" ? "p" : "t";
|
|
177
|
+
const source = sourceInfo.source.trim();
|
|
178
|
+
if (source === "auto" || source === "local" || source === "cli") {
|
|
179
|
+
return scopePrefix;
|
|
180
|
+
}
|
|
181
|
+
if (source.startsWith("npm:")) {
|
|
182
|
+
return `${scopePrefix}:${source}`;
|
|
183
|
+
}
|
|
184
|
+
const gitSource = parseGitUrl(source);
|
|
185
|
+
if (gitSource) {
|
|
186
|
+
const ref = gitSource.ref ? `@${gitSource.ref}` : "";
|
|
187
|
+
return `${scopePrefix}:git:${gitSource.host}/${gitSource.path}${ref}`;
|
|
188
|
+
}
|
|
189
|
+
return scopePrefix;
|
|
190
|
+
}
|
|
191
|
+
prefixAutocompleteDescription(description, sourceInfo) {
|
|
192
|
+
const sourceTag = this.getAutocompleteSourceTag(sourceInfo);
|
|
193
|
+
if (!sourceTag) {
|
|
194
|
+
return description;
|
|
195
|
+
}
|
|
196
|
+
return description ? `[${sourceTag}] ${description}` : `[${sourceTag}]`;
|
|
197
|
+
}
|
|
198
|
+
getBuiltInCommandConflictDiagnostics(extensionRunner) {
|
|
199
|
+
if (!extensionRunner) {
|
|
200
|
+
return [];
|
|
201
|
+
}
|
|
202
|
+
const builtinNames = new Set(BUILTIN_SLASH_COMMANDS.map((command) => command.name));
|
|
203
|
+
return extensionRunner
|
|
204
|
+
.getRegisteredCommands()
|
|
205
|
+
.filter((command) => builtinNames.has(command.name))
|
|
206
|
+
.map((command) => ({
|
|
207
|
+
type: "warning",
|
|
208
|
+
message: command.invocationName === command.name
|
|
209
|
+
? `Extension command '/${command.name}' conflicts with built-in interactive command. Skipping in autocomplete.`
|
|
210
|
+
: `Extension command '/${command.name}' conflicts with built-in interactive command. Available as '/${command.invocationName}'.`,
|
|
211
|
+
path: command.sourceInfo.path,
|
|
212
|
+
}));
|
|
213
|
+
}
|
|
171
214
|
setupAutocomplete(fdPath) {
|
|
172
215
|
// Define commands for autocomplete
|
|
173
216
|
const slashCommands = BUILTIN_SLASH_COMMANDS.map((command) => ({
|
|
@@ -203,13 +246,13 @@ export class InteractiveMode {
|
|
|
203
246
|
// Convert prompt templates to SlashCommand format for autocomplete
|
|
204
247
|
const templateCommands = this.session.promptTemplates.map((cmd) => ({
|
|
205
248
|
name: cmd.name,
|
|
206
|
-
description: cmd.description,
|
|
249
|
+
description: this.prefixAutocompleteDescription(cmd.description, cmd.sourceInfo),
|
|
207
250
|
}));
|
|
208
251
|
// Convert extension commands to SlashCommand format
|
|
209
252
|
const builtinCommandNames = new Set(slashCommands.map((c) => c.name));
|
|
210
|
-
const extensionCommands = (this.session.extensionRunner?.getRegisteredCommands(builtinCommandNames) ?? []).map((cmd) => ({
|
|
211
|
-
name: cmd.
|
|
212
|
-
description: cmd.description
|
|
253
|
+
const extensionCommands = (this.session.extensionRunner?.getRegisteredCommands().filter((cmd) => !builtinCommandNames.has(cmd.name)) ?? []).map((cmd) => ({
|
|
254
|
+
name: cmd.invocationName,
|
|
255
|
+
description: this.prefixAutocompleteDescription(cmd.description, cmd.sourceInfo),
|
|
213
256
|
getArgumentCompletions: cmd.getArgumentCompletions,
|
|
214
257
|
}));
|
|
215
258
|
// Build skill commands from session.skills (if enabled)
|
|
@@ -219,7 +262,10 @@ export class InteractiveMode {
|
|
|
219
262
|
for (const skill of this.session.resourceLoader.getSkills().skills) {
|
|
220
263
|
const commandName = `skill:${skill.name}`;
|
|
221
264
|
this.skillCommands.set(commandName, skill.filePath);
|
|
222
|
-
skillCommandList.push({
|
|
265
|
+
skillCommandList.push({
|
|
266
|
+
name: commandName,
|
|
267
|
+
description: this.prefixAutocompleteDescription(skill.description, skill.sourceInfo),
|
|
268
|
+
});
|
|
223
269
|
}
|
|
224
270
|
}
|
|
225
271
|
// Setup autocomplete
|
|
@@ -266,7 +312,8 @@ export class InteractiveMode {
|
|
|
266
312
|
hint("app.clipboard.pasteImage", "to paste image"),
|
|
267
313
|
rawKeyHint("drop files", "to attach"),
|
|
268
314
|
].join("\n");
|
|
269
|
-
|
|
315
|
+
const onboarding = theme.fg("dim", `Pi can explain its own features and look up its docs. Ask it how to use or extend Pi.`);
|
|
316
|
+
this.builtInHeader = new Text(`${logo}\n${instructions}\n\n${onboarding}`, 1, 0);
|
|
270
317
|
// Setup UI layout
|
|
271
318
|
this.headerContainer.addChild(new Spacer(1));
|
|
272
319
|
this.headerContainer.addChild(this.builtInHeader);
|
|
@@ -547,21 +594,21 @@ export class InteractiveMode {
|
|
|
547
594
|
/**
|
|
548
595
|
* Get a short path relative to the package root for display.
|
|
549
596
|
*/
|
|
550
|
-
getShortPath(fullPath,
|
|
551
|
-
|
|
597
|
+
getShortPath(fullPath, sourceInfo) {
|
|
598
|
+
const source = sourceInfo?.source ?? "";
|
|
552
599
|
const npmMatch = fullPath.match(/node_modules\/(@?[^/]+(?:\/[^/]+)?)\/(.*)/);
|
|
553
600
|
if (npmMatch && source.startsWith("npm:")) {
|
|
554
601
|
return npmMatch[2];
|
|
555
602
|
}
|
|
556
|
-
// For git packages, show path relative to repo root
|
|
557
603
|
const gitMatch = fullPath.match(/git\/[^/]+\/[^/]+\/(.*)/);
|
|
558
604
|
if (gitMatch && source.startsWith("git:")) {
|
|
559
605
|
return gitMatch[1];
|
|
560
606
|
}
|
|
561
|
-
// For local/auto, just use formatDisplayPath
|
|
562
607
|
return this.formatDisplayPath(fullPath);
|
|
563
608
|
}
|
|
564
|
-
getDisplaySourceInfo(
|
|
609
|
+
getDisplaySourceInfo(sourceInfo) {
|
|
610
|
+
const source = sourceInfo?.source ?? "local";
|
|
611
|
+
const scope = sourceInfo?.scope ?? "project";
|
|
565
612
|
if (source === "local") {
|
|
566
613
|
if (scope === "user") {
|
|
567
614
|
return { label: "user", color: "muted" };
|
|
@@ -580,7 +627,9 @@ export class InteractiveMode {
|
|
|
580
627
|
const scopeLabel = scope === "user" ? "user" : scope === "project" ? "project" : scope === "temporary" ? "temp" : undefined;
|
|
581
628
|
return { label: source, scopeLabel, color: "accent" };
|
|
582
629
|
}
|
|
583
|
-
getScopeGroup(
|
|
630
|
+
getScopeGroup(sourceInfo) {
|
|
631
|
+
const source = sourceInfo?.source ?? "local";
|
|
632
|
+
const scope = sourceInfo?.scope ?? "project";
|
|
584
633
|
if (source === "cli" || scope === "temporary")
|
|
585
634
|
return "path";
|
|
586
635
|
if (scope === "user")
|
|
@@ -589,28 +638,27 @@ export class InteractiveMode {
|
|
|
589
638
|
return "project";
|
|
590
639
|
return "path";
|
|
591
640
|
}
|
|
592
|
-
isPackageSource(
|
|
641
|
+
isPackageSource(sourceInfo) {
|
|
642
|
+
const source = sourceInfo?.source ?? "";
|
|
593
643
|
return source.startsWith("npm:") || source.startsWith("git:");
|
|
594
644
|
}
|
|
595
|
-
buildScopeGroups(
|
|
645
|
+
buildScopeGroups(items) {
|
|
596
646
|
const groups = {
|
|
597
647
|
user: { scope: "user", paths: [], packages: new Map() },
|
|
598
648
|
project: { scope: "project", paths: [], packages: new Map() },
|
|
599
649
|
path: { scope: "path", paths: [], packages: new Map() },
|
|
600
650
|
};
|
|
601
|
-
for (const
|
|
602
|
-
const
|
|
603
|
-
const source = meta?.source ?? "local";
|
|
604
|
-
const scope = meta?.scope ?? "project";
|
|
605
|
-
const groupKey = this.getScopeGroup(source, scope);
|
|
651
|
+
for (const item of items) {
|
|
652
|
+
const groupKey = this.getScopeGroup(item.sourceInfo);
|
|
606
653
|
const group = groups[groupKey];
|
|
607
|
-
|
|
654
|
+
const source = item.sourceInfo?.source ?? "local";
|
|
655
|
+
if (this.isPackageSource(item.sourceInfo)) {
|
|
608
656
|
const list = group.packages.get(source) ?? [];
|
|
609
|
-
list.push(
|
|
657
|
+
list.push(item);
|
|
610
658
|
group.packages.set(source, list);
|
|
611
659
|
}
|
|
612
660
|
else {
|
|
613
|
-
group.paths.push(
|
|
661
|
+
group.paths.push(item);
|
|
614
662
|
}
|
|
615
663
|
}
|
|
616
664
|
return [groups.project, groups.user, groups.path].filter((group) => group.paths.length > 0 || group.packages.size > 0);
|
|
@@ -619,57 +667,44 @@ export class InteractiveMode {
|
|
|
619
667
|
const lines = [];
|
|
620
668
|
for (const group of groups) {
|
|
621
669
|
lines.push(` ${theme.fg("accent", group.scope)}`);
|
|
622
|
-
const sortedPaths = [...group.paths].sort((a, b) => a.localeCompare(b));
|
|
623
|
-
for (const
|
|
624
|
-
lines.push(theme.fg("dim", ` ${options.formatPath(
|
|
670
|
+
const sortedPaths = [...group.paths].sort((a, b) => a.path.localeCompare(b.path));
|
|
671
|
+
for (const item of sortedPaths) {
|
|
672
|
+
lines.push(theme.fg("dim", ` ${options.formatPath(item)}`));
|
|
625
673
|
}
|
|
626
674
|
const sortedPackages = Array.from(group.packages.entries()).sort(([a], [b]) => a.localeCompare(b));
|
|
627
|
-
for (const [source,
|
|
675
|
+
for (const [source, items] of sortedPackages) {
|
|
628
676
|
lines.push(` ${theme.fg("mdLink", source)}`);
|
|
629
|
-
const sortedPackagePaths = [...
|
|
630
|
-
for (const
|
|
631
|
-
lines.push(theme.fg("dim", ` ${options.formatPackagePath(
|
|
677
|
+
const sortedPackagePaths = [...items].sort((a, b) => a.path.localeCompare(b.path));
|
|
678
|
+
for (const item of sortedPackagePaths) {
|
|
679
|
+
lines.push(theme.fg("dim", ` ${options.formatPackagePath(item, source)}`));
|
|
632
680
|
}
|
|
633
681
|
}
|
|
634
682
|
}
|
|
635
683
|
return lines.join("\n");
|
|
636
684
|
}
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
* Package manager stores metadata for directories, but we display file paths.
|
|
640
|
-
*/
|
|
641
|
-
findMetadata(p, metadata) {
|
|
642
|
-
// Try exact match first
|
|
643
|
-
const exact = metadata.get(p);
|
|
685
|
+
findSourceInfoForPath(p, sourceInfos) {
|
|
686
|
+
const exact = sourceInfos.get(p);
|
|
644
687
|
if (exact)
|
|
645
688
|
return exact;
|
|
646
|
-
// Try parent directories (package manager stores directory paths)
|
|
647
689
|
let current = p;
|
|
648
690
|
while (current.includes("/")) {
|
|
649
691
|
current = current.substring(0, current.lastIndexOf("/"));
|
|
650
|
-
const parent =
|
|
692
|
+
const parent = sourceInfos.get(current);
|
|
651
693
|
if (parent)
|
|
652
694
|
return parent;
|
|
653
695
|
}
|
|
654
696
|
return undefined;
|
|
655
697
|
}
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
const meta = this.findMetadata(p, metadata);
|
|
661
|
-
if (meta) {
|
|
662
|
-
const shortPath = this.getShortPath(p, meta.source);
|
|
663
|
-
const { label, scopeLabel } = this.getDisplaySourceInfo(meta.source, meta.scope);
|
|
698
|
+
formatPathWithSource(p, sourceInfo) {
|
|
699
|
+
if (sourceInfo) {
|
|
700
|
+
const shortPath = this.getShortPath(p, sourceInfo);
|
|
701
|
+
const { label, scopeLabel } = this.getDisplaySourceInfo(sourceInfo);
|
|
664
702
|
const labelText = scopeLabel ? `${label} (${scopeLabel})` : label;
|
|
665
703
|
return `${labelText} ${shortPath}`;
|
|
666
704
|
}
|
|
667
705
|
return this.formatDisplayPath(p);
|
|
668
706
|
}
|
|
669
|
-
|
|
670
|
-
* Format resource diagnostics with nice collision display using metadata.
|
|
671
|
-
*/
|
|
672
|
-
formatDiagnostics(diagnostics, metadata) {
|
|
707
|
+
formatDiagnostics(diagnostics, sourceInfos) {
|
|
673
708
|
const lines = [];
|
|
674
709
|
// Group collision diagnostics by name
|
|
675
710
|
const collisions = new Map();
|
|
@@ -690,21 +725,17 @@ export class InteractiveMode {
|
|
|
690
725
|
if (!first)
|
|
691
726
|
continue;
|
|
692
727
|
lines.push(theme.fg("warning", ` "${name}" collision:`));
|
|
693
|
-
|
|
694
|
-
lines.push(theme.fg("dim", ` ${theme.fg("success", "✓")} ${this.formatPathWithSource(first.winnerPath, metadata)}`));
|
|
695
|
-
// Show all losers
|
|
728
|
+
lines.push(theme.fg("dim", ` ${theme.fg("success", "✓")} ${this.formatPathWithSource(first.winnerPath, this.findSourceInfoForPath(first.winnerPath, sourceInfos))}`));
|
|
696
729
|
for (const d of collisionList) {
|
|
697
730
|
if (d.collision) {
|
|
698
|
-
lines.push(theme.fg("dim", ` ${theme.fg("warning", "✗")} ${this.formatPathWithSource(d.collision.loserPath,
|
|
731
|
+
lines.push(theme.fg("dim", ` ${theme.fg("warning", "✗")} ${this.formatPathWithSource(d.collision.loserPath, this.findSourceInfoForPath(d.collision.loserPath, sourceInfos))} (skipped)`));
|
|
699
732
|
}
|
|
700
733
|
}
|
|
701
734
|
}
|
|
702
|
-
// Format other diagnostics (skill name collisions, parse errors, etc.)
|
|
703
735
|
for (const d of otherDiagnostics) {
|
|
704
736
|
if (d.path) {
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
lines.push(theme.fg(d.type === "error" ? "error" : "warning", ` ${sourceInfo}`));
|
|
737
|
+
const formattedPath = this.formatPathWithSource(d.path, this.findSourceInfoForPath(d.path, sourceInfos));
|
|
738
|
+
lines.push(theme.fg(d.type === "error" ? "error" : "warning", ` ${formattedPath}`));
|
|
708
739
|
lines.push(theme.fg(d.type === "error" ? "error" : "warning", ` ${d.message}`));
|
|
709
740
|
}
|
|
710
741
|
else {
|
|
@@ -719,11 +750,36 @@ export class InteractiveMode {
|
|
|
719
750
|
if (!showListing && !showDiagnostics) {
|
|
720
751
|
return;
|
|
721
752
|
}
|
|
722
|
-
const metadata = this.session.resourceLoader.getPathMetadata();
|
|
723
753
|
const sectionHeader = (name, color = "mdHeading") => theme.fg(color, `[${name}]`);
|
|
724
754
|
const skillsResult = this.session.resourceLoader.getSkills();
|
|
725
755
|
const promptsResult = this.session.resourceLoader.getPrompts();
|
|
726
756
|
const themesResult = this.session.resourceLoader.getThemes();
|
|
757
|
+
const extensions = options?.extensions ??
|
|
758
|
+
this.session.resourceLoader.getExtensions().extensions.map((extension) => ({
|
|
759
|
+
path: extension.path,
|
|
760
|
+
sourceInfo: extension.sourceInfo,
|
|
761
|
+
}));
|
|
762
|
+
const sourceInfos = new Map();
|
|
763
|
+
for (const extension of extensions) {
|
|
764
|
+
if (extension.sourceInfo) {
|
|
765
|
+
sourceInfos.set(extension.path, extension.sourceInfo);
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
for (const skill of skillsResult.skills) {
|
|
769
|
+
if (skill.sourceInfo) {
|
|
770
|
+
sourceInfos.set(skill.filePath, skill.sourceInfo);
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
for (const prompt of promptsResult.prompts) {
|
|
774
|
+
if (prompt.sourceInfo) {
|
|
775
|
+
sourceInfos.set(prompt.filePath, prompt.sourceInfo);
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
for (const loadedTheme of themesResult.themes) {
|
|
779
|
+
if (loadedTheme.sourcePath && loadedTheme.sourceInfo) {
|
|
780
|
+
sourceInfos.set(loadedTheme.sourcePath, loadedTheme.sourceInfo);
|
|
781
|
+
}
|
|
782
|
+
}
|
|
727
783
|
if (showListing) {
|
|
728
784
|
const contextFiles = this.session.resourceLoader.getAgentsFiles().agentsFiles;
|
|
729
785
|
if (contextFiles.length > 0) {
|
|
@@ -736,39 +792,36 @@ export class InteractiveMode {
|
|
|
736
792
|
}
|
|
737
793
|
const skills = skillsResult.skills;
|
|
738
794
|
if (skills.length > 0) {
|
|
739
|
-
const
|
|
740
|
-
const groups = this.buildScopeGroups(skillPaths, metadata);
|
|
795
|
+
const groups = this.buildScopeGroups(skills.map((skill) => ({ path: skill.filePath, sourceInfo: skill.sourceInfo })));
|
|
741
796
|
const skillList = this.formatScopeGroups(groups, {
|
|
742
|
-
formatPath: (
|
|
743
|
-
formatPackagePath: (
|
|
797
|
+
formatPath: (item) => this.formatDisplayPath(item.path),
|
|
798
|
+
formatPackagePath: (item) => this.getShortPath(item.path, item.sourceInfo),
|
|
744
799
|
});
|
|
745
800
|
this.chatContainer.addChild(new Text(`${sectionHeader("Skills")}\n${skillList}`, 0, 0));
|
|
746
801
|
this.chatContainer.addChild(new Spacer(1));
|
|
747
802
|
}
|
|
748
803
|
const templates = this.session.promptTemplates;
|
|
749
804
|
if (templates.length > 0) {
|
|
750
|
-
const
|
|
751
|
-
const groups = this.buildScopeGroups(templatePaths, metadata);
|
|
805
|
+
const groups = this.buildScopeGroups(templates.map((template) => ({ path: template.filePath, sourceInfo: template.sourceInfo })));
|
|
752
806
|
const templateByPath = new Map(templates.map((t) => [t.filePath, t]));
|
|
753
807
|
const templateList = this.formatScopeGroups(groups, {
|
|
754
|
-
formatPath: (
|
|
755
|
-
const template = templateByPath.get(
|
|
756
|
-
return template ? `/${template.name}` : this.formatDisplayPath(
|
|
808
|
+
formatPath: (item) => {
|
|
809
|
+
const template = templateByPath.get(item.path);
|
|
810
|
+
return template ? `/${template.name}` : this.formatDisplayPath(item.path);
|
|
757
811
|
},
|
|
758
|
-
formatPackagePath: (
|
|
759
|
-
const template = templateByPath.get(
|
|
760
|
-
return template ? `/${template.name}` : this.formatDisplayPath(
|
|
812
|
+
formatPackagePath: (item) => {
|
|
813
|
+
const template = templateByPath.get(item.path);
|
|
814
|
+
return template ? `/${template.name}` : this.formatDisplayPath(item.path);
|
|
761
815
|
},
|
|
762
816
|
});
|
|
763
817
|
this.chatContainer.addChild(new Text(`${sectionHeader("Prompts")}\n${templateList}`, 0, 0));
|
|
764
818
|
this.chatContainer.addChild(new Spacer(1));
|
|
765
819
|
}
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
const groups = this.buildScopeGroups(extensionPaths, metadata);
|
|
820
|
+
if (extensions.length > 0) {
|
|
821
|
+
const groups = this.buildScopeGroups(extensions);
|
|
769
822
|
const extList = this.formatScopeGroups(groups, {
|
|
770
|
-
formatPath: (
|
|
771
|
-
formatPackagePath: (
|
|
823
|
+
formatPath: (item) => this.formatDisplayPath(item.path),
|
|
824
|
+
formatPackagePath: (item) => this.getShortPath(item.path, item.sourceInfo),
|
|
772
825
|
});
|
|
773
826
|
this.chatContainer.addChild(new Text(`${sectionHeader("Extensions", "mdHeading")}\n${extList}`, 0, 0));
|
|
774
827
|
this.chatContainer.addChild(new Spacer(1));
|
|
@@ -777,11 +830,13 @@ export class InteractiveMode {
|
|
|
777
830
|
const loadedThemes = themesResult.themes;
|
|
778
831
|
const customThemes = loadedThemes.filter((t) => t.sourcePath);
|
|
779
832
|
if (customThemes.length > 0) {
|
|
780
|
-
const
|
|
781
|
-
|
|
833
|
+
const groups = this.buildScopeGroups(customThemes.map((loadedTheme) => ({
|
|
834
|
+
path: loadedTheme.sourcePath,
|
|
835
|
+
sourceInfo: loadedTheme.sourceInfo,
|
|
836
|
+
})));
|
|
782
837
|
const themeList = this.formatScopeGroups(groups, {
|
|
783
|
-
formatPath: (
|
|
784
|
-
formatPackagePath: (
|
|
838
|
+
formatPath: (item) => this.formatDisplayPath(item.path),
|
|
839
|
+
formatPackagePath: (item) => this.getShortPath(item.path, item.sourceInfo),
|
|
785
840
|
});
|
|
786
841
|
this.chatContainer.addChild(new Text(`${sectionHeader("Themes")}\n${themeList}`, 0, 0));
|
|
787
842
|
this.chatContainer.addChild(new Spacer(1));
|
|
@@ -790,13 +845,13 @@ export class InteractiveMode {
|
|
|
790
845
|
if (showDiagnostics) {
|
|
791
846
|
const skillDiagnostics = skillsResult.diagnostics;
|
|
792
847
|
if (skillDiagnostics.length > 0) {
|
|
793
|
-
const warningLines = this.formatDiagnostics(skillDiagnostics,
|
|
848
|
+
const warningLines = this.formatDiagnostics(skillDiagnostics, sourceInfos);
|
|
794
849
|
this.chatContainer.addChild(new Text(`${theme.fg("warning", "[Skill conflicts]")}\n${warningLines}`, 0, 0));
|
|
795
850
|
this.chatContainer.addChild(new Spacer(1));
|
|
796
851
|
}
|
|
797
852
|
const promptDiagnostics = promptsResult.diagnostics;
|
|
798
853
|
if (promptDiagnostics.length > 0) {
|
|
799
|
-
const warningLines = this.formatDiagnostics(promptDiagnostics,
|
|
854
|
+
const warningLines = this.formatDiagnostics(promptDiagnostics, sourceInfos);
|
|
800
855
|
this.chatContainer.addChild(new Text(`${theme.fg("warning", "[Prompt conflicts]")}\n${warningLines}`, 0, 0));
|
|
801
856
|
this.chatContainer.addChild(new Spacer(1));
|
|
802
857
|
}
|
|
@@ -809,16 +864,17 @@ export class InteractiveMode {
|
|
|
809
864
|
}
|
|
810
865
|
const commandDiagnostics = this.session.extensionRunner?.getCommandDiagnostics() ?? [];
|
|
811
866
|
extensionDiagnostics.push(...commandDiagnostics);
|
|
867
|
+
extensionDiagnostics.push(...this.getBuiltInCommandConflictDiagnostics(this.session.extensionRunner));
|
|
812
868
|
const shortcutDiagnostics = this.session.extensionRunner?.getShortcutDiagnostics() ?? [];
|
|
813
869
|
extensionDiagnostics.push(...shortcutDiagnostics);
|
|
814
870
|
if (extensionDiagnostics.length > 0) {
|
|
815
|
-
const warningLines = this.formatDiagnostics(extensionDiagnostics,
|
|
871
|
+
const warningLines = this.formatDiagnostics(extensionDiagnostics, sourceInfos);
|
|
816
872
|
this.chatContainer.addChild(new Text(`${theme.fg("warning", "[Extension issues]")}\n${warningLines}`, 0, 0));
|
|
817
873
|
this.chatContainer.addChild(new Spacer(1));
|
|
818
874
|
}
|
|
819
875
|
const themeDiagnostics = themesResult.diagnostics;
|
|
820
876
|
if (themeDiagnostics.length > 0) {
|
|
821
|
-
const warningLines = this.formatDiagnostics(themeDiagnostics,
|
|
877
|
+
const warningLines = this.formatDiagnostics(themeDiagnostics, sourceInfos);
|
|
822
878
|
this.chatContainer.addChild(new Text(`${theme.fg("warning", "[Theme conflicts]")}\n${warningLines}`, 0, 0));
|
|
823
879
|
this.chatContainer.addChild(new Spacer(1));
|
|
824
880
|
}
|
|
@@ -907,19 +963,17 @@ export class InteractiveMode {
|
|
|
907
963
|
this.setupAutocomplete(this.fdPath);
|
|
908
964
|
const extensionRunner = this.session.extensionRunner;
|
|
909
965
|
if (!extensionRunner) {
|
|
910
|
-
this.showLoadedResources({
|
|
966
|
+
this.showLoadedResources({ extensions: [], force: false });
|
|
911
967
|
return;
|
|
912
968
|
}
|
|
913
969
|
this.setupExtensionShortcuts(extensionRunner);
|
|
914
|
-
this.showLoadedResources({
|
|
970
|
+
this.showLoadedResources({ force: false });
|
|
915
971
|
}
|
|
916
972
|
/**
|
|
917
973
|
* Get a registered tool definition by name (for custom rendering).
|
|
918
974
|
*/
|
|
919
975
|
getRegisteredToolDefinition(toolName) {
|
|
920
|
-
|
|
921
|
-
const registeredTool = tools.find((t) => t.definition.name === toolName);
|
|
922
|
-
return registeredTool?.definition;
|
|
976
|
+
return this.session.getToolDefinition(toolName);
|
|
923
977
|
}
|
|
924
978
|
/**
|
|
925
979
|
* Set up keyboard shortcuts registered by extensions.
|
|
@@ -1809,7 +1863,7 @@ export class InteractiveMode {
|
|
|
1809
1863
|
for (const content of this.streamingMessage.content) {
|
|
1810
1864
|
if (content.type === "toolCall") {
|
|
1811
1865
|
if (!this.pendingTools.has(content.id)) {
|
|
1812
|
-
const component = new ToolExecutionComponent(content.name, content.arguments, {
|
|
1866
|
+
const component = new ToolExecutionComponent(content.name, content.id, content.arguments, {
|
|
1813
1867
|
showImages: this.settingsManager.getShowImages(),
|
|
1814
1868
|
}, this.getRegisteredToolDefinition(content.name), this.ui);
|
|
1815
1869
|
component.setExpanded(this.toolOutputExpanded);
|
|
@@ -1869,7 +1923,7 @@ export class InteractiveMode {
|
|
|
1869
1923
|
case "tool_execution_start": {
|
|
1870
1924
|
let component = this.pendingTools.get(event.toolCallId);
|
|
1871
1925
|
if (!component) {
|
|
1872
|
-
component = new ToolExecutionComponent(event.toolName, event.args, {
|
|
1926
|
+
component = new ToolExecutionComponent(event.toolName, event.toolCallId, event.args, {
|
|
1873
1927
|
showImages: this.settingsManager.getShowImages(),
|
|
1874
1928
|
}, this.getRegisteredToolDefinition(event.toolName), this.ui);
|
|
1875
1929
|
component.setExpanded(this.toolOutputExpanded);
|
|
@@ -2125,7 +2179,7 @@ export class InteractiveMode {
|
|
|
2125
2179
|
// Render tool call components
|
|
2126
2180
|
for (const content of message.content) {
|
|
2127
2181
|
if (content.type === "toolCall") {
|
|
2128
|
-
const component = new ToolExecutionComponent(content.name, content.arguments, { showImages: this.settingsManager.getShowImages() }, this.getRegisteredToolDefinition(content.name), this.ui);
|
|
2182
|
+
const component = new ToolExecutionComponent(content.name, content.id, content.arguments, { showImages: this.settingsManager.getShowImages() }, this.getRegisteredToolDefinition(content.name), this.ui);
|
|
2129
2183
|
component.setExpanded(this.toolOutputExpanded);
|
|
2130
2184
|
this.chatContainer.addChild(component);
|
|
2131
2185
|
if (message.stopReason === "aborted" || message.stopReason === "error") {
|
|
@@ -3286,7 +3340,6 @@ export class InteractiveMode {
|
|
|
3286
3340
|
this.rebuildChatFromMessages();
|
|
3287
3341
|
dismissLoader(this.editor);
|
|
3288
3342
|
this.showLoadedResources({
|
|
3289
|
-
extensionPaths: runner?.getExtensionPaths() ?? [],
|
|
3290
3343
|
force: false,
|
|
3291
3344
|
showDiagnosticsWhenQuiet: true,
|
|
3292
3345
|
});
|