Compare commits
2 Commits
6a3c988030
...
78b02d37a8
| Author | SHA1 | Date | |
|---|---|---|---|
| 78b02d37a8 | |||
| 465fd34671 |
@ -93,21 +93,68 @@ async function runAdversaryAnalysis() {
|
|||||||
|
|
||||||
// 2. Quality Engineer (Reads Mutation Testing Scores)
|
// 2. Quality Engineer (Reads Mutation Testing Scores)
|
||||||
console.log(" [Quality] Analyzing Mutation Scores (e.g., Stryker)...");
|
console.log(" [Quality] Analyzing Mutation Scores (e.g., Stryker)...");
|
||||||
// Simulated mutation finding
|
try {
|
||||||
findings.qualityMutations.push({
|
const strykerCmd = await runCommand("stryker", ["run"]);
|
||||||
file: "src/core/auth_guards.ts",
|
if (strykerCmd.code !== 0) {
|
||||||
survivingMutants: 2,
|
const mutationReportPath = join(CWD, "reports", "mutation", "mutation.json");
|
||||||
recommendation: "Write tests covering empty CSRF token edge-case.",
|
if (existsSync(mutationReportPath)) {
|
||||||
});
|
const mutationData = JSON.parse(Deno.readTextFileSync(mutationReportPath));
|
||||||
|
if (mutationData.files) {
|
||||||
|
for (const [file, fileData] of Object.entries<any>(mutationData.files)) {
|
||||||
|
const surviving = fileData.mutants.filter((m: any) => m.status === "Survived");
|
||||||
|
if (surviving.length > 0) {
|
||||||
|
findings.qualityMutations.push({
|
||||||
|
file,
|
||||||
|
survivingMutants: surviving.length,
|
||||||
|
mutantIds: surviving.map((m: any) => m.id),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.warn(" Stryker run failed, but reports/mutation/mutation.json not found.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(" Failed to execute Stryker or parse mutation results:", e);
|
||||||
|
}
|
||||||
|
|
||||||
// 3. Performance Engineer (Reads OTel Traces)
|
// 3. Performance Engineer (Reads OTel Traces)
|
||||||
console.log(" [Performance] Ingesting OpenTelemetry Traces...");
|
console.log(" [Performance] Ingesting OpenTelemetry Traces...");
|
||||||
// Simulate OTel finding
|
const telemetryDir = join(CWD, ".forum", "telemetry");
|
||||||
findings.performanceBottlenecks.push({
|
if (existsSync(telemetryDir)) {
|
||||||
endpoint: "/api/events/:id/attendees",
|
try {
|
||||||
p99LatencyMs: 450,
|
for (const entry of Deno.readDirSync(telemetryDir)) {
|
||||||
bottleneck: "Missing index on username JOIN.",
|
if (entry.isFile && entry.name.endsWith(".trace.json")) {
|
||||||
});
|
const tracePath = join(telemetryDir, entry.name);
|
||||||
|
const traceData = JSON.parse(Deno.readTextFileSync(tracePath));
|
||||||
|
|
||||||
|
// Distill traces down to adhere to Zero-Token Rule
|
||||||
|
const distilledTraces = [];
|
||||||
|
if (Array.isArray(traceData)) {
|
||||||
|
for (const trace of traceData) {
|
||||||
|
if (trace.durationMs > 100) { // e.g., bottleneck threshold
|
||||||
|
distilledTraces.push({
|
||||||
|
id: trace.id,
|
||||||
|
operationName: trace.operationName,
|
||||||
|
durationMs: trace.durationMs
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (distilledTraces.length > 0) {
|
||||||
|
findings.performanceBottlenecks.push({
|
||||||
|
source: tracePath,
|
||||||
|
slowTraces: distilledTraces
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(" Failed to parse OTel traces:", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
console.log("-> Adversary Agent: Analysis complete.");
|
console.log("-> Adversary Agent: Analysis complete.");
|
||||||
|
|
||||||
|
|||||||
@ -65,17 +65,38 @@ async function writeGitNote(
|
|||||||
async function analyzeTelemetry() {
|
async function analyzeTelemetry() {
|
||||||
console.log("-> Analyst Agent: Analyzing team friction and telemetry...");
|
console.log("-> Analyst Agent: Analyzing team friction and telemetry...");
|
||||||
|
|
||||||
// 1. Ingest Telemetry Notes
|
// 1. Calculate MTTR Dynamically
|
||||||
|
let mttrStr = "Unknown (No telemetry note found for HEAD)";
|
||||||
|
try {
|
||||||
|
const gitLogCmd = await runCommand("git", ["show", "-s", "--format=%ct", "HEAD"]);
|
||||||
|
if (gitLogCmd.code === 0 && gitLogCmd.stdout) {
|
||||||
|
const commitTimestamp = parseInt(gitLogCmd.stdout, 10) * 1000; // Convert to ms
|
||||||
|
|
||||||
|
const noteCmd = await runCommand("git", ["notes", "--ref", "refs/notes/telemetry", "show", "HEAD"]);
|
||||||
|
if (noteCmd.code === 0 && noteCmd.stdout) {
|
||||||
|
const notePayload = JSON.parse(noteCmd.stdout);
|
||||||
|
if (notePayload.timestamp) {
|
||||||
|
const deltaMs = Math.abs(commitTimestamp - notePayload.timestamp);
|
||||||
|
const deltaHours = (deltaMs / (1000 * 60 * 60)).toFixed(2);
|
||||||
|
mttrStr = `${deltaHours} hours`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(" ⚠️ Failed to calculate MTTR:", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Ingest Telemetry Notes
|
||||||
const telemetryNotes = await fetchGitNotes("telemetry");
|
const telemetryNotes = await fetchGitNotes("telemetry");
|
||||||
|
|
||||||
console.log(` Found ${telemetryNotes.length} telemetry data points.`);
|
console.log(` Found ${telemetryNotes.length} telemetry data points.`);
|
||||||
|
|
||||||
// 2. Synthesize Workflow Optimizations
|
// 3. Synthesize Workflow Optimizations
|
||||||
const optimization = {
|
const optimization = {
|
||||||
agent: "Analyst",
|
agent: "Analyst",
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
metrics: {
|
metrics: {
|
||||||
mttr: "2.4 hours",
|
mttr: mttrStr,
|
||||||
prCommentRatio: 0.15,
|
prCommentRatio: 0.15,
|
||||||
frictionMarkers: "High rate of Gatekeeper check failures.",
|
frictionMarkers: "High rate of Gatekeeper check failures.",
|
||||||
},
|
},
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { parseArgs } from "https://deno.land/std@0.224.0/cli/parse_args.ts";
|
import { parseArgs } from "https://deno.land/std@0.224.0/cli/parse_args.ts";
|
||||||
|
import { parse as parseYaml } from "npm:yaml";
|
||||||
|
|
||||||
async function runCommand(
|
async function runCommand(
|
||||||
cmd: string,
|
cmd: string,
|
||||||
@ -37,6 +38,30 @@ async function fetchFromMetaState(path: string): Promise<string | null> {
|
|||||||
return check.stdout;
|
return check.stdout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches list of files in a directory on the meta-state branch.
|
||||||
|
*/
|
||||||
|
async function listMetaStateDir(path: string): Promise<string[]> {
|
||||||
|
const check = await runCommand("git", ["ls-tree", "-r", "--name-only", "meta-state", path]);
|
||||||
|
if (check.code !== 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return check.stdout.split("\n").filter(Boolean);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a specific Git Note exists for a namespace on HEAD.
|
||||||
|
*/
|
||||||
|
async function getGitNotePayload(namespace: string): Promise<any | null> {
|
||||||
|
const cmd = await runCommand("git", ["notes", "--ref", `refs/notes/${namespace}`, "show", "HEAD"]);
|
||||||
|
if (cmd.code !== 0 || !cmd.stdout) return null;
|
||||||
|
try {
|
||||||
|
return JSON.parse(cmd.stdout);
|
||||||
|
} catch (_e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function writeGitNote(
|
async function writeGitNote(
|
||||||
namespace: string,
|
namespace: string,
|
||||||
payload: Record<string, unknown>,
|
payload: Record<string, unknown>,
|
||||||
@ -88,16 +113,53 @@ async function evaluatePipeline() {
|
|||||||
Object.keys(transitions).join(", "),
|
Object.keys(transitions).join(", "),
|
||||||
);
|
);
|
||||||
|
|
||||||
// 2. Fetch YAML DAGs to check task states (Simulated here)
|
// 2. Fetch YAML DAGs to check task states
|
||||||
console.log(" Checking Project DAG constraints...");
|
console.log(" Checking Project DAG constraints...");
|
||||||
|
const taskFiles = await listMetaStateDir("tasks/");
|
||||||
|
|
||||||
|
const tasks = [];
|
||||||
|
for (const file of taskFiles) {
|
||||||
|
const content = await fetchFromMetaState(file);
|
||||||
|
if (content) {
|
||||||
|
try {
|
||||||
|
const task = parseYaml(content);
|
||||||
|
tasks.push(task);
|
||||||
|
} catch (_e) {
|
||||||
|
console.warn(` ⚠️ Failed to parse YAML for ${file}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(` Found ${tasks.length} tasks in meta-state:tasks/`);
|
||||||
|
|
||||||
|
// 3. Evaluate Bounded Model Checking rules
|
||||||
|
console.log(" Evaluating role transitions and notes...");
|
||||||
|
let pipelineValid = true;
|
||||||
|
let blockReason = "";
|
||||||
|
|
||||||
|
// Example verification based on transitions.json mapped rules
|
||||||
|
if (transitions["Coder"] && transitions["Coder"].requires) {
|
||||||
|
for (const req of transitions["Coder"].requires) {
|
||||||
|
if (req === "Gatekeeper_Approval") {
|
||||||
|
const gatekeeperNote = await getGitNotePayload("gatekeeper_checklist");
|
||||||
|
if (!gatekeeperNote || gatekeeperNote.status !== "Completed") {
|
||||||
|
pipelineValid = false;
|
||||||
|
blockReason = "Gatekeeper checklist is missing or not marked as 'Completed'.";
|
||||||
|
console.warn(` ❌ BMC Rule Failed: ${blockReason}`);
|
||||||
|
} else {
|
||||||
|
console.log(` ✅ BMC Rule Passed: Gatekeeper_Approval satisfied.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 3. Evaluate state
|
|
||||||
const evaluationResult = {
|
const evaluationResult = {
|
||||||
agent: "Evaluator",
|
agent: "Evaluator",
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
pipelineState: "Valid",
|
pipelineState: pipelineValid ? "Valid" : "Blocked",
|
||||||
message:
|
message: pipelineValid
|
||||||
"All Bounded Model Checking rules satisfied. Transition to Coder permitted.",
|
? "All Bounded Model Checking rules satisfied. Transition permitted."
|
||||||
|
: `Transition Blocked. Reason: ${blockReason}`,
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
|
|||||||
@ -72,38 +72,47 @@ async function analyzeRequirements() {
|
|||||||
console.log("-> Gatekeeper Agent: Analyzing requirements...");
|
console.log("-> Gatekeeper Agent: Analyzing requirements...");
|
||||||
|
|
||||||
// 1. Fetch Ontologies (Requirements)
|
// 1. Fetch Ontologies (Requirements)
|
||||||
// In a real implementation, we'd list files in meta-state:ontologies/
|
const ontologyGraphStr = await fetchFromMetaState(
|
||||||
// For now, let's simulate checking an ontology graph.
|
|
||||||
const _ontologyGraphStr = await fetchFromMetaState(
|
|
||||||
"ontologies/ontology.graph",
|
"ontologies/ontology.graph",
|
||||||
);
|
);
|
||||||
|
|
||||||
// 2. Fetch YAML DAGs (Tasks)
|
|
||||||
// In a real implementation, we'd parse YAML DAGs from meta-state:tasks/
|
|
||||||
|
|
||||||
// Example dummy logic to generate a checklist
|
|
||||||
console.log(" Parsing Ontologies and YAML DAGs...");
|
console.log(" Parsing Ontologies and YAML DAGs...");
|
||||||
|
|
||||||
|
const items: { id: string; description: string; verified: boolean }[] = [];
|
||||||
|
|
||||||
|
if (ontologyGraphStr) {
|
||||||
|
try {
|
||||||
|
const graph = JSON.parse(ontologyGraphStr);
|
||||||
|
if (Array.isArray(graph)) {
|
||||||
|
for (const obj of graph) {
|
||||||
|
if (obj["@type"] === "Requirement") {
|
||||||
|
items.push({
|
||||||
|
id: obj.id || "UNKNOWN",
|
||||||
|
description: obj.description || "No description provided.",
|
||||||
|
verified: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (graph["@graph"] && Array.isArray(graph["@graph"])) {
|
||||||
|
for (const obj of graph["@graph"]) {
|
||||||
|
if (obj["@type"] === "Requirement") {
|
||||||
|
items.push({
|
||||||
|
id: obj.id || "UNKNOWN",
|
||||||
|
description: obj.description || "No description provided.",
|
||||||
|
verified: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (_e) {
|
||||||
|
console.warn(" ⚠️ Failed to parse ontologies/ontology.graph JSON-LD");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const checklist = {
|
const checklist = {
|
||||||
generatedAt: Date.now(),
|
generatedAt: Date.now(),
|
||||||
agent: "Gatekeeper",
|
agent: "Gatekeeper",
|
||||||
items: [
|
items,
|
||||||
{
|
|
||||||
id: "REQ-001",
|
|
||||||
description: "Ensure authentication adheres to Auth-Yes standards",
|
|
||||||
verified: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "REQ-002",
|
|
||||||
description: "Verify Zero-Trust Ownership Checks on database queries",
|
|
||||||
verified: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "REQ-003",
|
|
||||||
description: "Confirm rate limiting uses modular pre-check pattern",
|
|
||||||
verified: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
status: "Pending Coder Implementation",
|
status: "Pending Coder Implementation",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { parseArgs } from "https://deno.land/std@0.224.0/cli/parse_args.ts";
|
import { parseArgs } from "https://deno.land/std@0.224.0/cli/parse_args.ts";
|
||||||
|
import { Database } from "jsr:@db/sqlite";
|
||||||
|
import * as sqliteVec from "npm:sqlite-vec";
|
||||||
|
|
||||||
async function runCommand(
|
async function runCommand(
|
||||||
cmd: string,
|
cmd: string,
|
||||||
@ -50,25 +52,92 @@ async function fetchGitNotes(namespace: string): Promise<string[]> {
|
|||||||
async function gatherHistoricalContext() {
|
async function gatherHistoricalContext() {
|
||||||
console.log("-> Historian Agent: Gathering historical context...");
|
console.log("-> Historian Agent: Gathering historical context...");
|
||||||
|
|
||||||
// 1. Fetch from Vector DB (sqlite-vec)
|
// 1. Construct search string from file changes
|
||||||
// In a full implementation, we'd query the sqlite database on the meta-state branch.
|
const diffCmd = await runCommand("git", ["diff", "--name-only", "HEAD~1", "HEAD"]);
|
||||||
console.log(
|
const searchVectorString = diffCmd.stdout.split("\n").filter(Boolean).join(" ");
|
||||||
" Querying local vector embeddings (sqlite-vec) for relevant architectural decisions...",
|
console.log(` Search vector string derived from diff: "${searchVectorString}"`);
|
||||||
);
|
|
||||||
|
|
||||||
// 2. Fetch Git Notes (Reasoning, Telemetry, etc.)
|
// 2. Fetch from Vector DB
|
||||||
|
console.log(" Extracting SQLite databases from meta-state branch...");
|
||||||
|
|
||||||
|
const extractedVectors: string[] = [];
|
||||||
|
try {
|
||||||
|
const checkDocs = await runCommand("git", ["ls-tree", "meta-state", "docs_graph.sqlite"]);
|
||||||
|
const checkTelemetry = await runCommand("git", ["ls-tree", "meta-state", "telemetry_graph.sqlite"]);
|
||||||
|
|
||||||
|
// Dummy vector string based on search string for PoC query, normally we would generate an embedding for searchVectorString
|
||||||
|
const dummyVector = new Uint8Array(new Float32Array([0,0,0]).buffer);
|
||||||
|
|
||||||
|
if (checkDocs.code === 0 && checkDocs.stdout.trim() !== "") {
|
||||||
|
const tempDbPath = await Deno.makeTempFile({ suffix: ".sqlite" });
|
||||||
|
const dbFile = await Deno.open(tempDbPath, { write: true });
|
||||||
|
const cmd = new Deno.Command("git", {
|
||||||
|
args: ["show", "meta-state:docs_graph.sqlite"],
|
||||||
|
stdout: "piped"
|
||||||
|
});
|
||||||
|
const output = await cmd.output();
|
||||||
|
await dbFile.write(output.stdout);
|
||||||
|
dbFile.close();
|
||||||
|
|
||||||
|
const db = new Database(tempDbPath);
|
||||||
|
db.enableLoadExtension = true;
|
||||||
|
sqliteVec.load(db);
|
||||||
|
db.enableLoadExtension = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const results = db.prepare("SELECT text, vec_distance_cosine(embedding, ?) as similarity FROM docs ORDER BY similarity DESC LIMIT 3").all(dummyVector);
|
||||||
|
for (const row of results) {
|
||||||
|
extractedVectors.push(`Doc2Vec: ${row.text}`);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(" ⚠️ Could not query docs_graph.sqlite:", e);
|
||||||
|
}
|
||||||
|
db.close();
|
||||||
|
await Deno.remove(tempDbPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkTelemetry.code === 0 && checkTelemetry.stdout.trim() !== "") {
|
||||||
|
const tempDbPath = await Deno.makeTempFile({ suffix: ".sqlite" });
|
||||||
|
const dbFile = await Deno.open(tempDbPath, { write: true });
|
||||||
|
const cmd = new Deno.Command("git", {
|
||||||
|
args: ["show", "meta-state:telemetry_graph.sqlite"],
|
||||||
|
stdout: "piped"
|
||||||
|
});
|
||||||
|
const output = await cmd.output();
|
||||||
|
await dbFile.write(output.stdout);
|
||||||
|
dbFile.close();
|
||||||
|
|
||||||
|
const db = new Database(tempDbPath);
|
||||||
|
db.enableLoadExtension = true;
|
||||||
|
sqliteVec.load(db);
|
||||||
|
db.enableLoadExtension = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Assume telemetry table for PoC purposes
|
||||||
|
const results = db.prepare("SELECT text, vec_distance_cosine(embedding, ?) as similarity FROM telemetry ORDER BY similarity DESC LIMIT 3").all(dummyVector);
|
||||||
|
for (const row of results) {
|
||||||
|
extractedVectors.push(`Telemetry2Vec: ${row.text}`);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(" ⚠️ Could not query telemetry_graph.sqlite:", e);
|
||||||
|
}
|
||||||
|
db.close();
|
||||||
|
await Deno.remove(tempDbPath);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(" ⚠️ Failed to query sqlite db:", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Fetch Git Notes (Reasoning, Telemetry, etc.)
|
||||||
const reasoningNotes = await fetchGitNotes("reasoning");
|
const reasoningNotes = await fetchGitNotes("reasoning");
|
||||||
const aiNotes = await fetchGitNotes("ai");
|
const aiNotes = await fetchGitNotes("ai");
|
||||||
|
|
||||||
const combinedContext = {
|
const combinedContext = {
|
||||||
agent: "Historian",
|
agent: "Historian",
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
extractedVectors: [
|
extractedVectors: extractedVectors.length ? extractedVectors : ["No historical vector matches found."],
|
||||||
"Doc2Vec: Previous attempt at caching Auth tokens failed due to Valkey race conditions (Commit 29a3f).",
|
|
||||||
],
|
|
||||||
historicalNotes: [...reasoningNotes, ...aiNotes],
|
historicalNotes: [...reasoningNotes, ...aiNotes],
|
||||||
directive:
|
directive: "Ensure new Coder implementations avoid previously failed architectural patterns.",
|
||||||
"Ensure new Coder implementations avoid previously failed architectural patterns.",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log("-> Historian Agent: Context gathered successfully.");
|
console.log("-> Historian Agent: Context gathered successfully.");
|
||||||
|
|||||||
@ -7,6 +7,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { parseArgs } from "https://deno.land/std@0.224.0/cli/parse_args.ts";
|
import { parseArgs } from "https://deno.land/std@0.224.0/cli/parse_args.ts";
|
||||||
|
import { join } from "https://deno.land/std@0.224.0/path/mod.ts";
|
||||||
|
import { existsSync } from "https://deno.land/std@0.224.0/fs/exists.ts";
|
||||||
|
|
||||||
|
import * as scip from "npm:@sourcegraph/scip-typescript@0.3.3/dist/src/scip.js";
|
||||||
|
|
||||||
|
const CWD = Deno.cwd();
|
||||||
|
|
||||||
async function runCommand(
|
async function runCommand(
|
||||||
cmd: string,
|
cmd: string,
|
||||||
@ -68,15 +74,47 @@ async function updateDocumentation() {
|
|||||||
|
|
||||||
console.log(` Detected changes in ${changedFiles.length} files.`);
|
console.log(` Detected changes in ${changedFiles.length} files.`);
|
||||||
|
|
||||||
|
const proposedUpdates: { file: string, action: string, sourceAst: string }[] = [];
|
||||||
|
|
||||||
|
let scipIndex: any = null;
|
||||||
|
const scipPath = join(CWD, "index.scip");
|
||||||
|
if (!existsSync(scipPath)) {
|
||||||
|
console.warn(" ⚠️ index.scip not found. Failing gracefully.");
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
const buffer = Deno.readFileSync(scipPath);
|
||||||
|
scipIndex = scip.scip.Index.deserializeBinary(buffer);
|
||||||
|
console.log(` Successfully loaded SCIP index with ${scipIndex.documents.length} documents.`);
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(" ⚠️ Failed to deserialize index.scip:", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scipIndex) {
|
||||||
|
for (const file of changedFiles) {
|
||||||
|
const doc = scipIndex.documents.find((d: any) => d.relative_path === file);
|
||||||
|
if (doc) {
|
||||||
|
if (doc.occurrences && doc.occurrences.length > 0) {
|
||||||
|
proposedUpdates.push({
|
||||||
|
file: `docs/drift/${file}.md`,
|
||||||
|
action: `Document structural changes detected in SCIP index for ${file}`,
|
||||||
|
sourceAst: scipPath
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 2. Generate Doc Updates
|
// 2. Generate Doc Updates
|
||||||
const docUpdates = {
|
const docUpdates = {
|
||||||
agent: "Translator",
|
agent: "Translator",
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
updates: [
|
updates: proposedUpdates.length > 0 ? proposedUpdates : [
|
||||||
{
|
{
|
||||||
file: "docs/api/events.md",
|
file: "none",
|
||||||
action: "Simulated: Added description for new 'expand' endpoint.",
|
action: "No structural AST drift detected requiring documentation updates.",
|
||||||
},
|
sourceAst: "none"
|
||||||
|
}
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
77
deno.lock
generated
77
deno.lock
generated
@ -55,9 +55,12 @@
|
|||||||
"npm:@peculiar/asn1-x509@^2.6.1": "2.9.4",
|
"npm:@peculiar/asn1-x509@^2.6.1": "2.9.4",
|
||||||
"npm:@peculiar/x509@*": "1.14.3",
|
"npm:@peculiar/x509@*": "1.14.3",
|
||||||
"npm:@peculiar/x509@^1.14.3": "1.14.3",
|
"npm:@peculiar/x509@^1.14.3": "1.14.3",
|
||||||
|
"npm:@sourcegraph/scip-typescript@0.3.3": "0.3.3",
|
||||||
"npm:ioredis@*": "6.0.0",
|
"npm:ioredis@*": "6.0.0",
|
||||||
"npm:postgres@3": "3.4.4",
|
"npm:postgres@3": "3.4.4",
|
||||||
"npm:postgres@3.4.4": "3.4.4"
|
"npm:postgres@3.4.4": "3.4.4",
|
||||||
|
"npm:sqlite-vec@*": "0.1.9",
|
||||||
|
"npm:yaml@*": "2.9.0"
|
||||||
},
|
},
|
||||||
"jsr": {
|
"jsr": {
|
||||||
"@cliffy/ansi@1.0.0-rc.7": {
|
"@cliffy/ansi@1.0.0-rc.7": {
|
||||||
@ -417,6 +420,17 @@
|
|||||||
"tsyringe"
|
"tsyringe"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"@sourcegraph/scip-typescript@0.3.3": {
|
||||||
|
"integrity": "sha512-G7pPx0DttN8qPc2+afEyhkSZeJP0L/zV9+HTEFKX53wNpzzWImED6W8MHEsCxQA7bnLAhtXJB/yQVH/dnKXedw==",
|
||||||
|
"dependencies": [
|
||||||
|
"commander",
|
||||||
|
"google-protobuf",
|
||||||
|
"pretty-ms",
|
||||||
|
"progress",
|
||||||
|
"typescript"
|
||||||
|
],
|
||||||
|
"bin": true
|
||||||
|
},
|
||||||
"asn1js@3.0.10": {
|
"asn1js@3.0.10": {
|
||||||
"integrity": "sha512-S2s3aOytiKdFRdulw2qPE51MzjzVOisppcVv7jVFR+Kw0kxwvFrDcYA0h7Ndqbmj0HkMIXYWaoj7fli8kgx1eg==",
|
"integrity": "sha512-S2s3aOytiKdFRdulw2qPE51MzjzVOisppcVv7jVFR+Kw0kxwvFrDcYA0h7Ndqbmj0HkMIXYWaoj7fli8kgx1eg==",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
@ -428,6 +442,9 @@
|
|||||||
"cluster-key-slot@1.1.1": {
|
"cluster-key-slot@1.1.1": {
|
||||||
"integrity": "sha512-rwHwUfXL40Chm1r08yrhU3qpUvdVlgkKNeyeGPOxnW8/SyVDvgRaed/Uz54AqWNaTCAThlj6QAs3TZcKI0xDEw=="
|
"integrity": "sha512-rwHwUfXL40Chm1r08yrhU3qpUvdVlgkKNeyeGPOxnW8/SyVDvgRaed/Uz54AqWNaTCAThlj6QAs3TZcKI0xDEw=="
|
||||||
},
|
},
|
||||||
|
"commander@9.5.0": {
|
||||||
|
"integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ=="
|
||||||
|
},
|
||||||
"debug@4.4.3": {
|
"debug@4.4.3": {
|
||||||
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
|
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
@ -437,6 +454,9 @@
|
|||||||
"denque@2.1.0": {
|
"denque@2.1.0": {
|
||||||
"integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw=="
|
"integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw=="
|
||||||
},
|
},
|
||||||
|
"google-protobuf@3.21.4": {
|
||||||
|
"integrity": "sha512-MnG7N936zcKTco4Jd2PX2U96Kf9PxygAPKBug+74LHzmHXmceN16MmRcdgZv+DGef/S9YvQAfRsNCn4cjf9yyQ=="
|
||||||
|
},
|
||||||
"ioredis@6.0.0": {
|
"ioredis@6.0.0": {
|
||||||
"integrity": "sha512-f+Dtubxfpf6KYFq7WVXJoOLn0bk4TJrMrN9SzeE+jrWrCWj7XX3fA6vkryafhADX+GMymRxgDJDOI33COkJc0w==",
|
"integrity": "sha512-f+Dtubxfpf6KYFq7WVXJoOLn0bk4TJrMrN9SzeE+jrWrCWj7XX3fA6vkryafhADX+GMymRxgDJDOI33COkJc0w==",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
@ -451,9 +471,21 @@
|
|||||||
"ms@2.1.3": {
|
"ms@2.1.3": {
|
||||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||||
},
|
},
|
||||||
|
"parse-ms@2.1.0": {
|
||||||
|
"integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA=="
|
||||||
|
},
|
||||||
"postgres@3.4.4": {
|
"postgres@3.4.4": {
|
||||||
"integrity": "sha512-IbyN+9KslkqcXa8AO9fxpk97PA4pzewvpi2B3Dwy9u4zpV32QicaEdgmF3eSQUzdRk7ttDHQejNgAEr4XoeH4A=="
|
"integrity": "sha512-IbyN+9KslkqcXa8AO9fxpk97PA4pzewvpi2B3Dwy9u4zpV32QicaEdgmF3eSQUzdRk7ttDHQejNgAEr4XoeH4A=="
|
||||||
},
|
},
|
||||||
|
"pretty-ms@7.0.1": {
|
||||||
|
"integrity": "sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==",
|
||||||
|
"dependencies": [
|
||||||
|
"parse-ms"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"progress@2.0.3": {
|
||||||
|
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="
|
||||||
|
},
|
||||||
"pvtsutils@1.3.6": {
|
"pvtsutils@1.3.6": {
|
||||||
"integrity": "sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==",
|
"integrity": "sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
@ -469,6 +501,41 @@
|
|||||||
"reflect-metadata@0.2.2": {
|
"reflect-metadata@0.2.2": {
|
||||||
"integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q=="
|
"integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q=="
|
||||||
},
|
},
|
||||||
|
"sqlite-vec-darwin-arm64@0.1.9": {
|
||||||
|
"integrity": "sha512-jSsZpE42OfBkGL/ItyJTVCUwl6o6Ka3U5rc4j+UBDIQzC1ulSSKMEhQLthsOnF/MdAf1MuAkYhkdKmmcjaIZQg==",
|
||||||
|
"os": ["darwin"],
|
||||||
|
"cpu": ["arm64"]
|
||||||
|
},
|
||||||
|
"sqlite-vec-darwin-x64@0.1.9": {
|
||||||
|
"integrity": "sha512-KDlVyqQT7pnOhU1ymB9gs7dMbSoVmKHitT+k1/xkjarcX8bBqPxWrGlK/R+C5WmWkfvWwyq5FfXfiBYCBs6PlA==",
|
||||||
|
"os": ["darwin"],
|
||||||
|
"cpu": ["x64"]
|
||||||
|
},
|
||||||
|
"sqlite-vec-linux-arm64@0.1.9": {
|
||||||
|
"integrity": "sha512-5wXVJ9c9kR4CHm/wVqXb/R+XUHTdpZ4nWbPHlS+gc9qQFVHs92Km4bPnCKX4rtcPMzvNis+SIzMJR1SCEwpuUw==",
|
||||||
|
"os": ["linux"],
|
||||||
|
"cpu": ["arm64"]
|
||||||
|
},
|
||||||
|
"sqlite-vec-linux-x64@0.1.9": {
|
||||||
|
"integrity": "sha512-w3tCH8xK2finW8fQJ/m8uqKodXUZ9KAuAar2UIhz4BHILfpE0WM/MTGCRfa7RjYbrYim5Luk3guvMOGI7T7JQA==",
|
||||||
|
"os": ["linux"],
|
||||||
|
"cpu": ["x64"]
|
||||||
|
},
|
||||||
|
"sqlite-vec-windows-x64@0.1.9": {
|
||||||
|
"integrity": "sha512-y3gEIyy/17bq2QFPQOWLE68TYWcRZkBQVA2XLrTPHNTOp55xJi/BBBmOm40tVMDMjtP+Elpk6UBUXdaq+46b0Q==",
|
||||||
|
"os": ["win32"],
|
||||||
|
"cpu": ["x64"]
|
||||||
|
},
|
||||||
|
"sqlite-vec@0.1.9": {
|
||||||
|
"integrity": "sha512-L7XJWRIBNvR9O5+vh1FQ+IGkh/3D2AzVksW5gdtk28m78Hy8skFD0pqReKH1Yp0/BUKRGcffgKvyO/EON5JXpA==",
|
||||||
|
"optionalDependencies": [
|
||||||
|
"sqlite-vec-darwin-arm64",
|
||||||
|
"sqlite-vec-darwin-x64",
|
||||||
|
"sqlite-vec-linux-arm64",
|
||||||
|
"sqlite-vec-linux-x64",
|
||||||
|
"sqlite-vec-windows-x64"
|
||||||
|
]
|
||||||
|
},
|
||||||
"standard-as-callback@2.1.0": {
|
"standard-as-callback@2.1.0": {
|
||||||
"integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A=="
|
"integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A=="
|
||||||
},
|
},
|
||||||
@ -484,11 +551,19 @@
|
|||||||
"tslib@1.14.1"
|
"tslib@1.14.1"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"typescript@4.9.5": {
|
||||||
|
"integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
|
||||||
|
"bin": true
|
||||||
|
},
|
||||||
"undici@5.29.0": {
|
"undici@5.29.0": {
|
||||||
"integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==",
|
"integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"@fastify/busboy"
|
"@fastify/busboy"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"yaml@2.9.0": {
|
||||||
|
"integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==",
|
||||||
|
"bin": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"remote": {
|
"remote": {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user