Round 2 regression fixes: - B10 (INV-2 outbox, CRITICAL): wiring.ts — switch durable events from eventBus.publish (live-only) to eventIngestor.ingest (persistent) for debug.record.created and memory.promoted. Add required RuntimeEvent fields (id, source, route). - B12 (Scheduler events, CRITICAL): Scheduler.ts — replace all 4 eventBus.publish calls with eventIngestor.ingest + registered event types (task.started/task.failed/agent.lost/agent.cancelled). Remove unregistered task.status.changed references. - B15 (duplicate ProjectionClient): remove orphan tui/src/ProjectionClient.ts (zero references, superseded by runtime/src/projection/ProjectionClient.ts re-exported via @aircoding/runtime barrel). - RuntimeApp: wire Scheduler→WorkerManager in constructor; document start() bootstrap→recover→hydrate→ready sequence (DD §22.2). - createRuntime: read project_id from .air/shared/project.json (DD §6.1 stable UUID), fallback to Date.now() only if not initialized. - B16 (api_key strict): ProviderManager.get_or_create_adapter now calls ModelConfigLoader.validate() before passing raw api_key to adapter. Also fix from R1 regression: - ArchitectureDesigner: replace broken additive-heuristic risk scoring (single runtime file→replan, large refactor→confirmation only) with change-scope classification (contracts→confirmation, breaking→escalate, large→replan, safe→silent_continue). Remove dead evaluate_risk(). - MainAgent test: update confirmation test from old state name AWAITING_CONFIRMATION to canonical CONFIRMING (B13 state machine fix). Test: 148/148 pass (regression + e2e + llm + toolchain-cpp). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
60 lines
1.7 KiB
TypeScript
Executable File
60 lines
1.7 KiB
TypeScript
Executable File
/**
|
|
* createRuntime - Bootstrap the full AirCoding runtime
|
|
* DD §22.2. Wires all subsystems via ServiceRegistry.
|
|
*
|
|
* @module packages/cli/src/bootstrap/createRuntime
|
|
*/
|
|
|
|
import { readFileSync, existsSync } from 'fs'
|
|
import { join } from 'path'
|
|
import { RuntimeApp, ProjectionClient } from '@aircoding/runtime'
|
|
import type { AirConfig } from './loadConfig.js'
|
|
|
|
export interface BootResult {
|
|
app: RuntimeApp
|
|
projection_client: ProjectionClient
|
|
start: () => Promise<void>
|
|
shutdown: () => Promise<void>
|
|
}
|
|
|
|
/**
|
|
* Load project_id from .air/shared/project.json (DD §6.1 stable UUID).
|
|
* Falls back to generated UUID if project is not initialized.
|
|
*/
|
|
function load_project_id(project_root: string): string {
|
|
const project_json = join(project_root, '.air', 'shared', 'project.json')
|
|
if (existsSync(project_json)) {
|
|
try {
|
|
const parsed = JSON.parse(readFileSync(project_json, 'utf-8'))
|
|
if (parsed.project_id) return parsed.project_id
|
|
} catch { /* fall through to fallback */ }
|
|
}
|
|
// Fallback: generate if project not yet initialized
|
|
return `proj_${Date.now().toString(36)}`
|
|
}
|
|
|
|
/**
|
|
* Create and start the AirCoding runtime.
|
|
*/
|
|
export async function createRuntime(config: AirConfig): Promise<BootResult> {
|
|
const project_root = config.project_root || process.cwd()
|
|
|
|
// Load stable project_id from .air/shared/project.json
|
|
const session_id = `session_${Date.now()}`
|
|
const project_id = load_project_id(project_root)
|
|
|
|
const app = new RuntimeApp({
|
|
project_root,
|
|
session_id,
|
|
project_id,
|
|
log_dir: `${project_root}/.air/logs`
|
|
})
|
|
|
|
return {
|
|
app,
|
|
projection_client: app.projection_client,
|
|
start: () => app.start(),
|
|
shutdown: () => app.shutdown()
|
|
}
|
|
}
|