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.
Files changed (113) hide show
  1. package/dist/agents/permissions.js +9 -6
  2. package/dist/agents/permissions.js.map +1 -1
  3. package/dist/cli.js +35 -14
  4. package/dist/cli.js.map +1 -1
  5. package/dist/context/compression/headroom.d.ts +6 -0
  6. package/dist/context/compression/headroom.js +61 -15
  7. package/dist/context/compression/headroom.js.map +1 -1
  8. package/dist/context/compression/types.d.ts +1 -0
  9. package/dist/context/envelope.js +1 -1
  10. package/dist/context/envelope.js.map +1 -1
  11. package/dist/context/gateway.d.ts +2 -1
  12. package/dist/context/gateway.js +77 -41
  13. package/dist/context/gateway.js.map +1 -1
  14. package/dist/context/policy.js +1 -1
  15. package/dist/context/policy.js.map +1 -1
  16. package/dist/context/preflight.js +10 -4
  17. package/dist/context/preflight.js.map +1 -1
  18. package/dist/context/repository/graphify.d.ts +1 -0
  19. package/dist/context/repository/graphify.js +4 -33
  20. package/dist/context/repository/graphify.js.map +1 -1
  21. package/dist/context/repository/serena.d.ts +1 -1
  22. package/dist/context/repository/serena.js +2 -1
  23. package/dist/context/repository/serena.js.map +1 -1
  24. package/dist/context/transport.d.ts +33 -0
  25. package/dist/context/transport.js +63 -0
  26. package/dist/context/transport.js.map +1 -0
  27. package/dist/context/types.d.ts +19 -1
  28. package/dist/context/types.js +1 -1
  29. package/dist/context/types.js.map +1 -1
  30. package/dist/core/config.js +6 -8
  31. package/dist/core/config.js.map +1 -1
  32. package/dist/core/doctor.js +6 -6
  33. package/dist/core/doctor.js.map +1 -1
  34. package/dist/core/init.js +2 -1
  35. package/dist/core/init.js.map +1 -1
  36. package/dist/core/run.js +37 -14
  37. package/dist/core/run.js.map +1 -1
  38. package/dist/core/types.d.ts +30 -0
  39. package/dist/core/verify.d.ts +2 -0
  40. package/dist/core/verify.js +3 -2
  41. package/dist/core/verify.js.map +1 -1
  42. package/dist/evals/fullStack.d.ts +20 -0
  43. package/dist/evals/fullStack.js +138 -0
  44. package/dist/evals/fullStack.js.map +1 -0
  45. package/dist/evidence/graph.js +24 -7
  46. package/dist/evidence/graph.js.map +1 -1
  47. package/dist/memory/candidates.d.ts +29 -0
  48. package/dist/memory/candidates.js +31 -0
  49. package/dist/memory/candidates.js.map +1 -0
  50. package/dist/paseo/launchSpec.js +4 -4
  51. package/dist/paseo/launchSpec.js.map +1 -1
  52. package/dist/provenance/generate.d.ts +34 -0
  53. package/dist/provenance/generate.js +209 -41
  54. package/dist/provenance/generate.js.map +1 -1
  55. package/dist/providers/engram.d.ts +27 -1
  56. package/dist/providers/engram.js +142 -6
  57. package/dist/providers/engram.js.map +1 -1
  58. package/dist/providers/graphify.d.ts +28 -1
  59. package/dist/providers/graphify.js +114 -16
  60. package/dist/providers/graphify.js.map +1 -1
  61. package/dist/providers/graphifyModel.d.ts +23 -0
  62. package/dist/providers/graphifyModel.js +101 -0
  63. package/dist/providers/graphifyModel.js.map +1 -0
  64. package/dist/providers/memory.d.ts +1 -0
  65. package/dist/providers/memory.js +2 -0
  66. package/dist/providers/memory.js.map +1 -0
  67. package/dist/providers/serenaMcp.d.ts +7 -0
  68. package/dist/providers/serenaMcp.js +77 -0
  69. package/dist/providers/serenaMcp.js.map +1 -0
  70. package/dist/providers/types.d.ts +8 -2
  71. package/dist/providers/versions.d.ts +10 -0
  72. package/dist/providers/versions.js +3 -0
  73. package/dist/providers/versions.js.map +1 -0
  74. package/dist/telemetry/events.d.ts +1 -0
  75. package/dist/telemetry/events.js +37 -21
  76. package/dist/telemetry/events.js.map +1 -1
  77. package/dist/telemetry/otlp.d.ts +7 -1
  78. package/dist/telemetry/otlp.js +20 -41
  79. package/dist/telemetry/otlp.js.map +1 -1
  80. package/dist/telemetry/tracing.d.ts +19 -0
  81. package/dist/telemetry/tracing.js +141 -0
  82. package/dist/telemetry/tracing.js.map +1 -0
  83. package/dist/toolchain/config.js +3 -2
  84. package/dist/toolchain/config.js.map +1 -1
  85. package/dist/validators/external.js +27 -5
  86. package/dist/validators/external.js.map +1 -1
  87. package/dist/validators/graphify.js +5 -73
  88. package/dist/validators/graphify.js.map +1 -1
  89. package/dist/validators/opa.d.ts +14 -1
  90. package/dist/validators/opa.js +6 -2
  91. package/dist/validators/opa.js.map +1 -1
  92. package/dist/validators/toolEvidence.d.ts +9 -0
  93. package/dist/validators/toolEvidence.js +137 -0
  94. package/dist/validators/toolEvidence.js.map +1 -0
  95. package/dist/workers/agentPrompt.d.ts +9 -0
  96. package/dist/workers/agentPrompt.js +121 -9
  97. package/dist/workers/agentPrompt.js.map +1 -1
  98. package/docs/ARCHITECTURE.md +6 -1
  99. package/docs/COMPONENT_MATURITY.md +47 -0
  100. package/docs/CONTEXT_EFFICIENCY.md +11 -2
  101. package/docs/MEMORY.md +9 -0
  102. package/docs/OBSERVABILITY.md +6 -1
  103. package/docs/OSS_STACK.md +8 -2
  104. package/docs/SECURITY.md +12 -0
  105. package/docs/component-maturity.json +34 -0
  106. package/package.json +7 -1
  107. package/policies/core/trust-boundary.rego +14 -4
  108. package/schemas/project.schema.json +1 -1
  109. package/schemas/validation-report.schema.json +2 -1
  110. package/scripts/headroom-bridge.py +88 -0
  111. package/templates/project.yaml +4 -0
  112. package/templates/provider-versions.json +10 -0
  113. 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("graphify", root);
8
- const graph = await graphExists(root);
9
- return {
10
- ok: cli || graph,
11
- message: graph ? "Graphify graph detected at graphify-out/graph.json. Refresh it through the Graphify skill or codeIntelligence.refreshCommand before after-snapshots." : cli ? "Graphify CLI detected, but no graphify-out/graph.json exists yet. Build the graph through the Graphify skill." : "Graphify CLI/graph not found. Structural validation can remain optional or be disabled."
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 update(root) {
15
- if (!(await graphExists(root)))
16
- throw new Error("Graphify graph is unavailable. Build or refresh graphify-out/graph.json through the Graphify assistant skill or codeIntelligence.refreshCommand.");
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
- async function graphExists(root) {
20
- try {
21
- await fs.access(path.join(root, "graphify-out", "graph.json"));
22
- return true;
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 false;
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;AAE7B,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,MAAM,OAAO,gCAAgC;IAClC,IAAI,GAAG,UAAU,CAAC;IAC3B,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAClD,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC;QACtC,OAAO;YACL,EAAE,EAAE,GAAG,IAAI,KAAK;YAChB,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,sJAAsJ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,+GAA+G,CAAC,CAAC,CAAC,yFAAyF;SAC5X,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,IAAI,CAAC,CAAC,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,kJAAkJ,CAAC,CAAC;IACtM,CAAC;CACF;AACD,KAAK,UAAU,WAAW,CAAC,IAAY;IACrC,IAAI,CAAC;QAAC,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,YAAY,CAAC,CAAC,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,KAAK,CAAC;IAAC,CAAC;AAC9G,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,2 @@
1
+ export { createMemoryProvider, EngramMemoryProvider, filterStaleRecords, memoryFingerprint } from "./engram.js";
2
+ //# sourceMappingURL=memory.js.map
@@ -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,7 @@
1
+ export interface SerenaMcpContractResult {
2
+ initialized: boolean;
3
+ toolNames: string[];
4
+ semanticTool: string;
5
+ retrievalText: string;
6
+ }
7
+ export declare function runSerenaMcpContract(root: string, command?: string): Promise<SerenaMcpContractResult>;
@@ -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?(record: MemoryRecord): Promise<string | undefined>;
18
- recall?(project: string, query: string): Promise<MemoryRecord[]>;
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,10 @@
1
+ export declare const providerVersions: {
2
+ headroom: string;
3
+ graphify: string;
4
+ engram: string;
5
+ serena: string;
6
+ trivy: string;
7
+ opengrep: string;
8
+ playwright: string;
9
+ pnpm: string;
10
+ };
@@ -0,0 +1,3 @@
1
+ import versions from "../../templates/provider-versions.json" with { type: "json" };
2
+ export const providerVersions = versions;
3
+ //# sourceMappingURL=versions.js.map
@@ -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;
@@ -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 { exportEventSpan } from "./otlp.js";
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 tracer = trace.getTracer("agentic-engineering-harness");
14
- const span = tracer.startSpan(name);
15
- for (const [key, value] of Object.entries(attributes)) {
16
- if (["string", "number", "boolean"].includes(typeof value))
17
- span.setAttribute(key, value);
18
- }
19
- span.end();
20
- const relative = config.telemetry?.localEventsFile ?? ".harness/telemetry/events.ndjson";
21
- const file = path.resolve(root, relative);
22
- await fs.mkdir(path.dirname(file), { recursive: true });
23
- await fs.appendFile(file, `${JSON.stringify({ at: at.toISOString(), name, attributes })}\n`);
24
- try {
25
- await exportEventSpan(config, name, attributes, at);
26
- }
27
- catch (error) {
28
- if (config.telemetry?.required)
29
- throw error;
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":"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"}
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/telemetry/events.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,9 @@
1
1
  import type { HarnessProjectConfig } from "../core/types.js";
2
- export declare function exportEventSpan(config: HarnessProjectConfig, name: string, attributes: Record<string, unknown>, at?: Date): Promise<void>;
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;