@faithfulalabi/agent-lens 0.4.0 → 0.4.1
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 +70 -8
- package/bin/agent-lens.js +2 -0
- package/dist/src/cli/commands/schedule.js +5 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -1,11 +1,31 @@
|
|
|
1
1
|
# agent-lens
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@faithfulalabi/agent-lens)
|
|
4
|
+
[](https://nodejs.org)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](https://github.com/faithfulalabi/agent-lens/actions/workflows/ci.yml)
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
**Read back everything a Claude Code session did — prompts, reasoning, tool calls, sub-agents,
|
|
9
|
+
inputs and outputs — in a local UI, long after the session ended.**
|
|
10
|
+
|
|
11
|
+
Claude Code expires its own transcripts. agent-lens keeps a verbatim copy of every session you have
|
|
12
|
+
ever run, on your machine, searchable after the source is gone. It reads the files the harness
|
|
13
|
+
already writes to disk: no account, no API key, and nothing added to your agent or your
|
|
14
|
+
application.
|
|
15
|
+
|
|
16
|
+

|
|
17
|
+
|
|
18
|
+
## Questions it answers
|
|
19
|
+
|
|
20
|
+
- **What did I actually ask for three weeks ago?** The archive still holds the session even once
|
|
21
|
+
Claude Code has expired its copy.
|
|
22
|
+
- **Where did that session go wrong?** Read the session back in order: every tool call, its real
|
|
23
|
+
input, its real output, where it happened.
|
|
24
|
+
- **What did the sub-agent do?** Open the `Agent` call and read the sub-agent's own transcript —
|
|
25
|
+
its reasoning, its tools, and what it reported back.
|
|
26
|
+
- **Which session touched this file?** Full-text search across prompts, tool payloads and output
|
|
27
|
+
too large to sit inline.
|
|
28
|
+
- **What is it costing?** Tokens and estimated cost, rolled up per session, per turn and per call.
|
|
9
29
|
|
|
10
30
|
## Quickstart
|
|
11
31
|
|
|
@@ -18,7 +38,48 @@ are there; new ones show up as they happen.
|
|
|
18
38
|
|
|
19
39
|
Requires Node.js `>=24`.
|
|
20
40
|
|
|
21
|
-
##
|
|
41
|
+
## A short tour
|
|
42
|
+
|
|
43
|
+
**Every call, with its real payload.** The session reads back as a conversation, with the tool calls
|
|
44
|
+
tucked into activity groups between the messages. Open one and it shows what actually went in and
|
|
45
|
+
what actually came back.
|
|
46
|
+
|
|
47
|
+

|
|
48
|
+
|
|
49
|
+
**Sub-agents keep their own transcript.** An `Agent` call links straight to the session the
|
|
50
|
+
sub-agent ran, with its own messages, its own tool calls and its own cost — and a way back to the
|
|
51
|
+
parent.
|
|
52
|
+
|
|
53
|
+

|
|
54
|
+
|
|
55
|
+
**Search reaches the payloads, not just the prompts.** Hits land on the event that carried them, and
|
|
56
|
+
the match is highlighted in place. The screen below is search scoped to one open session; search
|
|
57
|
+
across the whole archive is reached from the session list.
|
|
58
|
+
|
|
59
|
+

|
|
60
|
+
|
|
61
|
+
## How it compares
|
|
62
|
+
|
|
63
|
+
LangSmith, Langfuse and Arize Phoenix are tracing platforms for applications you are building, and
|
|
64
|
+
all three now also ship a Claude Code plugin. Each posture below was read from that tool's own
|
|
65
|
+
current documentation.
|
|
66
|
+
|
|
67
|
+
| Tool | What it needs from you | Where the data lives | What it reads |
|
|
68
|
+
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
|
69
|
+
| **LangSmith** | An account and an API key. Tracing comes from its SDK in your application, from OpenTelemetry, or from its Claude Code plugin. | LangChain's cloud by default. Self-hosted and BYOC are Enterprise-plan options. | Spans your application emits, or the turns its Claude Code plugin reports while a session runs. |
|
|
70
|
+
| **Langfuse** | An account — cloud or self-hosted — and a key pair. Tracing comes from its SDK, from OpenTelemetry, or from its Claude Code plugin. | Langfuse Cloud by default. Self-hosting is documented and open source. | Spans your application emits. Its Claude Code plugin reads each turn's transcript as that turn completes. |
|
|
71
|
+
| **Arize Phoenix** | A Phoenix instance to send to — the documented default is a local one, which needs no account. Tracing comes from OpenInference / OpenTelemetry, or from its Claude Code plugin. | Your own machine or infrastructure by default. | OpenTelemetry spans your application emits, or the turns its Claude Code plugin reports while a session runs. |
|
|
72
|
+
| **agent-lens** | One command. No account, no key, nothing added to your application or your agent. | Your machine only, under `~/.agent-lens`. | The transcript files Claude Code has already written to disk — including sessions that ran before agent-lens was ever on the machine. |
|
|
73
|
+
|
|
74
|
+
The last column is the difference. The other three observe a session as it happens, so the record
|
|
75
|
+
starts when you set them up. agent-lens reads what the harness already wrote, so the first run shows
|
|
76
|
+
you work you did before you had it — and keeps that work after Claude Code expires its own copy.
|
|
77
|
+
|
|
78
|
+
## What you keep — the durability contract
|
|
79
|
+
|
|
80
|
+
The reason to run this is the archive. Claude Code expires `~/.claude/projects` on its own
|
|
81
|
+
schedule; the archive is the copy that outlives it, and past that cliff it is the only copy there
|
|
82
|
+
is. Which makes the next part worth reading before you delete anything.
|
|
22
83
|
|
|
23
84
|
Three directories, three completely different promises.
|
|
24
85
|
|
|
@@ -128,8 +189,9 @@ people: on a shared machine, the agent being traced can read the trace API too.
|
|
|
128
189
|
|
|
129
190
|
## Contributing
|
|
130
191
|
|
|
131
|
-
See [CONTRIBUTING.md](CONTRIBUTING.md) for dev setup, the render loop against a real corpus,
|
|
132
|
-
one-door rule every change to
|
|
192
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for dev setup, the render loop against a real corpus, the
|
|
193
|
+
command that regenerates the screenshots on this page, and the one-door rule every change to
|
|
194
|
+
transcript reading has to satisfy.
|
|
133
195
|
|
|
134
196
|
## License
|
|
135
197
|
|
package/bin/agent-lens.js
CHANGED
|
@@ -32,6 +32,8 @@ if (!Number.isInteger(major) || major < MIN_NODE_MAJOR) {
|
|
|
32
32
|
process.exitCode = 1;
|
|
33
33
|
} else {
|
|
34
34
|
// Dynamic, so the guard above runs first — a static import would hoist past it.
|
|
35
|
+
// The generated archive wrapper guards an install on this specifier — keep
|
|
36
|
+
// BUILT_CLI_ENTRY in step with it.
|
|
35
37
|
const { main } = await import('../dist/src/cli/index.js');
|
|
36
38
|
// Setting the code and returning, rather than terminating the process here:
|
|
37
39
|
// the abrupt form truncates piped stdout mid-write. Exit codes 0/1/3 from
|
|
@@ -9,6 +9,7 @@ export const SCHEDULE_LABEL = 'com.agent-lens.archive';
|
|
|
9
9
|
export const LEGACY_LABEL = 'com.faithful.agent-lens.archive';
|
|
10
10
|
const START_INTERVAL_SECONDS = 900;
|
|
11
11
|
export const CRON_STAMP_FORMAT = '+%Y-%m-%dT%H:%M:%S%z';
|
|
12
|
+
export const BUILT_CLI_ENTRY = 'dist/src/cli/index.js';
|
|
12
13
|
export const WAKE_TIME_CAVEAT = 'a wall-clock schedule does not fire while the machine is asleep — treat the interval as a bound on wake time, not on elapsed time';
|
|
13
14
|
export const LINGER_CAVEAT = 'a systemd user timer does not run while you are logged out unless lingering is on for your user';
|
|
14
15
|
export const SYSTEMD_UNIT_BASE = 'agent-lens-archive';
|
|
@@ -93,6 +94,9 @@ export function buildWrapperScript(opts) {
|
|
|
93
94
|
const run = kind === 'source'
|
|
94
95
|
? '"$NODE" --import tsx "$ROOT/src/cli/index.ts" archive --dataDir "$DATA_DIR"'
|
|
95
96
|
: '"$NODE" "$ROOT/bin/agent-lens.js" archive --dataDir "$DATA_DIR"';
|
|
97
|
+
const requirement = kind === 'source'
|
|
98
|
+
? '[ -d "$ROOT/node_modules" ] || { say "FATAL node_modules missing — run npm install in $ROOT"; exit 1; }'
|
|
99
|
+
: `[ -f "$ROOT/${BUILT_CLI_ENTRY}" ] || { say "FATAL built CLI missing: $ROOT/${BUILT_CLI_ENTRY} — reinstall @faithfulalabi/agent-lens"; exit 1; }`;
|
|
96
100
|
return `#!/bin/sh
|
|
97
101
|
# agent-lens archive — unattended pass, invoked by the launchd agent
|
|
98
102
|
# ${SCHEDULE_LABEL} every ${START_INTERVAL_SECONDS / 60} minutes.
|
|
@@ -130,7 +134,7 @@ say() { printf '%s %s\\n' "$(stamp)" "$1" >>"$LOG"; }
|
|
|
130
134
|
[ -d "$ROOT" ] || { say "FATAL package root missing: $ROOT"; exit 1; }
|
|
131
135
|
[ -x "$NODE" ] || { say "FATAL node missing: $NODE"; exit 1; }
|
|
132
136
|
[ -e "${entry}" ] || { say "FATAL entry missing: ${entry}"; exit 1; }
|
|
133
|
-
|
|
137
|
+
${requirement}
|
|
134
138
|
|
|
135
139
|
cd "$ROOT" || { say "FATAL cannot cd to $ROOT"; exit 1; }
|
|
136
140
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@faithfulalabi/agent-lens",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Local-first agentic tracing platform: inspect everything your agent did in a session.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"dev": "tsx src/dev/server.ts",
|
|
39
39
|
"dev:ui": "npm --prefix ui run dev",
|
|
40
40
|
"render-gate": "tsx src/render-gate/index.ts",
|
|
41
|
+
"demo:capture": "node --import tsx scripts/capture-screenshots.mjs",
|
|
41
42
|
"test": "vitest run",
|
|
42
43
|
"typecheck": "tsc -p tsconfig.node.json --noEmit && npm --prefix ui run typecheck",
|
|
43
44
|
"build": "rm -rf dist && tsc -p tsconfig.build.json && npm --prefix ui run build",
|