@pi-minimal/plan-mode 0.0.0-stage → 1.0.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/LICENSE +21 -0
- package/README.md +23 -2
- package/index.ts +42 -0
- package/package.json +39 -4
- package/prompts.ts +9 -0
- package/settings.ts +18 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 pi-minimal contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @pi-minimal/plan-mode
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`/plan` toggles plan mode. When on, the system prompt tells the agent to stay
|
|
4
|
+
read-only and output a plan. Nothing is blocked: the agent is trusted to obey.
|
|
5
|
+
|
|
6
|
+
## Install
|
|
7
|
+
|
|
8
|
+
```sh
|
|
9
|
+
pi install ~/Code/pi-minimal/plan-mode
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Settings
|
|
13
|
+
|
|
14
|
+
Put settings in `~/.pi/agent/settings.json` (global) or `.pi/settings.json`
|
|
15
|
+
(project), under `"pi-minimal"."plan-mode"`. Merge the keys; do not overwrite
|
|
16
|
+
the file. Settings are read at session start (use `/reload`).
|
|
17
|
+
|
|
18
|
+
| Key | Type | Default | Meaning |
|
|
19
|
+
| --- | --- | --- | --- |
|
|
20
|
+
| `keyboardShortcut` | string (key id) | `ctrl+alt+p` | Shortcut that toggles plan mode. No pi default uses it. Some terminals need Alt/Option set as Meta, and multiplexers such as tmux may drop modifiers. If it does not work, pick another key. |
|
|
21
|
+
|
|
22
|
+
```json
|
|
23
|
+
{ "pi-minimal": { "plan-mode": { "keyboardShortcut": "ctrl+alt+o" } } }
|
|
24
|
+
```
|
package/index.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { PROMPT_PLAN_MODE_OFF, PROMPT_PLAN_MODE_ON, PROMPT_PLAN_MODE_REMINDER } from "./prompts.js";
|
|
3
|
+
import { loadSettings } from "./settings.js";
|
|
4
|
+
|
|
5
|
+
export default function (pi: ExtensionAPI) {
|
|
6
|
+
let on = false;
|
|
7
|
+
let used = false; // only sessions that used /plan at least once get a section in the prompt.
|
|
8
|
+
|
|
9
|
+
const togglePlanMode = (ctx: ExtensionContext) => {
|
|
10
|
+
on = !on;
|
|
11
|
+
used ||= on;
|
|
12
|
+
ctx.ui.setStatus("plan-mode", on ? ctx.ui.theme.fg("warning", "⏸ plan") : undefined);
|
|
13
|
+
ctx.ui.notify(`Plan mode ${on ? "ON" : "OFF"} (from your next message)`, "info");
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
pi.registerCommand("plan", {
|
|
17
|
+
description: "Toggle read-only plan mode (prompt-enforced)",
|
|
18
|
+
handler: async (_args, ctx) => togglePlanMode(ctx),
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// Read at session_start: settings are not available while the extension loads.
|
|
22
|
+
pi.on("session_start", () => {
|
|
23
|
+
const { keyboardShortcut } = loadSettings(pi);
|
|
24
|
+
pi.registerShortcut(keyboardShortcut, { description: "Toggle plan mode", handler: togglePlanMode });
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// pi diffs the section into the transcript only when its text changes.
|
|
28
|
+
pi.on("before_agent_start", (event) => {
|
|
29
|
+
if (used) event.systemPromptOptions.sections.plan_mode = on ? PROMPT_PLAN_MODE_ON : PROMPT_PLAN_MODE_OFF;
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// Short reminder (not stored in the transcript) to avoid the agent forgetting that plan mode is on during long runs.
|
|
33
|
+
pi.on("context", (event) => {
|
|
34
|
+
if (!on) return;
|
|
35
|
+
return {
|
|
36
|
+
messages: [
|
|
37
|
+
...event.messages,
|
|
38
|
+
{ role: "user", content: [{ type: "text", text: PROMPT_PLAN_MODE_REMINDER }], timestamp: Date.now() },
|
|
39
|
+
],
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,41 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-minimal/plan-mode",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Minimal plan mode for pi: /plan toggles a read-only instruction in the system prompt.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"pi-package",
|
|
7
|
+
"pi-extension"
|
|
8
|
+
],
|
|
9
|
+
"pi": {
|
|
10
|
+
"extensions": [
|
|
11
|
+
"./index.ts"
|
|
12
|
+
]
|
|
13
|
+
},
|
|
14
|
+
"peerDependencies": {
|
|
15
|
+
"@earendil-works/pi-coding-agent": "*"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@earendil-works/pi-coding-agent": "^1.2.0",
|
|
19
|
+
"@types/node": "^24.0.0",
|
|
20
|
+
"typescript": "^5.9.0"
|
|
21
|
+
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"check": "tsc -p ."
|
|
24
|
+
},
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "git+ssh://git@github.com/EviHex/pi-minimal.git",
|
|
28
|
+
"directory": "plan-mode"
|
|
29
|
+
},
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"files": [
|
|
32
|
+
"index.ts",
|
|
33
|
+
"prompts.ts",
|
|
34
|
+
"settings.ts",
|
|
35
|
+
"README.md",
|
|
36
|
+
"LICENSE"
|
|
37
|
+
],
|
|
38
|
+
"publishConfig": {
|
|
39
|
+
"access": "public"
|
|
40
|
+
}
|
|
41
|
+
}
|
package/prompts.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const PROMPT_PLAN_MODE_ON = `PLAN MODE is ON. Read and investigate only. Change nothing: no files, repo state, processes, docs, or remote data.
|
|
2
|
+
- Allowed: reading files, searching, read-only commands (ls, rg, cat, git/jj log|diff|status), and read-only API/MCP calls (get, list, search, read-only queries).
|
|
3
|
+
- Forbidden: anything that writes: edit/write tools, sed -i, writing to files with > or >> or tee (/dev/null or /tmp is fine), rm/mv/cp, installs, commits or checkouts, kill, POST/PUT/PATCH/DELETE requests, and MCP/API calls that create, update, or delete (databases, configs, Datadog dashboards, monitors, documentation). Do not delegate such work to subagents.
|
|
4
|
+
- If you are not sure a command is read-only, do not run it. Put it in the plan.
|
|
5
|
+
- The user runs /plan to exit plan mode before you execute it.`;
|
|
6
|
+
|
|
7
|
+
export const PROMPT_PLAN_MODE_OFF = "Plan mode is OFF. You may read and write freely.";
|
|
8
|
+
|
|
9
|
+
export const PROMPT_PLAN_MODE_REMINDER = "<system-reminder>Plan mode is ON: no state-altering action allowed.</system-reminder>";
|
package/settings.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import type { KeyId } from "@earendil-works/pi-tui";
|
|
3
|
+
|
|
4
|
+
/** What the user can configure in settings.json, under "pi-minimal"."plan-mode" */
|
|
5
|
+
export interface PlanModeSettings {
|
|
6
|
+
/** Keyboard shortcut to toggle plan mode. */
|
|
7
|
+
keyboardShortcut: KeyId;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/** Fallback when keys are not configured */
|
|
11
|
+
const DEFAULT_SETTINGS: PlanModeSettings = {
|
|
12
|
+
keyboardShortcut: "ctrl+alt+p"
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export function loadSettings(pi: ExtensionAPI): PlanModeSettings {
|
|
16
|
+
const file = pi.getSettings() as { "pi-minimal"?: { "plan-mode"?: Partial<PlanModeSettings> } };
|
|
17
|
+
return { ...DEFAULT_SETTINGS, ...file["pi-minimal"]?.["plan-mode"] };
|
|
18
|
+
}
|