@janvitos/pi-plan-build 0.1.36 → 0.1.38

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
@@ -91,7 +91,7 @@ Both actions leave Plan mode active, stop the agent, and wait for the next user
91
91
 
92
92
  When Pi uses `"tuiMode": "fullscreen"` and the saved plan contains top-level `- [ ]` items under `## Implementation Steps`, `plan_exit` offers the additional **Implement step by step** approval action. This is opt-in per plan; it does not replace either one-shot implementation option or **Stay in Plan mode**.
93
93
 
94
- The passive 64-column right panel reserves terminal columns, so the transcript and editor reflow instead of being covered. Long step instructions wrap across aligned continuation rows rather than being clipped. It never accepts focus or keyboard input and collapses below 132 terminal columns. The panel is a visual status aid only; all control happens through ordinary prompts. The agent interprets intent contextually, so these are examples rather than required commands:
94
+ The passive 64-column right panel reserves terminal columns, so the transcript and editor reflow instead of being covered. Long step instructions and panel guidance wrap instead of being clipped. It never accepts focus or keyboard input and collapses below 132 terminal columns. The panel is a visual status aid only; all control happens through ordinary prompts. Its guidance remains visible, and the main transcript says, “Awaiting your instructions.” The agent interprets intent contextually, so these are examples rather than required commands:
95
95
 
96
96
  - “Implement the next step,” “Start step 2,” or simply “Approved” / “Go ahead.”
97
97
  - “Step 1 is complete,” “I verified that one,” or “I already handled this.”
package/index.ts CHANGED
@@ -53,6 +53,7 @@ import {
53
53
  PLAN_EXIT_FRESH_CHOICE,
54
54
  PLAN_EXIT_STAY_ACKNOWLEDGEMENT,
55
55
  PLAN_EXIT_STAY_CHOICE,
56
+ PLAN_STEP_READY_ACKNOWLEDGEMENT,
56
57
  renderModeComposer,
57
58
  type Mode,
58
59
  unique,
@@ -64,6 +65,7 @@ const PLAN_REVIEW_ENTRY_TYPE = "pi-plan-build-review";
64
65
  const LEGACY_PLAN_REVIEW_ENTRY_TYPE = "opencode-plan-review";
65
66
  const MODE_NOTICE_ENTRY_TYPE = "pi-plan-build-notice";
66
67
  const LEGACY_MODE_NOTICE_ENTRY_TYPE = "opencode-mode-notice";
68
+ const PLAN_STEP_GUIDANCE_ENTRY_TYPE = "pi-plan-build-step-guidance";
67
69
  const STATUS_KEY = "pi-plan-build-mode";
68
70
  const PLAN_STEP_CHOICE = "Implement step by step";
69
71
  const PANEL_WIDTH = 64;
@@ -119,10 +121,13 @@ export default function planBuildModes(pi: ExtensionAPI): void {
119
121
  const message = typeof entry.data?.message === "string" ? entry.data.message : "Plan mode unchanged.";
120
122
  return new Text(theme.fg("warning", message), 0, 0);
121
123
  };
124
+ const renderPlanStepGuidance: EntryRenderer = (_entry, _options, theme) =>
125
+ new Text(theme.fg("success", PLAN_STEP_READY_ACKNOWLEDGEMENT), 0, 0);
122
126
  pi.registerEntryRenderer<{ plan: string }>(PLAN_REVIEW_ENTRY_TYPE, renderPlanReview);
123
127
  pi.registerEntryRenderer<{ plan: string }>(LEGACY_PLAN_REVIEW_ENTRY_TYPE, renderPlanReview);
124
128
  pi.registerEntryRenderer<{ message: string }>(MODE_NOTICE_ENTRY_TYPE, renderModeNotice);
125
129
  pi.registerEntryRenderer<{ message: string }>(LEGACY_MODE_NOTICE_ENTRY_TYPE, renderModeNotice);
130
+ pi.registerEntryRenderer(PLAN_STEP_GUIDANCE_ENTRY_TYPE, renderPlanStepGuidance);
126
131
 
127
132
  function stateData(): StoredState {
128
133
  return { version: 1, selectedMode, pendingReminder, toolsBeforeModes, ...(execution ? { execution } : {}) };
@@ -527,8 +532,8 @@ export default function planBuildModes(pi: ExtensionAPI): void {
527
532
  }
528
533
  const choices = [
529
534
  PLAN_EXIT_APPROVE_CHOICE,
530
- ...(stepExecution ? [PLAN_STEP_CHOICE] : []),
531
535
  PLAN_EXIT_FRESH_CHOICE,
536
+ ...(stepExecution ? [PLAN_STEP_CHOICE] : []),
532
537
  PLAN_EXIT_STAY_CHOICE,
533
538
  ];
534
539
  const selection = normalizePlanExitChoice(await ctx.ui.select(
@@ -541,6 +546,7 @@ export default function planBuildModes(pi: ExtensionAPI): void {
541
546
  await selectMode("build", ctx, "tool");
542
547
  updateExecution(stepExecution);
543
548
  ensurePanelLayout();
549
+ pi.appendEntry(PLAN_STEP_GUIDANCE_ENTRY_TYPE);
544
550
  return {
545
551
  content: [{ type: "text", text: "Step-by-step execution is ready. Stop now and wait for the user's natural-language instruction in the composer; the plan panel is visual-only." }],
546
552
  details: { approved: true, action: "step-by-step", mode: "build", planPath },
@@ -588,7 +594,7 @@ export default function planBuildModes(pi: ExtensionAPI): void {
588
594
  renderResult(result, _options, theme, context) {
589
595
  const details = result.details as { approved?: boolean; action?: string } | undefined;
590
596
  if (details?.action === "step-by-step" && !context.isError) {
591
- return new Text(theme.fg("success", "Step-by-step execution ready — waiting for your instruction."), 0, 0);
597
+ return new Text(theme.fg("success", "Step-by-step execution ready"), 0, 0);
592
598
  }
593
599
  if (details?.action === "implement-fresh" && !context.isError) {
594
600
  return new Text(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@janvitos/pi-plan-build",
3
- "version": "0.1.36",
3
+ "version": "0.1.38",
4
4
  "description": "Plan safely, approve explicitly, then implement here or in a clean session.",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/plan-panel.ts CHANGED
@@ -34,6 +34,9 @@ export class PlanPanel implements Component {
34
34
  const clipped = truncateToWidth(content, contentWidth, "");
35
35
  return `${border("│")} ${clipped}${" ".repeat(Math.max(0, contentWidth - visibleWidth(clipped)))} ${border("│")}`;
36
36
  };
37
+ const pushWrapped = (lines: string[], content: string) => {
38
+ for (const line of wrapTextWithAnsi(content, contentWidth)) lines.push(pad(line));
39
+ };
37
40
  const done = this.state.steps.filter((step) => step.status === "completed" || step.status === "skipped").length;
38
41
  const status = this.state.status === "completed" ? "complete" : this.state.status;
39
42
  const currentIndex = this.state.steps.findIndex((step) => step.id === this.state.selectedStepId);
@@ -65,8 +68,8 @@ export class PlanPanel implements Component {
65
68
  }
66
69
  lines.push(border(`├${"─".repeat(inner)}┤`));
67
70
  if (this.state.status === "completed") lines.push(pad(this.theme.fg("success", "Plan complete")));
68
- else if (this.state.status === "paused") lines.push(pad("Tell the agent to resume, cancel, or hide the plan."));
69
- else if (current?.status === "ready") lines.push(pad("Tell the agent to implement, complete, edit, skip, cancel, or hide this step."));
71
+ else if (this.state.status === "paused") pushWrapped(lines, "Tell the agent to resume, cancel, or hide the plan.");
72
+ else if (current?.status === "ready") pushWrapped(lines, "Tell the agent to implement, complete, edit, or skip steps. You can also cancel or hide the plan.");
70
73
  lines.push(border(`╰${"─".repeat(inner)}╯`));
71
74
  return lines.map((line) => truncateToWidth(line, safeWidth, ""));
72
75
  }
package/utils.ts CHANGED
@@ -136,6 +136,7 @@ export const PLAN_EXIT_FRESH_CHOICE = "Start fresh and implement";
136
136
  export const PLAN_EXIT_STAY_CHOICE = "Stay in Plan mode";
137
137
  export const PLAN_EXIT_STAY_ACKNOWLEDGEMENT =
138
138
  "Staying in Plan mode. Let me know when you’re ready to revise or implement the plan.";
139
+ export const PLAN_STEP_READY_ACKNOWLEDGEMENT = "Awaiting your instructions.";
139
140
 
140
141
  export type PlanExitDecision = "implement-here" | "implement-fresh" | "stay";
141
142