-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcli-import-commands.ts
More file actions
175 lines (168 loc) · 9.03 KB
/
Copy pathcli-import-commands.ts
File metadata and controls
175 lines (168 loc) · 9.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
import { resolve } from "node:path";
import type { Command } from "commander";
import chalk from "chalk";
function renderNormalization(plan: import("./importers/neutralImporter.js").NeutralImportPlan): void {
const receipt = plan.normalization;
if (!receipt) { console.log(" Normalization: legacy receipt; mapping losses and unknown timing were not recorded."); return; }
const count = receipt.counts;
console.log(` Source trust: ${receipt.sourceTrust}; evaluation: ${receipt.evaluation}`);
console.log(` Mapping: ${count.normalizedTraces} traces; ${count.failureTraces} reported failures`);
console.log(` Files skipped: ${count.skippedFiles} (${count.malformedFiles} malformed, ${count.unsupportedFiles} unsupported, ${count.oversizedFiles} oversized)`);
console.log(` Unknown timing: ${count.unknownTimestamps} event times; ${count.unknownDurations} durations`);
console.log(` Normalizer: ${receipt.normalizerVersion}; semantic digest: ${receipt.semanticDigest}`);
for (const loss of receipt.losses) console.log(chalk.gray(` ${loss}`));
for (const candidate of plan.candidates) console.log(` Source: ${candidate.path}; SHA-256 ${candidate.digest}; format ${candidate.sourceFormat?.version ?? candidate.format}`);
console.log(" Next: inspect the JSON receipt before applying, or use amc imports show <import-id> after applying.");
}
export function registerNeutralImportCommands(program: Command, activeAgent: (p: Command) => string | undefined): void {
program
.command("import <path>")
.description("Import neutral traces, runs, workflow graphs, configs, memory, evals, and benchmarks")
.option("--agent <agentId>", "agent ID")
.option("--dry-run", "detect and summarize without writing artifacts", false)
.option("--validate", "validate support without writing artifacts", false)
.option("--json", "JSON output")
.option("--expected-digest <sha256>", "apply only the semantic source digest reviewed in a preview")
.action(async (path: string, opts: { agent?: string; dryRun?: boolean; validate?: boolean; json?: boolean; expectedDigest?: string }) => {
try {
const agentId = opts.agent ?? activeAgent(program) ?? "default";
const mode = opts.validate ? "validate" : opts.dryRun ? "dry-run" : "import";
const { runNeutralImport } = await import("./importers/neutralImporter.js");
const result = runNeutralImport({
workspace: process.cwd(),
inputPath: resolve(process.cwd(), path),
agentId,
mode,
expectedSemanticDigest: opts.expectedDigest
});
if (opts.json) {
console.log(JSON.stringify(result, null, 2));
return;
}
console.log(chalk.bold(`Neutral import ${result.importId}`));
console.log(` Mode: ${result.mode}`);
console.log(` Status: ${result.plan.status}`);
console.log(` Artifacts: ${result.plan.candidateCount}`);
console.log(` Categories: ${result.plan.categories.join(", ") || "-"}`);
console.log(` Redactions: ${result.plan.redactionCount}`);
renderNormalization(result.plan);
if (!result.applied) {
console.log(chalk.gray(" Dry run only. Re-run without --dry-run or --validate to write AMC evidence."));
for (const path of result.plan.wouldWrite.slice(0, 8)) {
console.log(chalk.gray(` would write ${path}`));
}
return;
}
console.log(chalk.green(" Imported as SELF_REPORTED evidence. No maturity evaluation was performed."));
console.log(` Episode: ${result.episode?.episode.episodeId ?? "-"}`);
console.log(` Lifecycle: ${result.lifecycleRun?.artifact.lifecycleRunId ?? "-"}`);
console.log(` Trace index: ${result.traceFailureIndex?.ref.indexId ?? "-"}`);
console.log(` Manifest: ${result.resourceManifest?.manifest.manifestId ?? "-"}`);
for (const path of result.externalEvidencePaths ?? []) console.log(` Portable evidence: ${path}`);
} catch (error) {
console.error(chalk.red(error instanceof Error ? error.message : String(error)));
process.exit(1);
}
});
const imports = program
.command("imports")
.description("List, inspect, and roll back neutral import runs");
imports.command("verify-profile <path>")
.description("Independently verify an external-evidence profile without opening a workspace")
.option("--authorities <path>", "operator-admitted authority keys JSON; never taken from the evidence")
.option("--original <path>", "original source bytes to compare with the declared source digest")
.option("--expected-digest <sha256>", "independently received normalized semantic digest")
.option("--json", "JSON output")
.action(async (path: string, opts: { authorities?: string; original?: string; expectedDigest?: string; json?: boolean }) => {
try {
const { verifyExternalEvidenceFile } = await import("./standard/externalEvidenceFiles.js");
const result = verifyExternalEvidenceFile({ path: resolve(path), authoritiesPath: opts.authorities,
originalPath: opts.original, expectedNormalizedDigest: opts.expectedDigest });
if (opts.json) console.log(JSON.stringify(result, null, 2));
else {
console.log(`Profile: ${result.ok ? "valid" : "refused"}; source trust: ${result.trustTier}`);
console.log(`Original digest: ${result.originalDigest}; signature verified: ${result.signatureVerified}; parent session: ${result.parentSession}`);
for (const error of result.errors) console.error(error);
}
if (!result.ok) process.exitCode = 1;
} catch {
const result = { ok: false, errors: ["Unable to read a valid bounded profile or authority file"], trustTier: "SELF_REPORTED" };
if (opts.json) console.log(JSON.stringify(result)); else console.error(result.errors[0]);
process.exitCode = 1;
}
});
imports
.command("list")
.description("List recent neutral import runs")
.option("--limit <n>", "max imports", "25")
.option("--json", "JSON output")
.action(async (opts: { limit: string; json?: boolean }) => {
try {
const { listNeutralImports } = await import("./importers/neutralImporter.js");
const limit = Number.parseInt(opts.limit, 10);
const rows = listNeutralImports({
workspace: process.cwd(),
limit: Number.isFinite(limit) && limit > 0 ? limit : 25
});
if (opts.json) {
console.log(JSON.stringify({ imports: rows, total: rows.length }, null, 2));
return;
}
if (rows.length === 0) {
console.log(chalk.dim("No neutral imports found."));
return;
}
for (const row of rows) {
console.log(`${row.createdAt} ${row.importId} artifacts=${row.plan.candidateCount} categories=${row.plan.categories.join(",")}`);
}
} catch (error) {
console.error(chalk.red(error instanceof Error ? error.message : String(error)));
process.exit(1);
}
});
imports
.command("show <importId>")
.description("Inspect a neutral import manifest")
.option("--json", "JSON output")
.action(async (importId: string, opts: { json?: boolean }) => {
try {
const { loadNeutralImportManifest } = await import("./importers/neutralImporter.js");
const manifest = loadNeutralImportManifest({ workspace: process.cwd(), importId });
if (opts.json) {
console.log(JSON.stringify(manifest, null, 2));
return;
}
console.log(chalk.bold(`Neutral import ${manifest.importId}`));
console.log(` Created: ${manifest.createdAt}`);
console.log(` Agent: ${manifest.agentId}`);
console.log(` Source: ${manifest.sourcePath}`);
console.log(` Categories: ${manifest.plan.categories.join(", ") || "-"}`);
console.log(` Redactions: ${manifest.plan.redactionCount}`);
renderNormalization(manifest.plan);
for (const path of manifest.externalEvidencePaths ?? []) console.log(` Portable evidence: ${path}`);
} catch (error) {
console.error(chalk.red(error instanceof Error ? error.message : String(error)));
process.exit(1);
}
});
imports
.command("rollback <importId>")
.description("Remove files written by a neutral import run")
.option("--json", "JSON output")
.action(async (importId: string, opts: { json?: boolean }) => {
try {
const { rollbackNeutralImport } = await import("./importers/neutralImporter.js");
const result = rollbackNeutralImport({ workspace: process.cwd(), importId });
if (opts.json) {
console.log(JSON.stringify(result, null, 2));
return;
}
const removed = result.removed.filter((entry) => entry.status === "removed").length;
console.log(chalk.green(`Rolled back ${removed} file(s).`));
console.log(`Receipt: ${result.receiptPath}`);
} catch (error) {
console.error(chalk.red(error instanceof Error ? error.message : String(error)));
process.exit(1);
}
});
}