noctrace 1.0.0 → 1.2.0

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 CHANGED
@@ -88,6 +88,7 @@ Requires Node.js 20+. Optional `--install-hooks` flag enables real-time hook eve
88
88
  - **Agent Teams Panel** — detects running Agent Teams at `~/.claude/teams/`, shows members and task counts in a flyout
89
89
  - **Context Startup Flyout** — shows which instruction files (CLAUDE.md and others) loaded at session start with estimated token counts, parsed from JSONL system records
90
90
  - **Docker Support** — `npx noctrace --docker <container>` attaches to a running Docker container, injects a lightweight watcher, and streams JSONL events back to your host in real time. Zero container setup required
91
+ - **Patterns View (new in v1.2)** — a second top-level tab that aggregates across every session in the chosen time window (today, 7 days, 30 days). Three panels: health distribution (A/B/C/D/F grade counts with week-over-week delta arrows), project rot leaderboard (which codebases are degrading, ranked), and tool health grid (per-tool failure rate and p50/p95 latency). Zero spend or token tracking — this is about quality and waste
91
92
 
92
93
  ![Noctrace waterfall timeline](docs/screenshots/noctrace-waterfall.gif)
93
94
 
@@ -143,6 +144,7 @@ No config files. No cloud. Everything stays local. Optional hooks for richer rea
143
144
  | CLI Flag | Description |
144
145
  |----------|-------------|
145
146
  | `--docker <container>` | Attach to a running Docker container and stream its Claude Code sessions back to your host. Zero container setup |
147
+ | `--devcontainer <path>` | Resolve the running devcontainer for a local folder path and attach to it. Pass `.` for the current directory. Falls back to `--docker` if you pass a container name directly |
146
148
  | `--install-hooks` | Configure Claude Code to push real-time events to noctrace |
147
149
  | `--uninstall-hooks` | Remove noctrace hooks from Claude Code |
148
150
 
package/bin/noctrace.js CHANGED
@@ -197,14 +197,11 @@ if (args.includes('--disable')) {
197
197
  process.exit(0);
198
198
  }
199
199
 
200
- if (args.includes('--docker')) {
201
- const containerArg = args[args.indexOf('--docker') + 1];
202
- if (!containerArg || containerArg.startsWith('--')) {
203
- console.error('[noctrace] Usage: npx noctrace --docker <container-name-or-id>');
204
- console.error('[noctrace] Example: npx noctrace --docker my-claude-container');
205
- process.exit(1);
206
- }
207
-
200
+ /**
201
+ * Run Docker watcher mode with a known, already-validated container ID.
202
+ * Shared by --docker and --devcontainer.
203
+ */
204
+ async function runDockerMode(containerArg) {
208
205
  const {
209
206
  isValidContainerName,
210
207
  assertContainerRunning,
@@ -320,6 +317,44 @@ if (args.includes('--docker')) {
320
317
  await new Promise(() => {});
321
318
  }
322
319
 
320
+ if (args.includes('--docker')) {
321
+ const containerArg = args[args.indexOf('--docker') + 1];
322
+ if (!containerArg || containerArg.startsWith('--')) {
323
+ console.error('[noctrace] Usage: npx noctrace --docker <container-name-or-id>');
324
+ console.error('[noctrace] Example: npx noctrace --docker my-claude-container');
325
+ process.exit(1);
326
+ }
327
+ await runDockerMode(containerArg);
328
+ }
329
+
330
+ if (args.includes('--devcontainer')) {
331
+ const devcontainerArg = args[args.indexOf('--devcontainer') + 1];
332
+ if (!devcontainerArg || devcontainerArg.startsWith('--')) {
333
+ console.error('[noctrace] Usage: npx noctrace --devcontainer <path-or-container>');
334
+ console.error('[noctrace] Examples:');
335
+ console.error('[noctrace] npx noctrace --devcontainer .');
336
+ console.error('[noctrace] npx noctrace --devcontainer /Users/me/myproject');
337
+ console.error('[noctrace] npx noctrace --devcontainer my-devcontainer-id');
338
+ process.exit(1);
339
+ }
340
+
341
+ const { resolveDevcontainerContainer, defaultDockerRunner } =
342
+ await import('../dist/server/server/docker.js');
343
+
344
+ let resolvedContainer;
345
+ try {
346
+ resolvedContainer = resolveDevcontainerContainer(devcontainerArg, defaultDockerRunner);
347
+ } catch (err) {
348
+ const lines = err.message.split('\n');
349
+ for (const line of lines) {
350
+ console.error(`[noctrace] ${line}`);
351
+ }
352
+ process.exit(1);
353
+ }
354
+
355
+ await runDockerMode(resolvedContainer);
356
+ }
357
+
323
358
  if (args.includes('--mcp')) {
324
359
  // MCP mode: boot the Express server and speak JSON-RPC over stdio.
325
360
  // stdout is the JSON-RPC channel — all logging must go to stderr.