@scotthamilton77/sidekick 0.1.18 → 0.1.20

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/daemon.js CHANGED
@@ -62,6 +62,8 @@ var require_hook_events = __commonJS({
62
62
  exports2.isPostToolUseEvent = isPostToolUseEvent;
63
63
  exports2.isStopEvent = isStopEvent;
64
64
  exports2.isPreCompactEvent = isPreCompactEvent;
65
+ exports2.isSubagentStartEvent = isSubagentStartEvent;
66
+ exports2.isSubagentStopEvent = isSubagentStopEvent;
65
67
  exports2.HOOK_NAMES = [
66
68
  "SessionStart",
67
69
  "SessionEnd",
@@ -69,7 +71,9 @@ var require_hook_events = __commonJS({
69
71
  "PreToolUse",
70
72
  "PostToolUse",
71
73
  "Stop",
72
- "PreCompact"
74
+ "PreCompact",
75
+ "SubagentStart",
76
+ "SubagentStop"
73
77
  ];
74
78
  function isSessionStartEvent(event) {
75
79
  return event.hook === "SessionStart";
@@ -92,6 +96,12 @@ var require_hook_events = __commonJS({
92
96
  function isPreCompactEvent(event) {
93
97
  return event.hook === "PreCompact";
94
98
  }
99
+ function isSubagentStartEvent(event) {
100
+ return event.hook === "SubagentStart";
101
+ }
102
+ function isSubagentStopEvent(event) {
103
+ return event.hook === "SubagentStop";
104
+ }
95
105
  }
96
106
  });
97
107
 
@@ -16966,7 +16976,7 @@ var require_hook_input = __commonJS({
16966
16976
  "../types/dist/hook-input.js"(exports2) {
16967
16977
  "use strict";
16968
16978
  Object.defineProperty(exports2, "__esModule", { value: true });
16969
- exports2.HookInputSchema = exports2.StatuslineInputSchema = exports2.StatuslineWorkspaceSchema = exports2.StatuslineCostSchema = exports2.StatuslineContextWindowSchema = exports2.StatuslineModelSchema = exports2.NotificationInputSchema = exports2.PreCompactInputSchema = exports2.SessionEndInputSchema = exports2.SessionStartInputSchema = exports2.StopInputSchema = exports2.PostToolUseInputSchema = exports2.PreToolUseInputSchema = exports2.UserPromptSubmitInputSchema = exports2.HookInputBaseSchema = void 0;
16979
+ exports2.HookInputSchema = exports2.StatuslineInputSchema = exports2.StatuslineWorkspaceSchema = exports2.StatuslineCostSchema = exports2.StatuslineContextWindowSchema = exports2.StatuslineModelSchema = exports2.SubagentStopInputSchema = exports2.SubagentStartInputSchema = exports2.NotificationInputSchema = exports2.PreCompactInputSchema = exports2.SessionEndInputSchema = exports2.SessionStartInputSchema = exports2.StopInputSchema = exports2.PostToolUseInputSchema = exports2.PreToolUseInputSchema = exports2.UserPromptSubmitInputSchema = exports2.HookInputBaseSchema = void 0;
16970
16980
  var zod_1 = require_zod();
16971
16981
  exports2.HookInputBaseSchema = zod_1.z.object({
16972
16982
  /** Unique identifier for the current Claude session */
@@ -16978,7 +16988,11 @@ var require_hook_input = __commonJS({
16978
16988
  /** Current permission level: "default", "plan", "acceptEdits", or "bypassPermissions" */
16979
16989
  permission_mode: zod_1.z.string().optional(),
16980
16990
  /** Name of the triggered hook (e.g., "UserPromptSubmit", "SessionStart") */
16981
- hook_event_name: zod_1.z.string()
16991
+ hook_event_name: zod_1.z.string(),
16992
+ /** Unique identifier for the subagent (present when hook fires inside a subagent) */
16993
+ agent_id: zod_1.z.string().optional(),
16994
+ /** Agent type/name: "Bash", "Explore", "Plan", or custom (present when inside a subagent) */
16995
+ agent_type: zod_1.z.string().optional()
16982
16996
  });
16983
16997
  exports2.UserPromptSubmitInputSchema = exports2.HookInputBaseSchema.extend({
16984
16998
  /** The user's message text */
@@ -17026,6 +17040,26 @@ var require_hook_input = __commonJS({
17026
17040
  /** Type: "permission_prompt", "idle_prompt", "auth_success", or "elicitation_dialog" */
17027
17041
  notification_type: zod_1.z.string()
17028
17042
  });
17043
+ exports2.SubagentStartInputSchema = exports2.HookInputBaseSchema.extend({
17044
+ /** Unique identifier for the subagent (required per official docs) */
17045
+ agent_id: zod_1.z.string(),
17046
+ /** Agent name: "Bash", "Explore", "Plan", or custom agent name */
17047
+ agent_type: zod_1.z.string()
17048
+ });
17049
+ exports2.SubagentStopInputSchema = exports2.HookInputBaseSchema.extend({
17050
+ /** Unique identifier for the subagent */
17051
+ agent_id: zod_1.z.string(),
17052
+ /** Agent name */
17053
+ agent_type: zod_1.z.string(),
17054
+ /** Path to subagent's own transcript JSONL */
17055
+ agent_transcript_path: zod_1.z.string(),
17056
+ /** Text content of the subagent's final response */
17057
+ last_assistant_message: zod_1.z.string(),
17058
+ /** Permission mode for the subagent session */
17059
+ permission_mode: zod_1.z.string(),
17060
+ /** Optional: whether stop hook is active (probe doc says never populated; official docs show false) */
17061
+ stop_hook_active: zod_1.z.boolean().optional()
17062
+ });
17029
17063
  exports2.StatuslineModelSchema = zod_1.z.object({
17030
17064
  /** Full model identifier (e.g., "claude-opus-4-1") */
17031
17065
  id: zod_1.z.string(),
@@ -17081,13 +17115,15 @@ var require_hook_input = __commonJS({
17081
17115
  output_style: zod_1.z.object({ name: zod_1.z.string() }).optional()
17082
17116
  });
17083
17117
  exports2.HookInputSchema = zod_1.z.union([
17118
+ exports2.SessionStartInputSchema,
17119
+ exports2.SessionEndInputSchema,
17084
17120
  exports2.UserPromptSubmitInputSchema,
17085
17121
  exports2.PreToolUseInputSchema,
17086
17122
  exports2.PostToolUseInputSchema,
17087
17123
  exports2.StopInputSchema,
17088
- exports2.SessionStartInputSchema,
17089
- exports2.SessionEndInputSchema,
17090
17124
  exports2.PreCompactInputSchema,
17125
+ exports2.SubagentStartInputSchema,
17126
+ exports2.SubagentStopInputSchema,
17091
17127
  exports2.NotificationInputSchema,
17092
17128
  exports2.HookInputBaseSchema
17093
17129
  // Fallback for hooks without extra fields
@@ -17184,9 +17220,11 @@ var require_setup_status = __commonJS({
17184
17220
  "missing",
17185
17221
  // User declined or entries not present
17186
17222
  "incomplete",
17187
- // Section exists but missing end marker or required entries
17188
- "installed"
17189
- // Sidekick section present with all required entries
17223
+ // .sidekick/.gitignore exists but missing required entries (legacy: partial root section)
17224
+ "installed",
17225
+ // .sidekick/.gitignore present with all entries (new format)
17226
+ "legacy"
17227
+ // Root .gitignore has old marked section — functional, migrate recommended
17190
17228
  ]);
17191
17229
  exports2.ProjectApiKeyValueSchema = zod_1.z.union([exports2.ProjectApiKeyHealthSchema, exports2.ProjectApiKeyStatusSchema]);
17192
17230
  exports2.ProjectSetupStatusSchema = zod_1.z.object({
@@ -26223,6 +26261,18 @@ var require_dist2 = __commonJS({
26223
26261
  }
26224
26262
  });
26225
26263
 
26264
+ // ../sidekick-core/dist/error-utils.js
26265
+ var require_error_utils = __commonJS({
26266
+ "../sidekick-core/dist/error-utils.js"(exports2) {
26267
+ "use strict";
26268
+ Object.defineProperty(exports2, "__esModule", { value: true });
26269
+ exports2.toErrorMessage = toErrorMessage;
26270
+ function toErrorMessage(error) {
26271
+ return error instanceof Error ? error.message : String(error);
26272
+ }
26273
+ }
26274
+ });
26275
+
26226
26276
  // ../sidekick-core/dist/assets.js
26227
26277
  var require_assets = __commonJS({
26228
26278
  "../sidekick-core/dist/assets.js"(exports2) {
@@ -26236,6 +26286,7 @@ var require_assets = __commonJS({
26236
26286
  var yaml_1 = require_dist2();
26237
26287
  var node_os_1 = require("node:os");
26238
26288
  var node_path_1 = require("node:path");
26289
+ var error_utils_js_1 = require_error_utils();
26239
26290
  function createCascadingResolver(options) {
26240
26291
  const { cascadeLayers } = options;
26241
26292
  const findFile = (relativePath) => {
@@ -26285,7 +26336,7 @@ var require_assets = __commonJS({
26285
26336
  try {
26286
26337
  return (0, yaml_1.parse)(content);
26287
26338
  } catch (error) {
26288
- throw new Error(`Failed to parse YAML file ${relativePath}: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
26339
+ throw new Error(`Failed to parse YAML file ${relativePath}: ${(0, error_utils_js_1.toErrorMessage)(error)}`, { cause: error });
26289
26340
  }
26290
26341
  },
26291
26342
  cascadeLayers
@@ -26360,6 +26411,7 @@ var require_persona_loader = __commonJS({
26360
26411
  var node_path_1 = require("node:path");
26361
26412
  var types_1 = require_dist();
26362
26413
  var assets_js_1 = require_assets();
26414
+ var error_utils_js_1 = require_error_utils();
26363
26415
  function buildPersonaCascadeLayers(defaultPersonasDir, homeDir, projectRoot) {
26364
26416
  const layers = [];
26365
26417
  layers.push(defaultPersonasDir);
@@ -26387,7 +26439,7 @@ var require_persona_loader = __commonJS({
26387
26439
  }
26388
26440
  return result.data;
26389
26441
  } catch (error) {
26390
- const message = error instanceof Error ? error.message : String(error);
26442
+ const message = (0, error_utils_js_1.toErrorMessage)(error);
26391
26443
  logger?.warn(`Failed to load persona file ${filename}: ${message}`);
26392
26444
  return null;
26393
26445
  }
@@ -26970,6 +27022,7 @@ var require_config2 = __commonJS({
26970
27022
  var node_path_1 = require("node:path");
26971
27023
  var yaml_1 = require_dist2();
26972
27024
  var v4_1 = require_v4();
27025
+ var error_utils_js_1 = require_error_utils();
26973
27026
  function deepFreeze(obj) {
26974
27027
  if (obj === null || typeof obj !== "object") {
26975
27028
  return obj;
@@ -26996,7 +27049,7 @@ var require_config2 = __commonJS({
26996
27049
  consoleEnabled: v4_1.z.boolean(),
26997
27050
  /** Per-component log level overrides. Keys are component names (e.g., 'reminders', 'statusline'). */
26998
27051
  components: v4_1.z.record(v4_1.z.string(), LogLevelSchema).optional(),
26999
- /** Log rotation settings. Defaults to 10MB/5 files if not specified. */
27052
+ /** Log rotation settings. Defaults come from core.defaults.yaml (2MB/2 files). */
27000
27053
  rotation: v4_1.z.object({
27001
27054
  maxSizeBytes: v4_1.z.number().min(1),
27002
27055
  maxFiles: v4_1.z.number().min(1)
@@ -27046,7 +27099,10 @@ var require_config2 = __commonJS({
27046
27099
  fallbackProfileId: v4_1.z.string().optional(),
27047
27100
  // OpenRouter-specific provider routing (ignored for other providers)
27048
27101
  providerAllowlist: v4_1.z.array(v4_1.z.string()).optional(),
27049
- providerBlocklist: v4_1.z.array(v4_1.z.string()).optional()
27102
+ providerBlocklist: v4_1.z.array(v4_1.z.string()).optional(),
27103
+ // OpenRouter-specific: toggle the model's reasoning mode (maps to reasoning.enabled).
27104
+ // Ignored for non-openrouter providers.
27105
+ reasoning: v4_1.z.boolean().optional()
27050
27106
  });
27051
27107
  exports2.LlmConfigSchema = v4_1.z.object({
27052
27108
  defaultProfile: v4_1.z.string(),
@@ -27162,7 +27218,7 @@ var require_config2 = __commonJS({
27162
27218
  const parsed = (0, yaml_1.parse)(content);
27163
27219
  return parsed ?? {};
27164
27220
  } catch (err) {
27165
- const message = err instanceof Error ? err.message : String(err);
27221
+ const message = (0, error_utils_js_1.toErrorMessage)(err);
27166
27222
  throw new Error(`Failed to parse YAML at ${filePath}: ${message}`, { cause: err });
27167
27223
  }
27168
27224
  }
@@ -27470,6 +27526,7 @@ var require_config_writer = __commonJS({
27470
27526
  var node_os_1 = require("node:os");
27471
27527
  var node_path_1 = require("node:path");
27472
27528
  var yaml_1 = __importDefault(require_dist2());
27529
+ var error_utils_js_1 = require_error_utils();
27473
27530
  var config_1 = require_config2();
27474
27531
  var VALID_DOMAINS = /* @__PURE__ */ new Set(["core", "llm", "transcript", "features"]);
27475
27532
  var FORBIDDEN_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
@@ -27596,7 +27653,7 @@ var require_config_writer = __commonJS({
27596
27653
  } catch {
27597
27654
  }
27598
27655
  }
27599
- const message = err instanceof Error ? err.message : String(err);
27656
+ const message = (0, error_utils_js_1.toErrorMessage)(err);
27600
27657
  throw new Error(`Configuration validation failed after setting "${dotPath}": ${message}`, { cause: err });
27601
27658
  }
27602
27659
  return {
@@ -32760,7 +32817,12 @@ var require_log_events = __commonJS({
32760
32817
  "use strict";
32761
32818
  Object.defineProperty(exports2, "__esModule", { value: true });
32762
32819
  exports2.LogEvents = void 0;
32820
+ exports2.setSessionLogWriter = setSessionLogWriter;
32763
32821
  exports2.logEvent = logEvent;
32822
+ var sessionLogWriter = null;
32823
+ function setSessionLogWriter(writer) {
32824
+ sessionLogWriter = writer;
32825
+ }
32764
32826
  function buildContext(ctx) {
32765
32827
  return {
32766
32828
  sessionId: ctx.sessionId,
@@ -33167,10 +33229,219 @@ var require_log_events = __commonJS({
33167
33229
  source: event.source,
33168
33230
  ...meta
33169
33231
  });
33232
+ if (sessionLogWriter && event.context.sessionId) {
33233
+ const logFile = event.source === "cli" ? "sidekick.log" : "sidekickd.log";
33234
+ const line = JSON.stringify({
33235
+ time: event.time,
33236
+ type: event.type,
33237
+ source: event.source,
33238
+ context: event.context,
33239
+ ...meta
33240
+ }) + "\n";
33241
+ sessionLogWriter.write(event.context.sessionId, logFile, line).catch(() => {
33242
+ });
33243
+ }
33244
+ }
33245
+ }
33246
+ });
33247
+
33248
+ // ../sidekick-core/dist/staging-paths.js
33249
+ var require_staging_paths = __commonJS({
33250
+ "../sidekick-core/dist/staging-paths.js"(exports2) {
33251
+ "use strict";
33252
+ Object.defineProperty(exports2, "__esModule", { value: true });
33253
+ exports2.CONSUMED_FILE_PATTERN = void 0;
33254
+ exports2.getStagingRoot = getStagingRoot;
33255
+ exports2.getHookDir = getHookDir;
33256
+ exports2.getReminderPath = getReminderPath;
33257
+ exports2.isValidPathSegment = isValidPathSegment;
33258
+ exports2.validatePathSegment = validatePathSegment;
33259
+ exports2.filterActiveReminderFiles = filterActiveReminderFiles;
33260
+ exports2.createConsumedFilePattern = createConsumedFilePattern;
33261
+ exports2.extractConsumedTimestamp = extractConsumedTimestamp;
33262
+ var node_path_1 = require("node:path");
33263
+ function getStagingRoot(stateDir, sessionId) {
33264
+ return (0, node_path_1.join)(stateDir, "sessions", sessionId, "stage");
33265
+ }
33266
+ function getHookDir(stateDir, sessionId, hookName) {
33267
+ return (0, node_path_1.join)(getStagingRoot(stateDir, sessionId), hookName);
33268
+ }
33269
+ function getReminderPath(stateDir, sessionId, hookName, reminderName) {
33270
+ return (0, node_path_1.join)(getHookDir(stateDir, sessionId, hookName), `${reminderName}.json`);
33271
+ }
33272
+ function isValidPathSegment(s) {
33273
+ if (s === "")
33274
+ return false;
33275
+ if (s === "." || s === "..")
33276
+ return false;
33277
+ if (s.includes("/") || s.includes("\\"))
33278
+ return false;
33279
+ if ((0, node_path_1.basename)(s) !== s)
33280
+ return false;
33281
+ return /^[a-zA-Z0-9._-]+$/.test(s);
33282
+ }
33283
+ function validatePathSegment(segment, name) {
33284
+ if (!isValidPathSegment(segment)) {
33285
+ throw new Error(`Invalid ${name}: must be a non-empty alphanumeric string without path separators`);
33286
+ }
33287
+ }
33288
+ exports2.CONSUMED_FILE_PATTERN = /\.\d+\.json$/;
33289
+ function filterActiveReminderFiles(files) {
33290
+ return files.filter((f) => f.endsWith(".json") && !exports2.CONSUMED_FILE_PATTERN.test(f));
33291
+ }
33292
+ function createConsumedFilePattern(reminderName) {
33293
+ return new RegExp(`^${reminderName}\\.(\\d+)\\.json$`);
33294
+ }
33295
+ function extractConsumedTimestamp(filename, reminderName) {
33296
+ const pattern = createConsumedFilePattern(reminderName);
33297
+ const match = pattern.exec(filename);
33298
+ return match ? parseInt(match[1], 10) : null;
33170
33299
  }
33171
33300
  }
33172
33301
  });
33173
33302
 
33303
+ // ../sidekick-core/dist/session-log-writer.js
33304
+ var require_session_log_writer = __commonJS({
33305
+ "../sidekick-core/dist/session-log-writer.js"(exports2) {
33306
+ "use strict";
33307
+ Object.defineProperty(exports2, "__esModule", { value: true });
33308
+ exports2.SessionLogWriter = void 0;
33309
+ var promises_1 = require("node:fs/promises");
33310
+ var node_path_1 = require("node:path");
33311
+ var node_fs_1 = require("node:fs");
33312
+ var staging_paths_js_1 = require_staging_paths();
33313
+ var SessionLogWriter = class {
33314
+ sessionsDir;
33315
+ maxHandles;
33316
+ idleTimeoutMs;
33317
+ /** Map key: `${sessionId}/${logFile}` */
33318
+ handles = /* @__PURE__ */ new Map();
33319
+ /** Sentinel map to prevent duplicate handle creation on concurrent writes */
33320
+ pendingCreation = /* @__PURE__ */ new Map();
33321
+ constructor(options) {
33322
+ this.sessionsDir = options.sessionsDir;
33323
+ this.maxHandles = options.maxHandles ?? 10;
33324
+ this.idleTimeoutMs = options.idleTimeoutMs ?? 30 * 60 * 1e3;
33325
+ }
33326
+ get handleCount() {
33327
+ return this.handles.size;
33328
+ }
33329
+ /**
33330
+ * Write an NDJSON line to a per-session log file.
33331
+ * Creates the directory and file handle lazily.
33332
+ * Skips if sessionId is empty (daemon lifecycle events before session exists).
33333
+ */
33334
+ async write(sessionId, logFile, line) {
33335
+ if (!sessionId)
33336
+ return;
33337
+ if (!(0, staging_paths_js_1.isValidPathSegment)(sessionId) || !(0, staging_paths_js_1.isValidPathSegment)(logFile))
33338
+ return;
33339
+ const key = `${sessionId}/${logFile}`;
33340
+ const pending = this.pendingCreation.get(key);
33341
+ if (pending) {
33342
+ try {
33343
+ await pending;
33344
+ } catch {
33345
+ }
33346
+ }
33347
+ let entry = this.handles.get(key);
33348
+ if (!entry) {
33349
+ if (this.handles.size >= this.maxHandles) {
33350
+ this.evictLRU();
33351
+ }
33352
+ const creationPromise = this.createHandle(sessionId, logFile);
33353
+ this.pendingCreation.set(key, creationPromise);
33354
+ try {
33355
+ entry = await creationPromise;
33356
+ this.handles.set(key, entry);
33357
+ } finally {
33358
+ this.pendingCreation.delete(key);
33359
+ }
33360
+ }
33361
+ await entry.ready;
33362
+ entry.lastUsed = Date.now();
33363
+ this.resetIdleTimer(key, entry);
33364
+ return new Promise((resolve3, reject) => {
33365
+ entry.stream.write(line, (err) => {
33366
+ if (err) {
33367
+ void this.closeHandle(key);
33368
+ reject(err);
33369
+ } else {
33370
+ resolve3();
33371
+ }
33372
+ });
33373
+ });
33374
+ }
33375
+ async createHandle(sessionId, logFile) {
33376
+ const logDir = (0, node_path_1.join)(this.sessionsDir, sessionId, "logs");
33377
+ await (0, promises_1.mkdir)(logDir, { recursive: true });
33378
+ const filePath = (0, node_path_1.join)(logDir, logFile);
33379
+ const stream = (0, node_fs_1.createWriteStream)(filePath, { flags: "a" });
33380
+ const ready = new Promise((resolve3, reject) => {
33381
+ stream.once("open", () => resolve3());
33382
+ stream.once("error", (err) => {
33383
+ stream.destroy();
33384
+ reject(err);
33385
+ });
33386
+ });
33387
+ return {
33388
+ stream,
33389
+ lastUsed: Date.now(),
33390
+ timer: null,
33391
+ ready
33392
+ };
33393
+ }
33394
+ /** Close all handles for a specific session. */
33395
+ async closeSession(sessionId) {
33396
+ const prefix = `${sessionId}/`;
33397
+ const toClose = [];
33398
+ for (const key of this.handles.keys()) {
33399
+ if (key.startsWith(prefix)) {
33400
+ toClose.push(key);
33401
+ }
33402
+ }
33403
+ await Promise.all(toClose.map((key) => this.closeHandle(key)));
33404
+ }
33405
+ /** Close all open handles. */
33406
+ async closeAll() {
33407
+ const keys = [...this.handles.keys()];
33408
+ await Promise.all(keys.map((key) => this.closeHandle(key)));
33409
+ }
33410
+ async closeHandle(key) {
33411
+ const entry = this.handles.get(key);
33412
+ if (!entry)
33413
+ return;
33414
+ if (entry.timer)
33415
+ clearTimeout(entry.timer);
33416
+ this.handles.delete(key);
33417
+ return new Promise((resolve3) => {
33418
+ entry.stream.end(() => resolve3());
33419
+ });
33420
+ }
33421
+ evictLRU() {
33422
+ let oldestKey = "";
33423
+ let oldestTime = Infinity;
33424
+ for (const [key, entry] of this.handles) {
33425
+ if (entry.lastUsed < oldestTime) {
33426
+ oldestTime = entry.lastUsed;
33427
+ oldestKey = key;
33428
+ }
33429
+ }
33430
+ void this.closeHandle(oldestKey);
33431
+ }
33432
+ resetIdleTimer(key, entry) {
33433
+ if (entry.timer)
33434
+ clearTimeout(entry.timer);
33435
+ entry.timer = setTimeout(() => {
33436
+ void this.closeHandle(key);
33437
+ }, this.idleTimeoutMs);
33438
+ entry.timer.unref();
33439
+ }
33440
+ };
33441
+ exports2.SessionLogWriter = SessionLogWriter;
33442
+ }
33443
+ });
33444
+
33174
33445
  // ../../node_modules/.pnpm/date-fns@4.1.0/node_modules/date-fns/constants.cjs
33175
33446
  var require_constants2 = __commonJS({
33176
33447
  "../../node_modules/.pnpm/date-fns@4.1.0/node_modules/date-fns/constants.cjs"(exports2) {
@@ -44910,7 +45181,7 @@ var require_structured_logging = __commonJS({
44910
45181
  return mod && mod.__esModule ? mod : { "default": mod };
44911
45182
  };
44912
45183
  Object.defineProperty(exports2, "__esModule", { value: true });
44913
- exports2.DEFAULT_MAX_FILES = exports2.DEFAULT_ROTATE_SIZE_BYTES = exports2.LOG_LEVELS = exports2.logEvent = exports2.LogEvents = void 0;
45184
+ exports2.DEFAULT_MAX_FILES = exports2.DEFAULT_ROTATE_SIZE_BYTES = exports2.LOG_LEVELS = exports2.SessionLogWriter = exports2.setSessionLogWriter = exports2.logEvent = exports2.LogEvents = void 0;
44914
45185
  exports2.getComponentLogLevel = getComponentLogLevel;
44915
45186
  exports2.createLogManager = createLogManager;
44916
45187
  exports2.createContextLogger = createContextLogger;
@@ -44920,6 +45191,7 @@ var require_structured_logging = __commonJS({
44920
45191
  var node_fs_1 = require("node:fs");
44921
45192
  var node_path_1 = require("node:path");
44922
45193
  var node_stream_1 = require("node:stream");
45194
+ var error_utils_js_1 = require_error_utils();
44923
45195
  var log_events_1 = require_log_events();
44924
45196
  Object.defineProperty(exports2, "LogEvents", { enumerable: true, get: function() {
44925
45197
  return log_events_1.LogEvents;
@@ -44927,6 +45199,13 @@ var require_structured_logging = __commonJS({
44927
45199
  Object.defineProperty(exports2, "logEvent", { enumerable: true, get: function() {
44928
45200
  return log_events_1.logEvent;
44929
45201
  } });
45202
+ Object.defineProperty(exports2, "setSessionLogWriter", { enumerable: true, get: function() {
45203
+ return log_events_1.setSessionLogWriter;
45204
+ } });
45205
+ var session_log_writer_1 = require_session_log_writer();
45206
+ Object.defineProperty(exports2, "SessionLogWriter", { enumerable: true, get: function() {
45207
+ return session_log_writer_1.SessionLogWriter;
45208
+ } });
44930
45209
  exports2.LOG_LEVELS = {
44931
45210
  trace: 10,
44932
45211
  debug: 20,
@@ -44942,8 +45221,8 @@ var require_structured_logging = __commonJS({
44942
45221
  }
44943
45222
  return defaultLevel;
44944
45223
  }
44945
- exports2.DEFAULT_ROTATE_SIZE_BYTES = 10 * 1024 * 1024;
44946
- exports2.DEFAULT_MAX_FILES = 5;
45224
+ exports2.DEFAULT_ROTATE_SIZE_BYTES = 2 * 1024 * 1024;
45225
+ exports2.DEFAULT_MAX_FILES = 2;
44947
45226
  var DEFAULT_REDACT_KEYS = [
44948
45227
  "apiKey",
44949
45228
  "token",
@@ -45284,7 +45563,7 @@ var require_structured_logging = __commonJS({
45284
45563
  upgradeOptions.onUpgradeError(err);
45285
45564
  }
45286
45565
  activeLogger.error("Failed to upgrade to Pino logger", {
45287
- error: err instanceof Error ? err.message : String(err)
45566
+ error: (0, error_utils_js_1.toErrorMessage)(err)
45288
45567
  });
45289
45568
  }
45290
45569
  },
@@ -45300,7 +45579,7 @@ var require_structured_logging = __commonJS({
45300
45579
  };
45301
45580
  const rejectionHandler = (reason) => {
45302
45581
  logger.fatal("Unhandled promise rejection", {
45303
- reason: reason instanceof Error ? reason.message : String(reason)
45582
+ reason: (0, error_utils_js_1.toErrorMessage)(reason)
45304
45583
  });
45305
45584
  };
45306
45585
  process.on("uncaughtException", uncaughtHandler);
@@ -45393,13 +45672,11 @@ var require_daemon_client2 = __commonJS({
45393
45672
  var client_js_1 = require_client();
45394
45673
  var transport_js_1 = require_transport();
45395
45674
  var sandbox_js_1 = require_sandbox();
45675
+ var error_utils_js_1 = require_error_utils();
45396
45676
  var LOCK_TIMEOUT_MS = 1e4;
45397
45677
  var LOCK_RETRY_INTERVAL_MS = 100;
45398
45678
  var LOCK_STALE_THRESHOLD_MS = 3e4;
45399
45679
  var CLIENT_VERSION = require_package3().version;
45400
- function toErrorMsg(err) {
45401
- return err instanceof Error ? err.message : String(err);
45402
- }
45403
45680
  var DaemonClient = class {
45404
45681
  projectDir;
45405
45682
  logger;
@@ -45765,7 +46042,7 @@ var require_daemon_client2 = __commonJS({
45765
46042
  } catch (err) {
45766
46043
  logger.debug("Graceful stop failed, falling back to SIGKILL", {
45767
46044
  pid: info.pid,
45768
- error: toErrorMsg(err)
46045
+ error: (0, error_utils_js_1.toErrorMessage)(err)
45769
46046
  });
45770
46047
  }
45771
46048
  }
@@ -45774,7 +46051,7 @@ var require_daemon_client2 = __commonJS({
45774
46051
  logger.info("Killed daemon", { pid: info.pid, projectDir: info.projectDir });
45775
46052
  results.push({ projectDir: info.projectDir, pid: info.pid, killed: true });
45776
46053
  } catch (err) {
45777
- const msg = toErrorMsg(err);
46054
+ const msg = (0, error_utils_js_1.toErrorMessage)(err);
45778
46055
  logger.warn("Failed to kill daemon", { pid: info.pid, error: msg });
45779
46056
  results.push({ projectDir: info.projectDir, pid: info.pid, killed: false, error: msg });
45780
46057
  }
@@ -45786,7 +46063,7 @@ var require_daemon_client2 = __commonJS({
45786
46063
  });
45787
46064
  }
45788
46065
  } catch (err) {
45789
- logger.warn("Invalid PID file, removing", { pidFile, error: toErrorMsg(err) });
46066
+ logger.warn("Invalid PID file, removing", { pidFile, error: (0, error_utils_js_1.toErrorMessage)(err) });
45790
46067
  await promises_1.default.unlink(pidPath).catch(() => {
45791
46068
  });
45792
46069
  }
@@ -45807,7 +46084,7 @@ var require_daemon_client2 = __commonJS({
45807
46084
  });
45808
46085
  } catch (err) {
45809
46086
  logger.warn("Failed to run ps \u2014 cannot detect zombie daemons", {
45810
- error: toErrorMsg(err)
46087
+ error: (0, error_utils_js_1.toErrorMessage)(err)
45811
46088
  });
45812
46089
  return [];
45813
46090
  }
@@ -45868,7 +46145,7 @@ var require_daemon_client2 = __commonJS({
45868
46145
  logger.info("Killed zombie daemon", { pid: zombie.pid, command: zombie.command });
45869
46146
  results.push({ projectDir: "unknown", pid: zombie.pid, killed: true });
45870
46147
  } catch (err) {
45871
- const msg = toErrorMsg(err);
46148
+ const msg = (0, error_utils_js_1.toErrorMessage)(err);
45872
46149
  logger.warn("Failed to kill zombie daemon", { pid: zombie.pid, error: msg });
45873
46150
  results.push({ projectDir: "unknown", pid: zombie.pid, killed: false, error: msg });
45874
46151
  }
@@ -45920,60 +46197,94 @@ var require_gitignore = __commonJS({
45920
46197
  };
45921
46198
  })();
45922
46199
  Object.defineProperty(exports2, "__esModule", { value: true });
45923
- exports2.GITIGNORE_ENTRIES = exports2.SIDEKICK_SECTION_END = exports2.SIDEKICK_SECTION_START = void 0;
46200
+ exports2.GITIGNORE_ENTRIES = exports2.SIDEKICK_GITIGNORE_HEADER = exports2.SIDEKICK_SECTION_END = exports2.SIDEKICK_SECTION_START = void 0;
45924
46201
  exports2.installGitignoreSection = installGitignoreSection;
45925
- exports2.removeGitignoreSection = removeGitignoreSection;
45926
46202
  exports2.detectGitignoreStatus = detectGitignoreStatus;
46203
+ exports2.removeGitignoreSection = removeGitignoreSection;
46204
+ exports2.detectLegacyGitignoreSection = detectLegacyGitignoreSection;
46205
+ exports2.removeLegacyGitignoreSection = removeLegacyGitignoreSection;
45927
46206
  var fs = __importStar(require("node:fs/promises"));
45928
46207
  var path = __importStar(require("node:path"));
45929
46208
  exports2.SIDEKICK_SECTION_START = "# >>> sidekick";
45930
46209
  exports2.SIDEKICK_SECTION_END = "# <<< sidekick";
46210
+ exports2.SIDEKICK_GITIGNORE_HEADER = "# Sidekick \u2014 managed file, do not edit manually";
45931
46211
  exports2.GITIGNORE_ENTRIES = [
45932
- ".sidekick/logs/",
45933
- ".sidekick/sessions/",
45934
- ".sidekick/state/",
45935
- ".sidekick/setup-status.json",
45936
- ".sidekick/.env",
45937
- ".sidekick/.env.local",
45938
- ".sidekick/sidekick*.pid",
45939
- ".sidekick/sidekick*.token",
45940
- ".sidekick/*.local.yaml"
46212
+ "logs/",
46213
+ "sessions/",
46214
+ "state/",
46215
+ "setup-status.json",
46216
+ ".env",
46217
+ ".env.local",
46218
+ "sidekick*.pid",
46219
+ "sidekick*.token",
46220
+ "*.local.yaml"
45941
46221
  ];
45942
46222
  async function installGitignoreSection(projectDir2) {
45943
- const gitignorePath = path.join(projectDir2, ".gitignore");
45944
- let content = "";
46223
+ let status;
45945
46224
  try {
45946
- content = await fs.readFile(gitignorePath, "utf-8");
46225
+ status = await detectGitignoreStatus(projectDir2);
45947
46226
  } catch (err) {
45948
- if (err.code !== "ENOENT") {
45949
- return { status: "error", error: `Failed to read .gitignore: ${err.message}` };
45950
- }
46227
+ return { status: "error", error: `Failed to check gitignore status: ${err.message}` };
45951
46228
  }
45952
- const status = await detectGitignoreStatus(projectDir2);
45953
46229
  if (status === "installed") {
45954
46230
  return { status: "already-installed" };
45955
46231
  }
45956
- if (status === "incomplete") {
45957
- await removeGitignoreSection(projectDir2);
45958
- try {
45959
- content = await fs.readFile(gitignorePath, "utf-8");
45960
- } catch {
45961
- content = "";
45962
- }
46232
+ const sidekickDir = path.join(projectDir2, ".sidekick");
46233
+ try {
46234
+ await fs.mkdir(sidekickDir, { recursive: true });
46235
+ } catch (err) {
46236
+ return { status: "error", error: `Failed to create .sidekick directory: ${err.message}` };
45963
46237
  }
45964
- const section = ["", exports2.SIDEKICK_SECTION_START, ...exports2.GITIGNORE_ENTRIES, exports2.SIDEKICK_SECTION_END].join("\n");
45965
- const newContent = content.trimEnd() + section + "\n";
46238
+ const content = [exports2.SIDEKICK_GITIGNORE_HEADER, ...exports2.GITIGNORE_ENTRIES].join("\n") + "\n";
45966
46239
  try {
45967
- await fs.writeFile(gitignorePath, newContent);
46240
+ await fs.writeFile(path.join(sidekickDir, ".gitignore"), content);
45968
46241
  return { status: "installed", entriesAdded: exports2.GITIGNORE_ENTRIES };
45969
46242
  } catch (err) {
45970
- return { status: "error", error: `Failed to write .gitignore: ${err.message}` };
46243
+ return { status: "error", error: `Failed to write .sidekick/.gitignore: ${err.message}` };
45971
46244
  }
45972
46245
  }
46246
+ async function detectGitignoreStatus(projectDir2) {
46247
+ const sidekickGitignorePath = path.join(projectDir2, ".sidekick", ".gitignore");
46248
+ try {
46249
+ const content = await fs.readFile(sidekickGitignorePath, "utf-8");
46250
+ const missingEntries = exports2.GITIGNORE_ENTRIES.filter((entry) => !content.includes(entry));
46251
+ return missingEntries.length === 0 ? "installed" : "incomplete";
46252
+ } catch (err) {
46253
+ if (err.code !== "ENOENT") {
46254
+ throw err;
46255
+ }
46256
+ }
46257
+ const hasLegacy = await detectLegacyGitignoreSection(projectDir2);
46258
+ return hasLegacy ? "legacy" : "missing";
46259
+ }
45973
46260
  async function removeGitignoreSection(projectDir2) {
45974
- const gitignorePath = path.join(projectDir2, ".gitignore");
46261
+ let removed = false;
45975
46262
  try {
45976
- const content = await fs.readFile(gitignorePath, "utf-8");
46263
+ await fs.unlink(path.join(projectDir2, ".sidekick", ".gitignore"));
46264
+ removed = true;
46265
+ } catch (err) {
46266
+ if (err.code !== "ENOENT") {
46267
+ throw err;
46268
+ }
46269
+ }
46270
+ const legacyRemoved = await removeLegacyGitignoreSection(projectDir2);
46271
+ return removed || legacyRemoved;
46272
+ }
46273
+ async function detectLegacyGitignoreSection(projectDir2) {
46274
+ try {
46275
+ const content = await fs.readFile(path.join(projectDir2, ".gitignore"), "utf-8");
46276
+ return content.includes(exports2.SIDEKICK_SECTION_START);
46277
+ } catch (err) {
46278
+ if (err.code === "ENOENT") {
46279
+ return false;
46280
+ }
46281
+ throw err;
46282
+ }
46283
+ }
46284
+ async function removeLegacyGitignoreSection(projectDir2) {
46285
+ const rootGitignorePath = path.join(projectDir2, ".gitignore");
46286
+ try {
46287
+ const content = await fs.readFile(rootGitignorePath, "utf-8");
45977
46288
  const startIdx = content.indexOf(exports2.SIDEKICK_SECTION_START);
45978
46289
  const endIdx = content.indexOf(exports2.SIDEKICK_SECTION_END);
45979
46290
  if (startIdx === -1 || endIdx === -1 || endIdx < startIdx) {
@@ -45985,37 +46296,13 @@ var require_gitignore = __commonJS({
45985
46296
  const before = content.slice(0, lineStartIdx).trimEnd();
45986
46297
  const after = content.slice(actualEndIdx).trimStart();
45987
46298
  const newContent = before + (after ? "\n" + after : "") + "\n";
45988
- await fs.writeFile(gitignorePath, newContent);
46299
+ await fs.writeFile(rootGitignorePath, newContent);
45989
46300
  return true;
45990
- } catch {
45991
- return false;
45992
- }
45993
- }
45994
- async function detectGitignoreStatus(projectDir2) {
45995
- const gitignorePath = path.join(projectDir2, ".gitignore");
45996
- try {
45997
- const content = await fs.readFile(gitignorePath, "utf-8");
45998
- const hasStart = content.includes(exports2.SIDEKICK_SECTION_START);
45999
- const hasEnd = content.includes(exports2.SIDEKICK_SECTION_END);
46000
- if (!hasStart && !hasEnd) {
46001
- return "missing";
46002
- }
46003
- if (!hasStart || !hasEnd) {
46004
- return "incomplete";
46005
- }
46006
- const startIdx = content.indexOf(exports2.SIDEKICK_SECTION_START);
46007
- const endIdx = content.indexOf(exports2.SIDEKICK_SECTION_END);
46008
- if (endIdx <= startIdx) {
46009
- return "incomplete";
46010
- }
46011
- const sectionContent = content.slice(startIdx, endIdx + exports2.SIDEKICK_SECTION_END.length);
46012
- const missingEntries = exports2.GITIGNORE_ENTRIES.filter((entry) => !sectionContent.includes(entry));
46013
- if (missingEntries.length > 0) {
46014
- return "incomplete";
46301
+ } catch (err) {
46302
+ if (err.code === "ENOENT") {
46303
+ return false;
46015
46304
  }
46016
- return "installed";
46017
- } catch {
46018
- return "missing";
46305
+ throw err;
46019
46306
  }
46020
46307
  }
46021
46308
  }
@@ -46026,7 +46313,7 @@ var require_errors4 = __commonJS({
46026
46313
  "../shared-providers/dist/errors.js"(exports2) {
46027
46314
  "use strict";
46028
46315
  Object.defineProperty(exports2, "__esModule", { value: true });
46029
- exports2.TimeoutError = exports2.AuthError = exports2.RateLimitError = exports2.ProviderError = void 0;
46316
+ exports2.MalformedResponseError = exports2.TimeoutError = exports2.AuthError = exports2.RateLimitError = exports2.ProviderError = void 0;
46030
46317
  var ProviderError = class _ProviderError extends Error {
46031
46318
  provider;
46032
46319
  retryable;
@@ -46067,6 +46354,18 @@ var require_errors4 = __commonJS({
46067
46354
  }
46068
46355
  };
46069
46356
  exports2.TimeoutError = TimeoutError;
46357
+ var MalformedResponseError = class _MalformedResponseError extends ProviderError {
46358
+ code;
46359
+ providerMessage;
46360
+ constructor(provider, code, providerMessage, cause) {
46361
+ super(`Malformed response from ${provider}: ${code ?? "unknown"} - ${providerMessage ?? "no message"}`, provider, false, cause);
46362
+ this.name = "MalformedResponseError";
46363
+ this.code = code;
46364
+ this.providerMessage = providerMessage;
46365
+ Object.setPrototypeOf(this, _MalformedResponseError.prototype);
46366
+ }
46367
+ };
46368
+ exports2.MalformedResponseError = MalformedResponseError;
46070
46369
  }
46071
46370
  });
46072
46371
 
@@ -55045,6 +55344,7 @@ var require_base = __commonJS({
55045
55344
  model: response.model,
55046
55345
  durationMs,
55047
55346
  usage: response.usage,
55347
+ finishReason: response.finishReason,
55048
55348
  status: response.rawResponse.status,
55049
55349
  contentLength: response.content.length
55050
55350
  });
@@ -55092,6 +55392,7 @@ var require_openai_native = __commonJS({
55092
55392
  maxTokens;
55093
55393
  providerAllowlist;
55094
55394
  providerBlocklist;
55395
+ reasoning;
55095
55396
  constructor(config, logger) {
55096
55397
  super(logger);
55097
55398
  this.id = config.baseURL?.includes("openrouter") ? "openrouter" : "openai";
@@ -55100,6 +55401,7 @@ var require_openai_native = __commonJS({
55100
55401
  this.maxTokens = config.maxTokens;
55101
55402
  this.providerAllowlist = config.providerAllowlist;
55102
55403
  this.providerBlocklist = config.providerBlocklist;
55404
+ this.reasoning = config.reasoning;
55103
55405
  this.client = new openai_1.default({
55104
55406
  apiKey: config.apiKey,
55105
55407
  baseURL: config.baseURL,
@@ -55115,6 +55417,7 @@ var require_openai_native = __commonJS({
55115
55417
  maxTokens: this.maxTokens,
55116
55418
  providerAllowlist: this.providerAllowlist,
55117
55419
  providerBlocklist: this.providerBlocklist,
55420
+ reasoning: this.reasoning,
55118
55421
  apiKey: this.redactApiKey(config.apiKey)
55119
55422
  });
55120
55423
  }
@@ -55132,6 +55435,7 @@ var require_openai_native = __commonJS({
55132
55435
  }
55133
55436
  } : void 0;
55134
55437
  const providerRouting = this.buildProviderRouting();
55438
+ const reasoningParam = this.buildReasoningParam();
55135
55439
  const completion = await this.client.chat.completions.create({
55136
55440
  model: request.model ?? this.defaultModel,
55137
55441
  messages,
@@ -55139,8 +55443,13 @@ var require_openai_native = __commonJS({
55139
55443
  max_tokens: this.maxTokens,
55140
55444
  response_format: responseFormat,
55141
55445
  ...providerRouting,
55446
+ ...reasoningParam,
55142
55447
  ...request.additionalParams
55143
55448
  });
55449
+ if (!completion.choices || completion.choices.length === 0) {
55450
+ const errorPayload = completion.error;
55451
+ throw new errors_1.MalformedResponseError(this.id, errorPayload?.code, errorPayload?.message);
55452
+ }
55144
55453
  const response = {
55145
55454
  content: completion.choices[0]?.message?.content ?? "",
55146
55455
  model: completion.model,
@@ -55148,6 +55457,7 @@ var require_openai_native = __commonJS({
55148
55457
  inputTokens: completion.usage.prompt_tokens,
55149
55458
  outputTokens: completion.usage.completion_tokens
55150
55459
  } : void 0,
55460
+ finishReason: completion.choices[0]?.finish_reason ?? void 0,
55151
55461
  rawResponse: {
55152
55462
  status: 200,
55153
55463
  body: JSON.stringify(completion)
@@ -55183,7 +55493,25 @@ var require_openai_native = __commonJS({
55183
55493
  }
55184
55494
  return { provider: providerObj };
55185
55495
  }
55496
+ /**
55497
+ * Build OpenRouter reasoning param object.
55498
+ * Returns empty object if reasoning is unset or provider is not OpenRouter.
55499
+ * Maps `reasoning?: boolean` to OpenRouter's `reasoning: { enabled: <bool> }`.
55500
+ * @see https://openrouter.ai/docs/use-cases/reasoning-tokens
55501
+ */
55502
+ buildReasoningParam() {
55503
+ if (this.id !== "openrouter") {
55504
+ return {};
55505
+ }
55506
+ if (this.reasoning === void 0) {
55507
+ return {};
55508
+ }
55509
+ return { reasoning: { enabled: this.reasoning } };
55510
+ }
55186
55511
  mapError(error) {
55512
+ if (error instanceof errors_1.ProviderError) {
55513
+ return error;
55514
+ }
55187
55515
  if (error instanceof openai_1.default.APIError) {
55188
55516
  if (error.status === 401 || error.status === 403) {
55189
55517
  return new errors_1.AuthError(this.id, error);
@@ -55277,7 +55605,13 @@ var require_claude_cli_spawn = __commonJS({
55277
55605
  });
55278
55606
  const child = (0, node_child_process_1.spawn)(cliPath, args, {
55279
55607
  cwd,
55280
- stdio: ["pipe", "pipe", "pipe"]
55608
+ stdio: ["pipe", "pipe", "pipe"],
55609
+ // Recursion guard: Sidekick's own Claude Code hooks fire inside any
55610
+ // `claude -p` subprocess we spawn. Without this flag, the subprocess
55611
+ // hook handler would dispatch to the daemon, trigger another LLM call,
55612
+ // spawn another subprocess, and so on. handleHookCommand short-circuits
55613
+ // when SIDEKICK_SUBPROCESS=1 is set. See packages/sidekick-cli/src/commands/hook.ts.
55614
+ env: { ...process.env, SIDEKICK_SUBPROCESS: "1" }
55281
55615
  });
55282
55616
  let stdout = "";
55283
55617
  let stderr = "";
@@ -55339,6 +55673,31 @@ var require_claude_cli_spawn = __commonJS({
55339
55673
  }
55340
55674
  });
55341
55675
 
55676
+ // ../shared-providers/dist/providers/anthropic-stop-reason.js
55677
+ var require_anthropic_stop_reason = __commonJS({
55678
+ "../shared-providers/dist/providers/anthropic-stop-reason.js"(exports2) {
55679
+ "use strict";
55680
+ Object.defineProperty(exports2, "__esModule", { value: true });
55681
+ exports2.mapAnthropicStopReason = mapAnthropicStopReason;
55682
+ function mapAnthropicStopReason(stopReason) {
55683
+ if (!stopReason)
55684
+ return void 0;
55685
+ switch (stopReason) {
55686
+ case "end_turn":
55687
+ return "stop";
55688
+ case "max_tokens":
55689
+ return "length";
55690
+ case "stop_sequence":
55691
+ return "stop";
55692
+ case "tool_use":
55693
+ return "tool_calls";
55694
+ default:
55695
+ return stopReason;
55696
+ }
55697
+ }
55698
+ }
55699
+ });
55700
+
55342
55701
  // ../shared-providers/dist/providers/anthropic-cli.js
55343
55702
  var require_anthropic_cli = __commonJS({
55344
55703
  "../shared-providers/dist/providers/anthropic-cli.js"(exports2) {
@@ -55347,6 +55706,7 @@ var require_anthropic_cli = __commonJS({
55347
55706
  exports2.AnthropicCliProvider = void 0;
55348
55707
  var base_1 = require_base();
55349
55708
  var claude_cli_spawn_1 = require_claude_cli_spawn();
55709
+ var anthropic_stop_reason_1 = require_anthropic_stop_reason();
55350
55710
  var AnthropicCliProvider = class extends base_1.AbstractProvider {
55351
55711
  id = "claude-cli";
55352
55712
  defaultModel;
@@ -55408,6 +55768,7 @@ var require_anthropic_cli = __commonJS({
55408
55768
  inputTokens: parsed.usage.input_tokens ?? 0,
55409
55769
  outputTokens: parsed.usage.output_tokens ?? 0
55410
55770
  } : void 0,
55771
+ finishReason: (0, anthropic_stop_reason_1.mapAnthropicStopReason)(parsed.stop_reason),
55411
55772
  rawResponse: {
55412
55773
  status: 200,
55413
55774
  body: stdout
@@ -55679,6 +56040,7 @@ var require_openai_emulator = __commonJS({
55679
56040
  inputTokens,
55680
56041
  outputTokens
55681
56042
  },
56043
+ finishReason: "stop",
55682
56044
  rawResponse: {
55683
56045
  status: 200,
55684
56046
  body: JSON.stringify(rawBody)
@@ -55733,6 +56095,7 @@ var require_openrouter_emulator = __commonJS({
55733
56095
  inputTokens,
55734
56096
  outputTokens
55735
56097
  },
56098
+ finishReason: "stop",
55736
56099
  rawResponse: {
55737
56100
  status: 200,
55738
56101
  body: JSON.stringify(rawBody)
@@ -55753,6 +56116,7 @@ var require_claude_cli_emulator = __commonJS({
55753
56116
  var node_child_process_1 = require("node:child_process");
55754
56117
  var node_path_1 = require("node:path");
55755
56118
  var base_1 = require_base();
56119
+ var anthropic_stop_reason_1 = require_anthropic_stop_reason();
55756
56120
  var EMULATOR_SCRIPT = `#!/bin/bash
55757
56121
  # Claude CLI Emulator Script
55758
56122
  STATE_FILE="\${SIDEKICK_EMULATOR_STATE_PATH:-.sidekick/emulator-state/call-counts.json}"
@@ -55840,6 +56204,7 @@ echo "{\\"content\\":\\"\${CONTENT}\\",\\"message\\":\\"\${CONTENT}\\",\\"model\
55840
56204
  inputTokens,
55841
56205
  outputTokens
55842
56206
  },
56207
+ finishReason: (0, anthropic_stop_reason_1.mapAnthropicStopReason)(parsed.stop_reason),
55843
56208
  rawResponse: {
55844
56209
  status: 0,
55845
56210
  // Exit code
@@ -55976,7 +56341,8 @@ var require_factory = __commonJS({
55976
56341
  temperature: this.config.temperature,
55977
56342
  maxTokens: this.config.maxTokens,
55978
56343
  providerAllowlist: this.config.providerAllowlist,
55979
- providerBlocklist: this.config.providerBlocklist
56344
+ providerBlocklist: this.config.providerBlocklist,
56345
+ reasoning: this.config.reasoning
55980
56346
  };
55981
56347
  return new openai_native_1.OpenAINativeProvider(openrouterConfig, this.logger);
55982
56348
  }
@@ -56153,7 +56519,9 @@ var require_profile_factory = __commonJS({
56153
56519
  maxTokens: profile.maxTokens,
56154
56520
  // OpenRouter-specific provider routing
56155
56521
  providerAllowlist: profile.providerAllowlist ? [...profile.providerAllowlist] : void 0,
56156
- providerBlocklist: profile.providerBlocklist ? [...profile.providerBlocklist] : void 0
56522
+ providerBlocklist: profile.providerBlocklist ? [...profile.providerBlocklist] : void 0,
56523
+ // OpenRouter-specific reasoning toggle
56524
+ reasoning: profile.reasoning
56157
56525
  }, this.logger);
56158
56526
  return factory.create();
56159
56527
  }
@@ -56208,7 +56576,7 @@ var require_dist3 = __commonJS({
56208
56576
  "../shared-providers/dist/index.js"(exports2) {
56209
56577
  "use strict";
56210
56578
  Object.defineProperty(exports2, "__esModule", { value: true });
56211
- exports2.spawnClaudeCli = exports2.ClaudeCliEmulator = exports2.OpenRouterEmulator = exports2.OpenAIEmulator = exports2.EmulatorStateManager = exports2.AbstractEmulator = exports2.validateOpenAIKey = exports2.validateOpenRouterKey = exports2.AbstractProvider = exports2.AnthropicCliProvider = exports2.OpenAINativeProvider = exports2.FallbackProvider = exports2.ProfileProviderFactory = exports2.ProviderFactory = exports2.TimeoutError = exports2.AuthError = exports2.RateLimitError = exports2.ProviderError = void 0;
56579
+ exports2.spawnClaudeCli = exports2.ClaudeCliEmulator = exports2.OpenRouterEmulator = exports2.OpenAIEmulator = exports2.EmulatorStateManager = exports2.AbstractEmulator = exports2.validateOpenAIKey = exports2.validateOpenRouterKey = exports2.AbstractProvider = exports2.AnthropicCliProvider = exports2.OpenAINativeProvider = exports2.FallbackProvider = exports2.ProfileProviderFactory = exports2.ProviderFactory = exports2.MalformedResponseError = exports2.TimeoutError = exports2.AuthError = exports2.RateLimitError = exports2.ProviderError = void 0;
56212
56580
  var errors_1 = require_errors4();
56213
56581
  Object.defineProperty(exports2, "ProviderError", { enumerable: true, get: function() {
56214
56582
  return errors_1.ProviderError;
@@ -56222,6 +56590,9 @@ var require_dist3 = __commonJS({
56222
56590
  Object.defineProperty(exports2, "TimeoutError", { enumerable: true, get: function() {
56223
56591
  return errors_1.TimeoutError;
56224
56592
  } });
56593
+ Object.defineProperty(exports2, "MalformedResponseError", { enumerable: true, get: function() {
56594
+ return errors_1.MalformedResponseError;
56595
+ } });
56225
56596
  var factory_1 = require_factory();
56226
56597
  Object.defineProperty(exports2, "ProviderFactory", { enumerable: true, get: function() {
56227
56598
  return factory_1.ProviderFactory;
@@ -56511,6 +56882,7 @@ var require_plugin_detector = __commonJS({
56511
56882
  var crypto2 = __importStar(require("node:crypto"));
56512
56883
  var node_child_process_1 = require("node:child_process");
56513
56884
  var api_key_detector_js_1 = require_api_key_detector();
56885
+ var error_utils_js_1 = require_error_utils();
56514
56886
  function isSidekickStatuslineCommand(command) {
56515
56887
  return command?.toLowerCase().includes("sidekick") ?? false;
56516
56888
  }
@@ -56640,7 +57012,7 @@ var require_plugin_detector = __commonJS({
56640
57012
  return result;
56641
57013
  } catch (err) {
56642
57014
  logger?.warn("Failed to parse plugin list JSON", {
56643
- error: err instanceof Error ? err.message : String(err)
57015
+ error: (0, error_utils_js_1.toErrorMessage)(err)
56644
57016
  });
56645
57017
  logger?.info("Plugin detection completed", { result: "error" });
56646
57018
  return "error";
@@ -56844,7 +57216,16 @@ var require_doctor_engine = __commonJS({
56844
57216
  const expectedUserStatus = (0, api_key_detector_js_1.buildUserApiKeyStatus)(detection);
56845
57217
  const currentUserEntry = currentUserStatus.apiKeys[keyName];
56846
57218
  const currentStatus = typeof currentUserEntry === "object" ? currentUserEntry.status : currentUserEntry ?? "missing";
56847
- if (currentStatus !== "not-required" && (0, api_key_detector_js_1.toScopeStatus)(currentStatus) !== (0, api_key_detector_js_1.toScopeStatus)(expectedUserStatus.status)) {
57219
+ if (currentStatus === "not-required")
57220
+ continue;
57221
+ const isLegacyString = typeof currentUserEntry === "string";
57222
+ if (isLegacyString) {
57223
+ updatedUserApiKeys[keyName] = expectedUserStatus;
57224
+ userNeedsUpdate = true;
57225
+ } else if ((0, api_key_detector_js_1.toScopeStatus)(currentStatus) !== (0, api_key_detector_js_1.toScopeStatus)(expectedUserStatus.status)) {
57226
+ updatedUserApiKeys[keyName] = expectedUserStatus;
57227
+ userNeedsUpdate = true;
57228
+ } else if (typeof currentUserEntry === "object" && (currentUserEntry.used !== expectedUserStatus.used || JSON.stringify(currentUserEntry.scopes) !== JSON.stringify(expectedUserStatus.scopes))) {
56848
57229
  updatedUserApiKeys[keyName] = expectedUserStatus;
56849
57230
  userNeedsUpdate = true;
56850
57231
  }
@@ -56919,7 +57300,7 @@ var require_setup_status_service = __commonJS({
56919
57300
  };
56920
57301
  })();
56921
57302
  Object.defineProperty(exports2, "__esModule", { value: true });
56922
- exports2.SetupStatusService = exports2.LEGACY_USER_STATUS_FILENAME = exports2.PROJECT_STATUS_FILENAME = exports2.USER_STATUS_FILENAME = void 0;
57303
+ exports2.SetupStatusService = exports2.PROJECT_STATUS_FILENAME = exports2.USER_STATUS_FILENAME = void 0;
56923
57304
  exports2.createSetupStatusService = createSetupStatusService;
56924
57305
  var fs = __importStar(require("node:fs/promises"));
56925
57306
  var path = __importStar(require("node:path"));
@@ -56931,7 +57312,6 @@ var require_setup_status_service = __commonJS({
56931
57312
  var doctor_engine_js_1 = require_doctor_engine();
56932
57313
  exports2.USER_STATUS_FILENAME = "user-setup-status.json";
56933
57314
  exports2.PROJECT_STATUS_FILENAME = "setup-status.json";
56934
- exports2.LEGACY_USER_STATUS_FILENAME = exports2.PROJECT_STATUS_FILENAME;
56935
57315
  var SetupStatusService = class {
56936
57316
  projectDir;
56937
57317
  homeDir;
@@ -56945,10 +57325,6 @@ var require_setup_status_service = __commonJS({
56945
57325
  get userStatusPath() {
56946
57326
  return path.join(this.homeDir, ".sidekick", exports2.USER_STATUS_FILENAME);
56947
57327
  }
56948
- /** Legacy path for migration: old user-scope file that collided with project-scope */
56949
- get legacyUserStatusPath() {
56950
- return path.join(this.homeDir, ".sidekick", exports2.LEGACY_USER_STATUS_FILENAME);
56951
- }
56952
57328
  get projectStatusPath() {
56953
57329
  return path.join(this.projectDir, ".sidekick", exports2.PROJECT_STATUS_FILENAME);
56954
57330
  }
@@ -56982,7 +57358,7 @@ var require_setup_status_service = __commonJS({
56982
57358
  return parsed.data;
56983
57359
  } catch (err) {
56984
57360
  if (err.code === "ENOENT") {
56985
- return this.migrateFromLegacyUserStatus();
57361
+ return null;
56986
57362
  }
56987
57363
  if (err instanceof SyntaxError) {
56988
57364
  this.logger?.warn(`Corrupt ${exports2.USER_STATUS_FILENAME}, treating as missing`, {
@@ -56994,54 +57370,6 @@ var require_setup_status_service = __commonJS({
56994
57370
  throw err;
56995
57371
  }
56996
57372
  }
56997
- /**
56998
- * Migration: read user status from the legacy `setup-status.json` location,
56999
- * write it to the new `user-setup-status.json`, and remove the old file.
57000
- *
57001
- * Only migrates if the legacy file contains valid UserSetupStatus data
57002
- * (not project-format data that may have been written by the collision bug).
57003
- */
57004
- async migrateFromLegacyUserStatus() {
57005
- try {
57006
- const legacyContent = await fs.readFile(this.legacyUserStatusPath, "utf-8");
57007
- const parsed = types_1.UserSetupStatusSchema.safeParse(JSON.parse(legacyContent));
57008
- if (!parsed.success) {
57009
- this.logger?.debug("Legacy user status file exists but is not valid user format, skipping migration", {
57010
- path: this.legacyUserStatusPath
57011
- });
57012
- return null;
57013
- }
57014
- this.logger?.info("Migrating user status from legacy location", {
57015
- from: this.legacyUserStatusPath,
57016
- to: this.userStatusPath
57017
- });
57018
- await this.writeUserStatus(parsed.data);
57019
- try {
57020
- await fs.unlink(this.legacyUserStatusPath);
57021
- } catch (unlinkErr) {
57022
- if (unlinkErr.code !== "ENOENT") {
57023
- this.logger?.warn("Migrated user status but failed to remove legacy file", {
57024
- path: this.legacyUserStatusPath,
57025
- error: unlinkErr instanceof Error ? unlinkErr.message : String(unlinkErr)
57026
- });
57027
- }
57028
- }
57029
- this.logger?.info("Legacy user status migration complete");
57030
- return parsed.data;
57031
- } catch (err) {
57032
- if (err.code === "ENOENT") {
57033
- return null;
57034
- }
57035
- if (err instanceof SyntaxError) {
57036
- this.logger?.warn(`Corrupt legacy ${exports2.LEGACY_USER_STATUS_FILENAME}, treating as missing`, {
57037
- path: this.legacyUserStatusPath,
57038
- error: err.message
57039
- });
57040
- return null;
57041
- }
57042
- throw err;
57043
- }
57044
- }
57045
57373
  async getProjectStatus() {
57046
57374
  if (path.resolve(this.projectDir) === path.resolve(this.homeDir)) {
57047
57375
  this.logger?.debug("Skipping project status read: projectDir is the home directory", {
@@ -57409,61 +57737,6 @@ var require_errors6 = __commonJS({
57409
57737
  }
57410
57738
  });
57411
57739
 
57412
- // ../sidekick-core/dist/staging-paths.js
57413
- var require_staging_paths = __commonJS({
57414
- "../sidekick-core/dist/staging-paths.js"(exports2) {
57415
- "use strict";
57416
- Object.defineProperty(exports2, "__esModule", { value: true });
57417
- exports2.CONSUMED_FILE_PATTERN = void 0;
57418
- exports2.getStagingRoot = getStagingRoot;
57419
- exports2.getHookDir = getHookDir;
57420
- exports2.getReminderPath = getReminderPath;
57421
- exports2.isValidPathSegment = isValidPathSegment;
57422
- exports2.validatePathSegment = validatePathSegment;
57423
- exports2.filterActiveReminderFiles = filterActiveReminderFiles;
57424
- exports2.createConsumedFilePattern = createConsumedFilePattern;
57425
- exports2.extractConsumedTimestamp = extractConsumedTimestamp;
57426
- var node_path_1 = require("node:path");
57427
- function getStagingRoot(stateDir, sessionId) {
57428
- return (0, node_path_1.join)(stateDir, "sessions", sessionId, "stage");
57429
- }
57430
- function getHookDir(stateDir, sessionId, hookName) {
57431
- return (0, node_path_1.join)(getStagingRoot(stateDir, sessionId), hookName);
57432
- }
57433
- function getReminderPath(stateDir, sessionId, hookName, reminderName) {
57434
- return (0, node_path_1.join)(getHookDir(stateDir, sessionId, hookName), `${reminderName}.json`);
57435
- }
57436
- function isValidPathSegment(s) {
57437
- if (s === "")
57438
- return false;
57439
- if (s === "." || s === "..")
57440
- return false;
57441
- if (s.includes("/") || s.includes("\\"))
57442
- return false;
57443
- if ((0, node_path_1.basename)(s) !== s)
57444
- return false;
57445
- return /^[a-zA-Z0-9._-]+$/.test(s);
57446
- }
57447
- function validatePathSegment(segment, name) {
57448
- if (!isValidPathSegment(segment)) {
57449
- throw new Error(`Invalid ${name}: must be a non-empty alphanumeric string without path separators`);
57450
- }
57451
- }
57452
- exports2.CONSUMED_FILE_PATTERN = /\.\d+\.json$/;
57453
- function filterActiveReminderFiles(files) {
57454
- return files.filter((f) => f.endsWith(".json") && !exports2.CONSUMED_FILE_PATTERN.test(f));
57455
- }
57456
- function createConsumedFilePattern(reminderName) {
57457
- return new RegExp(`^${reminderName}\\.(\\d+)\\.json$`);
57458
- }
57459
- function extractConsumedTimestamp(filename, reminderName) {
57460
- const pattern = createConsumedFilePattern(reminderName);
57461
- const match = pattern.exec(filename);
57462
- return match ? parseInt(match[1], 10) : null;
57463
- }
57464
- }
57465
- });
57466
-
57467
57740
  // ../sidekick-core/dist/staging-service.js
57468
57741
  var require_staging_service = __commonJS({
57469
57742
  "../sidekick-core/dist/staging-service.js"(exports2) {
@@ -57477,6 +57750,7 @@ var require_staging_service = __commonJS({
57477
57750
  var structured_logging_1 = require_structured_logging();
57478
57751
  var errors_js_1 = require_errors6();
57479
57752
  var staging_paths_js_1 = require_staging_paths();
57753
+ var error_utils_js_1 = require_error_utils();
57480
57754
  var StagingServiceCore = class {
57481
57755
  options;
57482
57756
  constructor(options) {
@@ -57580,7 +57854,7 @@ var require_staging_service = __commonJS({
57580
57854
  hookName,
57581
57855
  reminderName,
57582
57856
  path: reminderPath,
57583
- error: err instanceof Error ? err.message : String(err)
57857
+ error: (0, error_utils_js_1.toErrorMessage)(err)
57584
57858
  });
57585
57859
  return null;
57586
57860
  }
@@ -57611,7 +57885,7 @@ var require_staging_service = __commonJS({
57611
57885
  }
57612
57886
  this.options.logger.warn("Skipping invalid reminder file", {
57613
57887
  path: reminderPath,
57614
- error: err instanceof Error ? err.message : String(err)
57888
+ error: (0, error_utils_js_1.toErrorMessage)(err)
57615
57889
  });
57616
57890
  }
57617
57891
  }
@@ -57672,7 +57946,7 @@ var require_staging_service = __commonJS({
57672
57946
  }
57673
57947
  this.options.logger.warn("Skipping invalid consumed reminder file", {
57674
57948
  path: reminderPath,
57675
- error: err instanceof Error ? err.message : String(err)
57949
+ error: (0, error_utils_js_1.toErrorMessage)(err)
57676
57950
  });
57677
57951
  }
57678
57952
  }
@@ -57824,6 +58098,7 @@ var require_handler_registry2 = __commonJS({
57824
58098
  exports2.HandlerRegistryImpl = void 0;
57825
58099
  var transcript_content_js_1 = require_transcript_content();
57826
58100
  var structured_logging_js_1 = require_structured_logging();
58101
+ var error_utils_js_1 = require_error_utils();
57827
58102
  var HandlerRegistryImpl = class {
57828
58103
  options;
57829
58104
  handlers = [];
@@ -57934,7 +58209,7 @@ var require_handler_registry2 = __commonJS({
57934
58209
  log.error("Handler execution failed", {
57935
58210
  handlerId: handler.id,
57936
58211
  hook,
57937
- error: err instanceof Error ? err.message : String(err)
58212
+ error: (0, error_utils_js_1.toErrorMessage)(err)
57938
58213
  });
57939
58214
  }
57940
58215
  }
@@ -57980,7 +58255,7 @@ var require_handler_registry2 = __commonJS({
57980
58255
  (0, structured_logging_js_1.logEvent)(this.options.logger, structured_logging_js_1.LogEvents.eventProcessed(logContext, { handlerId: handler.id, success: true }, { durationMs }));
57981
58256
  } catch (err) {
57982
58257
  const durationMs = Date.now() - startTime;
57983
- const errorMsg = err instanceof Error ? err.message : String(err);
58258
+ const errorMsg = (0, error_utils_js_1.toErrorMessage)(err);
57984
58259
  (0, structured_logging_js_1.logEvent)(this.options.logger, structured_logging_js_1.LogEvents.eventProcessed(logContext, { handlerId: handler.id, success: false }, { durationMs, error: errorMsg }));
57985
58260
  this.options.logger.error("Transcript handler failed", {
57986
58261
  handlerId: handler.id,
@@ -58339,6 +58614,9 @@ var require_path_resolver = __commonJS({
58339
58614
  sessionStagingDir(sessionId) {
58340
58615
  return (0, node_path_1.join)(this.sessionRootDir(sessionId), "stage");
58341
58616
  }
58617
+ sessionLogsDir(sessionId) {
58618
+ return (0, node_path_1.join)(this.sessionRootDir(sessionId), "logs");
58619
+ }
58342
58620
  hookStagingDir(sessionId, hookName) {
58343
58621
  return (0, node_path_1.join)(this.sessionStagingDir(sessionId), hookName);
58344
58622
  }
@@ -58408,6 +58686,7 @@ var require_state_service = __commonJS({
58408
58686
  var node_path_1 = require("node:path");
58409
58687
  var path_resolver_js_1 = require_path_resolver();
58410
58688
  var errors_js_1 = require_errors6();
58689
+ var error_utils_js_1 = require_error_utils();
58411
58690
  var errors_js_2 = require_errors6();
58412
58691
  Object.defineProperty(exports2, "StateNotFoundError", { enumerable: true, get: function() {
58413
58692
  return errors_js_2.StateNotFoundError;
@@ -58519,7 +58798,7 @@ var require_state_service = __commonJS({
58519
58798
  } catch (cleanupErr) {
58520
58799
  this.logger?.trace("Failed to cleanup temp file", {
58521
58800
  tmpPath,
58522
- error: cleanupErr instanceof Error ? cleanupErr.message : String(cleanupErr)
58801
+ error: (0, error_utils_js_1.toErrorMessage)(cleanupErr)
58523
58802
  });
58524
58803
  }
58525
58804
  throw err;
@@ -58645,7 +58924,7 @@ var require_state_service = __commonJS({
58645
58924
  } catch (err) {
58646
58925
  this.logger?.warn("Failed to preload state file", {
58647
58926
  file,
58648
- error: err instanceof Error ? err.message : String(err)
58927
+ error: (0, error_utils_js_1.toErrorMessage)(err)
58649
58928
  });
58650
58929
  }
58651
58930
  }
@@ -58671,7 +58950,7 @@ var require_state_service = __commonJS({
58671
58950
  this.logger?.warn("Corrupt state file detected", {
58672
58951
  path,
58673
58952
  reason,
58674
- error: error instanceof Error ? error.message : String(error)
58953
+ error: (0, error_utils_js_1.toErrorMessage)(error)
58675
58954
  });
58676
58955
  try {
58677
58956
  await fs.rename(path, bakPath);
@@ -58701,7 +58980,7 @@ var require_state_service = __commonJS({
58701
58980
  } catch (err) {
58702
58981
  this.logger?.warn("Failed to create dev mode backup", {
58703
58982
  path,
58704
- error: err instanceof Error ? err.message : String(err)
58983
+ error: (0, error_utils_js_1.toErrorMessage)(err)
58705
58984
  });
58706
58985
  }
58707
58986
  }
@@ -58764,12 +59043,17 @@ var require_typed_accessor = __commonJS({
58764
59043
  var SessionStateAccessor = class {
58765
59044
  stateService;
58766
59045
  descriptor;
58767
- constructor(stateService, descriptor) {
59046
+ journal;
59047
+ /** Descriptor filename without .json extension — used as journal file key */
59048
+ fileKey;
59049
+ constructor(stateService, descriptor, journal) {
58768
59050
  this.stateService = stateService;
58769
59051
  this.descriptor = descriptor;
59052
+ this.journal = journal;
58770
59053
  if (descriptor.scope !== "session") {
58771
59054
  throw new Error(`SessionStateAccessor requires a session-scoped descriptor, got: ${descriptor.scope}`);
58772
59055
  }
59056
+ this.fileKey = descriptor.filename.replace(/\.json$/, "");
58773
59057
  }
58774
59058
  /**
58775
59059
  * Read session state file.
@@ -58787,9 +59071,15 @@ var require_typed_accessor = __commonJS({
58787
59071
  */
58788
59072
  async write(sessionId, data) {
58789
59073
  const path = this.stateService.sessionStatePath(sessionId, this.descriptor.filename);
58790
- return this.stateService.write(path, data, this.descriptor.schema, {
59074
+ await this.stateService.write(path, data, this.descriptor.schema, {
58791
59075
  trackHistory: this.descriptor.trackHistory
58792
59076
  });
59077
+ if (this.journal) {
59078
+ try {
59079
+ await this.journal.appendIfChanged(sessionId, this.fileKey, data);
59080
+ } catch {
59081
+ }
59082
+ }
58793
59083
  }
58794
59084
  /**
58795
59085
  * Delete session state file.
@@ -58797,6 +59087,12 @@ var require_typed_accessor = __commonJS({
58797
59087
  async delete(sessionId) {
58798
59088
  const path = this.stateService.sessionStatePath(sessionId, this.descriptor.filename);
58799
59089
  await this.stateService.delete(path);
59090
+ if (this.journal) {
59091
+ try {
59092
+ await this.journal.appendDeletion(sessionId, this.fileKey);
59093
+ } catch {
59094
+ }
59095
+ }
58800
59096
  }
58801
59097
  /**
58802
59098
  * Get the path for a session state file.
@@ -59062,8 +59358,51 @@ var require_transcript_normalizer = __commonJS({
59062
59358
  exports2.parseUuid = parseUuid;
59063
59359
  exports2.renderTranscriptString = renderTranscriptString;
59064
59360
  var index_js_1 = require_state3();
59361
+ function buildRecapEntry(params) {
59362
+ const text = typeof params.rawText === "string" ? params.rawText.trim() : "";
59363
+ if (!text)
59364
+ return null;
59365
+ return {
59366
+ id: params.uuid ?? `line-${params.lineNumber}`,
59367
+ timestamp: new Date(params.timestamp ?? Date.now()),
59368
+ role: "system",
59369
+ type: "recap",
59370
+ content: text,
59371
+ metadata: {
59372
+ provider: "claude",
59373
+ lineNumber: params.lineNumber,
59374
+ recapSource: params.recapSource,
59375
+ leafUuid: params.leafUuid
59376
+ }
59377
+ };
59378
+ }
59065
59379
  function normalizeEntry(rawEntry, lineNumber) {
59066
59380
  const entryType = rawEntry.type;
59381
+ if (entryType === "summary") {
59382
+ const raw = rawEntry;
59383
+ const recap = buildRecapEntry({
59384
+ rawText: raw.summary,
59385
+ uuid: raw.uuid,
59386
+ timestamp: raw.timestamp,
59387
+ lineNumber,
59388
+ recapSource: "compaction",
59389
+ leafUuid: typeof raw.leafUuid === "string" ? raw.leafUuid : void 0
59390
+ });
59391
+ return recap ? [recap] : null;
59392
+ }
59393
+ if (entryType === "system") {
59394
+ const raw = rawEntry;
59395
+ if (raw.subtype !== "away_summary")
59396
+ return null;
59397
+ const recap = buildRecapEntry({
59398
+ rawText: raw.content,
59399
+ uuid: raw.uuid,
59400
+ timestamp: raw.timestamp,
59401
+ lineNumber,
59402
+ recapSource: "away"
59403
+ });
59404
+ return recap ? [recap] : null;
59405
+ }
59067
59406
  if (entryType !== "user" && entryType !== "assistant") {
59068
59407
  return null;
59069
59408
  }
@@ -59197,6 +59536,9 @@ var require_transcript_normalizer = __commonJS({
59197
59536
  return `[${timestamp}] ${role} TOOL_USE: ${String(toolContent.name)}`;
59198
59537
  } else if (type === "tool_result") {
59199
59538
  return `[${timestamp}] ${role} TOOL_RESULT`;
59539
+ } else if (type === "recap") {
59540
+ const content = typeof entry.content === "string" ? entry.content : "";
59541
+ return `[${timestamp}] RECAP: ${content}`;
59200
59542
  }
59201
59543
  return `[${timestamp}] ${role}: ${JSON.stringify(entry.content)}`;
59202
59544
  }).join("\n");
@@ -59215,6 +59557,7 @@ var require_transcript_excerpt_builder = __commonJS({
59215
59557
  exports2.extractTextContent = extractTextContent;
59216
59558
  exports2.getRawContentString = getRawContentString;
59217
59559
  var transcript_helpers_js_1 = require_transcript_helpers();
59560
+ var error_utils_js_1 = require_error_utils();
59218
59561
  function getBufferedEntries(buffer, head, count, bufferSize) {
59219
59562
  if (count === 0)
59220
59563
  return [];
@@ -59269,7 +59612,7 @@ var require_transcript_excerpt_builder = __commonJS({
59269
59612
  };
59270
59613
  } catch (err) {
59271
59614
  logger.error("Failed to extract transcript excerpt from buffer", {
59272
- error: err instanceof Error ? err.message : String(err)
59615
+ error: (0, error_utils_js_1.toErrorMessage)(err)
59273
59616
  });
59274
59617
  return {
59275
59618
  content: "",
@@ -59330,6 +59673,14 @@ var require_transcript_excerpt_builder = __commonJS({
59330
59673
  return null;
59331
59674
  }
59332
59675
  return `[SESSION_HINT]: ${entry.summary ?? ""}`;
59676
+ case "system": {
59677
+ if (entry.subtype !== "away_summary")
59678
+ return null;
59679
+ const content = entry.content;
59680
+ if (typeof content !== "string" || !content.trim())
59681
+ return null;
59682
+ return `[SESSION_RECAP]: ${content}`;
59683
+ }
59333
59684
  default:
59334
59685
  return null;
59335
59686
  }
@@ -62188,6 +62539,7 @@ var require_instrumented_llm_provider = __commonJS({
62188
62539
  var node_path_1 = require("node:path");
62189
62540
  var yaml_1 = __importDefault(require_dist2());
62190
62541
  var types_1 = require_dist();
62542
+ var error_utils_js_1 = require_error_utils();
62191
62543
  var STATE_FILE = "llm-metrics.json";
62192
62544
  var DEFAULT_DEBOUNCE_MS = 500;
62193
62545
  function hasFallbackTracking(provider) {
@@ -62238,7 +62590,7 @@ var require_instrumented_llm_provider = __commonJS({
62238
62590
  }
62239
62591
  } catch (err) {
62240
62592
  this.config.logger.warn("Failed to load LLM metrics, starting fresh", {
62241
- error: err instanceof Error ? err.message : String(err)
62593
+ error: (0, error_utils_js_1.toErrorMessage)(err)
62242
62594
  });
62243
62595
  }
62244
62596
  }
@@ -62325,7 +62677,7 @@ var require_instrumented_llm_provider = __commonJS({
62325
62677
  this.config.logger.debug("Debug dump written", { path: basePath });
62326
62678
  } catch (dumpError) {
62327
62679
  this.config.logger.warn("Failed to write debug dump", {
62328
- error: dumpError instanceof Error ? dumpError.message : String(dumpError)
62680
+ error: (0, error_utils_js_1.toErrorMessage)(dumpError)
62329
62681
  });
62330
62682
  }
62331
62683
  }
@@ -62550,7 +62902,7 @@ var require_instrumented_llm_provider = __commonJS({
62550
62902
  });
62551
62903
  } catch (err) {
62552
62904
  this.config.logger.warn("Failed to persist LLM metrics", {
62553
- error: err instanceof Error ? err.message : String(err)
62905
+ error: (0, error_utils_js_1.toErrorMessage)(err)
62554
62906
  });
62555
62907
  }
62556
62908
  }
@@ -62826,6 +63178,7 @@ var require_daemon_health = __commonJS({
62826
63178
  var fs = __importStar(require("node:fs/promises"));
62827
63179
  var node_path_1 = require("node:path");
62828
63180
  var types_1 = require_dist();
63181
+ var error_utils_js_1 = require_error_utils();
62829
63182
  function healthFilePath(projectDir2) {
62830
63183
  return (0, node_path_1.join)(projectDir2, ".sidekick", "state", "daemon-health.json");
62831
63184
  }
@@ -62884,7 +63237,7 @@ var require_daemon_health = __commonJS({
62884
63237
  logger.warn("Failed to write daemon health", {
62885
63238
  from,
62886
63239
  to,
62887
- error: err instanceof Error ? err.message : String(err)
63240
+ error: (0, error_utils_js_1.toErrorMessage)(err)
62888
63241
  });
62889
63242
  return false;
62890
63243
  }
@@ -62971,6 +63324,7 @@ var require_user_profile_loader = __commonJS({
62971
63324
  var node_path_1 = require("node:path");
62972
63325
  var yaml_1 = require_dist2();
62973
63326
  var types_1 = require_dist();
63327
+ var error_utils_js_1 = require_error_utils();
62974
63328
  function loadUserProfile(options) {
62975
63329
  const home = options?.homeDir ?? (0, node_os_1.homedir)();
62976
63330
  const filePath = (0, node_path_1.join)(home, ".sidekick", "user.yaml");
@@ -62992,7 +63346,7 @@ var require_user_profile_loader = __commonJS({
62992
63346
  } catch (err) {
62993
63347
  options?.logger?.warn("Failed to read user profile", {
62994
63348
  path: filePath,
62995
- error: err instanceof Error ? err.message : String(err)
63349
+ error: (0, error_utils_js_1.toErrorMessage)(err)
62996
63350
  });
62997
63351
  return null;
62998
63352
  }
@@ -63059,9 +63413,9 @@ var require_dist4 = __commonJS({
63059
63413
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p);
63060
63414
  };
63061
63415
  Object.defineProperty(exports2, "__esModule", { value: true });
63062
- exports2.readKeyFromEnvFile = exports2.determineOverallStatus = exports2.toScopeStatus = exports2.LEGACY_USER_STATUS_FILENAME = exports2.PROJECT_STATUS_FILENAME = exports2.USER_STATUS_FILENAME = exports2.createSetupStatusService = exports2.SetupStatusService = exports2.DaemonClient = exports2.findZombieDaemons = exports2.killZombieDaemons = exports2.killAllDaemons = exports2.logEvent = exports2.LogEvents = exports2.DEFAULT_MAX_FILES = exports2.DEFAULT_ROTATE_SIZE_BYTES = exports2.getComponentLogLevel = exports2.setupGlobalErrorHandlers = exports2.createLoggerFacade = exports2.createLogManager = exports2.createConsoleLogger = exports2.getUserDaemonsDir = exports2.getUserPidPath = exports2.getTokenPath = exports2.getSocketPath = exports2.getProjectHash = exports2.getPidPath = exports2.getLockPath = exports2.IpcService = exports2.IpcServer = exports2.loadPersonaFile = exports2.getDefaultPersonasDir = exports2.discoverPersonas = exports2.createPersonaLoader = exports2.reconstructTranscriptPath = exports2.encodeProjectPath = exports2.isPreCompactEvent = exports2.isStopEvent = exports2.isPostToolUseEvent = exports2.isPreToolUseEvent = exports2.isUserPromptSubmitEvent = exports2.isSessionEndEvent = exports2.isSessionStartEvent = exports2.isTranscriptEvent = exports2.isHookEvent = exports2.MetricsPersistPayloadSchema = exports2.CleanupPayloadSchema = exports2.ResumeGenerationPayloadSchema = exports2.SessionSummaryPayloadSchema = exports2.TaskTypes = void 0;
63063
- exports2.StateService = exports2.createHookableLogger = exports2.InstrumentedProfileProviderFactory = exports2.InstrumentedLLMProvider = exports2.ServiceFactoryImpl = exports2.TranscriptServiceImpl = exports2.createDefaultTokenUsage = exports2.createDefaultMetrics = exports2.copyWithTimestampSync = exports2.renameWithTimestampSync = exports2.renameWithTimestamp = exports2.copyWithTimestamp = exports2.getTimestampedPath = exports2.extractToolResultPreview = exports2.extractToolCallPreview = exports2.extractTextFromContent = exports2.extractContentPreview = exports2.HandlerRegistryImpl = exports2.extractConsumedTimestamp = exports2.createConsumedFilePattern = exports2.CONSUMED_FILE_PATTERN = exports2.filterActiveReminderFiles = exports2.validatePathSegment = exports2.isValidPathSegment = exports2.getReminderPath = exports2.getHookDir = exports2.getStagingRoot = exports2.SessionScopedStagingService = exports2.StagingServiceCore = exports2.GITIGNORE_ENTRIES = exports2.SIDEKICK_SECTION_END = exports2.SIDEKICK_SECTION_START = exports2.detectGitignoreStatus = exports2.removeGitignoreSection = exports2.installGitignoreSection = exports2.validateOpenAIKey = exports2.validateOpenRouterKey = exports2.runDoctorCheck = exports2.detectPluginLiveness = exports2.detectPluginInstallation = exports2.detectActualStatusline = exports2.spawnWithTimeout = exports2.getDoctorTimeout = exports2.DOCTOR_TIMEOUTS = exports2.projectApiKeyStatusFromHealth = exports2.userApiKeyStatusFromHealth = exports2.buildProjectApiKeyStatus = exports2.buildUserApiKeyStatus = exports2.detectAllApiKeys = exports2.detectActualApiKey = void 0;
63064
- exports2.CoalescingGuard = exports2.loadUserProfile = exports2.parseGitStatusOutput = exports2.getGitFileStatus = exports2.isInSandbox = exports2.updateDaemonHealth = exports2.readDaemonHealth = exports2.ProjectRegistryService = exports2.encodeProjectDir = exports2.DaemonGlobalLogMetricsDescriptor = exports2.CliLogMetricsDescriptor = exports2.DaemonLogMetricsDescriptor = exports2.CompactionHistoryDescriptor = exports2.TranscriptMetricsDescriptor = exports2.GlobalStateAccessor = exports2.SessionStateAccessor = exports2.globalState = exports2.sessionState = exports2.StateCorruptError = exports2.StateNotFoundError = void 0;
63416
+ exports2.PROJECT_STATUS_FILENAME = exports2.USER_STATUS_FILENAME = exports2.createSetupStatusService = exports2.SetupStatusService = exports2.DaemonClient = exports2.findZombieDaemons = exports2.killZombieDaemons = exports2.killAllDaemons = exports2.SessionLogWriter = exports2.setSessionLogWriter = exports2.logEvent = exports2.LogEvents = exports2.DEFAULT_MAX_FILES = exports2.DEFAULT_ROTATE_SIZE_BYTES = exports2.getComponentLogLevel = exports2.setupGlobalErrorHandlers = exports2.createLoggerFacade = exports2.createLogManager = exports2.createConsoleLogger = exports2.getUserDaemonsDir = exports2.getUserPidPath = exports2.getTokenPath = exports2.getSocketPath = exports2.getProjectHash = exports2.getPidPath = exports2.getLockPath = exports2.IpcService = exports2.IpcServer = exports2.loadPersonaFile = exports2.getDefaultPersonasDir = exports2.discoverPersonas = exports2.createPersonaLoader = exports2.reconstructTranscriptPath = exports2.encodeProjectPath = exports2.isSubagentStopEvent = exports2.isSubagentStartEvent = exports2.isPreCompactEvent = exports2.isStopEvent = exports2.isPostToolUseEvent = exports2.isPreToolUseEvent = exports2.isUserPromptSubmitEvent = exports2.isSessionEndEvent = exports2.isSessionStartEvent = exports2.isTranscriptEvent = exports2.isHookEvent = exports2.MetricsPersistPayloadSchema = exports2.CleanupPayloadSchema = exports2.ResumeGenerationPayloadSchema = exports2.SessionSummaryPayloadSchema = exports2.TaskTypes = void 0;
63417
+ exports2.createDefaultTokenUsage = exports2.createDefaultMetrics = exports2.copyWithTimestampSync = exports2.renameWithTimestampSync = exports2.renameWithTimestamp = exports2.copyWithTimestamp = exports2.getTimestampedPath = exports2.extractToolResultPreview = exports2.extractToolCallPreview = exports2.extractTextFromContent = exports2.extractContentPreview = exports2.HandlerRegistryImpl = exports2.extractConsumedTimestamp = exports2.createConsumedFilePattern = exports2.CONSUMED_FILE_PATTERN = exports2.filterActiveReminderFiles = exports2.validatePathSegment = exports2.isValidPathSegment = exports2.getReminderPath = exports2.getHookDir = exports2.getStagingRoot = exports2.SessionScopedStagingService = exports2.StagingServiceCore = exports2.GITIGNORE_ENTRIES = exports2.SIDEKICK_GITIGNORE_HEADER = exports2.SIDEKICK_SECTION_END = exports2.SIDEKICK_SECTION_START = exports2.removeLegacyGitignoreSection = exports2.detectLegacyGitignoreSection = exports2.detectGitignoreStatus = exports2.removeGitignoreSection = exports2.installGitignoreSection = exports2.validateOpenAIKey = exports2.validateOpenRouterKey = exports2.runDoctorCheck = exports2.detectPluginLiveness = exports2.detectPluginInstallation = exports2.detectActualStatusline = exports2.spawnWithTimeout = exports2.getDoctorTimeout = exports2.DOCTOR_TIMEOUTS = exports2.projectApiKeyStatusFromHealth = exports2.userApiKeyStatusFromHealth = exports2.buildProjectApiKeyStatus = exports2.buildUserApiKeyStatus = exports2.detectAllApiKeys = exports2.detectActualApiKey = exports2.readKeyFromEnvFile = exports2.determineOverallStatus = exports2.toScopeStatus = void 0;
63418
+ exports2.CoalescingGuard = exports2.loadUserProfile = exports2.parseGitStatusOutput = exports2.getGitFileStatus = exports2.toErrorMessage = exports2.isInSandbox = exports2.updateDaemonHealth = exports2.readDaemonHealth = exports2.ProjectRegistryService = exports2.encodeProjectDir = exports2.DaemonGlobalLogMetricsDescriptor = exports2.CliLogMetricsDescriptor = exports2.DaemonLogMetricsDescriptor = exports2.CompactionHistoryDescriptor = exports2.TranscriptMetricsDescriptor = exports2.GlobalStateAccessor = exports2.SessionStateAccessor = exports2.globalState = exports2.sessionState = exports2.StateCorruptError = exports2.StateNotFoundError = exports2.StateService = exports2.createHookableLogger = exports2.InstrumentedProfileProviderFactory = exports2.InstrumentedLLMProvider = exports2.ServiceFactoryImpl = exports2.TranscriptServiceImpl = void 0;
63065
63419
  var types_1 = require_dist();
63066
63420
  Object.defineProperty(exports2, "TaskTypes", { enumerable: true, get: function() {
63067
63421
  return types_1.TaskTypes;
@@ -63106,6 +63460,12 @@ var require_dist4 = __commonJS({
63106
63460
  Object.defineProperty(exports2, "isPreCompactEvent", { enumerable: true, get: function() {
63107
63461
  return types_2.isPreCompactEvent;
63108
63462
  } });
63463
+ Object.defineProperty(exports2, "isSubagentStartEvent", { enumerable: true, get: function() {
63464
+ return types_2.isSubagentStartEvent;
63465
+ } });
63466
+ Object.defineProperty(exports2, "isSubagentStopEvent", { enumerable: true, get: function() {
63467
+ return types_2.isSubagentStopEvent;
63468
+ } });
63109
63469
  __exportStar(require_assets(), exports2);
63110
63470
  var claude_paths_1 = require_claude_paths();
63111
63471
  Object.defineProperty(exports2, "encodeProjectPath", { enumerable: true, get: function() {
@@ -63194,6 +63554,12 @@ var require_dist4 = __commonJS({
63194
63554
  Object.defineProperty(exports2, "logEvent", { enumerable: true, get: function() {
63195
63555
  return structured_logging_1.logEvent;
63196
63556
  } });
63557
+ Object.defineProperty(exports2, "setSessionLogWriter", { enumerable: true, get: function() {
63558
+ return structured_logging_1.setSessionLogWriter;
63559
+ } });
63560
+ Object.defineProperty(exports2, "SessionLogWriter", { enumerable: true, get: function() {
63561
+ return structured_logging_1.SessionLogWriter;
63562
+ } });
63197
63563
  var daemon_client_1 = require_daemon_client2();
63198
63564
  Object.defineProperty(exports2, "killAllDaemons", { enumerable: true, get: function() {
63199
63565
  return daemon_client_1.killAllDaemons;
@@ -63220,9 +63586,6 @@ var require_dist4 = __commonJS({
63220
63586
  Object.defineProperty(exports2, "PROJECT_STATUS_FILENAME", { enumerable: true, get: function() {
63221
63587
  return setup_status_service_1.PROJECT_STATUS_FILENAME;
63222
63588
  } });
63223
- Object.defineProperty(exports2, "LEGACY_USER_STATUS_FILENAME", { enumerable: true, get: function() {
63224
- return setup_status_service_1.LEGACY_USER_STATUS_FILENAME;
63225
- } });
63226
63589
  var api_key_detector_1 = require_api_key_detector();
63227
63590
  Object.defineProperty(exports2, "toScopeStatus", { enumerable: true, get: function() {
63228
63591
  return api_key_detector_1.toScopeStatus;
@@ -63291,12 +63654,21 @@ var require_dist4 = __commonJS({
63291
63654
  Object.defineProperty(exports2, "detectGitignoreStatus", { enumerable: true, get: function() {
63292
63655
  return gitignore_1.detectGitignoreStatus;
63293
63656
  } });
63657
+ Object.defineProperty(exports2, "detectLegacyGitignoreSection", { enumerable: true, get: function() {
63658
+ return gitignore_1.detectLegacyGitignoreSection;
63659
+ } });
63660
+ Object.defineProperty(exports2, "removeLegacyGitignoreSection", { enumerable: true, get: function() {
63661
+ return gitignore_1.removeLegacyGitignoreSection;
63662
+ } });
63294
63663
  Object.defineProperty(exports2, "SIDEKICK_SECTION_START", { enumerable: true, get: function() {
63295
63664
  return gitignore_1.SIDEKICK_SECTION_START;
63296
63665
  } });
63297
63666
  Object.defineProperty(exports2, "SIDEKICK_SECTION_END", { enumerable: true, get: function() {
63298
63667
  return gitignore_1.SIDEKICK_SECTION_END;
63299
63668
  } });
63669
+ Object.defineProperty(exports2, "SIDEKICK_GITIGNORE_HEADER", { enumerable: true, get: function() {
63670
+ return gitignore_1.SIDEKICK_GITIGNORE_HEADER;
63671
+ } });
63300
63672
  Object.defineProperty(exports2, "GITIGNORE_ENTRIES", { enumerable: true, get: function() {
63301
63673
  return gitignore_1.GITIGNORE_ENTRIES;
63302
63674
  } });
@@ -63449,6 +63821,10 @@ var require_dist4 = __commonJS({
63449
63821
  Object.defineProperty(exports2, "isInSandbox", { enumerable: true, get: function() {
63450
63822
  return sandbox_1.isInSandbox;
63451
63823
  } });
63824
+ var error_utils_1 = require_error_utils();
63825
+ Object.defineProperty(exports2, "toErrorMessage", { enumerable: true, get: function() {
63826
+ return error_utils_1.toErrorMessage;
63827
+ } });
63452
63828
  var git_status_1 = require_git_status();
63453
63829
  Object.defineProperty(exports2, "getGitFileStatus", { enumerable: true, get: function() {
63454
63830
  return git_status_1.getGitFileStatus;
@@ -70484,6 +70860,7 @@ var require_reminder_utils = __commonJS({
70484
70860
  var node_path_1 = require("node:path");
70485
70861
  var yaml = __importStar(require_js_yaml());
70486
70862
  var zod_1 = require_zod2();
70863
+ var core_1 = require_dist4();
70487
70864
  var ReminderDefinitionSchema = zod_1.z.object({
70488
70865
  id: zod_1.z.string(),
70489
70866
  blocking: zod_1.z.boolean(),
@@ -70536,7 +70913,7 @@ var require_reminder_utils = __commonJS({
70536
70913
  if (logger) {
70537
70914
  logger.error("Failed to load reminder", {
70538
70915
  reminderId,
70539
- error: err instanceof Error ? err.message : String(err)
70916
+ error: (0, core_1.toErrorMessage)(err)
70540
70917
  });
70541
70918
  } else {
70542
70919
  console.error(`Failed to load reminder ${reminderId}:`, err);
@@ -71276,7 +71653,7 @@ var require_stage_pause_and_reflect = __commonJS({
71276
71653
  (0, staging_handler_utils_js_1.createStagingHandler)(context, {
71277
71654
  id: "reminders:stage-pause-and-reflect",
71278
71655
  priority: 80,
71279
- filter: { kind: "transcript", eventTypes: ["ToolCall"] },
71656
+ filter: { kind: "transcript", eventTypes: ["ToolResult"] },
71280
71657
  execute: async (event, ctx) => {
71281
71658
  if (!(0, types_1.isTranscriptEvent)(event))
71282
71659
  return void 0;
@@ -72959,17 +73336,15 @@ var require_track_verification_tools = __commonJS({
72959
73336
  var state_js_1 = require_state4();
72960
73337
  var FILE_EDIT_TOOLS = ["Write", "Edit", "MultiEdit"];
72961
73338
  var VC_TOOL_NAME_SET = new Set(types_js_1.VC_TOOL_REMINDER_IDS);
72962
- function extractToolInput(event) {
72963
- const entry = event.payload.entry;
72964
- return entry?.input;
72965
- }
73339
+ var MAX_PENDING_TOOL_CALLS = 100;
72966
73340
  function registerTrackVerificationTools(context) {
72967
73341
  if (!(0, types_1.isDaemonContext)(context))
72968
73342
  return;
73343
+ const pendingBySession = /* @__PURE__ */ new Map();
72969
73344
  context.handlers.register({
72970
73345
  id: "reminders:track-verification-tools",
72971
73346
  priority: 60,
72972
- filter: { kind: "transcript", eventTypes: ["ToolCall"] },
73347
+ filter: { kind: "transcript", eventTypes: ["ToolCall", "ToolResult"] },
72973
73348
  handler: async (event, ctx) => {
72974
73349
  if (!(0, types_1.isTranscriptEvent)(event))
72975
73350
  return;
@@ -72981,22 +73356,66 @@ var require_track_verification_tools = __commonJS({
72981
73356
  const sessionId = event.context?.sessionId;
72982
73357
  if (!sessionId)
72983
73358
  return;
72984
- const toolName = event.payload.toolName;
72985
- if (!toolName)
73359
+ if (event.eventType === "ToolCall") {
73360
+ const toolUseId = event.payload.entry.id;
73361
+ const toolName = event.payload.toolName;
73362
+ if (!toolUseId || !toolName)
73363
+ return;
73364
+ const entry = event.payload.entry;
73365
+ const input = entry?.input ?? {};
73366
+ let sessionMap = pendingBySession.get(sessionId);
73367
+ if (!sessionMap) {
73368
+ sessionMap = /* @__PURE__ */ new Map();
73369
+ pendingBySession.set(sessionId, sessionMap);
73370
+ }
73371
+ if (sessionMap.size >= MAX_PENDING_TOOL_CALLS) {
73372
+ const oldest = sessionMap.keys().next().value;
73373
+ if (oldest)
73374
+ sessionMap.delete(oldest);
73375
+ }
73376
+ sessionMap.set(toolUseId, { toolName, input });
72986
73377
  return;
72987
- const config = (0, types_js_1.getRemindersConfig)(context.config);
72988
- const verificationTools = config.verification_tools ?? {};
72989
- const runners = config.command_runners ?? [];
72990
- const remindersState = (0, state_js_1.createRemindersState)(daemonCtx.stateService);
72991
- const stateResult = await remindersState.verificationTools.read(sessionId);
72992
- const toolsState = { ...stateResult.data };
72993
- if (FILE_EDIT_TOOLS.includes(toolName)) {
72994
- await handleFileEdit(event, daemonCtx, sessionId, verificationTools, toolsState, remindersState);
72995
- } else if (toolName === "Bash") {
72996
- await handleBashCommand(event, daemonCtx, sessionId, verificationTools, toolsState, remindersState, runners);
73378
+ }
73379
+ if (event.eventType === "ToolResult") {
73380
+ const toolUseId = event.payload.entry.tool_use_id;
73381
+ if (!toolUseId)
73382
+ return;
73383
+ const sessionMap = pendingBySession.get(sessionId);
73384
+ const pending = sessionMap?.get(toolUseId);
73385
+ if (!pending)
73386
+ return;
73387
+ sessionMap.delete(toolUseId);
73388
+ if (sessionMap.size === 0)
73389
+ pendingBySession.delete(sessionId);
73390
+ const { toolName, input } = pending;
73391
+ const config = (0, types_js_1.getRemindersConfig)(context.config);
73392
+ const verificationTools = config.verification_tools ?? {};
73393
+ const runners = config.command_runners ?? [];
73394
+ const remindersState = (0, state_js_1.createRemindersState)(daemonCtx.stateService);
73395
+ const stateResult = await remindersState.verificationTools.read(sessionId);
73396
+ const toolsState = { ...stateResult.data };
73397
+ if (FILE_EDIT_TOOLS.includes(toolName)) {
73398
+ await handleFileEdit(input, daemonCtx, sessionId, verificationTools, toolsState, remindersState);
73399
+ } else if (toolName === "Bash") {
73400
+ await handleBashCommand(input, daemonCtx, sessionId, verificationTools, toolsState, remindersState, runners);
73401
+ }
72997
73402
  }
72998
73403
  }
72999
73404
  });
73405
+ context.handlers.register({
73406
+ id: "reminders:track-verification-tools-cleanup",
73407
+ priority: 60,
73408
+ filter: { kind: "hook", hooks: ["UserPromptSubmit", "Stop"] },
73409
+ // eslint-disable-next-line @typescript-eslint/require-await -- sync cleanup, async required by EventHandler type
73410
+ handler: async (event, _ctx) => {
73411
+ if (!(0, types_1.isHookEvent)(event))
73412
+ return;
73413
+ const sessionId = event.context?.sessionId;
73414
+ if (!sessionId)
73415
+ return;
73416
+ pendingBySession.delete(sessionId);
73417
+ }
73418
+ });
73000
73419
  }
73001
73420
  async function stageToolsForFiles(filePaths, daemonCtx, sessionId, verificationTools, toolsState, remindersState, triggeredBy = "file_edit") {
73002
73421
  const existingReminders = await daemonCtx.staging.listReminders("Stop");
@@ -73101,7 +73520,7 @@ var require_track_verification_tools = __commonJS({
73101
73520
  toolName,
73102
73521
  reminderId,
73103
73522
  sessionId,
73104
- error: error instanceof Error ? error.message : String(error)
73523
+ error: (0, core_1.toErrorMessage)(error)
73105
73524
  });
73106
73525
  }
73107
73526
  }
@@ -73115,8 +73534,8 @@ var require_track_verification_tools = __commonJS({
73115
73534
  await remindersState.verificationTools.write(sessionId, toolsState);
73116
73535
  return anyStaged;
73117
73536
  }
73118
- async function handleFileEdit(event, daemonCtx, sessionId, verificationTools, toolsState, remindersState) {
73119
- const filePath = extractToolInput(event)?.file_path;
73537
+ async function handleFileEdit(input, daemonCtx, sessionId, verificationTools, toolsState, remindersState) {
73538
+ const filePath = input.file_path;
73120
73539
  if (!filePath)
73121
73540
  return;
73122
73541
  const projectDir2 = daemonCtx.paths?.projectDir;
@@ -73124,8 +73543,8 @@ var require_track_verification_tools = __commonJS({
73124
73543
  return;
73125
73544
  await stageToolsForFiles([filePath], daemonCtx, sessionId, verificationTools, toolsState, remindersState);
73126
73545
  }
73127
- async function handleBashCommand(event, daemonCtx, sessionId, verificationTools, toolsState, remindersState, runners = []) {
73128
- const command = extractToolInput(event)?.command;
73546
+ async function handleBashCommand(input, daemonCtx, sessionId, verificationTools, toolsState, remindersState, runners = []) {
73547
+ const command = input.command;
73129
73548
  if (!command)
73130
73549
  return;
73131
73550
  let anyUnstaged = false;
@@ -73554,7 +73973,7 @@ var require_stage_persona_reminders = __commonJS({
73554
73973
  } catch (err) {
73555
73974
  logger.error("Failed to restage persona reminders", {
73556
73975
  sessionId,
73557
- error: err instanceof Error ? err.message : String(err)
73976
+ error: (0, core_1.toErrorMessage)(err)
73558
73977
  });
73559
73978
  }
73560
73979
  }
@@ -73790,6 +74209,38 @@ var require_stage_user_profile_reminders = __commonJS({
73790
74209
  }
73791
74210
  });
73792
74211
 
74212
+ // ../feature-reminders/dist/handlers/staging/cleanup-on-stop.js
74213
+ var require_cleanup_on_stop = __commonJS({
74214
+ "../feature-reminders/dist/handlers/staging/cleanup-on-stop.js"(exports2) {
74215
+ "use strict";
74216
+ Object.defineProperty(exports2, "__esModule", { value: true });
74217
+ exports2.registerCleanupOnStop = registerCleanupOnStop;
74218
+ var types_1 = require_dist();
74219
+ function registerCleanupOnStop(context) {
74220
+ if (!(0, types_1.isDaemonContext)(context))
74221
+ return;
74222
+ context.handlers.register({
74223
+ id: "reminders:cleanup-on-stop",
74224
+ priority: 50,
74225
+ filter: { kind: "hook", hooks: ["Stop"] },
74226
+ handler: async (event, ctx) => {
74227
+ if (!(0, types_1.isHookEvent)(event))
74228
+ return;
74229
+ if (!(0, types_1.isDaemonContext)(ctx))
74230
+ return;
74231
+ const daemonCtx = ctx;
74232
+ const sessionId = event.context?.sessionId;
74233
+ if (!sessionId)
74234
+ return;
74235
+ if (daemonCtx.orchestrator) {
74236
+ await daemonCtx.orchestrator.onStop(sessionId);
74237
+ }
74238
+ }
74239
+ });
74240
+ }
74241
+ }
74242
+ });
74243
+
73793
74244
  // ../feature-reminders/dist/handlers/staging/index.js
73794
74245
  var require_staging2 = __commonJS({
73795
74246
  "../feature-reminders/dist/handlers/staging/index.js"(exports2) {
@@ -73803,6 +74254,7 @@ var require_staging2 = __commonJS({
73803
74254
  var unstage_verify_completion_1 = require_unstage_verify_completion();
73804
74255
  var stage_persona_reminders_1 = require_stage_persona_reminders();
73805
74256
  var stage_user_profile_reminders_1 = require_stage_user_profile_reminders();
74257
+ var cleanup_on_stop_1 = require_cleanup_on_stop();
73806
74258
  function registerStagingHandlers(context) {
73807
74259
  (0, stage_default_user_prompt_1.registerStageDefaultUserPrompt)(context);
73808
74260
  (0, stage_pause_and_reflect_1.registerStagePauseAndReflect)(context);
@@ -73811,6 +74263,7 @@ var require_staging2 = __commonJS({
73811
74263
  (0, unstage_verify_completion_1.registerUnstageVerifyCompletion)(context);
73812
74264
  (0, stage_persona_reminders_1.registerStagePersonaReminders)(context);
73813
74265
  (0, stage_user_profile_reminders_1.registerStageUserProfileReminders)(context);
74266
+ (0, cleanup_on_stop_1.registerCleanupOnStop)(context);
73814
74267
  }
73815
74268
  }
73816
74269
  });
@@ -74531,7 +74984,7 @@ var require_orchestrator = __commonJS({
74531
74984
  } catch (err) {
74532
74985
  this.deps.logger.warn("Failed to unstage VC reminders after P&R staged", {
74533
74986
  sessionId,
74534
- error: err instanceof Error ? err.message : String(err)
74987
+ error: (0, core_1.toErrorMessage)(err)
74535
74988
  });
74536
74989
  }
74537
74990
  }
@@ -74555,27 +75008,10 @@ var require_orchestrator = __commonJS({
74555
75008
  } catch (err) {
74556
75009
  this.deps.logger.warn("Failed to reset P&R baseline after VC consumed", {
74557
75010
  sessionId,
74558
- error: err instanceof Error ? err.message : String(err)
74559
- });
74560
- }
74561
- try {
74562
- const staging = this.deps.getStagingService(sessionId);
74563
- const deleted = await staging.deleteReminder("PreToolUse", types_js_1.ReminderIds.PAUSE_AND_REFLECT);
74564
- if (deleted) {
74565
- (0, core_1.logEvent)(this.deps.logger.child({ context: { sessionId } }), events_js_1.ReminderEvents.reminderUnstaged({ sessionId }, {
74566
- reminderName: types_js_1.ReminderIds.PAUSE_AND_REFLECT,
74567
- hookName: "PreToolUse",
74568
- reason: "vc_consumed_cascade",
74569
- triggeredBy: "cascade_from_verify_completion"
74570
- }));
74571
- }
74572
- this.deps.logger.debug("VC unstage: P&R cascade from VC consumed", { sessionId, deleted });
74573
- } catch (err) {
74574
- this.deps.logger.warn("Failed to unstage P&R after VC consumed", {
74575
- sessionId,
74576
- error: err instanceof Error ? err.message : String(err)
75011
+ error: (0, core_1.toErrorMessage)(err)
74577
75012
  });
74578
75013
  }
75014
+ await this.unstagePauseAndReflect(sessionId, "vc_consumed_cascade", "cascade_from_verify_completion");
74579
75015
  }
74580
75016
  }
74581
75017
  /**
@@ -74592,7 +75028,43 @@ var require_orchestrator = __commonJS({
74592
75028
  } catch (err) {
74593
75029
  this.deps.logger.warn("Failed to clear P&R baseline on UserPromptSubmit", {
74594
75030
  sessionId,
74595
- error: err instanceof Error ? err.message : String(err)
75031
+ error: (0, core_1.toErrorMessage)(err)
75032
+ });
75033
+ }
75034
+ }
75035
+ /**
75036
+ * Called when Stop hook fires.
75037
+ *
75038
+ * P&R is designed to interrupt runaway execution — once the agent stops,
75039
+ * it's irrelevant. This is defensive: Rule 4 (VC consumed → unstage P&R)
75040
+ * covers the VC case, but this handles the no-VC case where P&R would
75041
+ * otherwise linger on PreToolUse.
75042
+ */
75043
+ async onStop(sessionId) {
75044
+ await this.unstagePauseAndReflect(sessionId, "agent_stopping", "stop_hook");
75045
+ }
75046
+ /**
75047
+ * Delete P&R from PreToolUse staging and log the event.
75048
+ * Shared by Rule 4 (VC consumed → unstage P&R) and onStop (agent stopping).
75049
+ */
75050
+ async unstagePauseAndReflect(sessionId, reason, triggeredBy) {
75051
+ try {
75052
+ const staging = this.deps.getStagingService(sessionId);
75053
+ const deleted = await staging.deleteReminder("PreToolUse", types_js_1.ReminderIds.PAUSE_AND_REFLECT);
75054
+ if (deleted) {
75055
+ (0, core_1.logEvent)(this.deps.logger.child({ context: { sessionId } }), events_js_1.ReminderEvents.reminderUnstaged({ sessionId }, {
75056
+ reminderName: types_js_1.ReminderIds.PAUSE_AND_REFLECT,
75057
+ hookName: "PreToolUse",
75058
+ reason,
75059
+ triggeredBy
75060
+ }));
75061
+ }
75062
+ this.deps.logger.debug("P&R unstaged", { sessionId, deleted, reason });
75063
+ } catch (err) {
75064
+ this.deps.logger.warn("Failed to unstage P&R", {
75065
+ sessionId,
75066
+ reason,
75067
+ error: (0, core_1.toErrorMessage)(err)
74596
75068
  });
74597
75069
  }
74598
75070
  }
@@ -74988,7 +75460,7 @@ var require_persona_selection = __commonJS({
74988
75460
  } catch (err) {
74989
75461
  ctx.logger.warn("Failed to ensure persona for session", {
74990
75462
  sessionId,
74991
- error: err instanceof Error ? err.message : String(err)
75463
+ error: (0, core_1.toErrorMessage)(err)
74992
75464
  });
74993
75465
  }
74994
75466
  }
@@ -75748,7 +76220,7 @@ var require_update_summary = __commonJS({
75748
76220
  ctx.logger.error("performAnalysis failed", {
75749
76221
  sessionId,
75750
76222
  reason,
75751
- error: err instanceof Error ? err.message : String(err)
76223
+ error: (0, core_1.toErrorMessage)(err)
75752
76224
  });
75753
76225
  }
75754
76226
  }
@@ -76075,6 +76547,7 @@ var require_config_watcher = __commonJS({
76075
76547
  };
76076
76548
  Object.defineProperty(exports2, "__esModule", { value: true });
76077
76549
  exports2.ConfigWatcher = void 0;
76550
+ var core_1 = require_dist4();
76078
76551
  var chokidar_1 = (init_chokidar(), __toCommonJS(chokidar_exports));
76079
76552
  var os_1 = require("os");
76080
76553
  var path_1 = __importDefault(require("path"));
@@ -76205,7 +76678,7 @@ var require_config_watcher = __commonJS({
76205
76678
  } catch (err) {
76206
76679
  this.logger.error("Error in config change handler", {
76207
76680
  file: filename,
76208
- error: err instanceof Error ? err.message : String(err)
76681
+ error: (0, core_1.toErrorMessage)(err)
76209
76682
  });
76210
76683
  }
76211
76684
  }, this.debounceMs);
@@ -76238,6 +76711,7 @@ var require_session_persona_watcher = __commonJS({
76238
76711
  Object.defineProperty(exports2, "__esModule", { value: true });
76239
76712
  exports2.SessionPersonaWatcher = void 0;
76240
76713
  exports2.extractSessionIdFromPath = extractSessionIdFromPath;
76714
+ var core_1 = require_dist4();
76241
76715
  var chokidar_1 = (init_chokidar(), __toCommonJS(chokidar_exports));
76242
76716
  var path_1 = __importDefault(require("path"));
76243
76717
  var PERSONA_FILENAME = "session-persona.json";
@@ -76358,7 +76832,7 @@ var require_session_persona_watcher = __commonJS({
76358
76832
  } catch (err) {
76359
76833
  this.logger.error("Error in persona change handler", {
76360
76834
  sessionId,
76361
- error: err instanceof Error ? err.message : String(err)
76835
+ error: (0, core_1.toErrorMessage)(err)
76362
76836
  });
76363
76837
  }
76364
76838
  }, this.debounceMs);
@@ -76655,7 +77129,7 @@ var require_context_metrics_service = __commonJS({
76655
77129
  this.logger.info("Triggering async CLI capture for base metrics");
76656
77130
  void this.captureBaseMetrics().catch((err) => {
76657
77131
  this.logger.warn("Failed to capture base metrics via CLI", {
76658
- error: err instanceof Error ? err.message : String(err),
77132
+ error: (0, core_1.toErrorMessage)(err),
76659
77133
  stack: err instanceof Error ? err.stack : void 0
76660
77134
  });
76661
77135
  });
@@ -76781,7 +77255,7 @@ var require_context_metrics_service = __commonJS({
76781
77255
  sessionId
76782
77256
  });
76783
77257
  } catch (err) {
76784
- const errorMessage = err instanceof Error ? err.message : String(err);
77258
+ const errorMessage = (0, core_1.toErrorMessage)(err);
76785
77259
  this.logger.warn("CLI capture failed", {
76786
77260
  error: errorMessage,
76787
77261
  stack: err instanceof Error ? err.stack : void 0
@@ -77073,7 +77547,7 @@ var require_cleanup_handler = __commonJS({
77073
77547
  } catch (statErr) {
77074
77548
  ctx.logger.warn("Failed to stat session directory", {
77075
77549
  session: entry.name,
77076
- error: statErr instanceof Error ? statErr.message : String(statErr)
77550
+ error: (0, core_1.toErrorMessage)(statErr)
77077
77551
  });
77078
77552
  }
77079
77553
  }
@@ -77089,7 +77563,7 @@ var require_cleanup_handler = __commonJS({
77089
77563
  return;
77090
77564
  }
77091
77565
  ctx.logger.error("Cleanup task failed", {
77092
- error: err instanceof Error ? err.message : String(err)
77566
+ error: (0, core_1.toErrorMessage)(err)
77093
77567
  });
77094
77568
  throw err;
77095
77569
  }
@@ -77265,6 +77739,7 @@ var require_task_engine = __commonJS({
77265
77739
  };
77266
77740
  Object.defineProperty(exports2, "__esModule", { value: true });
77267
77741
  exports2.TaskEngine = exports2.TaskTimeoutError = void 0;
77742
+ var core_1 = require_dist4();
77268
77743
  var crypto_1 = __importDefault(require("crypto"));
77269
77744
  var DEFAULT_TASK_TIMEOUT_MS = 5 * 60 * 1e3;
77270
77745
  var TaskTimeoutError = class extends Error {
@@ -77393,7 +77868,7 @@ var require_task_engine = __commonJS({
77393
77868
  this.logger.error("Task failed", {
77394
77869
  type: task.type,
77395
77870
  id: task.id,
77396
- error: err instanceof Error ? err.message : String(err),
77871
+ error: (0, core_1.toErrorMessage)(err),
77397
77872
  stack: err instanceof Error ? err.stack : void 0,
77398
77873
  durationMs
77399
77874
  });
@@ -77713,7 +78188,7 @@ var require_daemon_timer_manager = __commonJS({
77713
78188
  this.deps.logger.info("Project registered for UI discovery", { projectDir: this.deps.projectDir });
77714
78189
  } catch (err) {
77715
78190
  this.deps.logger.warn("Failed to register project", {
77716
- error: err instanceof Error ? err.message : String(err)
78191
+ error: (0, core_1.toErrorMessage)(err)
77717
78192
  });
77718
78193
  }
77719
78194
  }
@@ -77877,7 +78352,7 @@ var require_daemon_log_metrics = __commonJS({
77877
78352
  await this.daemonStatusAccessor.write(status);
77878
78353
  } catch (err) {
77879
78354
  this.logger?.warn("Failed to write heartbeat status", {
77880
- error: err instanceof Error ? err.message : String(err)
78355
+ error: (0, core_1.toErrorMessage)(err)
77881
78356
  });
77882
78357
  }
77883
78358
  await this.persistLogMetrics();
@@ -77919,7 +78394,7 @@ var require_daemon_log_metrics = __commonJS({
77919
78394
  } catch (err) {
77920
78395
  this.logger?.warn("Failed to persist log metrics", {
77921
78396
  sessionId,
77922
- error: err instanceof Error ? err.message : String(err)
78397
+ error: (0, core_1.toErrorMessage)(err)
77923
78398
  });
77924
78399
  }
77925
78400
  }
@@ -77932,7 +78407,7 @@ var require_daemon_log_metrics = __commonJS({
77932
78407
  await this.globalLogMetricsAccessor.write(globalMetrics);
77933
78408
  } catch (err) {
77934
78409
  this.logger?.warn("Failed to persist global log metrics", {
77935
- error: err instanceof Error ? err.message : String(err)
78410
+ error: (0, core_1.toErrorMessage)(err)
77936
78411
  });
77937
78412
  }
77938
78413
  }
@@ -78138,6 +78613,7 @@ var require_daemon = __commonJS({
78138
78613
  token = "";
78139
78614
  registryService;
78140
78615
  timerManager;
78616
+ sessionLogWriter;
78141
78617
  /** Cache persona for handoff on clear. */
78142
78618
  cachePersonaForClear(personaId) {
78143
78619
  this.lastClearedPersona = { personaId, timestamp: Date.now() };
@@ -78180,8 +78656,9 @@ var require_daemon = __commonJS({
78180
78656
  destinations: {
78181
78657
  file: {
78182
78658
  path: path_1.default.join(logDir, "sidekickd.log"),
78183
- maxSizeBytes: this.configService.core.logging.rotation?.maxSizeBytes ?? 10485760,
78184
- maxFiles: this.configService.core.logging.rotation?.maxFiles ?? 5
78659
+ maxSizeBytes: this.configService.core.logging.rotation?.maxSizeBytes ?? 2097152,
78660
+ // 2MB (ephemeral debug window)
78661
+ maxFiles: this.configService.core.logging.rotation?.maxFiles ?? 2
78185
78662
  },
78186
78663
  console: { enabled: this.configService.core.logging.consoleEnabled }
78187
78664
  }
@@ -78193,6 +78670,13 @@ var require_daemon = __commonJS({
78193
78670
  getStartTime: () => this.timerManager.startTime
78194
78671
  });
78195
78672
  this.logger = this.logMetrics.createCountingLogger();
78673
+ const sessionsDir = path_1.default.join(projectDir2, ".sidekick", "sessions");
78674
+ this.sessionLogWriter = new core_1.SessionLogWriter({
78675
+ sessionsDir,
78676
+ maxHandles: 10,
78677
+ idleTimeoutMs: 30 * 60 * 1e3
78678
+ });
78679
+ (0, core_1.setSessionLogWriter)(this.sessionLogWriter);
78196
78680
  this.stateService = new core_1.StateService(projectDir2, {
78197
78681
  cache: true,
78198
78682
  logger: this.logger,
@@ -78300,6 +78784,8 @@ var require_daemon = __commonJS({
78300
78784
  }
78301
78785
  async stop() {
78302
78786
  this.logger.info("Daemon stopping");
78787
+ (0, core_1.setSessionLogWriter)(null);
78788
+ await this.sessionLogWriter.closeAll();
78303
78789
  this.timerManager.stopAll();
78304
78790
  this.configWatcher.stop();
78305
78791
  this.personaWatcher.stop();
@@ -78374,7 +78860,7 @@ var require_daemon = __commonJS({
78374
78860
  this.logger.info("Configuration reloaded successfully");
78375
78861
  } catch (err) {
78376
78862
  this.logger.error("Failed to reload configuration", {
78377
- error: err instanceof Error ? err.message : String(err)
78863
+ error: (0, core_1.toErrorMessage)(err)
78378
78864
  });
78379
78865
  }
78380
78866
  }
@@ -78417,7 +78903,7 @@ var require_daemon = __commonJS({
78417
78903
  } catch (err) {
78418
78904
  this.logger.error("Failed to stage persona reminders on change", {
78419
78905
  sessionId: event.sessionId,
78420
- error: err instanceof Error ? err.message : String(err)
78906
+ error: (0, core_1.toErrorMessage)(err)
78421
78907
  });
78422
78908
  }
78423
78909
  }
@@ -78449,7 +78935,7 @@ var require_daemon = __commonJS({
78449
78935
  } catch (err) {
78450
78936
  this.logger.error("Failed to regenerate messages after persona change", {
78451
78937
  sessionId,
78452
- error: err instanceof Error ? err.message : String(err)
78938
+ error: (0, core_1.toErrorMessage)(err)
78453
78939
  });
78454
78940
  }
78455
78941
  }
@@ -78613,7 +79099,7 @@ var require_daemon = __commonJS({
78613
79099
  }
78614
79100
  } catch (err) {
78615
79101
  log.warn("Failed to cache persona for clear handoff", {
78616
- error: err instanceof Error ? err.message : String(err)
79102
+ error: (0, core_1.toErrorMessage)(err)
78617
79103
  });
78618
79104
  }
78619
79105
  } else {
@@ -78625,6 +79111,7 @@ var require_daemon = __commonJS({
78625
79111
  await this.llmManager.shutdownSessionProvider(sessionId, log);
78626
79112
  this.logMetrics.deleteSessionCounters(sessionId);
78627
79113
  await this.serviceFactory.shutdownSession(sessionId);
79114
+ await this.sessionLogWriter.closeSession(sessionId);
78628
79115
  log.info("Session ended");
78629
79116
  }
78630
79117
  }