@yusukeshib/pi-stash 0.2.0 → 0.3.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/README.md +10 -0
- package/extensions/index.ts +62 -33
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -52,6 +52,16 @@ pi install npm:@yusukeshib/pi-stash
|
|
|
52
52
|
| `/stash` | **Pop** — pick a saved entry, insert it into the editor, and remove it from the stash. Run repeatedly to stack several fragments together. |
|
|
53
53
|
| `/stash-clear` | Delete every stashed entry in this session (with confirm). |
|
|
54
54
|
|
|
55
|
+
### Shortcut
|
|
56
|
+
|
|
57
|
+
| Key | Action |
|
|
58
|
+
|-----|--------|
|
|
59
|
+
| `Ctrl+S` | If the editor has text, **push** it onto the stash and clear the editor. If the editor is empty, **pop** a saved entry into it. |
|
|
60
|
+
|
|
61
|
+
`Ctrl+S` is the one-key way to do what `/stash` does: park the prompt you're
|
|
62
|
+
halfway through typing, or pull one back — without typing the command. Rebind it
|
|
63
|
+
in `~/.pi/agent/keybindings.json` if it clashes with another shortcut.
|
|
64
|
+
|
|
55
65
|
While the stash is non-empty, a red `stash:N` badge is shown in the footer so
|
|
56
66
|
you never forget you have prompts parked.
|
|
57
67
|
|
package/extensions/index.ts
CHANGED
|
@@ -12,6 +12,12 @@
|
|
|
12
12
|
* remove it from the stash. Run repeatedly to stack fragments.
|
|
13
13
|
* /stash-clear Delete every entry (with confirm).
|
|
14
14
|
*
|
|
15
|
+
* Shortcut:
|
|
16
|
+
* Ctrl+S If the editor holds text, push it onto the stash (and clear
|
|
17
|
+
* the editor); otherwise pop a saved entry into the editor.
|
|
18
|
+
* A one-key way to park the prompt you're typing, or pull one
|
|
19
|
+
* back, without typing `/stash`.
|
|
20
|
+
*
|
|
15
21
|
* Storage: stash entries are persisted INSIDE the session itself via custom
|
|
16
22
|
* session entries (`pi.appendEntry`). Each session has its own stash, it
|
|
17
23
|
* survives restarts/resume, and it follows branching (fork/clone) correctly.
|
|
@@ -73,44 +79,67 @@ export default function (pi: ExtensionAPI) {
|
|
|
73
79
|
updateStatus(ctx);
|
|
74
80
|
});
|
|
75
81
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
if (text) {
|
|
83
|
-
if (entries.some((e) => e.text === text)) {
|
|
84
|
-
ctx.ui.notify("Already in stash", "info");
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
entries.push({ text, addedAt: Date.now() });
|
|
88
|
-
persist();
|
|
89
|
-
updateStatus(ctx);
|
|
90
|
-
ctx.ui.notify(`Stashed (${entries.length} total)`, "info");
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
82
|
+
/**
|
|
83
|
+
* Core stash behaviour shared by the `/stash` command and the Ctrl+S
|
|
84
|
+
* shortcut. With text → push; without text → pop into the editor.
|
|
85
|
+
*/
|
|
86
|
+
async function runStash(rawText: string, ctx: ExtensionContext): Promise<void> {
|
|
87
|
+
const text = (rawText ?? "").trim();
|
|
93
88
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
89
|
+
// PUSH: /stash <text>
|
|
90
|
+
if (text) {
|
|
91
|
+
if (entries.some((e) => e.text === text)) {
|
|
92
|
+
ctx.ui.notify("Already in stash", "info");
|
|
97
93
|
return;
|
|
98
94
|
}
|
|
99
|
-
|
|
100
|
-
const choice = await ctx.ui.select("Pop prompt:", labels);
|
|
101
|
-
if (choice === undefined) return; // cancelled / timed out
|
|
102
|
-
const idx = labels.indexOf(choice);
|
|
103
|
-
if (idx < 0) return;
|
|
104
|
-
|
|
105
|
-
const chosen = entries[idx].text;
|
|
106
|
-
const current = ctx.ui.getEditorText() ?? "";
|
|
107
|
-
const next = current.trim().length > 0 ? `${current}\n${chosen}` : chosen;
|
|
108
|
-
ctx.ui.setEditorText(next);
|
|
109
|
-
|
|
110
|
-
// pop = remove the chosen entry
|
|
111
|
-
entries.splice(idx, 1);
|
|
95
|
+
entries.push({ text, addedAt: Date.now() });
|
|
112
96
|
persist();
|
|
113
97
|
updateStatus(ctx);
|
|
98
|
+
ctx.ui.notify(`Stashed (${entries.length} total)`, "info");
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// POP: /stash → pick, insert into editor, remove from stash
|
|
103
|
+
if (entries.length === 0) {
|
|
104
|
+
ctx.ui.notify("Stash is empty. Add one with /stash <text>", "info");
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const labels = entries.map((e, i) => preview(e.text, i));
|
|
108
|
+
const choice = await ctx.ui.select("Pop prompt:", labels);
|
|
109
|
+
if (choice === undefined) return; // cancelled / timed out
|
|
110
|
+
const idx = labels.indexOf(choice);
|
|
111
|
+
if (idx < 0) return;
|
|
112
|
+
|
|
113
|
+
const chosen = entries[idx].text;
|
|
114
|
+
const current = ctx.ui.getEditorText() ?? "";
|
|
115
|
+
const next = current.trim().length > 0 ? `${current}\n${chosen}` : chosen;
|
|
116
|
+
ctx.ui.setEditorText(next);
|
|
117
|
+
|
|
118
|
+
// pop = remove the chosen entry
|
|
119
|
+
entries.splice(idx, 1);
|
|
120
|
+
persist();
|
|
121
|
+
updateStatus(ctx);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
pi.registerCommand("stash", {
|
|
125
|
+
description: "Push text (with arg) or pop an entry into the editor (no arg)",
|
|
126
|
+
handler: async (args, ctx) => {
|
|
127
|
+
await runStash(args ?? "", ctx);
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// Ctrl+S → same as bare `/stash`: pop an entry into the editor. If the
|
|
132
|
+
// editor already holds text, push it onto the stash instead.
|
|
133
|
+
pi.registerShortcut("ctrl+s", {
|
|
134
|
+
description: "Stash: push editor text, or pop a saved prompt",
|
|
135
|
+
handler: async (ctx) => {
|
|
136
|
+
const editorText = (ctx.ui.getEditorText() ?? "").trim();
|
|
137
|
+
if (editorText) {
|
|
138
|
+
ctx.ui.setEditorText("");
|
|
139
|
+
await runStash(editorText, ctx);
|
|
140
|
+
} else {
|
|
141
|
+
await runStash("", ctx);
|
|
142
|
+
}
|
|
114
143
|
},
|
|
115
144
|
});
|
|
116
145
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yusukeshib/pi-stash",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "A personal stash of reusable prompt fragments for the Pi coding agent. Push prompts you think of mid-task, then pop them into the editor when you need them.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|