迁移路径: /run/media/airlongdian/EasyU/AirCoding -> /home/airlongdian/DataDevices/AirWorkSpace/AirCoding Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
20 KiB
Executable File
C4 Code View and UML Class Model
Date: 2026-05-27 Status: Formal V1 code-view design for AirCoding V1.0.0 Alpha skeleton
This document refines AirPlan/docs/architecture/c4/module.md from container/module view into package-level code structure, class/service responsibilities, UML class diagrams, and implementation boundaries.
Canonical TypeScript interface contracts are defined in AirPlan/docs/architecture/interface-contracts-v1.md.
1. Code View Scope
The V1.0.0 Alpha code view covers these packages:
packages/contracts
packages/cli
packages/runtime
packages/llm
packages/toolchain-cpp
packages/tui
The code view is implementation-facing but remains architecture-only. It defines expected classes/interfaces and relationships; exact file names may be adjusted during implementation if contracts and dependencies remain stable.
2. Package Dependency Diagram
@startuml
skinparam componentStyle rectangle
package "packages/contracts" as contracts
package "packages/cli" as cli
package "packages/runtime" as runtime
package "packages/llm" as llm
package "packages/toolchain-cpp" as cpp
package "packages/tui" as tui
cli --> runtime
cli --> tui
cli --> llm
cli --> cpp
runtime --> contracts
runtime --> llm : adapter interfaces
runtime ..> cpp : capability registration boundary
llm --> contracts
cpp --> contracts
tui --> contracts
runtime --> llm : ProviderManager facade/API
@enduml
Rules:
contractsmust have no implementation-package dependencies.runtimemust not importtui.tuimust depend only oncontractsand a narrowProjectionClient/UI API boundary; it must not import runtime private services, query SQLite, or subscribe to EventBus directly.toolchain-cppexposes tools through capability registration, not direct runtime coupling.llmowns provider adapters, model config, provider conversion, and ProviderManager implementation;runtimeowns prompt assembly and calls LLM through the provider facade/API.
3. Contracts Package Code View
Expected directory:
packages/contracts/src/
index.ts
ids.ts
runtime.ts
event.ts
ipc.ts
task.ts
worker-result.ts
tool.ts
artifact.ts
evidence.ts
project.ts
provider.ts
permission.ts
ui.ts
error.ts
capability.ts
platform.ts
UML
@startuml
interface RuntimeEvent<T> {
id: UUID
type: string
version: number
timestamp: ISOTimeString
session_id: SessionID
project_id?: ProjectID
source: EventSource
route: string[]
payload: T
}
interface TaskSpec {
id: TaskID
type: TaskType
title: string
description: string
acceptance_criteria: string[]
scope: TaskScope
dependencies: TaskDependencySpec[]
verification: VerificationPolicy
constraints: TaskConstraints
context_refs: TaskContextRefs
output_contract: WorkerOutputContract
}
interface WorkerResult<T> {
task_id: TaskID
agent_id: AgentID
agent_type: AgentType
status: WorkerStatus
summary: string
changed_files: string[]
artifacts: ArtifactRef[]
verification: VerificationResult[]
risks: Risk[]
follow_up_tasks: FollowUpTask[]
evidence_refs: EvidenceRef[]
result: T
}
interface ToolDefinition<I, O> {
name: string
version: number
description: string
input_schema: JsonSchema<I>
output_schema: JsonSchema<O>
category: ToolCategory
permissions: ToolPermissionSpec
streaming: boolean
}
interface ProviderCapabilityMatrix
interface AirError
interface ArtifactRef
interface EvidenceRef
interface PermissionDecision
interface ProjectionSnapshot
interface CapabilityManifestV1
RuntimeEvent --> EventSource
TaskSpec --> WorkerResult : output contract
WorkerResult --> ArtifactRef
WorkerResult --> EvidenceRef
ToolDefinition --> PermissionDecision
AirError --> EvidenceRef
@enduml
Contract Ownership
| Contract | File | Primary consumers |
|---|---|---|
| IDs and aliases | ids.ts |
all packages |
| RuntimeEvent/EventSource | event.ts |
EventStore, EventBus, IPC, ProjectionStore |
| TaskSpec | task.ts |
Scheduler, workers, ContextAssembler |
| WorkerResult | worker-result.ts |
workers, Scheduler, Main Agent |
| ToolDefinition/ToolResult | tool.ts |
ToolRegistry, capabilities, workers |
| ArtifactRef/EvidenceRef | artifact.ts, evidence.ts |
ArtifactStore, EvidenceStore, reports |
| ProviderCapabilityMatrix | provider.ts |
ProviderManager, Scheduler, Doctor |
| AirError/ErrorKind | error.ts |
tools, Scheduler, agents, UI |
| IpcMessage/ControlMessage | ipc.ts |
WorkerManager, child workers |
| PermissionDecision | permission.ts |
PermissionEngine, ToolRegistry, UI |
| ProjectionSnapshot | ui.ts |
ProjectionStore, TUI/HUD |
| CapabilityManifestV1 | capability.ts |
CapabilityRegistry, Doctor |
4. Runtime Package Code View
Expected directory:
packages/runtime/src/
index.ts
app/
RuntimeApp.ts
ServiceRegistry.ts
config/
ConfigLoader.ts
ResourceLoader.ts
project/
ProjectLocator.ts
ProjectInitializer.ts
ProjectStore.ts
storage/
DatabaseManager.ts
MigrationRunner.ts
repositories/
events/
EventBus.ts
EventStore.ts
EventIngestor.ts
EventSchemaRegistry.ts
sessions/
SessionManager.ts
SessionStore.ts
scheduler/
Scheduler.ts
TaskGraph.ts
WavePlanner.ts
RetryPlanner.ts
WorkspaceManager.ts
AgentMonitor.ts
workers/
WorkerManager.ts
WorkerProcess.ts
WorkerProtocol.ts
roles/
tools/
ToolRegistry.ts
BuiltInToolRegistrar.ts
fs/
shell/
git/
project/
artifact/
context/
permission/
doctor/
security/
PermissionEngine.ts
PathClassifier.ts
CommandRiskAnalyzer.ts
SecretRedactor.ts
capabilities/
CapabilityRegistry.ts
CapabilityManifestValidator.ts
context/
ContextAssembler.ts
PromptLayerLoader.ts
CompactionPolicy.ts
artifacts/
ArtifactStore.ts
EvidenceStore.ts
knowledge/
DebugKnowledgeStore.ts
LearnedMemoryStore.ts
projection/
ProjectionStore.ts
projections/
doctor/
DoctorService.ts
checks/
logging/
Logger.ts
DeveloperLogEncryptor.ts
agents/
main/
architecture/
Runtime Service UML
@startuml
class RuntimeApp {
+start(options): Promise<void>
+shutdown(): Promise<void>
}
class ServiceRegistry {
+get<T>(token): T
+register(token, service): void
}
class ProjectStore {
+open(root): Promise<ProjectContext>
+initialize(root): Promise<ProjectContext>
}
class SessionManager {
+openSession(project, options): Promise<SessionContext>
+closeSession(sessionId): Promise<void>
}
class DatabaseManager {
+open(path): DatabaseHandle
+transaction(fn): Promise<T>
}
class MigrationRunner {
+migrate(db): Promise<void>
}
class EventStore {
+append(event): Promise<void>
+query(filter): Promise<RuntimeEvent[]>
}
class EventIngestor {
+ingest(event): Promise<void>
+ingest_ephemeral(event): Promise<void>
}
class EventBus {
+publish(event): void
+subscribe(filter, handler): Subscription
}
class ProjectionStore {
+hydrate(sessionId): Promise<void>
+apply(event): void
+snapshot(): ProjectionSnapshot
}
RuntimeApp --> ServiceRegistry
RuntimeApp --> ProjectStore
RuntimeApp --> SessionManager
SessionManager --> DatabaseManager
DatabaseManager --> MigrationRunner
EventIngestor --> EventStore : durable events
EventIngestor --> EventBus : ephemeral events
EventStore --> DatabaseManager
EventStore --> EventBus : publishes after commit
ProjectionStore --> SessionStore : hydrate via repositories
ProjectionStore --> EventBus : subscribes to live events
@enduml
Scheduler UML
@startuml
class Scheduler {
+create_tasks(session_id, specs): Promise<void>
+add_dependency(session_id, task_id, dependency): Promise<void>
+load_graph(session_id): Promise<TaskGraph>
+run_until_idle(session_id): Promise<SchedulerRunResult>
+cancel_task(task_id, reason): Promise<void>
-plan_wave(graph): SchedulerWavePlan
-dispatch(wave): Promise<void>
-collect_results(): Promise<void>
}
class TaskGraph {
+tasks: Map<TaskID, TaskNode>
+dependencies: TaskDependencyRecord[]
+getRunnableTasks(): TaskNode[]
+markTerminal(taskId, status): void
}
class WavePlanner {
+plan(graph, resources): SchedulerWavePlan
}
class RetryPlanner {
+decide(task, attempts, error): RetryDecision
}
class WorkspaceManager {
+createWorkspace(plan): Promise<WorkspaceRef>
+mergeWorkspace(workspaceId): Promise<MergeResult>
+cleanupWorkspace(workspaceId): Promise<void>
}
class AgentMonitor {
+recordHeartbeat(event): void
+detectLostAgents(): Promise<AgentLost[]>
+enforceTimeouts(): Promise<void>
}
class WorkerManager {
+spawn(taskSpec, contextPack): Promise<WorkerProcess>
+cancel(agentId, reason): Promise<void>
}
class WorkerProcess {
+agent_id: AgentID
+pid?: number
+send(envelope): void
+on_message(handler): void
}
Scheduler --> TaskGraph
Scheduler --> WavePlanner
Scheduler --> RetryPlanner
Scheduler --> WorkspaceManager
Scheduler --> AgentMonitor
Scheduler --> WorkerManager
Scheduler --> EventStore
Scheduler --> ContextAssembler
WorkerManager --> WorkerProcess
@enduml
Tool/Permission UML
@startuml
class ToolRegistry {
+register(definition, executor): void
+call(name, input, context): Promise<ToolResultEnvelope>
+list(): ToolDefinition[]
}
class PermissionEngine {
+evaluate(request): Promise<PermissionDecision>
+record(decision, context): Promise<void>
}
class PathClassifier {
+classify(path, projectRoot): PathRiskClassification
}
class CommandRiskAnalyzer {
+analyze(command, cwd): CommandRiskAnalysis
}
class CapabilityRegistry {
+discover(): Promise<CapabilityManifestV1[]>
+validate(manifest): Promise<ValidationResult>
+enable(capability_id): Promise<void>
+disable(capability_id): Promise<void>
+register_tools(tool_registry): Promise<void>
}
class DoctorService {
+run(input): Promise<DoctorRunOutput>
+checkCapability(capability): Promise<DoctorIssue[]>
}
ToolRegistry --> PermissionEngine
ToolRegistry --> EventIngestor
ToolRegistry --> ArtifactStore
PermissionEngine --> PathClassifier
PermissionEngine --> CommandRiskAnalyzer
PermissionEngine --> EventIngestor
CapabilityRegistry --> ToolRegistry : registers enabled tools
DoctorService --> CapabilityRegistry : reads manifests/checks dependencies
@enduml
Context/Agent UML
@startuml
class ContextAssembler {
+assemble(input): Promise<AssembledContext>
-loadLayers(profile): Promise<PromptLayer[]>
-fitBudget(context): BudgetFitResult
}
class PromptLayerLoader {
+loadRuntimeInvariant(): PromptLayer
+loadRole(role): PromptLayer
+loadProjectRules(project): PromptLayer[]
}
class MainAgent {
+handleUserMessage(message): Promise<void>
+presentProgress(): Promise<void>
+presentBlocker(blocker): Promise<void>
}
class ArchitectureDesigner {
+assessImpact(change): Promise<ArchitectureImpact>
+updateArchitectureDocs(update): Promise<DocumentUpdate>
}
interface ProviderManager {
+select_model(requirement): Promise<ModelAssignment>
+complete(request): AsyncIterable<ProviderStreamEvent>
}
ContextAssembler --> PromptLayerLoader
MainAgent --> ContextAssembler
MainAgent --> ProviderManager : LLM facade from packages/llm
MainAgent --> Scheduler
ArchitectureDesigner --> ContextAssembler
ArchitectureDesigner --> ProviderManager : LLM facade from packages/llm
ArchitectureDesigner --> EventIngestor
class DebugKnowledgeStore {
+insert(record): Promise<void>
+lookup_by_signature(sig): Promise<DebugRecord[]>
+lookup_by_task(task_id): Promise<DebugRecord[]>
+update(id, patch): Promise<void>
}
class LearnedMemoryStore {
+insert(memory): Promise<void>
+lookup_by_type(type): Promise<LearnedMemory[]>
+update_status(id, status): Promise<void>
+scan_stale(): Promise<LearnedMemory[]>
}
class CompactionPolicy {
+should_compact(messages, budget): boolean
+compact(messages, target): Promise<CompactionResult>
}
ExperienceMinerRole --> LearnedMemoryStore
DebuggerRole --> DebugKnowledgeStore
ContextAssembler --> CompactionPolicy
@enduml
5. LLM Package Code View
Expected directory:
packages/llm/src/
index.ts
ProviderManager.ts
ModelConfigLoader.ts
CapabilityMatrix.ts
ConversionReport.ts
adapters/
AnthropicAdapter.ts
OpenAICompatibleAdapter.ts
canonical/
AnthropicCanonical.ts
ToolUseConverter.ts
StreamNormalizer.ts
UML
@startuml
interface ProviderAdapter {
+provider_id: string
+list_models(): Promise<ProviderCapabilityMatrix[]>
+validate_model(model_id): Promise<ProviderCapabilityMatrix>
+complete(input): AsyncIterable<ProviderStreamEvent>
+count_tokens?(input): Promise<number>
}
class ProviderManager {
+load_config(): Promise<void>
+select_model(requirement): Promise<ModelAssignment>
+complete(input): AsyncIterable<ProviderStreamEvent>
}
class ModelConfigLoader
class CapabilityMatrixRegistry
class AnthropicAdapter
class OpenAICompatibleAdapter
class AnthropicCanonicalConverter
class StreamNormalizer
ProviderManager --> ProviderAdapter
ProviderManager --> ModelConfigLoader
ProviderManager --> CapabilityMatrixRegistry
AnthropicAdapter ..|> ProviderAdapter
OpenAICompatibleAdapter ..|> ProviderAdapter
OpenAICompatibleAdapter --> AnthropicCanonicalConverter
ProviderAdapter --> StreamNormalizer
@enduml
6. Toolchain C++ Package Code View
Expected directory:
packages/toolchain-cpp/src/
index.ts
capability.ts
CppToolRegistrar.ts
detect/
CppProjectDetector.ts
build/
CMakeConfigurator.ts
CppBuilder.ts
test/
CppTestRunner.ts
analysis/
CppcheckRunner.ts
ClangdClient.ts
DiagnosticParser.ts
UML
@startuml
class CppToolRegistrar {
+register(toolRegistry): void
}
class CppProjectDetector {
+detect(projectRoot): Promise<CppDetectOutput>
}
class CMakeConfigurator {
+configure(input): Promise<CppCmakeConfigureOutput>
}
class CppBuilder {
+build(input): Promise<CppBuildOutput>
}
class CppTestRunner {
+runTests(input): Promise<CppTestOutput>
}
class CppcheckRunner {
+run(input): Promise<CppcheckOutput>
}
class ClangdClient {
+query(input): Promise<ClangdQueryOutput>
}
class DiagnosticParser {
+parse_compiler_output(output): Diagnostic[]
+semantic_signature(diagnostic): string
}
CppToolRegistrar --> CppProjectDetector
CppToolRegistrar --> CMakeConfigurator
CppToolRegistrar --> CppBuilder
CppToolRegistrar --> CppTestRunner
CppToolRegistrar --> CppcheckRunner
CppToolRegistrar --> ClangdClient
CMakeConfigurator --> DiagnosticParser
CppBuilder --> DiagnosticParser
CppTestRunner --> DiagnosticParser
CppcheckRunner --> DiagnosticParser
@enduml
7. TUI Package Code View
Expected directory:
packages/tui/src/
index.ts
TuiApp.tsx
ProjectionClient.ts
components/
SessionView.tsx
TaskListView.tsx
AgentStatusView.tsx
ToolRunView.tsx
DiffView.tsx
EvidenceView.tsx
PermissionPrompt.tsx
BlockerReport.tsx
HudView.tsx
theme/
theme.ts
keymap/
keymap.ts
UML
@startuml
class TuiApp {
+start(): void
+stop(): void
}
class ProjectionClient {
+subscribe(handler): Subscription
+snapshot(): ProjectionSnapshot
}
class SessionView
class TaskListView
class AgentStatusView
class ToolRunView
class EvidenceView
class PermissionPrompt
class BlockerReport
class HudView
TuiApp --> ProjectionClient
TuiApp --> SessionView
TuiApp --> TaskListView
TuiApp --> AgentStatusView
TuiApp --> ToolRunView
TuiApp --> EvidenceView
TuiApp --> PermissionPrompt
TuiApp --> BlockerReport
TuiApp --> HudView
@enduml
Rules:
- UI components render projections only.
- Permission prompts emit user decisions through the narrow runtime UI command API, not private runtime services.
- UI never mutates domain tables directly.
- UI never imports
packages/runtime/src/*private implementation modules. - Diff/evidence views must link back to artifact/evidence refs.
8. CLI Package Code View
Expected directory:
packages/cli/src/
index.ts
commands/
run.ts
init.ts
doctor.ts
provider.ts
e2e.ts
release.ts
bootstrap/
createRuntime.ts
loadConfig.ts
UML
@startuml
class CliEntrypoint {
+main(argv): Promise<number>
}
class RunCommand
class InitCommand
class DoctorCommand
class ProviderCommand
class E2ECommand
class ReleaseCommand
class RuntimeFactory {
+create(options): Promise<RuntimeApp>
}
CliEntrypoint --> RunCommand
CliEntrypoint --> InitCommand
CliEntrypoint --> DoctorCommand
CliEntrypoint --> ProviderCommand
CliEntrypoint --> E2ECommand
CliEntrypoint --> ReleaseCommand
RunCommand --> RuntimeFactory
InitCommand --> RuntimeFactory
DoctorCommand --> RuntimeFactory
@enduml
9. Repository Interface Code View
Domain repositories live under packages/runtime/src/storage/repositories/.
@startuml
interface SessionRepository
interface MessageRepository
interface EventRepository
interface TaskRepository
interface AgentRepository
interface ToolRunRepository
interface CommandRunRepository
interface ArtifactRepository
interface DiagnosticRepository
interface EvidenceRepository
interface WorkspaceRepository
interface SummaryRepository
interface UiStateRepository
class SessionStore {
+sessions: SessionRepository
+messages: MessageRepository
+events: EventRepository
+tasks: TaskRepository
+agents: AgentRepository
+toolRuns: ToolRunRepository
+commandRuns: CommandRunRepository
+artifacts: ArtifactRepository
+diagnostics: DiagnosticRepository
+evidence: EvidenceRepository
+workspaces: WorkspaceRepository
+summaries: SummaryRepository
+uiState: UiStateRepository
}
@enduml
Repositories must be thin persistence adapters. Scheduling, permission, and projection logic must not be hidden inside repositories.
10. Worker Role Code View
@startuml
interface WorkerRole {
+run(taskSpec, contextPack, runtime): Promise<WorkerResult>
}
class WorkerRuntime {
+emit(event): void
+callTool(name, input): Promise<ToolResultEnvelope>
+checkpoint(data): Promise<void>
}
class ExecutorRole
class ReviewerRole
class DebuggerRole
class CompactorRole
class ExperienceMinerRole
ExecutorRole ..|> WorkerRole
ReviewerRole ..|> WorkerRole
DebuggerRole ..|> WorkerRole
CompactorRole ..|> WorkerRole
ExperienceMinerRole ..|> WorkerRole
WorkerRole --> WorkerRuntime
@enduml
Role constraints:
| Role | Write access | Required output |
|---|---|---|
| Executor | scoped project writes | ExecutorResult in WorkerResult |
| Reviewer | read-only | ReviewerResult |
| Debugger | scoped writes only when assigned | DebuggerResult |
| Compactor | summaries/artifacts only | CompactorResult |
| ExperienceMiner | candidates/rules/skills only when assigned | ExperienceMinerResult |
11. State Ownership Rules
| State | Owner | Access rule |
|---|---|---|
| session DB | SessionStore/EventStore | runtime services only |
| live events | EventBus | runtime services publish/subscribe |
| UI projections | ProjectionStore | TUI read only |
| artifacts | ArtifactStore | tools/workers via runtime API |
| evidence refs | EvidenceStore | reports/reviews/debug via runtime API |
| tasks/agents | Scheduler | repositories are storage only |
| permission decisions | PermissionEngine | ToolRegistry requests decisions |
| model config | ProviderManager | runtime/Doctor read through API |
| project rules | ContextAssembler/ProjectStore | workers receive context excerpts |
12. Implementation Cut Lines
V1.0.0 Alpha implementation must create public interfaces matching interface-contracts-v1.md. Classes may be implemented as functions/modules where idiomatic TypeScript is simpler, but module ownership, dependency direction, and service boundaries must remain intact.
Do not implement:
TUI direct DB access
worker direct SQLite writes
capability direct dependency install
provider adapter changing prompt semantics silently
tool execution without PermissionEngine
repositories containing scheduling policy