@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 +24 -0
- package/README.md +217 -120
- package/bin/cli.js +18 -0
- package/bin/dream.js +51 -0
- package/bin/entity.js +77 -0
- package/bin/pack.js +100 -0
- package/bot.js +2 -0
- package/core/dream.js +332 -0
- package/core/entities.js +329 -0
- package/core/pack-review.js +224 -0
- package/core/packs.js +334 -0
- package/core/persona.js +51 -0
- package/core/runner.js +26 -0
- package/core/subagent.js +3 -2
- package/core/system-prompt.js +130 -15
- package/package.json +1 -1
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-
|
|
12
|
-
- **
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
- **
|
|
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
|
|
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
|
|
20
|
-
|
|
21
|
-
|
|
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** —
|
|
25
|
-
- **
|
|
26
|
-
- **
|
|
27
|
-
- **
|
|
28
|
-
- **
|
|
29
|
-
- **Cross-platform** —
|
|
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
|
|
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
|
|
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
|
|
105
|
-
open-claudia
|
|
106
|
-
open-claudia
|
|
107
|
-
open-claudia
|
|
108
|
-
open-claudia
|
|
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
|
-
##
|
|
141
|
+
## Chat Commands
|
|
114
142
|
|
|
115
|
-
### Backend
|
|
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
|
|
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
|
|
144
|
-
| `/budget` | Set max spend for next task
|
|
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
|
-
| `/
|
|
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
|
-
###
|
|
183
|
+
### Memory & skills
|
|
154
184
|
|
|
155
185
|
| Command | Description |
|
|
156
186
|
|---------|-------------|
|
|
157
|
-
| `/
|
|
158
|
-
| `/
|
|
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
|
-
###
|
|
191
|
+
### Automation
|
|
162
192
|
|
|
163
193
|
| Command | Description |
|
|
164
194
|
|---------|-------------|
|
|
165
|
-
| `/
|
|
166
|
-
| `/
|
|
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
|
-
###
|
|
198
|
+
### Team & access
|
|
175
199
|
|
|
176
200
|
| Command | Description |
|
|
177
201
|
|---------|-------------|
|
|
178
|
-
| `/
|
|
179
|
-
| `/
|
|
180
|
-
| `/
|
|
181
|
-
| `/
|
|
182
|
-
| `/
|
|
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
|
-
|
|
210
|
+
### Claude Code auth
|
|
185
211
|
|
|
186
|
-
|
|
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
|
-
|
|
220
|
+
Tokens are redacted from chat output and logs.
|
|
189
221
|
|
|
190
|
-
|
|
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
|
-
|
|
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
|
-
| `/
|
|
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
|
|
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
|
|
278
|
-
|
|
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
|
|
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
|
-
|
|
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` |
|
|
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
|
|
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
|
|
297
|
-
| `
|
|
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
|
-
| `
|
|
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 |
|
|
314
|
-
| `
|
|
315
|
-
| `
|
|
316
|
-
| `
|
|
317
|
-
| `
|
|
318
|
-
| `
|
|
319
|
-
| `
|
|
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
|
|
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 };
|