@mediadatafusion/pi-workflow-suite 0.0.10 → 0.0.13

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.
Files changed (45) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/README.md +146 -20
  3. package/VERSION +1 -1
  4. package/agents/codebase-research.md +7 -5
  5. package/agents/general-worker.md +9 -7
  6. package/agents/implementation-planning.md +5 -3
  7. package/agents/quality-validation.md +9 -8
  8. package/agents/workflow-orchestrator.md +9 -7
  9. package/config/prompts/execute-approved-plan.md +12 -2
  10. package/config/prompts/mission-final-validation.md +38 -5
  11. package/config/prompts/mission-plan.md +17 -1
  12. package/config/prompts/mission-repair.md +16 -2
  13. package/config/prompts/mission-review-prompt.md +55 -0
  14. package/config/prompts/mission-run.md +18 -5
  15. package/config/prompts/validate-approved-plan.md +57 -3
  16. package/config/prompts/workflow-plan-prompt.md +11 -1
  17. package/config/prompts/workflow-repair.md +18 -2
  18. package/config/prompts/workflow-reviewer-prompt.md +60 -0
  19. package/config/prompts/workflow-summary.md +1 -4
  20. package/config/workflow-settings.example.json +13 -11
  21. package/extensions/subagent/index.ts +41 -18
  22. package/extensions/subagent/repolock-guard.ts +224 -4
  23. package/extensions/subagent/runner.ts +136 -12
  24. package/extensions/workflow-model-router.ts +152 -55
  25. package/extensions/workflow-modes.ts +4784 -1087
  26. package/extensions/workflow-settings-capabilities.ts +10 -0
  27. package/extensions/workflow-state.ts +139 -15
  28. package/extensions/workflow-subagent-policy.ts +13 -1
  29. package/extensions/workflow-summary.ts +8 -19
  30. package/extensions/workflow-tool-guard.ts +420 -39
  31. package/extensions/workflow-validation-classifier.ts +46 -4
  32. package/extensions/workflow-web-tools.ts +361 -1
  33. package/package.json +9 -5
  34. package/scripts/audit-live.sh +1 -1
  35. package/scripts/build-package-export.mjs +8 -13
  36. package/scripts/check-clean-release-tree.sh +3 -2
  37. package/scripts/check-package-media.mjs +78 -0
  38. package/scripts/install-to-live.sh +2 -0
  39. package/scripts/package-media-config.mjs +28 -0
  40. package/scripts/prepare-package-readme.mjs +19 -18
  41. package/scripts/quarantine-live-junk.sh +1 -1
  42. package/scripts/verify-live.sh +9 -1
  43. package/skills/implementation-planning/SKILL.md +1 -1
  44. package/skills/safe-execution/SKILL.md +1 -1
  45. package/skills/validation-review/SKILL.md +1 -1
@@ -37,6 +37,7 @@ export type WorkflowStartupLogo = "none" | "pi" | "custom";
37
37
  export type WorkflowStartupLogoFont = "block" | "shadow" | "outline" | "wide" | "double" | "three_d" | "solid";
38
38
  export type WorkflowStartupLogoShadowDirection = "down_right" | "down" | "up" | "left" | "right";
39
39
  export type WorkflowStartupLogoColorStyle = "theme" | "primary" | "split";
40
+ export type WorkflowWidgetTextPreset = "normal" | "bold" | "light" | "rich" | "italic" | "underline" | "terminal" | "smallcaps" | "typewriter";
40
41
  export type CustomBrandBaseVisual = "minimal" | "diagnostic_center" | "workflow_duo" | "mission_control" | "data_stream" | "neural_grid";
41
42
  export type RepairRetryGateName = "review" | "validation" | "missionValidation" | "missionFinalValidation";
42
43
 
@@ -93,6 +94,7 @@ export interface WorkflowSubagentSettings {
93
94
  planningOrchestrationPolicy?: PlanningOrchestrationPolicy;
94
95
  subagentTimeoutMinutes?: number;
95
96
  subagentStaleMinutes?: number;
97
+ allowBackgroundSubagents?: boolean;
96
98
  }
97
99
 
98
100
  export interface WorkflowSettings {
@@ -106,6 +108,8 @@ export interface WorkflowSettings {
106
108
  clarificationQualityGate?: boolean;
107
109
  allowClarificationWithoutAnalysis?: boolean;
108
110
  useSubagentsBeforeClarification?: boolean;
111
+ maxTokens?: number;
112
+ maxRuntimeHours?: number;
109
113
  };
110
114
  workflow: {
111
115
  requirePlanApprovalBeforeExecute: boolean;
@@ -138,6 +142,7 @@ export interface WorkflowSettings {
138
142
  planHistoryLimit?: number;
139
143
  planProgressEnabled?: boolean;
140
144
  planRuntimeEnabled?: boolean;
145
+ planShowProgressBar?: boolean;
141
146
  };
142
147
  standard: {
143
148
  enabled: boolean;
@@ -160,11 +165,13 @@ export interface WorkflowSettings {
160
165
  useStandardSpecificModels?: boolean;
161
166
  modelRole?: StandardModelRole;
162
167
  models?: Record<WorkflowRole, RoleModelSettings>;
168
+ maxTokens?: number;
163
169
  };
164
170
  missions: {
165
171
  enabled: boolean;
166
172
  defaultAutonomy: MissionAutonomy;
167
173
  maxRuntimeHours: number;
174
+ maxTokens?: number;
168
175
  checkpointIntervalMinutes: number;
169
176
  requireApprovalForDestructiveActions: boolean;
170
177
  requireValidationPerMilestone: boolean;
@@ -181,6 +188,7 @@ export interface WorkflowSettings {
181
188
  progressWidgetEnabled?: boolean;
182
189
  progressOutputMode?: "compact" | "detailed";
183
190
  showProgressBar?: boolean;
191
+ missionHistoryLimit?: number;
184
192
  heartbeatEnabled?: boolean;
185
193
  watchdogEnabled?: boolean;
186
194
  watchdogStaleMinutes?: number;
@@ -214,6 +222,7 @@ export interface WorkflowSettings {
214
222
  disableBashInPlanMode: boolean;
215
223
  disableBashInValidatorMode: boolean;
216
224
  blockDestructiveCommands: boolean;
225
+ allowPackageInstallInExecution: boolean;
217
226
  };
218
227
  ui: {
219
228
  showWorkflowStatus: boolean;
@@ -232,6 +241,8 @@ export interface WorkflowSettings {
232
241
  showPresetShortcutHint?: boolean;
233
242
  workflowTheme?: string;
234
243
  workflowThemeOverrides?: Record<string, string>;
244
+ widgetTextStyle?: WorkflowWidgetTextPreset;
245
+ startupTextStyle?: WorkflowWidgetTextPreset;
235
246
  startupVisual?: WorkflowStartupVisual;
236
247
  startupLogo?: WorkflowStartupLogo;
237
248
  startupLogoText?: string;
@@ -242,6 +253,7 @@ export interface WorkflowSettings {
242
253
  customBrandEnabled?: boolean;
243
254
  customBrandText?: string;
244
255
  customBrandBaseVisual?: CustomBrandBaseVisual;
256
+ debugPlanStepTracking?: boolean;
245
257
  };
246
258
  subagents: WorkflowSubagentSettings;
247
259
  context: {
@@ -249,10 +261,10 @@ export interface WorkflowSettings {
249
261
  compactionModelProvider: string;
250
262
  compactionModel: string;
251
263
  compactionAgent: string;
252
- customCompactionEnabled: boolean;
253
- autoCompactionEnabled: boolean;
254
- compactionTriggerPercent: number;
255
- compactionCooldownMinutes: number;
264
+ customCompactionEnabled?: boolean;
265
+ autoCompactionEnabled?: boolean;
266
+ compactionTriggerPercent?: number;
267
+ compactionCooldownMinutes?: number;
256
268
  customCompactionReserveTokens?: number;
257
269
  customCompactionKeepRecentTokens?: number;
258
270
  workflowCompactionCheckMode?: WorkflowCompactionCheckMode;
@@ -365,6 +377,7 @@ const BUILTIN_DEFAULT_WORKFLOW_SETTINGS = {
365
377
  "planHistoryLimit": 50,
366
378
  "planProgressEnabled": true,
367
379
  "planRuntimeEnabled": true,
380
+ "planShowProgressBar": true,
368
381
  "requireApprovalBeforeExecution": true,
369
382
  "requireApprovalPerStep": false,
370
383
  "validateAfterEachStep": false,
@@ -415,7 +428,8 @@ const BUILTIN_DEFAULT_WORKFLOW_SETTINGS = {
415
428
  "model": null,
416
429
  "thinkingLevel": "xhigh"
417
430
  }
418
- }
431
+ },
432
+ "maxTokens": 0
419
433
  },
420
434
  "missions": {
421
435
  "enabled": true,
@@ -429,14 +443,15 @@ const BUILTIN_DEFAULT_WORKFLOW_SETTINGS = {
429
443
  "autoRunAfterApproval": true,
430
444
  "offerReviewerBeforeApprove": false,
431
445
  "autoRunReviewerBeforeApprove": false,
432
- "autoRepairReviewFailures": false,
433
- "reviewRetryMode": "off",
434
- "maxReviewRetriesPerMission": 0,
446
+ "autoRepairReviewFailures": true,
447
+ "reviewRetryMode": "safe_only",
448
+ "maxReviewRetriesPerMission": 2,
435
449
  "continueAcrossMilestones": true,
436
450
  "pauseBetweenMilestones": false,
437
451
  "progressWidgetEnabled": true,
438
452
  "progressOutputMode": "compact",
439
453
  "showProgressBar": true,
454
+ "missionHistoryLimit": 50,
440
455
  "heartbeatEnabled": true,
441
456
  "watchdogEnabled": false,
442
457
  "watchdogStaleMinutes": 30,
@@ -488,13 +503,15 @@ const BUILTIN_DEFAULT_WORKFLOW_SETTINGS = {
488
503
  "clarificationTiming": "after_initial_analysis",
489
504
  "clarificationQualityGate": true,
490
505
  "allowClarificationWithoutAnalysis": false,
491
- "useSubagentsBeforeClarification": true
506
+ "useSubagentsBeforeClarification": true,
507
+ "maxTokens": 0
492
508
  },
493
509
  "safety": {
494
- "repoLockEnabled": false,
495
- "disableBashInPlanMode": true,
510
+ "repoLockEnabled": true,
511
+ "disableBashInPlanMode": false,
496
512
  "disableBashInValidatorMode": true,
497
- "blockDestructiveCommands": true
513
+ "blockDestructiveCommands": true,
514
+ "allowPackageInstallInExecution": true
498
515
  },
499
516
  "ui": {
500
517
  "showWorkflowStatus": true,
@@ -513,6 +530,8 @@ const BUILTIN_DEFAULT_WORKFLOW_SETTINGS = {
513
530
  "showPresetShortcutHint": true,
514
531
  "workflowTheme": "aurora",
515
532
  "workflowThemeOverrides": {},
533
+ "widgetTextStyle": undefined,
534
+ "startupTextStyle": undefined,
516
535
  "startupVisual": "mission_control",
517
536
  "startupLogo": "pi",
518
537
  "startupLogoText": "",
@@ -522,7 +541,8 @@ const BUILTIN_DEFAULT_WORKFLOW_SETTINGS = {
522
541
  "startupVisualOnSessionStart": true,
523
542
  "customBrandEnabled": false,
524
543
  "customBrandText": "",
525
- "customBrandBaseVisual": "mission_control"
544
+ "customBrandBaseVisual": "mission_control",
545
+ "debugPlanStepTracking": false
526
546
  },
527
547
  "shortcuts": {
528
548
  "planMode": null
@@ -562,7 +582,8 @@ const BUILTIN_DEFAULT_WORKFLOW_SETTINGS = {
562
582
  "requireParallelEditConflictProtection": true,
563
583
  "planningOrchestrationPolicy": "orchestrator_first",
564
584
  "subagentTimeoutMinutes": 20,
565
- "subagentStaleMinutes": 8
585
+ "subagentStaleMinutes": 8,
586
+ "allowBackgroundSubagents": true
566
587
  },
567
588
  "planning": {
568
589
  "clarificationMode": "auto",
@@ -572,7 +593,9 @@ const BUILTIN_DEFAULT_WORKFLOW_SETTINGS = {
572
593
  "clarificationTiming": "after_initial_analysis",
573
594
  "clarificationQualityGate": true,
574
595
  "allowClarificationWithoutAnalysis": false,
575
- "useSubagentsBeforeClarification": true
596
+ "useSubagentsBeforeClarification": true,
597
+ "maxTokens": 0,
598
+ "maxRuntimeHours": 0
576
599
  },
577
600
  "context": {
578
601
  "compactionMode": "pi_default",
@@ -580,8 +603,6 @@ const BUILTIN_DEFAULT_WORKFLOW_SETTINGS = {
580
603
  "compactionModel": "",
581
604
  "compactionAgent": "",
582
605
  "customCompactionEnabled": false,
583
- "autoCompactionEnabled": false,
584
- "compactionTriggerPercent": 85,
585
606
  "compactionCooldownMinutes": 5,
586
607
  "customCompactionReserveTokens": 16384,
587
608
  "customCompactionKeepRecentTokens": 20000,
@@ -776,6 +797,50 @@ export interface SettingsWriteResult {
776
797
  file: string;
777
798
  }
778
799
 
800
+ interface UpdateSettingsOptions {
801
+ preserveActivePreset?: boolean;
802
+ }
803
+
804
+ export const WORKFLOW_MANUAL_PRESET = "custom";
805
+
806
+ function presetOwnedSettingsSignature(settings: WorkflowSettings): string {
807
+ const { models: _ignoredStandardModels, ...standardWithoutModels } = settings.standard;
808
+ const { models: _ignoredMissionModels, ...missionsWithoutModels } = settings.missions;
809
+ return JSON.stringify({
810
+ planning: settings.planning,
811
+ workflow: settings.workflow,
812
+ standard: standardWithoutModels,
813
+ missions: missionsWithoutModels,
814
+ subagents: settings.subagents,
815
+ });
816
+ }
817
+
818
+ function applyActivePresetOverlay(settings: WorkflowSettings): WorkflowSettings {
819
+ const active = settings.presets?.activePreset ?? WORKFLOW_MANUAL_PRESET;
820
+ if (active === WORKFLOW_MANUAL_PRESET) return settings;
821
+ const preset = workflowPresetCatalog(settings)[active];
822
+ if (!preset) return settings;
823
+ const defaults = defaultWorkflowSettings();
824
+ const normalized = normalizeWorkflowPresetBundle(preset);
825
+ const currentStandardModels = settings.standard.models;
826
+ const currentMissionModels = settings.missions.models;
827
+ return {
828
+ ...settings,
829
+ planning: normalized.planning ? { ...settings.planning, ...normalized.planning } : settings.planning,
830
+ workflow: normalized.workflow ? { ...settings.workflow, ...normalized.workflow } : settings.workflow,
831
+ standard: {
832
+ ...defaults.standard,
833
+ ...settings.standard,
834
+ ...normalized.standard,
835
+ subagents: { ...(defaults.standard.subagents ?? {}), ...(settings.standard.subagents ?? {}), ...(normalized.standard.subagents ?? {}) },
836
+ models: currentStandardModels,
837
+ },
838
+ missions: normalized.missions ? { ...settings.missions, ...normalized.missions, models: currentMissionModels } : settings.missions,
839
+ subagents: normalized.subagents ? { ...settings.subagents, ...normalized.subagents } : settings.subagents,
840
+ presets: settings.presets,
841
+ };
842
+ }
843
+
779
844
  /** Load effective settings: project overrides merged over global. */
780
845
  export function loadEffectiveSettings(cwd: string): EffectiveSettings {
781
846
  const global = loadGlobalSettings();
@@ -783,7 +848,7 @@ export function loadEffectiveSettings(cwd: string): EffectiveSettings {
783
848
  if (!projectPath) return { settings: global, projectOverridePath: undefined };
784
849
  try {
785
850
  const project = JSON.parse(readFileSync(projectPath, "utf8")) as Partial<WorkflowSettings>;
786
- return { settings: mergeSettings(global, project), projectOverridePath: projectPath };
851
+ return { settings: applyActivePresetOverlay(mergeSettings(global, project)), projectOverridePath: projectPath };
787
852
  } catch {
788
853
  return { settings: global, projectOverridePath: projectPath };
789
854
  }
@@ -797,7 +862,7 @@ export function loadGlobalSettings(): WorkflowSettings {
797
862
  return defaults;
798
863
  }
799
864
  const parsed = parseWorkflowSettingsFile(WORKFLOW_SETTINGS_FILE, defaults, "global workflow settings") as Partial<WorkflowSettings>;
800
- return mergeSettings(defaults, parsed);
865
+ return applyActivePresetOverlay(mergeSettings(defaults, parsed));
801
866
  }
802
867
 
803
868
  /** Backwards-compatible: loads effective settings for a given cwd. */
@@ -855,10 +920,16 @@ export function createProjectSettingsOverride(cwd: string): SettingsWriteResult
855
920
  return { settings, scope: "project", file };
856
921
  }
857
922
 
858
- export function updateSettings(cwd: string, requestedScope: WorkflowSettingsScope | undefined, updater: (settings: WorkflowSettings) => void): SettingsWriteResult {
923
+ export function updateSettings(cwd: string, requestedScope: WorkflowSettingsScope | undefined, updater: (settings: WorkflowSettings) => void, options: UpdateSettingsOptions = {}): SettingsWriteResult {
859
924
  const target = getWriteTarget(cwd, requestedScope);
860
925
  const settings = target.scope === "global" ? loadGlobalSettings() : loadEffectiveSettings(cwd).settings;
926
+ const beforePreset = settings.presets?.activePreset ?? WORKFLOW_MANUAL_PRESET;
927
+ const beforePresetOwned = presetOwnedSettingsSignature(settings);
861
928
  updater(settings);
929
+ const afterPresetOwned = presetOwnedSettingsSignature(settings);
930
+ if (!options.preserveActivePreset && beforePreset !== WORKFLOW_MANUAL_PRESET && settings.presets?.activePreset === beforePreset && beforePresetOwned !== afterPresetOwned) {
931
+ settings.presets = { ...(settings.presets ?? {}), activePreset: WORKFLOW_MANUAL_PRESET, items: { ...(settings.presets?.items ?? {}) } };
932
+ }
862
933
  saveSettingsFile(target.file, settings);
863
934
  return { settings, scope: target.scope, file: target.file };
864
935
  }
@@ -869,58 +940,71 @@ export function builtInWorkflowPresets(): Record<string, WorkflowPresetBundle> {
869
940
  displayName: "Simple",
870
941
  description: "Fast end-to-end Plan/Mission/Standard workflow with minimal ceremony, automatic validation when work runs, low safe repair retries, and one-worker sub-agent support.",
871
942
  planning: { depth: "fast", clarificationMode: "auto", maxClarificationQuestions: 2, interactiveClarificationEnabled: true, clarificationQualityGate: false, useSubagentsBeforeClarification: true },
872
- workflow: { offerReviewerBeforeExecute: false, autoRunReviewerBeforeExecute: false, offerValidationAfterExecute: true, autoRunValidationAfterExecute: true, validateAfterExecution: true, requirePlanApprovalBeforeExecute: false, requireApprovalBeforeExecution: false, autoRepairReviewFailures: false, autoRepairValidationFailures: true, reviewRetryMode: "off", validationRetryMode: "safe_only", maxReviewRetriesPerPlan: 0, maxReviewRetriesPerWorkflow: 0, maxValidationRetriesPerPlan: 1, maxValidationRetriesPerWorkflow: 2, pauseAfterReviewFailure: true, pauseAfterValidationFailure: false, planProgressEnabled: true, planRuntimeEnabled: true },
943
+ workflow: { offerReviewerBeforeExecute: false, autoRunReviewerBeforeExecute: false, offerValidationAfterExecute: true, autoRunValidationAfterExecute: true, validateAfterExecution: true, requirePlanApprovalBeforeExecute: false, requireApprovalBeforeExecution: false, autoRepairReviewFailures: false, autoRepairValidationFailures: true, reviewRetryMode: "off", validationRetryMode: "safe_only", maxReviewRetriesPerPlan: 0, maxReviewRetriesPerWorkflow: 0, maxValidationRetriesPerPlan: 1, maxValidationRetriesPerWorkflow: 2, pauseAfterReviewFailure: true, pauseAfterValidationFailure: false, planProgressEnabled: true, planRuntimeEnabled: true, planShowProgressBar: true },
873
944
  standard: { enabled: true, autoTodoEnabled: true, todoProgressVisible: true, todoTriggerMode: "auto", clarificationEnabled: true, clarificationMode: "auto", maxClarificationQuestions: 1, interactiveClarificationEnabled: true, clarificationTiming: "after_initial_analysis", clarificationQualityGate: false, allowClarificationWithoutAnalysis: false, useSubagentsBeforeClarification: false, allowSubagents: true, subagentScope: "user", subagents: { planningPolicy: "forced", executionPolicy: "forced", repairPolicy: "forced", reviewPolicy: "auto", validationPolicy: "forced", autoUseDuringPlanning: true, autoUseDuringExecution: true, autoUseDuringRepair: true, autoUseDuringReview: true, autoUseDuringValidation: true, minPlanningWorkersForDeep: 1, minPlanningWorkersForMaximum: 1, minExecutionWorkersForDeep: 1, minExecutionWorkersForMaximum: 1, minRepairWorkersForDeep: 1, minRepairWorkersForMaximum: 1, minReviewWorkersForDeep: 1, minReviewWorkersForMaximum: 1, minValidationWorkersForDeep: 1, minValidationWorkersForMaximum: 1 }, statusWidgetVisible: true, useSharedExecutorModel: true, useStandardSpecificModels: false, modelRole: "executor" },
874
- missions: { defaultAutonomy: "approval_gated", requireValidationPerMilestone: true, autoRunAfterApproval: true, continueAcrossMilestones: true, pauseBetweenMilestones: false, clarificationMode: "auto", maxClarificationQuestions: 2, planningDepth: "fast", useSubagentsBeforeClarification: true, autoRepairValidationFailures: true, validationRetryMode: "safe_only", maxValidationRetriesPerMilestone: 1, maxValidationRetriesPerMission: 2, finalValidationEnabled: false, autoRepairFinalValidationFailures: false, maxFinalValidationRetries: 0, subagentPolicy: "forced", minWorkersForDeep: 1, minWorkersForMaximum: 1 },
875
- subagents: { planningPolicy: "forced", executionPolicy: "forced", repairPolicy: "forced", reviewPolicy: "auto", validationPolicy: "forced", autoUseDuringPlanning: true, autoUseDuringExecution: true, autoUseDuringRepair: true, autoUseDuringReview: true, autoUseDuringValidation: true, minPlanningWorkersForDeep: 1, minPlanningWorkersForMaximum: 1, minExecutionWorkersForDeep: 1, minExecutionWorkersForMaximum: 1, minRepairWorkersForDeep: 1, minRepairWorkersForMaximum: 1, minReviewWorkersForDeep: 1, minReviewWorkersForMaximum: 1, minValidationWorkersForDeep: 1, minValidationWorkersForMaximum: 1 },
945
+ missions: { defaultAutonomy: "approval_gated", requireValidationPerMilestone: true, autoRunAfterApproval: true, continueAcrossMilestones: true, pauseBetweenMilestones: false, clarificationMode: "auto", maxClarificationQuestions: 2, planningDepth: "fast", useSubagentsBeforeClarification: true, autoRepairReviewFailures: false, reviewRetryMode: "off", maxReviewRetriesPerMission: 0, autoRepairValidationFailures: true, validationRetryMode: "safe_only", maxValidationRetriesPerMilestone: 1, maxValidationRetriesPerMission: 2, finalValidationEnabled: false, autoRepairFinalValidationFailures: false, maxFinalValidationRetries: 0, subagentPolicy: "forced", minWorkersForDeep: 1, minWorkersForMaximum: 1 },
946
+ subagents: { planningPolicy: "forced", executionPolicy: "forced", repairPolicy: "forced", reviewPolicy: "auto", validationPolicy: "forced", autoUseDuringPlanning: true, autoUseDuringExecution: true, autoUseDuringRepair: true, autoUseDuringReview: true, autoUseDuringValidation: true, minPlanningWorkersForDeep: 1, minPlanningWorkersForMaximum: 1, minExecutionWorkersForDeep: 1, minExecutionWorkersForMaximum: 1, minRepairWorkersForDeep: 1, minRepairWorkersForMaximum: 1, minReviewWorkersForDeep: 1, minReviewWorkersForMaximum: 1, minValidationWorkersForDeep: 1, minValidationWorkersForMaximum: 1, allowBackgroundSubagents: false },
876
947
  },
877
948
  standard: {
878
949
  displayName: "Standard",
879
950
  description: "Default end-to-end workflow with useful clarification, automatic execution/validation after approval, safe repair retries, and balanced worker support.",
880
951
  planning: { depth: "standard", clarificationMode: "auto", maxClarificationQuestions: 3, interactiveClarificationEnabled: true, clarificationQualityGate: true, useSubagentsBeforeClarification: true },
881
- 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: 2, maxReviewRetriesPerWorkflow: 4, maxValidationRetriesPerPlan: 2, maxValidationRetriesPerWorkflow: 4, pauseAfterReviewFailure: false, pauseAfterValidationFailure: false, planProgressEnabled: true, planRuntimeEnabled: true },
952
+ 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: 2, maxReviewRetriesPerWorkflow: 4, maxValidationRetriesPerPlan: 2, maxValidationRetriesPerWorkflow: 4, pauseAfterReviewFailure: false, pauseAfterValidationFailure: false, planProgressEnabled: true, planRuntimeEnabled: true, planShowProgressBar: true },
882
953
  standard: { enabled: true, autoTodoEnabled: true, todoProgressVisible: true, todoTriggerMode: "auto", clarificationEnabled: true, clarificationMode: "auto", maxClarificationQuestions: 1, interactiveClarificationEnabled: true, clarificationTiming: "after_initial_analysis", clarificationQualityGate: true, allowClarificationWithoutAnalysis: false, useSubagentsBeforeClarification: false, 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: 1, minPlanningWorkersForMaximum: 1, minExecutionWorkersForDeep: 2, minExecutionWorkersForMaximum: 2, minRepairWorkersForDeep: 2, minRepairWorkersForMaximum: 2, minReviewWorkersForDeep: 2, minReviewWorkersForMaximum: 2, minValidationWorkersForDeep: 2, minValidationWorkersForMaximum: 2 }, statusWidgetVisible: true, useSharedExecutorModel: true, useStandardSpecificModels: false, modelRole: "executor" },
883
- missions: { defaultAutonomy: "approval_gated", requireValidationPerMilestone: true, autoRunAfterApproval: true, continueAcrossMilestones: true, pauseBetweenMilestones: false, clarificationMode: "auto", maxClarificationQuestions: 3, planningDepth: "standard", useSubagentsBeforeClarification: true, autoRepairValidationFailures: true, validationRetryMode: "safe_only", maxValidationRetriesPerMilestone: 2, maxValidationRetriesPerMission: 6, finalValidationEnabled: false, autoRepairFinalValidationFailures: false, maxFinalValidationRetries: 1, subagentPolicy: "forced", minWorkersForDeep: 1, minWorkersForMaximum: 1 },
884
- subagents: { planningPolicy: "forced", executionPolicy: "forced", repairPolicy: "forced", reviewPolicy: "forced", validationPolicy: "forced", autoUseDuringPlanning: true, autoUseDuringExecution: true, autoUseDuringRepair: true, autoUseDuringReview: true, autoUseDuringValidation: true, minPlanningWorkersForDeep: 1, minPlanningWorkersForMaximum: 1, minExecutionWorkersForDeep: 2, minExecutionWorkersForMaximum: 2, minRepairWorkersForDeep: 2, minRepairWorkersForMaximum: 2, minReviewWorkersForDeep: 2, minReviewWorkersForMaximum: 2, minValidationWorkersForDeep: 2, minValidationWorkersForMaximum: 2 },
954
+ missions: { defaultAutonomy: "approval_gated", requireValidationPerMilestone: true, autoRunAfterApproval: true, continueAcrossMilestones: true, pauseBetweenMilestones: false, clarificationMode: "auto", maxClarificationQuestions: 3, planningDepth: "standard", useSubagentsBeforeClarification: true, autoRepairReviewFailures: true, reviewRetryMode: "safe_only", maxReviewRetriesPerMission: 2, autoRepairValidationFailures: true, validationRetryMode: "safe_only", maxValidationRetriesPerMilestone: 2, maxValidationRetriesPerMission: 6, finalValidationEnabled: false, autoRepairFinalValidationFailures: false, maxFinalValidationRetries: 1, subagentPolicy: "forced", minWorkersForDeep: 1, minWorkersForMaximum: 1 },
955
+ subagents: { planningPolicy: "forced", executionPolicy: "forced", repairPolicy: "forced", reviewPolicy: "forced", validationPolicy: "forced", autoUseDuringPlanning: true, autoUseDuringExecution: true, autoUseDuringRepair: true, autoUseDuringReview: true, autoUseDuringValidation: true, minPlanningWorkersForDeep: 1, minPlanningWorkersForMaximum: 1, minExecutionWorkersForDeep: 2, minExecutionWorkersForMaximum: 2, minRepairWorkersForDeep: 2, minRepairWorkersForMaximum: 2, minReviewWorkersForDeep: 2, minReviewWorkersForMaximum: 2, minValidationWorkersForDeep: 2, minValidationWorkersForMaximum: 2, allowBackgroundSubagents: false },
885
956
  },
886
957
  deep: {
887
958
  displayName: "Deep",
888
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.",
889
960
  planning: { depth: "deep", clarificationMode: "always_for_nontrivial", maxClarificationQuestions: 5, interactiveClarificationEnabled: true, clarificationQualityGate: true, useSubagentsBeforeClarification: true },
890
- 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 },
891
- standard: { enabled: true, autoTodoEnabled: true, todoProgressVisible: true, todoTriggerMode: "required", clarificationEnabled: true, clarificationMode: "always_for_nontrivial", 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" },
892
- missions: { defaultAutonomy: "approval_gated", requireValidationPerMilestone: true, autoRunAfterApproval: true, continueAcrossMilestones: true, pauseBetweenMilestones: false, clarificationMode: "always_for_nontrivial", maxClarificationQuestions: 5, planningDepth: "deep", useSubagentsBeforeClarification: true, autoRepairValidationFailures: true, validationRetryMode: "safe_only", maxValidationRetriesPerMilestone: 3, maxValidationRetriesPerMission: 8, finalValidationEnabled: true, autoRepairFinalValidationFailures: true, maxFinalValidationRetries: 2, subagentPolicy: "forced", minWorkersForDeep: 3, minWorkersForMaximum: 3 },
893
- 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 },
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 },
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
+ 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
+ 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 },
894
965
  },
895
966
  maximum: {
896
967
  displayName: "Maximum",
897
968
  description: "Highest-rigor end-to-end workflow with strongest clarification, automatic review/validation, final mission validation, aggressive in-scope repair, and maximum worker teams.",
898
969
  planning: { depth: "maximum", clarificationMode: "always_for_nontrivial", maxClarificationQuestions: 5, interactiveClarificationEnabled: true, clarificationQualityGate: true, useSubagentsBeforeClarification: true },
899
- workflow: { offerReviewerBeforeExecute: false, autoRunReviewerBeforeExecute: true, offerValidationAfterExecute: true, autoRunValidationAfterExecute: true, validateAfterExecution: true, requirePlanApprovalBeforeExecute: false, requireApprovalBeforeExecution: false, autoRepairReviewFailures: true, autoRepairValidationFailures: true, reviewRetryMode: "aggressive_within_scope", validationRetryMode: "aggressive_within_scope", maxReviewRetriesPerPlan: 5, maxReviewRetriesPerWorkflow: 8, maxValidationRetriesPerPlan: 5, maxValidationRetriesPerWorkflow: 8, pauseAfterReviewFailure: false, pauseAfterValidationFailure: false, planProgressEnabled: true, planRuntimeEnabled: true },
900
- standard: { enabled: true, autoTodoEnabled: true, todoProgressVisible: true, todoTriggerMode: "required", clarificationEnabled: true, clarificationMode: "always_for_nontrivial", 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: 3, minPlanningWorkersForMaximum: 3, minExecutionWorkersForDeep: 4, minExecutionWorkersForMaximum: 4, minRepairWorkersForDeep: 3, minRepairWorkersForMaximum: 3, minReviewWorkersForDeep: 4, minReviewWorkersForMaximum: 4, minValidationWorkersForDeep: 4, minValidationWorkersForMaximum: 4 }, statusWidgetVisible: true, useSharedExecutorModel: true, useStandardSpecificModels: false, modelRole: "executor" },
901
- missions: { defaultAutonomy: "supervised_auto", requireValidationPerMilestone: true, autoRunAfterApproval: true, continueAcrossMilestones: true, pauseBetweenMilestones: false, clarificationMode: "always_for_nontrivial", maxClarificationQuestions: 6, planningDepth: "maximum", useSubagentsBeforeClarification: true, autoRepairValidationFailures: true, validationRetryMode: "aggressive_within_scope", maxValidationRetriesPerMilestone: 4, maxValidationRetriesPerMission: 12, finalValidationEnabled: true, autoRepairFinalValidationFailures: true, maxFinalValidationRetries: 4, subagentPolicy: "forced", minWorkersForDeep: 4, minWorkersForMaximum: 4 },
902
- subagents: { planningPolicy: "forced", executionPolicy: "forced", repairPolicy: "forced", reviewPolicy: "forced", validationPolicy: "forced", autoUseDuringPlanning: true, autoUseDuringExecution: true, autoUseDuringRepair: true, autoUseDuringReview: true, autoUseDuringValidation: true, minPlanningWorkersForDeep: 4, minPlanningWorkersForMaximum: 4, minExecutionWorkersForDeep: 4, minExecutionWorkersForMaximum: 4, minRepairWorkersForDeep: 3, minRepairWorkersForMaximum: 3, minReviewWorkersForDeep: 4, minReviewWorkersForMaximum: 4, minValidationWorkersForDeep: 4, minValidationWorkersForMaximum: 4 },
970
+ workflow: { offerReviewerBeforeExecute: false, autoRunReviewerBeforeExecute: true, offerValidationAfterExecute: true, autoRunValidationAfterExecute: true, validateAfterExecution: true, requirePlanApprovalBeforeExecute: false, requireApprovalBeforeExecution: false, autoRepairReviewFailures: true, autoRepairValidationFailures: true, reviewRetryMode: "aggressive_within_scope", validationRetryMode: "aggressive_within_scope", maxReviewRetriesPerPlan: 5, maxReviewRetriesPerWorkflow: 8, maxValidationRetriesPerPlan: 5, maxValidationRetriesPerWorkflow: 8, pauseAfterReviewFailure: false, pauseAfterValidationFailure: false, planProgressEnabled: true, planRuntimeEnabled: true, planShowProgressBar: true },
971
+ 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: 3, minPlanningWorkersForMaximum: 3, minExecutionWorkersForDeep: 4, minExecutionWorkersForMaximum: 4, minRepairWorkersForDeep: 3, minRepairWorkersForMaximum: 3, minReviewWorkersForDeep: 4, minReviewWorkersForMaximum: 4, minValidationWorkersForDeep: 4, minValidationWorkersForMaximum: 4 }, statusWidgetVisible: true, useSharedExecutorModel: true, useStandardSpecificModels: false, modelRole: "executor" },
972
+ missions: { defaultAutonomy: "supervised_auto", requireValidationPerMilestone: true, autoRunAfterApproval: true, continueAcrossMilestones: true, pauseBetweenMilestones: false, clarificationMode: "always_for_nontrivial", maxClarificationQuestions: 6, planningDepth: "maximum", useSubagentsBeforeClarification: true, autoRepairReviewFailures: true, reviewRetryMode: "aggressive_within_scope", maxReviewRetriesPerMission: 5, autoRepairValidationFailures: true, validationRetryMode: "aggressive_within_scope", maxValidationRetriesPerMilestone: 4, maxValidationRetriesPerMission: 12, finalValidationEnabled: true, autoRepairFinalValidationFailures: true, maxFinalValidationRetries: 4, subagentPolicy: "forced", minWorkersForDeep: 4, minWorkersForMaximum: 4 },
973
+ subagents: { planningPolicy: "forced", executionPolicy: "forced", repairPolicy: "forced", reviewPolicy: "forced", validationPolicy: "forced", autoUseDuringPlanning: true, autoUseDuringExecution: true, autoUseDuringRepair: true, autoUseDuringReview: true, autoUseDuringValidation: true, minPlanningWorkersForDeep: 4, minPlanningWorkersForMaximum: 4, minExecutionWorkersForDeep: 4, minExecutionWorkersForMaximum: 4, minRepairWorkersForDeep: 3, minRepairWorkersForMaximum: 3, minReviewWorkersForDeep: 4, minReviewWorkersForMaximum: 4, minValidationWorkersForDeep: 4, minValidationWorkersForMaximum: 4, allowBackgroundSubagents: true },
903
974
  },
904
975
  };
905
976
  }
906
977
 
907
978
  function normalizeWorkflowPresetBundle(preset: WorkflowPresetBundle): WorkflowPresetBundle & { standard: WorkflowSettings["standard"] } {
908
979
  const defaults = defaultWorkflowSettings();
980
+ const { models: _ignoredPresetStandardModels, ...standardWithoutModels } = (preset.standard ?? {}) as Partial<WorkflowSettings["standard"]>;
909
981
  return {
910
982
  ...preset,
911
983
  // Legacy custom presets saved before Standard Mode do not contain a
912
984
  // standard section. Hydrate it from safe defaults during apply so stale
913
985
  // Standard settings from the previously active preset cannot leak forward.
914
- standard: normalizeStandardSettings(defaults, defaults.standard, preset.standard as Partial<WorkflowSettings>["standard"] | undefined),
986
+ standard: normalizeStandardSettings(defaults, defaults.standard, standardWithoutModels as Partial<WorkflowSettings>["standard"] | undefined),
987
+ };
988
+ }
989
+
990
+ function workflowPresetBundleWithoutUserOwnedSettings(preset: WorkflowPresetBundle): WorkflowPresetBundle {
991
+ const { context: _ignoredContext, ...presetWithoutContext } = preset as WorkflowPresetBundle & { context?: unknown };
992
+ const { models: _ignoredStandardModels, ...standardWithoutModels } = (preset.standard ?? {}) as Partial<WorkflowSettings["standard"]>;
993
+ const { models: _ignoredMissionModels, ...missionsWithoutModels } = (preset.missions ?? {}) as Partial<WorkflowSettings["missions"]>;
994
+ return {
995
+ ...presetWithoutContext,
996
+ standard: { ...standardWithoutModels },
997
+ missions: { ...missionsWithoutModels },
915
998
  };
916
999
  }
917
1000
 
918
1001
  function applyPresetBundle(settings: WorkflowSettings, preset: WorkflowPresetBundle, name: string): void {
919
1002
  const defaults = defaultWorkflowSettings();
920
1003
  const normalized = normalizeWorkflowPresetBundle(preset);
1004
+ const currentStandardModels = settings.standard.models;
921
1005
  if (normalized.planning) settings.planning = { ...settings.planning, ...normalized.planning };
922
1006
  if (normalized.workflow) settings.workflow = { ...settings.workflow, ...normalized.workflow };
923
- settings.standard = { ...defaults.standard, ...normalized.standard, subagents: { ...(defaults.standard.subagents ?? {}), ...(normalized.standard?.subagents ?? {}) }, models: normalizeStandardModels(defaults, settings.standard, preset.standard as Partial<WorkflowSettings>["standard"] | undefined) };
1007
+ settings.standard = { ...defaults.standard, ...normalized.standard, subagents: { ...(defaults.standard.subagents ?? {}), ...(normalized.standard?.subagents ?? {}) }, models: currentStandardModels };
924
1008
  if (normalized.missions) settings.missions = { ...settings.missions, ...normalized.missions, models: settings.missions.models };
925
1009
  if (normalized.subagents) settings.subagents = { ...settings.subagents, ...normalized.subagents };
926
1010
  if (normalized.ui) settings.ui = { ...settings.ui, ...normalized.ui };
@@ -931,8 +1015,6 @@ export function normalizeWorkflowPresetName(name: string): string {
931
1015
  return name.trim().toLowerCase().replace(/[^A-Za-z0-9._-]+/g, "-").replace(/-+/g, "-").replace(/^-+|-+$/g, "");
932
1016
  }
933
1017
 
934
- export const WORKFLOW_MANUAL_PRESET = "custom";
935
-
936
1018
  export function workflowPresetCatalog(settings: WorkflowSettings = loadGlobalSettings()): Record<string, WorkflowPresetBundle> {
937
1019
  const items = { ...(settings.presets?.items ?? {}) };
938
1020
  delete items[WORKFLOW_MANUAL_PRESET];
@@ -1011,8 +1093,8 @@ export function workflowPresetMeaningLines(name: string, preset?: WorkflowPreset
1011
1093
  "Mission Mode: uses the saved mission autonomy, approval, milestone continuation, validation, and retry settings.",
1012
1094
  "Shared sub-agents: uses the saved planning, execution, repair, review, and validation worker policies.",
1013
1095
  "Custom preset source: user workflow-settings.json, not package source.",
1014
- "Sync boundary: live install and main promotion preserve workflow-settings.json; they do not copy, ship, or overwrite custom presets.",
1015
- "Does not change: models/providers/API keys/auth/session/runtime state/compaction model settings unless those values already exist in user settings.",
1096
+ "Extension updates preserve workflow-settings.json and do not overwrite custom presets.",
1097
+ "Does not change: models/providers/API keys/auth/session/runtime state/shared compaction settings.",
1016
1098
  ];
1017
1099
  const builtIn: Record<string, string[]> = {
1018
1100
  simple: [
@@ -1023,7 +1105,7 @@ export function workflowPresetMeaningLines(name: string, preset?: WorkflowPreset
1023
1105
  "Plan Mode: uses fast planning, avoids a second execution-approval stop after the initial approval, skips automatic review, runs lightweight validation, and allows a small safe repair retry budget.",
1024
1106
  "Mission Mode: starts after approval, auto-runs after approval, continues milestones without pause, keeps milestone validation on, and leaves final comprehensive validation off by default.",
1025
1107
  "Shared sub-agents: keeps planning, execution, repair, and validation lean with one-worker support; review remains available but is not forced automatically.",
1026
- "Does not change: models/providers/API keys/auth/session/runtime state/compaction model settings.",
1108
+ "Does not change: models/providers/API keys/auth/session/runtime state/shared compaction settings.",
1027
1109
  ],
1028
1110
  standard: [
1029
1111
  "Name: Standard — Balanced Autonomous",
@@ -1033,7 +1115,7 @@ export function workflowPresetMeaningLines(name: string, preset?: WorkflowPreset
1033
1115
  "Plan Mode: uses standard planning, avoids a second execution-approval stop after the initial approval, leaves review manual/optional, runs validation automatically, and performs safe repair/revalidation.",
1034
1116
  "Mission Mode: starts after approval, auto-runs after approval, continues milestones without pause, keeps milestone validation on, and leaves final comprehensive validation off by default.",
1035
1117
  "Shared sub-agents: uses one-worker planning and two-worker execution, repair, review, and validation when those phases run.",
1036
- "Does not change: models/providers/API keys/auth/session/runtime state/compaction model settings.",
1118
+ "Does not change: models/providers/API keys/auth/session/runtime state/shared compaction settings.",
1037
1119
  ],
1038
1120
  deep: [
1039
1121
  "Name: Deep — Careful Autonomous",
@@ -1043,7 +1125,7 @@ export function workflowPresetMeaningLines(name: string, preset?: WorkflowPreset
1043
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.",
1044
1126
  "Mission Mode: starts after approval, auto-runs after approval, continues milestones without pause, keeps milestone validation on, and enables final comprehensive validation.",
1045
1127
  "Shared sub-agents: forces larger teams across planning, execution, repair, review, and validation.",
1046
- "Does not change: models/providers/API keys/auth/session/runtime state/compaction model settings.",
1128
+ "Does not change: models/providers/API keys/auth/session/runtime state/shared compaction settings.",
1047
1129
  ],
1048
1130
  maximum: [
1049
1131
  "Name: Maximum — Thorough Autonomous",
@@ -1053,7 +1135,7 @@ export function workflowPresetMeaningLines(name: string, preset?: WorkflowPreset
1053
1135
  "Plan Mode: uses maximum planning, avoids a second execution-approval stop after the initial approval, runs automatic review and validation, and uses the largest bounded in-scope repair budget.",
1054
1136
  "Mission Mode: uses supervised-auto mission autonomy, auto-runs after approval, continues milestones without pause, keeps milestone and final validation on, and uses the highest bounded retry budget.",
1055
1137
  "Shared sub-agents: forces maximum teams across planning, execution, repair, review, and validation.",
1056
- "Does not change: models/providers/API keys/auth/session/runtime state/compaction model settings.",
1138
+ "Does not change: models/providers/API keys/auth/session/runtime state/shared compaction settings.",
1057
1139
  ],
1058
1140
  };
1059
1141
  if (builtIn[name]) return builtIn[name];
@@ -1062,14 +1144,14 @@ export function workflowPresetMeaningLines(name: string, preset?: WorkflowPreset
1062
1144
  `Purpose: ${preset?.description ?? "custom saved workflow preset."}`,
1063
1145
  "Applies to: the Standard, Plan, Mission, and shared sub-agent sections stored in this custom preset.",
1064
1146
  "Custom preset source: user workflow-settings.json, not package source.",
1065
- "Sync boundary: live install and main promotion preserve workflow-settings.json; they do not copy, ship, or overwrite custom presets.",
1147
+ "Extension updates preserve workflow-settings.json and do not overwrite custom presets.",
1066
1148
  ...(!preset?.standard ? ["Legacy/Incomplete: missing Standard Mode section; safe Standard defaults are applied when this preset is used."] : []),
1067
1149
  `Standard Mode: To Do ${preset?.standard?.todoTriggerMode ? standardTodoTriggerModeLabel(preset.standard.todoTriggerMode) : "safe defaults"}; clarification ${preset?.standard?.clarificationMode ?? "safe defaults"}; sub-agents ${preset?.standard?.allowSubagents === true ? "enabled" : preset?.standard?.allowSubagents === false ? "disabled" : "safe defaults"}.`,
1068
1150
  `Plan Mode: ${preset?.planning?.depth ?? "uses current"} planning; clarification ${preset?.planning?.clarificationMode ?? "uses current"}; max questions ${preset?.planning?.maxClarificationQuestions ?? "uses current"}; validation ${(preset?.workflow?.validateAfterExecution ?? preset?.workflow?.autoRunValidationAfterExecute) === true ? "automatic" : (preset?.workflow?.validateAfterExecution ?? preset?.workflow?.autoRunValidationAfterExecute) === false ? "manual/optional" : "uses current setting"}.`,
1069
1151
  `Mission Mode: autonomy ${preset?.missions?.defaultAutonomy ?? "uses current"}; auto-run after approval ${preset?.missions?.autoRunAfterApproval === true ? "enabled" : preset?.missions?.autoRunAfterApproval === false ? "disabled" : "uses current"}; milestone validation ${preset?.missions?.requireValidationPerMilestone === true ? "on" : preset?.missions?.requireValidationPerMilestone === false ? "off" : "uses current"}; final validation ${preset?.missions?.finalValidationEnabled === true ? "on" : preset?.missions?.finalValidationEnabled === false ? "off" : "uses current"}.`,
1070
1152
  `Shared sub-agents: planning ${preset?.subagents?.planningPolicy ?? "uses current"}; execution ${preset?.subagents?.executionPolicy ?? "uses current"}; repair ${preset?.subagents?.repairPolicy ?? "uses current"}; review ${preset?.subagents?.reviewPolicy ?? "uses current"}; validation ${preset?.subagents?.validationPolicy ?? "uses current"}.`,
1071
1153
  ...workflowPresetDiagnostics(name, preset),
1072
- "Does not change: models/providers/API keys/auth/session/runtime state/compaction model settings unless those values already exist in user settings.",
1154
+ "Does not change: models/providers/API keys/auth/session/runtime state/shared compaction settings.",
1073
1155
  ];
1074
1156
  }
1075
1157
 
@@ -1105,7 +1187,7 @@ export function renderWorkflowPresets(settings: WorkflowSettings = loadGlobalSet
1105
1187
  const active = settings.presets?.activePreset ?? WORKFLOW_MANUAL_PRESET;
1106
1188
  const names = workflowPresetNames(settings);
1107
1189
  const cards = [renderWorkflowPresetCard(WORKFLOW_MANUAL_PRESET, undefined, active === WORKFLOW_MANUAL_PRESET), ...names.map((name) => renderWorkflowPresetCard(name, catalog[name], name === active))];
1108
- 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 manual\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. Manual settings is only the no-saved-preset-active marker; live install/main promotion preserves workflow-settings.json and does not ship or overwrite custom presets. Presets adjust workflow behavior only and preserve model/provider choices, API keys, auth/session files, runtime workflow state, and compaction model settings.`;
1190
+ 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 manual\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. Manual settings is only the no-saved-preset-active marker; 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.`;
1109
1191
  }
1110
1192
 
1111
1193
  export function applyWorkflowPreset(cwd: string, requestedScope: WorkflowSettingsScope | undefined, name: string): SettingsWriteResult {
@@ -1114,7 +1196,7 @@ export function applyWorkflowPreset(cwd: string, requestedScope: WorkflowSetting
1114
1196
  const preset = resolved ? workflowPresetCatalog(settings)[resolved] : undefined;
1115
1197
  if (!resolved || !preset) throw new Error(`Unknown workflow preset: ${name}`);
1116
1198
  applyPresetBundle(settings, preset, resolved);
1117
- });
1199
+ }, { preserveActivePreset: true });
1118
1200
  }
1119
1201
 
1120
1202
  export function saveCurrentWorkflowPreset(cwd: string, requestedScope: WorkflowSettingsScope | undefined, name: string): SettingsWriteResult {
@@ -1123,17 +1205,18 @@ export function saveCurrentWorkflowPreset(cwd: string, requestedScope: WorkflowS
1123
1205
  assertValidCustomPresetName(name, safe);
1124
1206
  return updateSettings(cwd, requestedScope, (settings) => {
1125
1207
  settings.presets = { ...(settings.presets ?? {}), activePreset: safe, items: { ...(settings.presets?.items ?? {}) } };
1208
+ const { models: _ignoredStandardModels, ...standardPreset } = settings.standard;
1126
1209
  settings.presets.items![safe] = {
1127
1210
  displayName: name.trim(),
1128
1211
  description: "Custom saved workflow preset.",
1129
1212
  planning: { ...settings.planning },
1130
1213
  workflow: { ...settings.workflow },
1131
- standard: { ...settings.standard },
1214
+ standard: { ...standardPreset },
1132
1215
  missions: { ...settings.missions, models: undefined } as WorkflowPresetBundle["missions"],
1133
1216
  subagents: { ...settings.subagents },
1134
- ui: { showWorkflowStatus: settings.ui.showWorkflowStatus, showPlanModeIndicator: settings.ui.showPlanModeIndicator, planTopWidgetVisible: settings.ui.planTopWidgetVisible, missionTopWidgetVisible: settings.ui.missionTopWidgetVisible, missionBottomWidgetVisible: settings.ui.missionBottomWidgetVisible, workflowTheme: settings.ui.workflowTheme, workflowThemeOverrides: settings.ui.workflowThemeOverrides, startupVisual: settings.ui.startupVisual, startupVisualOnSessionStart: settings.ui.startupVisualOnSessionStart, customBrandEnabled: settings.ui.customBrandEnabled, customBrandText: settings.ui.customBrandText },
1217
+ ui: { showWorkflowStatus: settings.ui.showWorkflowStatus, showPlanModeIndicator: settings.ui.showPlanModeIndicator, planTopWidgetVisible: settings.ui.planTopWidgetVisible, planBottomWidgetVisible: settings.ui.planBottomWidgetVisible, missionTopWidgetVisible: settings.ui.missionTopWidgetVisible, missionBottomWidgetVisible: settings.ui.missionBottomWidgetVisible, workflowTheme: settings.ui.workflowTheme, workflowThemeOverrides: settings.ui.workflowThemeOverrides, startupVisual: settings.ui.startupVisual, startupVisualOnSessionStart: settings.ui.startupVisualOnSessionStart, customBrandEnabled: settings.ui.customBrandEnabled, customBrandText: settings.ui.customBrandText },
1135
1218
  };
1136
- });
1219
+ }, { preserveActivePreset: true });
1137
1220
  }
1138
1221
 
1139
1222
  export function createWorkflowPreset(cwd: string, requestedScope: WorkflowSettingsScope | undefined, name: string, templateName?: string): SettingsWriteResult {
@@ -1145,8 +1228,8 @@ export function createWorkflowPreset(cwd: string, requestedScope: WorkflowSettin
1145
1228
  const template = resolvedTemplate ? workflowPresetCatalog(settings)[resolvedTemplate] : undefined;
1146
1229
  if (templateName && !template) throw new Error(`Unknown workflow preset template: ${templateName}`);
1147
1230
  settings.presets = { ...(settings.presets ?? {}), items: { ...(settings.presets?.items ?? {}) } };
1148
- settings.presets.items![safe] = template ? { ...template, displayName: name.trim(), description: `Custom preset created from ${resolvedTemplate}.` } : { displayName: name.trim(), description: "Custom workflow preset.", planning: {}, workflow: {}, standard: {}, missions: {}, subagents: {}, ui: {} };
1149
- });
1231
+ settings.presets.items![safe] = template ? { ...workflowPresetBundleWithoutUserOwnedSettings(template), displayName: name.trim(), description: `Custom preset created from ${resolvedTemplate}.` } : { displayName: name.trim(), description: "Custom workflow preset.", planning: {}, workflow: {}, standard: {}, missions: {}, subagents: {}, ui: {} };
1232
+ }, { preserveActivePreset: true });
1150
1233
  }
1151
1234
 
1152
1235
  export function renameWorkflowPreset(cwd: string, requestedScope: WorkflowSettingsScope | undefined, oldName: string, newName: string): SettingsWriteResult {
@@ -1163,7 +1246,7 @@ export function renameWorkflowPreset(cwd: string, requestedScope: WorkflowSettin
1163
1246
  delete items[resolved];
1164
1247
  items[safe] = { ...existing, displayName: newName.trim() };
1165
1248
  settings.presets = { ...(settings.presets ?? {}), activePreset: settings.presets?.activePreset === resolved ? safe : settings.presets?.activePreset, items };
1166
- });
1249
+ }, { preserveActivePreset: true });
1167
1250
  }
1168
1251
 
1169
1252
  export function deleteWorkflowPreset(cwd: string, requestedScope: WorkflowSettingsScope | undefined, name: string): SettingsWriteResult {
@@ -1174,7 +1257,7 @@ export function deleteWorkflowPreset(cwd: string, requestedScope: WorkflowSettin
1174
1257
  const items = { ...(settings.presets?.items ?? {}) };
1175
1258
  delete items[resolved];
1176
1259
  settings.presets = { ...(settings.presets ?? {}), activePreset: settings.presets?.activePreset === resolved ? "custom" : settings.presets?.activePreset, items };
1177
- });
1260
+ }, { preserveActivePreset: true });
1178
1261
  }
1179
1262
 
1180
1263
  export function getModelForRole(role: WorkflowRole): RoleModelSettings {
@@ -1321,9 +1404,23 @@ export function workflowSettingsConsistencyDiagnostics(settings: WorkflowSetting
1321
1404
  if (settings.context.compactionMode === "custom_model" && (!settings.context.compactionModelProvider || !settings.context.compactionModel)) {
1322
1405
  diagnostics.push("custom compaction model mode is selected but compaction provider/model is incomplete");
1323
1406
  }
1407
+ if (settings.context.compactionMode === "custom_model" && settings.context.customCompactionEnabled !== true) {
1408
+ diagnostics.push("custom compaction mode is selected but customCompactionEnabled is not set — custom compaction will not activate");
1409
+ }
1324
1410
  if (settings.context.customCompactionEnabled === true && settings.context.compactionMode !== "custom_model") {
1325
1411
  diagnostics.push(`customCompactionEnabled=true but compactionMode=${settings.context.compactionMode}`);
1326
1412
  }
1413
+ if (settings.missions.autoRepairReviewFailures !== false && settings.missions.reviewRetryMode === "off") {
1414
+ diagnostics.push("mission review auto-repair is enabled but reviewRetryMode is off — override to safe_only will be applied at runtime; set reviewRetryMode explicitly to avoid confusion");
1415
+ }
1416
+ const activePreset = settings.presets?.activePreset ?? WORKFLOW_MANUAL_PRESET;
1417
+ if ((activePreset === "standard" || activePreset === "deep" || activePreset === "maximum")
1418
+ && (settings.missions.autoRepairReviewFailures === false || settings.missions.reviewRetryMode === "off" || (settings.missions.maxReviewRetriesPerMission ?? 0) <= 0)) {
1419
+ diagnostics.push(`active preset ${activePreset} expects Mission review repair to be available, but effective Mission review repair is disabled/off/zero; reapply the preset or update missions.autoRepairReviewFailures, missions.reviewRetryMode, and missions.maxReviewRetriesPerMission`);
1420
+ }
1421
+ if (settings.missions.autoRepairValidationFailures !== false && settings.missions.validationRetryMode === "off") {
1422
+ diagnostics.push("mission validation auto-repair is enabled but validationRetryMode is off — override to safe_only will be applied at runtime; set validationRetryMode explicitly to avoid confusion");
1423
+ }
1327
1424
  if (settings.missions.watchdogEnabled === true) {
1328
1425
  diagnostics.push("mission watchdog is enabled but interval/watchdog enforcement is partial in the current MVP");
1329
1426
  }