@henryqw/pi-prompt-creator 2.0.5 → 2.0.7
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 +12 -18
- package/extensions/prompt-creator.ts +13 -19
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Turn repeated requests or corrections in the current conversation into a reviewed global Pi prompt. A tool-free child drafts one candidate, while Main and the user control review and saving.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Automatic analysis only prepares a candidate; the extension never saves it without your approval.
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
@@ -29,13 +29,11 @@ Run `/promptor` in the interactive TUI after a repeated request or correction ap
|
|
|
29
29
|
|
|
30
30
|
The prompt is created at `~/.pi/agent/prompts/<name>.md`, then Pi reloads its resources. No selection menu or name prompt is required.
|
|
31
31
|
|
|
32
|
-
|
|
|
33
|
-
| --- | --- |
|
|
34
|
-
| `/promptor` |
|
|
35
|
-
|
|
|
36
|
-
|
|
|
37
|
-
| `/promptor dismiss` | Forget a candidate prepared by automatic analysis. |
|
|
38
|
-
| `/promptor automatic <on\|off>` | Enable or disable automatic analysis. |
|
|
32
|
+
| Surface | Type | Purpose |
|
|
33
|
+
| --- | --- | --- |
|
|
34
|
+
| `/promptor [analyze|dismiss|save [name]|automatic <on\|off>]` | command | For users in the interactive TUI: start or show analysis, dismiss a pending candidate, save a reviewed prompt, or control automatic analysis. |
|
|
35
|
+
| `pi-prompt-creator/draft` | task | For users configuring `/task-models`: choose the child model and thinking level for drafting. |
|
|
36
|
+
| Analysis status widget and candidate message | ui | Show analysis progress, readiness, or failure; a displayed candidate is marked as untrusted. |
|
|
39
37
|
|
|
40
38
|
## Flow
|
|
41
39
|
|
|
@@ -65,23 +63,19 @@ New user input does not stop a running child. Branch navigation discards its old
|
|
|
65
63
|
|
|
66
64
|
### Review and save
|
|
67
65
|
|
|
68
|
-
A manually requested analysis displays its completed candidate immediately. Automatic
|
|
66
|
+
A manually requested analysis displays its completed candidate immediately. Automatic analysis shows a running widget, then keeps a completed candidate behind the `Prompt ready — /promptor` widget until you run `/promptor` or `/promptor dismiss`, so background work never interrupts the conversation.
|
|
69
67
|
|
|
70
68
|
Displayed candidates are visible messages marked as untrusted.
|
|
71
69
|
|
|
72
70
|
Refine the candidate with Main. Ask Main to return only the complete Final Prompt Draft before saving it with `/promptor save [name]`.
|
|
73
71
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
Saving uses that latest retained Main reply as the entire file. Replies before the active compaction or branch summary cannot be saved.
|
|
72
|
+
Saving is allowed only after you show a candidate and Main then completes a valid Markdown review reply. Saving uses that latest retained Main reply as the entire file. Replies before the active compaction or branch summary cannot be saved.
|
|
77
73
|
|
|
78
74
|
An interrupted, failed, empty, or tool-use reply cannot be saved. The extension never falls back to an older reply.
|
|
79
75
|
|
|
80
76
|
A successful save ends that review. Show another candidate and complete another Main review reply before saving again.
|
|
81
77
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
Names start with a letter and contain at most 64 ASCII characters. Existing command names and prompt files are rejected.
|
|
78
|
+
`/promptor save` uses the suggested candidate name. Pass `/promptor save <name>` to choose another. Names must be lowercase kebab-case, start with a letter, and contain at most 64 ASCII characters. Existing command names and prompt files are rejected.
|
|
85
79
|
|
|
86
80
|
A successful save reloads Pi resources. If reload fails, the prompt remains saved and `/reload` can load it.
|
|
87
81
|
|
|
@@ -98,7 +92,7 @@ Package-owned: `~/.pi/agent/config/pi-prompt-creator/config.json`
|
|
|
98
92
|
| Name | Description | Values | Default |
|
|
99
93
|
| --- | --- | --- | --- |
|
|
100
94
|
| `automatic` | Runs automatic analysis after enough user inputs. | Boolean. | `true` |
|
|
101
|
-
| `inputThreshold` | Sets the number of non-empty user inputs before automatic analysis. | Positive integer. | `3` |
|
|
95
|
+
| `inputThreshold` | Sets the number of non-empty user inputs before automatic analysis. | Positive safe integer (`1`–`9007199254740991`). | `3` |
|
|
102
96
|
|
|
103
97
|
Edit either field, then run `/reload` to apply the change. Omitted fields use their defaults.
|
|
104
98
|
|
|
@@ -106,7 +100,7 @@ A missing file quietly uses both defaults. Startup never creates or rewrites the
|
|
|
106
100
|
|
|
107
101
|
Malformed config or unknown keys disable automatic analysis. Pi warns once and leaves the file unchanged.
|
|
108
102
|
|
|
109
|
-
Only
|
|
103
|
+
Only `/promptor automatic on` or `/promptor automatic off` writes the config. Toggling preserves the configured threshold.
|
|
110
104
|
|
|
111
105
|
## State and storage
|
|
112
106
|
|
|
@@ -128,7 +122,7 @@ Candidate and Final Prompt Draft Markdown must be non-empty and at most 16 KiB.
|
|
|
128
122
|
|
|
129
123
|
Candidate and saved Markdown reject NUL and other terminal controls. Ordinary tabs and line feeds are allowed.
|
|
130
124
|
|
|
131
|
-
No candidate clears the running widget without a notice. Invalid output or child failure shows `Prompt analysis failed — /promptor`.
|
|
125
|
+
No candidate clears the running widget without a notice. Invalid output or child failure shows `Prompt analysis failed — /promptor`. Failed analysis is not retried automatically; run `/promptor` or `/promptor analyze` to start again.
|
|
132
126
|
|
|
133
127
|
The failure widget clears after the next non-empty user input. Analysis has a two-minute idle timeout and five-minute hard timeout.
|
|
134
128
|
|
|
@@ -146,34 +146,31 @@ function conversationItem(message: ContextMessage): ConversationItem | undefined
|
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
function boundedConversation(messages: ContextMessage[], maxChars: number): ConversationItem[] {
|
|
149
|
-
const items = messages.flatMap((message
|
|
149
|
+
const items = messages.flatMap((message) => {
|
|
150
150
|
const item = conversationItem(message);
|
|
151
|
-
return item ? [
|
|
151
|
+
return item ? [item] : [];
|
|
152
152
|
});
|
|
153
153
|
let summaryIndex = -1;
|
|
154
154
|
for (let index = items.length - 1; index >= 0; index--) {
|
|
155
|
-
if (items[index]!.
|
|
155
|
+
if (items[index]!.role === "summary") {
|
|
156
156
|
summaryIndex = index;
|
|
157
157
|
break;
|
|
158
158
|
}
|
|
159
159
|
}
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
}
|
|
160
|
+
const summary = items[summaryIndex];
|
|
161
|
+
const summaryChars = summary ? JSON.stringify(summary).length : 0;
|
|
162
|
+
const keepSummary = !!summary && summaryChars <= maxChars;
|
|
163
|
+
const selected: ConversationItem[] = [];
|
|
164
|
+
let used = keepSummary ? summaryChars : 0;
|
|
166
165
|
for (let index = items.length - 1; index > summaryIndex; index--) {
|
|
167
166
|
const item = items[index]!;
|
|
168
|
-
const cost = item.
|
|
167
|
+
const cost = JSON.stringify(item).length + (used ? 1 : 0);
|
|
169
168
|
if (used + cost > maxChars) continue;
|
|
170
|
-
selected.
|
|
169
|
+
selected.push(item);
|
|
171
170
|
used += cost;
|
|
172
171
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
.filter(({ index }) => selected.has(index))
|
|
176
|
-
.map(({ item }) => item);
|
|
172
|
+
selected.reverse();
|
|
173
|
+
return keepSummary ? [summary, ...selected] : selected;
|
|
177
174
|
}
|
|
178
175
|
|
|
179
176
|
function analysisPayload(pi: ExtensionAPI, ctx: ExtensionContext): AnalysisPayload {
|
|
@@ -378,10 +375,8 @@ export default function promptCreatorExtension(pi: ExtensionAPI, options: Prompt
|
|
|
378
375
|
draft: string,
|
|
379
376
|
requestedName: string | undefined,
|
|
380
377
|
expectedReview: ReviewBoundary,
|
|
381
|
-
expectedBranch: number,
|
|
382
378
|
ctx: ExtensionCommandContext,
|
|
383
379
|
) => {
|
|
384
|
-
if (expectedBranch !== branchGeneration || reviewBoundary !== expectedReview) return;
|
|
385
380
|
const name = requestedName ?? candidateNameHint ?? "";
|
|
386
381
|
if (!isPromptName(name)) {
|
|
387
382
|
ctx.ui.notify(`Use lowercase kebab-case starting with a letter, up to ${MAX_NAME_CHARS} characters.`, "warning");
|
|
@@ -471,7 +466,6 @@ export default function promptCreatorExtension(pi: ExtensionAPI, options: Prompt
|
|
|
471
466
|
ctx.ui.notify("/promptor requires the interactive TUI.", "warning");
|
|
472
467
|
return;
|
|
473
468
|
}
|
|
474
|
-
const commandBranch = branchGeneration;
|
|
475
469
|
const review = reviewBoundary;
|
|
476
470
|
const draft = latestAssistantDraft(ctx, review);
|
|
477
471
|
const [action = "", ...values] = args.trim().split(/\s+/);
|
|
@@ -502,7 +496,7 @@ export default function promptCreatorExtension(pi: ExtensionAPI, options: Prompt
|
|
|
502
496
|
ctx.ui.notify("No reviewed Main draft is ready to save.", "warning");
|
|
503
497
|
return;
|
|
504
498
|
}
|
|
505
|
-
await saveLatestDraft(draft, values[0], review,
|
|
499
|
+
await saveLatestDraft(draft, values[0], review, ctx);
|
|
506
500
|
return;
|
|
507
501
|
}
|
|
508
502
|
if (action === "automatic" && values.length === 1 && (values[0] === "on" || values[0] === "off")) {
|