agentic-engineering-harness 0.6.27 → 0.6.28

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 (157) hide show
  1. package/README.md +3 -3
  2. package/dist/agents/permissions.js +10 -0
  3. package/dist/agents/permissions.js.map +1 -1
  4. package/dist/audit/run.js +2 -0
  5. package/dist/audit/run.js.map +1 -1
  6. package/dist/context/budget.d.ts +4 -0
  7. package/dist/context/budget.js +19 -0
  8. package/dist/context/budget.js.map +1 -0
  9. package/dist/context/classifier.d.ts +4 -0
  10. package/dist/context/classifier.js +14 -0
  11. package/dist/context/classifier.js.map +1 -0
  12. package/dist/context/compression/headroom.d.ts +17 -0
  13. package/dist/context/compression/headroom.js +52 -0
  14. package/dist/context/compression/headroom.js.map +1 -0
  15. package/dist/context/compression/index.d.ts +3 -0
  16. package/dist/context/compression/index.js +4 -0
  17. package/dist/context/compression/index.js.map +1 -0
  18. package/dist/context/compression/lifecycle.d.ts +20 -0
  19. package/dist/context/compression/lifecycle.js +70 -0
  20. package/dist/context/compression/lifecycle.js.map +1 -0
  21. package/dist/context/compression/types.d.ts +27 -0
  22. package/dist/context/compression/types.js +2 -0
  23. package/dist/context/compression/types.js.map +1 -0
  24. package/dist/context/envelope.d.ts +4 -0
  25. package/dist/context/envelope.js +20 -0
  26. package/dist/context/envelope.js.map +1 -0
  27. package/dist/context/estimator.d.ts +3 -0
  28. package/dist/context/estimator.js +10 -0
  29. package/dist/context/estimator.js.map +1 -0
  30. package/dist/context/eval.d.ts +19 -0
  31. package/dist/context/eval.js +12 -0
  32. package/dist/context/eval.js.map +1 -0
  33. package/dist/context/gateway.d.ts +22 -0
  34. package/dist/context/gateway.js +180 -0
  35. package/dist/context/gateway.js.map +1 -0
  36. package/dist/context/index.d.ts +15 -0
  37. package/dist/context/index.js +16 -0
  38. package/dist/context/index.js.map +1 -0
  39. package/dist/context/policy.d.ts +6 -0
  40. package/dist/context/policy.js +40 -0
  41. package/dist/context/policy.js.map +1 -0
  42. package/dist/context/preflight.d.ts +13 -0
  43. package/dist/context/preflight.js +19 -0
  44. package/dist/context/preflight.js.map +1 -0
  45. package/dist/context/projectors/audit.d.ts +2 -0
  46. package/dist/context/projectors/audit.js +30 -0
  47. package/dist/context/projectors/audit.js.map +1 -0
  48. package/dist/context/projectors/diff.d.ts +2 -0
  49. package/dist/context/projectors/diff.js +8 -0
  50. package/dist/context/projectors/diff.js.map +1 -0
  51. package/dist/context/projectors/explorer.d.ts +2 -0
  52. package/dist/context/projectors/explorer.js +5 -0
  53. package/dist/context/projectors/explorer.js.map +1 -0
  54. package/dist/context/projectors/index.d.ts +8 -0
  55. package/dist/context/projectors/index.js +9 -0
  56. package/dist/context/projectors/index.js.map +1 -0
  57. package/dist/context/projectors/operation.d.ts +3 -0
  58. package/dist/context/projectors/operation.js +26 -0
  59. package/dist/context/projectors/operation.js.map +1 -0
  60. package/dist/context/projectors/planner.d.ts +2 -0
  61. package/dist/context/projectors/planner.js +5 -0
  62. package/dist/context/projectors/planner.js.map +1 -0
  63. package/dist/context/projectors/source.d.ts +2 -0
  64. package/dist/context/projectors/source.js +5 -0
  65. package/dist/context/projectors/source.js.map +1 -0
  66. package/dist/context/projectors/structured.d.ts +2 -0
  67. package/dist/context/projectors/structured.js +24 -0
  68. package/dist/context/projectors/structured.js.map +1 -0
  69. package/dist/context/projectors/validation.d.ts +3 -0
  70. package/dist/context/projectors/validation.js +25 -0
  71. package/dist/context/projectors/validation.js.map +1 -0
  72. package/dist/context/provenance.d.ts +3 -0
  73. package/dist/context/provenance.js +13 -0
  74. package/dist/context/provenance.js.map +1 -0
  75. package/dist/context/repository/graphify.d.ts +2 -0
  76. package/dist/context/repository/graphify.js +36 -0
  77. package/dist/context/repository/graphify.js.map +1 -0
  78. package/dist/context/repository/index.d.ts +6 -0
  79. package/dist/context/repository/index.js +7 -0
  80. package/dist/context/repository/index.js.map +1 -0
  81. package/dist/context/repository/map.d.ts +6 -0
  82. package/dist/context/repository/map.js +34 -0
  83. package/dist/context/repository/map.js.map +1 -0
  84. package/dist/context/repository/rank.d.ts +3 -0
  85. package/dist/context/repository/rank.js +43 -0
  86. package/dist/context/repository/rank.js.map +1 -0
  87. package/dist/context/repository/render.d.ts +8 -0
  88. package/dist/context/repository/render.js +21 -0
  89. package/dist/context/repository/render.js.map +1 -0
  90. package/dist/context/repository/serena.d.ts +11 -0
  91. package/dist/context/repository/serena.js +26 -0
  92. package/dist/context/repository/serena.js.map +1 -0
  93. package/dist/context/repository/types.d.ts +34 -0
  94. package/dist/context/repository/types.js +2 -0
  95. package/dist/context/repository/types.js.map +1 -0
  96. package/dist/context/retrieval/authorization.d.ts +11 -0
  97. package/dist/context/retrieval/authorization.js +9 -0
  98. package/dist/context/retrieval/authorization.js.map +1 -0
  99. package/dist/context/retrieval/gateway.d.ts +33 -0
  100. package/dist/context/retrieval/gateway.js +69 -0
  101. package/dist/context/retrieval/gateway.js.map +1 -0
  102. package/dist/context/retrieval/index.d.ts +5 -0
  103. package/dist/context/retrieval/index.js +6 -0
  104. package/dist/context/retrieval/index.js.map +1 -0
  105. package/dist/context/retrieval/mcp.d.ts +3 -0
  106. package/dist/context/retrieval/mcp.js +8 -0
  107. package/dist/context/retrieval/mcp.js.map +1 -0
  108. package/dist/context/retrieval/persisted.d.ts +3 -0
  109. package/dist/context/retrieval/persisted.js +22 -0
  110. package/dist/context/retrieval/persisted.js.map +1 -0
  111. package/dist/context/retrieval/server.d.ts +1 -0
  112. package/dist/context/retrieval/server.js +52 -0
  113. package/dist/context/retrieval/server.js.map +1 -0
  114. package/dist/context/telemetry.d.ts +3 -0
  115. package/dist/context/telemetry.js +9 -0
  116. package/dist/context/telemetry.js.map +1 -0
  117. package/dist/context/types.d.ts +225 -0
  118. package/dist/context/types.js +29 -0
  119. package/dist/context/types.js.map +1 -0
  120. package/dist/core/config.js +20 -0
  121. package/dist/core/config.js.map +1 -1
  122. package/dist/core/doctor.js +21 -0
  123. package/dist/core/doctor.js.map +1 -1
  124. package/dist/core/run.js +2 -0
  125. package/dist/core/run.js.map +1 -1
  126. package/dist/core/types.d.ts +47 -0
  127. package/dist/entry.js +30 -0
  128. package/dist/entry.js.map +1 -1
  129. package/dist/main.js +1 -0
  130. package/dist/main.js.map +1 -1
  131. package/dist/operations/change.js +2 -0
  132. package/dist/operations/change.js.map +1 -1
  133. package/dist/paseo/launchSpec.d.ts +3 -0
  134. package/dist/paseo/launchSpec.js +17 -0
  135. package/dist/paseo/launchSpec.js.map +1 -1
  136. package/dist/providers/headroom.d.ts +2 -0
  137. package/dist/providers/headroom.js +3 -0
  138. package/dist/providers/headroom.js.map +1 -0
  139. package/dist/providers/serena.d.ts +1 -0
  140. package/dist/providers/serena.js +2 -0
  141. package/dist/providers/serena.js.map +1 -0
  142. package/dist/providers/types.d.ts +17 -0
  143. package/dist/toolchain/config.js +10 -1
  144. package/dist/toolchain/config.js.map +1 -1
  145. package/dist/toolchain/resolve.js +8 -0
  146. package/dist/toolchain/resolve.js.map +1 -1
  147. package/dist/workers/agentPrompt.js +20 -1
  148. package/dist/workers/agentPrompt.js.map +1 -1
  149. package/docs/ARCHITECTURE.md +14 -0
  150. package/docs/CONTEXT_EFFICIENCY.md +39 -0
  151. package/docs/OSS_STACK.md +4 -2
  152. package/package.json +2 -2
  153. package/presets/agents/default.jsonc +4 -4
  154. package/presets/agents/orchestration.jsonc +2 -2
  155. package/schemas/project.schema.json +14 -0
  156. package/templates/project.yaml +38 -0
  157. package/templates/toolchain.yaml +27 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provenance.js","sourceRoot":"","sources":["../../src/context/provenance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,CAAC,MAAM,0BAA0B,GAAG,gBAAgB,CAAC;AAE3D,MAAM,UAAU,MAAM,CAAC,KAAsB;IAC3C,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;QAC5C,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YAAE,OAAO,MAAM,CAAC;QAClF,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,MAAiC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtH,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { RepositoryContextMap } from "./types.js";
2
+ export declare function loadGraphifyContextMap(root: string, graphPath?: string): Promise<RepositoryContextMap | undefined>;
@@ -0,0 +1,36 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ export async function loadGraphifyContextMap(root, graphPath = "graphify-out/graph.json") {
4
+ let value;
5
+ try {
6
+ value = JSON.parse(await fs.readFile(path.resolve(root, graphPath), "utf8"));
7
+ }
8
+ catch {
9
+ return undefined;
10
+ }
11
+ return normalizeGraph(value);
12
+ }
13
+ function normalizeGraph(value) {
14
+ const object = value && typeof value === "object" ? value : {};
15
+ const rawNodes = Array.isArray(object.nodes) ? object.nodes : Array.isArray(object.files) ? object.files : [];
16
+ const nodes = rawNodes.flatMap((item, index) => {
17
+ if (!item || typeof item !== "object")
18
+ return [];
19
+ const record = item;
20
+ const file = String(record.file ?? record.path ?? record.name ?? "");
21
+ if (!file)
22
+ return [];
23
+ return [{ id: String(record.id ?? `${file}#${index}`), file, symbol: typeof record.symbol === "string" ? record.symbol : typeof record.name === "string" && record.name !== file ? record.name : undefined, signature: typeof record.signature === "string" ? record.signature : undefined, centrality: typeof record.centrality === "number" ? record.centrality : undefined, community: typeof record.community === "string" ? record.community : undefined }];
24
+ });
25
+ const rawEdges = Array.isArray(object.edges) ? object.edges : Array.isArray(object.links) ? object.links : [];
26
+ const edges = rawEdges.flatMap((item) => {
27
+ if (!item || typeof item !== "object")
28
+ return [];
29
+ const record = item;
30
+ const from = String(record.from ?? record.source ?? "");
31
+ const to = String(record.to ?? record.target ?? "");
32
+ return from && to ? [{ from, to, kind: typeof record.kind === "string" ? record.kind : typeof record.type === "string" ? record.type : undefined }] : [];
33
+ });
34
+ return { nodes, edges, provider: "graphify", generatedAt: typeof object.generatedAt === "string" ? object.generatedAt : undefined };
35
+ }
36
+ //# sourceMappingURL=graphify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graphify.js","sourceRoot":"","sources":["../../../src/context/repository/graphify.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export * from "./graphify.js";
2
+ export * from "./map.js";
3
+ export * from "./rank.js";
4
+ export * from "./render.js";
5
+ export * from "./serena.js";
6
+ export * from "./types.js";
@@ -0,0 +1,7 @@
1
+ export * from "./graphify.js";
2
+ export * from "./map.js";
3
+ export * from "./rank.js";
4
+ export * from "./render.js";
5
+ export * from "./serena.js";
6
+ export * from "./types.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/context/repository/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { HarnessProjectConfig } from "../../core/types.js";
2
+ import type { RepositoryContextMap, RepositoryRankRequest } from "./types.js";
3
+ import { type RepositoryMapRender } from "./render.js";
4
+ export declare function buildRepositoryContextMap(root: string, config: HarnessProjectConfig, request?: RepositoryRankRequest): Promise<RepositoryMapRender & {
5
+ map: RepositoryContextMap;
6
+ }>;
@@ -0,0 +1,34 @@
1
+ import { loadGraphifyContextMap } from "./graphify.js";
2
+ import { rankRepositoryNodes } from "./rank.js";
3
+ import { renderRepositoryMap } from "./render.js";
4
+ export async function buildRepositoryContextMap(root, config, request = {}) {
5
+ const graph = await loadGraphifyContextMap(root, config.codeIntelligence?.graphPath ?? "graphify-out/graph.json") ?? await filesystemContextMap(root);
6
+ const ranked = rankRepositoryNodes(graph, request);
7
+ const rendered = renderRepositoryMap(ranked, config.context?.repositoryMap?.tokenBudget ?? 2_000);
8
+ return { ...rendered, map: graph };
9
+ }
10
+ async function filesystemContextMap(root) {
11
+ const ignored = new Set([".git", "node_modules", "dist", ".harness", ".config"]);
12
+ const files = [];
13
+ async function visit(directory) {
14
+ if (files.length >= 5_000)
15
+ return;
16
+ for (const entry of await fs.readdir(directory, { withFileTypes: true }).catch(() => [])) {
17
+ if (ignored.has(entry.name))
18
+ continue;
19
+ const absolute = path.join(directory, entry.name);
20
+ if (entry.isDirectory())
21
+ await visit(absolute);
22
+ else if (entry.isFile())
23
+ files.push(path.relative(root, absolute).replaceAll(path.sep, "/"));
24
+ if (files.length >= 5_000)
25
+ return;
26
+ }
27
+ }
28
+ await visit(root);
29
+ files.sort();
30
+ return { provider: "filesystem", nodes: files.map((file) => ({ id: `file:${file}`, file })), edges: [] };
31
+ }
32
+ import fs from "node:fs/promises";
33
+ import path from "node:path";
34
+ //# sourceMappingURL=map.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"map.js","sourceRoot":"","sources":["../../../src/context/repository/map.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAEhD,OAAO,EAAE,mBAAmB,EAA4B,MAAM,aAAa,CAAC;AAE5E,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,IAAY,EAAE,MAA4B,EAAE,UAAiC,EAAE;IAC7H,MAAM,KAAK,GAAG,MAAM,sBAAsB,CAAC,IAAI,EAAE,MAAM,CAAC,gBAAgB,EAAE,SAAS,IAAI,yBAAyB,CAAC,IAAI,MAAM,oBAAoB,CAAC,IAAI,CAAC,CAAC;IACtJ,MAAM,MAAM,GAAG,mBAAmB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACnD,MAAM,QAAQ,GAAG,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,aAAa,EAAE,WAAW,IAAI,KAAK,CAAC,CAAC;IAClG,OAAO,EAAE,GAAG,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;AACrC,CAAC;AAED,KAAK,UAAU,oBAAoB,CAAC,IAAY;IAC9C,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC;IAAC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC7G,KAAK,UAAU,KAAK,CAAC,SAAiB;QACpC,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK;YAAE,OAAO;QAClC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAgC,CAAC,EAAE,CAAC;YACvH,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;gBAAE,SAAS;YACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YAClD,IAAI,KAAK,CAAC,WAAW,EAAE;gBAAE,MAAM,KAAK,CAAC,QAAQ,CAAC,CAAC;iBAC1C,IAAI,KAAK,CAAC,MAAM,EAAE;gBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;YAC7F,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK;gBAAE,OAAO;QACpC,CAAC;IACH,CAAC;IACD,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;IAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IAChC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,QAAQ,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;AAC3G,CAAC;AACD,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { RankedRepositoryNode, RepositoryContextMap, RepositoryNode, RepositoryRankRequest } from "./types.js";
2
+ export declare function rankRepositoryNodes(map: RepositoryContextMap, request: RepositoryRankRequest): RankedRepositoryNode[];
3
+ export declare function repositoryNodeKey(node: RepositoryNode): string;
@@ -0,0 +1,43 @@
1
+ export function rankRepositoryNodes(map, request) {
2
+ const explicit = new Set(request.explicitPaths ?? []);
3
+ const allowed = new Set(request.allowedPaths ?? []);
4
+ const changed = new Set(request.changedFiles ?? []);
5
+ const findings = new Set(request.findingLocations ?? []);
6
+ const references = new Set(request.referenceIds ?? []);
7
+ const ranked = map.nodes.map((node) => {
8
+ const reasons = [];
9
+ let score = 0;
10
+ if (explicit.has(node.file)) {
11
+ score += 100;
12
+ reasons.push("explicit-scope");
13
+ }
14
+ if (allowed.has(node.file)) {
15
+ score += 60;
16
+ reasons.push("task-scope");
17
+ }
18
+ if (changed.has(node.file) || node.changed) {
19
+ score += 40;
20
+ reasons.push("changed-file");
21
+ }
22
+ if (findings.has(node.file)) {
23
+ score += 35;
24
+ reasons.push("finding-location");
25
+ }
26
+ if (request.symbol && (node.symbol === request.symbol || node.file.includes(request.symbol))) {
27
+ score += 50;
28
+ reasons.push("exact-symbol");
29
+ }
30
+ if (references.has(node.id)) {
31
+ score += 30;
32
+ reasons.push("reference");
33
+ }
34
+ if (node.centrality !== undefined) {
35
+ score += Math.round(Math.max(0, Math.min(1, node.centrality)) * 20);
36
+ reasons.push("centrality");
37
+ }
38
+ return { ...node, score, reasons };
39
+ });
40
+ return ranked.sort((a, b) => b.score - a.score || a.file.localeCompare(b.file) || (a.symbol ?? "").localeCompare(b.symbol ?? "") || a.id.localeCompare(b.id));
41
+ }
42
+ export function repositoryNodeKey(node) { return `${node.file}${node.symbol ? `#${node.symbol}` : ""}`; }
43
+ //# sourceMappingURL=rank.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rank.js","sourceRoot":"","sources":["../../../src/context/repository/rank.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { RankedRepositoryNode } from "./types.js";
2
+ export interface RepositoryMapRender {
3
+ content: string;
4
+ selected: string[];
5
+ omitted: string[];
6
+ estimatedTokens: number;
7
+ }
8
+ export declare function renderRepositoryMap(nodes: RankedRepositoryNode[], tokenBudget: number): RepositoryMapRender;
@@ -0,0 +1,21 @@
1
+ import { estimateTokens } from "../estimator.js";
2
+ export function renderRepositoryMap(nodes, tokenBudget) {
3
+ if (!Number.isInteger(tokenBudget) || tokenBudget <= 0)
4
+ throw new Error("Repository map token budget must be positive.");
5
+ const selected = [];
6
+ const omitted = [];
7
+ let tokens = 0;
8
+ for (const node of nodes) {
9
+ const line = `${node.file}${node.symbol ? ` :: ${node.symbol}` : ""}${node.signature ? ` ${node.signature}` : ""} [score=${node.score}${node.reasons.length ? ` ${node.reasons.join(",")}` : ""}]`;
10
+ const next = estimateTokens(`${line}\n`);
11
+ if (tokens + next <= tokenBudget) {
12
+ selected.push(node);
13
+ tokens += next;
14
+ }
15
+ else
16
+ omitted.push(node);
17
+ }
18
+ const content = [...selected.map((node) => `${node.file}${node.symbol ? ` :: ${node.symbol}` : ""}${node.signature ? ` ${node.signature}` : ""} [score=${node.score}${node.reasons.length ? ` ${node.reasons.join(",")}` : ""}]`), omitted.length ? `[${omitted.length} lower-ranked repository nodes omitted; retrieve by authorized map fragment]` : undefined].filter((line) => Boolean(line)).join("\n");
19
+ return { content, selected: selected.map((node) => node.id), omitted: omitted.map((node) => node.id), estimatedTokens: estimateTokens(content) };
20
+ }
21
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../../../src/context/repository/render.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAKjD,MAAM,UAAU,mBAAmB,CAAC,KAA6B,EAAE,WAAmB;IACpF,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,WAAW,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACzH,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAAC,MAAM,OAAO,GAA2B,EAAE,CAAC;IAAC,IAAI,MAAM,GAAG,CAAC,CAAC;IACxG,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC;QACnM,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC;QACzC,IAAI,MAAM,GAAG,IAAI,IAAI,WAAW,EAAE,CAAC;YAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAAC,MAAM,IAAI,IAAI,CAAC;QAAC,CAAC;;YAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrG,CAAC;IACD,MAAM,OAAO,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,MAAM,8EAA8E,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7Z,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,eAAe,EAAE,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;AACnJ,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { McpServerConfig } from "../../core/types.js";
2
+ import type { ProviderHealth } from "../compression/types.js";
3
+ export declare const SERENA_VERSION = "1.5.3";
4
+ export declare class SerenaSemanticProvider {
5
+ private readonly command;
6
+ readonly name = "serena";
7
+ constructor(command?: string);
8
+ doctor(root: string): Promise<ProviderHealth>;
9
+ mcpServer(root: string): McpServerConfig;
10
+ }
11
+ export declare function semanticFirstInstruction(): string;
@@ -0,0 +1,26 @@
1
+ import { commandExists, runProcess } from "../../utils/process.js";
2
+ export const SERENA_VERSION = "1.5.3";
3
+ export class SerenaSemanticProvider {
4
+ command;
5
+ name = "serena";
6
+ constructor(command = "serena") {
7
+ this.command = command;
8
+ }
9
+ async doctor(root) {
10
+ if (!(await commandExists(this.command, root)))
11
+ return { ok: false, message: `Serena executable '${this.command}' was not found in the reconciled toolchain PATH.` };
12
+ const result = await runProcess(`${quote(this.command)} --version`, { cwd: root, timeoutMs: 15_000 });
13
+ if (result.exitCode !== 0)
14
+ return { ok: false, message: `Serena health check failed: ${result.stderr || result.stdout}` };
15
+ const version = (result.stdout || result.stderr).trim().split(/\r?\n/)[0];
16
+ return { ok: version.includes(SERENA_VERSION), version, message: version.includes(SERENA_VERSION) ? `Serena semantic retrieval ready (${version}).` : `Serena version drift: expected ${SERENA_VERSION}, got ${version}.` };
17
+ }
18
+ mcpServer(root) {
19
+ return { description: "AEH-managed local Serena semantic repository retrieval; editing is disabled by default.", type: "local", command: [this.command, "start-mcp-server", "--context", "ide-assistant", "--project", root], enabled: true, timeoutMs: 30_000 };
20
+ }
21
+ }
22
+ export function semanticFirstInstruction() {
23
+ return ["Semantic repository policy:", "1. Locate relevant symbols before reading complete files.", "2. Inspect symbol bodies only when required.", "3. Find referencing symbols before broad repository search.", "4. Read complete files only when file-level context is semantically required.", "5. Do not use Serena memory as AEH historical memory; Engram remains memory authority.", "6. Serena editing is disabled unless the assigned role and frozen scope explicitly permit it."].join("\n");
24
+ }
25
+ function quote(value) { return `'${value.replaceAll("'", "'\\''")}'`; }
26
+ //# sourceMappingURL=serena.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serena.js","sourceRoot":"","sources":["../../../src/context/repository/serena.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGnE,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC;AAEtC,MAAM,OAAO,sBAAsB;IAEJ;IADpB,IAAI,GAAG,QAAQ,CAAC;IACzB,YAA6B,UAAU,QAAQ;QAAlB,YAAO,GAAP,OAAO,CAAW;IAAG,CAAC;IAEnD,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,IAAI,CAAC,CAAC,MAAM,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,sBAAsB,IAAI,CAAC,OAAO,mDAAmD,EAAE,CAAC;QACrK,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;QACtG,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,+BAA+B,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;QAC1H,MAAM,OAAO,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1E,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,oCAAoC,OAAO,IAAI,CAAC,CAAC,CAAC,kCAAkC,cAAc,SAAS,OAAO,GAAG,EAAE,CAAC;IAC9N,CAAC;IAED,SAAS,CAAC,IAAY;QACpB,OAAO,EAAE,WAAW,EAAE,yFAAyF,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IACnQ,CAAC;CACF;AAED,MAAM,UAAU,wBAAwB;IACtC,OAAO,CAAC,6BAA6B,EAAE,2DAA2D,EAAE,8CAA8C,EAAE,6DAA6D,EAAE,+EAA+E,EAAE,wFAAwF,EAAE,+FAA+F,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC5e,CAAC;AAED,SAAS,KAAK,CAAC,KAAa,IAAY,OAAO,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC"}
@@ -0,0 +1,34 @@
1
+ export interface RepositoryNode {
2
+ id: string;
3
+ file: string;
4
+ symbol?: string;
5
+ signature?: string;
6
+ centrality?: number;
7
+ changed?: boolean;
8
+ community?: string;
9
+ }
10
+ export interface RepositoryEdge {
11
+ from: string;
12
+ to: string;
13
+ kind?: string;
14
+ }
15
+ export interface RepositoryContextMap {
16
+ nodes: RepositoryNode[];
17
+ edges: RepositoryEdge[];
18
+ provider: "graphify" | "filesystem" | string;
19
+ generatedAt?: string;
20
+ }
21
+ export interface RepositoryRankRequest {
22
+ explicitPaths?: string[];
23
+ allowedPaths?: string[];
24
+ changedFiles?: string[];
25
+ findingLocations?: string[];
26
+ symbol?: string;
27
+ referenceIds?: string[];
28
+ maxGraphHops?: number;
29
+ }
30
+ export interface RankedRepositoryNode extends RepositoryNode {
31
+ score: number;
32
+ reasons: string[];
33
+ distance?: number;
34
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/context/repository/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,11 @@
1
+ import type { ContextFragment } from "../types.js";
2
+ export interface RetrievalAuthorization {
3
+ root: string;
4
+ operationId: string;
5
+ logicalAgent: string;
6
+ allowedFragmentIds: string[];
7
+ fragments: Map<string, ContextFragment>;
8
+ }
9
+ export declare function authorizeRetrieval(input: Omit<RetrievalAuthorization, "fragments"> & {
10
+ fragments: ContextFragment[];
11
+ }): RetrievalAuthorization;
@@ -0,0 +1,9 @@
1
+ export function authorizeRetrieval(input) {
2
+ const fragments = new Map(input.fragments.map((fragment) => [fragment.id, fragment]));
3
+ const allowed = new Set(input.allowedFragmentIds);
4
+ for (const id of allowed)
5
+ if (!fragments.has(id))
6
+ throw new Error(`Cannot authorize unknown context fragment '${id}'.`);
7
+ return { ...input, allowedFragmentIds: [...allowed].sort(), fragments };
8
+ }
9
+ //# sourceMappingURL=authorization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authorization.js","sourceRoot":"","sources":["../../../src/context/retrieval/authorization.ts"],"names":[],"mappings":"AAUA,MAAM,UAAU,kBAAkB,CAAC,KAAmF;IACpH,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IACtF,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IAClD,KAAK,MAAM,EAAE,IAAI,OAAO;QAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,8CAA8C,EAAE,IAAI,CAAC,CAAC;IACxH,OAAO,EAAE,GAAG,KAAK,EAAE,kBAAkB,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC;AAC1E,CAAC"}
@@ -0,0 +1,33 @@
1
+ import type { RetrievalAuthorization } from "./authorization.js";
2
+ export interface RetrievalRequest {
3
+ fragmentId: string;
4
+ section?: "raw" | "source";
5
+ maxTokens?: number;
6
+ }
7
+ export interface RetrievalResult {
8
+ fragmentId: string;
9
+ content: string;
10
+ artifact: string;
11
+ sha256: string;
12
+ estimatedTokens: number;
13
+ repeated: boolean;
14
+ }
15
+ export interface RetrievalLimits {
16
+ maxRequestsPerTurn: number;
17
+ maxTokensPerRequest: number;
18
+ maxTotalTokensPerTurn: number;
19
+ }
20
+ export declare class ContextRetrievalGateway {
21
+ private readonly authorization;
22
+ private readonly limits;
23
+ private requests;
24
+ private totalTokens;
25
+ private readonly seen;
26
+ constructor(authorization: RetrievalAuthorization, limits: RetrievalLimits);
27
+ get metrics(): {
28
+ requests: number;
29
+ repeated: number;
30
+ totalTokens: number;
31
+ };
32
+ retrieve(request: RetrievalRequest): Promise<RetrievalResult>;
33
+ }
@@ -0,0 +1,69 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { estimateTokens } from "../estimator.js";
4
+ import { sha256 } from "../provenance.js";
5
+ export class ContextRetrievalGateway {
6
+ authorization;
7
+ limits;
8
+ requests = 0;
9
+ totalTokens = 0;
10
+ seen = new Set();
11
+ constructor(authorization, limits) {
12
+ this.authorization = authorization;
13
+ this.limits = limits;
14
+ }
15
+ get metrics() { return { requests: this.requests, repeated: [...this.seen].length < this.requests ? this.requests - [...this.seen].length : 0, totalTokens: this.totalTokens }; }
16
+ async retrieve(request) {
17
+ if (!this.authorization.allowedFragmentIds.includes(request.fragmentId))
18
+ throw new Error(`CONTEXT_RETRIEVAL_UNAUTHORIZED: fragment '${request.fragmentId}' is not authorized for operation '${this.authorization.operationId}'.`);
19
+ if (this.requests >= this.limits.maxRequestsPerTurn)
20
+ throw new Error("CONTEXT_RETRIEVAL_BUDGET_EXCEEDED: maximum requests per turn reached.");
21
+ const fragment = this.authorization.fragments.get(request.fragmentId);
22
+ if (!fragment)
23
+ throw new Error(`CONTEXT_RETRIEVAL_NOT_FOUND: fragment '${request.fragmentId}'.`);
24
+ const artifact = fragment.source?.artifact;
25
+ if (!artifact)
26
+ throw new Error(`CONTEXT_RETRIEVAL_NO_ARTIFACT: fragment '${request.fragmentId}' has no durable raw artifact.`);
27
+ const absolute = safeArtifactPath(this.authorization.root, artifact);
28
+ const raw = await fs.readFile(absolute, "utf8");
29
+ const expected = fragment.source?.sha256;
30
+ const actual = sha256(raw);
31
+ if (expected && expected !== actual)
32
+ throw new Error(`CONTEXT_RETRIEVAL_HASH_MISMATCH: ${artifact}.`);
33
+ const maxTokens = Math.min(request.maxTokens ?? this.limits.maxTokensPerRequest, this.limits.maxTokensPerRequest);
34
+ const tokens = estimateTokens(raw);
35
+ if (this.totalTokens + Math.min(tokens, maxTokens) > this.limits.maxTotalTokensPerTurn)
36
+ throw new Error("CONTEXT_RETRIEVAL_BUDGET_EXCEEDED: maximum tokens per turn reached.");
37
+ if (request.section && request.section !== "raw")
38
+ throw new Error(`Unsupported context retrieval section '${request.section}'.`);
39
+ this.requests += 1;
40
+ const repeated = this.seen.has(request.fragmentId);
41
+ this.seen.add(request.fragmentId);
42
+ const content = tokens <= maxTokens ? raw : boundedLines(raw, maxTokens);
43
+ this.totalTokens += estimateTokens(content);
44
+ return { fragmentId: request.fragmentId, content, artifact, sha256: actual, estimatedTokens: estimateTokens(content), repeated };
45
+ }
46
+ }
47
+ function safeArtifactPath(root, artifact) {
48
+ if (path.isAbsolute(artifact))
49
+ throw new Error("CONTEXT_RETRIEVAL_PATH_REJECTED: artifact paths must be relative to the operation root.");
50
+ const absoluteRoot = path.resolve(root);
51
+ const absolute = path.resolve(absoluteRoot, artifact);
52
+ if (absolute !== absoluteRoot && !absolute.startsWith(`${absoluteRoot}${path.sep}`))
53
+ throw new Error("CONTEXT_RETRIEVAL_PATH_REJECTED: artifact escapes the operation root.");
54
+ return absolute;
55
+ }
56
+ function boundedLines(value, maxTokens) {
57
+ const lines = value.split(/\r?\n/);
58
+ const selected = [];
59
+ let used = 0;
60
+ for (const line of lines) {
61
+ const next = estimateTokens(`${line}\n`);
62
+ if (used + next > maxTokens)
63
+ break;
64
+ selected.push(line);
65
+ used += next;
66
+ }
67
+ return `${selected.join("\n")}\n[bounded retrieval excerpt; retrieve again with a larger authorized budget for the complete raw artifact]`;
68
+ }
69
+ //# sourceMappingURL=gateway.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway.js","sourceRoot":"","sources":["../../../src/context/retrieval/gateway.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export * from "./authorization.js";
2
+ export * from "./gateway.js";
3
+ export * from "./mcp.js";
4
+ export * from "./persisted.js";
5
+ export * from "./server.js";
@@ -0,0 +1,6 @@
1
+ export * from "./authorization.js";
2
+ export * from "./gateway.js";
3
+ export * from "./mcp.js";
4
+ export * from "./persisted.js";
5
+ export * from "./server.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/context/retrieval/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ContextRetrievalGateway, RetrievalRequest } from "./gateway.js";
2
+ export declare function contextRetrievalToolDescription(): Record<string, unknown>;
3
+ export declare function handleContextRetrievalRequest(gateway: ContextRetrievalGateway, request: RetrievalRequest): Promise<Record<string, unknown>>;
@@ -0,0 +1,8 @@
1
+ export function contextRetrievalToolDescription() {
2
+ return { name: "aeh_context_retrieve", description: "Retrieve an already-authorized AEH context fragment artifact; arbitrary filesystem paths are rejected.", inputSchema: { type: "object", required: ["fragmentId"], properties: { fragmentId: { type: "string", minLength: 1 }, section: { enum: ["raw", "source"] }, maxTokens: { type: "integer", minimum: 1 } }, additionalProperties: false } };
3
+ }
4
+ export async function handleContextRetrievalRequest(gateway, request) {
5
+ const result = await gateway.retrieve(request);
6
+ return { status: "OK", ...result };
7
+ }
8
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../../src/context/retrieval/mcp.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,+BAA+B;IAC7C,OAAO,EAAE,IAAI,EAAE,sBAAsB,EAAE,WAAW,EAAE,wGAAwG,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,YAAY,CAAC,EAAE,UAAU,EAAE,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,oBAAoB,EAAE,KAAK,EAAE,EAAE,CAAC;AACzY,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,6BAA6B,CAAC,OAAgC,EAAE,OAAyB;IAC7G,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC/C,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC;AACrC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { HarnessProjectConfig } from "../../core/types.js";
2
+ import { type RetrievalRequest } from "./gateway.js";
3
+ export declare function retrievePersistedContext(root: string, config: HarnessProjectConfig, operationId: string, logicalAgent: string, request: RetrievalRequest): Promise<import("./gateway.js").RetrievalResult>;
@@ -0,0 +1,22 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { assertContextEnvelope } from "../types.js";
4
+ import { ContextRetrievalGateway } from "./gateway.js";
5
+ import { authorizeRetrieval } from "./authorization.js";
6
+ import { recordEvent } from "../../telemetry/events.js";
7
+ export async function retrievePersistedContext(root, config, operationId, logicalAgent, request) {
8
+ const envelopePath = path.resolve(root, ".harness", "context", safeSegment(operationId), "envelope.json");
9
+ const envelope = assertContextEnvelope(JSON.parse(await fs.readFile(envelopePath, "utf8")));
10
+ if (envelope.operationId !== operationId)
11
+ throw new Error("CONTEXT_RETRIEVAL_OPERATION_MISMATCH: envelope belongs to another operation.");
12
+ if (envelope.logicalAgent !== logicalAgent)
13
+ throw new Error("CONTEXT_RETRIEVAL_AGENT_MISMATCH: fragment is not authorized for this logical agent.");
14
+ const limits = config.context?.retrieval ?? {};
15
+ const gateway = new ContextRetrievalGateway(authorizeRetrieval({ root, operationId, logicalAgent, allowedFragmentIds: envelope.retrieval.allowedFragmentIds, fragments: envelope.fragments }), { maxRequestsPerTurn: limits.maxRequestsPerTurn ?? 8, maxTokensPerRequest: limits.maxTokensPerRequest ?? 6_000, maxTotalTokensPerTurn: limits.maxTotalTokensPerTurn ?? 20_000 });
16
+ const result = await gateway.retrieve(request);
17
+ if (config.telemetry?.enabled !== false)
18
+ await recordEvent(root, config, "harness.context.retrieve_original", { operationId, logicalAgent, fragmentId: request.fragmentId, estimatedTokens: result.estimatedTokens, repeated: result.repeated, artifact: result.artifact, sha256: result.sha256 });
19
+ return result;
20
+ }
21
+ function safeSegment(value) { const sanitized = value.replace(/[^A-Za-z0-9._-]+/g, "-").replace(/^-+|-+$/g, ""); return sanitized || "operation"; }
22
+ //# sourceMappingURL=persisted.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persisted.js","sourceRoot":"","sources":["../../../src/context/retrieval/persisted.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAyB,MAAM,cAAc,CAAC;AAC9E,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAExD,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,IAAY,EAAE,MAA4B,EAAE,WAAmB,EAAE,YAAoB,EAAE,OAAyB;IAC7J,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,CAAC,WAAW,CAAC,EAAE,eAAe,CAAC,CAAC;IAC1G,MAAM,QAAQ,GAAG,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IAC5F,IAAI,QAAQ,CAAC,WAAW,KAAK,WAAW;QAAE,MAAM,IAAI,KAAK,CAAC,8EAA8E,CAAC,CAAC;IAC1I,IAAI,QAAQ,CAAC,YAAY,KAAK,YAAY;QAAE,MAAM,IAAI,KAAK,CAAC,sFAAsF,CAAC,CAAC;IACpJ,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,EAAE,SAAS,IAAI,EAAE,CAAC;IAC/C,MAAM,OAAO,GAAG,IAAI,uBAAuB,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,YAAY,EAAE,kBAAkB,EAAE,QAAQ,CAAC,SAAS,CAAC,kBAAkB,EAAE,SAAS,EAAE,QAAQ,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,kBAAkB,EAAE,MAAM,CAAC,kBAAkB,IAAI,CAAC,EAAE,mBAAmB,EAAE,MAAM,CAAC,mBAAmB,IAAI,KAAK,EAAE,qBAAqB,EAAE,MAAM,CAAC,qBAAqB,IAAI,MAAM,EAAE,CAAC,CAAC;IAChX,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC/C,IAAI,MAAM,CAAC,SAAS,EAAE,OAAO,KAAK,KAAK;QAAE,MAAM,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,mCAAmC,EAAE,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,eAAe,EAAE,MAAM,CAAC,eAAe,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IACnS,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,WAAW,CAAC,KAAa,IAAY,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,mBAAmB,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,SAAS,IAAI,WAAW,CAAC,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function serveContextRetrievalMcp(): Promise<void>;
@@ -0,0 +1,52 @@
1
+ import readline from "node:readline";
2
+ import { loadProjectConfig } from "../../core/config.js";
3
+ import { contextRetrievalToolDescription } from "./mcp.js";
4
+ import { retrievePersistedContext } from "./persisted.js";
5
+ export async function serveContextRetrievalMcp() {
6
+ const root = process.env.AEH_CONTEXT_ROOT?.trim() || process.cwd();
7
+ const operationId = process.env.AEH_CONTEXT_OPERATION_ID?.trim();
8
+ const logicalAgent = process.env.AEH_LOGICAL_AGENT?.trim();
9
+ if (!operationId || !logicalAgent)
10
+ throw new Error("AEH context MCP requires AEH_CONTEXT_OPERATION_ID and AEH_LOGICAL_AGENT.");
11
+ const config = await loadProjectConfig(root);
12
+ const rl = readline.createInterface({ input: process.stdin, crlfDelay: Infinity });
13
+ for await (const line of rl) {
14
+ if (!line.trim())
15
+ continue;
16
+ let request;
17
+ try {
18
+ request = JSON.parse(line);
19
+ }
20
+ catch {
21
+ continue;
22
+ }
23
+ if (request.id === undefined || request.id === null)
24
+ continue;
25
+ try {
26
+ write({ jsonrpc: "2.0", id: request.id, result: await handle(request, root, config, operationId, logicalAgent) });
27
+ }
28
+ catch (error) {
29
+ write({ jsonrpc: "2.0", id: request.id, error: { code: -32603, message: error instanceof Error ? error.message : String(error) } });
30
+ }
31
+ }
32
+ }
33
+ async function handle(request, root, config, operationId, logicalAgent) {
34
+ if (request.method === "initialize")
35
+ return { protocolVersion: "2025-06-18", capabilities: { tools: {} }, serverInfo: { name: "aeh-context-retrieval", version: "1" } };
36
+ if (request.method === "ping")
37
+ return {};
38
+ if (request.method === "tools/list")
39
+ return { tools: [contextRetrievalToolDescription()] };
40
+ if (request.method !== "tools/call")
41
+ throw new Error(`Unsupported MCP method: ${request.method ?? "<missing>"}`);
42
+ const params = request.params ?? {};
43
+ if (params.name !== "aeh_context_retrieve")
44
+ throw new Error(`Unknown context tool '${String(params.name)}'.`);
45
+ const args = params.arguments && typeof params.arguments === "object" && !Array.isArray(params.arguments) ? params.arguments : {};
46
+ if (typeof args.fragmentId !== "string" || !args.fragmentId.trim())
47
+ throw new Error("fragmentId is required.");
48
+ const result = await retrievePersistedContext(root, config, operationId, logicalAgent, { fragmentId: args.fragmentId, section: args.section === "source" ? "source" : "raw", maxTokens: typeof args.maxTokens === "number" ? args.maxTokens : undefined });
49
+ return { content: [{ type: "text", text: result.content }], structuredContent: result };
50
+ }
51
+ function write(value) { process.stdout.write(`${JSON.stringify(value)}\n`); }
52
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/context/retrieval/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { HarnessProjectConfig } from "../core/types.js";
2
+ import type { ContextEnvelope, ContextMetrics } from "./types.js";
3
+ export declare function recordContextMetrics(root: string, config: HarnessProjectConfig, envelope: ContextEnvelope, metrics: ContextMetrics): Promise<void>;
@@ -0,0 +1,9 @@
1
+ import { recordEvent } from "../telemetry/events.js";
2
+ export async function recordContextMetrics(root, config, envelope, metrics) {
3
+ const base = { operationId: envelope.operationId, logicalAgent: envelope.logicalAgent, phase: envelope.phase, envelopeSha256: envelope.provenance.sha256 };
4
+ await recordEvent(root, config, "harness.context.project", { ...base, projectedBytes: metrics.projectedBytes, projectionRatio: metrics.projectionRatio ?? 0 });
5
+ if (metrics.compressedFragments > 0)
6
+ await recordEvent(root, config, "harness.context.compress", { ...base, compressedFragments: metrics.compressedFragments, compressionRatio: metrics.compressionRatio ?? 0 });
7
+ await recordEvent(root, config, "harness.context.operation_summary", { ...base, rawBytes: metrics.rawBytes, deliveredBytes: metrics.deliveredBytes, estimatedRawTokens: metrics.estimatedRawTokens, estimatedDeliveredTokens: metrics.estimatedDeliveredTokens, deliveredFragments: metrics.deliveredFragments, discardedFragments: metrics.discardedFragments });
8
+ }
9
+ //# sourceMappingURL=telemetry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../../src/context/telemetry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAGrD,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,IAAY,EAAE,MAA4B,EAAE,QAAyB,EAAE,OAAuB;IACvI,MAAM,IAAI,GAAG,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,YAAY,EAAE,QAAQ,CAAC,YAAY,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,cAAc,EAAE,QAAQ,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;IAC3J,MAAM,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,yBAAyB,EAAE,EAAE,GAAG,IAAI,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,eAAe,EAAE,OAAO,CAAC,eAAe,IAAI,CAAC,EAAE,CAAC,CAAC;IAC/J,IAAI,OAAO,CAAC,mBAAmB,GAAG,CAAC;QAAE,MAAM,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,0BAA0B,EAAE,EAAE,GAAG,IAAI,EAAE,mBAAmB,EAAE,OAAO,CAAC,mBAAmB,EAAE,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,IAAI,CAAC,EAAE,CAAC,CAAC;IACjN,MAAM,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,mCAAmC,EAAE,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,kBAAkB,EAAE,OAAO,CAAC,kBAAkB,EAAE,wBAAwB,EAAE,OAAO,CAAC,wBAAwB,EAAE,kBAAkB,EAAE,OAAO,CAAC,kBAAkB,EAAE,kBAAkB,EAAE,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;AACpW,CAAC"}