agentic-engineering-harness 0.6.28 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/permissions.js +9 -6
- package/dist/agents/permissions.js.map +1 -1
- package/dist/cli.js +35 -14
- package/dist/cli.js.map +1 -1
- package/dist/context/compression/headroom.d.ts +6 -0
- package/dist/context/compression/headroom.js +61 -15
- package/dist/context/compression/headroom.js.map +1 -1
- package/dist/context/compression/types.d.ts +1 -0
- package/dist/context/envelope.js +1 -1
- package/dist/context/envelope.js.map +1 -1
- package/dist/context/gateway.d.ts +2 -1
- package/dist/context/gateway.js +77 -41
- package/dist/context/gateway.js.map +1 -1
- package/dist/context/policy.js +1 -1
- package/dist/context/policy.js.map +1 -1
- package/dist/context/preflight.js +10 -4
- package/dist/context/preflight.js.map +1 -1
- package/dist/context/repository/graphify.d.ts +1 -0
- package/dist/context/repository/graphify.js +4 -33
- package/dist/context/repository/graphify.js.map +1 -1
- package/dist/context/repository/serena.d.ts +1 -1
- package/dist/context/repository/serena.js +2 -1
- package/dist/context/repository/serena.js.map +1 -1
- package/dist/context/transport.d.ts +33 -0
- package/dist/context/transport.js +63 -0
- package/dist/context/transport.js.map +1 -0
- package/dist/context/types.d.ts +19 -1
- package/dist/context/types.js +1 -1
- package/dist/context/types.js.map +1 -1
- package/dist/core/config.js +6 -8
- package/dist/core/config.js.map +1 -1
- package/dist/core/doctor.js +6 -6
- package/dist/core/doctor.js.map +1 -1
- package/dist/core/init.js +2 -1
- package/dist/core/init.js.map +1 -1
- package/dist/core/run.js +37 -14
- package/dist/core/run.js.map +1 -1
- package/dist/core/types.d.ts +30 -0
- package/dist/core/verify.d.ts +2 -0
- package/dist/core/verify.js +3 -2
- package/dist/core/verify.js.map +1 -1
- package/dist/evals/fullStack.d.ts +20 -0
- package/dist/evals/fullStack.js +138 -0
- package/dist/evals/fullStack.js.map +1 -0
- package/dist/evidence/graph.js +24 -7
- package/dist/evidence/graph.js.map +1 -1
- package/dist/memory/candidates.d.ts +29 -0
- package/dist/memory/candidates.js +31 -0
- package/dist/memory/candidates.js.map +1 -0
- package/dist/paseo/launchSpec.js +4 -4
- package/dist/paseo/launchSpec.js.map +1 -1
- package/dist/provenance/generate.d.ts +34 -0
- package/dist/provenance/generate.js +209 -41
- package/dist/provenance/generate.js.map +1 -1
- package/dist/providers/engram.d.ts +27 -1
- package/dist/providers/engram.js +142 -6
- package/dist/providers/engram.js.map +1 -1
- package/dist/providers/graphify.d.ts +28 -1
- package/dist/providers/graphify.js +114 -16
- package/dist/providers/graphify.js.map +1 -1
- package/dist/providers/graphifyModel.d.ts +23 -0
- package/dist/providers/graphifyModel.js +101 -0
- package/dist/providers/graphifyModel.js.map +1 -0
- package/dist/providers/memory.d.ts +1 -0
- package/dist/providers/memory.js +2 -0
- package/dist/providers/memory.js.map +1 -0
- package/dist/providers/serenaMcp.d.ts +7 -0
- package/dist/providers/serenaMcp.js +77 -0
- package/dist/providers/serenaMcp.js.map +1 -0
- package/dist/providers/types.d.ts +8 -2
- package/dist/providers/versions.d.ts +10 -0
- package/dist/providers/versions.js +3 -0
- package/dist/providers/versions.js.map +1 -0
- package/dist/telemetry/events.d.ts +1 -0
- package/dist/telemetry/events.js +37 -21
- package/dist/telemetry/events.js.map +1 -1
- package/dist/telemetry/otlp.d.ts +7 -1
- package/dist/telemetry/otlp.js +20 -41
- package/dist/telemetry/otlp.js.map +1 -1
- package/dist/telemetry/tracing.d.ts +19 -0
- package/dist/telemetry/tracing.js +141 -0
- package/dist/telemetry/tracing.js.map +1 -0
- package/dist/toolchain/config.js +3 -2
- package/dist/toolchain/config.js.map +1 -1
- package/dist/validators/external.js +27 -5
- package/dist/validators/external.js.map +1 -1
- package/dist/validators/graphify.js +5 -73
- package/dist/validators/graphify.js.map +1 -1
- package/dist/validators/opa.d.ts +14 -1
- package/dist/validators/opa.js +6 -2
- package/dist/validators/opa.js.map +1 -1
- package/dist/validators/toolEvidence.d.ts +9 -0
- package/dist/validators/toolEvidence.js +137 -0
- package/dist/validators/toolEvidence.js.map +1 -0
- package/dist/workers/agentPrompt.d.ts +9 -0
- package/dist/workers/agentPrompt.js +121 -9
- package/dist/workers/agentPrompt.js.map +1 -1
- package/docs/ARCHITECTURE.md +6 -1
- package/docs/COMPONENT_MATURITY.md +47 -0
- package/docs/CONTEXT_EFFICIENCY.md +11 -2
- package/docs/MEMORY.md +9 -0
- package/docs/OBSERVABILITY.md +6 -1
- package/docs/OSS_STACK.md +8 -2
- package/docs/SECURITY.md +12 -0
- package/docs/component-maturity.json +34 -0
- package/package.json +7 -1
- package/policies/core/trust-boundary.rego +14 -4
- package/schemas/project.schema.json +1 -1
- package/schemas/validation-report.schema.json +2 -1
- package/scripts/headroom-bridge.py +88 -0
- package/templates/project.yaml +4 -0
- package/templates/provider-versions.json +10 -0
- package/templates/toolchain.yaml +21 -6
|
@@ -1,28 +1,126 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
1
2
|
import fs from "node:fs/promises";
|
|
2
3
|
import path from "node:path";
|
|
3
|
-
import { commandExists } from "../utils/process.js";
|
|
4
|
+
import { commandExists, runProcess } from "../utils/process.js";
|
|
5
|
+
import { loadCanonicalGraph } from "./graphifyModel.js";
|
|
6
|
+
import { providerVersions } from "./versions.js";
|
|
7
|
+
const GRAPHIFY_COMMAND = "graphify";
|
|
8
|
+
export const GRAPHIFY_VERSION = providerVersions.graphify;
|
|
9
|
+
/** Graphify owns generation/freshness; all consumers use graphifyModel.ts. */
|
|
4
10
|
export class GraphifyCodeIntelligenceProvider {
|
|
11
|
+
config;
|
|
12
|
+
executor;
|
|
5
13
|
name = "graphify";
|
|
14
|
+
constructor(config, executor = runProcess) {
|
|
15
|
+
this.config = config;
|
|
16
|
+
this.executor = executor;
|
|
17
|
+
}
|
|
6
18
|
async doctor(root) {
|
|
7
|
-
const cli = await commandExists(
|
|
8
|
-
const graph = await
|
|
9
|
-
|
|
10
|
-
ok:
|
|
11
|
-
|
|
12
|
-
};
|
|
19
|
+
const cli = await commandExists(GRAPHIFY_COMMAND, root);
|
|
20
|
+
const graph = await this.load(root);
|
|
21
|
+
if (!cli && !graph)
|
|
22
|
+
return { ok: false, message: "Graphify CLI and canonical graph are unavailable." };
|
|
23
|
+
const version = cli ? await this.providerVersion(root).catch(() => undefined) : undefined;
|
|
24
|
+
return { ok: true, message: graph ? `Graphify canonical graph is readable${version ? ` (${version})` : ""}; freshness is repository-state bound.` : `Graphify CLI detected${version ? ` (${version})` : ""}; provider generation is available.` };
|
|
13
25
|
}
|
|
14
|
-
async
|
|
15
|
-
|
|
16
|
-
|
|
26
|
+
async build(root) { await this.generate(root, false); }
|
|
27
|
+
async refresh(root) { await this.generate(root, false); }
|
|
28
|
+
async update(root) { await this.generate(root, true); }
|
|
29
|
+
async load(root) { return loadCanonicalGraph(root, this.graphPath()); }
|
|
30
|
+
async isFresh(root) {
|
|
31
|
+
const graph = await this.load(root);
|
|
32
|
+
const metadata = await this.readMetadata(root);
|
|
33
|
+
if (!graph || !metadata || metadata.provider !== "graphify")
|
|
34
|
+
return false;
|
|
35
|
+
const current = await sourceFingerprint(root);
|
|
36
|
+
return metadata.sourceFingerprint === current.sourceFingerprint && metadata.gitCommit === current.gitCommit && metadata.graphSha256 === graph.sourceHash && metadata.providerVersion.length > 0;
|
|
17
37
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
38
|
+
async impact(root) {
|
|
39
|
+
const graph = await this.load(root);
|
|
40
|
+
return { provider: this.name, affectedNodes: graph?.nodes ?? [], affectedCommunities: [...new Set(Object.values(graph?.communities ?? {}))] };
|
|
41
|
+
}
|
|
42
|
+
async generate(root, incremental) {
|
|
43
|
+
const override = this.config?.codeIntelligence?.refreshCommand?.trim();
|
|
44
|
+
if (override) {
|
|
45
|
+
const result = await this.executor(override, { cwd: root, timeoutMs: 300_000 });
|
|
46
|
+
if (result.exitCode !== 0)
|
|
47
|
+
throw new Error(`GRAPHIFY_REFRESH_FAILED: ${result.stderr || result.stdout}`);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
if (!(await commandExists(GRAPHIFY_COMMAND, root)))
|
|
51
|
+
throw new Error("GRAPHIFY_UNAVAILABLE: Graphify CLI is not installed.");
|
|
52
|
+
const args = [GRAPHIFY_COMMAND, ".", ...(incremental ? ["--update"] : []), ...(this.config?.codeIntelligence?.codeOnly ? ["--code-only"] : []), "--no-viz"];
|
|
53
|
+
const result = await this.executor(args.map(quote).join(" "), { cwd: root, timeoutMs: 300_000 });
|
|
54
|
+
if (result.exitCode !== 0)
|
|
55
|
+
throw new Error(`GRAPHIFY_REFRESH_FAILED: ${result.stderr || result.stdout}`);
|
|
56
|
+
}
|
|
57
|
+
await this.targetConfiguredGraph(root);
|
|
58
|
+
const graphFile = path.resolve(root, this.graphPath());
|
|
59
|
+
const raw = await fs.readFile(graphFile, "utf8").catch(() => undefined);
|
|
60
|
+
if (!raw)
|
|
61
|
+
throw new Error("GRAPHIFY_OUTPUT_MISSING: Graphify completed without a readable configured graph output.");
|
|
62
|
+
if (!(await this.load(root)))
|
|
63
|
+
throw new Error("GRAPHIFY_OUTPUT_INVALID: configured graph output is not valid through the canonical AEH model.");
|
|
64
|
+
const fingerprint = await sourceFingerprint(root);
|
|
65
|
+
const metadata = { version: 1, provider: "graphify", providerVersion: override ? "override" : await this.providerVersion(root), gitCommit: fingerprint.gitCommit, sourceFingerprint: fingerprint.sourceFingerprint, graphSha256: crypto.createHash("sha256").update(raw).digest("hex"), generatedAt: new Date().toISOString() };
|
|
66
|
+
const file = this.metadataPath(root);
|
|
67
|
+
await fs.mkdir(path.dirname(file), { recursive: true });
|
|
68
|
+
await fs.writeFile(file, `${JSON.stringify(metadata, null, 2)}\n`, "utf8");
|
|
69
|
+
}
|
|
70
|
+
async targetConfiguredGraph(root) {
|
|
71
|
+
if (this.config?.codeIntelligence?.refreshCommand?.trim())
|
|
72
|
+
return;
|
|
73
|
+
const target = path.resolve(root, this.graphPath());
|
|
74
|
+
if (target === path.resolve(root, "graphify-out/graph.json"))
|
|
75
|
+
return;
|
|
76
|
+
const generated = await fs.readFile(path.resolve(root, "graphify-out/graph.json"), "utf8").catch(() => undefined);
|
|
77
|
+
if (!generated)
|
|
78
|
+
return;
|
|
79
|
+
await fs.mkdir(path.dirname(target), { recursive: true });
|
|
80
|
+
await fs.writeFile(target, generated, "utf8");
|
|
81
|
+
}
|
|
82
|
+
graphPath() { return this.config?.codeIntelligence?.graphPath ?? "graphify-out/graph.json"; }
|
|
83
|
+
metadataPath(root) { return path.resolve(root, this.config?.codeIntelligence?.snapshotDir ?? ".harness/graphify", "generation.json"); }
|
|
84
|
+
async readMetadata(root) { try {
|
|
85
|
+
return JSON.parse(await fs.readFile(this.metadataPath(root), "utf8"));
|
|
23
86
|
}
|
|
24
87
|
catch {
|
|
25
|
-
return
|
|
88
|
+
return undefined;
|
|
89
|
+
} }
|
|
90
|
+
async providerVersion(root) {
|
|
91
|
+
const result = await this.executor(`${quote(GRAPHIFY_COMMAND)} --version`, { cwd: root, timeoutMs: 30_000 });
|
|
92
|
+
if (result.exitCode !== 0)
|
|
93
|
+
throw new Error(`Graphify version check failed: ${result.stderr || result.stdout}`);
|
|
94
|
+
const version = (result.stdout || result.stderr).trim().split(/\r?\n/).at(0)?.trim();
|
|
95
|
+
if (!version)
|
|
96
|
+
throw new Error("Graphify version check returned no version.");
|
|
97
|
+
return version;
|
|
26
98
|
}
|
|
27
99
|
}
|
|
100
|
+
async function sourceFingerprint(root) {
|
|
101
|
+
const filesResult = await runProcess("git ls-files -co --exclude-standard", { cwd: root, timeoutMs: 30_000 });
|
|
102
|
+
const names = filesResult.exitCode === 0 ? filesResult.stdout.split(/\r?\n/).map((item) => item.trim()).filter((item) => item && !excluded(item)) : await fallbackSourceFiles(root);
|
|
103
|
+
const hash = crypto.createHash("sha256");
|
|
104
|
+
for (const name of [...new Set(names)].sort())
|
|
105
|
+
hash.update(name).update("\0").update(await fs.readFile(path.resolve(root, name)).catch(() => Buffer.from(""))).update("\0");
|
|
106
|
+
const commitResult = await runProcess("git rev-parse HEAD", { cwd: root, timeoutMs: 30_000 });
|
|
107
|
+
return { sourceFingerprint: hash.digest("hex"), gitCommit: commitResult.exitCode === 0 ? commitResult.stdout.trim() : undefined };
|
|
108
|
+
}
|
|
109
|
+
async function fallbackSourceFiles(root) {
|
|
110
|
+
const result = [];
|
|
111
|
+
const visit = async (directory) => {
|
|
112
|
+
for (const entry of await fs.readdir(directory, { withFileTypes: true }).catch(() => [])) {
|
|
113
|
+
const absolute = path.join(directory, entry.name);
|
|
114
|
+
const relative = path.relative(root, absolute).replaceAll("\\", "/");
|
|
115
|
+
if (entry.isDirectory() && !excluded(relative))
|
|
116
|
+
await visit(absolute);
|
|
117
|
+
else if (entry.isFile() && !excluded(relative))
|
|
118
|
+
result.push(relative);
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
await visit(root);
|
|
122
|
+
return result;
|
|
123
|
+
}
|
|
124
|
+
function excluded(relative) { return relative === ".git" || relative.startsWith(".git/") || relative === "node_modules" || relative.startsWith("node_modules/") || relative === ".harness" || relative.startsWith(".harness/") || relative === "graphify-out" || relative.startsWith("graphify-out/"); }
|
|
125
|
+
function quote(value) { return `'${value.replaceAll("'", "'\\''")}'`; }
|
|
28
126
|
//# sourceMappingURL=graphify.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graphify.js","sourceRoot":"","sources":["../../src/providers/graphify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"graphify.js","sourceRoot":"","sources":["../../src/providers/graphify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { RepositoryContextMap } from "../context/repository/types.js";
|
|
2
|
+
/** Canonical, lossless-enough structural representation consumed by all AEH Graphify users. */
|
|
3
|
+
export interface CanonicalGraphEdge {
|
|
4
|
+
from: string;
|
|
5
|
+
to: string;
|
|
6
|
+
relation: string;
|
|
7
|
+
}
|
|
8
|
+
export interface CanonicalGraph {
|
|
9
|
+
createdAt: string;
|
|
10
|
+
source: string;
|
|
11
|
+
sourceHash: string;
|
|
12
|
+
nodes: string[];
|
|
13
|
+
edges: string[];
|
|
14
|
+
edgePairs: CanonicalGraphEdge[];
|
|
15
|
+
nodeFiles: Record<string, string>;
|
|
16
|
+
communities: Record<string, string>;
|
|
17
|
+
centrality: Record<string, number>;
|
|
18
|
+
generatedAt?: string;
|
|
19
|
+
}
|
|
20
|
+
export declare function loadCanonicalGraph(root: string, graphPath?: string): Promise<CanonicalGraph | undefined>;
|
|
21
|
+
/** One parser for Graphify variants; callers must not normalize provider output independently. */
|
|
22
|
+
export declare function normalizeGraphDocument(raw: unknown, source?: string, sourceHash?: string): CanonicalGraph;
|
|
23
|
+
export declare function canonicalGraphToRepositoryMap(graph: CanonicalGraph): RepositoryContextMap;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
export async function loadCanonicalGraph(root, graphPath = "graphify-out/graph.json") {
|
|
5
|
+
const source = path.resolve(root, graphPath);
|
|
6
|
+
try {
|
|
7
|
+
const content = await fs.readFile(source, "utf8");
|
|
8
|
+
return normalizeGraphDocument(JSON.parse(content), graphPath, crypto.createHash("sha256").update(content).digest("hex"));
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/** One parser for Graphify variants; callers must not normalize provider output independently. */
|
|
15
|
+
export function normalizeGraphDocument(raw, source = "graphify", sourceHash = crypto.createHash("sha256").update(JSON.stringify(raw)).digest("hex")) {
|
|
16
|
+
const labels = new Map();
|
|
17
|
+
const nodeFiles = {};
|
|
18
|
+
const communities = {};
|
|
19
|
+
const edges = new Set();
|
|
20
|
+
const edgePairs = new Map();
|
|
21
|
+
const nodes = new Set();
|
|
22
|
+
const visitNodes = (value) => {
|
|
23
|
+
if (!value || typeof value !== "object")
|
|
24
|
+
return;
|
|
25
|
+
if (Array.isArray(value)) {
|
|
26
|
+
value.forEach(visitNodes);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const object = value;
|
|
30
|
+
const id = scalar(object.id ?? object.key ?? object.node_id);
|
|
31
|
+
const label = scalar(object.label ?? object.name ?? object.qualified_name ?? object.title ?? object.file ?? object.path);
|
|
32
|
+
if (id && label)
|
|
33
|
+
labels.set(id, label);
|
|
34
|
+
if (label)
|
|
35
|
+
nodes.add(label);
|
|
36
|
+
const community = scalar(object.community ?? object.community_id ?? object.cluster);
|
|
37
|
+
if (label && community)
|
|
38
|
+
communities[label] = community;
|
|
39
|
+
const file = scalar(object.file ?? object.path ?? object.filepath ?? object.file_path ?? object.source_file ?? object.sourcePath);
|
|
40
|
+
if (label && file && looksLikePath(file))
|
|
41
|
+
nodeFiles[label] = normalizePath(file);
|
|
42
|
+
Object.values(object).forEach(visitNodes);
|
|
43
|
+
};
|
|
44
|
+
visitNodes(raw);
|
|
45
|
+
const visitEdges = (value) => {
|
|
46
|
+
if (!value || typeof value !== "object")
|
|
47
|
+
return;
|
|
48
|
+
if (Array.isArray(value)) {
|
|
49
|
+
value.forEach(visitEdges);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const object = value;
|
|
53
|
+
const sourceId = scalar(object.source ?? object.from ?? object.source_id);
|
|
54
|
+
const targetId = scalar(object.target ?? object.to ?? object.target_id);
|
|
55
|
+
if (sourceId && targetId) {
|
|
56
|
+
const from = labels.get(sourceId) ?? sourceId;
|
|
57
|
+
const to = labels.get(targetId) ?? targetId;
|
|
58
|
+
const relation = scalar(object.relation ?? object.type ?? object.kind ?? object.label) ?? "relates";
|
|
59
|
+
nodes.add(from);
|
|
60
|
+
nodes.add(to);
|
|
61
|
+
const text = `${from} --${relation}--> ${to}`;
|
|
62
|
+
edges.add(text);
|
|
63
|
+
edgePairs.set(text, { from, to, relation });
|
|
64
|
+
}
|
|
65
|
+
Object.values(object).forEach(visitEdges);
|
|
66
|
+
};
|
|
67
|
+
visitEdges(raw);
|
|
68
|
+
const adjacency = new Map();
|
|
69
|
+
const add = (from, to) => { const set = adjacency.get(from) ?? new Set(); set.add(to); adjacency.set(from, set); };
|
|
70
|
+
for (const edge of edgePairs.values()) {
|
|
71
|
+
add(edge.from, edge.to);
|
|
72
|
+
add(edge.to, edge.from);
|
|
73
|
+
}
|
|
74
|
+
const denominator = Math.max(1, nodes.size - 1);
|
|
75
|
+
const centrality = {};
|
|
76
|
+
for (const node of nodes)
|
|
77
|
+
centrality[node] = (adjacency.get(node)?.size ?? 0) / denominator;
|
|
78
|
+
const record = raw && typeof raw === "object" ? raw : {};
|
|
79
|
+
return {
|
|
80
|
+
createdAt: new Date().toISOString(), source, sourceHash,
|
|
81
|
+
generatedAt: typeof record.generatedAt === "string" ? record.generatedAt : typeof record.createdAt === "string" ? record.createdAt : undefined,
|
|
82
|
+
edges: [...edges].sort(),
|
|
83
|
+
edgePairs: [...edgePairs.values()].sort((a, b) => `${a.from}:${a.relation}:${a.to}`.localeCompare(`${b.from}:${b.relation}:${b.to}`)),
|
|
84
|
+
nodes: [...nodes].sort(), nodeFiles, communities, centrality
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
export function canonicalGraphToRepositoryMap(graph) {
|
|
88
|
+
const nodes = graph.nodes.map((label) => ({
|
|
89
|
+
id: label,
|
|
90
|
+
file: graph.nodeFiles[label] ?? label,
|
|
91
|
+
symbol: graph.nodeFiles[label] ? label : undefined,
|
|
92
|
+
centrality: graph.centrality[label],
|
|
93
|
+
community: graph.communities[label]
|
|
94
|
+
}));
|
|
95
|
+
const edges = graph.edgePairs.map((edge) => ({ from: edge.from, to: edge.to, kind: edge.relation }));
|
|
96
|
+
return { provider: "graphify", generatedAt: graph.generatedAt, nodes, edges };
|
|
97
|
+
}
|
|
98
|
+
function scalar(value) { return typeof value === "string" || typeof value === "number" ? String(value) : undefined; }
|
|
99
|
+
function looksLikePath(value) { return /[\\/]/.test(value) || /\.[A-Za-z0-9]{1,8}$/.test(value); }
|
|
100
|
+
function normalizePath(value) { return value.replaceAll("\\", "/").replace(/^\.\//, ""); }
|
|
101
|
+
//# sourceMappingURL=graphifyModel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphifyModel.js","sourceRoot":"","sources":["../../src/providers/graphifyModel.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createMemoryProvider, EngramMemoryProvider, filterStaleRecords, memoryFingerprint } from "./engram.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/providers/memory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import readline from "node:readline";
|
|
3
|
+
export async function runSerenaMcpContract(root, command = "serena") {
|
|
4
|
+
const child = spawn(command, ["start-mcp-server", "--context", "ide-assistant", "--project", root], { cwd: root, stdio: ["pipe", "pipe", "pipe"] });
|
|
5
|
+
const pending = new Map();
|
|
6
|
+
let nextId = 1;
|
|
7
|
+
const lineReader = readline.createInterface({ input: child.stdout });
|
|
8
|
+
lineReader.on("line", (line) => {
|
|
9
|
+
try {
|
|
10
|
+
const message = JSON.parse(line);
|
|
11
|
+
if (typeof message.id !== "number")
|
|
12
|
+
return;
|
|
13
|
+
const request = pending.get(message.id);
|
|
14
|
+
if (!request)
|
|
15
|
+
return;
|
|
16
|
+
pending.delete(message.id);
|
|
17
|
+
if (message.error)
|
|
18
|
+
request.reject(new Error(message.error.message ?? "Serena MCP request failed"));
|
|
19
|
+
else
|
|
20
|
+
request.resolve(message.result);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
// Serena diagnostics belong on stderr; malformed stdout is handled by
|
|
24
|
+
// the request timeout rather than being treated as a valid response.
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
child.on("error", (error) => {
|
|
28
|
+
for (const request of pending.values())
|
|
29
|
+
request.reject(error instanceof Error ? error : new Error(String(error)));
|
|
30
|
+
pending.clear();
|
|
31
|
+
});
|
|
32
|
+
try {
|
|
33
|
+
const initialized = await request(child, pending, nextId++, "initialize", { protocolVersion: "2025-06-18", capabilities: {}, clientInfo: { name: "aeh-provider-contract", version: "1" } });
|
|
34
|
+
child.stdin.write(JSON.stringify({ jsonrpc: "2.0", method: "notifications/initialized", params: {} }) + "\n");
|
|
35
|
+
const listed = await request(child, pending, nextId++, "tools/list", {});
|
|
36
|
+
const tools = Array.isArray(listed?.tools) ? listed.tools : [];
|
|
37
|
+
const toolNames = tools.flatMap((tool) => typeof tool.name === "string" ? [tool.name] : []);
|
|
38
|
+
const semanticTool = ["get_symbols_overview", "find_symbol", "find_referencing_symbols"].find((name) => toolNames.includes(name));
|
|
39
|
+
if (!semanticTool)
|
|
40
|
+
throw new Error("Serena MCP did not expose a semantic read-only tool.");
|
|
41
|
+
const args = semanticTool === "get_symbols_overview"
|
|
42
|
+
? { relative_path: "src/serena-fixture.ts", max_answer_chars: 4_000 }
|
|
43
|
+
: { name_path_pattern: "SerenaFixtureSymbol", relative_path: "src/serena-fixture.ts", max_matches: 5 };
|
|
44
|
+
const called = await request(child, pending, nextId++, "tools/call", { name: semanticTool, arguments: args });
|
|
45
|
+
const retrievalText = JSON.stringify(called);
|
|
46
|
+
if (!retrievalText.includes("SerenaFixtureSymbol"))
|
|
47
|
+
throw new Error("Serena semantic retrieval did not return the fixture symbol.");
|
|
48
|
+
return { initialized: Boolean(initialized), toolNames, semanticTool, retrievalText };
|
|
49
|
+
}
|
|
50
|
+
finally {
|
|
51
|
+
lineReader.close();
|
|
52
|
+
child.stdin.end();
|
|
53
|
+
await stop(child);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function request(child, pending, id, method, params) {
|
|
57
|
+
return new Promise((resolve, reject) => {
|
|
58
|
+
const timer = setTimeout(() => {
|
|
59
|
+
pending.delete(id);
|
|
60
|
+
reject(new Error("Serena MCP request '" + method + "' timed out."));
|
|
61
|
+
}, 45_000);
|
|
62
|
+
pending.set(id, {
|
|
63
|
+
resolve: (value) => { clearTimeout(timer); resolve(value); },
|
|
64
|
+
reject: (error) => { clearTimeout(timer); reject(error); }
|
|
65
|
+
});
|
|
66
|
+
child.stdin.write(JSON.stringify({ jsonrpc: "2.0", id, method, params }) + "\n");
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
async function stop(child) {
|
|
70
|
+
if (child.exitCode !== null)
|
|
71
|
+
return;
|
|
72
|
+
await new Promise((resolve) => {
|
|
73
|
+
const timer = setTimeout(() => { child.kill("SIGTERM"); resolve(); }, 5_000);
|
|
74
|
+
child.once("exit", () => { clearTimeout(timer); resolve(); });
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=serenaMcp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serenaMcp.js","sourceRoot":"","sources":["../../src/providers/serenaMcp.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,8 @@ export interface MemoryRecord {
|
|
|
5
5
|
title: string;
|
|
6
6
|
content: string;
|
|
7
7
|
source?: string;
|
|
8
|
+
sourceSha256?: string;
|
|
9
|
+
createdAt?: string;
|
|
8
10
|
supersedes?: string;
|
|
9
11
|
tags?: string[];
|
|
10
12
|
}
|
|
@@ -14,8 +16,8 @@ export interface MemoryProvider {
|
|
|
14
16
|
ok: boolean;
|
|
15
17
|
message: string;
|
|
16
18
|
}>;
|
|
17
|
-
remember
|
|
18
|
-
recall
|
|
19
|
+
remember(record: MemoryRecord): Promise<string | undefined>;
|
|
20
|
+
recall(project: string, query: string): Promise<MemoryRecord[]>;
|
|
19
21
|
}
|
|
20
22
|
export interface CodeImpactReport {
|
|
21
23
|
provider: string;
|
|
@@ -29,7 +31,11 @@ export interface CodeIntelligenceProvider {
|
|
|
29
31
|
ok: boolean;
|
|
30
32
|
message: string;
|
|
31
33
|
}>;
|
|
34
|
+
build?(root: string): Promise<void>;
|
|
35
|
+
refresh?(root: string): Promise<void>;
|
|
32
36
|
update?(root: string): Promise<void>;
|
|
37
|
+
load?(root: string): Promise<unknown | undefined>;
|
|
38
|
+
isFresh?(root: string): Promise<boolean>;
|
|
33
39
|
impact?(root: string, diffRef?: string): Promise<CodeImpactReport>;
|
|
34
40
|
}
|
|
35
41
|
export interface SemanticRepositoryProvider {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"versions.js","sourceRoot":"","sources":["../../src/providers/versions.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,wCAAwC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAEpF,MAAM,CAAC,MAAM,gBAAgB,GAAG,QAS/B,CAAC"}
|
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
import type { HarnessProjectConfig } from "../core/types.js";
|
|
2
2
|
export declare function recordEvent(root: string, config: HarnessProjectConfig, name: string, attributes: Record<string, unknown>): Promise<void>;
|
|
3
|
+
export declare function resetOperationTrace(operationId?: string): void;
|
package/dist/telemetry/events.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { trace } from "@opentelemetry/api";
|
|
4
3
|
import { updateCurrentOperationPhase } from "../operations/state.js";
|
|
5
|
-
import {
|
|
4
|
+
import { finishPhase, finishTracing, markSpanError, safeAttributes, startEventSpan } from "./tracing.js";
|
|
5
|
+
import { SpanStatusCode } from "@opentelemetry/api";
|
|
6
6
|
export async function recordEvent(root, config, name, attributes) {
|
|
7
7
|
const phase = operationPhaseForEvent(name);
|
|
8
8
|
if (phase)
|
|
@@ -10,31 +10,32 @@ export async function recordEvent(root, config, name, attributes) {
|
|
|
10
10
|
if (config.telemetry?.enabled === false)
|
|
11
11
|
return;
|
|
12
12
|
const at = new Date();
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
await fs.appendFile(file, `${JSON.stringify({ at: new Date().toISOString(), name: "harness.telemetry.export.error", attributes: { sourceEvent: name, error: String(error) } })}\n`);
|
|
31
|
-
}
|
|
13
|
+
const operationId = typeof attributes.operationId === "string" ? attributes.operationId : typeof attributes.taskId === "string" ? attributes.taskId : undefined;
|
|
14
|
+
const localFile = path.resolve(root, config.telemetry?.localEventsFile ?? ".harness/telemetry/events.ndjson");
|
|
15
|
+
const safe = safeAttributes(attributes);
|
|
16
|
+
const started = startEventSpan(config, operationId, name, phase, { ...safe, "aeh.local_file": localFile });
|
|
17
|
+
const failed = attributes.status === "FAIL" || attributes.status === "FAILED" || typeof attributes.error === "string";
|
|
18
|
+
if (failed)
|
|
19
|
+
markSpanError(started.span, typeof attributes.error === "string" ? attributes.error : undefined);
|
|
20
|
+
else
|
|
21
|
+
started.span.setStatus({ code: SpanStatusCode.OK });
|
|
22
|
+
const spanContext = started.span.spanContext();
|
|
23
|
+
started.span.end();
|
|
24
|
+
await fs.mkdir(path.dirname(localFile), { recursive: true });
|
|
25
|
+
await fs.appendFile(localFile, `${JSON.stringify({ at: at.toISOString(), name, traceId: spanContext.traceId, spanId: spanContext.spanId, parentSpanId: started.parentSpanId, status: failed ? "ERROR" : "OK", attributes: safe })}\n`);
|
|
26
|
+
if (operationId && isPhaseTerminal(name, phase))
|
|
27
|
+
finishPhase(operationId, phase);
|
|
28
|
+
if (operationId && isOperationTerminal(name))
|
|
29
|
+
await finishTracing(config, operationId);
|
|
32
30
|
}
|
|
31
|
+
export function resetOperationTrace(operationId) { void operationId; /* SDK context owns propagation; retained for API compatibility. */ }
|
|
33
32
|
function operationPhaseForEvent(name) {
|
|
34
33
|
if (name === "harness.run.start")
|
|
35
34
|
return "executing";
|
|
36
35
|
if (name.includes("planner") || name.includes("wave"))
|
|
37
36
|
return "planning";
|
|
37
|
+
if (name.includes("verify") || name.includes("validation") || name.includes("graphify"))
|
|
38
|
+
return "validation";
|
|
38
39
|
if (name === "harness.repair.start" || name.includes("remediation"))
|
|
39
40
|
return "remediation";
|
|
40
41
|
if (name.includes("review"))
|
|
@@ -43,6 +44,21 @@ function operationPhaseForEvent(name) {
|
|
|
43
44
|
return "delivery";
|
|
44
45
|
if (name === "harness.audit.start")
|
|
45
46
|
return "preparing-audit";
|
|
47
|
+
if (name.includes("context"))
|
|
48
|
+
return "context";
|
|
49
|
+
if (name.includes("provenance"))
|
|
50
|
+
return "provenance";
|
|
46
51
|
return undefined;
|
|
47
52
|
}
|
|
53
|
+
function isPhaseTerminal(name, phase) {
|
|
54
|
+
if (!phase)
|
|
55
|
+
return false;
|
|
56
|
+
return (phase === "validation" && name === "harness.verify.finish") ||
|
|
57
|
+
(phase === "review" && name === "harness.review.finish") ||
|
|
58
|
+
(phase === "delivery" && name === "harness.delivery.finalize") ||
|
|
59
|
+
(phase === "planning" && name === "harness.plan.ready");
|
|
60
|
+
}
|
|
61
|
+
function isOperationTerminal(name) {
|
|
62
|
+
return new Set(["harness.run.finish", "harness.audit.finish", "harness.change.finish", "harness.quick.finish", "operation.finish", "operation.completed", "operation.failed"]).has(name);
|
|
63
|
+
}
|
|
48
64
|
//# sourceMappingURL=events.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/telemetry/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/telemetry/events.ts"],"names":[],"mappings":"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"}
|
package/dist/telemetry/otlp.d.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
1
|
import type { HarnessProjectConfig } from "../core/types.js";
|
|
2
|
-
export
|
|
2
|
+
export interface TraceContext {
|
|
3
|
+
traceId: string;
|
|
4
|
+
parentSpanId?: string;
|
|
5
|
+
spanId: string;
|
|
6
|
+
}
|
|
7
|
+
/** Compatibility entry point backed by the official OpenTelemetry SDK. */
|
|
8
|
+
export declare function exportEventSpan(config: HarnessProjectConfig, name: string, attributes: Record<string, unknown>, _at?: Date, parent?: TraceContext): Promise<void>;
|
|
3
9
|
export declare function resolveEndpoint(config: HarnessProjectConfig): string | undefined;
|