@aion0/forge 0.5.26 → 0.5.27
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/.forge/worktrees/pipeline-4dd8dc2d/CLAUDE.md +86 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/README.md +136 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/RELEASE_NOTES.md +36 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/agents/route.ts +17 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/auth/[...nextauth]/route.ts +3 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/auth/verify/route.ts +46 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/claude/[id]/route.ts +31 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/claude/[id]/stream/route.ts +63 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/claude/route.ts +28 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/claude-sessions/[projectName]/entries/route.ts +23 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/claude-sessions/[projectName]/live/route.ts +72 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/claude-sessions/[projectName]/route.ts +37 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/claude-sessions/sync/route.ts +17 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/claude-templates/route.ts +145 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/code/route.ts +299 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/delivery/[id]/route.ts +62 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/delivery/route.ts +40 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/detect-cli/route.ts +46 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/docs/route.ts +176 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/docs/sessions/route.ts +54 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/favorites/route.ts +26 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/flows/route.ts +6 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/flows/run/route.ts +19 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/git/route.ts +149 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/help/route.ts +84 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/issue-scanner/route.ts +116 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/logs/route.ts +100 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/mobile-chat/route.ts +115 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/monitor/route.ts +74 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/notifications/route.ts +42 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/notify/test/route.ts +33 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/online/route.ts +40 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/pipelines/[id]/route.ts +41 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/pipelines/route.ts +90 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/plugins/route.ts +75 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/preview/[...path]/route.ts +64 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/preview/route.ts +156 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/project-pipelines/route.ts +91 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/project-sessions/route.ts +61 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/projects/route.ts +26 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/sessions/[id]/chat/route.ts +64 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/sessions/[id]/messages/route.ts +9 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/sessions/[id]/route.ts +17 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/sessions/route.ts +20 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/settings/route.ts +64 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/skills/local/route.ts +228 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/skills/route.ts +182 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/smith-templates/route.ts +81 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/status/route.ts +12 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/tabs/route.ts +25 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/tasks/[id]/route.ts +51 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/tasks/[id]/stream/route.ts +77 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/tasks/link/route.ts +37 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/tasks/route.ts +44 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/tasks/session/route.ts +14 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/telegram/route.ts +23 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/templates/route.ts +6 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/terminal-bell/route.ts +39 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/terminal-cwd/route.ts +19 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/terminal-state/route.ts +15 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/tunnel/route.ts +26 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/upgrade/route.ts +43 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/usage/route.ts +20 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/version/route.ts +78 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/watchers/route.ts +33 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/workspace/[id]/agents/route.ts +35 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/workspace/[id]/memory/route.ts +23 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/workspace/[id]/smith/route.ts +22 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/workspace/[id]/stream/route.ts +31 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/api/workspace/route.ts +79 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/global-error.tsx +21 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/globals.css +52 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/icon.ico +0 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/icon.png +0 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/icon.svg +106 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/layout.tsx +17 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/login/LoginForm.tsx +96 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/login/page.tsx +10 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/mobile/page.tsx +10 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/app/page.tsx +22 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/bin/forge-server.mjs +484 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/check-forge-status.sh +71 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/cli/mw.ts +579 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/BrowserPanel.tsx +175 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/ChatPanel.tsx +191 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/ClaudeTerminal.tsx +267 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/CodeViewer.tsx +787 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/ConversationEditor.tsx +411 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/ConversationGraphView.tsx +347 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/ConversationTerminalView.tsx +303 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/Dashboard.tsx +807 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/DashboardWrapper.tsx +9 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/DeliveryFlowEditor.tsx +491 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/DeliveryList.tsx +230 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/DeliveryWorkspace.tsx +589 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/DocTerminal.tsx +187 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/DocsViewer.tsx +574 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/HelpDialog.tsx +169 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/HelpTerminal.tsx +141 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/InlinePipelineView.tsx +111 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/LogViewer.tsx +194 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/MarkdownContent.tsx +73 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/MobileView.tsx +385 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/MonitorPanel.tsx +122 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/NewSessionModal.tsx +93 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/NewTaskModal.tsx +492 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/PipelineEditor.tsx +570 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/PipelineView.tsx +1018 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/PluginsPanel.tsx +472 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/ProjectDetail.tsx +1618 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/ProjectList.tsx +108 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/ProjectManager.tsx +401 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/SessionList.tsx +74 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/SessionView.tsx +726 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/SettingsModal.tsx +1647 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/SkillsPanel.tsx +969 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/StatusBar.tsx +99 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/TabBar.tsx +46 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/TaskBoard.tsx +113 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/TaskDetail.tsx +372 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/TerminalLauncher.tsx +398 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/TunnelToggle.tsx +206 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/UsagePanel.tsx +207 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/WebTerminal.tsx +1743 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/WorkspaceTree.tsx +221 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/components/WorkspaceView.tsx +4048 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/dev-test.sh +5 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/docs/Forge_Memory_Layer_Design.docx +0 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/docs/Forge_Strategy_Research_2026.docx +0 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/docs/LOCAL-DEPLOY.md +144 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/docs/roadmap-multi-agent-workflow.md +330 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/forge-logo.png +0 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/forge-logo.svg +106 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/hooks/useSidebarResize.ts +52 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/install.sh +29 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/instrumentation.ts +35 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/agents/claude-adapter.ts +104 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/agents/generic-adapter.ts +64 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/agents/index.ts +245 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/agents/types.ts +70 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/artifacts.ts +106 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/auth.ts +62 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/builtin-plugins/docker.yaml +70 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/builtin-plugins/http.yaml +66 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/builtin-plugins/jenkins.yaml +92 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/builtin-plugins/llm-vision.yaml +85 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/builtin-plugins/playwright.yaml +111 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/builtin-plugins/shell-command.yaml +60 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/builtin-plugins/slack.yaml +48 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/builtin-plugins/webhook.yaml +56 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/claude-process.ts +361 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/claude-sessions.ts +266 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/claude-templates.ts +227 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/cloudflared.ts +424 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/crypto.ts +67 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/delivery.ts +787 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/dirs.ts +99 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/flows.ts +86 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/forge-mcp-server.ts +732 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/forge-skills/forge-inbox.md +38 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/forge-skills/forge-send.md +47 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/forge-skills/forge-status.md +32 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/forge-skills/forge-workspace-sync.md +37 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/help-docs/00-overview.md +40 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/help-docs/01-settings.md +194 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/help-docs/02-telegram.md +41 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/help-docs/03-tunnel.md +31 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/help-docs/04-tasks.md +52 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/help-docs/05-pipelines.md +460 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/help-docs/06-skills.md +43 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/help-docs/07-projects.md +73 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/help-docs/08-rules.md +53 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/help-docs/09-issue-autofix.md +55 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/help-docs/10-troubleshooting.md +89 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/help-docs/11-workspace.md +810 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/help-docs/CLAUDE.md +62 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/init.ts +266 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/issue-scanner.ts +298 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/logger.ts +79 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/notifications.ts +75 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/notify.ts +108 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/password.ts +97 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/pipeline-scheduler.ts +373 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/pipeline.ts +1565 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/plugins/executor.ts +347 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/plugins/registry.ts +228 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/plugins/types.ts +103 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/project-sessions.ts +53 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/projects.ts +86 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/session-manager.ts +156 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/session-utils.ts +53 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/session-watcher.ts +345 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/settings.ts +195 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/skills.ts +458 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/task-manager.ts +951 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/telegram-bot.ts +1477 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/telegram-standalone.ts +83 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/terminal-server.ts +70 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/terminal-standalone.ts +438 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/usage-scanner.ts +249 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/workspace/__tests__/state-machine.test.ts +388 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/workspace/__tests__/workspace.test.ts +311 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/workspace/agent-bus.ts +416 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/workspace/agent-worker.ts +655 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/workspace/backends/api-backend.ts +262 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/workspace/backends/cli-backend.ts +491 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/workspace/index.ts +84 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/workspace/manager.ts +136 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/workspace/orchestrator.ts +3415 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/workspace/persistence.ts +309 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/workspace/presets.ts +649 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/workspace/requests.ts +287 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/workspace/session-monitor.ts +240 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/workspace/skill-installer.ts +275 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/workspace/smith-memory.ts +498 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/workspace/types.ts +241 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/workspace/watch-manager.ts +560 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/lib/workspace-standalone.ts +978 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/middleware.ts +51 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/next.config.ts +26 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/package.json +74 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/pnpm-lock.yaml +3719 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/pnpm-workspace.yaml +1 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/postcss.config.mjs +7 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/publish.sh +133 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/scripts/bench/README.md +66 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/scripts/bench/results/.gitignore +2 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/scripts/bench/run.ts +635 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/scripts/bench/tasks/01-text-utils/task.md +26 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/scripts/bench/tasks/01-text-utils/validator.sh +46 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/scripts/bench/tasks/02-pagination/setup.sh +19 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/scripts/bench/tasks/02-pagination/task.md +48 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/scripts/bench/tasks/02-pagination/validator.sh +69 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/scripts/bench/tasks/03-bug-fix/setup.sh +82 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/scripts/bench/tasks/03-bug-fix/task.md +30 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/scripts/bench/tasks/03-bug-fix/validator.sh +29 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/scripts/verify-usage.ts +178 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/src/config/index.ts +129 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/src/core/db/database.ts +259 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/src/core/memory/strategy.ts +32 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/src/core/providers/chat.ts +65 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/src/core/providers/registry.ts +60 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/src/core/session/manager.ts +190 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/src/types/index.ts +129 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/start.sh +32 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/templates/smith-lead.json +45 -0
- package/.forge/worktrees/pipeline-4dd8dc2d/tsconfig.json +42 -0
- package/RELEASE_NOTES.md +11 -28
- package/app/api/terminal-bell/route.ts +6 -2
- package/components/WebTerminal.tsx +36 -2
- package/lib/terminal-standalone.ts +19 -2
- package/next-env.d.ts +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
## Project: Forge (@aion0/forge)
|
|
2
|
+
|
|
3
|
+
### Scripts
|
|
4
|
+
```bash
|
|
5
|
+
# ── Start ──
|
|
6
|
+
./start.sh # production (kill old processes → build → start)
|
|
7
|
+
./start.sh dev # development (hot-reload)
|
|
8
|
+
forge server start # production via npm link/install
|
|
9
|
+
forge server start --dev # dev mode
|
|
10
|
+
forge server start # background by default, logs to ~/.forge/forge.log
|
|
11
|
+
forge server start --foreground # foreground mode
|
|
12
|
+
forge server stop # stop default instance (port 8403)
|
|
13
|
+
forge server stop --port 4000 --dir ~/.forge-staging # stop specific instance
|
|
14
|
+
forge server restart # stop + start (safe for remote)
|
|
15
|
+
forge server rebuild # force rebuild
|
|
16
|
+
forge server start --port 4000 --terminal-port 4001 --dir ~/.forge-staging
|
|
17
|
+
forge server start --reset-terminal # kill terminal server (loses tmux attach)
|
|
18
|
+
forge --version # show version
|
|
19
|
+
|
|
20
|
+
# ── Test ──
|
|
21
|
+
./dev-test.sh # test instance (port 4000, data ~/.forge-test)
|
|
22
|
+
|
|
23
|
+
# ── Install ──
|
|
24
|
+
./install.sh # install from npm
|
|
25
|
+
./install.sh --local # install from local source (npm link + build)
|
|
26
|
+
|
|
27
|
+
# ── Publish ──
|
|
28
|
+
./publish.sh # bump patch version, commit, tag
|
|
29
|
+
./publish.sh minor # bump minor
|
|
30
|
+
./publish.sh 1.0.0 # explicit version
|
|
31
|
+
npm login && npm publish --access public --otp=<code>
|
|
32
|
+
|
|
33
|
+
# ── Monitor ──
|
|
34
|
+
./check-forge-status.sh # show process status + tmux sessions
|
|
35
|
+
|
|
36
|
+
# ── CLI ──
|
|
37
|
+
forge # help
|
|
38
|
+
forge --version # show version
|
|
39
|
+
forge tcode # show tunnel URL + session code
|
|
40
|
+
forge tasks # list tasks
|
|
41
|
+
forge task <project> "prompt" # submit task
|
|
42
|
+
forge watch <id> # live stream task output
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Key Paths
|
|
46
|
+
- Data: `~/.forge/` (settings, db, password, terminal-state, flows, bin)
|
|
47
|
+
- npm package: `@aion0/forge`
|
|
48
|
+
- GitHub: `github.com/aiwatching/forge`
|
|
49
|
+
|
|
50
|
+
### Help Docs Rule
|
|
51
|
+
When adding or changing a feature, check if `lib/help-docs/` needs updating. Each file covers one module:
|
|
52
|
+
- `00-overview.md` — install, start, data paths
|
|
53
|
+
- `01-settings.md` — all settings fields
|
|
54
|
+
- `02-telegram.md` — bot setup and commands
|
|
55
|
+
- `03-tunnel.md` — remote access
|
|
56
|
+
- `04-tasks.md` — background tasks
|
|
57
|
+
- `05-pipelines.md` — DAG workflows
|
|
58
|
+
- `06-skills.md` — marketplace
|
|
59
|
+
- `07-projects.md` — project management
|
|
60
|
+
- `08-rules.md` — CLAUDE.md templates
|
|
61
|
+
- `09-issue-autofix.md` — GitHub issue scanner
|
|
62
|
+
- `10-troubleshooting.md` — common issues
|
|
63
|
+
If a feature change affects user-facing behavior, update the corresponding help doc in the same commit.
|
|
64
|
+
|
|
65
|
+
### Architecture
|
|
66
|
+
- `forge-server.mjs` starts: Next.js + terminal-standalone + telegram-standalone
|
|
67
|
+
- `pnpm dev` / `start.sh dev` starts: Next.js (init.ts spawns terminal + telegram)
|
|
68
|
+
- `FORGE_EXTERNAL_SERVICES=1` → init.ts skips spawning (forge-server manages them)
|
|
69
|
+
|
|
70
|
+
## Obsidian Vault
|
|
71
|
+
Location: /Users/zliu/MyDocuments/obsidian-project/Projects/Bastion
|
|
72
|
+
When I ask about my notes, use bash to search and read files from this directory.
|
|
73
|
+
Example: find /Users/zliu/MyDocuments/obsidian-project -name "*.md" | head -20
|
|
74
|
+
|
|
75
|
+
<!-- forge:template:obsidian-vault -->
|
|
76
|
+
## Obsidian Vault
|
|
77
|
+
When I ask about my notes, use bash to search and read files from the vault directory.
|
|
78
|
+
Example: find <vault_path> -name "*.md" | head -20
|
|
79
|
+
<!-- /forge:template:obsidian-vault -->
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
<!-- FORGE:BEGIN -->
|
|
83
|
+
## Forge Workspace Integration
|
|
84
|
+
When you finish processing a task or message from Forge, end your final response with the marker: [FORGE_DONE]
|
|
85
|
+
This helps Forge detect task completion. Do not include this marker if you are still working.
|
|
86
|
+
<!-- FORGE:END -->
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="app/icon.ico" width="80" height="80" alt="Forge">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">Forge</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>Self-hosted Vibe Coding platform for Claude Code</strong><br>
|
|
9
|
+
Browser terminal · AI tasks · Remote access · Telegram bot
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
<p align="center">
|
|
13
|
+
<a href="https://www.npmjs.com/package/@aion0/forge"><img src="https://img.shields.io/npm/v/@aion0/forge" alt="npm"></a>
|
|
14
|
+
<a href="https://github.com/aiwatching/forge/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/@aion0/forge" alt="MIT"></a>
|
|
15
|
+
<a href="https://github.com/aiwatching/forge"><img src="https://img.shields.io/github/stars/aiwatching/forge?style=social" alt="stars"></a>
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
|
+
<p align="center">
|
|
19
|
+
<a href="https://www.youtube.com/watch?v=F3fiSiP3pZY">Watch Demo →</a>
|
|
20
|
+
</p>
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Demo & Install Guide
|
|
25
|
+
|
|
26
|
+
[](https://www.youtube.com/watch?v=F3fiSiP3pZY)
|
|
27
|
+
|
|
28
|
+
## Install
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install -g @aion0/forge
|
|
32
|
+
forge server start
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Open `http://localhost:8403`. First launch prompts you to set an admin password.
|
|
36
|
+
|
|
37
|
+
**Requirements:** Node.js ≥ 20, tmux, [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code)
|
|
38
|
+
|
|
39
|
+
## What is Forge?
|
|
40
|
+
|
|
41
|
+
Forge turns Claude Code into a remote-accessible coding platform. Run it on your machine, access from any device.
|
|
42
|
+
|
|
43
|
+
- **Vibe Code anywhere** — iPad, phone, any browser. Persistent tmux sessions survive refresh/restart
|
|
44
|
+
- **Background AI tasks** — Submit prompts that run while you sleep. Live output, cost tracking
|
|
45
|
+
- **Pipeline workflows** — Chain Claude Code steps in YAML (design → implement → review)
|
|
46
|
+
- **Remote access** — One-click Cloudflare Tunnel, no account needed
|
|
47
|
+
- **Telegram bot** — Create tasks, check status, take notes from your phone
|
|
48
|
+
- **Skills marketplace** — Browse & install Claude Code slash commands
|
|
49
|
+
|
|
50
|
+
No API keys required. Uses your existing Claude Code subscription. Code never leaves your machine.
|
|
51
|
+
|
|
52
|
+
## Multi-Agent Workspace <sup>v0.5.0</sup>
|
|
53
|
+
|
|
54
|
+
Define agent teams with roles, dependencies, and steps. Agents run as daemons and communicate via a structured message bus.
|
|
55
|
+
|
|
56
|
+
```mermaid
|
|
57
|
+
graph LR
|
|
58
|
+
Input["📋 Requirements"] --> PM["🎯 PM"]
|
|
59
|
+
PM --> Eng["🔨 Engineer"]
|
|
60
|
+
Eng --> QA["🧪 QA"]
|
|
61
|
+
Eng --> Rev["👁 Reviewer"]
|
|
62
|
+
QA --> Rev
|
|
63
|
+
|
|
64
|
+
style Input fill:#f0883e,stroke:#f0883e,color:#fff
|
|
65
|
+
style PM fill:#a371f7,stroke:#a371f7,color:#fff
|
|
66
|
+
style Eng fill:#58a6ff,stroke:#58a6ff,color:#fff
|
|
67
|
+
style QA fill:#3fb950,stroke:#3fb950,color:#fff
|
|
68
|
+
style Rev fill:#f778ba,stroke:#f778ba,color:#fff
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
- **Agent profiles** — Reusable configs with env vars, model overrides, custom API endpoints (Claude, Codex, Aider)
|
|
72
|
+
- **Message system** — Notifications (follow DAG) + Tickets (any direction, retry limits) with causedBy tracing
|
|
73
|
+
- **Manual mode** — Open a terminal on any agent, work interactively, return to auto
|
|
74
|
+
- **Watch manager** — Monitor files, git, or commands. Auto-analyze or require approval on changes
|
|
75
|
+
|
|
76
|
+
## Features
|
|
77
|
+
|
|
78
|
+
| | |
|
|
79
|
+
|---|---|
|
|
80
|
+
| **Multi-Agent Workspace** | Agent teams with DAG dependencies, message bus, watch monitoring, manual/auto mode |
|
|
81
|
+
| **Vibe Coding** | Browser tmux terminal, multi-tab, split panes, WebGL, Ctrl+F search |
|
|
82
|
+
| **AI Tasks** | Background Claude Code execution with live streaming output |
|
|
83
|
+
| **Pipelines** | YAML DAG workflows with parallel execution & visual editor |
|
|
84
|
+
| **Remote Access** | Cloudflare Tunnel with 2FA (password + session code) |
|
|
85
|
+
| **Docs Viewer** | Obsidian / markdown rendering with AI assistant |
|
|
86
|
+
| **Projects** | File browser, git operations, code viewer with syntax highlighting, diff view |
|
|
87
|
+
| **Skills** | Marketplace for skills & commands — browse, install, update, version tracking |
|
|
88
|
+
| **Telegram** | Tasks, sessions, notes, tunnel control from mobile |
|
|
89
|
+
| **CLI** | `forge task`, `forge watch`, `forge status`, and more |
|
|
90
|
+
|
|
91
|
+
## Quick Start
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
forge server start # start (background by default)
|
|
95
|
+
forge server start --foreground # run in foreground
|
|
96
|
+
forge server start --dev # dev mode with hot-reload
|
|
97
|
+
forge server stop # stop
|
|
98
|
+
forge server restart # restart
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### From source
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
git clone https://github.com/aiwatching/forge.git
|
|
105
|
+
cd forge && pnpm install
|
|
106
|
+
./start.sh # production
|
|
107
|
+
./start.sh dev # development
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## CLI
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
forge task <project> <prompt> # submit a task
|
|
114
|
+
forge tasks # list tasks
|
|
115
|
+
forge watch <id> # live stream output
|
|
116
|
+
forge status # process status
|
|
117
|
+
forge tcode # show tunnel URL + session code
|
|
118
|
+
forge projects # list projects
|
|
119
|
+
forge flows # list workflows
|
|
120
|
+
forge run <flow> # run a workflow
|
|
121
|
+
forge --reset-password # reset admin password
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Telegram Bot
|
|
125
|
+
|
|
126
|
+
Create a bot via [@BotFather](https://t.me/botfather), add the token in Settings.
|
|
127
|
+
|
|
128
|
+
`/task` — create task · `/tasks` — list · `/sessions` — AI summary · `/note` — quick note · `/tunnel_start` — start tunnel · `/watch` — monitor session
|
|
129
|
+
|
|
130
|
+
## Data
|
|
131
|
+
|
|
132
|
+
All data in `~/.forge/` — settings, database, terminal state, workflows, logs. Configurable via `--dir` flag.
|
|
133
|
+
|
|
134
|
+
## License
|
|
135
|
+
|
|
136
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Forge v0.5.26
|
|
2
|
+
|
|
3
|
+
Released: 2026-04-06
|
|
4
|
+
|
|
5
|
+
## Changes since v0.5.25
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
- feat: add review-mr as builtin pipeline
|
|
9
|
+
- feat: all pipeline steps use worktree, no shell mode exception
|
|
10
|
+
- feat: pipeline steps auto-use git worktree for isolated execution
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
- fix: pipeline tasks use same model as normal tasks, no pipelineModel override
|
|
14
|
+
- fix: task model selection — treat 'default' as fall-through
|
|
15
|
+
- fix: ignore stdin + parse worktree field in pipeline nodes
|
|
16
|
+
- fix: spawn claude without shell, resolve path via which
|
|
17
|
+
- fix: remove shell: '/bin/zsh' from claude spawn to prevent arg interpretation
|
|
18
|
+
- fix: all pipeline steps use worktree, shell gets env vars
|
|
19
|
+
- fix: all pipeline steps use worktree, shell gets env vars
|
|
20
|
+
- fix: shell/plugin pipeline steps skip worktree, run in project dir
|
|
21
|
+
- fix: only auto-worktree for agent/prompt mode, not shell steps
|
|
22
|
+
- fix: resolve rebase conflicts and fix anti-loop guard in messaging
|
|
23
|
+
|
|
24
|
+
### Documentation
|
|
25
|
+
- docs: update pipeline help with worktree env vars for shell steps
|
|
26
|
+
|
|
27
|
+
### Other
|
|
28
|
+
- try some fixes 2
|
|
29
|
+
- try some fixes
|
|
30
|
+
- daemon is exclusive writer of state.json
|
|
31
|
+
- skip auth in dev mode
|
|
32
|
+
- fix terminal copy/paste and selection
|
|
33
|
+
- add noreply and inbox to workspace messaging
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
**Full Changelog**: https://github.com/aiwatching/forge/compare/v0.5.25...v0.5.26
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { NextResponse } from 'next/server';
|
|
2
|
+
import { listAgents, getDefaultAgentId, resolveTerminalLaunch } from '@/lib/agents';
|
|
3
|
+
|
|
4
|
+
export async function GET(req: Request) {
|
|
5
|
+
const url = new URL(req.url);
|
|
6
|
+
const resolve = url.searchParams.get('resolve');
|
|
7
|
+
|
|
8
|
+
// GET /api/agents?resolve=claude → resolve terminal launch info for an agent
|
|
9
|
+
if (resolve) {
|
|
10
|
+
const info = resolveTerminalLaunch(resolve);
|
|
11
|
+
return NextResponse.json(info);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const agents = listAgents();
|
|
15
|
+
const defaultAgent = getDefaultAgentId();
|
|
16
|
+
return NextResponse.json({ agents, defaultAgent });
|
|
17
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { NextResponse } from 'next/server';
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
3
|
+
|
|
4
|
+
// In-memory valid tokens — shared across API routes in the same process
|
|
5
|
+
const tokenKey = Symbol.for('forge-api-tokens');
|
|
6
|
+
const g = globalThis as any;
|
|
7
|
+
if (!g[tokenKey]) g[tokenKey] = new Set<string>();
|
|
8
|
+
export const validTokens: Set<string> = g[tokenKey];
|
|
9
|
+
|
|
10
|
+
/** Verify a token is valid (for use in other API routes) */
|
|
11
|
+
export function isValidToken(req: Request): boolean {
|
|
12
|
+
// Check header
|
|
13
|
+
const headerToken = new Headers(req.headers).get('x-forge-token');
|
|
14
|
+
if (headerToken && validTokens.has(headerToken)) return true;
|
|
15
|
+
// Check cookie
|
|
16
|
+
const cookieHeader = new Headers(req.headers).get('cookie') || '';
|
|
17
|
+
const match = cookieHeader.match(/forge-api-token=([^;]+)/);
|
|
18
|
+
if (match && validTokens.has(match[1])) return true;
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export async function POST(req: Request) {
|
|
23
|
+
const body = await req.json();
|
|
24
|
+
const { password } = body;
|
|
25
|
+
|
|
26
|
+
if (!password) {
|
|
27
|
+
return NextResponse.json({ error: 'password required' }, { status: 400 });
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const { verifyAdmin } = await import('@/lib/password');
|
|
31
|
+
if (!verifyAdmin(password)) {
|
|
32
|
+
return NextResponse.json({ error: 'invalid password' }, { status: 401 });
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const token = randomUUID();
|
|
36
|
+
validTokens.add(token);
|
|
37
|
+
|
|
38
|
+
const res = NextResponse.json({ ok: true, token });
|
|
39
|
+
res.cookies.set('forge-api-token', token, {
|
|
40
|
+
httpOnly: true,
|
|
41
|
+
sameSite: 'lax',
|
|
42
|
+
maxAge: 86400,
|
|
43
|
+
path: '/',
|
|
44
|
+
});
|
|
45
|
+
return res;
|
|
46
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { NextResponse } from 'next/server';
|
|
2
|
+
import { getProcess, sendToClaudeSession, killProcess } from '@/lib/claude-process';
|
|
3
|
+
|
|
4
|
+
// Get session info
|
|
5
|
+
export async function GET(_req: Request, { params }: { params: Promise<{ id: string }> }) {
|
|
6
|
+
const { id } = await params;
|
|
7
|
+
const proc = getProcess(id);
|
|
8
|
+
if (!proc) return NextResponse.json({ error: 'Not found' }, { status: 404 });
|
|
9
|
+
return NextResponse.json(proc);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// Send a message to the Claude session
|
|
13
|
+
export async function POST(req: Request, { params }: { params: Promise<{ id: string }> }) {
|
|
14
|
+
const { id } = await params;
|
|
15
|
+
const body = await req.json();
|
|
16
|
+
|
|
17
|
+
if (body.type === 'message') {
|
|
18
|
+
const ok = sendToClaudeSession(id, body.content, body.conversationId);
|
|
19
|
+
if (!ok) {
|
|
20
|
+
return NextResponse.json({ error: 'Session not found or already running' }, { status: 400 });
|
|
21
|
+
}
|
|
22
|
+
return NextResponse.json({ ok: true });
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (body.type === 'kill') {
|
|
26
|
+
killProcess(id);
|
|
27
|
+
return NextResponse.json({ ok: true });
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return NextResponse.json({ error: 'Unknown type' }, { status: 400 });
|
|
31
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { attachToProcess } from '@/lib/claude-process';
|
|
2
|
+
|
|
3
|
+
export const dynamic = 'force-dynamic';
|
|
4
|
+
export const runtime = 'nodejs';
|
|
5
|
+
|
|
6
|
+
// SSE stream of Claude Code structured messages
|
|
7
|
+
export async function GET(_req: Request, { params }: { params: Promise<{ id: string }> }) {
|
|
8
|
+
const { id } = await params;
|
|
9
|
+
|
|
10
|
+
const encoder = new TextEncoder();
|
|
11
|
+
let unsubscribe: (() => void) | null = null;
|
|
12
|
+
let heartbeat: ReturnType<typeof setInterval> | null = null;
|
|
13
|
+
let closed = false;
|
|
14
|
+
|
|
15
|
+
const stream = new ReadableStream({
|
|
16
|
+
start(controller) {
|
|
17
|
+
// Heartbeat every 15s to keep connection alive
|
|
18
|
+
heartbeat = setInterval(() => {
|
|
19
|
+
if (!closed) {
|
|
20
|
+
try {
|
|
21
|
+
controller.enqueue(encoder.encode(': heartbeat\n\n'));
|
|
22
|
+
} catch {
|
|
23
|
+
// Controller closed
|
|
24
|
+
cleanup();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}, 15000);
|
|
28
|
+
|
|
29
|
+
unsubscribe = attachToProcess(id, (msg) => {
|
|
30
|
+
if (closed) return;
|
|
31
|
+
try {
|
|
32
|
+
controller.enqueue(encoder.encode(`data: ${JSON.stringify(msg)}\n\n`));
|
|
33
|
+
} catch {
|
|
34
|
+
cleanup();
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
if (!unsubscribe) {
|
|
39
|
+
controller.enqueue(encoder.encode(`data: ${JSON.stringify({ type: 'system', subtype: 'error', content: 'Session not found' })}\n\n`));
|
|
40
|
+
cleanup();
|
|
41
|
+
controller.close();
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
cancel() {
|
|
45
|
+
cleanup();
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
function cleanup() {
|
|
50
|
+
closed = true;
|
|
51
|
+
if (heartbeat) { clearInterval(heartbeat); heartbeat = null; }
|
|
52
|
+
if (unsubscribe) { unsubscribe(); unsubscribe = null; }
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return new Response(stream, {
|
|
56
|
+
headers: {
|
|
57
|
+
'Content-Type': 'text/event-stream',
|
|
58
|
+
'Cache-Control': 'no-cache, no-transform',
|
|
59
|
+
Connection: 'keep-alive',
|
|
60
|
+
'X-Accel-Buffering': 'no',
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { NextResponse } from 'next/server';
|
|
2
|
+
import { createClaudeSession, listProcesses, deleteSession } from '@/lib/claude-process';
|
|
3
|
+
import { getProjectInfo } from '@/lib/projects';
|
|
4
|
+
|
|
5
|
+
// List all Claude Code sessions
|
|
6
|
+
export async function GET() {
|
|
7
|
+
return NextResponse.json(listProcesses());
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// Create a new Claude Code session for a project
|
|
11
|
+
export async function POST(req: Request) {
|
|
12
|
+
const { projectName } = await req.json();
|
|
13
|
+
|
|
14
|
+
const project = getProjectInfo(projectName);
|
|
15
|
+
if (!project) {
|
|
16
|
+
return NextResponse.json({ error: `Project not found: ${projectName}` }, { status: 404 });
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const session = createClaudeSession(project.name, project.path);
|
|
20
|
+
return NextResponse.json(session);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Delete a session
|
|
24
|
+
export async function DELETE(req: Request) {
|
|
25
|
+
const { id } = await req.json();
|
|
26
|
+
deleteSession(id);
|
|
27
|
+
return NextResponse.json({ ok: true });
|
|
28
|
+
}
|
package/.forge/worktrees/pipeline-4dd8dc2d/app/api/claude-sessions/[projectName]/entries/route.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { NextResponse } from 'next/server';
|
|
2
|
+
import { getSessionFilePath, readSessionEntries } from '@/lib/claude-sessions';
|
|
3
|
+
import { statSync } from 'node:fs';
|
|
4
|
+
|
|
5
|
+
export async function GET(req: Request, { params }: { params: Promise<{ projectName: string }> }) {
|
|
6
|
+
const { projectName } = await params;
|
|
7
|
+
const url = new URL(req.url);
|
|
8
|
+
const sessionId = url.searchParams.get('sessionId');
|
|
9
|
+
|
|
10
|
+
if (!sessionId) {
|
|
11
|
+
return NextResponse.json({ error: 'sessionId required' }, { status: 400 });
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const filePath = getSessionFilePath(decodeURIComponent(projectName), sessionId);
|
|
15
|
+
if (!filePath) {
|
|
16
|
+
return NextResponse.json({ entries: [], count: 0, fileSize: 0 });
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const entries = readSessionEntries(filePath);
|
|
20
|
+
let fileSize = 0;
|
|
21
|
+
try { fileSize = statSync(filePath).size; } catch {}
|
|
22
|
+
return NextResponse.json({ entries, count: entries.length, fileSize });
|
|
23
|
+
}
|
package/.forge/worktrees/pipeline-4dd8dc2d/app/api/claude-sessions/[projectName]/live/route.ts
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { getSessionFilePath, readSessionEntries, tailSessionFile } from '@/lib/claude-sessions';
|
|
2
|
+
|
|
3
|
+
export const dynamic = 'force-dynamic';
|
|
4
|
+
export const runtime = 'nodejs';
|
|
5
|
+
|
|
6
|
+
export async function GET(req: Request, { params }: { params: Promise<{ projectName: string }> }) {
|
|
7
|
+
const { projectName } = await params;
|
|
8
|
+
const url = new URL(req.url);
|
|
9
|
+
const sessionId = url.searchParams.get('sessionId');
|
|
10
|
+
|
|
11
|
+
if (!sessionId) {
|
|
12
|
+
return new Response('sessionId parameter required', { status: 400 });
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const filePath = getSessionFilePath(decodeURIComponent(projectName), sessionId);
|
|
16
|
+
if (!filePath) {
|
|
17
|
+
return new Response('Session file not found', { status: 404 });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const encoder = new TextEncoder();
|
|
21
|
+
let cleanup: (() => void) | null = null;
|
|
22
|
+
let heartbeat: ReturnType<typeof setInterval> | null = null;
|
|
23
|
+
let closed = false;
|
|
24
|
+
|
|
25
|
+
const stream = new ReadableStream({
|
|
26
|
+
start(controller) {
|
|
27
|
+
// Send all existing entries
|
|
28
|
+
const existing = readSessionEntries(filePath);
|
|
29
|
+
controller.enqueue(encoder.encode(`data: ${JSON.stringify({ type: 'init', entries: existing })}\n\n`));
|
|
30
|
+
|
|
31
|
+
// Heartbeat
|
|
32
|
+
heartbeat = setInterval(() => {
|
|
33
|
+
if (!closed) {
|
|
34
|
+
try { controller.enqueue(encoder.encode(': heartbeat\n\n')); } catch { doCleanup(); }
|
|
35
|
+
}
|
|
36
|
+
}, 15000);
|
|
37
|
+
|
|
38
|
+
// Tail for new entries
|
|
39
|
+
cleanup = tailSessionFile(
|
|
40
|
+
filePath,
|
|
41
|
+
(entries) => {
|
|
42
|
+
if (closed) return;
|
|
43
|
+
try {
|
|
44
|
+
controller.enqueue(encoder.encode(`data: ${JSON.stringify({ type: 'update', entries })}\n\n`));
|
|
45
|
+
} catch { doCleanup(); }
|
|
46
|
+
},
|
|
47
|
+
() => {
|
|
48
|
+
doCleanup();
|
|
49
|
+
try { controller.close(); } catch {}
|
|
50
|
+
},
|
|
51
|
+
);
|
|
52
|
+
},
|
|
53
|
+
cancel() {
|
|
54
|
+
doCleanup();
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
function doCleanup() {
|
|
59
|
+
closed = true;
|
|
60
|
+
if (heartbeat) { clearInterval(heartbeat); heartbeat = null; }
|
|
61
|
+
if (cleanup) { cleanup(); cleanup = null; }
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return new Response(stream, {
|
|
65
|
+
headers: {
|
|
66
|
+
'Content-Type': 'text/event-stream',
|
|
67
|
+
'Cache-Control': 'no-cache, no-transform',
|
|
68
|
+
Connection: 'keep-alive',
|
|
69
|
+
'X-Accel-Buffering': 'no',
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { NextResponse } from 'next/server';
|
|
2
|
+
import { listClaudeSessions, deleteSession } from '@/lib/claude-sessions';
|
|
3
|
+
import { getDb } from '@/src/core/db/database';
|
|
4
|
+
import { getDbPath } from '@/src/config';
|
|
5
|
+
|
|
6
|
+
export async function GET(_req: Request, { params }: { params: Promise<{ projectName: string }> }) {
|
|
7
|
+
const { projectName } = await params;
|
|
8
|
+
const sessions = listClaudeSessions(decodeURIComponent(projectName));
|
|
9
|
+
return NextResponse.json(sessions);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export async function DELETE(req: Request, { params }: { params: Promise<{ projectName: string }> }) {
|
|
13
|
+
const { projectName } = await params;
|
|
14
|
+
const project = decodeURIComponent(projectName);
|
|
15
|
+
const body = await req.json();
|
|
16
|
+
|
|
17
|
+
// Support both single sessionId and batch sessionIds
|
|
18
|
+
const ids: string[] = body.sessionIds || (body.sessionId ? [body.sessionId] : []);
|
|
19
|
+
|
|
20
|
+
if (ids.length === 0) {
|
|
21
|
+
return NextResponse.json({ error: 'sessionId or sessionIds required' }, { status: 400 });
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const db = getDb(getDbPath());
|
|
25
|
+
let deletedCount = 0;
|
|
26
|
+
|
|
27
|
+
for (const id of ids) {
|
|
28
|
+
if (deleteSession(project, id)) {
|
|
29
|
+
deletedCount++;
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
db.prepare('DELETE FROM cached_sessions WHERE project_name = ? AND session_id = ?').run(project, id);
|
|
33
|
+
} catch {}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return NextResponse.json({ ok: true, deleted: deletedCount });
|
|
37
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { NextResponse } from 'next/server';
|
|
2
|
+
import { ensureInitialized } from '@/lib/init';
|
|
3
|
+
import { syncSessionsToDb, getAllCachedSessions } from '@/lib/session-watcher';
|
|
4
|
+
|
|
5
|
+
export async function GET() {
|
|
6
|
+
ensureInitialized();
|
|
7
|
+
const all = getAllCachedSessions();
|
|
8
|
+
return NextResponse.json(all);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export async function POST(req: Request) {
|
|
12
|
+
ensureInitialized();
|
|
13
|
+
const body = await req.json().catch(() => ({}));
|
|
14
|
+
const count = syncSessionsToDb(body.projectName);
|
|
15
|
+
const all = getAllCachedSessions();
|
|
16
|
+
return NextResponse.json({ synced: count, sessions: all });
|
|
17
|
+
}
|