@neatlogs/claude-code 0.1.0 → 0.1.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 ADDED
@@ -0,0 +1,58 @@
1
+ # @neatlogs/claude-code
2
+
3
+ Automatic observability for Claude Code sessions. Captures prompts, tool calls, thinking, and LLM responses as traces in Neatlogs via Claude Code hooks.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install -g @neatlogs/claude-code
9
+ ```
10
+
11
+ ## Setup
12
+
13
+ ```bash
14
+ neatlogs-claude-code setup --global --api-key YOUR_PROJECT_KEY
15
+ ```
16
+
17
+ This does two things:
18
+ 1. Saves your API key to `~/.config/neatlogs/config.json`
19
+ 2. Registers hooks in `~/.claude/settings.json` for all Claude Code lifecycle events
20
+
21
+ That's it. Restart Claude Code and all sessions are automatically traced.
22
+
23
+ ## What gets captured
24
+
25
+ Each Claude Code session produces a trace with:
26
+
27
+ - **Workflow span** — root span for the session
28
+ - **Turn spans** — one per user prompt (named with truncated prompt text)
29
+ - **Tool call spans** — Read, Edit, Bash, etc. with inputs, outputs, and duration
30
+ - **LLM spans** — model responses with token counts and thinking content
31
+ - **Subagent spans** — spawned agent work
32
+
33
+ ## Commands
34
+
35
+ ```bash
36
+ neatlogs-claude-code setup [--global|--project] [--api-key KEY] # Register hooks
37
+ neatlogs-claude-code hook # Process hook event (called by Claude Code)
38
+ neatlogs-claude-code --version # Print version
39
+ ```
40
+
41
+ ## Troubleshooting
42
+
43
+ **Hooks not firing:** Restart Claude Code after running setup.
44
+
45
+ **Permission error on install:** If you get EACCES, either use `nvm` (which handles permissions automatically) or configure npm to use a user-writable directory:
46
+ ```bash
47
+ npm config set prefix ~/.npm-global
48
+ echo 'export PATH="$HOME/.npm-global/bin:$PATH"' >> ~/.zshrc
49
+ source ~/.zshrc
50
+ ```
51
+
52
+ ## Uninstall
53
+
54
+ ```bash
55
+ npm uninstall -g @neatlogs/claude-code
56
+ ```
57
+
58
+ Hooks remain in `~/.claude/settings.json` but will be no-ops since the binary is gone. To clean them up, remove the `neatlogs-claude-code` entries from that file.
package/dist/cli.js CHANGED
@@ -518,6 +518,7 @@ function ensureSessionTrace(payload, config, shipper) {
518
518
  attrString("neatlogs.user_id", config.userId),
519
519
  attrString("neatlogs.session_id", payload.session_id),
520
520
  attrString("neatlogs.workflow_name", workflowName),
521
+ attrString("neatlogs.llm.effort_level", payload.effort?.level),
521
522
  attrString("neatlogs.input.value", payload.prompt),
522
523
  attrString("cwd", payload.cwd),
523
524
  { key: "neatlogs.sdk.name", value: { stringValue: PACKAGE_NAME } },
@@ -621,6 +622,7 @@ function handleUserPromptSubmit(payload, config, shipper) {
621
622
  endTimeUnixNano: now,
622
623
  attributes: [
623
624
  { key: "neatlogs.span.kind", value: { stringValue: "CHAIN" } },
625
+ attrString("neatlogs.llm.effort_level", payload.effort?.level),
624
626
  attrString("neatlogs.input.value", payload.prompt),
625
627
  attrString("cwd", payload.cwd)
626
628
  ].filter((a) => a !== void 0)
@@ -652,13 +654,11 @@ function handlePostToolUse(payload, config, shipper, error) {
652
654
  error ? { code: SpanStatusCode.ERROR, message: error } : void 0
653
655
  );
654
656
  shipper.enqueue(span);
655
- if (payload.permission_mode === "plan") {
656
- const sessionCtx = getSessionTrace(payload.session_id);
657
- if (sessionCtx) {
658
- const markerNow = nowNanoString();
659
- const marker = createSpan("neatlogs.trace.complete", sessionCtx, markerNow, markerNow, []);
660
- shipper.enqueue(marker);
661
- }
657
+ const sessionCtx = getSessionTrace(payload.session_id);
658
+ if (sessionCtx) {
659
+ const markerNow = nowNanoString();
660
+ const marker = createSpan("neatlogs.trace.complete", sessionCtx, markerNow, markerNow, []);
661
+ shipper.enqueue(marker);
662
662
  }
663
663
  }
664
664
  function handleSubagentStart(payload, config, shipper) {
package/dist/index.cjs CHANGED
@@ -599,6 +599,7 @@ function ensureSessionTrace(payload, config, shipper) {
599
599
  attrString("neatlogs.user_id", config.userId),
600
600
  attrString("neatlogs.session_id", payload.session_id),
601
601
  attrString("neatlogs.workflow_name", workflowName),
602
+ attrString("neatlogs.llm.effort_level", payload.effort?.level),
602
603
  attrString("neatlogs.input.value", payload.prompt),
603
604
  attrString("cwd", payload.cwd),
604
605
  { key: "neatlogs.sdk.name", value: { stringValue: PACKAGE_NAME } },
@@ -702,6 +703,7 @@ function handleUserPromptSubmit(payload, config, shipper) {
702
703
  endTimeUnixNano: now,
703
704
  attributes: [
704
705
  { key: "neatlogs.span.kind", value: { stringValue: "CHAIN" } },
706
+ attrString("neatlogs.llm.effort_level", payload.effort?.level),
705
707
  attrString("neatlogs.input.value", payload.prompt),
706
708
  attrString("cwd", payload.cwd)
707
709
  ].filter((a) => a !== void 0)
@@ -733,13 +735,11 @@ function handlePostToolUse(payload, config, shipper, error) {
733
735
  error ? { code: SpanStatusCode.ERROR, message: error } : void 0
734
736
  );
735
737
  shipper.enqueue(span);
736
- if (payload.permission_mode === "plan") {
737
- const sessionCtx = getSessionTrace(payload.session_id);
738
- if (sessionCtx) {
739
- const markerNow = nowNanoString();
740
- const marker = createSpan("neatlogs.trace.complete", sessionCtx, markerNow, markerNow, []);
741
- shipper.enqueue(marker);
742
- }
738
+ const sessionCtx = getSessionTrace(payload.session_id);
739
+ if (sessionCtx) {
740
+ const markerNow = nowNanoString();
741
+ const marker = createSpan("neatlogs.trace.complete", sessionCtx, markerNow, markerNow, []);
742
+ shipper.enqueue(marker);
743
743
  }
744
744
  }
745
745
  function handleSubagentStart(payload, config, shipper) {
package/dist/index.d.cts CHANGED
@@ -31,6 +31,9 @@ interface HookPayload {
31
31
  tool_response?: unknown;
32
32
  duration_ms?: number;
33
33
  tool_use_id?: string;
34
+ effort?: {
35
+ level?: string;
36
+ };
34
37
  error?: string;
35
38
  is_interrupt?: boolean;
36
39
  last_assistant_message?: string;
package/dist/index.d.ts CHANGED
@@ -31,6 +31,9 @@ interface HookPayload {
31
31
  tool_response?: unknown;
32
32
  duration_ms?: number;
33
33
  tool_use_id?: string;
34
+ effort?: {
35
+ level?: string;
36
+ };
34
37
  error?: string;
35
38
  is_interrupt?: boolean;
36
39
  last_assistant_message?: string;
package/dist/index.js CHANGED
@@ -559,6 +559,7 @@ function ensureSessionTrace(payload, config, shipper) {
559
559
  attrString("neatlogs.user_id", config.userId),
560
560
  attrString("neatlogs.session_id", payload.session_id),
561
561
  attrString("neatlogs.workflow_name", workflowName),
562
+ attrString("neatlogs.llm.effort_level", payload.effort?.level),
562
563
  attrString("neatlogs.input.value", payload.prompt),
563
564
  attrString("cwd", payload.cwd),
564
565
  { key: "neatlogs.sdk.name", value: { stringValue: PACKAGE_NAME } },
@@ -662,6 +663,7 @@ function handleUserPromptSubmit(payload, config, shipper) {
662
663
  endTimeUnixNano: now,
663
664
  attributes: [
664
665
  { key: "neatlogs.span.kind", value: { stringValue: "CHAIN" } },
666
+ attrString("neatlogs.llm.effort_level", payload.effort?.level),
665
667
  attrString("neatlogs.input.value", payload.prompt),
666
668
  attrString("cwd", payload.cwd)
667
669
  ].filter((a) => a !== void 0)
@@ -693,13 +695,11 @@ function handlePostToolUse(payload, config, shipper, error) {
693
695
  error ? { code: SpanStatusCode.ERROR, message: error } : void 0
694
696
  );
695
697
  shipper.enqueue(span);
696
- if (payload.permission_mode === "plan") {
697
- const sessionCtx = getSessionTrace(payload.session_id);
698
- if (sessionCtx) {
699
- const markerNow = nowNanoString();
700
- const marker = createSpan("neatlogs.trace.complete", sessionCtx, markerNow, markerNow, []);
701
- shipper.enqueue(marker);
702
- }
698
+ const sessionCtx = getSessionTrace(payload.session_id);
699
+ if (sessionCtx) {
700
+ const markerNow = nowNanoString();
701
+ const marker = createSpan("neatlogs.trace.complete", sessionCtx, markerNow, markerNow, []);
702
+ shipper.enqueue(marker);
703
703
  }
704
704
  }
705
705
  function handleSubagentStart(payload, config, shipper) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neatlogs/claude-code",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Neatlogs observability for Claude Code sessions — automatic tracing of prompts, tool calls, thinking, and LLM responses via hooks",
5
5
  "license": "MIT",
6
6
  "type": "module",