@rlabs-inc/memory 0.4.10 → 0.4.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -0
- package/dist/index.js +395 -73
- package/dist/index.mjs +379 -57
- package/dist/server/index.js +412 -86
- package/dist/server/index.mjs +385 -59
- package/package.json +2 -2
- package/src/core/curator.ts +92 -0
- package/src/server/index.ts +14 -4
package/dist/index.js
CHANGED
|
@@ -327,7 +327,7 @@ function shouldShowDebugMessage(message, filter) {
|
|
|
327
327
|
return shouldShowDebugCategories(categories, filter);
|
|
328
328
|
}
|
|
329
329
|
function getClaudeConfigHomeDir() {
|
|
330
|
-
return process.env.CLAUDE_CONFIG_DIR ??
|
|
330
|
+
return process.env.CLAUDE_CONFIG_DIR ?? import_path5.join(import_os3.homedir(), ".claude");
|
|
331
331
|
}
|
|
332
332
|
function isEnvTruthy(envVar) {
|
|
333
333
|
if (!envVar)
|
|
@@ -374,6 +374,7 @@ function getInitialState() {
|
|
|
374
374
|
}
|
|
375
375
|
return {
|
|
376
376
|
originalCwd: resolvedCwd,
|
|
377
|
+
projectRoot: resolvedCwd,
|
|
377
378
|
totalCostUSD: 0,
|
|
378
379
|
totalAPIDuration: 0,
|
|
379
380
|
totalAPIDurationWithoutRetries: 0,
|
|
@@ -411,6 +412,7 @@ function getInitialState() {
|
|
|
411
412
|
codeEditToolDecisionCounter: null,
|
|
412
413
|
activeTimeCounter: null,
|
|
413
414
|
sessionId: import_crypto.randomUUID(),
|
|
415
|
+
parentSessionId: undefined,
|
|
414
416
|
loggerProvider: null,
|
|
415
417
|
eventLogger: null,
|
|
416
418
|
meterProvider: null,
|
|
@@ -422,6 +424,7 @@ function getInitialState() {
|
|
|
422
424
|
inMemoryErrorLog: [],
|
|
423
425
|
inlinePlugins: [],
|
|
424
426
|
sessionBypassPermissionsMode: false,
|
|
427
|
+
sessionTrustAccepted: false,
|
|
425
428
|
sessionPersistenceDisabled: false,
|
|
426
429
|
hasExitedPlanMode: false,
|
|
427
430
|
needsPlanModeExitAttachment: false,
|
|
@@ -434,22 +437,13 @@ function getInitialState() {
|
|
|
434
437
|
teleportedSessionInfo: null,
|
|
435
438
|
invokedSkills: new Map,
|
|
436
439
|
slowOperations: [],
|
|
437
|
-
sdkBetas: undefined
|
|
440
|
+
sdkBetas: undefined,
|
|
441
|
+
mainThreadAgentType: undefined
|
|
438
442
|
};
|
|
439
443
|
}
|
|
440
444
|
function getSessionId() {
|
|
441
445
|
return STATE.sessionId;
|
|
442
446
|
}
|
|
443
|
-
function addSlowOperation(operation, durationMs) {
|
|
444
|
-
if (true)
|
|
445
|
-
return;
|
|
446
|
-
const now = Date.now();
|
|
447
|
-
STATE.slowOperations = STATE.slowOperations.filter((op) => now - op.timestamp < SLOW_OPERATION_TTL_MS);
|
|
448
|
-
STATE.slowOperations.push({ operation, durationMs, timestamp: now });
|
|
449
|
-
if (STATE.slowOperations.length > MAX_SLOW_OPERATIONS) {
|
|
450
|
-
STATE.slowOperations = STATE.slowOperations.slice(-MAX_SLOW_OPERATIONS);
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
447
|
function createBufferedWriter({
|
|
454
448
|
writeFn,
|
|
455
449
|
flushIntervalMs = 1000,
|
|
@@ -519,10 +513,7 @@ function withSlowLogging(operation, fn) {
|
|
|
519
513
|
return fn();
|
|
520
514
|
} finally {
|
|
521
515
|
const duration = performance.now() - startTime;
|
|
522
|
-
if (duration > SLOW_OPERATION_THRESHOLD_MS) {
|
|
523
|
-
logForDebugging(`[SLOW OPERATION DETECTED] ${operation} (${duration.toFixed(1)}ms)`);
|
|
524
|
-
addSlowOperation(operation, duration);
|
|
525
|
-
}
|
|
516
|
+
if (duration > SLOW_OPERATION_THRESHOLD_MS && false) {}
|
|
526
517
|
}
|
|
527
518
|
}
|
|
528
519
|
function jsonStringify(value, replacer, space) {
|
|
@@ -542,8 +533,8 @@ function getDebugWriter() {
|
|
|
542
533
|
debugWriter = createBufferedWriter({
|
|
543
534
|
writeFn: (content) => {
|
|
544
535
|
const path = getDebugLogPath();
|
|
545
|
-
if (!getFsImplementation().existsSync(
|
|
546
|
-
getFsImplementation().mkdirSync(
|
|
536
|
+
if (!getFsImplementation().existsSync(import_path6.dirname(path))) {
|
|
537
|
+
getFsImplementation().mkdirSync(import_path6.dirname(path));
|
|
547
538
|
}
|
|
548
539
|
getFsImplementation().appendFileSync(path, content);
|
|
549
540
|
updateLatestDebugLogSymlink();
|
|
@@ -556,7 +547,7 @@ function getDebugWriter() {
|
|
|
556
547
|
}
|
|
557
548
|
return debugWriter;
|
|
558
549
|
}
|
|
559
|
-
function
|
|
550
|
+
function logForDebugging2(message, { level } = {
|
|
560
551
|
level: "debug"
|
|
561
552
|
}) {
|
|
562
553
|
if (!shouldLogDebugMessage(message)) {
|
|
@@ -576,7 +567,7 @@ function logForDebugging(message, { level } = {
|
|
|
576
567
|
getDebugWriter().write(output);
|
|
577
568
|
}
|
|
578
569
|
function getDebugLogPath() {
|
|
579
|
-
return process.env.CLAUDE_CODE_DEBUG_LOGS_DIR ??
|
|
570
|
+
return process.env.CLAUDE_CODE_DEBUG_LOGS_DIR ?? import_path6.join(getClaudeConfigHomeDir(), "debug", `${getSessionId()}.txt`);
|
|
580
571
|
}
|
|
581
572
|
function withSlowLogging2(operation, fn) {
|
|
582
573
|
const startTime = performance.now();
|
|
@@ -584,10 +575,7 @@ function withSlowLogging2(operation, fn) {
|
|
|
584
575
|
return fn();
|
|
585
576
|
} finally {
|
|
586
577
|
const duration = performance.now() - startTime;
|
|
587
|
-
if (duration > SLOW_OPERATION_THRESHOLD_MS) {
|
|
588
|
-
logForDebugging(`[SLOW OPERATION DETECTED] fs.${operation} (${duration.toFixed(1)}ms)`);
|
|
589
|
-
addSlowOperation(`fs.${operation}`, duration);
|
|
590
|
-
}
|
|
578
|
+
if (duration > SLOW_OPERATION_THRESHOLD_MS && !isLoggingSlowOperation && false) {}
|
|
591
579
|
}
|
|
592
580
|
}
|
|
593
581
|
function getFsImplementation() {
|
|
@@ -604,8 +592,8 @@ function getOrCreateDebugFile() {
|
|
|
604
592
|
if (!process.env.DEBUG_CLAUDE_AGENT_SDK) {
|
|
605
593
|
return null;
|
|
606
594
|
}
|
|
607
|
-
const debugDir =
|
|
608
|
-
debugFilePath =
|
|
595
|
+
const debugDir = import_path7.join(getClaudeConfigHomeDir(), "debug");
|
|
596
|
+
debugFilePath = import_path7.join(debugDir, `sdk-${import_crypto2.randomUUID()}.txt`);
|
|
609
597
|
if (!import_fs3.existsSync(debugDir)) {
|
|
610
598
|
import_fs3.mkdirSync(debugDir, { recursive: true });
|
|
611
599
|
}
|
|
@@ -696,6 +684,7 @@ class ProcessTransport {
|
|
|
696
684
|
try {
|
|
697
685
|
const {
|
|
698
686
|
additionalDirectories = [],
|
|
687
|
+
agent,
|
|
699
688
|
betas,
|
|
700
689
|
cwd: cwd2,
|
|
701
690
|
executable = this.getDefaultExecutable(),
|
|
@@ -742,6 +731,8 @@ class ProcessTransport {
|
|
|
742
731
|
}
|
|
743
732
|
if (model)
|
|
744
733
|
args.push("--model", model);
|
|
734
|
+
if (agent)
|
|
735
|
+
args.push("--agent", agent);
|
|
745
736
|
if (betas && betas.length > 0) {
|
|
746
737
|
args.push("--betas", betas.join(","));
|
|
747
738
|
}
|
|
@@ -972,8 +963,13 @@ class ProcessTransport {
|
|
|
972
963
|
try {
|
|
973
964
|
for await (const line of rl) {
|
|
974
965
|
if (line.trim()) {
|
|
975
|
-
|
|
976
|
-
|
|
966
|
+
try {
|
|
967
|
+
const message = jsonParse(line);
|
|
968
|
+
yield message;
|
|
969
|
+
} catch (_parseError) {
|
|
970
|
+
logForSdkDebugging(`Non-JSON stdout: ${line}`);
|
|
971
|
+
throw new Error(`CLI output was not valid JSON. ` + `This may indicate an error during startup. ` + `Output: ${line.slice(0, 200)}${line.length > 200 ? "..." : ""}`);
|
|
972
|
+
}
|
|
977
973
|
}
|
|
978
974
|
}
|
|
979
975
|
await this.waitForExit();
|
|
@@ -6572,13 +6568,14 @@ function query({
|
|
|
6572
6568
|
let pathToClaudeCodeExecutable = rest.pathToClaudeCodeExecutable;
|
|
6573
6569
|
if (!pathToClaudeCodeExecutable) {
|
|
6574
6570
|
const filename = import_url.fileURLToPath(import.meta.url);
|
|
6575
|
-
const dirname2 =
|
|
6576
|
-
pathToClaudeCodeExecutable =
|
|
6571
|
+
const dirname2 = import_path4.join(filename, "..");
|
|
6572
|
+
pathToClaudeCodeExecutable = import_path4.join(dirname2, "cli.js");
|
|
6577
6573
|
}
|
|
6578
|
-
process.env.CLAUDE_AGENT_SDK_VERSION = "0.2.
|
|
6574
|
+
process.env.CLAUDE_AGENT_SDK_VERSION = "0.2.12";
|
|
6579
6575
|
const {
|
|
6580
6576
|
abortController = createAbortController(),
|
|
6581
6577
|
additionalDirectories = [],
|
|
6578
|
+
agent,
|
|
6582
6579
|
agents,
|
|
6583
6580
|
allowedTools = [],
|
|
6584
6581
|
betas,
|
|
@@ -6645,6 +6642,7 @@ function query({
|
|
|
6645
6642
|
const transport = new ProcessTransport({
|
|
6646
6643
|
abortController,
|
|
6647
6644
|
additionalDirectories,
|
|
6645
|
+
agent,
|
|
6648
6646
|
betas,
|
|
6649
6647
|
cwd: cwd2,
|
|
6650
6648
|
executable,
|
|
@@ -6726,7 +6724,7 @@ async function unstable_v2_prompt(message, options) {
|
|
|
6726
6724
|
_promise && await _promise;
|
|
6727
6725
|
}
|
|
6728
6726
|
}
|
|
6729
|
-
var
|
|
6727
|
+
var import_path4, import_url, import_events, import_child_process, import_readline, fs, import_promises, import_path5, import_os3, import_path6, import_process, import_fs2, import_crypto, import_crypto2, import_fs3, import_path7, import_crypto3, import_path8, import_url2, __create2, __getProtoOf2, __defProp2, __getOwnPropNames2, __hasOwnProp2, __toESM2 = (mod, isNodeMode, target) => {
|
|
6730
6728
|
target = mod != null ? __create2(__getProtoOf2(mod)) : {};
|
|
6731
6729
|
const to = isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target;
|
|
6732
6730
|
for (let key of __getOwnPropNames2(mod))
|
|
@@ -6777,10 +6775,10 @@ var import_path3, import_url, import_events, import_child_process, import_readli
|
|
|
6777
6775
|
throw error;
|
|
6778
6776
|
};
|
|
6779
6777
|
return next();
|
|
6780
|
-
}, require_code, require_scope, require_codegen, require_util, require_names, require_errors, require_boolSchema, require_rules, require_applicability, require_dataType, require_defaults, require_code2, require_keyword, require_subschema, require_fast_deep_equal, require_json_schema_traverse, require_resolve, require_validate, require_validation_error, require_ref_error, require_compile, require_data, require_scopedChars, require_utils, require_schemes, require_fast_uri, require_uri, require_core, require_id, require_ref, require_core2, require_limitNumber, require_multipleOf, require_ucs2length, require_limitLength, require_pattern, require_limitProperties, require_required, require_limitItems, require_equal, require_uniqueItems, require_const, require_enum, require_validation, require_additionalItems, require_items, require_prefixItems, require_items2020, require_contains, require_dependencies, require_propertyNames, require_additionalProperties, require_properties, require_patternProperties, require_not, require_anyOf, require_oneOf, require_allOf, require_if, require_thenElse, require_applicator, require_format, require_format2, require_metadata, require_draft7, require_types, require_discriminator, require_json_schema_draft_07, require_ajv, require_formats, require_limit, require_dist, DEFAULT_MAX_LISTENERS = 50, freeGlobal, _freeGlobal_default, freeSelf, root, _root_default, Symbol2, _Symbol_default, objectProto, hasOwnProperty, nativeObjectToString, symToStringTag, _getRawTag_default, objectProto2, nativeObjectToString2, _objectToString_default, nullTag = "[object Null]", undefinedTag = "[object Undefined]", symToStringTag2, _baseGetTag_default, isObject_default, asyncTag = "[object AsyncFunction]", funcTag = "[object Function]", genTag = "[object GeneratorFunction]", proxyTag = "[object Proxy]", isFunction_default, coreJsData, _coreJsData_default, maskSrcKey, _isMasked_default, funcProto, funcToString, _toSource_default, reRegExpChar, reIsHostCtor, funcProto2, objectProto3, funcToString2, hasOwnProperty2, reIsNative, _baseIsNative_default, _getValue_default, _getNative_default, nativeCreate, _nativeCreate_default, _hashClear_default, _hashDelete_default, HASH_UNDEFINED = "__lodash_hash_undefined__", objectProto4, hasOwnProperty3, _hashGet_default, objectProto5, hasOwnProperty4, _hashHas_default, HASH_UNDEFINED2 = "__lodash_hash_undefined__", _hashSet_default, _Hash_default, _listCacheClear_default, eq_default, _assocIndexOf_default, arrayProto, splice, _listCacheDelete_default, _listCacheGet_default, _listCacheHas_default, _listCacheSet_default, _ListCache_default, Map2, _Map_default, _mapCacheClear_default, _isKeyable_default, _getMapData_default, _mapCacheDelete_default, _mapCacheGet_default, _mapCacheHas_default, _mapCacheSet_default, _MapCache_default, FUNC_ERROR_TEXT = "Expected a function", memoize_default, CHUNK_SIZE = 2000, parseDebugFilter, MAX_OUTPUT_LENGTH = 150000, DEFAULT_MAX_OUTPUT_LENGTH = 30000, bashMaxOutputLengthValidator, taskMaxOutputLengthValidator, maxOutputTokensValidator, CLAUDE_CODE_20250219_BETA_HEADER = "claude-code-20250219", INTERLEAVED_THINKING_BETA_HEADER = "interleaved-thinking-2025-05-14", FINE_GRAINED_TOOL_STREAMING_BETA_HEADER = "fine-grained-tool-streaming-2025-05-14", SONNET_1M_BETA_HEADER = "context-1m-2025-08-07", CONTEXT_MANAGEMENT_BETA_HEADER = "context-management-2025-06-27", TOOL_EXAMPLES_BETA_HEADER = "tool-examples-2025-10-29", TOOL_SEARCH_BETA_HEADER_3P = "tool-search-tool-2025-10-19", BEDROCK_EXTRA_PARAMS_HEADERS, VERTEX_COUNT_TOKENS_ALLOWED_BETAS, STATE,
|
|
6778
|
+
}, require_code, require_scope, require_codegen, require_util, require_names, require_errors, require_boolSchema, require_rules, require_applicability, require_dataType, require_defaults, require_code2, require_keyword, require_subschema, require_fast_deep_equal, require_json_schema_traverse, require_resolve, require_validate, require_validation_error, require_ref_error, require_compile, require_data, require_scopedChars, require_utils, require_schemes, require_fast_uri, require_uri, require_core, require_id, require_ref, require_core2, require_limitNumber, require_multipleOf, require_ucs2length, require_limitLength, require_pattern, require_limitProperties, require_required, require_limitItems, require_equal, require_uniqueItems, require_const, require_enum, require_validation, require_additionalItems, require_items, require_prefixItems, require_items2020, require_contains, require_dependencies, require_propertyNames, require_additionalProperties, require_properties, require_patternProperties, require_not, require_anyOf, require_oneOf, require_allOf, require_if, require_thenElse, require_applicator, require_format, require_format2, require_metadata, require_draft7, require_types, require_discriminator, require_json_schema_draft_07, require_ajv, require_formats, require_limit, require_dist, DEFAULT_MAX_LISTENERS = 50, freeGlobal, _freeGlobal_default, freeSelf, root, _root_default, Symbol2, _Symbol_default, objectProto, hasOwnProperty, nativeObjectToString, symToStringTag, _getRawTag_default, objectProto2, nativeObjectToString2, _objectToString_default, nullTag = "[object Null]", undefinedTag = "[object Undefined]", symToStringTag2, _baseGetTag_default, isObject_default, asyncTag = "[object AsyncFunction]", funcTag = "[object Function]", genTag = "[object GeneratorFunction]", proxyTag = "[object Proxy]", isFunction_default, coreJsData, _coreJsData_default, maskSrcKey, _isMasked_default, funcProto, funcToString, _toSource_default, reRegExpChar, reIsHostCtor, funcProto2, objectProto3, funcToString2, hasOwnProperty2, reIsNative, _baseIsNative_default, _getValue_default, _getNative_default, nativeCreate, _nativeCreate_default, _hashClear_default, _hashDelete_default, HASH_UNDEFINED = "__lodash_hash_undefined__", objectProto4, hasOwnProperty3, _hashGet_default, objectProto5, hasOwnProperty4, _hashHas_default, HASH_UNDEFINED2 = "__lodash_hash_undefined__", _hashSet_default, _Hash_default, _listCacheClear_default, eq_default, _assocIndexOf_default, arrayProto, splice, _listCacheDelete_default, _listCacheGet_default, _listCacheHas_default, _listCacheSet_default, _ListCache_default, Map2, _Map_default, _mapCacheClear_default, _isKeyable_default, _getMapData_default, _mapCacheDelete_default, _mapCacheGet_default, _mapCacheHas_default, _mapCacheSet_default, _MapCache_default, FUNC_ERROR_TEXT = "Expected a function", memoize_default, CHUNK_SIZE = 2000, parseDebugFilter, MAX_OUTPUT_LENGTH = 150000, DEFAULT_MAX_OUTPUT_LENGTH = 30000, bashMaxOutputLengthValidator, taskMaxOutputLengthValidator, maxOutputTokensValidator, CLAUDE_CODE_20250219_BETA_HEADER = "claude-code-20250219", INTERLEAVED_THINKING_BETA_HEADER = "interleaved-thinking-2025-05-14", FINE_GRAINED_TOOL_STREAMING_BETA_HEADER = "fine-grained-tool-streaming-2025-05-14", SONNET_1M_BETA_HEADER = "context-1m-2025-08-07", CONTEXT_MANAGEMENT_BETA_HEADER = "context-management-2025-06-27", TOOL_EXAMPLES_BETA_HEADER = "tool-examples-2025-10-29", TOOL_SEARCH_BETA_HEADER_3P = "tool-search-tool-2025-10-19", BEDROCK_EXTRA_PARAMS_HEADERS, VERTEX_COUNT_TOKENS_ALLOWED_BETAS, STATE, cleanupFunctions, SLOW_OPERATION_THRESHOLD_MS = Infinity, jsonParse = (text, reviver) => {
|
|
6781
6779
|
const length = typeof text === "string" ? text.length : 0;
|
|
6782
6780
|
return withSlowLogging(`JSON.parse(${length} chars)`, () => JSON.parse(text, reviver));
|
|
6783
|
-
}, isDebugMode, getDebugFilter, isDebugToStdErr, hasFormattedOutput = false, debugWriter = null, updateLatestDebugLogSymlink, NodeFsOperations, activeFs, HOOK_EVENTS, EXIT_REASONS, AbortError, debugFilePath = null, initialized = false, Stream, Query, SessionImpl, util, objectUtil, ZodParsedType, getParsedType = (data) => {
|
|
6781
|
+
}, isDebugMode, getDebugFilter, isDebugToStdErr, hasFormattedOutput = false, debugWriter = null, updateLatestDebugLogSymlink, isLoggingSlowOperation = false, NodeFsOperations, activeFs, HOOK_EVENTS, EXIT_REASONS, AbortError, debugFilePath = null, initialized = false, Stream, Query, SessionImpl, util, objectUtil, ZodParsedType, getParsedType = (data) => {
|
|
6784
6782
|
const t = typeof data;
|
|
6785
6783
|
switch (t) {
|
|
6786
6784
|
case "undefined":
|
|
@@ -7484,24 +7482,24 @@ var import_path3, import_url, import_events, import_child_process, import_readli
|
|
|
7484
7482
|
return combined;
|
|
7485
7483
|
}, DEFAULT_REQUEST_TIMEOUT_MSEC = 60000, import_ajv, import_ajv_formats, Server, COMPLETABLE_SYMBOL, McpZodTypeKind, TOOL_NAME_REGEX, EMPTY_OBJECT_JSON_SCHEMA, EMPTY_COMPLETION_RESULT;
|
|
7486
7484
|
var init_sdk = __esm(() => {
|
|
7487
|
-
|
|
7485
|
+
import_path4 = require("path");
|
|
7488
7486
|
import_url = require("url");
|
|
7489
7487
|
import_events = require("events");
|
|
7490
7488
|
import_child_process = require("child_process");
|
|
7491
7489
|
import_readline = require("readline");
|
|
7492
7490
|
fs = __toESM(require("fs"));
|
|
7493
7491
|
import_promises = require("fs/promises");
|
|
7494
|
-
import_path4 = require("path");
|
|
7495
|
-
import_os3 = require("os");
|
|
7496
7492
|
import_path5 = require("path");
|
|
7493
|
+
import_os3 = require("os");
|
|
7494
|
+
import_path6 = require("path");
|
|
7497
7495
|
import_process = require("process");
|
|
7498
7496
|
import_fs2 = require("fs");
|
|
7499
7497
|
import_crypto = require("crypto");
|
|
7500
7498
|
import_crypto2 = require("crypto");
|
|
7501
7499
|
import_fs3 = require("fs");
|
|
7502
|
-
import_path6 = require("path");
|
|
7503
|
-
import_crypto3 = require("crypto");
|
|
7504
7500
|
import_path7 = require("path");
|
|
7501
|
+
import_crypto3 = require("crypto");
|
|
7502
|
+
import_path8 = require("path");
|
|
7505
7503
|
import_url2 = require("url");
|
|
7506
7504
|
__create2 = Object.create;
|
|
7507
7505
|
__getProtoOf2 = Object.getPrototypeOf;
|
|
@@ -13983,8 +13981,8 @@ var init_sdk = __esm(() => {
|
|
|
13983
13981
|
}
|
|
13984
13982
|
try {
|
|
13985
13983
|
const debugLogPath = getDebugLogPath();
|
|
13986
|
-
const debugLogsDir =
|
|
13987
|
-
const latestSymlinkPath =
|
|
13984
|
+
const debugLogsDir = import_path6.dirname(debugLogPath);
|
|
13985
|
+
const latestSymlinkPath = import_path6.join(debugLogsDir, "latest");
|
|
13988
13986
|
if (!getFsImplementation().existsSync(debugLogsDir)) {
|
|
13989
13987
|
getFsImplementation().mkdirSync(debugLogsDir);
|
|
13990
13988
|
}
|
|
@@ -14115,7 +14113,8 @@ var init_sdk = __esm(() => {
|
|
|
14115
14113
|
"SubagentStart",
|
|
14116
14114
|
"SubagentStop",
|
|
14117
14115
|
"PreCompact",
|
|
14118
|
-
"PermissionRequest"
|
|
14116
|
+
"PermissionRequest",
|
|
14117
|
+
"Setup"
|
|
14119
14118
|
];
|
|
14120
14119
|
EXIT_REASONS = [
|
|
14121
14120
|
"clear",
|
|
@@ -14303,7 +14302,7 @@ var init_sdk = __esm(() => {
|
|
|
14303
14302
|
this.firstResultReceivedResolve();
|
|
14304
14303
|
}
|
|
14305
14304
|
if (this.isSingleUserTurn) {
|
|
14306
|
-
|
|
14305
|
+
logForDebugging2(`[Query.readMessages] First result received for single-turn query, closing stdin`);
|
|
14307
14306
|
this.transport.endInput();
|
|
14308
14307
|
}
|
|
14309
14308
|
}
|
|
@@ -14546,23 +14545,23 @@ var init_sdk = __esm(() => {
|
|
|
14546
14545
|
return (await this.initialization).account;
|
|
14547
14546
|
}
|
|
14548
14547
|
async streamInput(stream) {
|
|
14549
|
-
|
|
14548
|
+
logForDebugging2(`[Query.streamInput] Starting to process input stream`);
|
|
14550
14549
|
try {
|
|
14551
14550
|
let messageCount = 0;
|
|
14552
14551
|
for await (const message of stream) {
|
|
14553
14552
|
messageCount++;
|
|
14554
|
-
|
|
14553
|
+
logForDebugging2(`[Query.streamInput] Processing message ${messageCount}: ${message.type}`);
|
|
14555
14554
|
if (this.abortController?.signal.aborted)
|
|
14556
14555
|
break;
|
|
14557
14556
|
await Promise.resolve(this.transport.write(jsonStringify(message) + `
|
|
14558
14557
|
`));
|
|
14559
14558
|
}
|
|
14560
|
-
|
|
14559
|
+
logForDebugging2(`[Query.streamInput] Finished processing ${messageCount} messages from input stream`);
|
|
14561
14560
|
if (messageCount > 0 && this.hasBidirectionalNeeds()) {
|
|
14562
|
-
|
|
14561
|
+
logForDebugging2(`[Query.streamInput] Has bidirectional needs, waiting for first result`);
|
|
14563
14562
|
await this.waitForFirstResult();
|
|
14564
14563
|
}
|
|
14565
|
-
|
|
14564
|
+
logForDebugging2(`[Query] Calling transport.endInput() to close stdin to CLI process`);
|
|
14566
14565
|
this.transport.endInput();
|
|
14567
14566
|
} catch (error) {
|
|
14568
14567
|
if (!(error instanceof AbortError)) {
|
|
@@ -14572,7 +14571,7 @@ var init_sdk = __esm(() => {
|
|
|
14572
14571
|
}
|
|
14573
14572
|
waitForFirstResult() {
|
|
14574
14573
|
if (this.firstResultReceived) {
|
|
14575
|
-
|
|
14574
|
+
logForDebugging2(`[Query.waitForFirstResult] Result already received, returning immediately`);
|
|
14576
14575
|
return Promise.resolve();
|
|
14577
14576
|
}
|
|
14578
14577
|
return new Promise((resolve) => {
|
|
@@ -14681,8 +14680,8 @@ var init_sdk = __esm(() => {
|
|
|
14681
14680
|
let pathToClaudeCodeExecutable = options.pathToClaudeCodeExecutable;
|
|
14682
14681
|
if (!pathToClaudeCodeExecutable) {
|
|
14683
14682
|
const filename = import_url2.fileURLToPath(import.meta.url);
|
|
14684
|
-
const dirname2 =
|
|
14685
|
-
pathToClaudeCodeExecutable =
|
|
14683
|
+
const dirname2 = import_path8.join(filename, "..");
|
|
14684
|
+
pathToClaudeCodeExecutable = import_path8.join(dirname2, "cli.js");
|
|
14686
14685
|
}
|
|
14687
14686
|
const processEnv = { ...options.env ?? process.env };
|
|
14688
14687
|
if (!processEnv.CLAUDE_CODE_ENTRYPOINT) {
|
|
@@ -14701,22 +14700,22 @@ var init_sdk = __esm(() => {
|
|
|
14701
14700
|
maxBudgetUsd: undefined,
|
|
14702
14701
|
model: options.model,
|
|
14703
14702
|
fallbackModel: undefined,
|
|
14704
|
-
permissionMode: "default",
|
|
14703
|
+
permissionMode: options.permissionMode ?? "default",
|
|
14705
14704
|
allowDangerouslySkipPermissions: false,
|
|
14706
14705
|
continueConversation: false,
|
|
14707
14706
|
resume: options.resume,
|
|
14708
14707
|
settingSources: [],
|
|
14709
|
-
allowedTools: [],
|
|
14710
|
-
disallowedTools: [],
|
|
14708
|
+
allowedTools: options.allowedTools ?? [],
|
|
14709
|
+
disallowedTools: options.disallowedTools ?? [],
|
|
14711
14710
|
mcpServers: {},
|
|
14712
14711
|
strictMcpConfig: false,
|
|
14713
|
-
canUseTool:
|
|
14714
|
-
hooks:
|
|
14712
|
+
canUseTool: !!options.canUseTool,
|
|
14713
|
+
hooks: !!options.hooks,
|
|
14715
14714
|
includePartialMessages: false,
|
|
14716
14715
|
forkSession: false,
|
|
14717
14716
|
resumeSessionAt: undefined
|
|
14718
14717
|
});
|
|
14719
|
-
this.query = new Query(transport, false,
|
|
14718
|
+
this.query = new Query(transport, false, options.canUseTool, options.hooks, this.abortController, new Map);
|
|
14720
14719
|
this.query.streamInput(this.inputStream);
|
|
14721
14720
|
}
|
|
14722
14721
|
async send(message) {
|
|
@@ -27572,7 +27571,7 @@ async function fileFromPath2(path, filenameOrOptions, options) {
|
|
|
27572
27571
|
const stats = await import_fs4.promises.stat(path);
|
|
27573
27572
|
return createFileFromPath(path, stats, filenameOrOptions, options);
|
|
27574
27573
|
}
|
|
27575
|
-
var import_fs4,
|
|
27574
|
+
var import_fs4, import_path9, import_node_domexception, __classPrivateFieldSet4 = function(receiver, state, value, kind2, f2) {
|
|
27576
27575
|
if (kind2 === "m")
|
|
27577
27576
|
throw new TypeError("Private method is not writable");
|
|
27578
27577
|
if (kind2 === "a" && !f2)
|
|
@@ -27589,7 +27588,7 @@ var import_fs4, import_path8, import_node_domexception, __classPrivateFieldSet4
|
|
|
27589
27588
|
}, _FileFromPath_path, _FileFromPath_start, MESSAGE, FileFromPath;
|
|
27590
27589
|
var init_fileFromPath = __esm(() => {
|
|
27591
27590
|
import_fs4 = require("fs");
|
|
27592
|
-
|
|
27591
|
+
import_path9 = require("path");
|
|
27593
27592
|
import_node_domexception = __toESM(require_node_domexception());
|
|
27594
27593
|
init_File();
|
|
27595
27594
|
init_isPlainObject2();
|
|
@@ -27601,7 +27600,7 @@ var init_fileFromPath = __esm(() => {
|
|
|
27601
27600
|
_FileFromPath_start.set(this, undefined);
|
|
27602
27601
|
__classPrivateFieldSet4(this, _FileFromPath_path, input.path, "f");
|
|
27603
27602
|
__classPrivateFieldSet4(this, _FileFromPath_start, input.start || 0, "f");
|
|
27604
|
-
this.name =
|
|
27603
|
+
this.name = import_path9.basename(__classPrivateFieldGet5(this, _FileFromPath_path, "f"));
|
|
27605
27604
|
this.size = input.size;
|
|
27606
27605
|
this.lastModified = input.lastModified;
|
|
27607
27606
|
}
|
|
@@ -34896,8 +34895,196 @@ function createEngine(config) {
|
|
|
34896
34895
|
}
|
|
34897
34896
|
// src/core/curator.ts
|
|
34898
34897
|
var import_os4 = require("os");
|
|
34899
|
-
var
|
|
34898
|
+
var import_path10 = require("path");
|
|
34900
34899
|
var import_fs5 = require("fs");
|
|
34900
|
+
var import_promises2 = require("fs/promises");
|
|
34901
|
+
|
|
34902
|
+
// src/core/session-parser.ts
|
|
34903
|
+
var import_path3 = require("path");
|
|
34904
|
+
function estimateTokens(text) {
|
|
34905
|
+
return Math.ceil(text.length / 4);
|
|
34906
|
+
}
|
|
34907
|
+
function estimateContentTokens(content) {
|
|
34908
|
+
if (typeof content === "string") {
|
|
34909
|
+
return estimateTokens(content);
|
|
34910
|
+
}
|
|
34911
|
+
let tokens = 0;
|
|
34912
|
+
for (const block of content) {
|
|
34913
|
+
if (typeof block === "object" && block !== null) {
|
|
34914
|
+
if (block.type === "text" && "text" in block) {
|
|
34915
|
+
tokens += estimateTokens(block.text);
|
|
34916
|
+
} else if (block.type === "thinking" && "thinking" in block) {
|
|
34917
|
+
tokens += estimateTokens(block.thinking);
|
|
34918
|
+
} else if (block.type === "tool_use" && "input" in block) {
|
|
34919
|
+
tokens += estimateTokens(JSON.stringify(block.input));
|
|
34920
|
+
} else if (block.type === "tool_result" && "content" in block) {
|
|
34921
|
+
if (typeof block.content === "string") {
|
|
34922
|
+
tokens += estimateTokens(block.content);
|
|
34923
|
+
} else {
|
|
34924
|
+
tokens += estimateContentTokens(block.content);
|
|
34925
|
+
}
|
|
34926
|
+
}
|
|
34927
|
+
if (block.type === "image") {
|
|
34928
|
+
tokens += 1000;
|
|
34929
|
+
}
|
|
34930
|
+
}
|
|
34931
|
+
}
|
|
34932
|
+
return tokens;
|
|
34933
|
+
}
|
|
34934
|
+
async function parseSessionFile(filepath) {
|
|
34935
|
+
const file = Bun.file(filepath);
|
|
34936
|
+
const content = await file.text();
|
|
34937
|
+
const fileSize = file.size;
|
|
34938
|
+
const lines = content.split(`
|
|
34939
|
+
`).filter((line) => line.trim());
|
|
34940
|
+
const messages = [];
|
|
34941
|
+
const timestamps = [];
|
|
34942
|
+
let summary;
|
|
34943
|
+
let isCompactSummary = false;
|
|
34944
|
+
let totalEstimatedTokens = 0;
|
|
34945
|
+
let internalSessionId;
|
|
34946
|
+
let context;
|
|
34947
|
+
let toolUseCount = 0;
|
|
34948
|
+
let toolResultCount = 0;
|
|
34949
|
+
let hasThinkingBlocks = false;
|
|
34950
|
+
let hasImages = false;
|
|
34951
|
+
let hasMetaMessages = false;
|
|
34952
|
+
for (const line of lines) {
|
|
34953
|
+
try {
|
|
34954
|
+
const entry = JSON.parse(line);
|
|
34955
|
+
if (entry.type === "summary" && entry.summary) {
|
|
34956
|
+
summary = entry.summary;
|
|
34957
|
+
continue;
|
|
34958
|
+
}
|
|
34959
|
+
if (entry.type !== "user" && entry.type !== "assistant") {
|
|
34960
|
+
continue;
|
|
34961
|
+
}
|
|
34962
|
+
if (entry.isMeta) {
|
|
34963
|
+
hasMetaMessages = true;
|
|
34964
|
+
continue;
|
|
34965
|
+
}
|
|
34966
|
+
if (!entry.message) {
|
|
34967
|
+
continue;
|
|
34968
|
+
}
|
|
34969
|
+
if (!internalSessionId && entry.sessionId) {
|
|
34970
|
+
internalSessionId = entry.sessionId;
|
|
34971
|
+
}
|
|
34972
|
+
if (!context && entry.type === "user") {
|
|
34973
|
+
if (entry.cwd || entry.gitBranch) {
|
|
34974
|
+
context = {
|
|
34975
|
+
cwd: entry.cwd,
|
|
34976
|
+
gitBranch: entry.gitBranch
|
|
34977
|
+
};
|
|
34978
|
+
}
|
|
34979
|
+
}
|
|
34980
|
+
if (entry.isCompactSummary) {
|
|
34981
|
+
isCompactSummary = true;
|
|
34982
|
+
}
|
|
34983
|
+
if (entry.timestamp) {
|
|
34984
|
+
timestamps.push(entry.timestamp);
|
|
34985
|
+
}
|
|
34986
|
+
const message = {
|
|
34987
|
+
role: entry.message.role,
|
|
34988
|
+
content: entry.message.content
|
|
34989
|
+
};
|
|
34990
|
+
const msgTokens = estimateContentTokens(message.content);
|
|
34991
|
+
totalEstimatedTokens += msgTokens;
|
|
34992
|
+
if (Array.isArray(message.content)) {
|
|
34993
|
+
for (const block of message.content) {
|
|
34994
|
+
if (typeof block === "object" && block !== null) {
|
|
34995
|
+
if (block.type === "tool_use")
|
|
34996
|
+
toolUseCount++;
|
|
34997
|
+
if (block.type === "tool_result")
|
|
34998
|
+
toolResultCount++;
|
|
34999
|
+
if (block.type === "thinking")
|
|
35000
|
+
hasThinkingBlocks = true;
|
|
35001
|
+
if (block.type === "image")
|
|
35002
|
+
hasImages = true;
|
|
35003
|
+
}
|
|
35004
|
+
}
|
|
35005
|
+
}
|
|
35006
|
+
messages.push(message);
|
|
35007
|
+
} catch {
|
|
35008
|
+
continue;
|
|
35009
|
+
}
|
|
35010
|
+
}
|
|
35011
|
+
const filename = import_path3.basename(filepath);
|
|
35012
|
+
const sessionId = filename.replace(/\.jsonl$/, "");
|
|
35013
|
+
const projectFolder = import_path3.basename(import_path3.join(filepath, ".."));
|
|
35014
|
+
return {
|
|
35015
|
+
id: sessionId,
|
|
35016
|
+
internalSessionId,
|
|
35017
|
+
projectId: projectFolder,
|
|
35018
|
+
projectName: getProjectDisplayName(projectFolder),
|
|
35019
|
+
filepath,
|
|
35020
|
+
messages,
|
|
35021
|
+
timestamps: {
|
|
35022
|
+
first: timestamps[0],
|
|
35023
|
+
last: timestamps[timestamps.length - 1]
|
|
35024
|
+
},
|
|
35025
|
+
context,
|
|
35026
|
+
metadata: {
|
|
35027
|
+
messageCount: messages.length,
|
|
35028
|
+
userMessageCount: messages.filter((m) => m.role === "user").length,
|
|
35029
|
+
assistantMessageCount: messages.filter((m) => m.role === "assistant").length,
|
|
35030
|
+
toolUseCount,
|
|
35031
|
+
toolResultCount,
|
|
35032
|
+
hasThinkingBlocks,
|
|
35033
|
+
hasImages,
|
|
35034
|
+
isCompactSummary,
|
|
35035
|
+
hasMetaMessages,
|
|
35036
|
+
estimatedTokens: totalEstimatedTokens,
|
|
35037
|
+
fileSize
|
|
35038
|
+
},
|
|
35039
|
+
summary
|
|
35040
|
+
};
|
|
35041
|
+
}
|
|
35042
|
+
function getProjectDisplayName(folderName) {
|
|
35043
|
+
const prefixesToStrip = [
|
|
35044
|
+
"-home-",
|
|
35045
|
+
"-mnt-c-Users-",
|
|
35046
|
+
"-mnt-c-users-",
|
|
35047
|
+
"-Users-"
|
|
35048
|
+
];
|
|
35049
|
+
let name = folderName;
|
|
35050
|
+
for (const prefix of prefixesToStrip) {
|
|
35051
|
+
if (name.toLowerCase().startsWith(prefix.toLowerCase())) {
|
|
35052
|
+
name = name.slice(prefix.length);
|
|
35053
|
+
break;
|
|
35054
|
+
}
|
|
35055
|
+
}
|
|
35056
|
+
const parts = name.split("-");
|
|
35057
|
+
const skipDirs = new Set(["projects", "code", "repos", "src", "dev", "work", "documents"]);
|
|
35058
|
+
const meaningfulParts = [];
|
|
35059
|
+
let foundProject = false;
|
|
35060
|
+
for (let i = 0;i < parts.length; i++) {
|
|
35061
|
+
const part = parts[i];
|
|
35062
|
+
if (!part)
|
|
35063
|
+
continue;
|
|
35064
|
+
if (i === 0 && !foundProject) {
|
|
35065
|
+
const remaining = parts.slice(i + 1).map((p) => p.toLowerCase());
|
|
35066
|
+
if (remaining.some((d) => skipDirs.has(d))) {
|
|
35067
|
+
continue;
|
|
35068
|
+
}
|
|
35069
|
+
}
|
|
35070
|
+
if (skipDirs.has(part.toLowerCase())) {
|
|
35071
|
+
foundProject = true;
|
|
35072
|
+
continue;
|
|
35073
|
+
}
|
|
35074
|
+
meaningfulParts.push(part);
|
|
35075
|
+
foundProject = true;
|
|
35076
|
+
}
|
|
35077
|
+
if (meaningfulParts.length) {
|
|
35078
|
+
return meaningfulParts.join("-");
|
|
35079
|
+
}
|
|
35080
|
+
for (let i = parts.length - 1;i >= 0; i--) {
|
|
35081
|
+
if (parts[i])
|
|
35082
|
+
return parts[i];
|
|
35083
|
+
}
|
|
35084
|
+
return folderName;
|
|
35085
|
+
}
|
|
35086
|
+
|
|
35087
|
+
// src/core/curator.ts
|
|
34901
35088
|
function getClaudeCommand() {
|
|
34902
35089
|
const envCommand = process.env.CURATOR_COMMAND;
|
|
34903
35090
|
if (envCommand) {
|
|
@@ -34907,7 +35094,7 @@ function getClaudeCommand() {
|
|
|
34907
35094
|
if (result.exitCode === 0) {
|
|
34908
35095
|
return result.stdout.toString().trim();
|
|
34909
35096
|
}
|
|
34910
|
-
const claudeLocal =
|
|
35097
|
+
const claudeLocal = import_path10.join(import_os4.homedir(), ".claude", "local", "claude");
|
|
34911
35098
|
if (import_fs5.existsSync(claudeLocal)) {
|
|
34912
35099
|
return claudeLocal;
|
|
34913
35100
|
}
|
|
@@ -35226,7 +35413,18 @@ Focus ONLY on technical, architectural, debugging, decision, workflow, and proje
|
|
|
35226
35413
|
logger.debug("parseCurationResponse: No JSON object found in response", "curator");
|
|
35227
35414
|
throw new Error("No JSON object found in response");
|
|
35228
35415
|
}
|
|
35229
|
-
|
|
35416
|
+
logger.debug(`parseCurationResponse: Attempting to parse ${jsonMatch.length} chars`, "curator");
|
|
35417
|
+
let data;
|
|
35418
|
+
try {
|
|
35419
|
+
data = JSON.parse(jsonMatch);
|
|
35420
|
+
} catch (parseErr) {
|
|
35421
|
+
logger.debug(`parseCurationResponse: JSON.parse failed: ${parseErr.message}`, "curator");
|
|
35422
|
+
logger.debug(`parseCurationResponse: Last 100 chars: '${jsonMatch.slice(-100)}'`, "curator");
|
|
35423
|
+
const openBraces = (jsonMatch.match(/\{/g) || []).length;
|
|
35424
|
+
const closeBraces = (jsonMatch.match(/\}/g) || []).length;
|
|
35425
|
+
logger.debug(`parseCurationResponse: Brace count - open: ${openBraces}, close: ${closeBraces}`, "curator");
|
|
35426
|
+
throw parseErr;
|
|
35427
|
+
}
|
|
35230
35428
|
const result = {
|
|
35231
35429
|
session_summary: data.session_summary ?? "",
|
|
35232
35430
|
interaction_tone: data.interaction_tone,
|
|
@@ -35324,7 +35522,13 @@ Focus ONLY on technical, architectural, debugging, decision, workflow, and proje
|
|
|
35324
35522
|
_validateTemporalClass(value) {
|
|
35325
35523
|
if (!value)
|
|
35326
35524
|
return;
|
|
35327
|
-
const valid = [
|
|
35525
|
+
const valid = [
|
|
35526
|
+
"eternal",
|
|
35527
|
+
"long_term",
|
|
35528
|
+
"medium_term",
|
|
35529
|
+
"short_term",
|
|
35530
|
+
"ephemeral"
|
|
35531
|
+
];
|
|
35328
35532
|
const str = String(value).toLowerCase().replace("-", "_").replace(" ", "_");
|
|
35329
35533
|
if (valid.includes(str))
|
|
35330
35534
|
return str;
|
|
@@ -35398,6 +35602,48 @@ ${content}
|
|
|
35398
35602
|
return lines.join(`
|
|
35399
35603
|
`);
|
|
35400
35604
|
}
|
|
35605
|
+
async curateWithSessionResume(claudeSessionId, triggerType = "session_end") {
|
|
35606
|
+
const { query: query2 } = await Promise.resolve().then(() => (init_sdk(), exports_sdk));
|
|
35607
|
+
const curationPrompt = this.buildCurationPrompt(triggerType);
|
|
35608
|
+
logger.debug(`Curator v2: Resuming session ${claudeSessionId}`, "curator");
|
|
35609
|
+
try {
|
|
35610
|
+
const q2 = query2({
|
|
35611
|
+
prompt: "Curate memories from this session according to your system instructions. Return ONLY the JSON structure.",
|
|
35612
|
+
options: {
|
|
35613
|
+
resume: claudeSessionId,
|
|
35614
|
+
appendSystemPrompt: curationPrompt,
|
|
35615
|
+
model: "claude-opus-4-5-20251101",
|
|
35616
|
+
permissionMode: "bypassPermissions"
|
|
35617
|
+
}
|
|
35618
|
+
});
|
|
35619
|
+
let resultText = "";
|
|
35620
|
+
for await (const message of q2) {
|
|
35621
|
+
if (message.type === "assistant" && "usage" in message && message.usage) {
|
|
35622
|
+
logger.debug(`Curator v2: Tokens used - input: ${message.usage.input_tokens}, output: ${message.usage.output_tokens}`, "curator");
|
|
35623
|
+
}
|
|
35624
|
+
if (message.type === "result") {
|
|
35625
|
+
if (message.subtype === "error") {
|
|
35626
|
+
logger.debug(`Curator v2: Error result - ${JSON.stringify(message)}`, "curator");
|
|
35627
|
+
return { session_summary: "", memories: [] };
|
|
35628
|
+
} else if (message.subtype === "success" && "result" in message) {
|
|
35629
|
+
resultText = message.result;
|
|
35630
|
+
}
|
|
35631
|
+
}
|
|
35632
|
+
}
|
|
35633
|
+
if (!resultText) {
|
|
35634
|
+
logger.debug("Curator v2: No result text received", "curator");
|
|
35635
|
+
return { session_summary: "", memories: [] };
|
|
35636
|
+
}
|
|
35637
|
+
logger.debug(`Curator v2: Complete response:
|
|
35638
|
+
${resultText}`, "curator");
|
|
35639
|
+
const result = this.parseCurationResponse(resultText);
|
|
35640
|
+
logger.debug(`Curator v2: Parsed ${result.memories.length} memories`, "curator");
|
|
35641
|
+
return result;
|
|
35642
|
+
} catch (error2) {
|
|
35643
|
+
logger.debug(`Curator v2: Session resume failed: ${error2.message}`, "curator");
|
|
35644
|
+
return { session_summary: "", memories: [] };
|
|
35645
|
+
}
|
|
35646
|
+
}
|
|
35401
35647
|
async curateWithAnthropicSDK(messages, triggerType = "session_end") {
|
|
35402
35648
|
if (!this._config.apiKey) {
|
|
35403
35649
|
throw new Error("API key required for Anthropic SDK mode. Set ANTHROPIC_API_KEY environment variable.");
|
|
@@ -35427,6 +35673,45 @@ ${content}
|
|
|
35427
35673
|
async curateFromSegment(segment, triggerType = "session_end") {
|
|
35428
35674
|
return this.curateWithSDK(segment.messages, triggerType);
|
|
35429
35675
|
}
|
|
35676
|
+
async curateFromSessionFile(sessionId, triggerType = "session_end", cwd2) {
|
|
35677
|
+
const sessionFile = await this._findSessionFile(sessionId, cwd2);
|
|
35678
|
+
if (!sessionFile) {
|
|
35679
|
+
logger.debug(`Curator: Could not find session file for ${sessionId}`, "curator");
|
|
35680
|
+
return { session_summary: "", memories: [] };
|
|
35681
|
+
}
|
|
35682
|
+
logger.debug(`Curator: Found session file: ${sessionFile}`, "curator");
|
|
35683
|
+
const session = await parseSessionFile(sessionFile);
|
|
35684
|
+
if (session.messages.length === 0) {
|
|
35685
|
+
logger.debug("Curator: Session has no messages", "curator");
|
|
35686
|
+
return { session_summary: "", memories: [] };
|
|
35687
|
+
}
|
|
35688
|
+
logger.debug(`Curator: Parsed ${session.messages.length} messages, ~${session.metadata.estimatedTokens} tokens`, "curator");
|
|
35689
|
+
return this.curateWithSDK(session.messages, triggerType);
|
|
35690
|
+
}
|
|
35691
|
+
async _findSessionFile(sessionId, cwd2) {
|
|
35692
|
+
const projectsDir = import_path10.join(import_os4.homedir(), ".claude", "projects");
|
|
35693
|
+
if (cwd2) {
|
|
35694
|
+
const projectFolder = cwd2.replace(/\//g, "-").replace(/^-/, "-");
|
|
35695
|
+
const sessionPath = import_path10.join(projectsDir, projectFolder, `${sessionId}.jsonl`);
|
|
35696
|
+
if (import_fs5.existsSync(sessionPath)) {
|
|
35697
|
+
return sessionPath;
|
|
35698
|
+
}
|
|
35699
|
+
const altPath = import_path10.join(projectsDir, cwd2.split("/").pop() || "", `${sessionId}.jsonl`);
|
|
35700
|
+
if (import_fs5.existsSync(altPath)) {
|
|
35701
|
+
return altPath;
|
|
35702
|
+
}
|
|
35703
|
+
}
|
|
35704
|
+
try {
|
|
35705
|
+
const projectFolders = await import_promises2.readdir(projectsDir);
|
|
35706
|
+
for (const folder of projectFolders) {
|
|
35707
|
+
const sessionPath = import_path10.join(projectsDir, folder, `${sessionId}.jsonl`);
|
|
35708
|
+
if (import_fs5.existsSync(sessionPath)) {
|
|
35709
|
+
return sessionPath;
|
|
35710
|
+
}
|
|
35711
|
+
}
|
|
35712
|
+
} catch {}
|
|
35713
|
+
return null;
|
|
35714
|
+
}
|
|
35430
35715
|
async curateWithCLI(sessionId, triggerType = "session_end", cwd2, cliTypeOverride) {
|
|
35431
35716
|
const type = cliTypeOverride ?? this._config.cliType;
|
|
35432
35717
|
const systemPrompt = this.buildCurationPrompt(triggerType);
|
|
@@ -35441,6 +35726,8 @@ ${content}
|
|
|
35441
35726
|
|
|
35442
35727
|
${userMessage}`, "--output-format", "json");
|
|
35443
35728
|
}
|
|
35729
|
+
logger.debug(`Curator: Spawning CLI with CLAUDE_CODE_MAX_OUTPUT_TOKENS=64000`, "curator");
|
|
35730
|
+
logger.debug(`Curator: Command: ${command} ${args.slice(0, 3).join(" ")}...`, "curator");
|
|
35444
35731
|
const proc = Bun.spawn([command, ...args], {
|
|
35445
35732
|
cwd: cwd2,
|
|
35446
35733
|
env: {
|
|
@@ -35456,16 +35743,17 @@ ${userMessage}`, "--output-format", "json");
|
|
|
35456
35743
|
new Response(proc.stderr).text()
|
|
35457
35744
|
]);
|
|
35458
35745
|
const exitCode = await proc.exited;
|
|
35746
|
+
logger.debug(`Curator CLI exit code: ${exitCode}`, "curator");
|
|
35747
|
+
if (stderr && stderr.trim()) {
|
|
35748
|
+
logger.debug(`Curator stderr (${stderr.length} chars): ${stderr}`, "curator");
|
|
35749
|
+
}
|
|
35459
35750
|
if (exitCode !== 0) {
|
|
35460
|
-
logger.debug(`Curator CLI exited with code ${exitCode}`, "curator");
|
|
35461
|
-
if (stderr) {
|
|
35462
|
-
logger.debug(`Curator stderr: ${stderr}`, "curator");
|
|
35463
|
-
}
|
|
35464
35751
|
return { session_summary: "", memories: [] };
|
|
35465
35752
|
}
|
|
35466
35753
|
logger.debug(`Curator CLI raw stdout (${stdout.length} chars):`, "curator");
|
|
35754
|
+
logger.debug(`Curator: '${stdout}'`, "curator");
|
|
35467
35755
|
if (logger.isVerbose()) {
|
|
35468
|
-
const preview = stdout.length > 2000 ? stdout
|
|
35756
|
+
const preview = stdout.length > 2000 ? stdout : stdout;
|
|
35469
35757
|
console.log(preview);
|
|
35470
35758
|
}
|
|
35471
35759
|
try {
|
|
@@ -35481,7 +35769,7 @@ ${userMessage}`, "--output-format", "json");
|
|
|
35481
35769
|
resultObj = cliOutput;
|
|
35482
35770
|
}
|
|
35483
35771
|
if (resultObj.type === "error" || resultObj.is_error === true) {
|
|
35484
|
-
logger.debug(`Curator: Error response from CLI: ${JSON.stringify(resultObj)
|
|
35772
|
+
logger.debug(`Curator: Error response from CLI: ${JSON.stringify(resultObj)}`, "curator");
|
|
35485
35773
|
return { session_summary: "", memories: [] };
|
|
35486
35774
|
}
|
|
35487
35775
|
let aiResponse = "";
|
|
@@ -35493,24 +35781,58 @@ ${userMessage}`, "--output-format", "json");
|
|
|
35493
35781
|
}
|
|
35494
35782
|
logger.debug(`Curator AI response (${aiResponse.length} chars):`, "curator");
|
|
35495
35783
|
if (logger.isVerbose()) {
|
|
35496
|
-
const preview = aiResponse.length > 3000 ? aiResponse
|
|
35784
|
+
const preview = aiResponse.length > 3000 ? aiResponse : aiResponse;
|
|
35497
35785
|
console.log(preview);
|
|
35498
35786
|
}
|
|
35499
35787
|
const codeBlockMatch = aiResponse.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
35500
35788
|
if (codeBlockMatch) {
|
|
35789
|
+
logger.debug(`Curator: Code block matched, extracting ${codeBlockMatch[1].length} chars`, "curator");
|
|
35501
35790
|
aiResponse = codeBlockMatch[1].trim();
|
|
35791
|
+
} else {
|
|
35792
|
+
logger.debug(`Curator: No code block found, using raw response`, "curator");
|
|
35793
|
+
if (aiResponse.length > 200) {
|
|
35794
|
+
logger.debug(`Curator: ${aiResponse}`, "curator");
|
|
35795
|
+
}
|
|
35502
35796
|
}
|
|
35503
35797
|
const jsonMatch = aiResponse.match(/\{[\s\S]*\}/)?.[0];
|
|
35504
35798
|
if (jsonMatch) {
|
|
35505
35799
|
logger.debug(`Curator: Found JSON object (${jsonMatch.length} chars), parsing...`, "curator");
|
|
35506
|
-
|
|
35800
|
+
const likelyTruncated = jsonMatch.length < aiResponse.length * 0.5;
|
|
35801
|
+
if (likelyTruncated) {
|
|
35802
|
+
logger.debug(`Curator: WARNING - JSON (${jsonMatch.length}) much smaller than response (${aiResponse.length}) - likely truncated`, "curator");
|
|
35803
|
+
const lastBrace = aiResponse.lastIndexOf("}");
|
|
35804
|
+
logger.debug(`Curator: Last } at position ${lastBrace}, char before: '${aiResponse[lastBrace - 1]}', char after: '${aiResponse[lastBrace + 1] || "EOF"}'`, "curator");
|
|
35805
|
+
const cutPoint = jsonMatch.length;
|
|
35806
|
+
logger.debug(`Curator: Around match end (${cutPoint}): '...${aiResponse.slice(Math.max(0, cutPoint - 50), cutPoint + 50)}...'`, "curator");
|
|
35807
|
+
}
|
|
35808
|
+
const result = this.parseCurationResponse(jsonMatch);
|
|
35809
|
+
if (result.memories.length === 0 && likelyTruncated) {
|
|
35810
|
+
logger.debug("Curator: CLI mode returned 0 memories with truncation detected, trying SDK fallback...", "curator");
|
|
35811
|
+
return this._fallbackToSDK(sessionId, triggerType, cwd2);
|
|
35812
|
+
}
|
|
35813
|
+
return result;
|
|
35507
35814
|
} else {
|
|
35508
35815
|
logger.debug("Curator: No JSON object found in AI response", "curator");
|
|
35509
35816
|
}
|
|
35510
35817
|
} catch (error2) {
|
|
35511
35818
|
logger.debug(`Curator: Parse error: ${error2.message}`, "curator");
|
|
35512
35819
|
}
|
|
35513
|
-
|
|
35820
|
+
logger.debug("Curator: CLI mode failed, trying SDK fallback...", "curator");
|
|
35821
|
+
return this._fallbackToSDK(sessionId, triggerType, cwd2);
|
|
35822
|
+
}
|
|
35823
|
+
async _fallbackToSDK(sessionId, triggerType, cwd2) {
|
|
35824
|
+
try {
|
|
35825
|
+
const result = await this.curateFromSessionFile(sessionId, triggerType, cwd2);
|
|
35826
|
+
if (result.memories.length > 0) {
|
|
35827
|
+
logger.debug(`Curator: SDK fallback succeeded with ${result.memories.length} memories`, "curator");
|
|
35828
|
+
} else {
|
|
35829
|
+
logger.debug("Curator: SDK fallback also returned 0 memories", "curator");
|
|
35830
|
+
}
|
|
35831
|
+
return result;
|
|
35832
|
+
} catch (error2) {
|
|
35833
|
+
logger.debug(`Curator: SDK fallback failed: ${error2.message}`, "curator");
|
|
35834
|
+
return { session_summary: "", memories: [] };
|
|
35835
|
+
}
|
|
35514
35836
|
}
|
|
35515
35837
|
}
|
|
35516
35838
|
function createCurator(config2) {
|