@tangle-network/traces 0.8.11 → 0.8.13
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 +7 -3
- package/dist/cli.js +46 -4
- package/install.sh +102 -0
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -28,9 +28,12 @@ It reads the transcripts your harness leaves on disk, reconstructs the run as sp
|
|
|
28
28
|
## Install
|
|
29
29
|
|
|
30
30
|
```bash
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
curl -fsSL https://raw.githubusercontent.com/tangle-network/traces/main/install.sh | bash
|
|
32
|
+
traces --version
|
|
33
|
+
|
|
34
|
+
npx --yes @tangle-network/traces@latest analyze --harness claude-code --last 1 # run without installing
|
|
35
|
+
npm i -g @tangle-network/traces # install manually
|
|
36
|
+
npm i @tangle-network/traces # use it as a library
|
|
34
37
|
```
|
|
35
38
|
|
|
36
39
|
Requires Node ≥ 22.
|
|
@@ -227,6 +230,7 @@ Merging to `main` publishes a patch release automatically:
|
|
|
227
230
|
2. It commits `chore(release): vX.Y.(Z+1) [skip release]` back to `main`.
|
|
228
231
|
3. It pushes the matching `vX.Y.(Z+1)` tag.
|
|
229
232
|
4. The same workflow verifies the tag, builds, publishes to npm, and creates a GitHub release.
|
|
233
|
+
5. `pnpm check:package` proves the npm tarball contains the `traces` binary before release.
|
|
230
234
|
|
|
231
235
|
Minor releases are manual. Run the Publish workflow from GitHub Actions and choose `minor`; it publishes `X.(Y+1).0`. Use manual `patch` only when you need a patch release without merging a new code change.
|
|
232
236
|
|
package/dist/cli.js
CHANGED
|
@@ -33,6 +33,7 @@ import {
|
|
|
33
33
|
} from "./chunk-PRRWLKSI.js";
|
|
34
34
|
|
|
35
35
|
// src/cli.ts
|
|
36
|
+
import { readFileSync } from "fs";
|
|
36
37
|
import { readFile, stat, writeFile } from "fs/promises";
|
|
37
38
|
|
|
38
39
|
// src/report.ts
|
|
@@ -44,15 +45,40 @@ var SEVERITY_BADGE = {
|
|
|
44
45
|
low: "\u{1F535} LOW",
|
|
45
46
|
info: "\u2139\uFE0F INFO"
|
|
46
47
|
};
|
|
48
|
+
function deterministicSummaryText(summary) {
|
|
49
|
+
const parts = [];
|
|
50
|
+
if (summary.stuckLoops > 0) parts.push(`${summary.stuckLoops} stuck loop(s)`);
|
|
51
|
+
if (summary.reactionSignals > 0) parts.push(`${summary.reactionSignals} human reaction signal(s)`);
|
|
52
|
+
if (summary.toolErrorRuns > 0) parts.push(`${summary.toolErrorRuns} tool-error run(s)`);
|
|
53
|
+
if (parts.length === 0) return "0 deterministic signals";
|
|
54
|
+
if (parts.length === 1) return parts[0];
|
|
55
|
+
return `${parts.slice(0, -1).join(", ")} and ${parts[parts.length - 1]}`;
|
|
56
|
+
}
|
|
57
|
+
function plural(count, singular, pluralForm = `${singular}s`) {
|
|
58
|
+
return count === 1 ? singular : pluralForm;
|
|
59
|
+
}
|
|
60
|
+
function summarizeDeterministicSignals(pipelines, reactions) {
|
|
61
|
+
const stuckLoops = pipelines.stuckLoops.findings.length;
|
|
62
|
+
const reactionSignals = Object.values(reactions.signals).reduce((total, count) => total + count, 0);
|
|
63
|
+
const toolErrorRuns = pipelines.toolUse.filter((run) => run.errorRate > 0).length;
|
|
64
|
+
return {
|
|
65
|
+
stuckLoops,
|
|
66
|
+
reactionSignals,
|
|
67
|
+
toolErrorRuns,
|
|
68
|
+
totalSignals: stuckLoops + reactionSignals + toolErrorRuns
|
|
69
|
+
};
|
|
70
|
+
}
|
|
47
71
|
function renderReport(result, meta) {
|
|
48
72
|
const lines = [];
|
|
49
73
|
const findings = [...result.findings].sort(
|
|
50
74
|
(a, b) => (SEVERITY_RANK[a.severity] ?? 9) - (SEVERITY_RANK[b.severity] ?? 9)
|
|
51
75
|
);
|
|
76
|
+
const deterministic = meta.deterministic ?? { stuckLoops: 0, reactionSignals: 0, toolErrorRuns: 0, totalSignals: 0 };
|
|
77
|
+
const findingSummary = deterministic.totalSignals > 0 ? `${findings.length} analyst ${plural(findings.length, "finding")} + ${deterministic.totalSignals} deterministic ${plural(deterministic.totalSignals, "signal")}` : `${findings.length} ${plural(findings.length, "finding")}`;
|
|
52
78
|
lines.push(`# Trace analysis \u2014 ${meta.harness}`);
|
|
53
79
|
lines.push("");
|
|
54
80
|
lines.push(
|
|
55
|
-
`${meta.sessionCount} session(s), ${meta.spanCount} spans \u2192 **${
|
|
81
|
+
`${meta.sessionCount} session(s), ${meta.spanCount} spans \u2192 **${findingSummary}** across ${result.per_analyst.length} analyst(s). Cost: $${result.total_cost_usd.toFixed(4)}.`
|
|
56
82
|
);
|
|
57
83
|
lines.push("");
|
|
58
84
|
lines.push("| Analyst | Status | Findings | Latency |");
|
|
@@ -61,8 +87,12 @@ function renderReport(result, meta) {
|
|
|
61
87
|
lines.push(`| \`${s.analyst_id}\` | ${s.status} | ${s.findings_count} | ${s.latency_ms}ms |`);
|
|
62
88
|
}
|
|
63
89
|
lines.push("");
|
|
64
|
-
if (findings.length === 0) {
|
|
90
|
+
if (findings.length === 0 && deterministic.totalSignals === 0) {
|
|
65
91
|
lines.push("_No findings \u2014 no behavioral inefficiencies or failure modes detected._");
|
|
92
|
+
} else if (findings.length === 0) {
|
|
93
|
+
lines.push(
|
|
94
|
+
`_No analyst findings. Deterministic checks found ${deterministicSummaryText(deterministic)}; see sections below._`
|
|
95
|
+
);
|
|
66
96
|
} else {
|
|
67
97
|
const byArea = /* @__PURE__ */ new Map();
|
|
68
98
|
for (const f of findings) {
|
|
@@ -194,6 +224,11 @@ function renderAdoption(ar) {
|
|
|
194
224
|
}
|
|
195
225
|
|
|
196
226
|
// src/cli.ts
|
|
227
|
+
function packageVersion() {
|
|
228
|
+
const pkg = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
|
|
229
|
+
if (typeof pkg.version !== "string" || !pkg.version) throw new Error("package.json is missing version");
|
|
230
|
+
return pkg.version;
|
|
231
|
+
}
|
|
197
232
|
function parseArgs(argv) {
|
|
198
233
|
const a = {
|
|
199
234
|
command: argv[0] === "--help" || argv[0] === "-h" ? "help" : argv[0] ?? "help",
|
|
@@ -520,7 +555,8 @@ async function cmdAnalyze(args) {
|
|
|
520
555
|
const pipelines = await runPipelines(spans, { minLoopOccurrences: args.minLoop });
|
|
521
556
|
const reactions = analyzeReactions(spans);
|
|
522
557
|
const adoption = await analyzeAdoption(spans, { cwds });
|
|
523
|
-
|
|
558
|
+
const deterministic = summarizeDeterministicSignals(pipelines, reactions);
|
|
559
|
+
let report = `${renderReport(result, { harness, sessionCount, spanCount: spans.length, otlpPath, deterministic })}
|
|
524
560
|
${renderPipelines(pipelines)}
|
|
525
561
|
${renderReactions(reactions)}
|
|
526
562
|
${renderAdoption(adoption)}`;
|
|
@@ -688,12 +724,18 @@ Options:
|
|
|
688
724
|
--no-content upload: strip prompt/response text \u2014 send metadata only
|
|
689
725
|
--redactor <cmd> upload: external PII scrubber (JSON array stdin\u2192stdout) after the regex pass
|
|
690
726
|
--yes, -y upload: skip the confirmation prompt
|
|
727
|
+
--version, -v Print the installed traces version
|
|
691
728
|
--help, -h Show help (use \`traces export --help\` for export examples)
|
|
692
729
|
|
|
693
730
|
Upload env: TANGLE_INGEST_URL (or TANGLE_ORCHESTRATOR_URL), TANGLE_INGEST_API_KEY (or TANGLE_API_KEY), TANGLE_TENANT_ID`);
|
|
694
731
|
}
|
|
695
732
|
async function main() {
|
|
696
|
-
const
|
|
733
|
+
const rawArgs = process.argv.slice(2);
|
|
734
|
+
if (rawArgs[0] === "--version" || rawArgs[0] === "-v" || rawArgs[0] === "version") {
|
|
735
|
+
console.log(`traces ${packageVersion()}`);
|
|
736
|
+
return;
|
|
737
|
+
}
|
|
738
|
+
const args = parseArgs(rawArgs);
|
|
697
739
|
if (args.help) {
|
|
698
740
|
if (args.command === "export" || args.command === "help" && args.input === "export") usageExport();
|
|
699
741
|
else usage();
|
package/install.sh
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
PACKAGE="@tangle-network/traces"
|
|
5
|
+
VERSION="${TRACES_VERSION:-latest}"
|
|
6
|
+
PREFIX="${TRACES_PREFIX:-}"
|
|
7
|
+
|
|
8
|
+
usage() {
|
|
9
|
+
cat <<'USAGE'
|
|
10
|
+
Install the traces CLI from npm.
|
|
11
|
+
|
|
12
|
+
Usage:
|
|
13
|
+
curl -fsSL https://raw.githubusercontent.com/tangle-network/traces/main/install.sh | bash
|
|
14
|
+
./install.sh [--version <version>] [--prefix <dir>]
|
|
15
|
+
|
|
16
|
+
Environment:
|
|
17
|
+
TRACES_VERSION npm version or tag to install (default: latest)
|
|
18
|
+
TRACES_PREFIX npm global prefix to use when the default is not writable
|
|
19
|
+
USAGE
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
while [ "$#" -gt 0 ]; do
|
|
23
|
+
case "$1" in
|
|
24
|
+
--version)
|
|
25
|
+
[ "${2:-}" ] || { echo "missing value for --version" >&2; exit 2; }
|
|
26
|
+
VERSION="$2"
|
|
27
|
+
shift 2
|
|
28
|
+
;;
|
|
29
|
+
--prefix)
|
|
30
|
+
[ "${2:-}" ] || { echo "missing value for --prefix" >&2; exit 2; }
|
|
31
|
+
PREFIX="$2"
|
|
32
|
+
shift 2
|
|
33
|
+
;;
|
|
34
|
+
-h|--help)
|
|
35
|
+
usage
|
|
36
|
+
exit 0
|
|
37
|
+
;;
|
|
38
|
+
*)
|
|
39
|
+
echo "unknown argument: $1" >&2
|
|
40
|
+
usage >&2
|
|
41
|
+
exit 2
|
|
42
|
+
;;
|
|
43
|
+
esac
|
|
44
|
+
done
|
|
45
|
+
|
|
46
|
+
if ! command -v node >/dev/null 2>&1; then
|
|
47
|
+
echo "Node.js >=22 is required before installing traces." >&2
|
|
48
|
+
exit 1
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
node_version="$(node -e "process.stdout.write(process.versions.node)")"
|
|
52
|
+
node_major="${node_version%%.*}"
|
|
53
|
+
if [ "$node_major" -lt 22 ]; then
|
|
54
|
+
echo "Node.js >=22 is required; found v$node_version." >&2
|
|
55
|
+
exit 1
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
if ! command -v npm >/dev/null 2>&1; then
|
|
59
|
+
echo "npm is required before installing traces." >&2
|
|
60
|
+
exit 1
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
install_args=(install -g "${PACKAGE}@${VERSION}")
|
|
64
|
+
npm_prefix="$(npm prefix -g)"
|
|
65
|
+
install_prefix="$npm_prefix"
|
|
66
|
+
|
|
67
|
+
if [ -n "$PREFIX" ]; then
|
|
68
|
+
mkdir -p "$PREFIX"
|
|
69
|
+
install_args+=(--prefix "$PREFIX")
|
|
70
|
+
install_prefix="$PREFIX"
|
|
71
|
+
else
|
|
72
|
+
if [ ! -w "$npm_prefix" ]; then
|
|
73
|
+
install_prefix="$HOME/.local"
|
|
74
|
+
mkdir -p "$install_prefix"
|
|
75
|
+
install_args+=(--prefix "$install_prefix")
|
|
76
|
+
echo "npm global prefix is not writable; installing into $install_prefix"
|
|
77
|
+
fi
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
npm "${install_args[@]}"
|
|
81
|
+
|
|
82
|
+
bin_dir="$install_prefix/bin"
|
|
83
|
+
if [ -x "$bin_dir/traces" ]; then
|
|
84
|
+
traces_cmd="$bin_dir/traces"
|
|
85
|
+
elif command -v traces >/dev/null 2>&1; then
|
|
86
|
+
traces_cmd="traces"
|
|
87
|
+
else
|
|
88
|
+
echo "Installed ${PACKAGE}@${VERSION}, but the traces binary was not found at $bin_dir/traces or on PATH." >&2
|
|
89
|
+
echo "Add this to PATH: $bin_dir" >&2
|
|
90
|
+
exit 1
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
version_output="$("$traces_cmd" --version 2>/dev/null || true)"
|
|
94
|
+
case "$version_output" in
|
|
95
|
+
traces\ [0-9]*.[0-9]*.[0-9]*) echo "$version_output" ;;
|
|
96
|
+
*) echo "traces installed: $traces_cmd" ;;
|
|
97
|
+
esac
|
|
98
|
+
case ":$PATH:" in
|
|
99
|
+
*":$bin_dir:"*) ;;
|
|
100
|
+
*) echo "Add this to PATH for future shells: $bin_dir" ;;
|
|
101
|
+
esac
|
|
102
|
+
echo "Run: traces analyze --harness claude-code --last 1"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/traces",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.13",
|
|
4
4
|
"description": "Point it at your coding-agent session traces (Claude Code, Codex, OpenCode, Gemini, Pi, …) and get failure-mode + efficiency findings. CLI + SDK over the @tangle-network/agent-eval analyst suite — observe live sessions, run your own analysts, redact, and upload to the Tangle Intelligence Platform.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
},
|
|
37
37
|
"files": [
|
|
38
38
|
"dist",
|
|
39
|
+
"install.sh",
|
|
39
40
|
"README.md"
|
|
40
41
|
],
|
|
41
42
|
"engines": {
|
|
@@ -56,6 +57,7 @@
|
|
|
56
57
|
"scripts": {
|
|
57
58
|
"dev": "tsx src/cli.ts",
|
|
58
59
|
"build": "tsup src/index.ts src/cli.ts --format esm --target node22 --clean --dts",
|
|
60
|
+
"check:package": "node scripts/check-package-bin.mjs",
|
|
59
61
|
"test": "vitest run",
|
|
60
62
|
"test:watch": "vitest",
|
|
61
63
|
"typecheck": "tsc --noEmit"
|