@mediadatafusion/pi-workflow-suite 0.0.19 → 0.0.20

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,17 @@
2
2
 
3
3
  All notable public releases will be documented in this file.
4
4
 
5
+ ## [0.0.20] - 2026-06-12
6
+
7
+ ### Improved
8
+
9
+ - Added platform-aware Workflow Suite shortcuts so macOS keeps the existing `Ctrl+Shift` shortcuts while Windows and Linux use function-key shortcuts for Standard, Plan, Mission, widget, and preset controls.
10
+ - Updated inline shortcut hints, widget documentation, and package README output so Windows and Linux users see shortcuts that match the active platform profile.
11
+
12
+ ### Hardened
13
+
14
+ - Added regression coverage that keeps shortcut registration, inline hints, README examples, and fallback commands aligned with the centralized shortcut registry.
15
+
5
16
  ## [0.0.19] - 2026-06-10
6
17
 
7
18
  ### Improved
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.19`
7
+ **Workflow Suite Version:** `v0.0.20`
8
8
 
9
9
  ## Overview
10
10
 
@@ -123,7 +123,7 @@ Pi Workflow Suite turns Pi into a guided workflow environment:
123
123
  | Token Budgets | Optional per-mode token and runtime caps (`maxTokens`, `maxRuntimeHours`) for Plan, Mission, and Standard Mode. Off by default (unlimited). When enabled, Workflow Suite tracks cumulative usage and blocks further agent turns when the budget is exceeded. |
124
124
  | Workflow Roles | Planner, Executor, Reviewer, Validator, Mission, and compaction responsibilities are separated by phase so each job has clear boundaries and can be matched to the right model. |
125
125
  | Model Selection | Configure which provider/model and thinking level powers each workflow role, with shared defaults plus Standard-specific and Mission-specific overrides for simpler or higher-rigor setups. |
126
- | Presets | Built-in and custom workflow profiles with selector commands and Ctrl+Shift+U cycling while active modes are running. |
126
+ | Presets | Built-in and custom workflow profiles with selector commands and platform-aware cycling shortcuts while active modes are running: macOS `Ctrl+Shift+U`, Windows/Linux `F4`. |
127
127
  | Settings | Interactive grouped settings UI plus direct commands for Standard, Plan, Mission, model selection, sub-agents, widgets, compaction, themes, and safety. |
128
128
  | Sub-agents And Skills | Bundled workflow agents and skills for discovery, planning, safe execution, validation, git-safe summaries, and project-rule audits, with clear capability boundaries. |
129
129
  | Widgets And Status | Mode-aware top/bottom widgets, editor hints, shortcut controls, progress display, runtime summaries, and current-setting visibility. |
@@ -132,9 +132,9 @@ Pi Workflow Suite turns Pi into a guided workflow environment:
132
132
  ## Feature Overview
133
133
 
134
134
  - Idle Mode as the default management state when no Standard, Plan, or Mission workflow is active.
135
- - Standard Mode through `/standard` and `Ctrl+Shift+S` for direct active work with optional dynamic To Do tracking.
136
- - Plan Mode through `/p` and `/plan` for approval-gated planned execution.
137
- - Mission Mode through `/mission`, `/m`, and `Ctrl+Shift+M` for durable milestone workflows.
135
+ - Standard Mode through `/standard` and the platform shortcut: macOS `Ctrl+Shift+S`, Windows/Linux `F6`.
136
+ - Plan Mode through `/p`, `/plan`, and the platform shortcut: macOS `Ctrl+Shift+L`, Windows/Linux `F7`.
137
+ - Mission Mode through `/mission`, `/m`, and the platform shortcut: macOS `Ctrl+Shift+M`, Windows/Linux `F8`.
138
138
  - Configurable clarification in Standard Mode, plus dynamic clarification in Plan Mode and Mission Mode.
139
139
  - Review, execution, validation, repair, retry, checkpoint, and final-validation controls where the selected mode supports them.
140
140
  - Plan history, mission checkpoint history, Standard runtime tracking, and Mission runtime tracking.
@@ -214,7 +214,7 @@ Configurable clarification:
214
214
 
215
215
  Core behavior:
216
216
 
217
- - `/standard` or `Ctrl+Shift+S` enters Standard Mode.
217
+ - `/standard` enters Standard Mode. The platform shortcut is macOS `Ctrl+Shift+S`, Windows/Linux `F6`.
218
218
  - `/standard <task>` enters Standard Mode and starts that task.
219
219
  - `/standard status` shows active Standard settings, latest auto-check decisions, and To Do progress.
220
220
  - `/standard todo` shows dynamic To Do tracking.
@@ -598,7 +598,8 @@ Quick access:
598
598
 
599
599
  ```text
600
600
  /workflow presets # open preset selector
601
- Ctrl+Shift+U # cycle presets while Standard/Plan/Mission Mode is active
601
+ macOS: Ctrl+Shift+U # cycle presets while Standard/Plan/Mission Mode is active
602
+ Windows/Linux: F4 # cycle presets while Standard/Plan/Mission Mode is active
602
603
  /workflow presets list
603
604
  /workflow presets apply <name>
604
605
  /workflow presets next
@@ -610,7 +611,9 @@ Ctrl+Shift+U # cycle presets while Standard/Plan/Mission Mode
610
611
  /workflow presets delete <name>
611
612
  ```
612
613
 
613
- The inline editor hints stay mode-specific and avoid idle clutter. By default, active workflows display compact, human-readable shortcuts and the other workflow mode:
614
+ The inline editor hints stay mode-specific and avoid idle clutter. By default, active workflows display compact, human-readable shortcuts for the active platform.
615
+
616
+ macOS examples:
614
617
 
615
618
  ```text
616
619
  Idle: Standard:Ctrl+Shift+S Plan:Ctrl+Shift+L Mission:Ctrl+Shift+M
@@ -619,7 +622,16 @@ Standard: Widgets:Ctrl+Shift+T/B Preset:deep Ctrl+Shift+U Plan:Ctrl+Shift+L Miss
619
622
  Mission: Widgets:Ctrl+Shift+T/B Preset:deep Ctrl+Shift+U Standard:Ctrl+Shift+S Plan:Ctrl+Shift+L
620
623
  ```
621
624
 
622
- Cross-switching is enabled by default (`Ctrl+Shift+S` toggles Standard Mode, `Ctrl+Shift+M` from Plan Mode enters Mission Mode, and `Ctrl+Shift+L` from Mission Mode enters Plan Mode).
625
+ Windows and Linux examples:
626
+
627
+ ```text
628
+ Idle: Standard:F6 Plan:F7 Mission:F8
629
+ Plan: Widgets:F2/F3 Preset:deep F4 Standard:F6 Mission:F8
630
+ Standard: Widgets:F2/F3 Preset:deep F4 Plan:F7 Mission:F8
631
+ Mission: Widgets:F2/F3 Preset:deep F4 Standard:F6 Plan:F7
632
+ ```
633
+
634
+ Cross-switching is enabled by default. On macOS, `Ctrl+Shift+S` toggles Standard Mode, `Ctrl+Shift+M` from Plan Mode enters Mission Mode, and `Ctrl+Shift+L` from Mission Mode enters Plan Mode. On Windows and Linux, the matching shortcuts are `F6`, `F8`, and `F7`.
623
635
 
624
636
  Human-friendly names are normalized for command use. For example, creating `Joe simple preset` saves it as `joe-simple-preset`, then lists the exact command to apply it. Custom presets can include Standard Mode To Do/clarification settings as well as shared Plan, Mission, sub-agent, workflow, and UI settings.
625
637
 
@@ -650,13 +662,18 @@ Depending on the active mode and settings, widgets can show:
650
662
  - active preset and shortcut hints,
651
663
  - sub-agent activity when worker orchestration is active.
652
664
 
653
- Widget shortcuts:
665
+ Workflow shortcuts are platform-aware. The macOS shortcuts preserve the original Workflow Suite behavior. Windows and Linux use function-key shortcuts because common terminal hosts may not reliably deliver `Ctrl+Shift+letter` chords to Pi.
654
666
 
655
- ```text
656
- Ctrl+Shift+T toggle the active workflow top widget
657
- Ctrl+Shift+B toggle the active workflow bottom widget
658
- Ctrl+Shift+U cycle workflow presets while Standard, Plan, or Mission Mode is active
659
- ```
667
+ | Action | macOS | Windows | Linux / WSL | Fallback command |
668
+ |---|---:|---:|---:|---|
669
+ | Toggle Standard Mode | `Ctrl+Shift+S` | `F6` | `F6` | `/standard` |
670
+ | Enter Plan Mode | `Ctrl+Shift+L` | `F7` | `F7` | `/plan` |
671
+ | Toggle Mission Mode | `Ctrl+Shift+M` | `F8` | `F8` | `/mission` |
672
+ | Toggle active workflow top widget | `Ctrl+Shift+T` | `F2` | `F2` | `/workflow widgets toggle top` |
673
+ | Toggle active workflow bottom widget | `Ctrl+Shift+B` | `F3` | `F3` | `/workflow widgets toggle bottom` |
674
+ | Cycle workflow presets while Standard, Plan, or Mission Mode is active | `Ctrl+Shift+U` | `F4` | `F4` | `/workflow presets next` |
675
+
676
+ The inline editor hints use the active platform profile. A Windows or Linux user should not see macOS-only `Ctrl+Shift+letter` hints for Workflow Suite actions.
660
677
 
661
678
  Widget commands:
662
679
 
@@ -1038,8 +1055,8 @@ pi install -l npm:@mediadatafusion/pi-workflow-suite
1038
1055
  ### Installing specific versions
1039
1056
 
1040
1057
  ```bash
1041
- pi install npm:@mediadatafusion/pi-workflow-suite@0.0.19
1042
- pi install -l npm:@mediadatafusion/pi-workflow-suite@0.0.19
1058
+ pi install npm:@mediadatafusion/pi-workflow-suite@0.0.20
1059
+ pi install -l npm:@mediadatafusion/pi-workflow-suite@0.0.20
1043
1060
  ```
1044
1061
 
1045
1062
  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>`.
@@ -1245,10 +1262,10 @@ See `docs/TROUBLESHOOTING.md` for detailed diagnostics.
1245
1262
 
1246
1263
  ## Versioning
1247
1264
 
1248
- The current preparation version is `v0.0.19`. Version information is intentionally aligned across:
1265
+ The current preparation version is `v0.0.20`. Version information is intentionally aligned across:
1249
1266
 
1250
- - `VERSION` (`v0.0.19`),
1251
- - `package.json` (`0.0.19`),
1267
+ - `VERSION` (`v0.0.20`),
1268
+ - `package.json` (`0.0.20`),
1252
1269
  - `package-lock.json`,
1253
1270
  - this README,
1254
1271
  - Workflow Suite settings/about output.
package/VERSION CHANGED
@@ -1 +1 @@
1
- v0.0.19
1
+ v0.0.20
@@ -2,6 +2,7 @@ import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "
2
2
  import { dirname, join } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
4
  import { getAgentDir, type ExtensionAPI, type ExtensionContext } from "@earendil-works/pi-coding-agent";
5
+ import { workflowPresetCycleShortcutLabel } from "./workflow-shortcuts.js";
5
6
 
6
7
  export type WorkflowRole = "planner" | "executor" | "validator" | "reviewer";
7
8
  export type MissionModelRole = WorkflowRole;
@@ -1224,7 +1225,7 @@ export function renderWorkflowPresets(settings: WorkflowSettings = loadGlobalSet
1224
1225
  const active = settings.presets?.activePreset ?? WORKFLOW_CUSTOM_PRESET_MARKER;
1225
1226
  const names = workflowPresetNames(settings);
1226
1227
  const cards = [renderWorkflowPresetCard(WORKFLOW_CUSTOM_PRESET_MARKER, undefined, active === WORKFLOW_CUSTOM_PRESET_MARKER), ...names.map((name) => renderWorkflowPresetCard(name, catalog[name], name === active))];
1227
- return `# Workflow Presets\n\nActive Preset: ${activeWorkflowPresetLabel(settings)}\nShortcut: Ctrl+Shift+U cycles saved presets while Plan/Mission/Standard Mode is active\nSelector: /workflow presets\n\n${cards.join("\n\n") || "No presets available."}\n\nQuick commands:\n- /workflow presets list\n- /workflow presets apply <name>\n- /workflow presets next\n- /workflow presets prev\n- /workflow presets save <name>\n- /workflow presets create <name> from simple|standard|deep|maximum\n- /workflow presets edit <name>\n- /workflow presets rename <old> to <new>\n- /workflow presets delete <name>\n\nBuilt-in presets are package-defined and sync with the extension. User-named custom presets are saved entries in workflow-settings.json and stay in hotkey cycling. The reserved custom marker only means no built-in or user-named preset is active. Extension updates preserve workflow-settings.json and do not overwrite custom presets. Presets adjust workflow behavior only and preserve model/provider choices, API keys, auth/session files, runtime workflow state, and shared compaction settings.`;
1228
+ return `# Workflow Presets\n\nActive Preset: ${activeWorkflowPresetLabel(settings)}\nShortcut: ${workflowPresetCycleShortcutLabel()} cycles saved presets while Plan/Mission/Standard Mode is active\nSelector: /workflow presets\n\n${cards.join("\n\n") || "No presets available."}\n\nQuick commands:\n- /workflow presets list\n- /workflow presets apply <name>\n- /workflow presets next\n- /workflow presets prev\n- /workflow presets save <name>\n- /workflow presets create <name> from simple|standard|deep|maximum\n- /workflow presets edit <name>\n- /workflow presets rename <old> to <new>\n- /workflow presets delete <name>\n\nBuilt-in presets are package-defined and sync with the extension. User-named custom presets are saved entries in workflow-settings.json and stay in hotkey cycling. The reserved custom marker only means no built-in or user-named preset is active. Extension updates preserve workflow-settings.json and do not overwrite custom presets. Presets adjust workflow behavior only and preserve model/provider choices, API keys, auth/session files, runtime workflow state, and shared compaction settings.`;
1228
1229
  }
1229
1230
 
1230
1231
  export function applyWorkflowPreset(cwd: string, requestedScope: WorkflowSettingsScope | undefined, name: string): SettingsWriteResult {
@@ -13,6 +13,7 @@ import { renderHandoffProjectContext, renderWorkflowStatus, renderWorkflowSummar
13
13
  import { BASE_EXECUTE_TOOLS, EXECUTE_TOOLS, PLAN_TOOLS, REVIEW_TOOLS, WORKFLOW_DIAGRAM_TOOL, WORKFLOW_PLAN_RESULT_TOOL, WORKFLOW_REVIEW_RESULT_TOOL, WORKFLOW_EXECUTION_RESULT_TOOL, WORKFLOW_VALIDATION_RESULT_TOOL, WORKFLOW_REPAIR_RESULT_TOOL, WORKFLOW_PROGRESS_TOOL, MISSION_PLAN_RESULT_TOOL, MISSION_MILESTONE_RESULT_TOOL, STANDARD_HANDOFF_RESULT_TOOL, isBlockedExecuteCommand, registerToolGuard, standardSafeReadOnlyBash, VALIDATOR_TOOLS } from "./workflow-tool-guard.js";
14
14
  import { refreshRuntimeWebTools, registerWorkflowWebTools, runtimeWebResearchGuidance, webSafePlanTools, withRuntimeWebTools } from "./workflow-web-tools.js";
15
15
  import { addMissionCheckpoint, applyPlanRuntimeAccounting, applyStandardRuntimeAccounting, clearOldMissionStates, clearOldWorkflowPlans, compact, createMissionState, createStandardRuntimeId, createWorkflowPlanId, emptyState, extractVerdict, isMissionRuntimeActiveStatus, isPlanRuntimeActiveMode, listMissionStates, listWorkflowPlans, loadMissionState, loadState, loadWorkflowPlan, missionActiveRuntimeMs, missionRuntimeCounterState, missionWallClockAgeMs, planActiveRuntimeMs, planRuntimeCounterState, planWallClockAgeMs, saveMissionState, saveState, saveWorkflowPlan, standardActiveRuntimeMs, standardRuntimeCounterState, standardWallClockAgeMs, PLAN_HISTORY_DIR, MISSION_HISTORY_DIR, type ClarificationAnswer, type ClarificationQuestion, type MissionAutonomy, type MissionMilestone, type MissionState, type PlanProgressState, type PlanStepStatus, type PlanValidationStatus, type SavedWorkflowPlan, type StandardTodoItemStatus, type StandardTodoState, type WorkflowState, type WorkflowTypedHandoffType } from "./workflow-state.js";
16
+ import { WORKFLOW_SHORTCUTS, workflowEntryShortcutLabel as workflowRegistryEntryShortcutLabel, workflowPresetCycleShortcutLabel, workflowSettingsShortcutLines, workflowShortcutKey, workflowWidgetShortcutLabel, type WorkflowShortcutActionId } from "./workflow-shortcuts.js";
16
17
  import { cleanupOrphanProcesses, clearSubagentResultCache, runWorkflowSubagents, workflowSubagentResultOutput, type WorkflowSubagentResult, type WorkflowSubagentTask } from "./subagent/runner.js";
17
18
  import { parseScope, parseBool, parsePlanningDepth, parseClarificationMode, parseStandardTodoTriggerMode, parseStandardClarificationMode, parseStandardModelRole, parseWorkflowAgentScope, parseClarificationTiming, parseSubagentPolicy, parseSubagentPlanningPolicy, parseEditConcurrencyMode, parsePlanningOrchestrationPolicy, parseCompactionMode, parseWorkflowCompactionCheckMode, parseMissionAutonomy, parseValidationRetryMode, parsePositiveInt, updatedMessage, parseClarifyingQuestions, parseShorthandAnswers, formatAnswersForPlanner, planValidationStatusForVerdict } from "./workflow-parsers.js";
18
19
  import { classifyValidationFailure, normalizeValidationVerdict, validationReportHasRepairableIssue } from "./workflow-validation-classifier.js";
@@ -2561,13 +2562,13 @@ Themes:
2561
2562
  - /workflow-settings theme brand base minimal|workflow_duo|mission_control|diagnostic_center|data_stream|neural_grid
2562
2563
 
2563
2564
  Workflow entry shortcuts:
2564
- - Ctrl+Shift+S toggles Standard Mode
2565
- - Ctrl+Shift+L enters Plan Mode
2566
- - Ctrl+Shift+M enters Mission Mode
2567
- - In the opposite active mode, Ctrl+Shift+L/M switches directly to that mode
2565
+ - ${workflowEntryShortcutLabel("standard").replace(/^Standard:/, "")} toggles Standard Mode
2566
+ - ${workflowEntryShortcutLabel("plan").replace(/^Plan:/, "")} enters Plan Mode
2567
+ - ${workflowEntryShortcutLabel("mission").replace(/^Mission:/, "")} enters Mission Mode
2568
+ - In the opposite active mode, ${workflowEntryShortcutLabel("plan").replace(/^Plan:/, "")}/${workflowEntryShortcutLabel("mission").replace(/^Mission:/, "")} switches directly to that mode
2568
2569
 
2569
2570
  Presets:
2570
- - Ctrl+Shift+U cycles workflow presets from the active Plan/Mission/Standard footer/status line
2571
+ - ${workflowPresetCycleShortcutLabel()} cycles workflow presets from the active Plan/Mission/Standard footer/status line
2571
2572
  - /workflow presets opens the preset selector
2572
2573
  - /workflow presets list
2573
2574
  - /workflow presets apply <name>
@@ -3708,11 +3709,7 @@ Startup On Session Start: ${settings.ui.startupVisualOnSessionStart === true ? "
3708
3709
  Custom Brand: ${settings.ui.customBrandEnabled === true ? "enabled" : "disabled"}
3709
3710
  Custom Brand Text: ${sanitizeCustomBrandText(settings.ui.customBrandText) || "(empty)"}
3710
3711
  Custom Brand Base Template: ${customBrandBaseVisualOrDefault(settings)}
3711
- Standard Shortcut: Ctrl+Shift+S toggles Standard Mode
3712
- Plan Shortcut: Ctrl+Shift+L enters Plan Mode
3713
- Mission Shortcut: Ctrl+Shift+M enters Mission Mode
3714
- Widget Shortcuts: Ctrl+Shift+T/B while Plan/Mission/Standard Mode is active
3715
- Preset Cycle Shortcut: Ctrl+Shift+U while Plan/Mission/Standard Mode is active
3712
+ ${workflowSettingsShortcutLines().join("\n")}
3716
3713
  Footer Line: idle displays Plan/Mission entry hints only; active workflows display compact widget/preset hints and workflow switch hints by default
3717
3714
  Fallback Commands: /workflow widgets status, /workflow presets, /standard, /plan, /mission
3718
3715
 
@@ -5032,15 +5029,10 @@ function planProgressWidget(state: WorkflowState, settings: ReturnType<typeof lo
5032
5029
  return lines;
5033
5030
  }
5034
5031
 
5035
- const STANDARD_MODE_SHORTCUT = "Ctrl+Shift+S";
5036
- const PLAN_MODE_SHORTCUT = "Ctrl+Shift+L";
5037
- const MISSION_MODE_SHORTCUT = "Ctrl+Shift+M";
5038
-
5039
5032
  type WorkflowEntryMode = "standard" | "plan" | "mission";
5040
5033
 
5041
5034
  function workflowEntryShortcutLabel(mode: WorkflowEntryMode): string {
5042
- if (mode === "standard") return `Standard:${STANDARD_MODE_SHORTCUT}`;
5043
- return mode === "plan" ? `Plan:${PLAN_MODE_SHORTCUT}` : `Mission:${MISSION_MODE_SHORTCUT}`;
5035
+ return workflowRegistryEntryShortcutLabel(mode);
5044
5036
  }
5045
5037
 
5046
5038
  function workflowFooterShortcutsEnabled(): boolean {
@@ -5053,10 +5045,10 @@ function workflowActiveShortcutSummary(mode: WorkflowEntryMode, state: WorkflowS
5053
5045
  const parts: string[] = [];
5054
5046
  if (shortcuts && ui.showWidgetShortcutHint !== false) {
5055
5047
  const bottomRelevant = mode === "plan" ? planBottomRelevant(state) : mode === "mission" ? missionBottomRelevant(state, activeMissionForUi(state)) : Boolean(state.standardTodo?.items.length);
5056
- parts.push(bottomRelevant ? "Widgets:Ctrl+Shift+T/B" : "Widget:Ctrl+Shift+T");
5048
+ parts.push(workflowWidgetShortcutLabel(bottomRelevant));
5057
5049
  }
5058
5050
  if (ui.showPresetShortcutHint !== false) {
5059
- parts.push(`Preset:${activeWorkflowPresetLabel(settings)}${shortcuts ? " Ctrl+Shift+U" : ""}`);
5051
+ parts.push(`Preset:${activeWorkflowPresetLabel(settings)}${shortcuts ? ` ${workflowPresetCycleShortcutLabel()}` : ""}`);
5060
5052
  }
5061
5053
  if (ui.showActiveWorkflowSwitchHint !== false) {
5062
5054
  const switchHints = (["standard", "plan", "mission"] as WorkflowEntryMode[])
@@ -5416,7 +5408,7 @@ function renderWorkflowThemePreview(settings: ReturnType<typeof loadWorkflowSett
5416
5408
  }
5417
5409
 
5418
5410
  function renderWorkflowFooterThemePreview(settings: ReturnType<typeof loadWorkflowSettings>): string {
5419
- const suffix = ` ${workflowShortcutStatusText(settings, "Widgets:Ctrl+Shift+T/B Preset:simple Mission:Ctrl+Shift+M")}`;
5411
+ const suffix = ` ${workflowShortcutStatusText(settings, `${workflowWidgetShortcutLabel(true)} Preset:simple ${workflowPresetCycleShortcutLabel()} ${workflowEntryShortcutLabel("mission")}`)}`;
5420
5412
  return [
5421
5413
  `${workflowWidgetRgb(settings, "title", "workflow:")}${workflowWidgetRgb(settings, "emphasis", "planning")}${suffix}`,
5422
5414
  `${workflowWidgetRgb(settings, "title", "workflow:")}${workflowWidgetRgb(settings, "progress", "executing")}${suffix}`,
@@ -7179,7 +7171,7 @@ function renderSavedPlan(plan: SavedWorkflowPlan): string {
7179
7171
  }
7180
7172
 
7181
7173
  function missionHelp(): string {
7182
- return `# Mission Mode Help\n\nMission Mode is a persistent milestone workflow for longer-running work. It runs alongside Plan Mode and does not replace /p.\n\nCommands:\n- /mission enters Mission Mode and waits for a goal\n- /mission help\n- /mission start <goal>\n- /mission <goal>\n- /mission clarify\n- /mission clarify answer 1A 2C\n- /mission clarify skip 1\n- /mission plan\n- /mission review\n- /mission approve\n- /mission run\n- /mission continue\n- /mission next\n- /mission pause\n- /mission resume\n- /mission retry\n- /mission repair\n- /mission revalidate\n- /mission set autonomy manual|approval_gated|supervised_auto|full_auto\n- /mission sync-settings\n- /mission status\n- /mission checkpoints\n- /mission stop\n- /mission list\n- /mission latest\n- /mission cleanup [limit]\n\nShortcuts:\n- Ctrl+Shift+M enters Mission Mode\n- Ctrl+Shift+L switches from Mission Mode to Plan Mode\n\nSafety:\n- Mission plans require approval before /mission run.\n- full_auto never runs unless missions.allowFullAuto=true.\n- Destructive actions, push, deploy, database mutation, and secret edits require explicit approval.\n- Mission run uses executor, validator/final-validator, safety, sub-agent, and repair gates and records stop or block reasons.\n- Validation failures attempt safe repair/revalidation within configured retry limits, then block for approval if limits or safety gates are hit.`;
7174
+ return `# Mission Mode Help\n\nMission Mode is a persistent milestone workflow for longer-running work. It runs alongside Plan Mode and does not replace /p.\n\nCommands:\n- /mission enters Mission Mode and waits for a goal\n- /mission help\n- /mission start <goal>\n- /mission <goal>\n- /mission clarify\n- /mission clarify answer 1A 2C\n- /mission clarify skip 1\n- /mission plan\n- /mission review\n- /mission approve\n- /mission run\n- /mission continue\n- /mission next\n- /mission pause\n- /mission resume\n- /mission retry\n- /mission repair\n- /mission revalidate\n- /mission set autonomy manual|approval_gated|supervised_auto|full_auto\n- /mission sync-settings\n- /mission status\n- /mission checkpoints\n- /mission stop\n- /mission list\n- /mission latest\n- /mission cleanup [limit]\n\nShortcuts:\n- ${workflowEntryShortcutLabel("mission").replace(/^Mission:/, "")} enters Mission Mode\n- ${workflowEntryShortcutLabel("plan").replace(/^Plan:/, "")} switches from Mission Mode to Plan Mode\n\nSafety:\n- Mission plans require approval before /mission run.\n- full_auto never runs unless missions.allowFullAuto=true.\n- Destructive actions, push, deploy, database mutation, and secret edits require explicit approval.\n- Mission run uses executor, validator/final-validator, safety, sub-agent, and repair gates and records stop or block reasons.\n- Validation failures attempt safe repair/revalidation within configured retry limits, then block for approval if limits or safety gates are hit.`;
7183
7175
  }
7184
7176
 
7185
7177
  function promptCandidateFiles(name: string): string[] {
@@ -9803,7 +9795,7 @@ export default function workflowModes(pi: ExtensionAPI): void {
9803
9795
  if (isStandardWorkflowMode(state)) {
9804
9796
  return `# Workflow Widgets\n\nStandard Top Widget: ${widgetVisibilityLabel(settings, "standardTop")}\nStandard To Do Widget: ${widgetVisibilityLabel(settings, "standardBottom")}\nStatus Line: ${widgetVisibilityStatus(state, settings) ?? "none"}\n${common}`;
9805
9797
  }
9806
- return `# Workflow Widgets\n\nNo active Plan/Mission/Standard widget is currently visible.\nStatus Line: ${widgetVisibilityStatus(state, settings) ?? "none"}\n\nEntry Shortcuts:\n- ${workflowEntryShortcutLabel("standard")}\n- ${workflowEntryShortcutLabel("plan")}\n- ${workflowEntryShortcutLabel("mission")}\n\nActive-mode editor hints use compact text such as: Widgets:Ctrl+Shift+T/B Preset:${activeWorkflowPresetLabel(settings)} Ctrl+Shift+U Standard:Ctrl+Shift+S Mission:Ctrl+Shift+M\nWidget toggles and preset cycling are visible only while Plan/Mission/Standard Mode is active.\n\n${common}`;
9798
+ return `# Workflow Widgets\n\nNo active Plan/Mission/Standard widget is currently visible.\nStatus Line: ${widgetVisibilityStatus(state, settings) ?? "none"}\n\nEntry Shortcuts:\n- ${workflowEntryShortcutLabel("standard")}\n- ${workflowEntryShortcutLabel("plan")}\n- ${workflowEntryShortcutLabel("mission")}\n\nActive-mode editor hints use compact text such as: ${workflowWidgetShortcutLabel(true)} Preset:${activeWorkflowPresetLabel(settings)} ${workflowPresetCycleShortcutLabel()} ${workflowEntryShortcutLabel("standard")} ${workflowEntryShortcutLabel("mission")}\nWidget toggles and preset cycling are visible only while Plan/Mission/Standard Mode is active.\n\n${common}`;
9807
9799
  };
9808
9800
 
9809
9801
  const renderEditorHintsSettings = (ctx: ExtensionContext): string => {
@@ -15729,11 +15721,11 @@ ${renderMissionStatus(activeMission ?? paused)}`);
15729
15721
  }
15730
15722
 
15731
15723
  function presetUsage(): string {
15732
- return "# Workflow Presets\n\nQuick use:\n- /workflow presets opens the selector\n- Ctrl+Shift+U cycles saved presets from the footer only while Plan/Mission/Standard Mode is active\n- /workflow presets list\n- /workflow presets apply <name>\n- /workflow presets next\n- /workflow presets prev\n- /workflow presets save <name>\n- /workflow presets create <name> from simple|standard|deep|maximum\n- /workflow presets edit <name>\n- /workflow presets rename <old> to <new>\n- /workflow presets delete <name>";
15724
+ return `# Workflow Presets\n\nQuick use:\n- /workflow presets opens the selector\n- ${workflowPresetCycleShortcutLabel()} cycles saved presets from the footer only while Plan/Mission/Standard Mode is active\n- /workflow presets list\n- /workflow presets apply <name>\n- /workflow presets next\n- /workflow presets prev\n- /workflow presets save <name>\n- /workflow presets create <name> from simple|standard|deep|maximum\n- /workflow presets edit <name>\n- /workflow presets rename <old> to <new>\n- /workflow presets delete <name>`;
15733
15725
  }
15734
15726
 
15735
15727
  function presetActionMessage(title: string, name: string, resultFile?: string, scope?: string): string {
15736
- return `# ${title}\n\nPreset: ${name}\n${scope ? `Scope: ${scope}\n` : ""}${resultFile ? `File: ${resultFile}\n` : ""}\nScope note: presets apply across Standard Mode, Plan Mode, Mission Mode, shared sub-agents, and selected UI settings.\nUse selector: /workflow presets\nCycle saved presets: Ctrl+Shift+U while Plan/Mission/Standard Mode is active\nFooter: idle displays Plan/Mission entry shortcuts only; active workflows display compact widget/preset hints and workflow switch hints by default.\n\nModel/provider choices and shared compaction settings are preserved.`;
15728
+ return `# ${title}\n\nPreset: ${name}\n${scope ? `Scope: ${scope}\n` : ""}${resultFile ? `File: ${resultFile}\n` : ""}\nScope note: presets apply across Standard Mode, Plan Mode, Mission Mode, shared sub-agents, and selected UI settings.\nUse selector: /workflow presets\nCycle saved presets: ${workflowPresetCycleShortcutLabel()} while Plan/Mission/Standard Mode is active\nFooter: idle displays Plan/Mission entry shortcuts only; active workflows display compact widget/preset hints and workflow switch hints by default.\n\nModel/provider choices and shared compaction settings are preserved.`;
15737
15729
  }
15738
15730
 
15739
15731
  function parsePresetCreate(rest: string): { name: string; template?: string } {
@@ -15761,7 +15753,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
15761
15753
  const { names, options } = presetDisplayOptions(settings);
15762
15754
  if (!ctx.hasUI) return show(pi, renderWorkflowPresets(settings));
15763
15755
  if (names.length === 0) return show(pi, "# Workflow Presets\n\nNo presets available.");
15764
- const choice = await ctx.ui.select(`Workflow Presets — active: ${activeWorkflowPresetLabel(settings)} — Ctrl+Shift+U cycles during Plan/Mission`, options);
15756
+ const choice = await ctx.ui.select(`Workflow Presets — active: ${activeWorkflowPresetLabel(settings)} — ${workflowPresetCycleShortcutLabel()} cycles during Plan/Mission`, options);
15765
15757
  if (!choice) return;
15766
15758
  const selected = names[options.indexOf(choice)];
15767
15759
  if (!selected) return;
@@ -15890,7 +15882,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
15890
15882
  const r = createWorkflowPreset(ctx.cwd, undefined, parsed.name, parsed.template);
15891
15883
  setWorkflowUi(ctx, state, activeSubagents);
15892
15884
  const safe = normalizeWorkflowPresetName(parsed.name);
15893
- return show(pi, `# Workflow Preset Created\n\nPreset: ${parsed.name}\nSaved As: ${safe}\n${parsed.template ? `Template: ${parsed.template}\n` : ""}Scope: ${r.scope}\nFile: ${r.file}\n\nThe preset was saved but not applied.\nScope note: presets apply across Standard Mode, Plan Mode, Mission Mode, shared sub-agents, and selected UI settings.\nApply now: /workflow presets apply ${safe}\nOpen selector: /workflow presets\nCycle saved presets: Ctrl+Shift+U while Plan/Mission/Standard Mode is active`);
15885
+ return show(pi, `# Workflow Preset Created\n\nPreset: ${parsed.name}\nSaved As: ${safe}\n${parsed.template ? `Template: ${parsed.template}\n` : ""}Scope: ${r.scope}\nFile: ${r.file}\n\nThe preset was saved but not applied.\nScope note: presets apply across Standard Mode, Plan Mode, Mission Mode, shared sub-agents, and selected UI settings.\nApply now: /workflow presets apply ${safe}\nOpen selector: /workflow presets\nCycle saved presets: ${workflowPresetCycleShortcutLabel()} while Plan/Mission/Standard Mode is active`);
15894
15886
  }
15895
15887
  if (action === "configure" || action === "edit") {
15896
15888
  if (!rest) return show(pi, "# Workflow Presets\n\nUsage: /workflow presets edit <name>");
@@ -16791,48 +16783,55 @@ Pi Version: v${VERSION}
16791
16783
  pi.registerCommand("m retry", { description: "Retry validation repair flow for current mission.", handler: async (_args, ctx) => handleMissionCommand("retry", ctx) });
16792
16784
  pi.registerCommand("m revalidate", { description: "Revalidate current mission milestone.", handler: async (_args, ctx) => handleMissionCommand("revalidate", ctx) });
16793
16785
 
16786
+ const workflowShortcutHandlers: Record<WorkflowShortcutActionId, (ctx: ExtensionContext) => Promise<void> | void> = {
16787
+ "workflow.widget.top.toggle": async (ctx) => {
16788
+ if (workflowWidgetUi(loadGlobalSettings()).enableWidgetShortcuts === false) { workflowEditorHintText = workflowEditorHintTextFor(state, loadWorkflowSettings(ctx.cwd), "Top:disabled"); return; }
16789
+ const slot = activeTopWidgetSlot();
16790
+ if (!slot) { workflowEditorHintText = workflowEditorHintTextFor(state, loadWorkflowSettings(ctx.cwd)); return; }
16791
+ toggleWorkflowWidget(ctx, slot);
16792
+ setWorkflowWidgetShortcutStatus(ctx, slot);
16793
+ },
16794
+ "workflow.widget.bottom.toggle": async (ctx) => {
16795
+ if (workflowWidgetUi(loadGlobalSettings()).enableWidgetShortcuts === false) { workflowEditorHintText = workflowEditorHintTextFor(state, loadWorkflowSettings(ctx.cwd), "Bottom:disabled"); return; }
16796
+ if (isPlanWorkflowUiMode(state) && planBottomRelevant(state)) {
16797
+ toggleWorkflowWidget(ctx, "planBottom");
16798
+ return setWorkflowWidgetShortcutStatus(ctx, "planBottom");
16799
+ }
16800
+ if (isMissionWorkflowMode(state) && missionBottomRelevant(state, activeMissionForUi(state))) {
16801
+ toggleWorkflowWidget(ctx, "missionBottom");
16802
+ return setWorkflowWidgetShortcutStatus(ctx, "missionBottom");
16803
+ }
16804
+ if (isStandardWorkflowMode(state)) {
16805
+ toggleWorkflowWidget(ctx, "standardBottom");
16806
+ return setWorkflowWidgetShortcutStatus(ctx, "standardBottom");
16807
+ }
16808
+ workflowEditorHintText = workflowEditorHintTextFor(state, loadWorkflowSettings(ctx.cwd)); return;
16809
+ },
16810
+ "workflow.presets.cycle": async (ctx) => {
16811
+ if (workflowWidgetUi(loadGlobalSettings()).enableWidgetShortcuts === false) { workflowEditorHintText = workflowEditorHintTextFor(state, loadWorkflowSettings(ctx.cwd), "Preset:disabled"); return; }
16812
+ if (!isPlanWorkflowUiMode(state) && !isMissionWorkflowMode(state) && !isStandardWorkflowMode(state)) { workflowEditorHintText = workflowEditorHintTextFor(state, loadWorkflowSettings(ctx.cwd)); return; }
16813
+ await cycleWorkflowPreset(ctx, 1);
16814
+ },
16815
+ "workflow.standard.toggle": async (ctx) => {
16816
+ if (isStandardWorkflowMode(state)) return exitStandardModeToIdle(ctx);
16817
+ await enterStandardMode(ctx);
16818
+ },
16819
+ "workflow.plan.toggle": async (ctx) => {
16820
+ if (isPlanWorkflowUiMode(state)) return exitPlanModeToIdle(ctx);
16821
+ await enterPlanModeAwaitingInput(ctx);
16822
+ },
16823
+ "workflow.mission.toggle": async (ctx) => {
16824
+ if (isMissionWorkflowMode(state)) return exitMissionModeToIdle(ctx);
16825
+ await enterMissionModeAwaitingInput(ctx);
16826
+ },
16827
+ };
16794
16828
 
16795
-
16796
- pi.registerShortcut("ctrl+shift+t", { description: "Toggle active Plan/Mission/Standard top workflow widget", handler: async (ctx) => {
16797
- if (workflowWidgetUi(loadGlobalSettings()).enableWidgetShortcuts === false) { workflowEditorHintText = workflowEditorHintTextFor(state, loadWorkflowSettings(ctx.cwd), "Top:disabled"); return; }
16798
- const slot = activeTopWidgetSlot();
16799
- if (!slot) { workflowEditorHintText = workflowEditorHintTextFor(state, loadWorkflowSettings(ctx.cwd)); return; }
16800
- toggleWorkflowWidget(ctx, slot);
16801
- setWorkflowWidgetShortcutStatus(ctx, slot);
16802
- }});
16803
- pi.registerShortcut("ctrl+shift+b", { description: "Toggle active Plan/Mission/Standard bottom workflow widget", handler: async (ctx) => {
16804
- if (workflowWidgetUi(loadGlobalSettings()).enableWidgetShortcuts === false) { workflowEditorHintText = workflowEditorHintTextFor(state, loadWorkflowSettings(ctx.cwd), "Bottom:disabled"); return; }
16805
- if (isPlanWorkflowUiMode(state) && planBottomRelevant(state)) {
16806
- toggleWorkflowWidget(ctx, "planBottom");
16807
- return setWorkflowWidgetShortcutStatus(ctx, "planBottom");
16808
- }
16809
- if (isMissionWorkflowMode(state) && missionBottomRelevant(state, activeMissionForUi(state))) {
16810
- toggleWorkflowWidget(ctx, "missionBottom");
16811
- return setWorkflowWidgetShortcutStatus(ctx, "missionBottom");
16812
- }
16813
- if (isStandardWorkflowMode(state)) {
16814
- toggleWorkflowWidget(ctx, "standardBottom");
16815
- return setWorkflowWidgetShortcutStatus(ctx, "standardBottom");
16816
- }
16817
- workflowEditorHintText = workflowEditorHintTextFor(state, loadWorkflowSettings(ctx.cwd)); return;
16818
- }});
16819
- pi.registerShortcut("ctrl+shift+u", { description: "Cycle workflow presets during Plan/Mission/Standard Mode", handler: async (ctx) => {
16820
- if (workflowWidgetUi(loadGlobalSettings()).enableWidgetShortcuts === false) { workflowEditorHintText = workflowEditorHintTextFor(state, loadWorkflowSettings(ctx.cwd), "Preset:disabled"); return; }
16821
- if (!isPlanWorkflowUiMode(state) && !isMissionWorkflowMode(state) && !isStandardWorkflowMode(state)) { workflowEditorHintText = workflowEditorHintTextFor(state, loadWorkflowSettings(ctx.cwd)); return; }
16822
- await cycleWorkflowPreset(ctx, 1);
16823
- }});
16824
- pi.registerShortcut("ctrl+shift+s", { description: "Toggle Standard Mode", handler: async (ctx) => {
16825
- if (isStandardWorkflowMode(state)) return exitStandardModeToIdle(ctx);
16826
- await enterStandardMode(ctx);
16827
- }});
16828
- pi.registerShortcut("ctrl+shift+l", { description: "Enter Plan Mode", handler: async (ctx) => {
16829
- if (isPlanWorkflowUiMode(state)) return exitPlanModeToIdle(ctx);
16830
- await enterPlanModeAwaitingInput(ctx);
16831
- }});
16832
- pi.registerShortcut("ctrl+shift+m", { description: "Toggle Mission Mode", handler: async (ctx) => {
16833
- if (isMissionWorkflowMode(state)) return exitMissionModeToIdle(ctx);
16834
- await enterMissionModeAwaitingInput(ctx);
16835
- }});
16829
+ for (const shortcut of WORKFLOW_SHORTCUTS) {
16830
+ pi.registerShortcut(workflowShortcutKey(shortcut.id), {
16831
+ description: shortcut.description,
16832
+ handler: workflowShortcutHandlers[shortcut.id],
16833
+ });
16834
+ }
16836
16835
 
16837
16836
  const handleWorkflowPlansCommand = async (args: string, _ctx: ExtensionContext): Promise<void> => {
16838
16837
  const parts = args.trim().split(/\s+/).filter(Boolean);
@@ -0,0 +1,114 @@
1
+ import type { KeyId } from "@earendil-works/pi-tui";
2
+
3
+ export type WorkflowShortcutPlatform = "darwin" | "win32" | "linux";
4
+ export type WorkflowShortcutActionId =
5
+ | "workflow.widget.top.toggle"
6
+ | "workflow.widget.bottom.toggle"
7
+ | "workflow.presets.cycle"
8
+ | "workflow.standard.toggle"
9
+ | "workflow.plan.toggle"
10
+ | "workflow.mission.toggle";
11
+
12
+ export interface WorkflowShortcutDefinition {
13
+ id: WorkflowShortcutActionId;
14
+ description: string;
15
+ fallbackCommand: string;
16
+ keys: Record<WorkflowShortcutPlatform, KeyId>;
17
+ }
18
+
19
+ export const WORKFLOW_SHORTCUTS: WorkflowShortcutDefinition[] = [
20
+ {
21
+ id: "workflow.widget.top.toggle",
22
+ description: "Toggle active Plan/Mission/Standard top workflow widget",
23
+ fallbackCommand: "/workflow widgets toggle top",
24
+ keys: { darwin: "ctrl+shift+t", win32: "f2", linux: "f2" },
25
+ },
26
+ {
27
+ id: "workflow.widget.bottom.toggle",
28
+ description: "Toggle active Plan/Mission/Standard bottom workflow widget",
29
+ fallbackCommand: "/workflow widgets toggle bottom",
30
+ keys: { darwin: "ctrl+shift+b", win32: "f3", linux: "f3" },
31
+ },
32
+ {
33
+ id: "workflow.presets.cycle",
34
+ description: "Cycle workflow presets during Plan/Mission/Standard Mode",
35
+ fallbackCommand: "/workflow presets next",
36
+ keys: { darwin: "ctrl+shift+u", win32: "f4", linux: "f4" },
37
+ },
38
+ {
39
+ id: "workflow.standard.toggle",
40
+ description: "Toggle Standard Mode",
41
+ fallbackCommand: "/standard",
42
+ keys: { darwin: "ctrl+shift+s", win32: "f6", linux: "f6" },
43
+ },
44
+ {
45
+ id: "workflow.plan.toggle",
46
+ description: "Enter Plan Mode",
47
+ fallbackCommand: "/plan",
48
+ keys: { darwin: "ctrl+shift+l", win32: "f7", linux: "f7" },
49
+ },
50
+ {
51
+ id: "workflow.mission.toggle",
52
+ description: "Toggle Mission Mode",
53
+ fallbackCommand: "/mission",
54
+ keys: { darwin: "ctrl+shift+m", win32: "f8", linux: "f8" },
55
+ },
56
+ ];
57
+
58
+ const SHORTCUT_BY_ID = new Map(WORKFLOW_SHORTCUTS.map((shortcut) => [shortcut.id, shortcut]));
59
+
60
+ export function workflowShortcutPlatform(platform = process.platform): WorkflowShortcutPlatform {
61
+ if (platform === "darwin" || platform === "win32" || platform === "linux") return platform;
62
+ return "linux";
63
+ }
64
+
65
+ export function workflowShortcutKey(id: WorkflowShortcutActionId, platform = process.platform): KeyId {
66
+ return workflowShortcutDefinition(id).keys[workflowShortcutPlatform(platform)];
67
+ }
68
+
69
+ export function workflowShortcutDefinition(id: WorkflowShortcutActionId): WorkflowShortcutDefinition {
70
+ const shortcut = SHORTCUT_BY_ID.get(id);
71
+ if (!shortcut) throw new Error(`Unknown Workflow Suite shortcut: ${id}`);
72
+ return shortcut;
73
+ }
74
+
75
+ export function workflowShortcutLabel(id: WorkflowShortcutActionId, platform = process.platform): string {
76
+ return workflowShortcutKeyLabel(workflowShortcutKey(id, platform));
77
+ }
78
+
79
+ export function workflowShortcutKeyLabel(key: KeyId): string {
80
+ return key.split("+").map((part) => {
81
+ if (/^f\d+$/i.test(part)) return part.toUpperCase();
82
+ return part.charAt(0).toUpperCase() + part.slice(1).toLowerCase();
83
+ }).join("+");
84
+ }
85
+
86
+ export function workflowEntryShortcutLabel(mode: "standard" | "plan" | "mission", platform = process.platform): string {
87
+ if (mode === "standard") return `Standard:${workflowShortcutLabel("workflow.standard.toggle", platform)}`;
88
+ if (mode === "plan") return `Plan:${workflowShortcutLabel("workflow.plan.toggle", platform)}`;
89
+ return `Mission:${workflowShortcutLabel("workflow.mission.toggle", platform)}`;
90
+ }
91
+
92
+ export function workflowWidgetShortcutLabel(includeBottom: boolean, platform = process.platform): string {
93
+ const prefix = includeBottom ? "Widgets" : "Widget";
94
+ if (!includeBottom) return `${prefix}:${workflowShortcutLabel("workflow.widget.top.toggle", platform)}`;
95
+ const activePlatform = workflowShortcutPlatform(platform);
96
+ if (activePlatform === "darwin") return `${prefix}:Ctrl+Shift+T/B`;
97
+ return `${prefix}:${workflowShortcutLabel("workflow.widget.top.toggle", platform)}/${workflowShortcutLabel("workflow.widget.bottom.toggle", platform)}`;
98
+ }
99
+
100
+ export function workflowPresetCycleShortcutLabel(platform = process.platform): string {
101
+ return workflowShortcutLabel("workflow.presets.cycle", platform);
102
+ }
103
+
104
+ export function workflowSettingsShortcutLines(platform = process.platform): string[] {
105
+ return [
106
+ `Standard Shortcut: ${workflowShortcutLabel("workflow.standard.toggle", platform)} toggles Standard Mode`,
107
+ `Plan Shortcut: ${workflowShortcutLabel("workflow.plan.toggle", platform)} enters Plan Mode`,
108
+ `Mission Shortcut: ${workflowShortcutLabel("workflow.mission.toggle", platform)} enters Mission Mode`,
109
+ `Widget Shortcuts: ${workflowWidgetShortcutLabel(true, platform).replace(/^Widgets:/, "")} while Plan/Mission/Standard Mode is active`,
110
+ `Preset Cycle Shortcut: ${workflowPresetCycleShortcutLabel(platform)} while Plan/Mission/Standard Mode is active`,
111
+ ];
112
+ }
113
+
114
+ export default function workflowShortcutsNoopExtension(): void {}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mediadatafusion/pi-workflow-suite",
3
- "version": "0.0.19",
3
+ "version": "0.0.20",
4
4
  "description": "Multi-agent workflow suite for Pi with Idle, Standard, Plan, Mission, approval gates, reviewer/validator roles, sub-agents, model routing, web search/fetch, browser checks, diagrams, compaction, presets, settings, themes, widgets, and Repo Lock.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -68,6 +68,7 @@ warn_unexpected_loadable_extensions() {
68
68
  extensions/subagent/index.ts
69
69
  extensions/workflow-model-router.ts
70
70
  extensions/workflow-modes.ts
71
+ extensions/workflow-shortcuts.ts
71
72
  extensions/workflow-parsers.ts
72
73
  extensions/workflow-settings-capabilities.ts
73
74
  extensions/workflow-state.ts
@@ -96,6 +97,7 @@ require_file "extensions/workflow-state.ts"
96
97
  require_file "extensions/workflow-summary.ts"
97
98
  require_file "extensions/workflow-tool-guard.ts"
98
99
  require_file "extensions/workflow-model-router.ts"
100
+ require_file "extensions/workflow-shortcuts.ts"
99
101
  require_file "extensions/subagent/index.ts"
100
102
  require_file "extensions/subagent/agents.ts"
101
103
  require_file "package.json"