@mediadatafusion/pi-workflow-suite 0.0.13 → 0.0.15

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/CHANGELOG.md CHANGED
@@ -2,6 +2,24 @@
2
2
 
3
3
  All notable public releases will be documented in this file.
4
4
 
5
+ ## [0.0.15] - 2026-06-09
6
+
7
+ ### Improved
8
+
9
+ - Improved Plan Mode approval handoffs so approval-ready plans remain visible while action menus are open.
10
+ - Refined the Deep Plan preset so reviewer review remains available without automatically starting by default.
11
+ - Improved workflow recovery around transient connection interruptions so Plan, Mission, and Standard workflows are easier to resume after short transport failures.
12
+
13
+ ### Hardened
14
+
15
+ - Expanded regression coverage for reviewer routing, sub-agent handoffs, package command surfaces, and interruption recovery.
16
+
17
+ ## [0.0.14] - 2026-06-08
18
+
19
+ ### Fixed
20
+
21
+ - Restored the npm/pi.dev publish preparation path so the package-safe README is active before npm publish starts, preserving the rendered package README while keeping media pinned to the published `0.0.12` assets.
22
+
5
23
  ## [0.0.13] - 2026-06-08
6
24
 
7
25
  ### Changed
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  [![Install](https://cdn.jsdelivr.net/npm/@mediadatafusion/pi-workflow-suite@0.0.12/docs/assets/readme-link-install.svg)](#installation) [![Quick Start](https://cdn.jsdelivr.net/npm/@mediadatafusion/pi-workflow-suite@0.0.12/docs/assets/readme-link-quick-start.svg)](#quick-start) [![Commands](https://cdn.jsdelivr.net/npm/@mediadatafusion/pi-workflow-suite@0.0.12/docs/assets/readme-link-commands.svg)](#core-commands) [![Settings](https://cdn.jsdelivr.net/npm/@mediadatafusion/pi-workflow-suite@0.0.12/docs/assets/readme-link-settings.svg)](#settings-reference)
6
6
 
7
- **Workflow Suite Version:** `v0.0.13`
7
+ **Workflow Suite Version:** `v0.0.15`
8
8
 
9
9
  ## Overview
10
10
 
@@ -578,15 +578,15 @@ Mission: approval-gated, auto-run after approval, standard planning, milestone v
578
578
 
579
579
  Deep — Careful
580
580
  Plan: deep, asks clarification for non-trivial work
581
- Review: automatic
582
- Validation: automatic
581
+ Review: manual/optional; not automatic before execution
582
+ Validation: automatic after execution
583
583
  Sub-agents: forced larger teams across planning/execution/repair/review/validation
584
584
  Mission: deep planning with final validation
585
585
 
586
586
  Maximum — Thorough
587
587
  Plan: maximum
588
588
  Review: automatic
589
- Validation: automatic
589
+ Validation: automatic after execution
590
590
  Sub-agents: forced maximum teams across planning/execution/repair/review/validation
591
591
  Mission: supervised auto, final validation, higher retry budget
592
592
  ```
@@ -1007,8 +1007,8 @@ pi install -l npm:@mediadatafusion/pi-workflow-suite
1007
1007
  ### Installing specific versions
1008
1008
 
1009
1009
  ```bash
1010
- pi install npm:@mediadatafusion/pi-workflow-suite@0.0.13
1011
- pi install -l npm:@mediadatafusion/pi-workflow-suite@0.0.13
1010
+ pi install npm:@mediadatafusion/pi-workflow-suite@0.0.15
1011
+ pi install -l npm:@mediadatafusion/pi-workflow-suite@0.0.15
1012
1012
  ```
1013
1013
 
1014
1014
  An unversioned install follows normal update behavior: `pi update` and `pi update --extensions` will pick up new package releases. A versioned install pins the package to that version. Pinned package specs are intentionally skipped by Pi's normal package update commands. To move a pinned install to a newer version, reinstall with the desired version. To switch back to latest tracking, use the unversioned install command without `@<version>`.
@@ -1214,10 +1214,10 @@ See `docs/TROUBLESHOOTING.md` for detailed diagnostics.
1214
1214
 
1215
1215
  ## Versioning
1216
1216
 
1217
- The current preparation version is `v0.0.13`. Version information is intentionally aligned across:
1217
+ The current preparation version is `v0.0.15`. Version information is intentionally aligned across:
1218
1218
 
1219
- - `VERSION` (`v0.0.13`),
1220
- - `package.json` (`0.0.13`),
1219
+ - `VERSION` (`v0.0.15`),
1220
+ - `package.json` (`0.0.15`),
1221
1221
  - `package-lock.json`,
1222
1222
  - this README,
1223
1223
  - Workflow Suite settings/about output.
package/VERSION CHANGED
@@ -1 +1 @@
1
- v0.0.13
1
+ v0.0.15
@@ -956,9 +956,9 @@ export function builtInWorkflowPresets(): Record<string, WorkflowPresetBundle> {
956
956
  },
957
957
  deep: {
958
958
  displayName: "Deep",
959
- description: "Careful end-to-end workflow for risky or codebase-heavy work with stronger clarification, automatic review/validation, final mission validation, and larger worker teams.",
959
+ description: "Careful end-to-end workflow for risky or codebase-heavy work with stronger clarification, manual Plan review, automatic validation, final mission validation, and larger worker teams.",
960
960
  planning: { depth: "deep", clarificationMode: "always_for_nontrivial", maxClarificationQuestions: 5, interactiveClarificationEnabled: true, clarificationQualityGate: true, useSubagentsBeforeClarification: true },
961
- workflow: { offerReviewerBeforeExecute: false, autoRunReviewerBeforeExecute: true, offerValidationAfterExecute: true, autoRunValidationAfterExecute: true, validateAfterExecution: true, requirePlanApprovalBeforeExecute: false, requireApprovalBeforeExecution: false, autoRepairReviewFailures: true, autoRepairValidationFailures: true, reviewRetryMode: "safe_only", validationRetryMode: "safe_only", maxReviewRetriesPerPlan: 3, maxReviewRetriesPerWorkflow: 6, maxValidationRetriesPerPlan: 3, maxValidationRetriesPerWorkflow: 6, pauseAfterReviewFailure: false, pauseAfterValidationFailure: false, planProgressEnabled: true, planRuntimeEnabled: true, planShowProgressBar: true },
961
+ workflow: { offerReviewerBeforeExecute: false, autoRunReviewerBeforeExecute: false, offerValidationAfterExecute: true, autoRunValidationAfterExecute: true, validateAfterExecution: true, requirePlanApprovalBeforeExecute: false, requireApprovalBeforeExecution: false, autoRepairReviewFailures: true, autoRepairValidationFailures: true, reviewRetryMode: "safe_only", validationRetryMode: "safe_only", maxReviewRetriesPerPlan: 3, maxReviewRetriesPerWorkflow: 6, maxValidationRetriesPerPlan: 3, maxValidationRetriesPerWorkflow: 6, pauseAfterReviewFailure: false, pauseAfterValidationFailure: false, planProgressEnabled: true, planRuntimeEnabled: true, planShowProgressBar: true },
962
962
  standard: { enabled: true, autoTodoEnabled: true, todoProgressVisible: true, todoTriggerMode: "auto", clarificationEnabled: true, clarificationMode: "auto", maxClarificationQuestions: 2, interactiveClarificationEnabled: true, clarificationTiming: "after_initial_analysis", clarificationQualityGate: true, allowClarificationWithoutAnalysis: false, useSubagentsBeforeClarification: true, allowSubagents: true, subagentScope: "user", subagents: { planningPolicy: "forced", executionPolicy: "forced", repairPolicy: "forced", reviewPolicy: "forced", validationPolicy: "forced", autoUseDuringPlanning: true, autoUseDuringExecution: true, autoUseDuringRepair: true, autoUseDuringReview: true, autoUseDuringValidation: true, minPlanningWorkersForDeep: 2, minPlanningWorkersForMaximum: 2, minExecutionWorkersForDeep: 3, minExecutionWorkersForMaximum: 3, minRepairWorkersForDeep: 2, minRepairWorkersForMaximum: 2, minReviewWorkersForDeep: 3, minReviewWorkersForMaximum: 3, minValidationWorkersForDeep: 3, minValidationWorkersForMaximum: 3 }, statusWidgetVisible: true, useSharedExecutorModel: true, useStandardSpecificModels: false, modelRole: "executor" },
963
963
  missions: { defaultAutonomy: "approval_gated", requireValidationPerMilestone: true, autoRunAfterApproval: true, continueAcrossMilestones: true, pauseBetweenMilestones: false, clarificationMode: "always_for_nontrivial", maxClarificationQuestions: 5, planningDepth: "deep", useSubagentsBeforeClarification: true, autoRepairReviewFailures: true, reviewRetryMode: "safe_only", maxReviewRetriesPerMission: 3, autoRepairValidationFailures: true, validationRetryMode: "safe_only", maxValidationRetriesPerMilestone: 3, maxValidationRetriesPerMission: 8, finalValidationEnabled: true, autoRepairFinalValidationFailures: true, maxFinalValidationRetries: 2, subagentPolicy: "forced", minWorkersForDeep: 3, minWorkersForMaximum: 3 },
964
964
  subagents: { planningPolicy: "forced", executionPolicy: "forced", repairPolicy: "forced", reviewPolicy: "forced", validationPolicy: "forced", autoUseDuringPlanning: true, autoUseDuringExecution: true, autoUseDuringRepair: true, autoUseDuringReview: true, autoUseDuringValidation: true, minPlanningWorkersForDeep: 3, minPlanningWorkersForMaximum: 3, minExecutionWorkersForDeep: 3, minExecutionWorkersForMaximum: 3, minRepairWorkersForDeep: 2, minRepairWorkersForMaximum: 2, minReviewWorkersForDeep: 3, minReviewWorkersForMaximum: 3, minValidationWorkersForDeep: 3, minValidationWorkersForMaximum: 3, allowBackgroundSubagents: true },
@@ -1077,7 +1077,7 @@ export function workflowPresetPickerLabel(name: string, preset?: WorkflowPresetB
1077
1077
  const summaries: Record<string, string> = {
1078
1078
  simple: "fast autonomous validation, low repair retries, 1-worker phases",
1079
1079
  standard: "balanced autonomous validation and safe repair",
1080
- deep: "careful autonomous review, validation, and final mission validation",
1080
+ deep: "careful manual review, autonomous validation, and final mission validation",
1081
1081
  maximum: "maximum autonomous rigor with bounded aggressive repair",
1082
1082
  };
1083
1083
  return summaries[name] ? `${title} — ${summaries[name]}` : title;
@@ -1122,7 +1122,7 @@ export function workflowPresetMeaningLines(name: string, preset?: WorkflowPreset
1122
1122
  "Purpose: higher-rigor built-in profile for broad, risky, or codebase-heavy work that still should not stall unnecessarily.",
1123
1123
  "Applies to: Standard Mode, Plan Mode, Mission Mode, and shared sub-agent intensity.",
1124
1124
  "Standard Mode: requires a To Do for substantive work, uses stronger clarification, resumes automatically after answers, and uses deeper Standard worker coverage.",
1125
- "Plan Mode: uses deep planning, clarifies non-trivial work, avoids a second execution-approval stop after the initial approval, runs automatic review and validation, and retries safe repairs.",
1125
+ "Plan Mode: uses deep planning, clarifies non-trivial work, avoids a second execution-approval stop after the initial approval, leaves review manual/optional, runs validation automatically, and retries safe repairs.",
1126
1126
  "Mission Mode: starts after approval, auto-runs after approval, continues milestones without pause, keeps milestone validation on, and enables final comprehensive validation.",
1127
1127
  "Shared sub-agents: forces larger teams across planning, execution, repair, review, and validation.",
1128
1128
  "Does not change: models/providers/API keys/auth/session/runtime state/shared compaction settings.",
@@ -1750,7 +1750,7 @@ ${requiredSubagentPreflightSection(options.preflightBlock)}
1750
1750
 
1751
1751
  ${subagentCapabilityTable()}
1752
1752
 
1753
- ${priorPlan ? `Current draft/approved plan to revise:\n${priorPlan}\n\n` : ""}${feedbackBlock}${options.forceClarification ? `CLARIFICATION IS REQUIRED BEFORE FINAL PLANNING. Reason: ${options.forceReason ?? "always_for_nontrivial classified this as non-trivial"}\nYour job in this turn is to perform lightweight task analysis, then generate only high-value clarification questions from the actual task. Do not produce an implementation plan in this turn. ${subagentsBeforeClarification ? "If planning depth/policy calls for it and sub-agent use is available, use read-only planning/research sub-agents before asking clarification so the questions are context-aware." : "Do not call sub-agents in this clarification-generation turn unless forced by sub-agent policy."} Do not use generic reusable workflow boilerplate questions.\n\n` : ""}${options.qualityGateFeedback ? `The previous clarification output failed the clarification quality gate: ${options.qualityGateFeedback}\nRegenerate better task-specific clarification questions${options.forceClarification ? ". Do not produce a final plan in this retry." : ", or use PLAN_DECISION: plan if no high-value question exists."}\n\n` : ""}MANDATORY STRUCTURED HANDOFF: Before your final response, call workflow_plan_result with decision=clarify, plan, or blocked. The tool payload is the primary control plane; visible markdown is fallback display only. If workflow_plan_result is unavailable, output the parser-safe PLAN_DECISION fallback once and STOP immediately; do not call subagent as an acknowledgement, do not retry invalid tool names, and do not continue analysis after the fallback.
1753
+ ${priorPlan ? `Current draft/approved plan to revise:\n${priorPlan}\n\n` : ""}${feedbackBlock}${options.forceClarification ? `CLARIFICATION IS REQUIRED BEFORE FINAL PLANNING. Reason: ${options.forceReason ?? "always_for_nontrivial classified this as non-trivial"}\nYour job in this turn is to perform lightweight task analysis, then generate only high-value clarification questions from the actual task. Do not produce an implementation plan in this turn. ${subagentsBeforeClarification ? "If planning depth/policy calls for it and sub-agent use is available, use read-only planning/research sub-agents before asking clarification so the questions are context-aware." : "Do not call sub-agents in this clarification-generation turn unless forced by sub-agent policy."} Do not use generic reusable workflow boilerplate questions.\n\n` : ""}${options.qualityGateFeedback ? `The previous clarification output failed the clarification quality gate: ${options.qualityGateFeedback}\nRegenerate better task-specific clarification questions${options.forceClarification ? ". Do not produce a final plan in this retry." : ", or use PLAN_DECISION: plan if no high-value question exists."}\n\n` : ""}MANDATORY STRUCTURED HANDOFF: Before your final response, call workflow_plan_result with decision=clarify, plan, or blocked. The tool payload is the primary control plane. After workflow_plan_result returns, print the user-facing markdown for that decision and stop: the approval-ready # Implementation Plan for decision=plan, the clarification questions for decision=clarify, or the blocker summary for decision=blocked. If workflow_plan_result is unavailable, output the parser-safe PLAN_DECISION fallback once and STOP immediately; do not call subagent as an acknowledgement, do not retry invalid tool names, and do not continue analysis after the fallback.
1754
1754
 
1755
1755
  LEGACY FALLBACK: Your VERY FIRST LINE must be exactly one of:
1756
1756
  ${options.forceClarification ? "PLAN_DECISION: clarify" : "PLAN_DECISION: clarify\nPLAN_DECISION: plan"}
@@ -13742,6 +13742,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
13742
13742
  showMissionPlanMenuFallback("Mission plan menu was skipped because the active mission state changed.");
13743
13743
  return;
13744
13744
  }
13745
+ showMissionPlanReadyCard(mission);
13745
13746
  if (!ctx.hasUI) return;
13746
13747
  const reviewChoice = ["PASS", "NOTES"].includes(mission.reviewerVerdict ?? "") ? [] : ["Review Mission Plan"];
13747
13748
  const choices = mission.autonomy === "manual" || mission.autonomy === "approval_gated"
@@ -13750,6 +13751,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
13750
13751
  const choice = await ctx.ui.select("Mission plan ready. Choose next action:", choices);
13751
13752
  if (!choice) {
13752
13753
  updateState({ mode: "mission_plan_ready", activeMissionId: mission.id, task: mission.goal, originalTask: mission.goal, draftPlan: mission.planText }, ctx);
13754
+ showMissionPlanMenuFallback("Mission plan menu was dismissed. The mission plan remains ready.");
13753
13755
  return recordWorkflowInternalEvent(ctx, `Mission plan menu dismissed: ${mission.id}`);
13754
13756
  }
13755
13757
  if (choice === "Review Mission Plan") {
@@ -13785,12 +13787,31 @@ ${renderMissionStatus(activeMission ?? paused)}`);
13785
13787
  show(pi, `# Mission Plan Ready\n\n${reason}\n\nUse one of:\n- \`/mission review\`\n- \`/mission approve\`\n- \`/mission revise <feedback>\`\n- \`/mission cancel\``);
13786
13788
  }
13787
13789
 
13790
+ function showMissionPlanReadyCard(mission: MissionState): void {
13791
+ const planText = mission.planText?.trim() ? mission.planText : "(none recorded)";
13792
+ show(pi, `# Mission Plan Ready\n\n${planText}\n\nChoose an action in the Mission menu, or use:\n- \`/mission review\`\n- \`/mission approve\`\n- \`/mission revise <feedback>\`\n- \`/mission cancel\``);
13793
+ }
13794
+
13788
13795
  // ── Menus ──────────────────────────────────────────────────────
13789
13796
 
13790
13797
  function showPlanMenuCommandFallback(reason: string): void {
13791
13798
  show(pi, `# Plan Ready\n\n${reason}\n\nUse one of:\n- \`/plan approve\`\n- \`/plan revise <feedback>\`\n- \`/plan cancel\``);
13792
13799
  }
13793
13800
 
13801
+ function showPlanReadyForApprovalCard(snapshot: WorkflowHandoffSnapshot, options: { includePlanText?: boolean } = {}): void {
13802
+ const planText = snapshot.draftPlan?.trim()
13803
+ ? snapshot.draftPlan
13804
+ : state.draftPlan?.trim()
13805
+ ? state.draftPlan
13806
+ : state.approvedPlan?.trim()
13807
+ ? state.approvedPlan
13808
+ : "(none recorded)";
13809
+ const body = options.includePlanText === true
13810
+ ? `${planText}\n\nChoose an action in the approval menu, or use:`
13811
+ : "Choose an action in the approval menu. The native plan above is the source of truth, and the saved plan remains recoverable with:";
13812
+ show(pi, `# Plan Ready For Approval\n\n${body}\n- \`/plan approve\`\n- \`/plan revise <feedback>\`\n- \`/plan cancel\``);
13813
+ }
13814
+
13794
13815
  function showPlanClarificationFallback(reason: string, questions?: ClarificationQuestion[]): void {
13795
13816
  const rendered = questions?.length ? `\n\n${renderClarificationQuestionsForUser(questions)}` : "";
13796
13817
  show(pi, `# Clarification Needed\n\n${reason}${rendered}\n\nAnswer with: /clarify answer 1A 2C\nSkip with: /clarify answer 1S\nCustom answer: /clarify answer 3D: your text`);
@@ -13845,9 +13866,10 @@ ${renderMissionStatus(activeMission ?? paused)}`);
13845
13866
  return;
13846
13867
  }
13847
13868
  if (!ctx.hasUI) {
13848
- showPlanMenuCommandFallback(snapshot.fallback);
13869
+ showPlanReadyForApprovalCard(snapshot, { includePlanText: true });
13849
13870
  return;
13850
13871
  }
13872
+ showPlanReadyForApprovalCard(snapshot);
13851
13873
  const settings = loadWorkflowSettings(ctx.cwd);
13852
13874
  const approveLabel = settings.models.reviewer.enabled ? "Approve and Run Workflow" : "Approve and Execute";
13853
13875
  let menuChoice: string | undefined;
@@ -13857,6 +13879,11 @@ ${renderMissionStatus(activeMission ?? paused)}`);
13857
13879
  showPlanMenuCommandFallback(`Interactive approval menu failed to open: ${error instanceof Error ? error.message : String(error)}`);
13858
13880
  return;
13859
13881
  }
13882
+ if (!menuChoice) {
13883
+ updateState({ mode: "plan_draft", activePlanId: snapshot.activePlanId ?? state.activePlanId, draftPlan: snapshot.draftPlan ?? state.draftPlan, task: snapshot.task ?? state.task }, ctx);
13884
+ showPlanMenuCommandFallback("Plan approval menu was dismissed. The plan remains ready for approval.");
13885
+ return;
13886
+ }
13860
13887
  if (menuChoice === "Approve and Execute" || menuChoice === "Approve and Run Workflow") {
13861
13888
  await approveCurrentPlan(ctx, "plan approved by user");
13862
13889
  } else if (menuChoice === "Revise Plan") {
@@ -17432,11 +17459,6 @@ Public workflow commands:
17432
17459
  else if (isMissionWorkflowMode(state)) updateState({ missionTokensUsed: (state.missionTokensUsed ?? 0) + turnTokens }, ctx);
17433
17460
  }
17434
17461
 
17435
- if (initialPlanParentSuppressed()) {
17436
- traceWorkflowTracking(ctx, "typed-initial-plan-parent-message-suppressed", { mode: state.mode, lifecycleStatus: state.planProgress?.lifecycleStatus });
17437
- return { message: { ...message, content: [{ type: "text" as const, text: "" }] } };
17438
- }
17439
-
17440
17462
  if (planReviewParentSuppressed()) {
17441
17463
  traceWorkflowTracking(ctx, "typed-plan-review-parent-message-suppressed", { mode: state.mode, lifecycleStatus: state.planProgress?.lifecycleStatus });
17442
17464
  return { message: { ...message, content: [{ type: "text" as const, text: "" }] } };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mediadatafusion/pi-workflow-suite",
3
- "version": "0.0.13",
3
+ "version": "0.0.15",
4
4
  "description": "Structured workflow orchestration suite for Pi with Standard, Plan, Mission, compaction, diagrams, web access, repo lock, and safety gates.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -114,7 +114,9 @@
114
114
  "prepack": "node scripts/prepare-package-readme.mjs apply",
115
115
  "postpack": "node scripts/prepare-package-readme.mjs restore --pack",
116
116
  "restore:package-readme": "node scripts/prepare-package-readme.mjs restore",
117
- "prepublishOnly": "node scripts/prepare-package-readme.mjs apply --publish",
117
+ "prepare:publish-readme": "node scripts/prepare-package-readme.mjs apply --publish && node scripts/prepare-package-readme.mjs check",
118
+ "cleanup:publish-readme": "node scripts/prepare-package-readme.mjs restore",
119
+ "prepublishOnly": "node scripts/prepare-package-readme.mjs ensure-publish-ready",
118
120
  "postpublish": "node scripts/prepare-package-readme.mjs restore --publish",
119
121
  "check:package-readme": "node scripts/prepare-package-readme.mjs check"
120
122
  }
@@ -106,11 +106,25 @@ function check() {
106
106
  assertPackageReadme(readFileSync(readmePath, 'utf8'));
107
107
  }
108
108
 
109
+ function ensurePublishReady() {
110
+ check();
111
+ if (!existsSync(publishMarkerPath)) {
112
+ throw new Error(
113
+ [
114
+ 'package README is package-safe but publish marker is missing.',
115
+ 'Run `npm run prepare:publish-readme` before `npm publish --access public` so npm sees the package README before publish starts.',
116
+ 'If a previous publish failed, run `npm run cleanup:publish-readme` first.',
117
+ ].join(' '),
118
+ );
119
+ }
120
+ }
121
+
109
122
  const command = process.argv[2];
110
123
  if (command === 'apply') apply();
111
124
  else if (command === 'restore') restore();
112
125
  else if (command === 'check') check();
126
+ else if (command === 'ensure-publish-ready') ensurePublishReady();
113
127
  else {
114
- console.error('Usage: prepare-package-readme.mjs apply|restore|check [--publish|--pack]');
128
+ console.error('Usage: prepare-package-readme.mjs apply|restore|check|ensure-publish-ready [--publish|--pack]');
115
129
  process.exit(1);
116
130
  }