@winspan/claude-forge 8.33.5 → 8.35.0
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/README.md +10 -30
- package/dist/agents/definition.d.ts +3 -0
- package/dist/agents/definition.d.ts.map +1 -1
- package/dist/agents/definition.js +3 -0
- package/dist/agents/definition.js.map +1 -1
- package/dist/agents/official-agents.d.ts.map +1 -1
- package/dist/agents/official-agents.js +6 -3
- package/dist/agents/official-agents.js.map +1 -1
- package/dist/agents/registry.d.ts +17 -1
- package/dist/agents/registry.d.ts.map +1 -1
- package/dist/agents/registry.js +106 -7
- package/dist/agents/registry.js.map +1 -1
- package/dist/capability/index.d.ts +6 -5
- package/dist/capability/index.d.ts.map +1 -1
- package/dist/capability/index.js +6 -5
- package/dist/capability/index.js.map +1 -1
- package/dist/capability/types.d.ts +5 -74
- package/dist/capability/types.d.ts.map +1 -1
- package/dist/capability/types.js +4 -1
- package/dist/capability/types.js.map +1 -1
- package/dist/cli/commands/executions.d.ts +3 -0
- package/dist/cli/commands/executions.d.ts.map +1 -0
- package/dist/cli/commands/executions.js +109 -0
- package/dist/cli/commands/executions.js.map +1 -0
- package/dist/cli/commands/skills.d.ts.map +1 -1
- package/dist/cli/commands/skills.js +83 -20
- package/dist/cli/commands/skills.js.map +1 -1
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/core/storage/rows.d.ts +14 -36
- package/dist/core/storage/rows.d.ts.map +1 -1
- package/dist/core/storage/schema.sql +27 -45
- package/dist/core/storage/sqlite.d.ts +11 -79
- package/dist/core/storage/sqlite.d.ts.map +1 -1
- package/dist/core/storage/sqlite.js +35 -362
- package/dist/core/storage/sqlite.js.map +1 -1
- package/dist/core/utils/token-tracker.d.ts +0 -1
- package/dist/core/utils/token-tracker.d.ts.map +1 -1
- package/dist/core/utils/token-tracker.js +0 -1
- package/dist/core/utils/token-tracker.js.map +1 -1
- package/dist/daemon/handlers/post-tool-use.d.ts +1 -9
- package/dist/daemon/handlers/post-tool-use.d.ts.map +1 -1
- package/dist/daemon/handlers/post-tool-use.js +2 -99
- package/dist/daemon/handlers/post-tool-use.js.map +1 -1
- package/dist/daemon/handlers/stop.d.ts +5 -15
- package/dist/daemon/handlers/stop.d.ts.map +1 -1
- package/dist/daemon/handlers/stop.js +25 -93
- package/dist/daemon/handlers/stop.js.map +1 -1
- package/dist/daemon/handlers/user-prompt.d.ts +3 -5
- package/dist/daemon/handlers/user-prompt.d.ts.map +1 -1
- package/dist/daemon/handlers/user-prompt.js +39 -98
- package/dist/daemon/handlers/user-prompt.js.map +1 -1
- package/dist/daemon/index.d.ts.map +1 -1
- package/dist/daemon/index.js +11 -56
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon/routing-observer.d.ts.map +1 -1
- package/dist/daemon/routing-observer.js +24 -1
- package/dist/daemon/routing-observer.js.map +1 -1
- package/dist/intelligence/execution-doc-builder.d.ts +61 -0
- package/dist/intelligence/execution-doc-builder.d.ts.map +1 -0
- package/dist/intelligence/execution-doc-builder.js +601 -0
- package/dist/intelligence/execution-doc-builder.js.map +1 -0
- package/dist/skills/invocation-guard.d.ts +45 -0
- package/dist/skills/invocation-guard.d.ts.map +1 -0
- package/dist/skills/invocation-guard.js +82 -0
- package/dist/skills/invocation-guard.js.map +1 -0
- package/dist/skills/official-skills.d.ts.map +1 -1
- package/dist/skills/official-skills.js +218 -20
- package/dist/skills/official-skills.js.map +1 -1
- package/dist/skills/registry.d.ts +22 -0
- package/dist/skills/registry.d.ts.map +1 -1
- package/dist/skills/registry.js +30 -2
- package/dist/skills/registry.js.map +1 -1
- package/dist/skills/tools/skill-invoke.d.ts +36 -0
- package/dist/skills/tools/skill-invoke.d.ts.map +1 -0
- package/dist/skills/tools/skill-invoke.js +82 -0
- package/dist/skills/tools/skill-invoke.js.map +1 -0
- package/dist/skills/tools/skill-list.d.ts +26 -0
- package/dist/skills/tools/skill-list.d.ts.map +1 -0
- package/dist/skills/tools/skill-list.js +35 -0
- package/dist/skills/tools/skill-list.js.map +1 -0
- package/dist/web/routes/execution-trace.d.ts.map +1 -1
- package/dist/web/routes/execution-trace.js +16 -0
- package/dist/web/routes/execution-trace.js.map +1 -1
- package/dist/web/routes/skill-stats.d.ts +12 -0
- package/dist/web/routes/skill-stats.d.ts.map +1 -0
- package/dist/web/routes/skill-stats.js +72 -0
- package/dist/web/routes/skill-stats.js.map +1 -0
- package/dist/web/routes/status.d.ts.map +1 -1
- package/dist/web/routes/status.js +8 -10
- package/dist/web/routes/status.js.map +1 -1
- package/dist/web/routes/token-usage.d.ts +1 -1
- package/dist/web/routes/token-usage.d.ts.map +1 -1
- package/dist/web/routes/token-usage.js +1 -16
- package/dist/web/routes/token-usage.js.map +1 -1
- package/dist/web/routes/types.d.ts +0 -6
- package/dist/web/routes/types.d.ts.map +1 -1
- package/dist/web/routes/types.js.map +1 -1
- package/dist/web/server.d.ts +0 -6
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +0 -5
- package/dist/web/server.js.map +1 -1
- package/dist/web/static/assets/{AIConfig-BbwRuWzm.js → AIConfig-DiUFET_Q.js} +2 -2
- package/dist/web/static/assets/{AIConfig-BbwRuWzm.js.map → AIConfig-DiUFET_Q.js.map} +1 -1
- package/dist/web/static/assets/{Agents-FyKzsN-g.js → Agents-bNNGbQnL.js} +2 -2
- package/dist/web/static/assets/{Agents-FyKzsN-g.js.map → Agents-bNNGbQnL.js.map} +1 -1
- package/dist/web/static/assets/{Events-C2OCOKAD.js → Events-DQHP6Uaq.js} +2 -2
- package/dist/web/static/assets/{Events-C2OCOKAD.js.map → Events-DQHP6Uaq.js.map} +1 -1
- package/dist/web/static/assets/ExecutionTrace-Co8ARdg-.js +3 -0
- package/dist/web/static/assets/ExecutionTrace-Co8ARdg-.js.map +1 -0
- package/dist/web/static/assets/{Methodologies-DwYLXc8o.js → Methodologies-CXNrDXwG.js} +2 -2
- package/dist/web/static/assets/{Methodologies-DwYLXc8o.js.map → Methodologies-CXNrDXwG.js.map} +1 -1
- package/dist/web/static/assets/{Sessions-CFpFk-5I.js → Sessions-ZQSCgXyy.js} +2 -2
- package/dist/web/static/assets/{Sessions-CFpFk-5I.js.map → Sessions-ZQSCgXyy.js.map} +1 -1
- package/dist/web/static/assets/{Skills-BkbegTV1.js → Skills-C5-5zOSH.js} +2 -2
- package/dist/web/static/assets/{Skills-BkbegTV1.js.map → Skills-C5-5zOSH.js.map} +1 -1
- package/dist/web/static/assets/{index-CIRlno4E.js → index-DJK5beK6.js} +3 -3
- package/dist/web/static/assets/{index-CIRlno4E.js.map → index-DJK5beK6.js.map} +1 -1
- package/dist/web/static/assets/index-phpuytMI.css +1 -0
- package/dist/web/static/index.html +2 -2
- package/package.json +2 -2
- package/dist/capability/execution-manager.d.ts +0 -96
- package/dist/capability/execution-manager.d.ts.map +0 -1
- package/dist/capability/execution-manager.js +0 -260
- package/dist/capability/execution-manager.js.map +0 -1
- package/dist/capability/executor/background-executor.d.ts +0 -58
- package/dist/capability/executor/background-executor.d.ts.map +0 -1
- package/dist/capability/executor/background-executor.js +0 -322
- package/dist/capability/executor/background-executor.js.map +0 -1
- package/dist/capability/executor/foreground-executor.d.ts +0 -26
- package/dist/capability/executor/foreground-executor.d.ts.map +0 -1
- package/dist/capability/executor/foreground-executor.js +0 -82
- package/dist/capability/executor/foreground-executor.js.map +0 -1
- package/dist/capability/executor/orchestrator.d.ts +0 -38
- package/dist/capability/executor/orchestrator.d.ts.map +0 -1
- package/dist/capability/executor/orchestrator.js +0 -158
- package/dist/capability/executor/orchestrator.js.map +0 -1
- package/dist/capability/executor/stream-parser.d.ts +0 -73
- package/dist/capability/executor/stream-parser.d.ts.map +0 -1
- package/dist/capability/executor/stream-parser.js +0 -56
- package/dist/capability/executor/stream-parser.js.map +0 -1
- package/dist/capability/executor/types.d.ts +0 -44
- package/dist/capability/executor/types.d.ts.map +0 -1
- package/dist/capability/executor/types.js +0 -9
- package/dist/capability/executor/types.js.map +0 -1
- package/dist/capability/executor/worker-auth-probe.d.ts +0 -30
- package/dist/capability/executor/worker-auth-probe.d.ts.map +0 -1
- package/dist/capability/executor/worker-auth-probe.js +0 -108
- package/dist/capability/executor/worker-auth-probe.js.map +0 -1
- package/dist/capability/methodologies/bmad.yaml +0 -81
- package/dist/capability/methodologies/code-quality-audit.yaml +0 -26
- package/dist/capability/methodologies/harness-engineering.yaml +0 -75
- package/dist/capability/methodologies/test-coverage-scan.yaml +0 -26
- package/dist/capability/methodology-planner.d.ts +0 -49
- package/dist/capability/methodology-planner.d.ts.map +0 -1
- package/dist/capability/methodology-planner.js +0 -306
- package/dist/capability/methodology-planner.js.map +0 -1
- package/dist/capability/methodology-registry.d.ts +0 -32
- package/dist/capability/methodology-registry.d.ts.map +0 -1
- package/dist/capability/methodology-registry.js +0 -113
- package/dist/capability/methodology-registry.js.map +0 -1
- package/dist/daemon/handlers/methodology-formatter.d.ts +0 -16
- package/dist/daemon/handlers/methodology-formatter.d.ts.map +0 -1
- package/dist/daemon/handlers/methodology-formatter.js +0 -119
- package/dist/daemon/handlers/methodology-formatter.js.map +0 -1
- package/dist/daemon/idle-detector.d.ts +0 -35
- package/dist/daemon/idle-detector.d.ts.map +0 -1
- package/dist/daemon/idle-detector.js +0 -56
- package/dist/daemon/idle-detector.js.map +0 -1
- package/dist/daemon/idle-trigger.d.ts +0 -53
- package/dist/daemon/idle-trigger.d.ts.map +0 -1
- package/dist/daemon/idle-trigger.js +0 -153
- package/dist/daemon/idle-trigger.js.map +0 -1
- package/dist/daemon/methodology-pending-queue.d.ts +0 -33
- package/dist/daemon/methodology-pending-queue.d.ts.map +0 -1
- package/dist/daemon/methodology-pending-queue.js +0 -120
- package/dist/daemon/methodology-pending-queue.js.map +0 -1
- package/dist/web/routes/methodology.d.ts +0 -12
- package/dist/web/routes/methodology.d.ts.map +0 -1
- package/dist/web/routes/methodology.js +0 -228
- package/dist/web/routes/methodology.js.map +0 -1
- package/dist/web/static/assets/ExecutionTrace-BsWSpu2v.js +0 -3
- package/dist/web/static/assets/ExecutionTrace-BsWSpu2v.js.map +0 -1
- package/dist/web/static/assets/index-N1EByy_h.css +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"mappings":"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","names":["sections","LayoutDashboard","MessageSquare","Activity","TrendingUp","GitBranch","Bot","BookOpen","Network","Cpu","Layout","location","useLocation","sidebarOpen","setSidebarOpen","useState","renderNav","onClick","jsx","Fragment","section","jsxs","item","Icon","isActive","Link","clsx","X","Menu","Outlet","Dashboard","lazy","Sessions","SessionDetail","Events","ExecutionTrace","Methodologies","MethodologyDetail","Agents","Skills","Routing","AIConfig","PageFallback","App","Routes","Route","Navigate","Suspense","ToastContext","createContext","useToast","ctx","useContext","nextId","ToastProvider","children","toasts","setToasts","remove","useCallback","id","prev","t","show","type","message","value","msg","ToastItem","toast","onClose","icons","CheckCircle","XCircle","AlertCircle","Info","borderColors","ConfirmContext","useConfirm","ConfirmProvider","state","setState","confirm","options","resolve","handleClose","result","variant","_a","iconColor","btnColor","AlertTriangle","queryClient","QueryClient","ReactDOM","React","QueryClientProvider","BrowserRouter"],"ignoreList":[],"sources":["../../src/components/Layout.tsx","../../src/App.tsx","../../src/components/Toast.tsx","../../src/components/Confirm.tsx","../../src/main.tsx"],"sourcesContent":["import { Outlet, Link, useLocation } from 'react-router-dom'\nimport {\n LayoutDashboard,\n MessageSquare,\n Activity,\n GitBranch,\n Menu,\n X,\n Bot,\n BookOpen,\n Network,\n Cpu,\n TrendingUp,\n} from 'lucide-react'\nimport { useState } from 'react'\nimport clsx from 'clsx'\n\ninterface NavItem {\n name: string\n href: string\n icon: any\n}\n\ninterface NavSection {\n title: string\n items: NavItem[]\n}\n\nconst sections: NavSection[] = [\n {\n title: '总览',\n items: [\n { name: '仪表盘', href: '/dashboard', icon: LayoutDashboard },\n ],\n },\n {\n title: '活动',\n items: [\n { name: '会话', href: '/sessions', icon: MessageSquare },\n { name: '事件', href: '/events', icon: Activity },\n { name: '执行追踪', href: '/execution-trace', icon: TrendingUp },\n { name: '方法论执行', href: '/methodologies', icon: GitBranch },\n ],\n },\n {\n title: '配置',\n items: [\n { name: 'Agent 管理', href: '/agents', icon: Bot },\n { name: 'Skill 管理', href: '/skills', icon: BookOpen },\n { name: 'Agent 路由', href: '/routing', icon: Network },\n { name: 'AI 配置', href: '/ai-config', icon: Cpu },\n ],\n },\n]\n\nexport default function Layout() {\n const location = useLocation()\n const [sidebarOpen, setSidebarOpen] = useState(false)\n\n const renderNav = (onClick?: () => void) => (\n <>\n {sections.map((section) => (\n <div key={section.title} className=\"mb-4\">\n <div className=\"px-3 py-2 text-xs font-semibold text-gray-400 uppercase tracking-wider\">\n {section.title}\n </div>\n {section.items.map((item) => {\n const Icon = item.icon\n const isActive = location.pathname === item.href || location.pathname.startsWith(item.href + '/')\n return (\n <Link\n key={item.name}\n to={item.href}\n onClick={onClick}\n className={clsx(\n 'group flex items-center px-3 py-2 text-sm font-medium rounded-md mb-0.5',\n isActive\n ? 'bg-indigo-50 text-indigo-600'\n : 'text-gray-700 hover:bg-gray-50'\n )}\n >\n <Icon className={clsx('mr-3 h-4 w-4', isActive ? 'text-indigo-600' : 'text-gray-400')} />\n {item.name}\n </Link>\n )\n })}\n </div>\n ))}\n </>\n )\n\n return (\n <div className=\"min-h-screen bg-gray-50\">\n {/* Mobile sidebar */}\n <div className={clsx('fixed inset-0 z-40 lg:hidden', sidebarOpen ? 'block' : 'hidden')}>\n <div className=\"fixed inset-0 bg-gray-600 bg-opacity-75\" onClick={() => setSidebarOpen(false)} />\n <div className=\"fixed inset-y-0 left-0 flex w-64 flex-col bg-white\">\n <div className=\"flex items-center justify-between px-4 py-4 border-b\">\n <div className=\"flex items-center gap-2\">\n <div className=\"w-8 h-8 rounded-lg bg-gradient-to-br from-indigo-500 to-purple-600 flex items-center justify-center text-white font-bold text-sm\">\n CF\n </div>\n <h1 className=\"text-base font-bold text-gray-900\">Claude Forge</h1>\n </div>\n <button onClick={() => setSidebarOpen(false)} className=\"text-gray-500\">\n <X className=\"h-5 w-5\" />\n </button>\n </div>\n <nav className=\"flex-1 overflow-y-auto px-2 py-4\">\n {renderNav(() => setSidebarOpen(false))}\n </nav>\n </div>\n </div>\n\n {/* Desktop sidebar */}\n <div className=\"hidden lg:fixed lg:inset-y-0 lg:flex lg:w-64 lg:flex-col\">\n <div className=\"flex flex-col flex-grow border-r border-gray-200 bg-white\">\n <div className=\"flex items-center gap-2 px-4 py-4 border-b\">\n <div className=\"w-8 h-8 rounded-lg bg-gradient-to-br from-indigo-500 to-purple-600 flex items-center justify-center text-white font-bold text-sm\">\n CF\n </div>\n <h1 className=\"text-base font-bold text-gray-900\">Claude Forge</h1>\n </div>\n <nav className=\"flex-1 overflow-y-auto px-2 py-4\">{renderNav()}</nav>\n </div>\n </div>\n\n {/* Main content */}\n <div className=\"lg:pl-64\">\n <div className=\"sticky top-0 z-10 flex h-14 flex-shrink-0 bg-white border-b border-gray-200 lg:hidden\">\n <button\n onClick={() => setSidebarOpen(true)}\n className=\"px-4 text-gray-500 focus:outline-none\"\n >\n <Menu className=\"h-5 w-5\" />\n </button>\n <div className=\"flex flex-1 items-center px-4\">\n <h1 className=\"text-base font-semibold text-gray-900\">Claude Forge</h1>\n </div>\n </div>\n <main className=\"py-6\">\n <div className=\"mx-auto max-w-7xl px-4 sm:px-6 lg:px-8\">\n <Outlet />\n </div>\n </main>\n </div>\n </div>\n )\n}\n","import { lazy, Suspense } from 'react'\nimport { Routes, Route, Navigate } from 'react-router-dom'\nimport Layout from './components/Layout'\n\n// 路由级代码分割:按需加载 page 组件,缩小主 bundle\nconst Dashboard = lazy(() => import('./pages/Dashboard'))\nconst Sessions = lazy(() => import('./pages/Sessions'))\nconst SessionDetail = lazy(() => import('./pages/SessionDetail'))\nconst Events = lazy(() => import('./pages/Events'))\nconst ExecutionTrace = lazy(() => import('./pages/ExecutionTrace'))\nconst Methodologies = lazy(() => import('./pages/Methodologies'))\nconst MethodologyDetail = lazy(() => import('./pages/MethodologyDetail'))\nconst Agents = lazy(() => import('./pages/Agents'))\nconst Skills = lazy(() => import('./pages/Skills'))\nconst Routing = lazy(() => import('./pages/Routing'))\nconst AIConfig = lazy(() => import('./pages/AIConfig'))\n\nfunction PageFallback() {\n return (\n <div className=\"flex items-center justify-center h-full py-16\">\n <div className=\"flex items-center gap-3 text-sm text-gray-500\">\n <div className=\"w-4 h-4 border-2 border-gray-300 border-t-blue-500 rounded-full animate-spin\" />\n 加载中...\n </div>\n </div>\n )\n}\n\nexport default function App() {\n return (\n <Routes>\n <Route path=\"/\" element={<Layout />}>\n <Route\n index\n element={<Navigate to=\"/dashboard\" replace />}\n />\n <Route\n path=\"dashboard\"\n element={\n <Suspense fallback={<PageFallback />}>\n <Dashboard />\n </Suspense>\n }\n />\n <Route\n path=\"sessions\"\n element={\n <Suspense fallback={<PageFallback />}>\n <Sessions />\n </Suspense>\n }\n />\n <Route\n path=\"sessions/:id\"\n element={\n <Suspense fallback={<PageFallback />}>\n <SessionDetail />\n </Suspense>\n }\n />\n <Route\n path=\"events\"\n element={\n <Suspense fallback={<PageFallback />}>\n <Events />\n </Suspense>\n }\n />\n <Route\n path=\"execution-trace\"\n element={\n <Suspense fallback={<PageFallback />}>\n <ExecutionTrace />\n </Suspense>\n }\n />\n <Route\n path=\"methodologies\"\n element={\n <Suspense fallback={<PageFallback />}>\n <Methodologies />\n </Suspense>\n }\n />\n <Route\n path=\"methodologies/:id\"\n element={\n <Suspense fallback={<PageFallback />}>\n <MethodologyDetail />\n </Suspense>\n }\n />\n <Route\n path=\"agents\"\n element={\n <Suspense fallback={<PageFallback />}>\n <Agents />\n </Suspense>\n }\n />\n <Route\n path=\"skills\"\n element={\n <Suspense fallback={<PageFallback />}>\n <Skills />\n </Suspense>\n }\n />\n <Route\n path=\"routing\"\n element={\n <Suspense fallback={<PageFallback />}>\n <Routing />\n </Suspense>\n }\n />\n <Route\n path=\"ai-config\"\n element={\n <Suspense fallback={<PageFallback />}>\n <AIConfig />\n </Suspense>\n }\n />\n </Route>\n </Routes>\n )\n}\n","import { createContext, useContext, useState, useCallback, ReactNode } from 'react'\nimport { CheckCircle, XCircle, AlertCircle, Info, X } from 'lucide-react'\nimport clsx from 'clsx'\n\ntype ToastType = 'success' | 'error' | 'warning' | 'info'\n\ninterface Toast {\n id: number\n type: ToastType\n message: string\n}\n\ninterface ToastContextValue {\n show: (type: ToastType, message: string) => void\n success: (message: string) => void\n error: (message: string) => void\n warning: (message: string) => void\n info: (message: string) => void\n}\n\nconst ToastContext = createContext<ToastContextValue | null>(null)\n\nexport function useToast() {\n const ctx = useContext(ToastContext)\n if (!ctx) throw new Error('useToast must be used within ToastProvider')\n return ctx\n}\n\nlet nextId = 1\n\nexport function ToastProvider({ children }: { children: ReactNode }) {\n const [toasts, setToasts] = useState<Toast[]>([])\n\n const remove = useCallback((id: number) => {\n setToasts(prev => prev.filter(t => t.id !== id))\n }, [])\n\n const show = useCallback((type: ToastType, message: string) => {\n const id = nextId++\n setToasts(prev => [...prev, { id, type, message }])\n setTimeout(() => remove(id), 4000)\n }, [remove])\n\n const value: ToastContextValue = {\n show,\n success: (msg) => show('success', msg),\n error: (msg) => show('error', msg),\n warning: (msg) => show('warning', msg),\n info: (msg) => show('info', msg),\n }\n\n return (\n <ToastContext.Provider value={value}>\n {children}\n <div className=\"fixed top-4 right-4 z-[9999] space-y-2 max-w-md\">\n {toasts.map(t => (\n <ToastItem key={t.id} toast={t} onClose={() => remove(t.id)} />\n ))}\n </div>\n </ToastContext.Provider>\n )\n}\n\nfunction ToastItem({ toast, onClose }: { toast: Toast; onClose: () => void }) {\n const icons = {\n success: <CheckCircle className=\"h-5 w-5 text-green-500\" />,\n error: <XCircle className=\"h-5 w-5 text-red-500\" />,\n warning: <AlertCircle className=\"h-5 w-5 text-yellow-500\" />,\n info: <Info className=\"h-5 w-5 text-blue-500\" />,\n }\n const borderColors = {\n success: 'border-green-200',\n error: 'border-red-200',\n warning: 'border-yellow-200',\n info: 'border-blue-200',\n }\n\n return (\n <div\n className={clsx(\n 'bg-white shadow-lg rounded-lg border px-4 py-3 flex items-start gap-3 animate-in slide-in-from-right',\n borderColors[toast.type]\n )}\n >\n {icons[toast.type]}\n <div className=\"flex-1 text-sm text-gray-800\">{toast.message}</div>\n <button onClick={onClose} className=\"text-gray-400 hover:text-gray-600\">\n <X className=\"h-4 w-4\" />\n </button>\n </div>\n )\n}\n","import { createContext, useContext, useState, useCallback, ReactNode } from 'react'\nimport { AlertTriangle } from 'lucide-react'\n\ninterface ConfirmOptions {\n title: string\n message: string\n confirmText?: string\n cancelText?: string\n variant?: 'danger' | 'warning' | 'info'\n}\n\ninterface ConfirmContextValue {\n confirm: (options: ConfirmOptions) => Promise<boolean>\n}\n\nconst ConfirmContext = createContext<ConfirmContextValue | null>(null)\n\nexport function useConfirm() {\n const ctx = useContext(ConfirmContext)\n if (!ctx) throw new Error('useConfirm must be used within ConfirmProvider')\n return ctx.confirm\n}\n\nexport function ConfirmProvider({ children }: { children: ReactNode }) {\n const [state, setState] = useState<{\n open: boolean\n options: ConfirmOptions | null\n resolve: ((value: boolean) => void) | null\n }>({ open: false, options: null, resolve: null })\n\n const confirm = useCallback((options: ConfirmOptions): Promise<boolean> => {\n return new Promise((resolve) => {\n setState({ open: true, options, resolve })\n })\n }, [])\n\n const handleClose = (result: boolean) => {\n if (state.resolve) state.resolve(result)\n setState({ open: false, options: null, resolve: null })\n }\n\n const variant = state.options?.variant || 'danger'\n const iconColor = {\n danger: 'text-red-600',\n warning: 'text-yellow-600',\n info: 'text-blue-600',\n }[variant]\n const btnColor = {\n danger: 'bg-red-600 hover:bg-red-700',\n warning: 'bg-yellow-600 hover:bg-yellow-700',\n info: 'bg-indigo-600 hover:bg-indigo-700',\n }[variant]\n\n return (\n <ConfirmContext.Provider value={{ confirm }}>\n {children}\n {state.open && state.options && (\n <div className=\"fixed inset-0 z-[9999] flex items-center justify-center\">\n <div\n className=\"absolute inset-0 bg-black bg-opacity-50\"\n onClick={() => handleClose(false)}\n />\n <div className=\"relative bg-white rounded-lg shadow-xl max-w-md w-full mx-4 p-6\">\n <div className=\"flex items-start gap-4\">\n <div className={`flex-shrink-0 ${iconColor}`}>\n <AlertTriangle className=\"h-6 w-6\" />\n </div>\n <div className=\"flex-1\">\n <h3 className=\"text-lg font-semibold text-gray-900 mb-2\">\n {state.options.title}\n </h3>\n <p className=\"text-sm text-gray-600 whitespace-pre-wrap\">\n {state.options.message}\n </p>\n </div>\n </div>\n <div className=\"flex justify-end gap-2 mt-6\">\n <button\n onClick={() => handleClose(false)}\n className=\"px-4 py-2 text-sm text-gray-700 bg-white border border-gray-300 rounded hover:bg-gray-50\"\n >\n {state.options.cancelText || '取消'}\n </button>\n <button\n onClick={() => handleClose(true)}\n className={`px-4 py-2 text-sm text-white rounded ${btnColor}`}\n >\n {state.options.confirmText || '确定'}\n </button>\n </div>\n </div>\n </div>\n )}\n </ConfirmContext.Provider>\n )\n}\n","import React from 'react'\nimport ReactDOM from 'react-dom/client'\nimport { BrowserRouter } from 'react-router-dom'\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query'\nimport App from './App'\nimport { ToastProvider } from './components/Toast'\nimport { ConfirmProvider } from './components/Confirm'\nimport './index.css'\n\nconst queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n refetchOnWindowFocus: false,\n retry: 1,\n },\n },\n})\n\nReactDOM.createRoot(document.getElementById('root')!).render(\n <React.StrictMode>\n <QueryClientProvider client={queryClient}>\n <ToastProvider>\n <ConfirmProvider>\n <BrowserRouter>\n <App />\n </BrowserRouter>\n </ConfirmProvider>\n </ToastProvider>\n </QueryClientProvider>\n </React.StrictMode>,\n)\n"],"file":"assets/index-CIRlno4E.js"}
|
|
1
|
+
{"version":3,"mappings":"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","names":["sections","LayoutDashboard","MessageSquare","Activity","TrendingUp","GitBranch","Bot","BookOpen","Network","Cpu","Layout","location","useLocation","sidebarOpen","setSidebarOpen","useState","renderNav","onClick","jsx","Fragment","section","jsxs","item","Icon","isActive","Link","clsx","X","Menu","Outlet","Dashboard","lazy","Sessions","SessionDetail","Events","ExecutionTrace","Methodologies","MethodologyDetail","Agents","Skills","Routing","AIConfig","PageFallback","App","Routes","Route","Navigate","Suspense","ToastContext","createContext","useToast","ctx","useContext","nextId","ToastProvider","children","toasts","setToasts","remove","useCallback","id","prev","t","show","type","message","value","msg","ToastItem","toast","onClose","icons","CheckCircle","XCircle","AlertCircle","Info","borderColors","ConfirmContext","useConfirm","ConfirmProvider","state","setState","confirm","options","resolve","handleClose","result","variant","_a","iconColor","btnColor","AlertTriangle","queryClient","QueryClient","ReactDOM","React","QueryClientProvider","BrowserRouter"],"ignoreList":[],"sources":["../../src/components/Layout.tsx","../../src/App.tsx","../../src/components/Toast.tsx","../../src/components/Confirm.tsx","../../src/main.tsx"],"sourcesContent":["import { Outlet, Link, useLocation } from 'react-router-dom'\nimport {\n LayoutDashboard,\n MessageSquare,\n Activity,\n GitBranch,\n Menu,\n X,\n Bot,\n BookOpen,\n Network,\n Cpu,\n TrendingUp,\n} from 'lucide-react'\nimport { useState } from 'react'\nimport clsx from 'clsx'\n\ninterface NavItem {\n name: string\n href: string\n icon: any\n}\n\ninterface NavSection {\n title: string\n items: NavItem[]\n}\n\nconst sections: NavSection[] = [\n {\n title: '总览',\n items: [\n { name: '仪表盘', href: '/dashboard', icon: LayoutDashboard },\n ],\n },\n {\n title: '活动',\n items: [\n { name: '会话', href: '/sessions', icon: MessageSquare },\n { name: '事件', href: '/events', icon: Activity },\n { name: '执行追踪', href: '/execution-trace', icon: TrendingUp },\n { name: '方法论执行', href: '/methodologies', icon: GitBranch },\n ],\n },\n {\n title: '配置',\n items: [\n { name: 'Agent 管理', href: '/agents', icon: Bot },\n { name: 'Skill 管理', href: '/skills', icon: BookOpen },\n { name: 'Agent 路由', href: '/routing', icon: Network },\n { name: 'AI 配置', href: '/ai-config', icon: Cpu },\n ],\n },\n]\n\nexport default function Layout() {\n const location = useLocation()\n const [sidebarOpen, setSidebarOpen] = useState(false)\n\n const renderNav = (onClick?: () => void) => (\n <>\n {sections.map((section) => (\n <div key={section.title} className=\"mb-4\">\n <div className=\"px-3 py-2 text-xs font-semibold text-gray-400 uppercase tracking-wider\">\n {section.title}\n </div>\n {section.items.map((item) => {\n const Icon = item.icon\n const isActive = location.pathname === item.href || location.pathname.startsWith(item.href + '/')\n return (\n <Link\n key={item.name}\n to={item.href}\n onClick={onClick}\n className={clsx(\n 'group flex items-center px-3 py-2 text-sm font-medium rounded-md mb-0.5',\n isActive\n ? 'bg-indigo-50 text-indigo-600'\n : 'text-gray-700 hover:bg-gray-50'\n )}\n >\n <Icon className={clsx('mr-3 h-4 w-4', isActive ? 'text-indigo-600' : 'text-gray-400')} />\n {item.name}\n </Link>\n )\n })}\n </div>\n ))}\n </>\n )\n\n return (\n <div className=\"min-h-screen bg-gray-50\">\n {/* Mobile sidebar */}\n <div className={clsx('fixed inset-0 z-40 lg:hidden', sidebarOpen ? 'block' : 'hidden')}>\n <div className=\"fixed inset-0 bg-gray-600 bg-opacity-75\" onClick={() => setSidebarOpen(false)} />\n <div className=\"fixed inset-y-0 left-0 flex w-64 flex-col bg-white\">\n <div className=\"flex items-center justify-between px-4 py-4 border-b\">\n <div className=\"flex items-center gap-2\">\n <div className=\"w-8 h-8 rounded-lg bg-gradient-to-br from-indigo-500 to-purple-600 flex items-center justify-center text-white font-bold text-sm\">\n CF\n </div>\n <h1 className=\"text-base font-bold text-gray-900\">Claude Forge</h1>\n </div>\n <button onClick={() => setSidebarOpen(false)} className=\"text-gray-500\">\n <X className=\"h-5 w-5\" />\n </button>\n </div>\n <nav className=\"flex-1 overflow-y-auto px-2 py-4\">\n {renderNav(() => setSidebarOpen(false))}\n </nav>\n </div>\n </div>\n\n {/* Desktop sidebar */}\n <div className=\"hidden lg:fixed lg:inset-y-0 lg:flex lg:w-64 lg:flex-col\">\n <div className=\"flex flex-col flex-grow border-r border-gray-200 bg-white\">\n <div className=\"flex items-center gap-2 px-4 py-4 border-b\">\n <div className=\"w-8 h-8 rounded-lg bg-gradient-to-br from-indigo-500 to-purple-600 flex items-center justify-center text-white font-bold text-sm\">\n CF\n </div>\n <h1 className=\"text-base font-bold text-gray-900\">Claude Forge</h1>\n </div>\n <nav className=\"flex-1 overflow-y-auto px-2 py-4\">{renderNav()}</nav>\n </div>\n </div>\n\n {/* Main content */}\n <div className=\"lg:pl-64\">\n <div className=\"sticky top-0 z-10 flex h-14 flex-shrink-0 bg-white border-b border-gray-200 lg:hidden\">\n <button\n onClick={() => setSidebarOpen(true)}\n className=\"px-4 text-gray-500 focus:outline-none\"\n >\n <Menu className=\"h-5 w-5\" />\n </button>\n <div className=\"flex flex-1 items-center px-4\">\n <h1 className=\"text-base font-semibold text-gray-900\">Claude Forge</h1>\n </div>\n </div>\n <main className=\"py-6\">\n <div className=\"mx-auto max-w-7xl px-4 sm:px-6 lg:px-8\">\n <Outlet />\n </div>\n </main>\n </div>\n </div>\n )\n}\n","import { lazy, Suspense } from 'react'\nimport { Routes, Route, Navigate } from 'react-router-dom'\nimport Layout from './components/Layout'\n\n// 路由级代码分割:按需加载 page 组件,缩小主 bundle\nconst Dashboard = lazy(() => import('./pages/Dashboard'))\nconst Sessions = lazy(() => import('./pages/Sessions'))\nconst SessionDetail = lazy(() => import('./pages/SessionDetail'))\nconst Events = lazy(() => import('./pages/Events'))\nconst ExecutionTrace = lazy(() => import('./pages/ExecutionTrace'))\nconst Methodologies = lazy(() => import('./pages/Methodologies'))\nconst MethodologyDetail = lazy(() => import('./pages/MethodologyDetail'))\nconst Agents = lazy(() => import('./pages/Agents'))\nconst Skills = lazy(() => import('./pages/Skills'))\nconst Routing = lazy(() => import('./pages/Routing'))\nconst AIConfig = lazy(() => import('./pages/AIConfig'))\n\nfunction PageFallback() {\n return (\n <div className=\"flex items-center justify-center h-full py-16\">\n <div className=\"flex items-center gap-3 text-sm text-gray-500\">\n <div className=\"w-4 h-4 border-2 border-gray-300 border-t-blue-500 rounded-full animate-spin\" />\n 加载中...\n </div>\n </div>\n )\n}\n\nexport default function App() {\n return (\n <Routes>\n <Route path=\"/\" element={<Layout />}>\n <Route\n index\n element={<Navigate to=\"/dashboard\" replace />}\n />\n <Route\n path=\"dashboard\"\n element={\n <Suspense fallback={<PageFallback />}>\n <Dashboard />\n </Suspense>\n }\n />\n <Route\n path=\"sessions\"\n element={\n <Suspense fallback={<PageFallback />}>\n <Sessions />\n </Suspense>\n }\n />\n <Route\n path=\"sessions/:id\"\n element={\n <Suspense fallback={<PageFallback />}>\n <SessionDetail />\n </Suspense>\n }\n />\n <Route\n path=\"events\"\n element={\n <Suspense fallback={<PageFallback />}>\n <Events />\n </Suspense>\n }\n />\n <Route\n path=\"execution-trace\"\n element={\n <Suspense fallback={<PageFallback />}>\n <ExecutionTrace />\n </Suspense>\n }\n />\n <Route\n path=\"methodologies\"\n element={\n <Suspense fallback={<PageFallback />}>\n <Methodologies />\n </Suspense>\n }\n />\n <Route\n path=\"methodologies/:id\"\n element={\n <Suspense fallback={<PageFallback />}>\n <MethodologyDetail />\n </Suspense>\n }\n />\n <Route\n path=\"agents\"\n element={\n <Suspense fallback={<PageFallback />}>\n <Agents />\n </Suspense>\n }\n />\n <Route\n path=\"skills\"\n element={\n <Suspense fallback={<PageFallback />}>\n <Skills />\n </Suspense>\n }\n />\n <Route\n path=\"routing\"\n element={\n <Suspense fallback={<PageFallback />}>\n <Routing />\n </Suspense>\n }\n />\n <Route\n path=\"ai-config\"\n element={\n <Suspense fallback={<PageFallback />}>\n <AIConfig />\n </Suspense>\n }\n />\n </Route>\n </Routes>\n )\n}\n","import { createContext, useContext, useState, useCallback, ReactNode } from 'react'\nimport { CheckCircle, XCircle, AlertCircle, Info, X } from 'lucide-react'\nimport clsx from 'clsx'\n\ntype ToastType = 'success' | 'error' | 'warning' | 'info'\n\ninterface Toast {\n id: number\n type: ToastType\n message: string\n}\n\ninterface ToastContextValue {\n show: (type: ToastType, message: string) => void\n success: (message: string) => void\n error: (message: string) => void\n warning: (message: string) => void\n info: (message: string) => void\n}\n\nconst ToastContext = createContext<ToastContextValue | null>(null)\n\nexport function useToast() {\n const ctx = useContext(ToastContext)\n if (!ctx) throw new Error('useToast must be used within ToastProvider')\n return ctx\n}\n\nlet nextId = 1\n\nexport function ToastProvider({ children }: { children: ReactNode }) {\n const [toasts, setToasts] = useState<Toast[]>([])\n\n const remove = useCallback((id: number) => {\n setToasts(prev => prev.filter(t => t.id !== id))\n }, [])\n\n const show = useCallback((type: ToastType, message: string) => {\n const id = nextId++\n setToasts(prev => [...prev, { id, type, message }])\n setTimeout(() => remove(id), 4000)\n }, [remove])\n\n const value: ToastContextValue = {\n show,\n success: (msg) => show('success', msg),\n error: (msg) => show('error', msg),\n warning: (msg) => show('warning', msg),\n info: (msg) => show('info', msg),\n }\n\n return (\n <ToastContext.Provider value={value}>\n {children}\n <div className=\"fixed top-4 right-4 z-[9999] space-y-2 max-w-md\">\n {toasts.map(t => (\n <ToastItem key={t.id} toast={t} onClose={() => remove(t.id)} />\n ))}\n </div>\n </ToastContext.Provider>\n )\n}\n\nfunction ToastItem({ toast, onClose }: { toast: Toast; onClose: () => void }) {\n const icons = {\n success: <CheckCircle className=\"h-5 w-5 text-green-500\" />,\n error: <XCircle className=\"h-5 w-5 text-red-500\" />,\n warning: <AlertCircle className=\"h-5 w-5 text-yellow-500\" />,\n info: <Info className=\"h-5 w-5 text-blue-500\" />,\n }\n const borderColors = {\n success: 'border-green-200',\n error: 'border-red-200',\n warning: 'border-yellow-200',\n info: 'border-blue-200',\n }\n\n return (\n <div\n className={clsx(\n 'bg-white shadow-lg rounded-lg border px-4 py-3 flex items-start gap-3 animate-in slide-in-from-right',\n borderColors[toast.type]\n )}\n >\n {icons[toast.type]}\n <div className=\"flex-1 text-sm text-gray-800\">{toast.message}</div>\n <button onClick={onClose} className=\"text-gray-400 hover:text-gray-600\">\n <X className=\"h-4 w-4\" />\n </button>\n </div>\n )\n}\n","import { createContext, useContext, useState, useCallback, ReactNode } from 'react'\nimport { AlertTriangle } from 'lucide-react'\n\ninterface ConfirmOptions {\n title: string\n message: string\n confirmText?: string\n cancelText?: string\n variant?: 'danger' | 'warning' | 'info'\n}\n\ninterface ConfirmContextValue {\n confirm: (options: ConfirmOptions) => Promise<boolean>\n}\n\nconst ConfirmContext = createContext<ConfirmContextValue | null>(null)\n\nexport function useConfirm() {\n const ctx = useContext(ConfirmContext)\n if (!ctx) throw new Error('useConfirm must be used within ConfirmProvider')\n return ctx.confirm\n}\n\nexport function ConfirmProvider({ children }: { children: ReactNode }) {\n const [state, setState] = useState<{\n open: boolean\n options: ConfirmOptions | null\n resolve: ((value: boolean) => void) | null\n }>({ open: false, options: null, resolve: null })\n\n const confirm = useCallback((options: ConfirmOptions): Promise<boolean> => {\n return new Promise((resolve) => {\n setState({ open: true, options, resolve })\n })\n }, [])\n\n const handleClose = (result: boolean) => {\n if (state.resolve) state.resolve(result)\n setState({ open: false, options: null, resolve: null })\n }\n\n const variant = state.options?.variant || 'danger'\n const iconColor = {\n danger: 'text-red-600',\n warning: 'text-yellow-600',\n info: 'text-blue-600',\n }[variant]\n const btnColor = {\n danger: 'bg-red-600 hover:bg-red-700',\n warning: 'bg-yellow-600 hover:bg-yellow-700',\n info: 'bg-indigo-600 hover:bg-indigo-700',\n }[variant]\n\n return (\n <ConfirmContext.Provider value={{ confirm }}>\n {children}\n {state.open && state.options && (\n <div className=\"fixed inset-0 z-[9999] flex items-center justify-center\">\n <div\n className=\"absolute inset-0 bg-black bg-opacity-50\"\n onClick={() => handleClose(false)}\n />\n <div className=\"relative bg-white rounded-lg shadow-xl max-w-md w-full mx-4 p-6\">\n <div className=\"flex items-start gap-4\">\n <div className={`flex-shrink-0 ${iconColor}`}>\n <AlertTriangle className=\"h-6 w-6\" />\n </div>\n <div className=\"flex-1\">\n <h3 className=\"text-lg font-semibold text-gray-900 mb-2\">\n {state.options.title}\n </h3>\n <p className=\"text-sm text-gray-600 whitespace-pre-wrap\">\n {state.options.message}\n </p>\n </div>\n </div>\n <div className=\"flex justify-end gap-2 mt-6\">\n <button\n onClick={() => handleClose(false)}\n className=\"px-4 py-2 text-sm text-gray-700 bg-white border border-gray-300 rounded hover:bg-gray-50\"\n >\n {state.options.cancelText || '取消'}\n </button>\n <button\n onClick={() => handleClose(true)}\n className={`px-4 py-2 text-sm text-white rounded ${btnColor}`}\n >\n {state.options.confirmText || '确定'}\n </button>\n </div>\n </div>\n </div>\n )}\n </ConfirmContext.Provider>\n )\n}\n","import React from 'react'\nimport ReactDOM from 'react-dom/client'\nimport { BrowserRouter } from 'react-router-dom'\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query'\nimport App from './App'\nimport { ToastProvider } from './components/Toast'\nimport { ConfirmProvider } from './components/Confirm'\nimport './index.css'\n\nconst queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n refetchOnWindowFocus: false,\n retry: 1,\n },\n },\n})\n\nReactDOM.createRoot(document.getElementById('root')!).render(\n <React.StrictMode>\n <QueryClientProvider client={queryClient}>\n <ToastProvider>\n <ConfirmProvider>\n <BrowserRouter>\n <App />\n </BrowserRouter>\n </ConfirmProvider>\n </ToastProvider>\n </QueryClientProvider>\n </React.StrictMode>,\n)\n"],"file":"assets/index-DJK5beK6.js"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.invisible{visibility:hidden}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.inset-y-0{top:0;bottom:0}.left-0{left:0}.left-2\.5{left:.625rem}.left-4{left:1rem}.right-0{right:0}.right-2{right:.5rem}.right-4{right:1rem}.top-0{top:0}.top-1\/2{top:50%}.top-10{top:2.5rem}.top-4{top:1rem}.-z-10{z-index:-10}.z-10{z-index:10}.z-20{z-index:20}.z-40{z-index:40}.z-50{z-index:50}.z-\[9999\]{z-index:9999}.mx-1{margin-left:.25rem;margin-right:.25rem}.mx-4{margin-left:1rem;margin-right:1rem}.mx-auto{margin-left:auto;margin-right:auto}.my-2{margin-top:.5rem;margin-bottom:.5rem}.mb-0\.5{margin-bottom:.125rem}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.ml-2{margin-left:.5rem}.ml-3{margin-left:.75rem}.ml-4{margin-left:1rem}.ml-8{margin-left:2rem}.ml-auto{margin-left:auto}.mr-1{margin-right:.25rem}.mr-2{margin-right:.5rem}.mr-3{margin-right:.75rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.line-clamp-3{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3}.block{display:block}.\!inline{display:inline!important}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-1\.5{height:.375rem}.h-10{height:2.5rem}.h-12{height:3rem}.h-14{height:3.5rem}.h-2{height:.5rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-60{height:15rem}.h-8{height:2rem}.h-full{height:100%}.max-h-64{max-height:16rem}.max-h-\[500px\]{max-height:500px}.min-h-screen{min-height:100vh}.w-0\.5{width:.125rem}.w-10{width:2.5rem}.w-12{width:3rem}.w-16{width:4rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-56{width:14rem}.w-6{width:1.5rem}.w-64{width:16rem}.w-8{width:2rem}.w-\[600px\]{width:600px}.w-\[800px\]{width:800px}.w-full{width:100%}.min-w-0{min-width:0px}.min-w-full{min-width:100%}.max-w-2xl{max-width:42rem}.max-w-7xl{max-width:80rem}.max-w-full{max-width:100%}.max-w-md{max-width:28rem}.max-w-none{max-width:none}.max-w-xl{max-width:36rem}.max-w-xs{max-width:20rem}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.flex-grow{flex-grow:1}.-translate-y-1\/2{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-0{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-full{--tw-translate-x: 100%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-pointer{cursor:pointer}.list-inside{list-style-position:inside}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.125rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem * var(--tw-space-y-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.divide-gray-200>:not([hidden])~:not([hidden]){--tw-divide-opacity: 1;border-color:rgb(229 231 235 / var(--tw-divide-opacity, 1))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.border{border-width:1px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-l-2{border-left-width:2px}.border-l-4{border-left-width:4px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-amber-300{--tw-border-opacity: 1;border-color:rgb(252 211 77 / var(--tw-border-opacity, 1))}.border-blue-200{--tw-border-opacity: 1;border-color:rgb(191 219 254 / var(--tw-border-opacity, 1))}.border-gray-100{--tw-border-opacity: 1;border-color:rgb(243 244 246 / var(--tw-border-opacity, 1))}.border-gray-200{--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1))}.border-gray-300{--tw-border-opacity: 1;border-color:rgb(209 213 219 / var(--tw-border-opacity, 1))}.border-green-200{--tw-border-opacity: 1;border-color:rgb(187 247 208 / var(--tw-border-opacity, 1))}.border-indigo-200{--tw-border-opacity: 1;border-color:rgb(199 210 254 / var(--tw-border-opacity, 1))}.border-indigo-500{--tw-border-opacity: 1;border-color:rgb(99 102 241 / var(--tw-border-opacity, 1))}.border-orange-200{--tw-border-opacity: 1;border-color:rgb(254 215 170 / var(--tw-border-opacity, 1))}.border-red-200{--tw-border-opacity: 1;border-color:rgb(254 202 202 / var(--tw-border-opacity, 1))}.border-yellow-200{--tw-border-opacity: 1;border-color:rgb(254 240 138 / var(--tw-border-opacity, 1))}.border-t-blue-500{--tw-border-opacity: 1;border-top-color:rgb(59 130 246 / var(--tw-border-opacity, 1))}.bg-amber-100{--tw-bg-opacity: 1;background-color:rgb(254 243 199 / var(--tw-bg-opacity, 1))}.bg-amber-50{--tw-bg-opacity: 1;background-color:rgb(255 251 235 / var(--tw-bg-opacity, 1))}.bg-amber-600{--tw-bg-opacity: 1;background-color:rgb(217 119 6 / var(--tw-bg-opacity, 1))}.bg-black{--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1))}.bg-black\/40{background-color:#0006}.bg-blue-100{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.bg-gray-100{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.bg-gray-200{--tw-bg-opacity: 1;background-color:rgb(229 231 235 / var(--tw-bg-opacity, 1))}.bg-gray-400{--tw-bg-opacity: 1;background-color:rgb(156 163 175 / var(--tw-bg-opacity, 1))}.bg-gray-50{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.bg-gray-600{--tw-bg-opacity: 1;background-color:rgb(75 85 99 / var(--tw-bg-opacity, 1))}.bg-green-100{--tw-bg-opacity: 1;background-color:rgb(220 252 231 / var(--tw-bg-opacity, 1))}.bg-green-300{--tw-bg-opacity: 1;background-color:rgb(134 239 172 / var(--tw-bg-opacity, 1))}.bg-green-50{--tw-bg-opacity: 1;background-color:rgb(240 253 244 / var(--tw-bg-opacity, 1))}.bg-green-500{--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.bg-indigo-100{--tw-bg-opacity: 1;background-color:rgb(224 231 255 / var(--tw-bg-opacity, 1))}.bg-indigo-50{--tw-bg-opacity: 1;background-color:rgb(238 242 255 / var(--tw-bg-opacity, 1))}.bg-indigo-600{--tw-bg-opacity: 1;background-color:rgb(79 70 229 / var(--tw-bg-opacity, 1))}.bg-orange-100{--tw-bg-opacity: 1;background-color:rgb(255 237 213 / var(--tw-bg-opacity, 1))}.bg-purple-100{--tw-bg-opacity: 1;background-color:rgb(243 232 255 / var(--tw-bg-opacity, 1))}.bg-purple-50{--tw-bg-opacity: 1;background-color:rgb(250 245 255 / var(--tw-bg-opacity, 1))}.bg-red-100{--tw-bg-opacity: 1;background-color:rgb(254 226 226 / var(--tw-bg-opacity, 1))}.bg-red-50{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.bg-red-600{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity, 1))}.bg-sky-100{--tw-bg-opacity: 1;background-color:rgb(224 242 254 / var(--tw-bg-opacity, 1))}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-yellow-100{--tw-bg-opacity: 1;background-color:rgb(254 249 195 / var(--tw-bg-opacity, 1))}.bg-yellow-600{--tw-bg-opacity: 1;background-color:rgb(202 138 4 / var(--tw-bg-opacity, 1))}.bg-opacity-0{--tw-bg-opacity: 0}.bg-opacity-50{--tw-bg-opacity: .5}.bg-opacity-75{--tw-bg-opacity: .75}.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}.from-indigo-500{--tw-gradient-from: #6366f1 var(--tw-gradient-from-position);--tw-gradient-to: rgb(99 102 241 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.to-purple-600{--tw-gradient-to: #9333ea var(--tw-gradient-to-position)}.p-1{padding:.25rem}.p-12{padding:3rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-16{padding-top:4rem;padding-bottom:4rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-2{padding-bottom:.5rem}.pb-4{padding-bottom:1rem}.pl-3{padding-left:.75rem}.pl-4{padding-left:1rem}.pl-8{padding-left:2rem}.pr-10{padding-right:2.5rem}.pr-8{padding-right:2rem}.pt-3{padding-top:.75rem}.pt-4{padding-top:1rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.italic{font-style:italic}.leading-relaxed{line-height:1.625}.tracking-wider{letter-spacing:.05em}.text-amber-600{--tw-text-opacity: 1;color:rgb(217 119 6 / var(--tw-text-opacity, 1))}.text-amber-700{--tw-text-opacity: 1;color:rgb(180 83 9 / var(--tw-text-opacity, 1))}.text-amber-800{--tw-text-opacity: 1;color:rgb(146 64 14 / var(--tw-text-opacity, 1))}.text-blue-500{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.text-blue-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.text-blue-700{--tw-text-opacity: 1;color:rgb(29 78 216 / var(--tw-text-opacity, 1))}.text-gray-300{--tw-text-opacity: 1;color:rgb(209 213 219 / var(--tw-text-opacity, 1))}.text-gray-400{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.text-gray-500{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.text-gray-600{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.text-gray-700{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.text-gray-800{--tw-text-opacity: 1;color:rgb(31 41 55 / var(--tw-text-opacity, 1))}.text-gray-900{--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.text-green-500{--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.text-green-600{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.text-green-700{--tw-text-opacity: 1;color:rgb(21 128 61 / var(--tw-text-opacity, 1))}.text-green-800{--tw-text-opacity: 1;color:rgb(22 101 52 / var(--tw-text-opacity, 1))}.text-indigo-600{--tw-text-opacity: 1;color:rgb(79 70 229 / var(--tw-text-opacity, 1))}.text-indigo-700{--tw-text-opacity: 1;color:rgb(67 56 202 / var(--tw-text-opacity, 1))}.text-orange-600{--tw-text-opacity: 1;color:rgb(234 88 12 / var(--tw-text-opacity, 1))}.text-orange-800{--tw-text-opacity: 1;color:rgb(154 52 18 / var(--tw-text-opacity, 1))}.text-purple-600{--tw-text-opacity: 1;color:rgb(147 51 234 / var(--tw-text-opacity, 1))}.text-purple-700{--tw-text-opacity: 1;color:rgb(126 34 206 / var(--tw-text-opacity, 1))}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-red-600{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.text-red-700{--tw-text-opacity: 1;color:rgb(185 28 28 / var(--tw-text-opacity, 1))}.text-red-800{--tw-text-opacity: 1;color:rgb(153 27 27 / var(--tw-text-opacity, 1))}.text-sky-600{--tw-text-opacity: 1;color:rgb(2 132 199 / var(--tw-text-opacity, 1))}.text-sky-700{--tw-text-opacity: 1;color:rgb(3 105 161 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-yellow-500{--tw-text-opacity: 1;color:rgb(234 179 8 / var(--tw-text-opacity, 1))}.text-yellow-600{--tw-text-opacity: 1;color:rgb(202 138 4 / var(--tw-text-opacity, 1))}.text-yellow-700{--tw-text-opacity: 1;color:rgb(161 98 7 / var(--tw-text-opacity, 1))}.underline{text-decoration-line:underline}.opacity-50{opacity:.5}.shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.ring-1{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-amber-200{--tw-ring-opacity: 1;--tw-ring-color: rgb(253 230 138 / var(--tw-ring-opacity, 1))}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-shadow{transition-property:box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-500{transition-duration:.5s}:root{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,PingFang SC,sans-serif;line-height:1.5;font-weight:400;color-scheme:light;font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}body{margin:0;min-height:100vh}.hover\:border-gray-300:hover{--tw-border-opacity: 1;border-color:rgb(209 213 219 / var(--tw-border-opacity, 1))}.hover\:bg-amber-700:hover{--tw-bg-opacity: 1;background-color:rgb(180 83 9 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-100:hover{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-200:hover{--tw-bg-opacity: 1;background-color:rgb(229 231 235 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-50:hover{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.hover\:bg-indigo-700:hover{--tw-bg-opacity: 1;background-color:rgb(67 56 202 / var(--tw-bg-opacity, 1))}.hover\:bg-orange-50:hover{--tw-bg-opacity: 1;background-color:rgb(255 247 237 / var(--tw-bg-opacity, 1))}.hover\:bg-red-50:hover{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.hover\:bg-red-700:hover{--tw-bg-opacity: 1;background-color:rgb(185 28 28 / var(--tw-bg-opacity, 1))}.hover\:bg-yellow-700:hover{--tw-bg-opacity: 1;background-color:rgb(161 98 7 / var(--tw-bg-opacity, 1))}.hover\:text-gray-600:hover{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.hover\:text-gray-700:hover{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.hover\:text-gray-900:hover{--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.hover\:text-indigo-700:hover{--tw-text-opacity: 1;color:rgb(67 56 202 / var(--tw-text-opacity, 1))}.hover\:text-red-600:hover{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.hover\:shadow-md:hover{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.focus\:border-indigo-500:focus{--tw-border-opacity: 1;border-color:rgb(99 102 241 / var(--tw-border-opacity, 1))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-1:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-indigo-500:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(99 102 241 / var(--tw-ring-opacity, 1))}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:bg-gray-400:disabled{--tw-bg-opacity: 1;background-color:rgb(156 163 175 / var(--tw-bg-opacity, 1))}.disabled\:bg-gray-50:disabled{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.disabled\:text-gray-400:disabled{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.disabled\:opacity-50:disabled{opacity:.5}@media (min-width: 640px){.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}}@media (min-width: 768px){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@media (min-width: 1024px){.lg\:fixed{position:fixed}.lg\:inset-y-0{top:0;bottom:0}.lg\:flex{display:flex}.lg\:hidden{display:none}.lg\:w-64{width:16rem}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:flex-col{flex-direction:column}.lg\:px-8{padding-left:2rem;padding-right:2rem}.lg\:pl-64{padding-left:16rem}}
|
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>Claude Forge 管理后台</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-DJK5beK6.js"></script>
|
|
9
9
|
<link rel="modulepreload" crossorigin href="/assets/react-vendor-CSp-GLFF.js">
|
|
10
10
|
<link rel="modulepreload" crossorigin href="/assets/vendor-CMMjVdZs.js">
|
|
11
11
|
<link rel="modulepreload" crossorigin href="/assets/react-router-I-HqunH7.js">
|
|
12
12
|
<link rel="modulepreload" crossorigin href="/assets/query-C99w429o.js">
|
|
13
13
|
<link rel="modulepreload" crossorigin href="/assets/syntax-highlighter-44FakypI.js">
|
|
14
14
|
<link rel="modulepreload" crossorigin href="/assets/lucide-BanPULT1.js">
|
|
15
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
15
|
+
<link rel="stylesheet" crossorigin href="/assets/index-phpuytMI.css">
|
|
16
16
|
</head>
|
|
17
17
|
<body>
|
|
18
18
|
<div id="root"></div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@winspan/claude-forge",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.35.0",
|
|
4
4
|
"description": "SDLC intelligent orchestration engine for Claude Code",
|
|
5
5
|
"main": "dist/cli/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
},
|
|
27
27
|
"scripts": {
|
|
28
28
|
"prebuild": "rm -rf dist",
|
|
29
|
-
"build": "tsc && mkdir -p dist/hooks && cp -r src/hooks/* dist/hooks/ && chmod +x dist/hooks/*.sh && cp src/core/storage/schema.sql dist/core/storage/schema.sql && mkdir -p dist/web/static && cp -r web/dist/* dist/web/static/ 2>/dev/null || cp src/web/static/index.html dist/web/static/ && cp -r src/web/static/vendor dist/web/static/ 2>/dev/null || true && mkdir -p dist/engine/conventions && cp src/engine/conventions/*.yaml dist/engine/conventions/
|
|
29
|
+
"build": "tsc && mkdir -p dist/hooks && cp -r src/hooks/* dist/hooks/ && chmod +x dist/hooks/*.sh && cp src/core/storage/schema.sql dist/core/storage/schema.sql && mkdir -p dist/web/static && cp -r web/dist/* dist/web/static/ 2>/dev/null || cp src/web/static/index.html dist/web/static/ && cp -r src/web/static/vendor dist/web/static/ 2>/dev/null || true && mkdir -p dist/engine/conventions && cp src/engine/conventions/*.yaml dist/engine/conventions/",
|
|
30
30
|
"build:web": "cd web && npm run build",
|
|
31
31
|
"build:all": "npm run build:web && npm run build",
|
|
32
32
|
"prepublishOnly": "npm run build:all",
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ExecutionManager — daemon 进程内单例,统筹所有 methodology_executions 的后台执行。
|
|
3
|
-
*
|
|
4
|
-
* 职责:
|
|
5
|
-
* 1. 提供 `start({session_id, plan, mode})` 入口:为前台/后台两种模式分别使用合适的 executor
|
|
6
|
-
* 2. 跟踪活跃的 orchestrator,让 cancel() 能真正 kill 子进程
|
|
7
|
-
* 3. 在 daemon 启动时扫一遍 listRunningBackgroundExecutions() —— 对应 worker
|
|
8
|
-
* 已不在了(孤儿 execution),标记为 failed("crashed")
|
|
9
|
-
*
|
|
10
|
-
* 不负责:路由决策 / planner / UI。
|
|
11
|
-
*/
|
|
12
|
-
import type { SQLiteStorage } from '../core/storage/sqlite.js';
|
|
13
|
-
import type { MethodologyRegistry } from './methodology-registry.js';
|
|
14
|
-
import type { ExecutionPlan } from './types.js';
|
|
15
|
-
import type { ExecutorEventListener } from './executor/types.js';
|
|
16
|
-
import { type BackgroundExecutorOptions } from './executor/background-executor.js';
|
|
17
|
-
export interface StartExecutionInput {
|
|
18
|
-
session_id: string;
|
|
19
|
-
methodology_id: string;
|
|
20
|
-
plan: ExecutionPlan;
|
|
21
|
-
mode: 'foreground' | 'background';
|
|
22
|
-
trigger_type?: 'manual' | 'idle' | 'scheduled';
|
|
23
|
-
}
|
|
24
|
-
export interface ExecutionManagerOptions {
|
|
25
|
-
background?: BackgroundExecutorOptions;
|
|
26
|
-
/**
|
|
27
|
-
* 判定 methodology_executions 进入 stale 的无推进阈值(ms)。
|
|
28
|
-
* 默认 30 分钟:超过此时长没有任何推进就标 stale。
|
|
29
|
-
*/
|
|
30
|
-
staleThresholdMs?: number;
|
|
31
|
-
}
|
|
32
|
-
export declare class ExecutionManager {
|
|
33
|
-
private storage;
|
|
34
|
-
private registry;
|
|
35
|
-
private foregroundExecutor;
|
|
36
|
-
private backgroundExecutor;
|
|
37
|
-
private activeOrchestrators;
|
|
38
|
-
private listeners;
|
|
39
|
-
private reconcileTimer;
|
|
40
|
-
private readonly staleThresholdMs;
|
|
41
|
-
constructor(storage: SQLiteStorage, registry: MethodologyRegistry, options?: ExecutionManagerOptions);
|
|
42
|
-
/**
|
|
43
|
-
* Create the execution row + kick off orchestrator.
|
|
44
|
-
* Returns the newly created execution id.
|
|
45
|
-
*/
|
|
46
|
-
start(input: StartExecutionInput): number;
|
|
47
|
-
cancel(execution_id: number): Promise<void>;
|
|
48
|
-
/**
|
|
49
|
-
* Subscribe to all executor events. Returns an unsubscribe function.
|
|
50
|
-
*/
|
|
51
|
-
subscribe(listener: ExecutorEventListener): () => void;
|
|
52
|
-
/**
|
|
53
|
-
* At daemon startup: find background executions whose worker_pid is no longer
|
|
54
|
-
* alive. Mark them failed so the UI shows a definitive state.
|
|
55
|
-
*/
|
|
56
|
-
reconcileOrphansOnStartup(): void;
|
|
57
|
-
/**
|
|
58
|
-
* Cross-session residue sweep: find `mode='foreground' AND status='running'`
|
|
59
|
-
* executions whose `started_at` is older than `maxAgeMs`, and mark them
|
|
60
|
-
* `cancelled`. Foreground executions are driven by Claude Code sessions — if
|
|
61
|
-
* the originating session ended without the Stop hook firing (crash, kill,
|
|
62
|
-
* detach, pre-guard legacy data), the row can stay `running` forever and
|
|
63
|
-
* blocks the session-level exclusivity check at UserPromptSubmit.
|
|
64
|
-
*
|
|
65
|
-
* Complements:
|
|
66
|
-
* - `reconcileOrphansOnStartup()` handles background workers (pid-based).
|
|
67
|
-
* - `sweepStaleMethodologies()` is the softer no-progress sweep (30min → `stale`).
|
|
68
|
-
*
|
|
69
|
-
* @param maxAgeMs absolute age since started_at. Default 4h.
|
|
70
|
-
* @returns list of execution ids that were cancelled.
|
|
71
|
-
*/
|
|
72
|
-
cancelStaleForegroundExecutions(maxAgeMs?: number): number[];
|
|
73
|
-
private isPidAlive;
|
|
74
|
-
/**
|
|
75
|
-
* Sweep methodology_executions that are still `running` but haven't made any
|
|
76
|
-
* progress for longer than `staleThresholdMs`. Mark them `stale` so the UI
|
|
77
|
-
* (and downstream schedulers) stop treating them as active.
|
|
78
|
-
*
|
|
79
|
-
* 判定依据:`now - (last_progress_at || started_at) > staleThresholdMs`
|
|
80
|
-
* 非 running 的 execution 一律忽略。
|
|
81
|
-
*
|
|
82
|
-
* 返回被标记为 stale 的 execution id 列表,便于测试 / 观测。
|
|
83
|
-
*/
|
|
84
|
-
sweepStaleMethodologies(now?: number): number[];
|
|
85
|
-
/**
|
|
86
|
-
* Start a periodic reconcile loop — picks up workers killed while daemon
|
|
87
|
-
* was running (e.g. user kill -9'd the pid). Safe to call once at startup.
|
|
88
|
-
* Returns a stop function.
|
|
89
|
-
*
|
|
90
|
-
* @param intervalMs reconcile interval in milliseconds
|
|
91
|
-
* @param idleTriggerCallback optional callback to trigger idle methodologies
|
|
92
|
-
*/
|
|
93
|
-
startReconcileLoop(intervalMs?: number, idleTriggerCallback?: () => Promise<void>): () => void;
|
|
94
|
-
stopReconcileLoop(): void;
|
|
95
|
-
}
|
|
96
|
-
//# sourceMappingURL=execution-manager.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"execution-manager.d.ts","sourceRoot":"","sources":["../../src/capability/execution-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAwB,MAAM,YAAY,CAAC;AACtE,OAAO,KAAK,EAAiB,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAEhF,OAAO,EAAsB,KAAK,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAKvG,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,aAAa,CAAC;IACpB,IAAI,EAAE,YAAY,GAAG,YAAY,CAAC;IAClC,YAAY,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;CAChD;AAED,MAAM,WAAW,uBAAuB;IACtC,UAAU,CAAC,EAAE,yBAAyB,CAAC;IACvC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,qBAAa,gBAAgB;IASzB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,QAAQ;IATlB,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,mBAAmB,CAAmC;IAC9D,OAAO,CAAC,SAAS,CAAoC;IACrD,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;gBAGhC,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,mBAAmB,EACrC,OAAO,GAAE,uBAA4B;IAgBvC;;;OAGG;IACH,KAAK,CAAC,KAAK,EAAE,mBAAmB,GAAG,MAAM;IAmDnC,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASjD;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,qBAAqB,GAAG,MAAM,IAAI;IAKtD;;;OAGG;IACH,yBAAyB,IAAI,IAAI;IAkBjC;;;;;;;;;;;;;;OAcG;IACH,+BAA+B,CAAC,QAAQ,GAAE,MAA2B,GAAG,MAAM,EAAE;IAyBhF,OAAO,CAAC,UAAU;IASlB;;;;;;;;;OASG;IACH,uBAAuB,CAAC,GAAG,GAAE,MAAmB,GAAG,MAAM,EAAE;IAkC3D;;;;;;;OAOG;IACH,kBAAkB,CAAC,UAAU,SAAS,EAAE,mBAAmB,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI;IA4B9F,iBAAiB,IAAI,IAAI;CAI1B"}
|
|
@@ -1,260 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ExecutionManager — daemon 进程内单例,统筹所有 methodology_executions 的后台执行。
|
|
3
|
-
*
|
|
4
|
-
* 职责:
|
|
5
|
-
* 1. 提供 `start({session_id, plan, mode})` 入口:为前台/后台两种模式分别使用合适的 executor
|
|
6
|
-
* 2. 跟踪活跃的 orchestrator,让 cancel() 能真正 kill 子进程
|
|
7
|
-
* 3. 在 daemon 启动时扫一遍 listRunningBackgroundExecutions() —— 对应 worker
|
|
8
|
-
* 已不在了(孤儿 execution),标记为 failed("crashed")
|
|
9
|
-
*
|
|
10
|
-
* 不负责:路由决策 / planner / UI。
|
|
11
|
-
*/
|
|
12
|
-
import { ForegroundExecutor } from './executor/foreground-executor.js';
|
|
13
|
-
import { BackgroundExecutor } from './executor/background-executor.js';
|
|
14
|
-
import { Orchestrator } from './executor/orchestrator.js';
|
|
15
|
-
import { probeWorkerAuth, WorkerAuthError } from './executor/worker-auth-probe.js';
|
|
16
|
-
import { logger } from '../core/utils/logger.js';
|
|
17
|
-
export class ExecutionManager {
|
|
18
|
-
storage;
|
|
19
|
-
registry;
|
|
20
|
-
foregroundExecutor;
|
|
21
|
-
backgroundExecutor;
|
|
22
|
-
activeOrchestrators = new Map();
|
|
23
|
-
listeners = new Set();
|
|
24
|
-
reconcileTimer = null;
|
|
25
|
-
staleThresholdMs;
|
|
26
|
-
constructor(storage, registry, options = {}) {
|
|
27
|
-
this.storage = storage;
|
|
28
|
-
this.registry = registry;
|
|
29
|
-
this.foregroundExecutor = new ForegroundExecutor(storage, registry);
|
|
30
|
-
this.backgroundExecutor = new BackgroundExecutor(storage, registry, options.background);
|
|
31
|
-
this.staleThresholdMs = options.staleThresholdMs ?? 30 * 60 * 1000;
|
|
32
|
-
// Relay executor events to external subscribers (SSE, metrics, ...)
|
|
33
|
-
const relay = (ev) => {
|
|
34
|
-
for (const l of this.listeners) {
|
|
35
|
-
try {
|
|
36
|
-
l(ev);
|
|
37
|
-
}
|
|
38
|
-
catch (err) {
|
|
39
|
-
logger.debug(`[ExecutionManager] relay failed: ${err}`);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
this.foregroundExecutor.subscribe(relay);
|
|
44
|
-
this.backgroundExecutor.subscribe(relay);
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Create the execution row + kick off orchestrator.
|
|
48
|
-
* Returns the newly created execution id.
|
|
49
|
-
*/
|
|
50
|
-
start(input) {
|
|
51
|
-
// 后台模式:前置认证探测,给调用方明确错误而不是等 worker 起来后才报错
|
|
52
|
-
if (input.mode === 'background') {
|
|
53
|
-
const probe = probeWorkerAuth();
|
|
54
|
-
if (!probe.available) {
|
|
55
|
-
throw new WorkerAuthError(probe);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
const executionId = this.storage.createMethodologyExecution({
|
|
59
|
-
session_id: input.session_id,
|
|
60
|
-
methodology_id: input.methodology_id,
|
|
61
|
-
plan_json: JSON.stringify(input.plan),
|
|
62
|
-
mode: input.mode,
|
|
63
|
-
trigger_type: input.trigger_type ?? 'manual',
|
|
64
|
-
});
|
|
65
|
-
// Seed the first phase_executions row so listings show immediately
|
|
66
|
-
if (input.plan.phases[0]) {
|
|
67
|
-
const p0 = input.plan.phases[0];
|
|
68
|
-
this.storage.createPhaseExecution({
|
|
69
|
-
methodology_execution_id: executionId,
|
|
70
|
-
phase_id: p0.id,
|
|
71
|
-
phase_index: 0,
|
|
72
|
-
agent_name: p0.agent,
|
|
73
|
-
prompt: p0.prompt,
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
const executor = input.mode === 'background' ? this.backgroundExecutor : this.foregroundExecutor;
|
|
77
|
-
const orch = new Orchestrator(this.storage, executor);
|
|
78
|
-
this.activeOrchestrators.set(executionId, orch);
|
|
79
|
-
// Fire-and-forget; errors are logged but don't crash the daemon.
|
|
80
|
-
orch.run(executionId)
|
|
81
|
-
.catch(err => {
|
|
82
|
-
logger.warn(`[ExecutionManager] orchestrator for ${executionId} threw: ${err}`);
|
|
83
|
-
try {
|
|
84
|
-
this.storage.updateMethodologyExecution(executionId, {
|
|
85
|
-
status: 'failed',
|
|
86
|
-
completed_at: Date.now(),
|
|
87
|
-
worker_pid: null,
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
catch { /* swallow */ }
|
|
91
|
-
})
|
|
92
|
-
.finally(() => {
|
|
93
|
-
this.activeOrchestrators.delete(executionId);
|
|
94
|
-
});
|
|
95
|
-
return executionId;
|
|
96
|
-
}
|
|
97
|
-
async cancel(execution_id) {
|
|
98
|
-
const exec = this.storage.getMethodologyExecution(execution_id);
|
|
99
|
-
if (!exec)
|
|
100
|
-
throw new Error(`execution ${execution_id} not found`);
|
|
101
|
-
const executor = exec.mode === 'background'
|
|
102
|
-
? this.backgroundExecutor
|
|
103
|
-
: this.foregroundExecutor;
|
|
104
|
-
await executor.cancel(execution_id);
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* Subscribe to all executor events. Returns an unsubscribe function.
|
|
108
|
-
*/
|
|
109
|
-
subscribe(listener) {
|
|
110
|
-
this.listeners.add(listener);
|
|
111
|
-
return () => { this.listeners.delete(listener); };
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* At daemon startup: find background executions whose worker_pid is no longer
|
|
115
|
-
* alive. Mark them failed so the UI shows a definitive state.
|
|
116
|
-
*/
|
|
117
|
-
reconcileOrphansOnStartup() {
|
|
118
|
-
const rows = this.storage.listRunningBackgroundExecutions();
|
|
119
|
-
for (const row of rows) {
|
|
120
|
-
const pid = row.worker_pid;
|
|
121
|
-
const alive = pid ? this.isPidAlive(pid) : false;
|
|
122
|
-
if (!alive) {
|
|
123
|
-
logger.warn(`[ExecutionManager] execution=${row.id} has stale worker_pid=${pid}; marking failed`);
|
|
124
|
-
this.storage.updateMethodologyExecution(row.id, {
|
|
125
|
-
status: 'failed',
|
|
126
|
-
completed_at: Date.now(),
|
|
127
|
-
worker_pid: null,
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Cross-session residue sweep: find `mode='foreground' AND status='running'`
|
|
134
|
-
* executions whose `started_at` is older than `maxAgeMs`, and mark them
|
|
135
|
-
* `cancelled`. Foreground executions are driven by Claude Code sessions — if
|
|
136
|
-
* the originating session ended without the Stop hook firing (crash, kill,
|
|
137
|
-
* detach, pre-guard legacy data), the row can stay `running` forever and
|
|
138
|
-
* blocks the session-level exclusivity check at UserPromptSubmit.
|
|
139
|
-
*
|
|
140
|
-
* Complements:
|
|
141
|
-
* - `reconcileOrphansOnStartup()` handles background workers (pid-based).
|
|
142
|
-
* - `sweepStaleMethodologies()` is the softer no-progress sweep (30min → `stale`).
|
|
143
|
-
*
|
|
144
|
-
* @param maxAgeMs absolute age since started_at. Default 4h.
|
|
145
|
-
* @returns list of execution ids that were cancelled.
|
|
146
|
-
*/
|
|
147
|
-
cancelStaleForegroundExecutions(maxAgeMs = 4 * 60 * 60 * 1000) {
|
|
148
|
-
const now = Date.now();
|
|
149
|
-
const rows = this.storage.listRunningForegroundExecutions();
|
|
150
|
-
const cancelled = [];
|
|
151
|
-
for (const row of rows) {
|
|
152
|
-
const startedAt = row.started_at ?? 0;
|
|
153
|
-
const age = now - startedAt;
|
|
154
|
-
if (age < maxAgeMs)
|
|
155
|
-
continue;
|
|
156
|
-
try {
|
|
157
|
-
this.storage.updateMethodologyExecution(row.id, {
|
|
158
|
-
status: 'cancelled',
|
|
159
|
-
completed_at: now,
|
|
160
|
-
});
|
|
161
|
-
cancelled.push(row.id);
|
|
162
|
-
logger.warn(`[ExecutionManager] execution=${row.id} session=${row.session_id} ` +
|
|
163
|
-
`foreground residue age=${Math.round(age / 60000)}min > ${Math.round(maxAgeMs / 60000)}min — marked cancelled`);
|
|
164
|
-
}
|
|
165
|
-
catch (err) {
|
|
166
|
-
logger.warn(`[ExecutionManager] cross-session cancel failed for execution=${row.id}: ${err}`);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
return cancelled;
|
|
170
|
-
}
|
|
171
|
-
isPidAlive(pid) {
|
|
172
|
-
try {
|
|
173
|
-
process.kill(pid, 0);
|
|
174
|
-
return true;
|
|
175
|
-
}
|
|
176
|
-
catch {
|
|
177
|
-
return false;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* Sweep methodology_executions that are still `running` but haven't made any
|
|
182
|
-
* progress for longer than `staleThresholdMs`. Mark them `stale` so the UI
|
|
183
|
-
* (and downstream schedulers) stop treating them as active.
|
|
184
|
-
*
|
|
185
|
-
* 判定依据:`now - (last_progress_at || started_at) > staleThresholdMs`
|
|
186
|
-
* 非 running 的 execution 一律忽略。
|
|
187
|
-
*
|
|
188
|
-
* 返回被标记为 stale 的 execution id 列表,便于测试 / 观测。
|
|
189
|
-
*/
|
|
190
|
-
sweepStaleMethodologies(now = Date.now()) {
|
|
191
|
-
const rows = this.storage.getDatabase().prepare(`SELECT id, status, started_at, last_progress_at
|
|
192
|
-
FROM methodology_executions
|
|
193
|
-
WHERE status = 'running'`).all();
|
|
194
|
-
const marked = [];
|
|
195
|
-
for (const row of rows) {
|
|
196
|
-
const reference = row.last_progress_at ?? row.started_at;
|
|
197
|
-
if (reference == null)
|
|
198
|
-
continue;
|
|
199
|
-
if (now - reference <= this.staleThresholdMs)
|
|
200
|
-
continue;
|
|
201
|
-
try {
|
|
202
|
-
this.storage.updateMethodologyExecution(row.id, {
|
|
203
|
-
status: 'stale',
|
|
204
|
-
completed_at: now,
|
|
205
|
-
});
|
|
206
|
-
marked.push(row.id);
|
|
207
|
-
logger.warn(`[ExecutionManager] execution=${row.id} marked stale (no progress for ${Math.round((now - reference) / 60_000)}min)`);
|
|
208
|
-
}
|
|
209
|
-
catch (err) {
|
|
210
|
-
logger.warn(`[ExecutionManager] failed to mark execution=${row.id} stale: ${err}`);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
return marked;
|
|
214
|
-
}
|
|
215
|
-
/**
|
|
216
|
-
* Start a periodic reconcile loop — picks up workers killed while daemon
|
|
217
|
-
* was running (e.g. user kill -9'd the pid). Safe to call once at startup.
|
|
218
|
-
* Returns a stop function.
|
|
219
|
-
*
|
|
220
|
-
* @param intervalMs reconcile interval in milliseconds
|
|
221
|
-
* @param idleTriggerCallback optional callback to trigger idle methodologies
|
|
222
|
-
*/
|
|
223
|
-
startReconcileLoop(intervalMs = 60_000, idleTriggerCallback) {
|
|
224
|
-
if (this.reconcileTimer)
|
|
225
|
-
clearInterval(this.reconcileTimer);
|
|
226
|
-
this.reconcileTimer = setInterval(() => {
|
|
227
|
-
try {
|
|
228
|
-
this.reconcileOrphansOnStartup();
|
|
229
|
-
}
|
|
230
|
-
catch (err) {
|
|
231
|
-
logger.debug(`[ExecutionManager] periodic reconcile failed: ${err}`);
|
|
232
|
-
}
|
|
233
|
-
try {
|
|
234
|
-
this.sweepStaleMethodologies();
|
|
235
|
-
}
|
|
236
|
-
catch (err) {
|
|
237
|
-
logger.debug(`[ExecutionManager] periodic stale sweep failed: ${err}`);
|
|
238
|
-
}
|
|
239
|
-
// Trigger idle methodologies if callback provided
|
|
240
|
-
if (idleTriggerCallback) {
|
|
241
|
-
idleTriggerCallback().catch(err => {
|
|
242
|
-
logger.debug(`[ExecutionManager] idle trigger callback failed: ${err}`);
|
|
243
|
-
});
|
|
244
|
-
}
|
|
245
|
-
}, intervalMs);
|
|
246
|
-
// Don't keep the event loop alive just for this.
|
|
247
|
-
this.reconcileTimer.unref?.();
|
|
248
|
-
return () => {
|
|
249
|
-
if (this.reconcileTimer)
|
|
250
|
-
clearInterval(this.reconcileTimer);
|
|
251
|
-
this.reconcileTimer = null;
|
|
252
|
-
};
|
|
253
|
-
}
|
|
254
|
-
stopReconcileLoop() {
|
|
255
|
-
if (this.reconcileTimer)
|
|
256
|
-
clearInterval(this.reconcileTimer);
|
|
257
|
-
this.reconcileTimer = null;
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
//# sourceMappingURL=execution-manager.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"execution-manager.js","sourceRoot":"","sources":["../../src/capability/execution-manager.ts"],"names":[],"mappings":"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"}
|