@earendil-works/pi-coding-agent 0.78.1 → 0.79.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 +33 -0
- package/README.md +21 -4
- package/dist/cli/args.d.ts +1 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +12 -2
- package/dist/cli/args.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts +3 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +1 -0
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +2 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +2 -2
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/compaction/utils.d.ts +1 -1
- package/dist/core/compaction/utils.d.ts.map +1 -1
- package/dist/core/compaction/utils.js +1 -1
- package/dist/core/compaction/utils.js.map +1 -1
- package/dist/core/extensions/index.d.ts +1 -1
- 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 +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +4 -4
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +6 -2
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +28 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +18 -1
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +1 -0
- package/dist/core/model-registry.js.map +1 -1
- 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 +25 -7
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/resource-loader.d.ts +13 -2
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +129 -54
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/settings-manager.d.ts +10 -2
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +71 -30
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +1 -0
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +1 -1
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +1 -1
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +1 -1
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +1 -1
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +1 -1
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +1 -1
- package/dist/core/tools/write.js.map +1 -1
- package/dist/core/trust-manager.d.ts +10 -0
- package/dist/core/trust-manager.d.ts.map +1 -0
- package/dist/core/trust-manager.js +133 -0
- package/dist/core/trust-manager.js.map +1 -0
- package/dist/index.d.ts +5 -4
- 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 +195 -6
- package/dist/main.js.map +1 -1
- package/dist/modes/index.d.ts +1 -1
- package/dist/modes/index.d.ts.map +1 -1
- package/dist/modes/index.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +2 -2
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +7 -0
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +1 -0
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +1 -0
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/trust-selector.d.ts +20 -0
- package/dist/modes/interactive/components/trust-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/trust-selector.js +86 -0
- package/dist/modes/interactive/components/trust-selector.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +7 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +85 -1
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +55 -8
- package/dist/package-manager-cli.js.map +1 -1
- package/docs/docs.json +4 -0
- package/docs/extensions.md +22 -1
- package/docs/index.md +1 -0
- package/docs/packages.md +3 -1
- package/docs/prompt-templates.md +1 -1
- package/docs/sdk.md +5 -0
- package/docs/security.md +57 -0
- package/docs/settings.md +10 -0
- package/docs/skills.md +1 -1
- package/docs/terminal-setup.md +36 -2
- package/docs/themes.md +1 -1
- package/docs/tmux.md +4 -2
- package/docs/usage.md +15 -3
- package/examples/extensions/README.md +1 -0
- 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/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/project-trust.ts +64 -0
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +12 -12
- package/package.json +4 -8
|
@@ -24,6 +24,7 @@ import { formatMissingSessionCwdPrompt, MissingSessionCwdError } from "../../cor
|
|
|
24
24
|
import { SessionManager } from "../../core/session-manager.js";
|
|
25
25
|
import { BUILTIN_SLASH_COMMANDS } from "../../core/slash-commands.js";
|
|
26
26
|
import { isInstallTelemetryEnabled } from "../../core/telemetry.js";
|
|
27
|
+
import { hasProjectConfigDir, hasProjectTrustInputs, ProjectTrustStore } from "../../core/trust-manager.js";
|
|
27
28
|
import { getChangelogPath, getNewEntries, parseChangelog } from "../../utils/changelog.js";
|
|
28
29
|
import { copyToClipboard } from "../../utils/clipboard.js";
|
|
29
30
|
import { extensionForImageMimeType, readClipboardImage } from "../../utils/clipboard-image.js";
|
|
@@ -59,6 +60,7 @@ import { SettingsSelectorComponent } from "./components/settings-selector.js";
|
|
|
59
60
|
import { SkillInvocationMessageComponent } from "./components/skill-invocation-message.js";
|
|
60
61
|
import { ToolExecutionComponent } from "./components/tool-execution.js";
|
|
61
62
|
import { TreeSelectorComponent } from "./components/tree-selector.js";
|
|
63
|
+
import { TrustSelectorComponent } from "./components/trust-selector.js";
|
|
62
64
|
import { UserMessageComponent } from "./components/user-message.js";
|
|
63
65
|
import { UserMessageSelectorComponent } from "./components/user-message-selector.js";
|
|
64
66
|
import { getAvailableThemes, getAvailableThemesWithPaths, getEditorTheme, getMarkdownTheme, getThemeByName, initTheme, onThemeChange, setRegisteredThemes, setTheme, setThemeInstance, stopThemeWatcher, Theme, theme, } from "./theme/theme.js";
|
|
@@ -213,6 +215,7 @@ export class InteractiveMode {
|
|
|
213
215
|
// Custom header from extension (undefined = use built-in header)
|
|
214
216
|
customHeader = undefined;
|
|
215
217
|
options;
|
|
218
|
+
autoTrustOnReloadCwd;
|
|
216
219
|
// Convenience accessors
|
|
217
220
|
get session() {
|
|
218
221
|
return this.runtimeHost.session;
|
|
@@ -229,6 +232,7 @@ export class InteractiveMode {
|
|
|
229
232
|
constructor(runtimeHost, options = {}) {
|
|
230
233
|
this.runtimeHost = runtimeHost;
|
|
231
234
|
this.options = options;
|
|
235
|
+
this.autoTrustOnReloadCwd = options.autoTrustOnReloadCwd;
|
|
232
236
|
this.runtimeHost.setBeforeSessionInvalidate(() => {
|
|
233
237
|
this.resetExtensionUI();
|
|
234
238
|
});
|
|
@@ -1555,6 +1559,20 @@ export class InteractiveMode {
|
|
|
1555
1559
|
/**
|
|
1556
1560
|
* Create the ExtensionUIContext for extensions.
|
|
1557
1561
|
*/
|
|
1562
|
+
createProjectTrustContext(cwd) {
|
|
1563
|
+
const ui = this.createExtensionUIContext();
|
|
1564
|
+
return {
|
|
1565
|
+
cwd,
|
|
1566
|
+
mode: "tui",
|
|
1567
|
+
hasUI: true,
|
|
1568
|
+
ui: {
|
|
1569
|
+
select: ui.select,
|
|
1570
|
+
confirm: ui.confirm,
|
|
1571
|
+
input: ui.input,
|
|
1572
|
+
notify: ui.notify,
|
|
1573
|
+
},
|
|
1574
|
+
};
|
|
1575
|
+
}
|
|
1558
1576
|
createExtensionUIContext() {
|
|
1559
1577
|
return {
|
|
1560
1578
|
select: (title, options, opts) => this.showExtensionSelector(title, options, opts),
|
|
@@ -2059,6 +2077,11 @@ export class InteractiveMode {
|
|
|
2059
2077
|
this.editor.setText("");
|
|
2060
2078
|
return;
|
|
2061
2079
|
}
|
|
2080
|
+
if (text === "/trust") {
|
|
2081
|
+
this.showTrustSelector();
|
|
2082
|
+
this.editor.setText("");
|
|
2083
|
+
return;
|
|
2084
|
+
}
|
|
2062
2085
|
if (text === "/login") {
|
|
2063
2086
|
this.showOAuthSelector("login");
|
|
2064
2087
|
this.editor.setText("");
|
|
@@ -2528,6 +2551,7 @@ export class InteractiveMode {
|
|
|
2528
2551
|
this.chatContainer.addChild(component);
|
|
2529
2552
|
// Render user message separately if present
|
|
2530
2553
|
if (skillBlock.userMessage) {
|
|
2554
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
2531
2555
|
const userComponent = new UserMessageComponent(skillBlock.userMessage, this.getMarkdownThemeWithSettings());
|
|
2532
2556
|
this.chatContainer.addChild(userComponent);
|
|
2533
2557
|
}
|
|
@@ -2627,6 +2651,7 @@ export class InteractiveMode {
|
|
|
2627
2651
|
updateFooter: true,
|
|
2628
2652
|
populateHistory: true,
|
|
2629
2653
|
});
|
|
2654
|
+
this.renderProjectTrustWarningIfNeeded();
|
|
2630
2655
|
// Show compaction info if session was compacted
|
|
2631
2656
|
const allEntries = this.sessionManager.getEntries();
|
|
2632
2657
|
const compactionCount = allEntries.filter((e) => e.type === "compaction").length;
|
|
@@ -2635,6 +2660,15 @@ export class InteractiveMode {
|
|
|
2635
2660
|
this.showStatus(`Session compacted ${times}`);
|
|
2636
2661
|
}
|
|
2637
2662
|
}
|
|
2663
|
+
renderProjectTrustWarningIfNeeded() {
|
|
2664
|
+
if (this.settingsManager.isProjectTrusted() || !hasProjectTrustInputs(this.sessionManager.getCwd())) {
|
|
2665
|
+
return;
|
|
2666
|
+
}
|
|
2667
|
+
if (this.chatContainer.children.length > 0) {
|
|
2668
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
2669
|
+
}
|
|
2670
|
+
this.chatContainer.addChild(new Text(theme.fg("warning", "This project is not trusted. Project instructions (AGENTS.md/CLAUDE.md), .pi resources, and project packages are ignored. Use /trust to save a trust decision, then restart pi."), 1, 0));
|
|
2671
|
+
}
|
|
2638
2672
|
async getUserInput() {
|
|
2639
2673
|
const queuedInput = this.pendingUserInputs.shift();
|
|
2640
2674
|
if (queuedInput !== undefined) {
|
|
@@ -3450,6 +3484,51 @@ export class InteractiveMode {
|
|
|
3450
3484
|
// Ignore auth lookup failures for warning-only checks.
|
|
3451
3485
|
}
|
|
3452
3486
|
}
|
|
3487
|
+
maybeSaveImplicitProjectTrustAfterReload() {
|
|
3488
|
+
const cwd = this.sessionManager.getCwd();
|
|
3489
|
+
if (this.autoTrustOnReloadCwd !== cwd) {
|
|
3490
|
+
return false;
|
|
3491
|
+
}
|
|
3492
|
+
if (!this.settingsManager.isProjectTrusted() || !hasProjectConfigDir(cwd)) {
|
|
3493
|
+
return false;
|
|
3494
|
+
}
|
|
3495
|
+
const trustStore = new ProjectTrustStore(this.runtimeHost.services.agentDir);
|
|
3496
|
+
try {
|
|
3497
|
+
if (trustStore.get(cwd) !== null) {
|
|
3498
|
+
this.autoTrustOnReloadCwd = undefined;
|
|
3499
|
+
return false;
|
|
3500
|
+
}
|
|
3501
|
+
trustStore.set(cwd, true);
|
|
3502
|
+
this.autoTrustOnReloadCwd = undefined;
|
|
3503
|
+
return true;
|
|
3504
|
+
}
|
|
3505
|
+
catch (error) {
|
|
3506
|
+
this.showWarning(`Could not save project trust after reload: ${error instanceof Error ? error.message : String(error)}`);
|
|
3507
|
+
return false;
|
|
3508
|
+
}
|
|
3509
|
+
}
|
|
3510
|
+
showTrustSelector() {
|
|
3511
|
+
const cwd = this.sessionManager.getCwd();
|
|
3512
|
+
const trustStore = new ProjectTrustStore(this.runtimeHost.services.agentDir);
|
|
3513
|
+
const savedDecision = trustStore.get(cwd);
|
|
3514
|
+
this.showSelector((done) => {
|
|
3515
|
+
const selector = new TrustSelectorComponent({
|
|
3516
|
+
cwd,
|
|
3517
|
+
savedDecision,
|
|
3518
|
+
projectTrusted: this.settingsManager.isProjectTrusted(),
|
|
3519
|
+
onSelect: (trusted) => {
|
|
3520
|
+
trustStore.set(cwd, trusted);
|
|
3521
|
+
done();
|
|
3522
|
+
this.showStatus(`Saved trust decision: ${trusted ? "trusted" : "untrusted"}. Restart pi for this to take effect.`);
|
|
3523
|
+
},
|
|
3524
|
+
onCancel: () => {
|
|
3525
|
+
done();
|
|
3526
|
+
this.ui.requestRender();
|
|
3527
|
+
},
|
|
3528
|
+
});
|
|
3529
|
+
return { component: selector, focus: selector };
|
|
3530
|
+
});
|
|
3531
|
+
}
|
|
3453
3532
|
showModelSelector(initialSearchInput) {
|
|
3454
3533
|
this.showSelector((done) => {
|
|
3455
3534
|
const selector = new ModelSelectorComponent(this.ui, this.session.model, this.settingsManager, this.session.modelRegistry, this.session.scopedModels, async (model) => {
|
|
@@ -3728,6 +3807,7 @@ export class InteractiveMode {
|
|
|
3728
3807
|
try {
|
|
3729
3808
|
const result = await this.runtimeHost.switchSession(sessionPath, {
|
|
3730
3809
|
withSession: options?.withSession,
|
|
3810
|
+
projectTrustContextFactory: (cwd) => this.createProjectTrustContext(cwd),
|
|
3731
3811
|
});
|
|
3732
3812
|
if (result.cancelled) {
|
|
3733
3813
|
return result;
|
|
@@ -3746,6 +3826,7 @@ export class InteractiveMode {
|
|
|
3746
3826
|
const result = await this.runtimeHost.switchSession(sessionPath, {
|
|
3747
3827
|
cwdOverride: selectedCwd,
|
|
3748
3828
|
withSession: options?.withSession,
|
|
3829
|
+
projectTrustContextFactory: (cwd) => this.createProjectTrustContext(cwd),
|
|
3749
3830
|
});
|
|
3750
3831
|
if (result.cancelled) {
|
|
3751
3832
|
return result;
|
|
@@ -4144,11 +4225,14 @@ export class InteractiveMode {
|
|
|
4144
4225
|
force: false,
|
|
4145
4226
|
showDiagnosticsWhenQuiet: true,
|
|
4146
4227
|
});
|
|
4228
|
+
const savedImplicitProjectTrust = this.maybeSaveImplicitProjectTrustAfterReload();
|
|
4147
4229
|
const modelsJsonError = this.session.modelRegistry.getError();
|
|
4148
4230
|
if (modelsJsonError) {
|
|
4149
4231
|
this.showError(`models.json error: ${modelsJsonError}`);
|
|
4150
4232
|
}
|
|
4151
|
-
this.showStatus(
|
|
4233
|
+
this.showStatus(savedImplicitProjectTrust
|
|
4234
|
+
? "Reloaded keybindings, extensions, skills, prompts, themes; saved project trust"
|
|
4235
|
+
: "Reloaded keybindings, extensions, skills, prompts, themes");
|
|
4152
4236
|
}
|
|
4153
4237
|
catch (error) {
|
|
4154
4238
|
dismissReloadBox(previousEditor);
|