@druumen/sessions-db 0.1.0 → 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.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,211 @@ 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.3] — 2026-05-15
9
+
10
+ CI metadata patch. **Same source code as 0.1.1 / 0.1.2** — both prior
11
+ versions stayed tombstone tags because separate npm-side gates
12
+ rejected the publish. This release fixes the second one. Cockpit pin
13
+ `>=0.1.0 <0.2.0` will pick up 0.1.3.
14
+
15
+ ### Fixed (CI / supply chain)
16
+
17
+ - `package.json` `repository.url` switched from
18
+ `git+ssh://git@gitlab.tinfant.org:8922/druumen/sessions-db.git` to
19
+ `git+https://github.com/druumen/sessions-db.git`. Required by npm
20
+ registry's provenance verification: when a package is published with
21
+ `--provenance` from GitHub Actions, npm rejects (HTTP 422) if the
22
+ signed provenance source URL doesn't match `repository.url` in the
23
+ shipped tarball's package.json. Defense against supply-chain attacks
24
+ where attestation comes from a different repo than the metadata
25
+ claims.
26
+
27
+ ### Repo SSoT vs publish-canonical mirror
28
+
29
+ - **Source-of-truth (development)**: `gitlab.tinfant.org/druumen/sessions-db`
30
+ (private to tinfant org, where MRs land + CI runs first).
31
+ - **Publish-canonical (npm-visible)**: `github.com/druumen/sessions-db`
32
+ (public mirror, what `npm publish --provenance` attests to + what
33
+ `npm view @druumen/sessions-db | grep repository` shows consumers).
34
+
35
+ This split is now documented in `README.md` and `RELEASING.md`. Issues
36
+ + MRs continue to live on GitLab; the GitHub mirror is for `npm
37
+ install` consumers' "view source" link + provenance attestation.
38
+
39
+ ### Tombstone tag note (0.1.2)
40
+
41
+ - `v0.1.2` exists on GitLab + GitHub mirror as a permanent tag against
42
+ commit `d908df77` but is **NOT published to npm**. The OIDC publish
43
+ attempt got past the auth fix from 0.1.2's CI change (npm 11.5.x),
44
+ signed provenance to Sigstore log `1549510274` (immutable), but
45
+ failed at the registry PUT with `422 Unprocessable Entity` because
46
+ of the repo URL mismatch fixed in 0.1.3.
47
+ - Together with `v0.1.1` (logIndex 1547090299 / 1549427812), there are
48
+ now **3 sigstore provenance records** on the public transparency log
49
+ for failed-publish attempts of this package's 0.1.x series. They
50
+ prove the GitHub Actions runner attempted publishes and serve as
51
+ audit trail.
52
+
53
+ ### `[ASSUMPTION]` lessons recorded (per `feedback_tag_vendor_assumptions_in_plans`)
54
+
55
+ Day-of-OIDC-bringup assumption miss #2 (after the npm-version one):
56
+ - "Provenance verification accepts any repository.url in package.json"
57
+ → wrong. npm rejects 422 if signed provenance source doesn't match
58
+ metadata. This is npm's documented behavior but wasn't surfaced in
59
+ the original D15 design or RELEASING.md.
60
+
61
+ Will save a second feedback memory specifically for "OIDC publish
62
+ requires repo-URL alignment with provenance signer" so future plans
63
+ flag it.
64
+
65
+ ## [0.1.2] — 2026-05-15
66
+
67
+ CI-only patch. **Same source code as 0.1.1** — but 0.1.1 never actually
68
+ landed on the npm registry; it stayed a tombstone tag because the
69
+ GitHub Actions OIDC publish workflow used npm 10.8.2 (default for
70
+ Node 20), which signs sigstore provenance fine but lacks the OIDC
71
+ trusted-publisher token-exchange flow that npm registry requires
72
+ (added in npm **11.5.1**). The publish PUT got 404 (npm-style auth
73
+ masking) twice in a row.
74
+
75
+ This release fixes the workflow + ships the same library code under
76
+ 0.1.2. Cockpit pinning `>=0.1.0 <0.2.0` will pick this up
77
+ automatically; no manual install change needed.
78
+
79
+ ### Fixed (CI / supply chain)
80
+
81
+ - `.github/workflows/publish.yml` now runs `npm install -g npm@latest`
82
+ before the publish step. Picks up OIDC trusted publisher support
83
+ (≥11.5.1) without changing the runner's Node version (constrained
84
+ by `engines: ">=18.0.0"` in package.json).
85
+
86
+ ### Tombstone tag note (0.1.1)
87
+
88
+ - `v0.1.1` exists on GitLab + GitHub mirror as a permanent tag against
89
+ commit `4350814e` but is **NOT published to npm**. Two failed OIDC
90
+ publish attempts left two sigstore provenance records on the public
91
+ transparency log (`logIndex 1547090299` and `logIndex 1549427812`),
92
+ immutable forever — they prove the GitHub Actions runner attempted
93
+ to publish that tag. Consumers should ignore `v0.1.1` entirely.
94
+ - The 0.1.1 CHANGELOG entry is preserved below as the full record of
95
+ the packaging fixes that **shipped under 0.1.2**.
96
+
97
+ ### `[ASSUMPTION]` lesson recorded
98
+
99
+ - Per memory `feedback_tag_vendor_assumptions_in_plans` (saved
100
+ 2026-05-15): the assumption "npm CLI shipped with Node 20 supports
101
+ OIDC trusted publisher" was written as fact in the original D15
102
+ publish.yml. Both Codex round-2 review and the cockpit owner's
103
+ bootstrap step 7 missed it because both audited "trusted publisher
104
+ is configured" without checking "is the runner's npm version
105
+ capable of using it." Real-world v0.1.1 publish surfaced the gap.
106
+
107
+ ## [0.1.1] — 2026-05-15
108
+
109
+ Packaging-only patch release. Fixes 3 independent bugs surfaced by the
110
+ first real consumer (Druumen Cockpit Phase 3 B1 integration) within
111
+ hours of 0.1.0 publish. **Zero runtime/library code changes** — same
112
+ public API surface, same test coverage. The fix is in how the package
113
+ is shipped, not what it does.
114
+
115
+ This is also the **first OIDC publish path test** — released via
116
+ GitHub Actions trusted publisher (no NPM_TOKEN_BOOTSTRAP), with
117
+ `--provenance` attestations. Consumers can now verify provenance via
118
+ `npm view @druumen/sessions-db@0.1.1 --json | jq .dist.attestations`.
119
+
120
+ ### Fixed
121
+
122
+ - **Bug A — Node16 module resolution ignores top-level `types`** when
123
+ `exports` map is present. 0.1.0 had bare-string-form
124
+ `"exports": { ".": "./lib/index.mjs" }` plus a top-level
125
+ `"types": "./types/index.d.ts"` — the top-level was silently
126
+ dropped under cockpit's `moduleResolution: "Node16"`. Symptom:
127
+ `TS7016: Could not find a declaration file for module '@druumen/sessions-db'`.
128
+ Fix: conditional exports map with explicit `types` + `import` +
129
+ `require` + `default` per entry. The top-level `types` is kept as
130
+ legacy fallback for `moduleResolution: "node"` (older TypeScript).
131
+
132
+ - **Bug B — `types/index.d.ts` re-exported type aliases not values**.
133
+ 0.1.0 had a hand-crafted `types/index.d.ts` with patterns like
134
+ `export type LoadProjection = typeof import('./storage.d.mts').loadProjection`
135
+ — these are TYPE ALIASES, not VALUE re-exports. Consumer could write
136
+ `import type { LoadProjection }` but not `import { loadProjection }`.
137
+ Symptom: `TS2305: Module '@druumen/sessions-db' has no exported
138
+ member 'loadProjection'`. Root cause: stale Day-2 artifact when
139
+ `lib/index.mjs` was a stub; never updated when Day 3 added real
140
+ value re-exports to `lib/index.mjs`. Fix: replace with a barrel
141
+ pattern that stitches `./index.d.mts` (auto-emitted value re-exports
142
+ mirroring lib/index.mjs) + `./types.d.mts` (auto-emitted type
143
+ declarations from lib/types.mjs `@typedef` block).
144
+
145
+ - **Bug C — pure ESM rejected by Node16 CJS context**. 0.1.0 was pure
146
+ ESM (`"type": "module"` + only `.mjs` source). Cockpit (Node16 +
147
+ no `"type":"module"` → CJS context) hit `TS1479: ECMAScript module
148
+ cannot be imported with require`. Fix: dual CJS+ESM build via
149
+ esbuild — `lib/index.cjs` (62 KB bundle) is generated alongside
150
+ `lib/index.mjs` by `npm run build:cjs`. Exports map's `require`
151
+ condition routes CJS consumers to the bundle, `import` condition
152
+ keeps ESM consumers on the per-file structure. The bundle is
153
+ regenerated at `prepublishOnly` time so it always matches the
154
+ current `lib/index.mjs` exports.
155
+
156
+ ### Added
157
+
158
+ - **Regression guards** so Bug A / B / C class issues surface at
159
+ publish time, not consumer integration time:
160
+ - `__tests__/pack-install-smoke/pack-install-smoke.test.mjs` —
161
+ end-to-end packaged-consumer smoke. `npm pack`s the source,
162
+ installs the tarball into a temp consumer dir, then exercises
163
+ the actual `package.json` exports map via 3 consumer styles:
164
+ (a) CJS `require('@druumen/sessions-db')`, (b) ESM
165
+ `import('@druumen/sessions-db')`, (c) TypeScript
166
+ `moduleResolution: "Node16"` with both type and value imports.
167
+ This is the canonical "consumer's POV" test — it would have
168
+ caught all 3 of 0.1.0's Bug A / B / C at publish time. The other
169
+ smokes complement it but bypass the exports map.
170
+ - `__tests__/cjs-smoke/cjs-smoke.test.mjs` — runtime CJS smoke
171
+ against `lib/index.cjs` directly. Asserts 35+ functions + 7+
172
+ constants are callable.
173
+ - `__tests__/types-smoke/cockpit-import.ts` — added VALUE imports
174
+ block (was type-imports-only).
175
+ - `__tests__/types-smoke/tsconfig.json` switched from
176
+ `moduleResolution: "Bundler"` to `"Node16"`.
177
+ - **CI build-freshness gate** — both GitLab `test-linux` and GitHub
178
+ Actions `Windows CI` now run `npm run build` followed by
179
+ `git diff --exit-code lib/index.cjs types/`. If a contributor
180
+ edits `lib/*.mjs` (changing exported signatures) but forgets to
181
+ rerun the build before commit, CI fails fast at PR time instead
182
+ of shipping a stale bundle to npm.
183
+
184
+ ### Build
185
+
186
+ - **`esbuild` ^0.25.x** added as a devDependency (single dep, no
187
+ runtime cost — bundle output has zero deps). `npm run build:cjs`
188
+ produces `lib/index.cjs` from `lib/index.mjs`. `npm run build`
189
+ runs both `build:types` (tsc) and `build:cjs` (esbuild).
190
+ `prepublishOnly` runs `npm run build` so the tarball always
191
+ contains the freshly-bundled CJS + freshly-emitted .d.mts.
192
+
193
+ - `package.json` `"main"` switched to `./lib/index.cjs` (CJS entry
194
+ for legacy tooling). `"module"` field added pointing to
195
+ `./lib/index.mjs` (legacy bundler hint, e.g. webpack 4).
196
+
197
+ ### Tarball delta vs 0.1.0
198
+
199
+ - 50 → 51 files (+1: `lib/index.cjs`)
200
+ - 108.6 KB → 123.6 KB (+15 KB, all CJS bundle)
201
+ - 371.2 KB → 432.8 KB unpacked (still well under target)
202
+
203
+ ### Codex round + lessons
204
+
205
+ - Codex adversarial review applied (agentId: see commit message of
206
+ the round-2 fix commit).
207
+ - Per `feedback_tag_vendor_assumptions_in_plans` saved 2026-05-15:
208
+ the assumption "ESM-only is fine for npm publishing" should have
209
+ been tagged `[ASSUMPTION]` in the original D-path plan, not
210
+ written as fact. Real-world consumer (cockpit Node16 CJS) surfaced
211
+ the gap. Documented for future plan-drafting discipline.
212
+
8
213
  ## [0.1.0] — 2026-05-15
9
214
 
10
215
  First public release. Extracted from the Druumen monorepo as a
@@ -41,7 +246,7 @@ dependencies.
41
246
  never walks to `/` on a slow networked mount.
42
247
  - **TypeScript types**: hand-curated `types/index.d.ts` re-export hub
43
248
  plus auto-emitted `.d.mts` siblings via `tsc --emitDeclarationOnly`
44
- + JSDoc on the source `.mjs` files. Cockpit and other TS consumers
249
+ driven by JSDoc on the source `.mjs` files. Cockpit and other TS consumers
45
250
  can `import type { KnownSession, Projection } from '@druumen/sessions-db'`.
46
251
  - **Cross-platform**: macOS / Linux / Windows all supported and
47
252
  CI-gated. Linux runs on GitLab `test-linux` (Node 20). Windows runs
@@ -88,6 +293,13 @@ dependencies.
88
293
  using a one-time `NPM_TOKEN_BOOTSTRAP` Granular Access Token (48h
89
294
  expiry, `@druumen` scope, masked + protected + environment-scoped
90
295
  variable, revoked immediately after publish).
296
+ - **v0.1.0 published WITHOUT provenance attestations** — intentional.
297
+ The bootstrap path runs from GitLab CI which has no GitHub-Actions-
298
+ style OIDC token issuer for npm; the npm registry only accepts
299
+ provenance from a recognized OIDC publisher (currently GitHub Actions
300
+ and GitLab.com SaaS). `npm view @druumen/sessions-db@0.1.0 --json | jq
301
+ .dist.attestations` returns `{}`. This is a one-time gap covering
302
+ only the bootstrap release; v0.1.1 onwards have full provenance.
91
303
  - **v0.1.1 onwards** publish from GitHub Actions
92
304
  (`.github/workflows/publish.yml`) via npm **OIDC trusted publishing**
93
305
  — no long-lived secrets, short-lived OIDC tokens validated by npm
@@ -247,3 +459,44 @@ contract.
247
459
  releases, uses `id-token: write` + `--provenance` flag for npm
248
460
  attestations. Inactive until trusted publisher configured on npm
249
461
  web (Bootstrap step 7).
462
+
463
+ ### Day 8 — 2026-05-15 (v0.1.0 published — 3 lessons learned)
464
+
465
+ - **Published**: `@druumen/sessions-db@0.1.0` live on npm registry at
466
+ 2026-05-15T08:22:56Z, Apache-2.0, `dist.shasum a70980a7…`. Pipeline
467
+ #429 (post-release-prep merge `645a8a4e`): `test-linux` 9.4s +
468
+ `mirror-to-github` 5.2s + `publish-npm` 12.6s. Trusted publisher
469
+ configured on npm web (org=druumen, repo=sessions-db, workflow=
470
+ publish.yml, env=npm-publish) immediately after bootstrap revoke,
471
+ arming OIDC path for 0.1.1+.
472
+
473
+ - **Lesson 1 (Δ35 — protected `v*` tag gap)**: First v0.1.0 tag
474
+ pipeline `mirror-to-github` failed because `GITHUB_MIRROR_TOKEN`
475
+ (protected variable) wasn't accessible from `v*` tag pipelines —
476
+ only `master` + `fix/*` were in the protected refs list. Fixed by
477
+ adding `v*` to GitLab Protected Tags (Maintainers can create).
478
+ RELEASING.md pre-flight now explicitly lists the protected-refs
479
+ audit including `v*`.
480
+
481
+ - **Lesson 2 (Δ36 — npm Granular "Bypass 2FA" checkbox)**: 5
482
+ consecutive `EOTP npm error code EOTP` failures during initial
483
+ publish attempts. Root cause discovered: npm removed Classic
484
+ Automation tokens in November 2025; only Granular Access Tokens
485
+ are now supported, and Granular tokens require an OTP at publish
486
+ time **even when the account is in `auth-only` 2FA mode**, unless
487
+ the explicit "Bypass two-factor authentication (2FA)" checkbox is
488
+ ticked at token creation. Token regenerated with the checkbox →
489
+ immediate publish success. RELEASING.md Step 1 now flags this as
490
+ a `MUST be checked` item with prominent ⚠️ marker.
491
+
492
+ - **Lesson 3 (Δ37 — v0.1.0 has no provenance)**: Documented in the
493
+ Supply chain section above. Bootstrap path runs from GitLab CI
494
+ which lacks GitHub-Actions-style npm OIDC integration; v0.1.0 ships
495
+ without `dist.attestations`. Intentional and one-time — v0.1.1+ via
496
+ OIDC restores full provenance.
497
+
498
+ - **Cockpit Phase 3 unblocked**: B1-B14 implementation begins
499
+ immediately on cockpit side. `npm install @druumen/sessions-db`
500
+ works for marketplace prep. Expect 1-2 minor patch releases
501
+ (0.1.1 / 0.1.2) shaking out integration corner cases — these will
502
+ be the first real exercise of the OIDC publish path.
package/README.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  Cross-session traceability for [Claude Code](https://claude.com/claude-code).
4
4
 
5
+ > **Repository note**: development happens at
6
+ > `gitlab.tinfant.org/druumen/sessions-db` (private to tinfant org —
7
+ > file MRs there). The `github.com/druumen/sessions-db` mirror is
8
+ > public and is the source-of-truth for npm provenance attestations
9
+ > + the consumer-facing "view source" link from
10
+ > <https://www.npmjs.com/package/@druumen/sessions-db>. Both are kept
11
+ > in sync via GitLab CI's `mirror-to-github` job.
12
+
5
13
  ## What it does
6
14
 
7
15
  Records every Claude Code session start (cwd, branch, transcript file,
@@ -120,6 +128,26 @@ The hook is bootstrap-safe by design:
120
128
  - Errors are logged to stderr (visible in Claude Code's session log)
121
129
  but never surfaced as user-facing failures.
122
130
 
131
+ #### Subpath imports `./cli` and `./hook` are ESM-only
132
+
133
+ The `@druumen/sessions-db/cli` and `@druumen/sessions-db/hook` exports
134
+ resolve to `.mjs` entry points and are intended to be **executed as
135
+ processes** (via the `bin` field's shim, or invoked directly with
136
+ `node <path>`). They are NOT intended for programmatic `require()` /
137
+ `import` from a consumer's runtime code.
138
+
139
+ If you need to run the CLI from your code, spawn it as a child process:
140
+
141
+ ```js
142
+ // CJS or ESM consumer — spawn the CLI as a process
143
+ import { spawnSync } from 'node:child_process';
144
+ spawnSync('npx', ['sessions-db', 'find', '...'], { stdio: 'inherit' });
145
+ ```
146
+
147
+ The main library entry (`@druumen/sessions-db`) IS dual-published as
148
+ both CJS and ESM and works from either context. Only the bin-style
149
+ subpaths are ESM-only.
150
+
123
151
  ## Path resolution
124
152
 
125
153
  When you don't pass an explicit `rootPath`, sessions-db walks a 5-priority