@jhizzard/termdeck 1.0.4 → 1.0.6
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.
|
|
3
|
+
"version": "1.0.6",
|
|
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"
|
|
@@ -78,6 +78,45 @@ create index if not exists memory_relationships_target_idx on memory_relationshi
|
|
|
78
78
|
|
|
79
79
|
-- ── match_memories helper RPC ─────────────────────────────────────────────
|
|
80
80
|
-- Used by remember.ts (dedup) and consolidate.ts (cluster seeding).
|
|
81
|
+
--
|
|
82
|
+
-- Sprint 52.1 — signature-drift guard. On long-lived v0.6.x-era installs
|
|
83
|
+
-- (Joshua's petvetbid, Brad's jizzard-brain), match_memories was created by
|
|
84
|
+
-- a prior Mnestra version with a different RETURN-table column shape:
|
|
85
|
+
-- (id, content, metadata, source_type, category, project, created_at, similarity)
|
|
86
|
+
-- vs the canonical:
|
|
87
|
+
-- (id, content, source_type, category, project, metadata, similarity)
|
|
88
|
+
-- Postgres rejects `CREATE OR REPLACE FUNCTION` when the return-table
|
|
89
|
+
-- column list changes — `cannot change return type of existing function`
|
|
90
|
+
-- — and the migration replay throws exit 5. Sprint 51.7 fixed Class M
|
|
91
|
+
-- (DB failure no longer strands hook upgrade) but this drift remained
|
|
92
|
+
-- and was the only blocker keeping `termdeck init --mnestra` from
|
|
93
|
+
-- finishing cleanly on existing v0.6.x installs. Sprint 51.8 fixed
|
|
94
|
+
-- Class N (settings.json wiring lockstep).
|
|
95
|
+
--
|
|
96
|
+
-- The do-block below drops all `public.match_memories` overloads
|
|
97
|
+
-- regardless of arg list, so the subsequent CREATE OR REPLACE always
|
|
98
|
+
-- lands cleanly on greenfield AND existing-drift installs. Idempotent —
|
|
99
|
+
-- on a brand-new project the loop iterates zero times. Scoped to schema
|
|
100
|
+
-- `public` so we never touch a same-named function in another schema.
|
|
101
|
+
-- No CASCADE: dependent objects in plpgsql/SQL function bodies (e.g.
|
|
102
|
+
-- `memory_recall_graph` from migration 010) reference functions by
|
|
103
|
+
-- name and resolve at call time, so the drop-then-recreate pattern is
|
|
104
|
+
-- safe without CASCADE. If a true hard dependency (view, generated
|
|
105
|
+
-- column) ever appears, the DROP fails loud — the right behavior.
|
|
106
|
+
|
|
107
|
+
do $$
|
|
108
|
+
declare
|
|
109
|
+
r record;
|
|
110
|
+
begin
|
|
111
|
+
for r in
|
|
112
|
+
select p.oid::regprocedure as sig
|
|
113
|
+
from pg_proc p
|
|
114
|
+
join pg_namespace n on n.oid = p.pronamespace
|
|
115
|
+
where p.proname = 'match_memories' and n.nspname = 'public'
|
|
116
|
+
loop
|
|
117
|
+
execute 'drop function ' || r.sig::text;
|
|
118
|
+
end loop;
|
|
119
|
+
end $$;
|
|
81
120
|
|
|
82
121
|
create or replace function match_memories (
|
|
83
122
|
query_embedding vector(1536),
|
|
@@ -12,6 +12,43 @@
|
|
|
12
12
|
--
|
|
13
13
|
-- Fix 5 — Project affinity scoring. Exact project match multiplies the
|
|
14
14
|
-- score by 1.5x; mismatches are penalised 0.7x.
|
|
15
|
+
--
|
|
16
|
+
-- Sprint 51.9 — signature-drift guard. Same Class A pattern Sprint 52.1
|
|
17
|
+
-- closed for `match_memories` (mig 001:81-95). Codex T4 surfaced the cousin
|
|
18
|
+
-- 2026-05-04 14:42 ET during Sprint 51.5b dogfood: long-lived v0.6.x-era
|
|
19
|
+
-- installs (Joshua's petvetbid, likely Brad's jizzard-brain) ALSO have a
|
|
20
|
+
-- 10-arg drift overload of `memory_hybrid_search` coexisting with the
|
|
21
|
+
-- canonical 8-arg signature. The drift overload carries the never-shipped
|
|
22
|
+
-- `recency_weight`/`decay_days` parameters from a pre-canonical Mnestra
|
|
23
|
+
-- iteration or the rag-system writer's bootstrap. PostgREST + MCP clients
|
|
24
|
+
-- hit ambiguous-overload errors when calling `memory_hybrid_search` with
|
|
25
|
+
-- the canonical 8-arg shape because Postgres can't disambiguate.
|
|
26
|
+
--
|
|
27
|
+
-- The do-block below drops all `public.memory_hybrid_search` overloads
|
|
28
|
+
-- regardless of arg list, so the subsequent CREATE OR REPLACE always
|
|
29
|
+
-- lands cleanly on greenfield AND existing-drift installs. Idempotent —
|
|
30
|
+
-- on a brand-new project the loop iterates zero times. Scoped to schema
|
|
31
|
+
-- `public`. No CASCADE — same reasoning as mig 001's guard: SQL function
|
|
32
|
+
-- bodies that call this function (none currently exist) would resolve
|
|
33
|
+
-- by name at call time.
|
|
34
|
+
--
|
|
35
|
+
-- mig 004 will subsequently `CREATE OR REPLACE` this function with the
|
|
36
|
+
-- match_count cap variant (still 8 args). End state: ONE 8-arg version
|
|
37
|
+
-- of memory_hybrid_search in public schema. Ambiguity gone.
|
|
38
|
+
|
|
39
|
+
do $$
|
|
40
|
+
declare
|
|
41
|
+
r record;
|
|
42
|
+
begin
|
|
43
|
+
for r in
|
|
44
|
+
select p.oid::regprocedure as sig
|
|
45
|
+
from pg_proc p
|
|
46
|
+
join pg_namespace n on n.oid = p.pronamespace
|
|
47
|
+
where p.proname = 'memory_hybrid_search' and n.nspname = 'public'
|
|
48
|
+
loop
|
|
49
|
+
execute 'drop function ' || r.sig::text;
|
|
50
|
+
end loop;
|
|
51
|
+
end $$;
|
|
15
52
|
|
|
16
53
|
create or replace function memory_hybrid_search (
|
|
17
54
|
query_text text,
|
|
@@ -15,38 +15,24 @@
|
|
|
15
15
|
--
|
|
16
16
|
-- Idempotent: every function uses CREATE OR REPLACE; every GRANT is
|
|
17
17
|
-- safe to re-run. No data mutation. Safe to re-apply on every install.
|
|
18
|
-
|
|
19
|
-
-- ── 1. cron.job_run_details lookup ───────────────────────────────────────
|
|
20
18
|
--
|
|
21
|
-
--
|
|
22
|
-
--
|
|
23
|
-
--
|
|
24
|
-
--
|
|
19
|
+
-- Sprint 51.9 — pg_cron-conditional cron probes. T3 caught 2026-05-04
|
|
20
|
+
-- 14:55 ET that fresh Supabase projects (mnestra-only, no rumen) hit
|
|
21
|
+
-- exit-5 on this migration: `cron.job_run_details` and `cron.job` are
|
|
22
|
+
-- parse-time-resolved by `language sql` functions, and a fresh project
|
|
23
|
+
-- does NOT have `pg_cron` enabled by default (only `pg_stat_statements,
|
|
24
|
+
-- pg_trgm, pgcrypto, plpgsql, supabase_vault, uuid-ossp, vector` are in
|
|
25
|
+
-- the default set). The two cron-touching functions
|
|
26
|
+
-- (`mnestra_doctor_cron_runs`, `mnestra_doctor_cron_job_exists`) +
|
|
27
|
+
-- their grants are now wrapped in a do$$ guard that only emits them
|
|
28
|
+
-- when `pg_cron` is enabled. The doctor's cron-related probes return
|
|
29
|
+
-- the existing `unknown` band (Sprint 51.5 T2 already established it)
|
|
30
|
+
-- when the wrappers don't exist — graceful degradation. Petvetbid +
|
|
31
|
+
-- jizzard-brain are unaffected because both have rumen installed,
|
|
32
|
+
-- which enables pg_cron via rumen's mig 002. Closes the
|
|
33
|
+
-- mnestra-only-no-rumen fresh-install path.
|
|
25
34
|
|
|
26
|
-
|
|
27
|
-
p_jobname text,
|
|
28
|
-
p_limit int default 10
|
|
29
|
-
)
|
|
30
|
-
returns table (
|
|
31
|
-
jobname text,
|
|
32
|
-
status text,
|
|
33
|
-
start_time timestamptz,
|
|
34
|
-
end_time timestamptz,
|
|
35
|
-
return_message text
|
|
36
|
-
)
|
|
37
|
-
language sql
|
|
38
|
-
security definer
|
|
39
|
-
set search_path = cron, public
|
|
40
|
-
as $$
|
|
41
|
-
select j.jobname, d.status, d.start_time, d.end_time, d.return_message
|
|
42
|
-
from cron.job_run_details d
|
|
43
|
-
join cron.job j on j.jobid = d.jobid
|
|
44
|
-
where j.jobname = p_jobname
|
|
45
|
-
order by d.start_time desc
|
|
46
|
-
limit greatest(coalesce(p_limit, 10), 1);
|
|
47
|
-
$$;
|
|
48
|
-
|
|
49
|
-
-- ── 2. column existence probe (public schema only) ───────────────────────
|
|
35
|
+
-- ── 1. column existence probe (public schema only — cron-independent) ───
|
|
50
36
|
|
|
51
37
|
create or replace function mnestra_doctor_column_exists(
|
|
52
38
|
p_table text,
|
|
@@ -66,7 +52,7 @@ as $$
|
|
|
66
52
|
);
|
|
67
53
|
$$;
|
|
68
54
|
|
|
69
|
-
-- ──
|
|
55
|
+
-- ── 2. RPC / function existence probe (cron-independent) ────────────────
|
|
70
56
|
|
|
71
57
|
create or replace function mnestra_doctor_rpc_exists(p_name text)
|
|
72
58
|
returns boolean
|
|
@@ -83,21 +69,12 @@ as $$
|
|
|
83
69
|
);
|
|
84
70
|
$$;
|
|
85
71
|
|
|
86
|
-
-- ──
|
|
87
|
-
|
|
88
|
-
create or replace function mnestra_doctor_cron_job_exists(p_jobname text)
|
|
89
|
-
returns boolean
|
|
90
|
-
language sql
|
|
91
|
-
security definer
|
|
92
|
-
set search_path = cron, public
|
|
93
|
-
as $$
|
|
94
|
-
select exists (select 1 from cron.job where jobname = p_jobname);
|
|
95
|
-
$$;
|
|
96
|
-
|
|
97
|
-
-- ── 5. vault.secrets existence probe (no value disclosure) ──────────────
|
|
72
|
+
-- ── 3. vault.secrets existence probe (no value disclosure) ──────────────
|
|
98
73
|
--
|
|
99
74
|
-- Existence-only — never returns the secret value. The doctor only needs
|
|
100
75
|
-- to know whether the named vault entry was created during stack install.
|
|
76
|
+
-- supabase_vault IS in the Supabase default extension set, so this is
|
|
77
|
+
-- safe to emit unconditionally on greenfield projects.
|
|
101
78
|
|
|
102
79
|
create or replace function mnestra_doctor_vault_secret_exists(p_name text)
|
|
103
80
|
returns boolean
|
|
@@ -108,10 +85,68 @@ as $$
|
|
|
108
85
|
select exists (select 1 from vault.secrets where name = p_name);
|
|
109
86
|
$$;
|
|
110
87
|
|
|
111
|
-
-- ──
|
|
88
|
+
-- ── 4. Grants for the cron-independent probes ───────────────────────────
|
|
112
89
|
|
|
113
|
-
grant execute on function mnestra_doctor_cron_runs(text, int) to service_role;
|
|
114
90
|
grant execute on function mnestra_doctor_column_exists(text, text) to service_role;
|
|
115
91
|
grant execute on function mnestra_doctor_rpc_exists(text) to service_role;
|
|
116
|
-
grant execute on function mnestra_doctor_cron_job_exists(text) to service_role;
|
|
117
92
|
grant execute on function mnestra_doctor_vault_secret_exists(text) to service_role;
|
|
93
|
+
|
|
94
|
+
-- ── 5. cron.* probes (only emit when pg_cron is enabled) ────────────────
|
|
95
|
+
--
|
|
96
|
+
-- The two SECURITY DEFINER wrappers below reference `cron.job_run_details`
|
|
97
|
+
-- and `cron.job`. Because Postgres parse-time-resolves identifiers in
|
|
98
|
+
-- `language sql` functions, the CREATE itself fails when `cron` schema
|
|
99
|
+
-- doesn't exist — not just function execution. The do$$ guard checks
|
|
100
|
+
-- pg_extension first; if pg_cron isn't enabled, we skip emitting these
|
|
101
|
+
-- two wrappers entirely. The doctor's cron probes return `unknown`
|
|
102
|
+
-- in that case (Sprint 51.5 T2 contract).
|
|
103
|
+
--
|
|
104
|
+
-- Idempotent: do$$ runs every replay; CREATE OR REPLACE keeps the
|
|
105
|
+
-- function definitions in sync if pg_cron later gets enabled and the
|
|
106
|
+
-- migration re-runs. Existing installs (petvetbid, jizzard-brain) have
|
|
107
|
+
-- pg_cron from Rumen's install path and emit these unconditionally.
|
|
108
|
+
|
|
109
|
+
do $cron_guard$
|
|
110
|
+
begin
|
|
111
|
+
if exists (select 1 from pg_extension where extname = 'pg_cron') then
|
|
112
|
+
execute $stmt$
|
|
113
|
+
create or replace function mnestra_doctor_cron_runs(
|
|
114
|
+
p_jobname text,
|
|
115
|
+
p_limit int default 10
|
|
116
|
+
)
|
|
117
|
+
returns table (
|
|
118
|
+
jobname text,
|
|
119
|
+
status text,
|
|
120
|
+
start_time timestamptz,
|
|
121
|
+
end_time timestamptz,
|
|
122
|
+
return_message text
|
|
123
|
+
)
|
|
124
|
+
language sql
|
|
125
|
+
security definer
|
|
126
|
+
set search_path = cron, public
|
|
127
|
+
as $body$
|
|
128
|
+
select j.jobname, d.status, d.start_time, d.end_time, d.return_message
|
|
129
|
+
from cron.job_run_details d
|
|
130
|
+
join cron.job j on j.jobid = d.jobid
|
|
131
|
+
where j.jobname = p_jobname
|
|
132
|
+
order by d.start_time desc
|
|
133
|
+
limit greatest(coalesce(p_limit, 10), 1);
|
|
134
|
+
$body$;
|
|
135
|
+
$stmt$;
|
|
136
|
+
|
|
137
|
+
execute $stmt$
|
|
138
|
+
create or replace function mnestra_doctor_cron_job_exists(p_jobname text)
|
|
139
|
+
returns boolean
|
|
140
|
+
language sql
|
|
141
|
+
security definer
|
|
142
|
+
set search_path = cron, public
|
|
143
|
+
as $body$
|
|
144
|
+
select exists (select 1 from cron.job where jobname = p_jobname);
|
|
145
|
+
$body$;
|
|
146
|
+
$stmt$;
|
|
147
|
+
|
|
148
|
+
execute 'grant execute on function mnestra_doctor_cron_runs(text, int) to service_role';
|
|
149
|
+
execute 'grant execute on function mnestra_doctor_cron_job_exists(text) to service_role';
|
|
150
|
+
end if;
|
|
151
|
+
end
|
|
152
|
+
$cron_guard$;
|