@henryqw/pi-prompt-creator 3.1.0 → 3.1.2

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 CHANGED
@@ -6,7 +6,7 @@ Automatic analysis only prepares a candidate; the extension never saves it witho
6
6
 
7
7
  ## Install
8
8
 
9
- Requires Pi 1.1.0 or later. Older Pi releases are no longer supported.
9
+ Requires Pi 1.1.0 or later in the 1.x series. Older Pi releases are no longer supported.
10
10
 
11
11
  ```bash
12
12
  pi install npm:@henryqw/pi-task-models
@@ -35,7 +35,7 @@ const READY_WIDGET = "Prompt ready — /promptor";
35
35
  const FAILURE_WIDGET = "Prompt analysis failed — /promptor";
36
36
  const REFINEMENT_GUIDANCE = "Refine this candidate conversationally with the user. When the user approves it, Main must emit only the complete Final Prompt Draft. Then run /promptor save to use the suggested name, or /promptor save <name>.";
37
37
 
38
- export const DRAFT_TASK = {
38
+ const DRAFT_TASK = {
39
39
  id: "pi-prompt-creator/draft",
40
40
  label: "Prompt draft",
41
41
  purpose: "Find a reusable prompt candidate in the current conversation.",
@@ -61,15 +61,16 @@ The object must have exactly these keys. name must start with a lowercase ASCII
61
61
  } satisfies Role;
62
62
 
63
63
  type Config = { automatic: boolean; inputThreshold: number };
64
- export type PromptCandidate = { name: string; markdown: string };
64
+ type PromptCandidate = { name: string; markdown: string };
65
65
  type ConversationItem = { role: "summary" | "user" | "assistant"; text: string };
66
66
  type ContextMessage = ReturnType<typeof buildSessionContext>["messages"][number];
67
+ type MessageContent = Extract<ContextMessage, { role: "user" | "assistant" }>["content"];
67
68
  type ExistingPrompt = { name: string; description: string };
68
69
  type AnalysisPayload = { currentConversation: ConversationItem[]; existingPrompts: ExistingPrompt[] };
69
70
  type ActiveRun = { controller: AbortController; branchGeneration: number };
70
71
  type ReviewBoundary = { entryId: string };
71
72
 
72
- export interface PromptCreatorOptions {
73
+ interface PromptCreatorOptions {
73
74
  agentDir?: string;
74
75
  executor?: EphemeralSubagentExecutor;
75
76
  }
@@ -94,11 +95,11 @@ function parseConfig(value: unknown): Config {
94
95
  return { automatic, inputThreshold };
95
96
  }
96
97
 
97
- export function isPromptName(value: unknown): value is string {
98
+ function isPromptName(value: unknown): value is string {
98
99
  return typeof value === "string" && value.length <= MAX_NAME_CHARS && NAME.test(value);
99
100
  }
100
101
 
101
- export function isPromptMarkdown(value: unknown): value is string {
102
+ function isPromptMarkdown(value: unknown): value is string {
102
103
  return typeof value === "string"
103
104
  && value.trim().length > 0
104
105
  && Buffer.byteLength(value, "utf8") <= MAX_MARKDOWN_BYTES
@@ -121,18 +122,10 @@ export function parseDraftOutput(output: string): PromptCandidate | null {
121
122
  return { name: candidate.name, markdown: candidate.markdown };
122
123
  }
123
124
 
124
- function messageText(content: unknown): string {
125
+ function messageText(content: MessageContent): string {
125
126
  if (typeof content === "string") return content;
126
127
  if (!Array.isArray(content)) return "";
127
- return content
128
- .flatMap((part) =>
129
- part && typeof part === "object" && !Array.isArray(part)
130
- && (part as Record<string, unknown>).type === "text"
131
- && typeof (part as Record<string, unknown>).text === "string"
132
- ? [(part as { text: string }).text]
133
- : [],
134
- )
135
- .join("\n");
128
+ return content.flatMap((part) => (part.type === "text" ? [part.text] : [])).join("\n");
136
129
  }
137
130
 
138
131
  function conversationItem(message: ContextMessage): ConversationItem | undefined {
@@ -229,11 +222,7 @@ ${quotedMarkdown}
229
222
  ${REFINEMENT_GUIDANCE}`;
230
223
  }
231
224
 
232
- function errorCode(error: unknown): string | undefined {
233
- return error && typeof error === "object" && "code" in error ? String(error.code) : undefined;
234
- }
235
-
236
- export async function createPromptFile(path: string, markdown: string): Promise<void> {
225
+ async function createPromptFile(path: string, markdown: string): Promise<void> {
237
226
  await mkdir(dirname(path), { recursive: true });
238
227
  let file: Awaited<ReturnType<typeof open>> | undefined;
239
228
  let created = false;
@@ -289,10 +278,10 @@ export default function promptCreatorExtension(pi: ExtensionAPI, options: Prompt
289
278
  const showFailure = (ctx: ExtensionContext) => {
290
279
  failure = true;
291
280
  candidate = undefined;
292
- if (ctx.mode === "tui") ctx.ui.setWidget(WIDGET_KEY, [FAILURE_WIDGET]);
281
+ ctx.ui.setWidget(WIDGET_KEY, [FAILURE_WIDGET]);
293
282
  };
294
283
  const isCurrent = (run: ActiveRun) =>
295
- activeRun === run && branchGeneration === run.branchGeneration && !run.controller.signal.aborted;
284
+ activeRun === run && branchGeneration === run.branchGeneration;
296
285
  const resetBranch = (ctx: ExtensionContext) => {
297
286
  branchGeneration += 1;
298
287
  inputCount = 0;
@@ -322,7 +311,6 @@ export default function promptCreatorExtension(pi: ExtensionAPI, options: Prompt
322
311
  reviewBoundary = boundaryId ? { entryId: boundaryId } : undefined;
323
312
  };
324
313
  const startAnalysis = (ctx: ExtensionContext, manual: boolean) => {
325
- if (ctx.mode !== "tui" || activeRun || candidate) return;
326
314
  if (manual) automaticConsumed = true;
327
315
  failure = false;
328
316
  candidateNameHint = undefined;
@@ -391,7 +379,7 @@ export default function promptCreatorExtension(pi: ExtensionAPI, options: Prompt
391
379
  await createPromptFile(path, draft);
392
380
  } catch (error) {
393
381
  ctx.ui.notify(
394
- errorCode(error) === "EEXIST" ? `Prompt /${name} already exists.` : `Could not save /${name}.`,
382
+ (error as NodeJS.ErrnoException).code === "EEXIST" ? `Prompt /${name} already exists.` : `Could not save /${name}.`,
395
383
  "error",
396
384
  );
397
385
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@henryqw/pi-prompt-creator",
3
- "version": "3.1.0",
3
+ "version": "3.1.2",
4
4
  "description": "Turn current Pi conversation signals into user-approved prompt templates.",
5
5
  "keywords": [
6
6
  "pi-package",