@inetafrica/open-claudia 2.4.2 → 2.6.0

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
@@ -1,5 +1,29 @@
1
1
  # Changelog
2
2
 
3
+ ## v2.6.0
4
+ - **Dream: nightly memory consolidation (Phase 3 of the memory system).** A quiet-hours pass (`core/dream.js`, default 4am via `DREAM_CRON`, model `DREAM_MODEL` default sonnet, `DREAM=off` to disable) reviews the entire pack + entity memory on a stronger model and returns a strict-JSON decision that bot code applies:
5
+ - **Merges** packs that drifted into the same topic (sections synthesised, not concatenated) — merged-away packs are backed up to `~/.open-claudia/backup/dream-<stamp>/` before removal.
6
+ - **Umbrella/parent pack trees**: creates umbrella packs over 3+ sibling topics (the umbrella's State is a family map, a router not a duplicate) and assigns parent/sub relationships, with cycle protection. Injected packs now show their parent ("Part of: …") and list sub-packs with dig-deeper hints.
7
+ - **Retags**: tightens pack descriptions and tags — the FTS router matches on those fields, so tighter metadata means fewer false injections.
8
+ - **Entity dedupe + cross-linking**: merges duplicate entities (aliases unioned, source backed up) and rewrites entity Notes with `[[pack-dir]]` cross-links.
9
+ - Reports in chat (owner Telegram channel) whenever it changed something; silent when there was nothing to tidy. Manual trigger: `open-claudia dream`, preview with `--dry-run`.
10
+ - **Personality system.** `~/.open-claudia/persona.md` (override with `PERSONA_FILE`) holds Open Claudia's voice — tone, quirks, emoji habits — on top of the user-owned soul. It feeds into the system prompt as a `## Personality` block that explicitly never overrides soul rules, ships with a warm default, and the dream pass may evolve it gently (bounded 80–2400 chars, previous version backed up, change announced).
11
+ - **Memory announcements got a face-lift.** Reviewer announcements are now grouped under a friendly header ("🧠 Took some notes while we worked:"), use per-kind emojis (📦 new pack, ✏️ update, 👤/🚀/🏢/📍/🖥️/🔖 entities by type), clip at word boundaries instead of mid-word, carry more of the actual content, and include an inspect hint for new packs. In-turn pack/entity writes announce in the same voice.
12
+
13
+ ## v2.5.0
14
+ - **Context packs: skills become living topic documents (skills + memory merged).** Each pack is `~/.open-claudia/packs/<dir>/PACK.md` with four sections — Stance (how to think about the topic: user preferences, hard rules), Procedure (verified how-to, what skills used to be), State (where work stands now; replaced wholesale as things move), Journal (dated one-line log of past sessions, capped at 30 entries).
15
+ - **Pre-turn router** (`core/packs.js` + `system-prompt.js`): the incoming message is FTS5-matched against all packs (porter-stemmed, field-weighted — name/description/tags hits count double, threshold keeps a single incidental body word from dragging a pack in; BM25 was unusable because its IDF collapses on small corpora). Matched packs are injected into the per-turn context block, once per (channel, session, pack-version) so re-injection only happens when a pack actually changed. Rides the user message, not the system prompt, to preserve the prompt-cache prefix.
16
+ - **Post-turn reviewer** (`core/pack-review.js`): after every substantial turn (>400 chars) a haiku subagent reviews the exchange and returns a strict-JSON decision — update a pack (journal line + State rewrite), create one for a new durable topic, or nothing. The model returns JSON only; all file writes are applied by bot code, so the reviewer needs no tools or permissions. Active by default (most working turns produce at least a journal line), `PACK_REVIEW=off` to disable, `PACK_REVIEW_MODEL` to change model. Every applied mutation is announced in chat (one line) — no silent learning.
17
+ - **In-turn writes announced**: `Write`/`Edit` aimed at a `PACK.md` triggers `Updating pack: X` / `New pack: X` chat lines, same as skills did.
18
+ - **`open-claudia pack list|show|match|migrate|remove|reindex`**: inspect packs, debug the router (`match` shows scores), and `pack migrate` folds existing `~/.claude/skills` into packs (body → Procedure section) with originals backed up to `~/.open-claudia/backup/skills-pre-packs/` — run it once after upgrading.
19
+ - `spawnSubagent` learned `model` and `systemPrompt` overrides (used by the reviewer; also available to `open-claudia agent`).
20
+ - **Entity memory (phase 2): contextual notes on people, places, projects, orgs and systems.** Each entity is a short file at `~/.open-claudia/entities/<slug>.md` — frontmatter (name, type, aliases, description) plus Notes (current truth, replaced wholesale) and Log (dated one-line observations, capped at 40).
21
+ - **Same router, second store** (`core/entities.js`): incoming messages are FTS5-matched against entities with the pack scoring scheme, except the strong fields are name/aliases — a single mention of "Emmanuel" injects the Emmanuel note, but one stray body word can't. Injected as a `## Known entities` block beside packs, deduped per (channel, session, entity-version).
22
+ - **Same reviewer, one call**: the post-turn haiku reviewer now also returns an `entities` array — it creates or updates entity notes (merge semantics: aliases union, Notes replace, Log appends) in the same pass that maintains packs, at no extra subagent cost. Entity changes are announced in chat like pack changes.
23
+ - **`open-claudia entity list|show|match|note|remove|reindex`**: inspect the store, debug the router, or jot a note manually (`entity note Emmanuel "owns inet-central org cleanup" --type person`).
24
+ - Direct `Write`/`Edit` to an entity file announces `Updating entity: X` / `New entity: X`, same as packs.
25
+ - This completes phase 2 of the packs system; "dream" consolidation (pack merging + skill trees + entity linking) is next.
26
+
3
27
  ## v2.4.2
4
28
  - Fix replies losing everything written before tool calls. The backend's final `result` event carries only the LAST text segment of a turn, but the stream parser assigned it over the accumulated `assistantText` — so a turn shaped "long explanation → tool calls → short closing line" delivered only the closing line, which read as nonsense without its context. `evt.result` is now a fallback used only when nothing was accumulated (some Cursor turns). Fixed in both `runClaude` and the auxiliary runner.
5
29
 
package/README.md CHANGED
@@ -2,36 +2,58 @@
2
2
 
3
3
  Your always-on AI coding assistant — Claude Code, Cursor Agent, and OpenAI Codex via Telegram or Kazee Chat.
4
4
 
5
- Send text, voice notes, screenshots, and files from your phone. Your chosen AI agent works on your projects and reports back.
5
+ Send text, voice notes, screenshots, and files from your phone. Your chosen AI agent works on your projects, remembers what it learned, and reports back.
6
6
 
7
7
  ## Features
8
8
 
9
+ ### Channels & backends
9
10
  - **Multi-channel** — run the same bot on Telegram, Kazee Chat, or both at once (`CHANNELS=telegram,kazee`). Each channel renders keyboards, files, voice notes, and edits natively
10
- - **Multi-backend** — switch between Claude Code, Cursor Agent, and OpenAI Codex on the fly (`/claude`, `/cursor`, `/codex`)
11
- - **Multi-project sessions** — switch between workspace projects
12
- - **Per-project conversation history** — auto-resumes last conversation, switch with `/sessions`
13
- - **Project transcript memory** — keeps redacted project JSONL transcripts outside the repo and points fresh/backend-switched sessions to them without pasting huge history
14
- - **Separate session persistence** — Claude, Cursor, and Codex each maintain their own conversation state
15
- - **Voice notes** — speak instructions, transcribed locally via Whisper
11
+ - **Multi-backend** — switch between Claude Code, Cursor Agent, and OpenAI Codex on the fly (`/claude`, `/cursor`, `/codex`); each keeps its own session state
12
+ - **Multi-user / team mode** — one bot serves multiple authorized users in parallel, each with their own conversations, settings, model, backend, and usage counters
13
+ - **Multi-project sessions** — switch between workspace projects; per-project conversation history auto-resumes
14
+
15
+ ### Memory & long-term context
16
+ - **Context packs** — living per-topic documents (one per project, system, or recurring task) holding Stance, Procedure, State, and Journal. Packs matching your message are auto-injected into the agent's context, and a background reviewer updates them after every substantial turn — the assistant keeps its train of thought across sessions and projects
17
+ - **Entity memory** — short notes on the people, places, projects, orgs, and systems you mention, extracted automatically and injected when they come up again
18
+ - **Dream consolidation** — a nightly pass on a stronger model that merges duplicate packs, builds umbrella/parent pack trees, tightens descriptions, dedupes entities, and reports what it tidied — with everything backed up first
19
+ - **Personality** — a persona file gives the assistant a consistent voice on top of your soul file, and the dream pass evolves it gently as you work together
20
+ - **Transcript search** — redacted project transcripts indexed in SQLite FTS5; `open-claudia transcript-search` gives the agent ~50ms ranked recall over months of history
21
+ - **Smart compaction** — long conversations are summarized proactively before they get slow; full briefs are archived to disk so nothing is truly lost (`/compact`, `/compactwindow`)
22
+ - **No silent learning** — every pack, entity, or skill the bot creates or changes is announced in chat with one line
23
+
24
+ ### Background work
25
+ - **Wakeups & crons** — the agent can schedule one-shot wake-ups ("check the deploy in 20 minutes") and recurring jobs that survive restarts
26
+ - **Persistent tasks** — a per-channel todo tree with plans and subtasks that survives compaction and restarts
27
+ - **Sub-agents** — throwaway research agents for side questions that shouldn't pollute the main conversation
28
+ - **Agent mode** — non-blocking side conversations while heavy tasks run in the background
29
+
30
+ ### Working from your phone
31
+ - **Voice notes** — speak instructions, transcribed locally via Whisper; voice questions get voice replies (macOS)
16
32
  - **Screenshots & images** — send UI mockups, errors, or code screenshots
17
- - **File sharing** — send PDFs, code files, documents saved and read by the agent
33
+ - **File sharing** — send PDFs, code files, documents; the agent can send files, photos, and voice clips back
18
34
  - **Reply context** — reply to any message (including files) for follow-up
19
- - **Streaming output** — see the agent working in real-time
20
- - **Agent mode** — non-blocking side conversations while heavy tasks run in the background
21
- - **Cron jobs** — scheduled tasks (standups, git digests, health checks)
35
+ - **Streaming output** — see the agent working in real time
36
+
37
+ ### Team
38
+ - **People roster** — the bot knows your team members, their channels, and notes about them
39
+ - **Intros** — unknown chats go through an owner-approved introduction flow
40
+ - **Cross-channel relay** — the agent can message teammates on their own channels (with provenance and an audit trail)
41
+ - **Identity links** — link chats across channels to one canonical user so history follows you
42
+
43
+ ### Operations
22
44
  - **Encrypted vault** — store API keys and credentials securely
23
45
  - **Customizable soul** — define your assistant's personality and knowledge
24
- - **Model switching** — toggle between models on either backend
25
- - **Plan mode, effort levels, budgets** full control from Telegram
26
- - **Auto-updates** — checks for new versions every 5 minutes, upgrade with `/upgrade`
27
- - **Requirements doctor** — `/doctor` / `/requirements` checks CLI installs, auth, voice tools, and writable paths after upgrades
28
- - **Multi-user auth** — authorize additional users with code verification
29
- - **Cross-platform** — works on macOS, Linux, and Windows
46
+ - **Model switching, plan mode, effort levels, budgets** — full control from chat
47
+ - **Token economy** byte-stable system prompt for maximum Anthropic prompt-cache hits; dynamic state rides each message instead
48
+ - **Web UI** — optional browser UI for setup and config (`open-claudia start --web`)
49
+ - **Auto-updates** — checks npm every 5 minutes, upgrade with `/upgrade`
50
+ - **Requirements doctor** — `/doctor` checks CLI installs, auth, voice tools, and writable paths
51
+ - **Cross-platform** — macOS, Linux, and Windows
30
52
 
31
53
  ## Prerequisites
32
54
 
33
- - [Node.js](https://nodejs.org/) 18+
34
- - A Telegram bot token (from [@BotFather](https://t.me/BotFather))
55
+ - [Node.js](https://nodejs.org/) 18+ (22.5+ recommended — its built-in SQLite powers transcript/pack/entity search; on older Node those features quietly disable themselves)
56
+ - A Telegram bot token (from [@BotFather](https://t.me/BotFather)) and/or a Kazee Chat bot
35
57
  - At least one authenticated CLI backend on the host machine (see below)
36
58
  - (Optional) [whisper.cpp](https://github.com/ggerganov/whisper.cpp) + ffmpeg for voice notes
37
59
 
@@ -63,14 +85,14 @@ agent status # Verify: should show your email and plan
63
85
  ```bash
64
86
  npm install -g @openai/codex
65
87
  codex login # Opens browser to authenticate
66
- # Or from Telegram after Open Claudia is running: /codex_login
88
+ # Or from chat after Open Claudia is running: /codex_login
67
89
  # If browser/device login cannot complete remotely: /codex_setup_token
68
90
  codex --version # Verify it works
69
91
  ```
70
92
 
71
93
  Docker images include the Codex CLI. Direct npm installs still need optional backend CLIs installed on the host.
72
94
 
73
- > **Important**: Claude Code can use macOS Keychain when you log in interactively, but a launchd/background bot may not be able to read that Keychain session. Open Claudia v1.14.0 adds Telegram auth helpers and supports `CLAUDE_CODE_OAUTH_TOKEN` for non-interactive Claude runs. Prefer `/setup_token` then `/use_oauth_token` if Telegram shows Claude auth/keychain errors.
95
+ > **Important**: Claude Code can use macOS Keychain when you log in interactively, but a launchd/background bot may not be able to read that Keychain session. Open Claudia supports `CLAUDE_CODE_OAUTH_TOKEN` for non-interactive Claude runs. Prefer `/setup_token` then `/use_oauth_token` if chat shows Claude auth/keychain errors.
74
96
 
75
97
  ### 2. Install Open Claudia
76
98
 
@@ -98,39 +120,47 @@ If setup is interrupted, running it again resumes from the last completed step.
98
120
 
99
121
  All configuration is stored in `~/.open-claudia/` — survives npm upgrades.
100
122
 
123
+ ### 4. (Optional) Add Kazee Chat
124
+
125
+ Set `CHANNELS=telegram,kazee` plus `KAZEE_URL`, `KAZEE_BOT_TOKEN`, `KAZEE_BOT_USER_ID`, and `KAZEE_OWNER_USER_ID` in `~/.open-claudia/.env`, or run `/channel add kazee` from an existing chat and follow the wizard.
126
+
101
127
  ## Run
102
128
 
103
129
  ```bash
104
- open-claudia start # Start the bot
105
- open-claudia stop # Stop the bot
106
- open-claudia status # Check if running (shows PID)
107
- open-claudia logs # View recent logs
108
- open-claudia auth # Manage chat authorizations
130
+ open-claudia start # Start the bot (--web adds the web UI, --quick skips slow health checks)
131
+ open-claudia web # Start with web UI for setup/config
132
+ open-claudia stop # Stop the bot
133
+ open-claudia status # Check if running (shows PID)
134
+ open-claudia health # Run environment health checks (-v for detail)
135
+ open-claudia logs # View recent logs
136
+ open-claudia auth # Manage chat authorizations
109
137
  ```
110
138
 
111
139
  If installed as a background service, the bot starts automatically on login and restarts on crash.
112
140
 
113
- ## Telegram Commands
141
+ ## Chat Commands
114
142
 
115
- ### Backend Switching
143
+ ### Backend switching
116
144
 
117
145
  | Command | Description |
118
146
  |---------|-------------|
119
- | `/cursor` | Switch to Cursor Agent backend |
120
147
  | `/claude` | Switch to Claude Code backend |
148
+ | `/cursor` | Switch to Cursor Agent backend |
121
149
  | `/codex` | Switch to OpenAI Codex backend |
122
150
  | `/backend` | Show current backend with picker |
123
151
 
124
152
  Each backend keeps its own persistent session. Switching doesn't lose your place — you can go back and forth freely.
125
153
 
126
- ### Session Management
154
+ ### Session management
127
155
 
128
156
  | Command | Description |
129
157
  |---------|-------------|
130
- | `/session` | Pick a project to work on |
158
+ | `/session [<project>]` | Pick a project to work on |
131
159
  | `/sessions` | List past conversations for current project |
132
160
  | `/projects` | Browse all workspace projects |
133
161
  | `/continue` | Resume last conversation explicitly |
162
+ | `/compact` | Summarize conversation context now |
163
+ | `/compactwindow [<tokens> \| off \| default]` | Set the auto-compact token threshold |
134
164
  | `/end` | End current session |
135
165
 
136
166
  When you select a project, the last conversation is automatically resumed. Tap "New conversation" to start fresh.
@@ -139,74 +169,145 @@ When you select a project, the last conversation is automatically resumed. Tap "
139
169
 
140
170
  | Command | Description |
141
171
  |---------|-------------|
142
- | `/model` | Switch model (opus / sonnet / haiku for Claude; any model flag for Cursor) |
143
- | `/effort` | Set effort level (low / medium / high / max) |
144
- | `/budget` | Set max spend for next task (e.g. `/budget 0.50`) — Claude only |
172
+ | `/model [<model>]` | Switch model (opus / sonnet / haiku for Claude; any model flag for Cursor/Codex) |
173
+ | `/effort [low\|medium\|high\|max]` | Set effort level |
174
+ | `/budget [$N]` | Set max spend for next task — Claude only |
145
175
  | `/plan` | Toggle plan mode — `--permission-mode plan` (Claude) / `--mode plan` (Cursor) |
146
176
  | `/ask` | Toggle ask mode — read-only Q&A, no edits (Cursor Agent only) |
147
- | `/compact` | Summarize conversation context |
148
- | `/worktree` | Toggle isolated git branch — Claude only |
177
+ | `/worktree` | Toggle isolated git branch |
149
178
  | `/mode` | Switch between direct and agent bot modes |
150
179
  | `/status` | Show current session, backend, and settings |
180
+ | `/usage` | Token usage and cost for this session |
151
181
  | `/doctor` / `/requirements` | Check Node, CLI binaries/versions/auth, voice stack, and writable paths |
152
182
 
153
- ### Automation
183
+ ### Memory & skills
154
184
 
155
185
  | Command | Description |
156
186
  |---------|-------------|
157
- | `/cron` | Manage scheduled tasks |
158
- | `/vault` | Manage encrypted credentials (password required) |
187
+ | `/learn [<hint>]` | Capture the last piece of work into the matching context pack |
188
+ | `/skills [show\|remove <name>]` | List, show, or remove legacy learned skills |
159
189
  | `/soul` | View/edit assistant identity and personality |
160
190
 
161
- ### Claude Code Auth
191
+ ### Automation
162
192
 
163
193
  | Command | Description |
164
194
  |---------|-------------|
165
- | `/auth_status` | Runs `claude auth status` and reports redacted status plus whether the bot has an OAuth token configured |
166
- | `/login` | Starts `claude auth login --claudeai --email sumeet@inet.africa`, sends the login URL/code, and accepts paste-back codes |
167
- | `/setup_token` | Starts `claude setup-token`; if Claude prints an OAuth token, Open Claudia stores it without echoing it |
168
- | `/use_oauth_token <token>` | Stores `CLAUDE_CODE_OAUTH_TOKEN` in config for launchd/non-interactive Claude runs; the Telegram message is deleted when possible |
169
- | `/use_oauth_token` | Secure pending mode: send the token as the next message and it will be deleted/stored without echo |
170
- | `/clear_oauth_token` | Removes the stored OAuth token from config/process, and from vault if it is unlocked |
171
-
172
- Tokens are redacted from Telegram output and logs. If the encrypted vault is unlocked, `/use_oauth_token` also mirrors the token into the vault, but `.env` storage is what lets launchd pass `CLAUDE_CODE_OAUTH_TOKEN` to Claude without relying on macOS Keychain.
195
+ | `/cron [add\|remove ...]` | Manage scheduled tasks |
196
+ | `/vault [create\|get\|set\|remove\|lock]` | Manage encrypted credentials (password required) |
173
197
 
174
- ### Codex Auth
198
+ ### Team & access
175
199
 
176
200
  | Command | Description |
177
201
  |---------|-------------|
178
- | `/codex_auth_status` | Runs `codex login status` and reports redacted status/version |
179
- | `/codex_login` | Starts `codex login --device-auth` and sends any login URL/device code printed by the CLI |
180
- | `/codex_setup_token` | Secure paste mode for an OpenAI API key; the message is deleted and passed to `codex login --with-api-key` without echoing it |
181
- | `/codex_setup_token <key>` | Same as above, but inline; the command message is deleted when possible |
182
- | `/cancel_codex_auth` | Cancels a pending Codex auth flow |
202
+ | `/auth [list \| revoke <chatId>]` | Request access; owner lists/revokes |
203
+ | `/people [show\|note\|link\|unlink\|add\|remove ...]` | Manage the team roster |
204
+ | `/intros [approve\|reject <id>]` | Approve/reject introductions from unknown chats |
205
+ | `/link [<chat-id>] <email-or-id>` | Link a chat to a canonical user id |
206
+ | `/links` | List identity links (owner) |
207
+ | `/whoami` | Show your canonical user id |
208
+ | `/channel [add kazee \| remove <id>]` | Add or remove channels |
183
209
 
184
- Codex tokens/API keys are redacted from Telegram output and logs. Device login support depends on the installed Codex CLI; if it requires a real TTY, Open Claudia will say so and suggest `/codex_setup_token` or an SSH/terminal fallback.
210
+ ### Claude Code auth
185
211
 
186
- ### Requirements Doctor
212
+ | Command | Description |
213
+ |---------|-------------|
214
+ | `/auth_status` | Reports redacted Claude auth status and whether an OAuth token is configured |
215
+ | `/login` | Starts a Claude login flow, sends the URL/code, accepts paste-back codes (`/auth_code <code>`, `/cancel_auth`) |
216
+ | `/setup_token` | Runs `claude setup-token`; the resulting OAuth token is stored without echoing it |
217
+ | `/use_oauth_token [<token>]` | Stores `CLAUDE_CODE_OAUTH_TOKEN` for non-interactive runs; the message is deleted when possible. Without an argument, send the token as the next message |
218
+ | `/clear_oauth_token` | Removes the stored OAuth token |
187
219
 
188
- `/doctor` (alias: `/requirements`) gives a mobile-friendly checklist after upgrades or whenever something feels broken:
220
+ Tokens are redacted from chat output and logs.
189
221
 
190
- - Node.js version
191
- - Claude CLI version/auth
192
- - Cursor Agent version/status when installed/configured
193
- - Codex CLI version/auth when installed/configured
194
- - ffmpeg/Whisper/model paths when voice is configured
195
- - Workspace and config directory writability
222
+ ### Codex auth
196
223
 
197
- `/upgrade` also includes a post-upgrade doctor summary before restarting.
224
+ | Command | Description |
225
+ |---------|-------------|
226
+ | `/codex_auth_status` | Reports redacted Codex auth status/version |
227
+ | `/codex_login` | Starts `codex login --device-auth` and relays the URL/device code |
228
+ | `/codex_setup_token [<key>]` | Secure paste mode for an OpenAI API key (message deleted, never echoed) |
229
+ | `/cancel_codex_auth` | Cancels a pending Codex auth flow |
198
230
 
199
231
  ### System
200
232
 
201
233
  | Command | Description |
202
234
  |---------|-------------|
203
235
  | `/version` | Show current running version |
204
- | `/doctor` / `/requirements` | Check installed CLI requirements/auth and writable paths |
205
- | `/upgrade` | Upgrade to latest version and restart |
236
+ | `/upgrade` | Upgrade to latest version and restart (includes a post-upgrade doctor summary) |
206
237
  | `/restart` | Restart the bot |
207
238
  | `/stop` | Cancel a running task |
208
239
  | `/help` | Show all commands |
209
240
 
241
+ ## Memory & Long-Term Context
242
+
243
+ Open Claudia layers three memory systems on top of the backend's native sessions:
244
+
245
+ **Context packs** (`~/.open-claudia/packs/<dir>/PACK.md`) are living per-topic documents with four sections: *Stance* (how to think about the topic — your preferences and hard rules), *Procedure* (verified how-to steps), *State* (where work stands now), and *Journal* (a dated one-line log of past sessions). Incoming messages are matched against packs (FTS5, field-weighted so a stray word can't drag a pack in) and hits are injected into the agent's context — mention a project anywhere and the assistant picks up its train of thought, decisions, and history without you re-explaining. After every substantial turn, a background reviewer on a cheap model updates the relevant pack (or creates one for a genuinely new topic). Every change is announced in chat.
246
+
247
+ **Entity memory** (`~/.open-claudia/entities/<slug>.md`) works the same way for the people, places, projects, orgs, and systems you mention — who they are, current truth, and a dated observation log. Mentioning a name injects its note.
248
+
249
+ **Dream consolidation** — while the per-turn reviewer takes quick notes, *dream* is the slow overnight pass (default 4am, on a stronger model): it merges packs that drifted into the same topic, builds parent/sub pack trees with umbrella summaries, tightens descriptions and tags so the router matches with less noise, dedupes entities, and cross-links notes. Anything merged away is backed up under `~/.open-claudia/backup/dream-<stamp>/` first, and every dream that changes something reports in chat. Configure with `DREAM_CRON` / `DREAM_MODEL`, disable with `DREAM=off`.
250
+
251
+ **Personality** — your `soul.md` holds identity and hard rules; `~/.open-claudia/persona.md` holds the voice on top — tone, quirks, emoji habits. It feeds into the system prompt and the dream pass may evolve it gently (bounded, backed up, announced). Edit it directly any time.
252
+
253
+ **Transcript index** — every project conversation is logged (redacted) to JSONL outside the repo and indexed in SQLite FTS5, giving the agent ranked search over your full history.
254
+
255
+ ```bash
256
+ open-claudia pack list|show <dir>|match "<text>"|migrate|remove <dir>|reindex
257
+ open-claudia entity list|show <slug>|match "<text>"|note <name> "<text>"|remove <slug>|reindex
258
+ open-claudia dream [--dry-run] # run the consolidation pass now
259
+ open-claudia transcript-search "<query>" # alias: ts; --all for every project
260
+ open-claudia transcript-window "<pattern>" # alias: tw; hits with surrounding turns
261
+ ```
262
+
263
+ `pack migrate` folds legacy `~/.claude/skills` into packs (originals backed up, never deleted) — run it once after upgrading from a pre-2.5 version.
264
+
265
+ When a conversation grows past the auto-compact threshold, the bot summarizes it proactively: the full brief is archived to `~/.open-claudia/briefs/` and a condensed version seeds the fresh session, so long-running work never hits a context wall.
266
+
267
+ ## Background Work
268
+
269
+ The agent can schedule its own future work — these survive bot restarts:
270
+
271
+ ```bash
272
+ open-claudia schedule-wakeup <30s|5m|2h|1d|ISO-date> "<prompt>" # one-shot; resumes the session
273
+ open-claudia cron-add "<5-field cron>" "<prompt>" # recurring
274
+ open-claudia cron-list / cron-remove <id>
275
+ ```
276
+
277
+ A persistent per-channel task tree tracks multi-turn work (plans with subtasks; completed items are removed automatically):
278
+
279
+ ```bash
280
+ open-claudia task plan "<title>" "<step 1>" "<step 2>" [--description "..."]
281
+ open-claudia task add|list|start <id>|done <id>|remove <id>
282
+ ```
283
+
284
+ And for side research that shouldn't pollute the main conversation:
285
+
286
+ ```bash
287
+ open-claudia agent "<prompt>" [--role "<role>"] # throwaway sub-agent, output on stdout
288
+ ```
289
+
290
+ ## Team & Cross-Channel
291
+
292
+ The setup owner is automatically authorized. To add more users:
293
+
294
+ - **From chat**: unknown users who message the bot go through an intro flow — the owner gets an approve/reject prompt (`/intros`). Or they send `/auth` for a direct request.
295
+ - **From the terminal**: `open-claudia auth` shows authorized chats and pending requests.
296
+
297
+ Each chat defaults to `telegram:<chatId>` as its user id. Link chats to a canonical id to share sessions and history across channels:
298
+
299
+ ```text
300
+ /link sumeet@example.com
301
+ /whoami
302
+ ```
303
+
304
+ The bot keeps a people roster (`/people`, or `open-claudia people list|show|note|link`) and can relay messages between team members with provenance and an audit trail:
305
+
306
+ ```bash
307
+ open-claudia send-to --person "<name>" "<message>"
308
+ open-claudia recent --person "<name>" [--limit 20] # read recent activity from another chat
309
+ ```
310
+
210
311
  ## Backend Comparison
211
312
 
212
313
  | | Claude Code | Cursor Agent | OpenAI Codex |
@@ -228,11 +329,13 @@ All three backends output structured JSON which Open Claudia parses for real-tim
228
329
 
229
330
  Send any file to the bot — PDFs, code files, documents, images. Files are saved to `~/.open-claudia/files/` with their original names. The agent reads the file and responds based on content.
230
331
 
231
- Add a caption to your file to give the agent specific instructions:
332
+ Add a caption to give the agent specific instructions:
232
333
  - Send a PDF with caption "summarize the key findings"
233
334
  - Send a code file with caption "find bugs in this"
234
335
  - Send a screenshot with caption "implement this design"
235
336
 
337
+ The agent can also send files back — documents, photos with inline previews, and voice clips — directly from within a task.
338
+
236
339
  ## Voice Notes
237
340
 
238
341
  Requires [whisper.cpp](https://github.com/ggerganov/whisper.cpp) and ffmpeg:
@@ -246,42 +349,22 @@ sudo apt install ffmpeg
246
349
  # Build whisper.cpp from source: https://github.com/ggerganov/whisper.cpp
247
350
  ```
248
351
 
249
- Voice notes are transcribed locally — nothing sent to external services.
250
-
251
- ## Multi-User Authorization
252
-
253
- The setup owner is automatically authorized. To add more users:
254
-
255
- **From Telegram** (unauthorized users):
256
- - Send `/auth` to the bot — the owner gets an Approve/Deny button prompt in Telegram
257
-
258
- **From the terminal** (owner):
259
- ```bash
260
- open-claudia auth
261
- ```
262
-
263
- This shows authorized chats, pending requests, and lets you approve/deny or add new users with code verification. Telegram button approvals use the same `auth.json` authorization list.
264
-
265
- Authorized chats are separate from identity links. By default each Telegram chat uses `telegram:<chatId>` as its user id. To share one session/history across channels later, link the chat to a canonical id:
266
-
267
- ```text
268
- /link sumeet@inet.africa
269
- /whoami
270
- ```
271
-
272
- The owner can link another Telegram chat with `/link <chatId> <email-or-user-id>` and list explicit links with `/links`.
352
+ Voice notes are transcribed locally — nothing sent to external services. On macOS, replies to voice messages come back as voice notes too.
273
353
 
274
354
  ## How It Works
275
355
 
276
356
  ```
277
- Phone (Telegram) --> Bot (Node.js) --> Claude Code CLI --> Your codebase
278
- --> Cursor Agent CLI -->
279
- <-- <-- <--
357
+ Phone (Telegram / Kazee) --> Bot (Node.js) --> Claude Code CLI --> Your codebase
358
+ --> Cursor Agent CLI -->
359
+ --> OpenAI Codex CLI -->
360
+ <-- <-- <--
280
361
  ```
281
362
 
282
- The bot spawns the active backend CLI in headless mode (`--print` / `-p`) for each message, streaming `stream-json`/JSONL output back to Telegram. It maintains native backend context via `--resume` and passes a system prompt that gives the agent awareness of the Telegram environment, configuration files, and the ability to send files/images directly.
363
+ The bot spawns the active backend CLI in headless mode (`--print` / `-p`) for each message, streaming `stream-json`/JSONL output back to the chat. It maintains native backend context via `--resume` and passes a system prompt that gives the agent awareness of the chat environment, configuration files, memory systems, and the ability to send files/images directly.
283
364
 
284
- Use `/cursor`, `/claude`, or `/codex` to switch which CLI handles your messages. Each maintains its own native session ID. Open Claudia does not summarize one backend into another during switches; instead it records a redacted project transcript outside the repo and injects a small pointer telling fresh/switched sessions to tail or search that transcript only if needed.
365
+ The appended system prompt is byte-stable within a session to maximize Anthropic prompt-cache hits; per-turn state (vault status, pending tasks, matched packs/entities) rides the user message instead, where it is always uncached anyway.
366
+
367
+ Open Claudia does not summarize one backend into another during switches; instead it records a redacted project transcript outside the repo and injects a small pointer telling fresh/switched sessions to search it only if needed.
285
368
 
286
369
  ## Configuration Files
287
370
 
@@ -289,36 +372,57 @@ All stored in `~/.open-claudia/`:
289
372
 
290
373
  | File | Purpose |
291
374
  |------|---------|
292
- | `.env` | Telegram token, workspace path, binary paths (`CLAUDE_PATH`, `CURSOR_PATH`) |
375
+ | `.env` | Tokens, workspace path, binary paths, channel config |
293
376
  | `auth.json` | Authorized users and pending requests |
294
- | `identities.json` | Channel-to-canonical-user mappings such as `telegram:<chatId> -> user@example.com` |
377
+ | `identities.json` | Channel-to-canonical-user mappings |
378
+ | `people.json` / `intros.json` | Team roster and pending introductions |
295
379
  | `vault.enc` | Encrypted credential store |
296
- | `soul.md` | Assistant identity and personality (editable via `/soul`) |
297
- | `crons.json` | Scheduled tasks |
380
+ | `soul.md` | Assistant identity and hard rules (editable via `/soul`) |
381
+ | `persona.md` | Assistant voice and quirks (feeds the system prompt; evolved gently by dream) |
382
+ | `crons.json` / `jobs.json` | Recurring crons and one-shot wakeups |
383
+ | `tasks/` | Persistent per-channel task trees |
384
+ | `packs/` | Context packs (living topic documents) + FTS index |
385
+ | `entities/` | Entity notes (people/places/projects) + FTS index |
298
386
  | `sessions.json` | Per-project conversation history |
299
387
  | `state.json` | Current session state including active backend (survives restarts) |
388
+ | `transcripts/` | Redacted project-scoped JSONL transcripts + FTS index |
389
+ | `briefs/` | Archived full compaction briefs |
390
+ | `audit.log` | Relay/intro/auth audit trail |
300
391
  | `bot.log` | Bot logs |
301
- | `transcripts/` | Redacted project-scoped JSONL transcripts keyed by normalized project path hash |
302
- | `files/` | Files received from Telegram |
392
+ | `files/` | Files received from chat |
303
393
  | `media/` | Temporary media (voice notes, photos) |
394
+ | `backup/` | Backups (skills folded by `pack migrate`; packs/entities merged away by dream) |
304
395
 
305
396
  ### Environment Variables (.env)
306
397
 
307
398
  | Variable | Required | Description |
308
399
  |----------|----------|-------------|
309
- | `TELEGRAM_BOT_TOKEN` | Yes | Bot token from BotFather |
310
- | `TELEGRAM_CHAT_ID` | Yes | Comma-separated authorized chat IDs |
400
+ | `TELEGRAM_BOT_TOKEN` | Yes* | Bot token from BotFather |
401
+ | `TELEGRAM_CHAT_ID` | Yes* | Comma-separated authorized chat IDs |
402
+ | `CHANNELS` | No | Channels to start: `telegram`, `kazee`, or `telegram,kazee` (default `telegram`) |
403
+ | `KAZEE_URL` / `KAZEE_BOT_TOKEN` / `KAZEE_BOT_USER_ID` / `KAZEE_OWNER_USER_ID` | Kazee only | Kazee Chat connection |
311
404
  | `WORKSPACE` | Yes | Path to your projects directory |
312
405
  | `CLAUDE_PATH` | Yes | Path to Claude Code CLI binary |
313
- | `CURSOR_PATH` | No | Path to Cursor Agent CLI binary (auto-detected if in PATH) |
314
- | `CODEX_PATH` | No | Path to OpenAI Codex CLI binary (auto-detected if in PATH) |
315
- | `PROJECT_TRANSCRIPTS` | No | Enable redacted project transcript JSONL files outside repos (default `true`) |
316
- | `TRANSCRIPT_MAX_ENTRY_CHARS` | No | Max redacted text stored per transcript entry before truncation (default `12000`) |
317
- | `TRANSCRIPTS_DIR` | No | Override transcript storage directory (default `~/.open-claudia/transcripts`) |
318
- | `WHISPER_CLI` | No | Path to whisper.cpp binary |
319
- | `WHISPER_MODEL` | No | Whisper model to use |
406
+ | `CURSOR_PATH` / `CODEX_PATH` | No | Paths to optional backend CLIs (auto-detected if in PATH) |
407
+ | `CLAUDE_CODE_OAUTH_TOKEN` | No | OAuth token for non-interactive Claude runs (set via `/use_oauth_token`) |
408
+ | `CLAUDE_MODEL` | No | Default Claude model |
409
+ | `AUTO_COMPACT_TOKENS` | No | Auto-compact threshold in tokens (also settable via `/compactwindow`) |
410
+ | `PROJECT_TRANSCRIPTS` | No | Enable redacted project transcripts (default `true`) |
411
+ | `TRANSCRIPT_MAX_ENTRY_CHARS` | No | Max chars per transcript entry (default `12000`) |
412
+ | `TRANSCRIPTS_DIR` / `PACKS_DIR` / `ENTITIES_DIR` | No | Override storage directories |
413
+ | `PACK_REVIEW` | No | `off` disables the post-turn pack/entity reviewer (default on) |
414
+ | `PACK_REVIEW_MODEL` | No | Model for the reviewer (default `haiku`) |
415
+ | `PACK_MATCH_THRESHOLD` / `ENTITY_MATCH_THRESHOLD` | No | Router match score thresholds (default `2`) |
416
+ | `DREAM` | No | `off` disables the nightly memory consolidation pass (default on) |
417
+ | `DREAM_CRON` | No | Schedule for the dream pass (default `0 4 * * *`) |
418
+ | `DREAM_MODEL` | No | Model for the dream pass (default `sonnet`) |
419
+ | `PERSONA_FILE` | No | Override the persona file location |
420
+ | `WEB_UI` / `WEB_PORT` / `WEB_PASSWORD` | No | Web UI toggle, port, and password |
421
+ | `WHISPER_CLI` / `WHISPER_MODEL` | No | whisper.cpp binary and model for voice notes |
320
422
  | `FFMPEG` | No | Path to ffmpeg binary |
321
423
 
424
+ \* Required for the Telegram channel.
425
+
322
426
  ## Background Service
323
427
 
324
428
  ### macOS (launchd)
@@ -346,14 +450,7 @@ sudo systemctl status claude-telegram-bot
346
450
 
347
451
  ## Auto-Updates
348
452
 
349
- The bot checks npm for new versions every 5 minutes. When an update is available, you get a Telegram notification:
350
-
351
- > "Hey! A new version is available (v1.10.0). You're on v1.9.2."
352
-
353
- Send `/upgrade` to update. The bot will:
354
- 1. Download and install the new version
355
- 2. Go offline briefly
356
- 3. Restart and notify you it's back
453
+ The bot checks npm for new versions every 5 minutes. When an update is available, you get a chat notification. Send `/upgrade` to update — the bot installs the new version, restarts, runs a doctor check, and notifies you it's back.
357
454
 
358
455
  For direct npm installs, `/upgrade` updates Open Claudia itself and does not install optional backend CLIs such as Codex or Cursor Agent. Container deployments should roll out a new Docker image when bundled CLI tools change.
359
456
 
@@ -367,7 +464,7 @@ Schedule recurring tasks:
367
464
  /cron add "*/30 * * * *" myproject "Health check: verify the API is responding"
368
465
  ```
369
466
 
370
- Presets available via `/cron` menu.
467
+ Presets available via `/cron` menu. The agent can also schedule its own jobs with `open-claudia cron-add` / `schedule-wakeup` (see Background Work).
371
468
 
372
469
  ## Vault
373
470
 
package/bin/cli.js CHANGED
@@ -274,11 +274,26 @@ switch (command) {
274
274
  break;
275
275
  }
276
276
 
277
+ case "pack": {
278
+ require("./pack").run(args.slice(1));
279
+ break;
280
+ }
281
+
282
+ case "entity": {
283
+ require("./entity").run(args.slice(1));
284
+ break;
285
+ }
286
+
277
287
  case "agent": {
278
288
  require("./agent").run(args.slice(1));
279
289
  break;
280
290
  }
281
291
 
292
+ case "dream": {
293
+ require("./dream").run(args.slice(1));
294
+ break;
295
+ }
296
+
282
297
  case "people": {
283
298
  require("./people").run(args.slice(1));
284
299
  break;
@@ -320,6 +335,9 @@ Memory tools:
320
335
  (alias: ts; --all for every project; --help for options)
321
336
  open-claudia transcript-window <pattern> Search project transcript, show hits with context
322
337
  (alias: tw; --help for options)
338
+ open-claudia pack list|show|match|migrate Context packs: living topic docs (skills + memory)
339
+ open-claudia entity list|show|match|note Entity notes: people/places/projects memory
340
+ open-claudia dream [--dry-run] Run the memory consolidation pass now
323
341
 
324
342
  Background work (only inside an active bot-spawned task):
325
343
  open-claudia schedule-wakeup <when> "<prompt>" One-shot future wake-up; resumes session
package/bin/dream.js ADDED
@@ -0,0 +1,51 @@
1
+ // open-claudia dream [--dry-run]
2
+ // Manually trigger the memory consolidation pass (normally runs on the
3
+ // quiet-hours cron inside the bot). Prints the report; from inside a
4
+ // bot-spawned task the parent agent can relay it to chat.
5
+
6
+ const path = require("path");
7
+
8
+ const HELP = `
9
+ Run the dream memory-consolidation pass now.
10
+
11
+ open-claudia dream [--dry-run]
12
+
13
+ Reviews all context packs and entities with a stronger model (DREAM_MODEL,
14
+ default sonnet): merges duplicate packs, builds umbrella/parent trees,
15
+ tightens descriptions and tags, dedupes entities, cross-links notes, and
16
+ may gently evolve the persona. Merged-away packs/entities are backed up
17
+ under ~/.open-claudia/backup/dream-<stamp>/ first.
18
+
19
+ --dry-run Ask the model for the decision and print it without applying.
20
+ `;
21
+
22
+ async function run(args) {
23
+ if (args[0] === "--help" || args[0] === "help") { console.log(HELP); process.exit(0); }
24
+ const dream = require(path.join(__dirname, "..", "core", "dream"));
25
+
26
+ if (args.includes("--dry-run")) {
27
+ const { spawnSubagent } = require(path.join(__dirname, "..", "core", "subagent"));
28
+ console.error("Dreaming (dry run)… this can take a minute or two.");
29
+ try {
30
+ const { text } = await spawnSubagent(dream.buildDreamPrompt(), {
31
+ model: dream.DREAM_MODEL,
32
+ timeoutMs: 8 * 60 * 1000,
33
+ systemPrompt: "You are a background memory consolidation process. Reply with ONLY the requested JSON object. No prose, no markdown, no tool use.",
34
+ });
35
+ const decision = dream.parseDream(text);
36
+ if (!decision) { console.error("Unparseable model output:"); console.log(text); process.exit(1); }
37
+ console.log(JSON.stringify(decision, null, 2));
38
+ process.exit(0);
39
+ } catch (e) { console.error(`dream failed: ${e.message}`); process.exit(1); }
40
+ }
41
+
42
+ console.error("Dreaming… this can take a minute or two.");
43
+ try {
44
+ const res = await dream.runDream({ trigger: "cli" });
45
+ if (res.skipped) { console.log(`Skipped: ${res.skipped}`); process.exit(0); }
46
+ console.log(res.message || `💤 Nothing needed tidying — memory is in good shape. (${res.report || "no report"})`);
47
+ process.exit(0);
48
+ } catch (e) { console.error(`dream failed: ${e.message}`); process.exit(1); }
49
+ }
50
+
51
+ module.exports = { run, HELP };