feat(aircoding): AirCoding V2 baseline — deterministic multi-agent architecture
Forked from OpenCode v1.17.4 with multi-agent system: - 5 agents: aircoding, scheduler, worker, architect, reviewer - Deterministic DAG scheduling engine (coordinator_tick) - Tool whitelists as hard enforcement - AirCoding validation plugin - System prompt injection for routing - V1 requirements: C4 docs, ADR, AGENTS.md, debug-log.md - Design documents in docs/
This commit is contained in:
50
packages/tui/test/plugin/runtime.test.ts
Normal file
50
packages/tui/test/plugin/runtime.test.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import { expect, test } from "bun:test"
|
||||
import { createPluginRuntime } from "../../src/plugin/runtime"
|
||||
|
||||
test("routes use the latest registration and restore previous registrations", () => {
|
||||
const runtime = createPluginRuntime()
|
||||
const first = () => "first"
|
||||
const second = () => "second"
|
||||
runtime.routes.register([{ name: "demo", render: first }])
|
||||
const dispose = runtime.routes.register([{ name: "demo", render: second }])
|
||||
|
||||
expect(runtime.routes.get("demo")).toBe(second)
|
||||
dispose()
|
||||
expect(runtime.routes.get("demo")).toBe(first)
|
||||
})
|
||||
|
||||
test("facade publishes and clears presentation state", async () => {
|
||||
const runtime = createPluginRuntime()
|
||||
runtime.update({
|
||||
commands: {
|
||||
async activate() {
|
||||
return true
|
||||
},
|
||||
async deactivate() {
|
||||
return true
|
||||
},
|
||||
async add() {
|
||||
return true
|
||||
},
|
||||
async install() {
|
||||
return { ok: true, dir: "/tmp", tui: true }
|
||||
},
|
||||
},
|
||||
status: [
|
||||
{
|
||||
id: "demo",
|
||||
source: "internal",
|
||||
spec: "demo",
|
||||
target: "demo",
|
||||
enabled: true,
|
||||
active: true,
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
expect(await runtime.commands().activate("demo")).toBe(true)
|
||||
expect(runtime.status()).toHaveLength(1)
|
||||
runtime.clear()
|
||||
expect(await runtime.commands().activate("demo")).toBe(false)
|
||||
expect(runtime.status()).toEqual([])
|
||||
})
|
||||
38
packages/tui/test/plugin/slots.test.tsx
Normal file
38
packages/tui/test/plugin/slots.test.tsx
Normal file
@@ -0,0 +1,38 @@
|
||||
/** @jsxImportSource @opentui/solid */
|
||||
import { expect, test } from "bun:test"
|
||||
import { createSlot, createSolidSlotRegistry, testRender, useRenderer } from "@opentui/solid"
|
||||
import { onMount } from "solid-js"
|
||||
|
||||
type Slots = {
|
||||
prompt: {}
|
||||
}
|
||||
|
||||
test("replace slot mounts plugin content once", async () => {
|
||||
let mounts = 0
|
||||
|
||||
const Probe = () => {
|
||||
onMount(() => {
|
||||
mounts += 1
|
||||
})
|
||||
return <box />
|
||||
}
|
||||
|
||||
const App = () => {
|
||||
const registry = createSolidSlotRegistry<Slots>(useRenderer(), {})
|
||||
const Slot = createSlot(registry)
|
||||
registry.register({ id: "plugin", slots: { prompt: () => <Probe /> } })
|
||||
|
||||
return (
|
||||
<Slot name="prompt" mode="replace">
|
||||
<box />
|
||||
</Slot>
|
||||
)
|
||||
}
|
||||
|
||||
const app = await testRender(() => <App />)
|
||||
try {
|
||||
expect(mounts).toBe(1)
|
||||
} finally {
|
||||
app.renderer.destroy()
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user