agentic-engineering-harness 0.4.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +273 -0
- package/dist/agents/audit.d.ts +12 -0
- package/dist/agents/audit.js +14 -0
- package/dist/agents/audit.js.map +1 -0
- package/dist/agents/compiler.d.ts +8 -0
- package/dist/agents/compiler.js +103 -0
- package/dist/agents/compiler.js.map +1 -0
- package/dist/agents/config.d.ts +6 -0
- package/dist/agents/config.js +161 -0
- package/dist/agents/config.js.map +1 -0
- package/dist/agents/escalation.d.ts +9 -0
- package/dist/agents/escalation.js +75 -0
- package/dist/agents/escalation.js.map +1 -0
- package/dist/agents/exceptionDetection.d.ts +24 -0
- package/dist/agents/exceptionDetection.js +42 -0
- package/dist/agents/exceptionDetection.js.map +1 -0
- package/dist/agents/findings.d.ts +14 -0
- package/dist/agents/findings.js +40 -0
- package/dist/agents/findings.js.map +1 -0
- package/dist/agents/gitCheckpoint.d.ts +6 -0
- package/dist/agents/gitCheckpoint.js +61 -0
- package/dist/agents/gitCheckpoint.js.map +1 -0
- package/dist/agents/jsonc.d.ts +1 -0
- package/dist/agents/jsonc.js +42 -0
- package/dist/agents/jsonc.js.map +1 -0
- package/dist/agents/outputContracts.d.ts +161 -0
- package/dist/agents/outputContracts.js +16 -0
- package/dist/agents/outputContracts.js.map +1 -0
- package/dist/agents/parallelism.d.ts +14 -0
- package/dist/agents/parallelism.js +54 -0
- package/dist/agents/parallelism.js.map +1 -0
- package/dist/agents/permissions.d.ts +5 -0
- package/dist/agents/permissions.js +30 -0
- package/dist/agents/permissions.js.map +1 -0
- package/dist/agents/qualityConvergence.d.ts +44 -0
- package/dist/agents/qualityConvergence.js +77 -0
- package/dist/agents/qualityConvergence.js.map +1 -0
- package/dist/agents/recovery.d.ts +13 -0
- package/dist/agents/recovery.js +35 -0
- package/dist/agents/recovery.js.map +1 -0
- package/dist/agents/reviewLifecycle.d.ts +30 -0
- package/dist/agents/reviewLifecycle.js +233 -0
- package/dist/agents/reviewLifecycle.js.map +1 -0
- package/dist/agents/routing.d.ts +9 -0
- package/dist/agents/routing.js +37 -0
- package/dist/agents/routing.js.map +1 -0
- package/dist/agents/structuredOutput.d.ts +1 -0
- package/dist/agents/structuredOutput.js +54 -0
- package/dist/agents/structuredOutput.js.map +1 -0
- package/dist/agents/types.d.ts +207 -0
- package/dist/agents/types.js +2 -0
- package/dist/agents/types.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +221 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/config.d.ts +3 -0
- package/dist/core/config.js +59 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/doctor.d.ts +8 -0
- package/dist/core/doctor.js +59 -0
- package/dist/core/doctor.js.map +1 -0
- package/dist/core/git.d.ts +8 -0
- package/dist/core/git.js +47 -0
- package/dist/core/git.js.map +1 -0
- package/dist/core/init.d.ts +1 -0
- package/dist/core/init.js +52 -0
- package/dist/core/init.js.map +1 -0
- package/dist/core/quick.d.ts +20 -0
- package/dist/core/quick.js +49 -0
- package/dist/core/quick.js.map +1 -0
- package/dist/core/repair.d.ts +8 -0
- package/dist/core/repair.js +7 -0
- package/dist/core/repair.js.map +1 -0
- package/dist/core/run.d.ts +38 -0
- package/dist/core/run.js +165 -0
- package/dist/core/run.js.map +1 -0
- package/dist/core/sdd.d.ts +10 -0
- package/dist/core/sdd.js +88 -0
- package/dist/core/sdd.js.map +1 -0
- package/dist/core/seal.d.ts +3 -0
- package/dist/core/seal.js +74 -0
- package/dist/core/seal.js.map +1 -0
- package/dist/core/triage.d.ts +22 -0
- package/dist/core/triage.js +38 -0
- package/dist/core/triage.js.map +1 -0
- package/dist/core/types.d.ts +354 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/verify.d.ts +6 -0
- package/dist/core/verify.js +51 -0
- package/dist/core/verify.js.map +1 -0
- package/dist/delivery/finalize.d.ts +17 -0
- package/dist/delivery/finalize.js +71 -0
- package/dist/delivery/finalize.js.map +1 -0
- package/dist/delivery/handoff.d.ts +39 -0
- package/dist/delivery/handoff.js +250 -0
- package/dist/delivery/handoff.js.map +1 -0
- package/dist/entry.d.ts +2 -0
- package/dist/entry.js +112 -0
- package/dist/entry.js.map +1 -0
- package/dist/evals/runner.d.ts +4 -0
- package/dist/evals/runner.js +112 -0
- package/dist/evals/runner.js.map +1 -0
- package/dist/evals/scoring.d.ts +3 -0
- package/dist/evals/scoring.js +41 -0
- package/dist/evals/scoring.js.map +1 -0
- package/dist/evals/types.d.ts +46 -0
- package/dist/evals/types.js +2 -0
- package/dist/evals/types.js.map +1 -0
- package/dist/issues/intake.d.ts +114 -0
- package/dist/issues/intake.js +213 -0
- package/dist/issues/intake.js.map +1 -0
- package/dist/memory/benchmark.d.ts +33 -0
- package/dist/memory/benchmark.js +69 -0
- package/dist/memory/benchmark.js.map +1 -0
- package/dist/metrics/runMetrics.d.ts +9 -0
- package/dist/metrics/runMetrics.js +34 -0
- package/dist/metrics/runMetrics.js.map +1 -0
- package/dist/metrics/usage.d.ts +3 -0
- package/dist/metrics/usage.js +53 -0
- package/dist/metrics/usage.js.map +1 -0
- package/dist/provenance/generate.d.ts +30 -0
- package/dist/provenance/generate.js +96 -0
- package/dist/provenance/generate.js.map +1 -0
- package/dist/providers/engram.d.ts +8 -0
- package/dist/providers/engram.js +14 -0
- package/dist/providers/engram.js.map +1 -0
- package/dist/providers/graphify.d.ts +9 -0
- package/dist/providers/graphify.js +28 -0
- package/dist/providers/graphify.js.map +1 -0
- package/dist/providers/paseo.d.ts +8 -0
- package/dist/providers/paseo.js +14 -0
- package/dist/providers/paseo.js.map +1 -0
- package/dist/providers/types.d.ts +41 -0
- package/dist/providers/types.js +2 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/telemetry/events.d.ts +2 -0
- package/dist/telemetry/events.js +29 -0
- package/dist/telemetry/events.js.map +1 -0
- package/dist/telemetry/otlp.d.ts +3 -0
- package/dist/telemetry/otlp.js +57 -0
- package/dist/telemetry/otlp.js.map +1 -0
- package/dist/toolchain/config.d.ts +10 -0
- package/dist/toolchain/config.js +54 -0
- package/dist/toolchain/config.js.map +1 -0
- package/dist/toolchain/doctor.d.ts +8 -0
- package/dist/toolchain/doctor.js +56 -0
- package/dist/toolchain/doctor.js.map +1 -0
- package/dist/toolchain/mise.d.ts +10 -0
- package/dist/toolchain/mise.js +61 -0
- package/dist/toolchain/mise.js.map +1 -0
- package/dist/toolchain/resolve.d.ts +8 -0
- package/dist/toolchain/resolve.js +159 -0
- package/dist/toolchain/resolve.js.map +1 -0
- package/dist/toolchain/setup.d.ts +7 -0
- package/dist/toolchain/setup.js +141 -0
- package/dist/toolchain/setup.js.map +1 -0
- package/dist/toolchain/types.d.ts +95 -0
- package/dist/toolchain/types.js +2 -0
- package/dist/toolchain/types.js.map +1 -0
- package/dist/utils/process.d.ts +15 -0
- package/dist/utils/process.js +94 -0
- package/dist/utils/process.js.map +1 -0
- package/dist/validators/commands.d.ts +2 -0
- package/dist/validators/commands.js +28 -0
- package/dist/validators/commands.js.map +1 -0
- package/dist/validators/constraints.d.ts +6 -0
- package/dist/validators/constraints.js +30 -0
- package/dist/validators/constraints.js.map +1 -0
- package/dist/validators/diffScope.d.ts +2 -0
- package/dist/validators/diffScope.js +36 -0
- package/dist/validators/diffScope.js.map +1 -0
- package/dist/validators/evidence.d.ts +6 -0
- package/dist/validators/evidence.js +8 -0
- package/dist/validators/evidence.js.map +1 -0
- package/dist/validators/external.d.ts +3 -0
- package/dist/validators/external.js +22 -0
- package/dist/validators/external.js.map +1 -0
- package/dist/validators/gherkin.d.ts +3 -0
- package/dist/validators/gherkin.js +59 -0
- package/dist/validators/gherkin.js.map +1 -0
- package/dist/validators/graphify.d.ts +4 -0
- package/dist/validators/graphify.js +108 -0
- package/dist/validators/graphify.js.map +1 -0
- package/dist/validators/opa.d.ts +3 -0
- package/dist/validators/opa.js +43 -0
- package/dist/validators/opa.js.map +1 -0
- package/dist/validators/openapi.d.ts +25 -0
- package/dist/validators/openapi.js +98 -0
- package/dist/validators/openapi.js.map +1 -0
- package/dist/validators/registry.d.ts +2 -0
- package/dist/validators/registry.js +36 -0
- package/dist/validators/registry.js.map +1 -0
- package/dist/validators/toolCommand.d.ts +5 -0
- package/dist/validators/toolCommand.js +33 -0
- package/dist/validators/toolCommand.js.map +1 -0
- package/dist/validators/types.d.ts +13 -0
- package/dist/validators/types.js +2 -0
- package/dist/validators/types.js.map +1 -0
- package/dist/workers/agentPrompt.d.ts +3 -0
- package/dist/workers/agentPrompt.js +84 -0
- package/dist/workers/agentPrompt.js.map +1 -0
- package/dist/workers/direct.d.ts +13 -0
- package/dist/workers/direct.js +30 -0
- package/dist/workers/direct.js.map +1 -0
- package/dist/workers/factory.d.ts +4 -0
- package/dist/workers/factory.js +10 -0
- package/dist/workers/factory.js.map +1 -0
- package/dist/workers/paseo.d.ts +14 -0
- package/dist/workers/paseo.js +29 -0
- package/dist/workers/paseo.js.map +1 -0
- package/dist/workers/podman.d.ts +13 -0
- package/dist/workers/podman.js +22 -0
- package/dist/workers/podman.js.map +1 -0
- package/dist/workers/prompt.d.ts +4 -0
- package/dist/workers/prompt.js +4 -0
- package/dist/workers/prompt.js.map +1 -0
- package/dist/workers/types.d.ts +11 -0
- package/dist/workers/types.js +2 -0
- package/dist/workers/types.js.map +1 -0
- package/docs/ARCHITECTURE.md +47 -0
- package/docs/EVALS.md +28 -0
- package/docs/MEMORY.md +28 -0
- package/docs/OBSERVABILITY.md +18 -0
- package/docs/OSS_STACK.md +27 -0
- package/docs/PASEO.md +9 -0
- package/docs/PUBLISHING.md +110 -0
- package/docs/SDD.md +35 -0
- package/docs/SECURITY.md +21 -0
- package/docs/V0.2.md +42 -0
- package/docs/V0.3.md +40 -0
- package/docs/V0.4.11.md +30 -0
- package/docs/V0.4.12.md +88 -0
- package/docs/V0.4.13.md +203 -0
- package/docs/V0.4.14.md +209 -0
- package/docs/V0.4.15.md +365 -0
- package/docs/V0.4.16.md +229 -0
- package/docs/V0.4.md +28 -0
- package/docs/VALIDATION.md +23 -0
- package/package.json +18 -0
- package/policies/core/dependency-policy.rego +12 -0
- package/policies/core/schema-policy.rego +12 -0
- package/policies/core/trust-boundary.rego +17 -0
- package/presets/agents/default.jsonc +80 -0
- package/presets/docker.yaml +4 -0
- package/presets/dotnet.yaml +12 -0
- package/presets/expo.yaml +6 -0
- package/presets/generic.yaml +3 -0
- package/presets/nextjs.yaml +8 -0
- package/presets/node.yaml +6 -0
- package/presets/pnpm.yaml +6 -0
- package/presets/postgres.yaml +4 -0
- package/schemas/agent-output-planner.schema.json +1 -0
- package/schemas/agent-topology.schema.json +37 -0
- package/schemas/project.schema.json +36 -0
- package/schemas/quick-contract.schema.json +17 -0
- package/schemas/task-contract.schema.json +18 -0
- package/schemas/toolchain.schema.json +70 -0
- package/schemas/validation-report.schema.json +15 -0
- package/skills/acceptance-traceability/SKILL.md +13 -0
- package/skills/deterministic-validation/SKILL.md +15 -0
- package/skills/engineering-workflow/SKILL.md +108 -0
- package/skills/finding-dedup/SKILL.md +12 -0
- package/skills/github-delivery-lifecycle/SKILL.md +16 -0
- package/skills/implementation-worker/SKILL.md +17 -0
- package/skills/lead-engineer/SKILL.md +30 -0
- package/skills/memory-hygiene/SKILL.md +22 -0
- package/skills/prompt-drift-audit/SKILL.md +10 -0
- package/skills/recovery-classifier/SKILL.md +13 -0
- package/skills/routing-normalizer/SKILL.md +17 -0
- package/skills/sdd/SKILL.md +21 -0
- package/skills/simplify/SKILL.md +16 -0
- package/skills/verification-planning/SKILL.md +17 -0
- package/skills/worktree-lifecycle/SKILL.md +18 -0
- package/templates/AGENTS.md +37 -0
- package/templates/agents.source.jsonc +39 -0
- package/templates/otel-collector.yaml +21 -0
- package/templates/project.yaml +196 -0
- package/templates/toolchain.yaml +127 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
const aliases = {
|
|
2
|
+
inputTokens: ["input_tokens", "inputTokens", "prompt_tokens", "promptTokens"],
|
|
3
|
+
outputTokens: ["output_tokens", "outputTokens", "completion_tokens", "completionTokens"],
|
|
4
|
+
totalTokens: ["total_tokens", "totalTokens"],
|
|
5
|
+
costUsd: ["cost_usd", "costUsd", "total_cost_usd", "totalCostUsd"]
|
|
6
|
+
};
|
|
7
|
+
export function extractUsageMetrics(text) {
|
|
8
|
+
const result = {};
|
|
9
|
+
result.inputTokens = integerMetric(text, aliases.inputTokens);
|
|
10
|
+
result.outputTokens = integerMetric(text, aliases.outputTokens);
|
|
11
|
+
result.totalTokens = integerMetric(text, aliases.totalTokens);
|
|
12
|
+
result.costUsd = decimalMetric(text, aliases.costUsd);
|
|
13
|
+
if (result.totalTokens === undefined && (result.inputTokens !== undefined || result.outputTokens !== undefined)) {
|
|
14
|
+
result.totalTokens = (result.inputTokens ?? 0) + (result.outputTokens ?? 0);
|
|
15
|
+
}
|
|
16
|
+
return stripUndefined(result);
|
|
17
|
+
}
|
|
18
|
+
export function mergeUsageMetrics(...items) {
|
|
19
|
+
const totals = {};
|
|
20
|
+
for (const item of items) {
|
|
21
|
+
if (item.inputTokens !== undefined)
|
|
22
|
+
totals.inputTokens = (totals.inputTokens ?? 0) + item.inputTokens;
|
|
23
|
+
if (item.outputTokens !== undefined)
|
|
24
|
+
totals.outputTokens = (totals.outputTokens ?? 0) + item.outputTokens;
|
|
25
|
+
if (item.totalTokens !== undefined)
|
|
26
|
+
totals.totalTokens = (totals.totalTokens ?? 0) + item.totalTokens;
|
|
27
|
+
if (item.costUsd !== undefined)
|
|
28
|
+
totals.costUsd = round((totals.costUsd ?? 0) + item.costUsd);
|
|
29
|
+
}
|
|
30
|
+
return totals;
|
|
31
|
+
}
|
|
32
|
+
function integerMetric(text, names) {
|
|
33
|
+
const value = numericMetric(text, names);
|
|
34
|
+
return value === undefined ? undefined : Math.round(value);
|
|
35
|
+
}
|
|
36
|
+
function decimalMetric(text, names) {
|
|
37
|
+
return numericMetric(text, names);
|
|
38
|
+
}
|
|
39
|
+
function numericMetric(text, names) {
|
|
40
|
+
let last;
|
|
41
|
+
for (const name of names) {
|
|
42
|
+
const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
43
|
+
const pattern = new RegExp(`[\"']?${escaped}[\"']?\\s*[:=]\\s*[\"']?([0-9]+(?:\\.[0-9]+)?)`, "gi");
|
|
44
|
+
for (const match of text.matchAll(pattern))
|
|
45
|
+
last = Number(match[1]);
|
|
46
|
+
}
|
|
47
|
+
return Number.isFinite(last) ? last : undefined;
|
|
48
|
+
}
|
|
49
|
+
function stripUndefined(metrics) {
|
|
50
|
+
return Object.fromEntries(Object.entries(metrics).filter(([, value]) => value !== undefined));
|
|
51
|
+
}
|
|
52
|
+
function round(value) { return Math.round(value * 1_000_000) / 1_000_000; }
|
|
53
|
+
//# sourceMappingURL=usage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage.js","sourceRoot":"","sources":["../../src/metrics/usage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { HarnessProjectConfig } from "../core/types.js";
|
|
2
|
+
export interface ProvenanceOptions {
|
|
3
|
+
artifact: string;
|
|
4
|
+
taskId?: string;
|
|
5
|
+
sbom?: boolean;
|
|
6
|
+
sign?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface ProvenanceResult {
|
|
9
|
+
artifact: string;
|
|
10
|
+
sha256: string;
|
|
11
|
+
statementFile: string;
|
|
12
|
+
predicateFile: string;
|
|
13
|
+
sbomFile?: string;
|
|
14
|
+
bundleFile?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function generateProvenance(root: string, config: HarnessProjectConfig, options: ProvenanceOptions): Promise<ProvenanceResult>;
|
|
17
|
+
export declare function buildSlsaPredicate(input: {
|
|
18
|
+
project: string;
|
|
19
|
+
artifact: string;
|
|
20
|
+
taskId?: string;
|
|
21
|
+
commit: string;
|
|
22
|
+
remote: string;
|
|
23
|
+
runDigest?: string;
|
|
24
|
+
reportDigest?: string;
|
|
25
|
+
buildType: string;
|
|
26
|
+
invocationId: string;
|
|
27
|
+
startedOn: string;
|
|
28
|
+
finishedOn: string;
|
|
29
|
+
}): Record<string, unknown>;
|
|
30
|
+
export declare function sha256File(file: string): Promise<string>;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import { createReadStream } from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { commandExists, runProcess } from "../utils/process.js";
|
|
6
|
+
export async function generateProvenance(root, config, options) {
|
|
7
|
+
const artifact = path.resolve(root, options.artifact);
|
|
8
|
+
const stat = await fs.stat(artifact);
|
|
9
|
+
if (!stat.isFile())
|
|
10
|
+
throw new Error("Provenance currently requires --artifact to point to a file.");
|
|
11
|
+
const digest = await sha256File(artifact);
|
|
12
|
+
const commit = await gitValue(root, "git rev-parse HEAD");
|
|
13
|
+
const remote = await gitValue(root, "git remote get-url origin");
|
|
14
|
+
const outputDir = path.resolve(root, config.provenance?.outputDir ?? ".harness/provenance");
|
|
15
|
+
await fs.mkdir(outputDir, { recursive: true });
|
|
16
|
+
const base = sanitize(path.basename(artifact));
|
|
17
|
+
const predicateFile = path.join(outputDir, `${base}.slsa-provenance.json`);
|
|
18
|
+
const statementFile = path.join(outputDir, `${base}.intoto.json`);
|
|
19
|
+
const runDigest = options.taskId ? await optionalDigest(path.resolve(root, config.sdd?.runsDir ?? ".harness/runs", `${options.taskId}.json`)) : undefined;
|
|
20
|
+
const reportDigest = options.taskId ? await optionalDigest(path.resolve(root, config.sdd?.reportsDir ?? ".harness/reports", `${options.taskId}.json`)) : undefined;
|
|
21
|
+
const predicate = buildSlsaPredicate({
|
|
22
|
+
project: config.project.name,
|
|
23
|
+
artifact: path.basename(artifact),
|
|
24
|
+
taskId: options.taskId,
|
|
25
|
+
commit,
|
|
26
|
+
remote,
|
|
27
|
+
runDigest,
|
|
28
|
+
reportDigest,
|
|
29
|
+
buildType: config.provenance?.buildType ?? "https://github.com/JamesMorales04/agentic-engineering-harness/v0.3",
|
|
30
|
+
invocationId: crypto.randomUUID(),
|
|
31
|
+
startedOn: new Date().toISOString(),
|
|
32
|
+
finishedOn: new Date().toISOString()
|
|
33
|
+
});
|
|
34
|
+
const statement = { _type: "https://in-toto.io/Statement/v1", subject: [{ name: path.basename(artifact), digest: { sha256: digest } }], predicateType: "https://slsa.dev/provenance/v1", predicate };
|
|
35
|
+
await fs.writeFile(predicateFile, `${JSON.stringify(predicate, null, 2)}\n`);
|
|
36
|
+
await fs.writeFile(statementFile, `${JSON.stringify(statement, null, 2)}\n`);
|
|
37
|
+
let sbomFile;
|
|
38
|
+
if (options.sbom !== false && await commandExists("trivy", root)) {
|
|
39
|
+
sbomFile = path.join(outputDir, `${base}.cyclonedx.json`);
|
|
40
|
+
const sbom = await runProcess(`trivy fs --format cyclonedx --output ${quote(sbomFile)} ${quote(root)}`, { cwd: root, timeoutMs: 600_000 });
|
|
41
|
+
if (sbom.exitCode !== 0)
|
|
42
|
+
throw new Error(`Trivy SBOM generation failed: ${sbom.stderr || sbom.stdout}`);
|
|
43
|
+
}
|
|
44
|
+
let bundleFile;
|
|
45
|
+
if (options.sign) {
|
|
46
|
+
if (!(await commandExists("cosign", root)))
|
|
47
|
+
throw new Error("--sign requested but cosign is not installed.");
|
|
48
|
+
bundleFile = path.join(outputDir, `${base}.sigstore.json`);
|
|
49
|
+
const key = config.provenance?.cosignKey ? ` --key ${quote(config.provenance.cosignKey)}` : "";
|
|
50
|
+
const signed = await runProcess(`cosign sign-blob ${quote(statementFile)} --bundle ${quote(bundleFile)}${key}`, { cwd: root, timeoutMs: 300_000, env: { COSIGN_YES: "true" } });
|
|
51
|
+
if (signed.exitCode !== 0)
|
|
52
|
+
throw new Error(`Cosign signing failed: ${signed.stderr || signed.stdout}`);
|
|
53
|
+
}
|
|
54
|
+
return { artifact: path.relative(root, artifact).replaceAll("\\", "/"), sha256: digest, statementFile: relative(root, statementFile), predicateFile: relative(root, predicateFile), sbomFile: sbomFile && relative(root, sbomFile), bundleFile: bundleFile && relative(root, bundleFile) };
|
|
55
|
+
}
|
|
56
|
+
export function buildSlsaPredicate(input) {
|
|
57
|
+
const internalParameters = {};
|
|
58
|
+
if (input.taskId)
|
|
59
|
+
internalParameters.taskId = input.taskId;
|
|
60
|
+
if (input.runDigest)
|
|
61
|
+
internalParameters.runReportSha256 = input.runDigest;
|
|
62
|
+
if (input.reportDigest)
|
|
63
|
+
internalParameters.validationReportSha256 = input.reportDigest;
|
|
64
|
+
return {
|
|
65
|
+
buildDefinition: {
|
|
66
|
+
buildType: input.buildType,
|
|
67
|
+
externalParameters: { project: input.project, artifact: input.artifact },
|
|
68
|
+
internalParameters,
|
|
69
|
+
resolvedDependencies: input.commit ? [{ uri: input.remote ? `git+${input.remote}` : "git:local", digest: { gitCommit: input.commit } }] : []
|
|
70
|
+
},
|
|
71
|
+
runDetails: {
|
|
72
|
+
builder: { id: "https://github.com/JamesMorales04/agentic-engineering-harness" },
|
|
73
|
+
metadata: { invocationId: input.invocationId, startedOn: input.startedOn, finishedOn: input.finishedOn }
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
export async function sha256File(file) {
|
|
78
|
+
return await new Promise((resolve, reject) => {
|
|
79
|
+
const hash = crypto.createHash("sha256");
|
|
80
|
+
const stream = createReadStream(file);
|
|
81
|
+
stream.on("data", (chunk) => hash.update(chunk));
|
|
82
|
+
stream.on("error", reject);
|
|
83
|
+
stream.on("end", () => resolve(hash.digest("hex")));
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
async function optionalDigest(file) { try {
|
|
87
|
+
return await sha256File(file);
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return undefined;
|
|
91
|
+
} }
|
|
92
|
+
async function gitValue(root, command) { const result = await runProcess(command, { cwd: root, timeoutMs: 30_000 }); return result.exitCode === 0 ? result.stdout.trim() : ""; }
|
|
93
|
+
function relative(root, file) { return path.relative(root, file).replaceAll("\\", "/"); }
|
|
94
|
+
function sanitize(value) { return value.replace(/[^A-Za-z0-9._-]/g, "-"); }
|
|
95
|
+
function quote(value) { return `'${value.replaceAll("'", "'\\''")}'`; }
|
|
96
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/provenance/generate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { commandExists } from "../utils/process.js";
|
|
2
|
+
export class EngramMemoryProvider {
|
|
3
|
+
name = "engram";
|
|
4
|
+
async doctor(root) {
|
|
5
|
+
const ok = await commandExists("engram", root);
|
|
6
|
+
return {
|
|
7
|
+
ok,
|
|
8
|
+
message: ok
|
|
9
|
+
? "Engram CLI detected. Memory remains advisory; Git artifacts remain authoritative."
|
|
10
|
+
: "Engram CLI was not found. Install/configure it or set memory.required=false."
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=engram.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engram.js","sourceRoot":"","sources":["../../src/providers/engram.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,MAAM,OAAO,oBAAoB;IACtB,IAAI,GAAG,QAAQ,CAAC;IAEzB,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC/C,OAAO;YACL,EAAE;YACF,OAAO,EAAE,EAAE;gBACT,CAAC,CAAC,mFAAmF;gBACrF,CAAC,CAAC,8EAA8E;SACnF,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CodeIntelligenceProvider } from "./types.js";
|
|
2
|
+
export declare class GraphifyCodeIntelligenceProvider implements CodeIntelligenceProvider {
|
|
3
|
+
readonly name = "graphify";
|
|
4
|
+
doctor(root: string): Promise<{
|
|
5
|
+
ok: boolean;
|
|
6
|
+
message: string;
|
|
7
|
+
}>;
|
|
8
|
+
update(root: string): Promise<void>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { commandExists } from "../utils/process.js";
|
|
4
|
+
export class GraphifyCodeIntelligenceProvider {
|
|
5
|
+
name = "graphify";
|
|
6
|
+
async doctor(root) {
|
|
7
|
+
const cli = await commandExists("graphify", root);
|
|
8
|
+
const graph = await graphExists(root);
|
|
9
|
+
return {
|
|
10
|
+
ok: cli || graph,
|
|
11
|
+
message: graph ? "Graphify graph detected at graphify-out/graph.json. Refresh it through the Graphify skill or codeIntelligence.refreshCommand before after-snapshots." : cli ? "Graphify CLI detected, but no graphify-out/graph.json exists yet. Build the graph through the Graphify skill." : "Graphify CLI/graph not found. Structural validation can remain optional or be disabled."
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
async update(root) {
|
|
15
|
+
if (!(await graphExists(root)))
|
|
16
|
+
throw new Error("Graphify graph is unavailable. Build or refresh graphify-out/graph.json through the Graphify assistant skill or codeIntelligence.refreshCommand.");
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
async function graphExists(root) {
|
|
20
|
+
try {
|
|
21
|
+
await fs.access(path.join(root, "graphify-out", "graph.json"));
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=graphify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphify.js","sourceRoot":"","sources":["../../src/providers/graphify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,MAAM,OAAO,gCAAgC;IAClC,IAAI,GAAG,UAAU,CAAC;IAC3B,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAClD,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC;QACtC,OAAO;YACL,EAAE,EAAE,GAAG,IAAI,KAAK;YAChB,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,sJAAsJ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,+GAA+G,CAAC,CAAC,CAAC,yFAAyF;SAC5X,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,IAAI,CAAC,CAAC,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,kJAAkJ,CAAC,CAAC;IACtM,CAAC;CACF;AACD,KAAK,UAAU,WAAW,CAAC,IAAY;IACrC,IAAI,CAAC;QAAC,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,YAAY,CAAC,CAAC,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,KAAK,CAAC;IAAC,CAAC;AAC9G,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { commandExists } from "../utils/process.js";
|
|
2
|
+
export class PaseoOrchestrationProvider {
|
|
3
|
+
name = "paseo";
|
|
4
|
+
async doctor(root) {
|
|
5
|
+
const ok = await commandExists("paseo", root);
|
|
6
|
+
return {
|
|
7
|
+
ok,
|
|
8
|
+
message: ok
|
|
9
|
+
? "Paseo CLI detected. Use the lead-agent skill to keep Codex as owner and OpenCode as implementation worker."
|
|
10
|
+
: "Paseo CLI was not found. Install it or set orchestration.required=false."
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=paseo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paseo.js","sourceRoot":"","sources":["../../src/providers/paseo.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,MAAM,OAAO,0BAA0B;IAC5B,IAAI,GAAG,OAAO,CAAC;IAExB,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC9C,OAAO;YACL,EAAE;YACF,OAAO,EAAE,EAAE;gBACT,CAAC,CAAC,4GAA4G;gBAC9G,CAAC,CAAC,0EAA0E;SAC/E,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export interface MemoryRecord {
|
|
2
|
+
id?: string;
|
|
3
|
+
project: string;
|
|
4
|
+
type: "decision" | "bug" | "discovery" | "convention" | "summary" | string;
|
|
5
|
+
title: string;
|
|
6
|
+
content: string;
|
|
7
|
+
source?: string;
|
|
8
|
+
supersedes?: string;
|
|
9
|
+
tags?: string[];
|
|
10
|
+
}
|
|
11
|
+
export interface MemoryProvider {
|
|
12
|
+
readonly name: string;
|
|
13
|
+
doctor(root: string): Promise<{
|
|
14
|
+
ok: boolean;
|
|
15
|
+
message: string;
|
|
16
|
+
}>;
|
|
17
|
+
remember?(record: MemoryRecord): Promise<string | undefined>;
|
|
18
|
+
recall?(project: string, query: string): Promise<MemoryRecord[]>;
|
|
19
|
+
}
|
|
20
|
+
export interface CodeImpactReport {
|
|
21
|
+
provider: string;
|
|
22
|
+
affectedNodes?: string[];
|
|
23
|
+
affectedCommunities?: string[];
|
|
24
|
+
raw?: unknown;
|
|
25
|
+
}
|
|
26
|
+
export interface CodeIntelligenceProvider {
|
|
27
|
+
readonly name: string;
|
|
28
|
+
doctor(root: string): Promise<{
|
|
29
|
+
ok: boolean;
|
|
30
|
+
message: string;
|
|
31
|
+
}>;
|
|
32
|
+
update?(root: string): Promise<void>;
|
|
33
|
+
impact?(root: string, diffRef?: string): Promise<CodeImpactReport>;
|
|
34
|
+
}
|
|
35
|
+
export interface OrchestrationProvider {
|
|
36
|
+
readonly name: string;
|
|
37
|
+
doctor(root: string): Promise<{
|
|
38
|
+
ok: boolean;
|
|
39
|
+
message: string;
|
|
40
|
+
}>;
|
|
41
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/providers/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { trace } from "@opentelemetry/api";
|
|
4
|
+
import { exportEventSpan } from "./otlp.js";
|
|
5
|
+
export async function recordEvent(root, config, name, attributes) {
|
|
6
|
+
if (config.telemetry?.enabled === false)
|
|
7
|
+
return;
|
|
8
|
+
const at = new Date();
|
|
9
|
+
const tracer = trace.getTracer("agentic-engineering-harness");
|
|
10
|
+
const span = tracer.startSpan(name);
|
|
11
|
+
for (const [key, value] of Object.entries(attributes)) {
|
|
12
|
+
if (["string", "number", "boolean"].includes(typeof value))
|
|
13
|
+
span.setAttribute(key, value);
|
|
14
|
+
}
|
|
15
|
+
span.end();
|
|
16
|
+
const relative = config.telemetry?.localEventsFile ?? ".harness/telemetry/events.ndjson";
|
|
17
|
+
const file = path.resolve(root, relative);
|
|
18
|
+
await fs.mkdir(path.dirname(file), { recursive: true });
|
|
19
|
+
await fs.appendFile(file, `${JSON.stringify({ at: at.toISOString(), name, attributes })}\n`);
|
|
20
|
+
try {
|
|
21
|
+
await exportEventSpan(config, name, attributes, at);
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
if (config.telemetry?.required)
|
|
25
|
+
throw error;
|
|
26
|
+
await fs.appendFile(file, `${JSON.stringify({ at: new Date().toISOString(), name: "harness.telemetry.export.error", attributes: { sourceEvent: name, error: String(error) } })}\n`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/telemetry/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAE5C,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAY,EAAE,MAA4B,EAAE,IAAY,EAAE,UAAmC;IAC7H,IAAI,MAAM,CAAC,SAAS,EAAE,OAAO,KAAK,KAAK;QAAE,OAAO;IAChD,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC;IACtB,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,6BAA6B,CAAC,CAAC;IAC9D,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACpC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QACtD,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,OAAO,KAAK,CAAC;YAAE,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,KAAkC,CAAC,CAAC;IACzH,CAAC;IACD,IAAI,CAAC,GAAG,EAAE,CAAC;IAEX,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,EAAE,eAAe,IAAI,kCAAkC,CAAC;IACzF,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC1C,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACxD,MAAM,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,IAAI,CAAC,CAAC;IAE7F,IAAI,CAAC;QAAC,MAAM,eAAe,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;IAAC,CAAC;IAC5D,OAAO,KAAK,EAAE,CAAC;QACb,IAAI,MAAM,CAAC,SAAS,EAAE,QAAQ;YAAE,MAAM,KAAK,CAAC;QAC5C,MAAM,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,gCAAgC,EAAE,UAAU,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;IACtL,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { HarnessProjectConfig } from "../core/types.js";
|
|
2
|
+
export declare function exportEventSpan(config: HarnessProjectConfig, name: string, attributes: Record<string, unknown>, at?: Date): Promise<void>;
|
|
3
|
+
export declare function resolveEndpoint(config: HarnessProjectConfig): string | undefined;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
export async function exportEventSpan(config, name, attributes, at = new Date()) {
|
|
3
|
+
if (config.telemetry?.exporter !== "otlp-http-json")
|
|
4
|
+
return;
|
|
5
|
+
const endpoint = resolveEndpoint(config);
|
|
6
|
+
if (!endpoint)
|
|
7
|
+
throw new Error("OTLP exporter is enabled but no endpoint is configured.");
|
|
8
|
+
const nanos = (BigInt(at.getTime()) * 1000000n).toString();
|
|
9
|
+
const payload = {
|
|
10
|
+
resourceSpans: [{
|
|
11
|
+
resource: { attributes: [attribute("service.name", config.telemetry?.serviceName ?? process.env.OTEL_SERVICE_NAME ?? config.project.name)] },
|
|
12
|
+
scopeSpans: [{
|
|
13
|
+
scope: { name: "agentic-engineering-harness", version: "0.3.0" },
|
|
14
|
+
spans: [{
|
|
15
|
+
traceId: crypto.randomBytes(16).toString("hex"), spanId: crypto.randomBytes(8).toString("hex"), name, kind: 1,
|
|
16
|
+
startTimeUnixNano: nanos, endTimeUnixNano: nanos,
|
|
17
|
+
attributes: Object.entries(attributes).flatMap(([key, value]) => value === undefined || value === null ? [] : [attribute(key, value)]),
|
|
18
|
+
status: { code: 1 }
|
|
19
|
+
}]
|
|
20
|
+
}]
|
|
21
|
+
}]
|
|
22
|
+
};
|
|
23
|
+
const response = await fetch(endpoint, {
|
|
24
|
+
method: "POST",
|
|
25
|
+
headers: { "content-type": "application/json", ...environmentHeaders(), ...(config.telemetry?.headers ?? {}) },
|
|
26
|
+
body: JSON.stringify(payload),
|
|
27
|
+
signal: AbortSignal.timeout(10_000)
|
|
28
|
+
});
|
|
29
|
+
if (!response.ok)
|
|
30
|
+
throw new Error(`OTLP exporter returned HTTP ${response.status}: ${await response.text()}`);
|
|
31
|
+
}
|
|
32
|
+
export function resolveEndpoint(config) {
|
|
33
|
+
const signal = process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT;
|
|
34
|
+
if (signal)
|
|
35
|
+
return signal;
|
|
36
|
+
const configured = config.telemetry?.endpoint ?? process.env.OTEL_EXPORTER_OTLP_ENDPOINT;
|
|
37
|
+
if (!configured)
|
|
38
|
+
return undefined;
|
|
39
|
+
return `${configured.replace(/\/$/, "")}/v1/traces`;
|
|
40
|
+
}
|
|
41
|
+
function attribute(key, value) {
|
|
42
|
+
if (typeof value === "boolean")
|
|
43
|
+
return { key, value: { boolValue: value } };
|
|
44
|
+
if (typeof value === "number")
|
|
45
|
+
return Number.isInteger(value) ? { key, value: { intValue: String(value) } } : { key, value: { doubleValue: String(value) } };
|
|
46
|
+
return { key, value: { stringValue: typeof value === "string" ? value : JSON.stringify(value) } };
|
|
47
|
+
}
|
|
48
|
+
function environmentHeaders() {
|
|
49
|
+
const raw = process.env.OTEL_EXPORTER_OTLP_TRACES_HEADERS ?? process.env.OTEL_EXPORTER_OTLP_HEADERS;
|
|
50
|
+
if (!raw)
|
|
51
|
+
return {};
|
|
52
|
+
return Object.fromEntries(raw.split(",").map((part) => part.trim()).filter(Boolean).map((part) => {
|
|
53
|
+
const index = part.indexOf("=");
|
|
54
|
+
return index < 0 ? [part, ""] : [part.slice(0, index), part.slice(index + 1)];
|
|
55
|
+
}));
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=otlp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"otlp.js","sourceRoot":"","sources":["../../src/telemetry/otlp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { HarnessProjectConfig } from "../core/types.js";
|
|
2
|
+
import type { ToolchainConfig, ToolchainLock, ToolchainState } from "./types.js";
|
|
3
|
+
export declare function toolchainConfigPath(config: HarnessProjectConfig): string;
|
|
4
|
+
export declare function toolchainLockPath(config: HarnessProjectConfig, toolchain: ToolchainConfig): string;
|
|
5
|
+
export declare function toolchainStatePath(config: HarnessProjectConfig, toolchain: ToolchainConfig): string;
|
|
6
|
+
export declare function generatedMisePath(config: HarnessProjectConfig, toolchain: ToolchainConfig): string;
|
|
7
|
+
export declare function loadToolchainConfig(root: string, config: HarnessProjectConfig): Promise<ToolchainConfig>;
|
|
8
|
+
export declare function loadToolchainLock(root: string, config: HarnessProjectConfig, toolchain: ToolchainConfig): Promise<ToolchainLock | undefined>;
|
|
9
|
+
export declare function loadToolchainState(root: string, config: HarnessProjectConfig, toolchain: ToolchainConfig): Promise<ToolchainState | undefined>;
|
|
10
|
+
export declare function writeJsonFile(file: string, value: unknown): Promise<void>;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import YAML from "yaml";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
const toolSchema = z.object({
|
|
6
|
+
kind: z.enum(["system", "mise"]),
|
|
7
|
+
command: z.string().min(1),
|
|
8
|
+
source: z.string().min(1).optional(),
|
|
9
|
+
version: z.string().min(1).optional(),
|
|
10
|
+
required: z.boolean().optional(),
|
|
11
|
+
dependsOn: z.array(z.string().min(1)).optional(),
|
|
12
|
+
activateWhen: z.array(z.string().min(1)).optional(),
|
|
13
|
+
container: z.object({ image: z.string().min(1), engine: z.string().min(1).optional() }).optional()
|
|
14
|
+
}).superRefine((value, ctx) => {
|
|
15
|
+
if (value.kind === "mise" && !value.source)
|
|
16
|
+
ctx.addIssue({ code: "custom", message: "mise tools require source" });
|
|
17
|
+
});
|
|
18
|
+
const schema = z.object({
|
|
19
|
+
version: z.literal(1),
|
|
20
|
+
manager: z.object({ provider: z.string().min(1), generatedConfig: z.string().optional(), lockFile: z.string().optional(), stateFile: z.string().optional(), minimumVersion: z.string().optional() }),
|
|
21
|
+
strategy: z.object({ validators: z.enum(["local", "prefer-container"]).optional(), containerEngine: z.string().optional() }).optional(),
|
|
22
|
+
profiles: z.record(z.string(), z.object({ extends: z.array(z.string()).optional(), tools: z.array(z.string()).optional() })).optional(),
|
|
23
|
+
tools: z.record(z.string(), toolSchema),
|
|
24
|
+
projectDependencies: z.object({ autoDetect: z.boolean().optional(), commands: z.array(z.string().min(1)).optional() }).optional()
|
|
25
|
+
});
|
|
26
|
+
export function toolchainConfigPath(config) { return config.toolchain?.configPath ?? ".harness/toolchain.yaml"; }
|
|
27
|
+
export function toolchainLockPath(config, toolchain) { return config.toolchain?.lockPath ?? toolchain.manager.lockFile ?? ".harness/toolchain.lock.json"; }
|
|
28
|
+
export function toolchainStatePath(config, toolchain) { return config.toolchain?.statePath ?? toolchain.manager.stateFile ?? ".harness/toolchain.state.json"; }
|
|
29
|
+
export function generatedMisePath(config, toolchain) { return config.toolchain?.generatedMisePath ?? toolchain.manager.generatedConfig ?? ".config/mise/conf.d/aeh.toml"; }
|
|
30
|
+
export async function loadToolchainConfig(root, config) {
|
|
31
|
+
const file = path.resolve(root, toolchainConfigPath(config));
|
|
32
|
+
return schema.parse(YAML.parse(await fs.readFile(file, "utf8")));
|
|
33
|
+
}
|
|
34
|
+
export async function loadToolchainLock(root, config, toolchain) {
|
|
35
|
+
try {
|
|
36
|
+
return JSON.parse(await fs.readFile(path.resolve(root, toolchainLockPath(config, toolchain)), "utf8"));
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export async function loadToolchainState(root, config, toolchain) {
|
|
43
|
+
try {
|
|
44
|
+
return JSON.parse(await fs.readFile(path.resolve(root, toolchainStatePath(config, toolchain)), "utf8"));
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
export async function writeJsonFile(file, value) {
|
|
51
|
+
await fs.mkdir(path.dirname(file), { recursive: true });
|
|
52
|
+
await fs.writeFile(file, `${JSON.stringify(value, null, 2)}\n`);
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/toolchain/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { HarnessProjectConfig } from "../core/types.js";
|
|
2
|
+
export interface ToolchainDoctorResult {
|
|
3
|
+
component: string;
|
|
4
|
+
required: boolean;
|
|
5
|
+
ok: boolean;
|
|
6
|
+
message: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function runToolchainDoctor(root: string, project: HarnessProjectConfig): Promise<ToolchainDoctorResult[]>;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { commandExists, runProcess } from "../utils/process.js";
|
|
2
|
+
import { loadToolchainConfig, loadToolchainLock, loadToolchainState } from "./config.js";
|
|
3
|
+
import { resolveToolchain } from "./resolve.js";
|
|
4
|
+
export async function runToolchainDoctor(root, project) {
|
|
5
|
+
let toolchain;
|
|
6
|
+
try {
|
|
7
|
+
toolchain = await loadToolchainConfig(root, project);
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
return [{ component: "toolchain", required: true, ok: false, message: "Toolchain config is missing or invalid; run aeh init or inspect .harness/toolchain.yaml." }];
|
|
11
|
+
}
|
|
12
|
+
const lock = await loadToolchainLock(root, project, toolchain);
|
|
13
|
+
const state = await loadToolchainState(root, project, toolchain);
|
|
14
|
+
const resolved = await resolveToolchain(root, project, toolchain, { containerAvailable: await commandExists(toolchain.strategy?.containerEngine ?? "podman", root) });
|
|
15
|
+
const results = [];
|
|
16
|
+
results.push({ component: "toolchain-lock", required: true, ok: Boolean(lock), message: lock ? `Resolved toolchain lock profile=${lock.profile}.` : "No resolved toolchain lock; run aeh setup." });
|
|
17
|
+
results.push({ component: "toolchain-state", required: true, ok: Boolean(state), message: state ? `${state.binPaths.length} provisioned bin path(s) active.` : "No machine-local toolchain state; run aeh setup." });
|
|
18
|
+
for (const tool of resolved.tools) {
|
|
19
|
+
const locked = lock?.tools[tool.name];
|
|
20
|
+
const available = await commandExists(tool.command, root);
|
|
21
|
+
const expected = locked?.resolvedVersion;
|
|
22
|
+
const actual = available ? await exactToolVersion(root, tool.command, locked?.provisioning, state?.manager.command) : undefined;
|
|
23
|
+
const versionOk = !expected || !actual || normalizeVersion(actual) === normalizeVersion(expected);
|
|
24
|
+
const ok = Boolean(locked) && available && versionOk;
|
|
25
|
+
const reasons = [];
|
|
26
|
+
if (!locked)
|
|
27
|
+
reasons.push("not present in toolchain lock");
|
|
28
|
+
if (!available)
|
|
29
|
+
reasons.push("command missing from reconciled PATH");
|
|
30
|
+
if (available && expected && actual && !versionOk)
|
|
31
|
+
reasons.push(`version drift locked=${expected} actual=${actual}`);
|
|
32
|
+
results.push({
|
|
33
|
+
component: `toolchain:${tool.name}`,
|
|
34
|
+
required: tool.required ?? true,
|
|
35
|
+
ok,
|
|
36
|
+
message: ok
|
|
37
|
+
? `${tool.command} compliant; provisioning=${locked.provisioning}${expected ? `; locked=${expected}` : ""}${locked?.digestRef ? `; digest=${locked.digestRef}` : ""}.`
|
|
38
|
+
: `${tool.command} non-compliant (${reasons.join("; ") || "version could not be verified"}); selected by ${tool.selectedBy.join(", ")}.`
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return results;
|
|
42
|
+
}
|
|
43
|
+
async function exactToolVersion(root, command, provisioning, managerCommand) {
|
|
44
|
+
if (provisioning === "mise" && managerCommand) {
|
|
45
|
+
const result = await runProcess(`${managerCommand} which ${shell(command)} --version`, { cwd: root, timeoutMs: 30_000, toolchain: false });
|
|
46
|
+
if (result.exitCode === 0 && result.stdout.trim())
|
|
47
|
+
return result.stdout.trim();
|
|
48
|
+
}
|
|
49
|
+
if (provisioning === "container")
|
|
50
|
+
return undefined;
|
|
51
|
+
const result = await runProcess(`${command} --version`, { cwd: root, timeoutMs: 15_000 });
|
|
52
|
+
return result.exitCode === 0 ? (result.stdout || result.stderr).split(/\r?\n/)[0]?.trim() : undefined;
|
|
53
|
+
}
|
|
54
|
+
function normalizeVersion(value) { return value.trim().replace(/^v/, "").replace(/^.*?((?:\d{4}|\d+)\.\d+(?:\.\d+)?).*$/, "$1"); }
|
|
55
|
+
function shell(value) { return `'${value.replaceAll("'", "'\\''")}'`; }
|
|
56
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/toolchain/doctor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACzF,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAIhD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAAY,EAAE,OAA6B;IAClF,IAAI,SAAS,CAAC;IACd,IAAI,CAAC;QAAC,SAAS,GAAG,MAAM,mBAAmB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAAC,CAAC;IAC7D,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,0FAA0F,EAAE,CAAC,CAAC;IAAC,CAAC;IAC9K,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IAAC,MAAM,KAAK,GAAG,MAAM,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IACjI,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC,SAAS,CAAC,QAAQ,EAAE,eAAe,IAAI,QAAQ,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;IACtK,MAAM,OAAO,GAA4B,EAAE,CAAC;IAC5C,OAAO,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,gBAAgB,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,mCAAmC,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,4CAA4C,EAAE,CAAC,CAAC;IACpM,OAAO,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,iBAAiB,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,kCAAkC,CAAC,CAAC,CAAC,kDAAkD,EAAE,CAAC,CAAC;IAErN,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtC,MAAM,SAAS,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC1D,MAAM,QAAQ,GAAG,MAAM,EAAE,eAAe,CAAC;QACzC,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,MAAM,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAChI,MAAM,SAAS,GAAG,CAAC,QAAQ,IAAI,CAAC,MAAM,IAAI,gBAAgB,CAAC,MAAM,CAAC,KAAK,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QAClG,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,SAAS,IAAI,SAAS,CAAC;QACrD,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,IAAI,CAAC,MAAM;YAAE,OAAO,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;QAC3D,IAAI,CAAC,SAAS;YAAE,OAAO,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;QACrE,IAAI,SAAS,IAAI,QAAQ,IAAI,MAAM,IAAI,CAAC,SAAS;YAAE,OAAO,CAAC,IAAI,CAAC,wBAAwB,QAAQ,WAAW,MAAM,EAAE,CAAC,CAAC;QACrH,OAAO,CAAC,IAAI,CAAC;YACX,SAAS,EAAE,aAAa,IAAI,CAAC,IAAI,EAAE;YACnC,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,IAAI;YAC/B,EAAE;YACF,OAAO,EAAE,EAAE;gBACT,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,4BAA4B,MAAO,CAAC,YAAY,GAAG,QAAQ,CAAC,CAAC,CAAC,YAAY,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,YAAY,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG;gBACvK,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,mBAAmB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,+BAA+B,kBAAkB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;SAC3I,CAAC,CAAC;IACL,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,IAAY,EAAE,OAAe,EAAE,YAAgC,EAAE,cAAkC;IACjI,IAAI,YAAY,KAAK,MAAM,IAAI,cAAc,EAAE,CAAC;QAC9C,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,GAAG,cAAc,UAAU,KAAK,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;QAC3I,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE;YAAE,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IACjF,CAAC;IACD,IAAI,YAAY,KAAK,WAAW;QAAE,OAAO,SAAS,CAAC;IACnD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,GAAG,OAAO,YAAY,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;IAC1F,OAAO,MAAM,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACxG,CAAC;AACD,SAAS,gBAAgB,CAAC,KAAa,IAAY,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,uCAAuC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;AAClJ,SAAS,KAAK,CAAC,KAAa,IAAY,OAAO,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC"}
|