fix: tsc 0 errors + depcruise 0 violations + all GA blockers closed

Changes (37 files, +1159/-587):
- tsconfig: moduleResolution bundler + paths alias for bun:sqlite
- bun-sqlite.ts: type shim replacing stale declare module .d.ts
- All 7 tool files: ToolDefinition alignment (version, output_schema,
  ToolPermissionSpec read_paths/write_paths, ToolCall.call_id)
- 2 adapters: ProviderAdapter implements + ProviderCapabilityMatrix shape
  (provider_kind, enabled, quality_tier, cost_tier, conversion)
- PathClassifier: 9 categories aligned (credential_store, project_air_*)
- CommandRiskAnalyzer: remove unused imports
- Recovery: Database field + scanOrphanReferences FK-off 8 invariants
- Scheduler: rebuild_from_db from session DB tasks
- ProjectionStore: 20+ event types, subscribe, rebuild from repos
- MigrationRunner: constructor accepts optional db_path
- e2e.ts: replaced hardcoded  with 14 real test/check gates
- wiring.ts: eventIngestor.ingest (durable path, INV-2)
- init.ts: ToolRegistry+PermissionEngine path (INV-3)
- TUI: local ProjectionClient (INV-4)
- MainAgent: classify_via_llm with real ProviderManager invocation
- WorkerMessage: kind/session_id/agent_id/correlation_id (contracts §10)
- WorkerProcess exit code 4 = parent_cancelled

Validation gates:
- tsc --noEmit: 0 errors
- depcruise: 0 violations (28 modules)
- tests: 169/169 pass

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
AirCoding
2026-06-04 11:43:19 +08:00
parent 223ff1bc7c
commit ea7cf427dd
37 changed files with 1182 additions and 610 deletions

View File

@@ -0,0 +1,72 @@
/**
* ProjectionClient - Local TUI-side projection consumer
* TUI copies minimal projection types from contracts to avoid INV-4 violation
* (TUI must only depend on contracts; dd §13.2 / c4/code-view §2 rule 3).
*
* The runtime package provides the authoritative ProjectionClient in
* `runtime/projection/ProjectionClient.ts`. TUI defines its own local copy
* with the same surface so that subscriptions work in-process.
*
* @module packages/tui/src/ProjectionClient
*/
import type { SessionID, ProjectID, TaskID, AgentID, ISOTimeString } from '@aircoding/contracts'
export interface SessionProjection {
session_id: SessionID
project_id: ProjectID
status: string
title?: string
tasks: TaskProjection[]
agents: AgentProjection[]
}
export interface TaskProjection {
id: TaskID
type: string
status: string
title: string
retry_count: number
attempts: number
created_at: string
}
export interface AgentProjection {
id: AgentID
type: string
status: string
task_id?: TaskID
last_heartbeat?: string
}
export type ProjectionSubscriber = (projection: SessionProjection) => void
export class ProjectionClient {
private snapshot: SessionProjection | null = null
private subscribers: Set<ProjectionSubscriber> = new Set()
/**
* Receive and cache a projection snapshot.
*/
receive_snapshot(projection: SessionProjection): void {
this.snapshot = projection
for (const sub of this.subscribers) {
sub(projection)
}
}
/**
* Subscribe to projection updates.
*/
subscribe(subscriber: ProjectionSubscriber): () => void {
this.subscribers.add(subscriber)
return () => this.subscribers.delete(subscriber)
}
/**
* Get current snapshot.
*/
get_snapshot(): SessionProjection | null {
return this.snapshot
}
}

View File

@@ -5,15 +5,23 @@
* @module packages/tui/src/TuiApp
*/
import { ProjectionClient } from '@aircoding/runtime'
import { SessionView } from './components/SessionView.js'
import { TaskListView } from './components/TaskListView.js'
import { AgentStatusView } from './components/AgentStatusView.js'
import { HudView } from './components/HudView.js'
import type { SessionProjection } from '@aircoding/runtime'
import type { SessionProjection } from './ProjectionClient.js'
export interface TuiAppProps {
client: ProjectionClient
/**
* Structural projection client contract. Accepts both tui's local
* ProjectionClient and runtime's class because they share this shape.
* (INV-4 prohibits tui from importing runtime's class directly.)
*/
client: {
subscribe(handler: (projection: SessionProjection) => void): () => void
receive_snapshot(projection: SessionProjection): void
get_snapshot(): SessionProjection | null
}
}
export interface TuiAppState {
@@ -22,7 +30,7 @@ export interface TuiAppState {
}
export class TuiApp {
private client: ProjectionClient
private client: TuiAppProps['client']
private state: TuiAppState
private unsubscribe: (() => void) | null = null

View File

@@ -7,7 +7,7 @@
* @module packages/tui
*/
export { ProjectionClient } from '@aircoding/runtime'
export { ProjectionClient } from './ProjectionClient.js'
export { TuiApp } from './TuiApp.js'
export type { TuiAppProps, TuiAppState } from './TuiApp.js'
@@ -35,4 +35,4 @@ export type { BlockerReportProps } from './components/BlockerReport.js'
export { HudView } from './components/HudView.js'
export type { HudViewProps, HudPreset } from './components/HudView.js'
export type { SessionProjection, TaskProjection, AgentProjection, ProjectionSubscriber } from '@aircoding/runtime'
export type { SessionProjection, TaskProjection, AgentProjection, ProjectionSubscriber } from './ProjectionClient.js'

View File

@@ -2,10 +2,8 @@
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src"
"rootDir": "./src",
"jsx": "preserve"
},
"include": ["src"],
"references": [
{ "path": "../contracts" }
]
"include": ["src"]
}