clementine-agent 1.0.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/.env.example +44 -0
- package/LICENSE +21 -0
- package/README.md +795 -0
- package/dist/agent/agent-manager.d.ts +69 -0
- package/dist/agent/agent-manager.js +441 -0
- package/dist/agent/assistant.d.ts +225 -0
- package/dist/agent/assistant.js +3888 -0
- package/dist/agent/auto-update.d.ts +32 -0
- package/dist/agent/auto-update.js +186 -0
- package/dist/agent/daily-planner.d.ts +24 -0
- package/dist/agent/daily-planner.js +379 -0
- package/dist/agent/execution-advisor.d.ts +10 -0
- package/dist/agent/execution-advisor.js +272 -0
- package/dist/agent/hooks.d.ts +45 -0
- package/dist/agent/hooks.js +564 -0
- package/dist/agent/insight-engine.d.ts +66 -0
- package/dist/agent/insight-engine.js +225 -0
- package/dist/agent/intent-classifier.d.ts +48 -0
- package/dist/agent/intent-classifier.js +214 -0
- package/dist/agent/link-extractor.d.ts +19 -0
- package/dist/agent/link-extractor.js +90 -0
- package/dist/agent/mcp-bridge.d.ts +62 -0
- package/dist/agent/mcp-bridge.js +435 -0
- package/dist/agent/metacognition.d.ts +66 -0
- package/dist/agent/metacognition.js +221 -0
- package/dist/agent/orchestrator.d.ts +81 -0
- package/dist/agent/orchestrator.js +790 -0
- package/dist/agent/profiles.d.ts +22 -0
- package/dist/agent/profiles.js +91 -0
- package/dist/agent/prompt-cache.d.ts +24 -0
- package/dist/agent/prompt-cache.js +68 -0
- package/dist/agent/prompt-evolver.d.ts +28 -0
- package/dist/agent/prompt-evolver.js +279 -0
- package/dist/agent/role-scaffolds.d.ts +28 -0
- package/dist/agent/role-scaffolds.js +433 -0
- package/dist/agent/safe-restart.d.ts +41 -0
- package/dist/agent/safe-restart.js +150 -0
- package/dist/agent/self-improve.d.ts +66 -0
- package/dist/agent/self-improve.js +1706 -0
- package/dist/agent/session-event-log.d.ts +114 -0
- package/dist/agent/session-event-log.js +233 -0
- package/dist/agent/skill-extractor.d.ts +72 -0
- package/dist/agent/skill-extractor.js +435 -0
- package/dist/agent/source-mods.d.ts +61 -0
- package/dist/agent/source-mods.js +230 -0
- package/dist/agent/source-preflight.d.ts +25 -0
- package/dist/agent/source-preflight.js +100 -0
- package/dist/agent/stall-guard.d.ts +62 -0
- package/dist/agent/stall-guard.js +109 -0
- package/dist/agent/strategic-planner.d.ts +60 -0
- package/dist/agent/strategic-planner.js +352 -0
- package/dist/agent/team-bus.d.ts +89 -0
- package/dist/agent/team-bus.js +556 -0
- package/dist/agent/team-router.d.ts +26 -0
- package/dist/agent/team-router.js +37 -0
- package/dist/agent/tool-loop-detector.d.ts +59 -0
- package/dist/agent/tool-loop-detector.js +242 -0
- package/dist/agent/workflow-runner.d.ts +36 -0
- package/dist/agent/workflow-runner.js +317 -0
- package/dist/agent/workflow-variables.d.ts +16 -0
- package/dist/agent/workflow-variables.js +62 -0
- package/dist/channels/discord-agent-bot.d.ts +101 -0
- package/dist/channels/discord-agent-bot.js +881 -0
- package/dist/channels/discord-bot-manager.d.ts +80 -0
- package/dist/channels/discord-bot-manager.js +262 -0
- package/dist/channels/discord-utils.d.ts +51 -0
- package/dist/channels/discord-utils.js +293 -0
- package/dist/channels/discord.d.ts +12 -0
- package/dist/channels/discord.js +1832 -0
- package/dist/channels/slack-agent-bot.d.ts +73 -0
- package/dist/channels/slack-agent-bot.js +320 -0
- package/dist/channels/slack-bot-manager.d.ts +66 -0
- package/dist/channels/slack-bot-manager.js +236 -0
- package/dist/channels/slack-utils.d.ts +39 -0
- package/dist/channels/slack-utils.js +189 -0
- package/dist/channels/slack.d.ts +11 -0
- package/dist/channels/slack.js +196 -0
- package/dist/channels/telegram.d.ts +10 -0
- package/dist/channels/telegram.js +235 -0
- package/dist/channels/webhook.d.ts +9 -0
- package/dist/channels/webhook.js +78 -0
- package/dist/channels/whatsapp.d.ts +11 -0
- package/dist/channels/whatsapp.js +181 -0
- package/dist/cli/chat.d.ts +14 -0
- package/dist/cli/chat.js +220 -0
- package/dist/cli/cron.d.ts +17 -0
- package/dist/cli/cron.js +552 -0
- package/dist/cli/dashboard.d.ts +15 -0
- package/dist/cli/dashboard.js +17677 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.js +2474 -0
- package/dist/cli/routes/delegations.d.ts +19 -0
- package/dist/cli/routes/delegations.js +154 -0
- package/dist/cli/routes/digest.d.ts +17 -0
- package/dist/cli/routes/digest.js +375 -0
- package/dist/cli/routes/goals.d.ts +14 -0
- package/dist/cli/routes/goals.js +258 -0
- package/dist/cli/routes/workflows.d.ts +18 -0
- package/dist/cli/routes/workflows.js +97 -0
- package/dist/cli/setup.d.ts +8 -0
- package/dist/cli/setup.js +619 -0
- package/dist/cli/tunnel.d.ts +35 -0
- package/dist/cli/tunnel.js +141 -0
- package/dist/config.d.ts +145 -0
- package/dist/config.js +278 -0
- package/dist/events/bus.d.ts +43 -0
- package/dist/events/bus.js +136 -0
- package/dist/gateway/cron-scheduler.d.ts +166 -0
- package/dist/gateway/cron-scheduler.js +1767 -0
- package/dist/gateway/delivery-queue.d.ts +30 -0
- package/dist/gateway/delivery-queue.js +110 -0
- package/dist/gateway/heartbeat-scheduler.d.ts +99 -0
- package/dist/gateway/heartbeat-scheduler.js +1298 -0
- package/dist/gateway/heartbeat.d.ts +3 -0
- package/dist/gateway/heartbeat.js +3 -0
- package/dist/gateway/lanes.d.ts +24 -0
- package/dist/gateway/lanes.js +76 -0
- package/dist/gateway/notifications.d.ts +29 -0
- package/dist/gateway/notifications.js +75 -0
- package/dist/gateway/router.d.ts +210 -0
- package/dist/gateway/router.js +1330 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +1015 -0
- package/dist/memory/chunker.d.ts +28 -0
- package/dist/memory/chunker.js +226 -0
- package/dist/memory/consolidation.d.ts +44 -0
- package/dist/memory/consolidation.js +171 -0
- package/dist/memory/context-assembler.d.ts +50 -0
- package/dist/memory/context-assembler.js +149 -0
- package/dist/memory/embeddings.d.ts +38 -0
- package/dist/memory/embeddings.js +180 -0
- package/dist/memory/graph-store.d.ts +66 -0
- package/dist/memory/graph-store.js +613 -0
- package/dist/memory/mmr.d.ts +21 -0
- package/dist/memory/mmr.js +75 -0
- package/dist/memory/search.d.ts +26 -0
- package/dist/memory/search.js +67 -0
- package/dist/memory/store.d.ts +530 -0
- package/dist/memory/store.js +2022 -0
- package/dist/security/integrity.d.ts +24 -0
- package/dist/security/integrity.js +58 -0
- package/dist/security/patterns.d.ts +34 -0
- package/dist/security/patterns.js +110 -0
- package/dist/security/scanner.d.ts +32 -0
- package/dist/security/scanner.js +263 -0
- package/dist/tools/admin-tools.d.ts +12 -0
- package/dist/tools/admin-tools.js +1278 -0
- package/dist/tools/external-tools.d.ts +11 -0
- package/dist/tools/external-tools.js +1327 -0
- package/dist/tools/goal-tools.d.ts +9 -0
- package/dist/tools/goal-tools.js +159 -0
- package/dist/tools/mcp-server.d.ts +13 -0
- package/dist/tools/mcp-server.js +141 -0
- package/dist/tools/memory-tools.d.ts +10 -0
- package/dist/tools/memory-tools.js +568 -0
- package/dist/tools/session-tools.d.ts +6 -0
- package/dist/tools/session-tools.js +146 -0
- package/dist/tools/shared.d.ts +216 -0
- package/dist/tools/shared.js +340 -0
- package/dist/tools/team-tools.d.ts +6 -0
- package/dist/tools/team-tools.js +447 -0
- package/dist/tools/tool-meta.d.ts +34 -0
- package/dist/tools/tool-meta.js +133 -0
- package/dist/tools/vault-tools.d.ts +8 -0
- package/dist/tools/vault-tools.js +457 -0
- package/dist/types.d.ts +716 -0
- package/dist/types.js +16 -0
- package/dist/vault-migrations/0001-add-execution-framework.d.ts +10 -0
- package/dist/vault-migrations/0001-add-execution-framework.js +47 -0
- package/dist/vault-migrations/0002-add-agentic-communication.d.ts +12 -0
- package/dist/vault-migrations/0002-add-agentic-communication.js +79 -0
- package/dist/vault-migrations/0003-update-execution-pipeline-narration.d.ts +11 -0
- package/dist/vault-migrations/0003-update-execution-pipeline-narration.js +73 -0
- package/dist/vault-migrations/helpers.d.ts +14 -0
- package/dist/vault-migrations/helpers.js +44 -0
- package/dist/vault-migrations/runner.d.ts +14 -0
- package/dist/vault-migrations/runner.js +139 -0
- package/dist/vault-migrations/types.d.ts +42 -0
- package/dist/vault-migrations/types.js +9 -0
- package/install.sh +320 -0
- package/package.json +84 -0
- package/scripts/postinstall.js +125 -0
- package/vault/00-System/AGENTS.md +66 -0
- package/vault/00-System/CRON.md +71 -0
- package/vault/00-System/HEARTBEAT.md +58 -0
- package/vault/00-System/MEMORY.md +16 -0
- package/vault/00-System/SOUL.md +96 -0
- package/vault/05-Tasks/TASKS.md +19 -0
- package/vault/06-Templates/_Daily-Template.md +28 -0
- package/vault/06-Templates/_People-Template.md +22 -0
package/install.sh
ADDED
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# ── Clementine Installer ─────────────────────────────────────────────
|
|
5
|
+
# One-command install: system deps, npm packages, build, CLI, setup.
|
|
6
|
+
# Safe to re-run — skips anything already installed.
|
|
7
|
+
# ──────────────────────────────────────────────────────────────────────
|
|
8
|
+
|
|
9
|
+
# ── Colors ────────────────────────────────────────────────────────────
|
|
10
|
+
GREEN='\033[0;32m'
|
|
11
|
+
RED='\033[0;31m'
|
|
12
|
+
YELLOW='\033[1;33m'
|
|
13
|
+
CYAN='\033[0;36m'
|
|
14
|
+
DIM='\033[0;90m'
|
|
15
|
+
BOLD='\033[1m'
|
|
16
|
+
RESET='\033[0m'
|
|
17
|
+
|
|
18
|
+
STEP=0
|
|
19
|
+
WARNINGS=0
|
|
20
|
+
|
|
21
|
+
# ── Helpers ───────────────────────────────────────────────────────────
|
|
22
|
+
step() { STEP=$((STEP + 1)); echo -e "\n ${BOLD}[${STEP}] $1${RESET}"; }
|
|
23
|
+
ok() { echo -e " ${GREEN}OK${RESET} $1"; }
|
|
24
|
+
warn() { echo -e " ${YELLOW}WARN${RESET} $1"; WARNINGS=$((WARNINGS + 1)); }
|
|
25
|
+
fail() { echo -e " ${RED}FAIL${RESET} $1"; echo; exit 1; }
|
|
26
|
+
info() { echo -e " ${DIM}$1${RESET}"; }
|
|
27
|
+
run() { echo -e " ${CYAN}Running:${RESET} $1"; eval "$1"; }
|
|
28
|
+
|
|
29
|
+
command_exists() { command -v "$1" &>/dev/null; }
|
|
30
|
+
|
|
31
|
+
# ── Cleanup trap ──────────────────────────────────────────────────────
|
|
32
|
+
trap 'if [ $? -ne 0 ]; then echo -e "\n ${RED}Installation failed.${RESET} Check the output above for details.\n"; fi' EXIT
|
|
33
|
+
|
|
34
|
+
# ── Banner ────────────────────────────────────────────────────────────
|
|
35
|
+
echo
|
|
36
|
+
echo -e "${CYAN}"
|
|
37
|
+
cat << 'BANNER'
|
|
38
|
+
██████╗██╗ ███████╗███╗ ███╗███████╗███╗ ██╗████████╗██╗███╗ ██╗███████╗
|
|
39
|
+
██╔════╝██║ ██╔════╝████╗ ████║██╔════╝████╗ ██║╚══██╔══╝██║████╗ ██║██╔════╝
|
|
40
|
+
██║ ██║ █████╗ ██╔████╔██║█████╗ ██╔██╗ ██║ ██║ ██║██╔██╗ ██║█████╗
|
|
41
|
+
██║ ██║ ██╔══╝ ██║╚██╔╝██║██╔══╝ ██║╚██╗██║ ██║ ██║██║╚██╗██║██╔══╝
|
|
42
|
+
╚██████╗███████╗███████╗██║ ╚═╝ ██║███████╗██║ ╚████║ ██║ ██║██║ ╚████║███████╗
|
|
43
|
+
╚═════╝╚══════╝╚══════╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚═╝╚═╝ ╚═══╝╚══════╝
|
|
44
|
+
BANNER
|
|
45
|
+
echo -e "${RESET}"
|
|
46
|
+
|
|
47
|
+
VERSION=$(node -e "console.log(require('./package.json').version)" 2>/dev/null || echo "unknown")
|
|
48
|
+
echo -e " ${BOLD}Installer${RESET} ${DIM}v${VERSION}${RESET}"
|
|
49
|
+
|
|
50
|
+
# ── Platform detection ────────────────────────────────────────────────
|
|
51
|
+
OS="$(uname -s)"
|
|
52
|
+
ARCH="$(uname -m)"
|
|
53
|
+
HAS_BREW=false
|
|
54
|
+
HAS_APT=false
|
|
55
|
+
MISSING_BREW=false
|
|
56
|
+
|
|
57
|
+
case "$OS" in
|
|
58
|
+
Darwin)
|
|
59
|
+
OS="darwin"
|
|
60
|
+
echo -e " ${DIM}Platform: macOS (${ARCH})${RESET}"
|
|
61
|
+
if command_exists brew; then
|
|
62
|
+
HAS_BREW=true
|
|
63
|
+
else
|
|
64
|
+
MISSING_BREW=true
|
|
65
|
+
fi
|
|
66
|
+
;;
|
|
67
|
+
Linux)
|
|
68
|
+
OS="linux"
|
|
69
|
+
echo -e " ${DIM}Platform: Linux (${ARCH})${RESET}"
|
|
70
|
+
if command_exists apt-get; then
|
|
71
|
+
HAS_APT=true
|
|
72
|
+
fi
|
|
73
|
+
;;
|
|
74
|
+
*)
|
|
75
|
+
echo -e "\n ${RED}Unsupported platform: ${OS}${RESET}"
|
|
76
|
+
echo -e " Clementine supports macOS and Linux (apt-based)."
|
|
77
|
+
exit 1
|
|
78
|
+
;;
|
|
79
|
+
esac
|
|
80
|
+
|
|
81
|
+
# ══════════════════════════════════════════════════════════════════════
|
|
82
|
+
# Phase 1: Pre-flight checks
|
|
83
|
+
# ══════════════════════════════════════════════════════════════════════
|
|
84
|
+
step "Checking prerequisites"
|
|
85
|
+
|
|
86
|
+
# Node.js
|
|
87
|
+
if command_exists node; then
|
|
88
|
+
NODE_VERSION=$(node --version)
|
|
89
|
+
NODE_MAJOR=$(echo "$NODE_VERSION" | sed 's/v//' | cut -d. -f1)
|
|
90
|
+
if [ "$NODE_MAJOR" -ge 20 ] && [ "$NODE_MAJOR" -le 24 ]; then
|
|
91
|
+
ok "Node.js ${NODE_VERSION}"
|
|
92
|
+
else
|
|
93
|
+
fail "Node.js ${NODE_VERSION} — need v20-24 LTS.
|
|
94
|
+
Switch version: nvm install 22 && nvm use 22
|
|
95
|
+
Then re-run: bash install.sh"
|
|
96
|
+
fi
|
|
97
|
+
else
|
|
98
|
+
fail "Node.js not found. Clementine requires Node.js 20-24 LTS.
|
|
99
|
+
Install via nvm:
|
|
100
|
+
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
|
|
101
|
+
nvm install 22
|
|
102
|
+
Then re-run: bash install.sh"
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
# npm
|
|
106
|
+
if command_exists npm; then
|
|
107
|
+
ok "npm $(npm --version)"
|
|
108
|
+
else
|
|
109
|
+
fail "npm not found. Should be bundled with Node.js — check your Node installation."
|
|
110
|
+
fi
|
|
111
|
+
|
|
112
|
+
# Git repo
|
|
113
|
+
if [ -d ".git" ]; then
|
|
114
|
+
ok "Git repository detected"
|
|
115
|
+
else
|
|
116
|
+
fail "Not a git repository. Clone first:
|
|
117
|
+
git clone https://github.com/Natebreynolds/Clementine-AI-Assistant.git clementine
|
|
118
|
+
cd clementine && bash install.sh"
|
|
119
|
+
fi
|
|
120
|
+
|
|
121
|
+
# ══════════════════════════════════════════════════════════════════════
|
|
122
|
+
# Phase 2: System dependencies
|
|
123
|
+
# ══════════════════════════════════════════════════════════════════════
|
|
124
|
+
step "Installing system dependencies"
|
|
125
|
+
|
|
126
|
+
if [ "$MISSING_BREW" = true ]; then
|
|
127
|
+
warn "Homebrew not found. Some dependencies may need manual install."
|
|
128
|
+
info "Install Homebrew: /bin/bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\""
|
|
129
|
+
fi
|
|
130
|
+
|
|
131
|
+
# ── Build tools ───────────────────────────────────────────────────────
|
|
132
|
+
if [ "$OS" = "darwin" ]; then
|
|
133
|
+
if xcode-select -p &>/dev/null; then
|
|
134
|
+
ok "Xcode Command Line Tools"
|
|
135
|
+
else
|
|
136
|
+
info "Installing Xcode Command Line Tools (a dialog may appear)..."
|
|
137
|
+
xcode-select --install 2>/dev/null || true
|
|
138
|
+
echo -e " ${YELLOW}Waiting for Xcode CLT installation to complete...${RESET}"
|
|
139
|
+
until xcode-select -p &>/dev/null; do
|
|
140
|
+
sleep 5
|
|
141
|
+
done
|
|
142
|
+
ok "Xcode Command Line Tools installed"
|
|
143
|
+
fi
|
|
144
|
+
elif [ "$OS" = "linux" ]; then
|
|
145
|
+
NEED_BUILD=false
|
|
146
|
+
if ! command_exists gcc; then NEED_BUILD=true; fi
|
|
147
|
+
if ! command_exists make; then NEED_BUILD=true; fi
|
|
148
|
+
|
|
149
|
+
if [ "$NEED_BUILD" = true ]; then
|
|
150
|
+
if [ "$HAS_APT" = true ]; then
|
|
151
|
+
info "Installing build-essential and python3..."
|
|
152
|
+
sudo apt-get update -qq
|
|
153
|
+
sudo apt-get install -y -qq build-essential python3
|
|
154
|
+
ok "Build tools installed"
|
|
155
|
+
else
|
|
156
|
+
warn "gcc/make not found and no apt-get available. Install build tools manually."
|
|
157
|
+
fi
|
|
158
|
+
else
|
|
159
|
+
ok "Build tools (gcc, make)"
|
|
160
|
+
fi
|
|
161
|
+
|
|
162
|
+
# Python3 (node-gyp needs it)
|
|
163
|
+
if command_exists python3; then
|
|
164
|
+
ok "python3"
|
|
165
|
+
elif [ "$HAS_APT" = true ]; then
|
|
166
|
+
sudo apt-get install -y -qq python3
|
|
167
|
+
ok "python3 installed"
|
|
168
|
+
else
|
|
169
|
+
warn "python3 not found. Native modules may fail to compile."
|
|
170
|
+
fi
|
|
171
|
+
fi
|
|
172
|
+
|
|
173
|
+
# ── redis-server ──────────────────────────────────────────────────────
|
|
174
|
+
if command_exists redis-server; then
|
|
175
|
+
ok "redis-server (knowledge graph)"
|
|
176
|
+
else
|
|
177
|
+
if [ "$HAS_BREW" = true ]; then
|
|
178
|
+
info "Installing redis..."
|
|
179
|
+
HOMEBREW_NO_AUTO_UPDATE=1 brew install redis 2>/dev/null
|
|
180
|
+
ok "redis-server installed"
|
|
181
|
+
elif [ "$HAS_APT" = true ]; then
|
|
182
|
+
info "Installing redis-server..."
|
|
183
|
+
sudo apt-get install -y -qq redis-server
|
|
184
|
+
ok "redis-server installed"
|
|
185
|
+
else
|
|
186
|
+
warn "redis-server not found (needed for knowledge graph, not core chat).
|
|
187
|
+
Install manually: brew install redis (macOS) or apt install redis-server (Linux)"
|
|
188
|
+
fi
|
|
189
|
+
fi
|
|
190
|
+
|
|
191
|
+
# ── libomp (OpenMP runtime for FalkorDB) ──────────────────────────────
|
|
192
|
+
LIBOMP_FOUND=false
|
|
193
|
+
if [ "$OS" = "darwin" ]; then
|
|
194
|
+
for p in /opt/homebrew/opt/libomp/lib/libomp.dylib /usr/local/opt/libomp/lib/libomp.dylib; do
|
|
195
|
+
[ -f "$p" ] && LIBOMP_FOUND=true && break
|
|
196
|
+
done
|
|
197
|
+
elif [ "$OS" = "linux" ]; then
|
|
198
|
+
for p in /usr/lib/libomp.so /usr/lib/x86_64-linux-gnu/libomp.so; do
|
|
199
|
+
[ -f "$p" ] && LIBOMP_FOUND=true && break
|
|
200
|
+
done
|
|
201
|
+
fi
|
|
202
|
+
|
|
203
|
+
if [ "$LIBOMP_FOUND" = true ]; then
|
|
204
|
+
ok "libomp (OpenMP runtime)"
|
|
205
|
+
else
|
|
206
|
+
if [ "$HAS_BREW" = true ]; then
|
|
207
|
+
info "Installing libomp..."
|
|
208
|
+
HOMEBREW_NO_AUTO_UPDATE=1 brew install libomp 2>/dev/null
|
|
209
|
+
ok "libomp installed"
|
|
210
|
+
elif [ "$HAS_APT" = true ]; then
|
|
211
|
+
info "Installing libomp-dev..."
|
|
212
|
+
sudo apt-get install -y -qq libomp-dev
|
|
213
|
+
ok "libomp installed"
|
|
214
|
+
else
|
|
215
|
+
warn "libomp not found (needed for knowledge graph, not core chat).
|
|
216
|
+
Install manually: brew install libomp (macOS) or apt install libomp-dev (Linux)"
|
|
217
|
+
fi
|
|
218
|
+
fi
|
|
219
|
+
|
|
220
|
+
# ══════════════════════════════════════════════════════════════════════
|
|
221
|
+
# Phase 3: npm install
|
|
222
|
+
# ══════════════════════════════════════════════════════════════════════
|
|
223
|
+
step "Installing npm packages"
|
|
224
|
+
|
|
225
|
+
if ! npm install --loglevel=error --no-audit 2>&1; then
|
|
226
|
+
fail "npm install failed. Check the output above.
|
|
227
|
+
Common fixes:
|
|
228
|
+
- Rebuild native modules: npm rebuild better-sqlite3
|
|
229
|
+
- Missing build tools: xcode-select --install (macOS) or apt install build-essential (Linux)
|
|
230
|
+
- Clear cache: rm -rf node_modules && npm install"
|
|
231
|
+
fi
|
|
232
|
+
ok "npm install complete"
|
|
233
|
+
|
|
234
|
+
# ══════════════════════════════════════════════════════════════════════
|
|
235
|
+
# Phase 4: Build TypeScript
|
|
236
|
+
# ══════════════════════════════════════════════════════════════════════
|
|
237
|
+
step "Building TypeScript"
|
|
238
|
+
|
|
239
|
+
if ! npm run build 2>&1; then
|
|
240
|
+
fail "Build failed. Try: rm -rf dist && npm run build"
|
|
241
|
+
fi
|
|
242
|
+
ok "Build complete"
|
|
243
|
+
|
|
244
|
+
# ══════════════════════════════════════════════════════════════════════
|
|
245
|
+
# Phase 5: Install CLI globally
|
|
246
|
+
# ══════════════════════════════════════════════════════════════════════
|
|
247
|
+
step "Installing CLI globally"
|
|
248
|
+
|
|
249
|
+
if npm install -g . --loglevel=error --no-audit 2>/dev/null; then
|
|
250
|
+
ok "clementine CLI installed"
|
|
251
|
+
elif sudo npm install -g . --loglevel=error --no-audit 2>/dev/null; then
|
|
252
|
+
ok "clementine CLI installed (with sudo)"
|
|
253
|
+
else
|
|
254
|
+
fail "Could not install CLI globally.
|
|
255
|
+
Try: sudo npm install -g . --loglevel=error --no-audit"
|
|
256
|
+
fi
|
|
257
|
+
|
|
258
|
+
# Verify
|
|
259
|
+
if command_exists clementine; then
|
|
260
|
+
ok "clementine command available"
|
|
261
|
+
else
|
|
262
|
+
warn "clementine not found in PATH. You may need to restart your shell."
|
|
263
|
+
fi
|
|
264
|
+
|
|
265
|
+
# ══════════════════════════════════════════════════════════════════════
|
|
266
|
+
# Phase 6: Post-install verification
|
|
267
|
+
# ══════════════════════════════════════════════════════════════════════
|
|
268
|
+
step "Running health checks"
|
|
269
|
+
|
|
270
|
+
# Claude CLI
|
|
271
|
+
if command_exists claude; then
|
|
272
|
+
ok "Claude Code CLI found"
|
|
273
|
+
else
|
|
274
|
+
warn "Claude Code CLI not found.
|
|
275
|
+
Install: npm install -g @anthropic-ai/claude-code
|
|
276
|
+
Authenticate: claude login
|
|
277
|
+
Clementine needs this to run, but setup can proceed without it."
|
|
278
|
+
fi
|
|
279
|
+
|
|
280
|
+
# Doctor (catch anything we missed — FalkorDB binaries, etc.)
|
|
281
|
+
echo
|
|
282
|
+
clementine doctor --fix || true
|
|
283
|
+
|
|
284
|
+
# ══════════════════════════════════════════════════════════════════════
|
|
285
|
+
# Phase 7: Configuration
|
|
286
|
+
# ══════════════════════════════════════════════════════════════════════
|
|
287
|
+
CLEMENTINE_HOME="${CLEMENTINE_HOME:-$HOME/.clementine}"
|
|
288
|
+
ENV_FILE="${CLEMENTINE_HOME}/.env"
|
|
289
|
+
|
|
290
|
+
step "Configuration"
|
|
291
|
+
|
|
292
|
+
if [ -f "$ENV_FILE" ]; then
|
|
293
|
+
ok "Configuration already exists (${ENV_FILE})"
|
|
294
|
+
info "To reconfigure: clementine config setup"
|
|
295
|
+
elif [ -t 0 ]; then
|
|
296
|
+
# Interactive terminal — launch setup wizard
|
|
297
|
+
info "Launching setup wizard..."
|
|
298
|
+
echo
|
|
299
|
+
clementine config setup
|
|
300
|
+
else
|
|
301
|
+
# Non-interactive (CI, piped input)
|
|
302
|
+
warn "Non-interactive environment detected. Skipping setup wizard."
|
|
303
|
+
info "Run manually: clementine config setup"
|
|
304
|
+
fi
|
|
305
|
+
|
|
306
|
+
# ══════════════════════════════════════════════════════════════════════
|
|
307
|
+
# Done
|
|
308
|
+
# ══════════════════════════════════════════════════════════════════════
|
|
309
|
+
echo
|
|
310
|
+
echo -e " ${GREEN}${BOLD}Installation complete!${RESET}"
|
|
311
|
+
if [ "$WARNINGS" -gt 0 ]; then
|
|
312
|
+
echo -e " ${YELLOW}${WARNINGS} warning(s) above — review before launching.${RESET}"
|
|
313
|
+
fi
|
|
314
|
+
echo
|
|
315
|
+
echo -e " ${BOLD}Next steps:${RESET}"
|
|
316
|
+
echo -e " clementine launch ${DIM}Start the daemon${RESET}"
|
|
317
|
+
echo -e " clementine launch --install ${DIM}Auto-start on login (macOS)${RESET}"
|
|
318
|
+
echo -e " clementine dashboard ${DIM}Open the web command center${RESET}"
|
|
319
|
+
echo -e " clementine doctor ${DIM}Verify everything is healthy${RESET}"
|
|
320
|
+
echo
|
package/package.json
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "clementine-agent",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Clementine — Personal AI Assistant (TypeScript)",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"clementine": "dist/cli/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "rm -rf dist.tmp 2>/dev/null; tsc --outDir dist.tmp && rm -rf dist && mv dist.tmp dist && chmod +x dist/cli/index.js",
|
|
12
|
+
"prepublishOnly": "npm run build && find dist -name '*.map' -delete",
|
|
13
|
+
"dev": "tsx src/index.ts",
|
|
14
|
+
"start": "node dist/index.js",
|
|
15
|
+
"mcp": "tsx src/tools/mcp-server.ts",
|
|
16
|
+
"cli": "tsx src/cli/index.ts",
|
|
17
|
+
"typecheck": "tsc --noEmit",
|
|
18
|
+
"test": "vitest run",
|
|
19
|
+
"test:watch": "vitest",
|
|
20
|
+
"postinstall": "node scripts/postinstall.js 2>/dev/null || true"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@anthropic-ai/claude-agent-sdk": "^0.2.91",
|
|
24
|
+
"@anthropic-ai/sdk": "^0.82.0",
|
|
25
|
+
"@inquirer/prompts": "^7.0.0",
|
|
26
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
27
|
+
"@slack/bolt": "^4.2.0",
|
|
28
|
+
"better-sqlite3": "^11.7.0",
|
|
29
|
+
"commander": "^13.1.0",
|
|
30
|
+
"cron-parser": "^5.5.0",
|
|
31
|
+
"discord.js": "^14.18.0",
|
|
32
|
+
"express": "^4.21.0",
|
|
33
|
+
"falkordblite": "^0.2.0",
|
|
34
|
+
"grammy": "^1.35.0",
|
|
35
|
+
"gray-matter": "^4.0.3",
|
|
36
|
+
"node-cron": "^3.0.3",
|
|
37
|
+
"pino": "^9.6.0",
|
|
38
|
+
"twilio": "^5.5.0",
|
|
39
|
+
"zod": "^4.3.6"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
43
|
+
"@types/express": "^5.0.0",
|
|
44
|
+
"@types/node": "^22.12.0",
|
|
45
|
+
"@types/node-cron": "^3.0.11",
|
|
46
|
+
"tsx": "^4.19.0",
|
|
47
|
+
"typescript": "^5.7.0",
|
|
48
|
+
"vitest": "^4.1.1"
|
|
49
|
+
},
|
|
50
|
+
"engines": {
|
|
51
|
+
"node": ">=20.0.0"
|
|
52
|
+
},
|
|
53
|
+
"author": "Nathan Reynolds",
|
|
54
|
+
"license": "MIT",
|
|
55
|
+
"repository": {
|
|
56
|
+
"type": "git",
|
|
57
|
+
"url": "https://github.com/Natebreynolds/Clementine-AI-Assistant.git"
|
|
58
|
+
},
|
|
59
|
+
"homepage": "https://github.com/Natebreynolds/Clementine-AI-Assistant",
|
|
60
|
+
"bugs": {
|
|
61
|
+
"url": "https://github.com/Natebreynolds/Clementine-AI-Assistant/issues"
|
|
62
|
+
},
|
|
63
|
+
"keywords": [
|
|
64
|
+
"ai-assistant",
|
|
65
|
+
"claude",
|
|
66
|
+
"discord-bot",
|
|
67
|
+
"slack-bot",
|
|
68
|
+
"personal-assistant",
|
|
69
|
+
"obsidian",
|
|
70
|
+
"memory",
|
|
71
|
+
"agent"
|
|
72
|
+
],
|
|
73
|
+
"files": [
|
|
74
|
+
"dist/",
|
|
75
|
+
"vault/",
|
|
76
|
+
"scripts/",
|
|
77
|
+
"install.sh",
|
|
78
|
+
"README.md",
|
|
79
|
+
".env.example"
|
|
80
|
+
],
|
|
81
|
+
"publishConfig": {
|
|
82
|
+
"access": "public"
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Clementine postinstall script.
|
|
4
|
+
*
|
|
5
|
+
* Runs after `npm install -g clementine-agent` to:
|
|
6
|
+
* 1. Rebuild native modules (better-sqlite3) for the current Node version
|
|
7
|
+
* 2. Initialize ~/.clementine/ directory structure if it doesn't exist
|
|
8
|
+
* 3. Copy default vault templates from package to data home
|
|
9
|
+
* 4. Check for `claude` CLI on PATH (needed for OAuth login)
|
|
10
|
+
* 5. Print first-run instructions
|
|
11
|
+
*
|
|
12
|
+
* Safe to re-run — skips steps already completed.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { execSync } from 'node:child_process';
|
|
16
|
+
import { cpSync, existsSync, mkdirSync, readdirSync } from 'node:fs';
|
|
17
|
+
import os from 'node:os';
|
|
18
|
+
import path from 'node:path';
|
|
19
|
+
import { fileURLToPath } from 'node:url';
|
|
20
|
+
|
|
21
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
22
|
+
const PKG_DIR = path.resolve(__dirname, '..');
|
|
23
|
+
const DATA_HOME = process.env.CLEMENTINE_HOME || path.join(os.homedir(), '.clementine');
|
|
24
|
+
|
|
25
|
+
// ── Step 1: Rebuild better-sqlite3 ─────────────────────────────────
|
|
26
|
+
try {
|
|
27
|
+
process.stdout.write('Rebuilding native modules...');
|
|
28
|
+
execSync('npm rebuild better-sqlite3 --quiet', {
|
|
29
|
+
stdio: 'pipe',
|
|
30
|
+
cwd: PKG_DIR,
|
|
31
|
+
});
|
|
32
|
+
process.stdout.write(' done.\n');
|
|
33
|
+
} catch {
|
|
34
|
+
// Non-fatal — prebuild-install may have a prebuilt binary available
|
|
35
|
+
process.stdout.write(' skipped (prebuilt may work).\n');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// ── Step 2: Create ~/.clementine directory structure ────────────────
|
|
39
|
+
const dirs = [
|
|
40
|
+
DATA_HOME,
|
|
41
|
+
path.join(DATA_HOME, 'logs'),
|
|
42
|
+
path.join(DATA_HOME, 'vault'),
|
|
43
|
+
path.join(DATA_HOME, 'vault', '00-System'),
|
|
44
|
+
path.join(DATA_HOME, 'vault', '01-Daily-Notes'),
|
|
45
|
+
path.join(DATA_HOME, 'vault', '02-People'),
|
|
46
|
+
path.join(DATA_HOME, 'vault', '03-Projects'),
|
|
47
|
+
path.join(DATA_HOME, 'vault', '04-Topics'),
|
|
48
|
+
path.join(DATA_HOME, 'vault', '05-Tasks'),
|
|
49
|
+
path.join(DATA_HOME, 'vault', '06-Templates'),
|
|
50
|
+
path.join(DATA_HOME, 'vault', '07-Inbox'),
|
|
51
|
+
path.join(DATA_HOME, 'agents'),
|
|
52
|
+
path.join(DATA_HOME, 'self-improve'),
|
|
53
|
+
path.join(DATA_HOME, 'cron'),
|
|
54
|
+
];
|
|
55
|
+
|
|
56
|
+
for (const dir of dirs) {
|
|
57
|
+
if (!existsSync(dir)) {
|
|
58
|
+
mkdirSync(dir, { recursive: true });
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// ── Step 3: Copy default vault templates if not already present ─────
|
|
63
|
+
const srcVault = path.join(PKG_DIR, 'vault', '00-System');
|
|
64
|
+
const dstVault = path.join(DATA_HOME, 'vault', '00-System');
|
|
65
|
+
|
|
66
|
+
if (existsSync(srcVault)) {
|
|
67
|
+
const files = readdirSync(srcVault).filter(f => f.endsWith('.md'));
|
|
68
|
+
let copied = 0;
|
|
69
|
+
for (const file of files) {
|
|
70
|
+
const dst = path.join(dstVault, file);
|
|
71
|
+
if (!existsSync(dst)) {
|
|
72
|
+
try {
|
|
73
|
+
cpSync(path.join(srcVault, file), dst);
|
|
74
|
+
copied++;
|
|
75
|
+
} catch { /* skip */ }
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (copied > 0) {
|
|
79
|
+
console.log(`Initialized ${copied} default vault files in ${dstVault}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// ── Step 4: Check for claude CLI ────────────────────────────────────
|
|
84
|
+
let claudeOnPath = false;
|
|
85
|
+
try {
|
|
86
|
+
execSync('claude --version', { stdio: 'pipe' });
|
|
87
|
+
claudeOnPath = true;
|
|
88
|
+
} catch { /* not on PATH */ }
|
|
89
|
+
|
|
90
|
+
// ── Step 5: Print instructions ──────────────────────────────────────
|
|
91
|
+
const alreadyConfigured = existsSync(path.join(DATA_HOME, '.env'));
|
|
92
|
+
|
|
93
|
+
if (alreadyConfigured) {
|
|
94
|
+
console.log('\n✓ Clementine already configured. Run `clementine status` to check.\n');
|
|
95
|
+
} else {
|
|
96
|
+
const claudeNote = claudeOnPath
|
|
97
|
+
? '║ Auth: run `clementine login` (uses your Claude Code subscription) ║'
|
|
98
|
+
: '║ Auth: install Claude Code CLI first, then `clementine login` ║';
|
|
99
|
+
|
|
100
|
+
console.log(`
|
|
101
|
+
╔══════════════════════════════════════════════════════════════════╗
|
|
102
|
+
║ Clementine installed successfully! ║
|
|
103
|
+
╠══════════════════════════════════════════════════════════════════╣
|
|
104
|
+
║ ║
|
|
105
|
+
║ Next steps: ║
|
|
106
|
+
║ ║
|
|
107
|
+
║ 1. Run: clementine login ║
|
|
108
|
+
║ Authenticate with your Claude Code subscription (OAuth) ║
|
|
109
|
+
║ ║
|
|
110
|
+
║ 2. Run: clementine setup ║
|
|
111
|
+
║ Configure your channels (Discord, Slack, Telegram...) ║
|
|
112
|
+
║ ║
|
|
113
|
+
║ 3. Run: clementine launch ║
|
|
114
|
+
║ Start the assistant as a background daemon ║
|
|
115
|
+
║ ║
|
|
116
|
+
║ 4. Run: clementine dashboard ║
|
|
117
|
+
║ Open the web command center at localhost:3030 ║
|
|
118
|
+
║ ║
|
|
119
|
+
║ ${claudeNote.padEnd(65)}║
|
|
120
|
+
║ ║
|
|
121
|
+
║ Data directory: ${DATA_HOME.padEnd(47)}║
|
|
122
|
+
║ ║
|
|
123
|
+
╚══════════════════════════════════════════════════════════════════╝
|
|
124
|
+
`);
|
|
125
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: core-system
|
|
3
|
+
role: operating-instructions
|
|
4
|
+
tags:
|
|
5
|
+
- system
|
|
6
|
+
- instructions
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Operating Instructions
|
|
10
|
+
|
|
11
|
+
## Priority Order
|
|
12
|
+
|
|
13
|
+
1. **Safety first** — never take irreversible actions without the owner's approval
|
|
14
|
+
2. **Be helpful** — actually solve the problem, don't just describe it
|
|
15
|
+
3. **Remember everything** — if it might matter later, write it down
|
|
16
|
+
4. **Stay in character** — I'm Clementine, not "an AI assistant"
|
|
17
|
+
|
|
18
|
+
## Message Handling
|
|
19
|
+
|
|
20
|
+
When the owner sends a message:
|
|
21
|
+
1. Read it carefully. Understand the intent, not just the literal words.
|
|
22
|
+
2. Check [[MEMORY]] and recent [[01-Daily-Notes|daily notes]] for relevant context.
|
|
23
|
+
3. If I need to take action, use my tools. Don't describe what I *would* do — do it.
|
|
24
|
+
4. Respond concisely. If I did something, confirm what I did.
|
|
25
|
+
5. Log key interactions to today's daily note.
|
|
26
|
+
|
|
27
|
+
## Memory Protocol
|
|
28
|
+
|
|
29
|
+
- **Durable facts** (preferences, people, decisions) → write to [[MEMORY]] or the appropriate topic/person note
|
|
30
|
+
- **Daily context** (conversations, things that happened today) → append to today's [[01-Daily-Notes|daily note]]
|
|
31
|
+
- **Tasks** → add to [[05-Tasks/TASKS|task list]] with status and priority
|
|
32
|
+
- **Quick captures** → write to [[07-Inbox|Inbox]] for later sorting
|
|
33
|
+
- If the owner tells me something about themselves, a person, or a project → update the relevant note immediately
|
|
34
|
+
|
|
35
|
+
## Task Protocol
|
|
36
|
+
|
|
37
|
+
- When asked to do something that isn't immediate → create a task
|
|
38
|
+
- Check tasks during heartbeats
|
|
39
|
+
- Move tasks through: `pending` → `in-progress` → `completed`
|
|
40
|
+
- Overdue tasks get flagged to the owner
|
|
41
|
+
|
|
42
|
+
## Heartbeat Protocol
|
|
43
|
+
|
|
44
|
+
During autonomous heartbeats (see [[HEARTBEAT]]):
|
|
45
|
+
1. Read standing instructions from HEARTBEAT.md
|
|
46
|
+
2. Check for overdue or pending tasks
|
|
47
|
+
3. Review any scheduled items
|
|
48
|
+
4. If something needs attention → send a DM
|
|
49
|
+
5. If nothing urgent → log a quiet entry to today's daily note
|
|
50
|
+
6. Stay within security tier limits (no Tier 3 actions)
|
|
51
|
+
|
|
52
|
+
## Wikilink Conventions
|
|
53
|
+
|
|
54
|
+
- People: `[[02-People/Person Name|Person Name]]`
|
|
55
|
+
- Projects: `[[03-Projects/Project Name|Project Name]]`
|
|
56
|
+
- Topics: `[[04-Topics/Topic Name|Topic Name]]`
|
|
57
|
+
- Tasks: `[[05-Tasks/TASKS|Tasks]]`
|
|
58
|
+
- Daily: `[[01-Daily-Notes/YYYY-MM-DD|today]]`
|
|
59
|
+
|
|
60
|
+
## What I Don't Do
|
|
61
|
+
|
|
62
|
+
- I don't push code without asking
|
|
63
|
+
- I don't delete files without asking
|
|
64
|
+
- I don't send emails/messages without asking
|
|
65
|
+
- I don't make purchases or financial transactions
|
|
66
|
+
- I don't access accounts or credentials without explicit instruction
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: core-system
|
|
3
|
+
role: cron-config
|
|
4
|
+
jobs:
|
|
5
|
+
- name: morning-briefing
|
|
6
|
+
schedule: "0 8 * * *"
|
|
7
|
+
prompt: >
|
|
8
|
+
Give the owner a comprehensive morning briefing:
|
|
9
|
+
1. Read the task list and list any overdue, due-today, or high-priority pending tasks
|
|
10
|
+
2. Read yesterday's daily note summary for context on what was happening
|
|
11
|
+
3. Check today's daily note for anything already logged
|
|
12
|
+
4. Check the inbox for unsorted items
|
|
13
|
+
5. Format as a clear briefing with sections: Tasks, Yesterday Recap, Today's Focus
|
|
14
|
+
Keep it concise but actionable.
|
|
15
|
+
tier: 1
|
|
16
|
+
enabled: true
|
|
17
|
+
|
|
18
|
+
- name: weekly-review
|
|
19
|
+
schedule: "0 18 * * 5"
|
|
20
|
+
prompt: >
|
|
21
|
+
Create a weekly review note:
|
|
22
|
+
1. Read daily notes from the past 7 days
|
|
23
|
+
2. Summarize what got done this week
|
|
24
|
+
3. List what's still pending
|
|
25
|
+
4. Suggest priorities for next week
|
|
26
|
+
5. Write the review to today's daily note under a "## Weekly Review" section
|
|
27
|
+
tier: 2
|
|
28
|
+
enabled: true
|
|
29
|
+
|
|
30
|
+
- name: daily-memory-cleanup
|
|
31
|
+
schedule: "0 22 * * *"
|
|
32
|
+
prompt: >
|
|
33
|
+
End of day cleanup:
|
|
34
|
+
1. Review today's daily note
|
|
35
|
+
2. Extract any durable facts (preferences, decisions, people details) and write them to MEMORY.md or the appropriate topic/person note
|
|
36
|
+
3. Move completed tasks from Pending to Completed in TASKS.md
|
|
37
|
+
4. Write a brief summary of the day in today's daily note under ## Summary
|
|
38
|
+
tier: 1
|
|
39
|
+
enabled: true
|
|
40
|
+
tags:
|
|
41
|
+
- system
|
|
42
|
+
- cron
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
# Cron Jobs
|
|
46
|
+
|
|
47
|
+
Scheduled tasks that run automatically at specific times. Edit the frontmatter above to add, modify, or disable jobs.
|
|
48
|
+
|
|
49
|
+
## Active Jobs
|
|
50
|
+
|
|
51
|
+
| Job | Schedule | Description |
|
|
52
|
+
|-----|----------|-------------|
|
|
53
|
+
| morning-briefing | 8:00 AM daily | Comprehensive morning briefing |
|
|
54
|
+
| weekly-review | 6:00 PM Fridays | Weekly summary + planning |
|
|
55
|
+
| daily-memory-cleanup | 10:00 PM daily | Promote daily facts to long-term memory |
|
|
56
|
+
|
|
57
|
+
## Schedule Syntax
|
|
58
|
+
|
|
59
|
+
Standard cron expressions: `minute hour day-of-month month day-of-week`
|
|
60
|
+
See [crontab.guru](https://crontab.guru) for help.
|
|
61
|
+
|
|
62
|
+
## Adding a Job
|
|
63
|
+
|
|
64
|
+
Add a new entry to the `jobs` list in the frontmatter above:
|
|
65
|
+
```yaml
|
|
66
|
+
- name: my-new-job
|
|
67
|
+
schedule: "0 12 * * *"
|
|
68
|
+
prompt: "What should Clementine do"
|
|
69
|
+
tier: 1
|
|
70
|
+
enabled: true
|
|
71
|
+
```
|