agentic-engineering-harness 0.6.29 → 0.8.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 (128) hide show
  1. package/dist/agents/permissions.js +4 -3
  2. package/dist/agents/permissions.js.map +1 -1
  3. package/dist/cli.js +34 -1
  4. package/dist/cli.js.map +1 -1
  5. package/dist/context/compression/headroom.d.ts +6 -1
  6. package/dist/context/compression/headroom.js +60 -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/gateway.d.ts +1 -0
  10. package/dist/context/gateway.js +58 -44
  11. package/dist/context/gateway.js.map +1 -1
  12. package/dist/context/repository/serena.d.ts +1 -1
  13. package/dist/context/repository/serena.js +2 -1
  14. package/dist/context/repository/serena.js.map +1 -1
  15. package/dist/context/transport.d.ts +33 -0
  16. package/dist/context/transport.js +63 -0
  17. package/dist/context/transport.js.map +1 -0
  18. package/dist/core/config.js +5 -5
  19. package/dist/core/config.js.map +1 -1
  20. package/dist/core/init.js +2 -1
  21. package/dist/core/init.js.map +1 -1
  22. package/dist/core/run.js +6 -2
  23. package/dist/core/run.js.map +1 -1
  24. package/dist/core/sdd.js +2 -2
  25. package/dist/core/sdd.js.map +1 -1
  26. package/dist/core/types.d.ts +53 -1
  27. package/dist/core/verify.js +2 -1
  28. package/dist/core/verify.js.map +1 -1
  29. package/dist/delivery/finalize.d.ts +1 -1
  30. package/dist/delivery/finalize.js +6 -1
  31. package/dist/delivery/finalize.js.map +1 -1
  32. package/dist/evals/fullStack.d.ts +10 -7
  33. package/dist/evals/fullStack.js +132 -36
  34. package/dist/evals/fullStack.js.map +1 -1
  35. package/dist/evidence/graph.d.ts +1 -0
  36. package/dist/evidence/graph.js +28 -11
  37. package/dist/evidence/graph.js.map +1 -1
  38. package/dist/issues/intake.d.ts +1 -1
  39. package/dist/maturity/inventory.d.ts +30 -0
  40. package/dist/maturity/inventory.js +53 -0
  41. package/dist/maturity/inventory.js.map +1 -0
  42. package/dist/memory/candidates.d.ts +29 -0
  43. package/dist/memory/candidates.js +31 -0
  44. package/dist/memory/candidates.js.map +1 -0
  45. package/dist/paseo/launchSpec.js +4 -4
  46. package/dist/paseo/launchSpec.js.map +1 -1
  47. package/dist/provenance/generate.d.ts +27 -1
  48. package/dist/provenance/generate.js +233 -75
  49. package/dist/provenance/generate.js.map +1 -1
  50. package/dist/providers/engram.d.ts +1 -0
  51. package/dist/providers/engram.js +40 -8
  52. package/dist/providers/engram.js.map +1 -1
  53. package/dist/providers/graphify.d.ts +20 -1
  54. package/dist/providers/graphify.js +106 -26
  55. package/dist/providers/graphify.js.map +1 -1
  56. package/dist/providers/serenaMcp.d.ts +7 -0
  57. package/dist/providers/serenaMcp.js +77 -0
  58. package/dist/providers/serenaMcp.js.map +1 -0
  59. package/dist/providers/validation/bddExecution.d.ts +15 -0
  60. package/dist/providers/validation/bddExecution.js +107 -0
  61. package/dist/providers/validation/bddExecution.js.map +1 -0
  62. package/dist/providers/validation/integrationEnvironment.d.ts +12 -0
  63. package/dist/providers/validation/integrationEnvironment.js +101 -0
  64. package/dist/providers/validation/integrationEnvironment.js.map +1 -0
  65. package/dist/providers/validation/pact.d.ts +15 -0
  66. package/dist/providers/validation/pact.js +79 -0
  67. package/dist/providers/validation/pact.js.map +1 -0
  68. package/dist/providers/validation/protocol.d.ts +7 -0
  69. package/dist/providers/validation/protocol.js +35 -0
  70. package/dist/providers/validation/protocol.js.map +1 -0
  71. package/dist/providers/validation/providerUtils.d.ts +18 -0
  72. package/dist/providers/validation/providerUtils.js +40 -0
  73. package/dist/providers/validation/providerUtils.js.map +1 -0
  74. package/dist/providers/validation/registry.d.ts +21 -0
  75. package/dist/providers/validation/registry.js +59 -0
  76. package/dist/providers/validation/registry.js.map +1 -0
  77. package/dist/providers/validation/reqnroll.d.ts +7 -0
  78. package/dist/providers/validation/reqnroll.js +50 -0
  79. package/dist/providers/validation/reqnroll.js.map +1 -0
  80. package/dist/providers/validation/testExecution.d.ts +15 -0
  81. package/dist/providers/validation/testExecution.js +122 -0
  82. package/dist/providers/validation/testExecution.js.map +1 -0
  83. package/dist/providers/validation/types.d.ts +158 -0
  84. package/dist/providers/validation/types.js +2 -0
  85. package/dist/providers/validation/types.js.map +1 -0
  86. package/dist/providers/versions.d.ts +10 -0
  87. package/dist/providers/versions.js +3 -0
  88. package/dist/providers/versions.js.map +1 -0
  89. package/dist/spec/openspec.js +12 -7
  90. package/dist/spec/openspec.js.map +1 -1
  91. package/dist/telemetry/events.js +36 -37
  92. package/dist/telemetry/events.js.map +1 -1
  93. package/dist/telemetry/otlp.d.ts +2 -1
  94. package/dist/telemetry/otlp.js +20 -41
  95. package/dist/telemetry/otlp.js.map +1 -1
  96. package/dist/telemetry/tracing.d.ts +19 -0
  97. package/dist/telemetry/tracing.js +141 -0
  98. package/dist/telemetry/tracing.js.map +1 -0
  99. package/dist/toolchain/config.js +3 -2
  100. package/dist/toolchain/config.js.map +1 -1
  101. package/dist/validators/external.js +6 -5
  102. package/dist/validators/external.js.map +1 -1
  103. package/dist/validators/gherkin.js +5 -56
  104. package/dist/validators/gherkin.js.map +1 -1
  105. package/dist/validators/registry.js +42 -3
  106. package/dist/validators/registry.js.map +1 -1
  107. package/dist/validators/toolEvidence.d.ts +2 -22
  108. package/dist/validators/toolEvidence.js +38 -5
  109. package/dist/validators/toolEvidence.js.map +1 -1
  110. package/dist/validators/types.d.ts +2 -1
  111. package/dist/workers/agentPrompt.js +5 -3
  112. package/dist/workers/agentPrompt.js.map +1 -1
  113. package/docs/ARCHITECTURE.md +60 -2
  114. package/docs/COMPONENT_MATURITY.md +19 -15
  115. package/docs/OSS_STACK.md +5 -4
  116. package/docs/V0.2.md +4 -1
  117. package/docs/VALIDATION.md +54 -3
  118. package/docs/VALIDATION_COMPATIBILITY.md +19 -0
  119. package/docs/component-maturity.json +34 -0
  120. package/maturity/components.yaml +59 -0
  121. package/package.json +8 -1
  122. package/schemas/project.schema.json +3 -3
  123. package/schemas/validation-report.schema.json +2 -1
  124. package/schemas/validation-result.schema.json +84 -0
  125. package/scripts/headroom-bridge.py +88 -0
  126. package/templates/project.yaml +1 -0
  127. package/templates/provider-versions.json +10 -0
  128. package/templates/toolchain.yaml +12 -4
@@ -1,9 +1,22 @@
1
1
  import type { HarnessProjectConfig } from "../core/types.js";
2
2
  import type { CodeIntelligenceProvider, CodeImpactReport } from "./types.js";
3
+ import { runProcess } from "../utils/process.js";
4
+ export interface GraphifyGenerationMetadata {
5
+ version: 1;
6
+ provider: "graphify";
7
+ providerVersion: string;
8
+ gitCommit?: string;
9
+ sourceFingerprint: string;
10
+ graphSha256: string;
11
+ generatedAt: string;
12
+ }
13
+ export declare const GRAPHIFY_VERSION: string;
14
+ /** Graphify owns generation/freshness; all consumers use graphifyModel.ts. */
3
15
  export declare class GraphifyCodeIntelligenceProvider implements CodeIntelligenceProvider {
4
16
  private readonly config?;
17
+ private readonly executor;
5
18
  readonly name = "graphify";
6
- constructor(config?: HarnessProjectConfig | undefined);
19
+ constructor(config?: HarnessProjectConfig | undefined, executor?: typeof runProcess);
7
20
  doctor(root: string): Promise<{
8
21
  ok: boolean;
9
22
  message: string;
@@ -14,4 +27,10 @@ export declare class GraphifyCodeIntelligenceProvider implements CodeIntelligenc
14
27
  load(root: string): Promise<unknown | undefined>;
15
28
  isFresh(root: string): Promise<boolean>;
16
29
  impact(root: string): Promise<CodeImpactReport>;
30
+ private generate;
31
+ private targetConfiguredGraph;
32
+ private graphPath;
33
+ private metadataPath;
34
+ private readMetadata;
35
+ private providerVersion;
17
36
  }
@@ -1,46 +1,126 @@
1
+ import crypto from "node:crypto";
2
+ import fs from "node:fs/promises";
3
+ import path from "node:path";
1
4
  import { commandExists, runProcess } from "../utils/process.js";
2
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. */
3
10
  export class GraphifyCodeIntelligenceProvider {
4
11
  config;
12
+ executor;
5
13
  name = "graphify";
6
- constructor(config) {
14
+ constructor(config, executor = runProcess) {
7
15
  this.config = config;
16
+ this.executor = executor;
8
17
  }
9
18
  async doctor(root) {
10
- const cli = await commandExists("graphify", root);
19
+ const cli = await commandExists(GRAPHIFY_COMMAND, root);
11
20
  const graph = await this.load(root);
12
- return {
13
- ok: Boolean(cli || graph),
14
- message: graph ? "Graphify graph detected and readable through the canonical AEH model." : cli ? "Graphify CLI detected but no readable graph exists; configure codeIntelligence.refreshCommand or build the graph before a required run." : "Graphify CLI/graph not found. Structural validation can remain optional or be disabled."
15
- };
16
- }
17
- async build(root) { await this.refresh(root); }
18
- async refresh(root) {
19
- const command = this.config?.codeIntelligence?.refreshCommand;
20
- if (command) {
21
- const result = await runProcess(command, { cwd: root, timeoutMs: 300_000 });
22
- if (result.exitCode !== 0)
23
- throw new Error(`Graphify refresh failed: ${result.stderr || result.stdout}`);
24
- }
25
- if (!(await this.load(root)))
26
- throw new Error("Graphify graph is unavailable after refresh. Configure codeIntelligence.refreshCommand or generate the configured graph path.");
27
- }
28
- async update(root) { await this.refresh(root); }
29
- async load(root) {
30
- return loadCanonicalGraph(root, this.config?.codeIntelligence?.graphPath ?? "graphify-out/graph.json");
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.` };
31
25
  }
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()); }
32
30
  async isFresh(root) {
33
31
  const graph = await this.load(root);
34
- if (!graph)
32
+ const metadata = await this.readMetadata(root);
33
+ if (!graph || !metadata || metadata.provider !== "graphify")
35
34
  return false;
36
- // A configured refresh command is the only provider-specific way to prove
37
- // freshness. Required runs invoke it before snapshots; this method remains
38
- // conservative for callers that need a readiness decision.
39
- return Boolean(graph.generatedAt);
35
+ const current = await sourceFingerprint(root);
36
+ return metadata.sourceFingerprint === current.sourceFingerprint && metadata.gitCommit === current.gitCommit && metadata.graphSha256 === graph.sourceHash && metadata.providerVersion.length > 0;
40
37
  }
41
38
  async impact(root) {
42
39
  const graph = await this.load(root);
43
40
  return { provider: this.name, affectedNodes: graph?.nodes ?? [], affectedCommunities: [...new Set(Object.values(graph?.communities ?? {}))] };
44
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"));
86
+ }
87
+ catch {
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;
98
+ }
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;
45
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("'", "'\\''")}'`; }
46
126
  //# sourceMappingURL=graphify.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"graphify.js","sourceRoot":"","sources":["../../src/providers/graphify.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,OAAO,gCAAgC;IAEd;IADpB,IAAI,GAAG,UAAU,CAAC;IAC3B,YAA6B,MAA6B;QAA7B,WAAM,GAAN,MAAM,CAAuB;IAAG,CAAC;IAC9D,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAClD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpC,OAAO;YACL,EAAE,EAAE,OAAO,CAAC,GAAG,IAAI,KAAK,CAAC;YACzB,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,uEAAuE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,yIAAyI,CAAC,CAAC,CAAC,yFAAyF;SACvU,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,KAAK,CAAC,IAAY,IAAmB,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACtE,KAAK,CAAC,OAAO,CAAC,IAAY;QACxB,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,gBAAgB,EAAE,cAAc,CAAC;QAC9D,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;YAC5E,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QAC3G,CAAC;QACD,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,+HAA+H,CAAC,CAAC;IACjL,CAAC;IACD,KAAK,CAAC,MAAM,CAAC,IAAY,IAAmB,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACvE,KAAK,CAAC,IAAI,CAAC,IAAY;QACrB,OAAO,kBAAkB,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,gBAAgB,EAAE,SAAS,IAAI,yBAAyB,CAAC,CAAC;IACzG,CAAC;IACD,KAAK,CAAC,OAAO,CAAC,IAAY;QACxB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK;YAAE,OAAO,KAAK,CAAC;QACzB,0EAA0E;QAC1E,2EAA2E;QAC3E,2DAA2D;QAC3D,OAAO,OAAO,CAAE,KAAkC,CAAC,WAAW,CAAC,CAAC;IAClE,CAAC;IACD,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAA2E,CAAC;QAC9G,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,IAAI,EAAE,EAAE,mBAAmB,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,WAAW,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAChJ,CAAC;CACF"}
1
+ {"version":3,"file":"graphify.js","sourceRoot":"","sources":["../../src/providers/graphify.ts"],"names":[],"mappings":"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"}
@@ -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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"}
@@ -0,0 +1,15 @@
1
+ import type { ValidationCapability } from "../../core/types.js";
2
+ import type { BddExecutionResult, ProviderDetection, ProviderDoctorResult, ProviderExecution, ProviderPlan, ValidationProvider, ValidationProviderContext } from "./types.js";
3
+ export declare class GenericBddExecutionProvider implements ValidationProvider<BddExecutionResult> {
4
+ readonly id: string;
5
+ readonly capabilities: ValidationCapability[];
6
+ detect(context: ValidationProviderContext): Promise<ProviderDetection | undefined>;
7
+ doctor(context: ValidationProviderContext): Promise<ProviderDoctorResult>;
8
+ plan(context: ValidationProviderContext, detection?: ProviderDetection): Promise<ProviderPlan>;
9
+ execute(context: ValidationProviderContext, plan: ProviderPlan): Promise<ProviderExecution>;
10
+ normalize(context: ValidationProviderContext, execution: ProviderExecution): Promise<BddExecutionResult>;
11
+ }
12
+ export declare function runBddExecution(context: ValidationProviderContext, provider?: ValidationProvider<BddExecutionResult>): Promise<{
13
+ result: BddExecutionResult;
14
+ required: boolean;
15
+ }>;
@@ -0,0 +1,107 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { commandExists } from "../../utils/process.js";
4
+ import { configuredCommand, doctorForCommand, executePlan, fileExists, resolveCwd } from "./providerUtils.js";
5
+ import { parseJson, persistRawArtifact } from "./protocol.js";
6
+ export class GenericBddExecutionProvider {
7
+ id = "bdd-runner";
8
+ capabilities = ["bdd"];
9
+ async detect(context) {
10
+ const explicit = await configuredCommand(context);
11
+ if (explicit.command)
12
+ return { provider: explicit.provider, command: explicit.command, runtime: explicit.runtime, reason: "explicit BDD provider configuration" };
13
+ const packageJson = await readPackageJson(context.root);
14
+ if (packageJson?.scripts?.bdd)
15
+ return { provider: "node-bdd-script", command: "npm run bdd", runtime: "node", reason: "package.json bdd script" };
16
+ if (packageJson?.scripts?.acceptance)
17
+ return { provider: "node-acceptance-script", command: "npm run acceptance", runtime: "node", reason: "package.json acceptance script" };
18
+ if (await fileExists(path.join(context.root, "features")) && await commandExists("pytest", context.root))
19
+ return { provider: "python-bdd", command: "pytest -q", runtime: "python", reason: "features directory and Python BDD-capable runner" };
20
+ return undefined;
21
+ }
22
+ async doctor(context) {
23
+ const detection = await this.detect(context);
24
+ if (!detection)
25
+ return { provider: this.id, available: false, message: "No BDD provider was detected." };
26
+ return doctorForCommand(detection.command, resolveCwd(context), detection.provider, { runtime: detection.runtime, reason: detection.reason });
27
+ }
28
+ async plan(context, detection) {
29
+ const selected = detection ?? await this.detect(context);
30
+ if (!selected?.command)
31
+ throw new Error("No BDD provider or command is configured.");
32
+ return { provider: selected.provider, capability: "bdd", command: renderCommand(selected.command, context), cwd: resolveCwd(context), runtime: selected.runtime, options: { timeoutMs: (context.spec?.timeoutSeconds ?? context.providerSpec?.timeoutSeconds ?? 900) * 1000 } };
33
+ }
34
+ async execute(context, plan) {
35
+ const execution = await executePlan(plan);
36
+ const id = context.spec?.id ?? context.providerSpec?.id ?? "bdd";
37
+ return { ...execution, rawArtifact: await persistRawArtifact(context.root, context.rawArtifactDirectory, id, execution.stdout, execution.stderr) };
38
+ }
39
+ async normalize(context, execution) {
40
+ const parsed = parseJson(execution.stdout);
41
+ const scenarios = normalizeScenarios(parsed, execution, context);
42
+ const failed = scenarios.filter((item) => item.status === "FAIL").length;
43
+ const skipped = scenarios.filter((item) => item.status === "SKIP").length;
44
+ const passed = scenarios.filter((item) => item.status === "PASS").length;
45
+ return { version: 1, provider: execution.plan.provider, capability: "bdd", command: execution.plan.command, runtime: execution.plan.runtime, status: execution.exitCode === 0 && failed === 0 ? "PASS" : "FAIL", scenarios, summary: { total: scenarios.length, passed, failed, skipped, durationMs: execution.durationMs }, rawArtifact: execution.rawArtifact };
46
+ }
47
+ }
48
+ export async function runBddExecution(context, provider = new GenericBddExecutionProvider()) {
49
+ const detection = await provider.detect(context);
50
+ if (!detection)
51
+ return { result: { version: 1, provider: provider.id, capability: "bdd", command: "", status: "SKIP", scenarios: [], summary: { total: 0, passed: 0, failed: 0, skipped: 0, durationMs: 0 }, rawArtifact: "" }, required: context.spec?.required ?? context.providerSpec?.required ?? true };
52
+ const plan = await provider.plan(context, detection);
53
+ const execution = await provider.execute(context, plan);
54
+ return { result: await provider.normalize(context, execution), required: context.spec?.required ?? context.providerSpec?.required ?? true };
55
+ }
56
+ function normalizeScenarios(value, execution, context) {
57
+ if (value && typeof value === "object" && !Array.isArray(value) && value.version === 1) {
58
+ const scenarios = value.scenarios;
59
+ if (Array.isArray(scenarios))
60
+ return scenarios.map((item) => normalizeScenario(item, execution, context));
61
+ }
62
+ if (Array.isArray(value)) {
63
+ const cucumber = value.flatMap((feature) => {
64
+ const item = record(feature);
65
+ const featureName = stringValue(item.name) ?? "feature";
66
+ const featureFile = stringValue(item.uri ?? item.location?.file);
67
+ return (Array.isArray(item.elements) ? item.elements : Array.isArray(item.children) ? item.children : []).filter((scenario) => ["scenario", "background"].includes(String(record(scenario).type ?? "scenario"))).map((scenario) => fromCucumber(record(scenario), featureName, featureFile, execution, context));
68
+ });
69
+ if (cucumber.length)
70
+ return cucumber;
71
+ }
72
+ const fallback = `${execution.stdout}\n${execution.stderr}`.split(/\r?\n/).filter((line) => /^\s*(Scenario:|scenario:)/i.test(line)).map((line, index) => ({ feature: "unknown", scenario: line.replace(/^\s*Scenario:\s*/i, "").trim(), tags: [], status: execution.exitCode === 0 ? "PASS" : "FAIL", requirementIds: index === 0 ? requirementIds(context) : [] }));
73
+ return fallback;
74
+ }
75
+ function normalizeScenario(value, execution, context) {
76
+ const item = record(value);
77
+ const status = statusValue(item.status, execution.exitCode);
78
+ const source = sourceValue(item.source ?? item.location);
79
+ const tags = arrayValue(item.tags);
80
+ const taggedRequirements = tags.map((tag) => tag.replace(/^@/, "")).filter((tag) => (context.contract.requirements ?? []).some((requirement) => requirement.id === tag));
81
+ return { feature: stringValue(item.feature) ?? "feature", rule: stringValue(item.rule), scenario: stringValue(item.scenario ?? item.name) ?? "scenario", examplesRow: numberValue(item.examplesRow), tags, status, durationMs: numberValue(item.durationMs), failingStep: stringValue(item.failingStep), source, error: stringValue(item.error ?? item.message), requirementIds: arrayValue(item.requirementIds).length ? arrayValue(item.requirementIds) : taggedRequirements.length ? taggedRequirements : requirementIds(context) };
82
+ }
83
+ function fromCucumber(item, feature, file, execution, context) {
84
+ const steps = Array.isArray(item.steps) ? item.steps : [];
85
+ const failedStep = steps.find((step) => ["failed", "undefined"].includes(String(record(step).result?.status ?? "")));
86
+ const result = record(failedStep ? record(failedStep).result : undefined);
87
+ const source = sourceValue(item.location) ?? (file ? { file, line: numberValue(record(item.location).line) } : undefined);
88
+ const tags = arrayValue(item.tags).map((tag) => typeof tag === "string" ? tag : stringValue(record(tag).name) ?? "").filter(Boolean);
89
+ const taggedRequirements = tags.map((tag) => tag.replace(/^@/, "")).filter((tag) => (context.contract.requirements ?? []).some((requirement) => requirement.id === tag));
90
+ return { feature, rule: stringValue(item.rule), scenario: stringValue(item.name) ?? "scenario", tags, status: failedStep ? "FAIL" : execution.exitCode === 0 ? "PASS" : "FAIL", durationMs: numberValue(item.duration) ?? numberValue(result.duration), failingStep: failedStep ? stringValue(record(failedStep).text ?? record(failedStep).keyword) : undefined, source, error: stringValue(result.message ?? result.error_message), requirementIds: taggedRequirements.length ? taggedRequirements : requirementIds(context) };
91
+ }
92
+ function requirementIds(context) { return (context.contract.requirements ?? []).filter((item) => item.capabilities?.includes("bdd") || !item.capabilities?.length).map((item) => item.id); }
93
+ function renderCommand(command, context) { return command.replaceAll("{taskId}", context.contract.task.id).replaceAll("{baseRef}", context.baseRef ?? "HEAD").replaceAll("{acceptance}", context.contract.source?.acceptance ?? ""); }
94
+ async function readPackageJson(root) { try {
95
+ return JSON.parse(await fs.readFile(path.join(root, "package.json"), "utf8"));
96
+ }
97
+ catch {
98
+ return undefined;
99
+ } }
100
+ function record(value) { return value && typeof value === "object" && !Array.isArray(value) ? value : {}; }
101
+ function stringValue(value) { return typeof value === "string" || typeof value === "number" ? String(value) : undefined; }
102
+ function numberValue(value) { return typeof value === "number" && Number.isFinite(value) ? value : undefined; }
103
+ function arrayValue(value) { return Array.isArray(value) ? value.map((item) => typeof item === "string" ? item : stringValue(record(item).name) ?? "").filter(Boolean) : []; }
104
+ function sourceValue(value) { const source = record(value); const file = stringValue(source.file ?? source.uri ?? source.path); const line = numberValue(source.line); const column = numberValue(source.column); return file || line || column ? { file, line, column } : undefined; }
105
+ function statusValue(value, exitCode) { const status = String(value ?? "").toLowerCase(); if (["skipped", "pending", "undefined"].includes(status))
106
+ return "SKIP"; return status === "failed" || status === "fail" || exitCode !== 0 ? "FAIL" : "PASS"; }
107
+ //# sourceMappingURL=bddExecution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bddExecution.js","sourceRoot":"","sources":["../../../src/providers/validation/bddExecution.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC9G,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAG9D,MAAM,OAAO,2BAA2B;IAC7B,EAAE,GAAW,YAAY,CAAC;IAC1B,YAAY,GAA2B,CAAC,KAAK,CAAC,CAAC;IAExD,KAAK,CAAC,MAAM,CAAC,OAAkC;QAC7C,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAClD,IAAI,QAAQ,CAAC,OAAO;YAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,qCAAqC,EAAE,CAAC;QAClK,MAAM,WAAW,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACxD,IAAI,WAAW,EAAE,OAAO,EAAE,GAAG;YAAE,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,yBAAyB,EAAE,CAAC;QAClJ,IAAI,WAAW,EAAE,OAAO,EAAE,UAAU;YAAE,OAAO,EAAE,QAAQ,EAAE,wBAAwB,EAAE,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,gCAAgC,EAAE,CAAC;QAC9K,IAAI,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,IAAI,MAAM,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC;YAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,kDAAkD,EAAE,CAAC;QACjP,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,OAAkC;QAC7C,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC7C,IAAI,CAAC,SAAS;YAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,+BAA+B,EAAE,CAAC;QACzG,OAAO,gBAAgB,CAAC,SAAS,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;IAChJ,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAAkC,EAAE,SAA6B;QAC1E,MAAM,QAAQ,GAAG,SAAS,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACzD,IAAI,CAAC,QAAQ,EAAE,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;QACrF,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,aAAa,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,cAAc,IAAI,OAAO,CAAC,YAAY,EAAE,cAAc,IAAI,GAAG,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC;IAClR,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,OAAkC,EAAE,IAAkB;QAClE,MAAM,SAAS,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC;QAAC,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,EAAE,IAAI,OAAO,CAAC,YAAY,EAAE,EAAE,IAAI,KAAK,CAAC;QAC5G,OAAO,EAAE,GAAG,SAAS,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,oBAAoB,EAAE,EAAE,EAAE,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;IACrJ,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,OAAkC,EAAE,SAA4B;QAC9E,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAAC,MAAM,SAAS,GAAG,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QAC7G,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;QAAC,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;QAAC,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;QAC9N,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,QAAQ,KAAK,CAAC,IAAI,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,CAAC,UAAU,EAAE,EAAE,WAAW,EAAE,SAAS,CAAC,WAAW,EAAE,CAAC;IACpW,CAAC;CACF;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAAkC,EAAE,WAAmD,IAAI,2BAA2B,EAAE;IAC5J,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACjD,IAAI,CAAC,SAAS;QAAE,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,IAAI,EAAE,QAAQ,IAAI,OAAO,CAAC,YAAY,EAAE,QAAQ,IAAI,IAAI,EAAE,CAAC;IAC7S,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAAC,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,IAAI,EAAE,QAAQ,IAAI,OAAO,CAAC,YAAY,EAAE,QAAQ,IAAI,IAAI,EAAE,CAAC;AAC7P,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAc,EAAE,SAA4B,EAAE,OAAkC;IAC1G,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAK,KAAiC,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;QACpH,MAAM,SAAS,GAAI,KAAiC,CAAC,SAAS,CAAC;QAC/D,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;IAC5G,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YACzC,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;YAAC,MAAM,WAAW,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC;YAAC,MAAM,WAAW,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YACxJ,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;QACnT,CAAC,CAAC,CAAC;QACH,IAAI,QAAQ,CAAC,MAAM;YAAE,OAAO,QAAQ,CAAC;IACvC,CAAC;IACD,MAAM,QAAQ,GAAG,GAAG,SAAS,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,4BAA4B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,MAAe,CAAC,CAAC,CAAC,MAAe,EAAE,cAAc,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACxX,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAc,EAAE,SAA4B,EAAE,OAAkC;IACzG,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAAC,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC;IAAC,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC;IAAC,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAAC,MAAM,kBAAkB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;IAChW,OAAO,EAAE,OAAO,EAAE,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,SAAS,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,WAAW,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,UAAU,EAAE,WAAW,EAAE,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,WAAW,EAAE,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,EAAE,cAAc,EAAE,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;AACzgB,CAAC;AAED,SAAS,YAAY,CAAC,IAA6B,EAAE,OAAe,EAAE,IAAwB,EAAE,SAA4B,EAAE,OAAkC;IAC9J,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IAAC,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAChL,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAAC,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACrM,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAAC,MAAM,kBAAkB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;IAChT,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,IAAI,MAAM,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,aAAa,CAAC,EAAE,cAAc,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;AACngB,CAAC;AAED,SAAS,cAAc,CAAC,OAAkC,IAAc,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACjO,SAAS,aAAa,CAAC,OAAe,EAAE,OAAkC,IAAY,OAAO,OAAO,CAAC,UAAU,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,WAAW,EAAE,OAAO,CAAC,OAAO,IAAI,MAAM,CAAC,CAAC,UAAU,CAAC,cAAc,EAAE,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AACjR,KAAK,UAAU,eAAe,CAAC,IAAY,IAA+D,IAAI,CAAC;IAAC,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAyC,CAAC;AAAC,CAAC;AAAC,MAAM,CAAC;IAAC,OAAO,SAAS,CAAC;AAAC,CAAC,CAAC,CAAC;AACtQ,SAAS,MAAM,CAAC,KAAc,IAAyB,OAAO,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAA4B,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAChK,SAAS,WAAW,CAAC,KAAc,IAAwB,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;AACvJ,SAAS,WAAW,CAAC,KAAc,IAAwB,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;AAC5I,SAAS,UAAU,CAAC,KAAc,IAAc,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACjM,SAAS,WAAW,CAAC,KAAc,IAA6C,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,IAAI,IAAI,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;AACzU,SAAS,WAAW,CAAC,KAAc,EAAE,QAAgB,IAAiC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;IAAE,OAAO,MAAM,CAAC,CAAC,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,MAAM,IAAI,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { ValidationCapability } from "../../core/types.js";
2
+ import type { IntegrationEnvironmentResult, ProviderDetection, ProviderDoctorResult, ProviderExecution, ProviderPlan, ValidationProvider, ValidationProviderContext } from "./types.js";
3
+ export declare class IntegrationEnvironmentProvider implements ValidationProvider<IntegrationEnvironmentResult> {
4
+ readonly id = "integration-environment";
5
+ readonly capabilities: ValidationCapability[];
6
+ detect(context: ValidationProviderContext): Promise<ProviderDetection | undefined>;
7
+ doctor(context: ValidationProviderContext): Promise<ProviderDoctorResult>;
8
+ plan(context: ValidationProviderContext, detection?: ProviderDetection): Promise<ProviderPlan>;
9
+ execute(context: ValidationProviderContext, plan: ProviderPlan): Promise<ProviderExecution>;
10
+ normalize(context: ValidationProviderContext, execution: ProviderExecution): Promise<IntegrationEnvironmentResult>;
11
+ }
12
+ export declare function validateEnvironmentRequirements(context: ValidationProviderContext): string[];
@@ -0,0 +1,101 @@
1
+ import { commandExists } from "../../utils/process.js";
2
+ import { configuredCommand, doctorForCommand, executePlan, resolveCwd } from "./providerUtils.js";
3
+ import { persistRawArtifact } from "./protocol.js";
4
+ export class IntegrationEnvironmentProvider {
5
+ id = "integration-environment";
6
+ capabilities = ["integration-test"];
7
+ async detect(context) {
8
+ const configured = await configuredCommand(context);
9
+ const options = context.spec?.options ?? context.providerSpec?.options ?? {};
10
+ if (configured.command || typeof options.provisionCommand === "string")
11
+ return { provider: configured.provider === "configured-command" ? String(options.provider ?? "configured-environment") : configured.provider, command: configured.command ?? String(options.provisionCommand), runtime: "oci-or-project", reason: "explicit integration environment lifecycle" };
12
+ if (typeof options.image === "string" && (await commandExists("podman", context.root) || await commandExists("docker", context.root)))
13
+ return { provider: "oci", command: `${await commandExists("podman", context.root) ? "podman" : "docker"} run --rm --network=none ${options.image}`, runtime: "oci", reason: "explicit OCI image and available runtime" };
14
+ return undefined;
15
+ }
16
+ async doctor(context) {
17
+ const detection = await this.detect(context);
18
+ if (!detection)
19
+ return { provider: this.id, available: false, message: "No integration environment provider was configured." };
20
+ const security = validateEnvironmentRequirements(context);
21
+ if (security.length)
22
+ return { provider: detection.provider, available: false, message: security.join(" "), details: { securityFailures: security } };
23
+ return doctorForCommand(detection.command, resolveCwd(context), detection.provider, { runtime: detection.runtime });
24
+ }
25
+ async plan(context, detection) {
26
+ const selected = detection ?? await this.detect(context);
27
+ if (!selected?.command)
28
+ throw new Error("No integration environment provider or lifecycle command is configured.");
29
+ return { provider: selected.provider, capability: "integration-test", command: selected.command, cwd: resolveCwd(context), runtime: selected.runtime, env: connectionData(context), options: { timeoutMs: (context.spec?.timeoutSeconds ?? context.providerSpec?.timeoutSeconds ?? 900) * 1000 } };
30
+ }
31
+ async execute(context, plan) {
32
+ const options = context.spec?.options ?? context.providerSpec?.options ?? {};
33
+ const lifecycle = [];
34
+ const provision = String(options.provisionCommand ?? plan.command);
35
+ const readiness = typeof options.readinessCommand === "string" ? options.readinessCommand : undefined;
36
+ const test = typeof options.testCommand === "string" ? options.testCommand : undefined;
37
+ const cleanup = typeof options.cleanupCommand === "string" ? options.cleanupCommand : undefined;
38
+ const started = Date.now();
39
+ let stdout = "";
40
+ let stderr = "";
41
+ let exitCode = 0;
42
+ const run = async (label, command) => { const result = await executePlan({ ...plan, command }); stdout += `--- ${label} ---\n${result.stdout}\n`; stderr += result.stderr ? `--- ${label} stderr ---\n${result.stderr}\n` : ""; if (result.exitCode !== 0 && exitCode === 0)
43
+ exitCode = result.exitCode; lifecycle.push(`${label}:${result.exitCode === 0 ? "PASS" : "FAIL"}`); };
44
+ try {
45
+ await run("provision", provision);
46
+ if (readiness)
47
+ await run("readiness", readiness);
48
+ if (test)
49
+ await run("test", test);
50
+ }
51
+ finally {
52
+ if (cleanup)
53
+ await run("cleanup", cleanup);
54
+ }
55
+ return { plan, exitCode, stdout: `${lifecycle.join(" ")}\n${stdout}`, stderr, durationMs: Date.now() - started, rawArtifact: await persistRawArtifact(context.root, context.rawArtifactDirectory, context.spec?.id ?? context.providerSpec?.id ?? "integration-environment", stdout, stderr) };
56
+ }
57
+ async normalize(context, execution) {
58
+ const lifecycle = { provisioned: /provision:PASS/.test(execution.stdout), ready: !/readiness:FAIL/.test(execution.stdout), tested: !/test:FAIL/.test(execution.stdout), cleaned: /cleanup:PASS/.test(execution.stdout), durationMs: execution.durationMs };
59
+ const requirements = environmentRequirements(context);
60
+ const failed = execution.exitCode !== 0 || !lifecycle.provisioned || !lifecycle.cleaned;
61
+ return { version: 1, provider: execution.plan.provider, capability: "integration-test", status: failed ? "FAIL" : "PASS", requirements, lifecycle, connectionData: redactConnectionData(execution.plan.env), rawArtifact: execution.rawArtifact };
62
+ }
63
+ }
64
+ export function validateEnvironmentRequirements(context) {
65
+ const options = context.spec?.options ?? context.providerSpec?.options ?? {};
66
+ const failures = [];
67
+ const network = String(options.network ?? "isolated");
68
+ if (!["isolated", "none", "project"].includes(network))
69
+ failures.push(`Unsupported integration network '${network}'.`);
70
+ if (options.privileged === true)
71
+ failures.push("Privileged integration environments are not allowed by default.");
72
+ if (network === "host")
73
+ failures.push("Host networking must not be implicit.");
74
+ if (options.dockerSocket === true)
75
+ failures.push("Docker socket access is not allowed by default.");
76
+ if (Array.isArray(options.mounts) && options.mounts.some((mount) => String(mount).startsWith("/")))
77
+ failures.push("Absolute host mounts require an explicit policy adapter.");
78
+ if (Array.isArray(options.credentials) && options.credentials.length && options.credentialsAllowlist !== true)
79
+ failures.push("Credentials require an explicit allowlist.");
80
+ const data = options.connectionData;
81
+ if (data && typeof data === "object" && !Array.isArray(data) && Object.keys(data).some((key) => /(password|token|secret|private.?key)/i.test(key)) && options.connectionDataAllowlist !== true)
82
+ failures.push("Sensitive connection data requires an explicit allowlist.");
83
+ return failures;
84
+ }
85
+ function environmentRequirements(context) {
86
+ const options = context.spec?.options ?? context.providerSpec?.options ?? {};
87
+ const network = String(options.network ?? "isolated");
88
+ return [{ kind: String(options.kind ?? "service"), image: typeof options.image === "string" ? options.image : undefined, network, ephemeral: options.ephemeral !== false, ports: Array.isArray(options.ports) ? options.ports.map(Number).filter(Number.isFinite) : undefined, environment: Array.isArray(options.environment) ? options.environment.map(String) : undefined, mounts: Array.isArray(options.mounts) ? options.mounts.map(String) : undefined }];
89
+ }
90
+ function connectionData(context) {
91
+ const value = context.spec?.options?.connectionData ?? context.providerSpec?.options?.connectionData;
92
+ if (!value || typeof value !== "object" || Array.isArray(value))
93
+ return undefined;
94
+ return Object.fromEntries(Object.entries(value).filter(([, item]) => typeof item === "string").map(([key, item]) => [key, item]));
95
+ }
96
+ function redactConnectionData(value) {
97
+ if (!value)
98
+ return undefined;
99
+ return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, /(password|token|secret|private.?key)/i.test(key) ? "<redacted>" : item]));
100
+ }
101
+ //# sourceMappingURL=integrationEnvironment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integrationEnvironment.js","sourceRoot":"","sources":["../../../src/providers/validation/integrationEnvironment.ts"],"names":[],"mappings":"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"}