@jhizzard/termdeck 1.0.8 → 1.0.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jhizzard/termdeck",
3
- "version": "1.0.8",
3
+ "version": "1.0.9",
4
4
  "description": "Browser-based terminal multiplexer with metadata overlays, panel flashback memory recall, and AI-aware session management",
5
5
  "bin": {
6
6
  "termdeck": "./packages/cli/src/index.js"
@@ -136,6 +136,29 @@ const PROBES = Object.freeze([
136
136
  " and column_name = 'session_id' limit 1",
137
137
  presentWhen: 'rowReturned'
138
138
  },
139
+ {
140
+ // Sprint 53 T2 — Rumen picker rewrite. memory_sessions.rumen_processed_at
141
+ // (added by mig 018) is the picker's idempotency stamp.
142
+ // rumen 0.5.0+ filters `WHERE rumen_processed_at IS NULL` in extract.ts
143
+ // and stamps `UPDATE … SET rumen_processed_at = NOW()` between
144
+ // synthesize and surface (rumen/src/index.ts). Without this column,
145
+ // rumen-tick errors on the WHERE clause and produces 0 sessions/tick.
146
+ // Mig 018's ADD COLUMN IF NOT EXISTS + partial index are idempotent
147
+ // on already-stamped installs; safe to apply repeatedly.
148
+ //
149
+ // T4-CODEX 2026-05-04 17:32 ET pre-FIX audit catch — without this probe,
150
+ // a user upgrading TermDeck and only running `init --rumen --yes`
151
+ // could deploy the new picker without the column.
152
+ name: 'memory_sessions.rumen_processed_at',
153
+ kind: 'mnestra',
154
+ migrationFile: '018_rumen_processed_at.sql',
155
+ probeSql:
156
+ "select 1 as present from information_schema.columns " +
157
+ "where table_schema = 'public' " +
158
+ " and table_name = 'memory_sessions' " +
159
+ " and column_name = 'rumen_processed_at' limit 1",
160
+ presentWhen: 'rowReturned'
161
+ },
139
162
  {
140
163
  name: 'rumen-tick cron schedule',
141
164
  kind: 'rumen',
@@ -0,0 +1,40 @@
1
+ -- Migration 018 — memory_sessions.rumen_processed_at column.
2
+ --
3
+ -- Sprint 53 T2 (Rumen picker rewrite). Adds a tracking column so Rumen's
4
+ -- extract phase can pick candidate sessions directly from memory_sessions
5
+ -- (one row per Claude Code session, post-Sprint-51.6 bundled hook) and
6
+ -- mark them as processed atomically when surface succeeds.
7
+ --
8
+ -- Why a column not a separate table: the picker hot path is "give me the
9
+ -- N most recent sessions Rumen hasn't seen yet." A boolean/timestamp on
10
+ -- memory_sessions answers that with one filtered range scan; a separate
11
+ -- rumen_processed table would force a NOT EXISTS / LEFT JOIN per tick.
12
+ --
13
+ -- Why timestamptz not boolean: the timestamp doubles as a debug aid
14
+ -- ("when did Rumen last touch this session?") and lets a future backfill
15
+ -- script identify the cutoff between pre-Sprint-53 (NULL — never touched
16
+ -- by the new picker) and post-Sprint-53 (stamped) without an extra column.
17
+ --
18
+ -- Idempotent — safe on:
19
+ -- 1. Joshua's daily-driver (pre-Sprint-53; column will be added with
20
+ -- every existing memory_sessions row at NULL → all become candidates
21
+ -- on the first post-deploy tick, which is the desired bootstrap).
22
+ -- 2. Brad's jizzard-brain (Linux SSH; same shape, same null-bootstrap).
23
+ -- 3. Fresh canonical installs (post-mig-017 schema; column added on
24
+ -- first run, no rows to backfill).
25
+ -- 4. Re-runs (ADD COLUMN IF NOT EXISTS + CREATE INDEX IF NOT EXISTS).
26
+ --
27
+ -- The partial index is the picker's hot path: SELECT … WHERE
28
+ -- rumen_processed_at IS NULL AND ended_at IS NOT NULL ORDER BY started_at DESC.
29
+ -- Indexing only NULL rows keeps the index tiny (hundreds of rows at any
30
+ -- given moment, since stamped rows drop out) — much smaller than a full
31
+ -- B-tree on rumen_processed_at would be.
32
+
33
+ alter table public.memory_sessions
34
+ add column if not exists rumen_processed_at timestamptz;
35
+
36
+ -- Partial index — covers only unprocessed sessions, ordered by recency.
37
+ -- Picker query plan: index range scan on the partial index, no seqscan.
38
+ create index if not exists memory_sessions_rumen_unprocessed_idx
39
+ on public.memory_sessions(started_at desc nulls last)
40
+ where rumen_processed_at is null;