From 5058c409d518a56398834e8bc2cc6c87084529f9 Mon Sep 17 00:00:00 2001 From: Prateek Date: Fri, 13 Feb 2026 17:02:42 +0530 Subject: [PATCH] feat: scaffold TypeScript monorepo with all plugin interfaces Phase 0 complete. Establishes: - pnpm workspace with 18 packages (core, cli, web, 15 plugins) - Complete type definitions in packages/core/src/types.ts defining all 8 plugin slot interfaces (Runtime, Agent, Workspace, Tracker, SCM, Notifier, Terminal) + core service interfaces - YAML config loader with Zod validation and sensible defaults - Plugin registry with built-in discovery - CLAUDE.md with conventions for spawned agents All agents can now branch from main and implement their assigned packages against the interfaces defined in types.ts. Co-Authored-By: Claude Opus 4.6 --- .gitignore | 6 + CLAUDE.md | 132 ++ agent-orchestrator.yaml.example | 86 ++ package.json | 18 + packages/cli/package.json | 27 + packages/cli/src/index.ts | 2 + packages/cli/tsconfig.json | 8 + packages/core/package.json | 31 + packages/core/src/config.ts | 283 ++++ packages/core/src/index.ts | 15 + packages/core/src/plugin-registry.ts | 98 ++ packages/core/src/types.ts | 842 +++++++++++ packages/core/tsconfig.json | 8 + packages/plugins/agent-aider/package.json | 26 + packages/plugins/agent-aider/src/index.ts | 1 + packages/plugins/agent-aider/tsconfig.json | 8 + .../plugins/agent-claude-code/package.json | 26 + .../plugins/agent-claude-code/src/index.ts | 1 + .../plugins/agent-claude-code/tsconfig.json | 8 + packages/plugins/agent-codex/package.json | 26 + packages/plugins/agent-codex/src/index.ts | 1 + packages/plugins/agent-codex/tsconfig.json | 8 + .../plugins/notifier-desktop/package.json | 26 + .../plugins/notifier-desktop/src/index.ts | 1 + .../plugins/notifier-desktop/tsconfig.json | 8 + packages/plugins/notifier-slack/package.json | 26 + packages/plugins/notifier-slack/src/index.ts | 1 + packages/plugins/notifier-slack/tsconfig.json | 8 + .../plugins/notifier-webhook/package.json | 26 + .../plugins/notifier-webhook/src/index.ts | 1 + .../plugins/notifier-webhook/tsconfig.json | 8 + packages/plugins/runtime-process/package.json | 26 + packages/plugins/runtime-process/src/index.ts | 1 + .../plugins/runtime-process/tsconfig.json | 8 + packages/plugins/runtime-tmux/package.json | 26 + packages/plugins/runtime-tmux/src/index.ts | 1 + packages/plugins/runtime-tmux/tsconfig.json | 8 + packages/plugins/scm-github/package.json | 26 + packages/plugins/scm-github/src/index.ts | 1 + packages/plugins/scm-github/tsconfig.json | 8 + packages/plugins/terminal-iterm2/package.json | 26 + packages/plugins/terminal-iterm2/src/index.ts | 1 + .../plugins/terminal-iterm2/tsconfig.json | 8 + packages/plugins/terminal-web/package.json | 26 + packages/plugins/terminal-web/src/index.ts | 1 + packages/plugins/terminal-web/tsconfig.json | 8 + packages/plugins/tracker-github/package.json | 26 + packages/plugins/tracker-github/src/index.ts | 1 + packages/plugins/tracker-github/tsconfig.json | 8 + packages/plugins/tracker-linear/package.json | 26 + packages/plugins/tracker-linear/src/index.ts | 1 + packages/plugins/tracker-linear/tsconfig.json | 8 + packages/plugins/workspace-clone/package.json | 26 + packages/plugins/workspace-clone/src/index.ts | 1 + .../plugins/workspace-clone/tsconfig.json | 8 + .../plugins/workspace-worktree/package.json | 26 + .../plugins/workspace-worktree/src/index.ts | 1 + .../plugins/workspace-worktree/tsconfig.json | 8 + packages/web/package.json | 26 + packages/web/src/app/layout.tsx | 8 + packages/web/src/app/page.tsx | 4 + packages/web/tsconfig.json | 16 + pnpm-lock.yaml | 1276 +++++++++++++++++ pnpm-workspace.yaml | 3 + tsconfig.base.json | 20 + 65 files changed, 3434 insertions(+) create mode 100644 .gitignore create mode 100644 CLAUDE.md create mode 100644 agent-orchestrator.yaml.example create mode 100644 package.json create mode 100644 packages/cli/package.json create mode 100644 packages/cli/src/index.ts create mode 100644 packages/cli/tsconfig.json create mode 100644 packages/core/package.json create mode 100644 packages/core/src/config.ts create mode 100644 packages/core/src/index.ts create mode 100644 packages/core/src/plugin-registry.ts create mode 100644 packages/core/src/types.ts create mode 100644 packages/core/tsconfig.json create mode 100644 packages/plugins/agent-aider/package.json create mode 100644 packages/plugins/agent-aider/src/index.ts create mode 100644 packages/plugins/agent-aider/tsconfig.json create mode 100644 packages/plugins/agent-claude-code/package.json create mode 100644 packages/plugins/agent-claude-code/src/index.ts create mode 100644 packages/plugins/agent-claude-code/tsconfig.json create mode 100644 packages/plugins/agent-codex/package.json create mode 100644 packages/plugins/agent-codex/src/index.ts create mode 100644 packages/plugins/agent-codex/tsconfig.json create mode 100644 packages/plugins/notifier-desktop/package.json create mode 100644 packages/plugins/notifier-desktop/src/index.ts create mode 100644 packages/plugins/notifier-desktop/tsconfig.json create mode 100644 packages/plugins/notifier-slack/package.json create mode 100644 packages/plugins/notifier-slack/src/index.ts create mode 100644 packages/plugins/notifier-slack/tsconfig.json create mode 100644 packages/plugins/notifier-webhook/package.json create mode 100644 packages/plugins/notifier-webhook/src/index.ts create mode 100644 packages/plugins/notifier-webhook/tsconfig.json create mode 100644 packages/plugins/runtime-process/package.json create mode 100644 packages/plugins/runtime-process/src/index.ts create mode 100644 packages/plugins/runtime-process/tsconfig.json create mode 100644 packages/plugins/runtime-tmux/package.json create mode 100644 packages/plugins/runtime-tmux/src/index.ts create mode 100644 packages/plugins/runtime-tmux/tsconfig.json create mode 100644 packages/plugins/scm-github/package.json create mode 100644 packages/plugins/scm-github/src/index.ts create mode 100644 packages/plugins/scm-github/tsconfig.json create mode 100644 packages/plugins/terminal-iterm2/package.json create mode 100644 packages/plugins/terminal-iterm2/src/index.ts create mode 100644 packages/plugins/terminal-iterm2/tsconfig.json create mode 100644 packages/plugins/terminal-web/package.json create mode 100644 packages/plugins/terminal-web/src/index.ts create mode 100644 packages/plugins/terminal-web/tsconfig.json create mode 100644 packages/plugins/tracker-github/package.json create mode 100644 packages/plugins/tracker-github/src/index.ts create mode 100644 packages/plugins/tracker-github/tsconfig.json create mode 100644 packages/plugins/tracker-linear/package.json create mode 100644 packages/plugins/tracker-linear/src/index.ts create mode 100644 packages/plugins/tracker-linear/tsconfig.json create mode 100644 packages/plugins/workspace-clone/package.json create mode 100644 packages/plugins/workspace-clone/src/index.ts create mode 100644 packages/plugins/workspace-clone/tsconfig.json create mode 100644 packages/plugins/workspace-worktree/package.json create mode 100644 packages/plugins/workspace-worktree/src/index.ts create mode 100644 packages/plugins/workspace-worktree/tsconfig.json create mode 100644 packages/web/package.json create mode 100644 packages/web/src/app/layout.tsx create mode 100644 packages/web/src/app/page.tsx create mode 100644 packages/web/tsconfig.json create mode 100644 pnpm-lock.yaml create mode 100644 pnpm-workspace.yaml create mode 100644 tsconfig.base.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..2408f8c87 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +node_modules/ +dist/ +.next/ +*.tsbuildinfo +.env +.env.local diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000..6fa27c3c5 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,132 @@ +# CLAUDE.md — Agent Orchestrator + +## What This Project Is + +An open-source, agent-agnostic system for orchestrating parallel AI coding agents. Any coding agent, any repo, any issue tracker, any runtime. The system manages session lifecycle, tracks PR/CI/review state, auto-handles routine issues (CI failures, review comments), and pushes notifications to humans only when their judgment is needed. + +**Core principle: Push, not pull.** The human spawns agents, walks away, and gets notified when needed. + +## Tech Stack + +- **Language**: TypeScript throughout (ESM, Node 20+) +- **Monorepo**: pnpm workspaces +- **Web**: Next.js 15 (App Router) + Tailwind CSS +- **CLI**: Commander.js +- **Config**: YAML + Zod validation +- **Real-time**: Server-Sent Events +- **State**: Flat metadata files + JSONL event log + +## Architecture + +8 plugin slots — every abstraction is swappable: + +| Slot | Interface | Default Plugin | +|------|-----------|---------------| +| Runtime | `Runtime` | tmux | +| Agent | `Agent` | claude-code | +| Workspace | `Workspace` | worktree | +| Tracker | `Tracker` | github | +| SCM | `SCM` | github | +| Notifier | `Notifier` | desktop | +| Terminal | `Terminal` | iterm2 | +| Lifecycle | (core, not pluggable) | — | + +All interfaces are defined in `packages/core/src/types.ts`. **Read this file first** — it is the source of truth for all abstractions. + +## Directory Structure + +``` +packages/ + core/ — @agent-orchestrator/core (types, config, services) + cli/ — @agent-orchestrator/cli (the `ao` command) + web/ — @agent-orchestrator/web (Next.js dashboard) + plugins/ + runtime-tmux/ — tmux session runtime + runtime-process/ — child process runtime + agent-claude-code/ — Claude Code adapter + agent-codex/ — Codex CLI adapter + agent-aider/ — Aider adapter + workspace-worktree/ — git worktree isolation + workspace-clone/ — git clone isolation + tracker-github/ — GitHub Issues tracker + tracker-linear/ — Linear tracker + scm-github/ — GitHub PRs, CI, reviews + notifier-desktop/ — OS desktop notifications + notifier-slack/ — Slack notifications + notifier-webhook/ — Generic webhook notifications + terminal-iterm2/ — macOS iTerm2 tab management + terminal-web/ — xterm.js web terminal +``` + +## Conventions + +### TypeScript +- ESM modules (`"type": "module"`) +- Use `.js` extensions in imports (TypeScript ESM requirement): `import { foo } from "./bar.js"` +- Strict mode enabled +- Use `node:` prefix for Node.js builtins: `import { readFileSync } from "node:fs"` + +### Plugin Structure +Every plugin exports a `PluginModule`: +```typescript +import type { PluginModule, Runtime } from "@agent-orchestrator/core"; + +export const manifest = { + name: "tmux", + slot: "runtime" as const, + description: "Runtime plugin: tmux sessions", + version: "0.1.0", +}; + +export function create(): Runtime { + return { + name: "tmux", + // ... implement interface + }; +} +``` + +### Shell Commands +When a plugin needs to run shell commands (git, tmux, gh, etc.), use `child_process.execFile` or `child_process.spawn` from `node:child_process`. Wrap them in async helpers. + +### Error Handling +- Throw typed errors, don't return error codes +- Plugin methods should throw if they can't do their job +- The core services catch and handle plugin errors + +### Config +- Config is loaded from `agent-orchestrator.yaml` (see `.yaml.example`) +- All paths support `~` expansion +- Per-project overrides for plugins and reactions + +## Reference Implementation + +The `scripts/` directory contains the original bash scripts that this TypeScript codebase replaces. Use them as specifications: + +| Script | What It Specifies | +|--------|------------------| +| `claude-ao-session` | Session lifecycle (spawn, list, kill, cleanup) | +| `claude-dashboard` | Web dashboard, API, activity detection | +| `claude-batch-spawn` | Batch spawning with duplicate detection | +| `send-to-session` | Smart message delivery (busy detection, wait-for-idle) | +| `claude-status` | JSONL introspection, live branch detection | +| `claude-review-check` | PR review scanning, fix prompt generation | +| `claude-bugbot-fix` | Automated comment detection + fixes | +| `claude-session-status` | Activity classification (working/idle/blocked) | +| `get-claude-session-info` | Agent introspection (session ID, summary extraction) | + +## Building + +```bash +pnpm install +pnpm build # build all packages +pnpm typecheck # typecheck all packages +``` + +## Key Design Decisions + +1. **Stateless orchestrator** — no database, just flat metadata files + event log +2. **Plugins implement interfaces** — every plugin is a pure implementation of an interface from `types.ts` +3. **Push notifications** — the Notifier is the primary human interface, not the dashboard +4. **Two-tier event handling** — auto-handle routine issues (CI, reviews), notify human only when judgment is needed +5. **Backwards-compatible metadata** — flat key=value files matching the existing bash script format diff --git a/agent-orchestrator.yaml.example b/agent-orchestrator.yaml.example new file mode 100644 index 000000000..c7fa2f9c2 --- /dev/null +++ b/agent-orchestrator.yaml.example @@ -0,0 +1,86 @@ +# Agent Orchestrator Configuration +# Copy to agent-orchestrator.yaml and customize. + +# Where to store session metadata +dataDir: ~/.agent-orchestrator + +# Where to create workspaces (git worktrees, clones) +worktreeDir: ~/.worktrees + +# Web dashboard port +port: 3000 + +# Default plugins (these are the defaults — you can omit this section) +defaults: + runtime: tmux # tmux | process | docker | kubernetes | ssh | e2b + agent: claude-code # claude-code | codex | aider | goose | custom + workspace: worktree # worktree | clone | copy + notifiers: [desktop] # desktop | slack | discord | webhook | email + +# Projects — at minimum, specify repo and path +projects: + my-app: + name: My App + repo: org/my-app + path: ~/my-app + defaultBranch: main + sessionPrefix: app + + # Issue tracker (defaults to github issues) + # tracker: + # plugin: linear + # teamId: "your-team-id" + + # Files to symlink into workspaces + # symlinks: [.env, .claude] + + # Commands to run after workspace creation + # postCreate: + # - "pnpm install" + + # Agent-specific config + # agentConfig: + # permissions: skip # --dangerously-skip-permissions + # model: opus + + # Per-project reaction overrides + # reactions: + # approved-and-green: + # auto: true # enable auto-merge for this project + +# Notification channels +# notifiers: +# slack: +# plugin: slack +# webhook: ${SLACK_WEBHOOK_URL} +# channel: "#agent-updates" + +# Notification routing by priority +# notificationRouting: +# urgent: [desktop, slack] # agent stuck, needs input, errored +# action: [desktop, slack] # PR ready to merge +# warning: [slack] # auto-fix failed +# info: [slack] # summary, all done + +# Reactions — auto-responses to events (these are the defaults) +# reactions: +# ci-failed: +# auto: true +# action: send-to-agent +# retries: 2 +# escalateAfter: 2 +# +# changes-requested: +# auto: true +# action: send-to-agent +# escalateAfter: 30m +# +# approved-and-green: +# auto: false # set to true for auto-merge +# action: notify +# priority: action +# +# agent-stuck: +# threshold: 10m +# action: notify +# priority: urgent diff --git a/package.json b/package.json new file mode 100644 index 000000000..05c44a155 --- /dev/null +++ b/package.json @@ -0,0 +1,18 @@ +{ + "name": "agent-orchestrator", + "version": "0.1.0", + "private": true, + "description": "Orchestrate parallel AI coding agents across any runtime, any repo, any issue tracker", + "license": "MIT", + "engines": { + "node": ">=20.0.0" + }, + "packageManager": "pnpm@9.15.4", + "scripts": { + "build": "pnpm -r build", + "dev": "pnpm --filter @agent-orchestrator/web dev", + "lint": "pnpm -r lint", + "typecheck": "pnpm -r typecheck", + "clean": "pnpm -r clean" + } +} diff --git a/packages/cli/package.json b/packages/cli/package.json new file mode 100644 index 000000000..b192ae821 --- /dev/null +++ b/packages/cli/package.json @@ -0,0 +1,27 @@ +{ + "name": "@agent-orchestrator/cli", + "version": "0.1.0", + "description": "CLI for agent-orchestrator — the `ao` command", + "type": "module", + "bin": { + "ao": "dist/index.js" + }, + "main": "dist/index.js", + "scripts": { + "build": "tsc", + "dev": "tsx src/index.ts", + "typecheck": "tsc --noEmit", + "clean": "rm -rf dist" + }, + "dependencies": { + "@agent-orchestrator/core": "workspace:*", + "chalk": "^5.4.0", + "commander": "^13.0.0", + "ora": "^8.1.0" + }, + "devDependencies": { + "@types/node": "^25.2.3", + "tsx": "^4.19.0", + "typescript": "^5.7.0" + } +} diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts new file mode 100644 index 000000000..99565bf7e --- /dev/null +++ b/packages/cli/src/index.ts @@ -0,0 +1,2 @@ +#!/usr/bin/env node +// CLI entry point — to be implemented diff --git a/packages/cli/tsconfig.json b/packages/cli/tsconfig.json new file mode 100644 index 000000000..5a24989cd --- /dev/null +++ b/packages/cli/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"] +} diff --git a/packages/core/package.json b/packages/core/package.json new file mode 100644 index 000000000..ab13f7221 --- /dev/null +++ b/packages/core/package.json @@ -0,0 +1,31 @@ +{ + "name": "@agent-orchestrator/core", + "version": "0.1.0", + "description": "Core library — types, config, session manager, lifecycle manager, event bus", + "type": "module", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + }, + "./types": { + "types": "./dist/types.d.ts", + "import": "./dist/types.js" + } + }, + "scripts": { + "build": "tsc", + "typecheck": "tsc --noEmit", + "clean": "rm -rf dist" + }, + "dependencies": { + "yaml": "^2.7.0", + "zod": "^3.24.0" + }, + "devDependencies": { + "@types/node": "^25.2.3", + "typescript": "^5.7.0" + } +} diff --git a/packages/core/src/config.ts b/packages/core/src/config.ts new file mode 100644 index 000000000..00d5d23b8 --- /dev/null +++ b/packages/core/src/config.ts @@ -0,0 +1,283 @@ +/** + * Configuration loader — reads agent-orchestrator.yaml and validates with Zod. + * + * Minimal config that just works: + * projects: + * my-app: + * repo: org/repo + * path: ~/my-app + * + * Everything else has sensible defaults. + */ + +import { readFileSync, existsSync } from "node:fs"; +import { resolve, join } from "node:path"; +import { homedir } from "node:os"; +import { parse as parseYaml } from "yaml"; +import { z } from "zod"; +import type { OrchestratorConfig } from "./types.js"; + +// ============================================================================= +// ZOD SCHEMAS +// ============================================================================= + +const ReactionConfigSchema = z.object({ + auto: z.boolean().default(true), + action: z.enum(["send-to-agent", "notify", "auto-merge"]).default("notify"), + message: z.string().optional(), + priority: z.enum(["urgent", "action", "warning", "info"]).optional(), + retries: z.number().optional(), + escalateAfter: z.union([z.number(), z.string()]).optional(), + threshold: z.string().optional(), + includeSummary: z.boolean().optional(), +}); + +const TrackerConfigSchema = z + .object({ + plugin: z.string(), + }) + .passthrough(); + +const SCMConfigSchema = z + .object({ + plugin: z.string(), + }) + .passthrough(); + +const NotifierConfigSchema = z + .object({ + plugin: z.string(), + }) + .passthrough(); + +const AgentSpecificConfigSchema = z + .object({ + permissions: z.enum(["skip", "default"]).optional(), + model: z.string().optional(), + }) + .passthrough(); + +const ProjectConfigSchema = z.object({ + name: z.string().optional(), + repo: z.string(), + path: z.string(), + defaultBranch: z.string().default("main"), + sessionPrefix: z.string().optional(), + runtime: z.string().optional(), + agent: z.string().optional(), + workspace: z.string().optional(), + tracker: TrackerConfigSchema.optional(), + scm: SCMConfigSchema.optional(), + symlinks: z.array(z.string()).optional(), + postCreate: z.array(z.string()).optional(), + agentConfig: AgentSpecificConfigSchema.optional(), + reactions: z.record(ReactionConfigSchema.partial()).optional(), +}); + +const DefaultPluginsSchema = z.object({ + runtime: z.string().default("tmux"), + agent: z.string().default("claude-code"), + workspace: z.string().default("worktree"), + notifiers: z.array(z.string()).default(["desktop"]), +}); + +const OrchestratorConfigSchema = z.object({ + dataDir: z.string().default("~/.agent-orchestrator"), + worktreeDir: z.string().default("~/.worktrees"), + port: z.number().default(3000), + defaults: DefaultPluginsSchema.default({}), + projects: z.record(ProjectConfigSchema), + notifiers: z.record(NotifierConfigSchema).default({}), + notificationRouting: z + .record(z.array(z.string())) + .default({ + urgent: ["desktop", "slack"], + action: ["desktop", "slack"], + warning: ["slack"], + info: ["slack"], + }), + reactions: z.record(ReactionConfigSchema).default({}), +}); + +// ============================================================================= +// CONFIG LOADING +// ============================================================================= + +/** Expand ~ to home directory */ +function expandHome(filepath: string): string { + if (filepath.startsWith("~/")) { + return join(homedir(), filepath.slice(2)); + } + return filepath; +} + +/** Expand all path fields in the config */ +function expandPaths(config: OrchestratorConfig): OrchestratorConfig { + config.dataDir = expandHome(config.dataDir); + config.worktreeDir = expandHome(config.worktreeDir); + + for (const project of Object.values(config.projects)) { + project.path = expandHome(project.path); + } + + return config; +} + +/** Apply defaults to project configs */ +function applyProjectDefaults( + config: OrchestratorConfig +): OrchestratorConfig { + for (const [id, project] of Object.entries(config.projects)) { + // Derive name from project ID if not set + if (!project.name) { + project.name = id; + } + + // Derive session prefix from project ID if not set + if (!project.sessionPrefix) { + project.sessionPrefix = id; + } + + // Infer SCM from repo if not set + if (!project.scm && project.repo.includes("/")) { + project.scm = { plugin: "github" }; + } + + // Infer tracker from repo if not set (default to github issues) + if (!project.tracker) { + project.tracker = { plugin: "github" }; + } + } + + return config; +} + +/** Apply default reactions */ +function applyDefaultReactions( + config: OrchestratorConfig +): OrchestratorConfig { + const defaults: Record = { + "ci-failed": { + auto: true, + action: "send-to-agent", + message: + "CI is failing on your PR. Run `gh pr checks` to see the failures, fix them, and push.", + retries: 2, + escalateAfter: 2, + }, + "changes-requested": { + auto: true, + action: "send-to-agent", + message: + "There are review comments on your PR. Check with `gh pr view --comments` and `gh api` for inline comments. Address each one, push fixes, and reply.", + escalateAfter: "30m", + }, + "bugbot-comments": { + auto: true, + action: "send-to-agent", + message: + "Automated review comments found on your PR. Fix the issues flagged by the bot.", + escalateAfter: "30m", + }, + "merge-conflicts": { + auto: true, + action: "send-to-agent", + message: + "Your branch has merge conflicts. Rebase on the default branch and resolve them.", + escalateAfter: "15m", + }, + "approved-and-green": { + auto: false, + action: "notify", + priority: "action", + message: "PR is ready to merge", + }, + "agent-stuck": { + auto: true, + action: "notify", + priority: "urgent", + threshold: "10m", + }, + "agent-needs-input": { + auto: true, + action: "notify", + priority: "urgent", + }, + "agent-exited": { + auto: true, + action: "notify", + priority: "urgent", + }, + "all-complete": { + auto: true, + action: "notify", + priority: "info", + includeSummary: true, + }, + }; + + // Merge defaults with user-specified reactions (user wins) + config.reactions = { ...defaults, ...config.reactions }; + + return config; +} + +/** Search for config file in standard locations */ +function findConfigFile(startDir?: string): string | null { + const searchPaths = [ + startDir ? resolve(startDir, "agent-orchestrator.yaml") : null, + startDir ? resolve(startDir, "agent-orchestrator.yml") : null, + resolve(process.cwd(), "agent-orchestrator.yaml"), + resolve(process.cwd(), "agent-orchestrator.yml"), + resolve(homedir(), ".agent-orchestrator.yaml"), + resolve(homedir(), ".agent-orchestrator.yml"), + resolve(homedir(), ".config", "agent-orchestrator", "config.yaml"), + ].filter((p): p is string => p !== null); + + for (const path of searchPaths) { + if (existsSync(path)) { + return path; + } + } + + return null; +} + +// ============================================================================= +// PUBLIC API +// ============================================================================= + +/** Load and validate config from a YAML file */ +export function loadConfig(configPath?: string): OrchestratorConfig { + const path = configPath ?? findConfigFile(); + + if (!path) { + throw new Error( + "No agent-orchestrator.yaml found. Run `ao init` to create one." + ); + } + + const raw = readFileSync(path, "utf-8"); + const parsed = parseYaml(raw); + + return validateConfig(parsed); +} + +/** Validate a raw config object */ +export function validateConfig(raw: unknown): OrchestratorConfig { + const validated = OrchestratorConfigSchema.parse(raw); + + let config = validated as OrchestratorConfig; + config = expandPaths(config); + config = applyProjectDefaults(config); + config = applyDefaultReactions(config); + + return config; +} + +/** Get the default config (useful for `ao init`) */ +export function getDefaultConfig(): OrchestratorConfig { + return validateConfig({ + projects: {}, + }); +} diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts new file mode 100644 index 000000000..96af10407 --- /dev/null +++ b/packages/core/src/index.ts @@ -0,0 +1,15 @@ +/** + * @agent-orchestrator/core + * + * Core library for the Agent Orchestrator. + * Exports all types, config loader, and service implementations. + */ + +// Types — everything plugins and consumers need +export * from "./types.js"; + +// Config — YAML loader + validation +export { loadConfig, validateConfig, getDefaultConfig } from "./config.js"; + +// Plugin registry +export { createPluginRegistry } from "./plugin-registry.js"; diff --git a/packages/core/src/plugin-registry.ts b/packages/core/src/plugin-registry.ts new file mode 100644 index 000000000..8fb8edc29 --- /dev/null +++ b/packages/core/src/plugin-registry.ts @@ -0,0 +1,98 @@ +/** + * Plugin Registry — discovers and loads plugins. + * + * Plugins can be: + * 1. Built-in (packages/plugins/*) + * 2. npm packages (@agent-orchestrator/plugin-*) + * 3. Local file paths specified in config + */ + +import type { + PluginSlot, + PluginManifest, + PluginModule, + PluginRegistry, + OrchestratorConfig, +} from "./types.js"; + +/** Map from "slot:name" → plugin instance */ +type PluginMap = Map; + +function makeKey(slot: PluginSlot, name: string): string { + return `${slot}:${name}`; +} + +/** Built-in plugin package names, mapped to their npm package */ +const BUILTIN_PLUGINS: Array<{ slot: PluginSlot; name: string; pkg: string }> = [ + // Runtimes + { slot: "runtime", name: "tmux", pkg: "@agent-orchestrator/plugin-runtime-tmux" }, + { slot: "runtime", name: "process", pkg: "@agent-orchestrator/plugin-runtime-process" }, + // Agents + { slot: "agent", name: "claude-code", pkg: "@agent-orchestrator/plugin-agent-claude-code" }, + { slot: "agent", name: "codex", pkg: "@agent-orchestrator/plugin-agent-codex" }, + { slot: "agent", name: "aider", pkg: "@agent-orchestrator/plugin-agent-aider" }, + // Workspaces + { slot: "workspace", name: "worktree", pkg: "@agent-orchestrator/plugin-workspace-worktree" }, + { slot: "workspace", name: "clone", pkg: "@agent-orchestrator/plugin-workspace-clone" }, + // Trackers + { slot: "tracker", name: "github", pkg: "@agent-orchestrator/plugin-tracker-github" }, + { slot: "tracker", name: "linear", pkg: "@agent-orchestrator/plugin-tracker-linear" }, + // SCM + { slot: "scm", name: "github", pkg: "@agent-orchestrator/plugin-scm-github" }, + // Notifiers + { slot: "notifier", name: "desktop", pkg: "@agent-orchestrator/plugin-notifier-desktop" }, + { slot: "notifier", name: "slack", pkg: "@agent-orchestrator/plugin-notifier-slack" }, + { slot: "notifier", name: "webhook", pkg: "@agent-orchestrator/plugin-notifier-webhook" }, + // Terminals + { slot: "terminal", name: "iterm2", pkg: "@agent-orchestrator/plugin-terminal-iterm2" }, + { slot: "terminal", name: "web", pkg: "@agent-orchestrator/plugin-terminal-web" }, +]; + +export function createPluginRegistry(): PluginRegistry { + const plugins: PluginMap = new Map(); + + return { + register(plugin: PluginModule): void { + const { manifest } = plugin; + const key = makeKey(manifest.slot, manifest.name); + const instance = plugin.create(); + plugins.set(key, { manifest, instance }); + }, + + get(slot: PluginSlot, name: string): T | null { + const entry = plugins.get(makeKey(slot, name)); + return entry ? (entry.instance as T) : null; + }, + + list(slot: PluginSlot): PluginManifest[] { + const result: PluginManifest[] = []; + for (const [key, entry] of plugins) { + if (key.startsWith(`${slot}:`)) { + result.push(entry.manifest); + } + } + return result; + }, + + async loadBuiltins(): Promise { + for (const builtin of BUILTIN_PLUGINS) { + try { + const mod = (await import(builtin.pkg)) as PluginModule; + if (mod.manifest && typeof mod.create === "function") { + this.register(mod); + } + } catch { + // Plugin not installed — that's fine, only load what's available + } + } + }, + + async loadFromConfig(config: OrchestratorConfig): Promise { + // First, load all built-ins + await this.loadBuiltins(); + + // Then, load any additional plugins specified in project configs + // (future: support npm package names and local file paths) + }, + }; +} diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts new file mode 100644 index 000000000..e1550a9f4 --- /dev/null +++ b/packages/core/src/types.ts @@ -0,0 +1,842 @@ +/** + * Agent Orchestrator — Core Type Definitions + * + * This file defines ALL interfaces and types that the system uses. + * Every plugin, CLI command, and web API route builds against these. + * + * Architecture: 8 plugin slots + core services + * 1. Runtime — where sessions execute (tmux, docker, k8s, process) + * 2. Agent — AI coding tool (claude-code, codex, aider) + * 3. Workspace — code isolation (worktree, clone) + * 4. Tracker — issue tracking (github, linear, jira) + * 5. SCM — source platform + PR/CI/reviews (github, gitlab) + * 6. Notifier — push notifications (desktop, slack, webhook) + * 7. Terminal — human interaction UI (iterm2, web, none) + * 8. Lifecycle Manager (core, not pluggable) + */ + +// ============================================================================= +// SESSION +// ============================================================================= + +/** Unique session identifier, e.g. "my-app-1", "backend-12" */ +export type SessionId = string; + +/** Session lifecycle states */ +export type SessionStatus = + | "spawning" + | "working" + | "pr_open" + | "ci_failed" + | "review_pending" + | "changes_requested" + | "approved" + | "mergeable" + | "merged" + | "cleanup" + | "needs_input" + | "stuck" + | "errored" + | "killed"; + +/** Activity state as detected by the agent plugin */ +export type ActivityState = + | "active" // agent is processing (thinking, writing code) + | "idle" // agent is at prompt, waiting for input + | "waiting_input" // agent is asking a question / permission prompt + | "blocked" // agent hit an error or is stuck + | "exited"; // agent process is no longer running + +/** A running agent session */ +export interface Session { + /** Unique session ID, e.g. "my-app-3" */ + id: SessionId; + + /** Which project this session belongs to */ + projectId: string; + + /** Current lifecycle status */ + status: SessionStatus; + + /** Activity state from agent plugin */ + activity: ActivityState; + + /** Git branch name */ + branch: string | null; + + /** Issue identifier (if working on an issue) */ + issueId: string | null; + + /** PR info (once PR is created) */ + pr: PRInfo | null; + + /** Workspace path on disk */ + workspacePath: string | null; + + /** Runtime handle for communicating with the session */ + runtimeHandle: RuntimeHandle | null; + + /** Agent introspection data (summary, cost, etc.) */ + agentInfo: AgentIntrospection | null; + + /** When the session was created */ + createdAt: Date; + + /** Last activity timestamp */ + lastActivityAt: Date; + + /** Metadata key-value pairs */ + metadata: Record; +} + +/** Config for creating a new session */ +export interface SessionSpawnConfig { + projectId: string; + issueId?: string; + branch?: string; + prompt?: string; +} + +// ============================================================================= +// RUNTIME — Plugin Slot 1 +// ============================================================================= + +/** + * Runtime determines WHERE and HOW agent sessions execute. + * tmux, docker, kubernetes, child processes, SSH, cloud sandboxes, etc. + */ +export interface Runtime { + readonly name: string; + + /** Create a new session environment and return a handle */ + create(config: RuntimeCreateConfig): Promise; + + /** Destroy a session environment */ + destroy(handle: RuntimeHandle): Promise; + + /** Send a text message/prompt to the running agent */ + sendMessage(handle: RuntimeHandle, message: string): Promise; + + /** Capture recent output from the session */ + getOutput(handle: RuntimeHandle, lines?: number): Promise; + + /** Check if the session environment is still alive */ + isAlive(handle: RuntimeHandle): Promise; + + /** Get resource metrics (uptime, memory, etc.) */ + getMetrics?(handle: RuntimeHandle): Promise; + + /** Get info needed to attach a human to this session (for Terminal plugin) */ + getAttachInfo?(handle: RuntimeHandle): Promise; +} + +export interface RuntimeCreateConfig { + sessionId: SessionId; + workspacePath: string; + launchCommand: string; + environment: Record; +} + +/** Opaque handle returned by runtime.create() */ +export interface RuntimeHandle { + /** Runtime-specific identifier (tmux session name, container ID, pod name, etc.) */ + id: string; + /** Which runtime created this handle */ + runtimeName: string; + /** Runtime-specific data */ + data: Record; +} + +export interface RuntimeMetrics { + uptimeMs: number; + memoryMb?: number; + cpuPercent?: number; +} + +export interface AttachInfo { + /** How to connect: tmux attach, docker exec, SSH, web URL, etc. */ + type: "tmux" | "docker" | "ssh" | "web" | "process"; + /** For tmux: session name. For docker: container ID. For web: URL. */ + target: string; + /** Optional: command to run to attach */ + command?: string; +} + +// ============================================================================= +// AGENT — Plugin Slot 2 +// ============================================================================= + +/** + * Agent adapter for a specific AI coding tool. + * Knows how to launch, detect activity, and introspect the agent. + */ +export interface Agent { + readonly name: string; + + /** Process name to look for (e.g. "claude", "codex", "aider") */ + readonly processName: string; + + /** Get the shell command to launch this agent */ + getLaunchCommand(config: AgentLaunchConfig): string; + + /** Get environment variables for the agent process */ + getEnvironment(config: AgentLaunchConfig): Record; + + /** Detect what the agent is currently doing */ + detectActivity(session: Session): Promise; + + /** Check if agent process is running (given runtime handle) */ + isProcessRunning(handle: RuntimeHandle): Promise; + + /** Extract information from agent's internal data (summary, cost, session ID) */ + introspect(session: Session): Promise; + + /** Optional: run setup after agent is launched (e.g. configure MCP servers) */ + postLaunchSetup?(session: Session): Promise; +} + +export interface AgentLaunchConfig { + sessionId: SessionId; + projectConfig: ProjectConfig; + issueId?: string; + prompt?: string; + permissions?: "skip" | "default"; + model?: string; +} + +export interface AgentIntrospection { + /** Agent's auto-generated summary of what it's working on */ + summary: string | null; + /** Agent's internal session ID (for resume) */ + agentSessionId: string | null; + /** Estimated cost so far */ + cost?: CostEstimate; + /** Last message type in agent's log */ + lastMessageType?: string; + /** When agent's log was last modified */ + lastLogModified?: Date; +} + +export interface CostEstimate { + inputTokens: number; + outputTokens: number; + estimatedCostUsd: number; +} + +// ============================================================================= +// WORKSPACE — Plugin Slot 3 +// ============================================================================= + +/** + * Workspace manages code isolation — how each session gets its own copy of the repo. + */ +export interface Workspace { + readonly name: string; + + /** Create an isolated workspace for a session */ + create(config: WorkspaceCreateConfig): Promise; + + /** Destroy a workspace */ + destroy(workspacePath: string): Promise; + + /** List existing workspaces for a project */ + list(projectId: string): Promise; + + /** Optional: run hooks after workspace creation (symlinks, installs, etc.) */ + postCreate?(info: WorkspaceInfo, project: ProjectConfig): Promise; +} + +export interface WorkspaceCreateConfig { + projectId: string; + project: ProjectConfig; + sessionId: SessionId; + branch: string; +} + +export interface WorkspaceInfo { + path: string; + branch: string; + sessionId: SessionId; + projectId: string; +} + +// ============================================================================= +// TRACKER — Plugin Slot 4 +// ============================================================================= + +/** + * Issue/task tracker integration — GitHub Issues, Linear, Jira, etc. + */ +export interface Tracker { + readonly name: string; + + /** Fetch issue details */ + getIssue(identifier: string, project: ProjectConfig): Promise; + + /** Check if issue is completed/closed */ + isCompleted(identifier: string, project: ProjectConfig): Promise; + + /** Generate a URL for the issue */ + issueUrl(identifier: string, project: ProjectConfig): string; + + /** Generate a git branch name for the issue */ + branchName(identifier: string, project: ProjectConfig): string; + + /** Generate a prompt for the agent to work on this issue */ + generatePrompt(identifier: string, project: ProjectConfig): Promise; + + /** Optional: list issues with filters */ + listIssues?(filters: IssueFilters, project: ProjectConfig): Promise; + + /** Optional: update issue state */ + updateIssue?(identifier: string, update: IssueUpdate, project: ProjectConfig): Promise; + + /** Optional: create a new issue */ + createIssue?(input: CreateIssueInput, project: ProjectConfig): Promise; +} + +export interface Issue { + id: string; + title: string; + description: string; + url: string; + state: "open" | "in_progress" | "closed" | "cancelled"; + labels: string[]; + assignee?: string; + priority?: number; +} + +export interface IssueFilters { + state?: "open" | "closed" | "all"; + labels?: string[]; + assignee?: string; + limit?: number; +} + +export interface IssueUpdate { + state?: "open" | "in_progress" | "closed"; + labels?: string[]; + assignee?: string; + comment?: string; +} + +export interface CreateIssueInput { + title: string; + description: string; + labels?: string[]; + assignee?: string; + priority?: number; +} + +// ============================================================================= +// SCM — Plugin Slot 5 +// ============================================================================= + +/** + * Source code management platform — PR lifecycle, CI checks, code reviews. + * This is the richest plugin interface, covering the full PR pipeline. + */ +export interface SCM { + readonly name: string; + + // --- PR Lifecycle --- + + /** Detect if a session has an open PR (by branch name) */ + detectPR(session: Session, project: ProjectConfig): Promise; + + /** Get current PR state */ + getPRState(pr: PRInfo): Promise; + + /** Merge a PR */ + mergePR(pr: PRInfo, method?: MergeMethod): Promise; + + /** Close a PR without merging */ + closePR(pr: PRInfo): Promise; + + // --- CI Tracking --- + + /** Get individual CI check statuses */ + getCIChecks(pr: PRInfo): Promise; + + /** Get overall CI summary */ + getCISummary(pr: PRInfo): Promise; + + // --- Review Tracking --- + + /** Get all reviews on a PR */ + getReviews(pr: PRInfo): Promise; + + /** Get the overall review decision */ + getReviewDecision(pr: PRInfo): Promise; + + /** Get pending (unresolved) review comments */ + getPendingComments(pr: PRInfo): Promise; + + /** Get automated review comments (bots, linters, security scanners) */ + getAutomatedComments(pr: PRInfo): Promise; + + // --- Merge Readiness --- + + /** Check if PR is ready to merge */ + getMergeability(pr: PRInfo): Promise; +} + +// --- PR Types --- + +export interface PRInfo { + number: number; + url: string; + title: string; + owner: string; + repo: string; + branch: string; + baseBranch: string; + isDraft: boolean; +} + +export type PRState = "open" | "merged" | "closed"; + +export type MergeMethod = "merge" | "squash" | "rebase"; + +// --- CI Types --- + +export interface CICheck { + name: string; + status: "pending" | "running" | "passed" | "failed" | "skipped"; + url?: string; + conclusion?: string; + startedAt?: Date; + completedAt?: Date; +} + +export type CIStatus = "pending" | "passing" | "failing" | "none"; + +// --- Review Types --- + +export interface Review { + author: string; + state: "approved" | "changes_requested" | "commented" | "dismissed" | "pending"; + body?: string; + submittedAt: Date; +} + +export type ReviewDecision = "approved" | "changes_requested" | "pending" | "none"; + +export interface ReviewComment { + id: string; + author: string; + body: string; + path?: string; + line?: number; + isResolved: boolean; + createdAt: Date; + url: string; +} + +export interface AutomatedComment { + id: string; + botName: string; + body: string; + path?: string; + line?: number; + severity: "error" | "warning" | "info"; + createdAt: Date; + url: string; +} + +// --- Merge Readiness --- + +export interface MergeReadiness { + mergeable: boolean; + ciPassing: boolean; + approved: boolean; + noConflicts: boolean; + blockers: string[]; +} + +// ============================================================================= +// NOTIFIER — Plugin Slot 6 (PRIMARY INTERFACE) +// ============================================================================= + +/** + * Notifier is the PRIMARY interface between the orchestrator and the human. + * The human walks away after spawning agents. Notifications bring them back. + * + * Push, not pull. The human never polls. + */ +export interface Notifier { + readonly name: string; + + /** Push a notification to the human */ + notify(event: OrchestratorEvent): Promise; + + /** Push a notification with actionable buttons/links */ + notifyWithActions?(event: OrchestratorEvent, actions: NotifyAction[]): Promise; + + /** Post a message to a channel (for team-visible notifiers like Slack) */ + post?(message: string, context?: NotifyContext): Promise; +} + +export interface NotifyAction { + label: string; + url?: string; + callbackEndpoint?: string; +} + +export interface NotifyContext { + sessionId?: SessionId; + projectId?: string; + prUrl?: string; + channel?: string; +} + +// ============================================================================= +// TERMINAL — Plugin Slot 7 +// ============================================================================= + +/** + * Terminal manages how humans view/interact with running sessions. + * Opens IDE tabs, browser windows, or terminal sessions. + */ +export interface Terminal { + readonly name: string; + + /** Open a session for human interaction */ + openSession(session: Session): Promise; + + /** Open all sessions for a project */ + openAll(sessions: Session[]): Promise; + + /** Check if a session is already open in a tab/window */ + isSessionOpen?(session: Session): Promise; +} + +// ============================================================================= +// EVENTS +// ============================================================================= + +/** Priority levels for events — determines notification routing */ +export type EventPriority = "urgent" | "action" | "warning" | "info"; + +/** All orchestrator event types */ +export type EventType = + // Session lifecycle + | "session.spawned" + | "session.working" + | "session.exited" + | "session.killed" + | "session.stuck" + | "session.needs_input" + | "session.errored" + // PR lifecycle + | "pr.created" + | "pr.updated" + | "pr.merged" + | "pr.closed" + // CI + | "ci.passing" + | "ci.failing" + | "ci.fix_sent" + | "ci.fix_failed" + // Reviews + | "review.pending" + | "review.approved" + | "review.changes_requested" + | "review.comments_sent" + | "review.comments_unresolved" + // Automated reviews + | "automated_review.found" + | "automated_review.fix_sent" + // Merge + | "merge.ready" + | "merge.conflicts" + | "merge.completed" + // Reactions + | "reaction.triggered" + | "reaction.escalated" + // Summary + | "summary.all_complete"; + +/** An event emitted by the orchestrator */ +export interface OrchestratorEvent { + id: string; + type: EventType; + priority: EventPriority; + sessionId: SessionId; + projectId: string; + timestamp: Date; + message: string; + data: Record; +} + +// ============================================================================= +// REACTIONS +// ============================================================================= + +/** A configured automatic reaction to an event */ +export interface ReactionConfig { + /** Whether this reaction is enabled */ + auto: boolean; + + /** What to do: send message to agent, notify human, auto-merge */ + action: "send-to-agent" | "notify" | "auto-merge"; + + /** Message to send (for send-to-agent) */ + message?: string; + + /** Priority for notifications */ + priority?: EventPriority; + + /** How many times to retry send-to-agent before escalating */ + retries?: number; + + /** Escalate to human notification after this many failures or this duration */ + escalateAfter?: number | string; + + /** Threshold duration for time-based triggers (e.g. "10m" for stuck detection) */ + threshold?: string; + + /** Whether to include a summary in the notification */ + includeSummary?: boolean; +} + +export interface ReactionResult { + reactionType: string; + success: boolean; + action: string; + message?: string; + escalated: boolean; +} + +// ============================================================================= +// CONFIGURATION +// ============================================================================= + +/** Top-level orchestrator configuration (from agent-orchestrator.yaml) */ +export interface OrchestratorConfig { + /** Where to store session metadata */ + dataDir: string; + + /** Where to create workspaces (worktrees, clones) */ + worktreeDir: string; + + /** Web dashboard port */ + port: number; + + /** Default plugin selections */ + defaults: DefaultPlugins; + + /** Project configurations */ + projects: Record; + + /** Notification channel configs */ + notifiers: Record; + + /** Notification routing by priority */ + notificationRouting: Record; + + /** Default reaction configs */ + reactions: Record; +} + +export interface DefaultPlugins { + runtime: string; + agent: string; + workspace: string; + notifiers: string[]; +} + +export interface ProjectConfig { + /** Display name */ + name: string; + + /** GitHub repo in "owner/repo" format */ + repo: string; + + /** Local path to the repo */ + path: string; + + /** Default branch (main, master, next, develop, etc.) */ + defaultBranch: string; + + /** Session name prefix (e.g. "app" → "app-1", "app-2") */ + sessionPrefix: string; + + /** Override default runtime */ + runtime?: string; + + /** Override default agent */ + agent?: string; + + /** Override default workspace */ + workspace?: string; + + /** Issue tracker configuration */ + tracker?: TrackerConfig; + + /** SCM configuration (usually inferred from repo) */ + scm?: SCMConfig; + + /** Files/dirs to symlink into workspaces */ + symlinks?: string[]; + + /** Commands to run after workspace creation */ + postCreate?: string[]; + + /** Agent-specific configuration */ + agentConfig?: AgentSpecificConfig; + + /** Per-project reaction overrides */ + reactions?: Record>; +} + +export interface TrackerConfig { + plugin: string; + /** Plugin-specific config (e.g. teamId for Linear) */ + [key: string]: unknown; +} + +export interface SCMConfig { + plugin: string; + [key: string]: unknown; +} + +export interface NotifierConfig { + plugin: string; + [key: string]: unknown; +} + +export interface AgentSpecificConfig { + permissions?: "skip" | "default"; + model?: string; + [key: string]: unknown; +} + +// ============================================================================= +// PLUGIN SYSTEM +// ============================================================================= + +/** Plugin slot types */ +export type PluginSlot = + | "runtime" + | "agent" + | "workspace" + | "tracker" + | "scm" + | "notifier" + | "terminal"; + +/** Plugin manifest — what every plugin exports */ +export interface PluginManifest { + /** Plugin name (e.g. "tmux", "claude-code", "github") */ + name: string; + + /** Which slot this plugin fills */ + slot: PluginSlot; + + /** Human-readable description */ + description: string; + + /** Version */ + version: string; +} + +/** What a plugin module must export */ +export interface PluginModule { + manifest: PluginManifest; + create(config?: Record): T; +} + +// ============================================================================= +// SESSION METADATA (flat file format) +// ============================================================================= + +/** + * Session metadata stored as flat key=value files. + * Matches the existing bash script format for backwards compatibility. + */ +export interface SessionMetadata { + worktree: string; + branch: string; + status: string; + issue?: string; + pr?: string; + summary?: string; + project?: string; + createdAt?: string; + runtimeHandle?: string; +} + +// ============================================================================= +// SERVICE INTERFACES (core, not pluggable) +// ============================================================================= + +/** Session manager — CRUD for sessions */ +export interface SessionManager { + spawn(config: SessionSpawnConfig): Promise; + list(projectId?: string): Promise; + get(sessionId: SessionId): Promise; + kill(sessionId: SessionId): Promise; + cleanup(projectId?: string): Promise; + send(sessionId: SessionId, message: string): Promise; +} + +export interface CleanupResult { + killed: string[]; + skipped: string[]; + errors: Array<{ sessionId: string; error: string }>; +} + +/** Lifecycle manager — state machine + reaction engine */ +export interface LifecycleManager { + /** Start the lifecycle polling loop */ + start(intervalMs?: number): void; + + /** Stop the lifecycle polling loop */ + stop(): void; + + /** Get current state for all sessions */ + getStates(): Map; + + /** Force-check a specific session now */ + check(sessionId: SessionId): Promise; + + /** Subscribe to lifecycle events */ + on(event: EventType | "*", handler: (event: OrchestratorEvent) => void): void; + off(event: EventType | "*", handler: (event: OrchestratorEvent) => void): void; +} + +/** Event bus — pub/sub + persistence */ +export interface EventBus { + emit(event: OrchestratorEvent): void; + on(event: EventType | "*", handler: (event: OrchestratorEvent) => void): void; + off(event: EventType | "*", handler: (event: OrchestratorEvent) => void): void; + getHistory(filter?: EventFilter): OrchestratorEvent[]; +} + +export interface EventFilter { + sessionId?: SessionId; + projectId?: string; + type?: EventType; + priority?: EventPriority; + since?: Date; + limit?: number; +} + +/** Plugin registry — discovery + loading */ +export interface PluginRegistry { + /** Register a plugin */ + register(plugin: PluginModule): void; + + /** Get a plugin by slot and name */ + get(slot: PluginSlot, name: string): T | null; + + /** List plugins for a slot */ + list(slot: PluginSlot): PluginManifest[]; + + /** Load built-in plugins */ + loadBuiltins(): Promise; + + /** Load plugins from config (npm packages, local paths) */ + loadFromConfig(config: OrchestratorConfig): Promise; +} diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json new file mode 100644 index 000000000..5a24989cd --- /dev/null +++ b/packages/core/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"] +} diff --git a/packages/plugins/agent-aider/package.json b/packages/plugins/agent-aider/package.json new file mode 100644 index 000000000..847cba3cb --- /dev/null +++ b/packages/plugins/agent-aider/package.json @@ -0,0 +1,26 @@ +{ + "name": "@agent-orchestrator/plugin-agent-aider", + "version": "0.1.0", + "description": "Agent plugin: Aider", + "type": "module", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + } + }, + "scripts": { + "build": "tsc", + "typecheck": "tsc --noEmit", + "clean": "rm -rf dist" + }, + "dependencies": { + "@agent-orchestrator/core": "workspace:*" + }, + "devDependencies": { + "@types/node": "^25.2.3", + "typescript": "^5.7.0" + } +} diff --git a/packages/plugins/agent-aider/src/index.ts b/packages/plugins/agent-aider/src/index.ts new file mode 100644 index 000000000..4e6800d44 --- /dev/null +++ b/packages/plugins/agent-aider/src/index.ts @@ -0,0 +1 @@ +// agent-aider plugin — to be implemented diff --git a/packages/plugins/agent-aider/tsconfig.json b/packages/plugins/agent-aider/tsconfig.json new file mode 100644 index 000000000..e1b71318a --- /dev/null +++ b/packages/plugins/agent-aider/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"] +} diff --git a/packages/plugins/agent-claude-code/package.json b/packages/plugins/agent-claude-code/package.json new file mode 100644 index 000000000..afa49c6b5 --- /dev/null +++ b/packages/plugins/agent-claude-code/package.json @@ -0,0 +1,26 @@ +{ + "name": "@agent-orchestrator/plugin-agent-claude-code", + "version": "0.1.0", + "description": "Agent plugin: Claude Code", + "type": "module", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + } + }, + "scripts": { + "build": "tsc", + "typecheck": "tsc --noEmit", + "clean": "rm -rf dist" + }, + "dependencies": { + "@agent-orchestrator/core": "workspace:*" + }, + "devDependencies": { + "@types/node": "^25.2.3", + "typescript": "^5.7.0" + } +} diff --git a/packages/plugins/agent-claude-code/src/index.ts b/packages/plugins/agent-claude-code/src/index.ts new file mode 100644 index 000000000..e822a8f31 --- /dev/null +++ b/packages/plugins/agent-claude-code/src/index.ts @@ -0,0 +1 @@ +// agent-claude-code plugin — to be implemented diff --git a/packages/plugins/agent-claude-code/tsconfig.json b/packages/plugins/agent-claude-code/tsconfig.json new file mode 100644 index 000000000..e1b71318a --- /dev/null +++ b/packages/plugins/agent-claude-code/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"] +} diff --git a/packages/plugins/agent-codex/package.json b/packages/plugins/agent-codex/package.json new file mode 100644 index 000000000..962a9e5fd --- /dev/null +++ b/packages/plugins/agent-codex/package.json @@ -0,0 +1,26 @@ +{ + "name": "@agent-orchestrator/plugin-agent-codex", + "version": "0.1.0", + "description": "Agent plugin: OpenAI Codex CLI", + "type": "module", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + } + }, + "scripts": { + "build": "tsc", + "typecheck": "tsc --noEmit", + "clean": "rm -rf dist" + }, + "dependencies": { + "@agent-orchestrator/core": "workspace:*" + }, + "devDependencies": { + "@types/node": "^25.2.3", + "typescript": "^5.7.0" + } +} diff --git a/packages/plugins/agent-codex/src/index.ts b/packages/plugins/agent-codex/src/index.ts new file mode 100644 index 000000000..421746bc2 --- /dev/null +++ b/packages/plugins/agent-codex/src/index.ts @@ -0,0 +1 @@ +// agent-codex plugin — to be implemented diff --git a/packages/plugins/agent-codex/tsconfig.json b/packages/plugins/agent-codex/tsconfig.json new file mode 100644 index 000000000..e1b71318a --- /dev/null +++ b/packages/plugins/agent-codex/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"] +} diff --git a/packages/plugins/notifier-desktop/package.json b/packages/plugins/notifier-desktop/package.json new file mode 100644 index 000000000..41817b2b9 --- /dev/null +++ b/packages/plugins/notifier-desktop/package.json @@ -0,0 +1,26 @@ +{ + "name": "@agent-orchestrator/plugin-notifier-desktop", + "version": "0.1.0", + "description": "Notifier plugin: OS desktop notifications", + "type": "module", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + } + }, + "scripts": { + "build": "tsc", + "typecheck": "tsc --noEmit", + "clean": "rm -rf dist" + }, + "dependencies": { + "@agent-orchestrator/core": "workspace:*" + }, + "devDependencies": { + "@types/node": "^25.2.3", + "typescript": "^5.7.0" + } +} diff --git a/packages/plugins/notifier-desktop/src/index.ts b/packages/plugins/notifier-desktop/src/index.ts new file mode 100644 index 000000000..7c9394c48 --- /dev/null +++ b/packages/plugins/notifier-desktop/src/index.ts @@ -0,0 +1 @@ +// notifier-desktop plugin — to be implemented diff --git a/packages/plugins/notifier-desktop/tsconfig.json b/packages/plugins/notifier-desktop/tsconfig.json new file mode 100644 index 000000000..e1b71318a --- /dev/null +++ b/packages/plugins/notifier-desktop/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"] +} diff --git a/packages/plugins/notifier-slack/package.json b/packages/plugins/notifier-slack/package.json new file mode 100644 index 000000000..adeb73955 --- /dev/null +++ b/packages/plugins/notifier-slack/package.json @@ -0,0 +1,26 @@ +{ + "name": "@agent-orchestrator/plugin-notifier-slack", + "version": "0.1.0", + "description": "Notifier plugin: Slack", + "type": "module", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + } + }, + "scripts": { + "build": "tsc", + "typecheck": "tsc --noEmit", + "clean": "rm -rf dist" + }, + "dependencies": { + "@agent-orchestrator/core": "workspace:*" + }, + "devDependencies": { + "@types/node": "^25.2.3", + "typescript": "^5.7.0" + } +} diff --git a/packages/plugins/notifier-slack/src/index.ts b/packages/plugins/notifier-slack/src/index.ts new file mode 100644 index 000000000..0c6295504 --- /dev/null +++ b/packages/plugins/notifier-slack/src/index.ts @@ -0,0 +1 @@ +// notifier-slack plugin — to be implemented diff --git a/packages/plugins/notifier-slack/tsconfig.json b/packages/plugins/notifier-slack/tsconfig.json new file mode 100644 index 000000000..e1b71318a --- /dev/null +++ b/packages/plugins/notifier-slack/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"] +} diff --git a/packages/plugins/notifier-webhook/package.json b/packages/plugins/notifier-webhook/package.json new file mode 100644 index 000000000..ff42d859f --- /dev/null +++ b/packages/plugins/notifier-webhook/package.json @@ -0,0 +1,26 @@ +{ + "name": "@agent-orchestrator/plugin-notifier-webhook", + "version": "0.1.0", + "description": "Notifier plugin: generic webhook", + "type": "module", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + } + }, + "scripts": { + "build": "tsc", + "typecheck": "tsc --noEmit", + "clean": "rm -rf dist" + }, + "dependencies": { + "@agent-orchestrator/core": "workspace:*" + }, + "devDependencies": { + "@types/node": "^25.2.3", + "typescript": "^5.7.0" + } +} diff --git a/packages/plugins/notifier-webhook/src/index.ts b/packages/plugins/notifier-webhook/src/index.ts new file mode 100644 index 000000000..41a13afa2 --- /dev/null +++ b/packages/plugins/notifier-webhook/src/index.ts @@ -0,0 +1 @@ +// notifier-webhook plugin — to be implemented diff --git a/packages/plugins/notifier-webhook/tsconfig.json b/packages/plugins/notifier-webhook/tsconfig.json new file mode 100644 index 000000000..e1b71318a --- /dev/null +++ b/packages/plugins/notifier-webhook/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"] +} diff --git a/packages/plugins/runtime-process/package.json b/packages/plugins/runtime-process/package.json new file mode 100644 index 000000000..26eb9f683 --- /dev/null +++ b/packages/plugins/runtime-process/package.json @@ -0,0 +1,26 @@ +{ + "name": "@agent-orchestrator/plugin-runtime-process", + "version": "0.1.0", + "description": "Runtime plugin: child processes", + "type": "module", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + } + }, + "scripts": { + "build": "tsc", + "typecheck": "tsc --noEmit", + "clean": "rm -rf dist" + }, + "dependencies": { + "@agent-orchestrator/core": "workspace:*" + }, + "devDependencies": { + "@types/node": "^25.2.3", + "typescript": "^5.7.0" + } +} diff --git a/packages/plugins/runtime-process/src/index.ts b/packages/plugins/runtime-process/src/index.ts new file mode 100644 index 000000000..624bca7fe --- /dev/null +++ b/packages/plugins/runtime-process/src/index.ts @@ -0,0 +1 @@ +// runtime-process plugin — to be implemented diff --git a/packages/plugins/runtime-process/tsconfig.json b/packages/plugins/runtime-process/tsconfig.json new file mode 100644 index 000000000..e1b71318a --- /dev/null +++ b/packages/plugins/runtime-process/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"] +} diff --git a/packages/plugins/runtime-tmux/package.json b/packages/plugins/runtime-tmux/package.json new file mode 100644 index 000000000..e22921bde --- /dev/null +++ b/packages/plugins/runtime-tmux/package.json @@ -0,0 +1,26 @@ +{ + "name": "@agent-orchestrator/plugin-runtime-tmux", + "version": "0.1.0", + "description": "Runtime plugin: tmux sessions", + "type": "module", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + } + }, + "scripts": { + "build": "tsc", + "typecheck": "tsc --noEmit", + "clean": "rm -rf dist" + }, + "dependencies": { + "@agent-orchestrator/core": "workspace:*" + }, + "devDependencies": { + "@types/node": "^25.2.3", + "typescript": "^5.7.0" + } +} diff --git a/packages/plugins/runtime-tmux/src/index.ts b/packages/plugins/runtime-tmux/src/index.ts new file mode 100644 index 000000000..b34e376d1 --- /dev/null +++ b/packages/plugins/runtime-tmux/src/index.ts @@ -0,0 +1 @@ +// runtime-tmux plugin — to be implemented diff --git a/packages/plugins/runtime-tmux/tsconfig.json b/packages/plugins/runtime-tmux/tsconfig.json new file mode 100644 index 000000000..e1b71318a --- /dev/null +++ b/packages/plugins/runtime-tmux/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"] +} diff --git a/packages/plugins/scm-github/package.json b/packages/plugins/scm-github/package.json new file mode 100644 index 000000000..b12ea7669 --- /dev/null +++ b/packages/plugins/scm-github/package.json @@ -0,0 +1,26 @@ +{ + "name": "@agent-orchestrator/plugin-scm-github", + "version": "0.1.0", + "description": "SCM plugin: GitHub (PRs, CI, reviews)", + "type": "module", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + } + }, + "scripts": { + "build": "tsc", + "typecheck": "tsc --noEmit", + "clean": "rm -rf dist" + }, + "dependencies": { + "@agent-orchestrator/core": "workspace:*" + }, + "devDependencies": { + "@types/node": "^25.2.3", + "typescript": "^5.7.0" + } +} diff --git a/packages/plugins/scm-github/src/index.ts b/packages/plugins/scm-github/src/index.ts new file mode 100644 index 000000000..475ee4fcb --- /dev/null +++ b/packages/plugins/scm-github/src/index.ts @@ -0,0 +1 @@ +// scm-github plugin — to be implemented diff --git a/packages/plugins/scm-github/tsconfig.json b/packages/plugins/scm-github/tsconfig.json new file mode 100644 index 000000000..e1b71318a --- /dev/null +++ b/packages/plugins/scm-github/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"] +} diff --git a/packages/plugins/terminal-iterm2/package.json b/packages/plugins/terminal-iterm2/package.json new file mode 100644 index 000000000..66912ff5c --- /dev/null +++ b/packages/plugins/terminal-iterm2/package.json @@ -0,0 +1,26 @@ +{ + "name": "@agent-orchestrator/plugin-terminal-iterm2", + "version": "0.1.0", + "description": "Terminal plugin: macOS iTerm2", + "type": "module", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + } + }, + "scripts": { + "build": "tsc", + "typecheck": "tsc --noEmit", + "clean": "rm -rf dist" + }, + "dependencies": { + "@agent-orchestrator/core": "workspace:*" + }, + "devDependencies": { + "@types/node": "^25.2.3", + "typescript": "^5.7.0" + } +} diff --git a/packages/plugins/terminal-iterm2/src/index.ts b/packages/plugins/terminal-iterm2/src/index.ts new file mode 100644 index 000000000..94406cc82 --- /dev/null +++ b/packages/plugins/terminal-iterm2/src/index.ts @@ -0,0 +1 @@ +// terminal-iterm2 plugin — to be implemented diff --git a/packages/plugins/terminal-iterm2/tsconfig.json b/packages/plugins/terminal-iterm2/tsconfig.json new file mode 100644 index 000000000..e1b71318a --- /dev/null +++ b/packages/plugins/terminal-iterm2/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"] +} diff --git a/packages/plugins/terminal-web/package.json b/packages/plugins/terminal-web/package.json new file mode 100644 index 000000000..9760d4a04 --- /dev/null +++ b/packages/plugins/terminal-web/package.json @@ -0,0 +1,26 @@ +{ + "name": "@agent-orchestrator/plugin-terminal-web", + "version": "0.1.0", + "description": "Terminal plugin: xterm.js web terminal", + "type": "module", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + } + }, + "scripts": { + "build": "tsc", + "typecheck": "tsc --noEmit", + "clean": "rm -rf dist" + }, + "dependencies": { + "@agent-orchestrator/core": "workspace:*" + }, + "devDependencies": { + "@types/node": "^25.2.3", + "typescript": "^5.7.0" + } +} diff --git a/packages/plugins/terminal-web/src/index.ts b/packages/plugins/terminal-web/src/index.ts new file mode 100644 index 000000000..700cb619f --- /dev/null +++ b/packages/plugins/terminal-web/src/index.ts @@ -0,0 +1 @@ +// terminal-web plugin — to be implemented diff --git a/packages/plugins/terminal-web/tsconfig.json b/packages/plugins/terminal-web/tsconfig.json new file mode 100644 index 000000000..e1b71318a --- /dev/null +++ b/packages/plugins/terminal-web/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"] +} diff --git a/packages/plugins/tracker-github/package.json b/packages/plugins/tracker-github/package.json new file mode 100644 index 000000000..43d5a1003 --- /dev/null +++ b/packages/plugins/tracker-github/package.json @@ -0,0 +1,26 @@ +{ + "name": "@agent-orchestrator/plugin-tracker-github", + "version": "0.1.0", + "description": "Tracker plugin: GitHub Issues", + "type": "module", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + } + }, + "scripts": { + "build": "tsc", + "typecheck": "tsc --noEmit", + "clean": "rm -rf dist" + }, + "dependencies": { + "@agent-orchestrator/core": "workspace:*" + }, + "devDependencies": { + "@types/node": "^25.2.3", + "typescript": "^5.7.0" + } +} diff --git a/packages/plugins/tracker-github/src/index.ts b/packages/plugins/tracker-github/src/index.ts new file mode 100644 index 000000000..aaeb086d8 --- /dev/null +++ b/packages/plugins/tracker-github/src/index.ts @@ -0,0 +1 @@ +// tracker-github plugin — to be implemented diff --git a/packages/plugins/tracker-github/tsconfig.json b/packages/plugins/tracker-github/tsconfig.json new file mode 100644 index 000000000..e1b71318a --- /dev/null +++ b/packages/plugins/tracker-github/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"] +} diff --git a/packages/plugins/tracker-linear/package.json b/packages/plugins/tracker-linear/package.json new file mode 100644 index 000000000..3b90a2cc0 --- /dev/null +++ b/packages/plugins/tracker-linear/package.json @@ -0,0 +1,26 @@ +{ + "name": "@agent-orchestrator/plugin-tracker-linear", + "version": "0.1.0", + "description": "Tracker plugin: Linear", + "type": "module", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + } + }, + "scripts": { + "build": "tsc", + "typecheck": "tsc --noEmit", + "clean": "rm -rf dist" + }, + "dependencies": { + "@agent-orchestrator/core": "workspace:*" + }, + "devDependencies": { + "@types/node": "^25.2.3", + "typescript": "^5.7.0" + } +} diff --git a/packages/plugins/tracker-linear/src/index.ts b/packages/plugins/tracker-linear/src/index.ts new file mode 100644 index 000000000..5cfd1bed4 --- /dev/null +++ b/packages/plugins/tracker-linear/src/index.ts @@ -0,0 +1 @@ +// tracker-linear plugin — to be implemented diff --git a/packages/plugins/tracker-linear/tsconfig.json b/packages/plugins/tracker-linear/tsconfig.json new file mode 100644 index 000000000..e1b71318a --- /dev/null +++ b/packages/plugins/tracker-linear/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"] +} diff --git a/packages/plugins/workspace-clone/package.json b/packages/plugins/workspace-clone/package.json new file mode 100644 index 000000000..3553d6e6c --- /dev/null +++ b/packages/plugins/workspace-clone/package.json @@ -0,0 +1,26 @@ +{ + "name": "@agent-orchestrator/plugin-workspace-clone", + "version": "0.1.0", + "description": "Workspace plugin: git clone", + "type": "module", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + } + }, + "scripts": { + "build": "tsc", + "typecheck": "tsc --noEmit", + "clean": "rm -rf dist" + }, + "dependencies": { + "@agent-orchestrator/core": "workspace:*" + }, + "devDependencies": { + "@types/node": "^25.2.3", + "typescript": "^5.7.0" + } +} diff --git a/packages/plugins/workspace-clone/src/index.ts b/packages/plugins/workspace-clone/src/index.ts new file mode 100644 index 000000000..415f5b63b --- /dev/null +++ b/packages/plugins/workspace-clone/src/index.ts @@ -0,0 +1 @@ +// workspace-clone plugin — to be implemented diff --git a/packages/plugins/workspace-clone/tsconfig.json b/packages/plugins/workspace-clone/tsconfig.json new file mode 100644 index 000000000..e1b71318a --- /dev/null +++ b/packages/plugins/workspace-clone/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"] +} diff --git a/packages/plugins/workspace-worktree/package.json b/packages/plugins/workspace-worktree/package.json new file mode 100644 index 000000000..abf15e7b3 --- /dev/null +++ b/packages/plugins/workspace-worktree/package.json @@ -0,0 +1,26 @@ +{ + "name": "@agent-orchestrator/plugin-workspace-worktree", + "version": "0.1.0", + "description": "Workspace plugin: git worktrees", + "type": "module", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + } + }, + "scripts": { + "build": "tsc", + "typecheck": "tsc --noEmit", + "clean": "rm -rf dist" + }, + "dependencies": { + "@agent-orchestrator/core": "workspace:*" + }, + "devDependencies": { + "@types/node": "^25.2.3", + "typescript": "^5.7.0" + } +} diff --git a/packages/plugins/workspace-worktree/src/index.ts b/packages/plugins/workspace-worktree/src/index.ts new file mode 100644 index 000000000..5ec1870aa --- /dev/null +++ b/packages/plugins/workspace-worktree/src/index.ts @@ -0,0 +1 @@ +// workspace-worktree plugin — to be implemented diff --git a/packages/plugins/workspace-worktree/tsconfig.json b/packages/plugins/workspace-worktree/tsconfig.json new file mode 100644 index 000000000..e1b71318a --- /dev/null +++ b/packages/plugins/workspace-worktree/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"] +} diff --git a/packages/web/package.json b/packages/web/package.json new file mode 100644 index 000000000..48e6d6fb8 --- /dev/null +++ b/packages/web/package.json @@ -0,0 +1,26 @@ +{ + "name": "@agent-orchestrator/web", + "version": "0.1.0", + "description": "Web dashboard for agent-orchestrator", + "private": true, + "type": "module", + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "typecheck": "tsc --noEmit", + "clean": "rm -rf .next" + }, + "dependencies": { + "@agent-orchestrator/core": "workspace:*", + "next": "^15.1.0", + "react": "^19.0.0", + "react-dom": "^19.0.0" + }, + "devDependencies": { + "@types/react": "^19.0.0", + "@types/react-dom": "^19.0.0", + "tailwindcss": "^4.0.0", + "typescript": "^5.7.0" + } +} diff --git a/packages/web/src/app/layout.tsx b/packages/web/src/app/layout.tsx new file mode 100644 index 000000000..a095d6d31 --- /dev/null +++ b/packages/web/src/app/layout.tsx @@ -0,0 +1,8 @@ +// Web dashboard layout — to be implemented +export default function RootLayout({ children }: { children: React.ReactNode }) { + return ( + + {children} + + ); +} diff --git a/packages/web/src/app/page.tsx b/packages/web/src/app/page.tsx new file mode 100644 index 000000000..2080bb04c --- /dev/null +++ b/packages/web/src/app/page.tsx @@ -0,0 +1,4 @@ +// Dashboard home — to be implemented +export default function Home() { + return
Agent Orchestrator Dashboard
; +} diff --git a/packages/web/tsconfig.json b/packages/web/tsconfig.json new file mode 100644 index 000000000..4df6fe12c --- /dev/null +++ b/packages/web/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src", + "jsx": "preserve", + "module": "ESNext", + "moduleResolution": "Bundler", + "plugins": [{ "name": "next" }], + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["src", "next-env.d.ts"], + "exclude": ["node_modules"] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 000000000..dc944249f --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,1276 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: {} + + packages/cli: + dependencies: + '@agent-orchestrator/core': + specifier: workspace:* + version: link:../core + chalk: + specifier: ^5.4.0 + version: 5.6.2 + commander: + specifier: ^13.0.0 + version: 13.1.0 + ora: + specifier: ^8.1.0 + version: 8.2.0 + devDependencies: + '@types/node': + specifier: ^25.2.3 + version: 25.2.3 + tsx: + specifier: ^4.19.0 + version: 4.21.0 + typescript: + specifier: ^5.7.0 + version: 5.9.3 + + packages/core: + dependencies: + yaml: + specifier: ^2.7.0 + version: 2.8.2 + zod: + specifier: ^3.24.0 + version: 3.25.76 + devDependencies: + '@types/node': + specifier: ^25.2.3 + version: 25.2.3 + typescript: + specifier: ^5.7.0 + version: 5.9.3 + + packages/plugins/agent-aider: + dependencies: + '@agent-orchestrator/core': + specifier: workspace:* + version: link:../../core + devDependencies: + '@types/node': + specifier: ^25.2.3 + version: 25.2.3 + typescript: + specifier: ^5.7.0 + version: 5.9.3 + + packages/plugins/agent-claude-code: + dependencies: + '@agent-orchestrator/core': + specifier: workspace:* + version: link:../../core + devDependencies: + '@types/node': + specifier: ^25.2.3 + version: 25.2.3 + typescript: + specifier: ^5.7.0 + version: 5.9.3 + + packages/plugins/agent-codex: + dependencies: + '@agent-orchestrator/core': + specifier: workspace:* + version: link:../../core + devDependencies: + '@types/node': + specifier: ^25.2.3 + version: 25.2.3 + typescript: + specifier: ^5.7.0 + version: 5.9.3 + + packages/plugins/notifier-desktop: + dependencies: + '@agent-orchestrator/core': + specifier: workspace:* + version: link:../../core + devDependencies: + '@types/node': + specifier: ^25.2.3 + version: 25.2.3 + typescript: + specifier: ^5.7.0 + version: 5.9.3 + + packages/plugins/notifier-slack: + dependencies: + '@agent-orchestrator/core': + specifier: workspace:* + version: link:../../core + devDependencies: + '@types/node': + specifier: ^25.2.3 + version: 25.2.3 + typescript: + specifier: ^5.7.0 + version: 5.9.3 + + packages/plugins/notifier-webhook: + dependencies: + '@agent-orchestrator/core': + specifier: workspace:* + version: link:../../core + devDependencies: + '@types/node': + specifier: ^25.2.3 + version: 25.2.3 + typescript: + specifier: ^5.7.0 + version: 5.9.3 + + packages/plugins/runtime-process: + dependencies: + '@agent-orchestrator/core': + specifier: workspace:* + version: link:../../core + devDependencies: + '@types/node': + specifier: ^25.2.3 + version: 25.2.3 + typescript: + specifier: ^5.7.0 + version: 5.9.3 + + packages/plugins/runtime-tmux: + dependencies: + '@agent-orchestrator/core': + specifier: workspace:* + version: link:../../core + devDependencies: + '@types/node': + specifier: ^25.2.3 + version: 25.2.3 + typescript: + specifier: ^5.7.0 + version: 5.9.3 + + packages/plugins/scm-github: + dependencies: + '@agent-orchestrator/core': + specifier: workspace:* + version: link:../../core + devDependencies: + '@types/node': + specifier: ^25.2.3 + version: 25.2.3 + typescript: + specifier: ^5.7.0 + version: 5.9.3 + + packages/plugins/terminal-iterm2: + dependencies: + '@agent-orchestrator/core': + specifier: workspace:* + version: link:../../core + devDependencies: + '@types/node': + specifier: ^25.2.3 + version: 25.2.3 + typescript: + specifier: ^5.7.0 + version: 5.9.3 + + packages/plugins/terminal-web: + dependencies: + '@agent-orchestrator/core': + specifier: workspace:* + version: link:../../core + devDependencies: + '@types/node': + specifier: ^25.2.3 + version: 25.2.3 + typescript: + specifier: ^5.7.0 + version: 5.9.3 + + packages/plugins/tracker-github: + dependencies: + '@agent-orchestrator/core': + specifier: workspace:* + version: link:../../core + devDependencies: + '@types/node': + specifier: ^25.2.3 + version: 25.2.3 + typescript: + specifier: ^5.7.0 + version: 5.9.3 + + packages/plugins/tracker-linear: + dependencies: + '@agent-orchestrator/core': + specifier: workspace:* + version: link:../../core + devDependencies: + '@types/node': + specifier: ^25.2.3 + version: 25.2.3 + typescript: + specifier: ^5.7.0 + version: 5.9.3 + + packages/plugins/workspace-clone: + dependencies: + '@agent-orchestrator/core': + specifier: workspace:* + version: link:../../core + devDependencies: + '@types/node': + specifier: ^25.2.3 + version: 25.2.3 + typescript: + specifier: ^5.7.0 + version: 5.9.3 + + packages/plugins/workspace-worktree: + dependencies: + '@agent-orchestrator/core': + specifier: workspace:* + version: link:../../core + devDependencies: + '@types/node': + specifier: ^25.2.3 + version: 25.2.3 + typescript: + specifier: ^5.7.0 + version: 5.9.3 + + packages/web: + dependencies: + '@agent-orchestrator/core': + specifier: workspace:* + version: link:../core + next: + specifier: ^15.1.0 + version: 15.5.12(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: + specifier: ^19.0.0 + version: 19.2.4 + react-dom: + specifier: ^19.0.0 + version: 19.2.4(react@19.2.4) + devDependencies: + '@types/react': + specifier: ^19.0.0 + version: 19.2.14 + '@types/react-dom': + specifier: ^19.0.0 + version: 19.2.3(@types/react@19.2.14) + tailwindcss: + specifier: ^4.0.0 + version: 4.1.18 + typescript: + specifier: ^5.7.0 + version: 5.9.3 + +packages: + + '@emnapi/runtime@1.8.1': + resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==} + + '@esbuild/aix-ppc64@0.27.3': + resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.27.3': + resolution: {integrity: sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.27.3': + resolution: {integrity: sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.27.3': + resolution: {integrity: sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.27.3': + resolution: {integrity: sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.27.3': + resolution: {integrity: sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.27.3': + resolution: {integrity: sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.27.3': + resolution: {integrity: sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.27.3': + resolution: {integrity: sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.27.3': + resolution: {integrity: sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.27.3': + resolution: {integrity: sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.27.3': + resolution: {integrity: sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.27.3': + resolution: {integrity: sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.27.3': + resolution: {integrity: sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.27.3': + resolution: {integrity: sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.27.3': + resolution: {integrity: sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.27.3': + resolution: {integrity: sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.27.3': + resolution: {integrity: sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.27.3': + resolution: {integrity: sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.27.3': + resolution: {integrity: sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.27.3': + resolution: {integrity: sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.27.3': + resolution: {integrity: sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.27.3': + resolution: {integrity: sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.27.3': + resolution: {integrity: sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.27.3': + resolution: {integrity: sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.27.3': + resolution: {integrity: sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@img/colour@1.0.0': + resolution: {integrity: sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==} + engines: {node: '>=18'} + + '@img/sharp-darwin-arm64@0.34.5': + resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.34.5': + resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.2.4': + resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.2.4': + resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.2.4': + resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linux-arm@1.2.4': + resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-ppc64@1.2.4': + resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} + cpu: [ppc64] + os: [linux] + + '@img/sharp-libvips-linux-riscv64@1.2.4': + resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} + cpu: [riscv64] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.2.4': + resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} + cpu: [s390x] + os: [linux] + + '@img/sharp-libvips-linux-x64@1.2.4': + resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} + cpu: [x64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} + cpu: [x64] + os: [linux] + + '@img/sharp-linux-arm64@0.34.5': + resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linux-arm@0.34.5': + resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + + '@img/sharp-linux-ppc64@0.34.5': + resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ppc64] + os: [linux] + + '@img/sharp-linux-riscv64@0.34.5': + resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [riscv64] + os: [linux] + + '@img/sharp-linux-s390x@0.34.5': + resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + + '@img/sharp-linux-x64@0.34.5': + resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-linuxmusl-arm64@0.34.5': + resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linuxmusl-x64@0.34.5': + resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-wasm32@0.34.5': + resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-arm64@0.34.5': + resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.34.5': + resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.34.5': + resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + + '@next/env@15.5.12': + resolution: {integrity: sha512-pUvdJN1on574wQHjaBfNGDt9Mz5utDSZFsIIQkMzPgNS8ZvT4H2mwOrOIClwsQOb6EGx5M76/CZr6G8i6pSpLg==} + + '@next/swc-darwin-arm64@15.5.12': + resolution: {integrity: sha512-RnRjBtH8S8eXCpUNkQ+543DUc7ys8y15VxmFU9HRqlo9BG3CcBUiwNtF8SNoi2xvGCVJq1vl2yYq+3oISBS0Zg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@next/swc-darwin-x64@15.5.12': + resolution: {integrity: sha512-nqa9/7iQlboF1EFtNhWxQA0rQstmYRSBGxSM6g3GxvxHxcoeqVXfGNr9stJOme674m2V7r4E3+jEhhGvSQhJRA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@next/swc-linux-arm64-gnu@15.5.12': + resolution: {integrity: sha512-dCzAjqhDHwmoB2M4eYfVKqXs99QdQxNQVpftvP1eGVppamXh/OkDAwV737Zr0KPXEqRUMN4uCjh6mjO+XtF3Mw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-arm64-musl@15.5.12': + resolution: {integrity: sha512-+fpGWvQiITgf7PUtbWY1H7qUSnBZsPPLyyq03QuAKpVoTy/QUx1JptEDTQMVvQhvizCEuNLEeghrQUyXQOekuw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-x64-gnu@15.5.12': + resolution: {integrity: sha512-jSLvgdRRL/hrFAPqEjJf1fFguC719kmcptjNVDJl26BnJIpjL3KH5h6mzR4mAweociLQaqvt4UyzfbFjgAdDcw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-linux-x64-musl@15.5.12': + resolution: {integrity: sha512-/uaF0WfmYqQgLfPmN6BvULwxY0dufI2mlN2JbOKqqceZh1G4hjREyi7pg03zjfyS6eqNemHAZPSoP84x17vo6w==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-win32-arm64-msvc@15.5.12': + resolution: {integrity: sha512-xhsL1OvQSfGmlL5RbOmU+FV120urrgFpYLq+6U8C6KIym32gZT6XF/SDE92jKzzlPWskkbjOKCpqk5m4i8PEfg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@next/swc-win32-x64-msvc@15.5.12': + resolution: {integrity: sha512-Z1Dh6lhFkxvBDH1FoW6OU/L6prYwPSlwjLiZkExIAh8fbP6iI/M7iGTQAJPYJ9YFlWobCZ1PHbchFhFYb2ADkw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@swc/helpers@0.5.15': + resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + + '@types/node@25.2.3': + resolution: {integrity: sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ==} + + '@types/react-dom@19.2.3': + resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} + peerDependencies: + '@types/react': ^19.2.0 + + '@types/react@19.2.14': + resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==} + + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + + caniuse-lite@1.0.30001769: + resolution: {integrity: sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg==} + + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + cli-cursor@5.0.0: + resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} + engines: {node: '>=18'} + + cli-spinners@2.9.2: + resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} + engines: {node: '>=6'} + + client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + + commander@13.1.0: + resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} + engines: {node: '>=18'} + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + emoji-regex@10.6.0: + resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} + + esbuild@0.27.3: + resolution: {integrity: sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==} + engines: {node: '>=18'} + hasBin: true + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + get-east-asian-width@1.4.0: + resolution: {integrity: sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==} + engines: {node: '>=18'} + + get-tsconfig@4.13.6: + resolution: {integrity: sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==} + + is-interactive@2.0.0: + resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} + engines: {node: '>=12'} + + is-unicode-supported@1.3.0: + resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} + engines: {node: '>=12'} + + is-unicode-supported@2.1.0: + resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} + engines: {node: '>=18'} + + log-symbols@6.0.0: + resolution: {integrity: sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==} + engines: {node: '>=18'} + + mimic-function@5.0.1: + resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} + engines: {node: '>=18'} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + next@15.5.12: + resolution: {integrity: sha512-Fi/wQ4Etlrn60rz78bebG1i1SR20QxvV8tVp6iJspjLUSHcZoeUXCt+vmWoEcza85ElZzExK/jJ/F6SvtGktjA==} + engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.51.1 + babel-plugin-react-compiler: '*' + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + + onetime@7.0.0: + resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} + engines: {node: '>=18'} + + ora@8.2.0: + resolution: {integrity: sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==} + engines: {node: '>=18'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + postcss@8.4.31: + resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} + engines: {node: ^10 || ^12 || >=14} + + react-dom@19.2.4: + resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==} + peerDependencies: + react: ^19.2.4 + + react@19.2.4: + resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} + engines: {node: '>=0.10.0'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + restore-cursor@5.1.0: + resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} + engines: {node: '>=18'} + + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + + sharp@0.34.5: + resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + stdin-discarder@0.2.2: + resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==} + engines: {node: '>=18'} + + string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} + engines: {node: '>=18'} + + strip-ansi@7.1.2: + resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} + engines: {node: '>=12'} + + styled-jsx@5.1.6: + resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + + tailwindcss@4.1.18: + resolution: {integrity: sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tsx@4.21.0: + resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} + engines: {node: '>=18.0.0'} + hasBin: true + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + + yaml@2.8.2: + resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} + engines: {node: '>= 14.6'} + hasBin: true + + zod@3.25.76: + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + +snapshots: + + '@emnapi/runtime@1.8.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@esbuild/aix-ppc64@0.27.3': + optional: true + + '@esbuild/android-arm64@0.27.3': + optional: true + + '@esbuild/android-arm@0.27.3': + optional: true + + '@esbuild/android-x64@0.27.3': + optional: true + + '@esbuild/darwin-arm64@0.27.3': + optional: true + + '@esbuild/darwin-x64@0.27.3': + optional: true + + '@esbuild/freebsd-arm64@0.27.3': + optional: true + + '@esbuild/freebsd-x64@0.27.3': + optional: true + + '@esbuild/linux-arm64@0.27.3': + optional: true + + '@esbuild/linux-arm@0.27.3': + optional: true + + '@esbuild/linux-ia32@0.27.3': + optional: true + + '@esbuild/linux-loong64@0.27.3': + optional: true + + '@esbuild/linux-mips64el@0.27.3': + optional: true + + '@esbuild/linux-ppc64@0.27.3': + optional: true + + '@esbuild/linux-riscv64@0.27.3': + optional: true + + '@esbuild/linux-s390x@0.27.3': + optional: true + + '@esbuild/linux-x64@0.27.3': + optional: true + + '@esbuild/netbsd-arm64@0.27.3': + optional: true + + '@esbuild/netbsd-x64@0.27.3': + optional: true + + '@esbuild/openbsd-arm64@0.27.3': + optional: true + + '@esbuild/openbsd-x64@0.27.3': + optional: true + + '@esbuild/openharmony-arm64@0.27.3': + optional: true + + '@esbuild/sunos-x64@0.27.3': + optional: true + + '@esbuild/win32-arm64@0.27.3': + optional: true + + '@esbuild/win32-ia32@0.27.3': + optional: true + + '@esbuild/win32-x64@0.27.3': + optional: true + + '@img/colour@1.0.0': + optional: true + + '@img/sharp-darwin-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.2.4 + optional: true + + '@img/sharp-darwin-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.2.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.2.4': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-riscv64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-s390x@1.2.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + optional: true + + '@img/sharp-linux-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.2.4 + optional: true + + '@img/sharp-linux-arm@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.2.4 + optional: true + + '@img/sharp-linux-ppc64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-ppc64': 1.2.4 + optional: true + + '@img/sharp-linux-riscv64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-riscv64': 1.2.4 + optional: true + + '@img/sharp-linux-s390x@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.2.4 + optional: true + + '@img/sharp-linux-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.2.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + optional: true + + '@img/sharp-wasm32@0.34.5': + dependencies: + '@emnapi/runtime': 1.8.1 + optional: true + + '@img/sharp-win32-arm64@0.34.5': + optional: true + + '@img/sharp-win32-ia32@0.34.5': + optional: true + + '@img/sharp-win32-x64@0.34.5': + optional: true + + '@next/env@15.5.12': {} + + '@next/swc-darwin-arm64@15.5.12': + optional: true + + '@next/swc-darwin-x64@15.5.12': + optional: true + + '@next/swc-linux-arm64-gnu@15.5.12': + optional: true + + '@next/swc-linux-arm64-musl@15.5.12': + optional: true + + '@next/swc-linux-x64-gnu@15.5.12': + optional: true + + '@next/swc-linux-x64-musl@15.5.12': + optional: true + + '@next/swc-win32-arm64-msvc@15.5.12': + optional: true + + '@next/swc-win32-x64-msvc@15.5.12': + optional: true + + '@swc/helpers@0.5.15': + dependencies: + tslib: 2.8.1 + + '@types/node@25.2.3': + dependencies: + undici-types: 7.16.0 + + '@types/react-dom@19.2.3(@types/react@19.2.14)': + dependencies: + '@types/react': 19.2.14 + + '@types/react@19.2.14': + dependencies: + csstype: 3.2.3 + + ansi-regex@6.2.2: {} + + caniuse-lite@1.0.30001769: {} + + chalk@5.6.2: {} + + cli-cursor@5.0.0: + dependencies: + restore-cursor: 5.1.0 + + cli-spinners@2.9.2: {} + + client-only@0.0.1: {} + + commander@13.1.0: {} + + csstype@3.2.3: {} + + detect-libc@2.1.2: + optional: true + + emoji-regex@10.6.0: {} + + esbuild@0.27.3: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.3 + '@esbuild/android-arm': 0.27.3 + '@esbuild/android-arm64': 0.27.3 + '@esbuild/android-x64': 0.27.3 + '@esbuild/darwin-arm64': 0.27.3 + '@esbuild/darwin-x64': 0.27.3 + '@esbuild/freebsd-arm64': 0.27.3 + '@esbuild/freebsd-x64': 0.27.3 + '@esbuild/linux-arm': 0.27.3 + '@esbuild/linux-arm64': 0.27.3 + '@esbuild/linux-ia32': 0.27.3 + '@esbuild/linux-loong64': 0.27.3 + '@esbuild/linux-mips64el': 0.27.3 + '@esbuild/linux-ppc64': 0.27.3 + '@esbuild/linux-riscv64': 0.27.3 + '@esbuild/linux-s390x': 0.27.3 + '@esbuild/linux-x64': 0.27.3 + '@esbuild/netbsd-arm64': 0.27.3 + '@esbuild/netbsd-x64': 0.27.3 + '@esbuild/openbsd-arm64': 0.27.3 + '@esbuild/openbsd-x64': 0.27.3 + '@esbuild/openharmony-arm64': 0.27.3 + '@esbuild/sunos-x64': 0.27.3 + '@esbuild/win32-arm64': 0.27.3 + '@esbuild/win32-ia32': 0.27.3 + '@esbuild/win32-x64': 0.27.3 + + fsevents@2.3.3: + optional: true + + get-east-asian-width@1.4.0: {} + + get-tsconfig@4.13.6: + dependencies: + resolve-pkg-maps: 1.0.0 + + is-interactive@2.0.0: {} + + is-unicode-supported@1.3.0: {} + + is-unicode-supported@2.1.0: {} + + log-symbols@6.0.0: + dependencies: + chalk: 5.6.2 + is-unicode-supported: 1.3.0 + + mimic-function@5.0.1: {} + + nanoid@3.3.11: {} + + next@15.5.12(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + dependencies: + '@next/env': 15.5.12 + '@swc/helpers': 0.5.15 + caniuse-lite: 1.0.30001769 + postcss: 8.4.31 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + styled-jsx: 5.1.6(react@19.2.4) + optionalDependencies: + '@next/swc-darwin-arm64': 15.5.12 + '@next/swc-darwin-x64': 15.5.12 + '@next/swc-linux-arm64-gnu': 15.5.12 + '@next/swc-linux-arm64-musl': 15.5.12 + '@next/swc-linux-x64-gnu': 15.5.12 + '@next/swc-linux-x64-musl': 15.5.12 + '@next/swc-win32-arm64-msvc': 15.5.12 + '@next/swc-win32-x64-msvc': 15.5.12 + sharp: 0.34.5 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + + onetime@7.0.0: + dependencies: + mimic-function: 5.0.1 + + ora@8.2.0: + dependencies: + chalk: 5.6.2 + cli-cursor: 5.0.0 + cli-spinners: 2.9.2 + is-interactive: 2.0.0 + is-unicode-supported: 2.1.0 + log-symbols: 6.0.0 + stdin-discarder: 0.2.2 + string-width: 7.2.0 + strip-ansi: 7.1.2 + + picocolors@1.1.1: {} + + postcss@8.4.31: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + react-dom@19.2.4(react@19.2.4): + dependencies: + react: 19.2.4 + scheduler: 0.27.0 + + react@19.2.4: {} + + resolve-pkg-maps@1.0.0: {} + + restore-cursor@5.1.0: + dependencies: + onetime: 7.0.0 + signal-exit: 4.1.0 + + scheduler@0.27.0: {} + + semver@7.7.4: + optional: true + + sharp@0.34.5: + dependencies: + '@img/colour': 1.0.0 + detect-libc: 2.1.2 + semver: 7.7.4 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.34.5 + '@img/sharp-darwin-x64': 0.34.5 + '@img/sharp-libvips-darwin-arm64': 1.2.4 + '@img/sharp-libvips-darwin-x64': 1.2.4 + '@img/sharp-libvips-linux-arm': 1.2.4 + '@img/sharp-libvips-linux-arm64': 1.2.4 + '@img/sharp-libvips-linux-ppc64': 1.2.4 + '@img/sharp-libvips-linux-riscv64': 1.2.4 + '@img/sharp-libvips-linux-s390x': 1.2.4 + '@img/sharp-libvips-linux-x64': 1.2.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + '@img/sharp-linux-arm': 0.34.5 + '@img/sharp-linux-arm64': 0.34.5 + '@img/sharp-linux-ppc64': 0.34.5 + '@img/sharp-linux-riscv64': 0.34.5 + '@img/sharp-linux-s390x': 0.34.5 + '@img/sharp-linux-x64': 0.34.5 + '@img/sharp-linuxmusl-arm64': 0.34.5 + '@img/sharp-linuxmusl-x64': 0.34.5 + '@img/sharp-wasm32': 0.34.5 + '@img/sharp-win32-arm64': 0.34.5 + '@img/sharp-win32-ia32': 0.34.5 + '@img/sharp-win32-x64': 0.34.5 + optional: true + + signal-exit@4.1.0: {} + + source-map-js@1.2.1: {} + + stdin-discarder@0.2.2: {} + + string-width@7.2.0: + dependencies: + emoji-regex: 10.6.0 + get-east-asian-width: 1.4.0 + strip-ansi: 7.1.2 + + strip-ansi@7.1.2: + dependencies: + ansi-regex: 6.2.2 + + styled-jsx@5.1.6(react@19.2.4): + dependencies: + client-only: 0.0.1 + react: 19.2.4 + + tailwindcss@4.1.18: {} + + tslib@2.8.1: {} + + tsx@4.21.0: + dependencies: + esbuild: 0.27.3 + get-tsconfig: 4.13.6 + optionalDependencies: + fsevents: 2.3.3 + + typescript@5.9.3: {} + + undici-types@7.16.0: {} + + yaml@2.8.2: {} + + zod@3.25.76: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 000000000..bc6fa49a3 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,3 @@ +packages: + - "packages/*" + - "packages/plugins/*" diff --git a/tsconfig.base.json b/tsconfig.base.json new file mode 100644 index 000000000..3391bb37a --- /dev/null +++ b/tsconfig.base.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "Node16", + "moduleResolution": "Node16", + "lib": ["ES2022"], + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "isolatedModules": true, + "verbatimModuleSyntax": true, + "outDir": "dist", + "rootDir": "src" + } +}