@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 +11 -0
- package/README.md +37 -20
- package/VERSION +1 -1
- package/extensions/workflow-model-router.ts +2 -1
- package/extensions/workflow-modes.ts +65 -66
- package/extensions/workflow-shortcuts.ts +114 -0
- package/package.json +1 -1
- package/scripts/verify-live.sh +2 -0
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
|
[](#installation) [](#quick-start) [](#core-commands) [](#settings-reference)
|
|
6
6
|
|
|
7
|
-
**Workflow Suite Version:** `v0.0.
|
|
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
|
|
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
|
|
136
|
-
- Plan Mode through `/p
|
|
137
|
-
- Mission Mode through `/mission`, `/m`, and `Ctrl+Shift+M
|
|
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`
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
656
|
-
|
|
657
|
-
Ctrl+Shift+
|
|
658
|
-
Ctrl+Shift+
|
|
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.
|
|
1042
|
-
pi install -l npm:@mediadatafusion/pi-workflow-suite@0.0.
|
|
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.
|
|
1265
|
+
The current preparation version is `v0.0.20`. Version information is intentionally aligned across:
|
|
1249
1266
|
|
|
1250
|
-
- `VERSION` (`v0.0.
|
|
1251
|
-
- `package.json` (`0.0.
|
|
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.
|
|
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:
|
|
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
|
-
-
|
|
2565
|
-
-
|
|
2566
|
-
-
|
|
2567
|
-
- In the opposite active 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
|
-
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
5048
|
+
parts.push(workflowWidgetShortcutLabel(bottomRelevant));
|
|
5057
5049
|
}
|
|
5058
5050
|
if (ui.showPresetShortcutHint !== false) {
|
|
5059
|
-
parts.push(`Preset:${activeWorkflowPresetLabel(settings)}${shortcuts ?
|
|
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,
|
|
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-
|
|
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:
|
|
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
|
|
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:
|
|
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)} —
|
|
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:
|
|
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
|
-
|
|
16797
|
-
|
|
16798
|
-
|
|
16799
|
-
|
|
16800
|
-
|
|
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.
|
|
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": {
|
package/scripts/verify-live.sh
CHANGED
|
@@ -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"
|