Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .archon/workflows/e2e-claude-smoke.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# E2E smoke test — Claude provider
# Verifies: provider selection, sendQuery, structured output, tool use
name: e2e-claude-smoke
description: "E2E smoke test for Claude provider. Runs a simple prompt + structured output node."
provider: claude

nodes:
- id: simple
prompt: "What is 2+2? Answer with just the number, nothing else."

- id: structured
prompt: "Classify this input as 'math' or 'text': '2+2=4'"
output_format:
type: object
properties:
category:
type: string
enum: ["math", "text"]
depends_on: [simple]

- id: tool-use
prompt: "Read the file packages/providers/package.json and tell me the package name. Answer with just the name."
depends_on: [simple]
21 changes: 21 additions & 0 deletions .archon/workflows/e2e-codex-smoke.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# E2E smoke test — Codex provider
# Verifies: provider selection, sendQuery, structured output
name: e2e-codex-smoke
description: "E2E smoke test for Codex provider. Runs a simple prompt + structured output node."
provider: codex

nodes:
- id: simple
prompt: "What is 2+2? Answer with just the number, nothing else."

- id: structured
prompt: "Classify this input as 'math' or 'text': '2+2=4'. Return JSON only."
output_format:
type: object
properties:
category:
type: string
enum: ["math", "text"]
required: ["category"]
additionalProperties: false
depends_on: [simple]
18 changes: 13 additions & 5 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,9 +266,16 @@ packages/
│ ├── adapters/ # CLI adapter (stdout output)
│ ├── commands/ # CLI command implementations
│ └── cli.ts # CLI entry point
├── providers/ # @archon/providers - AI agent providers (SDK deps live here)
│ └── src/
│ ├── types.ts # Contract layer (IAgentProvider, SendQueryOptions, MessageChunk — ZERO SDK deps)
│ ├── factory.ts # getAgentProvider() switch (built-in: claude, codex)
│ ├── errors.ts # UnknownProviderError
│ ├── claude/ # ClaudeProvider + parseClaudeConfig + MCP/hooks/skills translation
│ ├── codex/ # CodexProvider + parseCodexConfig + binary-resolver
│ └── index.ts # Package exports
├── core/ # @archon/core - Shared business logic
│ └── src/
│ ├── providers/ # AI SDK providers (Claude, Codex)
│ ├── config/ # YAML config loading
│ ├── db/ # Database connection, queries
│ ├── handlers/ # Command handler (slash commands)
Expand All @@ -289,7 +296,7 @@ packages/
│ ├── executor.ts # Workflow execution orchestrator (executeWorkflow)
│ ├── dag-executor.ts # DAG-specific execution logic
│ ├── store.ts # IWorkflowStore interface (database abstraction)
│ ├── deps.ts # WorkflowDeps injection types (IWorkflowPlatform, IWorkflowAgentProvider)
│ ├── deps.ts # WorkflowDeps injection types (IWorkflowPlatform, imports from @archon/providers/types)
│ ├── event-emitter.ts # Workflow observability events
│ ├── logger.ts # JSONL file logger
│ ├── validator.ts # Resource validation (command files, MCP configs, skill dirs)
Expand Down Expand Up @@ -401,10 +408,11 @@ import type { DagNode, WorkflowDefinition } from '@/lib/api';
**Package Split:**
- **@archon/paths**: Path resolution utilities, Pino logger factory, web dist cache path (`getWebDistDir`), CWD env stripper (`stripCwdEnv`, `strip-cwd-env-boot`) (no @archon/* deps; `pino` and `dotenv` are allowed external deps)
- **@archon/git**: Git operations - worktrees, branches, repos, exec wrappers (depends only on @archon/paths)
- **@archon/providers**: AI agent providers (Claude, Codex) — owns SDK deps, `IAgentProvider` interface, `sendQuery()` contract, and provider-specific option translation. `@archon/providers/types` is the contract subpath (zero SDK deps, zero runtime side effects) that `@archon/workflows` imports from. Providers receive raw `nodeConfig` + `assistantConfig` and translate to SDK-specific options internally.
- **@archon/isolation**: Worktree isolation types, providers, resolver, error classifiers (depends only on @archon/git + @archon/paths)
- **@archon/workflows**: Workflow engine - loader, router, executor, DAG, logger, bundled defaults (depends only on @archon/git + @archon/paths + @hono/zod-openapi + zod; DB/AI/config injected via `WorkflowDeps`)
- **@archon/workflows**: Workflow engine - loader, router, executor, DAG, logger, bundled defaults (depends only on @archon/git + @archon/paths + @archon/providers/types + @hono/zod-openapi + zod; DB/AI/config injected via `WorkflowDeps`)
- **@archon/cli**: Command-line interface for running workflows and starting the web UI server (depends on @archon/server + @archon/adapters for the serve command)
- **@archon/core**: Business logic, database, orchestration, AI providers (provides `createWorkflowStore()` adapter bridging core DB → `IWorkflowStore`)
- **@archon/core**: Business logic, database, orchestration (depends on @archon/providers for AI; provides `createWorkflowStore()` adapter bridging core DB → `IWorkflowStore`)
- **@archon/adapters**: Platform adapters for Slack, Telegram, GitHub, Discord (depends on @archon/core)
- **@archon/server**: OpenAPIHono HTTP server (Zod + OpenAPI spec generation via `@hono/zod-openapi`), Web adapter (SSE), API routes, Web UI static serving (depends on @archon/adapters)
- **@archon/web**: React frontend (Vite + Tailwind v4 + shadcn/ui + Zustand), SSE streaming to server. `WorkflowRunStatus`, `WorkflowDefinition`, and `DagNode` are all derived from `src/lib/api.generated.d.ts` (generated from the OpenAPI spec via `bun generate:types`; never import from `@archon/workflows`)
Expand Down Expand Up @@ -440,7 +448,7 @@ import type { DagNode, WorkflowDefinition } from '@/lib/api';
- Session management: Create new or resume existing
- Stream AI responses to platform

**4. AI Agent Providers** (`packages/core/src/providers/`)
**4. AI Agent Providers** (`packages/providers/src/`)
- Implement `IAgentProvider` interface
- **ClaudeProvider**: `@anthropic-ai/claude-agent-sdk`
- **CodexProvider**: `@openai/codex-sdk`
Expand Down
3 changes: 3 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ COPY packages/docs-web/package.json ./packages/docs-web/
COPY packages/git/package.json ./packages/git/
COPY packages/isolation/package.json ./packages/isolation/
COPY packages/paths/package.json ./packages/paths/
COPY packages/providers/package.json ./packages/providers/
COPY packages/server/package.json ./packages/server/
COPY packages/web/package.json ./packages/web/
COPY packages/workflows/package.json ./packages/workflows/
Expand Down Expand Up @@ -130,6 +131,7 @@ COPY packages/docs-web/package.json ./packages/docs-web/
COPY packages/git/package.json ./packages/git/
COPY packages/isolation/package.json ./packages/isolation/
COPY packages/paths/package.json ./packages/paths/
COPY packages/providers/package.json ./packages/providers/
COPY packages/server/package.json ./packages/server/
COPY packages/web/package.json ./packages/web/
COPY packages/workflows/package.json ./packages/workflows/
Expand All @@ -144,6 +146,7 @@ COPY packages/core/ ./packages/core/
COPY packages/git/ ./packages/git/
COPY packages/isolation/ ./packages/isolation/
COPY packages/paths/ ./packages/paths/
COPY packages/providers/ ./packages/providers/
COPY packages/server/ ./packages/server/
COPY packages/workflows/ ./packages/workflows/

Expand Down
45 changes: 32 additions & 13 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export default tseslint.config(
'**/*.js',
'*.mjs',
'**/*.test.ts',
'**/src/test/**', // Test helper files (mock factories, fixtures)
'*.d.ts', // Root-level declaration files (not in tsconfig project scope)
'**/*.generated.d.ts', // Auto-generated declaration files (e.g. openapi-typescript output)
'packages/web/vite.config.ts', // Vite config doesn't need type-checked linting
Expand Down
1 change: 1 addition & 0 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"@archon/git": "workspace:*",
"@archon/isolation": "workspace:*",
"@archon/paths": "workspace:*",
"@archon/providers": "workspace:*",
"@archon/server": "workspace:*",
"@archon/workflows": "workspace:*",
"@clack/prompts": "^1.0.0",
Expand Down
6 changes: 2 additions & 4 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
"./types": "./src/types/index.ts",
"./db": "./src/db/index.ts",
"./db/*": "./src/db/*.ts",
"./providers": "./src/providers/index.ts",
"./operations": "./src/operations/index.ts",
"./operations/*": "./src/operations/*.ts",
"./workflows": "./src/workflows/index.ts",
Expand All @@ -23,17 +22,16 @@
"./state/*": "./src/state/*.ts"
},
"scripts": {
"test": "bun test src/providers/codex-binary-guard.test.ts && bun test src/utils/codex-binary-resolver.test.ts && bun test src/utils/codex-binary-resolver-dev.test.ts && bun test src/providers/claude.test.ts src/providers/codex.test.ts src/providers/factory.test.ts && bun test src/handlers/command-handler.test.ts && bun test src/handlers/clone.test.ts && bun test src/db/adapters/postgres.test.ts && bun test src/db/adapters/sqlite.test.ts src/db/codebases.test.ts src/db/connection.test.ts src/db/conversations.test.ts src/db/env-vars.test.ts src/db/isolation-environments.test.ts src/db/messages.test.ts src/db/sessions.test.ts src/db/workflow-events.test.ts src/db/workflows.test.ts src/utils/defaults-copy.test.ts src/utils/worktree-sync.test.ts src/utils/conversation-lock.test.ts src/utils/credential-sanitizer.test.ts src/utils/port-allocation.test.ts src/utils/error.test.ts src/utils/error-formatter.test.ts src/utils/github-graphql.test.ts src/utils/env-leak-scanner.test.ts src/config/ src/state/ && bun test src/utils/path-validation.test.ts && bun test src/services/cleanup-service.test.ts && bun test src/services/title-generator.test.ts && bun test src/workflows/ && bun test src/operations/workflow-operations.test.ts && bun test src/operations/isolation-operations.test.ts && bun test src/orchestrator/orchestrator.test.ts && bun test src/orchestrator/orchestrator-agent.test.ts && bun test src/orchestrator/orchestrator-isolation.test.ts",
"test": "bun test src/handlers/command-handler.test.ts && bun test src/handlers/clone.test.ts && bun test src/db/adapters/postgres.test.ts && bun test src/db/adapters/sqlite.test.ts src/db/codebases.test.ts src/db/connection.test.ts src/db/conversations.test.ts src/db/env-vars.test.ts src/db/isolation-environments.test.ts src/db/messages.test.ts src/db/sessions.test.ts src/db/workflow-events.test.ts src/db/workflows.test.ts src/utils/defaults-copy.test.ts src/utils/worktree-sync.test.ts src/utils/conversation-lock.test.ts src/utils/credential-sanitizer.test.ts src/utils/port-allocation.test.ts src/utils/error.test.ts src/utils/error-formatter.test.ts src/utils/github-graphql.test.ts src/utils/env-leak-scanner.test.ts src/config/ src/state/ && bun test src/utils/path-validation.test.ts && bun test src/services/cleanup-service.test.ts && bun test src/services/title-generator.test.ts && bun test src/workflows/ && bun test src/operations/workflow-operations.test.ts && bun test src/operations/isolation-operations.test.ts && bun test src/orchestrator/orchestrator.test.ts && bun test src/orchestrator/orchestrator-agent.test.ts && bun test src/orchestrator/orchestrator-isolation.test.ts",
"type-check": "bun x tsc --noEmit",
"build": "echo 'No build needed - Bun runs TypeScript directly'"
},
"dependencies": {
"@anthropic-ai/claude-agent-sdk": "^0.2.89",
"@archon/git": "workspace:*",
"@archon/isolation": "workspace:*",
"@archon/paths": "workspace:*",
"@archon/providers": "workspace:*",
"@archon/workflows": "workspace:*",
"@openai/codex-sdk": "^0.116.0",
"pg": "^8.11.0",
"zod": "^3"
},
Expand Down
29 changes: 8 additions & 21 deletions packages/core/src/config/config-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,12 @@
* Global configuration (non-secret user preferences)
* Located at ~/.archon/config.yaml
*/
import type { ModelReasoningEffort, WebSearchMode } from '../types';

export interface CodexProviderDefaults {
model?: string;
modelReasoningEffort?: ModelReasoningEffort;
webSearchMode?: WebSearchMode;
additionalDirectories?: string[];
/** Path to the Codex CLI binary. Overrides auto-detection in compiled Archon builds.
* Only relevant for the Codex provider; ignored for Claude. */
codexBinaryPath?: string;
}
// Provider config defaults — canonical definitions live in @archon/providers/types.
// Imported and re-exported here so existing consumers don't break.
import type { ClaudeProviderDefaults, CodexProviderDefaults } from '@archon/providers/types';

export interface ClaudeCodexProviderDefaults {
model?: string;
/** Claude Code settingSources — controls which CLAUDE.md files are loaded.
* @default ['project']
* @see https://github.com/anthropics/claude-agent-sdk */
settingSources?: ('project' | 'user')[];
}
export type { ClaudeProviderDefaults, CodexProviderDefaults };

export interface GlobalConfig {
/**
Expand All @@ -47,7 +34,7 @@ export interface GlobalConfig {
* Assistant-specific defaults (model, reasoning effort, etc.)
*/
assistants?: {
claude?: ClaudeCodexProviderDefaults;
claude?: ClaudeProviderDefaults;
codex?: CodexProviderDefaults;
};

Expand Down Expand Up @@ -118,7 +105,7 @@ export interface RepoConfig {
* Assistant-specific defaults for this repository
*/
assistants?: {
claude?: ClaudeCodexProviderDefaults;
claude?: ClaudeProviderDefaults;
codex?: CodexProviderDefaults;
};

Expand Down Expand Up @@ -217,7 +204,7 @@ export interface MergedConfig {
botName: string;
assistant: 'claude' | 'codex';
assistants: {
claude: ClaudeCodexProviderDefaults;
claude: ClaudeProviderDefaults;
codex: CodexProviderDefaults;
};
streaming: {
Expand Down Expand Up @@ -281,7 +268,7 @@ export interface SafeConfig {
botName: string;
assistant: 'claude' | 'codex';
assistants: {
claude: Pick<ClaudeCodexProviderDefaults, 'model'>;
claude: Pick<ClaudeProviderDefaults, 'model'>;
codex: Pick<CodexProviderDefaults, 'model' | 'modelReasoningEffort' | 'webSearchMode'>;
};
streaming: {
Expand Down
Loading
Loading