/** * 诊断脚本 v3:手动建表,遍历全部 58 个 durable event type */ import { Database } from "bun:sqlite"; import { EventSchemaRegistry } from "./packages/runtime/src/events/EventSchemaRegistry.js"; import { EventStore } from "./packages/runtime/src/events/EventStore.js"; import { EventRepository } from "./packages/runtime/src/storage/repositories/EventRepository.js"; import { SessionRepository } from "./packages/runtime/src/storage/repositories/SessionRepository.js"; import { MessageRepository } from "./packages/runtime/src/storage/repositories/MessageRepository.js"; import { MessageDraftRepository } from "./packages/runtime/src/storage/repositories/MessageDraftRepository.js"; import { TaskRepository } from "./packages/runtime/src/storage/repositories/TaskRepository.js"; import { TaskDependencyRepository } from "./packages/runtime/src/storage/repositories/TaskDependencyRepository.js"; import { TaskAttemptRepository } from "./packages/runtime/src/storage/repositories/TaskAttemptRepository.js"; import { AgentRepository } from "./packages/runtime/src/storage/repositories/AgentRepository.js"; import { ToolRunRepository } from "./packages/runtime/src/storage/repositories/ToolRunRepository.js"; import { CommandRunRepository } from "./packages/runtime/src/storage/repositories/CommandRunRepository.js"; import { ArtifactRepository } from "./packages/runtime/src/storage/repositories/ArtifactRepository.js"; import { DiagnosticRepository } from "./packages/runtime/src/storage/repositories/DiagnosticRepository.js"; import { EvidenceRepository } from "./packages/runtime/src/storage/repositories/EvidenceRepository.js"; import { WorkspaceRepository } from "./packages/runtime/src/storage/repositories/WorkspaceRepository.js"; import { SummaryRepository } from "./packages/runtime/src/storage/repositories/SummaryRepository.js"; import { mkdirSync, existsSync, rmSync } from "fs"; import { join } from "path"; const TEST_DIR = "/tmp/h/aircoding-diag3"; const SESSION_ID = "diag_s"; const PROJECT_ID = "diag_p"; if (existsSync(TEST_DIR)) rmSync(TEST_DIR, { recursive: true }); mkdirSync(TEST_DIR, { recursive: true }); mkdirSync(join(TEST_DIR, ".air", "local", "sessions", SESSION_ID), { recursive: true }); const db = new Database(join(TEST_DIR, ".air", "local", "sessions", SESSION_ID, "session.db")); db.exec("PRAGMA journal_mode = WAL"); db.exec("PRAGMA synchronous = NORMAL"); db.exec("PRAGMA foreign_keys = OFF"); // Create schema manually (bypass MigrationRunner.query() issue) db.exec(`CREATE TABLE IF NOT EXISTS schema_meta (key TEXT PRIMARY KEY, value TEXT NOT NULL)`); db.exec(`CREATE TABLE IF NOT EXISTS sessions ( id TEXT PRIMARY KEY, project_id TEXT NOT NULL, project_root TEXT NOT NULL, title TEXT, status TEXT NOT NULL, created_at TEXT NOT NULL, updated_at TEXT NOT NULL, exited_at TEXT, model_provider_id TEXT, model_id TEXT, metadata_json TEXT )`); db.exec(`CREATE TABLE IF NOT EXISTS messages ( id TEXT PRIMARY KEY, session_id TEXT NOT NULL, role TEXT NOT NULL, canonical_format TEXT NOT NULL, content_json TEXT NOT NULL, parent_message_id TEXT, route_json TEXT, created_at TEXT NOT NULL, token_estimate INTEGER, metadata_json TEXT )`); db.exec(`CREATE TABLE IF NOT EXISTS message_drafts ( message_id TEXT PRIMARY KEY, session_id TEXT NOT NULL, role TEXT NOT NULL, canonical_format TEXT NOT NULL, partial_content_json TEXT NOT NULL, status TEXT NOT NULL, created_at TEXT NOT NULL, updated_at TEXT NOT NULL, metadata_json TEXT )`); db.exec(`CREATE TABLE IF NOT EXISTS events ( id TEXT PRIMARY KEY, session_id TEXT NOT NULL, type TEXT NOT NULL, version INTEGER NOT NULL, timestamp TEXT NOT NULL, source_kind TEXT NOT NULL, source_id TEXT, agent_type TEXT, task_id TEXT, agent_id TEXT, tool_run_id TEXT, command_run_id TEXT, route_json TEXT NOT NULL, route_text TEXT NOT NULL, payload_json TEXT NOT NULL )`); db.exec(`CREATE TABLE IF NOT EXISTS tasks ( id TEXT PRIMARY KEY, session_id TEXT NOT NULL, type TEXT NOT NULL, status TEXT NOT NULL, title TEXT NOT NULL, depends_on TEXT, task_spec_json TEXT NOT NULL, worker_result_json TEXT, assigned_agent_id TEXT, workspace_id TEXT, retry_count INTEGER NOT NULL DEFAULT 0, created_at TEXT NOT NULL, started_at TEXT, completed_at TEXT, heartbeat_at TEXT, metadata_json TEXT )`); db.exec(`CREATE TABLE IF NOT EXISTS task_dependencies ( id TEXT PRIMARY KEY, session_id TEXT NOT NULL, task_id TEXT NOT NULL, depends_on_task_id TEXT NOT NULL, dependency_type TEXT NOT NULL, reason TEXT, created_at TEXT NOT NULL )`); db.exec(`CREATE TABLE IF NOT EXISTS task_attempts ( id TEXT PRIMARY KEY, session_id TEXT NOT NULL, task_id TEXT NOT NULL, attempt_index INTEGER NOT NULL, agent_id TEXT, status TEXT NOT NULL, worker_result_json TEXT, failure_summary TEXT, evidence_refs_json TEXT, started_at TEXT NOT NULL, completed_at TEXT, debug_record_id TEXT )`); db.exec(`CREATE TABLE IF NOT EXISTS agents ( id TEXT PRIMARY KEY, session_id TEXT NOT NULL, type TEXT NOT NULL, status TEXT NOT NULL, pid INTEGER, task_id TEXT, model_provider_id TEXT, model_id TEXT, workspace_id TEXT, started_at TEXT NOT NULL, completed_at TEXT, heartbeat_at TEXT, last_heartbeat_at TEXT, metadata_json TEXT )`); db.exec(`CREATE TABLE IF NOT EXISTS tool_runs ( id TEXT PRIMARY KEY, session_id TEXT NOT NULL, task_id TEXT, agent_id TEXT, origin_message_id TEXT, tool_name TEXT NOT NULL, status TEXT NOT NULL, input_json TEXT NOT NULL, output_json TEXT, error_json TEXT, started_at TEXT NOT NULL, completed_at TEXT, duration_ms INTEGER, artifacts_json TEXT, evidence_refs_json TEXT, metadata_json TEXT )`); db.exec(`CREATE TABLE IF NOT EXISTS command_runs ( id TEXT PRIMARY KEY, session_id TEXT NOT NULL, task_id TEXT, agent_id TEXT, origin_message_id TEXT, tool_run_id TEXT, command TEXT NOT NULL, cwd TEXT NOT NULL, exit_code INTEGER, duration_ms INTEGER, stdout_artifact_id TEXT, stderr_artifact_id TEXT, combined_artifact_id TEXT, diagnostic_ids TEXT, parsed_diagnostics_json TEXT, started_at TEXT NOT NULL, completed_at TEXT, metadata_json TEXT )`); db.exec(`CREATE TABLE IF NOT EXISTS artifacts ( id TEXT PRIMARY KEY, session_id TEXT NOT NULL, type TEXT NOT NULL, uri TEXT NOT NULL, path TEXT NOT NULL, original_name TEXT, size_bytes INTEGER, sha256 TEXT, task_id TEXT, agent_id TEXT, tool_run_id TEXT, command_run_id TEXT, associated_entity_type TEXT, associated_entity_id TEXT, created_at TEXT NOT NULL, metadata_json TEXT )`); db.exec(`CREATE TABLE IF NOT EXISTS diagnostics ( id TEXT PRIMARY KEY, session_id TEXT NOT NULL, task_id TEXT, agent_id TEXT, command_run_id TEXT, artifact_id TEXT, language TEXT, toolchain TEXT, severity TEXT, file TEXT, line INTEGER, column INTEGER, code TEXT, message TEXT NOT NULL, semantic_signature TEXT NOT NULL, created_at TEXT NOT NULL, metadata_json TEXT )`); db.exec(`CREATE TABLE IF NOT EXISTS evidence_refs ( id TEXT PRIMARY KEY, session_id TEXT NOT NULL, task_id TEXT, agent_id TEXT, tool_run_id TEXT, command_run_id TEXT, artifact_id TEXT, diagnostic_id TEXT, message_id TEXT, kind TEXT NOT NULL, ref TEXT NOT NULL, location_json TEXT, claim TEXT NOT NULL, created_at TEXT NOT NULL )`); db.exec(`CREATE TABLE IF NOT EXISTS workspaces ( id TEXT PRIMARY KEY, session_id TEXT NOT NULL, task_id TEXT, agent_id TEXT, path TEXT NOT NULL, strategy TEXT NOT NULL, status TEXT NOT NULL, base_ref TEXT, branch_name TEXT, merged_ref TEXT, diff_artifact_id TEXT, created_at TEXT NOT NULL, merged_at TEXT )`); db.exec(`CREATE TABLE IF NOT EXISTS summaries ( id TEXT PRIMARY KEY, session_id TEXT NOT NULL, type TEXT NOT NULL, range_start_message_id TEXT, range_end_message_id TEXT, content_json TEXT NOT NULL, created_at TEXT NOT NULL, metadata_json TEXT )`); db.exec(`CREATE TABLE IF NOT EXISTS ui_state ( id TEXT PRIMARY KEY, session_id TEXT NOT NULL, scope TEXT, key TEXT, value_json TEXT, updated_at TEXT )`); // Repos const repos = { sessionRepo: new SessionRepository(db), messageRepo: new MessageRepository(db), messageDraftRepo: new MessageDraftRepository(db), taskRepo: new TaskRepository(db), taskDepRepo: new TaskDependencyRepository(db), taskAttemptRepo: new TaskAttemptRepository(db), agentRepo: new AgentRepository(db), toolRunRepo: new ToolRunRepository(db), commandRunRepo: new CommandRunRepository(db), artifactRepo: new ArtifactRepository(db), diagnosticRepo: new DiagnosticRepository(db), evidenceRepo: new EvidenceRepository(db), workspaceRepo: new WorkspaceRepository(db), summaryRepo: new SummaryRepository(db), }; const txManager = { async transaction(fn: (tx: any) => Promise): Promise { db.exec("BEGIN"); try { const r = await fn(db); db.exec("COMMIT"); return r; } catch (e) { db.exec("ROLLBACK"); throw e; } } }; const eventStore = new EventStore({ db, repos, txManager }); const SID = SESSION_ID, PID = PROJECT_ID, NOW = "2026-06-11T00:00:00.000Z"; // Seed session await eventStore.append({ id: "evt_s", type: "session.created", version: 1, session_id: SID, project_id: PID, timestamp: NOW, source: { kind: "system" }, route: ["diag"], payload: { session_id: SID, project_id: PID, project_root: TEST_DIR, title: "Diag", model_provider_id: "x", model_id: "x", metadata: {} } }); // Payload map const P: Record = { "session.created": { session_id: SID, project_id: PID, project_root: TEST_DIR, title: "t", model_provider_id: "x", model_id: "x", metadata: {} }, "session.archived": { session_id: SID, reason: "t" }, "session.deleted": { session_id: SID, reason: "t" }, "user.message.created": { message_id: "m1", canonical_format: "anthropic", content_json: { text: "hi" }, token_estimate: 10, metadata: {} }, "assistant.message.started": { message_id: "m2", canonical_format: "anthropic", content_json: {}, parent_message_id: "m1", metadata: {} }, "assistant.message.created": { message_id: "m3", canonical_format: "anthropic", content_json: { text: "r" }, parent_message_id: "m2", route: [], token_estimate: 15, metadata: {} }, "assistant.message.failed": { message_id: "m3", partial_content_json: {}, error: {}, evidence_refs: [], metadata: {} }, "agent.started": { agent_id: "a1", agent_type: "executor", task_id: "t1", pid: 123, model_provider_id: "x", model_id: "x", workspace_id: "w1", metadata: {} }, "agent.completed": { agent_id: "a1", task_id: "t1", summary: "done", worker_result_ref: "r1", metadata: {} }, "agent.failed": { agent_id: "a1", task_id: "t1", error: { message: "f" }, evidence_refs: [], metadata: {} }, "agent.lost": { agent_id: "a1", task_id: "t1", last_heartbeat_at: NOW, detection_reason: "t" }, "agent.cancelled": { agent_id: "a1", task_id: "t1", reason: "t" }, "task.created": { task_id: "t1", type: "execute", title: "Test", task_spec_json: { desc: "t" }, dependencies: [], metadata: {} }, "task.started": { task_id: "t1", agent_id: "a1", attempt_id: "at1", attempt_index: 0, workspace_id: "w1" }, "task.completed": { task_id: "t1", agent_id: "a1", attempt_id: "at1", worker_result_json: {}, summary: "done", changed_files: [], evidence_refs: [] }, "task.blocked": { task_id: "t1", agent_id: "a1", reason: "b", blocker_kind: "dep", evidence_refs: [], suggested_next_step: "fix" }, "task.failed": { task_id: "t1", agent_id: "a1", attempt_id: "at1", error: { message: "f" }, evidence_refs: [], metadata: {} }, "task.cancelled": { task_id: "t1", reason: "t", cancelled_by: "user" }, "task.interrupted": { task_id: "t1", reason: "t", resumable: true, resume_ref: "r" }, "task.invalidated": { task_id: "t1", adr_id: "adr1", reason: "t", rollback_ref: "r1" }, "task.removed": { task_id: "t1", reason: "t", removed_by: "user" }, "task.debug_requested": { task_id: "t1", reason: "dbg" }, "tool.started": { tool_run_id: "tr1", tool_name: "fs.read", task_id: "t1", agent_id: "a1", origin_message_id: "m1", input_json: { path: "f" }, metadata: {} }, "tool.completed": { tool_run_id: "tr1", output_json: { r: "ok" }, duration_ms: 100, artifact_ids: [], evidence_refs: [], metadata: {} }, "tool.failed": { tool_run_id: "tr1", duration_ms: 50, error: { message: "e" }, evidence_refs: [], metadata: {} }, "tool.cancelled": { tool_run_id: "tr1", reason: "t" }, "command.started": { command_run_id: "c1", task_id: "t1", agent_id: "a1", origin_message_id: "m1", tool_run_id: "tr1", command: "echo hi", cwd: TEST_DIR, metadata: {} }, "command.completed": { command_run_id: "c1", exit_code: 0, duration_ms: 10, stdout_artifact_id: "art1", stderr_artifact_id: "art2", combined_artifact_id: "art3", diagnostic_ids: [], parsed_diagnostics_json: {}, metadata: {} }, "command.failed": { command_run_id: "c1", exit_code: 1, duration_ms: 10, stdout_artifact_id: "art1", stderr_artifact_id: "art2", combined_artifact_id: "art3", error: { message: "e" }, evidence_refs: [], metadata: {} }, "artifact.created": { artifact_id: "art1", type: "log", uri: "file:///x", path: "/x", original_name: "x.log", size_bytes: 100, sha256: "abc", task_id: "t1", agent_id: "a1", tool_run_id: "tr1", command_run_id: "c1", associated_entity_type: "task", associated_entity_id: "t1", metadata: {} }, "diagnostic.created": { diagnostic_id: "d1", task_id: "t1", agent_id: "a1", command_run_id: "c1", artifact_id: "art1", language: "cpp", toolchain: "gcc", severity: "error", file: "f.cpp", line: 1, column: 0, code: "E01", message: "err", semantic_signature: "test/e", metadata: {} }, "evidence.created": { evidence_ref_id: "ev1", kind: "build_output", ref: "r1", location_json: {}, claim: "test", task_id: "t1", agent_id: "a1", tool_run_id: "tr1", command_run_id: "c1", artifact_id: "art1", diagnostic_id: "d1", message_id: "m1" }, "context.compaction.requested": { compaction_id: "co1", title: "Compaction", task_spec_json: { reason: "b" }, reason: "budget", range_start_message_id: "m1", range_end_message_id: "m3", target_budget_tokens: 100000 }, "context.compaction.started": { compaction_id: "co1", task_id: "t1", agent_id: "a1", range_start_message_id: "m1", range_end_message_id: "m3" }, "context.compaction.completed": { compaction_id: "co1", task_id: "t1", agent_id: "a1", summary_id: "s1", range_start_message_id: "m1", range_end_message_id: "m3", token_estimate_before: 100000, token_estimate_after: 30000 }, "context.compaction.failed": { compaction_id: "co1", task_id: "t1", agent_id: "a1", range_start_message_id: "m1", range_end_message_id: "m3", error: { message: "e" }, evidence_refs: [], metadata: {} }, "summary.created": { summary_id: "s1", type: "compaction", range_start_message_id: "m1", range_end_message_id: "m3", content_json: {}, metadata: {} }, "permission.decision.recorded": { decision_id: "dec1", subject: "fs.write", action: "allow", grant_scope: "task", reason: "t", risk_level: "low", decided_by: "user", scope_json: {}, expires_at: "" }, "permission.prompt.requested": { prompt_id: "pp1", subject: "fs.write", risk_level: "low", reason: "t", options: ["allow", "deny"], default_option: "deny", request_ref: {} }, "permission.prompt.resolved": { prompt_id: "pp1", selected_option: "allow", decision_id: "dec1", resolved_by: "user" }, "doctor.run.started": { run_id: "dr1", mode: "read_only", trigger: "startup", check_type: "platform" }, "doctor.issue.found": { run_id: "dr1", issue_id: "iss1", severity: "warning", capability: "bun", dependency: "none", message: "test", fix_available: false, fix_requires_confirmation: false }, "doctor.fix.started": { run_id: "dr1", issue_id: "iss1", fix_id: "f1", strategy: "auto", fix_type: "install" }, "doctor.fix.completed": { run_id: "dr1", issue_id: "iss1", fix_id: "f1", evidence_refs: [], fix_type: "install" }, "doctor.fix.failed": { run_id: "dr1", issue_id: "iss1", fix_id: "f1", error: "fail", evidence_refs: [], metadata: {} }, "doctor.run.completed": { run_id: "dr1", status: "ok", issue_count: 0, blocking_issue_count: 0, report_artifact_id: "art1" }, "requirement.changed": { change_id: "ch1", origin_message_id: "m1", summary: "c", change_type: "update", affected_refs: ["fr1"] }, "architecture.plan.updated": { plan_ref: "p1", update_kind: "update", summary: "u", affected_task_ids: [], adr_refs: [], c4_refs: [] }, "architecture.impact.completed": { assessment_id: "as1", requirement_change_id: "ch1", impact_level: "low", decision: "continue", summary: "ok", affected_task_ids: [], evidence_refs: [] }, "workspace.created": { workspace_id: "w1", task_id: "t1", agent_id: "a1", path: "/tmp/w1", strategy: "main", base_ref: "main", branch_name: "main" }, "workspace.merge.started": { workspace_id: "w1", task_id: "t1", strategy: "main", target_ref: "main" }, "workspace.merge.completed": { workspace_id: "w1", task_id: "t1", merged_ref: "abc", diff_artifact_id: "art1" }, "workspace.merge.conflicted": { workspace_id: "w1", task_id: "t1", conflict_files: ["a.txt"], conflict_artifact_id: "art1", suggested_resolution: "merge" }, "workspace.cleaned": { workspace_id: "w1", reason: "done" }, "memory.candidate.created": { candidate_id: "m1", source_ref: {}, memory_type: "project_rule", summary: "rule", evidence_refs: [] }, "memory.promoted": { candidate_id: "m1", target_ref: "rules.md", promoted_by: "user", summary: "promoted" }, "memory.archived": { candidate_id: "m1", memory_ref: "ref", reason: "stale" }, "debug.record.created": { debug_record_id: "dbg1", task_id: "t1", failure_signature: "sig", summary: "debug", evidence_refs: [], verification_refs: [] }, }; const allEvents = new EventSchemaRegistry().list().filter(e => e.persistence === 'durable'); let pass = 0, fail = 0, cid = 0; for (const ev of allEvents) { const payload = P[ev.type] || {}; cid++; try { await eventStore.append({ id: `diag_${cid}`, type: ev.type, version: ev.version, session_id: SID, project_id: PID, timestamp: NOW, source: { kind: "system" }, route: ["diag"], payload, }); pass++; } catch (e: any) { fail++; const msg = e.message || String(e); console.log(`FAIL ${ev.type}: ${msg.split('\n')[0]}`); } } console.log(`\n${pass}/${allEvents.length} passed, ${fail} failed`); db.close();