@druumen/sessions-db 0.1.3 → 0.1.4
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/CHANGELOG.md +43 -0
- package/cli/sessions-db-session-start-main.mjs +50 -12
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,49 @@ All notable changes to `@druumen/sessions-db` will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.1.4] — 2026-05-16
|
|
9
|
+
|
|
10
|
+
Hook gate relaxation so marketplace cockpit users on non-druumen
|
|
11
|
+
workspaces can actually record sessions.
|
|
12
|
+
|
|
13
|
+
### Changed (hook)
|
|
14
|
+
|
|
15
|
+
- `cli/sessions-db-session-start-main.mjs` — the cwd-gate accepts a
|
|
16
|
+
workspace as authorized when EITHER:
|
|
17
|
+
1. a `CLAUDE.md` containing the `Druumen Workspace` sentinel exists
|
|
18
|
+
at cwd or any ancestor (original 0.1.x behavior), OR
|
|
19
|
+
2. `.dru-code/sessions-db.json` or `tickets/_logs/sessions-db.json`
|
|
20
|
+
exists at cwd or any ancestor — i.e. the workspace was already
|
|
21
|
+
opted in via cockpit's Setup Wizard or a manual `initProjection`.
|
|
22
|
+
Either marker counts as explicit user consent for this workspace.
|
|
23
|
+
Workspaces with neither still bail silently — random scratch dirs
|
|
24
|
+
still don't get session events.
|
|
25
|
+
|
|
26
|
+
### Why
|
|
27
|
+
|
|
28
|
+
Cockpit-vscode 0.3.0+ ships the Setup Wizard which creates
|
|
29
|
+
`<workspace>/.dru-code/sessions-db.json` on Enable. Before this fix,
|
|
30
|
+
the hook then rejected every SessionStart in that workspace because no
|
|
31
|
+
CLAUDE.md sentinel was present — events.jsonl stayed empty and the
|
|
32
|
+
SESSIONS panel showed `0 active` forever. The `.dru-code/` file
|
|
33
|
+
already represents user consent; the gate now treats it as such.
|
|
34
|
+
|
|
35
|
+
### Test
|
|
36
|
+
|
|
37
|
+
- New `contract-1b` test in
|
|
38
|
+
`__tests__/hook/sessions-db-session-start.test.mjs` plants a
|
|
39
|
+
`.dru-code/sessions-db.json` in a workspace with NO CLAUDE.md
|
|
40
|
+
sentinel and verifies the hook records a session_seen event.
|
|
41
|
+
Existing `contract-1` still passes (workspace with neither marker
|
|
42
|
+
still rejects).
|
|
43
|
+
- Full suite: 446 tests, 0 fail.
|
|
44
|
+
|
|
45
|
+
### No public API change
|
|
46
|
+
|
|
47
|
+
Same exported surface as 0.1.3. The gate widening is additive;
|
|
48
|
+
consumers that previously passed still pass. Cockpit pin
|
|
49
|
+
`>=0.1.0 <0.2.0` picks up 0.1.4 automatically on `npm install`.
|
|
50
|
+
|
|
8
51
|
## [0.1.3] — 2026-05-15
|
|
9
52
|
|
|
10
53
|
CI metadata patch. **Same source code as 0.1.1 / 0.1.2** — both prior
|
|
@@ -9,8 +9,10 @@
|
|
|
9
9
|
* from a hook that is purely observational.
|
|
10
10
|
*
|
|
11
11
|
* Six-item safety contract (every test below cross-references one item):
|
|
12
|
-
* 1. cwd-gate: bail on any cwd
|
|
13
|
-
*
|
|
12
|
+
* 1. cwd-gate: bail on any cwd that is neither a Druumen Workspace
|
|
13
|
+
* (CLAUDE.md sentinel) nor an opted-in workspace (existing
|
|
14
|
+
* `.dru-code/sessions-db.json` or `tickets/_logs/sessions-db.json`
|
|
15
|
+
* under cwd or any ancestor). No event written when both rejected.
|
|
14
16
|
* 2. < 2 second budget: bootstrap's setTimeout(2000ms).unref() always wins.
|
|
15
17
|
* Each sub-probe respects a single global deadline derived from
|
|
16
18
|
* `gitContext({ totalBudgetMs })` — six probes can never sum past the
|
|
@@ -76,9 +78,13 @@ async function main() {
|
|
|
76
78
|
process.env.CLAUDE_PROJECT_DIR ||
|
|
77
79
|
process.cwd();
|
|
78
80
|
|
|
79
|
-
// (3) cwd-gate.
|
|
80
|
-
//
|
|
81
|
-
//
|
|
81
|
+
// (3) cwd-gate. Accept the cwd when EITHER of:
|
|
82
|
+
// - a CLAUDE.md "Druumen Workspace" sentinel exists at cwd or ancestor
|
|
83
|
+
// (druumen-monorepo opt-in), OR
|
|
84
|
+
// - a `.dru-code/sessions-db.json` or `tickets/_logs/sessions-db.json`
|
|
85
|
+
// already exists under cwd or ancestor (cockpit Setup Wizard or
|
|
86
|
+
// prior manual init already opted this workspace in).
|
|
87
|
+
// Any other repo bails silently.
|
|
82
88
|
if (!isDruumenWorkspace(cwd)) {
|
|
83
89
|
process.exit(0);
|
|
84
90
|
}
|
|
@@ -262,27 +268,59 @@ function readStdinJson({ timeoutMs }) {
|
|
|
262
268
|
}
|
|
263
269
|
|
|
264
270
|
/**
|
|
265
|
-
*
|
|
266
|
-
* "Druumen Workspace" sentinel. Bounded to 12 ancestors so a runaway loop
|
|
267
|
-
* (e.g. weird filesystem mount) cannot stall us.
|
|
271
|
+
* Decide whether the hook is allowed to record events for `cwd`.
|
|
268
272
|
*
|
|
269
|
-
*
|
|
273
|
+
* Two acceptance fast-paths, either of which is sufficient:
|
|
274
|
+
*
|
|
275
|
+
* 1. **Druumen Workspace sentinel** — a `CLAUDE.md` at `cwd` or any
|
|
276
|
+
* ancestor whose body contains the literal string "Druumen Workspace".
|
|
277
|
+
* Original 0.1.x gate; how the Druumen monorepo opts in.
|
|
278
|
+
*
|
|
279
|
+
* 2. **Pre-initialized sessions-db storage** — `.dru-code/sessions-db.json`
|
|
280
|
+
* or `tickets/_logs/sessions-db.json` already exists at `cwd` or any
|
|
281
|
+
* ancestor. The cockpit Setup Wizard creates this file when the user
|
|
282
|
+
* explicitly enables sessions tracking for a workspace; an external
|
|
283
|
+
* project that has never opted in will not have either marker.
|
|
284
|
+
*
|
|
285
|
+
* Either marker is treated as user consent for this workspace. The walk
|
|
286
|
+
* is bounded to 12 ancestors so a runaway loop (e.g. weird FS mount)
|
|
287
|
+
* cannot stall us; the loop terminates early as soon as ANY marker is
|
|
288
|
+
* found at the current level.
|
|
289
|
+
*
|
|
290
|
+
* The function name is kept (`isDruumenWorkspace`) for git history clarity
|
|
291
|
+
* even though the semantic has broadened to "authorized workspace". Both
|
|
292
|
+
* acceptance criteria are checked at each ancestor before walking up
|
|
293
|
+
* (cheap stat-only probes for the storage paths).
|
|
294
|
+
*
|
|
295
|
+
* Returns true on the first hit, false after 12 ancestors / filesystem
|
|
296
|
+
* root / read errors with no marker found.
|
|
270
297
|
*/
|
|
271
298
|
function isDruumenWorkspace(cwd) {
|
|
272
299
|
if (typeof cwd !== 'string' || cwd.length === 0) return false;
|
|
273
300
|
let dir = cwd;
|
|
274
301
|
for (let i = 0; i < 12; i++) {
|
|
275
|
-
|
|
276
|
-
|
|
302
|
+
// Fast-path 1: CLAUDE.md sentinel
|
|
303
|
+
const claudeMd = join(dir, 'CLAUDE.md');
|
|
304
|
+
if (existsSync(claudeMd)) {
|
|
277
305
|
try {
|
|
278
306
|
// We only need the first ~8KB to find the sentinel; CLAUDE.md is
|
|
279
307
|
// typically short, so reading the whole file is fine.
|
|
280
|
-
const body = readFileSync(
|
|
308
|
+
const body = readFileSync(claudeMd, 'utf8');
|
|
281
309
|
if (body.includes('Druumen Workspace')) return true;
|
|
282
310
|
} catch {
|
|
283
311
|
// unreadable — keep walking up just in case there's a higher one.
|
|
284
312
|
}
|
|
285
313
|
}
|
|
314
|
+
// Fast-path 2: pre-initialized sessions-db storage. Stat-only — we
|
|
315
|
+
// don't read these files here, just check existence. Either convention
|
|
316
|
+
// (cockpit-marketplace `.dru-code/` or druumen-monorepo `tickets/_logs/`)
|
|
317
|
+
// counts as opt-in.
|
|
318
|
+
if (
|
|
319
|
+
existsSync(join(dir, '.dru-code', 'sessions-db.json')) ||
|
|
320
|
+
existsSync(join(dir, 'tickets', '_logs', 'sessions-db.json'))
|
|
321
|
+
) {
|
|
322
|
+
return true;
|
|
323
|
+
}
|
|
286
324
|
const parent = dirname(dir);
|
|
287
325
|
if (parent === dir) return false;
|
|
288
326
|
dir = parent;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@druumen/sessions-db",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Cross-session traceability for Claude Code — events.jsonl SSoT + JSON projection cache + 3-priority identity reconciliation",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|