Files
wehub-resource-sync 23f7624596
ADR-166 MCP Bridge Security Lock / Static-source security lock (push) Failing after 0s
ADR-166 MCP Bridge Security Lock / Compose default binds loopback + Mongo has auth (push) Failing after 2s
CodeQL Advanced / Analyze (rust) (push) Failing after 0s
ADR-166 MCP Bridge Security Lock / plugin-agent-federation bindHost default (push) Failing after 1s
ADR-166 MCP Bridge Security Lock / Runtime behavior — 401 + terminal gate + fail-closed (push) Failing after 4s
business-pods-smoke / smoke (push) Failing after 1s
all-plugins-smoke / smoke-all (push) Failing after 2s
CI/CD Pipeline / Security & Code Quality (push) Failing after 1s
CI/CD Pipeline / Test Suite (ubuntu-latest) (push) Failing after 1s
CI/CD Pipeline / Build & Package (macos-latest) (push) Has been skipped
CI/CD Pipeline / Build & Package (ubuntu-latest) (push) Has been skipped
CI/CD Pipeline / Build & Package (windows-latest) (push) Has been skipped
CI/CD Pipeline / Documentation & Examples (push) Failing after 1s
Clone Tracker (14-day rolling) / Snapshot clones for ruflo ecosystem (push) Failing after 1s
CodeQL Advanced / Analyze (actions) (push) Failing after 1s
CodeQL Advanced / Analyze (javascript-typescript) (push) Failing after 1s
federation-peer-rust / stable-noop (push) Failing after 1s
metaharness-ci / score (push) Failing after 1s
metaharness-ci / router-compat (push) Failing after 0s
metaharness-ci / similarity-tests (push) Failing after 0s
no-agentbbs-smoke / smoke-without-agentbbs (push) Failing after 1s
V3 CI/CD Pipeline / Build V3 (windows-latest) (push) Has been skipped
codex-integration-audit / Codex integration audit (push) Failing after 1s
helpers-manifest-guard / guard (push) Failing after 1s
🔗 Cross-Agent Integration Tests / 🤝 Agent Coordination Tests (push) Has been skipped
🔗 Cross-Agent Integration Tests / 🧠 Memory Sharing Integration (push) Has been skipped
🔗 Cross-Agent Integration Tests / 🛡️ Fault Tolerance Tests (push) Has been skipped
🔗 Cross-Agent Integration Tests / ⚡ Performance Integration Tests (push) Has been skipped
metaharness-ci / mcp-scan (push) Failing after 1s
metaharness-ci / eject-dryrun (push) Failing after 1s
metaharness-ci / metaharness-real-data (push) Failing after 0s
no-cli-optdep-bloat-2561 / guard (push) Failing after 1s
no-metaharness-smoke / smoke-without-metaharness (push) Failing after 1s
no-phantom-agentic-flow-subpath / guard (push) Failing after 1s
🔄 Automated Rollback Manager / 🚨 Failure Detection (push) Failing after 1s
V3 CI/CD Pipeline / Plugin hooks smoke / ubuntu-latest / Node 22 (push) Failing after 1s
V3 CI/CD Pipeline / ruflo-graph-intelligence build + test smoke (#2044, ADR-123) (push) Failing after 1s
CVE Audit Gate / Audit root (critical-blocking) (push) Failing after 2s
cost-tracker-smoke / smoke (push) Failing after 3s
oia-audit-weekly / audit (push) Failing after 2s
ruflo-agent-smoke / ruflo-agent structural smoke (push) Failing after 1s
📊 Status Badges Update / 📊 Update Status Badges (push) Failing after 1s
V3 CI/CD Pipeline / Static regression guards (#2267 YAML + (push) Failing after 1s
V3 CI/CD Pipeline / Test V3 Packages (push) Failing after 0s
V3 CI/CD Pipeline / agent_execute provider routing smoke (#2042) (push) Failing after 0s
CVE Audit Gate / Audit v3 (critical-blocking) (push) Failing after 1s
federation-peer-rust / stable-native (push) Failing after 2s
🔗 Cross-Agent Integration Tests / 🚀 Integration Test Setup (push) Failing after 2s
neural-trader-smoke / runtime-smoke (push) Failing after 1s
V3 CI/CD Pipeline / Build V3 (macos-latest) (push) Has been skipped
V3 CI/CD Pipeline / Build V3 (ubuntu-latest) (push) Has been skipped
V3 CI/CD Pipeline / Type Check V3 (push) Failing after 1s
V3 CI/CD Pipeline / Smoke (no better-sqlite3) / ubuntu-latest / Node 24 (push) Failing after 1s
V3 CI/CD Pipeline / Smoke (no better-sqlite3) / ubuntu-latest / Node 22 (push) Failing after 2s
V3 CI/CD Pipeline / browser rvf create flag smoke (#2015) (push) Failing after 0s
V3 CI/CD Pipeline / Dependency review (#2046) (push) Has been skipped
V3 CI/CD Pipeline / Supply-chain audit (#2046) (push) Failing after 0s
V3 CI/CD Pipeline / witness marker drift smoke (#2021) (push) Failing after 1s
V3 CI/CD Pipeline / neural-trader portfolio CG smoke (#2068, ADR-126 Phase 3) (push) Failing after 1s
V3 CI/CD Pipeline / neural-trader backtest signing smoke (#2068, ADR-126 Phase 4) (push) Failing after 1s
V3 CI/CD Pipeline / kg-extract type-import classification smoke (#2049) (push) Failing after 0s
V3 CI/CD Pipeline / witness verify precondition smoke (#1880) (push) Failing after 2s
V3 CI/CD Pipeline / neural-trader pipeline risk-gate smoke (#2068, ADR-126 Phase 5) (push) Failing after 0s
V3 CI/CD Pipeline / neural-trader feature attribution smoke (#2068, ADR-126 Phase 6) (push) Failing after 0s
V3 CI/CD Pipeline / plugin-registry signature verification smoke (#1922, CWE-347) (push) Failing after 4s
V3 CI/CD Pipeline / memory stats legacy-DB smoke (#2120) (push) Failing after 4s
V3 CI/CD Pipeline / github deprecated actions smoke (#2089, ADR-127 Phase 3) (push) Failing after 1s
V3 CI/CD Pipeline / graph query + pathfinder smoke (ADR-130 P2+P5) (push) Has been skipped
V3 CI/CD Pipeline / graph trajectory hooks smoke (ADR-130 P3) (push) Has been skipped
V3 CI/CD Pipeline / graph plugin adapter smoke (ADR-130 P4) (push) Has been skipped
V3 CI/CD Pipeline / graph benchmark (ADR-130 P6) (push) Has been skipped
V3 CI/CD Pipeline / statusline generator delegation smoke (#2195) (push) Failing after 1s
V3 CI/CD Pipeline / wizard init regression guard (#2206 (push) Failing after 1s
V3 CI/CD Pipeline / memory no-stray-db smoke (ADR-125 P7) (push) Failing after 1s
V3 CI/CD Pipeline / github-safe injection smoke (#2089, ADR-127 Phase 1) (push) Failing after 1s
V3 CI/CD Pipeline / github actions pin smoke (#2089, ADR-127 Phase 1) (push) Failing after 1s
V3 CI/CD Pipeline / github attribution opt-in smoke (#2089, ADR-127 Phase 4) (push) Failing after 1s
V3 CI/CD Pipeline / pre-bash hook safety smoke (#2017) (push) Failing after 1s
V3 CI/CD Pipeline / Memory import smoke / ubuntu-latest (push) Failing after 0s
V3 CI/CD Pipeline / MCP protocol smoke / ubuntu-latest (push) Failing after 2s
V3 CI/CD Pipeline / ruvllm WASM auto-init smoke (#2086) (push) Failing after 4s
V3 CI/CD Pipeline / MCP paired-tool round-trip smoke (#1889) (push) Failing after 1s
V3 CI/CD Pipeline / Plugin package install-safety (#1902/#1903/#1904) (push) Failing after 1s
V3 CI/CD Pipeline / Tool description discoverability (ADR-112) (push) Failing after 3s
V3 CI/CD Pipeline / CLI npx-install smoke (#1147 / (22) (push) Failing after 1s
V3 CI/CD Pipeline / CLI npx-install smoke (#1147 / (24) (push) Failing after 1s
V3 CI/CD Pipeline / Windows hook shim smoke (#2132) / ubuntu-latest (push) Failing after 2s
V3 CI/CD Pipeline / Windows hook execution smoke (#2132) / ubuntu-latest (push) Failing after 1s
V3 CI/CD Pipeline / Windows init hooks smoke (#2132) / ubuntu-latest (push) Failing after 1s
V3 CI/CD Pipeline / Vector-index dimension audit (#1947) (push) Failing after 0s
V3 CI/CD Pipeline / Hook-command install safety (#1921) (push) Failing after 1s
V3 CI/CD Pipeline / ToolOutputGuardrail smoke (ADR-131, (push) Failing after 1s
V3 CI/CD Pipeline / init-bundle invariants smoke (#2095, ADR-128 Phase 5) (push) Failing after 1s
V3 CI/CD Pipeline / wasm provider bridge smoke (ADR-129 P1) (push) Failing after 2s
V3 CI/CD Pipeline / wasm gallery CRUD smoke (ADR-129 P3) (push) Failing after 1s
V3 CI/CD Pipeline / wasm plugin bridge smoke (ADR-129 P4) (push) Failing after 0s
V3 CI/CD Pipeline / wasm compose smoke (ADR-129 P2) (push) Failing after 4s
V3 CI/CD Pipeline / graph schema smoke (ADR-130 P1) (push) Failing after 0s
Validate Marketplace / validate (push) Failing after 1s
🔍 Verification Pipeline / 🚀 Setup Verification (push) Failing after 1s
🔍 Verification Pipeline / 🛡️ Security Verification (push) Has been skipped
🔍 Verification Pipeline / 📝 Code Quality (push) Has been skipped
🔍 Verification Pipeline / 🧪 Test Verification (${{ matrix.os }}, Node ${{ matrix.node }}) (push) Has been skipped
🔍 Verification Pipeline / 🏗️ Build Verification (push) Has been skipped
🔍 Verification Pipeline / 📚 Documentation Verification (push) Has been skipped
CVE Audit Gate / High-severity report (warn only) (push) Has been cancelled
🔄 Automated Rollback Manager / 🔄 Execute Rollback (push) Has been cancelled
🔄 Automated Rollback Manager / ✅ Post-Rollback Verification (push) Has been cancelled
🔄 Automated Rollback Manager / 📊 Rollback Monitoring (push) Has been cancelled
V3 CI/CD Pipeline / Windows init hooks smoke (#2132) / windows-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows hook execution smoke (#2132) / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows hook execution smoke (#2132) / windows-latest (push) Has been cancelled
🔄 Automated Rollback Manager / ⏳ Manual Rollback Approval (push) Has been cancelled
V3 CI/CD Pipeline / MCP protocol smoke / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Memory import smoke / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows hook shim smoke (#2132) / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows hook shim smoke (#2132) / windows-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows init hooks smoke (#2132) / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Witness verify (signed manifest) / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Witness verify (signed manifest) / ubuntu-latest (push) Has been cancelled
V3 CI/CD Pipeline / Witness verify (signed manifest) / windows-latest (push) Has been cancelled
V3 CI/CD Pipeline / Publish to npm (alpha) (push) Has been cancelled
V3 CI/CD Pipeline / Smoke (no better-sqlite3) / macos-latest / Node 22 (push) Has been cancelled
V3 CI/CD Pipeline / Plugin hooks smoke / macos-latest / Node 22 (push) Has been cancelled
CI/CD Pipeline / Deploy & Release (push) Has been cancelled
CI/CD Pipeline / CI Status (push) Has been cancelled
🔗 Cross-Agent Integration Tests / 📊 Integration Test Report (push) Has been cancelled
🔄 Automated Rollback Manager / 🔍 Pre-Rollback Validation (push) Has been cancelled
🔍 Verification Pipeline / ⚡ Performance Verification (push) Has been cancelled
🔍 Verification Pipeline / 📊 Verification Report (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:02:19 +08:00

29 KiB

ADR-027 Supplement: Domain-Driven Design for Codex Integration

Overview

This document defines the Domain-Driven Design (DDD) architecture for integrating OpenAI Codex support into claude-flow via the @claude-flow/codex package. The design follows the existing V3 architecture patterns while introducing new bounded contexts for Codex-specific functionality.

Package Information

  • Package Name: @claude-flow/codex
  • Location: v3/@claude-flow/codex/
  • Future Umbrella: coflow (npm/npx coflow)
  • Compatibility: Maintains claude-flow branding during transition

Strategic Design

Domain Vision

┌─────────────────────────────────────────────────────────────────────────────┐
│                           Claude Flow V3 Core Domain                         │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  ┌─────────────────┐  ┌─────────────────┐  ┌─────────────────────────────┐ │
│  │  Agent Domain   │  │  Memory Domain  │  │   Coordination Domain      │ │
│  │                 │  │                 │  │                             │ │
│  │  - Spawning     │  │  - AgentDB      │  │  - Swarm                   │ │
│  │  - Lifecycle    │  │  - HNSW         │  │  - Consensus               │ │
│  │  - Metrics      │  │  - Patterns     │  │  - Hive-Mind               │ │
│  └─────────────────┘  └─────────────────┘  └─────────────────────────────┘ │
│                                                                              │
│  ┌─────────────────────────────────────────────────────────────────────────┐│
│  │                     Platform Adaptation Layer                           ││
│  ├─────────────────────────────────────────────────────────────────────────┤│
│  │  ┌─────────────────────────┐    ┌─────────────────────────────────────┐││
│  │  │   Claude Code Context   │    │       Codex Context (NEW)          │││
│  │  │                         │    │                                     │││
│  │  │  - CLAUDE.md Generator  │    │  - AGENTS.md Generator             │││
│  │  │  - Skills (.md format)  │    │  - Skills (SKILL.md format)        │││
│  │  │  - settings.json        │    │  - config.toml                      │││
│  │  │  - Hooks System         │    │  - Automations                      │││
│  │  │  - .mcp.json            │    │  - MCP [mcp_servers]               │││
│  │  └─────────────────────────┘    └─────────────────────────────────────┘││
│  └─────────────────────────────────────────────────────────────────────────┘│
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

Bounded Contexts

1. Platform Adapter Context (New)

Purpose: Abstract platform-specific configurations behind a unified interface.

Ubiquitous Language:

  • Platform: Target CLI tool (Claude Code or Codex)
  • Manifest: Platform-specific project instructions file (CLAUDE.md or AGENTS.md)
  • Skill: Reusable task-specific instruction set
  • Configuration: Platform settings (JSON or TOML)
  • Automation: Scheduled or triggered background tasks

Aggregate Roots:

  • PlatformConfiguration
  • SkillLibrary
  • ManifestDocument

2. Codex Adapter Context (New)

Purpose: Handle all Codex-specific generation and configuration.

Ubiquitous Language:

  • AGENTS.md: Project instruction file for Codex
  • SKILL.md: Skill definition file with YAML frontmatter
  • config.toml: TOML configuration file
  • Approval Policy: Permission level for command execution
  • Sandbox Mode: Filesystem access restrictions
  • Progressive Disclosure: Lazy loading of skill instructions

3. Claude Code Adapter Context (Existing)

Purpose: Handle all Claude Code-specific generation (already implemented).

4. Init Context (Extended)

Purpose: Orchestrate project initialization across platforms.

Extensions:

  • Platform selection strategy
  • Dual-mode initialization
  • Cross-platform conversion

Tactical Design

Entities

PlatformConfiguration (Aggregate Root)

interface PlatformConfiguration {
  id: string;
  platform: Platform;
  manifestPath: string;
  skillsPath: string;
  configPath: string;
  createdAt: Date;
  updatedAt: Date;

  // Behavior
  validate(): ValidationResult;
  toJSON(): object;
  toTOML(): string;
}

enum Platform {
  CLAUDE_CODE = 'claude-code',
  CODEX = 'codex',
  DUAL = 'dual'
}

ManifestDocument (Entity)

interface ManifestDocument {
  id: string;
  platform: Platform;
  sections: ManifestSection[];
  byteSize: number;

  // Behavior
  addSection(section: ManifestSection): void;
  removeSection(sectionName: string): void;
  render(): string;
  validate(): ValidationResult;
}

interface ManifestSection {
  name: string;
  content: string;
  order: number;
  required: boolean;
}

Skill (Entity)

interface Skill {
  id: string;
  name: string;
  description: string;
  platform: Platform;

  // For Codex
  metadata?: SkillMetadata;
  scripts?: SkillScript[];
  references?: SkillReference[];
  assets?: SkillAsset[];

  // Behavior
  toClaudeFormat(): string;
  toCodexFormat(): SkillDirectory;
}

interface SkillMetadata {
  name: string;
  description: string;
  triggers?: string[];
  skipWhen?: string[];
}

interface SkillDirectory {
  path: string;
  skillMd: string;
  scripts: Map<string, string>;
  references: Map<string, string>;
  assets: Map<string, Buffer>;
  agentsYaml?: string;
}

CodexConfiguration (Entity)

interface CodexConfiguration {
  // Core settings
  model: string;
  approvalPolicy: ApprovalPolicy;
  sandboxMode: SandboxMode;
  webSearch: WebSearchMode;

  // Features
  features: FeatureFlags;

  // MCP servers
  mcpServers: Map<string, MCPServerConfig>;

  // Skills
  skills: SkillConfig[];

  // Profiles
  profiles: Map<string, ProfileConfig>;

  // Behavior
  toTOML(): string;
  validate(): ValidationResult;
  merge(other: Partial<CodexConfiguration>): CodexConfiguration;
}

enum ApprovalPolicy {
  UNTRUSTED = 'untrusted',
  ON_FAILURE = 'on-failure',
  ON_REQUEST = 'on-request',
  NEVER = 'never'
}

enum SandboxMode {
  READ_ONLY = 'read-only',
  WORKSPACE_WRITE = 'workspace-write',
  FULL_ACCESS = 'danger-full-access'
}

enum WebSearchMode {
  DISABLED = 'disabled',
  CACHED = 'cached',
  LIVE = 'live'
}

Value Objects

SkillIdentifier

class SkillIdentifier {
  constructor(
    public readonly name: string,
    public readonly scope: SkillScope
  ) {
    this.validate();
  }

  private validate(): void {
    if (!this.name.match(/^[a-z0-9-]+$/)) {
      throw new InvalidSkillNameError(this.name);
    }
  }

  get path(): string {
    return `${this.scope.basePath}/${this.name}`;
  }

  equals(other: SkillIdentifier): boolean {
    return this.name === other.name && this.scope.equals(other.scope);
  }
}

class SkillScope {
  constructor(
    public readonly type: 'repository' | 'user' | 'admin' | 'system',
    public readonly basePath: string
  ) {}

  equals(other: SkillScope): boolean {
    return this.type === other.type && this.basePath === other.basePath;
  }
}

ManifestPath

class ManifestPath {
  constructor(
    public readonly platform: Platform,
    public readonly projectRoot: string,
    public readonly isOverride: boolean = false
  ) {}

  get filename(): string {
    if (this.platform === Platform.CODEX) {
      return this.isOverride ? 'AGENTS.override.md' : 'AGENTS.md';
    }
    return this.isOverride ? 'CLAUDE.local.md' : 'CLAUDE.md';
  }

  get fullPath(): string {
    return path.join(this.projectRoot, this.filename);
  }
}

ConfigurationPath

class ConfigurationPath {
  constructor(
    public readonly platform: Platform,
    public readonly scope: 'global' | 'project',
    public readonly basePath: string
  ) {}

  get fullPath(): string {
    if (this.platform === Platform.CODEX) {
      return this.scope === 'global'
        ? path.join(os.homedir(), '.codex', 'config.toml')
        : path.join(this.basePath, '.agents', 'config.toml');
    }
    return this.scope === 'global'
      ? path.join(os.homedir(), '.claude', 'settings.json')
      : path.join(this.basePath, '.claude', 'settings.json');
  }
}

Aggregates

PlatformInitializationAggregate

class PlatformInitializationAggregate {
  private readonly id: string;
  private platform: Platform;
  private manifest: ManifestDocument;
  private skills: SkillLibrary;
  private configuration: PlatformConfiguration;
  private events: DomainEvent[] = [];

  constructor(options: InitializationOptions) {
    this.id = generateId();
    this.platform = options.platform;
  }

  // Commands
  initialize(options: InitOptions): InitResult {
    this.validatePreconditions(options);

    // Generate manifest
    this.manifest = this.generateManifest(options);
    this.events.push(new ManifestGenerated(this.manifest));

    // Generate skills
    this.skills = this.generateSkills(options);
    this.events.push(new SkillsGenerated(this.skills));

    // Generate configuration
    this.configuration = this.generateConfiguration(options);
    this.events.push(new ConfigurationGenerated(this.configuration));

    return this.buildResult();
  }

  convertFromOtherPlatform(source: Platform): ConversionResult {
    // Read existing configuration
    const existing = this.readExistingConfiguration(source);

    // Map to target platform
    const mapped = this.mapConfiguration(existing);

    // Generate new artifacts
    return this.generateFromMapped(mapped);
  }

  // Queries
  getGeneratedFiles(): GeneratedFile[] {
    return [
      ...this.manifest.getFiles(),
      ...this.skills.getFiles(),
      ...this.configuration.getFiles()
    ];
  }

  getDomainEvents(): DomainEvent[] {
    return [...this.events];
  }
}

SkillLibraryAggregate

class SkillLibraryAggregate {
  private readonly skills: Map<string, Skill> = new Map();
  private readonly platform: Platform;

  constructor(platform: Platform) {
    this.platform = platform;
  }

  addSkill(skill: Skill): void {
    if (this.skills.has(skill.name)) {
      throw new DuplicateSkillError(skill.name);
    }
    this.skills.set(skill.name, skill);
  }

  getSkill(name: string): Skill | undefined {
    return this.skills.get(name);
  }

  getAllSkills(): Skill[] {
    return Array.from(this.skills.values());
  }

  generateForPlatform(): SkillOutput[] {
    return this.getAllSkills().map(skill => {
      if (this.platform === Platform.CODEX) {
        return skill.toCodexFormat();
      }
      return skill.toClaudeFormat();
    });
  }

  convertTo(targetPlatform: Platform): SkillLibraryAggregate {
    const newLibrary = new SkillLibraryAggregate(targetPlatform);
    for (const skill of this.skills.values()) {
      newLibrary.addSkill(skill.cloneForPlatform(targetPlatform));
    }
    return newLibrary;
  }
}

Domain Services

PlatformDetectionService

class PlatformDetectionService {
  detect(projectPath: string): DetectedPlatform {
    const hasClaudeDir = fs.existsSync(path.join(projectPath, '.claude'));
    const hasAgentsDir = fs.existsSync(path.join(projectPath, '.agents'));
    const hasClaudeMd = fs.existsSync(path.join(projectPath, 'CLAUDE.md'));
    const hasAgentsMd = fs.existsSync(path.join(projectPath, 'AGENTS.md'));

    if (hasClaudeDir && hasAgentsDir) {
      return { platform: Platform.DUAL, existing: true };
    }
    if (hasClaudeDir || hasClaudeMd) {
      return { platform: Platform.CLAUDE_CODE, existing: true };
    }
    if (hasAgentsDir || hasAgentsMd) {
      return { platform: Platform.CODEX, existing: true };
    }

    return { platform: Platform.UNKNOWN, existing: false };
  }

  async detectUserPreference(): Promise<Platform> {
    // Check for global Codex config
    const codexConfig = path.join(os.homedir(), '.codex', 'config.toml');
    const claudeConfig = path.join(os.homedir(), '.claude');

    const hasCodex = fs.existsSync(codexConfig);
    const hasClaude = fs.existsSync(claudeConfig);

    if (hasCodex && !hasClaude) return Platform.CODEX;
    if (hasClaude && !hasCodex) return Platform.CLAUDE_CODE;
    if (hasCodex && hasClaude) return Platform.DUAL;

    return Platform.UNKNOWN;
  }
}

SkillConversionService

class SkillConversionService {
  convertClaudeToCodex(skill: ClaudeSkill): CodexSkill {
    // Parse YAML frontmatter from Claude skill
    const { metadata, content } = this.parseClaudeSkill(skill);

    // Create SKILL.md content
    const skillMd = this.generateSkillMd(metadata, content);

    // Extract scripts if any code blocks present
    const scripts = this.extractScripts(content);

    // Extract references (links to docs)
    const references = this.extractReferences(content);

    return new CodexSkill({
      name: metadata.name || skill.name,
      description: metadata.description || '',
      skillMd,
      scripts,
      references
    });
  }

  convertCodexToClaude(skill: CodexSkill): ClaudeSkill {
    // Parse SKILL.md
    const { frontmatter, body } = this.parseSkillMd(skill.skillMd);

    // Generate Claude skill format
    const claudeContent = this.generateClaudeSkill(frontmatter, body);

    return new ClaudeSkill({
      name: frontmatter.name,
      content: claudeContent
    });
  }

  private generateSkillMd(metadata: SkillMetadata, content: string): string {
    return `---
name: ${metadata.name}
description: ${metadata.description}
---

${content}`;
  }
}

ConfigurationMigrationService

class ConfigurationMigrationService {
  migrateClaudeToCodex(claudeSettings: ClaudeSettings): CodexConfiguration {
    return {
      model: 'gpt-5.3-codex',
      approvalPolicy: this.mapApprovalPolicy(claudeSettings),
      sandboxMode: this.mapSandboxMode(claudeSettings),
      webSearch: 'cached',
      features: this.mapFeatures(claudeSettings),
      mcpServers: this.migrateMcpServers(claudeSettings.mcpServers),
      skills: this.mapSkillsConfig(claudeSettings),
      profiles: new Map()
    };
  }

  migrateCodexToClaude(codexConfig: CodexConfiguration): ClaudeSettings {
    return {
      hooks: this.mapHooksFromApprovalPolicy(codexConfig.approvalPolicy),
      mcpServers: this.migrateMcpServersToJson(codexConfig.mcpServers),
      // ... other mappings
    };
  }

  private mapApprovalPolicy(settings: ClaudeSettings): ApprovalPolicy {
    // Map Claude Code permission mode to Codex approval policy
    const hooks = settings.hooks || {};
    if (hooks.preToolUse?.autoApprove) {
      return ApprovalPolicy.NEVER;
    }
    return ApprovalPolicy.ON_REQUEST;
  }

  private mapSandboxMode(settings: ClaudeSettings): SandboxMode {
    // Default to workspace-write for safety
    return SandboxMode.WORKSPACE_WRITE;
  }
}

Repositories

ManifestRepository

interface ManifestRepository {
  save(manifest: ManifestDocument): Promise<void>;
  load(path: ManifestPath): Promise<ManifestDocument | null>;
  exists(path: ManifestPath): Promise<boolean>;
  delete(path: ManifestPath): Promise<void>;
}

class FileSystemManifestRepository implements ManifestRepository {
  async save(manifest: ManifestDocument): Promise<void> {
    const content = manifest.render();
    await fs.writeFile(manifest.path.fullPath, content, 'utf-8');
  }

  async load(path: ManifestPath): Promise<ManifestDocument | null> {
    if (!await this.exists(path)) {
      return null;
    }
    const content = await fs.readFile(path.fullPath, 'utf-8');
    return ManifestDocument.parse(content, path.platform);
  }

  async exists(path: ManifestPath): Promise<boolean> {
    return fs.existsSync(path.fullPath);
  }

  async delete(path: ManifestPath): Promise<void> {
    await fs.unlink(path.fullPath);
  }
}

SkillRepository

interface SkillRepository {
  save(skill: Skill, scope: SkillScope): Promise<void>;
  load(identifier: SkillIdentifier): Promise<Skill | null>;
  list(scope: SkillScope): Promise<Skill[]>;
  delete(identifier: SkillIdentifier): Promise<void>;
}

class CodexSkillRepository implements SkillRepository {
  async save(skill: Skill, scope: SkillScope): Promise<void> {
    const directory = skill.toCodexFormat();
    const skillPath = path.join(scope.basePath, skill.name);

    // Create directory structure
    await fs.mkdir(skillPath, { recursive: true });
    await fs.mkdir(path.join(skillPath, 'scripts'), { recursive: true });
    await fs.mkdir(path.join(skillPath, 'references'), { recursive: true });

    // Write SKILL.md
    await fs.writeFile(
      path.join(skillPath, 'SKILL.md'),
      directory.skillMd,
      'utf-8'
    );

    // Write scripts
    for (const [name, content] of directory.scripts) {
      await fs.writeFile(
        path.join(skillPath, 'scripts', name),
        content,
        'utf-8'
      );
    }

    // Write references
    for (const [name, content] of directory.references) {
      await fs.writeFile(
        path.join(skillPath, 'references', name),
        content,
        'utf-8'
      );
    }

    // Write openai.yaml if present
    if (directory.agentsYaml) {
      await fs.mkdir(path.join(skillPath, 'agents'), { recursive: true });
      await fs.writeFile(
        path.join(skillPath, 'agents', 'openai.yaml'),
        directory.agentsYaml,
        'utf-8'
      );
    }
  }

  async load(identifier: SkillIdentifier): Promise<Skill | null> {
    const skillPath = identifier.path;
    const skillMdPath = path.join(skillPath, 'SKILL.md');

    if (!fs.existsSync(skillMdPath)) {
      return null;
    }

    const skillMd = await fs.readFile(skillMdPath, 'utf-8');
    const scripts = await this.loadDirectory(path.join(skillPath, 'scripts'));
    const references = await this.loadDirectory(path.join(skillPath, 'references'));

    return Skill.fromCodexFormat({
      skillMd,
      scripts,
      references,
      path: skillPath
    });
  }

  private async loadDirectory(dirPath: string): Promise<Map<string, string>> {
    const result = new Map<string, string>();
    if (!fs.existsSync(dirPath)) {
      return result;
    }

    const files = await fs.readdir(dirPath);
    for (const file of files) {
      const content = await fs.readFile(path.join(dirPath, file), 'utf-8');
      result.set(file, content);
    }
    return result;
  }
}

Application Services

InitializationApplicationService

class InitializationApplicationService {
  constructor(
    private readonly platformDetection: PlatformDetectionService,
    private readonly manifestRepo: ManifestRepository,
    private readonly skillRepo: SkillRepository,
    private readonly configRepo: ConfigurationRepository,
    private readonly conversionService: SkillConversionService
  ) {}

  async initializeForCodex(options: CodexInitOptions): Promise<InitResult> {
    // Check for existing configuration
    const detected = this.platformDetection.detect(options.projectPath);

    if (detected.existing && !options.force) {
      throw new ExistingConfigurationError(detected.platform);
    }

    // Create aggregate
    const aggregate = new PlatformInitializationAggregate({
      platform: Platform.CODEX,
      projectPath: options.projectPath
    });

    // Generate artifacts
    const result = aggregate.initialize(options);

    // Persist artifacts
    await this.manifestRepo.save(result.manifest);
    for (const skill of result.skills) {
      await this.skillRepo.save(skill, new SkillScope('repository', options.projectPath));
    }
    await this.configRepo.save(result.configuration);

    // Emit domain events
    for (const event of aggregate.getDomainEvents()) {
      await this.eventBus.publish(event);
    }

    return result;
  }

  async convertToCodex(projectPath: string): Promise<ConversionResult> {
    // Load existing Claude Code configuration
    const claudeManifest = await this.loadClaudeManifest(projectPath);
    const claudeSkills = await this.loadClaudeSkills(projectPath);
    const claudeSettings = await this.loadClaudeSettings(projectPath);

    // Convert manifest
    const codexManifest = this.convertManifest(claudeManifest);

    // Convert skills
    const codexSkills = claudeSkills.map(skill =>
      this.conversionService.convertClaudeToCodex(skill)
    );

    // Convert configuration
    const codexConfig = this.configMigration.migrateClaudeToCodex(claudeSettings);

    // Save converted artifacts
    await this.manifestRepo.save(codexManifest);
    for (const skill of codexSkills) {
      await this.skillRepo.save(skill, new SkillScope('repository', projectPath));
    }
    await this.configRepo.save(codexConfig);

    return {
      success: true,
      manifest: codexManifest,
      skills: codexSkills,
      configuration: codexConfig
    };
  }

  async initializeDualMode(options: DualModeInitOptions): Promise<DualModeResult> {
    // Initialize for Claude Code
    const claudeResult = await this.initializeForClaude(options);

    // Initialize for Codex
    const codexResult = await this.initializeForCodex(options);

    // Create sync configuration to keep them in sync
    await this.createSyncConfiguration(options.projectPath);

    return {
      claude: claudeResult,
      codex: codexResult,
      syncConfigPath: path.join(options.projectPath, '.claude-flow', 'platform-sync.yaml')
    };
  }
}

Domain Events

interface DomainEvent {
  eventId: string;
  timestamp: Date;
  aggregateId: string;
}

class ManifestGenerated implements DomainEvent {
  eventId: string;
  timestamp: Date;
  aggregateId: string;

  constructor(
    public readonly manifest: ManifestDocument,
    public readonly platform: Platform
  ) {
    this.eventId = generateEventId();
    this.timestamp = new Date();
    this.aggregateId = manifest.id;
  }
}

class SkillsGenerated implements DomainEvent {
  eventId: string;
  timestamp: Date;
  aggregateId: string;

  constructor(
    public readonly skills: Skill[],
    public readonly platform: Platform
  ) {
    this.eventId = generateEventId();
    this.timestamp = new Date();
    this.aggregateId = skills[0]?.id || 'unknown';
  }
}

class ConfigurationGenerated implements DomainEvent {
  eventId: string;
  timestamp: Date;
  aggregateId: string;

  constructor(
    public readonly configuration: PlatformConfiguration
  ) {
    this.eventId = generateEventId();
    this.timestamp = new Date();
    this.aggregateId = configuration.id;
  }
}

class PlatformConversionCompleted implements DomainEvent {
  eventId: string;
  timestamp: Date;
  aggregateId: string;

  constructor(
    public readonly sourcePlatform: Platform,
    public readonly targetPlatform: Platform,
    public readonly projectPath: string
  ) {
    this.eventId = generateEventId();
    this.timestamp = new Date();
    this.aggregateId = projectPath;
  }
}

Package Structure

v3/@claude-flow/
├── cli/
│   └── src/
│       └── commands/
│           └── init.ts              # Extended with --codex flag
│
├── codex/                           # NEW PACKAGE
│   ├── package.json
│   ├── src/
│   │   ├── index.ts
│   │   ├── domain/
│   │   │   ├── entities/
│   │   │   │   ├── manifest.ts
│   │   │   │   ├── skill.ts
│   │   │   │   └── configuration.ts
│   │   │   ├── value-objects/
│   │   │   │   ├── skill-identifier.ts
│   │   │   │   ├── manifest-path.ts
│   │   │   │   └── configuration-path.ts
│   │   │   ├── aggregates/
│   │   │   │   ├── initialization.ts
│   │   │   │   └── skill-library.ts
│   │   │   ├── services/
│   │   │   │   ├── platform-detection.ts
│   │   │   │   ├── skill-conversion.ts
│   │   │   │   └── config-migration.ts
│   │   │   └── events/
│   │   │       └── domain-events.ts
│   │   ├── application/
│   │   │   ├── initialization-service.ts
│   │   │   └── conversion-service.ts
│   │   ├── infrastructure/
│   │   │   ├── repositories/
│   │   │   │   ├── manifest-repository.ts
│   │   │   │   ├── skill-repository.ts
│   │   │   │   └── config-repository.ts
│   │   │   └── generators/
│   │   │       ├── agents-md-generator.ts
│   │   │       ├── skill-md-generator.ts
│   │   │       └── config-toml-generator.ts
│   │   └── templates/
│   │       ├── agents-md/
│   │       │   ├── default.md
│   │       │   ├── minimal.md
│   │       │   └── full.md
│   │       ├── skills/
│   │       │   ├── swarm-orchestration/
│   │       │   ├── memory-management/
│   │       │   └── ...
│   │       └── config/
│   │           ├── default.toml
│   │           └── profiles/
│   └── tests/
│       ├── unit/
│       └── integration/
│
└── shared/
    └── src/
        └── platform/
            └── types.ts              # Shared platform types

Integration Points

With Existing Init System

// v3/@claude-flow/cli/src/commands/init.ts

import { CodexInitializer } from '@claude-flow/codex';

// Add new options
const initCommand: Command = {
  name: 'init',
  options: [
    // ... existing options ...
    {
      name: 'codex',
      description: 'Initialize for OpenAI Codex',
      type: 'boolean',
      default: false,
    },
    {
      name: 'dual',
      description: 'Initialize for both Claude Code and Codex',
      type: 'boolean',
      default: false,
    },
    {
      name: 'from-claude',
      description: 'Convert existing Claude Code setup to Codex',
      type: 'boolean',
      default: false,
    },
    {
      name: 'from-codex',
      description: 'Convert existing Codex setup to Claude Code',
      type: 'boolean',
      default: false,
    },
  ],
  action: async (ctx) => {
    const codex = ctx.flags.codex as boolean;
    const dual = ctx.flags.dual as boolean;
    const fromClaude = ctx.flags['from-claude'] as boolean;
    const fromCodex = ctx.flags['from-codex'] as boolean;

    if (codex || dual) {
      const initializer = new CodexInitializer();
      // ... codex initialization logic
    }

    if (fromClaude) {
      const converter = new PlatformConverter();
      await converter.convertToCodex(ctx.cwd);
    }

    // ... existing Claude Code init logic
  }
};

Summary

This DDD design provides:

  1. Clear Bounded Contexts - Platform Adapter, Codex Adapter, Claude Code Adapter
  2. Rich Domain Model - Entities, Value Objects, Aggregates for each concept
  3. Domain Services - Platform detection, skill conversion, config migration
  4. Repository Pattern - Abstract persistence for manifests, skills, configurations
  5. Event Sourcing Ready - Domain events for all significant state changes
  6. Extensibility - New platforms can be added by implementing the adapter interface

The design maintains consistency with V3's existing DDD patterns while introducing the flexibility needed to support multiple agentic coding platforms.