clementine-agent 1.0.7 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -7,11 +7,15 @@
7
7
  ╚═════╝╚══════╝╚══════╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚═╝╚═╝ ╚═══╝╚══════╝
8
8
  ```
9
9
 
10
- A persistent, ever-learning personal AI assistant that runs as a background daemon on macOS.
10
+ A persistent, ever-learning personal AI assistant that runs as a background daemon on macOS and Linux.
11
11
  Built on the [Claude Code SDK](https://docs.anthropic.com/en/docs/claude-code-sdk), Obsidian-compatible vault, and SQLite FTS5.
12
12
 
13
13
  Connects to Discord, Slack, Telegram, WhatsApp, and webhooks. Remembers everything. Runs 24/7.
14
14
 
15
+ **Requirements:** Node.js 20+ (22 recommended) · [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code) authenticated · macOS or Linux.
16
+
17
+ **Contents:** [How it works](#how-it-works) · [Install](#install-recommended) · [Architecture](#architecture) · [CLI](#cli-reference) · [Configuration](#configuration) · [Channels](#channels) · [Agents & Teams](#agents--teams) · [Cron](#scheduled-tasks--cron-jobs) · [Unleashed mode](#unleashed-mode) · [Self-improvement](#self-improvement) · [Vault](#vault) · [Development](#development) · [Troubleshooting](#troubleshooting)
18
+
15
19
  ---
16
20
 
17
21
  ## How it works
@@ -63,45 +67,55 @@ The result: Clementine gets better the more you talk to it.
63
67
 
64
68
  ---
65
69
 
66
- ## Prerequisites
67
-
68
- - **Node.js 20-24 LTS** — `nvm install 22`
69
- - **Claude Code CLI** — already installed if you're reading this in Claude Code
70
+ ## Install (recommended)
70
71
 
71
- ## Quick start
72
+ Runtime: **Node.js 22 (recommended) or Node.js 20+**.
72
73
 
73
- **Option A — npm (recommended):**
74
74
  ```bash
75
- npm install -g clementine-agent
75
+ npm install -g clementine-agent@latest
76
76
  clementine setup
77
77
  ```
78
78
 
79
- **Option B — from source (for development):**
79
+ After setup:
80
+
80
81
  ```bash
81
- git clone https://github.com/Natebreynolds/Clementine-AI-Assistant.git clementine
82
- cd clementine
83
- bash install.sh
82
+ clementine launch # start as background daemon
83
+ clementine status # verify it's running
84
+ clementine dashboard # open the web command center
84
85
  ```
85
86
 
86
- The install script handles everything: system dependencies (redis, libomp, build tools), npm packages, TypeScript build, global CLI install, and launches the setup wizard. Safe to re-run — skips anything already installed.
87
+ Already installed? Update in place with `clementine update`.
87
88
 
88
- The setup wizard auto-generates a Discord bot invite URL from your token and offers to open it in your browser — no need to visit the Developer Portal manually.
89
+ ### Troubleshooting
89
90
 
90
- After setup:
91
+ **`EACCES: permission denied` on `npm install -g`.** Your Node was installed system-wide (`/usr/local/lib/...`) and npm can't write there without sudo. Fix it once, permanently:
91
92
 
92
93
  ```bash
93
- clementine launch # start as background daemon
94
- clementine status # verify it's running
95
- clementine dashboard # open the web command center
94
+ mkdir -p ~/.npm-global
95
+ npm config set prefix ~/.npm-global
96
+ echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.zshrc && source ~/.zshrc
97
+ npm install -g clementine-agent@latest
96
98
  ```
97
99
 
98
- Already have it? Update in place:
100
+ Or install Node via [nvm](https://github.com/nvm-sh/nvm) — user-scoped by default, no permission issues ever.
99
101
 
102
+ **`clementine: command not found` after install succeeded.** Run `npm config get prefix` — its `/bin` directory needs to be on your `PATH`. Add `export PATH="$(npm config get prefix)/bin:$PATH"` to your shell profile.
103
+
104
+ **Node version too old.** Install via nvm:
100
105
  ```bash
101
- clementine update
106
+ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
107
+ nvm install 22
108
+ ```
109
+
110
+ ### Install from source (for development)
111
+
112
+ ```bash
113
+ git clone https://github.com/Natebreynolds/Clementine-AI-Assistant.git clementine
114
+ cd clementine
115
+ bash install.sh
102
116
  ```
103
117
 
104
- That's it. Clementine is now running, connected to your configured channels, and learning.
118
+ Handles system dependencies (redis, libomp, build tools), npm packages, TypeScript build, global CLI install, and launches the setup wizard. Safe to re-run.
105
119
 
106
120
  ---
107
121
 
@@ -420,6 +434,43 @@ ENABLE_1M_CONTEXT=false # Enable 1M token context for Sonnet (toggle in dashb
420
434
 
421
435
  Secrets can also be stored in macOS Keychain (`security find-generic-password`) — Clementine checks Keychain as a fallback for any missing `.env` value.
422
436
 
437
+ ### Tuning Clementine
438
+
439
+ Clementine ships with sensible defaults. To change anything, use:
440
+
441
+ ```bash
442
+ clementine config set <KEY> <value> # writes to ~/.clementine/.env
443
+ clementine config get <KEY>
444
+ clementine config list # show all overrides
445
+ clementine restart # apply changes
446
+ ```
447
+
448
+ Your overrides live in `~/.clementine/.env` — **they survive every `npm update -g` / `clementine update`** because they're in your data home, not the package directory.
449
+
450
+ **Commonly tuned knobs:**
451
+
452
+ | Key | Default | What it does |
453
+ |-----|---------|--------------|
454
+ | `BUDGET_CHAT_USD` | `5.00` | Max spend per interactive chat message |
455
+ | `BUDGET_CRON_T1_USD` | `2.00` | Max spend per tier-1 cron job |
456
+ | `BUDGET_CRON_T2_USD` | `5.00` | Max spend per tier-2 cron job |
457
+ | `BUDGET_HEARTBEAT_USD` | `0.50` | Max spend per heartbeat tick |
458
+ | `DEFAULT_MODEL_TIER` | `sonnet` | Default model: `haiku` / `sonnet` / `opus` |
459
+ | `ENABLE_1M_CONTEXT` | `false` | Enable Sonnet 1M-token context (beta) |
460
+ | `HEARTBEAT_INTERVAL_MINUTES` | `30` | How often the agent auto-checks in |
461
+ | `HEARTBEAT_ACTIVE_START` | `8` | First hour of the active window (0–23) |
462
+ | `HEARTBEAT_ACTIVE_END` | `22` | Last hour of the active window |
463
+ | `TIMEZONE` | system TZ | IANA timezone string (e.g., `America/Los_Angeles`) |
464
+ | `ALLOW_ALL_USERS` | `false` | `true` = skip owner-only gate (trust all DMs) |
465
+ | `ASSISTANT_NAME` | `Clementine` | Display name across channels |
466
+
467
+ Example — raise the chat budget to `$10` without ever touching source:
468
+
469
+ ```bash
470
+ clementine config set BUDGET_CHAT_USD 10
471
+ clementine restart
472
+ ```
473
+
423
474
  ---
424
475
 
425
476
  ## Models
@@ -728,15 +779,6 @@ Key system files:
728
779
 
729
780
  ---
730
781
 
731
- ## Requirements
732
-
733
- - **Node.js 20-24 LTS** (for `--import` loader and `cpSync`)
734
- - **macOS** (Keychain integration, LaunchAgent — works on Linux without these)
735
- - **Claude Code CLI** installed and authenticated (`npm install -g @anthropic-ai/claude-code && claude login`)
736
- - No API key needed — authentication is handled by the Claude Code CLI
737
-
738
- ---
739
-
740
782
  ## Development
741
783
 
742
784
  ```bash
@@ -1966,7 +1966,10 @@ You have a cost budget per message — not a hard turn limit. Work until the tas
1966
1966
  const lower = errorText.toLowerCase();
1967
1967
  if (lower.includes('max_budget_usd') || lower.includes('budget')) {
1968
1968
  logger.warn({ sessionKey }, 'Chat query hit budget cap');
1969
- responseText = responseText || 'I hit the cost limit for this query. Try breaking it into smaller requests.';
1969
+ responseText = responseText || (`I hit the $${BUDGET.chat.toFixed(2)} cost cap for this query. Options:\n` +
1970
+ `• Break it into smaller requests\n` +
1971
+ `• Reply "deep mode" to queue this as a background task with a bigger budget\n` +
1972
+ `• Raise the cap permanently: \`clementine config set BUDGET_CHAT_USD 10\` then \`clementine restart\``);
1970
1973
  }
1971
1974
  else if (lower.includes('rate') && lower.includes('limit')) {
1972
1975
  hitRateLimit = true;
package/dist/config.d.ts CHANGED
@@ -39,14 +39,14 @@ export declare const OWNER_NAME: string;
39
39
  export declare function shellEscape(s: string): string;
40
40
  export declare const MODELS: Models;
41
41
  export declare const BUDGET: {
42
- readonly heartbeat: 0.5;
43
- readonly cronT1: 2;
44
- readonly cronT2: 5;
45
- readonly chat: 5;
46
- readonly unleashedPhase: undefined;
47
- readonly memoryExtraction: undefined;
48
- readonly summarization: undefined;
49
- readonly reflection: undefined;
42
+ heartbeat: number;
43
+ cronT1: number;
44
+ cronT2: number;
45
+ chat: number;
46
+ unleashedPhase: undefined;
47
+ memoryExtraction: undefined;
48
+ summarization: undefined;
49
+ reflection: undefined;
50
50
  };
51
51
  export declare const DEFAULT_MODEL_TIER: keyof Models;
52
52
  export declare const MODEL: string;
package/dist/config.js CHANGED
@@ -98,11 +98,13 @@ export const MODELS = {
98
98
  opus: 'claude-opus-4-6',
99
99
  };
100
100
  // ── Budget caps (USD per query) ──────────────────────────────────────
101
+ // User-tunable via `clementine config set BUDGET_<NAME>_USD <value>`
102
+ // (writes to ~/.clementine/.env, survives npm update -g).
101
103
  export const BUDGET = {
102
- heartbeat: 0.50, // $0.50 per heartbeat (Haiku, cheap)
103
- cronT1: 2.00, // $2 per tier-1 cron job (needs room for outlook+search)
104
- cronT2: 5.00, // $5 per tier-2 cron job
105
- chat: 5.00, // $5 per interactive chat message
104
+ heartbeat: Number(getEnv('BUDGET_HEARTBEAT_USD', '0.50')), // per heartbeat (Haiku)
105
+ cronT1: Number(getEnv('BUDGET_CRON_T1_USD', '2.00')), // per tier-1 cron job
106
+ cronT2: Number(getEnv('BUDGET_CRON_T2_USD', '5.00')), // per tier-2 cron job
107
+ chat: Number(getEnv('BUDGET_CHAT_USD', '5.00')), // per interactive chat
106
108
  unleashedPhase: undefined,
107
109
  memoryExtraction: undefined,
108
110
  summarization: undefined,
@@ -1137,7 +1137,7 @@ export function registerAdminTools(server) {
1137
1137
  // ── Source Self-Edit Tools ──────────────────────────────────────────────
1138
1138
  const SELF_IMPROVE_DIR = path.join(BASE_DIR, 'self-improve');
1139
1139
  const PENDING_SOURCE_DIR = path.join(SELF_IMPROVE_DIR, 'pending-source-changes');
1140
- server.tool('self_edit_source', 'Edit Clementine source code safely. Validates in a staging worktree, commits, builds, and triggers restart only if compilation succeeds. The daemon picks up the pending change and executes it.', {
1140
+ server.tool('self_edit_source', 'Edit most Clementine TypeScript source files (for new features or bug fixes). Validates in a staging worktree, compiles, and triggers restart on success. Blocked files: `src/config.ts`, `src/gateway/security-scanner.ts`, `src/security/scanner.ts`. Do NOT use this tool to change user-tunable settings (budget caps, model tier, heartbeat interval, timezone, channel IDs, etc.) — those live in `~/.clementine/.env` and are managed by the user via `clementine config set KEY value`, which survives `clementine update` / `npm update -g`.', {
1141
1141
  file: z.string().describe('Path relative to src/ (e.g., "channels/discord-agent-bot.ts")'),
1142
1142
  content: z.string().describe('Complete new file content'),
1143
1143
  reason: z.string().describe('Why this change is being made'),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clementine-agent",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "description": "Clementine — Personal AI Assistant (TypeScript)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",