@mediadatafusion/pi-workflow-suite 0.0.18 → 0.0.19
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 +7 -0
- package/README.md +62 -38
- package/VERSION +1 -1
- package/config/workflow-settings.example.json +1 -0
- package/extensions/workflow-model-router.ts +3 -0
- package/extensions/workflow-modes.ts +371 -179
- package/package.json +1 -1
|
@@ -8,7 +8,7 @@ import { StringEnum } from "@earendil-works/pi-ai";
|
|
|
8
8
|
import type { AssistantMessage, TextContent } from "@earendil-works/pi-ai";
|
|
9
9
|
import { CustomEditor, VERSION, compact as piCompact, estimateTokens as piEstimateTokens, findCutPoint as piFindCutPoint, getAgentDir, getMarkdownTheme, type ExtensionAPI, type ExtensionContext, type FileOperations, type SessionEntry, type ToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
10
10
|
import { Type } from "typebox";
|
|
11
|
-
import { activeWorkflowPresetLabel, applyMissionModelForRole, applyModelForRole, applyStandardModelForRole, applyWorkflowPreset, compactionModeLabel, createProjectSettingsOverride, createWorkflowPreset, defaultWorkflowSettings, deleteWorkflowPreset, effectivePlanApprovalRequired, effectiveReviewAutoRun, effectiveValidateAfterExecution, effectiveValidationAutoRun, effectiveRepairGate, formatRole, getDefaultWriteTarget, loadEffectiveSettings, loadGlobalSettings, loadWorkflowSettings, normalizeWorkflowPresetName, parseMissionModelRole, parseRole, parseThinkingLevel, renameWorkflowPreset, renderActiveWorkflowPresetSummary, renderStandardModelStrategy, renderWorkflowModels, renderWorkflowPresets, resolveWorkflowPresetName, roleIsConfigured, saveCurrentWorkflowPreset, setMissionModelForRole, setMissionThinkingForRole, setModelForRole, setRoleEnabled, setStandardModelForRole, setStandardThinkingForRole, setThinkingForRole, standardModelSource, standardModelSourceLabel, standardTodoTriggerModeLabel, updateSettings, workflowCompactionCheckModeLabel, workflowPresetCatalog, workflowPresetLabel, workflowPresetNames, workflowPresetPickerLabel, workflowRoleLabel, workflowSettingsConsistencyDiagnostics, WORKFLOW_CUSTOM_PRESET_MARKER, WORKFLOW_SETTINGS_FILE, type MissionModelRole, type RoleModelSettings, type WorkflowRole, type WorkflowSettingsScope, type WorkflowStartupLogo, type WorkflowStartupLogoColorStyle, type WorkflowStartupLogoFont, type WorkflowStartupLogoShadowDirection, type WorkflowStartupVisual, type CustomBrandBaseVisual, type StandardClarificationMode, type StandardModelRole, type StandardTodoTriggerMode, type WorkflowAgentScope } from "./workflow-model-router.js";
|
|
11
|
+
import { activeWorkflowPresetLabel, applyMissionModelForRole, applyModelForRole, applyStandardModelForRole, applyWorkflowPreset, compactionModeLabel, createProjectSettingsOverride, createWorkflowPreset, defaultWorkflowSettings, deleteWorkflowPreset, effectivePlanApprovalRequired, effectiveReviewAutoRun, effectiveValidateAfterExecution, effectiveValidationAutoRun, effectiveRepairGate, formatRole, getDefaultWriteTarget, loadEffectiveSettings, loadGlobalSettings, loadWorkflowSettings, normalizeWorkflowPresetName, parseMissionModelRole, parseRole, parseThinkingLevel, renameWorkflowPreset, renderActiveWorkflowPresetSummary, renderStandardModelStrategy, renderWorkflowModels, renderWorkflowPresets, resolveWorkflowPresetName, roleIsConfigured, saveCurrentWorkflowPreset, setMissionModelForRole, setMissionThinkingForRole, setModelForRole, setRoleEnabled, setStandardModelForRole, setStandardThinkingForRole, setThinkingForRole, standardModelSource, standardModelSourceLabel, standardTodoTriggerModeLabel, updateSettings, workflowCompactionCheckModeLabel, workflowPresetCatalog, workflowPresetLabel, workflowPresetNames, workflowPresetPickerLabel, workflowRoleLabel, workflowSettingsConsistencyDiagnostics, WORKFLOW_CUSTOM_PRESET_MARKER, WORKFLOW_SETTINGS_FILE, type MissionModelRole, type RoleModelSettings, type WorkflowRole, type WorkflowSettingsScope, type WorkflowStartupLogo, type WorkflowStartupLogoColorStyle, type WorkflowStartupLogoFont, type WorkflowStartupLogoShadowDirection, type WorkflowStartupVisual, type WorkflowEditorHintContrast, type CustomBrandBaseVisual, type StandardClarificationMode, type StandardModelRole, type StandardTodoTriggerMode, type WorkflowAgentScope } from "./workflow-model-router.js";
|
|
12
12
|
import { renderHandoffProjectContext, renderWorkflowStatus, renderWorkflowSummary } from "./workflow-summary.js";
|
|
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";
|
|
@@ -2680,6 +2680,7 @@ UI Widgets:
|
|
|
2680
2680
|
- /workflow-settings set ui showActiveWorkflowSwitchHint true|false
|
|
2681
2681
|
- /workflow-settings set ui showWidgetShortcutHint true|false
|
|
2682
2682
|
- /workflow-settings set ui showPresetShortcutHint true|false
|
|
2683
|
+
- /workflow-settings set ui editorHintContrast subtle|normal|bright|high
|
|
2683
2684
|
|
|
2684
2685
|
Sub-agents and parallelism:
|
|
2685
2686
|
- /workflow-settings set subagents enabled true|false
|
|
@@ -3684,7 +3685,7 @@ ${renderPlanModelSettings(settings)}
|
|
|
3684
3685
|
|
|
3685
3686
|
${renderMissionModelStrategy(settings)}
|
|
3686
3687
|
|
|
3687
|
-
## UI /
|
|
3688
|
+
## UI / Widgets
|
|
3688
3689
|
Plan Top Widget: ${widgetVisibilityLabel(settings, "planTop")}
|
|
3689
3690
|
Plan Bottom Widget: ${widgetVisibilityLabel(settings, "planBottom")}
|
|
3690
3691
|
Mission Top Widget: ${widgetVisibilityLabel(settings, "missionTop")}
|
|
@@ -3695,6 +3696,7 @@ Idle Entry Hint: ${workflowWidgetUi(settings).showIdleWorkflowEntryHint !== fals
|
|
|
3695
3696
|
Active Switch Hint: ${workflowWidgetUi(settings).showActiveWorkflowSwitchHint !== false ? "visible" : "hidden"}
|
|
3696
3697
|
Widget Shortcut Hint: ${workflowWidgetUi(settings).showWidgetShortcutHint !== false ? "visible" : "hidden"}
|
|
3697
3698
|
Preset Shortcut Hint: ${workflowWidgetUi(settings).showPresetShortcutHint !== false ? "visible" : "hidden"}
|
|
3699
|
+
Editor Hint Contrast: ${workflowEditorHintContrastLabel(workflowEditorHintContrast(settings))}
|
|
3698
3700
|
Workflow Theme: ${workflowThemeDisplayName(workflowThemeName(settings))}
|
|
3699
3701
|
Startup Visual: ${startupVisualOrDefault(settings)}
|
|
3700
3702
|
Startup Logo: ${startupLogoOrDefault(settings)}
|
|
@@ -5527,8 +5529,8 @@ class WorkflowSuiteEditor extends CustomEditor {
|
|
|
5527
5529
|
try {
|
|
5528
5530
|
const settings = loadWorkflowSettings(this.workflowCwd);
|
|
5529
5531
|
const decorate = workflowRoleTextDecoration(settings, "muted");
|
|
5530
|
-
let hintStyled =
|
|
5531
|
-
if (decorate) hintStyled = decorate(hintStyled);
|
|
5532
|
+
let hintStyled = workflowEditorHintStyledText(settings, workflowEditorHintText);
|
|
5533
|
+
if (workflowEditorHintContrast(settings) === "subtle" && decorate) hintStyled = decorate(hintStyled);
|
|
5532
5534
|
const innerWidth = width - 2;
|
|
5533
5535
|
const hintLen = visibleTextWidth(hintStyled);
|
|
5534
5536
|
const displayHint = hintLen > innerWidth ? truncateVisibleText(hintStyled, innerWidth) : hintStyled;
|
|
@@ -6525,6 +6527,13 @@ function isMissionWorkflowMode(state: WorkflowState): boolean {
|
|
|
6525
6527
|
}
|
|
6526
6528
|
|
|
6527
6529
|
type WorkflowWidgetSlot = "planTop" | "planBottom" | "missionTop" | "missionBottom" | "standardTop" | "standardBottom";
|
|
6530
|
+
const WORKFLOW_EDITOR_HINT_CONTRASTS: WorkflowEditorHintContrast[] = ["subtle", "normal", "bright", "high"];
|
|
6531
|
+
const WORKFLOW_EDITOR_HINT_CONTRAST_LABELS: Record<WorkflowEditorHintContrast, string> = {
|
|
6532
|
+
subtle: "Subtle",
|
|
6533
|
+
normal: "Normal",
|
|
6534
|
+
bright: "Bright",
|
|
6535
|
+
high: "High Contrast",
|
|
6536
|
+
};
|
|
6528
6537
|
type WorkflowWidgetUiSettings = ReturnType<typeof loadWorkflowSettings>["ui"] & {
|
|
6529
6538
|
showPlanModeIndicator?: boolean;
|
|
6530
6539
|
planModeIndicatorText?: string;
|
|
@@ -6538,6 +6547,7 @@ type WorkflowWidgetUiSettings = ReturnType<typeof loadWorkflowSettings>["ui"] &
|
|
|
6538
6547
|
showActiveWorkflowSwitchHint?: boolean;
|
|
6539
6548
|
showWidgetShortcutHint?: boolean;
|
|
6540
6549
|
showPresetShortcutHint?: boolean;
|
|
6550
|
+
editorHintContrast?: WorkflowEditorHintContrast;
|
|
6541
6551
|
};
|
|
6542
6552
|
|
|
6543
6553
|
const widgetVisibilityOverrides: Partial<Record<WorkflowWidgetSlot, boolean>> = {};
|
|
@@ -6554,6 +6564,38 @@ function workflowWidgetUi(settings: ReturnType<typeof loadWorkflowSettings>): Wo
|
|
|
6554
6564
|
return settings.ui as WorkflowWidgetUiSettings;
|
|
6555
6565
|
}
|
|
6556
6566
|
|
|
6567
|
+
function parseEditorHintContrast(value?: string): WorkflowEditorHintContrast | undefined {
|
|
6568
|
+
const input = value?.trim().toLowerCase().replace(/[\s_-]+/g, "");
|
|
6569
|
+
if (!input) return undefined;
|
|
6570
|
+
if (input === "subtle" || input === "muted" || input === "dim") return "subtle";
|
|
6571
|
+
if (input === "normal" || input === "default") return "normal";
|
|
6572
|
+
if (input === "bright") return "bright";
|
|
6573
|
+
if (input === "high" || input === "highcontrast" || input === "maximum") return "high";
|
|
6574
|
+
return undefined;
|
|
6575
|
+
}
|
|
6576
|
+
|
|
6577
|
+
function workflowEditorHintContrast(settings: ReturnType<typeof loadWorkflowSettings>): WorkflowEditorHintContrast {
|
|
6578
|
+
return parseEditorHintContrast(workflowWidgetUi(settings).editorHintContrast) ?? "normal";
|
|
6579
|
+
}
|
|
6580
|
+
|
|
6581
|
+
function workflowEditorHintContrastLabel(contrast: WorkflowEditorHintContrast): string {
|
|
6582
|
+
return WORKFLOW_EDITOR_HINT_CONTRAST_LABELS[contrast];
|
|
6583
|
+
}
|
|
6584
|
+
|
|
6585
|
+
function workflowEditorHintStyledText(settings: ReturnType<typeof loadWorkflowSettings>, text: string): string {
|
|
6586
|
+
switch (workflowEditorHintContrast(settings)) {
|
|
6587
|
+
case "subtle":
|
|
6588
|
+
return `\x1b[2m\x1b[38;5;240m${text}\x1b[0m`;
|
|
6589
|
+
case "bright":
|
|
6590
|
+
return `\x1b[38;5;250m${text}\x1b[0m`;
|
|
6591
|
+
case "high":
|
|
6592
|
+
return `\x1b[1m\x1b[38;5;255m${text}\x1b[0m`;
|
|
6593
|
+
case "normal":
|
|
6594
|
+
default:
|
|
6595
|
+
return `\x1b[38;5;245m${text}\x1b[0m`;
|
|
6596
|
+
}
|
|
6597
|
+
}
|
|
6598
|
+
|
|
6557
6599
|
function workflowWidgetVisible(settings: ReturnType<typeof loadWorkflowSettings>, slot: WorkflowWidgetSlot): boolean {
|
|
6558
6600
|
const override = widgetVisibilityOverrides[slot];
|
|
6559
6601
|
if (override !== undefined) return override;
|
|
@@ -9718,7 +9760,7 @@ export default function workflowModes(pi: ExtensionAPI): void {
|
|
|
9718
9760
|
const route = await applyModelForRole(pi, ctx, "planner", { cwd: ctx.cwd });
|
|
9719
9761
|
if (!route) return false;
|
|
9720
9762
|
updateState({ modelsUsed: { ...(state.modelsUsed ?? {}), planner: modelLabel(route) } }, ctx);
|
|
9721
|
-
if (showNotice) ctx
|
|
9763
|
+
if (showNotice) workflowUiNotify(ctx, `Active Plan Mode planner route reapplied: ${modelLabel(route)}\n${activeModelDiagnostic(ctx)}`, "info");
|
|
9722
9764
|
return true;
|
|
9723
9765
|
};
|
|
9724
9766
|
|
|
@@ -9727,13 +9769,13 @@ export default function workflowModes(pi: ExtensionAPI): void {
|
|
|
9727
9769
|
const settings = loadWorkflowSettings(ctx.cwd);
|
|
9728
9770
|
const standardRole = effectiveStandardModelRole(settings);
|
|
9729
9771
|
if (standardRole === "current") {
|
|
9730
|
-
if (showNotice) ctx
|
|
9772
|
+
if (showNotice) workflowUiNotify(ctx, `Standard Mode keeps the current Pi model.\n${activeModelDiagnostic(ctx)}`, "info");
|
|
9731
9773
|
return false;
|
|
9732
9774
|
}
|
|
9733
9775
|
const route = await applyStandardModelForRole(pi, ctx, standardRole, { cwd: ctx.cwd });
|
|
9734
9776
|
if (!route) return false;
|
|
9735
9777
|
updateState({ modelsUsed: { ...(state.modelsUsed ?? {}), [standardRole]: modelLabel(route) } }, ctx);
|
|
9736
|
-
if (showNotice) ctx
|
|
9778
|
+
if (showNotice) workflowUiNotify(ctx, `Active Standard Mode ${standardRole} route applied: ${modelLabel(route)}\n${activeModelDiagnostic(ctx)}`, "info");
|
|
9737
9779
|
return true;
|
|
9738
9780
|
};
|
|
9739
9781
|
|
|
@@ -9748,7 +9790,7 @@ export default function workflowModes(pi: ExtensionAPI): void {
|
|
|
9748
9790
|
const settings = loadWorkflowSettings(ctx.cwd);
|
|
9749
9791
|
const globalUi = workflowWidgetUi(loadGlobalSettings());
|
|
9750
9792
|
const ui = workflowWidgetUi(settings);
|
|
9751
|
-
const common = `Active Mode: ${state.mode}\nShortcuts: ${globalUi.enableWidgetShortcuts !== false ? "enabled" : "disabled"}\nRemember Visibility: ${globalUi.rememberWidgetVisibility !== false ? "enabled" : "disabled"}\nStorage: ${globalUi.rememberWidgetVisibility !== false ? "global settings" : "current Pi session"}\
|
|
9793
|
+
const common = `Active Mode: ${state.mode}\nShortcuts: ${globalUi.enableWidgetShortcuts !== false ? "enabled" : "disabled"}\nRemember Visibility: ${globalUi.rememberWidgetVisibility !== false ? "enabled" : "disabled"}\nStorage: ${globalUi.rememberWidgetVisibility !== false ? "global settings" : "current Pi session"}\nEditor Hints: idle entry ${ui.showIdleWorkflowEntryHint !== false ? "visible" : "hidden"}, active switch ${ui.showActiveWorkflowSwitchHint !== false ? "visible" : "hidden"}, widgets ${ui.showWidgetShortcutHint !== false ? "visible" : "hidden"}, preset ${ui.showPresetShortcutHint !== false ? "visible" : "hidden"}, contrast ${workflowEditorHintContrastLabel(workflowEditorHintContrast(settings))}`;
|
|
9752
9794
|
if (isPlanWorkflowUiMode(state)) {
|
|
9753
9795
|
const bottom = planBottomRelevant(state) ? widgetVisibilityLabel(settings, "planBottom") : "not applicable";
|
|
9754
9796
|
return `# Workflow Widgets\n\nPlan Top Widget: ${widgetVisibilityLabel(settings, "planTop")}\nPlan Bottom Widget: ${bottom}\nStatus Line: ${widgetVisibilityStatus(state, settings) ?? "none"}\n${common}`;
|
|
@@ -9761,7 +9803,13 @@ export default function workflowModes(pi: ExtensionAPI): void {
|
|
|
9761
9803
|
if (isStandardWorkflowMode(state)) {
|
|
9762
9804
|
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}`;
|
|
9763
9805
|
}
|
|
9764
|
-
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
|
|
9806
|
+
return `# Workflow Widgets\n\nNo active Plan/Mission/Standard widget is currently visible.\nStatus Line: ${widgetVisibilityStatus(state, settings) ?? "none"}\n\nEntry Shortcuts:\n- ${workflowEntryShortcutLabel("standard")}\n- ${workflowEntryShortcutLabel("plan")}\n- ${workflowEntryShortcutLabel("mission")}\n\nActive-mode editor hints use compact text such as: Widgets:Ctrl+Shift+T/B Preset:${activeWorkflowPresetLabel(settings)} Ctrl+Shift+U Standard:Ctrl+Shift+S Mission:Ctrl+Shift+M\nWidget toggles and preset cycling are visible only while Plan/Mission/Standard Mode is active.\n\n${common}`;
|
|
9807
|
+
};
|
|
9808
|
+
|
|
9809
|
+
const renderEditorHintsSettings = (ctx: ExtensionContext): string => {
|
|
9810
|
+
const settings = loadWorkflowSettings(ctx.cwd);
|
|
9811
|
+
const ui = workflowWidgetUi(settings);
|
|
9812
|
+
return `# Editor Hints\n\nThese hints render inline in the editor/input box.\n\nIdle Entry Hint: ${ui.showIdleWorkflowEntryHint !== false ? "visible" : "hidden"}\nActive Switch Hint: ${ui.showActiveWorkflowSwitchHint !== false ? "visible" : "hidden"}\nWidget Shortcut Hint: ${ui.showWidgetShortcutHint !== false ? "visible" : "hidden"}\nPreset Shortcut Hint: ${ui.showPresetShortcutHint !== false ? "visible" : "hidden"}\nHint Contrast: ${workflowEditorHintContrastLabel(workflowEditorHintContrast(settings))}`;
|
|
9765
9813
|
};
|
|
9766
9814
|
|
|
9767
9815
|
const setWorkflowWidgetVisibility = (ctx: ExtensionContext, slot: WorkflowWidgetSlot, visible: boolean): string => {
|
|
@@ -9814,7 +9862,7 @@ export default function workflowModes(pi: ExtensionAPI): void {
|
|
|
9814
9862
|
const messages = (["planTop", "planBottom", "missionTop", "missionBottom", "standardTop", "standardBottom"] as WorkflowWidgetSlot[]).map((slot) => setWorkflowWidgetVisibility(ctx, slot, visible));
|
|
9815
9863
|
return show(pi, `# Workflow Widgets\n\n${messages.join("\n")}\n\n${renderWorkflowWidgetsStatus(ctx)}`);
|
|
9816
9864
|
}
|
|
9817
|
-
return show(pi, "# Workflow Widgets\n\nUsage:\n- /workflow widgets status\n- /workflow widgets list\n- /workflow widgets configure\n- /workflow widgets toggle top\n- /workflow widgets toggle bottom\n- /workflow widgets on\n- /workflow widgets off\n\
|
|
9865
|
+
return show(pi, "# Workflow Widgets\n\nUsage:\n- /workflow widgets status\n- /workflow widgets list\n- /workflow widgets configure\n- /workflow widgets toggle top\n- /workflow widgets toggle bottom\n- /workflow widgets on\n- /workflow widgets off\n\nEditor hint behavior:\n- Idle: Plan/Mission entry shortcuts only\n- Active modes: compact widget/preset hints plus Plan/Mission switch hints by default\n- Active switch hints can be configured in /workflow-settings configure widgets -> Editor Hints");
|
|
9818
9866
|
};
|
|
9819
9867
|
|
|
9820
9868
|
const persistCurrentPlan = (ctx: ExtensionContext, approvalStatus: "draft" | "approved" | "revised" | "completed" | "archived", saveReason: string, handoff: { executionSummary?: string; reviewerReport?: string; validationReport?: string; repairAttempt?: string; finalReport?: string } = {}): string | undefined => {
|
|
@@ -14395,7 +14443,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14395
14443
|
const plannerReapplied = role === "planner" ? await reapplyPlannerRouteIfPlanMode(ctx, true) : false;
|
|
14396
14444
|
const standardSettings = loadWorkflowSettings(ctx.cwd);
|
|
14397
14445
|
const standardReapplied = effectiveStandardModelRole(standardSettings) === role ? await reapplyStandardRouteIfStandardMode(ctx, true) : false;
|
|
14398
|
-
ctx
|
|
14446
|
+
workflowUiNotify(ctx, `${role} model set to ${provider}/${model} in ${result.file}${plannerReapplied || standardReapplied ? `\n${activeModelDiagnostic(ctx)}` : ""}`, "info");
|
|
14399
14447
|
}
|
|
14400
14448
|
|
|
14401
14449
|
async function configureStandardRoleModel(ctx: ExtensionContext, role: WorkflowRole) {
|
|
@@ -14403,14 +14451,14 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14403
14451
|
if (!selected) return;
|
|
14404
14452
|
const result = setStandardModelForRole(role, selected.provider, selected.model, ctx.cwd);
|
|
14405
14453
|
await reapplyStandardRouteIfStandardMode(ctx, true);
|
|
14406
|
-
ctx
|
|
14454
|
+
workflowUiNotify(ctx, `standard ${role} model set to ${selected.provider}/${selected.model} in ${result.file}`, "info");
|
|
14407
14455
|
}
|
|
14408
14456
|
|
|
14409
14457
|
async function configureMissionRoleModel(ctx: ExtensionContext, role: MissionModelRole) {
|
|
14410
14458
|
const selected = await selectProviderAndModel(ctx, `Mission ${role} model`);
|
|
14411
14459
|
if (!selected) return;
|
|
14412
14460
|
const result = setMissionModelForRole(role, selected.provider, selected.model, ctx.cwd);
|
|
14413
|
-
ctx
|
|
14461
|
+
workflowUiNotify(ctx, `mission ${role} model set to ${selected.provider}/${selected.model} in ${result.file}`, "info");
|
|
14414
14462
|
}
|
|
14415
14463
|
|
|
14416
14464
|
async function configureStandardThinking(ctx: ExtensionContext) {
|
|
@@ -14420,7 +14468,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14420
14468
|
if (!level) return;
|
|
14421
14469
|
const result = setStandardThinkingForRole(role, level, ctx.cwd);
|
|
14422
14470
|
await reapplyStandardRouteIfStandardMode(ctx, true);
|
|
14423
|
-
ctx
|
|
14471
|
+
workflowUiNotify(ctx, `standard ${role} thinking set to ${level} in ${result.file}`, "info");
|
|
14424
14472
|
}
|
|
14425
14473
|
|
|
14426
14474
|
async function configureMissionThinking(ctx: ExtensionContext) {
|
|
@@ -14429,7 +14477,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14429
14477
|
const level = parseThinkingLevel((await ctx.ui.select("Select mission thinking level:", ["off", "minimal", "low", "medium", "high", "xhigh"])) ?? "");
|
|
14430
14478
|
if (!level) return;
|
|
14431
14479
|
const result = setMissionThinkingForRole(role, level, ctx.cwd);
|
|
14432
|
-
ctx
|
|
14480
|
+
workflowUiNotify(ctx, `mission ${role} thinking set to ${level} in ${result.file}`, "info");
|
|
14433
14481
|
}
|
|
14434
14482
|
|
|
14435
14483
|
async function configureThinking(ctx: ExtensionContext) {
|
|
@@ -14441,7 +14489,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14441
14489
|
const plannerReapplied = role === "planner" ? await reapplyPlannerRouteIfPlanMode(ctx, true) : false;
|
|
14442
14490
|
const standardSettings = loadWorkflowSettings(ctx.cwd);
|
|
14443
14491
|
const standardReapplied = effectiveStandardModelRole(standardSettings) === role ? await reapplyStandardRouteIfStandardMode(ctx, true) : false;
|
|
14444
|
-
ctx
|
|
14492
|
+
workflowUiNotify(ctx, `${role} thinking set to ${level} in ${result.file}${plannerReapplied || standardReapplied ? `\n${activeModelDiagnostic(ctx)}` : ""}`, "info");
|
|
14445
14493
|
}
|
|
14446
14494
|
|
|
14447
14495
|
async function chooseBool(ctx: ExtensionContext, title: string): Promise<boolean | undefined> {
|
|
@@ -14449,6 +14497,128 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14449
14497
|
return parseBool(choice ?? undefined);
|
|
14450
14498
|
}
|
|
14451
14499
|
|
|
14500
|
+
function humanizeWorkflowSettingSegment(segment: string): string {
|
|
14501
|
+
return segment
|
|
14502
|
+
.replace(/([a-z0-9])([A-Z])/g, "$1 $2")
|
|
14503
|
+
.replace(/[_-]+/g, " ")
|
|
14504
|
+
.replace(/\bui\b/gi, "UI")
|
|
14505
|
+
.replace(/\bapi\b/gi, "API")
|
|
14506
|
+
.replace(/\bto do\b/gi, "To Do")
|
|
14507
|
+
.trim()
|
|
14508
|
+
.replace(/\s+/g, " ")
|
|
14509
|
+
.replace(/\w\S*/g, (word) => word === "UI" || word === "API" ? word : word.charAt(0).toUpperCase() + word.slice(1).toLowerCase());
|
|
14510
|
+
}
|
|
14511
|
+
|
|
14512
|
+
function workflowSettingDisplayLabel(setting: string): string {
|
|
14513
|
+
const labels: Record<string, string> = {
|
|
14514
|
+
"ui.editorHintContrast": "Editor hint contrast",
|
|
14515
|
+
"ui.showIdleWorkflowEntryHint": "Idle entry hint",
|
|
14516
|
+
"ui.showActiveWorkflowSwitchHint": "Active switch hint",
|
|
14517
|
+
"ui.showWidgetShortcutHint": "Widget shortcut hint",
|
|
14518
|
+
"ui.showPresetShortcutHint": "Preset shortcut hint",
|
|
14519
|
+
"ui.enableWidgetShortcuts": "Widget shortcuts",
|
|
14520
|
+
"ui.rememberWidgetVisibility": "Remember widget visibility",
|
|
14521
|
+
"ui.workflowTheme": "Workflow theme",
|
|
14522
|
+
"ui.widgetTextStyle": "Widget text style",
|
|
14523
|
+
"ui.startupTextStyle": "Startup text style",
|
|
14524
|
+
"ui.startupVisual": "Startup visual",
|
|
14525
|
+
"ui.startupLogo": "Startup logo",
|
|
14526
|
+
"ui.startupLogoText": "Startup logo text",
|
|
14527
|
+
"ui.startupLogoFont": "Startup logo font",
|
|
14528
|
+
"ui.startupLogoShadowDirection": "Startup logo shadow direction",
|
|
14529
|
+
"ui.startupLogoColorStyle": "Startup logo color style",
|
|
14530
|
+
"ui.startupVisualOnSessionStart": "Startup on session start",
|
|
14531
|
+
"ui.customBrandEnabled": "Custom brand",
|
|
14532
|
+
"ui.customBrandText": "Custom brand text",
|
|
14533
|
+
"ui.customBrandBaseVisual": "Custom brand base visual",
|
|
14534
|
+
"interactiveClarificationEnabled": "Interactive clarification",
|
|
14535
|
+
"maxClarificationQuestions": "Max clarification questions",
|
|
14536
|
+
"planning.depth": "Planning depth",
|
|
14537
|
+
"planning.clarificationMode": "Planning clarification mode",
|
|
14538
|
+
"planning.interactiveClarificationEnabled": "Interactive clarification",
|
|
14539
|
+
"planning.maxClarificationQuestions": "Max clarification questions",
|
|
14540
|
+
"planning.clarificationTiming": "Planning clarification timing",
|
|
14541
|
+
"planning.maxTokens": "Planning token budget",
|
|
14542
|
+
"planning.maxRuntimeHours": "Planning runtime budget",
|
|
14543
|
+
"standard.allowSubagents": "Standard sub-agents",
|
|
14544
|
+
"standard.subagentScope": "Standard sub-agent scope",
|
|
14545
|
+
"standard.todoTriggerMode": "To Do trigger mode",
|
|
14546
|
+
"standard.clarificationMode": "Standard clarification mode",
|
|
14547
|
+
"standard.interactiveClarificationEnabled": "Standard interactive clarification",
|
|
14548
|
+
"standard.maxClarificationQuestions": "Standard max clarification questions",
|
|
14549
|
+
"standard.clarificationTiming": "Standard clarification timing",
|
|
14550
|
+
"standard.maxTokens": "Standard token budget",
|
|
14551
|
+
"standard.enabled": "Standard Mode",
|
|
14552
|
+
"subagents.enabled": "Sub-agents",
|
|
14553
|
+
"subagents.activityIndicatorEnabled": "Sub-agent activity indicator",
|
|
14554
|
+
"subagents.allowBackgroundSubagents": "Background sub-agents",
|
|
14555
|
+
"subagents.editConcurrencyMode": "Sub-agent edit concurrency mode",
|
|
14556
|
+
"subagents.planningOrchestrationPolicy": "Planning orchestration policy",
|
|
14557
|
+
"missions.enabled": "Mission Mode",
|
|
14558
|
+
"missions.defaultAutonomy": "Mission default autonomy",
|
|
14559
|
+
"missions.subagentPolicy": "Mission sub-agent policy",
|
|
14560
|
+
"missions.planningDepth": "Mission planning depth",
|
|
14561
|
+
"missions.clarificationMode": "Mission clarification mode",
|
|
14562
|
+
"missions.interactiveClarificationEnabled": "Mission interactive clarification",
|
|
14563
|
+
"missions.maxClarificationQuestions": "Mission max clarification questions",
|
|
14564
|
+
"missions.clarificationTiming": "Mission clarification timing",
|
|
14565
|
+
"missions.maxTokens": "Mission token budget",
|
|
14566
|
+
"missions.maxRuntimeHours": "Mission runtime budget",
|
|
14567
|
+
"missions.checkpointIntervalMinutes": "Mission checkpoint interval",
|
|
14568
|
+
"missions.heartbeatEnabled": "Mission heartbeat",
|
|
14569
|
+
"missions.watchdogEnabled": "Mission watchdog",
|
|
14570
|
+
"missions.watchdogStaleMinutes": "Mission watchdog stale minutes",
|
|
14571
|
+
"missions.missionHistoryLimit": "Mission history limit",
|
|
14572
|
+
"context.autoCompactionEnabled": "Workflow auto trigger",
|
|
14573
|
+
"context.compactionTriggerPercent": "Workflow trigger percent",
|
|
14574
|
+
"context.compactionCooldownMinutes": "Compaction cooldown",
|
|
14575
|
+
"context.customCompactionReserveTokens": "Custom compaction reserve tokens",
|
|
14576
|
+
"context.customCompactionKeepRecentTokens": "Custom compaction keep-recent tokens",
|
|
14577
|
+
"workflow.validationRetryMode": "Validation retry mode",
|
|
14578
|
+
"workflow.planHistoryLimit": "Plan history limit",
|
|
14579
|
+
"workflow.planShowProgressBar": "Plan progress bar",
|
|
14580
|
+
"safety.repoLockEnabled": "Project Repo Lock",
|
|
14581
|
+
};
|
|
14582
|
+
if (labels[setting]) return labels[setting];
|
|
14583
|
+
const parts = setting.split(".");
|
|
14584
|
+
return humanizeWorkflowSettingSegment(parts[parts.length - 1] || setting);
|
|
14585
|
+
}
|
|
14586
|
+
|
|
14587
|
+
function workflowSettingDisplayValue(setting: string, value: string): string {
|
|
14588
|
+
const clean = value.trim().replace(/\s+/g, " ");
|
|
14589
|
+
if (setting === "ui.editorHintContrast") {
|
|
14590
|
+
return workflowEditorHintContrastLabel(parseEditorHintContrast(clean) ?? "normal");
|
|
14591
|
+
}
|
|
14592
|
+
if (clean === "true") {
|
|
14593
|
+
return /^ui\.show.*Hint$/.test(setting) ? "shown" : "enabled";
|
|
14594
|
+
}
|
|
14595
|
+
if (clean === "false") {
|
|
14596
|
+
return /^ui\.show.*Hint$/.test(setting) ? "hidden" : "disabled";
|
|
14597
|
+
}
|
|
14598
|
+
return clean
|
|
14599
|
+
.replace(/_/g, " ")
|
|
14600
|
+
.replace(/\bpi\b/gi, "Pi")
|
|
14601
|
+
.replace(/\w\S*/g, (word) => word === "Pi" || word.toUpperCase() === "API" ? word : word.charAt(0).toUpperCase() + word.slice(1).toLowerCase());
|
|
14602
|
+
}
|
|
14603
|
+
|
|
14604
|
+
function workflowFriendlyNotification(message: string, level?: "info" | "warning" | "error"): string {
|
|
14605
|
+
if (level !== "info") return message;
|
|
14606
|
+
let text = message.replace(/\s+in\s+\/\S+/g, "").replace(/\s+/g, " ").trim();
|
|
14607
|
+
const settingMatch = text.match(/^([A-Za-z][A-Za-z0-9_]*(?:\.[A-Za-z0-9_]+)*)\s+set to\s+([^.;]+)([.;]?.*)$/);
|
|
14608
|
+
if (settingMatch) {
|
|
14609
|
+
const [, setting, value, tail = ""] = settingMatch;
|
|
14610
|
+
const label = workflowSettingDisplayLabel(setting);
|
|
14611
|
+
const displayValue = workflowSettingDisplayValue(setting, value);
|
|
14612
|
+
const suffix = tail.replace(/^[.;]\s*/, "").trim();
|
|
14613
|
+
return `${label} set to ${displayValue}.${suffix ? ` ${suffix}` : ""}`;
|
|
14614
|
+
}
|
|
14615
|
+
return text.charAt(0).toUpperCase() + text.slice(1);
|
|
14616
|
+
}
|
|
14617
|
+
|
|
14618
|
+
function workflowUiNotify(ctx: ExtensionContext, message: string, level?: "info" | "warning" | "error"): void {
|
|
14619
|
+
ctx.ui.notify(workflowFriendlyNotification(message, level), level);
|
|
14620
|
+
}
|
|
14621
|
+
|
|
14452
14622
|
async function showPlanningSettingsMenu(ctx: ExtensionContext) {
|
|
14453
14623
|
if (!ctx.hasUI) return show(pi, renderFullWorkflowSettings(loadWorkflowSettings(ctx.cwd)));
|
|
14454
14624
|
while (ctx.hasUI) {
|
|
@@ -14456,7 +14626,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14456
14626
|
if (!choice || choice === "Back") return;
|
|
14457
14627
|
if (choice === "Set planning.depth") {
|
|
14458
14628
|
const depth = parsePlanningDepth((await ctx.ui.select("Planning depth", ["fast", "standard", "deep", "maximum"])) ?? "");
|
|
14459
|
-
if (depth) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.planning.depth = depth; }); ctx
|
|
14629
|
+
if (depth) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.planning.depth = depth; }); workflowUiNotify(ctx, `planning.depth set to ${depth} in ${r.file}`, "info"); }
|
|
14460
14630
|
} else if (choice === "List Current Settings") {
|
|
14461
14631
|
const s = loadWorkflowSettings(ctx.cwd);
|
|
14462
14632
|
show(pi, `# Planning Settings\n\nplanning.depth: ${s.planning.depth}`);
|
|
@@ -14471,13 +14641,13 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14471
14641
|
if (!choice || choice === "Back") return;
|
|
14472
14642
|
if (choice === "Set clarificationMode") {
|
|
14473
14643
|
const mode = parseClarificationMode((await ctx.ui.select("Clarification mode", ["auto", "always_for_nontrivial", "never"])) ?? "");
|
|
14474
|
-
if (mode) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.planning.clarificationMode = mode; }); ctx
|
|
14644
|
+
if (mode) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.planning.clarificationMode = mode; }); workflowUiNotify(ctx, `planning.clarificationMode set to ${mode} in ${r.file}`, "info"); }
|
|
14475
14645
|
} else if (choice === "Set interactiveClarificationEnabled") {
|
|
14476
14646
|
const enabled = await chooseBool(ctx, "Interactive clarification enabled?");
|
|
14477
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.planning.interactiveClarificationEnabled = enabled; }); ctx
|
|
14647
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.planning.interactiveClarificationEnabled = enabled; }); workflowUiNotify(ctx, `interactiveClarificationEnabled set to ${enabled} in ${r.file}`, "info"); }
|
|
14478
14648
|
} else if (choice === "Set maxClarificationQuestions") {
|
|
14479
14649
|
const count = parsePositiveInt((await ctx.ui.select("Max clarification questions", ["1", "2", "3", "4", "5"])) ?? "");
|
|
14480
|
-
if (count) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.planning.maxClarificationQuestions = count; }); ctx
|
|
14650
|
+
if (count) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.planning.maxClarificationQuestions = count; }); workflowUiNotify(ctx, `maxClarificationQuestions set to ${count} in ${r.file}`, "info"); }
|
|
14481
14651
|
} else if (choice === "List Current Settings") {
|
|
14482
14652
|
const s = loadWorkflowSettings(ctx.cwd);
|
|
14483
14653
|
show(pi, `# Clarification Settings\n\nClarification Mode: ${s.planning.clarificationMode}\nInteractive Clarification: ${s.planning.interactiveClarificationEnabled !== false ? "enabled" : "disabled"}\nMax Clarification Questions: ${s.planning.maxClarificationQuestions}`);
|
|
@@ -14493,11 +14663,11 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14493
14663
|
if (!choice || choice === "Back") return;
|
|
14494
14664
|
if (choice.endsWith("Policy")) {
|
|
14495
14665
|
const policy = parseSubagentPolicy((await ctx.ui.select(`${label} policy`, ["off", "auto", "deep", "maximum", "forced"])) ?? "");
|
|
14496
|
-
if (policy) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.subagents as typeof s.subagents & Record<string, string>)[keys.policyKey] = policy; }); ctx
|
|
14666
|
+
if (policy) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.subagents as typeof s.subagents & Record<string, string>)[keys.policyKey] = policy; }); workflowUiNotify(ctx, `subagents.${keys.policyKey} set to ${policy} in ${r.file}`, "info"); }
|
|
14497
14667
|
} else {
|
|
14498
14668
|
const key = choice.includes("Deep") ? keys.deepKey : keys.maximumKey;
|
|
14499
14669
|
const count = parsePositiveInt((await ctx.ui.select(`${label} ${choice.includes("Deep") ? "deep" : "maximum / forced"} workers`, ["0", "1", "2", "3", "4", "5", "6", "7", "8"])) ?? "");
|
|
14500
|
-
if (count !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.subagents as typeof s.subagents & Record<string, number>)[key] = count; }); ctx
|
|
14670
|
+
if (count !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.subagents as typeof s.subagents & Record<string, number>)[key] = count; }); workflowUiNotify(ctx, `subagents.${key} set to ${count} in ${r.file}. Forced policy uses this phase's Maximum / Forced worker count.`, "info"); }
|
|
14501
14671
|
}
|
|
14502
14672
|
}
|
|
14503
14673
|
}
|
|
@@ -14515,7 +14685,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14515
14685
|
const standard = s.standard as typeof s.standard & { subagents?: Record<string, boolean | number | string | undefined> };
|
|
14516
14686
|
standard.subagents = { ...(standard.subagents ?? {}), [keys.policyKey]: policy };
|
|
14517
14687
|
});
|
|
14518
|
-
ctx
|
|
14688
|
+
workflowUiNotify(ctx, `standard.subagents.${keys.policyKey} set to ${policy} in ${r.file}`, "info");
|
|
14519
14689
|
}
|
|
14520
14690
|
} else {
|
|
14521
14691
|
const key = choice.includes("Deep") ? keys.deepKey : keys.maximumKey;
|
|
@@ -14525,7 +14695,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14525
14695
|
const standard = s.standard as typeof s.standard & { subagents?: Record<string, boolean | number | string | undefined> };
|
|
14526
14696
|
standard.subagents = { ...(standard.subagents ?? {}), [key]: count };
|
|
14527
14697
|
});
|
|
14528
|
-
ctx
|
|
14698
|
+
workflowUiNotify(ctx, `standard.subagents.${key} set to ${count} in ${r.file}. Forced policy uses this Standard phase's Maximum / Forced worker count.`, "info");
|
|
14529
14699
|
}
|
|
14530
14700
|
}
|
|
14531
14701
|
}
|
|
@@ -14544,7 +14714,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14544
14714
|
const standard = s.standard as typeof s.standard & { subagents?: Record<string, boolean | number | string | undefined> };
|
|
14545
14715
|
standard.subagents = { ...(standard.subagents ?? {}), [key]: enabled };
|
|
14546
14716
|
});
|
|
14547
|
-
ctx
|
|
14717
|
+
workflowUiNotify(ctx, `standard.subagents.${key} set to ${enabled} in ${r.file}`, "info");
|
|
14548
14718
|
}
|
|
14549
14719
|
}
|
|
14550
14720
|
}
|
|
@@ -14561,7 +14731,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14561
14731
|
const standard = s.standard as typeof s.standard & { subagents?: Record<string, boolean | number | string | undefined> };
|
|
14562
14732
|
standard.subagents = { ...(standard.subagents ?? {}), [key]: enabled };
|
|
14563
14733
|
});
|
|
14564
|
-
ctx
|
|
14734
|
+
workflowUiNotify(ctx, `standard.subagents.${key} set to ${enabled} in ${r.file}`, "info");
|
|
14565
14735
|
}
|
|
14566
14736
|
}
|
|
14567
14737
|
}
|
|
@@ -14573,7 +14743,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14573
14743
|
if (!choice || choice === "Back") return;
|
|
14574
14744
|
if (choice === "Enable / Disable Standard Sub-agents") {
|
|
14575
14745
|
const enabled = await chooseBool(ctx, "standard.allowSubagents?");
|
|
14576
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.standard.allowSubagents = enabled; }); ctx
|
|
14746
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.standard.allowSubagents = enabled; }); workflowUiNotify(ctx, `standard.allowSubagents set to ${enabled} in ${r.file}`, "info"); }
|
|
14577
14747
|
} else if (choice === "Standard Planning / Research Policy / Workers") await showStandardSubagentPhaseSettingsMenu(ctx, "Planning", "Standard Planning / Research");
|
|
14578
14748
|
else if (choice === "Standard Execution Policy / Workers") await showStandardSubagentPhaseSettingsMenu(ctx, "Execution", "Standard Execution");
|
|
14579
14749
|
else if (choice === "Standard Repair Policy / Workers") await showStandardSubagentPhaseSettingsMenu(ctx, "Repair", "Standard Repair");
|
|
@@ -14581,15 +14751,15 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14581
14751
|
else if (choice === "Standard Validation Policy / Workers") await showStandardSubagentPhaseSettingsMenu(ctx, "Validation", "Standard Validation");
|
|
14582
14752
|
else if (choice === "Agent Scope") {
|
|
14583
14753
|
const scope = parseWorkflowAgentScope((await ctx.ui.select("Standard agent scope", ["user", "project", "both"])) ?? "");
|
|
14584
|
-
if (scope) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.standard.subagentScope = scope; }); ctx
|
|
14754
|
+
if (scope) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.standard.subagentScope = scope; }); workflowUiNotify(ctx, `standard.subagentScope set to ${scope} in ${r.file}`, "info"); }
|
|
14585
14755
|
} else if (choice === "Auto-use Toggles") await showStandardSubagentAutoUseMenu(ctx);
|
|
14586
14756
|
else if (choice === "Parallel Agent Settings") await showStandardParallelismSettingsMenu(ctx);
|
|
14587
14757
|
else if (choice === "Activity Indicator") {
|
|
14588
14758
|
const enabled = await chooseBool(ctx, "subagents.activityIndicatorEnabled?");
|
|
14589
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.subagents.activityIndicatorEnabled = enabled; }); ctx
|
|
14759
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.subagents.activityIndicatorEnabled = enabled; }); workflowUiNotify(ctx, `subagents.activityIndicatorEnabled set to ${enabled} in ${r.file}`, "info"); renderWorkflowSubagentActivity(ctx); }
|
|
14590
14760
|
} else if (choice === "List Current Settings") {
|
|
14591
14761
|
const s = loadWorkflowSettings(ctx.cwd);
|
|
14592
|
-
show(pi, `#
|
|
14762
|
+
show(pi, `# Standard Sub-agents / Workers\n\nSub-agents: ${s.standard.allowSubagents !== false ? "enabled" : "disabled"}\nAgent Scope: ${s.standard.subagentScope ?? "user"}\nActivity Indicator: ${s.subagents.activityIndicatorEnabled !== false ? "enabled" : "disabled"}\nAuto-use Planning: ${s.standard.subagents?.autoUseDuringPlanning !== false ? "on" : "off"}\nAuto-use Execution: ${s.standard.subagents?.autoUseDuringExecution !== false ? "on" : "off"}\nAuto-use Repair: ${s.standard.subagents?.autoUseDuringRepair !== false ? "on" : "off"}\nAuto-use Review: ${s.standard.subagents?.autoUseDuringReview !== false ? "on" : "off"}\nAuto-use Validation: ${s.standard.subagents?.autoUseDuringValidation !== false ? "on" : "off"}`);
|
|
14593
14763
|
}
|
|
14594
14764
|
}
|
|
14595
14765
|
}
|
|
@@ -14601,11 +14771,11 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14601
14771
|
if (!choice || choice === "Back") return;
|
|
14602
14772
|
if (choice === "Mission Planning Policy") {
|
|
14603
14773
|
const policy = parseSubagentPolicy((await ctx.ui.select("Mission planning policy", ["off", "auto", "deep", "maximum", "forced"])) ?? "");
|
|
14604
|
-
if (policy) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.subagentPolicy = policy; }); ctx
|
|
14774
|
+
if (policy) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.subagentPolicy = policy; }); workflowUiNotify(ctx, `missions.subagentPolicy set to ${policy} in ${r.file}`, "info"); }
|
|
14605
14775
|
} else {
|
|
14606
14776
|
const key = choice.includes("Deep") ? "minWorkersForDeep" : "minWorkersForMaximum";
|
|
14607
14777
|
const count = parsePositiveInt((await ctx.ui.select(choice, ["0", "1", "2", "3", "4", "5", "6", "7", "8"])) ?? "");
|
|
14608
|
-
if (count !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.missions as typeof s.missions & Record<string, number>)[key] = count; }); ctx
|
|
14778
|
+
if (count !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.missions as typeof s.missions & Record<string, number>)[key] = count; }); workflowUiNotify(ctx, `missions.${key} set to ${count} in ${r.file}. Forced mission planning uses Mission Planning Maximum / Forced Workers.`, "info"); }
|
|
14609
14779
|
}
|
|
14610
14780
|
}
|
|
14611
14781
|
}
|
|
@@ -14618,7 +14788,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14618
14788
|
const keyMap: Record<string, string> = { "Planning Auto-use": "autoUseDuringPlanning", "Execution Auto-use": "autoUseDuringExecution", "Repair Auto-use": "autoUseDuringRepair", "Review Auto-use": "autoUseDuringReview", "Validation Auto-use": "autoUseDuringValidation" };
|
|
14619
14789
|
const key = keyMap[choice];
|
|
14620
14790
|
const enabled = await chooseBool(ctx, `${key}?`);
|
|
14621
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.subagents as typeof s.subagents & Record<string, boolean>)[key] = enabled; }); ctx
|
|
14791
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.subagents as typeof s.subagents & Record<string, boolean>)[key] = enabled; }); workflowUiNotify(ctx, `subagents.${key} set to ${enabled} in ${r.file}`, "info"); }
|
|
14622
14792
|
}
|
|
14623
14793
|
}
|
|
14624
14794
|
|
|
@@ -14629,7 +14799,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14629
14799
|
if (!choice || choice === "Back") return;
|
|
14630
14800
|
if (choice === "Enable / Disable Sub-agents") {
|
|
14631
14801
|
const enabled = await chooseBool(ctx, "subagents.enabled?");
|
|
14632
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.subagents.enabled = enabled; }); ctx
|
|
14802
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.subagents.enabled = enabled; }); workflowUiNotify(ctx, `subagents.enabled set to ${enabled} in ${r.file}`, "info"); }
|
|
14633
14803
|
} else if (choice === "Planning Policy / Workers") await showSubagentPhaseSettingsMenu(ctx, "Planning", "Shared Planning");
|
|
14634
14804
|
else if (choice === "Execution Policy / Workers") await showSubagentPhaseSettingsMenu(ctx, "Execution", "Shared Execution");
|
|
14635
14805
|
else if (choice === "Repair Policy / Workers") await showSubagentPhaseSettingsMenu(ctx, "Repair", "Shared Repair");
|
|
@@ -14639,10 +14809,10 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14639
14809
|
else if (choice === "Parallel Agent Settings") await showParallelismSettingsMenu(ctx);
|
|
14640
14810
|
else if (choice === "Background Sub-agents") {
|
|
14641
14811
|
const enabled = await chooseBool(ctx, "subagents.allowBackgroundSubagents?");
|
|
14642
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.subagents.allowBackgroundSubagents = enabled; }); ctx
|
|
14812
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.subagents.allowBackgroundSubagents = enabled; }); workflowUiNotify(ctx, `subagents.allowBackgroundSubagents set to ${enabled} in ${r.file}. Background sub-agents run in Planning/Review/Validation phases without blocking the parent.`, "info"); }
|
|
14643
14813
|
} else if (choice === "Activity Indicator") {
|
|
14644
14814
|
const enabled = await chooseBool(ctx, "subagents.activityIndicatorEnabled?");
|
|
14645
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.subagents.activityIndicatorEnabled = enabled; }); ctx
|
|
14815
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.subagents.activityIndicatorEnabled = enabled; }); workflowUiNotify(ctx, `subagents.activityIndicatorEnabled set to ${enabled} in ${r.file}`, "info"); renderWorkflowSubagentActivity(ctx); }
|
|
14646
14816
|
} else if (choice === "List Current Settings") {
|
|
14647
14817
|
const s = loadWorkflowSettings(ctx.cwd);
|
|
14648
14818
|
show(pi, `# Shared Sub-agents / Workers\n\nSub-agents: ${s.subagents.enabled !== false ? "enabled" : "disabled"}\nBackground Sub-agents: ${s.subagents.allowBackgroundSubagents === true ? "enabled" : "disabled"}\nActivity Indicator: ${s.subagents.activityIndicatorEnabled !== false ? "enabled" : "disabled"}\nAuto-use Planning: ${s.subagents.autoUseDuringPlanning !== false ? "on" : "off"}\nAuto-use Execution: ${s.subagents.autoUseDuringExecution !== false ? "on" : "off"}\nAuto-use Repair: ${s.subagents.autoUseDuringRepair !== false ? "on" : "off"}\nAuto-use Review: ${s.subagents.autoUseDuringReview !== false ? "on" : "off"}\nAuto-use Validation: ${s.subagents.autoUseDuringValidation !== false ? "on" : "off"}`);
|
|
@@ -14657,7 +14827,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14657
14827
|
if (!choice || choice === "Back") return;
|
|
14658
14828
|
if (choice === "Enable / Disable Sub-agents") {
|
|
14659
14829
|
const enabled = await chooseBool(ctx, "subagents.enabled?");
|
|
14660
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.subagents.enabled = enabled; }); ctx
|
|
14830
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.subagents.enabled = enabled; }); workflowUiNotify(ctx, `subagents.enabled set to ${enabled} in ${r.file}`, "info"); }
|
|
14661
14831
|
} else if (choice === "Plan Planning Policy / Workers") await showSubagentPhaseSettingsMenu(ctx, "Planning", "Plan Planning");
|
|
14662
14832
|
else if (choice === "Plan Execution Policy / Workers") await showSubagentPhaseSettingsMenu(ctx, "Execution", "Plan Execution");
|
|
14663
14833
|
else if (choice === "Plan Repair Policy / Workers") await showSubagentPhaseSettingsMenu(ctx, "Repair", "Plan Repair");
|
|
@@ -14667,10 +14837,10 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14667
14837
|
else if (choice === "Parallel Agent Settings") await showParallelismSettingsMenu(ctx);
|
|
14668
14838
|
else if (choice === "Activity Indicator") {
|
|
14669
14839
|
const enabled = await chooseBool(ctx, "subagents.activityIndicatorEnabled?");
|
|
14670
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.subagents.activityIndicatorEnabled = enabled; }); ctx
|
|
14840
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.subagents.activityIndicatorEnabled = enabled; }); workflowUiNotify(ctx, `subagents.activityIndicatorEnabled set to ${enabled} in ${r.file}`, "info"); renderWorkflowSubagentActivity(ctx); }
|
|
14671
14841
|
} else if (choice === "List Current Settings") {
|
|
14672
14842
|
const s = loadWorkflowSettings(ctx.cwd);
|
|
14673
|
-
show(pi, `#
|
|
14843
|
+
show(pi, `# Plan Sub-agents / Workers\n\n${renderPlanSubagentWorkerSettings(s)}`);
|
|
14674
14844
|
}
|
|
14675
14845
|
}
|
|
14676
14846
|
}
|
|
@@ -14682,7 +14852,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14682
14852
|
if (!choice || choice === "Back") return;
|
|
14683
14853
|
if (choice === "Enable / Disable Sub-agents") {
|
|
14684
14854
|
const enabled = await chooseBool(ctx, "subagents.enabled?");
|
|
14685
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.subagents.enabled = enabled; }); ctx
|
|
14855
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.subagents.enabled = enabled; }); workflowUiNotify(ctx, `subagents.enabled set to ${enabled} in ${r.file}`, "info"); }
|
|
14686
14856
|
} else if (choice === "Mission Planning Policy / Workers") await showMissionPlanningSubagentSettingsMenu(ctx);
|
|
14687
14857
|
else if (choice === "Mission Execution Policy / Workers") await showSubagentPhaseSettingsMenu(ctx, "Execution", "Mission Execution");
|
|
14688
14858
|
else if (choice === "Mission Repair Policy / Workers") await showSubagentPhaseSettingsMenu(ctx, "Repair", "Mission Repair");
|
|
@@ -14692,7 +14862,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14692
14862
|
else if (choice === "Parallel Agent Settings") await showParallelismSettingsMenu(ctx);
|
|
14693
14863
|
else if (choice === "Activity Indicator") {
|
|
14694
14864
|
const enabled = await chooseBool(ctx, "subagents.activityIndicatorEnabled?");
|
|
14695
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.subagents.activityIndicatorEnabled = enabled; }); ctx
|
|
14865
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.subagents.activityIndicatorEnabled = enabled; }); workflowUiNotify(ctx, `subagents.activityIndicatorEnabled set to ${enabled} in ${r.file}`, "info"); renderWorkflowSubagentActivity(ctx); }
|
|
14696
14866
|
} else if (choice === "List Current Settings") {
|
|
14697
14867
|
const s = loadWorkflowSettings(ctx.cwd);
|
|
14698
14868
|
show(pi, `# Mission Sub-agents / Workers\n\n${renderMissionSubagentWorkerSettings(s)}`);
|
|
@@ -14708,10 +14878,10 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14708
14878
|
if (choice?.startsWith("Set allow") || choice === "Set requireParallelEditConflictProtection") {
|
|
14709
14879
|
const key = choice.replace("Set ", "");
|
|
14710
14880
|
const enabled = await chooseBool(ctx, `${key}?`);
|
|
14711
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.subagents as typeof s.subagents & Record<string, boolean>)[key] = enabled; }); ctx
|
|
14881
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.subagents as typeof s.subagents & Record<string, boolean>)[key] = enabled; }); workflowUiNotify(ctx, `subagents.${key} set to ${enabled} in ${r.file}`, "info"); }
|
|
14712
14882
|
} else if (choice === "Set editConcurrencyMode") {
|
|
14713
14883
|
const mode = parseEditConcurrencyMode((await ctx.ui.select("Edit concurrency mode", ["sequential", "scoped", "blocked"])) ?? "");
|
|
14714
|
-
if (mode) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.subagents.editConcurrencyMode = mode; }); ctx
|
|
14884
|
+
if (mode) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.subagents.editConcurrencyMode = mode; }); workflowUiNotify(ctx, `subagents.editConcurrencyMode set to ${mode} in ${r.file}`, "info"); }
|
|
14715
14885
|
} else if (choice === "List Current Settings") {
|
|
14716
14886
|
const s = loadWorkflowSettings(ctx.cwd);
|
|
14717
14887
|
show(pi, `# Parallelism Settings\n\nParallel Read-Only: ${s.subagents.allowParallelReadOnly !== false ? "enabled" : "disabled"}\nParallel Planning: ${s.subagents.allowParallelPlanning !== false ? "enabled" : "disabled"}\nParallel Execution: ${s.subagents.allowParallelExecution !== false ? "enabled" : "disabled"}\nParallel Repair: ${s.subagents.allowParallelRepair !== false ? "enabled" : "disabled"}\nParallel Review: ${s.subagents.allowParallelReview !== false ? "enabled" : "disabled"}\nParallel Validation: ${s.subagents.allowParallelValidation !== false ? "enabled" : "disabled"}\nParallel File Edits: ${s.subagents.allowParallelEdits !== false ? "enabled" : "disabled"}\nEdit Concurrency Mode: ${s.subagents.editConcurrencyMode ?? "sequential"}\nConflict Protection: ${s.subagents.requireParallelEditConflictProtection !== false ? "enabled" : "disabled"}`);
|
|
@@ -14723,7 +14893,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14723
14893
|
const models = ctx.modelRegistry.getAll();
|
|
14724
14894
|
const providers = [...new Set(models.map((m) => m.provider))].sort();
|
|
14725
14895
|
if (providers.length === 0) {
|
|
14726
|
-
ctx
|
|
14896
|
+
workflowUiNotify(ctx, "No models are available in the model registry.", "error");
|
|
14727
14897
|
return undefined;
|
|
14728
14898
|
}
|
|
14729
14899
|
const providerChoice = await ctx.ui.select(`${title}: select provider`, [...providers, "Custom provider name"]);
|
|
@@ -14737,7 +14907,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14737
14907
|
}
|
|
14738
14908
|
const providerModels = models.filter((m) => m.provider === providerChoice).map((m) => m.id).sort();
|
|
14739
14909
|
if (providerModels.length === 0) {
|
|
14740
|
-
ctx
|
|
14910
|
+
workflowUiNotify(ctx, `No models found for provider ${providerChoice}.`, "error");
|
|
14741
14911
|
return undefined;
|
|
14742
14912
|
}
|
|
14743
14913
|
const modelChoice = await ctx.ui.select(`${title}: select model`, providerModels.map((model) => `${providerChoice}/${model}`));
|
|
@@ -14764,7 +14934,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14764
14934
|
s.context.compactionModelProvider = provider;
|
|
14765
14935
|
s.context.compactionModel = "";
|
|
14766
14936
|
});
|
|
14767
|
-
ctx
|
|
14937
|
+
workflowUiNotify(ctx, provider ? `Compaction provider preference stored as ${provider} in ${result.file}. Trigger behavior was not changed.` : `Compaction provider reset to Pi default in ${result.file}. Trigger behavior was not changed.`, "info");
|
|
14768
14938
|
}
|
|
14769
14939
|
|
|
14770
14940
|
async function selectCompactionModel(ctx: ExtensionContext) {
|
|
@@ -14777,7 +14947,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14777
14947
|
s.context.compactionModelProvider = "";
|
|
14778
14948
|
s.context.compactionModel = "";
|
|
14779
14949
|
});
|
|
14780
|
-
ctx
|
|
14950
|
+
workflowUiNotify(ctx, `Compaction summary model reset to Pi default in ${result.file}. Trigger behavior was not changed.`, "info");
|
|
14781
14951
|
return;
|
|
14782
14952
|
}
|
|
14783
14953
|
|
|
@@ -14788,7 +14958,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14788
14958
|
selectedProvider = chosen;
|
|
14789
14959
|
}
|
|
14790
14960
|
if (!selectedProvider) {
|
|
14791
|
-
ctx
|
|
14961
|
+
workflowUiNotify(ctx, "Select a custom compaction provider before selecting a custom model.", "warning");
|
|
14792
14962
|
return;
|
|
14793
14963
|
}
|
|
14794
14964
|
const providerModels = ctx.modelRegistry.getAll().filter((m) => m.provider === selectedProvider).map((m) => m.id).sort();
|
|
@@ -14800,7 +14970,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14800
14970
|
s.context.compactionModelProvider = selectedProvider;
|
|
14801
14971
|
s.context.compactionModel = model;
|
|
14802
14972
|
});
|
|
14803
|
-
ctx
|
|
14973
|
+
workflowUiNotify(ctx, `Compaction model preference stored as ${selectedProvider}/${model} in ${result.file}. Trigger behavior was not changed.`, "info");
|
|
14804
14974
|
}
|
|
14805
14975
|
|
|
14806
14976
|
async function selectCompactionAgent(ctx: ExtensionContext) {
|
|
@@ -14814,7 +14984,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14814
14984
|
s.context.compactionAgent = agent;
|
|
14815
14985
|
s.context.customCompactionEnabled = true;
|
|
14816
14986
|
});
|
|
14817
|
-
ctx
|
|
14987
|
+
workflowUiNotify(ctx, `Compaction agent stored as ${agent} in ${result.file}. Current releases keep Pi default fallback behavior for agent-routed compaction.`, "info");
|
|
14818
14988
|
}
|
|
14819
14989
|
|
|
14820
14990
|
async function showCompactionSettingsMenu(ctx: ExtensionContext) {
|
|
@@ -14833,53 +15003,53 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14833
15003
|
if (trigger === "Pi default") delete s.context.autoCompactionEnabled;
|
|
14834
15004
|
else s.context.autoCompactionEnabled = trigger === "Enabled";
|
|
14835
15005
|
});
|
|
14836
|
-
ctx
|
|
15006
|
+
workflowUiNotify(ctx, `Workflow auto trigger set to ${trigger.toLowerCase()} in ${r.file}.`, "info");
|
|
14837
15007
|
} else if (choice === "Workflow Trigger Percent") {
|
|
14838
15008
|
const mode = await ctx.ui.select("Workflow Trigger Percent", ["Pi default", "Custom percent", "Back"]);
|
|
14839
15009
|
if (!mode || mode === "Back") continue;
|
|
14840
15010
|
if (mode === "Pi default") {
|
|
14841
15011
|
const r = updateSettings(ctx.cwd, undefined, (s) => { delete s.context.compactionTriggerPercent; });
|
|
14842
|
-
ctx
|
|
15012
|
+
workflowUiNotify(ctx, `Workflow compaction trigger percent override removed in ${r.file}; Pi native trigger formula remains in control.`, "info");
|
|
14843
15013
|
} else {
|
|
14844
15014
|
const raw = String((await ctx.ui.input("Workflow compaction trigger percent (50-95)", String(compactionTriggerPercentOverride(loadWorkflowSettings(ctx.cwd)) ?? 85))) ?? "").trim();
|
|
14845
15015
|
const count = Number(raw);
|
|
14846
|
-
if (Number.isInteger(count) && count >= 50 && count <= 95) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.context.compactionTriggerPercent = count; }); ctx
|
|
14847
|
-
else ctx
|
|
15016
|
+
if (Number.isInteger(count) && count >= 50 && count <= 95) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.context.compactionTriggerPercent = count; }); workflowUiNotify(ctx, `Workflow compaction trigger percent set to ${count}% in ${r.file}`, "info"); }
|
|
15017
|
+
else workflowUiNotify(ctx, "Trigger percent must be an integer from 50 to 95.", "error");
|
|
14848
15018
|
}
|
|
14849
15019
|
} else if (choice === "Workflow Trigger Cooldown") {
|
|
14850
15020
|
const mode = await ctx.ui.select("Workflow Trigger Cooldown", ["Pi default", "Custom cooldown", "Back"]);
|
|
14851
15021
|
if (!mode || mode === "Back") continue;
|
|
14852
15022
|
if (mode === "Pi default") {
|
|
14853
15023
|
const r = updateSettings(ctx.cwd, undefined, (s) => { s.context.compactionCooldownMinutes = 5; });
|
|
14854
|
-
ctx
|
|
15024
|
+
workflowUiNotify(ctx, `Compaction cooldown reset to Pi default (5 minutes) in ${r.file}.`, "info");
|
|
14855
15025
|
} else {
|
|
14856
15026
|
const count = Number((await ctx.ui.input("Minimum minutes between Workflow Suite proactive compaction attempts", String(compactionCooldownMinutes(loadWorkflowSettings(ctx.cwd)))) ?? ""));
|
|
14857
|
-
if (Number.isInteger(count) && count >= 0 && count <= 240) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.context.compactionCooldownMinutes = count; }); ctx
|
|
14858
|
-
else ctx
|
|
15027
|
+
if (Number.isInteger(count) && count >= 0 && count <= 240) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.context.compactionCooldownMinutes = count; }); workflowUiNotify(ctx, `Compaction cooldown set to ${count} minute(s) in ${r.file}. This is the minimum wait between proactive compaction attempts, not a delay before compaction starts.`, "info"); }
|
|
15028
|
+
else workflowUiNotify(ctx, "Cooldown must be an integer from 0 to 240 minutes.", "error");
|
|
14859
15029
|
}
|
|
14860
15030
|
} else if (choice === "Custom Reserve Tokens") {
|
|
14861
15031
|
const mode = await ctx.ui.select("Custom Reserve Tokens", ["Pi default", "Custom reserve tokens", "Back"]);
|
|
14862
15032
|
if (!mode || mode === "Back") continue;
|
|
14863
15033
|
if (mode === "Pi default") {
|
|
14864
15034
|
const r = updateSettings(ctx.cwd, undefined, (s) => { s.context.customCompactionReserveTokens = DEFAULT_PI_COMPACTION_RESERVE_TOKENS; });
|
|
14865
|
-
ctx
|
|
15035
|
+
workflowUiNotify(ctx, `Custom compaction reserve tokens reset to Pi default (${DEFAULT_PI_COMPACTION_RESERVE_TOKENS.toLocaleString()}) in ${r.file}`, "info");
|
|
14866
15036
|
} else {
|
|
14867
15037
|
const raw = String((await ctx.ui.input("Custom compaction reserve tokens (4096-65536)", String(customCompactionReserveTokens(loadWorkflowSettings(ctx.cwd)))) ?? "")).trim();
|
|
14868
15038
|
const count = Number(raw);
|
|
14869
|
-
if (Number.isInteger(count) && count >= 4096 && count <= 65536) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.context.customCompactionReserveTokens = count; }); ctx
|
|
14870
|
-
else ctx
|
|
15039
|
+
if (Number.isInteger(count) && count >= 4096 && count <= 65536) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.context.customCompactionReserveTokens = count; }); workflowUiNotify(ctx, `Custom compaction reserve tokens set to ${count.toLocaleString()} in ${r.file}`, "info"); }
|
|
15040
|
+
else workflowUiNotify(ctx, "Reserve tokens must be an integer from 4096 to 65536.", "error");
|
|
14871
15041
|
}
|
|
14872
15042
|
} else if (choice === "Custom Keep Recent Tokens") {
|
|
14873
15043
|
const mode = await ctx.ui.select("Custom Keep Recent Tokens", ["Pi default", "Custom keep-recent tokens", "Back"]);
|
|
14874
15044
|
if (!mode || mode === "Back") continue;
|
|
14875
15045
|
if (mode === "Pi default") {
|
|
14876
15046
|
const r = updateSettings(ctx.cwd, undefined, (s) => { s.context.customCompactionKeepRecentTokens = DEFAULT_PI_COMPACTION_KEEP_RECENT_TOKENS; });
|
|
14877
|
-
ctx
|
|
15047
|
+
workflowUiNotify(ctx, `Custom compaction keep-recent tokens reset to Pi default (${DEFAULT_PI_COMPACTION_KEEP_RECENT_TOKENS.toLocaleString()}) in ${r.file}`, "info");
|
|
14878
15048
|
} else {
|
|
14879
15049
|
const raw = String((await ctx.ui.input("Custom compaction keep-recent tokens (1000-200000)", String(customCompactionKeepRecentTokens(loadWorkflowSettings(ctx.cwd)))) ?? "")).trim();
|
|
14880
15050
|
const count = Number(raw);
|
|
14881
|
-
if (Number.isInteger(count) && count >= 1000 && count <= 200000) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.context.customCompactionKeepRecentTokens = count; }); ctx
|
|
14882
|
-
else ctx
|
|
15051
|
+
if (Number.isInteger(count) && count >= 1000 && count <= 200000) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.context.customCompactionKeepRecentTokens = count; }); workflowUiNotify(ctx, `Custom compaction keep-recent tokens set to ${count.toLocaleString()} in ${r.file}`, "info"); }
|
|
15052
|
+
else workflowUiNotify(ctx, "Keep-recent tokens must be an integer from 1000 to 200000.", "error");
|
|
14883
15053
|
}
|
|
14884
15054
|
} else if (choice === "List Current Settings") {
|
|
14885
15055
|
const s = loadWorkflowSettings(ctx.cwd);
|
|
@@ -14930,7 +15100,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14930
15100
|
}
|
|
14931
15101
|
});
|
|
14932
15102
|
await reapplyStandardRouteIfStandardMode(ctx, true);
|
|
14933
|
-
ctx
|
|
15103
|
+
workflowUiNotify(ctx, `Standard model source set to ${source} in ${result.file}`, "info");
|
|
14934
15104
|
} else if (choice === "Standard Model Role") {
|
|
14935
15105
|
const role = parseStandardModelRole((await ctx.ui.select("Standard model role", ["Current Pi model", "Planner", "Executor", "Reviewer", "Validator"])) ?? "");
|
|
14936
15106
|
if (!role) continue;
|
|
@@ -14944,7 +15114,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14944
15114
|
}
|
|
14945
15115
|
});
|
|
14946
15116
|
await reapplyStandardRouteIfStandardMode(ctx, true);
|
|
14947
|
-
ctx
|
|
15117
|
+
workflowUiNotify(ctx, `Standard model role set to ${workflowRoleLabel(role)} in ${result.file}`, "info");
|
|
14948
15118
|
} else if (choice === "Configure Standard Planner") await configureStandardRoleModel(ctx, "planner");
|
|
14949
15119
|
else if (choice === "Configure Standard Executor") await configureStandardRoleModel(ctx, "executor");
|
|
14950
15120
|
else if (choice === "Configure Standard Reviewer") await configureStandardRoleModel(ctx, "reviewer");
|
|
@@ -14965,10 +15135,10 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14965
15135
|
const options = key === "maxValidationRetriesPerPlan" ? ["0", "1", "2", "3", "4", "5", "10"] : ["0", "1", "2", "4", "8", "12", "20", "50", "100"];
|
|
14966
15136
|
const raw = await ctx.ui.select(setting, options);
|
|
14967
15137
|
const count = raw === undefined ? undefined : Number(raw);
|
|
14968
|
-
if (Number.isInteger(count) && count >= 0 && count <= max) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.workflow as typeof s.workflow & Record<string, number>)[key] = count; }); ctx
|
|
15138
|
+
if (Number.isInteger(count) && count >= 0 && count <= max) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.workflow as typeof s.workflow & Record<string, number>)[key] = count; }); workflowUiNotify(ctx, `workflow.${key} set to ${count} in ${r.file}`, "info"); }
|
|
14969
15139
|
} else if (setting === "Validation Retry Mode") {
|
|
14970
15140
|
const mode = parseValidationRetryMode((await ctx.ui.select("Validation retry mode", ["off", "safe_only", "aggressive_within_scope"])) ?? "");
|
|
14971
|
-
if (mode) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.workflow.validationRetryMode = mode; }); ctx
|
|
15141
|
+
if (mode) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.workflow.validationRetryMode = mode; }); workflowUiNotify(ctx, `workflow.validationRetryMode set to ${mode} in ${r.file}`, "info"); }
|
|
14972
15142
|
} else {
|
|
14973
15143
|
const keyMap: Record<string, keyof ReturnType<typeof loadWorkflowSettings>["workflow"]> = {
|
|
14974
15144
|
"Auto Repair Validation Failures": "autoRepairValidationFailures",
|
|
@@ -14978,7 +15148,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14978
15148
|
};
|
|
14979
15149
|
const key = keyMap[setting];
|
|
14980
15150
|
const enabled = await chooseBool(ctx, `${String(key)}?`);
|
|
14981
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.workflow as Record<string, unknown>)[String(key)] = enabled; }); ctx
|
|
15151
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.workflow as Record<string, unknown>)[String(key)] = enabled; }); workflowUiNotify(ctx, `workflow.${String(key)} set to ${enabled} in ${r.file}`, "info"); }
|
|
14982
15152
|
}
|
|
14983
15153
|
}
|
|
14984
15154
|
}
|
|
@@ -14992,26 +15162,26 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
14992
15162
|
await showModelSettingsMenu(ctx);
|
|
14993
15163
|
} else if (choice === "Planning Depth") {
|
|
14994
15164
|
const depth = parsePlanningDepth((await ctx.ui.select("Planning depth", ["fast", "standard", "deep", "maximum"])) ?? "");
|
|
14995
|
-
if (depth) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.planning.depth = depth; }); ctx
|
|
15165
|
+
if (depth) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.planning.depth = depth; }); workflowUiNotify(ctx, `planning.depth set to ${depth} in ${r.file}`, "info"); }
|
|
14996
15166
|
} else if (choice === "Plan Clarification") {
|
|
14997
15167
|
const setting = await ctx.ui.select("Plan Clarification", ["Clarification Mode", "Interactive Clarification", "Max Clarification Questions", "Timing", "Quality Gate", "Allow Without Analysis", "Use Sub-agents Before Clarification", "Back"]);
|
|
14998
15168
|
if (!setting || setting === "Back") continue;
|
|
14999
15169
|
if (setting === "Clarification Mode") {
|
|
15000
15170
|
const mode = parseClarificationMode((await ctx.ui.select("Plan clarification mode", ["auto", "always_for_nontrivial", "never"])) ?? "");
|
|
15001
|
-
if (mode) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.planning.clarificationMode = mode; }); ctx
|
|
15171
|
+
if (mode) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.planning.clarificationMode = mode; }); workflowUiNotify(ctx, `planning.clarificationMode set to ${mode} in ${r.file}`, "info"); }
|
|
15002
15172
|
} else if (setting === "Interactive Clarification") {
|
|
15003
15173
|
const enabled = await chooseBool(ctx, "Interactive clarification enabled?");
|
|
15004
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.planning.interactiveClarificationEnabled = enabled; }); ctx
|
|
15174
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.planning.interactiveClarificationEnabled = enabled; }); workflowUiNotify(ctx, `planning.interactiveClarificationEnabled set to ${enabled} in ${r.file}`, "info"); }
|
|
15005
15175
|
} else if (setting === "Max Clarification Questions") {
|
|
15006
15176
|
const count = parsePositiveInt((await ctx.ui.select("Max clarification questions", ["1", "2", "3", "4", "5"])) ?? "");
|
|
15007
|
-
if (count) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.planning.maxClarificationQuestions = count; }); ctx
|
|
15177
|
+
if (count) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.planning.maxClarificationQuestions = count; }); workflowUiNotify(ctx, `planning.maxClarificationQuestions set to ${count} in ${r.file}`, "info"); }
|
|
15008
15178
|
} else if (setting === "Timing") {
|
|
15009
15179
|
const timing = parseClarificationTiming((await ctx.ui.select("Plan clarification timing", ["after_initial_analysis", "immediate"])) ?? "");
|
|
15010
|
-
if (timing) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.planning.clarificationTiming = timing; }); ctx
|
|
15180
|
+
if (timing) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.planning.clarificationTiming = timing; }); workflowUiNotify(ctx, `planning.clarificationTiming set to ${timing} in ${r.file}`, "info"); }
|
|
15011
15181
|
} else {
|
|
15012
15182
|
const key = setting === "Quality Gate" ? "clarificationQualityGate" : setting === "Allow Without Analysis" ? "allowClarificationWithoutAnalysis" : "useSubagentsBeforeClarification";
|
|
15013
15183
|
const enabled = await chooseBool(ctx, `planning.${key}?`);
|
|
15014
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.planning as typeof s.planning & Record<string, boolean | string | number | undefined>)[key] = enabled; }); ctx
|
|
15184
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.planning as typeof s.planning & Record<string, boolean | string | number | undefined>)[key] = enabled; }); workflowUiNotify(ctx, `planning.${key} set to ${enabled} in ${r.file}`, "info"); }
|
|
15015
15185
|
}
|
|
15016
15186
|
} else if (choice === "Plan Sub-agents / Workers") {
|
|
15017
15187
|
await showPlanSubagentWorkerSettingsMenu(ctx);
|
|
@@ -15020,16 +15190,16 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
15020
15190
|
if (!setting || setting === "Back") continue;
|
|
15021
15191
|
const enabled = await chooseBool(ctx, `${setting}?`);
|
|
15022
15192
|
if (enabled === undefined) continue;
|
|
15023
|
-
if (setting === "Reviewer Enabled") { const r = setRoleEnabled("reviewer", enabled, ctx.cwd); ctx
|
|
15024
|
-
else if (setting === "Validator Enabled") { const r = setRoleEnabled("validator", enabled, ctx.cwd); ctx
|
|
15025
|
-
else if (setting === "Auto Run Reviewer") { const r = updateSettings(ctx.cwd, undefined, (s) => { s.workflow.autoRunReviewerBeforeExecute = enabled; }); ctx
|
|
15026
|
-
else if (setting === "Auto Run Validation") { const r = updateSettings(ctx.cwd, undefined, (s) => { s.workflow.autoRunValidationAfterExecute = enabled; }); ctx
|
|
15027
|
-
else if (setting === "Auto Repair Review Failures") { const r = updateSettings(ctx.cwd, undefined, (s) => { s.workflow.autoRepairReviewFailures = enabled; }); ctx
|
|
15028
|
-
else if (setting === "Pause After Review Failure") { const r = updateSettings(ctx.cwd, undefined, (s) => { s.workflow.pauseAfterReviewFailure = enabled; }); ctx
|
|
15029
|
-
else if (setting === "Approval Before Execution") { const r = updateSettings(ctx.cwd, undefined, (s) => { s.workflow.requireApprovalBeforeExecution = enabled; s.workflow.requirePlanApprovalBeforeExecute = enabled; }); ctx
|
|
15030
|
-
else if (setting === "Approval Per Step") { const r = updateSettings(ctx.cwd, undefined, (s) => { s.workflow.requireApprovalPerStep = enabled; }); ctx
|
|
15031
|
-
else if (setting === "Validate After Each Step") { const r = updateSettings(ctx.cwd, undefined, (s) => { s.workflow.validateAfterEachStep = enabled; }); ctx
|
|
15032
|
-
else if (setting === "Validate After Full Execution") { const r = updateSettings(ctx.cwd, undefined, (s) => { s.workflow.validateAfterExecution = enabled; s.workflow.autoRunValidationAfterExecute = enabled; }); ctx
|
|
15193
|
+
if (setting === "Reviewer Enabled") { const r = setRoleEnabled("reviewer", enabled, ctx.cwd); workflowUiNotify(ctx, `reviewer.enabled set to ${enabled} in ${r.file}`, "info"); }
|
|
15194
|
+
else if (setting === "Validator Enabled") { const r = setRoleEnabled("validator", enabled, ctx.cwd); workflowUiNotify(ctx, `validator.enabled set to ${enabled} in ${r.file}`, "info"); }
|
|
15195
|
+
else if (setting === "Auto Run Reviewer") { const r = updateSettings(ctx.cwd, undefined, (s) => { s.workflow.autoRunReviewerBeforeExecute = enabled; }); workflowUiNotify(ctx, `workflow.autoRunReviewerBeforeExecute set to ${enabled} in ${r.file}`, "info"); }
|
|
15196
|
+
else if (setting === "Auto Run Validation") { const r = updateSettings(ctx.cwd, undefined, (s) => { s.workflow.autoRunValidationAfterExecute = enabled; }); workflowUiNotify(ctx, `workflow.autoRunValidationAfterExecute set to ${enabled} in ${r.file}`, "info"); }
|
|
15197
|
+
else if (setting === "Auto Repair Review Failures") { const r = updateSettings(ctx.cwd, undefined, (s) => { s.workflow.autoRepairReviewFailures = enabled; }); workflowUiNotify(ctx, `workflow.autoRepairReviewFailures set to ${enabled} in ${r.file}`, "info"); }
|
|
15198
|
+
else if (setting === "Pause After Review Failure") { const r = updateSettings(ctx.cwd, undefined, (s) => { s.workflow.pauseAfterReviewFailure = enabled; }); workflowUiNotify(ctx, `workflow.pauseAfterReviewFailure set to ${enabled} in ${r.file}`, "info"); }
|
|
15199
|
+
else if (setting === "Approval Before Execution") { const r = updateSettings(ctx.cwd, undefined, (s) => { s.workflow.requireApprovalBeforeExecution = enabled; s.workflow.requirePlanApprovalBeforeExecute = enabled; }); workflowUiNotify(ctx, `workflow.requireApprovalBeforeExecution set to ${enabled} in ${r.file}`, "info"); }
|
|
15200
|
+
else if (setting === "Approval Per Step") { const r = updateSettings(ctx.cwd, undefined, (s) => { s.workflow.requireApprovalPerStep = enabled; }); workflowUiNotify(ctx, `workflow.requireApprovalPerStep set to ${enabled} in ${r.file}`, "info"); }
|
|
15201
|
+
else if (setting === "Validate After Each Step") { const r = updateSettings(ctx.cwd, undefined, (s) => { s.workflow.validateAfterEachStep = enabled; }); workflowUiNotify(ctx, `workflow.validateAfterEachStep set to ${enabled} in ${r.file}`, "info"); }
|
|
15202
|
+
else if (setting === "Validate After Full Execution") { const r = updateSettings(ctx.cwd, undefined, (s) => { s.workflow.validateAfterExecution = enabled; s.workflow.autoRunValidationAfterExecute = enabled; }); workflowUiNotify(ctx, `workflow.validateAfterExecution set to ${enabled} in ${r.file}`, "info"); }
|
|
15033
15203
|
} else if (choice === "Repair / Validation Retry") {
|
|
15034
15204
|
await showWorkflowRepairRetrySettingsMenu(ctx);
|
|
15035
15205
|
} else if (choice === "Plan Progress / Runtime") {
|
|
@@ -15045,28 +15215,28 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
15045
15215
|
const choice = await ctx.ui.select("Plan Token Budget", ["Default (unlimited)", "Custom..."]);
|
|
15046
15216
|
if (choice === "Default (unlimited)") {
|
|
15047
15217
|
const r = updateSettings(ctx.cwd, undefined, (s) => { s.planning.maxTokens = 0; });
|
|
15048
|
-
ctx
|
|
15218
|
+
workflowUiNotify(ctx, `planning.maxTokens set to default (unlimited) in ${r.file}`, "info");
|
|
15049
15219
|
} else if (choice === "Custom...") {
|
|
15050
15220
|
const count = parsePositiveInt((await ctx.ui.input("Enter custom plan token budget", String(current > 0 ? current : ""))) ?? "");
|
|
15051
|
-
if (count !== undefined && count >= 0) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.planning.maxTokens = count; }); ctx
|
|
15221
|
+
if (count !== undefined && count >= 0) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.planning.maxTokens = count; }); workflowUiNotify(ctx, `planning.maxTokens set to ${count === 0 ? "unlimited" : count.toLocaleString()} in ${r.file}`, "info"); }
|
|
15052
15222
|
}
|
|
15053
15223
|
} else if (setting === "Runtime Budget") {
|
|
15054
15224
|
const current = loadWorkflowSettings(ctx.cwd).planning.maxRuntimeHours ?? 0;
|
|
15055
15225
|
const choice = await ctx.ui.select("Plan Runtime Budget", ["Default (unlimited)", "Custom..."]);
|
|
15056
15226
|
if (choice === "Default (unlimited)") {
|
|
15057
15227
|
const r = updateSettings(ctx.cwd, undefined, (s) => { s.planning.maxRuntimeHours = 0; });
|
|
15058
|
-
ctx
|
|
15228
|
+
workflowUiNotify(ctx, `planning.maxRuntimeHours set to default (unlimited) in ${r.file}`, "info");
|
|
15059
15229
|
} else if (choice === "Custom...") {
|
|
15060
15230
|
const count = parsePositiveInt((await ctx.ui.input("Enter custom plan runtime budget (hours)", String(current > 0 ? current : ""))) ?? "");
|
|
15061
|
-
if (count !== undefined && count > 0) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.planning.maxRuntimeHours = count; }); ctx
|
|
15231
|
+
if (count !== undefined && count > 0) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.planning.maxRuntimeHours = count; }); workflowUiNotify(ctx, `planning.maxRuntimeHours set to ${count} hours in ${r.file}`, "info"); }
|
|
15062
15232
|
}
|
|
15063
15233
|
} else if (setting === "Progress Bar Display") {
|
|
15064
15234
|
const enabled = await chooseBool(ctx, "workflow.planShowProgressBar?");
|
|
15065
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.workflow.planShowProgressBar = enabled; }); ctx
|
|
15235
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.workflow.planShowProgressBar = enabled; }); workflowUiNotify(ctx, `workflow.planShowProgressBar set to ${enabled} in ${r.file}`, "info"); }
|
|
15066
15236
|
} else {
|
|
15067
15237
|
const key = setting === "Progress Tracking" ? "planProgressEnabled" : "planRuntimeEnabled";
|
|
15068
15238
|
const enabled = await chooseBool(ctx, `workflow.${key}?`);
|
|
15069
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.workflow as typeof s.workflow & Record<string, boolean>)[key] = enabled; }); ctx
|
|
15239
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.workflow as typeof s.workflow & Record<string, boolean>)[key] = enabled; }); workflowUiNotify(ctx, `workflow.${key} set to ${enabled} in ${r.file}`, "info"); }
|
|
15070
15240
|
}
|
|
15071
15241
|
} else if (choice === "Plan History") {
|
|
15072
15242
|
const setting = await ctx.ui.select("Plan History", ["Save Plans", "Save Plan History", "Plan History Limit", "Back"]);
|
|
@@ -15074,11 +15244,11 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
15074
15244
|
if (!setting || setting === "Back") continue;
|
|
15075
15245
|
if (setting === "Plan History Limit") {
|
|
15076
15246
|
const count = parsePositiveInt((await ctx.ui.input("Plan history limit", String(workflow.planHistoryLimit ?? 50))) ?? "");
|
|
15077
|
-
if (count !== undefined && count > 0) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.workflow.planHistoryLimit = count; }); ctx
|
|
15247
|
+
if (count !== undefined && count > 0) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.workflow.planHistoryLimit = count; }); workflowUiNotify(ctx, `workflow.planHistoryLimit set to ${count} in ${r.file}`, "info"); }
|
|
15078
15248
|
} else {
|
|
15079
15249
|
const key = setting === "Save Plans" ? "savePlans" : "savePlanHistory";
|
|
15080
15250
|
const enabled = await chooseBool(ctx, `${key}?`);
|
|
15081
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.workflow as typeof s.workflow & Record<string, boolean>)[key] = enabled; }); ctx
|
|
15251
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.workflow as typeof s.workflow & Record<string, boolean>)[key] = enabled; }); workflowUiNotify(ctx, `workflow.${key} set to ${enabled} in ${r.file}`, "info"); }
|
|
15082
15252
|
}
|
|
15083
15253
|
} else if (choice === "List Current Settings") {
|
|
15084
15254
|
const s = loadWorkflowSettings(ctx.cwd);
|
|
@@ -15094,11 +15264,11 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
15094
15264
|
if (!setting || setting === "Back") return;
|
|
15095
15265
|
if (setting === "To Do Trigger Mode") {
|
|
15096
15266
|
const mode = parseStandardTodoTriggerMode((await ctx.ui.select("To Do Trigger Mode", ["Disabled", "On request", "Automatic when useful", "Required"])) ?? "");
|
|
15097
|
-
if (mode) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.standard.todoTriggerMode = mode; s.standard.autoTodoEnabled = mode !== "off"; }); ctx
|
|
15267
|
+
if (mode) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.standard.todoTriggerMode = mode; s.standard.autoTodoEnabled = mode !== "off"; }); workflowUiNotify(ctx, `To Do Trigger Mode set to ${standardTodoTriggerModeLabel(mode)} in ${r.file}`, "info"); }
|
|
15098
15268
|
} else {
|
|
15099
15269
|
const key = setting === "Automatic To Do Enabled" ? "autoTodoEnabled" : "todoProgressVisible";
|
|
15100
15270
|
const enabled = await chooseBool(ctx, `standard.${key}?`);
|
|
15101
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.standard as typeof s.standard & Record<string, boolean>)[key] = enabled; }); ctx
|
|
15271
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.standard as typeof s.standard & Record<string, boolean>)[key] = enabled; }); workflowUiNotify(ctx, `standard.${key} set to ${enabled} in ${r.file}`, "info"); }
|
|
15102
15272
|
}
|
|
15103
15273
|
}
|
|
15104
15274
|
}
|
|
@@ -15110,20 +15280,20 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
15110
15280
|
if (!setting || setting === "Back") return;
|
|
15111
15281
|
if (setting === "Clarification Mode") {
|
|
15112
15282
|
const mode = parseStandardClarificationMode((await ctx.ui.select("Standard clarification mode", ["auto", "always_for_nontrivial", "never"])) ?? "");
|
|
15113
|
-
if (mode) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.standard.clarificationMode = mode; s.standard.clarificationEnabled = mode !== "never"; }); ctx
|
|
15283
|
+
if (mode) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.standard.clarificationMode = mode; s.standard.clarificationEnabled = mode !== "never"; }); workflowUiNotify(ctx, `standard.clarificationMode set to ${mode} in ${r.file}`, "info"); }
|
|
15114
15284
|
} else if (setting === "Interactive Clarification") {
|
|
15115
15285
|
const enabled = await chooseBool(ctx, "Standard interactive clarification enabled?");
|
|
15116
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.standard.interactiveClarificationEnabled = enabled; }); ctx
|
|
15286
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.standard.interactiveClarificationEnabled = enabled; }); workflowUiNotify(ctx, `standard.interactiveClarificationEnabled set to ${enabled} in ${r.file}`, "info"); }
|
|
15117
15287
|
} else if (setting === "Max Clarification Questions") {
|
|
15118
15288
|
const count = parsePositiveInt((await ctx.ui.select("Max Standard clarification questions", ["0", "1", "2"])) ?? "");
|
|
15119
|
-
if (count !== undefined && count >= 0) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.standard.maxClarificationQuestions = count; }); ctx
|
|
15289
|
+
if (count !== undefined && count >= 0) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.standard.maxClarificationQuestions = count; }); workflowUiNotify(ctx, `standard.maxClarificationQuestions set to ${count} in ${r.file}`, "info"); }
|
|
15120
15290
|
} else if (setting === "Timing") {
|
|
15121
15291
|
const timing = parseClarificationTiming((await ctx.ui.select("Standard clarification timing", ["after_initial_analysis", "immediate"])) ?? "");
|
|
15122
|
-
if (timing) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.standard.clarificationTiming = timing; }); ctx
|
|
15292
|
+
if (timing) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.standard.clarificationTiming = timing; }); workflowUiNotify(ctx, `standard.clarificationTiming set to ${timing} in ${r.file}`, "info"); }
|
|
15123
15293
|
} else {
|
|
15124
15294
|
const key = setting === "Quality Gate" ? "clarificationQualityGate" : setting === "Allow Without Analysis" ? "allowClarificationWithoutAnalysis" : "useSubagentsBeforeClarification";
|
|
15125
15295
|
const enabled = await chooseBool(ctx, `standard.${key}?`);
|
|
15126
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.standard as typeof s.standard & Record<string, boolean | string | number | undefined>)[key] = enabled; }); ctx
|
|
15296
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.standard as typeof s.standard & Record<string, boolean | string | number | undefined>)[key] = enabled; }); workflowUiNotify(ctx, `standard.${key} set to ${enabled} in ${r.file}`, "info"); }
|
|
15127
15297
|
}
|
|
15128
15298
|
}
|
|
15129
15299
|
}
|
|
@@ -15143,15 +15313,15 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
15143
15313
|
const choice = await ctx.ui.select("Standard Token Budget", ["Default (unlimited)", "Custom..."]);
|
|
15144
15314
|
if (choice === "Default (unlimited)") {
|
|
15145
15315
|
const r = updateSettings(ctx.cwd, undefined, (s) => { s.standard.maxTokens = 0; });
|
|
15146
|
-
ctx
|
|
15316
|
+
workflowUiNotify(ctx, `standard.maxTokens set to default (unlimited) in ${r.file}`, "info");
|
|
15147
15317
|
} else if (choice === "Custom...") {
|
|
15148
15318
|
const count = parsePositiveInt((await ctx.ui.input("Enter custom standard token budget", String(current > 0 ? current : ""))) ?? "");
|
|
15149
|
-
if (count !== undefined && count >= 0) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.standard.maxTokens = count; }); ctx
|
|
15319
|
+
if (count !== undefined && count >= 0) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.standard.maxTokens = count; }); workflowUiNotify(ctx, `standard.maxTokens set to ${count === 0 ? "unlimited" : count.toLocaleString()} in ${r.file}`, "info"); }
|
|
15150
15320
|
}
|
|
15151
15321
|
} else {
|
|
15152
15322
|
const key = setting === "Status Widget Visible" ? "statusWidgetVisible" : "todoProgressVisible";
|
|
15153
15323
|
const enabled = await chooseBool(ctx, `standard.${key}?`);
|
|
15154
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.standard as typeof s.standard & Record<string, boolean>)[key] = enabled; }); ctx
|
|
15324
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.standard as typeof s.standard & Record<string, boolean>)[key] = enabled; }); workflowUiNotify(ctx, `standard.${key} set to ${enabled} in ${r.file}`, "info"); }
|
|
15155
15325
|
}
|
|
15156
15326
|
}
|
|
15157
15327
|
}
|
|
@@ -15168,7 +15338,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
15168
15338
|
}
|
|
15169
15339
|
if (choice === "Enable / Disable Standard Mode") {
|
|
15170
15340
|
const enabled = await chooseBool(ctx, "standard.enabled?");
|
|
15171
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.standard.enabled = enabled; }); ctx
|
|
15341
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.standard.enabled = enabled; }); workflowUiNotify(ctx, `standard.enabled set to ${enabled} in ${r.file}`, "info"); }
|
|
15172
15342
|
} else if (choice === "Standard To Do" || choice === "To Do Behavior") {
|
|
15173
15343
|
await showStandardTodoSettingsMenu(ctx);
|
|
15174
15344
|
} else if (choice === "Standard Clarification" || choice === "Clarification") {
|
|
@@ -15197,7 +15367,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
15197
15367
|
if (!source) continue;
|
|
15198
15368
|
const enabled = source === "Mission-Specific Models";
|
|
15199
15369
|
const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.useMissionSpecificModels = enabled; });
|
|
15200
|
-
ctx
|
|
15370
|
+
workflowUiNotify(ctx, `missions.useMissionSpecificModels set to ${enabled} in ${r.file}`, "info");
|
|
15201
15371
|
} else if (choice === "Configure Mission Planner") await configureMissionRoleModel(ctx, "planner");
|
|
15202
15372
|
else if (choice === "Configure Mission Executor") await configureMissionRoleModel(ctx, "executor");
|
|
15203
15373
|
else if (choice === "Configure Mission Reviewer") await configureMissionRoleModel(ctx, "reviewer");
|
|
@@ -15218,13 +15388,13 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
15218
15388
|
show(pi, renderHeartbeatWatchdogStatus(loadWorkflowSettings(ctx.cwd), activeMission ?? loadMissionState()));
|
|
15219
15389
|
} else if (choice === "Enable / Disable Heartbeat") {
|
|
15220
15390
|
const enabled = await chooseBool(ctx, "missions.heartbeatEnabled?");
|
|
15221
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.heartbeatEnabled = enabled; }); ctx
|
|
15391
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.heartbeatEnabled = enabled; }); workflowUiNotify(ctx, `missions.heartbeatEnabled set to ${enabled} in ${r.file}`, "info"); }
|
|
15222
15392
|
} else if (choice === "Enable / Disable Watchdog") {
|
|
15223
15393
|
const enabled = await chooseBool(ctx, "missions.watchdogEnabled? (warning only; no auto-recovery)");
|
|
15224
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.watchdogEnabled = enabled; }); ctx
|
|
15394
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.watchdogEnabled = enabled; }); workflowUiNotify(ctx, `missions.watchdogEnabled set to ${enabled} in ${r.file}`, "info"); }
|
|
15225
15395
|
} else if (choice === "Set Watchdog Stale Minutes") {
|
|
15226
15396
|
const count = parsePositiveInt((await ctx.ui.input("watchdogStaleMinutes", String(loadWorkflowSettings(ctx.cwd).missions.watchdogStaleMinutes ?? 30))) ?? "");
|
|
15227
|
-
if (count !== undefined && count > 0) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.watchdogStaleMinutes = count; }); ctx
|
|
15397
|
+
if (count !== undefined && count > 0) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.watchdogStaleMinutes = count; }); workflowUiNotify(ctx, `missions.watchdogStaleMinutes set to ${count} in ${r.file}`, "info"); }
|
|
15228
15398
|
}
|
|
15229
15399
|
}
|
|
15230
15400
|
}
|
|
@@ -15237,11 +15407,11 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
15237
15407
|
const enabled = await chooseBool(ctx, `${setting}?`);
|
|
15238
15408
|
if (enabled === undefined) continue;
|
|
15239
15409
|
if (setting === "Mission Reviewer Enabled") {
|
|
15240
|
-
if (loadWorkflowSettings(ctx.cwd).missions.useMissionSpecificModels) { const r = updateSettings(ctx.cwd, undefined, (s) => { setMissionRoleEnabled(s, "reviewer", enabled); }); ctx
|
|
15241
|
-
else { const r = setRoleEnabled("reviewer", enabled, ctx.cwd); ctx
|
|
15410
|
+
if (loadWorkflowSettings(ctx.cwd).missions.useMissionSpecificModels) { const r = updateSettings(ctx.cwd, undefined, (s) => { setMissionRoleEnabled(s, "reviewer", enabled); }); workflowUiNotify(ctx, `missions.models.reviewer.enabled set to ${enabled} in ${r.file}`, "info"); }
|
|
15411
|
+
else { const r = setRoleEnabled("reviewer", enabled, ctx.cwd); workflowUiNotify(ctx, `reviewer.enabled set to ${enabled} in ${r.file}`, "info"); }
|
|
15242
15412
|
} else if (setting === "Mission Validator Enabled") {
|
|
15243
|
-
if (loadWorkflowSettings(ctx.cwd).missions.useMissionSpecificModels) { const r = updateSettings(ctx.cwd, undefined, (s) => { setMissionRoleEnabled(s, "validator", enabled); }); ctx
|
|
15244
|
-
else { const r = setRoleEnabled("validator", enabled, ctx.cwd); ctx
|
|
15413
|
+
if (loadWorkflowSettings(ctx.cwd).missions.useMissionSpecificModels) { const r = updateSettings(ctx.cwd, undefined, (s) => { setMissionRoleEnabled(s, "validator", enabled); }); workflowUiNotify(ctx, `missions.models.validator.enabled set to ${enabled} in ${r.file}`, "info"); }
|
|
15414
|
+
else { const r = setRoleEnabled("validator", enabled, ctx.cwd); workflowUiNotify(ctx, `validator.enabled set to ${enabled} in ${r.file}`, "info"); }
|
|
15245
15415
|
} else {
|
|
15246
15416
|
const keyMap: Record<string, string> = {
|
|
15247
15417
|
"Offer Reviewer Before Approval": "offerReviewerBeforeApprove",
|
|
@@ -15259,7 +15429,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
15259
15429
|
s.missions.reviewRetryMode = "safe_only";
|
|
15260
15430
|
}
|
|
15261
15431
|
});
|
|
15262
|
-
ctx
|
|
15432
|
+
workflowUiNotify(ctx, `missions.${key} set to ${enabled} in ${r.file}`, "info");
|
|
15263
15433
|
}
|
|
15264
15434
|
}
|
|
15265
15435
|
}
|
|
@@ -15272,18 +15442,18 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
15272
15442
|
if (setting === "Max Review Retries Per Mission") {
|
|
15273
15443
|
const raw = await ctx.ui.select(setting, ["0", "1", "2", "3", "4", "5", "10"]);
|
|
15274
15444
|
const count = raw === undefined ? undefined : Number(raw);
|
|
15275
|
-
if (Number.isInteger(count) && count >= 0 && count <= 10) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.maxReviewRetriesPerMission = count; }); ctx
|
|
15445
|
+
if (Number.isInteger(count) && count >= 0 && count <= 10) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.maxReviewRetriesPerMission = count; }); workflowUiNotify(ctx, `missions.maxReviewRetriesPerMission set to ${count} in ${r.file}`, "info"); }
|
|
15276
15446
|
} else if (setting === "Max Retries Per Milestone" || setting === "Max Retries Per Mission" || setting === "Max Final Validation Retries") {
|
|
15277
15447
|
const key = setting === "Max Retries Per Milestone" ? "maxValidationRetriesPerMilestone" : setting === "Max Retries Per Mission" ? "maxValidationRetriesPerMission" : "maxFinalValidationRetries";
|
|
15278
15448
|
const max = key === "maxValidationRetriesPerMission" ? 100 : 10;
|
|
15279
15449
|
const options = key === "maxValidationRetriesPerMission" ? ["0", "1", "2", "4", "8", "12", "20", "50", "100"] : ["0", "1", "2", "3", "4", "5", "10"];
|
|
15280
15450
|
const raw = await ctx.ui.select(setting, options);
|
|
15281
15451
|
const count = raw === undefined ? undefined : Number(raw);
|
|
15282
|
-
if (Number.isInteger(count) && count >= 0 && count <= max) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.missions as typeof s.missions & Record<string, number>)[key] = count; }); ctx
|
|
15452
|
+
if (Number.isInteger(count) && count >= 0 && count <= max) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.missions as typeof s.missions & Record<string, number>)[key] = count; }); workflowUiNotify(ctx, `missions.${key} set to ${count} in ${r.file}`, "info"); }
|
|
15283
15453
|
} else if (setting === "Validation Retry Mode" || setting === "Review Retry Mode") {
|
|
15284
15454
|
const key = setting === "Validation Retry Mode" ? "validationRetryMode" : "reviewRetryMode";
|
|
15285
15455
|
const mode = parseValidationRetryMode((await ctx.ui.select(`${key}`, ["off", "safe_only", "aggressive_within_scope"])) ?? "");
|
|
15286
|
-
if (mode) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.missions as typeof s.missions & Record<string, string | undefined>)[key] = mode; }); ctx
|
|
15456
|
+
if (mode) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.missions as typeof s.missions & Record<string, string | undefined>)[key] = mode; }); workflowUiNotify(ctx, `missions.${key} set to ${mode} in ${r.file}`, "info"); }
|
|
15287
15457
|
} else {
|
|
15288
15458
|
const keyMap: Record<string, string> = {
|
|
15289
15459
|
"Auto Repair Review Failures": "autoRepairReviewFailures",
|
|
@@ -15296,7 +15466,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
15296
15466
|
};
|
|
15297
15467
|
const key = keyMap[setting];
|
|
15298
15468
|
const enabled = await chooseBool(ctx, `${String(key)}?`);
|
|
15299
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.missions as Record<string, unknown>)[String(key)] = enabled; if (key === "autoRepairReviewFailures" && enabled && s.missions.reviewRetryMode === "off") { s.missions.reviewRetryMode = "safe_only"; } }); ctx
|
|
15469
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.missions as Record<string, unknown>)[String(key)] = enabled; if (key === "autoRepairReviewFailures" && enabled && s.missions.reviewRetryMode === "off") { s.missions.reviewRetryMode = "safe_only"; } }); workflowUiNotify(ctx, `missions.${String(key)} set to ${enabled} in ${r.file}`, "info"); }
|
|
15300
15470
|
}
|
|
15301
15471
|
}
|
|
15302
15472
|
}
|
|
@@ -15309,12 +15479,12 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
15309
15479
|
if (setting === "Max Final Validation Retries") {
|
|
15310
15480
|
const raw = await ctx.ui.select(setting, ["0", "1", "2", "3", "4", "5", "10"]);
|
|
15311
15481
|
const count = raw === undefined ? undefined : Number(raw);
|
|
15312
|
-
if (Number.isInteger(count) && count >= 0 && count <= 10) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.maxFinalValidationRetries = count; }); ctx
|
|
15482
|
+
if (Number.isInteger(count) && count >= 0 && count <= 10) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.maxFinalValidationRetries = count; }); workflowUiNotify(ctx, `missions.maxFinalValidationRetries set to ${count} in ${r.file}`, "info"); }
|
|
15313
15483
|
} else {
|
|
15314
15484
|
const keyMap: Record<string, string> = { "Final Comprehensive Validation": "finalValidationEnabled", "Final Validation Requires Pass": "finalValidationRequiresPass", "Auto Repair Final Validation Failures": "autoRepairFinalValidationFailures" };
|
|
15315
15485
|
const key = keyMap[setting];
|
|
15316
15486
|
const enabled = await chooseBool(ctx, `${String(key)}?`);
|
|
15317
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.missions as Record<string, unknown>)[String(key)] = enabled; }); ctx
|
|
15487
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.missions as Record<string, unknown>)[String(key)] = enabled; }); workflowUiNotify(ctx, `missions.${String(key)} set to ${enabled} in ${r.file}`, "info"); }
|
|
15318
15488
|
}
|
|
15319
15489
|
}
|
|
15320
15490
|
}
|
|
@@ -15329,12 +15499,12 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
15329
15499
|
const count = parsePositiveInt((await ctx.ui.input("Mission history limit", String(current))) ?? "");
|
|
15330
15500
|
if (count !== undefined && count >= 1 && count <= 500) {
|
|
15331
15501
|
const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.missionHistoryLimit = count; });
|
|
15332
|
-
ctx
|
|
15502
|
+
workflowUiNotify(ctx, `missions.missionHistoryLimit set to ${count} in ${r.file}`, "info");
|
|
15333
15503
|
}
|
|
15334
15504
|
} else if (setting === "Cleanup Saved Missions") {
|
|
15335
15505
|
const settings = loadWorkflowSettings(ctx.cwd);
|
|
15336
15506
|
const removed = clearOldMissionStates(settings.missions.missionHistoryLimit ?? 50);
|
|
15337
|
-
ctx
|
|
15507
|
+
workflowUiNotify(ctx, `Removed ${removed} old mission file${removed === 1 ? "" : "s"}.`, "info");
|
|
15338
15508
|
} else if (setting === "List Current Settings") {
|
|
15339
15509
|
const settings = loadWorkflowSettings(ctx.cwd);
|
|
15340
15510
|
show(pi, `# Mission History\n\nMission History Limit: ${settings.missions.missionHistoryLimit ?? 50}\nMissions Directory: ${MISSION_HISTORY_DIR}`);
|
|
@@ -15351,48 +15521,48 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
15351
15521
|
await showMissionModelBehaviorMenu(ctx);
|
|
15352
15522
|
} else if (choice === "Enable / Disable Mission Mode") {
|
|
15353
15523
|
const enabled = await chooseBool(ctx, "Missions enabled?");
|
|
15354
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.enabled = enabled; }); ctx
|
|
15524
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.enabled = enabled; }); workflowUiNotify(ctx, `missions.enabled set to ${enabled} in ${r.file}`, "info"); }
|
|
15355
15525
|
} else if (choice === "Mission Autonomy") {
|
|
15356
15526
|
const setting = await ctx.ui.select("Mission Autonomy", ["Default Autonomy", "Allow Full Auto", "Auto Run After Approval", "Continue Across Milestones", "Pause Between Milestones", "Auto Resume", "Back"]);
|
|
15357
15527
|
if (!setting || setting === "Back") continue;
|
|
15358
15528
|
if (setting === "Default Autonomy") {
|
|
15359
15529
|
const autonomy = parseMissionAutonomy((await ctx.ui.select("Mission default autonomy", ["manual", "approval_gated", "supervised_auto", "full_auto"])) ?? "");
|
|
15360
|
-
if (autonomy) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.defaultAutonomy = autonomy; }); ctx
|
|
15530
|
+
if (autonomy) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.defaultAutonomy = autonomy; }); workflowUiNotify(ctx, `missions.defaultAutonomy set to ${autonomy} in ${r.file}${autonomy === "full_auto" && !r.settings.missions.allowFullAuto ? "; full_auto will be blocked until allowFullAuto=true" : ""}`, "info"); }
|
|
15361
15531
|
} else {
|
|
15362
15532
|
const keyMap: Record<string, keyof ReturnType<typeof loadWorkflowSettings>["missions"]> = { "Allow Full Auto": "allowFullAuto", "Auto Run After Approval": "autoRunAfterApproval", "Continue Across Milestones": "continueAcrossMilestones", "Pause Between Milestones": "pauseBetweenMilestones", "Auto Resume": "autoResume" };
|
|
15363
15533
|
const key = keyMap[setting];
|
|
15364
15534
|
const enabled = await chooseBool(ctx, `${String(key)}?`);
|
|
15365
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.missions as Record<string, unknown>)[String(key)] = enabled; }); ctx
|
|
15535
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.missions as Record<string, unknown>)[String(key)] = enabled; }); workflowUiNotify(ctx, `missions.${String(key)} set to ${enabled} in ${r.file}${key === "allowFullAuto" && enabled === false && r.settings.missions.defaultAutonomy === "full_auto" ? "; full_auto default is retained but blocked" : ""}`, "info"); }
|
|
15366
15536
|
}
|
|
15367
15537
|
} else if (choice === "Default Autonomy") {
|
|
15368
15538
|
const autonomy = parseMissionAutonomy((await ctx.ui.select("Mission default autonomy", ["manual", "approval_gated", "supervised_auto", "full_auto"])) ?? "");
|
|
15369
|
-
if (autonomy) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.defaultAutonomy = autonomy; }); ctx
|
|
15539
|
+
if (autonomy) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.defaultAutonomy = autonomy; }); workflowUiNotify(ctx, `missions.defaultAutonomy set to ${autonomy} in ${r.file}${autonomy === "full_auto" && !r.settings.missions.allowFullAuto ? "; full_auto will be blocked until allowFullAuto=true" : ""}`, "info"); }
|
|
15370
15540
|
} else if (choice === "Mission Clarification") {
|
|
15371
15541
|
const setting = await ctx.ui.select("Mission Clarification", ["Clarification Mode", "Interactive Clarification", "Max Clarification Questions", "Timing", "Quality Gate", "Allow Without Analysis", "Use Sub-agents Before Clarification", "Back"]);
|
|
15372
15542
|
if (!setting || setting === "Back") continue;
|
|
15373
15543
|
if (setting === "Clarification Mode") {
|
|
15374
15544
|
const mode = parseClarificationMode((await ctx.ui.select("Mission clarification mode", ["auto", "always_for_nontrivial", "never"])) ?? "");
|
|
15375
|
-
if (mode) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.clarificationMode = mode; }); ctx
|
|
15545
|
+
if (mode) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.clarificationMode = mode; }); workflowUiNotify(ctx, `missions.clarificationMode set to ${mode} in ${r.file}`, "info"); }
|
|
15376
15546
|
} else if (setting === "Interactive Clarification") {
|
|
15377
15547
|
const enabled = await chooseBool(ctx, "Mission interactive clarification enabled?");
|
|
15378
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.interactiveClarificationEnabled = enabled; }); ctx
|
|
15548
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.interactiveClarificationEnabled = enabled; }); workflowUiNotify(ctx, `missions.interactiveClarificationEnabled set to ${enabled} in ${r.file}`, "info"); }
|
|
15379
15549
|
} else if (setting === "Max Clarification Questions") {
|
|
15380
15550
|
const count = parsePositiveInt((await ctx.ui.select("Mission max clarification questions", ["1", "2", "3", "4", "5", "6"])) ?? "");
|
|
15381
|
-
if (count) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.maxClarificationQuestions = count; }); ctx
|
|
15551
|
+
if (count) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.maxClarificationQuestions = count; }); workflowUiNotify(ctx, `missions.maxClarificationQuestions set to ${count} in ${r.file}`, "info"); }
|
|
15382
15552
|
} else if (setting === "Timing") {
|
|
15383
15553
|
const timing = parseClarificationTiming((await ctx.ui.select("Mission clarification timing", ["after_initial_analysis", "immediate"])) ?? "");
|
|
15384
|
-
if (timing) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.clarificationTiming = timing; }); ctx
|
|
15554
|
+
if (timing) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.clarificationTiming = timing; }); workflowUiNotify(ctx, `missions.clarificationTiming set to ${timing} in ${r.file}`, "info"); }
|
|
15385
15555
|
} else {
|
|
15386
15556
|
const key = setting === "Quality Gate" ? "clarificationQualityGate" : setting === "Allow Without Analysis" ? "allowClarificationWithoutAnalysis" : "useSubagentsBeforeClarification";
|
|
15387
15557
|
const enabled = await chooseBool(ctx, `missions.${key}?`);
|
|
15388
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.missions as typeof s.missions & Record<string, boolean | string | number | undefined>)[key] = enabled; }); ctx
|
|
15558
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.missions as typeof s.missions & Record<string, boolean | string | number | undefined>)[key] = enabled; }); workflowUiNotify(ctx, `missions.${key} set to ${enabled} in ${r.file}`, "info"); }
|
|
15389
15559
|
}
|
|
15390
15560
|
} else if (choice === "Mission Planning Depth") {
|
|
15391
15561
|
const depth = parsePlanningDepth((await ctx.ui.select("Mission planning depth", ["fast", "standard", "deep", "maximum"])) ?? "");
|
|
15392
|
-
if (depth) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.planningDepth = depth; }); ctx
|
|
15562
|
+
if (depth) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.planningDepth = depth; }); workflowUiNotify(ctx, `missions.planningDepth set to ${depth} in ${r.file}`, "info"); }
|
|
15393
15563
|
} else if (choice === "Mission Sub-Agent Policy") {
|
|
15394
15564
|
const policy = parseSubagentPolicy((await ctx.ui.select("Mission sub-agent policy", ["off", "auto", "deep", "maximum", "forced"])) ?? "");
|
|
15395
|
-
if (policy) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.subagentPolicy = policy; }); ctx
|
|
15565
|
+
if (policy) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.subagentPolicy = policy; }); workflowUiNotify(ctx, `missions.subagentPolicy set to ${policy} in ${r.file}`, "info"); }
|
|
15396
15566
|
} else if (choice === "Mission Sub-agents / Workers" || choice === "Mission Worker Targets") {
|
|
15397
15567
|
await showMissionSubagentWorkerSettingsMenu(ctx);
|
|
15398
15568
|
} else if (choice === "Mission History") {
|
|
@@ -15408,50 +15578,50 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
15408
15578
|
if (setting === "Progress Widget" || setting === "Progress Bar Display") {
|
|
15409
15579
|
const key = setting === "Progress Widget" ? "progressWidgetEnabled" : "showProgressBar";
|
|
15410
15580
|
const enabled = await chooseBool(ctx, `missions.${key}?`);
|
|
15411
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.missions as typeof s.missions & Record<string, boolean>)[key] = enabled; }); ctx
|
|
15581
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.missions as typeof s.missions & Record<string, boolean>)[key] = enabled; }); workflowUiNotify(ctx, `missions.${key} set to ${enabled} in ${r.file}`, "info"); }
|
|
15412
15582
|
} else if (setting === "Heartbeat / Watchdog") await showHeartbeatWatchdogMenu(ctx);
|
|
15413
15583
|
else if (setting === "Token Budget") {
|
|
15414
15584
|
const current = loadWorkflowSettings(ctx.cwd).missions.maxTokens ?? 0;
|
|
15415
15585
|
const choice = await ctx.ui.select("Mission Token Budget", ["Default (unlimited)", "Custom..."]);
|
|
15416
15586
|
if (choice === "Default (unlimited)") {
|
|
15417
15587
|
const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.maxTokens = 0; });
|
|
15418
|
-
ctx
|
|
15588
|
+
workflowUiNotify(ctx, `missions.maxTokens set to default (unlimited) in ${r.file}`, "info");
|
|
15419
15589
|
} else if (choice === "Custom...") {
|
|
15420
15590
|
const count = parsePositiveInt((await ctx.ui.input("Enter custom mission token budget", String(current > 0 ? current : ""))) ?? "");
|
|
15421
|
-
if (count !== undefined && count >= 0) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.maxTokens = count; }); ctx
|
|
15591
|
+
if (count !== undefined && count >= 0) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.maxTokens = count; }); workflowUiNotify(ctx, `missions.maxTokens set to ${count === 0 ? "unlimited" : count.toLocaleString()} in ${r.file}`, "info"); }
|
|
15422
15592
|
}
|
|
15423
15593
|
} else if (setting === "Runtime Budget") {
|
|
15424
15594
|
const current = loadWorkflowSettings(ctx.cwd).missions.maxRuntimeHours;
|
|
15425
15595
|
const choice = await ctx.ui.select("Mission Runtime Budget", ["Default (13 hours)", "Custom..."]);
|
|
15426
15596
|
if (choice === "Default (13 hours)") {
|
|
15427
15597
|
const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.maxRuntimeHours = 13; });
|
|
15428
|
-
ctx
|
|
15598
|
+
workflowUiNotify(ctx, `missions.maxRuntimeHours set to default (13 hours) in ${r.file}`, "info");
|
|
15429
15599
|
} else if (choice === "Custom...") {
|
|
15430
15600
|
const count = parsePositiveInt((await ctx.ui.input("Enter custom runtime budget (hours)", String(current !== 13 ? current : ""))) ?? "");
|
|
15431
|
-
if (count !== undefined && count > 0) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.maxRuntimeHours = count; }); ctx
|
|
15601
|
+
if (count !== undefined && count > 0) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.maxRuntimeHours = count; }); workflowUiNotify(ctx, `missions.maxRuntimeHours set to ${count} hours in ${r.file}`, "info"); }
|
|
15432
15602
|
}
|
|
15433
15603
|
} else {
|
|
15434
15604
|
const count = parsePositiveInt((await ctx.ui.input("checkpointIntervalMinutes", "30")) ?? "");
|
|
15435
|
-
if (count !== undefined && count > 0) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.checkpointIntervalMinutes = count; }); ctx
|
|
15605
|
+
if (count !== undefined && count > 0) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.checkpointIntervalMinutes = count; }); workflowUiNotify(ctx, `missions.checkpointIntervalMinutes set to ${count} in ${r.file}`, "info"); }
|
|
15436
15606
|
}
|
|
15437
15607
|
} else if (choice === "Runtime Budget") {
|
|
15438
15608
|
const current = loadWorkflowSettings(ctx.cwd).missions.maxRuntimeHours;
|
|
15439
15609
|
const choice2 = await ctx.ui.select("Mission Runtime Budget", ["Default (13 hours)", "Custom..."]);
|
|
15440
15610
|
if (choice2 === "Default (13 hours)") {
|
|
15441
15611
|
const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.maxRuntimeHours = 13; });
|
|
15442
|
-
ctx
|
|
15612
|
+
workflowUiNotify(ctx, `missions.maxRuntimeHours set to default (13 hours) in ${r.file}`, "info");
|
|
15443
15613
|
} else if (choice2 === "Custom...") {
|
|
15444
15614
|
const count = parsePositiveInt((await ctx.ui.input("Enter custom runtime budget (hours)", String(current !== 13 ? current : ""))) ?? "");
|
|
15445
|
-
if (count !== undefined && count > 0) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.maxRuntimeHours = count; }); ctx
|
|
15615
|
+
if (count !== undefined && count > 0) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.maxRuntimeHours = count; }); workflowUiNotify(ctx, `missions.maxRuntimeHours set to ${count} hours in ${r.file}`, "info"); }
|
|
15446
15616
|
}
|
|
15447
15617
|
} else if (choice === "Checkpoint Interval") {
|
|
15448
15618
|
const count = parsePositiveInt((await ctx.ui.input("checkpointIntervalMinutes", "30")) ?? "");
|
|
15449
|
-
if (count !== undefined && count > 0) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.checkpointIntervalMinutes = count; }); ctx
|
|
15619
|
+
if (count !== undefined && count > 0) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.missions.checkpointIntervalMinutes = count; }); workflowUiNotify(ctx, `missions.checkpointIntervalMinutes set to ${count} in ${r.file}`, "info"); }
|
|
15450
15620
|
} else if (choice === "Approval Safety" || choice === "Validation Per Milestone" || choice === "Full Auto Safety" || choice === "Auto Resume") {
|
|
15451
15621
|
const keyMap: Record<string, keyof ReturnType<typeof loadWorkflowSettings>["missions"]> = { "Validation Per Milestone": "requireValidationPerMilestone", "Approval Safety": "requireApprovalForDestructiveActions", "Full Auto Safety": "allowFullAuto", "Auto Resume": "autoResume" };
|
|
15452
15622
|
const key = keyMap[choice];
|
|
15453
15623
|
const enabled = await chooseBool(ctx, `${String(key)}?`);
|
|
15454
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.missions as Record<string, unknown>)[String(key)] = enabled; }); ctx
|
|
15624
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { (s.missions as Record<string, unknown>)[String(key)] = enabled; }); workflowUiNotify(ctx, `missions.${String(key)} set to ${enabled} in ${r.file}${key === "allowFullAuto" && enabled === false && r.settings.missions.defaultAutonomy === "full_auto" ? "; full_auto default is retained but blocked" : ""}`, "info"); }
|
|
15455
15625
|
} else if (choice === "Review / Validation Behavior") {
|
|
15456
15626
|
await showMissionReviewValidationBehaviorMenu(ctx);
|
|
15457
15627
|
} else if (choice === "Repair / Validation Retry" || choice === "Mission Repair / Validation" || choice === "Repair / Validation Retry Settings") {
|
|
@@ -15484,18 +15654,18 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
15484
15654
|
const enabled = await chooseBool(ctx, "safety.repoLockEnabled for this project only?");
|
|
15485
15655
|
if (enabled !== undefined) {
|
|
15486
15656
|
const r = updateSettings(ctx.cwd, "project", (s) => { s.safety.repoLockEnabled = enabled; });
|
|
15487
|
-
ctx
|
|
15657
|
+
workflowUiNotify(ctx, `Project Repo Lock set to ${enabled} in ${r.file}. This project override wins over global settings and does not apply to other repos.`, "info");
|
|
15488
15658
|
}
|
|
15489
15659
|
} else {
|
|
15490
15660
|
const key = keyMap[choice];
|
|
15491
15661
|
const enabled = await chooseBool(ctx, `${String(key)}?`);
|
|
15492
|
-
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.safety[key] = enabled; }); ctx
|
|
15662
|
+
if (enabled !== undefined) { const r = updateSettings(ctx.cwd, undefined, (s) => { s.safety[key] = enabled; }); workflowUiNotify(ctx, `safety.${String(key)} set to ${enabled} in ${r.file}`, "info"); }
|
|
15493
15663
|
}
|
|
15494
15664
|
}
|
|
15495
15665
|
}
|
|
15496
15666
|
|
|
15497
|
-
async function
|
|
15498
|
-
if (!ctx.hasUI) return show(pi,
|
|
15667
|
+
async function showEditorHintsSettingsMenu(ctx: ExtensionContext) {
|
|
15668
|
+
if (!ctx.hasUI) return show(pi, renderEditorHintsSettings(ctx));
|
|
15499
15669
|
const options = [
|
|
15500
15670
|
{ label: "Idle Entry Hint", key: "showIdleWorkflowEntryHint" as const },
|
|
15501
15671
|
{ label: "Active Switch Hint", key: "showActiveWorkflowSwitchHint" as const },
|
|
@@ -15506,17 +15676,31 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
15506
15676
|
const settings = loadWorkflowSettings(ctx.cwd);
|
|
15507
15677
|
const ui = workflowWidgetUi(settings);
|
|
15508
15678
|
const labels = options.map((option) => `${option.label}: ${ui[option.key] !== false ? "visible" : "hidden"}`);
|
|
15509
|
-
const
|
|
15679
|
+
const contrastLabel = `Hint Contrast: ${workflowEditorHintContrastLabel(workflowEditorHintContrast(settings))}`;
|
|
15680
|
+
const choice = await ctx.ui.select("Editor Hints", [...labels, contrastLabel, "List Current Settings", "Back"]);
|
|
15510
15681
|
if (!choice || choice === "Back") return;
|
|
15511
|
-
if (choice === "List Current Settings") { show(pi,
|
|
15682
|
+
if (choice === "List Current Settings") { show(pi, renderEditorHintsSettings(ctx)); continue; }
|
|
15683
|
+
if (choice === contrastLabel) {
|
|
15684
|
+
const current = workflowEditorHintContrast(settings);
|
|
15685
|
+
const contrastChoice = await ctx.ui.select("Editor Hint Contrast", WORKFLOW_EDITOR_HINT_CONTRASTS.map((contrast) => `${workflowEditorHintContrastLabel(contrast)}${contrast === current ? " (current)" : ""}`).concat("Back"));
|
|
15686
|
+
if (!contrastChoice || contrastChoice === "Back") continue;
|
|
15687
|
+
const contrast = parseEditorHintContrast(contrastChoice.replace(/\s+\(current\)$/, ""));
|
|
15688
|
+
if (contrast) {
|
|
15689
|
+
updateSettings(ctx.cwd, "global", (s) => { workflowWidgetUi(s).editorHintContrast = contrast; });
|
|
15690
|
+
setWorkflowUi(ctx, state, activeSubagents);
|
|
15691
|
+
workflowEditorHintText = workflowEditorHintTextFor(state, loadWorkflowSettings(ctx.cwd));
|
|
15692
|
+
workflowUiNotify(ctx, `Editor hint contrast set to ${workflowEditorHintContrastLabel(contrast)}.`, "info");
|
|
15693
|
+
}
|
|
15694
|
+
continue;
|
|
15695
|
+
}
|
|
15512
15696
|
const index = labels.indexOf(choice);
|
|
15513
15697
|
const option = options[index];
|
|
15514
15698
|
if (!option) continue;
|
|
15515
15699
|
const enabled = await chooseBool(ctx, `ui.${option.key}?`);
|
|
15516
15700
|
if (enabled !== undefined) {
|
|
15517
|
-
|
|
15701
|
+
updateSettings(ctx.cwd, "global", (s) => { workflowWidgetUi(s)[option.key] = enabled; });
|
|
15518
15702
|
setWorkflowUi(ctx, state, activeSubagents);
|
|
15519
|
-
ctx
|
|
15703
|
+
workflowUiNotify(ctx, `${option.label} ${enabled ? "shown" : "hidden"}.`, "info");
|
|
15520
15704
|
}
|
|
15521
15705
|
}
|
|
15522
15706
|
}
|
|
@@ -15524,22 +15708,22 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
15524
15708
|
async function showUiWidgetsSettingsMenu(ctx: ExtensionContext) {
|
|
15525
15709
|
if (!ctx.hasUI) return show(pi, renderWorkflowWidgetsStatus(ctx));
|
|
15526
15710
|
while (ctx.hasUI) {
|
|
15527
|
-
const choice = await ctx.ui.select("UI Widgets", ["Plan Top Widget", "Plan Bottom Widget", "Mission Top Widget", "Mission Bottom Widget", "Enable Widget Shortcuts", "Remember Widget Visibility", "
|
|
15711
|
+
const choice = await ctx.ui.select("UI Widgets", ["Plan Top Widget", "Plan Bottom Widget", "Mission Top Widget", "Mission Bottom Widget", "Enable Widget Shortcuts", "Remember Widget Visibility", "Editor Hints", "List Current Settings", "Back"]);
|
|
15528
15712
|
if (!choice || choice === "Back") return;
|
|
15529
15713
|
if (choice === "List Current Settings") show(pi, renderWorkflowWidgetsStatus(ctx));
|
|
15530
|
-
else if (choice === "
|
|
15714
|
+
else if (choice === "Editor Hints") await showEditorHintsSettingsMenu(ctx);
|
|
15531
15715
|
else if (choice === "Enable Widget Shortcuts" || choice === "Remember Widget Visibility") {
|
|
15532
15716
|
const key = choice === "Enable Widget Shortcuts" ? "enableWidgetShortcuts" : "rememberWidgetVisibility";
|
|
15533
15717
|
const enabled = await chooseBool(ctx, `ui.${key}?`);
|
|
15534
15718
|
if (enabled !== undefined) {
|
|
15535
|
-
|
|
15719
|
+
updateSettings(ctx.cwd, "global", (s) => { workflowWidgetUi(s)[key] = enabled; });
|
|
15536
15720
|
setWorkflowUi(ctx, state, activeSubagents);
|
|
15537
|
-
ctx
|
|
15721
|
+
workflowUiNotify(ctx, `${choice} ${enabled ? "enabled" : "disabled"}.`, "info");
|
|
15538
15722
|
}
|
|
15539
15723
|
} else {
|
|
15540
15724
|
const slot: WorkflowWidgetSlot = choice === "Plan Top Widget" ? "planTop" : choice === "Plan Bottom Widget" ? "planBottom" : choice === "Mission Top Widget" ? "missionTop" : "missionBottom";
|
|
15541
15725
|
const visible = await chooseBool(ctx, `${widgetSlotLabel(slot)} visible?`);
|
|
15542
|
-
if (visible !== undefined) ctx
|
|
15726
|
+
if (visible !== undefined) workflowUiNotify(ctx, setWorkflowWidgetVisibility(ctx, slot, visible), "info");
|
|
15543
15727
|
}
|
|
15544
15728
|
}
|
|
15545
15729
|
}
|
|
@@ -15591,14 +15775,14 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
15591
15775
|
const result = applyWorkflowPreset(ctx.cwd, undefined, resolved);
|
|
15592
15776
|
setWorkflowUi(ctx, state, activeSubagents);
|
|
15593
15777
|
const label = workflowPresetLabel(resolved, workflowPresetCatalog(result.settings)[resolved]);
|
|
15594
|
-
if (notifyOnly) ctx
|
|
15778
|
+
if (notifyOnly) workflowUiNotify(ctx, `Workflow preset active: ${label}`, "info");
|
|
15595
15779
|
else show(pi, presetActionMessage("Workflow Preset Applied", label, result.file, result.scope));
|
|
15596
15780
|
}
|
|
15597
15781
|
|
|
15598
15782
|
async function markWorkflowPresetCustom(ctx: ExtensionContext): Promise<void> {
|
|
15599
15783
|
const result = updateSettings(ctx.cwd, undefined, (s) => { s.presets = { ...(s.presets ?? {}), activePreset: WORKFLOW_CUSTOM_PRESET_MARKER, items: { ...(s.presets?.items ?? {}) } }; });
|
|
15600
15784
|
setWorkflowUi(ctx, state, activeSubagents);
|
|
15601
|
-
ctx
|
|
15785
|
+
workflowUiNotify(ctx, `Workflow preset marker cleared in ${result.file}; workflow settings unchanged.`, "info");
|
|
15602
15786
|
}
|
|
15603
15787
|
|
|
15604
15788
|
async function cycleWorkflowPreset(ctx: ExtensionContext, direction: 1 | -1): Promise<void> {
|
|
@@ -15666,7 +15850,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
15666
15850
|
if (policy) updateSettings(ctx.cwd, undefined, (s) => { const item = (s.presets!.items![name] ??= { planning: {}, workflow: {}, missions: {}, subagents: {} }); item.subagents = { ...(item.subagents ?? {}), planningPolicy: policy, executionPolicy: policy, repairPolicy: policy, reviewPolicy: policy, validationPolicy: policy }; });
|
|
15667
15851
|
}
|
|
15668
15852
|
setWorkflowUi(ctx, state, activeSubagents);
|
|
15669
|
-
ctx
|
|
15853
|
+
workflowUiNotify(ctx, `Preset ${name} updated in ${r.file}`, "info");
|
|
15670
15854
|
} catch (e) { show(pi, `# Workflow Preset Error\n\n${e instanceof Error ? e.message : String(e)}`); }
|
|
15671
15855
|
}
|
|
15672
15856
|
}
|
|
@@ -15761,7 +15945,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
15761
15945
|
async function showCustomBrandStartupVisualMenu(ctx: ExtensionContext): Promise<boolean | undefined> {
|
|
15762
15946
|
if (!ctx.hasUI) return undefined;
|
|
15763
15947
|
const saved = updateSettings(ctx.cwd, undefined, (s) => { s.ui.startupVisual = "custom_brand"; });
|
|
15764
|
-
ctx
|
|
15948
|
+
workflowUiNotify(ctx, `ui.startupVisual set to custom_brand in ${saved.file}`, "info");
|
|
15765
15949
|
while (ctx.hasUI) {
|
|
15766
15950
|
const choice = await ctx.ui.select("Custom Brand Startup Visual", ["Set Text", "Choose Base Template", "Preview", "List Theme Settings", "Back"]);
|
|
15767
15951
|
if (!choice || choice === "Back") return undefined;
|
|
@@ -15770,13 +15954,13 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
15770
15954
|
} else if (choice === "Set Text") {
|
|
15771
15955
|
const text = sanitizeCustomBrandText(await ctx.ui.input("Custom brand text", sanitizeCustomBrandText(loadWorkflowSettings(ctx.cwd).ui.customBrandText) || "WORKFLOW SUITE"));
|
|
15772
15956
|
const r = updateSettings(ctx.cwd, undefined, (s) => { s.ui.customBrandEnabled = true; s.ui.customBrandText = text; s.ui.startupVisual = "custom_brand"; });
|
|
15773
|
-
ctx
|
|
15957
|
+
workflowUiNotify(ctx, `ui.customBrandText set in ${r.file}`, "info");
|
|
15774
15958
|
void showStartupVisual(ctx, { intent: "manual" });
|
|
15775
15959
|
} else if (choice === "Choose Base Template") {
|
|
15776
15960
|
const base = parseCustomBrandBaseVisual((await ctx.ui.select("Custom brand base template", WORKFLOW_CUSTOM_BRAND_BASE_VISUALS)) ?? "");
|
|
15777
15961
|
if (base) {
|
|
15778
15962
|
const r = updateSettings(ctx.cwd, undefined, (s) => { s.ui.customBrandBaseVisual = base; s.ui.startupVisual = "custom_brand"; });
|
|
15779
|
-
ctx
|
|
15963
|
+
workflowUiNotify(ctx, `ui.customBrandBaseVisual set to ${base} in ${r.file}`, "info");
|
|
15780
15964
|
void showStartupVisual(ctx, { intent: "manual" });
|
|
15781
15965
|
}
|
|
15782
15966
|
} else if (choice === "Preview") {
|
|
@@ -15798,27 +15982,27 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
15798
15982
|
const text = startupLogoText(loadWorkflowSettings(ctx.cwd)) || "WFS";
|
|
15799
15983
|
const value = sanitizeCustomBrandText(await ctx.ui.input("Custom logo letters (max 6 A-Z/0-9)", text)).toUpperCase().replace(/[^A-Z0-9]/g, "").slice(0, 6);
|
|
15800
15984
|
const r = updateSettings(ctx.cwd, undefined, (s) => { s.ui.startupLogo = "custom"; s.ui.startupLogoText = value; });
|
|
15801
|
-
ctx
|
|
15985
|
+
workflowUiNotify(ctx, `ui.startupLogoText set to ${value || "(empty)"} in ${r.file}`, "info");
|
|
15802
15986
|
void showStartupVisual(ctx, { intent: "manual" });
|
|
15803
15987
|
} else if (choice === "Choose Font") {
|
|
15804
15988
|
const font = parseStartupLogoFont((await ctx.ui.select("Custom logo font", WORKFLOW_STARTUP_LOGO_FONTS)) ?? "");
|
|
15805
15989
|
if (font) {
|
|
15806
15990
|
const r = updateSettings(ctx.cwd, undefined, (s) => { s.ui.startupLogo = "custom"; s.ui.startupLogoFont = font; });
|
|
15807
|
-
ctx
|
|
15991
|
+
workflowUiNotify(ctx, `ui.startupLogoFont set to ${font} in ${r.file}`, "info");
|
|
15808
15992
|
void showStartupVisual(ctx, { intent: "manual" });
|
|
15809
15993
|
}
|
|
15810
15994
|
} else if (choice === "Choose Shadow Direction") {
|
|
15811
15995
|
const direction = parseStartupLogoShadowDirection((await ctx.ui.select("Custom logo shadow direction", WORKFLOW_STARTUP_LOGO_SHADOW_DIRECTIONS)) ?? "");
|
|
15812
15996
|
if (direction) {
|
|
15813
15997
|
const r = updateSettings(ctx.cwd, undefined, (s) => { s.ui.startupLogo = "custom"; s.ui.startupLogoShadowDirection = direction; });
|
|
15814
|
-
ctx
|
|
15998
|
+
workflowUiNotify(ctx, `ui.startupLogoShadowDirection set to ${direction} in ${r.file}`, "info");
|
|
15815
15999
|
void showStartupVisual(ctx, { intent: "manual" });
|
|
15816
16000
|
}
|
|
15817
16001
|
} else if (choice === "Choose Color Style") {
|
|
15818
16002
|
const colorStyle = parseStartupLogoColorStyle((await ctx.ui.select("Custom logo color style", WORKFLOW_STARTUP_LOGO_COLOR_STYLES)) ?? "");
|
|
15819
16003
|
if (colorStyle) {
|
|
15820
16004
|
const r = updateSettings(ctx.cwd, undefined, (s) => { s.ui.startupLogo = "custom"; s.ui.startupLogoColorStyle = colorStyle; });
|
|
15821
|
-
ctx
|
|
16005
|
+
workflowUiNotify(ctx, `ui.startupLogoColorStyle set to ${colorStyle} in ${r.file}`, "info");
|
|
15822
16006
|
void showStartupVisual(ctx, { intent: "manual" });
|
|
15823
16007
|
}
|
|
15824
16008
|
} else if (choice === "Preview") {
|
|
@@ -15843,7 +16027,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
15843
16027
|
} else {
|
|
15844
16028
|
const r = updateSettings(ctx.cwd, undefined, (s) => { s.ui.startupVisual = visual; });
|
|
15845
16029
|
const canPreview = startupVisualOrDefault(r.settings) !== "none";
|
|
15846
|
-
ctx
|
|
16030
|
+
workflowUiNotify(ctx, canPreview ? `Startup visual set to ${visual} in ${r.file}` : `Startup visual set to ${visual} (disabled) in ${r.file}`, "info");
|
|
15847
16031
|
if (canPreview) void showStartupVisual(ctx, { intent: "manual" });
|
|
15848
16032
|
}
|
|
15849
16033
|
}
|
|
@@ -15851,14 +16035,14 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
15851
16035
|
const name = parseWidgetTextPreset((await ctx.ui.select("Startup text style", (WORKFLOW_WIDGET_TEXT_PRESETS as readonly string[]).map((p) => WORKFLOW_WIDGET_TEXT_PRESET_LABELS[p]))) ?? "");
|
|
15852
16036
|
if (name) {
|
|
15853
16037
|
const r = updateSettings(ctx.cwd, undefined, (s) => { s.ui.startupTextStyle = name; });
|
|
15854
|
-
ctx
|
|
16038
|
+
workflowUiNotify(ctx, `Startup text style set to ${WORKFLOW_WIDGET_TEXT_PRESET_LABELS[name]} in ${r.file}.`, "info");
|
|
15855
16039
|
void showStartupVisual(ctx, { intent: "manual" });
|
|
15856
16040
|
}
|
|
15857
16041
|
} else if (choice === "Turn On" || choice === "Turn Off") {
|
|
15858
16042
|
const visual: WorkflowStartupVisual = choice === "Turn On" ? "mission_control" : "none";
|
|
15859
16043
|
const r = updateSettings(ctx.cwd, undefined, (s) => { s.ui.startupVisual = visual; });
|
|
15860
16044
|
const canPreview = startupVisualOrDefault(r.settings) !== "none";
|
|
15861
|
-
ctx
|
|
16045
|
+
workflowUiNotify(ctx, canPreview ? `Startup visual turned on (${visual}) in ${r.file}` : `Startup visual turned off in ${r.file}`, "info");
|
|
15862
16046
|
if (canPreview) void showStartupVisual(ctx, { intent: "manual" });
|
|
15863
16047
|
} else if (choice === "On Session Start") {
|
|
15864
16048
|
const enabled = await chooseBool(ctx, "Show startup visual on session start?");
|
|
@@ -15867,12 +16051,12 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
15867
16051
|
s.ui.startupVisualOnSessionStart = enabled;
|
|
15868
16052
|
if (enabled === true && (parseStartupVisual(s.ui.startupVisual) ?? "none") === "none") s.ui.startupVisual = "minimal";
|
|
15869
16053
|
});
|
|
15870
|
-
ctx
|
|
16054
|
+
workflowUiNotify(ctx, `Startup on session start ${enabled ? "enabled" : "disabled"} in ${r.file}`, "info");
|
|
15871
16055
|
void showStartupVisual(ctx, { intent: "manual" });
|
|
15872
16056
|
}
|
|
15873
16057
|
} else if (choice === "Preview") {
|
|
15874
16058
|
const previewed = await showStartupVisual(ctx, { intent: "manual" });
|
|
15875
|
-
if (!previewed) ctx
|
|
16059
|
+
if (!previewed) workflowUiNotify(ctx, "Startup visual is disabled. Choose a visual or turn it on to preview.", "info");
|
|
15876
16060
|
}
|
|
15877
16061
|
}
|
|
15878
16062
|
return undefined;
|
|
@@ -15901,7 +16085,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
15901
16085
|
const r = updateSettings(ctx.cwd, undefined, (s) => { s.ui.workflowTheme = name; });
|
|
15902
16086
|
applyWorkflowEditorTheme(ctx);
|
|
15903
16087
|
setWorkflowUi(ctx, state, activeSubagents);
|
|
15904
|
-
ctx
|
|
16088
|
+
workflowUiNotify(ctx, `ui.workflowTheme set to ${workflowThemeDisplayName(name)} in ${r.file}`, "info");
|
|
15905
16089
|
void showStartupVisual(ctx, { intent: "manual" });
|
|
15906
16090
|
}
|
|
15907
16091
|
} else if (choice === "Startup Visual") {
|
|
@@ -15910,7 +16094,7 @@ ${renderMissionStatus(activeMission ?? paused)}`);
|
|
|
15910
16094
|
const logo = parseStartupLogo((await ctx.ui.select("Startup logo", WORKFLOW_STARTUP_LOGOS)) ?? "");
|
|
15911
16095
|
if (logo) {
|
|
15912
16096
|
const r = updateSettings(ctx.cwd, undefined, (s) => { s.ui.startupLogo = logo; });
|
|
15913
|
-
ctx
|
|
16097
|
+
workflowUiNotify(ctx, `ui.startupLogo set to ${logo} in ${r.file}`, "info");
|
|
15914
16098
|
if (logo === "custom") await showCustomStartupLogoMenu(ctx);
|
|
15915
16099
|
else void showStartupVisual(ctx, { intent: "manual" });
|
|
15916
16100
|
}
|
|
@@ -16070,20 +16254,20 @@ Pi Version: v${VERSION}
|
|
|
16070
16254
|
workflowLastAutoCompactionAt = Date.now();
|
|
16071
16255
|
clearDeferredWorkflowCompaction();
|
|
16072
16256
|
rememberWorkflowCompactionCheck(`${checkpoint} boundary triggered at ${percent.toFixed(1)}% context`);
|
|
16073
|
-
try { ctx
|
|
16257
|
+
try { workflowUiNotify(ctx, `Workflow auto-compaction triggered at ${percent.toFixed(1)}% context usage.`, "info"); } catch { /* UI may be unavailable */ }
|
|
16074
16258
|
ctx.compact({
|
|
16075
16259
|
customInstructions,
|
|
16076
16260
|
onComplete: () => {
|
|
16077
16261
|
workflowAutoCompactionRunning = false;
|
|
16078
16262
|
workflowLastAutoCompactionAt = Date.now();
|
|
16079
16263
|
rememberWorkflowCompactionCheck(`${checkpoint} boundary compaction completed`);
|
|
16080
|
-
try { ctx
|
|
16264
|
+
try { workflowUiNotify(ctx, "Workflow auto-compaction complete.", "info"); } catch { /* UI may be unavailable */ }
|
|
16081
16265
|
},
|
|
16082
16266
|
onError: (error: Error) => {
|
|
16083
16267
|
workflowAutoCompactionRunning = false;
|
|
16084
16268
|
rememberWorkflowCompactionCheck(`${checkpoint} boundary compaction failed — ${error.message}`);
|
|
16085
16269
|
rememberCustomCompactionStatus(`proactive compaction request failed: ${error.message}`);
|
|
16086
|
-
try { ctx
|
|
16270
|
+
try { workflowUiNotify(ctx, `Workflow auto-compaction skipped: ${error.message}`, "warning"); } catch { /* UI may be unavailable */ }
|
|
16087
16271
|
},
|
|
16088
16272
|
});
|
|
16089
16273
|
}
|
|
@@ -16136,7 +16320,7 @@ Pi Version: v${VERSION}
|
|
|
16136
16320
|
const model = ctx.modelRegistry.find(provider, modelId);
|
|
16137
16321
|
if (!model) {
|
|
16138
16322
|
rememberCustomCompactionStatus(`fallback to Pi default: model not found ${provider}/${modelId}`);
|
|
16139
|
-
ctx
|
|
16323
|
+
workflowUiNotify(ctx, `Custom compaction model not found: ${provider}/${modelId}; using Pi default compaction.`, "warning");
|
|
16140
16324
|
return;
|
|
16141
16325
|
}
|
|
16142
16326
|
|
|
@@ -16144,12 +16328,12 @@ Pi Version: v${VERSION}
|
|
|
16144
16328
|
if (auth.ok === false) {
|
|
16145
16329
|
const authError = auth.error;
|
|
16146
16330
|
rememberCustomCompactionStatus(`fallback to Pi default: auth failed for ${provider}/${modelId}: ${authError}`);
|
|
16147
|
-
ctx
|
|
16331
|
+
workflowUiNotify(ctx, `Custom compaction auth failed for ${provider}/${modelId}: ${authError}; using Pi default compaction.`, "warning");
|
|
16148
16332
|
return;
|
|
16149
16333
|
}
|
|
16150
16334
|
if (!auth.apiKey) {
|
|
16151
16335
|
rememberCustomCompactionStatus(`fallback to Pi default: no API key for ${provider}/${modelId}`);
|
|
16152
|
-
ctx
|
|
16336
|
+
workflowUiNotify(ctx, `No API key for custom compaction model ${provider}/${modelId}; using Pi default compaction.`, "warning");
|
|
16153
16337
|
return;
|
|
16154
16338
|
}
|
|
16155
16339
|
|
|
@@ -16161,14 +16345,14 @@ Pi Version: v${VERSION}
|
|
|
16161
16345
|
const fitNote = fitted.adjusted && fitted.safeInputTokens
|
|
16162
16346
|
? ` Adaptive fit: summarizing about ${Math.round(fitted.inputTokens).toLocaleString()} tokens within ${Math.round(fitted.safeInputTokens).toLocaleString()} safe input tokens for the compaction model.`
|
|
16163
16347
|
: "";
|
|
16164
|
-
ctx
|
|
16348
|
+
workflowUiNotify(ctx, `Custom compaction using ${provider}/${modelId}. Keep recent: ${customCompactionKeepRecentTokens(settings).toLocaleString()} tokens; reserve: ${customCompactionReserveTokens(settings).toLocaleString()} tokens.${fitNote}`, "info");
|
|
16165
16349
|
const result = await compactionApi.compact(fitted.preparation, model, auth.apiKey, auth.headers, event.customInstructions, event.signal);
|
|
16166
16350
|
rememberCustomCompactionStatus(`custom compaction succeeded using ${provider}/${modelId}${fitted.adjusted ? " with adaptive context fit" : ""}`);
|
|
16167
16351
|
return { compaction: result };
|
|
16168
16352
|
} catch (error) {
|
|
16169
16353
|
const message = error instanceof Error ? error.message : String(error);
|
|
16170
16354
|
rememberCustomCompactionStatus(`fallback to Pi default: custom compaction failed for ${provider}/${modelId}: ${message}`);
|
|
16171
|
-
if (!event.signal.aborted) ctx
|
|
16355
|
+
if (!event.signal.aborted) workflowUiNotify(ctx, `Custom compaction failed: ${message}; using Pi default compaction.`, "warning");
|
|
16172
16356
|
return;
|
|
16173
16357
|
}
|
|
16174
16358
|
});
|
|
@@ -17025,6 +17209,14 @@ Pi Version: v${VERSION}
|
|
|
17025
17209
|
setWorkflowUi(ctx, state, activeSubagents);
|
|
17026
17210
|
return show(pi, updatedMessage(result.scope, result.file, `ui.${key}`, String(bool)));
|
|
17027
17211
|
}
|
|
17212
|
+
if (subject === "ui" && key === "editorHintContrast") {
|
|
17213
|
+
const contrast = parseEditorHintContrast(value);
|
|
17214
|
+
if (!contrast) return show(pi, "# Error\n\nUsage: `/workflow-settings set ui editorHintContrast <subtle|normal|bright|high>`");
|
|
17215
|
+
const result = updateSettings(ctx.cwd, scope ?? "global", (s) => { workflowWidgetUi(s).editorHintContrast = contrast; });
|
|
17216
|
+
setWorkflowUi(ctx, state, activeSubagents);
|
|
17217
|
+
workflowEditorHintText = workflowEditorHintTextFor(state, loadWorkflowSettings(ctx.cwd));
|
|
17218
|
+
return show(pi, updatedMessage(result.scope, result.file, "ui.editorHintContrast", contrast));
|
|
17219
|
+
}
|
|
17028
17220
|
if (subject === "subagents" && (key === "enabled" || key === "activityIndicatorEnabled" || key === "autoUseDuringPlanning" || key === "autoUseDuringExecution" || key === "autoUseDuringRepair" || key === "autoUseDuringReview" || key === "autoUseDuringValidation" || key === "allowParallelReadOnly" || key === "allowParallelPlanning" || key === "allowParallelExecution" || key === "allowParallelRepair" || key === "allowParallelReview" || key === "allowParallelValidation" || key === "allowParallelEdits" || key === "requireParallelEditConflictProtection" || key === "allowBackgroundSubagents")) {
|
|
17029
17221
|
if (bool === undefined) return show(pi, "# Error\n\nUsage: `/workflow-settings set subagents <enabled|activityIndicatorEnabled|autoUseDuringPlanning|autoUseDuringExecution|autoUseDuringRepair|autoUseDuringReview|autoUseDuringValidation|allowParallelReadOnly|allowParallelPlanning|allowParallelExecution|allowParallelRepair|allowParallelReview|allowParallelValidation|allowParallelEdits|requireParallelEditConflictProtection> <true|false>`");
|
|
17030
17222
|
const result = updateSettings(ctx.cwd, scope, (s) => {
|