@thehammer/danx-session-telemetry 0.1.1 → 0.1.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.
|
@@ -89,6 +89,28 @@ export interface SessionLogWatcherOptions {
|
|
|
89
89
|
* binds `<repo>/claude-projects/` at `/home/danxbot/.claude/projects/` and
|
|
90
90
|
* relies on the same encoding for the bound subdir name. Keep the encoding
|
|
91
91
|
* logic centralized here so both runtimes stay in lockstep.
|
|
92
|
+
*
|
|
93
|
+
* DX-3069 — Windows host-mode dispatches (this dev machine included, see
|
|
94
|
+
* `.claude/rules/agent-dispatch.md` "Host" runtime) pass an ALREADY-ABSOLUTE
|
|
95
|
+
* Windows cwd (`C:\Users\...`), which never starts with `/`. The prior
|
|
96
|
+
* `cwd.startsWith("/") ? cwd : "/" + cwd` unconditionally prepended `/`,
|
|
97
|
+
* producing a malformed path (`/C:\Users\...`) that `realpathSync` cannot
|
|
98
|
+
* resolve (ENOENT — Windows reads the leading `/C:` as its own root segment),
|
|
99
|
+
* so the code fell into the catch and kept that malformed string. The old
|
|
100
|
+
* regex (`/[/._]/g`) never touched `\` or `:`, so every backslash and the
|
|
101
|
+
* drive-letter colon survived verbatim into the "encoded" dir name, and
|
|
102
|
+
* `join(homedir(), ".claude", "projects", encoded)` then produced a NESTED,
|
|
103
|
+
* DOUBLED path — `C:\Users\...\.claude\projects\-C:\Users\...` — a directory
|
|
104
|
+
* Claude Code never writes to, so every host-mode watcher on Windows silently
|
|
105
|
+
* never found its own transcript. Verified empirically against a real Claude
|
|
106
|
+
* Code install on this machine: `C:\Users\newms\projects\danxbot` encodes on
|
|
107
|
+
* disk to `C--Users-newms-projects-danxbot` (`ls ~/.claude/projects`) — no
|
|
108
|
+
* leading dash, `:` and each `\` both become `-`, exactly like `/` and `.` do
|
|
109
|
+
* for a POSIX cwd. `isAbsolute` (platform-native — win32 on Windows, posix
|
|
110
|
+
* elsewhere) replaces the POSIX-only `startsWith("/")` check so an
|
|
111
|
+
* already-absolute Windows path is never re-prefixed, and the replacement
|
|
112
|
+
* regex now also covers `\` and `:` so no separator survives into the
|
|
113
|
+
* encoded name on either platform.
|
|
92
114
|
*/
|
|
93
115
|
export declare function encodeClaudeProjectsCwd(cwd: string): string;
|
|
94
116
|
/**
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
import { existsSync, realpathSync } from "node:fs";
|
|
24
24
|
import { open, readFile, readdir, stat } from "node:fs/promises";
|
|
25
25
|
import { homedir } from "node:os";
|
|
26
|
-
import { basename, dirname, join } from "node:path";
|
|
26
|
+
import { basename, dirname, isAbsolute, join } from "node:path";
|
|
27
27
|
import { createLogger } from "./internal-logger.js";
|
|
28
28
|
import { buildAssistantSummary, buildToolResultSummary, } from "./tool-summary.js";
|
|
29
29
|
const log = createLogger("session-log-watcher");
|
|
@@ -68,9 +68,31 @@ export const DISPATCH_TAG_PREFIX = "<!-- danxbot-dispatch:";
|
|
|
68
68
|
* binds `<repo>/claude-projects/` at `/home/danxbot/.claude/projects/` and
|
|
69
69
|
* relies on the same encoding for the bound subdir name. Keep the encoding
|
|
70
70
|
* logic centralized here so both runtimes stay in lockstep.
|
|
71
|
+
*
|
|
72
|
+
* DX-3069 — Windows host-mode dispatches (this dev machine included, see
|
|
73
|
+
* `.claude/rules/agent-dispatch.md` "Host" runtime) pass an ALREADY-ABSOLUTE
|
|
74
|
+
* Windows cwd (`C:\Users\...`), which never starts with `/`. The prior
|
|
75
|
+
* `cwd.startsWith("/") ? cwd : "/" + cwd` unconditionally prepended `/`,
|
|
76
|
+
* producing a malformed path (`/C:\Users\...`) that `realpathSync` cannot
|
|
77
|
+
* resolve (ENOENT — Windows reads the leading `/C:` as its own root segment),
|
|
78
|
+
* so the code fell into the catch and kept that malformed string. The old
|
|
79
|
+
* regex (`/[/._]/g`) never touched `\` or `:`, so every backslash and the
|
|
80
|
+
* drive-letter colon survived verbatim into the "encoded" dir name, and
|
|
81
|
+
* `join(homedir(), ".claude", "projects", encoded)` then produced a NESTED,
|
|
82
|
+
* DOUBLED path — `C:\Users\...\.claude\projects\-C:\Users\...` — a directory
|
|
83
|
+
* Claude Code never writes to, so every host-mode watcher on Windows silently
|
|
84
|
+
* never found its own transcript. Verified empirically against a real Claude
|
|
85
|
+
* Code install on this machine: `C:\Users\newms\projects\danxbot` encodes on
|
|
86
|
+
* disk to `C--Users-newms-projects-danxbot` (`ls ~/.claude/projects`) — no
|
|
87
|
+
* leading dash, `:` and each `\` both become `-`, exactly like `/` and `.` do
|
|
88
|
+
* for a POSIX cwd. `isAbsolute` (platform-native — win32 on Windows, posix
|
|
89
|
+
* elsewhere) replaces the POSIX-only `startsWith("/")` check so an
|
|
90
|
+
* already-absolute Windows path is never re-prefixed, and the replacement
|
|
91
|
+
* regex now also covers `\` and `:` so no separator survives into the
|
|
92
|
+
* encoded name on either platform.
|
|
71
93
|
*/
|
|
72
94
|
export function encodeClaudeProjectsCwd(cwd) {
|
|
73
|
-
const normalized = cwd
|
|
95
|
+
const normalized = isAbsolute(cwd) ? cwd : `/${cwd}`;
|
|
74
96
|
let resolved;
|
|
75
97
|
try {
|
|
76
98
|
resolved = realpathSync(normalized);
|
|
@@ -80,12 +102,13 @@ export function encodeClaudeProjectsCwd(cwd) {
|
|
|
80
102
|
resolved = normalized;
|
|
81
103
|
}
|
|
82
104
|
// Claude Code encodes its cwd into ~/.claude/projects/<dir> by replacing
|
|
83
|
-
// EVERY non-alphanumeric separator
|
|
84
|
-
//
|
|
85
|
-
//
|
|
86
|
-
//
|
|
87
|
-
//
|
|
88
|
-
|
|
105
|
+
// EVERY non-alphanumeric separator with `-`: `/`, `.`, and `_` on every
|
|
106
|
+
// platform, plus `\` and the drive-letter `:` on Windows. The `_` matters:
|
|
107
|
+
// the clean-room key (`cleanRoomKey`, DX-1511) joins its components with
|
|
108
|
+
// `__`, so Claude writes the dir as `--` on disk. Omitting `_` here made
|
|
109
|
+
// the watcher wait on a `__` path Claude never creates → "session file not
|
|
110
|
+
// found after 180s" on every clean-room dispatch.
|
|
111
|
+
return resolved.replace(/[/\\:._]/g, "-");
|
|
89
112
|
}
|
|
90
113
|
/**
|
|
91
114
|
* Derives the Claude Code session directory from a working directory path.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thehammer/danx-session-telemetry",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Shared Claude Code transcript collector (DX-2962) — incremental JSONL tailing for the danxbot worker and the danx-dashboard-mcp desktop bridge, so both run identical collector code.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -37,6 +37,6 @@
|
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@types/node": "^22.0.0",
|
|
39
39
|
"typescript": "^5.7.0",
|
|
40
|
-
"vitest": "^4.
|
|
40
|
+
"vitest": "^4.0.18"
|
|
41
41
|
}
|
|
42
42
|
}
|