Files
AirCoding/diag-events.ts
AirCoding ae44be31d5 chore: push all design docs, V2 plan specs, and current working state
Includes AirPlan design documents, AircOding-alpha1-plan, AirPlanV2,
AirPlan-ParaV2, AirPlan-Para V1 reference docs, and all working code
changes across packages.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-12 17:12:29 +08:00

249 lines
18 KiB
TypeScript
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 诊断脚本 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<T>(fn: (tx: any) => Promise<T>): Promise<T> {
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<string, any> = {
"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();