mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-17 23:51:08 +00:00
114 lines
3.8 KiB
TypeScript
114 lines
3.8 KiB
TypeScript
#!/usr/bin/env npx tsx
|
||
/**
|
||
* Scenario test for the AI-Native Git Layer (agent_trace.jsonl).
|
||
*
|
||
* Run from repo root:
|
||
* pnpm tsx scripts/test-trace-scenario.ts
|
||
* or
|
||
* npx tsx scripts/test-trace-scenario.ts
|
||
*
|
||
* This script simulates: select_active_intent → write_to_file → post-hook appends to agent_trace.jsonl.
|
||
* It then prints the last trace entry so you can verify intent_id, mutation_class, content_hash, and REQ-ID.
|
||
*/
|
||
import fs from "fs/promises"
|
||
import path from "path"
|
||
|
||
import { PreHook } from "../src/hooks/pre-hook"
|
||
import { HookMiddleware } from "../src/hooks/middleware"
|
||
import { contentHash } from "../src/hooks/content-hash"
|
||
|
||
const cwd = process.cwd()
|
||
const tracePath = path.join(cwd, ".orchestration", "agent_trace.jsonl")
|
||
|
||
async function main() {
|
||
console.log("=== Traceability scenario (terminal test) ===\n")
|
||
|
||
let activeIntentId: string | null = null
|
||
const preHook = new PreHook({
|
||
cwd,
|
||
getActiveIntentId: () => activeIntentId,
|
||
setActiveIntentId: (id) => {
|
||
activeIntentId = id
|
||
},
|
||
requireIntentForDestructiveOnly: true,
|
||
})
|
||
|
||
const middleware = new HookMiddleware({
|
||
preHook,
|
||
getActiveIntentId: () => activeIntentId,
|
||
getCwd: () => cwd,
|
||
getReqId: () => "REQ-scenario-" + Date.now(),
|
||
getSessionLogId: () => "session-scenario",
|
||
getModelId: () => "scenario-runner",
|
||
getVcsRevisionId: () => undefined,
|
||
})
|
||
|
||
// Step 1: Select intent (like the agent would)
|
||
console.log("1. select_active_intent(INT-001) ...")
|
||
const selectResult = await middleware.preToolUse("select_active_intent", { intent_id: "INT-001" })
|
||
if (selectResult.blocked) {
|
||
console.error(" FAIL: select_active_intent blocked:", selectResult.error)
|
||
process.exit(1)
|
||
}
|
||
console.log(" OK – intent context loaded\n")
|
||
|
||
// Step 2: Simulate write_to_file with intent_id and mutation_class
|
||
const writeParams = {
|
||
path: "src/api/weather.ts",
|
||
content: "// Weather API\nconst getWeather = () => ({ temp: 72 })\nexport { getWeather }\n",
|
||
intent_id: "INT-001",
|
||
mutation_class: "INTENT_EVOLUTION" as const,
|
||
}
|
||
console.log("2. write_to_file (pre-hook check) ...")
|
||
const preWrite = await middleware.preToolUse("write_to_file", writeParams)
|
||
if (preWrite.blocked) {
|
||
console.error(" FAIL: write_to_file blocked:", preWrite.error)
|
||
process.exit(1)
|
||
}
|
||
console.log(" OK – within scope\n")
|
||
|
||
// Step 3: Post-hook appends to agent_trace.jsonl (like after real write)
|
||
console.log("3. postToolUse (append to agent_trace.jsonl) ...")
|
||
await middleware.postToolUse("write_to_file", writeParams, {})
|
||
console.log(" OK – trace entry appended\n")
|
||
|
||
// Step 4: Read and display the last trace entry
|
||
const raw = await fs.readFile(tracePath, "utf-8")
|
||
const lines = raw.trim().split("\n").filter(Boolean)
|
||
const lastLine = lines[lines.length - 1]
|
||
if (!lastLine) {
|
||
console.error(" FAIL: no lines in agent_trace.jsonl")
|
||
process.exit(1)
|
||
}
|
||
|
||
const entry = JSON.parse(lastLine)
|
||
const expectedHash = contentHash(writeParams.content)
|
||
|
||
console.log("4. Last trace entry (from .orchestration/agent_trace.jsonl):\n")
|
||
console.log(JSON.stringify(entry, null, 2))
|
||
console.log("\n--- Checks ---")
|
||
console.log(
|
||
" intent (specification):",
|
||
entry.files[0].conversations[0].related?.find((r: { type: string }) => r.type === "specification")?.value ??
|
||
"missing",
|
||
)
|
||
console.log(
|
||
" REQ-ID (request): ",
|
||
entry.files[0].conversations[0].related?.find((r: { type: string }) => r.type === "request")?.value ??
|
||
"missing",
|
||
)
|
||
console.log(
|
||
" content_hash in ranges: ",
|
||
entry.files[0].conversations[0].ranges[0]?.content_hash?.startsWith("sha256:") ? "yes" : "no",
|
||
)
|
||
console.log(
|
||
" expected hash match: ",
|
||
entry.files[0].conversations[0].ranges[0]?.content_hash === expectedHash ? "yes" : "no",
|
||
)
|
||
console.log("\n=== Scenario done. ===\n")
|
||
}
|
||
|
||
main().catch((err) => {
|
||
console.error(err)
|
||
process.exit(1)
|
||
})
|