lsd-pi 1.1.10 → 1.2.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/dist/resources/extensions/slash-commands/index.js +2 -0
- package/dist/resources/extensions/slash-commands/init.js +47 -0
- package/dist/resources/extensions/slash-commands/plan.js +231 -50
- package/dist/resources/extensions/slash-commands/tools.js +14 -27
- package/dist/resources/extensions/subagent/index.js +5 -10
- package/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +11 -5
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader-lsd-md.test.js +59 -7
- package/packages/pi-coding-agent/dist/core/resource-loader-lsd-md.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js +4 -4
- package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.d.ts +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +18 -7
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.test.js +80 -0
- package/packages/pi-coding-agent/dist/core/sdk.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +12 -5
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +23 -9
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +8 -4
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +32 -5
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +8 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +34 -25
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session.ts +13 -5
- package/packages/pi-coding-agent/src/core/resource-loader-lsd-md.test.ts +67 -7
- package/packages/pi-coding-agent/src/core/resource-loader.ts +4 -4
- package/packages/pi-coding-agent/src/core/sdk.test.ts +100 -0
- package/packages/pi-coding-agent/src/core/sdk.ts +23 -8
- package/packages/pi-coding-agent/src/core/settings-manager.ts +36 -15
- package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +41 -10
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +11 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +43 -27
- package/pkg/package.json +1 -1
- package/src/resources/extensions/slash-commands/index.ts +2 -0
- package/src/resources/extensions/slash-commands/init.ts +55 -0
- package/src/resources/extensions/slash-commands/plan.ts +268 -52
- package/src/resources/extensions/slash-commands/tools.ts +15 -29
- package/src/resources/extensions/subagent/index.ts +5 -10
|
@@ -178,6 +178,17 @@ export interface InteractiveModeOptions {
|
|
|
178
178
|
runSetupWizard?: () => Promise<void>;
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
+
function getToolNamesForProfile(
|
|
182
|
+
profile: "balanced" | "full",
|
|
183
|
+
editMode: "standard" | "hashline",
|
|
184
|
+
availableToolNames: string[],
|
|
185
|
+
): string[] {
|
|
186
|
+
const balancedToolNames = editMode === "hashline"
|
|
187
|
+
? ["hashline_read", "bash", "hashline_edit", "write", "lsp", "bg_shell", "tool_search", "tool_enable", "Skill", "subagent", "await_subagent", "ask_user_questions"]
|
|
188
|
+
: ["read", "bash", "edit", "write", "lsp", "bg_shell", "tool_search", "tool_enable", "Skill", "subagent", "await_subagent", "ask_user_questions"];
|
|
189
|
+
return profile === "full" ? availableToolNames : balancedToolNames;
|
|
190
|
+
}
|
|
191
|
+
|
|
181
192
|
export class InteractiveMode {
|
|
182
193
|
private session: AgentSession;
|
|
183
194
|
private ui: TUI;
|
|
@@ -2405,13 +2416,13 @@ export class InteractiveMode {
|
|
|
2405
2416
|
await handleAgentEvent(this as any, event);
|
|
2406
2417
|
}
|
|
2407
2418
|
|
|
2408
|
-
private getLatestPlanModeState(): { active?: boolean; latestPlanPath?: string } | undefined {
|
|
2419
|
+
private getLatestPlanModeState(): { active?: boolean; latestPlanPath?: string; approvalStatus?: string } | undefined {
|
|
2409
2420
|
try {
|
|
2410
2421
|
const entries = this.session.sessionManager.getEntries();
|
|
2411
2422
|
for (let i = entries.length - 1; i >= 0; i--) {
|
|
2412
2423
|
const entry = entries[i];
|
|
2413
2424
|
if (entry.type === "custom" && entry.customType === "plan-mode-state" && entry.data && typeof entry.data === "object") {
|
|
2414
|
-
return entry.data as { active?: boolean; latestPlanPath?: string };
|
|
2425
|
+
return entry.data as { active?: boolean; latestPlanPath?: string; approvalStatus?: string };
|
|
2415
2426
|
}
|
|
2416
2427
|
}
|
|
2417
2428
|
} catch {
|
|
@@ -2421,17 +2432,26 @@ export class InteractiveMode {
|
|
|
2421
2432
|
}
|
|
2422
2433
|
|
|
2423
2434
|
private getPlanModeEditorBadge(): string {
|
|
2435
|
+
// Show badge when actively in plan mode OR when plan is approved (executing)
|
|
2436
|
+
// Only clear when plan is cancelled or there's no plan state at all.
|
|
2437
|
+
const permMode = getPermissionMode();
|
|
2424
2438
|
const planState = this.getLatestPlanModeState();
|
|
2425
|
-
if (!planState?.active) return "";
|
|
2426
2439
|
|
|
2427
|
-
const
|
|
2440
|
+
const inPlanMode = permMode === "plan";
|
|
2441
|
+
const planApproved = planState?.approvalStatus === "approved" && !planState?.active;
|
|
2442
|
+
|
|
2443
|
+
if (!inPlanMode && !planApproved) return "";
|
|
2444
|
+
|
|
2445
|
+
const planName = planState?.latestPlanPath
|
|
2428
2446
|
? path.basename(planState.latestPlanPath).replace(/\.md$/i, "")
|
|
2429
2447
|
: "draft";
|
|
2430
|
-
const badgeText =
|
|
2448
|
+
const badgeText = inPlanMode
|
|
2449
|
+
? ` plan ${planName} · /plan to show plan `
|
|
2450
|
+
: ` plan ${planName} · executing `;
|
|
2431
2451
|
|
|
2432
2452
|
// Deterministic "random" color per plan so it feels varied without flickering.
|
|
2433
2453
|
const palette = [18, 19, 20, 24, 25, 26, 27, 54, 55, 56, 57, 60, 88, 89, 90, 124, 125, 126, 160, 161, 162];
|
|
2434
|
-
const seed = planState
|
|
2454
|
+
const seed = planState?.latestPlanPath ?? planName;
|
|
2435
2455
|
const digest = crypto.createHash("sha256").update(seed).digest();
|
|
2436
2456
|
const bg256 = palette[digest[0] % palette.length] ?? 25;
|
|
2437
2457
|
|
|
@@ -3407,11 +3427,12 @@ export class InteractiveMode {
|
|
|
3407
3427
|
planModeReasoningModel: this.settingsManager.getPlanModeReasoningModel() ?? "default",
|
|
3408
3428
|
planModeReviewModel: this.settingsManager.getPlanModeReviewModel() ?? "default",
|
|
3409
3429
|
planModeCodingModel: this.settingsManager.getPlanModeCodingModel() ?? "default",
|
|
3430
|
+
autoSuggestPlanMode: this.settingsManager.getAutoSuggestPlanMode(),
|
|
3431
|
+
autoSwitchPlanModel: this.settingsManager.getAutoSwitchPlanModel(),
|
|
3410
3432
|
showImages: this.settingsManager.getShowImages(),
|
|
3411
3433
|
autoResizeImages: this.settingsManager.getImageAutoResize(),
|
|
3412
3434
|
blockImages: this.settingsManager.getBlockImages(),
|
|
3413
3435
|
enableSkillCommands: this.settingsManager.getEnableSkillCommands(),
|
|
3414
|
-
toolSearch: this.settingsManager.getToolSearch(),
|
|
3415
3436
|
toolProfile: this.settingsManager.getToolProfile(),
|
|
3416
3437
|
codexRotate: this.settingsManager.getCodexRotate(),
|
|
3417
3438
|
cacheTimer: this.settingsManager.getCacheTimer(),
|
|
@@ -3420,6 +3441,7 @@ export class InteractiveMode {
|
|
|
3420
3441
|
followUpMode: this.session.followUpMode,
|
|
3421
3442
|
transport: this.settingsManager.getTransport(),
|
|
3422
3443
|
thinkingLevel: this.session.thinkingLevel,
|
|
3444
|
+
anthropicAdaptiveByDefault: this.settingsManager.getAnthropicAdaptiveByDefault(),
|
|
3423
3445
|
availableThinkingLevels: this.session.getAvailableThinkingLevels(),
|
|
3424
3446
|
currentTheme: this.settingsManager.getTheme() || "dark",
|
|
3425
3447
|
currentThemeAccent: this.settingsManager.getThemeAccent() || "default",
|
|
@@ -3554,6 +3576,14 @@ export class InteractiveMode {
|
|
|
3554
3576
|
`Plan coding model: ${modelRef === "default" ? "use current/default model" : modelRef}`,
|
|
3555
3577
|
);
|
|
3556
3578
|
},
|
|
3579
|
+
onAutoSuggestPlanModeChange: (enabled) => {
|
|
3580
|
+
this.settingsManager.setAutoSuggestPlanMode(enabled);
|
|
3581
|
+
this.showStatus(`Auto-suggest plan mode: ${enabled ? "enabled" : "disabled"}`);
|
|
3582
|
+
},
|
|
3583
|
+
onAutoSwitchPlanModelChange: (enabled) => {
|
|
3584
|
+
this.settingsManager.setAutoSwitchPlanModel(enabled);
|
|
3585
|
+
this.showStatus(`OpusPlan mode: ${enabled ? "enabled" : "disabled"}`);
|
|
3586
|
+
},
|
|
3557
3587
|
onShowImagesChange: (enabled) => {
|
|
3558
3588
|
this.settingsManager.setShowImages(enabled);
|
|
3559
3589
|
for (const child of this.chatContainer.children) {
|
|
@@ -3572,28 +3602,10 @@ export class InteractiveMode {
|
|
|
3572
3602
|
this.settingsManager.setEnableSkillCommands(enabled);
|
|
3573
3603
|
this.setupAutocomplete();
|
|
3574
3604
|
},
|
|
3575
|
-
onToolSearchChange: (enabled) => {
|
|
3576
|
-
const profile = enabled ? "minimal" : "balanced";
|
|
3577
|
-
this.settingsManager.setToolProfile(profile);
|
|
3578
|
-
const nextActiveToolNames = profile === "minimal"
|
|
3579
|
-
? (this.session.editMode === "hashline"
|
|
3580
|
-
? ["hashline_read", "bash", "lsp", "tool_search", "tool_enable"]
|
|
3581
|
-
: ["read", "bash", "lsp", "tool_search", "tool_enable"])
|
|
3582
|
-
: (this.session.editMode === "hashline"
|
|
3583
|
-
? ["hashline_read", "bash", "hashline_edit", "write", "lsp", "bg_shell", "tool_search", "tool_enable", "Skill", "subagent", "await_subagent"]
|
|
3584
|
-
: ["read", "bash", "edit", "write", "lsp", "bg_shell", "tool_search", "tool_enable", "Skill", "subagent", "await_subagent"]);
|
|
3585
|
-
this.session.setActiveToolsByName(nextActiveToolNames);
|
|
3586
|
-
this.showStatus(`Tool profile: ${profile}`);
|
|
3587
|
-
},
|
|
3588
3605
|
onToolProfileChange: (profile) => {
|
|
3589
3606
|
this.settingsManager.setToolProfile(profile);
|
|
3590
|
-
const
|
|
3591
|
-
|
|
3592
|
-
? ["hashline_read", "bash", "lsp", "tool_search", "tool_enable"]
|
|
3593
|
-
: ["read", "bash", "lsp", "tool_search", "tool_enable"])
|
|
3594
|
-
: (this.session.editMode === "hashline"
|
|
3595
|
-
? ["hashline_read", "bash", "hashline_edit", "write", "lsp", "bg_shell", "tool_search", "tool_enable", "Skill", "subagent", "await_subagent"]
|
|
3596
|
-
: ["read", "bash", "edit", "write", "lsp", "bg_shell", "tool_search", "tool_enable", "Skill", "subagent", "await_subagent"]);
|
|
3607
|
+
const allToolNames = this.session.getAllTools().map((tool) => tool.name);
|
|
3608
|
+
const nextActiveToolNames = getToolNamesForProfile(profile, this.session.editMode, allToolNames);
|
|
3597
3609
|
this.session.setActiveToolsByName(nextActiveToolNames);
|
|
3598
3610
|
this.showStatus(`Tool profile: ${profile}`);
|
|
3599
3611
|
},
|
|
@@ -3642,6 +3654,10 @@ export class InteractiveMode {
|
|
|
3642
3654
|
this.footer.invalidate();
|
|
3643
3655
|
this.updateEditorBorderColor();
|
|
3644
3656
|
},
|
|
3657
|
+
onAnthropicAdaptiveByDefaultChange: (enabled) => {
|
|
3658
|
+
this.settingsManager.setAnthropicAdaptiveByDefault(enabled);
|
|
3659
|
+
this.showStatus(`Anthropic adaptive default: ${enabled ? "enabled" : "disabled"}`);
|
|
3660
|
+
},
|
|
3645
3661
|
onThemeChange: (themeName) => {
|
|
3646
3662
|
const result = setTheme(themeName, true, this.settingsManager.getThemeAccent());
|
|
3647
3663
|
this.settingsManager.setTheme(themeName);
|
package/pkg/package.json
CHANGED
|
@@ -2,6 +2,7 @@ import type { ExtensionAPI } from "@gsd/pi-coding-agent";
|
|
|
2
2
|
import auditCommand from "./audit.js";
|
|
3
3
|
import clearCommand from "./clear.js";
|
|
4
4
|
import contextCommand from "./context.js";
|
|
5
|
+
import initCommand from "./init.js";
|
|
5
6
|
import planCommand from "./plan.js";
|
|
6
7
|
import toolSearchExtension from "./tools.js";
|
|
7
8
|
|
|
@@ -9,6 +10,7 @@ export default function slashCommands(pi: ExtensionAPI) {
|
|
|
9
10
|
auditCommand(pi);
|
|
10
11
|
clearCommand(pi);
|
|
11
12
|
contextCommand(pi);
|
|
13
|
+
initCommand(pi);
|
|
12
14
|
planCommand(pi);
|
|
13
15
|
toolSearchExtension(pi);
|
|
14
16
|
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { getAgentDir, type ExtensionAPI, type ExtensionCommandContext } from "@gsd/pi-coding-agent";
|
|
2
|
+
import { existsSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { join, resolve } from "node:path";
|
|
4
|
+
|
|
5
|
+
const STARTER_CONTENT = `# Project Context
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
- Add a short description of this project and its purpose.
|
|
9
|
+
|
|
10
|
+
## Commands
|
|
11
|
+
- Build:
|
|
12
|
+
- Test:
|
|
13
|
+
- Lint:
|
|
14
|
+
|
|
15
|
+
## Conventions
|
|
16
|
+
- Add coding conventions, architecture notes, and review expectations.
|
|
17
|
+
`;
|
|
18
|
+
|
|
19
|
+
function ensureFile(filePath: string): "created" | "exists" {
|
|
20
|
+
if (existsSync(filePath)) {
|
|
21
|
+
return "exists";
|
|
22
|
+
}
|
|
23
|
+
writeFileSync(filePath, STARTER_CONTENT, "utf-8");
|
|
24
|
+
return "created";
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default function initCommand(pi: ExtensionAPI) {
|
|
28
|
+
pi.registerCommand("init", {
|
|
29
|
+
description: "Initialize global and project LSD.md files if they do not exist",
|
|
30
|
+
async handler(_args: string, ctx: ExtensionCommandContext) {
|
|
31
|
+
const globalPath = resolve(getAgentDir(), "..", "LSD.md");
|
|
32
|
+
const projectPath = join(ctx.cwd, "LSD.md");
|
|
33
|
+
|
|
34
|
+
const globalStatus = ensureFile(globalPath);
|
|
35
|
+
const projectStatus = ensureFile(projectPath);
|
|
36
|
+
|
|
37
|
+
await ctx.reload();
|
|
38
|
+
|
|
39
|
+
const lines = ["Initialized LSD.md files", ""];
|
|
40
|
+
lines.push(`Global: ${globalStatus === "created" ? "created" : "exists"} ${globalPath}`);
|
|
41
|
+
lines.push(`Project: ${projectStatus === "created" ? "created" : "exists"} ${projectPath}`);
|
|
42
|
+
|
|
43
|
+
if (globalStatus === "exists" && projectStatus === "exists") {
|
|
44
|
+
lines.push("");
|
|
45
|
+
lines.push("Nothing changed.");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
pi.sendMessage({
|
|
49
|
+
customType: "init:report",
|
|
50
|
+
content: lines.join("\n"),
|
|
51
|
+
display: true,
|
|
52
|
+
});
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
}
|