@rlabs-inc/memory 0.4.7 → 0.4.8

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 CHANGED
@@ -35223,10 +35223,11 @@ Focus ONLY on technical, architectural, debugging, decision, workflow, and proje
35223
35223
  try {
35224
35224
  const jsonMatch = responseJson.match(/\{[\s\S]*\}/)?.[0];
35225
35225
  if (!jsonMatch) {
35226
+ logger.debug("parseCurationResponse: No JSON object found in response", "curator");
35226
35227
  throw new Error("No JSON object found in response");
35227
35228
  }
35228
35229
  const data = JSON.parse(jsonMatch);
35229
- return {
35230
+ const result = {
35230
35231
  session_summary: data.session_summary ?? "",
35231
35232
  interaction_tone: data.interaction_tone,
35232
35233
  project_snapshot: data.project_snapshot ? {
@@ -35241,7 +35242,10 @@ Focus ONLY on technical, architectural, debugging, decision, workflow, and proje
35241
35242
  } : undefined,
35242
35243
  memories: this._parseMemories(data.memories ?? [])
35243
35244
  };
35244
- } catch {
35245
+ logger.debug(`Curator parsed: ${result.memories.length} memories, summary: ${result.session_summary ? "yes" : "no"}, snapshot: ${result.project_snapshot ? "yes" : "no"}`, "curator");
35246
+ return result;
35247
+ } catch (error2) {
35248
+ logger.debug(`parseCurationResponse error: ${error2.message}`, "curator");
35245
35249
  return {
35246
35250
  session_summary: "",
35247
35251
  memories: []
@@ -35345,7 +35349,6 @@ This session has ended. Please curate the memories from this conversation accord
35345
35349
  options: {
35346
35350
  systemPrompt,
35347
35351
  permissionMode: "bypassPermissions",
35348
- maxTurns: 1,
35349
35352
  model: "claude-opus-4-5-20251101"
35350
35353
  }
35351
35354
  });
@@ -35357,8 +35360,14 @@ This session has ended. Please curate the memories from this conversation accord
35357
35360
  }
35358
35361
  }
35359
35362
  if (!resultText) {
35363
+ logger.debug("Curator SDK: No result text returned from Agent SDK", "curator");
35360
35364
  return { session_summary: "", memories: [] };
35361
35365
  }
35366
+ logger.debug(`Curator SDK raw response (${resultText.length} chars):`, "curator");
35367
+ if (logger.isVerbose()) {
35368
+ const preview = resultText.length > 3000 ? resultText.slice(0, 3000) + "...[truncated]" : resultText;
35369
+ console.log(preview);
35370
+ }
35362
35371
  return this.parseCurationResponse(resultText);
35363
35372
  }
35364
35373
  _formatConversationTranscript(messages) {
@@ -35405,7 +35414,7 @@ ${content}
35405
35414
  ];
35406
35415
  const response = await client.messages.create({
35407
35416
  model: "claude-sonnet-4-20250514",
35408
- max_tokens: 8192,
35417
+ max_tokens: 64000,
35409
35418
  system: systemPrompt,
35410
35419
  messages: conversationMessages
35411
35420
  });
@@ -35425,7 +35434,7 @@ ${content}
35425
35434
  const args = [];
35426
35435
  let command = this._config.cliCommand;
35427
35436
  if (type === "claude-code") {
35428
- args.push("--resume", sessionId, "-p", userMessage, "--append-system-prompt", systemPrompt, "--output-format", "json", "--max-turns", "1");
35437
+ args.push("--resume", sessionId, "-p", userMessage, "--append-system-prompt", systemPrompt, "--output-format", "json");
35429
35438
  } else {
35430
35439
  command = "gemini";
35431
35440
  args.push("--resume", sessionId, "-p", `${systemPrompt}
@@ -35436,7 +35445,8 @@ ${userMessage}`, "--output-format", "json");
35436
35445
  cwd: cwd2,
35437
35446
  env: {
35438
35447
  ...process.env,
35439
- MEMORY_CURATOR_ACTIVE: "1"
35448
+ MEMORY_CURATOR_ACTIVE: "1",
35449
+ CLAUDE_CODE_MAX_OUTPUT_TOKENS: "64000"
35440
35450
  },
35441
35451
  stdout: "pipe",
35442
35452
  stderr: "pipe"
@@ -35447,37 +35457,59 @@ ${userMessage}`, "--output-format", "json");
35447
35457
  ]);
35448
35458
  const exitCode = await proc.exited;
35449
35459
  if (exitCode !== 0) {
35460
+ logger.debug(`Curator CLI exited with code ${exitCode}`, "curator");
35461
+ if (stderr) {
35462
+ logger.debug(`Curator stderr: ${stderr}`, "curator");
35463
+ }
35450
35464
  return { session_summary: "", memories: [] };
35451
35465
  }
35466
+ logger.debug(`Curator CLI raw stdout (${stdout.length} chars):`, "curator");
35467
+ if (logger.isVerbose()) {
35468
+ const preview = stdout.length > 2000 ? stdout.slice(0, 2000) + "...[truncated]" : stdout;
35469
+ console.log(preview);
35470
+ }
35452
35471
  try {
35453
35472
  const cliOutput = JSON.parse(stdout);
35454
35473
  let resultObj;
35455
35474
  if (Array.isArray(cliOutput)) {
35456
35475
  resultObj = cliOutput.find((item) => item.type === "result");
35457
35476
  if (!resultObj) {
35477
+ logger.debug("Curator: No result object found in CLI output array", "curator");
35458
35478
  return { session_summary: "", memories: [] };
35459
35479
  }
35460
35480
  } else {
35461
35481
  resultObj = cliOutput;
35462
35482
  }
35463
35483
  if (resultObj.type === "error" || resultObj.is_error === true) {
35484
+ logger.debug(`Curator: Error response from CLI: ${JSON.stringify(resultObj).slice(0, 500)}`, "curator");
35464
35485
  return { session_summary: "", memories: [] };
35465
35486
  }
35466
35487
  let aiResponse = "";
35467
35488
  if (typeof resultObj.result === "string") {
35468
35489
  aiResponse = resultObj.result;
35469
35490
  } else {
35491
+ logger.debug(`Curator: result field is not a string: ${typeof resultObj.result}`, "curator");
35470
35492
  return { session_summary: "", memories: [] };
35471
35493
  }
35494
+ logger.debug(`Curator AI response (${aiResponse.length} chars):`, "curator");
35495
+ if (logger.isVerbose()) {
35496
+ const preview = aiResponse.length > 3000 ? aiResponse.slice(0, 3000) + "...[truncated]" : aiResponse;
35497
+ console.log(preview);
35498
+ }
35472
35499
  const codeBlockMatch = aiResponse.match(/```(?:json)?\s*([\s\S]*?)```/);
35473
35500
  if (codeBlockMatch) {
35474
35501
  aiResponse = codeBlockMatch[1].trim();
35475
35502
  }
35476
35503
  const jsonMatch = aiResponse.match(/\{[\s\S]*\}/)?.[0];
35477
35504
  if (jsonMatch) {
35505
+ logger.debug(`Curator: Found JSON object (${jsonMatch.length} chars), parsing...`, "curator");
35478
35506
  return this.parseCurationResponse(jsonMatch);
35507
+ } else {
35508
+ logger.debug("Curator: No JSON object found in AI response", "curator");
35479
35509
  }
35480
- } catch {}
35510
+ } catch (error2) {
35511
+ logger.debug(`Curator: Parse error: ${error2.message}`, "curator");
35512
+ }
35481
35513
  return { session_summary: "", memories: [] };
35482
35514
  }
35483
35515
  }
package/dist/index.mjs CHANGED
@@ -35192,10 +35192,11 @@ Focus ONLY on technical, architectural, debugging, decision, workflow, and proje
35192
35192
  try {
35193
35193
  const jsonMatch = responseJson.match(/\{[\s\S]*\}/)?.[0];
35194
35194
  if (!jsonMatch) {
35195
+ logger.debug("parseCurationResponse: No JSON object found in response", "curator");
35195
35196
  throw new Error("No JSON object found in response");
35196
35197
  }
35197
35198
  const data = JSON.parse(jsonMatch);
35198
- return {
35199
+ const result = {
35199
35200
  session_summary: data.session_summary ?? "",
35200
35201
  interaction_tone: data.interaction_tone,
35201
35202
  project_snapshot: data.project_snapshot ? {
@@ -35210,7 +35211,10 @@ Focus ONLY on technical, architectural, debugging, decision, workflow, and proje
35210
35211
  } : undefined,
35211
35212
  memories: this._parseMemories(data.memories ?? [])
35212
35213
  };
35213
- } catch {
35214
+ logger.debug(`Curator parsed: ${result.memories.length} memories, summary: ${result.session_summary ? "yes" : "no"}, snapshot: ${result.project_snapshot ? "yes" : "no"}`, "curator");
35215
+ return result;
35216
+ } catch (error2) {
35217
+ logger.debug(`parseCurationResponse error: ${error2.message}`, "curator");
35214
35218
  return {
35215
35219
  session_summary: "",
35216
35220
  memories: []
@@ -35314,7 +35318,6 @@ This session has ended. Please curate the memories from this conversation accord
35314
35318
  options: {
35315
35319
  systemPrompt,
35316
35320
  permissionMode: "bypassPermissions",
35317
- maxTurns: 1,
35318
35321
  model: "claude-opus-4-5-20251101"
35319
35322
  }
35320
35323
  });
@@ -35326,8 +35329,14 @@ This session has ended. Please curate the memories from this conversation accord
35326
35329
  }
35327
35330
  }
35328
35331
  if (!resultText) {
35332
+ logger.debug("Curator SDK: No result text returned from Agent SDK", "curator");
35329
35333
  return { session_summary: "", memories: [] };
35330
35334
  }
35335
+ logger.debug(`Curator SDK raw response (${resultText.length} chars):`, "curator");
35336
+ if (logger.isVerbose()) {
35337
+ const preview = resultText.length > 3000 ? resultText.slice(0, 3000) + "...[truncated]" : resultText;
35338
+ console.log(preview);
35339
+ }
35331
35340
  return this.parseCurationResponse(resultText);
35332
35341
  }
35333
35342
  _formatConversationTranscript(messages) {
@@ -35374,7 +35383,7 @@ ${content}
35374
35383
  ];
35375
35384
  const response = await client.messages.create({
35376
35385
  model: "claude-sonnet-4-20250514",
35377
- max_tokens: 8192,
35386
+ max_tokens: 64000,
35378
35387
  system: systemPrompt,
35379
35388
  messages: conversationMessages
35380
35389
  });
@@ -35394,7 +35403,7 @@ ${content}
35394
35403
  const args = [];
35395
35404
  let command = this._config.cliCommand;
35396
35405
  if (type === "claude-code") {
35397
- args.push("--resume", sessionId, "-p", userMessage, "--append-system-prompt", systemPrompt, "--output-format", "json", "--max-turns", "1");
35406
+ args.push("--resume", sessionId, "-p", userMessage, "--append-system-prompt", systemPrompt, "--output-format", "json");
35398
35407
  } else {
35399
35408
  command = "gemini";
35400
35409
  args.push("--resume", sessionId, "-p", `${systemPrompt}
@@ -35405,7 +35414,8 @@ ${userMessage}`, "--output-format", "json");
35405
35414
  cwd: cwd2,
35406
35415
  env: {
35407
35416
  ...process.env,
35408
- MEMORY_CURATOR_ACTIVE: "1"
35417
+ MEMORY_CURATOR_ACTIVE: "1",
35418
+ CLAUDE_CODE_MAX_OUTPUT_TOKENS: "64000"
35409
35419
  },
35410
35420
  stdout: "pipe",
35411
35421
  stderr: "pipe"
@@ -35416,37 +35426,59 @@ ${userMessage}`, "--output-format", "json");
35416
35426
  ]);
35417
35427
  const exitCode = await proc.exited;
35418
35428
  if (exitCode !== 0) {
35429
+ logger.debug(`Curator CLI exited with code ${exitCode}`, "curator");
35430
+ if (stderr) {
35431
+ logger.debug(`Curator stderr: ${stderr}`, "curator");
35432
+ }
35419
35433
  return { session_summary: "", memories: [] };
35420
35434
  }
35435
+ logger.debug(`Curator CLI raw stdout (${stdout.length} chars):`, "curator");
35436
+ if (logger.isVerbose()) {
35437
+ const preview = stdout.length > 2000 ? stdout.slice(0, 2000) + "...[truncated]" : stdout;
35438
+ console.log(preview);
35439
+ }
35421
35440
  try {
35422
35441
  const cliOutput = JSON.parse(stdout);
35423
35442
  let resultObj;
35424
35443
  if (Array.isArray(cliOutput)) {
35425
35444
  resultObj = cliOutput.find((item) => item.type === "result");
35426
35445
  if (!resultObj) {
35446
+ logger.debug("Curator: No result object found in CLI output array", "curator");
35427
35447
  return { session_summary: "", memories: [] };
35428
35448
  }
35429
35449
  } else {
35430
35450
  resultObj = cliOutput;
35431
35451
  }
35432
35452
  if (resultObj.type === "error" || resultObj.is_error === true) {
35453
+ logger.debug(`Curator: Error response from CLI: ${JSON.stringify(resultObj).slice(0, 500)}`, "curator");
35433
35454
  return { session_summary: "", memories: [] };
35434
35455
  }
35435
35456
  let aiResponse = "";
35436
35457
  if (typeof resultObj.result === "string") {
35437
35458
  aiResponse = resultObj.result;
35438
35459
  } else {
35460
+ logger.debug(`Curator: result field is not a string: ${typeof resultObj.result}`, "curator");
35439
35461
  return { session_summary: "", memories: [] };
35440
35462
  }
35463
+ logger.debug(`Curator AI response (${aiResponse.length} chars):`, "curator");
35464
+ if (logger.isVerbose()) {
35465
+ const preview = aiResponse.length > 3000 ? aiResponse.slice(0, 3000) + "...[truncated]" : aiResponse;
35466
+ console.log(preview);
35467
+ }
35441
35468
  const codeBlockMatch = aiResponse.match(/```(?:json)?\s*([\s\S]*?)```/);
35442
35469
  if (codeBlockMatch) {
35443
35470
  aiResponse = codeBlockMatch[1].trim();
35444
35471
  }
35445
35472
  const jsonMatch = aiResponse.match(/\{[\s\S]*\}/)?.[0];
35446
35473
  if (jsonMatch) {
35474
+ logger.debug(`Curator: Found JSON object (${jsonMatch.length} chars), parsing...`, "curator");
35447
35475
  return this.parseCurationResponse(jsonMatch);
35476
+ } else {
35477
+ logger.debug("Curator: No JSON object found in AI response", "curator");
35448
35478
  }
35449
- } catch {}
35479
+ } catch (error2) {
35480
+ logger.debug(`Curator: Parse error: ${error2.message}`, "curator");
35481
+ }
35450
35482
  return { session_summary: "", memories: [] };
35451
35483
  }
35452
35484
  }
@@ -42980,10 +42980,11 @@ Focus ONLY on technical, architectural, debugging, decision, workflow, and proje
42980
42980
  try {
42981
42981
  const jsonMatch = responseJson.match(/\{[\s\S]*\}/)?.[0];
42982
42982
  if (!jsonMatch) {
42983
+ logger.debug("parseCurationResponse: No JSON object found in response", "curator");
42983
42984
  throw new Error("No JSON object found in response");
42984
42985
  }
42985
42986
  const data = JSON.parse(jsonMatch);
42986
- return {
42987
+ const result = {
42987
42988
  session_summary: data.session_summary ?? "",
42988
42989
  interaction_tone: data.interaction_tone,
42989
42990
  project_snapshot: data.project_snapshot ? {
@@ -42998,7 +42999,10 @@ Focus ONLY on technical, architectural, debugging, decision, workflow, and proje
42998
42999
  } : undefined,
42999
43000
  memories: this._parseMemories(data.memories ?? [])
43000
43001
  };
43001
- } catch {
43002
+ logger.debug(`Curator parsed: ${result.memories.length} memories, summary: ${result.session_summary ? "yes" : "no"}, snapshot: ${result.project_snapshot ? "yes" : "no"}`, "curator");
43003
+ return result;
43004
+ } catch (error2) {
43005
+ logger.debug(`parseCurationResponse error: ${error2.message}`, "curator");
43002
43006
  return {
43003
43007
  session_summary: "",
43004
43008
  memories: []
@@ -43102,7 +43106,6 @@ This session has ended. Please curate the memories from this conversation accord
43102
43106
  options: {
43103
43107
  systemPrompt,
43104
43108
  permissionMode: "bypassPermissions",
43105
- maxTurns: 1,
43106
43109
  model: "claude-opus-4-5-20251101"
43107
43110
  }
43108
43111
  });
@@ -43114,8 +43117,14 @@ This session has ended. Please curate the memories from this conversation accord
43114
43117
  }
43115
43118
  }
43116
43119
  if (!resultText) {
43120
+ logger.debug("Curator SDK: No result text returned from Agent SDK", "curator");
43117
43121
  return { session_summary: "", memories: [] };
43118
43122
  }
43123
+ logger.debug(`Curator SDK raw response (${resultText.length} chars):`, "curator");
43124
+ if (logger.isVerbose()) {
43125
+ const preview = resultText.length > 3000 ? resultText.slice(0, 3000) + "...[truncated]" : resultText;
43126
+ console.log(preview);
43127
+ }
43119
43128
  return this.parseCurationResponse(resultText);
43120
43129
  }
43121
43130
  _formatConversationTranscript(messages) {
@@ -43162,7 +43171,7 @@ ${content}
43162
43171
  ];
43163
43172
  const response = await client.messages.create({
43164
43173
  model: "claude-sonnet-4-20250514",
43165
- max_tokens: 8192,
43174
+ max_tokens: 64000,
43166
43175
  system: systemPrompt,
43167
43176
  messages: conversationMessages
43168
43177
  });
@@ -43182,7 +43191,7 @@ ${content}
43182
43191
  const args = [];
43183
43192
  let command = this._config.cliCommand;
43184
43193
  if (type === "claude-code") {
43185
- args.push("--resume", sessionId, "-p", userMessage, "--append-system-prompt", systemPrompt, "--output-format", "json", "--max-turns", "1");
43194
+ args.push("--resume", sessionId, "-p", userMessage, "--append-system-prompt", systemPrompt, "--output-format", "json");
43186
43195
  } else {
43187
43196
  command = "gemini";
43188
43197
  args.push("--resume", sessionId, "-p", `${systemPrompt}
@@ -43193,7 +43202,8 @@ ${userMessage}`, "--output-format", "json");
43193
43202
  cwd: cwd2,
43194
43203
  env: {
43195
43204
  ...process.env,
43196
- MEMORY_CURATOR_ACTIVE: "1"
43205
+ MEMORY_CURATOR_ACTIVE: "1",
43206
+ CLAUDE_CODE_MAX_OUTPUT_TOKENS: "64000"
43197
43207
  },
43198
43208
  stdout: "pipe",
43199
43209
  stderr: "pipe"
@@ -43204,37 +43214,59 @@ ${userMessage}`, "--output-format", "json");
43204
43214
  ]);
43205
43215
  const exitCode = await proc.exited;
43206
43216
  if (exitCode !== 0) {
43217
+ logger.debug(`Curator CLI exited with code ${exitCode}`, "curator");
43218
+ if (stderr) {
43219
+ logger.debug(`Curator stderr: ${stderr}`, "curator");
43220
+ }
43207
43221
  return { session_summary: "", memories: [] };
43208
43222
  }
43223
+ logger.debug(`Curator CLI raw stdout (${stdout.length} chars):`, "curator");
43224
+ if (logger.isVerbose()) {
43225
+ const preview = stdout.length > 2000 ? stdout.slice(0, 2000) + "...[truncated]" : stdout;
43226
+ console.log(preview);
43227
+ }
43209
43228
  try {
43210
43229
  const cliOutput = JSON.parse(stdout);
43211
43230
  let resultObj;
43212
43231
  if (Array.isArray(cliOutput)) {
43213
43232
  resultObj = cliOutput.find((item) => item.type === "result");
43214
43233
  if (!resultObj) {
43234
+ logger.debug("Curator: No result object found in CLI output array", "curator");
43215
43235
  return { session_summary: "", memories: [] };
43216
43236
  }
43217
43237
  } else {
43218
43238
  resultObj = cliOutput;
43219
43239
  }
43220
43240
  if (resultObj.type === "error" || resultObj.is_error === true) {
43241
+ logger.debug(`Curator: Error response from CLI: ${JSON.stringify(resultObj).slice(0, 500)}`, "curator");
43221
43242
  return { session_summary: "", memories: [] };
43222
43243
  }
43223
43244
  let aiResponse = "";
43224
43245
  if (typeof resultObj.result === "string") {
43225
43246
  aiResponse = resultObj.result;
43226
43247
  } else {
43248
+ logger.debug(`Curator: result field is not a string: ${typeof resultObj.result}`, "curator");
43227
43249
  return { session_summary: "", memories: [] };
43228
43250
  }
43251
+ logger.debug(`Curator AI response (${aiResponse.length} chars):`, "curator");
43252
+ if (logger.isVerbose()) {
43253
+ const preview = aiResponse.length > 3000 ? aiResponse.slice(0, 3000) + "...[truncated]" : aiResponse;
43254
+ console.log(preview);
43255
+ }
43229
43256
  const codeBlockMatch = aiResponse.match(/```(?:json)?\s*([\s\S]*?)```/);
43230
43257
  if (codeBlockMatch) {
43231
43258
  aiResponse = codeBlockMatch[1].trim();
43232
43259
  }
43233
43260
  const jsonMatch = aiResponse.match(/\{[\s\S]*\}/)?.[0];
43234
43261
  if (jsonMatch) {
43262
+ logger.debug(`Curator: Found JSON object (${jsonMatch.length} chars), parsing...`, "curator");
43235
43263
  return this.parseCurationResponse(jsonMatch);
43264
+ } else {
43265
+ logger.debug("Curator: No JSON object found in AI response", "curator");
43236
43266
  }
43237
- } catch {}
43267
+ } catch (error2) {
43268
+ logger.debug(`Curator: Parse error: ${error2.message}`, "curator");
43269
+ }
43238
43270
  return { session_summary: "", memories: [] };
43239
43271
  }
43240
43272
  }
@@ -42960,10 +42960,11 @@ Focus ONLY on technical, architectural, debugging, decision, workflow, and proje
42960
42960
  try {
42961
42961
  const jsonMatch = responseJson.match(/\{[\s\S]*\}/)?.[0];
42962
42962
  if (!jsonMatch) {
42963
+ logger.debug("parseCurationResponse: No JSON object found in response", "curator");
42963
42964
  throw new Error("No JSON object found in response");
42964
42965
  }
42965
42966
  const data = JSON.parse(jsonMatch);
42966
- return {
42967
+ const result = {
42967
42968
  session_summary: data.session_summary ?? "",
42968
42969
  interaction_tone: data.interaction_tone,
42969
42970
  project_snapshot: data.project_snapshot ? {
@@ -42978,7 +42979,10 @@ Focus ONLY on technical, architectural, debugging, decision, workflow, and proje
42978
42979
  } : undefined,
42979
42980
  memories: this._parseMemories(data.memories ?? [])
42980
42981
  };
42981
- } catch {
42982
+ logger.debug(`Curator parsed: ${result.memories.length} memories, summary: ${result.session_summary ? "yes" : "no"}, snapshot: ${result.project_snapshot ? "yes" : "no"}`, "curator");
42983
+ return result;
42984
+ } catch (error2) {
42985
+ logger.debug(`parseCurationResponse error: ${error2.message}`, "curator");
42982
42986
  return {
42983
42987
  session_summary: "",
42984
42988
  memories: []
@@ -43082,7 +43086,6 @@ This session has ended. Please curate the memories from this conversation accord
43082
43086
  options: {
43083
43087
  systemPrompt,
43084
43088
  permissionMode: "bypassPermissions",
43085
- maxTurns: 1,
43086
43089
  model: "claude-opus-4-5-20251101"
43087
43090
  }
43088
43091
  });
@@ -43094,8 +43097,14 @@ This session has ended. Please curate the memories from this conversation accord
43094
43097
  }
43095
43098
  }
43096
43099
  if (!resultText) {
43100
+ logger.debug("Curator SDK: No result text returned from Agent SDK", "curator");
43097
43101
  return { session_summary: "", memories: [] };
43098
43102
  }
43103
+ logger.debug(`Curator SDK raw response (${resultText.length} chars):`, "curator");
43104
+ if (logger.isVerbose()) {
43105
+ const preview = resultText.length > 3000 ? resultText.slice(0, 3000) + "...[truncated]" : resultText;
43106
+ console.log(preview);
43107
+ }
43099
43108
  return this.parseCurationResponse(resultText);
43100
43109
  }
43101
43110
  _formatConversationTranscript(messages) {
@@ -43142,7 +43151,7 @@ ${content}
43142
43151
  ];
43143
43152
  const response = await client.messages.create({
43144
43153
  model: "claude-sonnet-4-20250514",
43145
- max_tokens: 8192,
43154
+ max_tokens: 64000,
43146
43155
  system: systemPrompt,
43147
43156
  messages: conversationMessages
43148
43157
  });
@@ -43162,7 +43171,7 @@ ${content}
43162
43171
  const args = [];
43163
43172
  let command = this._config.cliCommand;
43164
43173
  if (type === "claude-code") {
43165
- args.push("--resume", sessionId, "-p", userMessage, "--append-system-prompt", systemPrompt, "--output-format", "json", "--max-turns", "1");
43174
+ args.push("--resume", sessionId, "-p", userMessage, "--append-system-prompt", systemPrompt, "--output-format", "json");
43166
43175
  } else {
43167
43176
  command = "gemini";
43168
43177
  args.push("--resume", sessionId, "-p", `${systemPrompt}
@@ -43173,7 +43182,8 @@ ${userMessage}`, "--output-format", "json");
43173
43182
  cwd: cwd2,
43174
43183
  env: {
43175
43184
  ...process.env,
43176
- MEMORY_CURATOR_ACTIVE: "1"
43185
+ MEMORY_CURATOR_ACTIVE: "1",
43186
+ CLAUDE_CODE_MAX_OUTPUT_TOKENS: "64000"
43177
43187
  },
43178
43188
  stdout: "pipe",
43179
43189
  stderr: "pipe"
@@ -43184,37 +43194,59 @@ ${userMessage}`, "--output-format", "json");
43184
43194
  ]);
43185
43195
  const exitCode = await proc.exited;
43186
43196
  if (exitCode !== 0) {
43197
+ logger.debug(`Curator CLI exited with code ${exitCode}`, "curator");
43198
+ if (stderr) {
43199
+ logger.debug(`Curator stderr: ${stderr}`, "curator");
43200
+ }
43187
43201
  return { session_summary: "", memories: [] };
43188
43202
  }
43203
+ logger.debug(`Curator CLI raw stdout (${stdout.length} chars):`, "curator");
43204
+ if (logger.isVerbose()) {
43205
+ const preview = stdout.length > 2000 ? stdout.slice(0, 2000) + "...[truncated]" : stdout;
43206
+ console.log(preview);
43207
+ }
43189
43208
  try {
43190
43209
  const cliOutput = JSON.parse(stdout);
43191
43210
  let resultObj;
43192
43211
  if (Array.isArray(cliOutput)) {
43193
43212
  resultObj = cliOutput.find((item) => item.type === "result");
43194
43213
  if (!resultObj) {
43214
+ logger.debug("Curator: No result object found in CLI output array", "curator");
43195
43215
  return { session_summary: "", memories: [] };
43196
43216
  }
43197
43217
  } else {
43198
43218
  resultObj = cliOutput;
43199
43219
  }
43200
43220
  if (resultObj.type === "error" || resultObj.is_error === true) {
43221
+ logger.debug(`Curator: Error response from CLI: ${JSON.stringify(resultObj).slice(0, 500)}`, "curator");
43201
43222
  return { session_summary: "", memories: [] };
43202
43223
  }
43203
43224
  let aiResponse = "";
43204
43225
  if (typeof resultObj.result === "string") {
43205
43226
  aiResponse = resultObj.result;
43206
43227
  } else {
43228
+ logger.debug(`Curator: result field is not a string: ${typeof resultObj.result}`, "curator");
43207
43229
  return { session_summary: "", memories: [] };
43208
43230
  }
43231
+ logger.debug(`Curator AI response (${aiResponse.length} chars):`, "curator");
43232
+ if (logger.isVerbose()) {
43233
+ const preview = aiResponse.length > 3000 ? aiResponse.slice(0, 3000) + "...[truncated]" : aiResponse;
43234
+ console.log(preview);
43235
+ }
43209
43236
  const codeBlockMatch = aiResponse.match(/```(?:json)?\s*([\s\S]*?)```/);
43210
43237
  if (codeBlockMatch) {
43211
43238
  aiResponse = codeBlockMatch[1].trim();
43212
43239
  }
43213
43240
  const jsonMatch = aiResponse.match(/\{[\s\S]*\}/)?.[0];
43214
43241
  if (jsonMatch) {
43242
+ logger.debug(`Curator: Found JSON object (${jsonMatch.length} chars), parsing...`, "curator");
43215
43243
  return this.parseCurationResponse(jsonMatch);
43244
+ } else {
43245
+ logger.debug("Curator: No JSON object found in AI response", "curator");
43216
43246
  }
43217
- } catch {}
43247
+ } catch (error2) {
43248
+ logger.debug(`Curator: Parse error: ${error2.message}`, "curator");
43249
+ }
43218
43250
  return { session_summary: "", memories: [] };
43219
43251
  }
43220
43252
  }
@@ -38,9 +38,13 @@ async function main() {
38
38
 
39
39
  const sessionId = input.session_id || 'unknown'
40
40
  const cwd = process.env.CLAUDE_PROJECT_DIR || input.cwd || process.cwd()
41
- const trigger = input.trigger || 'pre_compact'
42
41
  const hookEvent = input.hook_event_name || 'PreCompact'
43
42
 
43
+ // Determine trigger type from hook event name (more reliable than input.trigger)
44
+ // PreCompact = context is being compacted, session still active
45
+ // SessionEnd/Stop = session is ending
46
+ const trigger = hookEvent === 'PreCompact' ? 'pre_compact' : 'session_end'
47
+
44
48
  const projectId = getProjectId(cwd)
45
49
 
46
50
  console.error(info(`🧠 Curating memories (${hookEvent})...`))
@@ -54,7 +58,7 @@ async function main() {
54
58
  session_id: sessionId,
55
59
  project_id: projectId,
56
60
  claude_session_id: sessionId,
57
- trigger: trigger === 'pre_compact' || trigger === 'manual' ? 'pre_compact' : 'session_end',
61
+ trigger,
58
62
  cwd,
59
63
  }),
60
64
  signal: AbortSignal.timeout(5000),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rlabs-inc/memory",
3
- "version": "0.4.7",
3
+ "version": "0.4.8",
4
4
  "description": "AI Memory System - Consciousness continuity through intelligent memory curation and retrieval",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -6,8 +6,10 @@
6
6
  import { homedir } from 'os'
7
7
  import { join } from 'path'
8
8
  import { existsSync } from 'fs'
9
+ import { readdir } from 'fs/promises'
9
10
  import type { CuratedMemory, CurationResult, CurationTrigger, ContextType } from '../types/memory.ts'
10
11
  import { logger } from '../utils/logger.ts'
12
+ import { parseSessionFile, type ParsedMessage } from './session-parser.ts'
11
13
 
12
14
  /**
13
15
  * Get the correct Claude CLI command path
@@ -401,8 +403,23 @@ Focus ONLY on technical, architectural, debugging, decision, workflow, and proje
401
403
  throw new Error('No JSON object found in response')
402
404
  }
403
405
 
406
+ // Log JSON structure for debugging
407
+ logger.debug(`parseCurationResponse: Attempting to parse ${jsonMatch.length} chars`, 'curator')
408
+
404
409
  // Simple parse - match Python's approach
405
- const data = JSON.parse(jsonMatch)
410
+ let data: any
411
+ try {
412
+ data = JSON.parse(jsonMatch)
413
+ } catch (parseErr: any) {
414
+ // Log more details about where parse failed
415
+ logger.debug(`parseCurationResponse: JSON.parse failed: ${parseErr.message}`, 'curator')
416
+ logger.debug(`parseCurationResponse: Last 100 chars: '${jsonMatch.slice(-100)}'`, 'curator')
417
+ // Try to find where the JSON breaks
418
+ const openBraces = (jsonMatch.match(/\{/g) || []).length
419
+ const closeBraces = (jsonMatch.match(/\}/g) || []).length
420
+ logger.debug(`parseCurationResponse: Brace count - open: ${openBraces}, close: ${closeBraces}`, 'curator')
421
+ throw parseErr
422
+ }
406
423
 
407
424
  const result: CurationResult = {
408
425
  session_summary: data.session_summary ?? '',
@@ -664,6 +681,75 @@ This session has ended. Please curate the memories from this conversation accord
664
681
  return this.curateWithSDK(segment.messages, triggerType)
665
682
  }
666
683
 
684
+ /**
685
+ * Find and curate from a session file directly
686
+ * Uses SDK mode to avoid CLI output truncation issues
687
+ */
688
+ async curateFromSessionFile(
689
+ sessionId: string,
690
+ triggerType: CurationTrigger = 'session_end',
691
+ cwd?: string
692
+ ): Promise<CurationResult> {
693
+ // Find the session file
694
+ const sessionFile = await this._findSessionFile(sessionId, cwd)
695
+ if (!sessionFile) {
696
+ logger.debug(`Curator: Could not find session file for ${sessionId}`, 'curator')
697
+ return { session_summary: '', memories: [] }
698
+ }
699
+
700
+ logger.debug(`Curator: Found session file: ${sessionFile}`, 'curator')
701
+
702
+ // Parse the session
703
+ const session = await parseSessionFile(sessionFile)
704
+ if (session.messages.length === 0) {
705
+ logger.debug('Curator: Session has no messages', 'curator')
706
+ return { session_summary: '', memories: [] }
707
+ }
708
+
709
+ logger.debug(`Curator: Parsed ${session.messages.length} messages, ~${session.metadata.estimatedTokens} tokens`, 'curator')
710
+
711
+ // Use SDK mode with the parsed messages
712
+ return this.curateWithSDK(session.messages as any, triggerType)
713
+ }
714
+
715
+ /**
716
+ * Find the session file path given a session ID
717
+ */
718
+ private async _findSessionFile(sessionId: string, cwd?: string): Promise<string | null> {
719
+ const projectsDir = join(homedir(), '.claude', 'projects')
720
+
721
+ // If we have cwd, try to derive the project folder name
722
+ if (cwd) {
723
+ // Convert cwd to Claude's folder naming: /home/user/project -> -home-user-project
724
+ const projectFolder = cwd.replace(/\//g, '-').replace(/^-/, '-')
725
+ const sessionPath = join(projectsDir, projectFolder, `${sessionId}.jsonl`)
726
+ if (existsSync(sessionPath)) {
727
+ return sessionPath
728
+ }
729
+
730
+ // Also try the exact folder name (cwd might already be encoded)
731
+ const altPath = join(projectsDir, cwd.split('/').pop() || '', `${sessionId}.jsonl`)
732
+ if (existsSync(altPath)) {
733
+ return altPath
734
+ }
735
+ }
736
+
737
+ // Search all project folders for the session ID
738
+ try {
739
+ const projectFolders = await readdir(projectsDir)
740
+ for (const folder of projectFolders) {
741
+ const sessionPath = join(projectsDir, folder, `${sessionId}.jsonl`)
742
+ if (existsSync(sessionPath)) {
743
+ return sessionPath
744
+ }
745
+ }
746
+ } catch {
747
+ // Projects dir doesn't exist
748
+ }
749
+
750
+ return null
751
+ }
752
+
667
753
  /**
668
754
  * Curate using CLI subprocess (for hook mode)
669
755
  * Resumes a session and asks it to curate
@@ -700,6 +786,9 @@ This session has ended. Please curate the memories from this conversation accord
700
786
  }
701
787
 
702
788
  // Execute CLI
789
+ logger.debug(`Curator: Spawning CLI with CLAUDE_CODE_MAX_OUTPUT_TOKENS=64000`, 'curator')
790
+ logger.debug(`Curator: Command: ${command} ${args.slice(0, 3).join(' ')}...`, 'curator')
791
+
703
792
  const proc = Bun.spawn([command, ...args], {
704
793
  cwd,
705
794
  env: {
@@ -718,16 +807,19 @@ This session has ended. Please curate the memories from this conversation accord
718
807
  ])
719
808
  const exitCode = await proc.exited
720
809
 
810
+ logger.debug(`Curator CLI exit code: ${exitCode}`, 'curator')
811
+ if (stderr && stderr.trim()) {
812
+ logger.debug(`Curator stderr (${stderr.length} chars): ${stderr.slice(0, 500)}`, 'curator')
813
+ }
814
+
721
815
  if (exitCode !== 0) {
722
- logger.debug(`Curator CLI exited with code ${exitCode}`, 'curator')
723
- if (stderr) {
724
- logger.debug(`Curator stderr: ${stderr}`, 'curator')
725
- }
726
816
  return { session_summary: '', memories: [] }
727
817
  }
728
818
 
729
819
  // Log raw response in verbose mode
730
820
  logger.debug(`Curator CLI raw stdout (${stdout.length} chars):`, 'curator')
821
+ // Always log the last 100 chars to see where output ends
822
+ logger.debug(`Curator: stdout ends with: '${stdout.slice(-100)}'`, 'curator')
731
823
  if (logger.isVerbose()) {
732
824
  // Show first 2000 chars to avoid flooding console
733
825
  const preview = stdout.length > 2000 ? stdout.slice(0, 2000) + '...[truncated]' : stdout
@@ -778,14 +870,43 @@ This session has ended. Please curate the memories from this conversation accord
778
870
  // Remove markdown code blocks if present (```json ... ```)
779
871
  const codeBlockMatch = aiResponse.match(/```(?:json)?\s*([\s\S]*?)```/)
780
872
  if (codeBlockMatch) {
873
+ logger.debug(`Curator: Code block matched, extracting ${codeBlockMatch[1]!.length} chars`, 'curator')
781
874
  aiResponse = codeBlockMatch[1]!.trim()
875
+ } else {
876
+ logger.debug(`Curator: No code block found, using raw response`, 'curator')
877
+ // Log the last 200 chars to see where truncation happened
878
+ if (aiResponse.length > 200) {
879
+ logger.debug(`Curator: Last 200 chars of response: ${aiResponse.slice(-200)}`, 'curator')
880
+ }
782
881
  }
783
882
 
784
883
  // Now find the JSON object (same regex as Python)
785
884
  const jsonMatch = aiResponse.match(/\{[\s\S]*\}/)?.[0]
786
885
  if (jsonMatch) {
787
886
  logger.debug(`Curator: Found JSON object (${jsonMatch.length} chars), parsing...`, 'curator')
788
- return this.parseCurationResponse(jsonMatch)
887
+
888
+ // Detect likely truncation: JSON much smaller than response
889
+ const likelyTruncated = jsonMatch.length < aiResponse.length * 0.5
890
+
891
+ if (likelyTruncated) {
892
+ logger.debug(`Curator: WARNING - JSON (${jsonMatch.length}) much smaller than response (${aiResponse.length}) - likely truncated`, 'curator')
893
+ // Find the last } position and log what's around it
894
+ const lastBrace = aiResponse.lastIndexOf('}')
895
+ logger.debug(`Curator: Last } at position ${lastBrace}, char before: '${aiResponse[lastBrace-1]}', char after: '${aiResponse[lastBrace+1] || 'EOF'}'`, 'curator')
896
+ // Log chars around the cut point
897
+ const cutPoint = jsonMatch.length
898
+ logger.debug(`Curator: Around match end (${cutPoint}): '...${aiResponse.slice(Math.max(0, cutPoint-50), cutPoint+50)}...'`, 'curator')
899
+ }
900
+
901
+ const result = this.parseCurationResponse(jsonMatch)
902
+
903
+ // If we got 0 memories and likely truncated, try SDK fallback
904
+ if (result.memories.length === 0 && likelyTruncated) {
905
+ logger.debug('Curator: CLI mode returned 0 memories with truncation detected, trying SDK fallback...', 'curator')
906
+ return this._fallbackToSDK(sessionId, triggerType, cwd)
907
+ }
908
+
909
+ return result
789
910
  } else {
790
911
  logger.debug('Curator: No JSON object found in AI response', 'curator')
791
912
  }
@@ -794,7 +915,31 @@ This session has ended. Please curate the memories from this conversation accord
794
915
  logger.debug(`Curator: Parse error: ${error.message}`, 'curator')
795
916
  }
796
917
 
797
- return { session_summary: '', memories: [] }
918
+ // CLI mode failed - try SDK fallback
919
+ logger.debug('Curator: CLI mode failed, trying SDK fallback...', 'curator')
920
+ return this._fallbackToSDK(sessionId, triggerType, cwd)
921
+ }
922
+
923
+ /**
924
+ * Fallback to SDK mode when CLI mode fails (e.g., output truncation)
925
+ */
926
+ private async _fallbackToSDK(
927
+ sessionId: string,
928
+ triggerType: CurationTrigger,
929
+ cwd?: string
930
+ ): Promise<CurationResult> {
931
+ try {
932
+ const result = await this.curateFromSessionFile(sessionId, triggerType, cwd)
933
+ if (result.memories.length > 0) {
934
+ logger.debug(`Curator: SDK fallback succeeded with ${result.memories.length} memories`, 'curator')
935
+ } else {
936
+ logger.debug('Curator: SDK fallback also returned 0 memories', 'curator')
937
+ }
938
+ return result
939
+ } catch (error: any) {
940
+ logger.debug(`Curator: SDK fallback failed: ${error.message}`, 'curator')
941
+ return { session_summary: '', memories: [] }
942
+ }
798
943
  }
799
944
  }
800
945