{"version":3,"file":"handlers.mjs","names":[],"sources":["../../src/command/handlers.ts"],"sourcesContent":["import {\n\tDynamicBorder,\n\ttype ExtensionCommandContext,\n\tgetSettingsListTheme,\n\ttype Theme,\n} from '@earendil-works/pi-coding-agent';\nimport { Container, type SettingItem, SettingsList, Text } from '@earendil-works/pi-tui';\nimport { THINKING_LEVEL_VALUES } from '@live-compaction/command/completions';\nimport {\n\tcreatePanelItems,\n\ttype PanelExternalAction,\n\tpromptLabel,\n\tSETTING_IDS,\n\tsyncPanelItems,\n} from '@live-compaction/command/panel';\nimport type { ConfigScope, PresetConfig, PromptKind } from '@live-compaction/config';\nimport { loadEffectiveConfig } from '@live-compaction/config';\nimport type { LiveCompactionController, LiveCompactionState } from '@live-compaction/controller';\nimport { getPresetNames, parseThinkingLevelSelection } from '@live-compaction/controller';\n\n// ---------------------------------------------------------------------------\n// Simple helpers\n// ---------------------------------------------------------------------------\n\nexport async function chooseScope(\n\tctx: ExtensionCommandContext,\n\tallowProject: boolean,\n): Promise<ConfigScope | undefined> {\n\tif (!allowProject) return 'global';\n\tconst result = await ctx.ui.select('Choose scope', ['global', 'project']);\n\tif (result === 'global' || result === 'project') return result;\n\treturn undefined;\n}\n\nexport async function promptForPreset(\n\tctx: ExtensionCommandContext,\n\tname: string,\n\tcurrent?: PresetConfig,\n): Promise<PresetConfig | undefined> {\n\tconst model = await ctx.ui.input(\n\t\t`${name}: provider/modelId`,\n\t\tcurrent?.model ?? 'anthropic/claude-sonnet-4',\n\t);\n\tconst normalizedModel = model?.trim();\n\tif (!normalizedModel) return undefined;\n\tconst thinkingSelection = await ctx.ui.select(`${name}: thinking level`, [\n\t\t...THINKING_LEVEL_VALUES,\n\t]);\n\tif (!thinkingSelection) return undefined;\n\treturn {\n\t\tmodel: normalizedModel,\n\t\tthinkingLevel: parseThinkingLevelSelection(thinkingSelection),\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Prompt handlers\n// ---------------------------------------------------------------------------\n\nexport async function editPrompt(\n\tkind: PromptKind,\n\tscope: ConfigScope,\n\tctx: ExtensionCommandContext,\n\tcontroller: LiveCompactionController,\n): Promise<void> {\n\tconst state = await controller.loadState(ctx, scope);\n\tconst currentText =\n\t\tkind === 'compaction' ? state.compactionPrompt.text : state.branchSummaryPrompt.text;\n\tconst edited = await ctx.ui.editor(`${promptLabel(kind)} (${scope})`, currentText);\n\tif (edited === undefined) return;\n\tawait controller.savePrompt(scope, kind, edited, ctx);\n\tctx.ui.notify(`${promptLabel(kind)} saved for ${scope} scope.`, 'info');\n}\n\nexport async function resetPrompt(\n\tkind: PromptKind,\n\tscope: ConfigScope,\n\tctx: ExtensionCommandContext,\n\tcontroller: LiveCompactionController,\n): Promise<void> {\n\tconst confirmed = await ctx.ui.confirm(\n\t\t`Reset ${promptLabel(kind)}`,\n\t\t`Remove the ${scope} ${promptLabel(kind).toLowerCase()} override?`,\n\t);\n\tif (!confirmed) return;\n\tawait controller.resetPrompt(scope, kind, ctx);\n\tctx.ui.notify(`${promptLabel(kind)} reset for ${scope} scope.`, 'info');\n}\n\n// ---------------------------------------------------------------------------\n// Preset management\n// ---------------------------------------------------------------------------\n\nexport async function managePreset(\n\taction: PanelExternalAction['action'],\n\tscope: ConfigScope,\n\tctx: ExtensionCommandContext,\n\tcontroller: LiveCompactionController,\n): Promise<void> {\n\tconst state = await controller.loadState(ctx, scope);\n\tconst presetNames = getPresetNames(state.config);\n\n\tif (action === 'add') {\n\t\tconst name = await ctx.ui.input('Preset name', 'fast');\n\t\tconst normalizedName = name?.trim();\n\t\tif (!normalizedName) return;\n\t\tconst preset = await promptForPreset(ctx, normalizedName);\n\t\tif (!preset) return;\n\t\tawait controller.upsertPreset(scope, normalizedName, preset, ctx);\n\t\tctx.ui.notify(`Preset '${normalizedName}' saved for ${scope} scope.`, 'info');\n\t\treturn;\n\t}\n\n\tif (presetNames.length === 0) {\n\t\tctx.ui.notify(`No presets are defined for ${scope} scope.`, 'warning');\n\t\treturn;\n\t}\n\n\tconst title = action === 'edit' ? `Edit preset (${scope})` : `Delete preset (${scope})`;\n\tconst presetName = await ctx.ui.select(title, presetNames);\n\tif (!presetName) return;\n\n\tif (action === 'edit') {\n\t\tconst preset = await promptForPreset(ctx, presetName, state.config.presets[presetName]);\n\t\tif (!preset) return;\n\t\tawait controller.upsertPreset(scope, presetName, preset, ctx);\n\t\tctx.ui.notify(`Preset '${presetName}' updated for ${scope} scope.`, 'info');\n\t\treturn;\n\t}\n\n\tconst confirmed = await ctx.ui.confirm(\n\t\t'Delete preset',\n\t\t`Delete preset '${presetName}' from ${scope} scope?`,\n\t);\n\tif (!confirmed) return;\n\tawait controller.deletePreset(scope, presetName, ctx);\n\tctx.ui.notify(`Preset '${presetName}' deleted from ${scope} scope.`, 'info');\n}\n\n// ---------------------------------------------------------------------------\n// Scope picker\n// ---------------------------------------------------------------------------\n\nexport async function pickInitialScope(ctx: ExtensionCommandContext): Promise<ConfigScope> {\n\ttry {\n\t\tconst effective = await loadEffectiveConfig(ctx.cwd);\n\t\tconst preference = effective.defaultPanelScope;\n\t\tif (preference === 'project' && ctx.cwd) return 'project';\n\t\treturn 'global';\n\t} catch {\n\t\treturn 'global';\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Main settings panel\n// ---------------------------------------------------------------------------\n\nfunction buildSettingsList(\n\titems: SettingItem[],\n\t_scope: string,\n\t_state: LiveCompactionState,\n\tcontroller: LiveCompactionController,\n\tctx: ExtensionCommandContext,\n\tgetScope: () => ConfigScope,\n\tsetScope: (s: ConfigScope) => void,\n\trefreshState: () => Promise<void>,\n\tdone: (action?: PanelExternalAction) => void,\n\t_theme: Theme,\n\t_tui: { requestRender(): void },\n): SettingsList {\n\treturn new SettingsList(\n\t\titems,\n\t\t12,\n\t\tgetSettingsListTheme(),\n\t\tasync (id, newValue) => {\n\t\t\tif (id === SETTING_IDS.scope) {\n\t\t\t\tif (newValue === 'global' || newValue === 'project') {\n\t\t\t\t\tsetScope(newValue);\n\t\t\t\t\tawait refreshState();\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (id === SETTING_IDS.defaultScope) {\n\t\t\t\tif (newValue === 'global' || newValue === 'project') {\n\t\t\t\t\tconst currentState = await controller.loadState(ctx, getScope());\n\t\t\t\t\tawait controller.setConfig(\n\t\t\t\t\t\tgetScope(),\n\t\t\t\t\t\t{ ...currentState.config, defaultPanelScope: newValue },\n\t\t\t\t\t\tctx,\n\t\t\t\t\t);\n\t\t\t\t\tawait refreshState();\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (id === SETTING_IDS.inheritSessionModel) {\n\t\t\t\tconst currentState = await controller.loadState(ctx, getScope());\n\t\t\t\tawait controller.setConfig(\n\t\t\t\t\tgetScope(),\n\t\t\t\t\t{ ...currentState.config, inheritSessionModel: newValue === 'on' },\n\t\t\t\t\tctx,\n\t\t\t\t);\n\t\t\t\tawait refreshState();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (id === SETTING_IDS.compactionFiles || id === SETTING_IDS.branchFiles) {\n\t\t\t\tconst currentState = await controller.loadState(ctx, getScope());\n\t\t\t\tconst next = {\n\t\t\t\t\t...currentState.config,\n\t\t\t\t\tincludeFilesTouched: {\n\t\t\t\t\t\t...currentState.config.includeFilesTouched,\n\t\t\t\t\t\t...(id === SETTING_IDS.compactionFiles\n\t\t\t\t\t\t\t? { inCompactionSummary: newValue === 'on' }\n\t\t\t\t\t\t\t: { inBranchSummary: newValue === 'on' }),\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t\tawait controller.setConfig(getScope(), next, ctx);\n\t\t\t\tawait refreshState();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (id === SETTING_IDS.defaultPreset) {\n\t\t\t\tconst currentState = await controller.loadState(ctx, getScope());\n\t\t\t\tawait controller.setConfig(\n\t\t\t\t\tgetScope(),\n\t\t\t\t\t{ ...currentState.config, defaultPreset: newValue },\n\t\t\t\t\tctx,\n\t\t\t\t);\n\t\t\t\tawait refreshState();\n\t\t\t}\n\t\t},\n\t\t() => done(undefined),\n\t\t{ enableSearch: true },\n\t);\n}\n\nexport async function openPanel(\n\tctx: ExtensionCommandContext,\n\tcontroller: LiveCompactionController,\n): Promise<void> {\n\tlet scope: ConfigScope = await pickInitialScope(ctx);\n\n\twhile (true) {\n\t\tlet state = await controller.loadState(ctx, scope);\n\t\tconst action = await ctx.ui.custom<PanelExternalAction | undefined>((tui, theme, _kb, done) => {\n\t\t\tconst items = createPanelItems(\n\t\t\t\t() => state,\n\t\t\t\ttheme,\n\t\t\t\t() => tui.requestRender(),\n\t\t\t\tdone,\n\t\t\t);\n\t\t\tsyncPanelItems(items, state);\n\n\t\t\tconst container = new Container();\n\t\t\tcontainer.addChild(new DynamicBorder((value: string) => theme.fg('accent', value)));\n\t\t\tcontainer.addChild(new Text(theme.fg('accent', theme.bold('Grounded Compaction')), 0, 0));\n\t\t\tcontainer.addChild(new Text(theme.fg('dim', controller.summarizeState(state)), 0, 0));\n\n\t\t\tlet settingsList: SettingsList | null = null;\n\t\t\tconst refreshState = async (): Promise<void> => {\n\t\t\t\tstate = await controller.loadState(ctx, scope);\n\t\t\t\tsyncPanelItems(items, state);\n\t\t\t\tsettingsList?.invalidate();\n\t\t\t\tcontainer.invalidate();\n\t\t\t\ttui.requestRender();\n\t\t\t};\n\n\t\t\tsettingsList = buildSettingsList(\n\t\t\t\titems,\n\t\t\t\tscope,\n\t\t\t\tstate,\n\t\t\t\tcontroller,\n\t\t\t\tctx,\n\t\t\t\t() => scope,\n\t\t\t\t(s) => {\n\t\t\t\t\tscope = s;\n\t\t\t\t},\n\t\t\t\trefreshState,\n\t\t\t\tdone,\n\t\t\t\ttheme,\n\t\t\t\ttui,\n\t\t\t);\n\n\t\t\tcontainer.addChild(settingsList);\n\t\t\tcontainer.addChild(\n\t\t\t\tnew Text(theme.fg('dim', '/live-compaction show • verify • path • reset'), 0),\n\t\t\t);\n\n\t\t\treturn {\n\t\t\t\trender(width: number): string[] {\n\t\t\t\t\treturn container.render(width);\n\t\t\t\t},\n\t\t\t\tinvalidate(): void {\n\t\t\t\t\tcontainer.invalidate();\n\t\t\t\t},\n\t\t\t\thandleInput(data: string): void {\n\t\t\t\t\tsettingsList?.handleInput(data);\n\t\t\t\t\ttui.requestRender();\n\t\t\t\t},\n\t\t\t};\n\t\t});\n\n\t\tif (!action) return;\n\n\t\tif (action.kind === 'preset') {\n\t\t\tawait managePreset(action.action, scope, ctx, controller);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (action.action === 'edit') {\n\t\t\tawait editPrompt(action.promptKind, scope, ctx, controller);\n\t\t\tcontinue;\n\t\t}\n\n\t\tawait resetPrompt(action.promptKind, scope, ctx, controller);\n\t}\n}\n"],"mappings":"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"}