[Sync] Pi chat mode + plan-mode rework, fastfetch icons, Claude statusline, fl KDE shortcuts
Re-export of the private tree at b5580f8 (2026-11-11). - pi: new chat-mode extension, plan-mode rework, README and settings updates, version bump - fastfetch: Packages/Display/WM/GPU/Memory key icons moved off the legacy Nerd Fonts v2 Material range (blank on v3 fonts) to Font Awesome glyphs - claude: statusline runs git with --no-optional-locks, model default, pr-loop skill note, gh sync fix - fl: kglobalshortcutsrc update
This commit is contained in:
1 parent
47166d877f
commit
78354d9afe
9 files changed
+255
-41
No files matched your search
@@ -178,17 +178,35 @@ export default function planModeExtension(pi: ExtensionAPI): void {
|
||||
handler: async (ctx) => togglePlanMode(ctx),
|
||||
});
|
||||
|
||||
// Block destructive bash commands in plan mode
|
||||
pi.on("tool_call", async (event) => {
|
||||
// LOCAL EDIT: upstream blocks every bash command outside the read-only allowlist. That
|
||||
// allowlist is coarse (any `>` counts as a write, so `free -h 2>/dev/null` is refused),
|
||||
// and a refusal sends the model straight back to writing a plan around the gap. So ask
|
||||
// instead: allowlisted commands still run unprompted, anything else needs a Yes. With no
|
||||
// UI (`pi -p`) nothing can answer, so that case still blocks as upstream does. The
|
||||
// "Bash runs read-only allowlisted commands freely…" line in the prompt below goes with it.
|
||||
pi.on("tool_call", async (event, ctx) => {
|
||||
if (!planModeEnabled || event.toolName !== "bash") return;
|
||||
|
||||
const command = event.input.command as string;
|
||||
if (!isSafeCommand(command)) {
|
||||
if (isSafeCommand(command)) return;
|
||||
|
||||
if (!ctx.hasUI) {
|
||||
return {
|
||||
block: true,
|
||||
reason: `Plan mode: command blocked (not allowlisted). Use /plan to disable plan mode first.\nCommand: ${command}`,
|
||||
};
|
||||
}
|
||||
|
||||
const choice = await ctx.ui.select(
|
||||
`⏸ Plan mode: this command is not on the read-only allowlist:\n\n ${command}\n\nAllow?`,
|
||||
["Yes", "No"],
|
||||
);
|
||||
if (choice !== "Yes") {
|
||||
return {
|
||||
block: true,
|
||||
reason: "Plan mode: the user declined this command. Do not retry it; continue with what you have, or ask the user.",
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// Filter out stale plan mode context when not in plan mode
|
||||
@@ -227,7 +245,7 @@ You are in plan mode - a read-only exploration mode for safe code analysis.
|
||||
Restrictions:
|
||||
- Built-in edit and write tools are disabled
|
||||
- Other currently active tools remain available
|
||||
- Bash is restricted to an allowlist of read-only commands
|
||||
- Bash runs read-only allowlisted commands freely; any other command asks the user for approval first
|
||||
|
||||
Ask clarifying questions using the questionnaire tool.
|
||||
|
||||
@@ -295,16 +313,14 @@ After completing a step, include a [DONE:n] tag in your response.`,
|
||||
|
||||
if (!planModeEnabled || !ctx.hasUI) return;
|
||||
|
||||
// Extract todos from last assistant message
|
||||
// LOCAL EDIT: upstream kept the previous plan's steps whenever the latest reply had
|
||||
// none, so once one plan had been written, every later answer in plan mode (a plain
|
||||
// question, a command's output) re-opened "what next?" with that stale plan. Only
|
||||
// offer to execute a plan that the reply which just finished actually wrote.
|
||||
const lastAssistant = [...event.messages].reverse().find(isAssistantMessage);
|
||||
if (lastAssistant) {
|
||||
const extracted = extractTodoItems(getTextContent(lastAssistant));
|
||||
if (extracted.length > 0) {
|
||||
todoItems = extracted;
|
||||
}
|
||||
}
|
||||
|
||||
if (todoItems.length === 0) return;
|
||||
const extracted = lastAssistant ? extractTodoItems(getTextContent(lastAssistant)) : [];
|
||||
if (extracted.length === 0) return;
|
||||
todoItems = extracted;
|
||||
persistState();
|
||||
|
||||
// Show plan steps and prompt for next action
|
||||
|
||||
Reference in new issue
Block a user