@tangle-network/traces 0.11.0 → 0.11.3
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/README.md +161 -13
- package/dist/{chunk-JCI5YXNT.js → chunk-CK5F5TWO.js} +3566 -913
- package/dist/cli.js +208 -21
- package/dist/index.d.ts +1137 -9
- package/dist/index.js +167 -1
- package/docs/replay-batch-20260802.md +76 -0
- package/docs/replay-verify.md +105 -0
- package/package.json +6 -4
- package/skills/inspect-agent-traces/SKILL.md +31 -2
package/dist/cli.js
CHANGED
|
@@ -6,6 +6,8 @@ import {
|
|
|
6
6
|
appendAll,
|
|
7
7
|
buildPolicyEvidenceRecord,
|
|
8
8
|
buildSessionIndexFromRows,
|
|
9
|
+
cmdReplayVerify,
|
|
10
|
+
cmdReplayVerifyBatch,
|
|
9
11
|
collectSessionSelection,
|
|
10
12
|
commandAnalyzer,
|
|
11
13
|
commandRedactor,
|
|
@@ -26,8 +28,10 @@ import {
|
|
|
26
28
|
parseSession,
|
|
27
29
|
parseSince,
|
|
28
30
|
planUpload,
|
|
31
|
+
readOtlpInput,
|
|
29
32
|
readSessionIndexFile,
|
|
30
33
|
renderInspectionReport,
|
|
34
|
+
renderValidation,
|
|
31
35
|
resolveAdapter,
|
|
32
36
|
resolveRunWatchTarget,
|
|
33
37
|
runTraceImprovement,
|
|
@@ -42,6 +46,7 @@ import {
|
|
|
42
46
|
streamSessions,
|
|
43
47
|
totalAgenticFailureMessage,
|
|
44
48
|
traceStreamEventsFromSpans,
|
|
49
|
+
validationExitCode,
|
|
45
50
|
watchRunTarget,
|
|
46
51
|
watchSessions,
|
|
47
52
|
writeInspectionReportFile,
|
|
@@ -49,7 +54,7 @@ import {
|
|
|
49
54
|
writePolicyEvidenceFile,
|
|
50
55
|
writeSessionIndexFile,
|
|
51
56
|
writeTraceEvidenceExportFile
|
|
52
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-CK5F5TWO.js";
|
|
53
58
|
|
|
54
59
|
// src/cli.ts
|
|
55
60
|
import { readFileSync } from "fs";
|
|
@@ -155,6 +160,9 @@ function parseArgs(argv) {
|
|
|
155
160
|
case "--otlp":
|
|
156
161
|
a.otlp = next();
|
|
157
162
|
break;
|
|
163
|
+
case "--otlp-out":
|
|
164
|
+
a.otlpOut = next();
|
|
165
|
+
break;
|
|
158
166
|
case "--llm":
|
|
159
167
|
a.llm = true;
|
|
160
168
|
break;
|
|
@@ -239,6 +247,30 @@ function parseArgs(argv) {
|
|
|
239
247
|
}
|
|
240
248
|
return a;
|
|
241
249
|
}
|
|
250
|
+
var OTLP_INPUT_COMMANDS = /* @__PURE__ */ new Set(["analyze", "investigate", "improve", "stream", "validate"]);
|
|
251
|
+
function migrateWritingOtlpFlag(args) {
|
|
252
|
+
if (args.otlp === void 0 || OTLP_INPUT_COMMANDS.has(args.command)) return args;
|
|
253
|
+
if (args.otlpOut !== void 0) {
|
|
254
|
+
throw new Error(
|
|
255
|
+
`${args.command} was given both --otlp and --otlp-out. --otlp is the deprecated spelling of --otlp-out on writing commands; pass only --otlp-out.`
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
console.error(
|
|
259
|
+
`warning: --otlp is deprecated on \`${args.command}\` and will be removed in 0.12. --otlp now READS OTLP-JSONL; use --otlp-out <path> to write the artifact. Treating it as --otlp-out for this run.`
|
|
260
|
+
);
|
|
261
|
+
return { ...args, otlpOut: args.otlp, otlp: void 0 };
|
|
262
|
+
}
|
|
263
|
+
function validateOtlpSelection(raw) {
|
|
264
|
+
const args = migrateWritingOtlpFlag(raw);
|
|
265
|
+
if (args.otlp === void 0) return args;
|
|
266
|
+
if (args.input) throw new Error("--otlp cannot be combined with an input file");
|
|
267
|
+
if (args.session) throw new Error("--otlp reads a file and cannot be combined with --session");
|
|
268
|
+
if (args.supervisorRunDir) throw new Error("--otlp cannot be combined with --supervisor-run-dir");
|
|
269
|
+
if (args.workflow || args.latestTurn) {
|
|
270
|
+
throw new Error("--workflow and --latest-turn expand harness sessions and cannot be combined with --otlp");
|
|
271
|
+
}
|
|
272
|
+
return args;
|
|
273
|
+
}
|
|
242
274
|
var CURRENT_SESSION_COMMANDS = /* @__PURE__ */ new Set([
|
|
243
275
|
"analyze",
|
|
244
276
|
"investigate",
|
|
@@ -457,7 +489,45 @@ function selectedSessionSource(ref, spans, sessionIdOverride) {
|
|
|
457
489
|
} : {}
|
|
458
490
|
};
|
|
459
491
|
}
|
|
492
|
+
async function collectOtlpSpans(path) {
|
|
493
|
+
const input = await readOtlpInput(path);
|
|
494
|
+
if (input.spans.length === 0) {
|
|
495
|
+
throw new Error(
|
|
496
|
+
`no analyzable spans in ${path} (${input.files.length} file(s), ${input.rows.length} row(s), ${input.issues.length} unusable). Run \`traces validate ${path}\` for the per-finding reason.`
|
|
497
|
+
);
|
|
498
|
+
}
|
|
499
|
+
const fileByTrace = /* @__PURE__ */ new Map();
|
|
500
|
+
for (const file of input.files) {
|
|
501
|
+
for (const traceId of file.traceIds) if (!fileByTrace.has(traceId)) fileByTrace.set(traceId, file.path);
|
|
502
|
+
}
|
|
503
|
+
const byTrace = /* @__PURE__ */ new Map();
|
|
504
|
+
for (const span of input.spans) {
|
|
505
|
+
const grouped = byTrace.get(span.trace_id) ?? [];
|
|
506
|
+
grouped.push(span);
|
|
507
|
+
byTrace.set(span.trace_id, grouped);
|
|
508
|
+
}
|
|
509
|
+
return {
|
|
510
|
+
spans: [...input.spans],
|
|
511
|
+
harness: "otlp",
|
|
512
|
+
cwds: [],
|
|
513
|
+
sources: [...byTrace].map(([traceId, spans]) => selectedSessionSource({
|
|
514
|
+
harness: "otlp",
|
|
515
|
+
sessionId: traceId,
|
|
516
|
+
path: fileByTrace.get(traceId) ?? path,
|
|
517
|
+
cwd: null,
|
|
518
|
+
mtimeMs: 0
|
|
519
|
+
}, spans, traceId)),
|
|
520
|
+
conformance: input.validation,
|
|
521
|
+
conformanceSubject: path,
|
|
522
|
+
conformanceFiles: input.files,
|
|
523
|
+
conformanceSkipped: input.skipped,
|
|
524
|
+
conformanceIssues: input.issues,
|
|
525
|
+
conformanceWithheld: input.withheld,
|
|
526
|
+
conformanceUnreadable: input.unreadable
|
|
527
|
+
};
|
|
528
|
+
}
|
|
460
529
|
async function collectSpans(args) {
|
|
530
|
+
if (args.otlp) return collectOtlpSpans(args.otlp);
|
|
461
531
|
if (args.input) {
|
|
462
532
|
if (args.workflow) throw new Error("--workflow reads discovered sessions and cannot be combined with an input file");
|
|
463
533
|
return collectImportedSpans(args);
|
|
@@ -481,11 +551,37 @@ async function collectSpans(args) {
|
|
|
481
551
|
...selection.workflow ? { workflow: selection.workflow } : {}
|
|
482
552
|
};
|
|
483
553
|
}
|
|
554
|
+
async function cmdValidate(args) {
|
|
555
|
+
const path = args.otlp ?? args.input;
|
|
556
|
+
if (!path) {
|
|
557
|
+
throw new Error("validate needs an OTLP-JSONL file or directory: `traces validate <file|dir>`");
|
|
558
|
+
}
|
|
559
|
+
const input = await readOtlpInput(path);
|
|
560
|
+
const report = renderValidation(input.validation, {
|
|
561
|
+
subject: path,
|
|
562
|
+
files: input.files,
|
|
563
|
+
skipped: input.skipped,
|
|
564
|
+
issues: input.issues,
|
|
565
|
+
withheld: input.withheld,
|
|
566
|
+
unreadable: input.unreadable,
|
|
567
|
+
spans: input.spans
|
|
568
|
+
});
|
|
569
|
+
const validation = input.validation;
|
|
570
|
+
if (args.out) {
|
|
571
|
+
await saveReport(args.out, report);
|
|
572
|
+
console.log(
|
|
573
|
+
`conformance report \u2192 ${args.out} (${validation.findings.length} finding(s), ${validation.capabilities.filter((capability) => capability.available).length}/${validation.capabilities.length} capabilities available)`
|
|
574
|
+
);
|
|
575
|
+
} else {
|
|
576
|
+
console.log(report);
|
|
577
|
+
}
|
|
578
|
+
process.exitCode = validationExitCode(validation);
|
|
579
|
+
}
|
|
484
580
|
async function cmdConvert(args) {
|
|
485
581
|
const { spans, workflow } = await collectSpans(args);
|
|
486
582
|
if (spans.length === 0) throw new Error("no spans found for the given selection");
|
|
487
583
|
warnIncompleteWorkflow(workflow);
|
|
488
|
-
const path = await writeOtlpFile(spans, args.
|
|
584
|
+
const path = await writeOtlpFile(spans, args.otlpOut);
|
|
489
585
|
console.log(`wrote ${spans.length} spans \u2192 ${path}`);
|
|
490
586
|
}
|
|
491
587
|
function workflowIssueText(issue) {
|
|
@@ -519,7 +615,7 @@ async function cmdEvidence(args) {
|
|
|
519
615
|
const rows = selection.rows.filter((row) => row.spans.length > 0);
|
|
520
616
|
if (rows.length === 0) throw new Error("no spans found for the given selection");
|
|
521
617
|
warnIncompleteWorkflow(selection.workflow);
|
|
522
|
-
const otlpPath = args.
|
|
618
|
+
const otlpPath = args.otlpOut ? await writeOtlpFile(rows.flatMap((row) => row.spans), args.otlpOut) : void 0;
|
|
523
619
|
const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
524
620
|
const records = await Promise.all(rows.map(
|
|
525
621
|
(row) => buildPolicyEvidenceRecord(row.ref, row.spans, {
|
|
@@ -578,7 +674,7 @@ async function cmdExport(args) {
|
|
|
578
674
|
if (!args.input) throw new Error("export needs an input file; run `traces export --help` for examples");
|
|
579
675
|
const format = traceEvidenceFormat(args.format);
|
|
580
676
|
const attributes = await loadExportAttributes(args);
|
|
581
|
-
const outPath = args.out ?? args.
|
|
677
|
+
const outPath = args.out ?? args.otlpOut;
|
|
582
678
|
if (outPath) {
|
|
583
679
|
const result2 = await writeTraceEvidenceExportFile(args.input, outPath, { format, attributes });
|
|
584
680
|
console.log(
|
|
@@ -780,8 +876,20 @@ async function cmdInvestigate(args) {
|
|
|
780
876
|
}
|
|
781
877
|
assertAgenticAnalystsRan(args, result.agenticPerAnalyst);
|
|
782
878
|
}
|
|
879
|
+
function conformanceOptions(collected) {
|
|
880
|
+
return {
|
|
881
|
+
...collected.conformance ? { conformance: collected.conformance } : {},
|
|
882
|
+
...collected.conformanceSubject ? { conformanceSubject: collected.conformanceSubject } : {},
|
|
883
|
+
...collected.conformanceFiles ? { conformanceFiles: collected.conformanceFiles } : {},
|
|
884
|
+
...collected.conformanceSkipped ? { conformanceSkipped: collected.conformanceSkipped } : {},
|
|
885
|
+
...collected.conformanceIssues ? { conformanceIssues: collected.conformanceIssues } : {},
|
|
886
|
+
...collected.conformanceWithheld ? { conformanceWithheld: collected.conformanceWithheld } : {},
|
|
887
|
+
...collected.conformanceUnreadable ? { conformanceUnreadable: collected.conformanceUnreadable } : {}
|
|
888
|
+
};
|
|
889
|
+
}
|
|
783
890
|
async function investigate(args, options = {}) {
|
|
784
|
-
const
|
|
891
|
+
const collected = await collectSpans(args);
|
|
892
|
+
const { spans, harness, cwds, sources, workflow } = collected;
|
|
785
893
|
if (spans.length === 0) throw new Error("no spans found for the given selection");
|
|
786
894
|
const config = args.config !== void 0 || options.loadDefaultConfig !== false ? await loadTracesConfig(args.config) : void 0;
|
|
787
895
|
const analystModel = args.model ?? process.env.TRACES_ANALYST_MODEL ?? DEFAULT_ANALYST_MODEL;
|
|
@@ -796,14 +904,16 @@ async function investigate(args, options = {}) {
|
|
|
796
904
|
engine,
|
|
797
905
|
model: args.llm ? analystModel : args.model,
|
|
798
906
|
budgetUsd: args.budget,
|
|
799
|
-
otlpOutPath: args.
|
|
907
|
+
otlpOutPath: args.otlpOut,
|
|
800
908
|
externalAnalyzers: externalAnalyzersFromArgs(args),
|
|
801
909
|
analyzerPrompt: args.analyzerPrompt,
|
|
802
|
-
log: analystLog
|
|
910
|
+
log: analystLog,
|
|
911
|
+
...conformanceOptions(collected)
|
|
803
912
|
}, config));
|
|
804
913
|
}
|
|
805
914
|
async function cmdImprove(args) {
|
|
806
|
-
const
|
|
915
|
+
const collected = await collectSpans(args);
|
|
916
|
+
const { spans, harness, cwds, sources, workflow } = collected;
|
|
807
917
|
if (spans.length === 0) throw new Error("no spans found for the given selection");
|
|
808
918
|
const config = await loadTracesConfig(args.config);
|
|
809
919
|
const analystModel = args.model ?? process.env.TRACES_ANALYST_MODEL ?? DEFAULT_ANALYST_MODEL;
|
|
@@ -819,10 +929,11 @@ async function cmdImprove(args) {
|
|
|
819
929
|
engine,
|
|
820
930
|
model: args.llm ? analystModel : args.model,
|
|
821
931
|
budgetUsd: args.budget,
|
|
822
|
-
otlpOutPath: args.
|
|
932
|
+
otlpOutPath: args.otlpOut,
|
|
823
933
|
externalAnalyzers: externalAnalyzersFromArgs(args),
|
|
824
934
|
analyzerPrompt: args.analyzerPrompt,
|
|
825
|
-
log: analystLog
|
|
935
|
+
log: analystLog,
|
|
936
|
+
...conformanceOptions(collected)
|
|
826
937
|
}, config),
|
|
827
938
|
outDir: args.dir ?? args.out
|
|
828
939
|
});
|
|
@@ -890,12 +1001,13 @@ async function streamExplicitSession(args, extraAnalysts) {
|
|
|
890
1001
|
async function cmdStream(args) {
|
|
891
1002
|
const config = await loadTracesConfig(args.config);
|
|
892
1003
|
const preset = streamPreset(args);
|
|
893
|
-
|
|
894
|
-
|
|
1004
|
+
const source = args.otlp ?? args.input;
|
|
1005
|
+
if (source) {
|
|
1006
|
+
const { spans, harness } = args.otlp ? await collectOtlpSpans(args.otlp) : await collectImportedSpans(args);
|
|
895
1007
|
const ref = {
|
|
896
1008
|
harness,
|
|
897
|
-
sessionId: basename(
|
|
898
|
-
path: resolve(
|
|
1009
|
+
sessionId: basename(source),
|
|
1010
|
+
path: resolve(source),
|
|
899
1011
|
cwd: args.cwd ?? null,
|
|
900
1012
|
mtimeMs: Date.now()
|
|
901
1013
|
};
|
|
@@ -1034,7 +1146,7 @@ Window: since ${new Date(sinceMs).toISOString()}
|
|
|
1034
1146
|
return;
|
|
1035
1147
|
}
|
|
1036
1148
|
if (args.dryRun) {
|
|
1037
|
-
const res2 = await executeUpload(plan, { dryRun: true, otlpOut: args.
|
|
1149
|
+
const res2 = await executeUpload(plan, { dryRun: true, otlpOut: args.otlpOut, stripContent: args.noContent, redactor });
|
|
1038
1150
|
console.log(`dry run: ${candidates.length - res2.skippedSessions} session(s), ${totalRedactions} redaction(s). Redacted OTLP -> ${res2.otlpPath}`);
|
|
1039
1151
|
console.log("No upload performed. Set TANGLE_INGEST_URL / TANGLE_INGEST_API_KEY / TANGLE_TENANT_ID and drop --dry-run to send.");
|
|
1040
1152
|
return;
|
|
@@ -1097,21 +1209,74 @@ The command validates every native step, rejects annotation leakage, writes
|
|
|
1097
1209
|
<traj_id>.otlp.jsonl files, and records input and output SHA-256 hashes in
|
|
1098
1210
|
codetracebench-import.json. The output directory must not already exist.`);
|
|
1099
1211
|
}
|
|
1212
|
+
function usageValidate() {
|
|
1213
|
+
console.log(`traces validate: report what a trace can and cannot answer
|
|
1214
|
+
|
|
1215
|
+
Usage:
|
|
1216
|
+
traces validate <file.jsonl|dir> [--out conformance.md]
|
|
1217
|
+
|
|
1218
|
+
Reads OTLP-JSONL and prints the conformance report from
|
|
1219
|
+
@tangle-network/agent-trace-contract:
|
|
1220
|
+
|
|
1221
|
+
- findings by severity, each naming the CONSEQUENCE of the defect and the
|
|
1222
|
+
capabilities it blocks
|
|
1223
|
+
- the capability table: token-accounting, cost-attribution, tool-usage,
|
|
1224
|
+
loop-convergence, tree-comparison, steering-chain, latency-analysis \u2014
|
|
1225
|
+
available or not, with the trace's own reason
|
|
1226
|
+
- rows that could not be read at all, with the line and the reason
|
|
1227
|
+
|
|
1228
|
+
A directory reads the OTLP files under it, recursively \u2014 only the otlp/
|
|
1229
|
+
subdirectory when the producer made one. A run directory's raw event, stream and
|
|
1230
|
+
SDK logs are also *.jsonl; they are listed with what they actually hold, not read
|
|
1231
|
+
as several hundred broken spans. Identical re-declarations of a span across
|
|
1232
|
+
per-shot files are counted as repeats, not defects; only a repeat with DIFFERENT
|
|
1233
|
+
content is an error.
|
|
1234
|
+
|
|
1235
|
+
Exit code:
|
|
1236
|
+
0 no error findings, and at least one capability available (warnings mean
|
|
1237
|
+
thinner analysis, not wrong analysis)
|
|
1238
|
+
1 an error finding, or nothing analysable at all \u2014 an empty file, or one
|
|
1239
|
+
whose every line was unreadable, answers no question and is not a pass
|
|
1240
|
+
|
|
1241
|
+
Nothing is fixed up: a span with an unreadable timestamp is reported, never
|
|
1242
|
+
repaired, because a synthesized value puts invented work into a total.
|
|
1243
|
+
|
|
1244
|
+
Examples:
|
|
1245
|
+
traces validate spans.otlp.jsonl
|
|
1246
|
+
traces validate results/sessions --out conformance.md
|
|
1247
|
+
traces validate spans.otlp.jsonl && traces analyze --otlp spans.otlp.jsonl`);
|
|
1248
|
+
}
|
|
1100
1249
|
function usage() {
|
|
1101
|
-
console.log(`traces: analyze
|
|
1250
|
+
console.log(`traces: analyze agent traces \u2014 yours, or any system's
|
|
1251
|
+
|
|
1252
|
+
Two ways in:
|
|
1253
|
+
--otlp <file|dir> Spans a system already emitted in the
|
|
1254
|
+
@tangle-network/agent-trace-contract shape. No adapter, no
|
|
1255
|
+
translation. This is how you integrate a NEW system.
|
|
1256
|
+
--harness <id> Run an adapter over a coding agent's proprietary session
|
|
1257
|
+
store (Claude Code, Codex, OpenCode, \u2026) \u2014 the legacy edge,
|
|
1258
|
+
for formats we do not control.
|
|
1102
1259
|
|
|
1103
1260
|
Commands:
|
|
1261
|
+
validate Report what a trace can and cannot answer (exit 1 on error findings)
|
|
1104
1262
|
list List discovered sessions
|
|
1105
|
-
analyze Run analyst suite + loop/waste pipelines over
|
|
1263
|
+
analyze Run analyst suite + loop/waste pipelines over OTLP (--otlp), sessions,
|
|
1264
|
+
or an input file; names every analysis the spans could not support
|
|
1106
1265
|
(--supervisor-run-dir <dir> reports a supervision tree instead)
|
|
1107
1266
|
investigate Run typed investigation flow, including BYO config + evidence-backed actions
|
|
1108
1267
|
improve Write findings, evidence, report, and canonical trace artifacts
|
|
1109
|
-
convert Emit OTLP-JSONL only (HALO: use analyze --analyzer halo)
|
|
1268
|
+
convert Emit OTLP-JSONL only, to --otlp-out (HALO: use analyze --analyzer halo)
|
|
1110
1269
|
index Emit a reusable session index JSON for later investigation
|
|
1111
1270
|
inspect Read a session index and print ranked improvement findings
|
|
1112
1271
|
export Convert evidence/events files to OpenInference JSONL for HALO
|
|
1113
1272
|
import-codetracebench
|
|
1114
1273
|
Convert CodeTracer-normalized CodeTraceBench trajectories in bulk
|
|
1274
|
+
replay-verify
|
|
1275
|
+
Replay a trajectory prefix in a sandbox, execute step k both recorded
|
|
1276
|
+
and corrected, and emit an executed-proof verdict (--help for flags)
|
|
1277
|
+
replay-verify-batch
|
|
1278
|
+
Measure replayability + fix-flip rates across gold-labeled corpora:
|
|
1279
|
+
arm A per replayable case, LLM-generated arm-B fixes (--help for flags)
|
|
1115
1280
|
evidence Emit compact session-evidence JSONL for downstream policy miners
|
|
1116
1281
|
stream Emit JSONL trace stream events for live visualizers or replay
|
|
1117
1282
|
watch Online observer: tail active sessions, notify on loops + semantic findings
|
|
@@ -1138,7 +1303,15 @@ Options:
|
|
|
1138
1303
|
--since <t> upload: window, 30m / 2h / 7d or an ISO date (default 24h); analyze: ISO cutoff
|
|
1139
1304
|
--out <path> Write report to a file
|
|
1140
1305
|
--dir <path> improve: write artifacts to this directory
|
|
1141
|
-
--otlp <
|
|
1306
|
+
--otlp <file|dir> READ OTLP-JSONL emitted by any system, skipping the adapters.
|
|
1307
|
+
A directory reads the OTLP files under it \u2014 only the otlp/
|
|
1308
|
+
subdirectory when the producer made one \u2014 and names the JSONL
|
|
1309
|
+
that is not OTLP instead of reading it as broken spans.
|
|
1310
|
+
Supported by: validate, analyze, investigate, improve, stream.
|
|
1311
|
+
On a WRITING command it is the deprecated spelling of
|
|
1312
|
+
--otlp-out; it still works, with a warning, until 0.12.
|
|
1313
|
+
--otlp-out <path> WRITE the OTLP-JSONL artifact here (also evidence
|
|
1314
|
+
provenance / dry-run upload preview)
|
|
1142
1315
|
--format <kind> analyze/export: auto | policy-evidence | sandbox-events | openinference | intelligence-spans | chat-trajectory
|
|
1143
1316
|
--metadata <json> analyze/export file: attach JSON object fields as span attributes
|
|
1144
1317
|
--attr <k=v> analyze/export file: attach one span attribute (repeatable)
|
|
@@ -1166,7 +1339,8 @@ Options:
|
|
|
1166
1339
|
--redactor <cmd> upload: external PII scrubber (JSON array stdin\u2192stdout) after the regex pass
|
|
1167
1340
|
--yes, -y upload: skip the confirmation prompt
|
|
1168
1341
|
--version, -v Print the installed traces version
|
|
1169
|
-
--help, -h Show help (use \`traces
|
|
1342
|
+
--help, -h Show help (use \`traces validate --help\`, \`traces export --help\`,
|
|
1343
|
+
or \`traces import-codetracebench --help\`)
|
|
1170
1344
|
|
|
1171
1345
|
Watch a run tree (any depth; driver spend and child spend stay separate,
|
|
1172
1346
|
and a cost the harness never priced reads "unknown", never $0):
|
|
@@ -1183,18 +1357,28 @@ async function main() {
|
|
|
1183
1357
|
console.log(`traces ${packageVersion()}`);
|
|
1184
1358
|
return;
|
|
1185
1359
|
}
|
|
1360
|
+
if (rawArgs[0] === "replay-verify") {
|
|
1361
|
+
await cmdReplayVerify(rawArgs.slice(1));
|
|
1362
|
+
return;
|
|
1363
|
+
}
|
|
1364
|
+
if (rawArgs[0] === "replay-verify-batch") {
|
|
1365
|
+
await cmdReplayVerifyBatch(rawArgs.slice(1));
|
|
1366
|
+
return;
|
|
1367
|
+
}
|
|
1186
1368
|
const parsedArgs = parseArgs(rawArgs);
|
|
1187
1369
|
if (parsedArgs.help) {
|
|
1188
1370
|
if (parsedArgs.command === "import-codetracebench" || parsedArgs.command === "help" && parsedArgs.input === "import-codetracebench") usageImportCodeTraceBench();
|
|
1189
1371
|
else if (parsedArgs.command === "export" || parsedArgs.command === "help" && parsedArgs.input === "export") usageExport();
|
|
1372
|
+
else if (parsedArgs.command === "validate" || parsedArgs.command === "help" && parsedArgs.input === "validate") usageValidate();
|
|
1190
1373
|
else usage();
|
|
1191
1374
|
return;
|
|
1192
1375
|
}
|
|
1193
|
-
const args = validateWorkflowSelection(applyCurrentSessionSelection(parsedArgs));
|
|
1376
|
+
const args = validateOtlpSelection(validateWorkflowSelection(applyCurrentSessionSelection(parsedArgs)));
|
|
1194
1377
|
switch (args.command) {
|
|
1195
1378
|
case "help":
|
|
1196
1379
|
if (args.input === "import-codetracebench") usageImportCodeTraceBench();
|
|
1197
1380
|
else if (args.input === "export") usageExport();
|
|
1381
|
+
else if (args.input === "validate") usageValidate();
|
|
1198
1382
|
else usage();
|
|
1199
1383
|
break;
|
|
1200
1384
|
case "list":
|
|
@@ -1203,6 +1387,9 @@ async function main() {
|
|
|
1203
1387
|
case "analyze":
|
|
1204
1388
|
await cmdAnalyze(args);
|
|
1205
1389
|
break;
|
|
1390
|
+
case "validate":
|
|
1391
|
+
await cmdValidate(args);
|
|
1392
|
+
break;
|
|
1206
1393
|
case "investigate":
|
|
1207
1394
|
await cmdInvestigate(args);
|
|
1208
1395
|
break;
|