memhouse 0.0.1 → 0.3.1
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/LICENSE +22 -0
- package/README.md +72 -3
- package/bin/memhouse.js +559 -0
- package/cache.js +850 -0
- package/ch-ingest.js +329 -0
- package/ch-schema.js +152 -0
- package/clickhouse.js +87 -0
- package/editors/adapter-errors.js +52 -0
- package/editors/antigravity.js +1048 -0
- package/editors/base.js +321 -0
- package/editors/claude.js +386 -0
- package/editors/codebuff.js +338 -0
- package/editors/codex.js +537 -0
- package/editors/commandcode.js +166 -0
- package/editors/copilot-jetbrains.js +207 -0
- package/editors/copilot.js +260 -0
- package/editors/cursor-agent.js +202 -0
- package/editors/cursor.js +498 -0
- package/editors/gemini.js +231 -0
- package/editors/goose.js +386 -0
- package/editors/gsd.js +366 -0
- package/editors/index.js +274 -0
- package/editors/kiro.js +315 -0
- package/editors/opencode.js +432 -0
- package/editors/vscode.js +413 -0
- package/editors/windsurf.js +634 -0
- package/editors/zed.js +229 -0
- package/index.js +424 -2
- package/mcp-server.js +294 -0
- package/mem-house/DESIGN.md +119 -0
- package/mem-house/delivery/AGENT-INSTALL.md +87 -0
- package/mem-house/delivery/PROMPT.md +42 -0
- package/mem-house/delivery/install.sh +181 -0
- package/mem-house/delivery/kernel-install.md +83 -0
- package/mem-house/delivery/plugin/.claude-plugin/plugin.json +8 -0
- package/mem-house/delivery/skills/memhouse-search/SKILL.md +104 -0
- package/mem-house/delivery/skills/memhouse-sessions/SKILL.md +94 -0
- package/mem-house/delivery/skills/memhouse-sql/SKILL.md +115 -0
- package/mem-house/rls.sql +17 -0
- package/mem-house/schema.sql +145 -0
- package/mem-house/server/queries.js +878 -0
- package/mem-house/server/server.js +228 -0
- package/mem-house/shipper/ship.js +461 -0
- package/misc/syntax-check.js +38 -0
- package/package.json +59 -7
- package/pricing.js +88 -0
- package/pricing.json +992 -0
- package/public/assets/index-CCPh7a2Z.js +75 -0
- package/public/assets/index-DV6ONi_F.css +2 -0
- package/public/index.html +16 -0
- package/relay-client.js +306 -0
- package/relay-server.js +577 -0
- package/server.js +860 -0
- package/share-image.js +367 -0
- package/ui/eslint.config.js +29 -0
- package/ui/index.html +15 -0
- package/ui/package-lock.json +4229 -0
- package/ui/package.json +38 -0
- package/ui/src/App.jsx +364 -0
- package/ui/src/components/ActivityHeatmap.jsx +206 -0
- package/ui/src/components/AiAuditCard.jsx +254 -0
- package/ui/src/components/AnimatedLoader.jsx +14 -0
- package/ui/src/components/AnimatedLogo.jsx +96 -0
- package/ui/src/components/ChatSidebar.jsx +226 -0
- package/ui/src/components/DateRangePicker.jsx +104 -0
- package/ui/src/components/EditorDot.jsx +11 -0
- package/ui/src/components/EditorIcon.jsx +117 -0
- package/ui/src/components/KpiCard.jsx +9 -0
- package/ui/src/components/LiveFeed.jsx +128 -0
- package/ui/src/components/LoginScreen.jsx +81 -0
- package/ui/src/components/MessageRenderer.jsx +148 -0
- package/ui/src/components/PageHeader.jsx +11 -0
- package/ui/src/components/SectionTitle.jsx +3 -0
- package/ui/src/components/ShareModal.jsx +305 -0
- package/ui/src/components/TokenTimeline.jsx +258 -0
- package/ui/src/hooks/useLive.jsx +15 -0
- package/ui/src/index.css +83 -0
- package/ui/src/lib/api.js +343 -0
- package/ui/src/lib/constants.js +88 -0
- package/ui/src/lib/theme.jsx +23 -0
- package/ui/src/main.jsx +16 -0
- package/ui/src/pages/Artifacts.jsx +575 -0
- package/ui/src/pages/Compare.jsx +232 -0
- package/ui/src/pages/CostAnalysis.jsx +354 -0
- package/ui/src/pages/Dashboard.jsx +529 -0
- package/ui/src/pages/DeepAnalysis.jsx +495 -0
- package/ui/src/pages/GSD.jsx +726 -0
- package/ui/src/pages/MCPs.jsx +744 -0
- package/ui/src/pages/ProjectDetail.jsx +325 -0
- package/ui/src/pages/Projects.jsx +249 -0
- package/ui/src/pages/RelayDashboard.jsx +590 -0
- package/ui/src/pages/RelayUserDetail.jsx +466 -0
- package/ui/src/pages/Sessions.jsx +535 -0
- package/ui/src/pages/Settings.jsx +241 -0
- package/ui/src/pages/SqlViewer.jsx +370 -0
- package/ui/src/pages/Subscriptions.jsx +411 -0
- package/ui/vite.config.js +18 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
-- mem-house HOUSE schema — the typed common session store (see DESIGN.md).
|
|
2
|
+
--
|
|
3
|
+
-- Applied by the agency OWNER (`memhouse_root`) inside its own house; names are
|
|
4
|
+
-- UNQUALIFIED so this works whatever the operator named the house. Requires
|
|
5
|
+
-- ClickHouse >= 26.2 natively; 25.11 also works because the shipper passes
|
|
6
|
+
-- allow_experimental_full_text_index=1 per-query when applying this file
|
|
7
|
+
-- (the messages text indexes are still gated on 25.x; 26.x+ ignores the flag).
|
|
8
|
+
--
|
|
9
|
+
-- Parse-on-client: the shipper runs the 17 editor adapters and ships TYPED rows —
|
|
10
|
+
-- these tables are the contract. `extra JSON` on each table is the escape hatch for
|
|
11
|
+
-- adapter fields not yet normalized (never lose data to the schema).
|
|
12
|
+
--
|
|
13
|
+
-- Versioning/idempotency: ReplacingMergeTree(ingested_at) everywhere. `messages` is
|
|
14
|
+
-- keyed (session_id, user_id, seq): re-shipping a grown or corrected session
|
|
15
|
+
-- REPLACES stale rows (latest-wins) instead of accumulating variants, and the
|
|
16
|
+
-- user_id in every key means two members shipping the same adapter-local
|
|
17
|
+
-- session_id can never collapse or overwrite each other's rows. Identity is
|
|
18
|
+
-- server-stamped (`user_id MATERIALIZED currentUser()`; writers must use
|
|
19
|
+
-- async_insert=0) and is the RLS anchor (rls.sql). Readers should query with the
|
|
20
|
+
-- `final=1` setting.
|
|
21
|
+
--
|
|
22
|
+
-- session_id is CANONICAL and globally unique: '<source>:<adapter-local id>',
|
|
23
|
+
-- stamped by the shipper. Adapter-local ids are only unique within one editor;
|
|
24
|
+
-- the source prefix makes every key, incremental comparison, delete, view join,
|
|
25
|
+
-- and API id collision-free across editors. `source` remains a plain column for
|
|
26
|
+
-- filtering.
|
|
27
|
+
--
|
|
28
|
+
-- BREAKING (pre-release): the user_id-in-key change alters ORDER BY, which
|
|
29
|
+
-- CREATE TABLE IF NOT EXISTS will NOT apply to an existing house — recreate with
|
|
30
|
+
-- `memhouse reset` (or DROP the tables and re-run --ensure-schema). The
|
|
31
|
+
-- source-prefixed session_id change needs no DDL, but rows shipped before it
|
|
32
|
+
-- linger under their old bare ids — run `memhouse reset` once after upgrading.
|
|
33
|
+
|
|
34
|
+
-- One row per session (adapter-level metadata; aggregates live in sessions_v).
|
|
35
|
+
CREATE TABLE IF NOT EXISTS sessions
|
|
36
|
+
(
|
|
37
|
+
session_id String,
|
|
38
|
+
source LowCardinality(String),
|
|
39
|
+
host LowCardinality(String),
|
|
40
|
+
name String DEFAULT '',
|
|
41
|
+
mode LowCardinality(String) DEFAULT '',
|
|
42
|
+
folder String DEFAULT '',
|
|
43
|
+
project String DEFAULT '',
|
|
44
|
+
git_branch String DEFAULT '',
|
|
45
|
+
created_at Nullable(DateTime64(3, 'UTC')),
|
|
46
|
+
last_updated_at Nullable(DateTime64(3, 'UTC')),
|
|
47
|
+
message_count UInt32 DEFAULT 0,
|
|
48
|
+
path String DEFAULT '',
|
|
49
|
+
extra JSON,
|
|
50
|
+
user_id String MATERIALIZED currentUser(),
|
|
51
|
+
ingested_at DateTime64(3, 'UTC') DEFAULT now64(3)
|
|
52
|
+
)
|
|
53
|
+
ENGINE = ReplacingMergeTree(ingested_at)
|
|
54
|
+
ORDER BY (session_id, user_id);
|
|
55
|
+
|
|
56
|
+
-- One row per message. FTS: two lower(text) materialized columns each carry one
|
|
57
|
+
-- text index (ngram for substring/LIKE, word for token match) — query with
|
|
58
|
+
-- lowercased terms, SELECT `text` for display.
|
|
59
|
+
CREATE TABLE IF NOT EXISTS messages
|
|
60
|
+
(
|
|
61
|
+
session_id String,
|
|
62
|
+
seq UInt32,
|
|
63
|
+
source LowCardinality(String),
|
|
64
|
+
host LowCardinality(String),
|
|
65
|
+
ts DateTime64(3, 'UTC'),
|
|
66
|
+
role LowCardinality(String),
|
|
67
|
+
model LowCardinality(String) DEFAULT '',
|
|
68
|
+
input_tokens UInt64 DEFAULT 0,
|
|
69
|
+
output_tokens UInt64 DEFAULT 0,
|
|
70
|
+
cache_read_tokens UInt64 DEFAULT 0,
|
|
71
|
+
cache_write_tokens UInt64 DEFAULT 0,
|
|
72
|
+
text String,
|
|
73
|
+
project String DEFAULT '',
|
|
74
|
+
folder String DEFAULT '',
|
|
75
|
+
is_subagent Bool DEFAULT false,
|
|
76
|
+
extra JSON,
|
|
77
|
+
line_hash UInt64,
|
|
78
|
+
user_id String MATERIALIZED currentUser(),
|
|
79
|
+
ingested_at DateTime64(3, 'UTC') DEFAULT now64(3),
|
|
80
|
+
text_ngram String MATERIALIZED lower(text),
|
|
81
|
+
text_word String MATERIALIZED lower(text),
|
|
82
|
+
INDEX idx_text_ngram text_ngram TYPE text(tokenizer = ngrams(3)) GRANULARITY 1,
|
|
83
|
+
INDEX idx_text_word text_word TYPE text(tokenizer = splitByNonAlpha) GRANULARITY 1
|
|
84
|
+
)
|
|
85
|
+
ENGINE = ReplacingMergeTree(ingested_at)
|
|
86
|
+
ORDER BY (session_id, user_id, seq);
|
|
87
|
+
|
|
88
|
+
-- One row per tool call (memory-house has no equivalent; this powers the tool
|
|
89
|
+
-- analytics). `seq` = owning message's seq; `idx` = call index within the session.
|
|
90
|
+
CREATE TABLE IF NOT EXISTS tool_calls
|
|
91
|
+
(
|
|
92
|
+
session_id String,
|
|
93
|
+
seq UInt32,
|
|
94
|
+
idx UInt32,
|
|
95
|
+
source LowCardinality(String),
|
|
96
|
+
host LowCardinality(String),
|
|
97
|
+
tool_name LowCardinality(String),
|
|
98
|
+
args String DEFAULT '{}',
|
|
99
|
+
ts DateTime64(3, 'UTC'),
|
|
100
|
+
project String DEFAULT '',
|
|
101
|
+
folder String DEFAULT '',
|
|
102
|
+
user_id String MATERIALIZED currentUser(),
|
|
103
|
+
ingested_at DateTime64(3, 'UTC') DEFAULT now64(3)
|
|
104
|
+
)
|
|
105
|
+
ENGINE = ReplacingMergeTree(ingested_at)
|
|
106
|
+
ORDER BY (session_id, user_id, idx);
|
|
107
|
+
|
|
108
|
+
-- Analytics-ready rollup: session metadata + message aggregates. Query with final=1.
|
|
109
|
+
-- LEFT JOIN (not INNER): stable-empty sessions are deliberately stored (the row
|
|
110
|
+
-- absorbs the incremental skip) and must stay visible with zero aggregates, not
|
|
111
|
+
-- vanish from every dashboard count. join_use_nulls makes unmatched message
|
|
112
|
+
-- columns NULL so count(m.seq)/coalesce produce true zeros instead of counting
|
|
113
|
+
-- the placeholder row.
|
|
114
|
+
CREATE OR REPLACE VIEW sessions_v AS
|
|
115
|
+
SELECT
|
|
116
|
+
s.session_id AS session_id,
|
|
117
|
+
any(s.source) AS source,
|
|
118
|
+
any(s.host) AS host,
|
|
119
|
+
any(s.name) AS name,
|
|
120
|
+
any(s.mode) AS mode,
|
|
121
|
+
any(s.folder) AS folder,
|
|
122
|
+
any(s.project) AS project,
|
|
123
|
+
any(s.git_branch) AS git_branch,
|
|
124
|
+
s.user_id AS user_id,
|
|
125
|
+
any(s.created_at) AS created_at,
|
|
126
|
+
any(s.last_updated_at) AS last_updated_at,
|
|
127
|
+
min(m.ts) AS started,
|
|
128
|
+
max(m.ts) AS ended,
|
|
129
|
+
coalesce(dateDiff('second', min(m.ts), max(m.ts)), 0) AS duration_sec,
|
|
130
|
+
count(m.seq) AS total_msgs,
|
|
131
|
+
countIf(m.role = 'user') AS user_msgs,
|
|
132
|
+
countIf(m.role = 'assistant') AS assistant_msgs,
|
|
133
|
+
countIf(m.is_subagent) AS subagent_msgs,
|
|
134
|
+
groupUniqArrayIf(m.model, m.model NOT IN ('', '<synthetic>')) AS models,
|
|
135
|
+
coalesce(sum(m.input_tokens), 0) AS input_tokens,
|
|
136
|
+
coalesce(sum(m.output_tokens), 0) AS output_tokens,
|
|
137
|
+
coalesce(sum(m.cache_read_tokens), 0) AS cache_read_tokens,
|
|
138
|
+
coalesce(sum(m.cache_write_tokens), 0) AS cache_write_tokens,
|
|
139
|
+
coalesce(sumIf(length(m.text), m.role = 'user'), 0) AS user_chars,
|
|
140
|
+
coalesce(sumIf(length(m.text), m.role = 'assistant'), 0) AS assistant_chars,
|
|
141
|
+
coalesce(substring(argMinIf(m.text, m.seq, m.role = 'user' AND m.text != ''), 1, 200), '') AS first_prompt
|
|
142
|
+
FROM sessions AS s
|
|
143
|
+
LEFT JOIN messages AS m ON m.session_id = s.session_id AND m.user_id = s.user_id
|
|
144
|
+
GROUP BY s.session_id, s.user_id
|
|
145
|
+
SETTINGS join_use_nulls = 1;
|