UNPKG

@blundergoat/goat-flow

Version:

AI coding agent harness and local dashboard for Claude Code, OpenAI Codex, Google Antigravity, and GitHub Copilot - setup audits, guardrails, structured skills, deny hooks, and persistent learning loops.

152 lines (151 loc) 5.93 kB
"use strict"; /** * Dashboard custom-prompt surface helpers and UI actions. */ function dashboardCustomPromptSurfaceTags(ctx) { return dashboardParseTargetSurfaces(ctx.customPromptDraft.bestTargetSurfacesText); } function dashboardSetCustomPromptSurfaceTags(ctx, surfaces) { ctx.customPromptDraft.bestTargetSurfacesText = dashboardJoinTargetSurfaces(surfaces); } function dashboardAddCustomPromptSurface(ctx, surface) { const next = dashboardNormalizeSurfaceTag(surface); if (!next) return; const tags = dashboardCustomPromptSurfaceTags(ctx); if (!tags.includes(next)) { dashboardSetCustomPromptSurfaceTags(ctx, [...tags, next]); } ctx.customPromptSurfaceDraft = ""; } function dashboardRemoveCustomPromptSurface(ctx, surface) { const target = dashboardNormalizeSurfaceTag(surface); dashboardSetCustomPromptSurfaceTags(ctx, dashboardCustomPromptSurfaceTags(ctx).filter((tag) => tag !== target)); } function dashboardCustomPromptSurfaceSuggestions(ctx) { const selected = new Set(dashboardCustomPromptSurfaceTags(ctx)); const seen = new Set(); const suggestions = []; for (const preset of ctx.allPresets ?? []) { for (const surface of preset.bestTargetSurfaces ?? []) { const normalized = dashboardNormalizeSurfaceTag(surface); if (!normalized || selected.has(normalized) || seen.has(normalized)) { continue; } seen.add(normalized); suggestions.push(normalized); } } return suggestions.sort(); } function dashboardPreviewCustomPromptPreset(ctx) { const draft = ctx.customPromptDraft; const prompt = draft.prompt.trim(); const route = CUSTOM_PROMPT_ROUTES.has(draft.route) ? draft.route : "direct"; const requiresGoatFlowInstall = draft.requiresGoatFlowInstall === true; return { id: ctx.editingCustomPromptId ?? "custom:preview", name: draft.name.trim() || "Untitled custom prompt", desc: draft.desc.trim() || draft.notes.trim() || "Custom prompt", prompt: prompt || "Write your prompt body...", cat: "custom", route, source: "custom", globalSafe: dashboardResolvedGlobalSafe({ requiresGoatFlowInstall, globalSafe: draft.globalSafe, }), internalOnly: false, qualityMode: false, requiresGh: draft.requiresGh, requiresPrOrIssue: draft.requiresPrOrIssue, requiresLocalDiff: draft.requiresLocalDiff, requiresUiApp: draft.requiresUiApp, requiresDependencyFiles: draft.requiresDependencyFiles, requiresGoatFlowInstall, mayCheckoutBranch: draft.mayCheckoutBranch, requiresCleanWorktree: draft.requiresCleanWorktree, mayWriteFiles: draft.mayWriteFiles, artifactRequired: draft.artifactRequired, bestTargetSurfaces: dashboardCustomPromptSurfaceTags(ctx), fallbackPrompt: draft.notes.trim(), costTier: "medium", }; } function dashboardOpenNewCustomPrompt(ctx) { ctx.customPromptDraft = dashboardDefaultCustomPromptDraft(); ctx.customPromptSurfaceDraft = ""; ctx.customPromptSubmitAttempted = false; ctx.editingCustomPromptId = null; ctx.showCustomPromptEditor = true; } function dashboardOpenEditCustomPrompt(ctx, preset) { if (!preset?.id.startsWith("custom:")) return; const custom = ctx.customPrompts.find((entry) => entry.id === preset.id); if (!custom) return; ctx.customPromptDraft = dashboardCustomPromptDraftFromCustom(custom); ctx.customPromptSurfaceDraft = ""; ctx.customPromptSubmitAttempted = false; ctx.editingCustomPromptId = custom.id; ctx.showCustomPromptEditor = true; } function dashboardDuplicateCustomPrompt(ctx, preset) { if (!preset) return; ctx.customPromptDraft = { ...dashboardCustomPromptDraftFromPreset(preset), name: `${preset.name} (copy)`, }; ctx.customPromptSurfaceDraft = ""; ctx.customPromptSubmitAttempted = false; ctx.editingCustomPromptId = null; ctx.showCustomPromptEditor = true; } function dashboardStartCustomPromptFromPresetId(ctx, presetId) { const preset = (ctx.allPresets ?? []).find((entry) => entry.id === presetId); if (!preset) return; dashboardDuplicateCustomPrompt(ctx, preset); } function dashboardSaveCustomPrompt(ctx) { const errors = dashboardValidateCustomPromptDraft(ctx); if (errors.length > 0) { ctx.showToast(errors[0] ?? "Custom prompt is invalid", true); return null; } const editing = ctx.editingCustomPromptId; const existing = editing ? ctx.customPrompts.find((custom) => custom.id === editing) : undefined; const next = dashboardBuildCustomPrompt(ctx, existing); if (existing) { ctx.customPrompts = ctx.customPrompts.map((custom) => custom.id === existing.id ? next : custom); } else { ctx.customPrompts = [...ctx.customPrompts, next]; } dashboardPersistCustomPrompts(ctx); ctx.selectedPreset = dashboardCustomPromptToPreset(next); ctx.showCustomPromptEditor = false; ctx.editingCustomPromptId = null; ctx.customPromptSubmitAttempted = false; ctx.showToast(existing ? "Custom prompt updated" : "Custom prompt saved"); return next; } function dashboardDeleteSelectedCustomPrompt(ctx) { const selected = ctx.selectedPreset; if (!selected?.id.startsWith("custom:")) return; if (!window.confirm(`Delete custom prompt "${selected.name}"?`)) return; ctx.customPrompts = ctx.customPrompts.filter((custom) => custom.id !== selected.id); dashboardPersistCustomPrompts(ctx); ctx.selectedPreset = null; ctx.showCustomPromptEditor = false; ctx.editingCustomPromptId = null; ctx.customPromptSubmitAttempted = false; ctx.showToast("Custom prompt deleted"); }