@keyoku/openclaw 1.0.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/bin/init.js +15 -0
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +58 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/context.d.ts.map +1 -1
  6. package/dist/context.js +21 -1
  7. package/dist/context.js.map +1 -1
  8. package/dist/heartbeat-setup.d.ts +8 -1
  9. package/dist/heartbeat-setup.d.ts.map +1 -1
  10. package/dist/heartbeat-setup.js +58 -15
  11. package/dist/heartbeat-setup.js.map +1 -1
  12. package/dist/hooks.d.ts.map +1 -1
  13. package/dist/hooks.js +76 -50
  14. package/dist/hooks.js.map +1 -1
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +4 -1
  17. package/dist/index.js.map +1 -1
  18. package/dist/init.d.ts +21 -0
  19. package/dist/init.d.ts.map +1 -0
  20. package/dist/init.js +573 -0
  21. package/dist/init.js.map +1 -0
  22. package/dist/migrate-vector-store.d.ts +52 -0
  23. package/dist/migrate-vector-store.d.ts.map +1 -0
  24. package/dist/migrate-vector-store.js +158 -0
  25. package/dist/migrate-vector-store.js.map +1 -0
  26. package/dist/service.d.ts.map +1 -1
  27. package/dist/service.js +27 -3
  28. package/dist/service.js.map +1 -1
  29. package/package.json +13 -4
  30. package/skills/keyoku-memory/SKILL.md +67 -0
  31. package/src/capture.ts +0 -116
  32. package/src/cli.ts +0 -95
  33. package/src/config.ts +0 -43
  34. package/src/context.ts +0 -164
  35. package/src/heartbeat-setup.ts +0 -53
  36. package/src/hooks.ts +0 -175
  37. package/src/incremental-capture.ts +0 -88
  38. package/src/index.ts +0 -68
  39. package/src/migration.ts +0 -241
  40. package/src/service.ts +0 -145
  41. package/src/tools.ts +0 -239
  42. package/src/types.ts +0 -40
  43. package/test/capture.test.ts +0 -139
  44. package/test/context.test.ts +0 -273
  45. package/test/hooks.test.ts +0 -137
  46. package/test/tools.test.ts +0 -174
  47. package/tsconfig.json +0 -8
package/dist/init.js ADDED
@@ -0,0 +1,573 @@
1
+ /**
2
+ * One-command installer for the Keyoku OpenClaw plugin.
3
+ *
4
+ * `npx @keyoku/openclaw init`
5
+ *
6
+ * 1. Detects OpenClaw config
7
+ * 2. Downloads keyoku-engine binary if missing
8
+ * 3. Registers plugin in openclaw.json (with full config defaults)
9
+ * 4. Configures DB path (~/.keyoku/data/keyoku.db)
10
+ * 5. Sets up LLM provider + API key (embeddings auto-match extraction provider)
11
+ * 6. Sets autonomy level (observe/suggest/act)
12
+ * 7. Auto-detects timezone, configures quiet hours
13
+ * 8. Installs SKILL.md (LLM guidebook) to workspace
14
+ * 9. Offers migration of existing OpenClaw memories
15
+ * 10. Health check to verify everything works
16
+ */
17
+ import { existsSync, readFileSync, writeFileSync, mkdirSync, chmodSync, createWriteStream, cpSync } from 'node:fs';
18
+ import { join, dirname } from 'node:path';
19
+ import { fileURLToPath } from 'node:url';
20
+ import { createInterface } from 'node:readline';
21
+ import { pipeline } from 'node:stream/promises';
22
+ import { KeyokuClient } from '@keyoku/memory';
23
+ import { importMemoryFiles } from './migration.js';
24
+ import { migrateAllVectorStores, discoverVectorDbs } from './migrate-vector-store.js';
25
+ const __dirname = dirname(fileURLToPath(import.meta.url));
26
+ const HOME = process.env.HOME ?? '';
27
+ const OPENCLAW_CONFIG_PATH = join(HOME, '.openclaw', 'openclaw.json');
28
+ const KEYOKU_BIN_DIR = join(HOME, '.keyoku', 'bin');
29
+ const KEYOKU_BIN_PATH = join(KEYOKU_BIN_DIR, 'keyoku');
30
+ const OPENCLAW_MEMORY_DIR = join(HOME, '.openclaw', 'memory');
31
+ function log(msg) {
32
+ console.log(` ${msg}`);
33
+ }
34
+ function success(msg) {
35
+ console.log(` [OK] ${msg}`);
36
+ }
37
+ function warn(msg) {
38
+ console.log(` [!] ${msg}`);
39
+ }
40
+ // Pre-buffered stdin lines for piped (non-TTY) input.
41
+ // When stdin is a pipe, readline only delivers the first line via question().
42
+ // We read all lines upfront and serve them from the buffer.
43
+ let stdinLines = null;
44
+ let stdinReady = null;
45
+ function ensureStdinBuffer() {
46
+ if (stdinReady)
47
+ return stdinReady;
48
+ if (process.stdin.isTTY) {
49
+ stdinReady = Promise.resolve();
50
+ return stdinReady;
51
+ }
52
+ stdinReady = new Promise((resolve) => {
53
+ const rl = createInterface({ input: process.stdin });
54
+ const lines = [];
55
+ rl.on('line', (line) => lines.push(line));
56
+ rl.on('close', () => {
57
+ stdinLines = lines;
58
+ resolve();
59
+ });
60
+ });
61
+ return stdinReady;
62
+ }
63
+ // Shared readline for TTY interactive mode
64
+ let ttyRl = null;
65
+ function closeTtyReadline() {
66
+ if (ttyRl) {
67
+ ttyRl.close();
68
+ ttyRl = null;
69
+ }
70
+ }
71
+ async function prompt(question) {
72
+ await ensureStdinBuffer();
73
+ // Piped mode — read from pre-buffered lines
74
+ if (stdinLines !== null) {
75
+ process.stdout.write(` ${question} `);
76
+ const answer = stdinLines.shift() ?? '';
77
+ console.log(answer);
78
+ return answer.trim();
79
+ }
80
+ // TTY mode — interactive prompt
81
+ if (!ttyRl) {
82
+ ttyRl = createInterface({ input: process.stdin, output: process.stdout });
83
+ }
84
+ return new Promise((resolve) => {
85
+ ttyRl.question(` ${question} `, (answer) => {
86
+ resolve(answer.trim());
87
+ });
88
+ });
89
+ }
90
+ /** Prompt that lowercases the answer (for y/n and enum choices). */
91
+ async function promptLower(question) {
92
+ return (await prompt(question)).toLowerCase();
93
+ }
94
+ /**
95
+ * Detect platform and architecture for binary download.
96
+ */
97
+ function getPlatformInfo() {
98
+ const platform = process.platform;
99
+ const arch = process.arch;
100
+ const osMap = {
101
+ darwin: 'darwin',
102
+ linux: 'linux',
103
+ win32: 'windows',
104
+ };
105
+ const archMap = {
106
+ x64: 'amd64',
107
+ arm64: 'arm64',
108
+ };
109
+ return {
110
+ os: osMap[platform] ?? platform,
111
+ arch: archMap[arch] ?? arch,
112
+ };
113
+ }
114
+ /**
115
+ * Download the keyoku-engine binary from GitHub releases.
116
+ */
117
+ async function downloadBinary() {
118
+ const { os, arch } = getPlatformInfo();
119
+ const binaryName = os === 'windows' ? 'keyoku-server.exe' : 'keyoku-server';
120
+ const assetName = `keyoku-server-${os}-${arch}${os === 'windows' ? '.exe' : ''}`;
121
+ log(`Downloading keyoku-engine for ${os}/${arch}...`);
122
+ try {
123
+ // Get latest release info from GitHub API
124
+ const releaseRes = await fetch('https://api.github.com/repos/keyoku-ai/keyoku-engine/releases/latest', { headers: { Accept: 'application/vnd.github.v3+json' } });
125
+ if (!releaseRes.ok) {
126
+ warn(`Could not fetch latest release: ${releaseRes.status} ${releaseRes.statusText}`);
127
+ return false;
128
+ }
129
+ const release = await releaseRes.json();
130
+ const asset = release.assets.find((a) => a.name === assetName);
131
+ if (!asset) {
132
+ warn(`No binary found for ${os}/${arch} in release ${release.tag_name}`);
133
+ warn(`Available assets: ${release.assets.map((a) => a.name).join(', ')}`);
134
+ return false;
135
+ }
136
+ log(`Downloading ${asset.name} from release ${release.tag_name}...`);
137
+ // Download the binary
138
+ const downloadRes = await fetch(asset.browser_download_url);
139
+ if (!downloadRes.ok || !downloadRes.body) {
140
+ warn(`Download failed: ${downloadRes.status}`);
141
+ return false;
142
+ }
143
+ // Ensure directory exists
144
+ mkdirSync(KEYOKU_BIN_DIR, { recursive: true });
145
+ // Stream to file
146
+ const destPath = KEYOKU_BIN_PATH;
147
+ const fileStream = createWriteStream(destPath);
148
+ // @ts-expect-error — Node fetch body is a ReadableStream, pipeline handles it
149
+ await pipeline(downloadRes.body, fileStream);
150
+ // Make executable
151
+ if (os !== 'windows') {
152
+ chmodSync(destPath, 0o755);
153
+ }
154
+ success(`Binary installed at ${destPath}`);
155
+ return true;
156
+ }
157
+ catch (err) {
158
+ warn(`Failed to download binary: ${String(err)}`);
159
+ return false;
160
+ }
161
+ }
162
+ /**
163
+ * Read and parse the OpenClaw config file.
164
+ */
165
+ function readOpenClawConfig() {
166
+ if (!existsSync(OPENCLAW_CONFIG_PATH))
167
+ return null;
168
+ try {
169
+ return JSON.parse(readFileSync(OPENCLAW_CONFIG_PATH, 'utf-8'));
170
+ }
171
+ catch {
172
+ return null;
173
+ }
174
+ }
175
+ /**
176
+ * Write the OpenClaw config file.
177
+ */
178
+ function writeOpenClawConfig(config) {
179
+ writeFileSync(OPENCLAW_CONFIG_PATH, JSON.stringify(config, null, 2) + '\n', 'utf-8');
180
+ }
181
+ /**
182
+ * Install the SKILL.md guidebook to the workspace skills directory.
183
+ * This teaches the LLM how to interpret heartbeat signals, use memory naturally, etc.
184
+ */
185
+ function installSkill() {
186
+ // The skill ships with the package at ../skills/keyoku-memory/SKILL.md
187
+ const bundledSkillDir = join(__dirname, '..', 'skills', 'keyoku-memory');
188
+ const bundledSkillPath = join(bundledSkillDir, 'SKILL.md');
189
+ // Install to workspace skills (highest precedence)
190
+ const workspaceSkillDir = join(HOME, '.openclaw', 'skills', 'keyoku-memory');
191
+ if (existsSync(join(workspaceSkillDir, 'SKILL.md'))) {
192
+ success('SKILL.md already installed in workspace');
193
+ return;
194
+ }
195
+ if (!existsSync(bundledSkillPath)) {
196
+ warn('Bundled SKILL.md not found — skill will load from plugin package instead');
197
+ return;
198
+ }
199
+ mkdirSync(workspaceSkillDir, { recursive: true });
200
+ cpSync(bundledSkillPath, join(workspaceSkillDir, 'SKILL.md'));
201
+ success('SKILL.md installed to ~/.openclaw/skills/keyoku-memory/');
202
+ }
203
+ /**
204
+ * Set up LLM provider and API keys.
205
+ * Embeddings auto-match the extraction provider (no separate key needed for Gemini).
206
+ */
207
+ async function setupLlmProvider() {
208
+ console.log('');
209
+ log('LLM Provider Setup');
210
+ log('Keyoku needs an LLM for memory extraction and embeddings.');
211
+ log('Supported providers: OpenAI, Gemini, Anthropic (embeddings via OpenAI or Gemini).');
212
+ console.log('');
213
+ // Check existing env vars
214
+ const hasOpenAI = !!process.env.OPENAI_API_KEY;
215
+ const hasAnthropic = !!process.env.ANTHROPIC_API_KEY;
216
+ const hasGemini = !!process.env.GEMINI_API_KEY;
217
+ // Extraction provider
218
+ const currentProvider = process.env.KEYOKU_EXTRACTION_PROVIDER;
219
+ if (currentProvider) {
220
+ success(`Extraction provider: ${currentProvider} (${process.env.KEYOKU_EXTRACTION_MODEL || 'default model'})`);
221
+ }
222
+ else {
223
+ // Auto-detect best available provider
224
+ if (hasGemini) {
225
+ log('Using Gemini for extraction + embeddings (detected GEMINI_API_KEY)');
226
+ appendToEnvFile('KEYOKU_EXTRACTION_PROVIDER', 'gemini');
227
+ appendToEnvFile('KEYOKU_EXTRACTION_MODEL', 'gemini-2.5-flash');
228
+ appendToEnvFile('KEYOKU_EMBEDDING_PROVIDER', 'gemini');
229
+ appendToEnvFile('KEYOKU_EMBEDDING_MODEL', 'gemini-embedding-001');
230
+ }
231
+ else if (hasOpenAI) {
232
+ log('Using OpenAI for extraction + embeddings (detected OPENAI_API_KEY)');
233
+ appendToEnvFile('KEYOKU_EXTRACTION_PROVIDER', 'openai');
234
+ appendToEnvFile('KEYOKU_EXTRACTION_MODEL', 'gpt-5-mini');
235
+ appendToEnvFile('KEYOKU_EMBEDDING_PROVIDER', 'openai');
236
+ appendToEnvFile('KEYOKU_EMBEDDING_MODEL', 'text-embedding-3-small');
237
+ }
238
+ else if (hasAnthropic) {
239
+ log('Using Anthropic for extraction (detected ANTHROPIC_API_KEY)');
240
+ appendToEnvFile('KEYOKU_EXTRACTION_PROVIDER', 'anthropic');
241
+ appendToEnvFile('KEYOKU_EXTRACTION_MODEL', 'claude-haiku-4-5-20251001');
242
+ warn('Anthropic does not provide embeddings — you\'ll need an OpenAI or Gemini key for embeddings');
243
+ }
244
+ else {
245
+ // No API key detected — prompt for one
246
+ console.log('');
247
+ log('No API key detected. Which provider would you like to use?');
248
+ log(' 1) Gemini (recommended — free tier, handles extraction + embeddings)');
249
+ log(' 2) OpenAI (handles extraction + embeddings)');
250
+ log(' 3) Anthropic (extraction only — needs OpenAI or Gemini for embeddings)');
251
+ console.log('');
252
+ const choice = await prompt('Provider [1/2/3] (default: 1):');
253
+ if (choice === '2') {
254
+ const key = await prompt('Enter your OpenAI API key (sk-...):');
255
+ if (key && key.startsWith('sk-')) {
256
+ appendToEnvFile('OPENAI_API_KEY', key);
257
+ appendToEnvFile('KEYOKU_EXTRACTION_PROVIDER', 'openai');
258
+ appendToEnvFile('KEYOKU_EXTRACTION_MODEL', 'gpt-5-mini');
259
+ appendToEnvFile('KEYOKU_EMBEDDING_PROVIDER', 'openai');
260
+ appendToEnvFile('KEYOKU_EMBEDDING_MODEL', 'text-embedding-3-small');
261
+ success('OpenAI configured for extraction + embeddings');
262
+ }
263
+ else {
264
+ warn('Invalid key. You\'ll need to set OPENAI_API_KEY manually.');
265
+ }
266
+ }
267
+ else if (choice === '3') {
268
+ const key = await prompt('Enter your Anthropic API key (sk-ant-...):');
269
+ if (key) {
270
+ appendToEnvFile('ANTHROPIC_API_KEY', key);
271
+ appendToEnvFile('KEYOKU_EXTRACTION_PROVIDER', 'anthropic');
272
+ appendToEnvFile('KEYOKU_EXTRACTION_MODEL', 'claude-haiku-4-5-20251001');
273
+ warn('You\'ll also need an OpenAI or Gemini key for embeddings.');
274
+ }
275
+ else {
276
+ warn('No key provided. Set ANTHROPIC_API_KEY manually.');
277
+ }
278
+ }
279
+ else {
280
+ // Default: Gemini
281
+ const key = await prompt('Enter your Gemini API key:');
282
+ if (key) {
283
+ appendToEnvFile('GEMINI_API_KEY', key);
284
+ appendToEnvFile('KEYOKU_EXTRACTION_PROVIDER', 'gemini');
285
+ appendToEnvFile('KEYOKU_EXTRACTION_MODEL', 'gemini-2.5-flash');
286
+ appendToEnvFile('KEYOKU_EMBEDDING_PROVIDER', 'gemini');
287
+ appendToEnvFile('KEYOKU_EMBEDDING_MODEL', 'gemini-embedding-001');
288
+ success('Gemini configured for extraction + embeddings');
289
+ }
290
+ else {
291
+ warn('No key provided. Set GEMINI_API_KEY manually.');
292
+ }
293
+ }
294
+ }
295
+ }
296
+ // Show detected API keys
297
+ if (hasOpenAI)
298
+ success('OPENAI_API_KEY detected');
299
+ if (hasGemini)
300
+ success('GEMINI_API_KEY detected');
301
+ if (hasAnthropic)
302
+ success('ANTHROPIC_API_KEY detected');
303
+ }
304
+ /**
305
+ * Append a key=value to ~/.keyoku/.env (creates if needed).
306
+ * This file is sourced by the service when starting keyoku-engine.
307
+ */
308
+ function appendToEnvFile(key, value) {
309
+ const envDir = join(HOME, '.keyoku');
310
+ const envPath = join(envDir, '.env');
311
+ mkdirSync(envDir, { recursive: true });
312
+ let content = '';
313
+ if (existsSync(envPath)) {
314
+ content = readFileSync(envPath, 'utf-8');
315
+ // Replace existing key if present
316
+ const regex = new RegExp(`^${key}=.*$`, 'm');
317
+ if (regex.test(content)) {
318
+ content = content.replace(regex, `${key}=${value}`);
319
+ writeFileSync(envPath, content, 'utf-8');
320
+ return;
321
+ }
322
+ }
323
+ // Append new key
324
+ const line = `${key}=${value}\n`;
325
+ writeFileSync(envPath, content + line, 'utf-8');
326
+ }
327
+ /**
328
+ * Detect the system timezone (IANA format).
329
+ */
330
+ function detectTimezone() {
331
+ try {
332
+ return Intl.DateTimeFormat().resolvedOptions().timeZone;
333
+ }
334
+ catch {
335
+ return 'America/Los_Angeles';
336
+ }
337
+ }
338
+ /**
339
+ * Set up autonomy level — controls how aggressively heartbeat acts on signals.
340
+ */
341
+ async function setupAutonomy(config) {
342
+ console.log('');
343
+ log('Autonomy Level');
344
+ log('Controls how the agent acts on heartbeat signals (deadlines, reminders, etc.).');
345
+ console.log('');
346
+ log(' observe — Note signals silently, only act when the user asks');
347
+ log(' suggest — Mention important signals naturally in conversation (recommended)');
348
+ log(' act — Proactively execute actions (create reminders, follow up, etc.)');
349
+ console.log('');
350
+ const answer = await promptLower('Autonomy level [observe/suggest/act] (default: suggest):');
351
+ const level = ['observe', 'suggest', 'act'].includes(answer) ? answer : 'suggest';
352
+ // Save to plugin config in openclaw.json
353
+ const entry = config.plugins?.entries?.['keyoku-memory'];
354
+ if (entry) {
355
+ if (!entry.config)
356
+ entry.config = {};
357
+ entry.config.autonomy = level;
358
+ writeOpenClawConfig(config);
359
+ }
360
+ success(`Autonomy set to: ${level}`);
361
+ }
362
+ /**
363
+ * Set up timezone and quiet hours — controls when heartbeats are suppressed.
364
+ */
365
+ async function setupTimezoneAndQuietHours() {
366
+ console.log('');
367
+ log('Timezone & Quiet Hours');
368
+ // Auto-detect timezone
369
+ const detected = detectTimezone();
370
+ const tzAnswer = await prompt(`Timezone? (detected: ${detected}, press Enter to accept):`);
371
+ const timezone = tzAnswer || detected;
372
+ appendToEnvFile('KEYOKU_QUIET_HOURS_TIMEZONE', timezone);
373
+ success(`Timezone: ${timezone}`);
374
+ // Quiet hours
375
+ console.log('');
376
+ log('Quiet hours suppress non-urgent heartbeat signals (e.g., 11pm–7am).');
377
+ const enableQuiet = await promptLower('Enable quiet hours? (y/n, default: y):');
378
+ if (enableQuiet === 'n') {
379
+ appendToEnvFile('KEYOKU_QUIET_HOURS_ENABLED', 'false');
380
+ log('Quiet hours disabled — heartbeats can fire anytime');
381
+ return;
382
+ }
383
+ appendToEnvFile('KEYOKU_QUIET_HOURS_ENABLED', 'true');
384
+ const startAnswer = await prompt('Quiet start hour (0-23, default: 23):');
385
+ const endAnswer = await prompt('Quiet end hour (0-23, default: 7):');
386
+ const start = startAnswer ? parseInt(startAnswer, 10) : 23;
387
+ const end = endAnswer ? parseInt(endAnswer, 10) : 7;
388
+ if (!isNaN(start) && start >= 0 && start <= 23) {
389
+ appendToEnvFile('KEYOKU_QUIET_HOUR_START', String(start));
390
+ }
391
+ if (!isNaN(end) && end >= 0 && end <= 23) {
392
+ appendToEnvFile('KEYOKU_QUIET_HOUR_END', String(end));
393
+ }
394
+ success(`Quiet hours: ${isNaN(start) ? 23 : start}:00 – ${isNaN(end) ? 7 : end}:00 (${timezone})`);
395
+ }
396
+ /**
397
+ * Run a health check against keyoku-engine to verify the install works.
398
+ */
399
+ async function healthCheck() {
400
+ const url = 'http://localhost:18900';
401
+ log('Running health check...');
402
+ try {
403
+ const controller = new AbortController();
404
+ const timer = setTimeout(() => controller.abort(), 3000);
405
+ const res = await fetch(`${url}/api/v1/health`, { signal: controller.signal });
406
+ clearTimeout(timer);
407
+ if (res.ok) {
408
+ success('Keyoku engine is healthy');
409
+ return true;
410
+ }
411
+ warn(`Health check returned ${res.status}`);
412
+ return false;
413
+ }
414
+ catch {
415
+ // Engine isn't running yet — that's fine, it auto-starts with OpenClaw
416
+ log('Keyoku engine not running (it will auto-start when OpenClaw loads the plugin)');
417
+ return false;
418
+ }
419
+ }
420
+ /**
421
+ * Main init function — orchestrates the full setup.
422
+ */
423
+ export async function init() {
424
+ console.log(`
425
+ ╔══════════════════════════════════════════╗
426
+ ║ ║
427
+ ║ ▄█▀▀▀▄ Keyoku ║
428
+ ║ ██▄▄▄▀ Memory Engine for OpenClaw ║
429
+ ║ ▀▀▀▀▀ ║
430
+ ║ ║
431
+ ╚══════════════════════════════════════════╝
432
+ `);
433
+ // Step 1: Detect OpenClaw
434
+ const config = readOpenClawConfig();
435
+ if (!config) {
436
+ warn(`OpenClaw config not found at ${OPENCLAW_CONFIG_PATH}`);
437
+ warn('Make sure OpenClaw is installed first: https://openclaw.dev');
438
+ process.exit(1);
439
+ }
440
+ success('OpenClaw config detected');
441
+ // Step 2: Check if already installed
442
+ const entries = config.plugins?.entries ?? {};
443
+ const alreadyRegistered = !!entries['keyoku-memory']?.enabled;
444
+ if (alreadyRegistered) {
445
+ success('Keyoku plugin already registered in OpenClaw config');
446
+ }
447
+ else {
448
+ // Step 3: Ensure binary exists
449
+ if (existsSync(KEYOKU_BIN_PATH)) {
450
+ success(`Keyoku binary found at ${KEYOKU_BIN_PATH}`);
451
+ }
452
+ else {
453
+ log('Keyoku binary not found — downloading...');
454
+ const downloaded = await downloadBinary();
455
+ if (!downloaded) {
456
+ warn('Could not download binary. You can install it manually:');
457
+ warn(' Visit: https://github.com/keyoku-ai/keyoku-engine/releases');
458
+ warn(` Place the binary at: ${KEYOKU_BIN_PATH}`);
459
+ const proceed = await promptLower('Continue without binary? (y/n)');
460
+ if (proceed !== 'y') {
461
+ process.exit(1);
462
+ }
463
+ }
464
+ }
465
+ // Step 4: Register plugin in config
466
+ if (!config.plugins)
467
+ config.plugins = {};
468
+ if (!config.plugins.entries)
469
+ config.plugins.entries = {};
470
+ if (!config.plugins.slots)
471
+ config.plugins.slots = {};
472
+ config.plugins.entries['keyoku-memory'] = {
473
+ enabled: true,
474
+ config: {
475
+ keyokuUrl: 'http://localhost:18900',
476
+ autoRecall: true,
477
+ autoCapture: true,
478
+ heartbeat: true,
479
+ topK: 5,
480
+ },
481
+ };
482
+ config.plugins.slots['memory'] = 'keyoku-memory';
483
+ writeOpenClawConfig(config);
484
+ success('Plugin registered in openclaw.json');
485
+ }
486
+ // Step 5: Ensure DB path is configured
487
+ const dbPath = join(HOME, '.keyoku', 'data', 'keyoku.db');
488
+ appendToEnvFile('KEYOKU_DB_PATH', dbPath);
489
+ // Step 6: Set up LLM provider + API keys
490
+ await setupLlmProvider();
491
+ // Step 7: Autonomy level
492
+ await setupAutonomy(config);
493
+ // Step 8: Timezone & quiet hours
494
+ await setupTimezoneAndQuietHours();
495
+ // Step 9: Install SKILL.md guidebook
496
+ console.log('');
497
+ installSkill();
498
+ // Step 10: Check for existing memories to migrate
499
+ const memoryMdPath = join(HOME, '.openclaw', 'MEMORY.md');
500
+ const hasMemoryMd = existsSync(memoryMdPath);
501
+ const vectorDbs = discoverVectorDbs(OPENCLAW_MEMORY_DIR);
502
+ const hasVectorStores = vectorDbs.length > 0;
503
+ if (hasMemoryMd || hasVectorStores) {
504
+ console.log('');
505
+ log('Found existing OpenClaw memories:');
506
+ if (hasMemoryMd)
507
+ log(` - MEMORY.md`);
508
+ if (hasVectorStores)
509
+ log(` - ${vectorDbs.length} vector store(s) in ~/.openclaw/memory/`);
510
+ const migrate = await promptLower('Migrate existing memories into Keyoku? (y/n)');
511
+ if (migrate === 'y') {
512
+ log('Starting migration...');
513
+ const client = new KeyokuClient({
514
+ baseUrl: 'http://localhost:18900',
515
+ token: process.env.KEYOKU_SESSION_TOKEN,
516
+ timeout: 60000,
517
+ });
518
+ const entityId = 'default';
519
+ // Migrate markdown files
520
+ if (hasMemoryMd) {
521
+ try {
522
+ const mdResult = await importMemoryFiles({
523
+ client,
524
+ entityId,
525
+ workspaceDir: join(HOME, '.openclaw'),
526
+ logger: console,
527
+ });
528
+ success(`Markdown: ${mdResult.imported} imported, ${mdResult.skipped} skipped`);
529
+ }
530
+ catch (err) {
531
+ warn(`Markdown migration failed: ${String(err)}`);
532
+ warn('Make sure Keyoku is running (it will auto-start when OpenClaw loads the plugin)');
533
+ }
534
+ }
535
+ // Migrate vector stores
536
+ if (hasVectorStores) {
537
+ try {
538
+ const vsResult = await migrateAllVectorStores({
539
+ client,
540
+ entityId,
541
+ memoryDir: OPENCLAW_MEMORY_DIR,
542
+ logger: console,
543
+ });
544
+ success(`Vector store: ${vsResult.imported} imported, ${vsResult.skipped} skipped`);
545
+ }
546
+ catch (err) {
547
+ warn(`Vector store migration failed: ${String(err)}`);
548
+ }
549
+ }
550
+ }
551
+ else {
552
+ log('Skipping migration. You can run it later with: openclaw memory migrate');
553
+ }
554
+ }
555
+ // Step 11: Health check
556
+ console.log('');
557
+ await healthCheck();
558
+ // Done — close readline before exiting
559
+ closeTtyReadline();
560
+ console.log('');
561
+ console.log(' ╔══════════════════════════════════════════╗');
562
+ console.log(' ║ Setup complete! ║');
563
+ console.log(' ╚══════════════════════════════════════════╝');
564
+ console.log('');
565
+ log('Restart OpenClaw to load the plugin:');
566
+ log(' openclaw restart (or close and reopen your editor)');
567
+ console.log('');
568
+ log('The plugin will auto-start Keyoku when OpenClaw loads.');
569
+ log('Your agent now has persistent memory and heartbeat awareness.');
570
+ log('Run `openclaw memory stats` to check your memory status.');
571
+ log('Run `openclaw memory migrate` to migrate data later.\n');
572
+ }
573
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Vector store migration — imports OpenClaw's SQLite-based vector store into Keyoku.
3
+ *
4
+ * OpenClaw stores memory chunks in SQLite at ~/.openclaw/memory/<agentId>.sqlite
5
+ * with a `chunks` table (id, path, source, text, embedding, start_line, end_line).
6
+ *
7
+ * This migrator reads the text from each chunk, deduplicates against existing
8
+ * Keyoku memories, and stores each unique chunk. Embeddings are NOT migrated —
9
+ * Keyoku re-embeds with its own model.
10
+ */
11
+ import type { KeyokuClient } from '@keyoku/memory';
12
+ export interface VectorMigrationResult {
13
+ totalChunks: number;
14
+ imported: number;
15
+ skipped: number;
16
+ errors: number;
17
+ }
18
+ /**
19
+ * Discover OpenClaw SQLite memory databases.
20
+ */
21
+ export declare function discoverVectorDbs(memoryDir: string): string[];
22
+ /**
23
+ * Migrate a single OpenClaw SQLite vector store into Keyoku.
24
+ */
25
+ export declare function migrateVectorStore(params: {
26
+ client: KeyokuClient;
27
+ entityId: string;
28
+ sqlitePath: string;
29
+ agentId?: string;
30
+ dryRun?: boolean;
31
+ batchSize?: number;
32
+ delayMs?: number;
33
+ logger?: {
34
+ info: (msg: string) => void;
35
+ warn: (msg: string) => void;
36
+ };
37
+ }): Promise<VectorMigrationResult>;
38
+ /**
39
+ * Migrate all OpenClaw vector stores found in a directory.
40
+ */
41
+ export declare function migrateAllVectorStores(params: {
42
+ client: KeyokuClient;
43
+ entityId: string;
44
+ memoryDir: string;
45
+ agentId?: string;
46
+ dryRun?: boolean;
47
+ logger?: {
48
+ info: (msg: string) => void;
49
+ warn: (msg: string) => void;
50
+ };
51
+ }): Promise<VectorMigrationResult>;
52
+ //# sourceMappingURL=migrate-vector-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate-vector-store.d.ts","sourceRoot":"","sources":["../src/migrate-vector-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAyBnD,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAeD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAK7D;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE;IAC/C,MAAM,EAAE,YAAY,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAAC,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,CAAC;CACvE,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAsGjC;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAAC,MAAM,EAAE;IACnD,MAAM,EAAE,YAAY,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAAC,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,CAAC;CACvE,GAAG,OAAO,CAAC,qBAAqB,CAAC,CA6BjC"}