From 1c0027428d3b5a1ad09c078527698b1e51773b36 Mon Sep 17 00:00:00 2001 From: David Date: Tue, 20 Jan 2026 23:32:11 +0100 Subject: [PATCH 01/13] docs: Add comprehensive Genesis specification documentation 12-section enterprise-grade documentation generated through forensic codebase analysis covering architecture, requirements, security, testing, deployment, and operations. Sections included: - Introduction & Executive Summary - Product Requirements (50+ functional/non-functional) - Technology Stack (all dependencies with versions) - Process Flowcharts (ASCII diagrams) - Architecture Design (modules, patterns, ADRs) - Data Models (TypeScript interfaces, storage schemas) - Security & Compliance (STRIDE threat model) - Testing Strategy (Vitest, Playwright) - Monitoring & Observability (logging, metrics) - Deployment & Operations (Docker, Electron) - Documentation standards - Reference Collections & Glossary Co-Authored-By: Claude Opus 4.5 --- genesis_spec/README.md | 55 +++ .../Automaker_Section_01_Introduction.md | 127 ++++++ ...tomaker_Section_02_Product_Requirements.md | 209 ++++++++++ .../Automaker_Section_03_Technology_Stack.md | 213 ++++++++++ ...Automaker_Section_04_Process_Flowcharts.md | 362 +++++++++++++++++ ...utomaker_Section_05_Architecture_Design.md | 316 +++++++++++++++ .../Automaker_Section_06_Data_Models.md | 377 ++++++++++++++++++ ...utomaker_Section_07_Security_Compliance.md | 316 +++++++++++++++ .../Automaker_Section_08_Testing_Strategy.md | 352 ++++++++++++++++ ...ker_Section_09_Monitoring_Observability.md | 319 +++++++++++++++ ...omaker_Section_10_Deployment_Operations.md | 360 +++++++++++++++++ .../Automaker_Section_11_Documentation.md | 314 +++++++++++++++ ...omaker_Section_12_Reference_Collections.md | 280 +++++++++++++ 13 files changed, 3600 insertions(+) create mode 100644 genesis_spec/README.md create mode 100644 genesis_spec/section_guides/Automaker_Section_01_Introduction.md create mode 100644 genesis_spec/section_guides/Automaker_Section_02_Product_Requirements.md create mode 100644 genesis_spec/section_guides/Automaker_Section_03_Technology_Stack.md create mode 100644 genesis_spec/section_guides/Automaker_Section_04_Process_Flowcharts.md create mode 100644 genesis_spec/section_guides/Automaker_Section_05_Architecture_Design.md create mode 100644 genesis_spec/section_guides/Automaker_Section_06_Data_Models.md create mode 100644 genesis_spec/section_guides/Automaker_Section_07_Security_Compliance.md create mode 100644 genesis_spec/section_guides/Automaker_Section_08_Testing_Strategy.md create mode 100644 genesis_spec/section_guides/Automaker_Section_09_Monitoring_Observability.md create mode 100644 genesis_spec/section_guides/Automaker_Section_10_Deployment_Operations.md create mode 100644 genesis_spec/section_guides/Automaker_Section_11_Documentation.md create mode 100644 genesis_spec/section_guides/Automaker_Section_12_Reference_Collections.md diff --git a/genesis_spec/README.md b/genesis_spec/README.md new file mode 100644 index 000000000..e3d4115e0 --- /dev/null +++ b/genesis_spec/README.md @@ -0,0 +1,55 @@ +# Automaker Genesis Specification + +**Comprehensive technical documentation for the Automaker autonomous AI development studio** + +--- + +## Overview + +This Genesis Specification provides exhaustive, enterprise-grade documentation generated through forensic analysis of the Automaker codebase. It serves as the single source of truth for understanding Automaker's architecture, requirements, and implementation. + +## Document Index + +| Section | Title | Description | +|---------|-------|-------------| +| [01](section_guides/Automaker_Section_01_Introduction.md) | Introduction & Executive Summary | Project overview, vision, scope, and success criteria | +| [02](section_guides/Automaker_Section_02_Product_Requirements.md) | Product Requirements | Functional and non-functional requirements, user stories | +| [03](section_guides/Automaker_Section_03_Technology_Stack.md) | Technology Stack | Dependencies, tools, and runtime requirements | +| [04](section_guides/Automaker_Section_04_Process_Flowcharts.md) | Process Flowcharts | System flows, data flows, and state machines | +| [05](section_guides/Automaker_Section_05_Architecture_Design.md) | Architecture Design | Module structure, patterns, and API design | +| [06](section_guides/Automaker_Section_06_Data_Models.md) | Data Models | Entity definitions, schemas, and storage | +| [07](section_guides/Automaker_Section_07_Security_Compliance.md) | Security & Compliance | Threat model, authentication, and data protection | +| [08](section_guides/Automaker_Section_08_Testing_Strategy.md) | Testing Strategy | Test approach, frameworks, and coverage | +| [09](section_guides/Automaker_Section_09_Monitoring_Observability.md) | Monitoring & Observability | Logging, metrics, and health checks | +| [10](section_guides/Automaker_Section_10_Deployment_Operations.md) | Deployment & Operations | Build, install, and operational procedures | +| [11](section_guides/Automaker_Section_11_Documentation.md) | Documentation | Doc structure and standards | +| [12](section_guides/Automaker_Section_12_Reference_Collections.md) | Reference Collections | External resources and glossary | + +## Quick Stats + +| Metric | Value | +|--------|-------| +| Lines of Code | ~195,000 | +| TypeScript Files | ~1,001 | +| Backend Services | 18+ | +| Shared Libraries | 7 | +| Version | 0.12.0 | + +## Usage + +### For New Contributors +Start with Section 01 (Introduction) for an overview, then review Section 03 (Technology Stack) to understand dependencies. + +### For Architects +Consult Section 05 (Architecture Design) for design decisions and patterns. + +### For AI Agents +Use this documentation as context for autonomous development tasks. Each section provides structured information suitable for LLM consumption. + +### For Security Auditors +Review Section 07 (Security & Compliance) for the threat model and security controls. + +--- + +**Generated**: 2026-01-20 +**Generator**: Genesis Documentation Skill diff --git a/genesis_spec/section_guides/Automaker_Section_01_Introduction.md b/genesis_spec/section_guides/Automaker_Section_01_Introduction.md new file mode 100644 index 000000000..d6ac4a446 --- /dev/null +++ b/genesis_spec/section_guides/Automaker_Section_01_Introduction.md @@ -0,0 +1,127 @@ +# Automaker Genesis Specification - Section 01: Introduction & Executive Summary + +**Version**: 1.0.0 +**Last Updated**: 2026-01-20 +**Status**: Active Development (v0.12.0) + +--- + +## 1.1 Executive Summary + +Automaker is an **autonomous AI development studio** that revolutionizes software development by orchestrating AI agents to implement features, fix bugs, and manage code in isolated git worktrees. Built as a desktop application using Electron with a React frontend and Express backend, Automaker provides a Kanban-based workflow where Claude-based AI agents autonomously execute development tasks. + +The platform bridges the gap between human-guided development and fully autonomous AI coding, providing: +- **Multi-agent orchestration** via Claude Agent SDK +- **Isolated feature development** using git worktrees +- **Real-time collaboration** through WebSocket streaming +- **Multi-provider AI support** (Claude, Codex, Cursor, OpenCode) +- **Enterprise-ready security** with encrypted credential storage + +**Key Metrics:** +- ~195,000 lines of TypeScript code +- ~1,001 TypeScript source files +- 7 shared library packages +- 18+ backend services +- Multi-platform support (macOS, Windows, Linux) + +--- + +## 1.2 Project Vision + +Automaker aims to be the **definitive autonomous development environment** where AI agents handle the full software development lifecycle - from ideation and planning to implementation, testing, and deployment - while developers maintain strategic oversight and control. + +**Long-term Goals:** +1. Enable fully autonomous feature development with minimal human intervention +2. Support multiple AI providers for flexibility and cost optimization +3. Integrate seamlessly with existing development workflows (GitHub, CI/CD) +4. Provide enterprise-grade security and auditability +5. Build a community-driven ecosystem of plugins and extensions + +--- + +## 1.3 Scope Definition + +### In Scope + +| Category | Included | +|----------|----------| +| **AI Agent Management** | Spawning, monitoring, and stopping Claude-based agents | +| **Session Management** | Creating, persisting, archiving, and resuming agent sessions | +| **Feature Development** | Autonomous implementation with planning modes (skip, lite, spec, full) | +| **Git Integration** | Worktree isolation, branching, committing, PR creation | +| **Terminal Access** | PTY-based terminal with xterm.js for command execution | +| **Multi-Provider Support** | Claude, Codex, Cursor CLI, OpenCode providers | +| **Real-time Communication** | WebSocket streaming for live updates | +| **Desktop & Web Modes** | Electron app and browser-based UI | +| **Configuration Management** | Global and per-project settings | +| **MCP Server Integration** | Model Context Protocol server support | + +### Out of Scope + +| Category | Excluded | +|----------|----------| +| **Direct Code Editing** | Not a replacement for VS Code/IDEs | +| **CI/CD Pipeline Execution** | Relies on external CI systems | +| **Cloud Hosting** | Self-hosted or local deployment only | +| **Team Collaboration** | Single-user focus (multi-user planned) | +| **Mobile Applications** | Desktop and web only | + +--- + +## 1.4 Success Criteria + +| Criterion | Metric | Target | +|-----------|--------|--------| +| Feature Completion Rate | Successfully implemented features | >85% | +| Agent Reliability | Sessions without crashes | >99% | +| Build Success | CI pipeline pass rate | >95% | +| Test Coverage | Server-side code coverage | >80% | +| User Adoption | Active installations | Growth metric | +| Performance | Agent response latency | <5s for initial response | + +--- + +## 1.5 Document Purpose + +This Genesis Specification serves as the **single source of truth** for understanding Automaker's architecture, requirements, and implementation. It is intended for: + +- **New Contributors**: Onboarding and understanding codebase +- **Architects**: System design decisions and patterns +- **AI Agents**: Context for autonomous development tasks +- **Maintainers**: Reference for troubleshooting and enhancement +- **Security Auditors**: Security model and compliance review + +**How to Use This Document:** +1. Start with Section 01 (Introduction) for overview +2. Review Section 03 (Technology Stack) for dependencies +3. Consult Section 05 (Architecture) for design decisions +4. Reference Section 10 (Deployment) for operational procedures + +--- + +## 1.6 Quality Checklist + +- [x] Executive summary captures essence of Automaker +- [x] Vision is clear and inspiring +- [x] Scope boundaries are explicitly defined +- [x] Success criteria are measurable +- [x] Document purpose explains usage + +--- + +## 1.7 Document Index + +| Section | Title | Purpose | +|---------|-------|---------| +| 01 | Introduction & Executive Summary | Project overview and scope | +| 02 | Product Requirements | Functional and non-functional requirements | +| 03 | Technology Stack | Dependencies and tools | +| 04 | Process Flowcharts | System and data flows | +| 05 | Architecture Design | Module structure and patterns | +| 06 | Data Models | Entity definitions and schemas | +| 07 | Security & Compliance | Security architecture and threat model | +| 08 | Testing Strategy | Test approach and coverage | +| 09 | Monitoring & Observability | Logging, metrics, and health checks | +| 10 | Deployment & Operations | Build, install, and runtime procedures | +| 11 | Documentation | Doc structure and standards | +| 12 | Reference Collections | External resources and glossary | diff --git a/genesis_spec/section_guides/Automaker_Section_02_Product_Requirements.md b/genesis_spec/section_guides/Automaker_Section_02_Product_Requirements.md new file mode 100644 index 000000000..16d2f82fa --- /dev/null +++ b/genesis_spec/section_guides/Automaker_Section_02_Product_Requirements.md @@ -0,0 +1,209 @@ +# Automaker Genesis Specification - Section 02: Product Requirements + +**Version**: 1.0.0 +**Last Updated**: 2026-01-20 +**Status**: Active Development + +--- + +## 2.1 Functional Requirements + +### Core Agent Features + +| ID | Requirement | Priority | Status | +|----|-------------|----------|--------| +| FR-001 | System shall spawn and manage Claude-based AI agents | P0 | Implemented | +| FR-002 | System shall support conversation session persistence | P0 | Implemented | +| FR-003 | System shall stream agent responses via WebSocket | P0 | Implemented | +| FR-004 | System shall support agent interruption/abortion | P0 | Implemented | +| FR-005 | System shall maintain conversation history per session | P0 | Implemented | +| FR-006 | System shall support image input to agents | P1 | Implemented | +| FR-007 | System shall queue prompts for sequential execution | P1 | Implemented | +| FR-008 | System shall support custom system prompts | P1 | Implemented | + +### Auto-Mode Features + +| ID | Requirement | Priority | Status | +|----|-------------|----------|--------| +| FR-010 | System shall support autonomous feature development | P0 | Implemented | +| FR-011 | System shall provide multiple planning modes (skip, lite, spec, full) | P0 | Implemented | +| FR-012 | System shall isolate features in git worktrees | P0 | Implemented | +| FR-013 | System shall support feature verification workflow | P0 | Implemented | +| FR-014 | System shall support plan approval workflow | P0 | Implemented | +| FR-015 | System shall track feature status through pipeline stages | P1 | Implemented | +| FR-016 | System shall support feature dependency resolution | P1 | Implemented | +| FR-017 | System shall generate feature specifications | P1 | Implemented | + +### Session Management + +| ID | Requirement | Priority | Status | +|----|-------------|----------|--------| +| FR-020 | System shall create named agent sessions | P0 | Implemented | +| FR-021 | System shall list all sessions with metadata | P0 | Implemented | +| FR-022 | System shall archive/unarchive sessions | P1 | Implemented | +| FR-023 | System shall delete sessions permanently | P1 | Implemented | +| FR-024 | System shall associate sessions with project paths | P1 | Implemented | +| FR-025 | System shall persist sessions across server restarts | P0 | Implemented | + +### Terminal Features + +| ID | Requirement | Priority | Status | +|----|-------------|----------|--------| +| FR-030 | System shall provide PTY-based terminal sessions | P0 | Implemented | +| FR-031 | System shall support multiple concurrent terminals | P1 | Implemented | +| FR-032 | System shall maintain terminal scrollback buffer | P1 | Implemented | +| FR-033 | System shall support terminal resize operations | P1 | Implemented | +| FR-034 | System shall optionally require terminal password | P2 | Implemented | + +### Git Integration + +| ID | Requirement | Priority | Status | +|----|-------------|----------|--------| +| FR-040 | System shall create/remove git worktrees | P0 | Implemented | +| FR-041 | System shall display file diffs | P1 | Implemented | +| FR-042 | System shall commit changes with messages | P1 | Implemented | +| FR-043 | System shall list GitHub PRs and issues | P2 | Implemented | +| FR-044 | System shall validate GitHub issues | P2 | Implemented | + +### Settings & Configuration + +| ID | Requirement | Priority | Status | +|----|-------------|----------|--------| +| FR-050 | System shall support global settings | P0 | Implemented | +| FR-051 | System shall support per-project settings | P0 | Implemented | +| FR-052 | System shall store API credentials securely | P0 | Implemented | +| FR-053 | System shall support theme customization | P2 | Implemented | +| FR-054 | System shall support keyboard shortcuts | P2 | Implemented | +| FR-055 | System shall support custom prompt templates | P1 | Implemented | + +### Multi-Provider Support + +| ID | Requirement | Priority | Status | +|----|-------------|----------|--------| +| FR-060 | System shall support Claude models | P0 | Implemented | +| FR-061 | System shall support Codex models | P1 | Implemented | +| FR-062 | System shall support Cursor CLI | P1 | Implemented | +| FR-063 | System shall support OpenCode CLI | P2 | Implemented | +| FR-064 | System shall cache model responses | P2 | Implemented | + +--- + +## 2.2 Non-Functional Requirements + +### Performance + +| ID | Category | Requirement | Target | +|----|----------|-------------|--------| +| NFR-001 | Performance | Initial page load time | <3s | +| NFR-002 | Performance | Agent first response | <5s | +| NFR-003 | Performance | WebSocket message latency | <100ms | +| NFR-004 | Performance | Terminal input latency | <50ms | +| NFR-005 | Performance | Session restore time | <2s | + +### Security + +| ID | Category | Requirement | Target | +|----|----------|-------------|--------| +| NFR-010 | Security | API key encryption at rest | Required | +| NFR-011 | Security | WebSocket authentication | Required | +| NFR-012 | Security | CORS policy enforcement | Required | +| NFR-013 | Security | Path traversal prevention | Required | +| NFR-014 | Security | Input validation on all endpoints | Required | + +### Scalability + +| ID | Category | Requirement | Target | +|----|----------|-------------|--------| +| NFR-020 | Scalability | Concurrent agent sessions | 10+ | +| NFR-021 | Scalability | Terminal sessions | 20+ | +| NFR-022 | Scalability | Session history storage | 1000+ messages | +| NFR-023 | Scalability | Feature queue depth | 100+ | + +### Reliability + +| ID | Category | Requirement | Target | +|----|----------|-------------|--------| +| NFR-030 | Reliability | Server uptime | 99.9% | +| NFR-031 | Reliability | Graceful shutdown handling | Required | +| NFR-032 | Reliability | Session data persistence | Atomic writes | +| NFR-033 | Reliability | Error recovery | Auto-reconnect | + +### Usability + +| ID | Category | Requirement | Target | +|----|----------|-------------|--------| +| NFR-040 | Usability | Keyboard navigation | Full support | +| NFR-041 | Usability | Responsive design | 1024px+ | +| NFR-042 | Usability | Dark/Light theme | Both | +| NFR-043 | Usability | Real-time status updates | Required | + +### Maintainability + +| ID | Category | Requirement | Target | +|----|----------|-------------|--------| +| NFR-050 | Maintainability | TypeScript coverage | 100% | +| NFR-051 | Maintainability | Shared type definitions | Monorepo libs | +| NFR-052 | Maintainability | Code documentation | Public APIs | +| NFR-053 | Maintainability | Test coverage | >80% server | + +--- + +## 2.3 User Stories + +### As a Developer + +1. **US-001**: As a developer, I want to start an AI agent session so I can get help with coding tasks. +2. **US-002**: As a developer, I want to queue multiple features so the AI can work through them autonomously. +3. **US-003**: As a developer, I want to see real-time progress of agent work so I can monitor development. +4. **US-004**: As a developer, I want to review and approve implementation plans before coding begins. +5. **US-005**: As a developer, I want features developed in isolated branches so my main codebase stays clean. + +### As a Team Lead + +6. **US-010**: As a team lead, I want to track feature completion status across multiple sessions. +7. **US-011**: As a team lead, I want to configure AI behavior per project for consistency. +8. **US-012**: As a team lead, I want audit trails of all AI agent actions for review. + +### As an Administrator + +13. **US-020**: As an admin, I want to securely store API credentials so they're not exposed. +14. **US-021**: As an admin, I want to configure which AI providers are available. +15. **US-022**: As an admin, I want to enable/disable terminal access for security. + +--- + +## 2.4 Acceptance Criteria + +### Agent Session (FR-001) + +- [ ] Agent starts within 5 seconds of request +- [ ] Agent responds to prompts with streaming output +- [ ] Agent can be stopped mid-execution +- [ ] Session persists after server restart +- [ ] Multiple sessions can run concurrently + +### Auto-Mode (FR-010) + +- [ ] Features can be queued for autonomous execution +- [ ] Each feature runs in isolated git worktree +- [ ] Planning mode is configurable per feature +- [ ] Plan approval is required before implementation +- [ ] Feature status updates in real-time + +### Terminal (FR-030) + +- [ ] Terminal connects via WebSocket +- [ ] Input is echoed with <50ms latency +- [ ] Scrollback buffer preserves history +- [ ] Resize events propagate correctly +- [ ] Multiple terminals can run simultaneously + +--- + +## 2.5 Quality Checklist + +- [x] All major features have functional requirements +- [x] NFRs cover all quality attributes (performance, security, etc.) +- [x] Priorities are assigned (P0 = critical, P1 = important, P2 = nice-to-have) +- [x] Acceptance criteria are testable +- [x] User stories cover primary personas diff --git a/genesis_spec/section_guides/Automaker_Section_03_Technology_Stack.md b/genesis_spec/section_guides/Automaker_Section_03_Technology_Stack.md new file mode 100644 index 000000000..89bb3f0bb --- /dev/null +++ b/genesis_spec/section_guides/Automaker_Section_03_Technology_Stack.md @@ -0,0 +1,213 @@ +# Automaker Genesis Specification - Section 03: Technology Stack + +**Version**: 1.0.0 +**Last Updated**: 2026-01-20 +**Status**: Active Development + +--- + +## 3.1 Core Technologies + +| Technology | Version | Purpose | +|------------|---------|---------| +| TypeScript | 5.9.3 | Primary language for all code | +| Node.js | 22.x | Runtime environment | +| React | 19.2.3 | Frontend UI framework | +| Express | 5.2.1 | Backend HTTP server | +| Electron | 39.2.7 | Desktop application wrapper | +| Vite | 7.3.0 | Frontend build tool | + +--- + +## 3.2 Dependencies + +### Backend Production Dependencies + +| Package | Version | Purpose | +|---------|---------|---------| +| @anthropic-ai/claude-agent-sdk | 0.1.76 | Claude AI agent orchestration | +| @modelcontextprotocol/sdk | 1.25.2 | MCP server integration | +| @openai/codex-sdk | 0.77.0 | Codex model access | +| express | 5.2.1 | HTTP server framework | +| ws | 8.18.3 | WebSocket server | +| node-pty | 1.1.0-beta41 | Terminal emulation | +| cors | 2.8.5 | CORS middleware | +| cookie-parser | 1.4.7 | Cookie handling | +| morgan | 1.10.1 | HTTP request logging | +| dotenv | 17.2.3 | Environment variables | + +### Frontend Production Dependencies + +| Package | Version | Purpose | +|---------|---------|---------| +| react | 19.2.3 | UI framework | +| react-dom | 19.2.3 | React DOM renderer | +| @tanstack/react-router | 1.141.6 | Type-safe routing | +| @tanstack/react-query | 5.90.12 | Server state management | +| zustand | 5.0.9 | Client state management | +| @xterm/xterm | 5.5.0 | Terminal emulator | +| @uiw/react-codemirror | 4.25.4 | Code editor | +| @xyflow/react | 12.10.0 | Flow diagrams | +| @radix-ui/* | Various | Accessible UI components | +| tailwind-merge | 3.4.0 | Tailwind class merging | +| lucide-react | 0.562.0 | Icons | +| sonner | 2.0.7 | Toast notifications | +| react-markdown | 10.1.0 | Markdown rendering | +| dagre | 0.8.5 | Graph layout algorithms | + +### Development Dependencies + +| Package | Version | Purpose | +|---------|---------|---------| +| typescript | 5.9.3 | TypeScript compiler | +| vitest | 4.0.16 | Unit testing framework | +| @playwright/test | 1.57.0 | E2E testing framework | +| eslint | 9.39.2 | Code linting | +| tailwindcss | 4.1.18 | CSS framework | +| electron-builder | 26.0.12 | Desktop app packaging | +| @vitejs/plugin-react | 5.1.2 | React Vite plugin | +| tsx | 4.21.0 | TypeScript execution | + +### Shared Library Packages (@automaker/*) + +| Package | Version | Purpose | +|---------|---------|---------| +| @automaker/types | 1.0.0 | Shared TypeScript interfaces | +| @automaker/utils | 1.0.0 | Common utility functions | +| @automaker/prompts | 1.0.0 | AI prompt templates | +| @automaker/platform | 1.0.0 | OS-specific abstractions | +| @automaker/model-resolver | 1.0.0 | AI model selection logic | +| @automaker/dependency-resolver | 1.0.0 | Feature dependency ordering | +| @automaker/git-utils | 1.0.0 | Git operation helpers | + +--- + +## 3.3 Build Tools + +| Tool | Purpose | +|------|---------| +| npm | Package management (workspaces) | +| Vite | Frontend bundling and dev server | +| tsc | TypeScript compilation | +| electron-builder | Desktop app packaging | +| tsx | Development-time TypeScript execution | + +### Build Configuration + +``` +Root package.json (npm workspaces) +├── apps/server/ → tsc → dist/ +├── apps/ui/ → vite → dist/ +└── libs/* → tsc → dist/ +``` + +--- + +## 3.4 Runtime Requirements + +### Development Environment + +| Requirement | Minimum | Recommended | +|-------------|---------|-------------| +| Node.js | 22.0.0 | 22.x (latest LTS) | +| npm | 10.x | Latest | +| OS | macOS, Windows, Linux | Any | +| RAM | 4GB | 8GB+ | +| Disk | 2GB | 5GB+ | + +### Production Environment (Docker) + +| Requirement | Value | +|-------------|-------| +| Base Image | node:22-slim | +| Port (Server) | 3008 | +| Port (UI) | 80 | +| Data Directory | /data | +| Projects Directory | /projects | + +### Desktop Application + +| Platform | Architecture | Format | +|----------|--------------|--------| +| macOS | x64, arm64 | DMG, ZIP | +| Windows | x64 | NSIS installer | +| Linux | x64 | AppImage, DEB, RPM | + +--- + +## 3.5 External Services + +### AI Providers + +| Service | Authentication | Purpose | +|---------|---------------|---------| +| Anthropic Claude | API Key | Primary AI agent | +| OpenAI Codex | API Key | Alternative provider | +| Cursor CLI | OAuth | IDE integration | +| OpenCode CLI | OAuth | Multi-provider access | + +### Development Services + +| Service | Purpose | +|---------|---------| +| GitHub | Version control, PRs, issues | +| GitHub Actions | CI/CD pipeline | +| Discord | Community support | + +### Optional Integrations + +| Service | Purpose | +|---------|---------| +| MCP Servers | Extended tool capabilities | +| Playwright Browsers | E2E testing | +| Docker Registry | Container distribution | + +--- + +## 3.6 Technology Decisions + +### Why TypeScript? + +- Type safety across frontend and backend +- Shared type definitions via monorepo +- Excellent IDE support and refactoring +- Growing ecosystem and community + +### Why React 19? + +- Industry standard for UI development +- Concurrent rendering for smooth UX +- Large ecosystem of compatible libraries +- Team familiarity and hiring pool + +### Why Electron? + +- Cross-platform desktop support +- Full Node.js API access +- Native OS integration +- Single codebase for web and desktop + +### Why Express 5? + +- Mature and stable HTTP framework +- Async/await support +- Large middleware ecosystem +- Easy WebSocket integration + +### Why Zustand over Redux? + +- Simpler API with less boilerplate +- Better TypeScript integration +- Smaller bundle size +- Easier learning curve + +--- + +## 3.7 Quality Checklist + +- [x] All dependencies documented with versions +- [x] Versions are pinned in package.json +- [x] Purpose is clear for each dependency +- [x] Runtime requirements specified +- [x] External services documented +- [x] Technology decisions explained diff --git a/genesis_spec/section_guides/Automaker_Section_04_Process_Flowcharts.md b/genesis_spec/section_guides/Automaker_Section_04_Process_Flowcharts.md new file mode 100644 index 000000000..80688d2f6 --- /dev/null +++ b/genesis_spec/section_guides/Automaker_Section_04_Process_Flowcharts.md @@ -0,0 +1,362 @@ +# Automaker Genesis Specification - Section 04: Process Flowcharts + +**Version**: 1.0.0 +**Last Updated**: 2026-01-20 +**Status**: Active Development + +--- + +## 4.1 System Overview Flow + +``` ++------------------+ +------------------+ +------------------+ +| Electron | | Browser | | Docker | +| Desktop | | Client | | Container | ++--------+---------+ +--------+---------+ +--------+---------+ + | | | + +------------------------+------------------------+ + | + v + +-------------+--------------+ + | React UI (Vite) | + | - TanStack Router | + | - Zustand State | + | - xterm.js Terminal | + +-------------+--------------+ + | + | HTTP/WebSocket + v + +-------------+--------------+ + | Express Backend (3008) | + | - REST API Routes | + | - WebSocket Events | + | - Service Layer | + +-------------+--------------+ + | + +------------------------+------------------------+ + | | | + v v v ++--------+---------+ +----------+----------+ +---------+--------+ +| Agent Service | | Terminal Service | | Settings Service | +| - Claude SDK | | - node-pty | | - JSON storage | +| - Codex SDK | | - PTY sessions | | - Credentials | ++--------+---------+ +----------+----------+ +---------+--------+ + | | | + v v v ++--------+---------+ +----------+----------+ +---------+--------+ +| AI Providers | | Shell Process | | File System | +| (Anthropic API) | | (bash/zsh/cmd) | | (~/.automaker) | ++------------------+ +---------------------+ +------------------+ +``` + +--- + +## 4.2 Core Process Flows + +### 4.2.1 Agent Session Flow + +``` ++-------------+ +---------------+ +----------------+ +| Client | | Backend | | Agent Service | ++------+------+ +-------+-------+ +--------+-------+ + | | | + | POST /sessions | | + +------------------->| | + | | createSession() | + | +--------------------->| + | | | + | | sessionId | + |<-------------------+<---------------------+ + | | | + | WS Connect | | + | /api/events | | + +------------------->| | + | | | + | POST /agent/start | | + +------------------->| | + | | startConversation() | + | +--------------------->| + | | | + | POST /agent/send | | + +------------------->| | + | | sendMessage() | + | +--------------------->| + | | | + | WS: stream | Claude API | + |<-------------------+<---------------------+ + | | | + | WS: tool_use | | + |<-------------------+ | + | | | + | WS: complete | | + |<-------------------+ | + | | | +``` + +### 4.2.2 Auto-Mode Feature Development Flow + +``` ++-------------+ +---------------+ +----------------+ +-------------+ +| Client | | Auto-Mode | | Agent Service | | Git Utils | ++------+------+ +-------+-------+ +--------+-------+ +------+------+ + | | | | + | Run Feature | | | + +------------------->| | | + | | Create Worktree | | + | +---------------------------------------------> + | | | | + | |<---------------------------------------------+ + | | | | + | | Start Planning | | + | +--------------------->| | + | | | | + | WS: planning | Generate Plan | | + |<-------------------+<---------------------+ | + | | | | + | Approve Plan | | | + +------------------->| | | + | | | | + | | Start Implementing | | + | +--------------------->| | + | | | | + | WS: implementing | Execute Code | | + |<-------------------+<---------------------+ | + | | | | + | Verify Feature | | | + +------------------->| | | + | | | | + | Commit Feature | | | + +------------------->| | | + | | Git Commit | | + | +---------------------------------------------> + | | | | + | WS: committed | | | + |<-------------------+ | | +``` + +### 4.2.3 Terminal Session Flow + +``` ++-------------+ +---------------+ +----------------+ +-------------+ +| Client | | Backend | |Terminal Service| | node-pty | ++------+------+ +-------+-------+ +--------+-------+ +------+------+ + | | | | + | POST /terminal | | | + | /sessions | | | + +------------------->| | | + | | createSession() | | + | +--------------------->| | + | | | spawn() | + | | +--------------------> + | | | | + | | sessionId | | + |<-------------------+<---------------------+ | + | | | | + | WS Connect | | | + | /api/terminal/ws | | | + +------------------->| | | + | | | | + | WS: connected | | | + |<-------------------+ | | + | | | | + | WS: scrollback | | | + |<-------------------+ | | + | | | | + | WS: {type:"input"}| | | + +------------------->| | | + | | write() | | + | +--------------------->| | + | | | write() | + | | +--------------------> + | | | | + | | | onData | + | | |<--------------------+ + | WS: {type:"data"}| | | + |<-------------------+<---------------------+ | +``` + +--- + +## 4.3 Data Flow Diagrams + +### 4.3.1 Settings Data Flow + +``` ++------------------+ +------------------+ +------------------+ +| UI Settings | | Settings Service| | File System | +| Component | | | | | ++--------+---------+ +--------+---------+ +--------+---------+ + | | | + | GET /settings/global | | + +----------------------->| | + | | readFile() | + | +----------------------->| + | | | + | | settings.json | + | |<-----------------------+ + | | | + | GlobalSettings | | + |<-----------------------+ | + | | | + | POST /settings/global | | + +----------------------->| | + | | writeFile() | + | +----------------------->| + | | | + | { success: true } | | + |<-----------------------+ | + +Storage Locations: + ~/.automaker/settings.json (Global settings) + ~/.automaker/credentials.json (API keys - encrypted) + {project}/.automaker/settings.json (Project settings) +``` + +### 4.3.2 Event Stream Data Flow + +``` ++------------------+ +------------------+ +| React Client | | Express Server | ++--------+---------+ +--------+---------+ + | | + | WebSocket Connect: ws://localhost:3008/api/events + +------------------------------------------------>| + | | + | { type: "agent:stream", | + | sessionId: "...", | + | content: "..." } | + |<------------------------------------------------+ + | | + | { type: "agent:tool_use", | + | sessionId: "...", | + | tool: { name, input } } | + |<------------------------------------------------+ + | | + | { type: "agent:complete", | + | sessionId: "...", | + | content: "..." } | + |<------------------------------------------------+ + | | + | { type: "feature:status", | + | featureId: "...", | + | status: "implementing" } | + |<------------------------------------------------+ +``` + +--- + +## 4.4 State Machines + +### 4.4.1 Feature Status State Machine + +``` + +----------+ + | pending | + +----+-----+ + | + runFeature() + | + v + +----------+ + +--------->| planning |<--------+ + | +----+-----+ | + | | | + | approvePlan() rejectPlan() + | | | + | v | + | +----------+ | + +----------| approved | | + +----+-----+ | + | | + startImplementation() | + | | + v | + +--------------+ | + +----->| implementing +---------+ + | +------+-------+ error + | | + | completeImplementation() + | | + | v + | +-----------+ + +------+ verifying | + error +-----+-----+ + | + verifyFeature() + | + v + +-----------+ + | committing| + +-----+-----+ + | + commitFeature() + | + v + +----------+ + | done | + +----------+ +``` + +### 4.4.2 Agent Session State Machine + +``` + +----------+ + | idle | + +----+-----+ + | + sendMessage() + | + v + +----------+ + | running |<----+ + +----+-----+ | + | | + +----------------+------+ | + | | | + completion abort() error (retry) + | | | + v v | + +----------+ +----------+ + | idle | | stopped +----+ + +----------+ +----------+ +``` + +--- + +## 4.5 Sequence Diagrams + +### 4.5.1 Authentication Flow + +``` ++--------+ +--------+ +----------+ +---------+ +| Client | | Server | | AuthLib | | KeyStore| ++---+----+ +---+----+ +----+-----+ +----+----+ + | | | | + | Login | | | + +------------->| | | + | | validateKey | | + | +-------------->| | + | | | getPassword | + | | +--------------->| + | | | | + | | | API key | + | | |<---------------+ + | | | | + | | isValid | | + | |<--------------+ | + | | | | + | Set Cookie | | | + |<-------------+ | | + | | | | +``` + +--- + +## 4.6 Quality Checklist + +- [x] Main system flow is documented +- [x] All major features have process flows +- [x] Error paths are shown in state machines +- [x] Diagrams use ASCII art (not Unicode) +- [x] Data flows show storage locations +- [x] Sequence diagrams show inter-component communication diff --git a/genesis_spec/section_guides/Automaker_Section_05_Architecture_Design.md b/genesis_spec/section_guides/Automaker_Section_05_Architecture_Design.md new file mode 100644 index 000000000..836cf2183 --- /dev/null +++ b/genesis_spec/section_guides/Automaker_Section_05_Architecture_Design.md @@ -0,0 +1,316 @@ +# Automaker Genesis Specification - Section 05: Architecture Design + +**Version**: 1.0.0 +**Last Updated**: 2026-01-20 +**Status**: Active Development + +--- + +## 5.1 High-Level Architecture + +``` ++-------------------------------------------------------------------------+ +| Automaker | ++-------------------------------------------------------------------------+ +| | +| +---------------------------+ +----------------------------------+ | +| | Frontend (UI) | | Backend (Server) | | +| | +---------------------+ | | +----------------------------+ | | +| | | React 19 App | | | | Express 5 Server | | | +| | | - TanStack Router | | | | - REST API Routes | | | +| | | - Zustand Stores | | | | - WebSocket Events | | | +| | | - xterm.js | | | | - Auth Middleware | | | +| | | - CodeMirror | | | +----------------------------+ | | +| | +---------------------+ | | | | | +| | | | | v | | +| | +---------------------+ | | +----------------------------+ | | +| | | Electron Main | | | | Services Layer | | | +| | | - IPC Bridge | | | | - AgentService | | | +| | | - Native APIs | | | | - AutoModeService | | | +| | +---------------------+ | | | - TerminalService | | | +| +---------------------------+ | | - SettingsService | | | +| | | - FeatureLoader | | | +| +---------------------------+ | +----------------------------+ | | +| | Shared Libraries | | | | | +| | - @automaker/types | | v | | +| | - @automaker/utils | | +----------------------------+ | | +| | - @automaker/prompts | | | Provider Layer | | | +| | - @automaker/platform | | | - Claude Provider | | | +| | - @automaker/git-utils | | | - Codex Provider | | | +| +---------------------------+ | | - Cursor Provider | | | +| | +----------------------------+ | | ++-------------------------------------------------------------------------+ +``` + +--- + +## 5.2 Module Structure + +### Backend Module Structure + +``` +apps/server/src/ ++-- index.ts # Entry point, server initialization ++-- lib/ # Shared utilities +| +-- auth.ts # Authentication helpers +| +-- events.ts # Event emitter +| +-- secure-fs.ts # Secure file operations +| +-- sdk-options.ts # SDK configuration builder +| +-- settings-helpers.ts # Settings utilities +| ++-- middleware/ # Express middleware +| +-- require-json-content-type.ts +| ++-- providers/ # AI provider implementations +| +-- provider-factory.ts # Provider selection +| +-- claude-provider.ts # Claude Agent SDK +| +-- codex-provider.ts # Codex integration +| +-- cursor-provider.ts # Cursor CLI +| +-- opencode-provider.ts # OpenCode CLI +| ++-- routes/ # REST API endpoints +| +-- agent/ # Agent management +| +-- auto-mode/ # Autonomous development +| +-- sessions/ # Session CRUD +| +-- terminal/ # Terminal access +| +-- settings/ # Configuration +| +-- git/ # Git operations +| +-- github/ # GitHub integration +| +-- features/ # Feature management +| +-- worktree/ # Git worktrees +| ... (25+ route modules) +| ++-- services/ # Business logic + +-- agent-service.ts # Agent orchestration + +-- auto-mode-service.ts # Auto-mode workflows + +-- terminal-service.ts # PTY management + +-- settings-service.ts # Settings persistence + +-- feature-loader.ts # Feature loading + +-- pipeline-service.ts # Pipeline execution + +-- ideation-service.ts # Feature brainstorming + ... (18+ service modules) +``` + +### Frontend Module Structure + +``` +apps/ui/src/ ++-- main.tsx # React entry point ++-- App.tsx # Root component ++-- index.css # Global styles +| ++-- components/ # Reusable components +| +-- ui/ # Base UI (Radix-based) +| | +-- button.tsx +| | +-- dialog.tsx +| | +-- input.tsx +| | ... +| +-- layout/ # Layout components +| +-- session/ # Session components +| +-- agent/ # Agent components +| +-- terminal/ # Terminal components +| +-- editor/ # Code editor +| +-- auto-mode/ # Auto-mode UI +| ++-- routes/ # Page components +| +-- __root.tsx # Root layout +| +-- index.tsx # Home page +| +-- sessions.tsx # Sessions view +| +-- settings.tsx # Settings page +| ... +| ++-- stores/ # Zustand state +| +-- session-store.ts +| +-- agent-store.ts +| +-- settings-store.ts +| +-- feature-store.ts +| ++-- hooks/ # Custom React hooks +| +-- useWebSocket.ts +| +-- useAgent.ts +| +-- useTerminal.ts +| ++-- lib/ # Utilities + +-- api.ts # API client + +-- utils.ts # Helpers +``` + +--- + +## 5.3 Design Patterns + +| Pattern | Location | Purpose | +|---------|----------|---------| +| **Factory** | `provider-factory.ts` | Create appropriate AI provider based on model | +| **Service Layer** | `services/` | Encapsulate business logic from routes | +| **Event Emitter** | `lib/events.ts` | Decouple components via pub/sub | +| **Repository** | `SettingsService` | Abstract data persistence | +| **Adapter** | Provider classes | Unified interface for AI providers | +| **Strategy** | Planning modes | Interchangeable planning algorithms | +| **Observer** | WebSocket events | Real-time UI updates | +| **Singleton** | Terminal/DevServer services | Shared stateful resources | +| **Builder** | `sdk-options.ts` | Construct complex SDK options | +| **Middleware** | Express middleware | Request processing pipeline | + +### Pattern Examples + +**Factory Pattern - Provider Selection:** +```typescript +// provider-factory.ts +class ProviderFactory { + static getProviderForModel(model: string): Provider { + if (model.startsWith('claude-')) { + return new ClaudeProvider(); + } else if (model.startsWith('codex-')) { + return new CodexProvider(); + } + throw new Error(`Unknown model: ${model}`); + } +} +``` + +**Event Emitter Pattern:** +```typescript +// lib/events.ts +interface EventEmitter { + emit(type: string, payload: unknown): void; + subscribe(callback: EventCallback): () => void; +} +``` + +--- + +## 5.4 API Design + +### REST API Structure + +| Method | Endpoint | Purpose | +|--------|----------|---------| +| **Sessions** | +| POST | /api/sessions | Create session | +| GET | /api/sessions | List sessions | +| PUT | /api/sessions/:id | Update session | +| DELETE | /api/sessions/:id | Delete session | +| **Agent** | +| POST | /api/agent/start | Start conversation | +| POST | /api/agent/send | Send message | +| POST | /api/agent/stop | Stop agent | +| GET | /api/agent/history | Get history | +| **Auto-Mode** | +| POST | /api/auto-mode/run-feature | Start feature | +| POST | /api/auto-mode/approve-plan | Approve plan | +| POST | /api/auto-mode/verify | Verify feature | +| POST | /api/auto-mode/commit | Commit changes | +| **Terminal** | +| POST | /api/terminal/sessions | Create terminal | +| DELETE | /api/terminal/sessions/:id | Kill terminal | +| **Settings** | +| GET | /api/settings/global | Get global settings | +| POST | /api/settings/global | Update global settings | +| GET | /api/settings/project | Get project settings | + +### WebSocket API + +| Endpoint | Events | +|----------|--------| +| `/api/events` | agent:stream, agent:complete, agent:error, feature:status | +| `/api/terminal/ws` | connected, scrollback, data, exit | + +--- + +## 5.5 Integration Points + +### External Integrations + +| Integration | Protocol | Purpose | +|-------------|----------|---------| +| Anthropic API | HTTPS | Claude model inference | +| OpenAI API | HTTPS | Codex model inference | +| GitHub API | HTTPS | PRs, issues, repos | +| MCP Servers | stdio/HTTP | Extended tools | +| Cursor CLI | subprocess | Cursor model access | + +### Internal Integrations + +| From | To | Method | +|------|-----|--------| +| Routes | Services | Direct call | +| Services | Events | Event emitter | +| Events | WebSocket | Broadcast | +| UI | Backend | HTTP/WS | +| Electron | Backend | localhost | + +--- + +## 5.6 Architectural Decisions + +### ADR-001: Monorepo Structure + +**Context:** Need to share code between frontend and backend. + +**Decision:** Use npm workspaces with `libs/` for shared packages. + +**Rationale:** +- Single repository for all code +- Shared TypeScript types +- Atomic commits across packages +- Simplified dependency management + +### ADR-002: Service Layer Pattern + +**Context:** Business logic was mixed into route handlers. + +**Decision:** Extract all business logic into dedicated service classes. + +**Rationale:** +- Separation of concerns +- Easier testing (mock services) +- Reusable logic across routes +- Clear ownership of functionality + +### ADR-003: Provider Abstraction + +**Context:** Need to support multiple AI providers with different APIs. + +**Decision:** Create provider interface with factory pattern. + +**Rationale:** +- Unified interface for all providers +- Easy to add new providers +- Swap providers at runtime +- Consistent error handling + +### ADR-004: Event-Driven Architecture + +**Context:** UI needs real-time updates from backend operations. + +**Decision:** Use WebSocket with event emitter pattern. + +**Rationale:** +- Low latency updates +- Decoupled components +- Scalable to multiple clients +- Works with existing React patterns + +### ADR-005: Git Worktree Isolation + +**Context:** Features developed concurrently could conflict. + +**Decision:** Each feature runs in its own git worktree. + +**Rationale:** +- Complete isolation between features +- No merge conflicts during development +- Easy cleanup after completion +- Supports parallel development + +--- + +## 5.7 Quality Checklist + +- [x] Architecture is clearly diagrammed +- [x] Modules have defined responsibilities +- [x] Design patterns are documented +- [x] API contracts are specified +- [x] Integration points are mapped +- [x] Architectural decisions have rationale (ADR style) diff --git a/genesis_spec/section_guides/Automaker_Section_06_Data_Models.md b/genesis_spec/section_guides/Automaker_Section_06_Data_Models.md new file mode 100644 index 000000000..77bb0c53c --- /dev/null +++ b/genesis_spec/section_guides/Automaker_Section_06_Data_Models.md @@ -0,0 +1,377 @@ +# Automaker Genesis Specification - Section 06: Data Models + +**Version**: 1.0.0 +**Last Updated**: 2026-01-20 +**Status**: Active Development + +--- + +## 6.1 Core Entities + +### Session + +```typescript +interface AgentSession { + id: string; // Unique identifier (msg_timestamp_random) + name: string; // User-defined session name + projectPath?: string; // Associated project directory + workingDirectory: string; // Current working directory + createdAt: string; // ISO 8601 timestamp + updatedAt: string; // ISO 8601 timestamp + archived?: boolean; // Soft delete flag + tags?: string[]; // User-defined tags + model?: string; // AI model (e.g., "claude-sonnet-4-20250514") + sdkSessionId?: string; // Claude SDK session for continuity +} +``` + +### Message + +```typescript +interface Message { + id: string; // Unique identifier + role: 'user' | 'assistant'; // Message sender + content: string; // Text content + images?: Array<{ // Optional image attachments + data: string; // Base64 encoded + mimeType: string; // e.g., "image/png" + filename: string; // Original filename + }>; + timestamp: string; // ISO 8601 timestamp + isError?: boolean; // Error message flag +} +``` + +### Feature + +```typescript +interface Feature { + id: string; // Unique identifier + name: string; // Feature name + description: string; // Detailed description + status: FeatureStatus; // Current state + priority: number; // Execution order + dependencies: string[]; // Feature IDs this depends on + images?: FeatureImagePath[]; // Associated images + textFiles?: FeatureTextFilePath[]; // Associated text files + createdAt?: string; // ISO 8601 timestamp + updatedAt?: string; // ISO 8601 timestamp + descriptionHistory?: DescriptionHistoryEntry[]; +} + +type FeatureStatus = + | 'pending' + | 'planning' + | 'approved' + | 'implementing' + | 'verifying' + | 'committing' + | 'done' + | 'error'; +``` + +### Settings + +```typescript +interface GlobalSettings { + theme: ThemeMode; // 'light' | 'dark' | 'system' + defaultModel: string; // Default AI model + maxConcurrentAgents: number; // Parallel agent limit + telemetryEnabled: boolean; // Usage analytics + autoUpdate: boolean; // Auto-update setting + serverLogLevel: ServerLogLevel; // 'error' | 'warn' | 'info' | 'debug' + enableRequestLogging: boolean; // HTTP request logging + keyboardShortcuts: KeyboardShortcuts; + phaseModels: PhaseModelConfig; // Model per auto-mode phase + boardBackground: BoardBackgroundSettings; + eventHooks: EventHook[]; // Custom event triggers + mcpServers: Record; + skillsEnabled: boolean; + skillsSources: Array<'user' | 'project'>; + subagentsEnabled: boolean; + subagentsSources: Array<'user' | 'project'>; +} + +interface ProjectSettings { + name: string; // Project name + model?: string; // Override model + autoModeEnabled: boolean; // Enable auto-mode + planningMode: PlanningMode; // 'skip' | 'lite' | 'spec' | 'full' + autoLoadClaudeMd: boolean; // Load CLAUDE.md automatically + gitWorkflow: { + branchPrefix: string; // e.g., "feature/" + commitPrefix: string; // e.g., "feat:" + autoCommit: boolean; // Auto-commit on completion + }; + hooks: { + preToolUse?: string[]; // Commands before tool use + postToolUse?: string[]; // Commands after tool use + }; +} + +interface Credentials { + anthropicApiKey?: string; // Encrypted API key + githubToken?: string; // GitHub access token + cursorSession?: string; // Cursor session token + codexApiKey?: string; // Codex API key +} +``` + +### Provider Types + +```typescript +interface ProviderConfig { + model: string; // Model identifier + apiKey?: string; // API authentication + timeout?: number; // Request timeout (ms) +} + +interface ExecuteOptions { + prompt: string; // User prompt + model: string; // Bare model ID + originalModel: string; // Model with prefix + cwd: string; // Working directory + systemPrompt?: string; // System prompt + maxTurns?: number; // Max agentic turns + allowedTools?: string[]; // Permitted tools + abortController: AbortController; + conversationHistory?: ConversationMessage[]; + settingSources?: Array<'user' | 'project'>; + sdkSessionId?: string; // Resume session + mcpServers?: Record; + agents?: Record; + thinkingLevel?: ThinkingLevel; // Claude thinking mode + reasoningEffort?: ReasoningEffort; // Codex reasoning +} +``` + +--- + +## 6.2 Entity Relationships + +``` ++----------------+ +----------------+ +| Session | | Feature | ++----------------+ +----------------+ +| id | | id | +| name | | name | +| projectPath | | description | +| messages[] +------>+ status | +| model | | priority | ++-------+--------+ | dependencies[] | + | +--------+-------+ + | | + v v ++----------------+ +----------------+ +| Message | | Worktree | ++----------------+ +----------------+ +| id | | path | +| role | | branch | +| content | | featureId | +| images[] | +----------------+ +| timestamp | ++----------------+ + ++----------------+ +----------------+ +| GlobalSettings | |ProjectSettings | ++----------------+ +----------------+ +| theme | | name | +| defaultModel | | model | +| eventHooks[] | | planningMode | +| mcpServers{} | | gitWorkflow{} | ++-------+--------+ +--------+-------+ + | | + +------------+------------+ + | + v + +--------------+ + | Credentials | + +--------------+ + | anthropicKey | + | githubToken | + +--------------+ +``` + +--- + +## 6.3 Database Schema + +Automaker uses **file-based storage** (JSON) rather than a traditional database. + +### Storage Locations + +``` +~/.automaker/ # Global config directory ++-- settings.json # GlobalSettings ++-- credentials.json # Credentials (encrypted) ++-- usage/ # Usage tracking +| ++-- data/ # Server data directory + +-- sessions-metadata.json # Session index + +-- agent-sessions/ # Session data + | +-- {sessionId}.json # Messages array + | +-- {sessionId}-queue.json # Prompt queue + | + +-- notifications/ # Notification storage + +-- notifications.json + +{project}/.automaker/ # Per-project config ++-- settings.json # ProjectSettings ++-- features/ # Feature data +| +-- {featureId}/ +| +-- spec.md # Feature specification +| +-- plan.json # Implementation plan +| +-- progress.json # Status tracking +| ++-- agent-sessions/ # Project-scoped sessions + +-- {sessionId}/ + +-- messages.json + +-- events.json + +-- state.json +``` + +### File Schemas + +**sessions-metadata.json:** +```json +{ + "session_123": { + "id": "session_123", + "name": "Feature Development", + "projectPath": "/home/user/project", + "workingDirectory": "/home/user/project", + "createdAt": "2026-01-20T10:00:00Z", + "updatedAt": "2026-01-20T12:30:00Z", + "archived": false, + "model": "claude-sonnet-4-20250514" + } +} +``` + +**{sessionId}.json (Messages):** +```json +[ + { + "id": "msg_1705741200_abc123", + "role": "user", + "content": "Help me refactor the auth module", + "timestamp": "2026-01-20T10:00:00Z" + }, + { + "id": "msg_1705741260_def456", + "role": "assistant", + "content": "I'll help you refactor...", + "timestamp": "2026-01-20T10:01:00Z" + } +] +``` + +--- + +## 6.4 API Schemas + +### Request Schemas + +**Create Session:** +```typescript +interface CreateSessionParams { + name: string; + projectPath?: string; + workingDirectory?: string; + model?: string; +} +``` + +**Send Message:** +```typescript +interface SendMessageRequest { + sessionId: string; + message: string; + workingDirectory?: string; + imagePaths?: string[]; + model?: string; + thinkingLevel?: ThinkingLevel; + reasoningEffort?: ReasoningEffort; +} +``` + +**Run Feature:** +```typescript +interface RunFeatureRequest { + featureId: string; + projectPath: string; + planningMode?: PlanningMode; + model?: string; +} +``` + +### Response Schemas + +**Session Response:** +```typescript +interface SessionResponse { + success: boolean; + session?: AgentSession; + error?: string; +} +``` + +**Agent Stream Event:** +```typescript +interface AgentStreamEvent { + type: 'started' | 'stream' | 'tool_use' | 'complete' | 'error'; + sessionId: string; + messageId?: string; + content?: string; + tool?: { name: string; input: unknown }; + error?: string; +} +``` + +--- + +## 6.5 Configuration Schema + +### Environment Variables + +| Variable | Type | Default | Description | +|----------|------|---------|-------------| +| PORT | number | 3008 | Server port | +| HOST | string | 0.0.0.0 | Server host | +| DATA_DIR | string | ./data | Data directory | +| ANTHROPIC_API_KEY | string | - | Claude API key | +| CORS_ORIGIN | string | - | Allowed origins | +| ENABLE_REQUEST_LOGGING | boolean | true | HTTP logging | + +### MCP Server Configuration + +```typescript +interface McpServerConfig { + type: 'stdio' | 'sse' | 'http'; + command?: string; // stdio: executable + args?: string[]; // stdio: arguments + url?: string; // sse/http: server URL + env?: Record; // Environment variables +} + +// Example: +{ + "filesystem": { + "type": "stdio", + "command": "npx", + "args": ["-y", "@modelcontextprotocol/server-filesystem", "/home"] + } +} +``` + +--- + +## 6.6 Quality Checklist + +- [x] All core entities documented with TypeScript interfaces +- [x] Field types and purposes are specified +- [x] Entity relationships are diagrammed +- [x] Storage locations are documented +- [x] API request/response schemas provided +- [x] Configuration schema includes env vars and MCP config +- [x] Validation rules implied through types diff --git a/genesis_spec/section_guides/Automaker_Section_07_Security_Compliance.md b/genesis_spec/section_guides/Automaker_Section_07_Security_Compliance.md new file mode 100644 index 000000000..35c530591 --- /dev/null +++ b/genesis_spec/section_guides/Automaker_Section_07_Security_Compliance.md @@ -0,0 +1,316 @@ +# Automaker Genesis Specification - Section 07: Security & Compliance + +**Version**: 1.0.0 +**Last Updated**: 2026-01-20 +**Status**: Active Development + +--- + +## 7.1 Security Model + +### Security Architecture Overview + +``` ++-------------------------------------------------------------------+ +| Security Layers | ++-------------------------------------------------------------------+ +| | +| +--------------------+ +--------------------+ +---------------+| +| | Authentication | | Authorization | | Data Protection| +| | - API Key auth | | - Path validation | | - Encrypted || +| | - Session tokens | | - Tool restrictions| | credentials || +| | - WS tokens | | - CORS policy | | - Secure FS || +| +--------------------+ +--------------------+ +---------------+| +| | +| +--------------------+ +--------------------+ +---------------+| +| | Input Validation | | Network Security | | Audit Logging || +| | - JSON schema | | - TLS termination | | - Request logs|| +| | - Path traversal | | - Rate limiting | | - Event history| +| | - Size limits | | - Origin checks | | - Error logs || +| +--------------------+ +--------------------+ +---------------+| +| | ++-------------------------------------------------------------------+ +``` + +### Security Principles + +1. **Defense in Depth**: Multiple layers of security controls +2. **Least Privilege**: Minimal permissions by default +3. **Secure by Default**: Safe configurations out of the box +4. **Fail Secure**: Deny access on errors +5. **Audit Everything**: Log security-relevant events + +--- + +## 7.2 Threat Model + +### STRIDE Analysis + +| Threat | Category | Mitigation | +|--------|----------|------------| +| **Spoofing** | Identity | API key validation, session tokens | +| **Tampering** | Data | Input validation, secure file operations | +| **Repudiation** | Actions | Request logging, event history | +| **Information Disclosure** | Data | Encrypted credentials, path restrictions | +| **Denial of Service** | Availability | Rate limiting, input size limits | +| **Elevation of Privilege** | Authorization | Path validation, tool restrictions | + +### Threat Scenarios + +| ID | Threat | Impact | Likelihood | Mitigation | +|----|--------|--------|------------|------------| +| T-001 | API key exposure | Critical | Medium | Encrypted storage, env vars | +| T-002 | Path traversal | High | Medium | Allowlist validation | +| T-003 | Command injection | Critical | Low | No shell exec in user input | +| T-004 | CSRF attacks | Medium | Medium | JSON content-type required | +| T-005 | WebSocket hijacking | High | Low | Token authentication | +| T-006 | Terminal escape | High | Low | PTY isolation, password option | + +--- + +## 7.3 Authentication + +### API Key Authentication + +```typescript +// Primary authentication method +function checkRawAuthentication( + headers: Record, + query: Record, + cookies: Record +): boolean { + // 1. Check X-API-Key header + const apiKey = headers['x-api-key']; + if (apiKey && validateApiKey(apiKey)) return true; + + // 2. Check session token + const sessionToken = headers['x-session-token'] || query['token']; + if (sessionToken && validateSessionToken(sessionToken)) return true; + + // 3. Check session cookie + const sessionCookie = cookies['automaker_session']; + if (sessionCookie && validateSessionCookie(sessionCookie)) return true; + + return false; +} +``` + +### WebSocket Authentication + +```typescript +// WebSocket-specific token validation +function authenticateWebSocket(request: IncomingMessage): boolean { + // Standard auth methods + if (checkRawAuthentication(headers, query, cookies)) return true; + + // Short-lived WebSocket connection token + const wsToken = url.searchParams.get('wsToken'); + if (wsToken && validateWsConnectionToken(wsToken)) return true; + + return false; +} +``` + +### Terminal Password Protection + +```typescript +// Optional password for terminal access +interface TerminalConfig { + enabled: boolean; + passwordRequired: boolean; + passwordHash?: string; // bcrypt hash +} + +// Token issued after password verification +function validateTerminalToken(token: string | undefined): boolean { + if (!token) return false; + return verifyJWT(token, TERMINAL_SECRET); +} +``` + +--- + +## 7.4 Authorization + +### Path Validation + +```typescript +// Centralized path security +import { initAllowedPaths, isPathAllowed } from '@automaker/platform'; + +// Initialize on startup +initAllowedPaths(); // Sets up home directory restrictions + +// Validate before any file operation +function validateWorkingDirectory(path: string): void { + if (!isPathAllowed(path)) { + throw new PathNotAllowedError(path); + } +} +``` + +### Secure File System Operations + +```typescript +// All file operations go through secure-fs.ts +import * as secureFs from '../lib/secure-fs.js'; + +// Validates path before operation +async function readFile(path: string): Promise { + validatePath(path); + return fs.readFile(path, 'utf-8'); +} + +async function writeFile(path: string, content: string): Promise { + validatePath(path); + return fs.writeFile(path, content, 'utf-8'); +} +``` + +### Tool Restrictions + +```typescript +// Agent tools are explicitly allowlisted +const allowedTools = [ + 'Read', 'Write', 'Edit', + 'Glob', 'Grep', 'Bash', + 'WebSearch', 'WebFetch' +]; + +// Additional tools require configuration +if (skillsConfig.shouldIncludeInTools) { + allowedTools.push('Skill'); +} +if (subagentsConfig.shouldIncludeInTools) { + allowedTools.push('Task'); +} +``` + +--- + +## 7.5 Data Protection + +### Credential Storage + +```typescript +// System keychain for sensitive data +import keytar from 'keytar'; + +// Store API key securely +await keytar.setPassword('automaker', 'anthropic-api-key', apiKey); + +// Retrieve API key +const key = await keytar.getPassword('automaker', 'anthropic-api-key'); + +// Fallback to encrypted file if keychain unavailable +interface EncryptedCredentials { + version: number; + data: string; // AES-256-GCM encrypted + iv: string; // Initialization vector + tag: string; // Auth tag +} +``` + +### Data at Rest + +| Data Type | Protection | +|-----------|------------| +| API Keys | System keychain / AES-256 encrypted file | +| Session Data | JSON files (user-accessible) | +| Settings | JSON files (user-accessible) | +| Logs | Plain text (user-accessible) | + +### Data in Transit + +| Connection | Protocol | Encryption | +|------------|----------|------------| +| API Calls | HTTPS | TLS 1.2+ | +| WebSocket | WSS | TLS 1.2+ | +| Local (Electron) | HTTP | N/A (localhost) | +| Docker Internal | HTTP | N/A (isolated network) | + +--- + +## 7.6 Audit Logging + +### Request Logging + +```typescript +// Morgan middleware for HTTP requests +app.use( + morgan(':method :url :status-colored', { + skip: (req) => !requestLoggingEnabled || req.url === '/api/health', + }) +); +``` + +### Event History + +```typescript +interface StoredEvent { + id: string; + type: string; // Event type (e.g., 'agent:tool_use') + timestamp: string; // ISO 8601 + sessionId?: string; // Associated session + payload: unknown; // Event data + source: string; // Origin (e.g., 'agent-service') +} + +// Events are persisted for replay and audit +const eventHistoryService = getEventHistoryService(); +eventHistoryService.store(event); +``` + +### Security Event Logging + +```typescript +// Security-relevant events +logger.info('Client connected, ready state:', ws.readyState); +logger.info('Authentication failed, rejecting connection'); +logger.warn(`Unknown message type: ${msg.type}`); +logger.error('Unhandled Promise Rejection:', reason); +``` + +--- + +## 7.7 Compliance Requirements + +### Current Compliance Status + +| Standard | Status | Notes | +|----------|--------|-------| +| GDPR | Partial | User data stored locally | +| SOC 2 | N/A | Not applicable (local app) | +| HIPAA | N/A | Not applicable | +| PCI DSS | N/A | No payment processing | + +### Privacy Considerations + +- **Local-first**: All data stored on user's machine +- **No telemetry by default**: Opt-in analytics +- **No cloud storage**: Sessions stay local unless explicitly synced +- **API key handling**: Keys sent directly to providers, not stored remotely + +### Security Best Practices Checklist + +- [x] CORS policy prevents cross-origin attacks +- [x] JSON content-type required for POST/PUT/PATCH +- [x] Path traversal prevention via allowlist +- [x] API keys stored in system keychain when available +- [x] WebSocket connections authenticated +- [x] Terminal access optionally password-protected +- [x] Graceful shutdown prevents data loss +- [x] Input validation on all endpoints +- [x] Rate limiting via provider SDKs + +--- + +## 7.8 Quality Checklist + +- [x] Threat model documented using STRIDE +- [x] Authentication mechanisms explained +- [x] Authorization (path validation) documented +- [x] Data protection (at rest and in transit) specified +- [x] Audit logging requirements defined +- [x] Compliance considerations addressed +- [x] Security best practices listed diff --git a/genesis_spec/section_guides/Automaker_Section_08_Testing_Strategy.md b/genesis_spec/section_guides/Automaker_Section_08_Testing_Strategy.md new file mode 100644 index 000000000..1258aa602 --- /dev/null +++ b/genesis_spec/section_guides/Automaker_Section_08_Testing_Strategy.md @@ -0,0 +1,352 @@ +# Automaker Genesis Specification - Section 08: Testing Strategy + +**Version**: 1.0.0 +**Last Updated**: 2026-01-20 +**Status**: Active Development + +--- + +## 8.1 Testing Philosophy + +### Test Pyramid + +``` + /\ + / \ + / E2E \ <- Few, slow, high confidence + /--------\ + / Integ \ <- Some, moderate speed + /------------\ + / Unit \ <- Many, fast, isolated + /________________\ +``` + +### Guiding Principles + +1. **Test Behavior, Not Implementation**: Focus on what code does, not how +2. **Fast Feedback**: Unit tests should run in milliseconds +3. **Isolation**: Tests should not depend on external services +4. **Deterministic**: Same input always produces same output +5. **Maintainable**: Tests should be easy to understand and update + +--- + +## 8.2 Test Types + +| Type | Coverage Target | Tools | Location | +|------|-----------------|-------|----------| +| Unit | 80%+ | Vitest | `apps/server/tests/unit/` | +| Integration | Key flows | Vitest | `apps/server/tests/` | +| E2E | Critical paths | Playwright | `e2e/` | +| Package | Shared libs | Vitest | `libs/*/tests/` | + +### Unit Tests (Vitest) + +- **Purpose**: Test individual functions and classes in isolation +- **Speed**: <100ms per test +- **Mocking**: External dependencies are mocked +- **Assertions**: Vitest expect API + +### Integration Tests + +- **Purpose**: Test service interactions and API routes +- **Speed**: <1s per test +- **Mocking**: External APIs mocked, internal services real +- **Assertions**: Response validation + +### End-to-End Tests (Playwright) + +- **Purpose**: Test complete user workflows +- **Speed**: 5-30s per test +- **Environment**: Full stack (UI + Server) +- **Assertions**: DOM state and network responses + +--- + +## 8.3 Test Organization + +### Directory Structure + +``` +apps/server/ ++-- tests/ + +-- unit/ + | +-- services/ + | | +-- agent-service.test.ts + | | +-- auto-mode-service.test.ts + | | +-- terminal-service.test.ts + | | +-- settings-service.test.ts + | | +-- feature-loader.test.ts + | | +-- pipeline-service.test.ts + | | +-- ideation-service.test.ts + | | +-- claude-usage-service.test.ts + | | +-- dev-server-service.test.ts + | | +-- mcp-test-service.test.ts + | | +-- cursor-config-service.test.ts + | | +-- auto-mode-service-planning.test.ts + | | +-- auto-mode-task-parsing.test.ts + | | + | +-- routes/ + | | +-- pipeline.test.ts + | | +-- running-agents.test.ts + | | +-- app-spec/ + | | +-- common.test.ts + | | +-- parse-and-create-features.test.ts + | | + | +-- lib/ + | +-- security.test.ts + | +-- prompt-builder.test.ts + +apps/ui/ ++-- tests/ + +-- e2e/ + +-- example.spec.ts + +libs/*/ ++-- tests/ + +-- *.test.ts +``` + +### Naming Conventions + +- Test files: `*.test.ts` or `*.spec.ts` +- Describe blocks: Feature or class name +- Test names: `should when ` + +```typescript +describe('AgentService', () => { + describe('sendMessage', () => { + it('should stream responses when agent is not running', async () => { + // Test implementation + }); + + it('should throw error when session not found', async () => { + // Test implementation + }); + }); +}); +``` + +--- + +## 8.4 Test Examples + +### Unit Test Example + +```typescript +// apps/server/tests/unit/services/agent-service.test.ts +import { describe, it, expect, vi, beforeEach } from 'vitest'; +import { AgentService } from '../../../src/services/agent-service.js'; + +describe('AgentService', () => { + let agentService: AgentService; + let mockEvents: EventEmitter; + let mockSettings: SettingsService; + + beforeEach(() => { + mockEvents = { emit: vi.fn(), subscribe: vi.fn() }; + mockSettings = { getGlobalSettings: vi.fn() }; + agentService = new AgentService('./test-data', mockEvents, mockSettings); + }); + + describe('createSession', () => { + it('should create session with generated ID', async () => { + const session = await agentService.createSession('Test Session'); + + expect(session.id).toBeDefined(); + expect(session.name).toBe('Test Session'); + expect(session.createdAt).toBeDefined(); + }); + + it('should validate working directory path', async () => { + await expect( + agentService.createSession('Test', '/etc/passwd') + ).rejects.toThrow('Path not allowed'); + }); + }); +}); +``` + +### Integration Test Example + +```typescript +// apps/server/tests/integration/routes/sessions.test.ts +import { describe, it, expect, beforeAll, afterAll } from 'vitest'; +import request from 'supertest'; +import { createTestServer } from '../../helpers/server.js'; + +describe('Sessions API', () => { + let app: Express.Application; + + beforeAll(async () => { + app = await createTestServer(); + }); + + it('POST /api/sessions creates a new session', async () => { + const response = await request(app) + .post('/api/sessions') + .send({ name: 'Test Session' }) + .set('X-API-Key', 'test-key') + .expect(200); + + expect(response.body.success).toBe(true); + expect(response.body.session.name).toBe('Test Session'); + }); +}); +``` + +### E2E Test Example + +```typescript +// e2e/example.spec.ts +import { test, expect } from '@playwright/test'; + +test('user can create a new session', async ({ page }) => { + await page.goto('http://localhost:3007'); + + // Click create session button + await page.click('[data-testid="create-session"]'); + + // Fill in session name + await page.fill('[data-testid="session-name-input"]', 'My Test Session'); + + // Submit + await page.click('[data-testid="create-session-submit"]'); + + // Verify session appears in list + await expect(page.locator('text=My Test Session')).toBeVisible(); +}); +``` + +--- + +## 8.5 CI/CD Testing + +### GitHub Actions Workflow + +```yaml +# .github/workflows/ci.yml +name: CI + +on: [push, pull_request] + +jobs: + format: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: '22' + - run: npm ci + - run: npm run format:check + + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + - run: npm ci + - run: npm run build + + test-packages: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + - run: npm ci + - run: npm run test:packages + + test-server: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + - run: npm ci + - run: npm run test:server +``` + +### CI Testing Environment + +```bash +# Mock agent mode for CI (no API key required) +AUTOMAKER_MOCK_AGENT=true npm run test +``` + +--- + +## 8.6 Coverage Metrics + +### Coverage Targets + +| Area | Current | Target | +|------|---------|--------| +| Server Unit Tests | ~75% | 80% | +| Shared Packages | ~60% | 70% | +| E2E Critical Paths | ~50% | 80% | + +### Coverage Reports + +```bash +# Generate coverage report +npm run test:server:coverage + +# Output location +coverage/ ++-- lcov-report/ +| +-- index.html # HTML report ++-- lcov.info # LCOV format ++-- coverage-summary.json +``` + +### Coverage Configuration + +```typescript +// vitest.config.ts +export default defineConfig({ + test: { + coverage: { + provider: 'v8', + reporter: ['text', 'lcov', 'html'], + exclude: [ + 'node_modules', + 'dist', + '**/*.test.ts', + '**/types/**', + ], + thresholds: { + lines: 80, + branches: 75, + functions: 80, + statements: 80, + }, + }, + }, +}); +``` + +--- + +## 8.7 Test Commands Reference + +| Command | Description | +|---------|-------------| +| `npm run test` | Run E2E tests (Playwright) | +| `npm run test:headed` | E2E with visible browser | +| `npm run test:server` | Server unit tests | +| `npm run test:server:coverage` | Server tests with coverage | +| `npm run test:packages` | Shared library tests | +| `npm run test:all` | All tests | +| `npm run test:watch` | Watch mode | + +--- + +## 8.8 Quality Checklist + +- [x] Test strategy defined (pyramid approach) +- [x] Coverage targets set for all areas +- [x] Test examples provided for each type +- [x] CI integration documented +- [x] Coverage reporting configured +- [x] Test commands listed +- [x] Naming conventions established diff --git a/genesis_spec/section_guides/Automaker_Section_09_Monitoring_Observability.md b/genesis_spec/section_guides/Automaker_Section_09_Monitoring_Observability.md new file mode 100644 index 000000000..bbd143fe0 --- /dev/null +++ b/genesis_spec/section_guides/Automaker_Section_09_Monitoring_Observability.md @@ -0,0 +1,319 @@ +# Automaker Genesis Specification - Section 09: Monitoring & Observability + +**Version**: 1.0.0 +**Last Updated**: 2026-01-20 +**Status**: Active Development + +--- + +## 9.1 Observability Architecture + +### Three Pillars + +``` ++-------------------------------------------------------------------------+ +| Observability Stack | ++-------------------------------------------------------------------------+ +| | +| +---------------------+ +---------------------+ +------------------+ | +| | LOGS | | METRICS | | TRACES | | +| | | | | | | | +| | - Request logs | | - HTTP status codes | | - WebSocket | | +| | - Error logs | | - Session counts | | connections | | +| | - Event history | | - Agent usage | | - API latency | | +| | - Agent activity | | - Terminal sessions | | - Event flow | | +| | | | | | | | +| | Morgan + Custom | | Event-based | | Event History | | +| +---------------------+ +---------------------+ +------------------+ | +| | ++-------------------------------------------------------------------------+ +``` + +--- + +## 9.2 Logging + +### Log Levels + +| Level | Use Case | Example | +|-------|----------|---------| +| ERROR | System failures | `Failed to save session: ENOENT` | +| WARN | Recoverable issues | `No ANTHROPIC_API_KEY configured` | +| INFO | Normal operations | `Agent service initialized` | +| DEBUG | Detailed tracing | `Event received: { type, hasPayload }` | + +### Logger Implementation + +```typescript +// @automaker/utils - createLogger +import { createLogger, setLogLevel, LogLevel } from '@automaker/utils'; + +const logger = createLogger('AgentService'); + +// Configure log level from settings +const LOG_LEVEL_MAP: Record = { + error: LogLevel.ERROR, + warn: LogLevel.WARN, + info: LogLevel.INFO, + debug: LogLevel.DEBUG, +}; + +// Set level at startup +const settings = await settingsService.getGlobalSettings(); +if (settings.serverLogLevel) { + setLogLevel(LOG_LEVEL_MAP[settings.serverLogLevel]); +} +``` + +### Request Logging + +```typescript +// Morgan middleware with colored status codes +morgan.token('status-colored', (_req, res) => { + const status = res.statusCode; + if (status >= 500) return `\x1b[31m${status}\x1b[0m`; // Red + if (status >= 400) return `\x1b[33m${status}\x1b[0m`; // Yellow + if (status >= 300) return `\x1b[36m${status}\x1b[0m`; // Cyan + return `\x1b[32m${status}\x1b[0m`; // Green +}); + +app.use(morgan(':method :url :status-colored', { + skip: (req) => !requestLoggingEnabled || req.url === '/api/health', +})); +``` + +### Log Output Locations + +| Environment | Output | +|-------------|--------| +| Development | Console (stdout) | +| Docker | Container logs (stdout) | +| Electron | Console + file (~/.automaker/logs/) | + +### Structured Logging Format + +```typescript +// Error logging with context +logger.error('Error processing message:', { + sessionId, + messageType: msg.type, + error: error.message, + stack: error.stack, +}); + +// Info logging with metrics +logger.info('Event received:', { + type, + hasPayload: !!payload, + payloadKeys: payload ? Object.keys(payload) : [], + wsReadyState: ws.readyState, +}); +``` + +--- + +## 9.3 Metrics + +### Application Metrics + +| Metric | Type | Description | +|--------|------|-------------| +| `agent_sessions_active` | Gauge | Currently active sessions | +| `agent_messages_total` | Counter | Total messages sent | +| `agent_errors_total` | Counter | Total agent errors | +| `terminal_sessions_active` | Gauge | Active terminal sessions | +| `websocket_connections` | Gauge | Connected WebSocket clients | +| `feature_completions` | Counter | Completed feature implementations | + +### Collection Points + +```typescript +// Session metrics (implicit via Map size) +const sessions = new Map(); +// sessions.size = active session count + +// Terminal connections tracking +const terminalConnections: Map> = new Map(); +// terminalConnections.size = active terminal sessions + +// WebSocket client count +wss.clients.size; // Connected event clients +``` + +### Usage Tracking Services + +```typescript +// Claude API usage +const claudeUsageService = new ClaudeUsageService(); +// Tracks token usage, request counts, costs + +// Codex API usage +const codexUsageService = new CodexUsageService(codexAppServerService); +// Tracks model usage, rate limits +``` + +--- + +## 9.4 Distributed Tracing + +### Event Flow Tracing + +```typescript +// Event History Service provides trace-like capability +interface StoredEvent { + id: string; // Unique event ID + type: string; // Event type + timestamp: string; // ISO timestamp + sessionId?: string; // Correlation ID + payload: unknown; // Event data +} + +// All events stored for replay +eventHistoryService.store({ + id: generateId(), + type: 'agent:tool_use', + timestamp: new Date().toISOString(), + sessionId, + payload: { tool: toolName, input }, +}); +``` + +### Session-Based Correlation + +```typescript +// All events include sessionId for correlation +this.emitAgentEvent(sessionId, { + type: 'stream', + messageId: currentAssistantMessage.id, + content: responseText, + isComplete: false, +}); + +// Query events by session +const events = await eventHistoryService.getBySession(sessionId); +``` + +--- + +## 9.5 Health Checks + +### Basic Health Endpoint + +```typescript +// GET /api/health - Unauthenticated +app.use('/api/health', createHealthRoutes()); + +// Response +{ + "status": "ok", + "timestamp": "2026-01-20T12:00:00Z" +} +``` + +### Detailed Health Endpoint + +```typescript +// GET /api/health/detailed - Authenticated +app.get('/api/health/detailed', authMiddleware, createDetailedHandler()); + +// Response +{ + "status": "ok", + "timestamp": "2026-01-20T12:00:00Z", + "uptime": 3600, + "memory": { + "heapUsed": 150000000, + "heapTotal": 200000000, + "rss": 250000000 + }, + "services": { + "agent": "healthy", + "terminal": "healthy", + "settings": "healthy" + } +} +``` + +### Docker Health Check + +```dockerfile +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD curl -f http://localhost:3008/api/health || exit 1 +``` + +--- + +## 9.6 Alerting + +### Error Conditions + +| Condition | Severity | Action | +|-----------|----------|--------| +| Uncaught Exception | Critical | Log + Exit | +| Unhandled Rejection | Warning | Log + Continue | +| WebSocket Disconnect | Info | Log + Cleanup | +| Auth Failure | Warning | Log + Reject | +| Path Traversal Attempt | Warning | Log + Reject | + +### Global Error Handlers + +```typescript +// Unhandled Promise Rejection +process.on('unhandledRejection', (reason: unknown) => { + logger.error('Unhandled Promise Rejection:', { + reason: reason instanceof Error ? reason.message : String(reason), + stack: reason instanceof Error ? reason.stack : undefined, + }); + // Continue running - don't crash +}); + +// Uncaught Exception +process.on('uncaughtException', (error: Error) => { + logger.error('Uncaught Exception:', { + message: error.message, + stack: error.stack, + }); + // Exit - process state is unknown + process.exit(1); +}); +``` + +--- + +## 9.7 Dashboards + +### Console Dashboard (Startup) + +``` ++===========================================================+ +| Automaker Backend Server | ++===========================================================+ +| Listening: 0.0.0.0:3008 | +| HTTP API: http://localhost:3008 | +| WebSocket: ws://localhost:3008/api/events | +| Terminal: ws://localhost:3008/api/terminal/ws | +| Health: http://localhost:3008/api/health | +| Terminal: enabled (password protected) | ++===========================================================+ +``` + +### Status Information + +```typescript +// Runtime status (via API) +GET /api/running-agents // List active agents +GET /api/auto-mode/status // Auto-mode status +GET /api/terminal/sessions // Terminal status +``` + +--- + +## 9.8 Quality Checklist + +- [x] Logging strategy defined with levels +- [x] Key metrics identified +- [x] Health checks documented +- [x] Error handling and alerting specified +- [x] Event tracing via EventHistoryService +- [x] Dashboard/status endpoints listed +- [x] Structured logging format shown diff --git a/genesis_spec/section_guides/Automaker_Section_10_Deployment_Operations.md b/genesis_spec/section_guides/Automaker_Section_10_Deployment_Operations.md new file mode 100644 index 000000000..b7ab599a8 --- /dev/null +++ b/genesis_spec/section_guides/Automaker_Section_10_Deployment_Operations.md @@ -0,0 +1,360 @@ +# Automaker Genesis Specification - Section 10: Deployment & Operations + +**Version**: 1.0.0 +**Last Updated**: 2026-01-20 +**Status**: Active Development + +--- + +## 10.1 Build System + +### Build Commands + +| Command | Description | +|---------|-------------| +| `npm run build` | Build all packages and apps | +| `npm run build:packages` | Build shared libraries only | +| `npm run build --workspace=apps/server` | Build server only | +| `npm run build --workspace=apps/ui` | Build UI only | +| `npm run build:electron` | Build desktop app | + +### Build Process Flow + +``` +npm run build + | + v ++------------------+ +| build:packages | libs/types, libs/utils, libs/prompts, +| | libs/platform, libs/git-utils, etc. ++--------+---------+ + | + v ++--------+---------+ +------------------+ +| apps/server/ | | apps/ui/ | +| tsc -> dist/ | | vite -> dist/ | ++------------------+ +------------------+ +``` + +### TypeScript Configuration + +```json +// tsconfig.json (root) +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "bundler", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "paths": { + "@automaker/*": ["./libs/*/src"] + } + } +} +``` + +--- + +## 10.2 Installation Methods + +### Development Setup + +```bash +# Clone repository +git clone https://github.com/AutoMaker-Org/automaker.git +cd automaker + +# Install dependencies +npm install + +# Build shared packages +npm run build:packages + +# Start development servers +npm run dev # Interactive launcher +npm run dev:web # Browser mode +npm run dev:electron # Desktop mode +``` + +### Docker Deployment + +```bash +# Build server image +docker build --target server -t automaker-server . + +# Build UI image +docker build --target ui -t automaker-ui . + +# Run with docker-compose +docker-compose up -d +``` + +### Desktop Application + +```bash +# Build for current platform +npm run build:electron + +# Platform-specific builds +npm run build:electron:mac # macOS DMG +npm run build:electron:win # Windows NSIS +npm run build:electron:linux # Linux AppImage + +# Output in apps/ui/release/ +``` + +--- + +## 10.3 Configuration + +### Configuration Hierarchy + +``` +1. Environment Variables (highest priority) +2. Global Settings (~/.automaker/settings.json) +3. Project Settings ({project}/.automaker/settings.json) +4. Default Values (lowest priority) +``` + +### Environment Variables + +| Variable | Default | Description | +|----------|---------|-------------| +| `PORT` | 3008 | Server HTTP port | +| `HOST` | 0.0.0.0 | Server bind address | +| `HOSTNAME` | localhost | Display hostname | +| `DATA_DIR` | ./data | Data storage directory | +| `ANTHROPIC_API_KEY` | - | Claude API authentication | +| `CORS_ORIGIN` | - | Allowed CORS origins | +| `ENABLE_REQUEST_LOGGING` | true | HTTP request logging | + +### Docker Environment + +```yaml +# docker-compose.yml +services: + server: + image: automaker-server + environment: + - PORT=3008 + - DATA_DIR=/data + - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} + - GH_TOKEN=${GH_TOKEN} + volumes: + - automaker-data:/data + - ./projects:/projects + ports: + - "3008:3008" +``` + +--- + +## 10.4 Runtime Requirements + +### System Requirements + +| Component | Minimum | Recommended | +|-----------|---------|-------------| +| CPU | 2 cores | 4+ cores | +| RAM | 4 GB | 8+ GB | +| Disk | 2 GB | 10+ GB | +| Node.js | 22.0.0 | 22.x LTS | + +### Required Software + +| Software | Purpose | +|----------|---------| +| Node.js 22+ | Runtime | +| Git | Version control | +| npm | Package management | + +### Optional Software + +| Software | Purpose | +|----------|---------| +| Docker | Containerized deployment | +| Claude CLI | Claude agent access | +| Cursor CLI | Cursor model access | +| GitHub CLI | Git operations | + +--- + +## 10.5 Operational Procedures + +### Start Server + +```bash +# Development +npm run dev:server + +# Production (built) +node apps/server/dist/index.js + +# Docker +docker-compose up -d server +``` + +### Stop Server + +```bash +# Graceful shutdown (SIGTERM/SIGINT) +Ctrl+C (interactive) +kill -15 + +# Docker +docker-compose down +``` + +### Restart + +```bash +# Docker +docker-compose restart server + +# Process manager (if using PM2) +pm2 restart automaker-server +``` + +### Upgrade + +```bash +# Pull latest changes +git pull origin main + +# Install new dependencies +npm install + +# Rebuild packages +npm run build:packages +npm run build + +# Restart server +npm run dev +``` + +--- + +## 10.6 Maintenance + +### Cleanup Tasks + +```bash +# Clear old session data (manual) +rm -rf ~/.automaker/data/agent-sessions/* + +# Clean node_modules and reinstall +rm -rf node_modules +npm install + +# Clear build artifacts +rm -rf apps/*/dist libs/*/dist +``` + +### Backup + +```bash +# Backup user data +cp -r ~/.automaker ~/automaker-backup-$(date +%Y%m%d) + +# Backup project settings +cp -r {project}/.automaker {project}/.automaker-backup +``` + +### Restore + +```bash +# Restore from backup +cp -r ~/automaker-backup-20260120 ~/.automaker +``` + +--- + +## 10.7 Troubleshooting + +### Common Issues + +| Issue | Cause | Solution | +|-------|-------|----------| +| Port already in use | Previous process | `lsof -ti:3008 \| xargs kill -9` | +| WebSocket disconnects | Timeout | Check firewall settings | +| Agent won't start | Missing API key | Set ANTHROPIC_API_KEY | +| Terminal not working | node-pty issue | `npm rebuild node-pty` | +| Session not persisting | Write permissions | Check DATA_DIR permissions | + +### Debug Mode + +```bash +# Enable debug logging +DEBUG=automaker:* npm run dev + +# Set log level in settings +# ~/.automaker/settings.json +{ + "serverLogLevel": "debug" +} +``` + +### Log Locations + +| Location | Content | +|----------|---------| +| Console (stdout) | Server logs | +| ~/.automaker/logs/ | Persistent logs (Electron) | +| Docker logs | `docker logs automaker-server` | + +### Port Conflict Resolution + +```bash +# Find process using port +lsof -i :3008 + +# Kill process +kill -9 + +# Or use different port +PORT=3009 npm run dev +``` + +--- + +## 10.8 Scaling + +### Horizontal Scaling + +Not currently supported - single-instance architecture. Future considerations: +- Session state externalization (Redis) +- Load balancer for UI +- Separate agent worker processes + +### Vertical Scaling + +| Resource | Impact | +|----------|--------| +| More CPU | Faster builds, more concurrent terminals | +| More RAM | More concurrent sessions, larger contexts | +| SSD | Faster file operations, session loading | + +### Performance Tuning + +```bash +# Increase Node.js memory limit +NODE_OPTIONS="--max-old-space-size=4096" npm run dev + +# Disable request logging for performance +ENABLE_REQUEST_LOGGING=false npm run dev +``` + +--- + +## 10.9 Quality Checklist + +- [x] Build system documented +- [x] All installation methods covered +- [x] Configuration options listed +- [x] Runtime requirements specified +- [x] Operational procedures complete +- [x] Maintenance procedures documented +- [x] Troubleshooting guide provided +- [x] Scaling considerations noted diff --git a/genesis_spec/section_guides/Automaker_Section_11_Documentation.md b/genesis_spec/section_guides/Automaker_Section_11_Documentation.md new file mode 100644 index 000000000..36926658d --- /dev/null +++ b/genesis_spec/section_guides/Automaker_Section_11_Documentation.md @@ -0,0 +1,314 @@ +# Automaker Genesis Specification - Section 11: Documentation & Knowledge Management + +**Version**: 1.0.0 +**Last Updated**: 2026-01-20 +**Status**: Active Development + +--- + +## 11.1 Documentation Structure + +### Documentation Hierarchy + +``` +automaker/ ++-- README.md # Project overview and quick start ++-- CONTRIBUTING.md # Contribution guidelines ++-- ARCHITECTURE.md # Technical architecture ++-- CLAUDE.md # AI agent context ++-- LICENSE # License terms ++-- CHANGELOG.md # Version history +| ++-- docs/ # Extended documentation +| +-- getting-started.md +| +-- api-reference.md +| +-- troubleshooting.md +| ++-- genesis_spec/ # Genesis documentation + +-- section_guides/ + +-- Automaker_Section_01_Introduction.md + +-- Automaker_Section_02_Product_Requirements.md + +-- ... (12 sections total) +``` + +### Documentation Types + +| Type | Location | Purpose | Audience | +|------|----------|---------|----------| +| README | Root | Quick start, overview | New users | +| CONTRIBUTING | Root | How to contribute | Contributors | +| ARCHITECTURE | Root | Technical overview | Developers | +| CLAUDE.md | Root | AI agent instructions | AI agents | +| Genesis Spec | genesis_spec/ | Comprehensive reference | All | +| API Docs | Inline | Endpoint documentation | Integrators | +| Code Comments | Source | Implementation details | Maintainers | + +--- + +## 11.2 Code Documentation + +### TypeScript/JSDoc Standards + +```typescript +/** + * Agent Service - Manages AI agent sessions and conversations + * + * Handles spawning, messaging, and lifecycle of Claude-based agents. + * Sessions are persisted to disk and can be resumed across restarts. + * + * @example + * const agentService = new AgentService(dataDir, events, settings); + * await agentService.initialize(); + * const session = await agentService.createSession('My Session'); + */ +export class AgentService { + /** + * Send a message to an active agent session + * + * @param params - Message parameters + * @param params.sessionId - Target session ID + * @param params.message - User message content + * @param params.imagePaths - Optional image attachments + * @param params.model - Override model for this message + * @returns Promise resolving to message result + * @throws Error if session not found or agent already running + */ + async sendMessage(params: SendMessageParams): Promise { + // Implementation + } +} +``` + +### Comment Guidelines + +1. **File Headers**: Purpose and module overview +2. **Class Comments**: Responsibility and usage examples +3. **Method Comments**: Parameters, return values, exceptions +4. **Complex Logic**: Explain why, not what +5. **TODO/FIXME**: Include issue reference + +```typescript +// Good: Explains reasoning +// Rate limit resize operations to prevent storm during panel splits +const RESIZE_MIN_INTERVAL_MS = 100; + +// Bad: States the obvious +// Set interval to 100 +const RESIZE_MIN_INTERVAL_MS = 100; +``` + +--- + +## 11.3 API Documentation + +### REST API Documentation Pattern + +```typescript +/** + * @route POST /api/sessions + * @group Sessions - Session management operations + * @param {CreateSessionParams} body.required - Session creation parameters + * @returns {SessionResponse} 200 - Session created successfully + * @returns {ErrorResponse} 400 - Invalid parameters + * @returns {ErrorResponse} 401 - Unauthorized + * + * @example request + * { + * "name": "My Development Session", + * "projectPath": "/home/user/myproject" + * } + * + * @example response - 200 + * { + * "success": true, + * "session": { + * "id": "session_123", + * "name": "My Development Session", + * "createdAt": "2026-01-20T10:00:00Z" + * } + * } + */ +``` + +### WebSocket Event Documentation + +```typescript +/** + * WebSocket Events - /api/events + * + * Events: + * - agent:stream - Streaming response content + * - agent:tool_use - Agent using a tool + * - agent:complete - Message completed + * - agent:error - Error occurred + * - feature:status - Feature status changed + * + * @example agent:stream + * { + * "type": "agent:stream", + * "sessionId": "session_123", + * "messageId": "msg_456", + * "content": "Here's the refactored code...", + * "isComplete": false + * } + */ +``` + +--- + +## 11.4 Architecture Documentation + +### Architecture Decision Records (ADRs) + +Location: Inline in ARCHITECTURE.md or separate `docs/adrs/` + +```markdown +# ADR-001: Monorepo Structure + +## Status +Accepted + +## Context +Need to share TypeScript types and utilities between frontend and backend. + +## Decision +Use npm workspaces with `libs/` directory for shared packages. + +## Consequences +- Single repository for all code +- Shared TypeScript types via @automaker/* +- Atomic commits across packages +- Build order dependency management required +``` + +### Component Documentation + +Each major component should document: +- Purpose and responsibility +- Dependencies (internal and external) +- Configuration options +- Public API surface +- Error handling behavior + +--- + +## 11.5 User Documentation + +### Getting Started Guide + +```markdown +# Getting Started with Automaker + +## Prerequisites +- Node.js 22+ +- Git +- Anthropic API key + +## Installation +1. Clone the repository +2. Run `npm install` +3. Set `ANTHROPIC_API_KEY` environment variable +4. Run `npm run dev` + +## First Session +1. Click "New Session" +2. Enter a name for your session +3. Type a message to the AI agent +4. Watch the response stream in real-time +``` + +### Feature Tutorials + +- Creating and managing sessions +- Using auto-mode for feature development +- Configuring settings +- Working with terminals +- Git workflow integration + +--- + +## 11.6 Contributing Guidelines + +### Document Updates Required + +| Change Type | Documentation Required | +|-------------|----------------------| +| New feature | README, user guide, API docs | +| API change | API reference, CHANGELOG | +| Bug fix | CHANGELOG | +| Refactoring | ARCHITECTURE (if significant) | +| Configuration | Settings documentation | + +### Documentation Review Checklist + +- [ ] Code comments for public APIs +- [ ] README updated if user-facing change +- [ ] CHANGELOG entry added +- [ ] API documentation updated +- [ ] Architecture docs updated (if applicable) + +--- + +## 11.7 Changelog Management + +### Changelog Format (Keep a Changelog) + +```markdown +# Changelog + +All notable changes to this project will be documented in this file. + +## [Unreleased] + +### Added +- New feature description + +### Changed +- Changed behavior description + +### Deprecated +- Soon-to-be removed features + +### Removed +- Removed features + +### Fixed +- Bug fix description + +### Security +- Security fix description + +## [0.12.0] - 2026-01-15 + +### Added +- Multi-provider support (Codex, Cursor, OpenCode) +- Event hook system for custom automation +``` + +### Version Numbering + +``` +MAJOR.MINOR.PATCH + +MAJOR: Breaking changes +MINOR: New features (backward compatible) +PATCH: Bug fixes (backward compatible) + +Examples: +0.12.0 -> 0.12.1 (bug fix) +0.12.0 -> 0.13.0 (new feature) +0.12.0 -> 1.0.0 (breaking change / stable release) +``` + +--- + +## 11.8 Quality Checklist + +- [x] Documentation structure defined +- [x] Code documentation standards set +- [x] API documentation pattern established +- [x] Architecture documentation guidelines +- [x] User documentation structure +- [x] Contributing guidelines for docs +- [x] Changelog format specified +- [x] Version numbering explained diff --git a/genesis_spec/section_guides/Automaker_Section_12_Reference_Collections.md b/genesis_spec/section_guides/Automaker_Section_12_Reference_Collections.md new file mode 100644 index 000000000..ff1738357 --- /dev/null +++ b/genesis_spec/section_guides/Automaker_Section_12_Reference_Collections.md @@ -0,0 +1,280 @@ +# Automaker Genesis Specification - Section 12: Reference Collections + +**Version**: 1.0.0 +**Last Updated**: 2026-01-20 +**Status**: Active Development + +--- + +## 12.1 Official Resources + +### Project Links + +| Resource | URL | +|----------|-----| +| GitHub Repository | https://github.com/AutoMaker-Org/automaker | +| Issue Tracker | https://github.com/AutoMaker-Org/automaker/issues | +| Pull Requests | https://github.com/AutoMaker-Org/automaker/pulls | +| Discord Community | https://discord.gg/jjem7aEDKU | + +### Documentation + +| Document | Location | +|----------|----------| +| README | `/README.md` | +| Contributing Guide | `/CONTRIBUTING.md` | +| Architecture | `/ARCHITECTURE.md` | +| Claude Context | `/CLAUDE.md` | +| License | `/LICENSE` | + +--- + +## 12.2 Technology References + +### Core Technologies + +| Technology | Documentation | +|------------|--------------| +| TypeScript | https://www.typescriptlang.org/docs/ | +| Node.js | https://nodejs.org/docs/ | +| React | https://react.dev/ | +| Express | https://expressjs.com/ | +| Electron | https://www.electronjs.org/docs | +| Vite | https://vitejs.dev/ | + +### AI SDKs + +| SDK | Documentation | +|-----|--------------| +| Claude Agent SDK | https://docs.anthropic.com/claude/docs | +| MCP Protocol | https://modelcontextprotocol.io/ | +| Codex SDK | https://platform.openai.com/docs | + +### Frontend Libraries + +| Library | Documentation | +|---------|--------------| +| TanStack Router | https://tanstack.com/router | +| TanStack Query | https://tanstack.com/query | +| Zustand | https://zustand-demo.pmnd.rs/ | +| Radix UI | https://www.radix-ui.com/docs | +| Tailwind CSS | https://tailwindcss.com/docs | +| xterm.js | https://xtermjs.org/ | +| CodeMirror | https://codemirror.net/docs/ | + +### Backend Libraries + +| Library | Documentation | +|---------|--------------| +| Express 5 | https://expressjs.com/en/5x/api.html | +| ws (WebSocket) | https://github.com/websockets/ws | +| node-pty | https://github.com/microsoft/node-pty | +| Morgan | https://github.com/expressjs/morgan | + +### Testing Tools + +| Tool | Documentation | +|------|--------------| +| Vitest | https://vitest.dev/ | +| Playwright | https://playwright.dev/ | + +--- + +## 12.3 Related Projects + +### Dependencies + +| Project | Purpose | Repository | +|---------|---------|------------| +| Claude Code | Claude CLI tool | https://github.com/anthropics/claude-code | +| Cursor | AI-powered IDE | https://cursor.com/ | +| GitHub CLI | Git operations | https://cli.github.com/ | + +### Inspiration + +| Project | Relevance | +|---------|-----------| +| Devin | Autonomous AI developer concept | +| Aider | AI pair programming | +| Continue | IDE AI integration | + +--- + +## 12.4 Architecture Patterns + +### Design Patterns Used + +| Pattern | Reference | +|---------|-----------| +| Factory Pattern | https://refactoring.guru/design-patterns/factory-method | +| Service Layer | https://martinfowler.com/eaaCatalog/serviceLayer.html | +| Event-Driven | https://martinfowler.com/articles/201701-event-driven.html | +| Repository Pattern | https://martinfowler.com/eaaCatalog/repository.html | + +### Architecture Styles + +| Style | Reference | +|-------|-----------| +| Monorepo | https://monorepo.tools/ | +| Layered Architecture | https://www.oreilly.com/library/view/software-architecture-patterns/9781491971437/ | +| Event Sourcing | https://martinfowler.com/eaaDev/EventSourcing.html | + +--- + +## 12.5 Security Resources + +### Security Guidelines + +| Topic | Reference | +|-------|-----------| +| OWASP Top 10 | https://owasp.org/www-project-top-ten/ | +| Node.js Security | https://nodejs.org/en/docs/guides/security/ | +| Electron Security | https://www.electronjs.org/docs/tutorial/security | + +### Authentication + +| Topic | Reference | +|-------|-----------| +| API Key Best Practices | https://cloud.google.com/docs/authentication/api-keys | +| Keytar (System Keychain) | https://github.com/atom/node-keytar | + +--- + +## 12.6 Development Tools + +### IDE Support + +| IDE | Extension | +|-----|-----------| +| VS Code | ESLint, Prettier, TypeScript | +| WebStorm | Built-in TypeScript support | +| Cursor | AI-powered editing | + +### CLI Tools + +| Tool | Purpose | +|------|---------| +| npm | Package management | +| tsx | TypeScript execution | +| electron-builder | Desktop packaging | +| gh | GitHub operations | + +### Debugging + +| Tool | Purpose | +|------|---------| +| Chrome DevTools | Frontend debugging | +| Node.js Inspector | Backend debugging | +| React DevTools | Component inspection | + +--- + +## 12.7 Community Resources + +### Support Channels + +| Channel | URL | +|---------|-----| +| Discord | https://discord.gg/jjem7aEDKU | +| GitHub Discussions | https://github.com/AutoMaker-Org/automaker/discussions | +| Issues | https://github.com/AutoMaker-Org/automaker/issues | + +### Learning Resources + +| Resource | Topic | +|----------|-------| +| React Documentation | Frontend development | +| Express Guide | Backend API development | +| Electron Tutorial | Desktop app development | + +--- + +## 12.8 Quick Reference Cards + +### NPM Scripts Cheatsheet + +```bash +# Development +npm run dev # Interactive launcher +npm run dev:web # Browser mode +npm run dev:electron # Desktop mode + +# Building +npm run build # Build all +npm run build:packages # Shared libs only +npm run build:electron # Desktop app + +# Testing +npm run test # E2E tests +npm run test:server # Unit tests +npm run test:all # All tests + +# Quality +npm run lint # ESLint +npm run format # Prettier +npm run typecheck # TypeScript check +``` + +### Environment Variables Cheatsheet + +```bash +# Required +ANTHROPIC_API_KEY=sk-ant-... + +# Optional +PORT=3008 +HOST=0.0.0.0 +DATA_DIR=./data +CORS_ORIGIN=http://localhost:3007 +ENABLE_REQUEST_LOGGING=true + +# Debug +DEBUG=automaker:* +``` + +### Docker Commands Cheatsheet + +```bash +# Build +docker build --target server -t automaker-server . +docker build --target ui -t automaker-ui . + +# Run +docker-compose up -d +docker-compose down +docker-compose logs -f server + +# Health check +curl http://localhost:3008/api/health +``` + +--- + +## 12.9 Glossary + +| Term | Definition | +|------|------------| +| **Agent** | AI-powered assistant that executes tasks autonomously | +| **Auto-Mode** | Autonomous feature development workflow | +| **Feature** | Unit of work to be implemented by agents | +| **MCP** | Model Context Protocol - standard for AI tool integration | +| **Planning Mode** | Strategy for feature planning (skip, lite, spec, full) | +| **Provider** | AI model backend (Claude, Codex, Cursor) | +| **Session** | Persistent conversation context with an agent | +| **Worktree** | Git worktree for isolated feature development | +| **PTY** | Pseudo-terminal for shell emulation | +| **WebSocket** | Bidirectional communication protocol for real-time updates | + +--- + +## 12.10 Quality Checklist + +- [x] Official project links listed +- [x] Technology documentation referenced +- [x] Related projects documented +- [x] Architecture pattern references provided +- [x] Security resources linked +- [x] Development tools listed +- [x] Community resources documented +- [x] Quick reference cards created +- [x] Glossary complete with all terms From 9782e9aafadd0bc72295c6d6d708799d6bff7b0e Mon Sep 17 00:00:00 2001 From: Justus Date: Wed, 21 Jan 2026 01:31:03 +0100 Subject: [PATCH 02/13] chore: add greptile and qodo configurations and agent workflows --- .agent/skills/git-worktrees/SKILL.md | 11 ++++++++++ .agent/workflows/git-worktree.md | 30 ++++++++++++++++++++++++++++ .qodo.toml | 12 +++++++++++ greptile.json | 15 ++++++++++++++ 4 files changed, 68 insertions(+) create mode 100644 .agent/skills/git-worktrees/SKILL.md create mode 100644 .agent/workflows/git-worktree.md create mode 100644 .qodo.toml create mode 100644 greptile.json diff --git a/.agent/skills/git-worktrees/SKILL.md b/.agent/skills/git-worktrees/SKILL.md new file mode 100644 index 000000000..b09381af4 --- /dev/null +++ b/.agent/skills/git-worktrees/SKILL.md @@ -0,0 +1,11 @@ +# Git Worktrees Skill +# IDENTIFIER: automaker-worktree-skill + +## Description +This skill enables the agent to manage isolated development environments using Git Worktrees, which is the preferred way to work in the Automaker repository. + +## Instructions +- Always use `git worktree list` before creating new ones to avoid path conflicts. +- Prefer naming worktrees with the prefix `../automaker-worktree-`. +- Ensure you are in the root of the repository before running worktree commands. +- Use the `git-worktree` workflow for step-by-step execution. diff --git a/.agent/workflows/git-worktree.md b/.agent/workflows/git-worktree.md new file mode 100644 index 000000000..6fddc2c94 --- /dev/null +++ b/.agent/workflows/git-worktree.md @@ -0,0 +1,30 @@ +--- +description: How to manage git worktrees in Automaker (IDENTIFIER: automaker-worktree-workflow) +--- + +# Git Worktree Workflow + +This workflow describes how to safely use git worktrees for feature development in Automaker. + +1. **Check existing worktrees**: + ```bash + git worktree list + ``` + +2. **Create a new worktree for a feature**: + ```bash + git worktree add ../automaker-feature- -b feature/ + ``` + +3. **Navigate to the worktree**: + - `cd ../automaker-feature-` + +4. **Remove worktree after completion**: + ```bash + git worktree remove ../automaker-feature- + git branch -d feature/ + ``` + +// turbo +5. **Verify current setup**: + git status diff --git a/.qodo.toml b/.qodo.toml new file mode 100644 index 000000000..794660977 --- /dev/null +++ b/.qodo.toml @@ -0,0 +1,12 @@ +# Qodo configuration for Automaker +# IDENTIFIER: automaker-qodo-config + +[tests] +framework = "vitest" +directory = "libs" +test_pattern = "**/*.test.ts" + +[quality] +enabled = true +check_types = true +scripts = ["npm run lint"] diff --git a/greptile.json b/greptile.json new file mode 100644 index 000000000..dc7ec6a1f --- /dev/null +++ b/greptile.json @@ -0,0 +1,15 @@ +{ + "name": "automaker-greptile-config", + "project": "automaker", + "labels": [ + "ai-review" + ], + "commentTypes": [ + "logic", + "architecture", + "security" + ], + "instructions": "This is an Automaker-specific configuration. Focus on the monorepo structure (libs/ vs apps/), the Claude Agent SDK integration, and ensure that changes adhere to the patterns defined in CLAUDE.md and DEVELOPMENT_WORKFLOW.md.", + "strictness": 1, + "triggerOnUpdates": true +} \ No newline at end of file From 0dd4e6292fb56cac8f26e3bd0108d28e3c75e77b Mon Sep 17 00:00:00 2001 From: Justus Date: Wed, 21 Jan 2026 02:30:18 +0100 Subject: [PATCH 03/13] feat(server): add Sprites.dev environment configuration --- apps/server/src/config/sprites.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 apps/server/src/config/sprites.ts diff --git a/apps/server/src/config/sprites.ts b/apps/server/src/config/sprites.ts new file mode 100644 index 000000000..57e7c2325 --- /dev/null +++ b/apps/server/src/config/sprites.ts @@ -0,0 +1,13 @@ +export const spritesConfig = { + SPRITES_TOKEN: process.env.SPRITES_TOKEN, + SPRITES_API_BASE: process.env.SPRITES_API_BASE || "https://api.sprites.dev/v1", + GITHUB_TOKEN: process.env.GITHUB_TOKEN, + LINEAR_API_KEY: process.env.LINEAR_API_KEY, + CLAUDE_OAUTH_TOKEN: process.env.CLAUDE_OAUTH_TOKEN, + DEFAULT_REPO_URL: process.env.DEFAULT_REPO_URL, + DEFAULT_BRANCH: process.env.DEFAULT_BRANCH || "main", + GIT_USER_NAME: process.env.GIT_USER_NAME || "Automaker Agent", + GIT_USER_EMAIL: process.env.GIT_USER_EMAIL || "agent@automaker.dev", + OTEL_RECEIVER_PORT: parseInt(process.env.OTEL_RECEIVER_PORT || "4317"), + OTEL_RECEIVER_HOST: process.env.OTEL_RECEIVER_HOST || "0.0.0.0", +}; From af261da666e31b7d91ecdc717c58ddfb0352c695 Mon Sep 17 00:00:00 2001 From: Justus Date: Wed, 21 Jan 2026 12:04:35 +0100 Subject: [PATCH 04/13] feat: Add `tsconfig.json` to configure TypeScript compilation for the server. --- apps/server/tsconfig.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/apps/server/tsconfig.json b/apps/server/tsconfig.json index c83c53332..16dc4280a 100644 --- a/apps/server/tsconfig.json +++ b/apps/server/tsconfig.json @@ -15,6 +15,11 @@ "declarationMap": true, "sourceMap": true }, - "include": ["src/**/*"], - "exclude": ["node_modules", "dist"] + "include": [ + "src/**/*" + ], + "exclude": [ + "node_modules", + "dist" + ] } From 718e16e587ee0fc62f6a6f6ef00f599edb5e61d3 Mon Sep 17 00:00:00 2001 From: Justus Date: Wed, 21 Jan 2026 12:06:58 +0100 Subject: [PATCH 05/13] feat: implement SpriteApiClient and address workflow/config review comments --- .agent/workflows/git-worktree.md | 7 +- .qodo.toml | 11 +- apps/server/package.json | 1 + apps/server/src/services/sprite-api-client.ts | 233 ++++++++++++++++++ .../unit/services/sprite-api-client.test.ts | 159 ++++++++++++ apps/server/tsconfig.json | 6 +- package-lock.json | 136 ++++++---- 7 files changed, 486 insertions(+), 67 deletions(-) create mode 100644 apps/server/src/services/sprite-api-client.ts create mode 100644 apps/server/tests/unit/services/sprite-api-client.test.ts diff --git a/.agent/workflows/git-worktree.md b/.agent/workflows/git-worktree.md index 6fddc2c94..37d8e270a 100644 --- a/.agent/workflows/git-worktree.md +++ b/.agent/workflows/git-worktree.md @@ -13,18 +13,17 @@ This workflow describes how to safely use git worktrees for feature development 2. **Create a new worktree for a feature**: ```bash - git worktree add ../automaker-feature- -b feature/ + git worktree add ../automaker-worktree- -b feature/ ``` 3. **Navigate to the worktree**: - - `cd ../automaker-feature-` + - `cd ../automaker-worktree-` 4. **Remove worktree after completion**: ```bash - git worktree remove ../automaker-feature- + git worktree remove ../automaker-worktree- git branch -d feature/ ``` -// turbo 5. **Verify current setup**: git status diff --git a/.qodo.toml b/.qodo.toml index 794660977..1505f8dde 100644 --- a/.qodo.toml +++ b/.qodo.toml @@ -1,12 +1,5 @@ # Qodo configuration for Automaker # IDENTIFIER: automaker-qodo-config -[tests] -framework = "vitest" -directory = "libs" -test_pattern = "**/*.test.ts" - -[quality] -enabled = true -check_types = true -scripts = ["npm run lint"] +[pr_test] +testing_framework = "vitest" diff --git a/apps/server/package.json b/apps/server/package.json index e214eb022..68b031584 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -34,6 +34,7 @@ "@automaker/utils": "1.0.0", "@modelcontextprotocol/sdk": "1.25.2", "@openai/codex-sdk": "^0.77.0", + "axios": "^1.13.2", "cookie-parser": "1.4.7", "cors": "2.8.5", "dotenv": "17.2.3", diff --git a/apps/server/src/services/sprite-api-client.ts b/apps/server/src/services/sprite-api-client.ts new file mode 100644 index 000000000..d1cc9b232 --- /dev/null +++ b/apps/server/src/services/sprite-api-client.ts @@ -0,0 +1,233 @@ +import { EventEmitter } from 'events'; +import { createLogger } from '@automaker/utils'; +import { spritesConfig } from '../config/sprites.js'; + +const logger = createLogger('SpriteApiClient'); + +export interface Sprite { + id: string; + name: string; + status: 'running' | 'hibernating' | 'provisioning' | 'error'; + lastActivityAt: string; + createdAt: string; +} + +export interface Checkpoint { + id: string; + spriteId: string; + name: string; + createdAt: string; +} + +export interface ExecResult { + stdout: string; + stderr: string; + exitCode: number; + durationMs: number; +} + +export interface SpriteConfig { + name: string; + repoUrl?: string; + branch?: string; + env?: Record; +} + +/** + * SpriteApiClient - Client for interacting with the Sprites.dev REST API + * + * Handles sprite lifecycle, command execution, and state management. + * Uses native Node 22 fetch for communication. + */ +export class SpriteApiClient extends EventEmitter { + private apiBase: string; + private token: string; + private statusCache: Map = new Map(); + + constructor() { + super(); + this.apiBase = spritesConfig.SPRITES_API_BASE || 'https://api.sprites.dev/v1'; + this.token = spritesConfig.SPRITES_TOKEN || ''; + + if (!this.token) { + logger.warn('SPRITES_TOKEN is not configured. API calls will fail.'); + } + } + + /** + * Helper to perform authenticated fetch requests + */ + private async request(path: string, options: RequestInit = {}): Promise { + const url = `${this.apiBase}${path.startsWith('/') ? path : `/${path}`}`; + const headers = { + 'Authorization': `Bearer ${this.token}`, + 'Content-Type': 'application/json', + ...options.headers, + }; + + try { + const response = await fetch(url, { ...options, headers }); + + if (!response.ok) { + const errorText = await response.text(); + throw new Error(`Sprites API Error (${response.status}): ${errorText || response.statusText}`); + } + + if (response.status === 204) { + return {} as T; + } + + return (await response.json()) as T; + } catch (error) { + logger.error(`Request to ${url} failed:`, error); + throw error; + } + } + + // ============================================================================ + // Sprite CRUD + // ============================================================================ + + /** + * List all sprites associated with the account + */ + async listSprites(): Promise { + const sprites = await this.request('/sprites'); + sprites.forEach(s => this.statusCache.set(s.id, s)); + return sprites; + } + + /** + * Get details for a specific sprite + */ + async getSprite(id: string): Promise { + const sprite = await this.request(`/sprites/${id}`); + this.statusCache.set(sprite.id, sprite); + return sprite; + } + + /** + * Provision a new sprite + */ + async createSprite(config: SpriteConfig): Promise { + logger.info(`Creating sprite: ${config.name}`); + const sprite = await this.request('/sprites', { + method: 'POST', + body: JSON.stringify({ + ...config, + repoUrl: config.repoUrl || spritesConfig.DEFAULT_REPO_URL, + branch: config.branch || spritesConfig.DEFAULT_BRANCH, + }), + }); + + this.statusCache.set(sprite.id, sprite); + this.emit('spriteCreated', sprite); + return sprite; + } + + /** + * Delete a sprite + */ + async deleteSprite(id: string): Promise { + logger.info(`Deleting sprite: ${id}`); + await this.request(`/sprites/${id}`, { method: 'DELETE' }); + this.statusCache.delete(id); + this.emit('spriteDeleted', id); + } + + // ============================================================================ + // Command Execution + // ============================================================================ + + /** + * Execute a shell command on a sprite + */ + async execCommand(spriteId: string, command: string, timeout: number = 60000): Promise { + logger.debug(`Executing on sprite ${spriteId}: ${command}`); + + const result = await this.request(`/sprites/${spriteId}/exec`, { + method: 'POST', + body: JSON.stringify({ command, timeout }), + }); + + return result; + } + + // ============================================================================ + // Checkpointing + // ============================================================================ + + /** + * Create a checkpoint of the current sprite state + */ + async createCheckpoint(spriteId: string, name: string): Promise { + logger.info(`Creating checkpoint '${name}' for sprite ${spriteId}`); + return this.request(`/sprites/${spriteId}/checkpoints`, { + method: 'POST', + body: JSON.stringify({ name }), + }); + } + + /** + * Restore a sprite to a specified checkpoint + */ + async restoreCheckpoint(spriteId: string, checkpointId: string): Promise { + logger.info(`Restoring sprite ${spriteId} to checkpoint ${checkpointId}`); + await this.request(`/sprites/${spriteId}/restore`, { + method: 'POST', + body: JSON.stringify({ checkpointId }), + }); + this.emit('spriteRestored', { spriteId, checkpointId }); + } + + // ============================================================================ + // Lifecycle Management + // ============================================================================ + + /** + * Shut down (hibernate) a running sprite + */ + async shutdownSprite(spriteId: string): Promise { + logger.info(`Shutting down sprite ${spriteId}`); + await this.request(`/sprites/${spriteId}/shutdown`, { method: 'POST' }); + + const sprite = this.statusCache.get(spriteId); + if (sprite) { + sprite.status = 'hibernating'; + this.emit('spriteStatusChanged', sprite); + } + } + + /** + * Wake up a hibernating sprite + */ + async wakeSprite(spriteId: string): Promise { + logger.info(`Waking up sprite ${spriteId}`); + await this.request(`/sprites/${spriteId}/wake`, { method: 'POST' }); + + const sprite = this.statusCache.get(spriteId); + if (sprite) { + sprite.status = 'running'; + this.emit('spriteStatusChanged', sprite); + } + } + + // ============================================================================ + // Utilities + // ============================================================================ + + /** + * Get the console URL for a sprite in the Sprites dashboard + */ + getConsoleUrl(spriteName: string): string { + const baseUrl = this.apiBase.replace('/v1', '').replace('api.', ''); + return `${baseUrl}/dashboard/sprites/${spriteName}`; + } + + /** + * Clear local status cache + */ + clearCache(): void { + this.statusCache.clear(); + } +} diff --git a/apps/server/tests/unit/services/sprite-api-client.test.ts b/apps/server/tests/unit/services/sprite-api-client.test.ts new file mode 100644 index 000000000..14b5a031c --- /dev/null +++ b/apps/server/tests/unit/services/sprite-api-client.test.ts @@ -0,0 +1,159 @@ +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; +import { SpriteApiClient } from '../../../src/services/sprite-api-client.js'; + +// Mock the config +vi.mock('../../../src/config/sprites.js', () => ({ + spritesConfig: { + SPRITES_TOKEN: 'test-token', + SPRITES_API_BASE: 'https://api.test.dev/v1', + DEFAULT_REPO_URL: 'https://github.com/test/repo', + DEFAULT_BRANCH: 'main' + } +})); + +describe('SpriteApiClient', () => { + let client: SpriteApiClient; + + beforeEach(() => { + client = new SpriteApiClient(); + // Reset global fetch mock + vi.stubGlobal('fetch', vi.fn()); + }); + + afterEach(() => { + vi.unstubAllGlobals(); + }); + + describe('Sprite CRUD', () => { + it('should list sprites and update cache', async () => { + const mockSprites = [ + { id: 's1', name: 'sprite1', status: 'running' }, + { id: 's2', name: 'sprite2', status: 'hibernating' } + ]; + + vi.mocked(fetch).mockResolvedValueOnce({ + ok: true, + json: async () => mockSprites + } as Response); + + const sprites = await client.listSprites(); + + expect(fetch).toHaveBeenCalledWith('https://api.test.dev/v1/sprites', expect.objectContaining({ + headers: expect.objectContaining({ + 'Authorization': 'Bearer test-token' + }) + })); + expect(sprites).toEqual(mockSprites); + + // Verify cache by getting a sprite (it should be in cache, though getSprite calls API) + // Actually statusCache is private, but let's check if getSprite works + vi.mocked(fetch).mockResolvedValueOnce({ + ok: true, + json: async () => mockSprites[0] + } as Response); + + const sprite = await client.getSprite('s1'); + expect(sprite).toEqual(mockSprites[0]); + }); + + it('should create a sprite and emit event', async () => { + const mockSprite = { id: 's3', name: 'new-sprite', status: 'provisioning' }; + const config = { name: 'new-sprite' }; + + vi.mocked(fetch).mockResolvedValueOnce({ + ok: true, + json: async () => mockSprite + } as Response); + + const spy = vi.fn(); + client.on('spriteCreated', spy); + + const sprite = await client.createSprite(config); + + expect(sprite).toEqual(mockSprite); + expect(fetch).toHaveBeenCalledWith('https://api.test.dev/v1/sprites', expect.objectContaining({ + method: 'POST', + body: JSON.stringify({ + name: 'new-sprite', + repoUrl: 'https://github.com/test/repo', + branch: 'main' + }) + })); + expect(spy).toHaveBeenCalledWith(mockSprite); + }); + + it('should delete a sprite and emit event', async () => { + vi.mocked(fetch).mockResolvedValueOnce({ + ok: true, + status: 204 + } as Response); + + const spy = vi.fn(); + client.on('spriteDeleted', spy); + + await client.deleteSprite('s1'); + + expect(fetch).toHaveBeenCalledWith('https://api.test.dev/v1/sprites/s1', expect.objectContaining({ + method: 'DELETE' + })); + expect(spy).toHaveBeenCalledWith('s1'); + }); + }); + + describe('Command Execution', () => { + it('should execute command', async () => { + const mockResult = { stdout: 'hello', stderr: '', exitCode: 0, durationMs: 100 }; + + vi.mocked(fetch).mockResolvedValueOnce({ + ok: true, + json: async () => mockResult + } as Response); + + const result = await client.execCommand('s1', 'echo hello'); + + expect(result).toEqual(mockResult); + expect(fetch).toHaveBeenCalledWith('https://api.test.dev/v1/sprites/s1/exec', expect.objectContaining({ + method: 'POST', + body: JSON.stringify({ command: 'echo hello', timeout: 60000 }) + })); + }); + }); + + describe('Lifecycle Management', () => { + it('should shutdown sprite', async () => { + vi.mocked(fetch).mockResolvedValueOnce({ + ok: true, + status: 204 + } as Response); + + const spy = vi.fn(); + client.on('spriteStatusChanged', spy); + + await client.shutdownSprite('s1'); + + expect(fetch).toHaveBeenCalledWith('https://api.test.dev/v1/sprites/s1/shutdown', expect.objectContaining({ + method: 'POST' + })); + }); + + it('should wake up sprite', async () => { + vi.mocked(fetch).mockResolvedValueOnce({ + ok: true, + status: 204 + } as Response); + + await client.wakeSprite('s1'); + + expect(fetch).toHaveBeenCalledWith('https://api.test.dev/v1/sprites/s1/wake', expect.objectContaining({ + method: 'POST' + })); + }); + }); + + describe('Utilities', () => { + it('should generate correct console URL', () => { + const url = client.getConsoleUrl('test-sprite'); + expect(url).toBe('https://test.dev/dashboard/sprites/test-sprite'); + }); + }); +}); diff --git a/apps/server/tsconfig.json b/apps/server/tsconfig.json index 16dc4280a..618f942ec 100644 --- a/apps/server/tsconfig.json +++ b/apps/server/tsconfig.json @@ -3,7 +3,9 @@ "target": "ES2022", "module": "NodeNext", "moduleResolution": "NodeNext", - "lib": ["ES2022"], + "lib": [ + "ES2022" + ], "outDir": "./dist", "rootDir": "./src", "strict": true, @@ -22,4 +24,4 @@ "node_modules", "dist" ] -} +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 8fc7b149c..d6c0a0ff3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,6 @@ "tree-kill": "1.2.2" }, "devDependencies": { - "dmg-license": "^1.0.11", "husky": "9.1.7", "lint-staged": "16.2.7", "prettier": "3.7.4", @@ -26,6 +25,9 @@ }, "engines": { "node": ">=22.0.0 <23.0.0" + }, + "optionalDependencies": { + "dmg-license": "^1.0.11" } }, "apps/server": { @@ -43,6 +45,7 @@ "@automaker/utils": "1.0.0", "@modelcontextprotocol/sdk": "1.25.2", "@openai/codex-sdk": "^0.77.0", + "axios": "^1.13.2", "cookie-parser": "1.4.7", "cors": "2.8.5", "dotenv": "17.2.3", @@ -1497,7 +1500,7 @@ }, "node_modules/@electron/node-gyp": { "version": "10.2.0-electron.1", - "resolved": "git+https://github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2", + "resolved": "git+ssh://git@github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2", "integrity": "sha512-4MSBTT8y07YUDqf69/vSh80Hh791epYqGtWHO3zSKhYFwQg+gx9wi1PqbqP6YqC4WMsNxZ5l9oDmnWdK5pfCKQ==", "dev": true, "license": "MIT", @@ -6114,7 +6117,7 @@ "version": "25.0.3", "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.3.tgz", "integrity": "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "undici-types": "~7.16.0" @@ -6124,15 +6127,15 @@ "version": "7.16.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@types/plist": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@types/plist/-/plist-3.0.5.tgz", "integrity": "sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==", - "dev": true, "license": "MIT", + "optional": true, "dependencies": { "@types/node": "*", "xmlbuilder": ">=11.0.1" @@ -6156,7 +6159,6 @@ "version": "19.2.7", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz", "integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==", - "dev": true, "license": "MIT", "dependencies": { "csstype": "^3.2.2" @@ -6166,7 +6168,7 @@ "version": "19.2.3", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", - "dev": true, + "devOptional": true, "license": "MIT", "peerDependencies": { "@types/react": "^19.2.0" @@ -6213,8 +6215,8 @@ "version": "1.10.11", "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.11.tgz", "integrity": "sha512-RlDm9K7+o5stv0Co8i8ZRGxDbrTxhJtgjqjFyVh/tXQyl/rYtTKlnTvZ88oSTeYREWurwx20Js4kTuKCsFkUtg==", - "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true }, "node_modules/@types/ws": { "version": "8.18.1", @@ -6719,7 +6721,7 @@ "version": "0.8.11", "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.11.tgz", "integrity": "sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=10.0.0" @@ -6921,7 +6923,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", @@ -7003,7 +7005,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -7013,7 +7015,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -7237,8 +7239,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true, "license": "MIT", + "optional": true, "engines": { "node": ">=0.8" } @@ -7289,8 +7291,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, "license": "MIT", + "optional": true, "engines": { "node": ">=8" } @@ -7316,7 +7318,6 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true, "license": "MIT" }, "node_modules/at-least-node": { @@ -7329,6 +7330,17 @@ "node": ">= 4.0.0" } }, + "node_modules/axios": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", + "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/babel-dead-code-elimination": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/babel-dead-code-elimination/-/babel-dead-code-elimination-1.0.11.tgz", @@ -7363,7 +7375,7 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, + "devOptional": true, "funding": [ { "type": "github", @@ -7537,7 +7549,7 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, + "devOptional": true, "funding": [ { "type": "github", @@ -8033,8 +8045,8 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", - "dev": true, "license": "MIT", + "optional": true, "dependencies": { "slice-ansi": "^3.0.0", "string-width": "^4.2.0" @@ -8128,7 +8140,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -8141,7 +8153,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/colorette": { @@ -8155,7 +8167,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" @@ -8309,8 +8320,8 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true }, "node_modules/cors": { "version": "2.8.5", @@ -8329,8 +8340,8 @@ "version": "3.8.0", "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, "license": "MIT", + "optional": true, "dependencies": { "buffer": "^5.1.0" } @@ -8377,7 +8388,6 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "dev": true, "license": "MIT" }, "node_modules/d3-color": { @@ -8626,7 +8636,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.4.0" @@ -8792,8 +8801,8 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/dmg-license/-/dmg-license-1.0.11.tgz", "integrity": "sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q==", - "dev": true, "license": "MIT", + "optional": true, "os": [ "darwin" ], @@ -9057,7 +9066,7 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/encodeurl": { @@ -9187,7 +9196,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -9682,11 +9690,11 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz", "integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==", - "dev": true, "engines": [ "node >=0.6.0" ], - "license": "MIT" + "license": "MIT", + "optional": true }, "node_modules/fast-deep-equal": { "version": "3.1.3", @@ -9698,7 +9706,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/fast-levenshtein": { @@ -9849,6 +9857,26 @@ "dev": true, "license": "ISC" }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/foreground-child": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", @@ -9883,7 +9911,6 @@ "version": "4.0.5", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", - "dev": true, "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -9900,7 +9927,6 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -9910,7 +9936,6 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, "license": "MIT", "dependencies": { "mime-db": "1.52.0" @@ -10316,7 +10341,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" @@ -10648,8 +10672,8 @@ "version": "1.1.7", "resolved": "https://registry.npmjs.org/iconv-corefoundation/-/iconv-corefoundation-1.1.7.tgz", "integrity": "sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==", - "dev": true, "license": "MIT", + "optional": true, "os": [ "darwin" ], @@ -10678,7 +10702,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, + "devOptional": true, "funding": [ { "type": "github", @@ -10866,7 +10890,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -11132,7 +11156,7 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/json-schema-typed": { @@ -11253,6 +11277,7 @@ "os": [ "android" ], + "peer": true, "engines": { "node": ">= 12.0.0" }, @@ -11318,6 +11343,7 @@ "os": [ "freebsd" ], + "peer": true, "engines": { "node": ">= 12.0.0" }, @@ -13077,8 +13103,8 @@ "version": "1.7.2", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", - "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true }, "node_modules/node-api-version": { "version": "0.2.1", @@ -13677,7 +13703,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@xmldom/xmldom": "^0.8.8", @@ -13778,6 +13804,12 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, "node_modules/pump": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", @@ -13793,7 +13825,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=6" @@ -14593,8 +14625,8 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", - "dev": true, "license": "MIT", + "optional": true, "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -14608,7 +14640,7 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">= 6.0.0", @@ -14805,7 +14837,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -14850,7 +14882,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -15609,7 +15641,7 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, + "devOptional": true, "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" @@ -15709,8 +15741,8 @@ "version": "1.10.1", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz", "integrity": "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==", - "dev": true, "license": "MIT", + "optional": true, "dependencies": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", @@ -16153,7 +16185,7 @@ "version": "15.1.1", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=8.0" From 08e7e019bb8e73840aa0fceddcbdc60afa52cff6 Mon Sep 17 00:00:00 2001 From: Justus Date: Wed, 21 Jan 2026 12:17:10 +0100 Subject: [PATCH 06/13] refactor: update SpriteApiClient to use axios and update tests --- apps/server/src/services/sprite-api-client.ts | 68 +++++------ .../unit/services/sprite-api-client.test.ts | 113 +++++++++++------- 2 files changed, 101 insertions(+), 80 deletions(-) diff --git a/apps/server/src/services/sprite-api-client.ts b/apps/server/src/services/sprite-api-client.ts index d1cc9b232..5c93e938d 100644 --- a/apps/server/src/services/sprite-api-client.ts +++ b/apps/server/src/services/sprite-api-client.ts @@ -1,4 +1,5 @@ import { EventEmitter } from 'events'; +import axios, { AxiosInstance, AxiosResponse } from 'axios'; import { createLogger } from '@automaker/utils'; import { spritesConfig } from '../config/sprites.js'; @@ -37,50 +38,46 @@ export interface SpriteConfig { * SpriteApiClient - Client for interacting with the Sprites.dev REST API * * Handles sprite lifecycle, command execution, and state management. - * Uses native Node 22 fetch for communication. + * Uses axios for communication. */ export class SpriteApiClient extends EventEmitter { - private apiBase: string; - private token: string; + private axiosInstance: AxiosInstance; private statusCache: Map = new Map(); constructor() { super(); - this.apiBase = spritesConfig.SPRITES_API_BASE || 'https://api.sprites.dev/v1'; - this.token = spritesConfig.SPRITES_TOKEN || ''; + const apiBase = spritesConfig.SPRITES_API_BASE || 'https://api.sprites.dev/v1'; + const token = spritesConfig.SPRITES_TOKEN || ''; - if (!this.token) { + if (!token) { logger.warn('SPRITES_TOKEN is not configured. API calls will fail.'); } + + this.axiosInstance = axios.create({ + baseURL: apiBase, + headers: { + 'Authorization': `Bearer ${token}`, + 'Content-Type': 'application/json', + }, + }); } /** - * Helper to perform authenticated fetch requests + * Helper to perform authenticated requests using axios */ - private async request(path: string, options: RequestInit = {}): Promise { - const url = `${this.apiBase}${path.startsWith('/') ? path : `/${path}`}`; - const headers = { - 'Authorization': `Bearer ${this.token}`, - 'Content-Type': 'application/json', - ...options.headers, - }; - + private async request(url: string, options: any = {}): Promise { try { - const response = await fetch(url, { ...options, headers }); - - if (!response.ok) { - const errorText = await response.text(); - throw new Error(`Sprites API Error (${response.status}): ${errorText || response.statusText}`); - } - - if (response.status === 204) { - return {} as T; - } - - return (await response.json()) as T; - } catch (error) { - logger.error(`Request to ${url} failed:`, error); - throw error; + const response: AxiosResponse = await this.axiosInstance({ + url, + ...options, + }); + + return response.data; + } catch (error: any) { + const status = error.response?.status; + const errorText = error.response?.data ? JSON.stringify(error.response.data) : error.message; + logger.error(`Request to ${url} failed (${status}):`, errorText); + throw new Error(`Sprites API Error (${status || 'Unknown'}): ${errorText}`); } } @@ -113,7 +110,7 @@ export class SpriteApiClient extends EventEmitter { logger.info(`Creating sprite: ${config.name}`); const sprite = await this.request('/sprites', { method: 'POST', - body: JSON.stringify({ + data: JSON.stringify({ ...config, repoUrl: config.repoUrl || spritesConfig.DEFAULT_REPO_URL, branch: config.branch || spritesConfig.DEFAULT_BRANCH, @@ -147,7 +144,7 @@ export class SpriteApiClient extends EventEmitter { const result = await this.request(`/sprites/${spriteId}/exec`, { method: 'POST', - body: JSON.stringify({ command, timeout }), + data: JSON.stringify({ command, timeout }), }); return result; @@ -164,7 +161,7 @@ export class SpriteApiClient extends EventEmitter { logger.info(`Creating checkpoint '${name}' for sprite ${spriteId}`); return this.request(`/sprites/${spriteId}/checkpoints`, { method: 'POST', - body: JSON.stringify({ name }), + data: JSON.stringify({ name }), }); } @@ -175,7 +172,7 @@ export class SpriteApiClient extends EventEmitter { logger.info(`Restoring sprite ${spriteId} to checkpoint ${checkpointId}`); await this.request(`/sprites/${spriteId}/restore`, { method: 'POST', - body: JSON.stringify({ checkpointId }), + data: JSON.stringify({ checkpointId }), }); this.emit('spriteRestored', { spriteId, checkpointId }); } @@ -220,7 +217,8 @@ export class SpriteApiClient extends EventEmitter { * Get the console URL for a sprite in the Sprites dashboard */ getConsoleUrl(spriteName: string): string { - const baseUrl = this.apiBase.replace('/v1', '').replace('api.', ''); + const apiBase = this.axiosInstance.defaults.baseURL || ''; + const baseUrl = apiBase.replace('/v1', '').replace('api.', ''); return `${baseUrl}/dashboard/sprites/${spriteName}`; } diff --git a/apps/server/tests/unit/services/sprite-api-client.test.ts b/apps/server/tests/unit/services/sprite-api-client.test.ts index 14b5a031c..e9ceef502 100644 --- a/apps/server/tests/unit/services/sprite-api-client.test.ts +++ b/apps/server/tests/unit/services/sprite-api-client.test.ts @@ -1,4 +1,5 @@ -import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; +import { describe, it, expect, vi, beforeEach } from 'vitest'; +import axios from 'axios'; import { SpriteApiClient } from '../../../src/services/sprite-api-client.js'; // Mock the config @@ -11,17 +12,29 @@ vi.mock('../../../src/config/sprites.js', () => ({ } })); +// Mock axios +vi.mock('axios', () => { + return { + default: { + create: vi.fn(), + } + }; +}); + describe('SpriteApiClient', () => { let client: SpriteApiClient; + let mockAxiosInstance: any; beforeEach(() => { - client = new SpriteApiClient(); - // Reset global fetch mock - vi.stubGlobal('fetch', vi.fn()); - }); + vi.clearAllMocks(); + + mockAxiosInstance = vi.fn(); + mockAxiosInstance.defaults = { baseURL: 'https://api.test.dev/v1' }; + + // Setup the create mock to return our instance mock + vi.mocked(axios.create).mockReturnValue(mockAxiosInstance); - afterEach(() => { - vi.unstubAllGlobals(); + client = new SpriteApiClient(); }); describe('Sprite CRUD', () => { @@ -31,26 +44,31 @@ describe('SpriteApiClient', () => { { id: 's2', name: 'sprite2', status: 'hibernating' } ]; - vi.mocked(fetch).mockResolvedValueOnce({ - ok: true, - json: async () => mockSprites - } as Response); + mockAxiosInstance.mockResolvedValueOnce({ + data: mockSprites, + status: 200 + }); const sprites = await client.listSprites(); - expect(fetch).toHaveBeenCalledWith('https://api.test.dev/v1/sprites', expect.objectContaining({ + expect(axios.create).toHaveBeenCalledWith(expect.objectContaining({ + baseURL: 'https://api.test.dev/v1', headers: expect.objectContaining({ 'Authorization': 'Bearer test-token' }) })); + + expect(mockAxiosInstance).toHaveBeenCalledWith(expect.objectContaining({ + url: '/sprites' + })); + expect(sprites).toEqual(mockSprites); - // Verify cache by getting a sprite (it should be in cache, though getSprite calls API) - // Actually statusCache is private, but let's check if getSprite works - vi.mocked(fetch).mockResolvedValueOnce({ - ok: true, - json: async () => mockSprites[0] - } as Response); + // Verify second call for getSprite + mockAxiosInstance.mockResolvedValueOnce({ + data: mockSprites[0], + status: 200 + }); const sprite = await client.getSprite('s1'); expect(sprite).toEqual(mockSprites[0]); @@ -60,10 +78,10 @@ describe('SpriteApiClient', () => { const mockSprite = { id: 's3', name: 'new-sprite', status: 'provisioning' }; const config = { name: 'new-sprite' }; - vi.mocked(fetch).mockResolvedValueOnce({ - ok: true, - json: async () => mockSprite - } as Response); + mockAxiosInstance.mockResolvedValueOnce({ + data: mockSprite, + status: 201 + }); const spy = vi.fn(); client.on('spriteCreated', spy); @@ -71,9 +89,10 @@ describe('SpriteApiClient', () => { const sprite = await client.createSprite(config); expect(sprite).toEqual(mockSprite); - expect(fetch).toHaveBeenCalledWith('https://api.test.dev/v1/sprites', expect.objectContaining({ + expect(mockAxiosInstance).toHaveBeenCalledWith(expect.objectContaining({ method: 'POST', - body: JSON.stringify({ + url: '/sprites', + data: JSON.stringify({ name: 'new-sprite', repoUrl: 'https://github.com/test/repo', branch: 'main' @@ -83,18 +102,19 @@ describe('SpriteApiClient', () => { }); it('should delete a sprite and emit event', async () => { - vi.mocked(fetch).mockResolvedValueOnce({ - ok: true, + mockAxiosInstance.mockResolvedValueOnce({ + data: {}, status: 204 - } as Response); + }); const spy = vi.fn(); client.on('spriteDeleted', spy); await client.deleteSprite('s1'); - expect(fetch).toHaveBeenCalledWith('https://api.test.dev/v1/sprites/s1', expect.objectContaining({ - method: 'DELETE' + expect(mockAxiosInstance).toHaveBeenCalledWith(expect.objectContaining({ + method: 'DELETE', + url: '/sprites/s1' })); expect(spy).toHaveBeenCalledWith('s1'); }); @@ -104,48 +124,51 @@ describe('SpriteApiClient', () => { it('should execute command', async () => { const mockResult = { stdout: 'hello', stderr: '', exitCode: 0, durationMs: 100 }; - vi.mocked(fetch).mockResolvedValueOnce({ - ok: true, - json: async () => mockResult - } as Response); + mockAxiosInstance.mockResolvedValueOnce({ + data: mockResult, + status: 200 + }); const result = await client.execCommand('s1', 'echo hello'); expect(result).toEqual(mockResult); - expect(fetch).toHaveBeenCalledWith('https://api.test.dev/v1/sprites/s1/exec', expect.objectContaining({ + expect(mockAxiosInstance).toHaveBeenCalledWith(expect.objectContaining({ method: 'POST', - body: JSON.stringify({ command: 'echo hello', timeout: 60000 }) + url: '/sprites/s1/exec', + data: JSON.stringify({ command: 'echo hello', timeout: 60000 }) })); }); }); describe('Lifecycle Management', () => { it('should shutdown sprite', async () => { - vi.mocked(fetch).mockResolvedValueOnce({ - ok: true, + mockAxiosInstance.mockResolvedValueOnce({ + data: {}, status: 204 - } as Response); + }); const spy = vi.fn(); client.on('spriteStatusChanged', spy); await client.shutdownSprite('s1'); - expect(fetch).toHaveBeenCalledWith('https://api.test.dev/v1/sprites/s1/shutdown', expect.objectContaining({ - method: 'POST' + expect(mockAxiosInstance).toHaveBeenCalledWith(expect.objectContaining({ + method: 'POST', + url: '/sprites/s1/shutdown' })); }); it('should wake up sprite', async () => { - vi.mocked(fetch).mockResolvedValueOnce({ - ok: true, + mockAxiosInstance.mockResolvedValueOnce({ + data: {}, status: 204 - } as Response); + }); await client.wakeSprite('s1'); - expect(fetch).toHaveBeenCalledWith('https://api.test.dev/v1/sprites/s1/wake', expect.objectContaining({ - method: 'POST' + expect(mockAxiosInstance).toHaveBeenCalledWith(expect.objectContaining({ + method: 'POST', + url: '/sprites/s1/wake' })); }); }); From 9132b06250affa007360835e0da4f5806c4791e2 Mon Sep 17 00:00:00 2001 From: Justus Date: Wed, 21 Jan 2026 14:15:50 +0100 Subject: [PATCH 07/13] chore: configure Tooling (Qodo, Greptile, Sprites) and CI --- .github/workflows/pr_agent.yml | 24 + .pr_agent.toml | 5 + package-lock.json | 4337 ++++++++++++++++++++++++++++++-- package.json | 4 +- 4 files changed, 4197 insertions(+), 173 deletions(-) create mode 100644 .github/workflows/pr_agent.yml create mode 100644 .pr_agent.toml diff --git a/.github/workflows/pr_agent.yml b/.github/workflows/pr_agent.yml new file mode 100644 index 000000000..da5377bc7 --- /dev/null +++ b/.github/workflows/pr_agent.yml @@ -0,0 +1,24 @@ +name: Qodo PR Agent + +on: + pull_request: + types: [opened, reopened, ready_for_review] + issue_comment: + types: [created, edited] + +permissions: + pull-requests: write + issues: write + contents: read + +jobs: + pr_agent: + runs-on: ubuntu-latest + name: Run PR Agent + if: ${{ github.event.sender.type != 'Bot' }} + steps: + - id: pr-agent + uses: Codium-ai/pr-agent@main + env: + OPENAI_KEY: ${{ secrets.OPENAI_KEY }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.pr_agent.toml b/.pr_agent.toml new file mode 100644 index 000000000..1505f8dde --- /dev/null +++ b/.pr_agent.toml @@ -0,0 +1,5 @@ +# Qodo configuration for Automaker +# IDENTIFIER: automaker-qodo-config + +[pr_test] +testing_framework = "vitest" diff --git a/package-lock.json b/package-lock.json index d6c0a0ff3..988a46716 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,8 @@ "tree-kill": "1.2.2" }, "devDependencies": { + "@qodo/command": "^0.36.0", + "greptile": "^1.0.6", "husky": "9.1.7", "lint-staged": "16.2.7", "prettier": "3.7.4", @@ -611,6 +613,49 @@ "undici-types": "~6.21.0" } }, + "node_modules/@alcalzone/ansi-tokenize": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@alcalzone/ansi-tokenize/-/ansi-tokenize-0.2.3.tgz", + "integrity": "sha512-jsElTJ0sQ4wHRz+C45tfect76BwbTbgkgKByOzpCN9xG61N5V6u/glvg1CsNJhq2xJIFpKHSwG3D2wPPuEYOrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@alcalzone/ansi-tokenize/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@alcalzone/ansi-tokenize/node_modules/is-fullwidth-code-point": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@anthropic-ai/claude-agent-sdk": { "version": "0.1.76", "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.1.76.tgz", @@ -1183,6 +1228,13 @@ "node": ">=18" } }, + "node_modules/@cfworker/json-schema": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@cfworker/json-schema/-/json-schema-4.1.1.tgz", + "integrity": "sha512-gAmrUZSGtKc3AiBL71iNWxDsyUC5uMaKKGdvzYsBoTW/xi42JQHl7eKV2OYzCUqvc+D2RCcf7EXY2iCyFIk6og==", + "devOptional": true, + "license": "MIT" + }, "node_modules/@codemirror/autocomplete": { "version": "6.20.0", "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.20.0.tgz", @@ -1299,6 +1351,17 @@ "w3c-keyname": "^2.2.4" } }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/@develar/schema-utils": { "version": "2.6.5", "resolved": "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz", @@ -1500,7 +1563,7 @@ }, "node_modules/@electron/node-gyp": { "version": "10.2.0-electron.1", - "resolved": "git+ssh://git@github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2", + "resolved": "git+https://github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2", "integrity": "sha512-4MSBTT8y07YUDqf69/vSh80Hh791epYqGtWHO3zSKhYFwQg+gx9wi1PqbqP6YqC4WMsNxZ5l9oDmnWdK5pfCKQ==", "dev": true, "license": "MIT", @@ -2985,6 +3048,51 @@ "dev": true, "license": "MIT" }, + "node_modules/@git-diff-view/cli": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@git-diff-view/cli/-/cli-0.0.2.tgz", + "integrity": "sha512-cO4G+AOIpTYVSuVnhVLnZFci04yQmB54VBrvrfiFFsWHieK6lF1BXH2A1BNcmObhfZLCocQtoTDYkufJLyvnRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@git-diff-view/core": "^0.0.31", + "@types/hast": "^3.0.0", + "fast-diff": "^1.3.0", + "highlight.js": "^11.11.0", + "lowlight": "^3.3.0", + "reactivity-store": "^0.3.11", + "use-sync-external-store": "^1.4.0" + }, + "peerDependencies": { + "ink": "^6.1.0", + "react": "^19.1.0" + } + }, + "node_modules/@git-diff-view/core": { + "version": "0.0.31", + "resolved": "https://registry.npmjs.org/@git-diff-view/core/-/core-0.0.31.tgz", + "integrity": "sha512-x0hYxdW4cbyoLPNH0uTPizsDxhvIGoPLrupWew0688/xdh58CzoHJ+Ljr7P4f4jBPZ5Zhm0FfVzKmgd2N8bxZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@git-diff-view/lowlight": "^0.0.31", + "fast-diff": "^1.3.0", + "highlight.js": "^11.11.0", + "lowlight": "^3.3.0" + } + }, + "node_modules/@git-diff-view/lowlight": { + "version": "0.0.31", + "resolved": "https://registry.npmjs.org/@git-diff-view/lowlight/-/lowlight-0.0.31.tgz", + "integrity": "sha512-IO5HikpT0ttQpdl1s2t5JcmCKXd7Q28bVha+QoMO1ZsAGn1v67ohGgZ5GHZ4vPoJRy1aSTlmspz4JG50F2srKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "highlight.js": "^11.11.0", + "lowlight": "^3.3.0" + } + }, "node_modules/@hono/node-server": { "version": "1.19.7", "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.7.tgz", @@ -3523,6 +3631,91 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@langchain/core": { + "version": "0.3.80", + "resolved": "https://registry.npmjs.org/@langchain/core/-/core-0.3.80.tgz", + "integrity": "sha512-vcJDV2vk1AlCwSh3aBm/urQ1ZrlXFFBocv11bz/NBUfLWD5/UDNMzwPdaAd2dKvNmTWa9FM2lirLU3+JCf4cRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cfworker/json-schema": "^4.0.2", + "ansi-styles": "^5.0.0", + "camelcase": "6", + "decamelize": "1.2.0", + "js-tiktoken": "^1.0.12", + "langsmith": "^0.3.67", + "mustache": "^4.2.0", + "p-queue": "^6.6.2", + "p-retry": "4", + "uuid": "^10.0.0", + "zod": "^3.25.32", + "zod-to-json-schema": "^3.22.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@langchain/core/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@langchain/core/node_modules/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@langchain/openai": { + "version": "0.6.17", + "resolved": "https://registry.npmjs.org/@langchain/openai/-/openai-0.6.17.tgz", + "integrity": "sha512-JVSzD+FL5v/2UQxKd+ikB1h4PQOtn0VlK8nqW2kPp0fshItCv4utrjBKXC/rubBnSXoRTyonBINe8QRZ6OojVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tiktoken": "^1.0.12", + "openai": "5.12.2", + "zod": "^3.25.32" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@langchain/core": ">=0.3.68 <0.4.0" + } + }, + "node_modules/@langchain/textsplitters": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@langchain/textsplitters/-/textsplitters-0.1.0.tgz", + "integrity": "sha512-djI4uw9rlkAb5iMhtLED+xJebDdAG935AdP4eRTB02R7OB/act55Bj9wsskhZsvuyQRpO4O1wQOp85s6T6GWmw==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tiktoken": "^1.0.12" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@langchain/core": ">=0.2.21 <0.4.0" + } + }, "node_modules/@lezer/common": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.5.0.tgz", @@ -3703,6 +3896,44 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/@npmcli/agent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-3.0.0.tgz", @@ -3772,6 +4003,173 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/@octokit/auth-token": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", + "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/core": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.2.tgz", + "integrity": "sha512-/g2d4sW9nUDJOMz3mabVQvOGhVa4e/BN/Um7yca9Bb2XTzPPnfTWHWQg+IsEYO7M3Vx+EXvaM/I2pJWIMun1bg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/auth-token": "^4.0.0", + "@octokit/graphql": "^7.1.0", + "@octokit/request": "^8.4.1", + "@octokit/request-error": "^5.1.1", + "@octokit/types": "^13.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/endpoint": { + "version": "9.0.6", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.6.tgz", + "integrity": "sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/graphql": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.1.1.tgz", + "integrity": "sha512-3mkDltSfcDUoa176nlGoA32RGjeWjl3K7F/BwHwRMJUW/IteSa4bnSV8p2ThNkcIcZU2umkZWxwETSSCJf2Q7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/request": "^8.4.1", + "@octokit/types": "^13.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "24.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz", + "integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "11.4.4-cjs.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.4.4-cjs.2.tgz", + "integrity": "sha512-2dK6z8fhs8lla5PaOTgqfCGBxgAv/le+EhPs27KklPhm1bKObpu6lXzwfUEQ16ajXzqNrKMujsFyo9K2eaoISw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.7.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" + } + }, + "node_modules/@octokit/plugin-request-log": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.1.tgz", + "integrity": "sha512-GihNqNpGHorUrO7Qa9JbAl0dbLnqJVrV8OXe2Zm5/Y4wFkZQDfTreBzVmiRfJVfE4mClXdihHnbpyyO9FSX4HA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "13.3.2-cjs.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-13.3.2-cjs.1.tgz", + "integrity": "sha512-VUjIjOOvF2oELQmiFpWA1aOPdawpyaCUqcEBc/UOUnj3Xp6DJGrJ1+bjUIIDzdHjnFNO6q57ODMfdEZnoBkCwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.8.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "^5" + } + }, + "node_modules/@octokit/request": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.1.tgz", + "integrity": "sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/endpoint": "^9.0.6", + "@octokit/request-error": "^5.1.1", + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/request-error": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.1.tgz", + "integrity": "sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.1.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/rest": { + "version": "20.1.2", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.1.2.tgz", + "integrity": "sha512-GmYiltypkHHtihFwPRxlaorG5R9VAHuk/vbszVoRTGXnAsY60wYLkh/E2XiFmdZmqrisw+9FaazS1i5SbdWYgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/core": "^5.0.2", + "@octokit/plugin-paginate-rest": "11.4.4-cjs.2", + "@octokit/plugin-request-log": "^4.0.0", + "@octokit/plugin-rest-endpoint-methods": "13.3.2-cjs.1" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/types": { + "version": "13.10.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz", + "integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^24.2.0" + } + }, "node_modules/@openai/codex-sdk": { "version": "0.77.0", "resolved": "https://registry.npmjs.org/@openai/codex-sdk/-/codex-sdk-0.77.0.tgz", @@ -3815,26 +4213,166 @@ "dev": true, "license": "MIT" }, - "node_modules/@radix-ui/number": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", - "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==", - "license": "MIT" - }, - "node_modules/@radix-ui/primitive": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", - "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==", - "license": "MIT" - }, - "node_modules/@radix-ui/react-arrow": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", - "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==", - "license": "MIT", + "node_modules/@qodo/command": { + "version": "0.36.0", + "resolved": "https://registry.npmjs.org/@qodo/command/-/command-0.36.0.tgz", + "integrity": "sha512-JjnIhH7YCHXjl1RzMvHOZ4SXo4vZi7psrc4h/a4/Gid8KNZlEab3omWQQiNpcyyKQzxMG72+4+t15dAxkrku0Q==", + "dev": true, + "hasInstallScript": true, + "license": "SEE LICENSE IN LICENSE", "dependencies": { - "@radix-ui/react-primitive": "2.1.3" - }, + "@git-diff-view/cli": "^0.0.2", + "@langchain/core": "0.3.80", + "@langchain/openai": "^0.6.7", + "@modelcontextprotocol/sdk": "^1.17.2", + "@slack/bolt": "^4.4.0", + "@slack/socket-mode": "^2.0.4", + "@slack/web-api": "^7.9.3", + "@types/swagger-ui-express": "^4.1.8", + "axios": "^1.12.2", + "cli-highlight": "^2.1.11", + "dedent": "^1.6.0", + "diff": "^8.0.2", + "dotenv": "^17.2.1", + "eventsource": "^4.0.0", + "express": "^5.1.0", + "fast-glob": "^3.3.3", + "fdir": "^6.4.6", + "ignore": "^7.0.5", + "ink": "^6.1.1", + "ink-ascii": "^0.0.4", + "ink-select-input": "^6.2.0", + "ink-spinner": "^5.0.0", + "ink-text-input": "^6.0.0", + "jmespath": "^0.16.0", + "langchain": "^0.3.30", + "marked": "^15.0.12", + "marked-terminal": "^7.3.0", + "meow": "^13.2.0", + "open": "^10.2.0", + "react": "^19.1.1", + "react-devtools-core": "^6.1.5", + "shiki": "^3.9.2", + "swagger-ui-express": "^5.0.1", + "tar": "^7.4.3", + "tasuku": "^2.0.1", + "toml": "^3.0.0", + "uuid": "^11.1.0", + "ws": "^8.18.3", + "yaml": "^2.8.1", + "zod": "^3.25.76", + "zod-to-json-schema": "^3.24.6" + }, + "bin": { + "qodo": "bin/qodo.js" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@qodo/command/node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@qodo/command/node_modules/eventsource": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-4.1.0.tgz", + "integrity": "sha512-2GuF51iuHX6A9xdTccMTsNb7VO0lHZihApxhvQzJB5A03DvHDd2FQepodbMaztPBmBcE/ox7o2gqaxGhYB9LhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eventsource-parser": "^3.0.1" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@qodo/command/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/@qodo/command/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@qodo/command/node_modules/tar": { + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.6.tgz", + "integrity": "sha512-xqUeu2JAIJpXyvskvU3uvQW8PAmHrtXp2KDuMJwQqW8Sqq0CaZBAQ+dKS3RBXVhU4wC5NjAdKrmh84241gO9cA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@qodo/command/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@radix-ui/number": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", + "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==", + "license": "MIT" + }, + "node_modules/@radix-ui/primitive": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", + "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==", + "license": "MIT" + }, + "node_modules/@radix-ui/react-arrow": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", + "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", @@ -5244,6 +5782,88 @@ "win32" ] }, + "node_modules/@scarf/scarf": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scarf/scarf/-/scarf-1.4.0.tgz", + "integrity": "sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0" + }, + "node_modules/@shikijs/core": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-3.21.0.tgz", + "integrity": "sha512-AXSQu/2n1UIQekY8euBJlvFYZIw0PHY63jUzGbrOma4wPxzznJXTXkri+QcHeBNaFxiiOljKxxJkVSoB3PjbyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.21.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4", + "hast-util-to-html": "^9.0.5" + } + }, + "node_modules/@shikijs/engine-javascript": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-3.21.0.tgz", + "integrity": "sha512-ATwv86xlbmfD9n9gKRiwuPpWgPENAWCLwYCGz9ugTJlsO2kOzhOkvoyV/UD+tJ0uT7YRyD530x6ugNSffmvIiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.21.0", + "@shikijs/vscode-textmate": "^10.0.2", + "oniguruma-to-es": "^4.3.4" + } + }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.21.0.tgz", + "integrity": "sha512-OYknTCct6qiwpQDqDdf3iedRdzj6hFlOPv5hMvI+hkWfCKs5mlJ4TXziBG9nyabLwGulrUjHiCq3xCspSzErYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.21.0", + "@shikijs/vscode-textmate": "^10.0.2" + } + }, + "node_modules/@shikijs/langs": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.21.0.tgz", + "integrity": "sha512-g6mn5m+Y6GBJ4wxmBYqalK9Sp0CFkUqfNzUy2pJglUginz6ZpWbaWjDB4fbQ/8SHzFjYbtU6Ddlp1pc+PPNDVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.21.0" + } + }, + "node_modules/@shikijs/themes": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.21.0.tgz", + "integrity": "sha512-BAE4cr9EDiZyYzwIHEk7JTBJ9CzlPuM4PchfcA5ao1dWXb25nv6hYsoDiBq2aZK9E3dlt3WB78uI96UESD+8Mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.21.0" + } + }, + "node_modules/@shikijs/types": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.21.0.tgz", + "integrity": "sha512-zGrWOxZ0/+0ovPY7PvBU2gIS9tmhSUUt30jAcNV0Bq0gb2S98gwfjIs1vxlmH5zM7/4YxLamT6ChlqqAJmPPjA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", + "dev": true, + "license": "MIT" + }, "node_modules/@sindresorhus/is": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", @@ -5257,6 +5877,129 @@ "url": "https://github.com/sindresorhus/is?sponsor=1" } }, + "node_modules/@slack/bolt": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@slack/bolt/-/bolt-4.6.0.tgz", + "integrity": "sha512-xPgfUs2+OXSugz54Ky07pA890+Qydk22SYToi8uGpXeHSt1JWwFJkRyd/9Vlg5I1AdfdpGXExDpwnbuN9Q/2dQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@slack/logger": "^4.0.0", + "@slack/oauth": "^3.0.4", + "@slack/socket-mode": "^2.0.5", + "@slack/types": "^2.18.0", + "@slack/web-api": "^7.12.0", + "axios": "^1.12.0", + "express": "^5.0.0", + "path-to-regexp": "^8.1.0", + "raw-body": "^3", + "tsscmp": "^1.0.6" + }, + "engines": { + "node": ">=18", + "npm": ">=8.6.0" + }, + "peerDependencies": { + "@types/express": "^5.0.0" + } + }, + "node_modules/@slack/logger": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@slack/logger/-/logger-4.0.0.tgz", + "integrity": "sha512-Wz7QYfPAlG/DR+DfABddUZeNgoeY7d1J39OCR2jR+v7VBsB8ezulDK5szTnDDPDwLH5IWhLvXIHlCFZV7MSKgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": ">=18.0.0" + }, + "engines": { + "node": ">= 18", + "npm": ">= 8.6.0" + } + }, + "node_modules/@slack/oauth": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@slack/oauth/-/oauth-3.0.4.tgz", + "integrity": "sha512-+8H0g7mbrHndEUbYCP7uYyBCbwqmm3E6Mo3nfsDvZZW74zKk1ochfH/fWSvGInYNCVvaBUbg3RZBbTp0j8yJCg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@slack/logger": "^4", + "@slack/web-api": "^7.10.0", + "@types/jsonwebtoken": "^9", + "@types/node": ">=18", + "jsonwebtoken": "^9" + }, + "engines": { + "node": ">=18", + "npm": ">=8.6.0" + } + }, + "node_modules/@slack/socket-mode": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@slack/socket-mode/-/socket-mode-2.0.5.tgz", + "integrity": "sha512-VaapvmrAifeFLAFaDPfGhEwwunTKsI6bQhYzxRXw7BSujZUae5sANO76WqlVsLXuhVtCVrBWPiS2snAQR2RHJQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@slack/logger": "^4", + "@slack/web-api": "^7.10.0", + "@types/node": ">=18", + "@types/ws": "^8", + "eventemitter3": "^5", + "ws": "^8" + }, + "engines": { + "node": ">= 18", + "npm": ">= 8.6.0" + } + }, + "node_modules/@slack/types": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/@slack/types/-/types-2.19.0.tgz", + "integrity": "sha512-7+QZ38HGcNh/b/7MpvPG6jnw7mliV6UmrquJLqgdxkzJgQEYUcEztvFWRU49z0x4vthF0ixL5lTK601AXrS8IA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12.13.0", + "npm": ">= 6.12.0" + } + }, + "node_modules/@slack/web-api": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@slack/web-api/-/web-api-7.13.0.tgz", + "integrity": "sha512-ERcExbWrnkDN8ovoWWe6Wgt/usanj1dWUd18dJLpctUI4mlPS0nKt81Joh8VI+OPbNnY1lIilVt9gdMBD9U2ig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@slack/logger": "^4.0.0", + "@slack/types": "^2.18.0", + "@types/node": ">=18.0.0", + "@types/retry": "0.12.0", + "axios": "^1.11.0", + "eventemitter3": "^5.0.1", + "form-data": "^4.0.4", + "is-electron": "2.2.2", + "is-stream": "^2", + "p-queue": "^6", + "p-retry": "^4", + "retry": "^0.13.1" + }, + "engines": { + "node": ">= 18", + "npm": ">= 8.6.0" + } + }, + "node_modules/@slack/web-api/node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/@standard-schema/spec": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", @@ -5677,16 +6420,6 @@ "url": "https://github.com/sponsors/tannerlinsley" } }, - "node_modules/@tanstack/router-generator/node_modules/zod": { - "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, "node_modules/@tanstack/router-plugin": { "version": "1.141.7", "resolved": "https://registry.npmjs.org/@tanstack/router-plugin/-/router-plugin-1.141.7.tgz", @@ -5741,16 +6474,6 @@ } } }, - "node_modules/@tanstack/router-plugin/node_modules/zod": { - "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, "node_modules/@tanstack/router-utils": { "version": "1.141.0", "resolved": "https://registry.npmjs.org/@tanstack/router-utils/-/router-utils-1.141.0.tgz", @@ -6078,6 +6801,17 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/jsonwebtoken": { + "version": "9.0.10", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.10.tgz", + "integrity": "sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/ms": "*", + "@types/node": "*" + } + }, "node_modules/@types/keyv": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", @@ -6184,6 +6918,13 @@ "@types/node": "*" } }, + "node_modules/@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/send": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz", @@ -6205,12 +6946,30 @@ "@types/node": "*" } }, + "node_modules/@types/swagger-ui-express": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@types/swagger-ui-express/-/swagger-ui-express-4.1.8.tgz", + "integrity": "sha512-AhZV8/EIreHFmBV5wAs0gzJUNq9JbbSXgJLQubCC0jtIo6prnI9MIRRxnU4MZX9RB9yXxF1V4R7jtLl/Wcj31g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express": "*", + "@types/serve-static": "*" + } + }, "node_modules/@types/unist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", "license": "MIT" }, + "node_modules/@types/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/verror": { "version": "1.10.11", "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.11.tgz", @@ -6239,6 +6998,13 @@ "@types/node": "*" } }, + "node_modules/@types/yoga-layout": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@types/yoga-layout/-/yoga-layout-1.9.2.tgz", + "integrity": "sha512-S9q47ByT2pPvD65IvrWp7qppVMpk9WGMbVq9wbWZOHg6tnXSD4vyhao6nOSBwwfDdV2p3Kx9evA9vI+XWTfDvw==", + "dev": true, + "license": "MIT" + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.50.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.50.0.tgz", @@ -6717,6 +7483,23 @@ "url": "https://opencollective.com/vitest" } }, + "node_modules/@vue/reactivity": { + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.27.tgz", + "integrity": "sha512-vvorxn2KXfJ0nBEnj4GYshSgsyMNFnIQah/wczXlsNXt+ijhugmW+PpJ2cNPe4V6jpnBcs0MhCODKllWG+nvoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/shared": "3.5.27" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.27", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.27.tgz", + "integrity": "sha512-dXr/3CgqXsJkZ0n9F3I4elY8wM9jMJpP3pvRG52r6m0tu/MsAFIe6JpXVGeNMd/D9F4hQynWT8Rfuj0bdm9kFQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@xmldom/xmldom": { "version": "0.8.11", "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.11.tgz", @@ -7037,6 +7820,13 @@ "node": ">=14" } }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "license": "MIT" + }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -7216,16 +8006,37 @@ "node": ">= 10.0.0" } }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "node_modules/arch": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", + "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", "dev": true, - "license": "Python-2.0" - }, - "node_modules/aria-hidden": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/aria-hidden": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==", "license": "MIT", "dependencies": { @@ -7235,6 +8046,23 @@ "node": ">=10" } }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", @@ -7291,8 +8119,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "devOptional": true, "license": "MIT", - "optional": true, "engines": { "node": ">=8" } @@ -7330,6 +8158,19 @@ "node": ">= 4.0.0" } }, + "node_modules/auto-bind": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-5.0.1.tgz", + "integrity": "sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/axios": { "version": "1.13.2", "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", @@ -7414,6 +8255,13 @@ "node": ">= 0.8" } }, + "node_modules/before-after-hook": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", @@ -7580,6 +8428,13 @@ "node": "*" } }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "dev": true, + "license": "BSD-3-Clause" + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -7665,6 +8520,22 @@ "node": ">= 10.0.0" } }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -7831,6 +8702,19 @@ "node": ">=6" } }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001760", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001760.tgz", @@ -7889,6 +8773,16 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/character-entities": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", @@ -8015,6 +8909,19 @@ "node": ">=6" } }, + "node_modules/cli-boxes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", + "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", @@ -8028,6 +8935,86 @@ "node": ">=8" } }, + "node_modules/cli-highlight": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz", + "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==", + "dev": true, + "license": "ISC", + "dependencies": { + "chalk": "^4.0.0", + "highlight.js": "^10.7.1", + "mz": "^2.4.0", + "parse5": "^5.1.1", + "parse5-htmlparser2-tree-adapter": "^6.0.0", + "yargs": "^16.0.0" + }, + "bin": { + "highlight": "bin/highlight" + }, + "engines": { + "node": ">=8.0.0", + "npm": ">=5.0.0" + } + }, + "node_modules/cli-highlight/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/cli-highlight/node_modules/highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, + "node_modules/cli-highlight/node_modules/parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "dev": true, + "license": "MIT" + }, + "node_modules/cli-highlight/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cli-highlight/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, "node_modules/cli-spinners": { "version": "2.9.2", "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", @@ -8041,12 +9028,28 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, "node_modules/cli-truncate": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "devOptional": true, "license": "MIT", - "optional": true, "dependencies": { "slice-ansi": "^3.0.0", "string-width": "^4.2.0" @@ -8058,6 +9061,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/clipboardy": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-2.3.0.tgz", + "integrity": "sha512-mKhiIL2DrQIsuXMgBgnfEHOZOryC7kY7YO//TN6c63wlEm3NG5tz+YgY5rVi29KCmq/QQjKYvM7a19+MDOTHOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "arch": "^2.1.1", + "execa": "^1.0.0", + "is-wsl": "^2.1.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -8121,6 +9139,19 @@ "react-dom": "^18 || ^19 || ^19.0.0-rc" } }, + "node_modules/code-excerpt": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-4.0.0.tgz", + "integrity": "sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==", + "dev": true, + "license": "MIT", + "dependencies": { + "convert-to-spaces": "^2.0.1" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, "node_modules/codemirror": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.2.tgz", @@ -8244,6 +9275,16 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/console-table-printer": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/console-table-printer/-/console-table-printer-2.15.0.tgz", + "integrity": "sha512-SrhBq4hYVjLCkBVOWaTzceJalvn5K1Zq5aQA6wXC/cYjI3frKWNPEMK3sZsJfNNQApvCQmgBcc13ZKmFj8qExw==", + "dev": true, + "license": "MIT", + "dependencies": { + "simple-wcswidth": "^1.1.2" + } + }, "node_modules/content-disposition": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", @@ -8273,6 +9314,16 @@ "dev": true, "license": "MIT" }, + "node_modules/convert-to-spaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-2.0.1.tgz", + "integrity": "sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, "node_modules/cookie": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", @@ -8522,6 +9573,16 @@ } } }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/decode-named-character-reference": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz", @@ -8564,6 +9625,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/dedent": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.1.tgz", + "integrity": "sha512-9JmrhGZpOlEgOLdQgSm0zxFaYoQon408V1v49aqTWuXENVlnCuY9JBZcXZiCsZQWDjTm5Qf/nIvAy77mXDAjEg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -8571,6 +9647,36 @@ "dev": true, "license": "MIT" }, + "node_modules/default-browser": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.4.0.tgz", + "integrity": "sha512-XDuvSq38Hr1MdN47EDvYtx3U0MTqpCEn+F6ft8z2vYDzMrvQhVp0ui9oQdqW3MvK3vqUETglt1tVGgjLuJ5izg==", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz", + "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/defaults": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", @@ -8613,6 +9719,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/define-properties": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", @@ -8650,6 +9769,13 @@ "node": ">= 0.8" } }, + "node_modules/deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", + "dev": true, + "license": "ISC" + }, "node_modules/dequal": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", @@ -8659,6 +9785,17 @@ "node": ">=6" } }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, "node_modules/detect-libc": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", @@ -8885,6 +10022,16 @@ "dev": true, "license": "MIT" }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -9069,6 +10216,13 @@ "devOptional": true, "license": "MIT" }, + "node_modules/emojilib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", + "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==", + "dev": true, + "license": "MIT" + }, "node_modules/encodeurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", @@ -9207,6 +10361,17 @@ "node": ">= 0.4" } }, + "node_modules/es-toolkit": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.44.0.tgz", + "integrity": "sha512-6penXeZalaV88MM3cGkFZZfOoLGWshWWfdy0tWw/RlVVyhvMaWSBTOvXNeiW3e5FwdS5ePW0LGEu17zT139ktg==", + "dev": true, + "license": "MIT", + "workspaces": [ + "docs", + "benchmarks" + ] + }, "node_modules/es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", @@ -9584,8 +10749,123 @@ "node": ">=18.0.0" } }, - "node_modules/expect-type": { - "version": "1.3.0", + "node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/execa/node_modules/cross-spawn": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", + "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/execa/node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/execa/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/execa/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/execa/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/expect-type": { + "version": "1.3.0", "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", "dev": true, @@ -9702,6 +10982,30 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "license": "MIT" }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -9732,6 +11036,16 @@ ], "license": "BSD-3-Clause" }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, "node_modules/fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", @@ -9749,6 +11063,61 @@ "dev": true, "license": "MIT" }, + "node_modules/figlet": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/figlet/-/figlet-1.9.4.tgz", + "integrity": "sha512-uN6QE+TrzTAHC1IWTyrc4FfGo2KH/82J8Jl1tyKB7+z5DBit/m3D++Iu5lg91qJMnQQ3vpJrj5gxcK/pk4R9tQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^14.0.0" + }, + "bin": { + "figlet": "bin/index.js" + }, + "engines": { + "node": ">= 17.0.0" + } + }, + "node_modules/figlet/node_modules/commander": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.2.tgz", + "integrity": "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/figures": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", + "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-unicode-supported": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/figures/node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -10301,114 +11670,496 @@ "lodash": "^4.17.15" } }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/greptile": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/greptile/-/greptile-1.0.6.tgz", + "integrity": "sha512-D6Gd3FaA8ihoQrLQ13SUusHETa2zPonKHEATRDYU0JA+Vnsm7WTzQyMhxOIE2ThZNHSjDC6qzrob+xQlFfJwCg==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" + "license": "ISC", + "dependencies": { + "@octokit/rest": "^20.0.2", + "axios": "^1.6.7", + "cli-spinners": "^2.9.2", + "clipboardy": "^2.3.0", + "express": "^4.18.2", + "js-base64": "^3.7.6", + "node-fetch": "^2.7.0", + "open": "^8.4.0", + "ora": "^5.4.1", + "punycode": "^2.3.1", + "shelljs": "^0.8.4", + "yargs": "^17.7.2" + }, + "bin": { + "greptile": "bin/index.js" } }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "node_modules/greptile/node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "es-define-property": "^1.0.0" + "mime-types": "~2.1.34", + "negotiator": "0.6.3" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">= 0.6" } }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "node_modules/greptile/node_modules/body-parser": { + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz", + "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", + "dev": true, "license": "MIT", - "engines": { - "node": ">= 0.4" + "dependencies": { + "bytes": "~3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "~1.2.0", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "on-finished": "~2.4.1", + "qs": "~6.14.0", + "raw-body": "~2.5.3", + "type-is": "~1.6.18", + "unpipe": "~1.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "node_modules/greptile/node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, "license": "MIT", "dependencies": { - "has-symbols": "^1.0.3" + "safe-buffer": "5.2.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 0.6" } }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "node_modules/greptile/node_modules/cookie-signature": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", + "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==", + "dev": true, + "license": "MIT" + }, + "node_modules/greptile/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, "license": "MIT", "dependencies": { - "function-bind": "^1.1.2" - }, + "ms": "2.0.0" + } + }, + "node_modules/greptile/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/greptile/node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true, + "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=8" } }, - "node_modules/hast-util-from-parse5": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz", - "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==", + "node_modules/greptile/node_modules/express": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", + "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", + "dev": true, "license": "MIT", "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "hastscript": "^9.0.0", - "property-information": "^7.0.0", - "vfile": "^6.0.0", - "vfile-location": "^5.0.0", - "web-namespaces": "^2.0.0" + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "~1.20.3", + "content-disposition": "~0.5.4", + "content-type": "~1.0.4", + "cookie": "~0.7.1", + "cookie-signature": "~1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.3.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "~2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "~0.1.12", + "proxy-addr": "~2.0.7", + "qs": "~6.14.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "~0.19.0", + "serve-static": "~1.16.2", + "setprototypeof": "1.2.0", + "statuses": "~2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://opencollective.com/express" } }, - "node_modules/hast-util-parse-selector": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", - "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "node_modules/greptile/node_modules/finalhandler": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz", + "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==", + "dev": true, "license": "MIT", "dependencies": { - "@types/hast": "^3.0.0" + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "~2.4.1", + "parseurl": "~1.3.3", + "statuses": "~2.0.2", + "unpipe": "~1.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": ">= 0.8" } }, - "node_modules/hast-util-raw": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.1.0.tgz", - "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", + "node_modules/greptile/node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/greptile/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, "license": "MIT", "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "@ungap/structured-clone": "^1.0.0", - "hast-util-from-parse5": "^8.0.0", - "hast-util-to-parse5": "^8.0.0", - "html-void-elements": "^3.0.0", + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/greptile/node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/greptile/node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/greptile/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/greptile/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/greptile/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/greptile/node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/greptile/node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/greptile/node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/greptile/node_modules/raw-body": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", + "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/greptile/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/greptile/node_modules/send": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz", + "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.1", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "~2.4.1", + "range-parser": "~1.2.1", + "statuses": "~2.0.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/greptile/node_modules/serve-static": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz", + "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "~0.19.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/greptile/node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz", + "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^9.0.0", + "property-information": "^7.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.1.0.tgz", + "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-from-parse5": "^8.0.0", + "hast-util-to-parse5": "^8.0.0", + "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "parse5": "^7.0.0", "unist-util-position": "^5.0.0", @@ -10437,6 +12188,30 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hast-util-to-html": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", + "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-to-jsx-runtime": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", @@ -10513,7 +12288,17 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/hosted-git-info": { + "node_modules/highlight.js": { + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz", + "integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/hosted-git-info": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", @@ -10763,40 +12548,783 @@ "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">=8" + } + }, + "node_modules/infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true, + "license": "ISC" + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ink": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/ink/-/ink-6.6.0.tgz", + "integrity": "sha512-QDt6FgJxgmSxAelcOvOHUvFxbIUjVpCH5bx+Slvc5m7IEcpGt3dYwbz/L+oRnqEGeRvwy1tineKK4ect3nW1vQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alcalzone/ansi-tokenize": "^0.2.1", + "ansi-escapes": "^7.2.0", + "ansi-styles": "^6.2.1", + "auto-bind": "^5.0.1", + "chalk": "^5.6.0", + "cli-boxes": "^3.0.0", + "cli-cursor": "^4.0.0", + "cli-truncate": "^5.1.1", + "code-excerpt": "^4.0.0", + "es-toolkit": "^1.39.10", + "indent-string": "^5.0.0", + "is-in-ci": "^2.0.0", + "patch-console": "^2.0.0", + "react-reconciler": "^0.33.0", + "signal-exit": "^3.0.7", + "slice-ansi": "^7.1.0", + "stack-utils": "^2.0.6", + "string-width": "^8.1.0", + "type-fest": "^4.27.0", + "widest-line": "^5.0.0", + "wrap-ansi": "^9.0.0", + "ws": "^8.18.0", + "yoga-layout": "~3.2.1" + }, + "engines": { + "node": ">=20" + }, + "peerDependencies": { + "@types/react": ">=19.0.0", + "react": ">=19.0.0", + "react-devtools-core": "^6.1.2" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react-devtools-core": { + "optional": true + } + } + }, + "node_modules/ink-ascii": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/ink-ascii/-/ink-ascii-0.0.4.tgz", + "integrity": "sha512-x6mZTHevoiAHgxrhxMpSc2p0lomq34uyGjwEFkpku7Rhxg30/MBnAi9gCHR17SMmaqRDzQRp1MS9s8Qvd4RHsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "figlet": "^1.2.4", + "ink": "^2.6.0", + "react": "^16.12.0" + }, + "peerDependencies": { + "ink": ">=2.5.0", + "react": ">=16.11.0" + } + }, + "node_modules/ink-ascii/node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ink-ascii/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ink-ascii/node_modules/auto-bind": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-4.0.0.tgz", + "integrity": "sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ink-ascii/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ink-ascii/node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/ink-ascii/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/ink-ascii/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/ink-ascii/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ink-ascii/node_modules/ink": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/ink/-/ink-2.7.1.tgz", + "integrity": "sha512-s7lJuQDJEdjqtaIWhp3KYHl6WV3J04U9zoQ6wVc+Xoa06XM27SXUY57qC5DO46xkF0CfgXMKkKNcgvSu/SAEpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^4.2.1", + "arrify": "^2.0.1", + "auto-bind": "^4.0.0", + "chalk": "^3.0.0", + "cli-cursor": "^3.1.0", + "cli-truncate": "^2.1.0", + "is-ci": "^2.0.0", + "lodash.throttle": "^4.1.1", + "log-update": "^3.0.0", + "prop-types": "^15.6.2", + "react-reconciler": "^0.24.0", + "scheduler": "^0.18.0", + "signal-exit": "^3.0.2", + "slice-ansi": "^3.0.0", + "string-length": "^3.1.0", + "widest-line": "^3.1.0", + "wrap-ansi": "^6.2.0", + "yoga-layout-prebuilt": "^1.9.3" + }, + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "@types/react": ">=16.8.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/ink-ascii/node_modules/is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/ink-ascii/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ink-ascii/node_modules/log-update": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-3.4.0.tgz", + "integrity": "sha512-ILKe88NeMt4gmDvk/eb615U/IVn7K9KWGkoYbdatQ69Z65nj1ZzjM6fHXfcs0Uge+e+EGnMW7DY4T9yko8vWFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^3.2.0", + "cli-cursor": "^2.1.0", + "wrap-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ink-ascii/node_modules/log-update/node_modules/ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ink-ascii/node_modules/log-update/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ink-ascii/node_modules/log-update/node_modules/cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ink-ascii/node_modules/log-update/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ink-ascii/node_modules/log-update/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ink-ascii/node_modules/log-update/node_modules/wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ink-ascii/node_modules/mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ink-ascii/node_modules/onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ink-ascii/node_modules/react": { + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", + "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ink-ascii/node_modules/react-reconciler": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.24.0.tgz", + "integrity": "sha512-gAGnwWkf+NOTig9oOowqid9O0HjTDC+XVGBCAmJYYJ2A2cN/O4gDdIuuUQjv8A4v6GDwVfJkagpBBLW5OW9HSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.18.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "react": "^16.0.0" + } + }, + "node_modules/ink-ascii/node_modules/restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ink-ascii/node_modules/scheduler": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.18.0.tgz", + "integrity": "sha512-agTSHR1Nbfi6ulI0kYNK0203joW2Y5W4po4l+v03tOoiJKpTBbxpNhWDvqc/4IcOw+KLmSiQLTasZ4cab2/UWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "node_modules/ink-ascii/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ink-ascii/node_modules/widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ink-ascii/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ink-select-input": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/ink-select-input/-/ink-select-input-6.2.0.tgz", + "integrity": "sha512-304fZXxkpYxJ9si5lxRCaX01GNlmPBgOZumXXRnPYbHW/iI31cgQynqk2tRypGLOF1cMIwPUzL2LSm6q4I5rQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "figures": "^6.1.0", + "to-rotated": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "ink": ">=5.0.0", + "react": ">=18.0.0" + } + }, + "node_modules/ink-spinner": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ink-spinner/-/ink-spinner-5.0.0.tgz", + "integrity": "sha512-EYEasbEjkqLGyPOUc8hBJZNuC5GvXGMLu0w5gdTNskPc7Izc5vO3tdQEYnzvshucyGCBXc86ig0ujXPMWaQCdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cli-spinners": "^2.7.0" + }, + "engines": { + "node": ">=14.16" + }, + "peerDependencies": { + "ink": ">=4.0.0", + "react": ">=18.0.0" + } + }, + "node_modules/ink-text-input": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/ink-text-input/-/ink-text-input-6.0.0.tgz", + "integrity": "sha512-Fw64n7Yha5deb1rHY137zHTAbSTNelUKuB5Kkk2HACXEtwIHBCf9OH2tP/LQ9fRYTl1F0dZgbW0zPnZk6FA9Lw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "type-fest": "^4.18.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "ink": ">=5", + "react": ">=18" + } + }, + "node_modules/ink-text-input/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ink-text-input/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ink/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ink/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ink/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ink/node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ink/node_modules/cli-truncate": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.1.1.tgz", + "integrity": "sha512-SroPvNHxUnk+vIW/dOSfNqdy1sPEFkrTk6TUtqLCnBlo3N7TNYYkzzN7uSD6+jVjrdO4+p8nH7JzH6cIvUem6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "slice-ansi": "^7.1.0", + "string-width": "^8.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ink/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/ink/node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ink/node_modules/is-fullwidth-code-point": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ink/node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ink/node_modules/slice-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", + "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/ink/node_modules/string-width": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.0.tgz", + "integrity": "sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ink/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/ink/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ink/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true, - "license": "ISC" - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "node_modules/ink/node_modules/wrap-ansi/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "once": "^1.3.0", - "wrappy": "1" + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, "node_modules/inline-style-parser": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.7.tgz", "integrity": "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==", "license": "MIT" }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/ip-address": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", @@ -10866,6 +13394,22 @@ "is-ci": "bin.js" } }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-decimal": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", @@ -10876,6 +13420,29 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-electron": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-electron/-/is-electron-2.2.2.tgz", + "integrity": "sha512-FO/Rhvz5tuw4MCWkpMzHFKWD2LsfHzIb7i6MdPYZ/KW7AlxawyLkqdy+jPZP1WubqEADE3O4FUENlJHDfQASRg==", + "dev": true, + "license": "MIT" + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -10919,6 +13486,57 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/is-in-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-in-ci/-/is-in-ci-2.0.0.tgz", + "integrity": "sha512-cFeerHriAnhrQSbpAxL37W1wcJKUUX07HyLWZCW1URJT/ra3GyUTzBgUnh24TMVfNTV2Hij2HLxkPHFZfOZy5w==", + "dev": true, + "license": "MIT", + "bin": { + "is-in-ci": "cli.js" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-inside-container/node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-interactive": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", @@ -10964,6 +13582,19 @@ "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", "license": "MIT" }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", @@ -10977,6 +13608,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/isbinaryfile": { "version": "5.0.7", "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.7.tgz", @@ -11103,6 +13747,16 @@ "jiti": "lib/jiti-cli.mjs" } }, + "node_modules/jmespath": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", + "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/jose": { "version": "6.1.3", "resolved": "https://registry.npmjs.org/jose/-/jose-6.1.3.tgz", @@ -11112,6 +13766,23 @@ "url": "https://github.com/sponsors/panva" } }, + "node_modules/js-base64": { + "version": "3.7.8", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.8.tgz", + "integrity": "sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/js-tiktoken": { + "version": "1.0.21", + "resolved": "https://registry.npmjs.org/js-tiktoken/-/js-tiktoken-1.0.21.tgz", + "integrity": "sha512-biOj/6M5qdgx5TKjDnFT1ymSpM5tbd3ylwDtrQvFQSu0Z7bBYko2dF+W/aUkXUPuk6IVpRxk/3Q2sHOzGlS36g==", + "dev": true, + "license": "MIT", + "dependencies": { + "base64-js": "^1.5.1" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -11180,37 +13851,252 @@ "license": "ISC", "optional": true }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jsonwebtoken": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz", + "integrity": "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==", + "dev": true, + "license": "MIT", + "dependencies": { + "jws": "^4.0.1", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jwa": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", + "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jwa": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/langchain": { + "version": "0.3.37", + "resolved": "https://registry.npmjs.org/langchain/-/langchain-0.3.37.tgz", + "integrity": "sha512-1jPsZ6xsxkcQPUvqRjvfuOLwZLLyt49hzcOK7OYAJovIkkOxd5gzK4Yw6giPUQ8g4XHyvULNlWBz+subdkcokw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@langchain/openai": ">=0.1.0 <0.7.0", + "@langchain/textsplitters": ">=0.0.0 <0.2.0", + "js-tiktoken": "^1.0.12", + "js-yaml": "^4.1.0", + "jsonpointer": "^5.0.1", + "langsmith": "^0.3.67", + "openapi-types": "^12.1.3", + "p-retry": "4", + "uuid": "^10.0.0", + "yaml": "^2.2.1", + "zod": "^3.25.32" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@langchain/anthropic": "*", + "@langchain/aws": "*", + "@langchain/cerebras": "*", + "@langchain/cohere": "*", + "@langchain/core": ">=0.3.58 <0.4.0", + "@langchain/deepseek": "*", + "@langchain/google-genai": "*", + "@langchain/google-vertexai": "*", + "@langchain/google-vertexai-web": "*", + "@langchain/groq": "*", + "@langchain/mistralai": "*", + "@langchain/ollama": "*", + "@langchain/xai": "*", + "axios": "*", + "cheerio": "*", + "handlebars": "^4.7.8", + "peggy": "^3.0.2", + "typeorm": "*" + }, + "peerDependenciesMeta": { + "@langchain/anthropic": { + "optional": true + }, + "@langchain/aws": { + "optional": true + }, + "@langchain/cerebras": { + "optional": true + }, + "@langchain/cohere": { + "optional": true + }, + "@langchain/deepseek": { + "optional": true + }, + "@langchain/google-genai": { + "optional": true + }, + "@langchain/google-vertexai": { + "optional": true + }, + "@langchain/google-vertexai-web": { + "optional": true + }, + "@langchain/groq": { + "optional": true + }, + "@langchain/mistralai": { + "optional": true + }, + "@langchain/ollama": { + "optional": true + }, + "@langchain/xai": { + "optional": true + }, + "axios": { + "optional": true + }, + "cheerio": { + "optional": true + }, + "handlebars": { + "optional": true + }, + "peggy": { + "optional": true + }, + "typeorm": { + "optional": true + } + } + }, + "node_modules/langchain/node_modules/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], "license": "MIT", "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" + "uuid": "dist/bin/uuid" } }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "node_modules/langsmith": { + "version": "0.3.87", + "resolved": "https://registry.npmjs.org/langsmith/-/langsmith-0.3.87.tgz", + "integrity": "sha512-XXR1+9INH8YX96FKWc5tie0QixWz6tOqAsAKfcJyPkE0xPep+NDz0IQLR32q4bn10QK3LqD2HN6T3n6z1YLW7Q==", "dev": true, "license": "MIT", - "optionalDependencies": { - "graceful-fs": "^4.1.6" + "dependencies": { + "@types/uuid": "^10.0.0", + "chalk": "^4.1.2", + "console-table-printer": "^2.12.1", + "p-queue": "^6.6.2", + "semver": "^7.6.3", + "uuid": "^10.0.0" + }, + "peerDependencies": { + "@opentelemetry/api": "*", + "@opentelemetry/exporter-trace-otlp-proto": "*", + "@opentelemetry/sdk-trace-base": "*", + "openai": "*" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@opentelemetry/exporter-trace-otlp-proto": { + "optional": true + }, + "@opentelemetry/sdk-trace-base": { + "optional": true + }, + "openai": { + "optional": true + } } }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "node_modules/langsmith/node_modules/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" + "bin": { + "uuid": "dist/bin/uuid" } }, "node_modules/lazy-val": { @@ -11739,6 +14625,48 @@ "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", "license": "MIT" }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -11746,6 +14674,20 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==", + "dev": true, + "license": "MIT" + }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -11973,6 +14915,19 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, "node_modules/lowercase-keys": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", @@ -11983,6 +14938,22 @@ "node": ">=8" } }, + "node_modules/lowlight": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-3.3.0.tgz", + "integrity": "sha512-0JNhgFoPvP6U6lE/UdVsSq99tn6DhjjpAj5MxG49ewd2mOBVtwWYIT8ClyABhq198aXXODMU6Ox8DrGy/CpTZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "devlop": "^1.0.0", + "highlight.js": "~11.11.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -12063,6 +15034,67 @@ "node": "^18.17.0 || >=20.5.0" } }, + "node_modules/marked": { + "version": "15.0.12", + "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.12.tgz", + "integrity": "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==", + "dev": true, + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/marked-terminal": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-7.3.0.tgz", + "integrity": "sha512-t4rBvPsHc57uE/2nJOLmMbZCQ4tgAccAED3ngXQqW6g+TxA488JzJ+FK3lQkzBQOI1mRV/r/Kq+1ZlJ4D0owQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^7.0.0", + "ansi-regex": "^6.1.0", + "chalk": "^5.4.1", + "cli-highlight": "^2.1.11", + "cli-table3": "^0.6.5", + "node-emoji": "^2.2.0", + "supports-hyperlinks": "^3.1.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "marked": ">=1 <16" + } + }, + "node_modules/marked-terminal/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/marked-terminal/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/matcher": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", @@ -12248,6 +15280,19 @@ "node": ">= 0.8" } }, + "node_modules/meow": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", + "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/merge-descriptors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", @@ -12260,6 +15305,26 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/micromark": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", @@ -13038,6 +16103,28 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, + "node_modules/mustache": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", + "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", + "dev": true, + "license": "MIT", + "bin": { + "mustache": "bin/mustache" + } + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, "node_modules/nano-spawn": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/nano-spawn/-/nano-spawn-2.0.0.tgz", @@ -13086,6 +16173,13 @@ "node": ">= 0.6" } }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true, + "license": "MIT" + }, "node_modules/node-abi": { "version": "4.24.0", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-4.24.0.tgz", @@ -13116,6 +16210,43 @@ "semver": "^7.3.5" } }, + "node_modules/node-emoji": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.2.0.tgz", + "integrity": "sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^4.6.0", + "char-regex": "^1.0.2", + "emojilib": "^2.4.0", + "skin-tone": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/node-gyp": { "version": "11.5.0", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-11.5.0.tgz", @@ -13266,6 +16397,29 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -13355,6 +16509,73 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/oniguruma-parser": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/oniguruma-parser/-/oniguruma-parser-0.12.1.tgz", + "integrity": "sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/oniguruma-to-es": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-4.3.4.tgz", + "integrity": "sha512-3VhUGN3w2eYxnTzHn+ikMI+fp/96KoRSVK9/kMTcFqj1NRDh2IhQCKvYxDnWePKRXY/AqH+Fuiyb7VHSzBjHfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "oniguruma-parser": "^0.12.1", + "regex": "^6.0.1", + "regex-recursion": "^6.0.2" + } + }, + "node_modules/open": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", + "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "wsl-utils": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/openai": { + "version": "5.12.2", + "resolved": "https://registry.npmjs.org/openai/-/openai-5.12.2.tgz", + "integrity": "sha512-xqzHHQch5Tws5PcKR2xsZGX9xtch+JQFz5zb14dGqlshmmDAFBFEWmeIpf7wVqWV+w7Emj7jRgkNJakyKE0tYQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "openai": "bin/cli" + }, + "peerDependencies": { + "ws": "^8.18.0", + "zod": "^3.23.8" + }, + "peerDependenciesMeta": { + "ws": { + "optional": true + }, + "zod": { + "optional": true + } + } + }, + "node_modules/openapi-types": { + "version": "12.1.3", + "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-12.1.3.tgz", + "integrity": "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==", + "dev": true, + "license": "MIT" + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -13404,7 +16625,17 @@ "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">=8" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" } }, "node_modules/p-limit": { @@ -13452,6 +16683,67 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-queue": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", + "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.4", + "p-timeout": "^3.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue/node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true, + "license": "MIT" + }, + "node_modules/p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-retry/node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", @@ -13509,6 +16801,23 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse5": "^6.0.1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true, + "license": "MIT" + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -13518,6 +16827,16 @@ "node": ">= 0.8" } }, + "node_modules/patch-console": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/patch-console/-/patch-console-2.0.0.tgz", + "integrity": "sha512-0YNdUceMdaQwoKce1gatDScmMo5pu/tfABfnzEqeG0gtTmd7mh/WcwgUjtAeOU7N8nFFlbQBnFK2gXW5fGvmMA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -13547,6 +16866,13 @@ "node": ">=8" } }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, "node_modules/path-scurry": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", @@ -13781,6 +17107,18 @@ "node": ">=10" } }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, "node_modules/property-information": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", @@ -13846,6 +17184,27 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/quick-lru": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", @@ -13908,6 +17267,39 @@ "node": ">=0.10.0" } }, + "node_modules/react-devtools-core": { + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-6.1.5.tgz", + "integrity": "sha512-ePrwPfxAnB+7hgnEr8vpKxL9cmnp7F322t8oqcPshbIQQhDKgFDW4tjhF2wjVbdXF9O/nyuy3sQWd9JGpiLPvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shell-quote": "^1.6.1", + "ws": "^7" + } + }, + "node_modules/react-devtools-core/node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/react-dom": { "version": "19.2.3", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz", @@ -13920,6 +17312,13 @@ "react": "^19.2.3" } }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true, + "license": "MIT" + }, "node_modules/react-markdown": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-10.1.0.tgz", @@ -13947,6 +17346,22 @@ "react": ">=18" } }, + "node_modules/react-reconciler": { + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.33.0.tgz", + "integrity": "sha512-KetWRytFv1epdpJc3J4G75I4WrplZE5jOL7Yq0p34+OVOKF4Se7WrdIdVC45XsSSmUTlht2FM/fM1FZb1mfQeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "react": "^19.2.0" + } + }, "node_modules/react-refresh": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", @@ -14026,6 +17441,21 @@ } } }, + "node_modules/reactivity-store": { + "version": "0.3.12", + "resolved": "https://registry.npmjs.org/reactivity-store/-/reactivity-store-0.3.12.tgz", + "integrity": "sha512-Idz9EL4dFUtQbHySZQzckWOTUfqjdYpUtNW0iOysC32mG7IjiUGB77QrsyR5eAWBkRiS9JscF6A3fuQAIy+LrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/reactivity": "~3.5.22", + "@vue/shared": "~3.5.22", + "use-sync-external-store": "^1.6.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/read-binary-file-arch": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/read-binary-file-arch/-/read-binary-file-arch-1.0.6.tgz", @@ -14094,6 +17524,45 @@ "node": ">=0.10.0" } }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "dev": true, + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/regex/-/regex-6.1.0.tgz", + "integrity": "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-recursion": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-6.0.2.tgz", + "integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-utilities": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz", + "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==", + "dev": true, + "license": "MIT" + }, "node_modules/rehype-raw": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", @@ -14193,6 +17662,27 @@ "url": "https://github.com/sponsors/jet2jet" } }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/resolve-alpn": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", @@ -14257,6 +17747,17 @@ "node": ">= 4" } }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, "node_modules/rfdc": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", @@ -14341,6 +17842,43 @@ "node": ">= 18" } }, + "node_modules/run-applescript": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", + "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -14507,6 +18045,54 @@ "node": ">=8" } }, + "node_modules/shell-quote": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/shiki": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-3.21.0.tgz", + "integrity": "sha512-N65B/3bqL/TI2crrXr+4UivctrAGEjmsib5rPMMPpFp1xAx/w03v8WZ9RDDFYteXoEgY7qZ4HGgl5KBIu1153w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/core": "3.21.0", + "@shikijs/engine-javascript": "3.21.0", + "@shikijs/engine-oniguruma": "3.21.0", + "@shikijs/langs": "3.21.0", + "@shikijs/themes": "3.21.0", + "@shikijs/types": "3.21.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, "node_modules/side-channel": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", @@ -14606,6 +18192,13 @@ "node": ">=10" } }, + "node_modules/simple-wcswidth": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/simple-wcswidth/-/simple-wcswidth-1.1.2.tgz", + "integrity": "sha512-j7piyCjAeTDSjzTSQ7DokZtMNwNlEAyxqSZeCS+CXH7fJ4jx3FuJ/mTW3mE+6JLs4VJBbcll0Kjn+KXI5t21Iw==", + "dev": true, + "license": "MIT" + }, "node_modules/sirv": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz", @@ -14621,12 +18214,25 @@ "node": ">=18" } }, + "node_modules/skin-tone": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", + "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "unicode-emoji-modifier-base": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/slice-ansi": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "devOptional": true, "license": "MIT", - "optional": true, "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -14756,7 +18362,30 @@ "minipass": "^7.0.3" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" } }, "node_modules/stackback": { @@ -14833,6 +18462,53 @@ "node": ">=0.6.19" } }, + "node_modules/string-length": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-3.1.0.tgz", + "integrity": "sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "astral-regex": "^1.0.0", + "strip-ansi": "^5.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-length/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/string-length/node_modules/astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/string-length/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -14905,6 +18581,16 @@ "node": ">=8" } }, + "node_modules/strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -14968,6 +18654,62 @@ "node": ">=8" } }, + "node_modules/supports-hyperlinks": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.2.0.tgz", + "integrity": "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=14.18" + }, + "funding": { + "url": "https://github.com/chalk/supports-hyperlinks?sponsor=1" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/swagger-ui-dist": { + "version": "5.31.0", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.31.0.tgz", + "integrity": "sha512-zSUTIck02fSga6rc0RZP3b7J7wgHXwLea8ZjgLA3Vgnb8QeOl3Wou2/j5QkzSGeoz6HusP/coYuJl33aQxQZpg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@scarf/scarf": "=1.4.0" + } + }, + "node_modules/swagger-ui-express": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-5.0.1.tgz", + "integrity": "sha512-SrNU3RiBGTLLmFU8GIJdOdanJTl4TOmT27tt3bWWHppqYmAZ6IDuEuBvMU6nZq0zLEe6b/1rACXCgLZqO6ZfrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "swagger-ui-dist": ">=5.0.0" + }, + "engines": { + "node": ">= v0.10.32" + }, + "peerDependencies": { + "express": ">=4.0.0 || >=5.0.0-beta" + } + }, "node_modules/tailwind-merge": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.4.0.tgz", @@ -15087,6 +18829,16 @@ "dev": true, "license": "ISC" }, + "node_modules/tasuku": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/tasuku/-/tasuku-2.0.5.tgz", + "integrity": "sha512-rb3fI9WGTKfzLgHhDiCJJoc/6uWlyuSuBiIPdHANPT3Ou0071BlIUiVnajnGfn4dOmLKkrmdHberWXd2EUcRjA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/tasuku?sponsor=1" + } + }, "node_modules/temp-file": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.4.0.tgz", @@ -15136,6 +18888,29 @@ "node": ">= 10.0.0" } }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/tiny-async-pool": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/tiny-async-pool/-/tiny-async-pool-1.3.0.tgz", @@ -15276,6 +19051,19 @@ "node": ">=8.0" } }, + "node_modules/to-rotated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-rotated/-/to-rotated-1.0.0.tgz", + "integrity": "sha512-KsEID8AfgUy+pxVRLsWp0VzCa69wxzUDZnzGbyIST/bcgcrMvTYoFBX/QORH4YApoD89EDuUovx4BTdpOn319Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -15285,6 +19073,13 @@ "node": ">=0.6" } }, + "node_modules/toml": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", + "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==", + "dev": true, + "license": "MIT" + }, "node_modules/totalist": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", @@ -15295,6 +19090,13 @@ "node": ">=6" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true, + "license": "MIT" + }, "node_modules/tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", @@ -15353,6 +19155,16 @@ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, + "node_modules/tsscmp": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz", + "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6.x" + } + }, "node_modules/tsx": { "version": "4.21.0", "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", @@ -15445,6 +19257,16 @@ "dev": true, "license": "MIT" }, + "node_modules/unicode-emoji-modifier-base": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", + "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/unified": { "version": "11.0.5", "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", @@ -15558,6 +19380,13 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/universal-user-agent": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", + "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==", + "dev": true, + "license": "ISC" + }, "node_modules/universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -15728,6 +19557,30 @@ "dev": true, "license": "MIT" }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -16068,6 +19921,13 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true, + "license": "BSD-2-Clause" + }, "node_modules/webpack-virtual-modules": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", @@ -16075,6 +19935,17 @@ "dev": true, "license": "MIT" }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -16107,6 +19978,76 @@ "node": ">=8" } }, + "node_modules/widest-line": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-5.0.0.tgz", + "integrity": "sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/widest-line/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/widest-line/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/widest-line/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/widest-line/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", @@ -16181,6 +20122,38 @@ } } }, + "node_modules/wsl-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", + "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wsl-utils/node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/xmlbuilder": { "version": "15.1.1", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", @@ -16277,10 +20250,30 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/yoga-layout": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/yoga-layout/-/yoga-layout-3.2.1.tgz", + "integrity": "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/yoga-layout-prebuilt": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/yoga-layout-prebuilt/-/yoga-layout-prebuilt-1.10.0.tgz", + "integrity": "sha512-YnOmtSbv4MTf7RGJMK0FvZ+KD8OEe/J5BNnR0GHhD8J/XcG/Qvxgszm0Un6FTHWW4uHlTgP0IztiXQnGyIR45g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/yoga-layout": "1.9.2" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/zod": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.2.1.tgz", - "integrity": "sha512-0wZ1IRqGGhMP76gLqz8EyfBXKk0J2qo2+H3fi4mcUP/KtTocoX08nmIAHl1Z2kJIZbZee8KOpBCSNPRgauucjw==", + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" diff --git a/package.json b/package.json index 0756f8688..d4bad7a00 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,9 @@ "husky": "9.1.7", "lint-staged": "16.2.7", "prettier": "3.7.4", - "vitest": "4.0.16" + "vitest": "4.0.16", + "@qodo/command": "^0.36.0", + "greptile": "^1.0.6" }, "optionalDependencies": { "dmg-license": "^1.0.11" From 2489bae0624bc6f7d3ac2277e901b4cab315ab38 Mon Sep 17 00:00:00 2001 From: Justus Date: Wed, 21 Jan 2026 14:27:50 +0100 Subject: [PATCH 08/13] fix(config): improve qodo pr_reviewer settings and fix greptile json --- .pr_agent.toml | 7 +++++++ greptile.json | 21 +++++++-------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.pr_agent.toml b/.pr_agent.toml index 1505f8dde..638fcbb88 100644 --- a/.pr_agent.toml +++ b/.pr_agent.toml @@ -3,3 +3,10 @@ [pr_test] testing_framework = "vitest" + +[pr_reviewer] +require_score_review = true +enable_review_labels_security = true +enable_review_labels_effort = true +num_code_suggestions = 4 +inline_code_comments = true diff --git a/greptile.json b/greptile.json index dc7ec6a1f..68f55f061 100644 --- a/greptile.json +++ b/greptile.json @@ -1,15 +1,8 @@ { - "name": "automaker-greptile-config", - "project": "automaker", - "labels": [ - "ai-review" - ], - "commentTypes": [ - "logic", - "architecture", - "security" - ], - "instructions": "This is an Automaker-specific configuration. Focus on the monorepo structure (libs/ vs apps/), the Claude Agent SDK integration, and ensure that changes adhere to the patterns defined in CLAUDE.md and DEVELOPMENT_WORKFLOW.md.", - "strictness": 1, - "triggerOnUpdates": true -} \ No newline at end of file + "name": "automaker-greptile-config", + "project": "automaker", + "commentTypes": ["logic", "architecture", "security"], + "instructions": "This is an Automaker-specific configuration. Focus on the monorepo structure (libs/ vs apps/), the Claude Agent SDK integration, and ensure that changes adhere to the patterns defined in CLAUDE.md and DEVELOPMENT_WORKFLOW.md.", + "strictness": 1, + "triggerOnUpdates": true +} From 5618cd2a8c31d9b681cef656bb3d233e9e0206bd Mon Sep 17 00:00:00 2001 From: Justus Date: Wed, 21 Jan 2026 17:25:49 +0100 Subject: [PATCH 09/13] feat: implement sprites.dev client, configure tools, and set OpenAI key --- .agent/skills/git-worktrees/SKILL.md | 3 + .agent/workflows/git-worktree.md | 3 + apps/server/src/config/sprites.ts | 22 +- apps/server/src/services/sprite-api-client.ts | 400 +++++++++--------- .../unit/services/sprite-api-client.test.ts | 326 +++++++------- apps/server/tsconfig.json | 15 +- genesis_spec/README.md | 46 +- .../Automaker_Section_01_Introduction.md | 86 ++-- ...tomaker_Section_02_Product_Requirements.md | 184 ++++---- .../Automaker_Section_03_Technology_Stack.md | 200 ++++----- ...utomaker_Section_05_Architecture_Design.md | 113 ++--- .../Automaker_Section_06_Data_Models.md | 142 ++++--- ...utomaker_Section_07_Security_Compliance.md | 88 ++-- .../Automaker_Section_08_Testing_Strategy.md | 51 +-- ...ker_Section_09_Monitoring_Observability.md | 78 ++-- ...omaker_Section_10_Deployment_Operations.md | 99 ++--- .../Automaker_Section_11_Documentation.md | 49 ++- ...omaker_Section_12_Reference_Collections.md | 210 ++++----- 18 files changed, 1082 insertions(+), 1033 deletions(-) diff --git a/.agent/skills/git-worktrees/SKILL.md b/.agent/skills/git-worktrees/SKILL.md index b09381af4..040931fe3 100644 --- a/.agent/skills/git-worktrees/SKILL.md +++ b/.agent/skills/git-worktrees/SKILL.md @@ -1,10 +1,13 @@ # Git Worktrees Skill + # IDENTIFIER: automaker-worktree-skill ## Description + This skill enables the agent to manage isolated development environments using Git Worktrees, which is the preferred way to work in the Automaker repository. ## Instructions + - Always use `git worktree list` before creating new ones to avoid path conflicts. - Prefer naming worktrees with the prefix `../automaker-worktree-`. - Ensure you are in the root of the repository before running worktree commands. diff --git a/.agent/workflows/git-worktree.md b/.agent/workflows/git-worktree.md index 37d8e270a..015eaaab3 100644 --- a/.agent/workflows/git-worktree.md +++ b/.agent/workflows/git-worktree.md @@ -7,11 +7,13 @@ description: How to manage git worktrees in Automaker (IDENTIFIER: automaker-wor This workflow describes how to safely use git worktrees for feature development in Automaker. 1. **Check existing worktrees**: + ```bash git worktree list ``` 2. **Create a new worktree for a feature**: + ```bash git worktree add ../automaker-worktree- -b feature/ ``` @@ -20,6 +22,7 @@ This workflow describes how to safely use git worktrees for feature development - `cd ../automaker-worktree-` 4. **Remove worktree after completion**: + ```bash git worktree remove ../automaker-worktree- git branch -d feature/ diff --git a/apps/server/src/config/sprites.ts b/apps/server/src/config/sprites.ts index 57e7c2325..965822ed0 100644 --- a/apps/server/src/config/sprites.ts +++ b/apps/server/src/config/sprites.ts @@ -1,13 +1,13 @@ export const spritesConfig = { - SPRITES_TOKEN: process.env.SPRITES_TOKEN, - SPRITES_API_BASE: process.env.SPRITES_API_BASE || "https://api.sprites.dev/v1", - GITHUB_TOKEN: process.env.GITHUB_TOKEN, - LINEAR_API_KEY: process.env.LINEAR_API_KEY, - CLAUDE_OAUTH_TOKEN: process.env.CLAUDE_OAUTH_TOKEN, - DEFAULT_REPO_URL: process.env.DEFAULT_REPO_URL, - DEFAULT_BRANCH: process.env.DEFAULT_BRANCH || "main", - GIT_USER_NAME: process.env.GIT_USER_NAME || "Automaker Agent", - GIT_USER_EMAIL: process.env.GIT_USER_EMAIL || "agent@automaker.dev", - OTEL_RECEIVER_PORT: parseInt(process.env.OTEL_RECEIVER_PORT || "4317"), - OTEL_RECEIVER_HOST: process.env.OTEL_RECEIVER_HOST || "0.0.0.0", + SPRITES_TOKEN: process.env.SPRITES_TOKEN, + SPRITES_API_BASE: process.env.SPRITES_API_BASE || 'https://api.sprites.dev/v1', + GITHUB_TOKEN: process.env.GITHUB_TOKEN, + LINEAR_API_KEY: process.env.LINEAR_API_KEY, + CLAUDE_OAUTH_TOKEN: process.env.CLAUDE_OAUTH_TOKEN, + DEFAULT_REPO_URL: process.env.DEFAULT_REPO_URL, + DEFAULT_BRANCH: process.env.DEFAULT_BRANCH || 'main', + GIT_USER_NAME: process.env.GIT_USER_NAME || 'Automaker Agent', + GIT_USER_EMAIL: process.env.GIT_USER_EMAIL || 'agent@automaker.dev', + OTEL_RECEIVER_PORT: parseInt(process.env.OTEL_RECEIVER_PORT || '4317'), + OTEL_RECEIVER_HOST: process.env.OTEL_RECEIVER_HOST || '0.0.0.0', }; diff --git a/apps/server/src/services/sprite-api-client.ts b/apps/server/src/services/sprite-api-client.ts index 5c93e938d..1aca08ea4 100644 --- a/apps/server/src/services/sprite-api-client.ts +++ b/apps/server/src/services/sprite-api-client.ts @@ -6,226 +6,230 @@ import { spritesConfig } from '../config/sprites.js'; const logger = createLogger('SpriteApiClient'); export interface Sprite { - id: string; - name: string; - status: 'running' | 'hibernating' | 'provisioning' | 'error'; - lastActivityAt: string; - createdAt: string; + id: string; + name: string; + status: 'running' | 'hibernating' | 'provisioning' | 'error'; + lastActivityAt: string; + createdAt: string; } export interface Checkpoint { - id: string; - spriteId: string; - name: string; - createdAt: string; + id: string; + spriteId: string; + name: string; + createdAt: string; } export interface ExecResult { - stdout: string; - stderr: string; - exitCode: number; - durationMs: number; + stdout: string; + stderr: string; + exitCode: number; + durationMs: number; } export interface SpriteConfig { - name: string; - repoUrl?: string; - branch?: string; - env?: Record; + name: string; + repoUrl?: string; + branch?: string; + env?: Record; } /** * SpriteApiClient - Client for interacting with the Sprites.dev REST API - * + * * Handles sprite lifecycle, command execution, and state management. * Uses axios for communication. */ export class SpriteApiClient extends EventEmitter { - private axiosInstance: AxiosInstance; - private statusCache: Map = new Map(); - - constructor() { - super(); - const apiBase = spritesConfig.SPRITES_API_BASE || 'https://api.sprites.dev/v1'; - const token = spritesConfig.SPRITES_TOKEN || ''; - - if (!token) { - logger.warn('SPRITES_TOKEN is not configured. API calls will fail.'); - } - - this.axiosInstance = axios.create({ - baseURL: apiBase, - headers: { - 'Authorization': `Bearer ${token}`, - 'Content-Type': 'application/json', - }, - }); - } - - /** - * Helper to perform authenticated requests using axios - */ - private async request(url: string, options: any = {}): Promise { - try { - const response: AxiosResponse = await this.axiosInstance({ - url, - ...options, - }); - - return response.data; - } catch (error: any) { - const status = error.response?.status; - const errorText = error.response?.data ? JSON.stringify(error.response.data) : error.message; - logger.error(`Request to ${url} failed (${status}):`, errorText); - throw new Error(`Sprites API Error (${status || 'Unknown'}): ${errorText}`); - } - } + private axiosInstance: AxiosInstance; + private statusCache: Map = new Map(); - // ============================================================================ - // Sprite CRUD - // ============================================================================ - - /** - * List all sprites associated with the account - */ - async listSprites(): Promise { - const sprites = await this.request('/sprites'); - sprites.forEach(s => this.statusCache.set(s.id, s)); - return sprites; - } + constructor() { + super(); + const apiBase = spritesConfig.SPRITES_API_BASE || 'https://api.sprites.dev/v1'; + const token = spritesConfig.SPRITES_TOKEN || ''; - /** - * Get details for a specific sprite - */ - async getSprite(id: string): Promise { - const sprite = await this.request(`/sprites/${id}`); - this.statusCache.set(sprite.id, sprite); - return sprite; + if (!token) { + logger.warn('SPRITES_TOKEN is not configured. API calls will fail.'); } - /** - * Provision a new sprite - */ - async createSprite(config: SpriteConfig): Promise { - logger.info(`Creating sprite: ${config.name}`); - const sprite = await this.request('/sprites', { - method: 'POST', - data: JSON.stringify({ - ...config, - repoUrl: config.repoUrl || spritesConfig.DEFAULT_REPO_URL, - branch: config.branch || spritesConfig.DEFAULT_BRANCH, - }), - }); - - this.statusCache.set(sprite.id, sprite); - this.emit('spriteCreated', sprite); - return sprite; + this.axiosInstance = axios.create({ + baseURL: apiBase, + headers: { + Authorization: `Bearer ${token}`, + 'Content-Type': 'application/json', + }, + }); + } + + /** + * Helper to perform authenticated requests using axios + */ + private async request(url: string, options: any = {}): Promise { + try { + const response: AxiosResponse = await this.axiosInstance({ + url, + ...options, + }); + + return response.data; + } catch (error: any) { + const status = error.response?.status; + const errorText = error.response?.data ? JSON.stringify(error.response.data) : error.message; + logger.error(`Request to ${url} failed (${status}):`, errorText); + throw new Error(`Sprites API Error (${status || 'Unknown'}): ${errorText}`); } - - /** - * Delete a sprite - */ - async deleteSprite(id: string): Promise { - logger.info(`Deleting sprite: ${id}`); - await this.request(`/sprites/${id}`, { method: 'DELETE' }); - this.statusCache.delete(id); - this.emit('spriteDeleted', id); + } + + // ============================================================================ + // Sprite CRUD + // ============================================================================ + + /** + * List all sprites associated with the account + */ + async listSprites(): Promise { + const sprites = await this.request('/sprites'); + sprites.forEach((s) => this.statusCache.set(s.id, s)); + return sprites; + } + + /** + * Get details for a specific sprite + */ + async getSprite(id: string): Promise { + const sprite = await this.request(`/sprites/${id}`); + this.statusCache.set(sprite.id, sprite); + return sprite; + } + + /** + * Provision a new sprite + */ + async createSprite(config: SpriteConfig): Promise { + logger.info(`Creating sprite: ${config.name}`); + const sprite = await this.request('/sprites', { + method: 'POST', + data: JSON.stringify({ + ...config, + repoUrl: config.repoUrl || spritesConfig.DEFAULT_REPO_URL, + branch: config.branch || spritesConfig.DEFAULT_BRANCH, + }), + }); + + this.statusCache.set(sprite.id, sprite); + this.emit('spriteCreated', sprite); + return sprite; + } + + /** + * Delete a sprite + */ + async deleteSprite(id: string): Promise { + logger.info(`Deleting sprite: ${id}`); + await this.request(`/sprites/${id}`, { method: 'DELETE' }); + this.statusCache.delete(id); + this.emit('spriteDeleted', id); + } + + // ============================================================================ + // Command Execution + // ============================================================================ + + /** + * Execute a shell command on a sprite + */ + async execCommand( + spriteId: string, + command: string, + timeout: number = 60000 + ): Promise { + logger.debug(`Executing on sprite ${spriteId}: ${command}`); + + const result = await this.request(`/sprites/${spriteId}/exec`, { + method: 'POST', + data: JSON.stringify({ command, timeout }), + }); + + return result; + } + + // ============================================================================ + // Checkpointing + // ============================================================================ + + /** + * Create a checkpoint of the current sprite state + */ + async createCheckpoint(spriteId: string, name: string): Promise { + logger.info(`Creating checkpoint '${name}' for sprite ${spriteId}`); + return this.request(`/sprites/${spriteId}/checkpoints`, { + method: 'POST', + data: JSON.stringify({ name }), + }); + } + + /** + * Restore a sprite to a specified checkpoint + */ + async restoreCheckpoint(spriteId: string, checkpointId: string): Promise { + logger.info(`Restoring sprite ${spriteId} to checkpoint ${checkpointId}`); + await this.request(`/sprites/${spriteId}/restore`, { + method: 'POST', + data: JSON.stringify({ checkpointId }), + }); + this.emit('spriteRestored', { spriteId, checkpointId }); + } + + // ============================================================================ + // Lifecycle Management + // ============================================================================ + + /** + * Shut down (hibernate) a running sprite + */ + async shutdownSprite(spriteId: string): Promise { + logger.info(`Shutting down sprite ${spriteId}`); + await this.request(`/sprites/${spriteId}/shutdown`, { method: 'POST' }); + + const sprite = this.statusCache.get(spriteId); + if (sprite) { + sprite.status = 'hibernating'; + this.emit('spriteStatusChanged', sprite); } - - // ============================================================================ - // Command Execution - // ============================================================================ - - /** - * Execute a shell command on a sprite - */ - async execCommand(spriteId: string, command: string, timeout: number = 60000): Promise { - logger.debug(`Executing on sprite ${spriteId}: ${command}`); - - const result = await this.request(`/sprites/${spriteId}/exec`, { - method: 'POST', - data: JSON.stringify({ command, timeout }), - }); - - return result; - } - - // ============================================================================ - // Checkpointing - // ============================================================================ - - /** - * Create a checkpoint of the current sprite state - */ - async createCheckpoint(spriteId: string, name: string): Promise { - logger.info(`Creating checkpoint '${name}' for sprite ${spriteId}`); - return this.request(`/sprites/${spriteId}/checkpoints`, { - method: 'POST', - data: JSON.stringify({ name }), - }); - } - - /** - * Restore a sprite to a specified checkpoint - */ - async restoreCheckpoint(spriteId: string, checkpointId: string): Promise { - logger.info(`Restoring sprite ${spriteId} to checkpoint ${checkpointId}`); - await this.request(`/sprites/${spriteId}/restore`, { - method: 'POST', - data: JSON.stringify({ checkpointId }), - }); - this.emit('spriteRestored', { spriteId, checkpointId }); - } - - // ============================================================================ - // Lifecycle Management - // ============================================================================ - - /** - * Shut down (hibernate) a running sprite - */ - async shutdownSprite(spriteId: string): Promise { - logger.info(`Shutting down sprite ${spriteId}`); - await this.request(`/sprites/${spriteId}/shutdown`, { method: 'POST' }); - - const sprite = this.statusCache.get(spriteId); - if (sprite) { - sprite.status = 'hibernating'; - this.emit('spriteStatusChanged', sprite); - } - } - - /** - * Wake up a hibernating sprite - */ - async wakeSprite(spriteId: string): Promise { - logger.info(`Waking up sprite ${spriteId}`); - await this.request(`/sprites/${spriteId}/wake`, { method: 'POST' }); - - const sprite = this.statusCache.get(spriteId); - if (sprite) { - sprite.status = 'running'; - this.emit('spriteStatusChanged', sprite); - } - } - - // ============================================================================ - // Utilities - // ============================================================================ - - /** - * Get the console URL for a sprite in the Sprites dashboard - */ - getConsoleUrl(spriteName: string): string { - const apiBase = this.axiosInstance.defaults.baseURL || ''; - const baseUrl = apiBase.replace('/v1', '').replace('api.', ''); - return `${baseUrl}/dashboard/sprites/${spriteName}`; - } - - /** - * Clear local status cache - */ - clearCache(): void { - this.statusCache.clear(); + } + + /** + * Wake up a hibernating sprite + */ + async wakeSprite(spriteId: string): Promise { + logger.info(`Waking up sprite ${spriteId}`); + await this.request(`/sprites/${spriteId}/wake`, { method: 'POST' }); + + const sprite = this.statusCache.get(spriteId); + if (sprite) { + sprite.status = 'running'; + this.emit('spriteStatusChanged', sprite); } + } + + // ============================================================================ + // Utilities + // ============================================================================ + + /** + * Get the console URL for a sprite in the Sprites dashboard + */ + getConsoleUrl(spriteName: string): string { + const apiBase = this.axiosInstance.defaults.baseURL || ''; + const baseUrl = apiBase.replace('/v1', '').replace('api.', ''); + return `${baseUrl}/dashboard/sprites/${spriteName}`; + } + + /** + * Clear local status cache + */ + clearCache(): void { + this.statusCache.clear(); + } } diff --git a/apps/server/tests/unit/services/sprite-api-client.test.ts b/apps/server/tests/unit/services/sprite-api-client.test.ts index e9ceef502..f5180f205 100644 --- a/apps/server/tests/unit/services/sprite-api-client.test.ts +++ b/apps/server/tests/unit/services/sprite-api-client.test.ts @@ -4,179 +4,193 @@ import { SpriteApiClient } from '../../../src/services/sprite-api-client.js'; // Mock the config vi.mock('../../../src/config/sprites.js', () => ({ - spritesConfig: { - SPRITES_TOKEN: 'test-token', - SPRITES_API_BASE: 'https://api.test.dev/v1', - DEFAULT_REPO_URL: 'https://github.com/test/repo', - DEFAULT_BRANCH: 'main' - } + spritesConfig: { + SPRITES_TOKEN: 'test-token', + SPRITES_API_BASE: 'https://api.test.dev/v1', + DEFAULT_REPO_URL: 'https://github.com/test/repo', + DEFAULT_BRANCH: 'main', + }, })); // Mock axios vi.mock('axios', () => { - return { - default: { - create: vi.fn(), - } - }; + return { + default: { + create: vi.fn(), + }, + }; }); describe('SpriteApiClient', () => { - let client: SpriteApiClient; - let mockAxiosInstance: any; - - beforeEach(() => { - vi.clearAllMocks(); - - mockAxiosInstance = vi.fn(); - mockAxiosInstance.defaults = { baseURL: 'https://api.test.dev/v1' }; - - // Setup the create mock to return our instance mock - vi.mocked(axios.create).mockReturnValue(mockAxiosInstance); - - client = new SpriteApiClient(); + let client: SpriteApiClient; + let mockAxiosInstance: any; + + beforeEach(() => { + vi.clearAllMocks(); + + mockAxiosInstance = vi.fn(); + mockAxiosInstance.defaults = { baseURL: 'https://api.test.dev/v1' }; + + // Setup the create mock to return our instance mock + vi.mocked(axios.create).mockReturnValue(mockAxiosInstance); + + client = new SpriteApiClient(); + }); + + describe('Sprite CRUD', () => { + it('should list sprites and update cache', async () => { + const mockSprites = [ + { id: 's1', name: 'sprite1', status: 'running' }, + { id: 's2', name: 'sprite2', status: 'hibernating' }, + ]; + + mockAxiosInstance.mockResolvedValueOnce({ + data: mockSprites, + status: 200, + }); + + const sprites = await client.listSprites(); + + expect(axios.create).toHaveBeenCalledWith( + expect.objectContaining({ + baseURL: 'https://api.test.dev/v1', + headers: expect.objectContaining({ + Authorization: 'Bearer test-token', + }), + }) + ); + + expect(mockAxiosInstance).toHaveBeenCalledWith( + expect.objectContaining({ + url: '/sprites', + }) + ); + + expect(sprites).toEqual(mockSprites); + + // Verify second call for getSprite + mockAxiosInstance.mockResolvedValueOnce({ + data: mockSprites[0], + status: 200, + }); + + const sprite = await client.getSprite('s1'); + expect(sprite).toEqual(mockSprites[0]); }); - describe('Sprite CRUD', () => { - it('should list sprites and update cache', async () => { - const mockSprites = [ - { id: 's1', name: 'sprite1', status: 'running' }, - { id: 's2', name: 'sprite2', status: 'hibernating' } - ]; - - mockAxiosInstance.mockResolvedValueOnce({ - data: mockSprites, - status: 200 - }); - - const sprites = await client.listSprites(); - - expect(axios.create).toHaveBeenCalledWith(expect.objectContaining({ - baseURL: 'https://api.test.dev/v1', - headers: expect.objectContaining({ - 'Authorization': 'Bearer test-token' - }) - })); - - expect(mockAxiosInstance).toHaveBeenCalledWith(expect.objectContaining({ - url: '/sprites' - })); - - expect(sprites).toEqual(mockSprites); - - // Verify second call for getSprite - mockAxiosInstance.mockResolvedValueOnce({ - data: mockSprites[0], - status: 200 - }); - - const sprite = await client.getSprite('s1'); - expect(sprite).toEqual(mockSprites[0]); - }); - - it('should create a sprite and emit event', async () => { - const mockSprite = { id: 's3', name: 'new-sprite', status: 'provisioning' }; - const config = { name: 'new-sprite' }; - - mockAxiosInstance.mockResolvedValueOnce({ - data: mockSprite, - status: 201 - }); - - const spy = vi.fn(); - client.on('spriteCreated', spy); - - const sprite = await client.createSprite(config); - - expect(sprite).toEqual(mockSprite); - expect(mockAxiosInstance).toHaveBeenCalledWith(expect.objectContaining({ - method: 'POST', - url: '/sprites', - data: JSON.stringify({ - name: 'new-sprite', - repoUrl: 'https://github.com/test/repo', - branch: 'main' - }) - })); - expect(spy).toHaveBeenCalledWith(mockSprite); - }); - - it('should delete a sprite and emit event', async () => { - mockAxiosInstance.mockResolvedValueOnce({ - data: {}, - status: 204 - }); - - const spy = vi.fn(); - client.on('spriteDeleted', spy); - - await client.deleteSprite('s1'); - - expect(mockAxiosInstance).toHaveBeenCalledWith(expect.objectContaining({ - method: 'DELETE', - url: '/sprites/s1' - })); - expect(spy).toHaveBeenCalledWith('s1'); - }); + it('should create a sprite and emit event', async () => { + const mockSprite = { id: 's3', name: 'new-sprite', status: 'provisioning' }; + const config = { name: 'new-sprite' }; + + mockAxiosInstance.mockResolvedValueOnce({ + data: mockSprite, + status: 201, + }); + + const spy = vi.fn(); + client.on('spriteCreated', spy); + + const sprite = await client.createSprite(config); + + expect(sprite).toEqual(mockSprite); + expect(mockAxiosInstance).toHaveBeenCalledWith( + expect.objectContaining({ + method: 'POST', + url: '/sprites', + data: JSON.stringify({ + name: 'new-sprite', + repoUrl: 'https://github.com/test/repo', + branch: 'main', + }), + }) + ); + expect(spy).toHaveBeenCalledWith(mockSprite); }); - describe('Command Execution', () => { - it('should execute command', async () => { - const mockResult = { stdout: 'hello', stderr: '', exitCode: 0, durationMs: 100 }; + it('should delete a sprite and emit event', async () => { + mockAxiosInstance.mockResolvedValueOnce({ + data: {}, + status: 204, + }); - mockAxiosInstance.mockResolvedValueOnce({ - data: mockResult, - status: 200 - }); + const spy = vi.fn(); + client.on('spriteDeleted', spy); - const result = await client.execCommand('s1', 'echo hello'); + await client.deleteSprite('s1'); - expect(result).toEqual(mockResult); - expect(mockAxiosInstance).toHaveBeenCalledWith(expect.objectContaining({ - method: 'POST', - url: '/sprites/s1/exec', - data: JSON.stringify({ command: 'echo hello', timeout: 60000 }) - })); - }); + expect(mockAxiosInstance).toHaveBeenCalledWith( + expect.objectContaining({ + method: 'DELETE', + url: '/sprites/s1', + }) + ); + expect(spy).toHaveBeenCalledWith('s1'); }); + }); + + describe('Command Execution', () => { + it('should execute command', async () => { + const mockResult = { stdout: 'hello', stderr: '', exitCode: 0, durationMs: 100 }; + + mockAxiosInstance.mockResolvedValueOnce({ + data: mockResult, + status: 200, + }); + + const result = await client.execCommand('s1', 'echo hello'); + + expect(result).toEqual(mockResult); + expect(mockAxiosInstance).toHaveBeenCalledWith( + expect.objectContaining({ + method: 'POST', + url: '/sprites/s1/exec', + data: JSON.stringify({ command: 'echo hello', timeout: 60000 }), + }) + ); + }); + }); + + describe('Lifecycle Management', () => { + it('should shutdown sprite', async () => { + mockAxiosInstance.mockResolvedValueOnce({ + data: {}, + status: 204, + }); + + const spy = vi.fn(); + client.on('spriteStatusChanged', spy); + + await client.shutdownSprite('s1'); + + expect(mockAxiosInstance).toHaveBeenCalledWith( + expect.objectContaining({ + method: 'POST', + url: '/sprites/s1/shutdown', + }) + ); + }); + + it('should wake up sprite', async () => { + mockAxiosInstance.mockResolvedValueOnce({ + data: {}, + status: 204, + }); + + await client.wakeSprite('s1'); - describe('Lifecycle Management', () => { - it('should shutdown sprite', async () => { - mockAxiosInstance.mockResolvedValueOnce({ - data: {}, - status: 204 - }); - - const spy = vi.fn(); - client.on('spriteStatusChanged', spy); - - await client.shutdownSprite('s1'); - - expect(mockAxiosInstance).toHaveBeenCalledWith(expect.objectContaining({ - method: 'POST', - url: '/sprites/s1/shutdown' - })); - }); - - it('should wake up sprite', async () => { - mockAxiosInstance.mockResolvedValueOnce({ - data: {}, - status: 204 - }); - - await client.wakeSprite('s1'); - - expect(mockAxiosInstance).toHaveBeenCalledWith(expect.objectContaining({ - method: 'POST', - url: '/sprites/s1/wake' - })); - }); + expect(mockAxiosInstance).toHaveBeenCalledWith( + expect.objectContaining({ + method: 'POST', + url: '/sprites/s1/wake', + }) + ); }); + }); - describe('Utilities', () => { - it('should generate correct console URL', () => { - const url = client.getConsoleUrl('test-sprite'); - expect(url).toBe('https://test.dev/dashboard/sprites/test-sprite'); - }); + describe('Utilities', () => { + it('should generate correct console URL', () => { + const url = client.getConsoleUrl('test-sprite'); + expect(url).toBe('https://test.dev/dashboard/sprites/test-sprite'); }); + }); }); diff --git a/apps/server/tsconfig.json b/apps/server/tsconfig.json index 618f942ec..c83c53332 100644 --- a/apps/server/tsconfig.json +++ b/apps/server/tsconfig.json @@ -3,9 +3,7 @@ "target": "ES2022", "module": "NodeNext", "moduleResolution": "NodeNext", - "lib": [ - "ES2022" - ], + "lib": ["ES2022"], "outDir": "./dist", "rootDir": "./src", "strict": true, @@ -17,11 +15,6 @@ "declarationMap": true, "sourceMap": true }, - "include": [ - "src/**/*" - ], - "exclude": [ - "node_modules", - "dist" - ] -} \ No newline at end of file + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/genesis_spec/README.md b/genesis_spec/README.md index e3d4115e0..cbffc460e 100644 --- a/genesis_spec/README.md +++ b/genesis_spec/README.md @@ -10,43 +10,47 @@ This Genesis Specification provides exhaustive, enterprise-grade documentation g ## Document Index -| Section | Title | Description | -|---------|-------|-------------| -| [01](section_guides/Automaker_Section_01_Introduction.md) | Introduction & Executive Summary | Project overview, vision, scope, and success criteria | -| [02](section_guides/Automaker_Section_02_Product_Requirements.md) | Product Requirements | Functional and non-functional requirements, user stories | -| [03](section_guides/Automaker_Section_03_Technology_Stack.md) | Technology Stack | Dependencies, tools, and runtime requirements | -| [04](section_guides/Automaker_Section_04_Process_Flowcharts.md) | Process Flowcharts | System flows, data flows, and state machines | -| [05](section_guides/Automaker_Section_05_Architecture_Design.md) | Architecture Design | Module structure, patterns, and API design | -| [06](section_guides/Automaker_Section_06_Data_Models.md) | Data Models | Entity definitions, schemas, and storage | -| [07](section_guides/Automaker_Section_07_Security_Compliance.md) | Security & Compliance | Threat model, authentication, and data protection | -| [08](section_guides/Automaker_Section_08_Testing_Strategy.md) | Testing Strategy | Test approach, frameworks, and coverage | -| [09](section_guides/Automaker_Section_09_Monitoring_Observability.md) | Monitoring & Observability | Logging, metrics, and health checks | -| [10](section_guides/Automaker_Section_10_Deployment_Operations.md) | Deployment & Operations | Build, install, and operational procedures | -| [11](section_guides/Automaker_Section_11_Documentation.md) | Documentation | Doc structure and standards | -| [12](section_guides/Automaker_Section_12_Reference_Collections.md) | Reference Collections | External resources and glossary | +| Section | Title | Description | +| --------------------------------------------------------------------- | -------------------------------- | -------------------------------------------------------- | +| [01](section_guides/Automaker_Section_01_Introduction.md) | Introduction & Executive Summary | Project overview, vision, scope, and success criteria | +| [02](section_guides/Automaker_Section_02_Product_Requirements.md) | Product Requirements | Functional and non-functional requirements, user stories | +| [03](section_guides/Automaker_Section_03_Technology_Stack.md) | Technology Stack | Dependencies, tools, and runtime requirements | +| [04](section_guides/Automaker_Section_04_Process_Flowcharts.md) | Process Flowcharts | System flows, data flows, and state machines | +| [05](section_guides/Automaker_Section_05_Architecture_Design.md) | Architecture Design | Module structure, patterns, and API design | +| [06](section_guides/Automaker_Section_06_Data_Models.md) | Data Models | Entity definitions, schemas, and storage | +| [07](section_guides/Automaker_Section_07_Security_Compliance.md) | Security & Compliance | Threat model, authentication, and data protection | +| [08](section_guides/Automaker_Section_08_Testing_Strategy.md) | Testing Strategy | Test approach, frameworks, and coverage | +| [09](section_guides/Automaker_Section_09_Monitoring_Observability.md) | Monitoring & Observability | Logging, metrics, and health checks | +| [10](section_guides/Automaker_Section_10_Deployment_Operations.md) | Deployment & Operations | Build, install, and operational procedures | +| [11](section_guides/Automaker_Section_11_Documentation.md) | Documentation | Doc structure and standards | +| [12](section_guides/Automaker_Section_12_Reference_Collections.md) | Reference Collections | External resources and glossary | ## Quick Stats -| Metric | Value | -|--------|-------| -| Lines of Code | ~195,000 | -| TypeScript Files | ~1,001 | -| Backend Services | 18+ | -| Shared Libraries | 7 | -| Version | 0.12.0 | +| Metric | Value | +| ---------------- | -------- | +| Lines of Code | ~195,000 | +| TypeScript Files | ~1,001 | +| Backend Services | 18+ | +| Shared Libraries | 7 | +| Version | 0.12.0 | ## Usage ### For New Contributors + Start with Section 01 (Introduction) for an overview, then review Section 03 (Technology Stack) to understand dependencies. ### For Architects + Consult Section 05 (Architecture Design) for design decisions and patterns. ### For AI Agents + Use this documentation as context for autonomous development tasks. Each section provides structured information suitable for LLM consumption. ### For Security Auditors + Review Section 07 (Security & Compliance) for the threat model and security controls. --- diff --git a/genesis_spec/section_guides/Automaker_Section_01_Introduction.md b/genesis_spec/section_guides/Automaker_Section_01_Introduction.md index d6ac4a446..cd0704d7d 100644 --- a/genesis_spec/section_guides/Automaker_Section_01_Introduction.md +++ b/genesis_spec/section_guides/Automaker_Section_01_Introduction.md @@ -11,6 +11,7 @@ Automaker is an **autonomous AI development studio** that revolutionizes software development by orchestrating AI agents to implement features, fix bugs, and manage code in isolated git worktrees. Built as a desktop application using Electron with a React frontend and Express backend, Automaker provides a Kanban-based workflow where Claude-based AI agents autonomously execute development tasks. The platform bridges the gap between human-guided development and fully autonomous AI coding, providing: + - **Multi-agent orchestration** via Claude Agent SDK - **Isolated feature development** using git worktrees - **Real-time collaboration** through WebSocket streaming @@ -18,6 +19,7 @@ The platform bridges the gap between human-guided development and fully autonomo - **Enterprise-ready security** with encrypted credential storage **Key Metrics:** + - ~195,000 lines of TypeScript code - ~1,001 TypeScript source files - 7 shared library packages @@ -31,6 +33,7 @@ The platform bridges the gap between human-guided development and fully autonomo Automaker aims to be the **definitive autonomous development environment** where AI agents handle the full software development lifecycle - from ideation and planning to implementation, testing, and deployment - while developers maintain strategic oversight and control. **Long-term Goals:** + 1. Enable fully autonomous feature development with minimal human intervention 2. Support multiple AI providers for flexibility and cost optimization 3. Integrate seamlessly with existing development workflows (GitHub, CI/CD) @@ -43,41 +46,41 @@ Automaker aims to be the **definitive autonomous development environment** where ### In Scope -| Category | Included | -|----------|----------| -| **AI Agent Management** | Spawning, monitoring, and stopping Claude-based agents | -| **Session Management** | Creating, persisting, archiving, and resuming agent sessions | -| **Feature Development** | Autonomous implementation with planning modes (skip, lite, spec, full) | -| **Git Integration** | Worktree isolation, branching, committing, PR creation | -| **Terminal Access** | PTY-based terminal with xterm.js for command execution | -| **Multi-Provider Support** | Claude, Codex, Cursor CLI, OpenCode providers | -| **Real-time Communication** | WebSocket streaming for live updates | -| **Desktop & Web Modes** | Electron app and browser-based UI | -| **Configuration Management** | Global and per-project settings | -| **MCP Server Integration** | Model Context Protocol server support | +| Category | Included | +| ---------------------------- | ---------------------------------------------------------------------- | +| **AI Agent Management** | Spawning, monitoring, and stopping Claude-based agents | +| **Session Management** | Creating, persisting, archiving, and resuming agent sessions | +| **Feature Development** | Autonomous implementation with planning modes (skip, lite, spec, full) | +| **Git Integration** | Worktree isolation, branching, committing, PR creation | +| **Terminal Access** | PTY-based terminal with xterm.js for command execution | +| **Multi-Provider Support** | Claude, Codex, Cursor CLI, OpenCode providers | +| **Real-time Communication** | WebSocket streaming for live updates | +| **Desktop & Web Modes** | Electron app and browser-based UI | +| **Configuration Management** | Global and per-project settings | +| **MCP Server Integration** | Model Context Protocol server support | ### Out of Scope -| Category | Excluded | -|----------|----------| -| **Direct Code Editing** | Not a replacement for VS Code/IDEs | -| **CI/CD Pipeline Execution** | Relies on external CI systems | -| **Cloud Hosting** | Self-hosted or local deployment only | -| **Team Collaboration** | Single-user focus (multi-user planned) | -| **Mobile Applications** | Desktop and web only | +| Category | Excluded | +| ---------------------------- | -------------------------------------- | +| **Direct Code Editing** | Not a replacement for VS Code/IDEs | +| **CI/CD Pipeline Execution** | Relies on external CI systems | +| **Cloud Hosting** | Self-hosted or local deployment only | +| **Team Collaboration** | Single-user focus (multi-user planned) | +| **Mobile Applications** | Desktop and web only | --- ## 1.4 Success Criteria -| Criterion | Metric | Target | -|-----------|--------|--------| -| Feature Completion Rate | Successfully implemented features | >85% | -| Agent Reliability | Sessions without crashes | >99% | -| Build Success | CI pipeline pass rate | >95% | -| Test Coverage | Server-side code coverage | >80% | -| User Adoption | Active installations | Growth metric | -| Performance | Agent response latency | <5s for initial response | +| Criterion | Metric | Target | +| ----------------------- | --------------------------------- | ------------------------ | +| Feature Completion Rate | Successfully implemented features | >85% | +| Agent Reliability | Sessions without crashes | >99% | +| Build Success | CI pipeline pass rate | >95% | +| Test Coverage | Server-side code coverage | >80% | +| User Adoption | Active installations | Growth metric | +| Performance | Agent response latency | <5s for initial response | --- @@ -92,6 +95,7 @@ This Genesis Specification serves as the **single source of truth** for understa - **Security Auditors**: Security model and compliance review **How to Use This Document:** + 1. Start with Section 01 (Introduction) for overview 2. Review Section 03 (Technology Stack) for dependencies 3. Consult Section 05 (Architecture) for design decisions @@ -111,17 +115,17 @@ This Genesis Specification serves as the **single source of truth** for understa ## 1.7 Document Index -| Section | Title | Purpose | -|---------|-------|---------| -| 01 | Introduction & Executive Summary | Project overview and scope | -| 02 | Product Requirements | Functional and non-functional requirements | -| 03 | Technology Stack | Dependencies and tools | -| 04 | Process Flowcharts | System and data flows | -| 05 | Architecture Design | Module structure and patterns | -| 06 | Data Models | Entity definitions and schemas | -| 07 | Security & Compliance | Security architecture and threat model | -| 08 | Testing Strategy | Test approach and coverage | -| 09 | Monitoring & Observability | Logging, metrics, and health checks | -| 10 | Deployment & Operations | Build, install, and runtime procedures | -| 11 | Documentation | Doc structure and standards | -| 12 | Reference Collections | External resources and glossary | +| Section | Title | Purpose | +| ------- | -------------------------------- | ------------------------------------------ | +| 01 | Introduction & Executive Summary | Project overview and scope | +| 02 | Product Requirements | Functional and non-functional requirements | +| 03 | Technology Stack | Dependencies and tools | +| 04 | Process Flowcharts | System and data flows | +| 05 | Architecture Design | Module structure and patterns | +| 06 | Data Models | Entity definitions and schemas | +| 07 | Security & Compliance | Security architecture and threat model | +| 08 | Testing Strategy | Test approach and coverage | +| 09 | Monitoring & Observability | Logging, metrics, and health checks | +| 10 | Deployment & Operations | Build, install, and runtime procedures | +| 11 | Documentation | Doc structure and standards | +| 12 | Reference Collections | External resources and glossary | diff --git a/genesis_spec/section_guides/Automaker_Section_02_Product_Requirements.md b/genesis_spec/section_guides/Automaker_Section_02_Product_Requirements.md index 16d2f82fa..34fa9e990 100644 --- a/genesis_spec/section_guides/Automaker_Section_02_Product_Requirements.md +++ b/genesis_spec/section_guides/Automaker_Section_02_Product_Requirements.md @@ -10,81 +10,81 @@ ### Core Agent Features -| ID | Requirement | Priority | Status | -|----|-------------|----------|--------| -| FR-001 | System shall spawn and manage Claude-based AI agents | P0 | Implemented | -| FR-002 | System shall support conversation session persistence | P0 | Implemented | -| FR-003 | System shall stream agent responses via WebSocket | P0 | Implemented | -| FR-004 | System shall support agent interruption/abortion | P0 | Implemented | -| FR-005 | System shall maintain conversation history per session | P0 | Implemented | -| FR-006 | System shall support image input to agents | P1 | Implemented | -| FR-007 | System shall queue prompts for sequential execution | P1 | Implemented | -| FR-008 | System shall support custom system prompts | P1 | Implemented | +| ID | Requirement | Priority | Status | +| ------ | ------------------------------------------------------ | -------- | ----------- | +| FR-001 | System shall spawn and manage Claude-based AI agents | P0 | Implemented | +| FR-002 | System shall support conversation session persistence | P0 | Implemented | +| FR-003 | System shall stream agent responses via WebSocket | P0 | Implemented | +| FR-004 | System shall support agent interruption/abortion | P0 | Implemented | +| FR-005 | System shall maintain conversation history per session | P0 | Implemented | +| FR-006 | System shall support image input to agents | P1 | Implemented | +| FR-007 | System shall queue prompts for sequential execution | P1 | Implemented | +| FR-008 | System shall support custom system prompts | P1 | Implemented | ### Auto-Mode Features -| ID | Requirement | Priority | Status | -|----|-------------|----------|--------| -| FR-010 | System shall support autonomous feature development | P0 | Implemented | -| FR-011 | System shall provide multiple planning modes (skip, lite, spec, full) | P0 | Implemented | -| FR-012 | System shall isolate features in git worktrees | P0 | Implemented | -| FR-013 | System shall support feature verification workflow | P0 | Implemented | -| FR-014 | System shall support plan approval workflow | P0 | Implemented | -| FR-015 | System shall track feature status through pipeline stages | P1 | Implemented | -| FR-016 | System shall support feature dependency resolution | P1 | Implemented | -| FR-017 | System shall generate feature specifications | P1 | Implemented | +| ID | Requirement | Priority | Status | +| ------ | --------------------------------------------------------------------- | -------- | ----------- | +| FR-010 | System shall support autonomous feature development | P0 | Implemented | +| FR-011 | System shall provide multiple planning modes (skip, lite, spec, full) | P0 | Implemented | +| FR-012 | System shall isolate features in git worktrees | P0 | Implemented | +| FR-013 | System shall support feature verification workflow | P0 | Implemented | +| FR-014 | System shall support plan approval workflow | P0 | Implemented | +| FR-015 | System shall track feature status through pipeline stages | P1 | Implemented | +| FR-016 | System shall support feature dependency resolution | P1 | Implemented | +| FR-017 | System shall generate feature specifications | P1 | Implemented | ### Session Management -| ID | Requirement | Priority | Status | -|----|-------------|----------|--------| -| FR-020 | System shall create named agent sessions | P0 | Implemented | -| FR-021 | System shall list all sessions with metadata | P0 | Implemented | -| FR-022 | System shall archive/unarchive sessions | P1 | Implemented | -| FR-023 | System shall delete sessions permanently | P1 | Implemented | -| FR-024 | System shall associate sessions with project paths | P1 | Implemented | -| FR-025 | System shall persist sessions across server restarts | P0 | Implemented | +| ID | Requirement | Priority | Status | +| ------ | ---------------------------------------------------- | -------- | ----------- | +| FR-020 | System shall create named agent sessions | P0 | Implemented | +| FR-021 | System shall list all sessions with metadata | P0 | Implemented | +| FR-022 | System shall archive/unarchive sessions | P1 | Implemented | +| FR-023 | System shall delete sessions permanently | P1 | Implemented | +| FR-024 | System shall associate sessions with project paths | P1 | Implemented | +| FR-025 | System shall persist sessions across server restarts | P0 | Implemented | ### Terminal Features -| ID | Requirement | Priority | Status | -|----|-------------|----------|--------| -| FR-030 | System shall provide PTY-based terminal sessions | P0 | Implemented | -| FR-031 | System shall support multiple concurrent terminals | P1 | Implemented | -| FR-032 | System shall maintain terminal scrollback buffer | P1 | Implemented | -| FR-033 | System shall support terminal resize operations | P1 | Implemented | -| FR-034 | System shall optionally require terminal password | P2 | Implemented | +| ID | Requirement | Priority | Status | +| ------ | -------------------------------------------------- | -------- | ----------- | +| FR-030 | System shall provide PTY-based terminal sessions | P0 | Implemented | +| FR-031 | System shall support multiple concurrent terminals | P1 | Implemented | +| FR-032 | System shall maintain terminal scrollback buffer | P1 | Implemented | +| FR-033 | System shall support terminal resize operations | P1 | Implemented | +| FR-034 | System shall optionally require terminal password | P2 | Implemented | ### Git Integration -| ID | Requirement | Priority | Status | -|----|-------------|----------|--------| -| FR-040 | System shall create/remove git worktrees | P0 | Implemented | -| FR-041 | System shall display file diffs | P1 | Implemented | -| FR-042 | System shall commit changes with messages | P1 | Implemented | -| FR-043 | System shall list GitHub PRs and issues | P2 | Implemented | -| FR-044 | System shall validate GitHub issues | P2 | Implemented | +| ID | Requirement | Priority | Status | +| ------ | ----------------------------------------- | -------- | ----------- | +| FR-040 | System shall create/remove git worktrees | P0 | Implemented | +| FR-041 | System shall display file diffs | P1 | Implemented | +| FR-042 | System shall commit changes with messages | P1 | Implemented | +| FR-043 | System shall list GitHub PRs and issues | P2 | Implemented | +| FR-044 | System shall validate GitHub issues | P2 | Implemented | ### Settings & Configuration -| ID | Requirement | Priority | Status | -|----|-------------|----------|--------| -| FR-050 | System shall support global settings | P0 | Implemented | -| FR-051 | System shall support per-project settings | P0 | Implemented | -| FR-052 | System shall store API credentials securely | P0 | Implemented | -| FR-053 | System shall support theme customization | P2 | Implemented | -| FR-054 | System shall support keyboard shortcuts | P2 | Implemented | -| FR-055 | System shall support custom prompt templates | P1 | Implemented | +| ID | Requirement | Priority | Status | +| ------ | -------------------------------------------- | -------- | ----------- | +| FR-050 | System shall support global settings | P0 | Implemented | +| FR-051 | System shall support per-project settings | P0 | Implemented | +| FR-052 | System shall store API credentials securely | P0 | Implemented | +| FR-053 | System shall support theme customization | P2 | Implemented | +| FR-054 | System shall support keyboard shortcuts | P2 | Implemented | +| FR-055 | System shall support custom prompt templates | P1 | Implemented | ### Multi-Provider Support -| ID | Requirement | Priority | Status | -|----|-------------|----------|--------| -| FR-060 | System shall support Claude models | P0 | Implemented | -| FR-061 | System shall support Codex models | P1 | Implemented | -| FR-062 | System shall support Cursor CLI | P1 | Implemented | -| FR-063 | System shall support OpenCode CLI | P2 | Implemented | -| FR-064 | System shall cache model responses | P2 | Implemented | +| ID | Requirement | Priority | Status | +| ------ | ---------------------------------- | -------- | ----------- | +| FR-060 | System shall support Claude models | P0 | Implemented | +| FR-061 | System shall support Codex models | P1 | Implemented | +| FR-062 | System shall support Cursor CLI | P1 | Implemented | +| FR-063 | System shall support OpenCode CLI | P2 | Implemented | +| FR-064 | System shall cache model responses | P2 | Implemented | --- @@ -92,59 +92,59 @@ ### Performance -| ID | Category | Requirement | Target | -|----|----------|-------------|--------| -| NFR-001 | Performance | Initial page load time | <3s | -| NFR-002 | Performance | Agent first response | <5s | +| ID | Category | Requirement | Target | +| ------- | ----------- | ------------------------- | ------ | +| NFR-001 | Performance | Initial page load time | <3s | +| NFR-002 | Performance | Agent first response | <5s | | NFR-003 | Performance | WebSocket message latency | <100ms | -| NFR-004 | Performance | Terminal input latency | <50ms | -| NFR-005 | Performance | Session restore time | <2s | +| NFR-004 | Performance | Terminal input latency | <50ms | +| NFR-005 | Performance | Session restore time | <2s | ### Security -| ID | Category | Requirement | Target | -|----|----------|-------------|--------| -| NFR-010 | Security | API key encryption at rest | Required | -| NFR-011 | Security | WebSocket authentication | Required | -| NFR-012 | Security | CORS policy enforcement | Required | -| NFR-013 | Security | Path traversal prevention | Required | +| ID | Category | Requirement | Target | +| ------- | -------- | --------------------------------- | -------- | +| NFR-010 | Security | API key encryption at rest | Required | +| NFR-011 | Security | WebSocket authentication | Required | +| NFR-012 | Security | CORS policy enforcement | Required | +| NFR-013 | Security | Path traversal prevention | Required | | NFR-014 | Security | Input validation on all endpoints | Required | ### Scalability -| ID | Category | Requirement | Target | -|----|----------|-------------|--------| -| NFR-020 | Scalability | Concurrent agent sessions | 10+ | -| NFR-021 | Scalability | Terminal sessions | 20+ | -| NFR-022 | Scalability | Session history storage | 1000+ messages | -| NFR-023 | Scalability | Feature queue depth | 100+ | +| ID | Category | Requirement | Target | +| ------- | ----------- | ------------------------- | -------------- | +| NFR-020 | Scalability | Concurrent agent sessions | 10+ | +| NFR-021 | Scalability | Terminal sessions | 20+ | +| NFR-022 | Scalability | Session history storage | 1000+ messages | +| NFR-023 | Scalability | Feature queue depth | 100+ | ### Reliability -| ID | Category | Requirement | Target | -|----|----------|-------------|--------| -| NFR-030 | Reliability | Server uptime | 99.9% | -| NFR-031 | Reliability | Graceful shutdown handling | Required | -| NFR-032 | Reliability | Session data persistence | Atomic writes | -| NFR-033 | Reliability | Error recovery | Auto-reconnect | +| ID | Category | Requirement | Target | +| ------- | ----------- | -------------------------- | -------------- | +| NFR-030 | Reliability | Server uptime | 99.9% | +| NFR-031 | Reliability | Graceful shutdown handling | Required | +| NFR-032 | Reliability | Session data persistence | Atomic writes | +| NFR-033 | Reliability | Error recovery | Auto-reconnect | ### Usability -| ID | Category | Requirement | Target | -|----|----------|-------------|--------| -| NFR-040 | Usability | Keyboard navigation | Full support | -| NFR-041 | Usability | Responsive design | 1024px+ | -| NFR-042 | Usability | Dark/Light theme | Both | -| NFR-043 | Usability | Real-time status updates | Required | +| ID | Category | Requirement | Target | +| ------- | --------- | ------------------------ | ------------ | +| NFR-040 | Usability | Keyboard navigation | Full support | +| NFR-041 | Usability | Responsive design | 1024px+ | +| NFR-042 | Usability | Dark/Light theme | Both | +| NFR-043 | Usability | Real-time status updates | Required | ### Maintainability -| ID | Category | Requirement | Target | -|----|----------|-------------|--------| -| NFR-050 | Maintainability | TypeScript coverage | 100% | +| ID | Category | Requirement | Target | +| ------- | --------------- | ----------------------- | ------------- | +| NFR-050 | Maintainability | TypeScript coverage | 100% | | NFR-051 | Maintainability | Shared type definitions | Monorepo libs | -| NFR-052 | Maintainability | Code documentation | Public APIs | -| NFR-053 | Maintainability | Test coverage | >80% server | +| NFR-052 | Maintainability | Code documentation | Public APIs | +| NFR-053 | Maintainability | Test coverage | >80% server | --- diff --git a/genesis_spec/section_guides/Automaker_Section_03_Technology_Stack.md b/genesis_spec/section_guides/Automaker_Section_03_Technology_Stack.md index 89bb3f0bb..275789800 100644 --- a/genesis_spec/section_guides/Automaker_Section_03_Technology_Stack.md +++ b/genesis_spec/section_guides/Automaker_Section_03_Technology_Stack.md @@ -8,14 +8,14 @@ ## 3.1 Core Technologies -| Technology | Version | Purpose | -|------------|---------|---------| -| TypeScript | 5.9.3 | Primary language for all code | -| Node.js | 22.x | Runtime environment | -| React | 19.2.3 | Frontend UI framework | -| Express | 5.2.1 | Backend HTTP server | -| Electron | 39.2.7 | Desktop application wrapper | -| Vite | 7.3.0 | Frontend build tool | +| Technology | Version | Purpose | +| ---------- | ------- | ----------------------------- | +| TypeScript | 5.9.3 | Primary language for all code | +| Node.js | 22.x | Runtime environment | +| React | 19.2.3 | Frontend UI framework | +| Express | 5.2.1 | Backend HTTP server | +| Electron | 39.2.7 | Desktop application wrapper | +| Vite | 7.3.0 | Frontend build tool | --- @@ -23,74 +23,74 @@ ### Backend Production Dependencies -| Package | Version | Purpose | -|---------|---------|---------| -| @anthropic-ai/claude-agent-sdk | 0.1.76 | Claude AI agent orchestration | -| @modelcontextprotocol/sdk | 1.25.2 | MCP server integration | -| @openai/codex-sdk | 0.77.0 | Codex model access | -| express | 5.2.1 | HTTP server framework | -| ws | 8.18.3 | WebSocket server | -| node-pty | 1.1.0-beta41 | Terminal emulation | -| cors | 2.8.5 | CORS middleware | -| cookie-parser | 1.4.7 | Cookie handling | -| morgan | 1.10.1 | HTTP request logging | -| dotenv | 17.2.3 | Environment variables | +| Package | Version | Purpose | +| ------------------------------ | ------------ | ----------------------------- | +| @anthropic-ai/claude-agent-sdk | 0.1.76 | Claude AI agent orchestration | +| @modelcontextprotocol/sdk | 1.25.2 | MCP server integration | +| @openai/codex-sdk | 0.77.0 | Codex model access | +| express | 5.2.1 | HTTP server framework | +| ws | 8.18.3 | WebSocket server | +| node-pty | 1.1.0-beta41 | Terminal emulation | +| cors | 2.8.5 | CORS middleware | +| cookie-parser | 1.4.7 | Cookie handling | +| morgan | 1.10.1 | HTTP request logging | +| dotenv | 17.2.3 | Environment variables | ### Frontend Production Dependencies -| Package | Version | Purpose | -|---------|---------|---------| -| react | 19.2.3 | UI framework | -| react-dom | 19.2.3 | React DOM renderer | -| @tanstack/react-router | 1.141.6 | Type-safe routing | -| @tanstack/react-query | 5.90.12 | Server state management | -| zustand | 5.0.9 | Client state management | -| @xterm/xterm | 5.5.0 | Terminal emulator | -| @uiw/react-codemirror | 4.25.4 | Code editor | -| @xyflow/react | 12.10.0 | Flow diagrams | -| @radix-ui/* | Various | Accessible UI components | -| tailwind-merge | 3.4.0 | Tailwind class merging | -| lucide-react | 0.562.0 | Icons | -| sonner | 2.0.7 | Toast notifications | -| react-markdown | 10.1.0 | Markdown rendering | -| dagre | 0.8.5 | Graph layout algorithms | +| Package | Version | Purpose | +| ---------------------- | ------- | ------------------------ | +| react | 19.2.3 | UI framework | +| react-dom | 19.2.3 | React DOM renderer | +| @tanstack/react-router | 1.141.6 | Type-safe routing | +| @tanstack/react-query | 5.90.12 | Server state management | +| zustand | 5.0.9 | Client state management | +| @xterm/xterm | 5.5.0 | Terminal emulator | +| @uiw/react-codemirror | 4.25.4 | Code editor | +| @xyflow/react | 12.10.0 | Flow diagrams | +| @radix-ui/\* | Various | Accessible UI components | +| tailwind-merge | 3.4.0 | Tailwind class merging | +| lucide-react | 0.562.0 | Icons | +| sonner | 2.0.7 | Toast notifications | +| react-markdown | 10.1.0 | Markdown rendering | +| dagre | 0.8.5 | Graph layout algorithms | ### Development Dependencies -| Package | Version | Purpose | -|---------|---------|---------| -| typescript | 5.9.3 | TypeScript compiler | -| vitest | 4.0.16 | Unit testing framework | -| @playwright/test | 1.57.0 | E2E testing framework | -| eslint | 9.39.2 | Code linting | -| tailwindcss | 4.1.18 | CSS framework | -| electron-builder | 26.0.12 | Desktop app packaging | -| @vitejs/plugin-react | 5.1.2 | React Vite plugin | -| tsx | 4.21.0 | TypeScript execution | - -### Shared Library Packages (@automaker/*) - -| Package | Version | Purpose | -|---------|---------|---------| -| @automaker/types | 1.0.0 | Shared TypeScript interfaces | -| @automaker/utils | 1.0.0 | Common utility functions | -| @automaker/prompts | 1.0.0 | AI prompt templates | -| @automaker/platform | 1.0.0 | OS-specific abstractions | -| @automaker/model-resolver | 1.0.0 | AI model selection logic | -| @automaker/dependency-resolver | 1.0.0 | Feature dependency ordering | -| @automaker/git-utils | 1.0.0 | Git operation helpers | +| Package | Version | Purpose | +| -------------------- | ------- | ---------------------- | +| typescript | 5.9.3 | TypeScript compiler | +| vitest | 4.0.16 | Unit testing framework | +| @playwright/test | 1.57.0 | E2E testing framework | +| eslint | 9.39.2 | Code linting | +| tailwindcss | 4.1.18 | CSS framework | +| electron-builder | 26.0.12 | Desktop app packaging | +| @vitejs/plugin-react | 5.1.2 | React Vite plugin | +| tsx | 4.21.0 | TypeScript execution | + +### Shared Library Packages (@automaker/\*) + +| Package | Version | Purpose | +| ------------------------------ | ------- | ---------------------------- | +| @automaker/types | 1.0.0 | Shared TypeScript interfaces | +| @automaker/utils | 1.0.0 | Common utility functions | +| @automaker/prompts | 1.0.0 | AI prompt templates | +| @automaker/platform | 1.0.0 | OS-specific abstractions | +| @automaker/model-resolver | 1.0.0 | AI model selection logic | +| @automaker/dependency-resolver | 1.0.0 | Feature dependency ordering | +| @automaker/git-utils | 1.0.0 | Git operation helpers | --- ## 3.3 Build Tools -| Tool | Purpose | -|------|---------| -| npm | Package management (workspaces) | -| Vite | Frontend bundling and dev server | -| tsc | TypeScript compilation | -| electron-builder | Desktop app packaging | -| tsx | Development-time TypeScript execution | +| Tool | Purpose | +| ---------------- | ------------------------------------- | +| npm | Package management (workspaces) | +| Vite | Frontend bundling and dev server | +| tsc | TypeScript compilation | +| electron-builder | Desktop app packaging | +| tsx | Development-time TypeScript execution | ### Build Configuration @@ -107,31 +107,31 @@ Root package.json (npm workspaces) ### Development Environment -| Requirement | Minimum | Recommended | -|-------------|---------|-------------| -| Node.js | 22.0.0 | 22.x (latest LTS) | -| npm | 10.x | Latest | -| OS | macOS, Windows, Linux | Any | -| RAM | 4GB | 8GB+ | -| Disk | 2GB | 5GB+ | +| Requirement | Minimum | Recommended | +| ----------- | --------------------- | ----------------- | +| Node.js | 22.0.0 | 22.x (latest LTS) | +| npm | 10.x | Latest | +| OS | macOS, Windows, Linux | Any | +| RAM | 4GB | 8GB+ | +| Disk | 2GB | 5GB+ | ### Production Environment (Docker) -| Requirement | Value | -|-------------|-------| -| Base Image | node:22-slim | -| Port (Server) | 3008 | -| Port (UI) | 80 | -| Data Directory | /data | -| Projects Directory | /projects | +| Requirement | Value | +| ------------------ | ------------ | +| Base Image | node:22-slim | +| Port (Server) | 3008 | +| Port (UI) | 80 | +| Data Directory | /data | +| Projects Directory | /projects | ### Desktop Application -| Platform | Architecture | Format | -|----------|--------------|--------| -| macOS | x64, arm64 | DMG, ZIP | -| Windows | x64 | NSIS installer | -| Linux | x64 | AppImage, DEB, RPM | +| Platform | Architecture | Format | +| -------- | ------------ | ------------------ | +| macOS | x64, arm64 | DMG, ZIP | +| Windows | x64 | NSIS installer | +| Linux | x64 | AppImage, DEB, RPM | --- @@ -139,28 +139,28 @@ Root package.json (npm workspaces) ### AI Providers -| Service | Authentication | Purpose | -|---------|---------------|---------| -| Anthropic Claude | API Key | Primary AI agent | -| OpenAI Codex | API Key | Alternative provider | -| Cursor CLI | OAuth | IDE integration | -| OpenCode CLI | OAuth | Multi-provider access | +| Service | Authentication | Purpose | +| ---------------- | -------------- | --------------------- | +| Anthropic Claude | API Key | Primary AI agent | +| OpenAI Codex | API Key | Alternative provider | +| Cursor CLI | OAuth | IDE integration | +| OpenCode CLI | OAuth | Multi-provider access | ### Development Services -| Service | Purpose | -|---------|---------| -| GitHub | Version control, PRs, issues | -| GitHub Actions | CI/CD pipeline | -| Discord | Community support | +| Service | Purpose | +| -------------- | ---------------------------- | +| GitHub | Version control, PRs, issues | +| GitHub Actions | CI/CD pipeline | +| Discord | Community support | ### Optional Integrations -| Service | Purpose | -|---------|---------| -| MCP Servers | Extended tool capabilities | -| Playwright Browsers | E2E testing | -| Docker Registry | Container distribution | +| Service | Purpose | +| ------------------- | -------------------------- | +| MCP Servers | Extended tool capabilities | +| Playwright Browsers | E2E testing | +| Docker Registry | Container distribution | --- diff --git a/genesis_spec/section_guides/Automaker_Section_05_Architecture_Design.md b/genesis_spec/section_guides/Automaker_Section_05_Architecture_Design.md index 836cf2183..a498e8648 100644 --- a/genesis_spec/section_guides/Automaker_Section_05_Architecture_Design.md +++ b/genesis_spec/section_guides/Automaker_Section_05_Architecture_Design.md @@ -139,22 +139,23 @@ apps/ui/src/ ## 5.3 Design Patterns -| Pattern | Location | Purpose | -|---------|----------|---------| -| **Factory** | `provider-factory.ts` | Create appropriate AI provider based on model | -| **Service Layer** | `services/` | Encapsulate business logic from routes | -| **Event Emitter** | `lib/events.ts` | Decouple components via pub/sub | -| **Repository** | `SettingsService` | Abstract data persistence | -| **Adapter** | Provider classes | Unified interface for AI providers | -| **Strategy** | Planning modes | Interchangeable planning algorithms | -| **Observer** | WebSocket events | Real-time UI updates | -| **Singleton** | Terminal/DevServer services | Shared stateful resources | -| **Builder** | `sdk-options.ts` | Construct complex SDK options | -| **Middleware** | Express middleware | Request processing pipeline | +| Pattern | Location | Purpose | +| ----------------- | --------------------------- | --------------------------------------------- | +| **Factory** | `provider-factory.ts` | Create appropriate AI provider based on model | +| **Service Layer** | `services/` | Encapsulate business logic from routes | +| **Event Emitter** | `lib/events.ts` | Decouple components via pub/sub | +| **Repository** | `SettingsService` | Abstract data persistence | +| **Adapter** | Provider classes | Unified interface for AI providers | +| **Strategy** | Planning modes | Interchangeable planning algorithms | +| **Observer** | WebSocket events | Real-time UI updates | +| **Singleton** | Terminal/DevServer services | Shared stateful resources | +| **Builder** | `sdk-options.ts` | Construct complex SDK options | +| **Middleware** | Express middleware | Request processing pipeline | ### Pattern Examples **Factory Pattern - Provider Selection:** + ```typescript // provider-factory.ts class ProviderFactory { @@ -170,6 +171,7 @@ class ProviderFactory { ``` **Event Emitter Pattern:** + ```typescript // lib/events.ts interface EventEmitter { @@ -184,37 +186,37 @@ interface EventEmitter { ### REST API Structure -| Method | Endpoint | Purpose | -|--------|----------|---------| -| **Sessions** | -| POST | /api/sessions | Create session | -| GET | /api/sessions | List sessions | -| PUT | /api/sessions/:id | Update session | -| DELETE | /api/sessions/:id | Delete session | -| **Agent** | -| POST | /api/agent/start | Start conversation | -| POST | /api/agent/send | Send message | -| POST | /api/agent/stop | Stop agent | -| GET | /api/agent/history | Get history | +| Method | Endpoint | Purpose | +| ------------- | --------------------------- | ---------------------- | +| **Sessions** | +| POST | /api/sessions | Create session | +| GET | /api/sessions | List sessions | +| PUT | /api/sessions/:id | Update session | +| DELETE | /api/sessions/:id | Delete session | +| **Agent** | +| POST | /api/agent/start | Start conversation | +| POST | /api/agent/send | Send message | +| POST | /api/agent/stop | Stop agent | +| GET | /api/agent/history | Get history | | **Auto-Mode** | -| POST | /api/auto-mode/run-feature | Start feature | -| POST | /api/auto-mode/approve-plan | Approve plan | -| POST | /api/auto-mode/verify | Verify feature | -| POST | /api/auto-mode/commit | Commit changes | -| **Terminal** | -| POST | /api/terminal/sessions | Create terminal | -| DELETE | /api/terminal/sessions/:id | Kill terminal | -| **Settings** | -| GET | /api/settings/global | Get global settings | -| POST | /api/settings/global | Update global settings | -| GET | /api/settings/project | Get project settings | +| POST | /api/auto-mode/run-feature | Start feature | +| POST | /api/auto-mode/approve-plan | Approve plan | +| POST | /api/auto-mode/verify | Verify feature | +| POST | /api/auto-mode/commit | Commit changes | +| **Terminal** | +| POST | /api/terminal/sessions | Create terminal | +| DELETE | /api/terminal/sessions/:id | Kill terminal | +| **Settings** | +| GET | /api/settings/global | Get global settings | +| POST | /api/settings/global | Update global settings | +| GET | /api/settings/project | Get project settings | ### WebSocket API -| Endpoint | Events | -|----------|--------| -| `/api/events` | agent:stream, agent:complete, agent:error, feature:status | -| `/api/terminal/ws` | connected, scrollback, data, exit | +| Endpoint | Events | +| ------------------ | --------------------------------------------------------- | +| `/api/events` | agent:stream, agent:complete, agent:error, feature:status | +| `/api/terminal/ws` | connected, scrollback, data, exit | --- @@ -222,23 +224,23 @@ interface EventEmitter { ### External Integrations -| Integration | Protocol | Purpose | -|-------------|----------|---------| -| Anthropic API | HTTPS | Claude model inference | -| OpenAI API | HTTPS | Codex model inference | -| GitHub API | HTTPS | PRs, issues, repos | -| MCP Servers | stdio/HTTP | Extended tools | -| Cursor CLI | subprocess | Cursor model access | +| Integration | Protocol | Purpose | +| ------------- | ---------- | ---------------------- | +| Anthropic API | HTTPS | Claude model inference | +| OpenAI API | HTTPS | Codex model inference | +| GitHub API | HTTPS | PRs, issues, repos | +| MCP Servers | stdio/HTTP | Extended tools | +| Cursor CLI | subprocess | Cursor model access | ### Internal Integrations -| From | To | Method | -|------|-----|--------| -| Routes | Services | Direct call | -| Services | Events | Event emitter | -| Events | WebSocket | Broadcast | -| UI | Backend | HTTP/WS | -| Electron | Backend | localhost | +| From | To | Method | +| -------- | --------- | ------------- | +| Routes | Services | Direct call | +| Services | Events | Event emitter | +| Events | WebSocket | Broadcast | +| UI | Backend | HTTP/WS | +| Electron | Backend | localhost | --- @@ -251,6 +253,7 @@ interface EventEmitter { **Decision:** Use npm workspaces with `libs/` for shared packages. **Rationale:** + - Single repository for all code - Shared TypeScript types - Atomic commits across packages @@ -263,6 +266,7 @@ interface EventEmitter { **Decision:** Extract all business logic into dedicated service classes. **Rationale:** + - Separation of concerns - Easier testing (mock services) - Reusable logic across routes @@ -275,6 +279,7 @@ interface EventEmitter { **Decision:** Create provider interface with factory pattern. **Rationale:** + - Unified interface for all providers - Easy to add new providers - Swap providers at runtime @@ -287,6 +292,7 @@ interface EventEmitter { **Decision:** Use WebSocket with event emitter pattern. **Rationale:** + - Low latency updates - Decoupled components - Scalable to multiple clients @@ -299,6 +305,7 @@ interface EventEmitter { **Decision:** Each feature runs in its own git worktree. **Rationale:** + - Complete isolation between features - No merge conflicts during development - Easy cleanup after completion diff --git a/genesis_spec/section_guides/Automaker_Section_06_Data_Models.md b/genesis_spec/section_guides/Automaker_Section_06_Data_Models.md index 77bb0c53c..d16fa51f3 100644 --- a/genesis_spec/section_guides/Automaker_Section_06_Data_Models.md +++ b/genesis_spec/section_guides/Automaker_Section_06_Data_Models.md @@ -12,16 +12,16 @@ ```typescript interface AgentSession { - id: string; // Unique identifier (msg_timestamp_random) - name: string; // User-defined session name - projectPath?: string; // Associated project directory - workingDirectory: string; // Current working directory - createdAt: string; // ISO 8601 timestamp - updatedAt: string; // ISO 8601 timestamp - archived?: boolean; // Soft delete flag - tags?: string[]; // User-defined tags - model?: string; // AI model (e.g., "claude-sonnet-4-20250514") - sdkSessionId?: string; // Claude SDK session for continuity + id: string; // Unique identifier (msg_timestamp_random) + name: string; // User-defined session name + projectPath?: string; // Associated project directory + workingDirectory: string; // Current working directory + createdAt: string; // ISO 8601 timestamp + updatedAt: string; // ISO 8601 timestamp + archived?: boolean; // Soft delete flag + tags?: string[]; // User-defined tags + model?: string; // AI model (e.g., "claude-sonnet-4-20250514") + sdkSessionId?: string; // Claude SDK session for continuity } ``` @@ -29,16 +29,17 @@ interface AgentSession { ```typescript interface Message { - id: string; // Unique identifier - role: 'user' | 'assistant'; // Message sender - content: string; // Text content - images?: Array<{ // Optional image attachments - data: string; // Base64 encoded - mimeType: string; // e.g., "image/png" - filename: string; // Original filename + id: string; // Unique identifier + role: 'user' | 'assistant'; // Message sender + content: string; // Text content + images?: Array<{ + // Optional image attachments + data: string; // Base64 encoded + mimeType: string; // e.g., "image/png" + filename: string; // Original filename }>; - timestamp: string; // ISO 8601 timestamp - isError?: boolean; // Error message flag + timestamp: string; // ISO 8601 timestamp + isError?: boolean; // Error message flag } ``` @@ -46,16 +47,16 @@ interface Message { ```typescript interface Feature { - id: string; // Unique identifier - name: string; // Feature name - description: string; // Detailed description - status: FeatureStatus; // Current state - priority: number; // Execution order - dependencies: string[]; // Feature IDs this depends on - images?: FeatureImagePath[]; // Associated images + id: string; // Unique identifier + name: string; // Feature name + description: string; // Detailed description + status: FeatureStatus; // Current state + priority: number; // Execution order + dependencies: string[]; // Feature IDs this depends on + images?: FeatureImagePath[]; // Associated images textFiles?: FeatureTextFilePath[]; // Associated text files - createdAt?: string; // ISO 8601 timestamp - updatedAt?: string; // ISO 8601 timestamp + createdAt?: string; // ISO 8601 timestamp + updatedAt?: string; // ISO 8601 timestamp descriptionHistory?: DescriptionHistoryEntry[]; } @@ -74,17 +75,17 @@ type FeatureStatus = ```typescript interface GlobalSettings { - theme: ThemeMode; // 'light' | 'dark' | 'system' - defaultModel: string; // Default AI model - maxConcurrentAgents: number; // Parallel agent limit - telemetryEnabled: boolean; // Usage analytics - autoUpdate: boolean; // Auto-update setting + theme: ThemeMode; // 'light' | 'dark' | 'system' + defaultModel: string; // Default AI model + maxConcurrentAgents: number; // Parallel agent limit + telemetryEnabled: boolean; // Usage analytics + autoUpdate: boolean; // Auto-update setting serverLogLevel: ServerLogLevel; // 'error' | 'warn' | 'info' | 'debug' enableRequestLogging: boolean; // HTTP request logging keyboardShortcuts: KeyboardShortcuts; phaseModels: PhaseModelConfig; // Model per auto-mode phase boardBackground: BoardBackgroundSettings; - eventHooks: EventHook[]; // Custom event triggers + eventHooks: EventHook[]; // Custom event triggers mcpServers: Record; skillsEnabled: boolean; skillsSources: Array<'user' | 'project'>; @@ -93,27 +94,27 @@ interface GlobalSettings { } interface ProjectSettings { - name: string; // Project name - model?: string; // Override model - autoModeEnabled: boolean; // Enable auto-mode - planningMode: PlanningMode; // 'skip' | 'lite' | 'spec' | 'full' - autoLoadClaudeMd: boolean; // Load CLAUDE.md automatically + name: string; // Project name + model?: string; // Override model + autoModeEnabled: boolean; // Enable auto-mode + planningMode: PlanningMode; // 'skip' | 'lite' | 'spec' | 'full' + autoLoadClaudeMd: boolean; // Load CLAUDE.md automatically gitWorkflow: { - branchPrefix: string; // e.g., "feature/" - commitPrefix: string; // e.g., "feat:" - autoCommit: boolean; // Auto-commit on completion + branchPrefix: string; // e.g., "feature/" + commitPrefix: string; // e.g., "feat:" + autoCommit: boolean; // Auto-commit on completion }; hooks: { - preToolUse?: string[]; // Commands before tool use - postToolUse?: string[]; // Commands after tool use + preToolUse?: string[]; // Commands before tool use + postToolUse?: string[]; // Commands after tool use }; } interface Credentials { - anthropicApiKey?: string; // Encrypted API key - githubToken?: string; // GitHub access token - cursorSession?: string; // Cursor session token - codexApiKey?: string; // Codex API key + anthropicApiKey?: string; // Encrypted API key + githubToken?: string; // GitHub access token + cursorSession?: string; // Cursor session token + codexApiKey?: string; // Codex API key } ``` @@ -121,23 +122,23 @@ interface Credentials { ```typescript interface ProviderConfig { - model: string; // Model identifier - apiKey?: string; // API authentication - timeout?: number; // Request timeout (ms) + model: string; // Model identifier + apiKey?: string; // API authentication + timeout?: number; // Request timeout (ms) } interface ExecuteOptions { - prompt: string; // User prompt - model: string; // Bare model ID - originalModel: string; // Model with prefix - cwd: string; // Working directory - systemPrompt?: string; // System prompt - maxTurns?: number; // Max agentic turns - allowedTools?: string[]; // Permitted tools + prompt: string; // User prompt + model: string; // Bare model ID + originalModel: string; // Model with prefix + cwd: string; // Working directory + systemPrompt?: string; // System prompt + maxTurns?: number; // Max agentic turns + allowedTools?: string[]; // Permitted tools abortController: AbortController; conversationHistory?: ConversationMessage[]; settingSources?: Array<'user' | 'project'>; - sdkSessionId?: string; // Resume session + sdkSessionId?: string; // Resume session mcpServers?: Record; agents?: Record; thinkingLevel?: ThinkingLevel; // Claude thinking mode @@ -233,6 +234,7 @@ Automaker uses **file-based storage** (JSON) rather than a traditional database. ### File Schemas **sessions-metadata.json:** + ```json { "session_123": { @@ -249,6 +251,7 @@ Automaker uses **file-based storage** (JSON) rather than a traditional database. ``` **{sessionId}.json (Messages):** + ```json [ { @@ -273,6 +276,7 @@ Automaker uses **file-based storage** (JSON) rather than a traditional database. ### Request Schemas **Create Session:** + ```typescript interface CreateSessionParams { name: string; @@ -283,6 +287,7 @@ interface CreateSessionParams { ``` **Send Message:** + ```typescript interface SendMessageRequest { sessionId: string; @@ -296,6 +301,7 @@ interface SendMessageRequest { ``` **Run Feature:** + ```typescript interface RunFeatureRequest { featureId: string; @@ -308,6 +314,7 @@ interface RunFeatureRequest { ### Response Schemas **Session Response:** + ```typescript interface SessionResponse { success: boolean; @@ -317,6 +324,7 @@ interface SessionResponse { ``` **Agent Stream Event:** + ```typescript interface AgentStreamEvent { type: 'started' | 'stream' | 'tool_use' | 'complete' | 'error'; @@ -334,14 +342,14 @@ interface AgentStreamEvent { ### Environment Variables -| Variable | Type | Default | Description | -|----------|------|---------|-------------| -| PORT | number | 3008 | Server port | -| HOST | string | 0.0.0.0 | Server host | -| DATA_DIR | string | ./data | Data directory | -| ANTHROPIC_API_KEY | string | - | Claude API key | -| CORS_ORIGIN | string | - | Allowed origins | -| ENABLE_REQUEST_LOGGING | boolean | true | HTTP logging | +| Variable | Type | Default | Description | +| ---------------------- | ------- | ------- | --------------- | +| PORT | number | 3008 | Server port | +| HOST | string | 0.0.0.0 | Server host | +| DATA_DIR | string | ./data | Data directory | +| ANTHROPIC_API_KEY | string | - | Claude API key | +| CORS_ORIGIN | string | - | Allowed origins | +| ENABLE_REQUEST_LOGGING | boolean | true | HTTP logging | ### MCP Server Configuration diff --git a/genesis_spec/section_guides/Automaker_Section_07_Security_Compliance.md b/genesis_spec/section_guides/Automaker_Section_07_Security_Compliance.md index 35c530591..2987ad75f 100644 --- a/genesis_spec/section_guides/Automaker_Section_07_Security_Compliance.md +++ b/genesis_spec/section_guides/Automaker_Section_07_Security_Compliance.md @@ -46,25 +46,25 @@ ### STRIDE Analysis -| Threat | Category | Mitigation | -|--------|----------|------------| -| **Spoofing** | Identity | API key validation, session tokens | -| **Tampering** | Data | Input validation, secure file operations | -| **Repudiation** | Actions | Request logging, event history | -| **Information Disclosure** | Data | Encrypted credentials, path restrictions | -| **Denial of Service** | Availability | Rate limiting, input size limits | -| **Elevation of Privilege** | Authorization | Path validation, tool restrictions | +| Threat | Category | Mitigation | +| -------------------------- | ------------- | ---------------------------------------- | +| **Spoofing** | Identity | API key validation, session tokens | +| **Tampering** | Data | Input validation, secure file operations | +| **Repudiation** | Actions | Request logging, event history | +| **Information Disclosure** | Data | Encrypted credentials, path restrictions | +| **Denial of Service** | Availability | Rate limiting, input size limits | +| **Elevation of Privilege** | Authorization | Path validation, tool restrictions | ### Threat Scenarios -| ID | Threat | Impact | Likelihood | Mitigation | -|----|--------|--------|------------|------------| -| T-001 | API key exposure | Critical | Medium | Encrypted storage, env vars | -| T-002 | Path traversal | High | Medium | Allowlist validation | -| T-003 | Command injection | Critical | Low | No shell exec in user input | -| T-004 | CSRF attacks | Medium | Medium | JSON content-type required | -| T-005 | WebSocket hijacking | High | Low | Token authentication | -| T-006 | Terminal escape | High | Low | PTY isolation, password option | +| ID | Threat | Impact | Likelihood | Mitigation | +| ----- | ------------------- | -------- | ---------- | ------------------------------ | +| T-001 | API key exposure | Critical | Medium | Encrypted storage, env vars | +| T-002 | Path traversal | High | Medium | Allowlist validation | +| T-003 | Command injection | Critical | Low | No shell exec in user input | +| T-004 | CSRF attacks | Medium | Medium | JSON content-type required | +| T-005 | WebSocket hijacking | High | Low | Token authentication | +| T-006 | Terminal escape | High | Low | PTY isolation, password option | --- @@ -171,11 +171,7 @@ async function writeFile(path: string, content: string): Promise { ```typescript // Agent tools are explicitly allowlisted -const allowedTools = [ - 'Read', 'Write', 'Edit', - 'Glob', 'Grep', 'Bash', - 'WebSearch', 'WebFetch' -]; +const allowedTools = ['Read', 'Write', 'Edit', 'Glob', 'Grep', 'Bash', 'WebSearch', 'WebFetch']; // Additional tools require configuration if (skillsConfig.shouldIncludeInTools) { @@ -206,28 +202,28 @@ const key = await keytar.getPassword('automaker', 'anthropic-api-key'); interface EncryptedCredentials { version: number; data: string; // AES-256-GCM encrypted - iv: string; // Initialization vector - tag: string; // Auth tag + iv: string; // Initialization vector + tag: string; // Auth tag } ``` ### Data at Rest -| Data Type | Protection | -|-----------|------------| -| API Keys | System keychain / AES-256 encrypted file | -| Session Data | JSON files (user-accessible) | -| Settings | JSON files (user-accessible) | -| Logs | Plain text (user-accessible) | +| Data Type | Protection | +| ------------ | ---------------------------------------- | +| API Keys | System keychain / AES-256 encrypted file | +| Session Data | JSON files (user-accessible) | +| Settings | JSON files (user-accessible) | +| Logs | Plain text (user-accessible) | ### Data in Transit -| Connection | Protocol | Encryption | -|------------|----------|------------| -| API Calls | HTTPS | TLS 1.2+ | -| WebSocket | WSS | TLS 1.2+ | -| Local (Electron) | HTTP | N/A (localhost) | -| Docker Internal | HTTP | N/A (isolated network) | +| Connection | Protocol | Encryption | +| ---------------- | -------- | ---------------------- | +| API Calls | HTTPS | TLS 1.2+ | +| WebSocket | WSS | TLS 1.2+ | +| Local (Electron) | HTTP | N/A (localhost) | +| Docker Internal | HTTP | N/A (isolated network) | --- @@ -249,11 +245,11 @@ app.use( ```typescript interface StoredEvent { id: string; - type: string; // Event type (e.g., 'agent:tool_use') - timestamp: string; // ISO 8601 - sessionId?: string; // Associated session - payload: unknown; // Event data - source: string; // Origin (e.g., 'agent-service') + type: string; // Event type (e.g., 'agent:tool_use') + timestamp: string; // ISO 8601 + sessionId?: string; // Associated session + payload: unknown; // Event data + source: string; // Origin (e.g., 'agent-service') } // Events are persisted for replay and audit @@ -277,12 +273,12 @@ logger.error('Unhandled Promise Rejection:', reason); ### Current Compliance Status -| Standard | Status | Notes | -|----------|--------|-------| -| GDPR | Partial | User data stored locally | -| SOC 2 | N/A | Not applicable (local app) | -| HIPAA | N/A | Not applicable | -| PCI DSS | N/A | No payment processing | +| Standard | Status | Notes | +| -------- | ------- | -------------------------- | +| GDPR | Partial | User data stored locally | +| SOC 2 | N/A | Not applicable (local app) | +| HIPAA | N/A | Not applicable | +| PCI DSS | N/A | No payment processing | ### Privacy Considerations diff --git a/genesis_spec/section_guides/Automaker_Section_08_Testing_Strategy.md b/genesis_spec/section_guides/Automaker_Section_08_Testing_Strategy.md index 1258aa602..42274b92f 100644 --- a/genesis_spec/section_guides/Automaker_Section_08_Testing_Strategy.md +++ b/genesis_spec/section_guides/Automaker_Section_08_Testing_Strategy.md @@ -33,12 +33,12 @@ ## 8.2 Test Types -| Type | Coverage Target | Tools | Location | -|------|-----------------|-------|----------| -| Unit | 80%+ | Vitest | `apps/server/tests/unit/` | -| Integration | Key flows | Vitest | `apps/server/tests/` | -| E2E | Critical paths | Playwright | `e2e/` | -| Package | Shared libs | Vitest | `libs/*/tests/` | +| Type | Coverage Target | Tools | Location | +| ----------- | --------------- | ---------- | ------------------------- | +| Unit | 80%+ | Vitest | `apps/server/tests/unit/` | +| Integration | Key flows | Vitest | `apps/server/tests/` | +| E2E | Critical paths | Playwright | `e2e/` | +| Package | Shared libs | Vitest | `libs/*/tests/` | ### Unit Tests (Vitest) @@ -159,9 +159,9 @@ describe('AgentService', () => { }); it('should validate working directory path', async () => { - await expect( - agentService.createSession('Test', '/etc/passwd') - ).rejects.toThrow('Path not allowed'); + await expect(agentService.createSession('Test', '/etc/passwd')).rejects.toThrow( + 'Path not allowed' + ); }); }); }); @@ -279,11 +279,11 @@ AUTOMAKER_MOCK_AGENT=true npm run test ### Coverage Targets -| Area | Current | Target | -|------|---------|--------| -| Server Unit Tests | ~75% | 80% | -| Shared Packages | ~60% | 70% | -| E2E Critical Paths | ~50% | 80% | +| Area | Current | Target | +| ------------------ | ------- | ------ | +| Server Unit Tests | ~75% | 80% | +| Shared Packages | ~60% | 70% | +| E2E Critical Paths | ~50% | 80% | ### Coverage Reports @@ -308,12 +308,7 @@ export default defineConfig({ coverage: { provider: 'v8', reporter: ['text', 'lcov', 'html'], - exclude: [ - 'node_modules', - 'dist', - '**/*.test.ts', - '**/types/**', - ], + exclude: ['node_modules', 'dist', '**/*.test.ts', '**/types/**'], thresholds: { lines: 80, branches: 75, @@ -329,15 +324,15 @@ export default defineConfig({ ## 8.7 Test Commands Reference -| Command | Description | -|---------|-------------| -| `npm run test` | Run E2E tests (Playwright) | -| `npm run test:headed` | E2E with visible browser | -| `npm run test:server` | Server unit tests | +| Command | Description | +| ------------------------------ | -------------------------- | +| `npm run test` | Run E2E tests (Playwright) | +| `npm run test:headed` | E2E with visible browser | +| `npm run test:server` | Server unit tests | | `npm run test:server:coverage` | Server tests with coverage | -| `npm run test:packages` | Shared library tests | -| `npm run test:all` | All tests | -| `npm run test:watch` | Watch mode | +| `npm run test:packages` | Shared library tests | +| `npm run test:all` | All tests | +| `npm run test:watch` | Watch mode | --- diff --git a/genesis_spec/section_guides/Automaker_Section_09_Monitoring_Observability.md b/genesis_spec/section_guides/Automaker_Section_09_Monitoring_Observability.md index bbd143fe0..25bc513ad 100644 --- a/genesis_spec/section_guides/Automaker_Section_09_Monitoring_Observability.md +++ b/genesis_spec/section_guides/Automaker_Section_09_Monitoring_Observability.md @@ -35,12 +35,12 @@ ### Log Levels -| Level | Use Case | Example | -|-------|----------|---------| -| ERROR | System failures | `Failed to save session: ENOENT` | -| WARN | Recoverable issues | `No ANTHROPIC_API_KEY configured` | -| INFO | Normal operations | `Agent service initialized` | -| DEBUG | Detailed tracing | `Event received: { type, hasPayload }` | +| Level | Use Case | Example | +| ----- | ------------------ | -------------------------------------- | +| ERROR | System failures | `Failed to save session: ENOENT` | +| WARN | Recoverable issues | `No ANTHROPIC_API_KEY configured` | +| INFO | Normal operations | `Agent service initialized` | +| DEBUG | Detailed tracing | `Event received: { type, hasPayload }` | ### Logger Implementation @@ -74,21 +74,23 @@ morgan.token('status-colored', (_req, res) => { if (status >= 500) return `\x1b[31m${status}\x1b[0m`; // Red if (status >= 400) return `\x1b[33m${status}\x1b[0m`; // Yellow if (status >= 300) return `\x1b[36m${status}\x1b[0m`; // Cyan - return `\x1b[32m${status}\x1b[0m`; // Green + return `\x1b[32m${status}\x1b[0m`; // Green }); -app.use(morgan(':method :url :status-colored', { - skip: (req) => !requestLoggingEnabled || req.url === '/api/health', -})); +app.use( + morgan(':method :url :status-colored', { + skip: (req) => !requestLoggingEnabled || req.url === '/api/health', + }) +); ``` ### Log Output Locations -| Environment | Output | -|-------------|--------| -| Development | Console (stdout) | -| Docker | Container logs (stdout) | -| Electron | Console + file (~/.automaker/logs/) | +| Environment | Output | +| ----------- | ----------------------------------- | +| Development | Console (stdout) | +| Docker | Container logs (stdout) | +| Electron | Console + file (~/.automaker/logs/) | ### Structured Logging Format @@ -116,14 +118,14 @@ logger.info('Event received:', { ### Application Metrics -| Metric | Type | Description | -|--------|------|-------------| -| `agent_sessions_active` | Gauge | Currently active sessions | -| `agent_messages_total` | Counter | Total messages sent | -| `agent_errors_total` | Counter | Total agent errors | -| `terminal_sessions_active` | Gauge | Active terminal sessions | -| `websocket_connections` | Gauge | Connected WebSocket clients | -| `feature_completions` | Counter | Completed feature implementations | +| Metric | Type | Description | +| -------------------------- | ------- | --------------------------------- | +| `agent_sessions_active` | Gauge | Currently active sessions | +| `agent_messages_total` | Counter | Total messages sent | +| `agent_errors_total` | Counter | Total agent errors | +| `terminal_sessions_active` | Gauge | Active terminal sessions | +| `websocket_connections` | Gauge | Connected WebSocket clients | +| `feature_completions` | Counter | Completed feature implementations | ### Collection Points @@ -161,11 +163,11 @@ const codexUsageService = new CodexUsageService(codexAppServerService); ```typescript // Event History Service provides trace-like capability interface StoredEvent { - id: string; // Unique event ID - type: string; // Event type - timestamp: string; // ISO timestamp - sessionId?: string; // Correlation ID - payload: unknown; // Event data + id: string; // Unique event ID + type: string; // Event type + timestamp: string; // ISO timestamp + sessionId?: string; // Correlation ID + payload: unknown; // Event data } // All events stored for replay @@ -247,13 +249,13 @@ HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ ### Error Conditions -| Condition | Severity | Action | -|-----------|----------|--------| -| Uncaught Exception | Critical | Log + Exit | -| Unhandled Rejection | Warning | Log + Continue | -| WebSocket Disconnect | Info | Log + Cleanup | -| Auth Failure | Warning | Log + Reject | -| Path Traversal Attempt | Warning | Log + Reject | +| Condition | Severity | Action | +| ---------------------- | -------- | -------------- | +| Uncaught Exception | Critical | Log + Exit | +| Unhandled Rejection | Warning | Log + Continue | +| WebSocket Disconnect | Info | Log + Cleanup | +| Auth Failure | Warning | Log + Reject | +| Path Traversal Attempt | Warning | Log + Reject | ### Global Error Handlers @@ -301,9 +303,9 @@ process.on('uncaughtException', (error: Error) => { ```typescript // Runtime status (via API) -GET /api/running-agents // List active agents -GET /api/auto-mode/status // Auto-mode status -GET /api/terminal/sessions // Terminal status +GET / api / running - agents; // List active agents +GET / api / auto - mode / status; // Auto-mode status +GET / api / terminal / sessions; // Terminal status ``` --- diff --git a/genesis_spec/section_guides/Automaker_Section_10_Deployment_Operations.md b/genesis_spec/section_guides/Automaker_Section_10_Deployment_Operations.md index b7ab599a8..79d3100bf 100644 --- a/genesis_spec/section_guides/Automaker_Section_10_Deployment_Operations.md +++ b/genesis_spec/section_guides/Automaker_Section_10_Deployment_Operations.md @@ -10,13 +10,13 @@ ### Build Commands -| Command | Description | -|---------|-------------| -| `npm run build` | Build all packages and apps | -| `npm run build:packages` | Build shared libraries only | -| `npm run build --workspace=apps/server` | Build server only | -| `npm run build --workspace=apps/ui` | Build UI only | -| `npm run build:electron` | Build desktop app | +| Command | Description | +| --------------------------------------- | --------------------------- | +| `npm run build` | Build all packages and apps | +| `npm run build:packages` | Build shared libraries only | +| `npm run build --workspace=apps/server` | Build server only | +| `npm run build --workspace=apps/ui` | Build UI only | +| `npm run build:electron` | Build desktop app | ### Build Process Flow @@ -120,15 +120,15 @@ npm run build:electron:linux # Linux AppImage ### Environment Variables -| Variable | Default | Description | -|----------|---------|-------------| -| `PORT` | 3008 | Server HTTP port | -| `HOST` | 0.0.0.0 | Server bind address | -| `HOSTNAME` | localhost | Display hostname | -| `DATA_DIR` | ./data | Data storage directory | -| `ANTHROPIC_API_KEY` | - | Claude API authentication | -| `CORS_ORIGIN` | - | Allowed CORS origins | -| `ENABLE_REQUEST_LOGGING` | true | HTTP request logging | +| Variable | Default | Description | +| ------------------------ | --------- | ------------------------- | +| `PORT` | 3008 | Server HTTP port | +| `HOST` | 0.0.0.0 | Server bind address | +| `HOSTNAME` | localhost | Display hostname | +| `DATA_DIR` | ./data | Data storage directory | +| `ANTHROPIC_API_KEY` | - | Claude API authentication | +| `CORS_ORIGIN` | - | Allowed CORS origins | +| `ENABLE_REQUEST_LOGGING` | true | HTTP request logging | ### Docker Environment @@ -146,7 +146,7 @@ services: - automaker-data:/data - ./projects:/projects ports: - - "3008:3008" + - '3008:3008' ``` --- @@ -156,28 +156,28 @@ services: ### System Requirements | Component | Minimum | Recommended | -|-----------|---------|-------------| -| CPU | 2 cores | 4+ cores | -| RAM | 4 GB | 8+ GB | -| Disk | 2 GB | 10+ GB | -| Node.js | 22.0.0 | 22.x LTS | +| --------- | ------- | ----------- | +| CPU | 2 cores | 4+ cores | +| RAM | 4 GB | 8+ GB | +| Disk | 2 GB | 10+ GB | +| Node.js | 22.0.0 | 22.x LTS | ### Required Software -| Software | Purpose | -|----------|---------| -| Node.js 22+ | Runtime | -| Git | Version control | -| npm | Package management | +| Software | Purpose | +| ----------- | ------------------ | +| Node.js 22+ | Runtime | +| Git | Version control | +| npm | Package management | ### Optional Software -| Software | Purpose | -|----------|---------| -| Docker | Containerized deployment | -| Claude CLI | Claude agent access | -| Cursor CLI | Cursor model access | -| GitHub CLI | Git operations | +| Software | Purpose | +| ---------- | ------------------------ | +| Docker | Containerized deployment | +| Claude CLI | Claude agent access | +| Cursor CLI | Cursor model access | +| GitHub CLI | Git operations | --- @@ -275,13 +275,13 @@ cp -r ~/automaker-backup-20260120 ~/.automaker ### Common Issues -| Issue | Cause | Solution | -|-------|-------|----------| -| Port already in use | Previous process | `lsof -ti:3008 \| xargs kill -9` | -| WebSocket disconnects | Timeout | Check firewall settings | -| Agent won't start | Missing API key | Set ANTHROPIC_API_KEY | -| Terminal not working | node-pty issue | `npm rebuild node-pty` | -| Session not persisting | Write permissions | Check DATA_DIR permissions | +| Issue | Cause | Solution | +| ---------------------- | ----------------- | -------------------------------- | +| Port already in use | Previous process | `lsof -ti:3008 \| xargs kill -9` | +| WebSocket disconnects | Timeout | Check firewall settings | +| Agent won't start | Missing API key | Set ANTHROPIC_API_KEY | +| Terminal not working | node-pty issue | `npm rebuild node-pty` | +| Session not persisting | Write permissions | Check DATA_DIR permissions | ### Debug Mode @@ -298,11 +298,11 @@ DEBUG=automaker:* npm run dev ### Log Locations -| Location | Content | -|----------|---------| -| Console (stdout) | Server logs | -| ~/.automaker/logs/ | Persistent logs (Electron) | -| Docker logs | `docker logs automaker-server` | +| Location | Content | +| ------------------ | ------------------------------ | +| Console (stdout) | Server logs | +| ~/.automaker/logs/ | Persistent logs (Electron) | +| Docker logs | `docker logs automaker-server` | ### Port Conflict Resolution @@ -324,17 +324,18 @@ PORT=3009 npm run dev ### Horizontal Scaling Not currently supported - single-instance architecture. Future considerations: + - Session state externalization (Redis) - Load balancer for UI - Separate agent worker processes ### Vertical Scaling -| Resource | Impact | -|----------|--------| -| More CPU | Faster builds, more concurrent terminals | +| Resource | Impact | +| -------- | ----------------------------------------- | +| More CPU | Faster builds, more concurrent terminals | | More RAM | More concurrent sessions, larger contexts | -| SSD | Faster file operations, session loading | +| SSD | Faster file operations, session loading | ### Performance Tuning diff --git a/genesis_spec/section_guides/Automaker_Section_11_Documentation.md b/genesis_spec/section_guides/Automaker_Section_11_Documentation.md index 36926658d..58d9b2d17 100644 --- a/genesis_spec/section_guides/Automaker_Section_11_Documentation.md +++ b/genesis_spec/section_guides/Automaker_Section_11_Documentation.md @@ -33,15 +33,15 @@ automaker/ ### Documentation Types -| Type | Location | Purpose | Audience | -|------|----------|---------|----------| -| README | Root | Quick start, overview | New users | -| CONTRIBUTING | Root | How to contribute | Contributors | -| ARCHITECTURE | Root | Technical overview | Developers | -| CLAUDE.md | Root | AI agent instructions | AI agents | -| Genesis Spec | genesis_spec/ | Comprehensive reference | All | -| API Docs | Inline | Endpoint documentation | Integrators | -| Code Comments | Source | Implementation details | Maintainers | +| Type | Location | Purpose | Audience | +| ------------- | ------------- | ----------------------- | ------------ | +| README | Root | Quick start, overview | New users | +| CONTRIBUTING | Root | How to contribute | Contributors | +| ARCHITECTURE | Root | Technical overview | Developers | +| CLAUDE.md | Root | AI agent instructions | AI agents | +| Genesis Spec | genesis_spec/ | Comprehensive reference | All | +| API Docs | Inline | Endpoint documentation | Integrators | +| Code Comments | Source | Implementation details | Maintainers | --- @@ -166,17 +166,21 @@ Location: Inline in ARCHITECTURE.md or separate `docs/adrs/` # ADR-001: Monorepo Structure ## Status + Accepted ## Context + Need to share TypeScript types and utilities between frontend and backend. ## Decision + Use npm workspaces with `libs/` directory for shared packages. ## Consequences + - Single repository for all code -- Shared TypeScript types via @automaker/* +- Shared TypeScript types via @automaker/\* - Atomic commits across packages - Build order dependency management required ``` @@ -184,6 +188,7 @@ Use npm workspaces with `libs/` directory for shared packages. ### Component Documentation Each major component should document: + - Purpose and responsibility - Dependencies (internal and external) - Configuration options @@ -200,17 +205,20 @@ Each major component should document: # Getting Started with Automaker ## Prerequisites + - Node.js 22+ - Git - Anthropic API key ## Installation + 1. Clone the repository 2. Run `npm install` 3. Set `ANTHROPIC_API_KEY` environment variable 4. Run `npm run dev` ## First Session + 1. Click "New Session" 2. Enter a name for your session 3. Type a message to the AI agent @@ -231,13 +239,13 @@ Each major component should document: ### Document Updates Required -| Change Type | Documentation Required | -|-------------|----------------------| -| New feature | README, user guide, API docs | -| API change | API reference, CHANGELOG | -| Bug fix | CHANGELOG | -| Refactoring | ARCHITECTURE (if significant) | -| Configuration | Settings documentation | +| Change Type | Documentation Required | +| ------------- | ----------------------------- | +| New feature | README, user guide, API docs | +| API change | API reference, CHANGELOG | +| Bug fix | CHANGELOG | +| Refactoring | ARCHITECTURE (if significant) | +| Configuration | Settings documentation | ### Documentation Review Checklist @@ -261,26 +269,33 @@ All notable changes to this project will be documented in this file. ## [Unreleased] ### Added + - New feature description ### Changed + - Changed behavior description ### Deprecated + - Soon-to-be removed features ### Removed + - Removed features ### Fixed + - Bug fix description ### Security + - Security fix description ## [0.12.0] - 2026-01-15 ### Added + - Multi-provider support (Codex, Cursor, OpenCode) - Event hook system for custom automation ``` diff --git a/genesis_spec/section_guides/Automaker_Section_12_Reference_Collections.md b/genesis_spec/section_guides/Automaker_Section_12_Reference_Collections.md index ff1738357..bcd71e042 100644 --- a/genesis_spec/section_guides/Automaker_Section_12_Reference_Collections.md +++ b/genesis_spec/section_guides/Automaker_Section_12_Reference_Collections.md @@ -10,22 +10,22 @@ ### Project Links -| Resource | URL | -|----------|-----| -| GitHub Repository | https://github.com/AutoMaker-Org/automaker | -| Issue Tracker | https://github.com/AutoMaker-Org/automaker/issues | -| Pull Requests | https://github.com/AutoMaker-Org/automaker/pulls | -| Discord Community | https://discord.gg/jjem7aEDKU | +| Resource | URL | +| ----------------- | ------------------------------------------------- | +| GitHub Repository | https://github.com/AutoMaker-Org/automaker | +| Issue Tracker | https://github.com/AutoMaker-Org/automaker/issues | +| Pull Requests | https://github.com/AutoMaker-Org/automaker/pulls | +| Discord Community | https://discord.gg/jjem7aEDKU | ### Documentation -| Document | Location | -|----------|----------| -| README | `/README.md` | +| Document | Location | +| ------------------ | ------------------ | +| README | `/README.md` | | Contributing Guide | `/CONTRIBUTING.md` | -| Architecture | `/ARCHITECTURE.md` | -| Claude Context | `/CLAUDE.md` | -| License | `/LICENSE` | +| Architecture | `/ARCHITECTURE.md` | +| Claude Context | `/CLAUDE.md` | +| License | `/LICENSE` | --- @@ -33,49 +33,49 @@ ### Core Technologies -| Technology | Documentation | -|------------|--------------| +| Technology | Documentation | +| ---------- | ------------------------------------ | | TypeScript | https://www.typescriptlang.org/docs/ | -| Node.js | https://nodejs.org/docs/ | -| React | https://react.dev/ | -| Express | https://expressjs.com/ | -| Electron | https://www.electronjs.org/docs | -| Vite | https://vitejs.dev/ | +| Node.js | https://nodejs.org/docs/ | +| React | https://react.dev/ | +| Express | https://expressjs.com/ | +| Electron | https://www.electronjs.org/docs | +| Vite | https://vitejs.dev/ | ### AI SDKs -| SDK | Documentation | -|-----|--------------| +| SDK | Documentation | +| ---------------- | -------------------------------------- | | Claude Agent SDK | https://docs.anthropic.com/claude/docs | -| MCP Protocol | https://modelcontextprotocol.io/ | -| Codex SDK | https://platform.openai.com/docs | +| MCP Protocol | https://modelcontextprotocol.io/ | +| Codex SDK | https://platform.openai.com/docs | ### Frontend Libraries -| Library | Documentation | -|---------|--------------| -| TanStack Router | https://tanstack.com/router | -| TanStack Query | https://tanstack.com/query | -| Zustand | https://zustand-demo.pmnd.rs/ | -| Radix UI | https://www.radix-ui.com/docs | -| Tailwind CSS | https://tailwindcss.com/docs | -| xterm.js | https://xtermjs.org/ | -| CodeMirror | https://codemirror.net/docs/ | +| Library | Documentation | +| --------------- | ----------------------------- | +| TanStack Router | https://tanstack.com/router | +| TanStack Query | https://tanstack.com/query | +| Zustand | https://zustand-demo.pmnd.rs/ | +| Radix UI | https://www.radix-ui.com/docs | +| Tailwind CSS | https://tailwindcss.com/docs | +| xterm.js | https://xtermjs.org/ | +| CodeMirror | https://codemirror.net/docs/ | ### Backend Libraries -| Library | Documentation | -|---------|--------------| -| Express 5 | https://expressjs.com/en/5x/api.html | -| ws (WebSocket) | https://github.com/websockets/ws | -| node-pty | https://github.com/microsoft/node-pty | -| Morgan | https://github.com/expressjs/morgan | +| Library | Documentation | +| -------------- | ------------------------------------- | +| Express 5 | https://expressjs.com/en/5x/api.html | +| ws (WebSocket) | https://github.com/websockets/ws | +| node-pty | https://github.com/microsoft/node-pty | +| Morgan | https://github.com/expressjs/morgan | ### Testing Tools -| Tool | Documentation | -|------|--------------| -| Vitest | https://vitest.dev/ | +| Tool | Documentation | +| ---------- | ----------------------- | +| Vitest | https://vitest.dev/ | | Playwright | https://playwright.dev/ | --- @@ -84,19 +84,19 @@ ### Dependencies -| Project | Purpose | Repository | -|---------|---------|------------| +| Project | Purpose | Repository | +| ----------- | --------------- | ----------------------------------------- | | Claude Code | Claude CLI tool | https://github.com/anthropics/claude-code | -| Cursor | AI-powered IDE | https://cursor.com/ | -| GitHub CLI | Git operations | https://cli.github.com/ | +| Cursor | AI-powered IDE | https://cursor.com/ | +| GitHub CLI | Git operations | https://cli.github.com/ | ### Inspiration -| Project | Relevance | -|---------|-----------| -| Devin | Autonomous AI developer concept | -| Aider | AI pair programming | -| Continue | IDE AI integration | +| Project | Relevance | +| -------- | ------------------------------- | +| Devin | Autonomous AI developer concept | +| Aider | AI pair programming | +| Continue | IDE AI integration | --- @@ -104,20 +104,20 @@ ### Design Patterns Used -| Pattern | Reference | -|---------|-----------| -| Factory Pattern | https://refactoring.guru/design-patterns/factory-method | -| Service Layer | https://martinfowler.com/eaaCatalog/serviceLayer.html | -| Event-Driven | https://martinfowler.com/articles/201701-event-driven.html | -| Repository Pattern | https://martinfowler.com/eaaCatalog/repository.html | +| Pattern | Reference | +| ------------------ | ---------------------------------------------------------- | +| Factory Pattern | https://refactoring.guru/design-patterns/factory-method | +| Service Layer | https://martinfowler.com/eaaCatalog/serviceLayer.html | +| Event-Driven | https://martinfowler.com/articles/201701-event-driven.html | +| Repository Pattern | https://martinfowler.com/eaaCatalog/repository.html | ### Architecture Styles -| Style | Reference | -|-------|-----------| -| Monorepo | https://monorepo.tools/ | +| Style | Reference | +| -------------------- | ---------------------------------------------------------------------------------- | +| Monorepo | https://monorepo.tools/ | | Layered Architecture | https://www.oreilly.com/library/view/software-architecture-patterns/9781491971437/ | -| Event Sourcing | https://martinfowler.com/eaaDev/EventSourcing.html | +| Event Sourcing | https://martinfowler.com/eaaDev/EventSourcing.html | --- @@ -125,18 +125,18 @@ ### Security Guidelines -| Topic | Reference | -|-------|-----------| -| OWASP Top 10 | https://owasp.org/www-project-top-ten/ | -| Node.js Security | https://nodejs.org/en/docs/guides/security/ | +| Topic | Reference | +| ----------------- | ------------------------------------------------- | +| OWASP Top 10 | https://owasp.org/www-project-top-ten/ | +| Node.js Security | https://nodejs.org/en/docs/guides/security/ | | Electron Security | https://www.electronjs.org/docs/tutorial/security | ### Authentication -| Topic | Reference | -|-------|-----------| -| API Key Best Practices | https://cloud.google.com/docs/authentication/api-keys | -| Keytar (System Keychain) | https://github.com/atom/node-keytar | +| Topic | Reference | +| ------------------------ | ----------------------------------------------------- | +| API Key Best Practices | https://cloud.google.com/docs/authentication/api-keys | +| Keytar (System Keychain) | https://github.com/atom/node-keytar | --- @@ -144,28 +144,28 @@ ### IDE Support -| IDE | Extension | -|-----|-----------| -| VS Code | ESLint, Prettier, TypeScript | -| WebStorm | Built-in TypeScript support | -| Cursor | AI-powered editing | +| IDE | Extension | +| -------- | ---------------------------- | +| VS Code | ESLint, Prettier, TypeScript | +| WebStorm | Built-in TypeScript support | +| Cursor | AI-powered editing | ### CLI Tools -| Tool | Purpose | -|------|---------| -| npm | Package management | -| tsx | TypeScript execution | -| electron-builder | Desktop packaging | -| gh | GitHub operations | +| Tool | Purpose | +| ---------------- | -------------------- | +| npm | Package management | +| tsx | TypeScript execution | +| electron-builder | Desktop packaging | +| gh | GitHub operations | ### Debugging -| Tool | Purpose | -|------|---------| -| Chrome DevTools | Frontend debugging | -| Node.js Inspector | Backend debugging | -| React DevTools | Component inspection | +| Tool | Purpose | +| ----------------- | -------------------- | +| Chrome DevTools | Frontend debugging | +| Node.js Inspector | Backend debugging | +| React DevTools | Component inspection | --- @@ -173,19 +173,19 @@ ### Support Channels -| Channel | URL | -|---------|-----| -| Discord | https://discord.gg/jjem7aEDKU | +| Channel | URL | +| ------------------ | ------------------------------------------------------ | +| Discord | https://discord.gg/jjem7aEDKU | | GitHub Discussions | https://github.com/AutoMaker-Org/automaker/discussions | -| Issues | https://github.com/AutoMaker-Org/automaker/issues | +| Issues | https://github.com/AutoMaker-Org/automaker/issues | ### Learning Resources -| Resource | Topic | -|----------|-------| -| React Documentation | Frontend development | -| Express Guide | Backend API development | -| Electron Tutorial | Desktop app development | +| Resource | Topic | +| ------------------- | ----------------------- | +| React Documentation | Frontend development | +| Express Guide | Backend API development | +| Electron Tutorial | Desktop app development | --- @@ -252,18 +252,18 @@ curl http://localhost:3008/api/health ## 12.9 Glossary -| Term | Definition | -|------|------------| -| **Agent** | AI-powered assistant that executes tasks autonomously | -| **Auto-Mode** | Autonomous feature development workflow | -| **Feature** | Unit of work to be implemented by agents | -| **MCP** | Model Context Protocol - standard for AI tool integration | -| **Planning Mode** | Strategy for feature planning (skip, lite, spec, full) | -| **Provider** | AI model backend (Claude, Codex, Cursor) | -| **Session** | Persistent conversation context with an agent | -| **Worktree** | Git worktree for isolated feature development | -| **PTY** | Pseudo-terminal for shell emulation | -| **WebSocket** | Bidirectional communication protocol for real-time updates | +| Term | Definition | +| ----------------- | ---------------------------------------------------------- | +| **Agent** | AI-powered assistant that executes tasks autonomously | +| **Auto-Mode** | Autonomous feature development workflow | +| **Feature** | Unit of work to be implemented by agents | +| **MCP** | Model Context Protocol - standard for AI tool integration | +| **Planning Mode** | Strategy for feature planning (skip, lite, spec, full) | +| **Provider** | AI model backend (Claude, Codex, Cursor) | +| **Session** | Persistent conversation context with an agent | +| **Worktree** | Git worktree for isolated feature development | +| **PTY** | Pseudo-terminal for shell emulation | +| **WebSocket** | Bidirectional communication protocol for real-time updates | --- From 9cf23a1badff914e752e32cfa9950df983be1638 Mon Sep 17 00:00:00 2001 From: Justus Date: Wed, 21 Jan 2026 18:38:46 +0100 Subject: [PATCH 10/13] fix(server): fallback to openai for title generation if anthropic key missing --- .../src/routes/features/routes/generate-title.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/apps/server/src/routes/features/routes/generate-title.ts b/apps/server/src/routes/features/routes/generate-title.ts index e7603eb8e..6b0a1a00c 100644 --- a/apps/server/src/routes/features/routes/generate-title.ts +++ b/apps/server/src/routes/features/routes/generate-title.ts @@ -60,12 +60,23 @@ export function createGenerateTitleHandler( const prompts = await getPromptCustomization(settingsService, '[GenerateTitle]'); const systemPrompt = prompts.titleGeneration.systemPrompt; + let model = CLAUDE_MODEL_MAP.haiku; + + // Fallback to OpenAI if Anthropic key is missing but OpenAI key is present + if (!process.env.ANTHROPIC_API_KEY && process.env.OPENAI_API_KEY) { + // Use gpt-4o which is comparable/better than haiku + model = 'codex-gpt-4o'; + logger.info( + 'Using OpenAI (codex-gpt-4o) for title generation due to missing Anthropic key' + ); + } + const userPrompt = `Generate a concise title for this feature:\n\n${trimmedDescription}`; // Use simpleQuery - provider abstraction handles all the streaming/extraction const result = await simpleQuery({ prompt: `${systemPrompt}\n\n${userPrompt}`, - model: CLAUDE_MODEL_MAP.haiku, + model, cwd: process.cwd(), maxTurns: 1, allowedTools: [], From 9de310b4b428abf0e3aa6f00d04eb0fbedfefc9b Mon Sep 17 00:00:00 2001 From: Justus Date: Wed, 21 Jan 2026 18:41:29 +0100 Subject: [PATCH 11/13] fix(server): implement system-wide openai fallback for missing anthropic key --- apps/server/src/lib/sdk-options.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/apps/server/src/lib/sdk-options.ts b/apps/server/src/lib/sdk-options.ts index cc1df2f57..6a57efedd 100644 --- a/apps/server/src/lib/sdk-options.ts +++ b/apps/server/src/lib/sdk-options.ts @@ -215,6 +215,19 @@ export function getModelForUseCase( default: CLAUDE_MODEL_MAP['opus'], }; + // Fallback to OpenAI if Anthropic key is missing but OpenAI key is present + if (!process.env.ANTHROPIC_API_KEY && process.env.OPENAI_API_KEY) { + // Override defaults with OpenAI equivalents + defaultModels.spec = 'codex-gpt-4o'; + defaultModels.features = 'codex-gpt-4o'; + defaultModels.suggestions = 'codex-gpt-4o'; + defaultModels.chat = 'codex-gpt-4o'; + defaultModels.auto = 'codex-gpt-4o'; + defaultModels.default = 'codex-gpt-4o'; + + logger.info(`Using OpenAI (codex-gpt-4o) for ${useCase} due to missing Anthropic key`); + } + return resolveModelString(defaultModels[useCase] || DEFAULT_MODELS.claude); } From bc64683ec6be3abf9f1bccbb6bfd3349ca27cdf2 Mon Sep 17 00:00:00 2001 From: Justus Date: Wed, 21 Jan 2026 19:10:49 +0100 Subject: [PATCH 12/13] fix(server): provide fallback codex models if cli missing but api key present --- .../src/services/codex-model-cache-service.ts | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/apps/server/src/services/codex-model-cache-service.ts b/apps/server/src/services/codex-model-cache-service.ts index 7e171428c..d38cb95d6 100644 --- a/apps/server/src/services/codex-model-cache-service.ts +++ b/apps/server/src/services/codex-model-cache-service.ts @@ -149,6 +149,37 @@ export class CodexModelCacheService { try { // Check if app-server is available const isAvailable = await this.appServerService.isAvailable(); + + // FALLBACK: If CLI is not available but we have an OpenAI API Key (e.g. in CI or limited env), + // provide default models so the UI doesn't block. + if (!isAvailable && process.env.OPENAI_API_KEY) { + logger.info('[doRefresh] CLI unavailable but OPENAI_API_KEY found. Using fallback models.'); + const fallbackModels: CodexModel[] = [ + { + id: 'codex-gpt-4o', + label: 'GPT-4o (Fallback)', + description: 'Fallback model using direct OpenAI API', + hasThinking: false, + supportsVision: true, + tier: 'premium', + isDefault: true, + }, + { + id: 'codex-gpt-4o-mini', + label: 'GPT-4o Mini (Fallback)', + description: 'Fast fallback model using direct OpenAI API', + hasThinking: false, + supportsVision: true, + tier: 'basic', + isDefault: false, + }, + ]; + + // Save to cache so subsequent requests are fast + await this.saveToCache(fallbackModels); + return fallbackModels; + } + if (!isAvailable) { return []; } From 51209deb3644372862ed8e7d5d797191844c5ff4 Mon Sep 17 00:00:00 2001 From: Justus Date: Wed, 21 Jan 2026 19:23:57 +0100 Subject: [PATCH 13/13] fix(e2e): navigate via title instead of unstable id in project switcher --- apps/ui/tests/projects/new-project-creation.spec.ts | 4 ++-- apps/ui/tests/projects/open-existing-project.spec.ts | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/ui/tests/projects/new-project-creation.spec.ts b/apps/ui/tests/projects/new-project-creation.spec.ts index 9d2f3362c..cb0e38d46 100644 --- a/apps/ui/tests/projects/new-project-creation.spec.ts +++ b/apps/ui/tests/projects/new-project-creation.spec.ts @@ -77,8 +77,8 @@ test.describe('Project Creation', () => { } // Wait for project to be set as current and visible on the page - // The project name appears in the project switcher button - await expect(page.getByTestId(`project-switcher-project-${projectName}`)).toBeVisible({ + // The project name appears in the project switcher button (title attribute) + await expect(page.getByTitle(projectName)).toBeVisible({ timeout: 15000, }); diff --git a/apps/ui/tests/projects/open-existing-project.spec.ts b/apps/ui/tests/projects/open-existing-project.spec.ts index 3f4a8a367..22c686047 100644 --- a/apps/ui/tests/projects/open-existing-project.spec.ts +++ b/apps/ui/tests/projects/open-existing-project.spec.ts @@ -157,8 +157,10 @@ test.describe('Open Project', () => { // Wait for a project to be set as current and visible on the page // The project name appears in the project switcher button + // Wait for a project to be set as current and visible on the page + // The project name appears in the project switcher button (title attribute) if (targetProjectName) { - await expect(page.getByTestId(`project-switcher-project-${targetProjectName}`)).toBeVisible({ + await expect(page.getByTitle(targetProjectName)).toBeVisible({ timeout: 15000, }); }