@rlabs-inc/memory 0.1.0 → 0.2.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.
- package/dist/index.js +130 -18
- package/dist/index.mjs +130 -18
- package/dist/server/index.js +141 -18
- package/dist/server/index.mjs +141 -18
- package/hooks/curation.ts +74 -0
- package/hooks/session-start.ts +82 -0
- package/hooks/user-prompt.ts +81 -0
- package/package.json +14 -8
- package/src/cli/colors.ts +174 -0
- package/src/cli/commands/doctor.ts +143 -0
- package/src/cli/commands/install.ts +153 -0
- package/src/cli/commands/serve.ts +76 -0
- package/src/cli/commands/stats.ts +64 -0
- package/src/cli/index.ts +128 -0
- package/src/core/curator.ts +7 -48
- package/src/core/engine.test.ts +321 -0
- package/src/core/engine.ts +45 -8
- package/src/core/retrieval.ts +1 -1
- package/src/core/store.ts +109 -98
- package/src/server/index.ts +15 -40
- package/src/types/schema.ts +1 -1
- package/src/utils/logger.ts +158 -107
- package/bun.lock +0 -102
- package/test-retrieval.ts +0 -91
- package/tsconfig.json +0 -16
package/dist/index.js
CHANGED
|
@@ -10784,9 +10784,15 @@ class Database {
|
|
|
10784
10784
|
if (!id)
|
|
10785
10785
|
continue;
|
|
10786
10786
|
const record = this._columns.getRecord(index);
|
|
10787
|
-
const
|
|
10788
|
-
|
|
10789
|
-
|
|
10787
|
+
const withMeta = {
|
|
10788
|
+
id,
|
|
10789
|
+
...record,
|
|
10790
|
+
created: this._created[index] || 0,
|
|
10791
|
+
updated: this._updated[index] || 0,
|
|
10792
|
+
stale: this._staleFlags[index] || false
|
|
10793
|
+
};
|
|
10794
|
+
if (filter(withMeta)) {
|
|
10795
|
+
results.push(withMeta);
|
|
10790
10796
|
}
|
|
10791
10797
|
}
|
|
10792
10798
|
return results;
|
|
@@ -10797,9 +10803,15 @@ class Database {
|
|
|
10797
10803
|
if (!id)
|
|
10798
10804
|
continue;
|
|
10799
10805
|
const record = this._columns.getRecord(index);
|
|
10800
|
-
const
|
|
10801
|
-
|
|
10802
|
-
|
|
10806
|
+
const withMeta = {
|
|
10807
|
+
id,
|
|
10808
|
+
...record,
|
|
10809
|
+
created: this._created[index] || 0,
|
|
10810
|
+
updated: this._updated[index] || 0,
|
|
10811
|
+
stale: this._staleFlags[index] || false
|
|
10812
|
+
};
|
|
10813
|
+
if (filter(withMeta)) {
|
|
10814
|
+
return withMeta;
|
|
10803
10815
|
}
|
|
10804
10816
|
}
|
|
10805
10817
|
return null;
|
|
@@ -11153,9 +11165,12 @@ class MemoryStore {
|
|
|
11153
11165
|
}
|
|
11154
11166
|
async getProject(projectId) {
|
|
11155
11167
|
if (this._projects.has(projectId)) {
|
|
11168
|
+
console.log(`\uD83D\uDD04 [DEBUG] Returning cached databases for ${projectId}`);
|
|
11156
11169
|
return this._projects.get(projectId);
|
|
11157
11170
|
}
|
|
11171
|
+
console.log(`\uD83C\uDD95 [DEBUG] Creating NEW databases for ${projectId}`);
|
|
11158
11172
|
const projectPath = import_path2.join(this._config.basePath, projectId);
|
|
11173
|
+
console.log(` Path: ${projectPath}`);
|
|
11159
11174
|
const [memories, summaries, snapshots, sessions] = await Promise.all([
|
|
11160
11175
|
createDatabase({
|
|
11161
11176
|
path: import_path2.join(projectPath, "memories"),
|
|
@@ -11340,20 +11355,31 @@ class MemoryStore {
|
|
|
11340
11355
|
}
|
|
11341
11356
|
async storeSessionSummary(projectId, sessionId, summary, interactionTone = "") {
|
|
11342
11357
|
const { summaries } = await this.getProject(projectId);
|
|
11343
|
-
|
|
11358
|
+
console.log(`\uD83D\uDCDD [DEBUG] Storing summary for ${projectId}:`);
|
|
11359
|
+
console.log(` Summary length: ${summary.length} chars`);
|
|
11360
|
+
console.log(` Summaries count before: ${summaries.all().length}`);
|
|
11361
|
+
const id = await summaries.insert({
|
|
11344
11362
|
session_id: sessionId,
|
|
11345
11363
|
project_id: projectId,
|
|
11346
11364
|
summary,
|
|
11347
11365
|
interaction_tone: interactionTone
|
|
11348
11366
|
});
|
|
11367
|
+
console.log(` Summaries count after: ${summaries.all().length}`);
|
|
11368
|
+
console.log(` Inserted ID: ${id}`);
|
|
11369
|
+
return id;
|
|
11349
11370
|
}
|
|
11350
11371
|
async getLatestSummary(projectId) {
|
|
11351
11372
|
const { summaries } = await this.getProject(projectId);
|
|
11373
|
+
console.log(`\uD83D\uDCD6 [DEBUG] Getting latest summary for ${projectId}:`);
|
|
11352
11374
|
const all = summaries.all();
|
|
11353
|
-
|
|
11375
|
+
console.log(` Summaries found: ${all.length}`);
|
|
11376
|
+
if (!all.length) {
|
|
11377
|
+
console.log(` No summaries found!`);
|
|
11354
11378
|
return null;
|
|
11379
|
+
}
|
|
11355
11380
|
all.sort((a, b) => b.created - a.created);
|
|
11356
11381
|
const latest = all[0];
|
|
11382
|
+
console.log(` Latest summary: ${latest.summary.slice(0, 50)}...`);
|
|
11357
11383
|
return {
|
|
11358
11384
|
id: latest.id,
|
|
11359
11385
|
session_id: latest.session_id,
|
|
@@ -11738,6 +11764,12 @@ class MemoryEngine {
|
|
|
11738
11764
|
}
|
|
11739
11765
|
async _getStore(projectId, projectPath) {
|
|
11740
11766
|
const key = this._config.storageMode === "local" && projectPath ? projectPath : projectId;
|
|
11767
|
+
console.log(`\uD83C\uDFEA [DEBUG] _getStore called:`);
|
|
11768
|
+
console.log(` projectId: ${projectId}`);
|
|
11769
|
+
console.log(` projectPath: ${projectPath}`);
|
|
11770
|
+
console.log(` storageMode: ${this._config.storageMode}`);
|
|
11771
|
+
console.log(` cache key: ${key}`);
|
|
11772
|
+
console.log(` cached: ${this._stores.has(key)}`);
|
|
11741
11773
|
if (this._stores.has(key)) {
|
|
11742
11774
|
return this._stores.get(key);
|
|
11743
11775
|
}
|
|
@@ -11910,14 +11942,31 @@ function createEngine(config) {
|
|
|
11910
11942
|
return new MemoryEngine(config);
|
|
11911
11943
|
}
|
|
11912
11944
|
// src/core/curator.ts
|
|
11945
|
+
var import_os3 = require("os");
|
|
11946
|
+
var import_path5 = require("path");
|
|
11947
|
+
var import_fs3 = require("fs");
|
|
11948
|
+
function getClaudeCommand() {
|
|
11949
|
+
const envCommand = process.env.CURATOR_COMMAND;
|
|
11950
|
+
if (envCommand) {
|
|
11951
|
+
return envCommand;
|
|
11952
|
+
}
|
|
11953
|
+
const claudeLocal = import_path5.join(import_os3.homedir(), ".claude", "local", "claude");
|
|
11954
|
+
if (import_fs3.existsSync(claudeLocal)) {
|
|
11955
|
+
return claudeLocal;
|
|
11956
|
+
}
|
|
11957
|
+
return "claude";
|
|
11958
|
+
}
|
|
11959
|
+
|
|
11913
11960
|
class Curator {
|
|
11914
11961
|
_config;
|
|
11915
11962
|
constructor(config = {}) {
|
|
11963
|
+
const cliCommand = config.cliCommand ?? getClaudeCommand();
|
|
11916
11964
|
this._config = {
|
|
11917
11965
|
apiKey: config.apiKey ?? "",
|
|
11918
|
-
cliCommand
|
|
11966
|
+
cliCommand,
|
|
11919
11967
|
cliType: config.cliType ?? "claude-code"
|
|
11920
11968
|
};
|
|
11969
|
+
console.log(`\uD83E\uDDE0 Curator initialized with CLI: ${cliCommand}`);
|
|
11921
11970
|
}
|
|
11922
11971
|
buildCurationPrompt(triggerType = "session_end") {
|
|
11923
11972
|
return `You have just had a conversation. As this session is ending (${triggerType}), please curate memories for the Claude Tools Memory System.
|
|
@@ -12111,33 +12160,96 @@ ${prompt}`
|
|
|
12111
12160
|
return this.parseCurationResponse(content.text);
|
|
12112
12161
|
}
|
|
12113
12162
|
async curateWithCLI(sessionId, triggerType = "session_end", cwd) {
|
|
12114
|
-
const
|
|
12163
|
+
const systemPrompt = this.buildCurationPrompt(triggerType);
|
|
12164
|
+
const userMessage = "This session has ended. Please curate the memories from our conversation according to the instructions in your system prompt. Return ONLY the JSON structure.";
|
|
12115
12165
|
const args = [];
|
|
12116
12166
|
if (this._config.cliType === "claude-code") {
|
|
12117
|
-
args.push("--resume", sessionId, "-p", prompt, "--output-format", "json", "--max-turns", "1");
|
|
12167
|
+
args.push("--resume", sessionId, "-p", userMessage, "--append-system-prompt", systemPrompt, "--output-format", "json", "--max-turns", "1");
|
|
12118
12168
|
} else {
|
|
12119
|
-
args.push("--resume", sessionId, "-p",
|
|
12169
|
+
args.push("--resume", sessionId, "-p", `${systemPrompt}
|
|
12170
|
+
|
|
12171
|
+
${userMessage}`, "--output-format", "json");
|
|
12120
12172
|
}
|
|
12173
|
+
console.log(`
|
|
12174
|
+
\uD83D\uDCCB Executing CLI command:`);
|
|
12175
|
+
console.log(` Command: ${this._config.cliCommand}`);
|
|
12176
|
+
console.log(` Args: --resume ${sessionId} -p [user_message] --append-system-prompt [curation_instructions] --output-format json --max-turns 1`);
|
|
12177
|
+
console.log(` CWD: ${cwd || "not set"}`);
|
|
12178
|
+
console.log(` User message: "${userMessage.slice(0, 50)}..."`);
|
|
12179
|
+
console.log(` System prompt length: ${systemPrompt.length} chars`);
|
|
12121
12180
|
const proc = Bun.spawn([this._config.cliCommand, ...args], {
|
|
12122
12181
|
cwd,
|
|
12123
12182
|
env: {
|
|
12124
12183
|
...process.env,
|
|
12125
12184
|
MEMORY_CURATOR_ACTIVE: "1"
|
|
12126
|
-
}
|
|
12185
|
+
},
|
|
12186
|
+
stderr: "pipe"
|
|
12127
12187
|
});
|
|
12128
|
-
const
|
|
12188
|
+
const [stdout, stderr] = await Promise.all([
|
|
12189
|
+
new Response(proc.stdout).text(),
|
|
12190
|
+
new Response(proc.stderr).text()
|
|
12191
|
+
]);
|
|
12129
12192
|
const exitCode = await proc.exited;
|
|
12193
|
+
console.log(`
|
|
12194
|
+
\uD83D\uDCE4 CLI Response:`);
|
|
12195
|
+
console.log(` Exit code: ${exitCode}`);
|
|
12196
|
+
console.log(` Stdout length: ${stdout.length} chars`);
|
|
12197
|
+
console.log(` Stderr length: ${stderr.length} chars`);
|
|
12198
|
+
if (stderr) {
|
|
12199
|
+
console.log(`
|
|
12200
|
+
⚠️ Stderr output:`);
|
|
12201
|
+
console.log(stderr.slice(0, 1000));
|
|
12202
|
+
}
|
|
12203
|
+
if (stdout) {
|
|
12204
|
+
console.log(`
|
|
12205
|
+
\uD83D\uDCE5 Stdout output (first 500 chars):`);
|
|
12206
|
+
console.log(stdout.slice(0, 500));
|
|
12207
|
+
}
|
|
12130
12208
|
if (exitCode !== 0) {
|
|
12131
|
-
console.error(`
|
|
12209
|
+
console.error(`
|
|
12210
|
+
❌ CLI exited with code ${exitCode}`);
|
|
12132
12211
|
return { session_summary: "", memories: [] };
|
|
12133
12212
|
}
|
|
12134
12213
|
try {
|
|
12135
|
-
const
|
|
12214
|
+
const cliOutput = JSON.parse(stdout);
|
|
12215
|
+
if (cliOutput.type === "error" || cliOutput.is_error === true) {
|
|
12216
|
+
console.log(`
|
|
12217
|
+
❌ CLI returned error:`);
|
|
12218
|
+
console.log(` Type: ${cliOutput.type}`);
|
|
12219
|
+
console.log(` Message: ${cliOutput.message || cliOutput.error || "Unknown error"}`);
|
|
12220
|
+
return { session_summary: "", memories: [] };
|
|
12221
|
+
}
|
|
12222
|
+
let aiResponse = "";
|
|
12223
|
+
if (typeof cliOutput.result === "string") {
|
|
12224
|
+
aiResponse = cliOutput.result;
|
|
12225
|
+
console.log(`
|
|
12226
|
+
\uD83D\uDCE6 Extracted result from CLI wrapper (${aiResponse.length} chars)`);
|
|
12227
|
+
} else {
|
|
12228
|
+
console.log(`
|
|
12229
|
+
⚠️ No result field in CLI output`);
|
|
12230
|
+
console.log(` Keys: ${Object.keys(cliOutput).join(", ")}`);
|
|
12231
|
+
return { session_summary: "", memories: [] };
|
|
12232
|
+
}
|
|
12233
|
+
const codeBlockMatch = aiResponse.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
12234
|
+
if (codeBlockMatch) {
|
|
12235
|
+
aiResponse = codeBlockMatch[1].trim();
|
|
12236
|
+
console.log(`\uD83D\uDCDD Extracted JSON from markdown code block`);
|
|
12237
|
+
}
|
|
12238
|
+
const jsonMatch = aiResponse.match(/\{[\s\S]*\}/)?.[0];
|
|
12136
12239
|
if (jsonMatch) {
|
|
12137
|
-
|
|
12240
|
+
console.log(`✅ Found JSON object (${jsonMatch.length} chars)`);
|
|
12241
|
+
const result = this.parseCurationResponse(jsonMatch);
|
|
12242
|
+
console.log(` Parsed ${result.memories.length} memories`);
|
|
12243
|
+
return result;
|
|
12244
|
+
} else {
|
|
12245
|
+
console.log(`
|
|
12246
|
+
⚠️ No JSON object found in AI response`);
|
|
12247
|
+
console.log(` Response preview: ${aiResponse.slice(0, 200)}...`);
|
|
12138
12248
|
}
|
|
12139
12249
|
} catch (error) {
|
|
12140
|
-
console.error(
|
|
12250
|
+
console.error(`
|
|
12251
|
+
❌ Failed to parse CLI output:`, error);
|
|
12252
|
+
console.log(` Raw stdout (first 500 chars): ${stdout.slice(0, 500)}`);
|
|
12141
12253
|
}
|
|
12142
12254
|
return { session_summary: "", memories: [] };
|
|
12143
12255
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -10753,9 +10753,15 @@ class Database {
|
|
|
10753
10753
|
if (!id)
|
|
10754
10754
|
continue;
|
|
10755
10755
|
const record = this._columns.getRecord(index);
|
|
10756
|
-
const
|
|
10757
|
-
|
|
10758
|
-
|
|
10756
|
+
const withMeta = {
|
|
10757
|
+
id,
|
|
10758
|
+
...record,
|
|
10759
|
+
created: this._created[index] || 0,
|
|
10760
|
+
updated: this._updated[index] || 0,
|
|
10761
|
+
stale: this._staleFlags[index] || false
|
|
10762
|
+
};
|
|
10763
|
+
if (filter(withMeta)) {
|
|
10764
|
+
results.push(withMeta);
|
|
10759
10765
|
}
|
|
10760
10766
|
}
|
|
10761
10767
|
return results;
|
|
@@ -10766,9 +10772,15 @@ class Database {
|
|
|
10766
10772
|
if (!id)
|
|
10767
10773
|
continue;
|
|
10768
10774
|
const record = this._columns.getRecord(index);
|
|
10769
|
-
const
|
|
10770
|
-
|
|
10771
|
-
|
|
10775
|
+
const withMeta = {
|
|
10776
|
+
id,
|
|
10777
|
+
...record,
|
|
10778
|
+
created: this._created[index] || 0,
|
|
10779
|
+
updated: this._updated[index] || 0,
|
|
10780
|
+
stale: this._staleFlags[index] || false
|
|
10781
|
+
};
|
|
10782
|
+
if (filter(withMeta)) {
|
|
10783
|
+
return withMeta;
|
|
10772
10784
|
}
|
|
10773
10785
|
}
|
|
10774
10786
|
return null;
|
|
@@ -11122,9 +11134,12 @@ class MemoryStore {
|
|
|
11122
11134
|
}
|
|
11123
11135
|
async getProject(projectId) {
|
|
11124
11136
|
if (this._projects.has(projectId)) {
|
|
11137
|
+
console.log(`\uD83D\uDD04 [DEBUG] Returning cached databases for ${projectId}`);
|
|
11125
11138
|
return this._projects.get(projectId);
|
|
11126
11139
|
}
|
|
11140
|
+
console.log(`\uD83C\uDD95 [DEBUG] Creating NEW databases for ${projectId}`);
|
|
11127
11141
|
const projectPath = join2(this._config.basePath, projectId);
|
|
11142
|
+
console.log(` Path: ${projectPath}`);
|
|
11128
11143
|
const [memories, summaries, snapshots, sessions] = await Promise.all([
|
|
11129
11144
|
createDatabase({
|
|
11130
11145
|
path: join2(projectPath, "memories"),
|
|
@@ -11309,20 +11324,31 @@ class MemoryStore {
|
|
|
11309
11324
|
}
|
|
11310
11325
|
async storeSessionSummary(projectId, sessionId, summary, interactionTone = "") {
|
|
11311
11326
|
const { summaries } = await this.getProject(projectId);
|
|
11312
|
-
|
|
11327
|
+
console.log(`\uD83D\uDCDD [DEBUG] Storing summary for ${projectId}:`);
|
|
11328
|
+
console.log(` Summary length: ${summary.length} chars`);
|
|
11329
|
+
console.log(` Summaries count before: ${summaries.all().length}`);
|
|
11330
|
+
const id = await summaries.insert({
|
|
11313
11331
|
session_id: sessionId,
|
|
11314
11332
|
project_id: projectId,
|
|
11315
11333
|
summary,
|
|
11316
11334
|
interaction_tone: interactionTone
|
|
11317
11335
|
});
|
|
11336
|
+
console.log(` Summaries count after: ${summaries.all().length}`);
|
|
11337
|
+
console.log(` Inserted ID: ${id}`);
|
|
11338
|
+
return id;
|
|
11318
11339
|
}
|
|
11319
11340
|
async getLatestSummary(projectId) {
|
|
11320
11341
|
const { summaries } = await this.getProject(projectId);
|
|
11342
|
+
console.log(`\uD83D\uDCD6 [DEBUG] Getting latest summary for ${projectId}:`);
|
|
11321
11343
|
const all = summaries.all();
|
|
11322
|
-
|
|
11344
|
+
console.log(` Summaries found: ${all.length}`);
|
|
11345
|
+
if (!all.length) {
|
|
11346
|
+
console.log(` No summaries found!`);
|
|
11323
11347
|
return null;
|
|
11348
|
+
}
|
|
11324
11349
|
all.sort((a, b) => b.created - a.created);
|
|
11325
11350
|
const latest = all[0];
|
|
11351
|
+
console.log(` Latest summary: ${latest.summary.slice(0, 50)}...`);
|
|
11326
11352
|
return {
|
|
11327
11353
|
id: latest.id,
|
|
11328
11354
|
session_id: latest.session_id,
|
|
@@ -11707,6 +11733,12 @@ class MemoryEngine {
|
|
|
11707
11733
|
}
|
|
11708
11734
|
async _getStore(projectId, projectPath) {
|
|
11709
11735
|
const key = this._config.storageMode === "local" && projectPath ? projectPath : projectId;
|
|
11736
|
+
console.log(`\uD83C\uDFEA [DEBUG] _getStore called:`);
|
|
11737
|
+
console.log(` projectId: ${projectId}`);
|
|
11738
|
+
console.log(` projectPath: ${projectPath}`);
|
|
11739
|
+
console.log(` storageMode: ${this._config.storageMode}`);
|
|
11740
|
+
console.log(` cache key: ${key}`);
|
|
11741
|
+
console.log(` cached: ${this._stores.has(key)}`);
|
|
11710
11742
|
if (this._stores.has(key)) {
|
|
11711
11743
|
return this._stores.get(key);
|
|
11712
11744
|
}
|
|
@@ -11879,14 +11911,31 @@ function createEngine(config) {
|
|
|
11879
11911
|
return new MemoryEngine(config);
|
|
11880
11912
|
}
|
|
11881
11913
|
// src/core/curator.ts
|
|
11914
|
+
import { homedir as homedir3 } from "os";
|
|
11915
|
+
import { join as join4 } from "path";
|
|
11916
|
+
import { existsSync } from "fs";
|
|
11917
|
+
function getClaudeCommand() {
|
|
11918
|
+
const envCommand = process.env.CURATOR_COMMAND;
|
|
11919
|
+
if (envCommand) {
|
|
11920
|
+
return envCommand;
|
|
11921
|
+
}
|
|
11922
|
+
const claudeLocal = join4(homedir3(), ".claude", "local", "claude");
|
|
11923
|
+
if (existsSync(claudeLocal)) {
|
|
11924
|
+
return claudeLocal;
|
|
11925
|
+
}
|
|
11926
|
+
return "claude";
|
|
11927
|
+
}
|
|
11928
|
+
|
|
11882
11929
|
class Curator {
|
|
11883
11930
|
_config;
|
|
11884
11931
|
constructor(config = {}) {
|
|
11932
|
+
const cliCommand = config.cliCommand ?? getClaudeCommand();
|
|
11885
11933
|
this._config = {
|
|
11886
11934
|
apiKey: config.apiKey ?? "",
|
|
11887
|
-
cliCommand
|
|
11935
|
+
cliCommand,
|
|
11888
11936
|
cliType: config.cliType ?? "claude-code"
|
|
11889
11937
|
};
|
|
11938
|
+
console.log(`\uD83E\uDDE0 Curator initialized with CLI: ${cliCommand}`);
|
|
11890
11939
|
}
|
|
11891
11940
|
buildCurationPrompt(triggerType = "session_end") {
|
|
11892
11941
|
return `You have just had a conversation. As this session is ending (${triggerType}), please curate memories for the Claude Tools Memory System.
|
|
@@ -12080,33 +12129,96 @@ ${prompt}`
|
|
|
12080
12129
|
return this.parseCurationResponse(content.text);
|
|
12081
12130
|
}
|
|
12082
12131
|
async curateWithCLI(sessionId, triggerType = "session_end", cwd) {
|
|
12083
|
-
const
|
|
12132
|
+
const systemPrompt = this.buildCurationPrompt(triggerType);
|
|
12133
|
+
const userMessage = "This session has ended. Please curate the memories from our conversation according to the instructions in your system prompt. Return ONLY the JSON structure.";
|
|
12084
12134
|
const args = [];
|
|
12085
12135
|
if (this._config.cliType === "claude-code") {
|
|
12086
|
-
args.push("--resume", sessionId, "-p", prompt, "--output-format", "json", "--max-turns", "1");
|
|
12136
|
+
args.push("--resume", sessionId, "-p", userMessage, "--append-system-prompt", systemPrompt, "--output-format", "json", "--max-turns", "1");
|
|
12087
12137
|
} else {
|
|
12088
|
-
args.push("--resume", sessionId, "-p",
|
|
12138
|
+
args.push("--resume", sessionId, "-p", `${systemPrompt}
|
|
12139
|
+
|
|
12140
|
+
${userMessage}`, "--output-format", "json");
|
|
12089
12141
|
}
|
|
12142
|
+
console.log(`
|
|
12143
|
+
\uD83D\uDCCB Executing CLI command:`);
|
|
12144
|
+
console.log(` Command: ${this._config.cliCommand}`);
|
|
12145
|
+
console.log(` Args: --resume ${sessionId} -p [user_message] --append-system-prompt [curation_instructions] --output-format json --max-turns 1`);
|
|
12146
|
+
console.log(` CWD: ${cwd || "not set"}`);
|
|
12147
|
+
console.log(` User message: "${userMessage.slice(0, 50)}..."`);
|
|
12148
|
+
console.log(` System prompt length: ${systemPrompt.length} chars`);
|
|
12090
12149
|
const proc = Bun.spawn([this._config.cliCommand, ...args], {
|
|
12091
12150
|
cwd,
|
|
12092
12151
|
env: {
|
|
12093
12152
|
...process.env,
|
|
12094
12153
|
MEMORY_CURATOR_ACTIVE: "1"
|
|
12095
|
-
}
|
|
12154
|
+
},
|
|
12155
|
+
stderr: "pipe"
|
|
12096
12156
|
});
|
|
12097
|
-
const
|
|
12157
|
+
const [stdout, stderr] = await Promise.all([
|
|
12158
|
+
new Response(proc.stdout).text(),
|
|
12159
|
+
new Response(proc.stderr).text()
|
|
12160
|
+
]);
|
|
12098
12161
|
const exitCode = await proc.exited;
|
|
12162
|
+
console.log(`
|
|
12163
|
+
\uD83D\uDCE4 CLI Response:`);
|
|
12164
|
+
console.log(` Exit code: ${exitCode}`);
|
|
12165
|
+
console.log(` Stdout length: ${stdout.length} chars`);
|
|
12166
|
+
console.log(` Stderr length: ${stderr.length} chars`);
|
|
12167
|
+
if (stderr) {
|
|
12168
|
+
console.log(`
|
|
12169
|
+
⚠️ Stderr output:`);
|
|
12170
|
+
console.log(stderr.slice(0, 1000));
|
|
12171
|
+
}
|
|
12172
|
+
if (stdout) {
|
|
12173
|
+
console.log(`
|
|
12174
|
+
\uD83D\uDCE5 Stdout output (first 500 chars):`);
|
|
12175
|
+
console.log(stdout.slice(0, 500));
|
|
12176
|
+
}
|
|
12099
12177
|
if (exitCode !== 0) {
|
|
12100
|
-
console.error(`
|
|
12178
|
+
console.error(`
|
|
12179
|
+
❌ CLI exited with code ${exitCode}`);
|
|
12101
12180
|
return { session_summary: "", memories: [] };
|
|
12102
12181
|
}
|
|
12103
12182
|
try {
|
|
12104
|
-
const
|
|
12183
|
+
const cliOutput = JSON.parse(stdout);
|
|
12184
|
+
if (cliOutput.type === "error" || cliOutput.is_error === true) {
|
|
12185
|
+
console.log(`
|
|
12186
|
+
❌ CLI returned error:`);
|
|
12187
|
+
console.log(` Type: ${cliOutput.type}`);
|
|
12188
|
+
console.log(` Message: ${cliOutput.message || cliOutput.error || "Unknown error"}`);
|
|
12189
|
+
return { session_summary: "", memories: [] };
|
|
12190
|
+
}
|
|
12191
|
+
let aiResponse = "";
|
|
12192
|
+
if (typeof cliOutput.result === "string") {
|
|
12193
|
+
aiResponse = cliOutput.result;
|
|
12194
|
+
console.log(`
|
|
12195
|
+
\uD83D\uDCE6 Extracted result from CLI wrapper (${aiResponse.length} chars)`);
|
|
12196
|
+
} else {
|
|
12197
|
+
console.log(`
|
|
12198
|
+
⚠️ No result field in CLI output`);
|
|
12199
|
+
console.log(` Keys: ${Object.keys(cliOutput).join(", ")}`);
|
|
12200
|
+
return { session_summary: "", memories: [] };
|
|
12201
|
+
}
|
|
12202
|
+
const codeBlockMatch = aiResponse.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
12203
|
+
if (codeBlockMatch) {
|
|
12204
|
+
aiResponse = codeBlockMatch[1].trim();
|
|
12205
|
+
console.log(`\uD83D\uDCDD Extracted JSON from markdown code block`);
|
|
12206
|
+
}
|
|
12207
|
+
const jsonMatch = aiResponse.match(/\{[\s\S]*\}/)?.[0];
|
|
12105
12208
|
if (jsonMatch) {
|
|
12106
|
-
|
|
12209
|
+
console.log(`✅ Found JSON object (${jsonMatch.length} chars)`);
|
|
12210
|
+
const result = this.parseCurationResponse(jsonMatch);
|
|
12211
|
+
console.log(` Parsed ${result.memories.length} memories`);
|
|
12212
|
+
return result;
|
|
12213
|
+
} else {
|
|
12214
|
+
console.log(`
|
|
12215
|
+
⚠️ No JSON object found in AI response`);
|
|
12216
|
+
console.log(` Response preview: ${aiResponse.slice(0, 200)}...`);
|
|
12107
12217
|
}
|
|
12108
12218
|
} catch (error) {
|
|
12109
|
-
console.error(
|
|
12219
|
+
console.error(`
|
|
12220
|
+
❌ Failed to parse CLI output:`, error);
|
|
12221
|
+
console.log(` Raw stdout (first 500 chars): ${stdout.slice(0, 500)}`);
|
|
12110
12222
|
}
|
|
12111
12223
|
return { session_summary: "", memories: [] };
|
|
12112
12224
|
}
|