@scotthamilton77/sidekick 0.1.19 → 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 {
@@ -33259,6 +33316,8 @@ var require_session_log_writer = __commonJS({
33259
33316
  idleTimeoutMs;
33260
33317
  /** Map key: `${sessionId}/${logFile}` */
33261
33318
  handles = /* @__PURE__ */ new Map();
33319
+ /** Sentinel map to prevent duplicate handle creation on concurrent writes */
33320
+ pendingCreation = /* @__PURE__ */ new Map();
33262
33321
  constructor(options) {
33263
33322
  this.sessionsDir = options.sessionsDir;
33264
33323
  this.maxHandles = options.maxHandles ?? 10;
@@ -33278,30 +33337,26 @@ var require_session_log_writer = __commonJS({
33278
33337
  if (!(0, staging_paths_js_1.isValidPathSegment)(sessionId) || !(0, staging_paths_js_1.isValidPathSegment)(logFile))
33279
33338
  return;
33280
33339
  const key = `${sessionId}/${logFile}`;
33340
+ const pending = this.pendingCreation.get(key);
33341
+ if (pending) {
33342
+ try {
33343
+ await pending;
33344
+ } catch {
33345
+ }
33346
+ }
33281
33347
  let entry = this.handles.get(key);
33282
33348
  if (!entry) {
33283
33349
  if (this.handles.size >= this.maxHandles) {
33284
33350
  this.evictLRU();
33285
33351
  }
33286
- const logDir = (0, node_path_1.join)(this.sessionsDir, sessionId, "logs");
33287
- await (0, promises_1.mkdir)(logDir, { recursive: true });
33288
- const filePath = (0, node_path_1.join)(logDir, logFile);
33289
- const stream = (0, node_fs_1.createWriteStream)(filePath, { flags: "a" });
33290
- const ready = new Promise((resolve3, reject) => {
33291
- stream.once("open", () => resolve3());
33292
- stream.once("error", (err) => {
33293
- this.handles.delete(key);
33294
- stream.destroy();
33295
- reject(err);
33296
- });
33297
- });
33298
- entry = {
33299
- stream,
33300
- lastUsed: Date.now(),
33301
- timer: null,
33302
- ready
33303
- };
33304
- this.handles.set(key, entry);
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
+ }
33305
33360
  }
33306
33361
  await entry.ready;
33307
33362
  entry.lastUsed = Date.now();
@@ -33317,6 +33372,25 @@ var require_session_log_writer = __commonJS({
33317
33372
  });
33318
33373
  });
33319
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
+ }
33320
33394
  /** Close all handles for a specific session. */
33321
33395
  async closeSession(sessionId) {
33322
33396
  const prefix = `${sessionId}/`;
@@ -45117,6 +45191,7 @@ var require_structured_logging = __commonJS({
45117
45191
  var node_fs_1 = require("node:fs");
45118
45192
  var node_path_1 = require("node:path");
45119
45193
  var node_stream_1 = require("node:stream");
45194
+ var error_utils_js_1 = require_error_utils();
45120
45195
  var log_events_1 = require_log_events();
45121
45196
  Object.defineProperty(exports2, "LogEvents", { enumerable: true, get: function() {
45122
45197
  return log_events_1.LogEvents;
@@ -45146,8 +45221,8 @@ var require_structured_logging = __commonJS({
45146
45221
  }
45147
45222
  return defaultLevel;
45148
45223
  }
45149
- exports2.DEFAULT_ROTATE_SIZE_BYTES = 10 * 1024 * 1024;
45150
- exports2.DEFAULT_MAX_FILES = 5;
45224
+ exports2.DEFAULT_ROTATE_SIZE_BYTES = 2 * 1024 * 1024;
45225
+ exports2.DEFAULT_MAX_FILES = 2;
45151
45226
  var DEFAULT_REDACT_KEYS = [
45152
45227
  "apiKey",
45153
45228
  "token",
@@ -45488,7 +45563,7 @@ var require_structured_logging = __commonJS({
45488
45563
  upgradeOptions.onUpgradeError(err);
45489
45564
  }
45490
45565
  activeLogger.error("Failed to upgrade to Pino logger", {
45491
- error: err instanceof Error ? err.message : String(err)
45566
+ error: (0, error_utils_js_1.toErrorMessage)(err)
45492
45567
  });
45493
45568
  }
45494
45569
  },
@@ -45504,7 +45579,7 @@ var require_structured_logging = __commonJS({
45504
45579
  };
45505
45580
  const rejectionHandler = (reason) => {
45506
45581
  logger.fatal("Unhandled promise rejection", {
45507
- reason: reason instanceof Error ? reason.message : String(reason)
45582
+ reason: (0, error_utils_js_1.toErrorMessage)(reason)
45508
45583
  });
45509
45584
  };
45510
45585
  process.on("uncaughtException", uncaughtHandler);
@@ -45597,13 +45672,11 @@ var require_daemon_client2 = __commonJS({
45597
45672
  var client_js_1 = require_client();
45598
45673
  var transport_js_1 = require_transport();
45599
45674
  var sandbox_js_1 = require_sandbox();
45675
+ var error_utils_js_1 = require_error_utils();
45600
45676
  var LOCK_TIMEOUT_MS = 1e4;
45601
45677
  var LOCK_RETRY_INTERVAL_MS = 100;
45602
45678
  var LOCK_STALE_THRESHOLD_MS = 3e4;
45603
45679
  var CLIENT_VERSION = require_package3().version;
45604
- function toErrorMsg(err) {
45605
- return err instanceof Error ? err.message : String(err);
45606
- }
45607
45680
  var DaemonClient = class {
45608
45681
  projectDir;
45609
45682
  logger;
@@ -45969,7 +46042,7 @@ var require_daemon_client2 = __commonJS({
45969
46042
  } catch (err) {
45970
46043
  logger.debug("Graceful stop failed, falling back to SIGKILL", {
45971
46044
  pid: info.pid,
45972
- error: toErrorMsg(err)
46045
+ error: (0, error_utils_js_1.toErrorMessage)(err)
45973
46046
  });
45974
46047
  }
45975
46048
  }
@@ -45978,7 +46051,7 @@ var require_daemon_client2 = __commonJS({
45978
46051
  logger.info("Killed daemon", { pid: info.pid, projectDir: info.projectDir });
45979
46052
  results.push({ projectDir: info.projectDir, pid: info.pid, killed: true });
45980
46053
  } catch (err) {
45981
- const msg = toErrorMsg(err);
46054
+ const msg = (0, error_utils_js_1.toErrorMessage)(err);
45982
46055
  logger.warn("Failed to kill daemon", { pid: info.pid, error: msg });
45983
46056
  results.push({ projectDir: info.projectDir, pid: info.pid, killed: false, error: msg });
45984
46057
  }
@@ -45990,7 +46063,7 @@ var require_daemon_client2 = __commonJS({
45990
46063
  });
45991
46064
  }
45992
46065
  } catch (err) {
45993
- 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) });
45994
46067
  await promises_1.default.unlink(pidPath).catch(() => {
45995
46068
  });
45996
46069
  }
@@ -46011,7 +46084,7 @@ var require_daemon_client2 = __commonJS({
46011
46084
  });
46012
46085
  } catch (err) {
46013
46086
  logger.warn("Failed to run ps \u2014 cannot detect zombie daemons", {
46014
- error: toErrorMsg(err)
46087
+ error: (0, error_utils_js_1.toErrorMessage)(err)
46015
46088
  });
46016
46089
  return [];
46017
46090
  }
@@ -46072,7 +46145,7 @@ var require_daemon_client2 = __commonJS({
46072
46145
  logger.info("Killed zombie daemon", { pid: zombie.pid, command: zombie.command });
46073
46146
  results.push({ projectDir: "unknown", pid: zombie.pid, killed: true });
46074
46147
  } catch (err) {
46075
- const msg = toErrorMsg(err);
46148
+ const msg = (0, error_utils_js_1.toErrorMessage)(err);
46076
46149
  logger.warn("Failed to kill zombie daemon", { pid: zombie.pid, error: msg });
46077
46150
  results.push({ projectDir: "unknown", pid: zombie.pid, killed: false, error: msg });
46078
46151
  }
@@ -46124,60 +46197,94 @@ var require_gitignore = __commonJS({
46124
46197
  };
46125
46198
  })();
46126
46199
  Object.defineProperty(exports2, "__esModule", { value: true });
46127
- 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;
46128
46201
  exports2.installGitignoreSection = installGitignoreSection;
46129
- exports2.removeGitignoreSection = removeGitignoreSection;
46130
46202
  exports2.detectGitignoreStatus = detectGitignoreStatus;
46203
+ exports2.removeGitignoreSection = removeGitignoreSection;
46204
+ exports2.detectLegacyGitignoreSection = detectLegacyGitignoreSection;
46205
+ exports2.removeLegacyGitignoreSection = removeLegacyGitignoreSection;
46131
46206
  var fs = __importStar(require("node:fs/promises"));
46132
46207
  var path = __importStar(require("node:path"));
46133
46208
  exports2.SIDEKICK_SECTION_START = "# >>> sidekick";
46134
46209
  exports2.SIDEKICK_SECTION_END = "# <<< sidekick";
46210
+ exports2.SIDEKICK_GITIGNORE_HEADER = "# Sidekick \u2014 managed file, do not edit manually";
46135
46211
  exports2.GITIGNORE_ENTRIES = [
46136
- ".sidekick/logs/",
46137
- ".sidekick/sessions/",
46138
- ".sidekick/state/",
46139
- ".sidekick/setup-status.json",
46140
- ".sidekick/.env",
46141
- ".sidekick/.env.local",
46142
- ".sidekick/sidekick*.pid",
46143
- ".sidekick/sidekick*.token",
46144
- ".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"
46145
46221
  ];
46146
46222
  async function installGitignoreSection(projectDir2) {
46147
- const gitignorePath = path.join(projectDir2, ".gitignore");
46148
- let content = "";
46223
+ let status;
46149
46224
  try {
46150
- content = await fs.readFile(gitignorePath, "utf-8");
46225
+ status = await detectGitignoreStatus(projectDir2);
46151
46226
  } catch (err) {
46152
- if (err.code !== "ENOENT") {
46153
- return { status: "error", error: `Failed to read .gitignore: ${err.message}` };
46154
- }
46227
+ return { status: "error", error: `Failed to check gitignore status: ${err.message}` };
46155
46228
  }
46156
- const status = await detectGitignoreStatus(projectDir2);
46157
46229
  if (status === "installed") {
46158
46230
  return { status: "already-installed" };
46159
46231
  }
46160
- if (status === "incomplete") {
46161
- await removeGitignoreSection(projectDir2);
46162
- try {
46163
- content = await fs.readFile(gitignorePath, "utf-8");
46164
- } catch {
46165
- content = "";
46166
- }
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}` };
46167
46237
  }
46168
- const section = ["", exports2.SIDEKICK_SECTION_START, ...exports2.GITIGNORE_ENTRIES, exports2.SIDEKICK_SECTION_END].join("\n");
46169
- const newContent = content.trimEnd() + section + "\n";
46238
+ const content = [exports2.SIDEKICK_GITIGNORE_HEADER, ...exports2.GITIGNORE_ENTRIES].join("\n") + "\n";
46170
46239
  try {
46171
- await fs.writeFile(gitignorePath, newContent);
46240
+ await fs.writeFile(path.join(sidekickDir, ".gitignore"), content);
46172
46241
  return { status: "installed", entriesAdded: exports2.GITIGNORE_ENTRIES };
46173
46242
  } catch (err) {
46174
- return { status: "error", error: `Failed to write .gitignore: ${err.message}` };
46243
+ return { status: "error", error: `Failed to write .sidekick/.gitignore: ${err.message}` };
46244
+ }
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
+ }
46175
46256
  }
46257
+ const hasLegacy = await detectLegacyGitignoreSection(projectDir2);
46258
+ return hasLegacy ? "legacy" : "missing";
46176
46259
  }
46177
46260
  async function removeGitignoreSection(projectDir2) {
46178
- const gitignorePath = path.join(projectDir2, ".gitignore");
46261
+ let removed = false;
46262
+ try {
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");
46179
46286
  try {
46180
- const content = await fs.readFile(gitignorePath, "utf-8");
46287
+ const content = await fs.readFile(rootGitignorePath, "utf-8");
46181
46288
  const startIdx = content.indexOf(exports2.SIDEKICK_SECTION_START);
46182
46289
  const endIdx = content.indexOf(exports2.SIDEKICK_SECTION_END);
46183
46290
  if (startIdx === -1 || endIdx === -1 || endIdx < startIdx) {
@@ -46189,37 +46296,13 @@ var require_gitignore = __commonJS({
46189
46296
  const before = content.slice(0, lineStartIdx).trimEnd();
46190
46297
  const after = content.slice(actualEndIdx).trimStart();
46191
46298
  const newContent = before + (after ? "\n" + after : "") + "\n";
46192
- await fs.writeFile(gitignorePath, newContent);
46299
+ await fs.writeFile(rootGitignorePath, newContent);
46193
46300
  return true;
46194
- } catch {
46195
- return false;
46196
- }
46197
- }
46198
- async function detectGitignoreStatus(projectDir2) {
46199
- const gitignorePath = path.join(projectDir2, ".gitignore");
46200
- try {
46201
- const content = await fs.readFile(gitignorePath, "utf-8");
46202
- const hasStart = content.includes(exports2.SIDEKICK_SECTION_START);
46203
- const hasEnd = content.includes(exports2.SIDEKICK_SECTION_END);
46204
- if (!hasStart && !hasEnd) {
46205
- return "missing";
46206
- }
46207
- if (!hasStart || !hasEnd) {
46208
- return "incomplete";
46209
- }
46210
- const startIdx = content.indexOf(exports2.SIDEKICK_SECTION_START);
46211
- const endIdx = content.indexOf(exports2.SIDEKICK_SECTION_END);
46212
- if (endIdx <= startIdx) {
46213
- return "incomplete";
46214
- }
46215
- const sectionContent = content.slice(startIdx, endIdx + exports2.SIDEKICK_SECTION_END.length);
46216
- const missingEntries = exports2.GITIGNORE_ENTRIES.filter((entry) => !sectionContent.includes(entry));
46217
- if (missingEntries.length > 0) {
46218
- return "incomplete";
46301
+ } catch (err) {
46302
+ if (err.code === "ENOENT") {
46303
+ return false;
46219
46304
  }
46220
- return "installed";
46221
- } catch {
46222
- return "missing";
46305
+ throw err;
46223
46306
  }
46224
46307
  }
46225
46308
  }
@@ -46230,7 +46313,7 @@ var require_errors4 = __commonJS({
46230
46313
  "../shared-providers/dist/errors.js"(exports2) {
46231
46314
  "use strict";
46232
46315
  Object.defineProperty(exports2, "__esModule", { value: true });
46233
- exports2.TimeoutError = exports2.AuthError = exports2.RateLimitError = exports2.ProviderError = void 0;
46316
+ exports2.MalformedResponseError = exports2.TimeoutError = exports2.AuthError = exports2.RateLimitError = exports2.ProviderError = void 0;
46234
46317
  var ProviderError = class _ProviderError extends Error {
46235
46318
  provider;
46236
46319
  retryable;
@@ -46271,6 +46354,18 @@ var require_errors4 = __commonJS({
46271
46354
  }
46272
46355
  };
46273
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;
46274
46369
  }
46275
46370
  });
46276
46371
 
@@ -55249,6 +55344,7 @@ var require_base = __commonJS({
55249
55344
  model: response.model,
55250
55345
  durationMs,
55251
55346
  usage: response.usage,
55347
+ finishReason: response.finishReason,
55252
55348
  status: response.rawResponse.status,
55253
55349
  contentLength: response.content.length
55254
55350
  });
@@ -55296,6 +55392,7 @@ var require_openai_native = __commonJS({
55296
55392
  maxTokens;
55297
55393
  providerAllowlist;
55298
55394
  providerBlocklist;
55395
+ reasoning;
55299
55396
  constructor(config, logger) {
55300
55397
  super(logger);
55301
55398
  this.id = config.baseURL?.includes("openrouter") ? "openrouter" : "openai";
@@ -55304,6 +55401,7 @@ var require_openai_native = __commonJS({
55304
55401
  this.maxTokens = config.maxTokens;
55305
55402
  this.providerAllowlist = config.providerAllowlist;
55306
55403
  this.providerBlocklist = config.providerBlocklist;
55404
+ this.reasoning = config.reasoning;
55307
55405
  this.client = new openai_1.default({
55308
55406
  apiKey: config.apiKey,
55309
55407
  baseURL: config.baseURL,
@@ -55319,6 +55417,7 @@ var require_openai_native = __commonJS({
55319
55417
  maxTokens: this.maxTokens,
55320
55418
  providerAllowlist: this.providerAllowlist,
55321
55419
  providerBlocklist: this.providerBlocklist,
55420
+ reasoning: this.reasoning,
55322
55421
  apiKey: this.redactApiKey(config.apiKey)
55323
55422
  });
55324
55423
  }
@@ -55336,6 +55435,7 @@ var require_openai_native = __commonJS({
55336
55435
  }
55337
55436
  } : void 0;
55338
55437
  const providerRouting = this.buildProviderRouting();
55438
+ const reasoningParam = this.buildReasoningParam();
55339
55439
  const completion = await this.client.chat.completions.create({
55340
55440
  model: request.model ?? this.defaultModel,
55341
55441
  messages,
@@ -55343,8 +55443,13 @@ var require_openai_native = __commonJS({
55343
55443
  max_tokens: this.maxTokens,
55344
55444
  response_format: responseFormat,
55345
55445
  ...providerRouting,
55446
+ ...reasoningParam,
55346
55447
  ...request.additionalParams
55347
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
+ }
55348
55453
  const response = {
55349
55454
  content: completion.choices[0]?.message?.content ?? "",
55350
55455
  model: completion.model,
@@ -55352,6 +55457,7 @@ var require_openai_native = __commonJS({
55352
55457
  inputTokens: completion.usage.prompt_tokens,
55353
55458
  outputTokens: completion.usage.completion_tokens
55354
55459
  } : void 0,
55460
+ finishReason: completion.choices[0]?.finish_reason ?? void 0,
55355
55461
  rawResponse: {
55356
55462
  status: 200,
55357
55463
  body: JSON.stringify(completion)
@@ -55387,7 +55493,25 @@ var require_openai_native = __commonJS({
55387
55493
  }
55388
55494
  return { provider: providerObj };
55389
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
+ }
55390
55511
  mapError(error) {
55512
+ if (error instanceof errors_1.ProviderError) {
55513
+ return error;
55514
+ }
55391
55515
  if (error instanceof openai_1.default.APIError) {
55392
55516
  if (error.status === 401 || error.status === 403) {
55393
55517
  return new errors_1.AuthError(this.id, error);
@@ -55481,7 +55605,13 @@ var require_claude_cli_spawn = __commonJS({
55481
55605
  });
55482
55606
  const child = (0, node_child_process_1.spawn)(cliPath, args, {
55483
55607
  cwd,
55484
- 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" }
55485
55615
  });
55486
55616
  let stdout = "";
55487
55617
  let stderr = "";
@@ -55543,6 +55673,31 @@ var require_claude_cli_spawn = __commonJS({
55543
55673
  }
55544
55674
  });
55545
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
+
55546
55701
  // ../shared-providers/dist/providers/anthropic-cli.js
55547
55702
  var require_anthropic_cli = __commonJS({
55548
55703
  "../shared-providers/dist/providers/anthropic-cli.js"(exports2) {
@@ -55551,6 +55706,7 @@ var require_anthropic_cli = __commonJS({
55551
55706
  exports2.AnthropicCliProvider = void 0;
55552
55707
  var base_1 = require_base();
55553
55708
  var claude_cli_spawn_1 = require_claude_cli_spawn();
55709
+ var anthropic_stop_reason_1 = require_anthropic_stop_reason();
55554
55710
  var AnthropicCliProvider = class extends base_1.AbstractProvider {
55555
55711
  id = "claude-cli";
55556
55712
  defaultModel;
@@ -55612,6 +55768,7 @@ var require_anthropic_cli = __commonJS({
55612
55768
  inputTokens: parsed.usage.input_tokens ?? 0,
55613
55769
  outputTokens: parsed.usage.output_tokens ?? 0
55614
55770
  } : void 0,
55771
+ finishReason: (0, anthropic_stop_reason_1.mapAnthropicStopReason)(parsed.stop_reason),
55615
55772
  rawResponse: {
55616
55773
  status: 200,
55617
55774
  body: stdout
@@ -55883,6 +56040,7 @@ var require_openai_emulator = __commonJS({
55883
56040
  inputTokens,
55884
56041
  outputTokens
55885
56042
  },
56043
+ finishReason: "stop",
55886
56044
  rawResponse: {
55887
56045
  status: 200,
55888
56046
  body: JSON.stringify(rawBody)
@@ -55937,6 +56095,7 @@ var require_openrouter_emulator = __commonJS({
55937
56095
  inputTokens,
55938
56096
  outputTokens
55939
56097
  },
56098
+ finishReason: "stop",
55940
56099
  rawResponse: {
55941
56100
  status: 200,
55942
56101
  body: JSON.stringify(rawBody)
@@ -55957,6 +56116,7 @@ var require_claude_cli_emulator = __commonJS({
55957
56116
  var node_child_process_1 = require("node:child_process");
55958
56117
  var node_path_1 = require("node:path");
55959
56118
  var base_1 = require_base();
56119
+ var anthropic_stop_reason_1 = require_anthropic_stop_reason();
55960
56120
  var EMULATOR_SCRIPT = `#!/bin/bash
55961
56121
  # Claude CLI Emulator Script
55962
56122
  STATE_FILE="\${SIDEKICK_EMULATOR_STATE_PATH:-.sidekick/emulator-state/call-counts.json}"
@@ -56044,6 +56204,7 @@ echo "{\\"content\\":\\"\${CONTENT}\\",\\"message\\":\\"\${CONTENT}\\",\\"model\
56044
56204
  inputTokens,
56045
56205
  outputTokens
56046
56206
  },
56207
+ finishReason: (0, anthropic_stop_reason_1.mapAnthropicStopReason)(parsed.stop_reason),
56047
56208
  rawResponse: {
56048
56209
  status: 0,
56049
56210
  // Exit code
@@ -56180,7 +56341,8 @@ var require_factory = __commonJS({
56180
56341
  temperature: this.config.temperature,
56181
56342
  maxTokens: this.config.maxTokens,
56182
56343
  providerAllowlist: this.config.providerAllowlist,
56183
- providerBlocklist: this.config.providerBlocklist
56344
+ providerBlocklist: this.config.providerBlocklist,
56345
+ reasoning: this.config.reasoning
56184
56346
  };
56185
56347
  return new openai_native_1.OpenAINativeProvider(openrouterConfig, this.logger);
56186
56348
  }
@@ -56357,7 +56519,9 @@ var require_profile_factory = __commonJS({
56357
56519
  maxTokens: profile.maxTokens,
56358
56520
  // OpenRouter-specific provider routing
56359
56521
  providerAllowlist: profile.providerAllowlist ? [...profile.providerAllowlist] : void 0,
56360
- providerBlocklist: profile.providerBlocklist ? [...profile.providerBlocklist] : void 0
56522
+ providerBlocklist: profile.providerBlocklist ? [...profile.providerBlocklist] : void 0,
56523
+ // OpenRouter-specific reasoning toggle
56524
+ reasoning: profile.reasoning
56361
56525
  }, this.logger);
56362
56526
  return factory.create();
56363
56527
  }
@@ -56412,7 +56576,7 @@ var require_dist3 = __commonJS({
56412
56576
  "../shared-providers/dist/index.js"(exports2) {
56413
56577
  "use strict";
56414
56578
  Object.defineProperty(exports2, "__esModule", { value: true });
56415
- 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;
56416
56580
  var errors_1 = require_errors4();
56417
56581
  Object.defineProperty(exports2, "ProviderError", { enumerable: true, get: function() {
56418
56582
  return errors_1.ProviderError;
@@ -56426,6 +56590,9 @@ var require_dist3 = __commonJS({
56426
56590
  Object.defineProperty(exports2, "TimeoutError", { enumerable: true, get: function() {
56427
56591
  return errors_1.TimeoutError;
56428
56592
  } });
56593
+ Object.defineProperty(exports2, "MalformedResponseError", { enumerable: true, get: function() {
56594
+ return errors_1.MalformedResponseError;
56595
+ } });
56429
56596
  var factory_1 = require_factory();
56430
56597
  Object.defineProperty(exports2, "ProviderFactory", { enumerable: true, get: function() {
56431
56598
  return factory_1.ProviderFactory;
@@ -56715,6 +56882,7 @@ var require_plugin_detector = __commonJS({
56715
56882
  var crypto2 = __importStar(require("node:crypto"));
56716
56883
  var node_child_process_1 = require("node:child_process");
56717
56884
  var api_key_detector_js_1 = require_api_key_detector();
56885
+ var error_utils_js_1 = require_error_utils();
56718
56886
  function isSidekickStatuslineCommand(command) {
56719
56887
  return command?.toLowerCase().includes("sidekick") ?? false;
56720
56888
  }
@@ -56844,7 +57012,7 @@ var require_plugin_detector = __commonJS({
56844
57012
  return result;
56845
57013
  } catch (err) {
56846
57014
  logger?.warn("Failed to parse plugin list JSON", {
56847
- error: err instanceof Error ? err.message : String(err)
57015
+ error: (0, error_utils_js_1.toErrorMessage)(err)
56848
57016
  });
56849
57017
  logger?.info("Plugin detection completed", { result: "error" });
56850
57018
  return "error";
@@ -57048,7 +57216,16 @@ var require_doctor_engine = __commonJS({
57048
57216
  const expectedUserStatus = (0, api_key_detector_js_1.buildUserApiKeyStatus)(detection);
57049
57217
  const currentUserEntry = currentUserStatus.apiKeys[keyName];
57050
57218
  const currentStatus = typeof currentUserEntry === "object" ? currentUserEntry.status : currentUserEntry ?? "missing";
57051
- 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))) {
57052
57229
  updatedUserApiKeys[keyName] = expectedUserStatus;
57053
57230
  userNeedsUpdate = true;
57054
57231
  }
@@ -57123,7 +57300,7 @@ var require_setup_status_service = __commonJS({
57123
57300
  };
57124
57301
  })();
57125
57302
  Object.defineProperty(exports2, "__esModule", { value: true });
57126
- 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;
57127
57304
  exports2.createSetupStatusService = createSetupStatusService;
57128
57305
  var fs = __importStar(require("node:fs/promises"));
57129
57306
  var path = __importStar(require("node:path"));
@@ -57135,7 +57312,6 @@ var require_setup_status_service = __commonJS({
57135
57312
  var doctor_engine_js_1 = require_doctor_engine();
57136
57313
  exports2.USER_STATUS_FILENAME = "user-setup-status.json";
57137
57314
  exports2.PROJECT_STATUS_FILENAME = "setup-status.json";
57138
- exports2.LEGACY_USER_STATUS_FILENAME = exports2.PROJECT_STATUS_FILENAME;
57139
57315
  var SetupStatusService = class {
57140
57316
  projectDir;
57141
57317
  homeDir;
@@ -57149,10 +57325,6 @@ var require_setup_status_service = __commonJS({
57149
57325
  get userStatusPath() {
57150
57326
  return path.join(this.homeDir, ".sidekick", exports2.USER_STATUS_FILENAME);
57151
57327
  }
57152
- /** Legacy path for migration: old user-scope file that collided with project-scope */
57153
- get legacyUserStatusPath() {
57154
- return path.join(this.homeDir, ".sidekick", exports2.LEGACY_USER_STATUS_FILENAME);
57155
- }
57156
57328
  get projectStatusPath() {
57157
57329
  return path.join(this.projectDir, ".sidekick", exports2.PROJECT_STATUS_FILENAME);
57158
57330
  }
@@ -57186,7 +57358,7 @@ var require_setup_status_service = __commonJS({
57186
57358
  return parsed.data;
57187
57359
  } catch (err) {
57188
57360
  if (err.code === "ENOENT") {
57189
- return this.migrateFromLegacyUserStatus();
57361
+ return null;
57190
57362
  }
57191
57363
  if (err instanceof SyntaxError) {
57192
57364
  this.logger?.warn(`Corrupt ${exports2.USER_STATUS_FILENAME}, treating as missing`, {
@@ -57198,54 +57370,6 @@ var require_setup_status_service = __commonJS({
57198
57370
  throw err;
57199
57371
  }
57200
57372
  }
57201
- /**
57202
- * Migration: read user status from the legacy `setup-status.json` location,
57203
- * write it to the new `user-setup-status.json`, and remove the old file.
57204
- *
57205
- * Only migrates if the legacy file contains valid UserSetupStatus data
57206
- * (not project-format data that may have been written by the collision bug).
57207
- */
57208
- async migrateFromLegacyUserStatus() {
57209
- try {
57210
- const legacyContent = await fs.readFile(this.legacyUserStatusPath, "utf-8");
57211
- const parsed = types_1.UserSetupStatusSchema.safeParse(JSON.parse(legacyContent));
57212
- if (!parsed.success) {
57213
- this.logger?.debug("Legacy user status file exists but is not valid user format, skipping migration", {
57214
- path: this.legacyUserStatusPath
57215
- });
57216
- return null;
57217
- }
57218
- this.logger?.info("Migrating user status from legacy location", {
57219
- from: this.legacyUserStatusPath,
57220
- to: this.userStatusPath
57221
- });
57222
- await this.writeUserStatus(parsed.data);
57223
- try {
57224
- await fs.unlink(this.legacyUserStatusPath);
57225
- } catch (unlinkErr) {
57226
- if (unlinkErr.code !== "ENOENT") {
57227
- this.logger?.warn("Migrated user status but failed to remove legacy file", {
57228
- path: this.legacyUserStatusPath,
57229
- error: unlinkErr instanceof Error ? unlinkErr.message : String(unlinkErr)
57230
- });
57231
- }
57232
- }
57233
- this.logger?.info("Legacy user status migration complete");
57234
- return parsed.data;
57235
- } catch (err) {
57236
- if (err.code === "ENOENT") {
57237
- return null;
57238
- }
57239
- if (err instanceof SyntaxError) {
57240
- this.logger?.warn(`Corrupt legacy ${exports2.LEGACY_USER_STATUS_FILENAME}, treating as missing`, {
57241
- path: this.legacyUserStatusPath,
57242
- error: err.message
57243
- });
57244
- return null;
57245
- }
57246
- throw err;
57247
- }
57248
- }
57249
57373
  async getProjectStatus() {
57250
57374
  if (path.resolve(this.projectDir) === path.resolve(this.homeDir)) {
57251
57375
  this.logger?.debug("Skipping project status read: projectDir is the home directory", {
@@ -57626,6 +57750,7 @@ var require_staging_service = __commonJS({
57626
57750
  var structured_logging_1 = require_structured_logging();
57627
57751
  var errors_js_1 = require_errors6();
57628
57752
  var staging_paths_js_1 = require_staging_paths();
57753
+ var error_utils_js_1 = require_error_utils();
57629
57754
  var StagingServiceCore = class {
57630
57755
  options;
57631
57756
  constructor(options) {
@@ -57729,7 +57854,7 @@ var require_staging_service = __commonJS({
57729
57854
  hookName,
57730
57855
  reminderName,
57731
57856
  path: reminderPath,
57732
- error: err instanceof Error ? err.message : String(err)
57857
+ error: (0, error_utils_js_1.toErrorMessage)(err)
57733
57858
  });
57734
57859
  return null;
57735
57860
  }
@@ -57760,7 +57885,7 @@ var require_staging_service = __commonJS({
57760
57885
  }
57761
57886
  this.options.logger.warn("Skipping invalid reminder file", {
57762
57887
  path: reminderPath,
57763
- error: err instanceof Error ? err.message : String(err)
57888
+ error: (0, error_utils_js_1.toErrorMessage)(err)
57764
57889
  });
57765
57890
  }
57766
57891
  }
@@ -57821,7 +57946,7 @@ var require_staging_service = __commonJS({
57821
57946
  }
57822
57947
  this.options.logger.warn("Skipping invalid consumed reminder file", {
57823
57948
  path: reminderPath,
57824
- error: err instanceof Error ? err.message : String(err)
57949
+ error: (0, error_utils_js_1.toErrorMessage)(err)
57825
57950
  });
57826
57951
  }
57827
57952
  }
@@ -57973,6 +58098,7 @@ var require_handler_registry2 = __commonJS({
57973
58098
  exports2.HandlerRegistryImpl = void 0;
57974
58099
  var transcript_content_js_1 = require_transcript_content();
57975
58100
  var structured_logging_js_1 = require_structured_logging();
58101
+ var error_utils_js_1 = require_error_utils();
57976
58102
  var HandlerRegistryImpl = class {
57977
58103
  options;
57978
58104
  handlers = [];
@@ -58083,7 +58209,7 @@ var require_handler_registry2 = __commonJS({
58083
58209
  log.error("Handler execution failed", {
58084
58210
  handlerId: handler.id,
58085
58211
  hook,
58086
- error: err instanceof Error ? err.message : String(err)
58212
+ error: (0, error_utils_js_1.toErrorMessage)(err)
58087
58213
  });
58088
58214
  }
58089
58215
  }
@@ -58129,7 +58255,7 @@ var require_handler_registry2 = __commonJS({
58129
58255
  (0, structured_logging_js_1.logEvent)(this.options.logger, structured_logging_js_1.LogEvents.eventProcessed(logContext, { handlerId: handler.id, success: true }, { durationMs }));
58130
58256
  } catch (err) {
58131
58257
  const durationMs = Date.now() - startTime;
58132
- const errorMsg = err instanceof Error ? err.message : String(err);
58258
+ const errorMsg = (0, error_utils_js_1.toErrorMessage)(err);
58133
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 }));
58134
58260
  this.options.logger.error("Transcript handler failed", {
58135
58261
  handlerId: handler.id,
@@ -58560,6 +58686,7 @@ var require_state_service = __commonJS({
58560
58686
  var node_path_1 = require("node:path");
58561
58687
  var path_resolver_js_1 = require_path_resolver();
58562
58688
  var errors_js_1 = require_errors6();
58689
+ var error_utils_js_1 = require_error_utils();
58563
58690
  var errors_js_2 = require_errors6();
58564
58691
  Object.defineProperty(exports2, "StateNotFoundError", { enumerable: true, get: function() {
58565
58692
  return errors_js_2.StateNotFoundError;
@@ -58671,7 +58798,7 @@ var require_state_service = __commonJS({
58671
58798
  } catch (cleanupErr) {
58672
58799
  this.logger?.trace("Failed to cleanup temp file", {
58673
58800
  tmpPath,
58674
- error: cleanupErr instanceof Error ? cleanupErr.message : String(cleanupErr)
58801
+ error: (0, error_utils_js_1.toErrorMessage)(cleanupErr)
58675
58802
  });
58676
58803
  }
58677
58804
  throw err;
@@ -58797,7 +58924,7 @@ var require_state_service = __commonJS({
58797
58924
  } catch (err) {
58798
58925
  this.logger?.warn("Failed to preload state file", {
58799
58926
  file,
58800
- error: err instanceof Error ? err.message : String(err)
58927
+ error: (0, error_utils_js_1.toErrorMessage)(err)
58801
58928
  });
58802
58929
  }
58803
58930
  }
@@ -58823,7 +58950,7 @@ var require_state_service = __commonJS({
58823
58950
  this.logger?.warn("Corrupt state file detected", {
58824
58951
  path,
58825
58952
  reason,
58826
- error: error instanceof Error ? error.message : String(error)
58953
+ error: (0, error_utils_js_1.toErrorMessage)(error)
58827
58954
  });
58828
58955
  try {
58829
58956
  await fs.rename(path, bakPath);
@@ -58853,7 +58980,7 @@ var require_state_service = __commonJS({
58853
58980
  } catch (err) {
58854
58981
  this.logger?.warn("Failed to create dev mode backup", {
58855
58982
  path,
58856
- error: err instanceof Error ? err.message : String(err)
58983
+ error: (0, error_utils_js_1.toErrorMessage)(err)
58857
58984
  });
58858
58985
  }
58859
58986
  }
@@ -58916,12 +59043,17 @@ var require_typed_accessor = __commonJS({
58916
59043
  var SessionStateAccessor = class {
58917
59044
  stateService;
58918
59045
  descriptor;
58919
- constructor(stateService, descriptor) {
59046
+ journal;
59047
+ /** Descriptor filename without .json extension — used as journal file key */
59048
+ fileKey;
59049
+ constructor(stateService, descriptor, journal) {
58920
59050
  this.stateService = stateService;
58921
59051
  this.descriptor = descriptor;
59052
+ this.journal = journal;
58922
59053
  if (descriptor.scope !== "session") {
58923
59054
  throw new Error(`SessionStateAccessor requires a session-scoped descriptor, got: ${descriptor.scope}`);
58924
59055
  }
59056
+ this.fileKey = descriptor.filename.replace(/\.json$/, "");
58925
59057
  }
58926
59058
  /**
58927
59059
  * Read session state file.
@@ -58939,9 +59071,15 @@ var require_typed_accessor = __commonJS({
58939
59071
  */
58940
59072
  async write(sessionId, data) {
58941
59073
  const path = this.stateService.sessionStatePath(sessionId, this.descriptor.filename);
58942
- return this.stateService.write(path, data, this.descriptor.schema, {
59074
+ await this.stateService.write(path, data, this.descriptor.schema, {
58943
59075
  trackHistory: this.descriptor.trackHistory
58944
59076
  });
59077
+ if (this.journal) {
59078
+ try {
59079
+ await this.journal.appendIfChanged(sessionId, this.fileKey, data);
59080
+ } catch {
59081
+ }
59082
+ }
58945
59083
  }
58946
59084
  /**
58947
59085
  * Delete session state file.
@@ -58949,6 +59087,12 @@ var require_typed_accessor = __commonJS({
58949
59087
  async delete(sessionId) {
58950
59088
  const path = this.stateService.sessionStatePath(sessionId, this.descriptor.filename);
58951
59089
  await this.stateService.delete(path);
59090
+ if (this.journal) {
59091
+ try {
59092
+ await this.journal.appendDeletion(sessionId, this.fileKey);
59093
+ } catch {
59094
+ }
59095
+ }
58952
59096
  }
58953
59097
  /**
58954
59098
  * Get the path for a session state file.
@@ -59214,8 +59358,51 @@ var require_transcript_normalizer = __commonJS({
59214
59358
  exports2.parseUuid = parseUuid;
59215
59359
  exports2.renderTranscriptString = renderTranscriptString;
59216
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
+ }
59217
59379
  function normalizeEntry(rawEntry, lineNumber) {
59218
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
+ }
59219
59406
  if (entryType !== "user" && entryType !== "assistant") {
59220
59407
  return null;
59221
59408
  }
@@ -59349,6 +59536,9 @@ var require_transcript_normalizer = __commonJS({
59349
59536
  return `[${timestamp}] ${role} TOOL_USE: ${String(toolContent.name)}`;
59350
59537
  } else if (type === "tool_result") {
59351
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}`;
59352
59542
  }
59353
59543
  return `[${timestamp}] ${role}: ${JSON.stringify(entry.content)}`;
59354
59544
  }).join("\n");
@@ -59367,6 +59557,7 @@ var require_transcript_excerpt_builder = __commonJS({
59367
59557
  exports2.extractTextContent = extractTextContent;
59368
59558
  exports2.getRawContentString = getRawContentString;
59369
59559
  var transcript_helpers_js_1 = require_transcript_helpers();
59560
+ var error_utils_js_1 = require_error_utils();
59370
59561
  function getBufferedEntries(buffer, head, count, bufferSize) {
59371
59562
  if (count === 0)
59372
59563
  return [];
@@ -59421,7 +59612,7 @@ var require_transcript_excerpt_builder = __commonJS({
59421
59612
  };
59422
59613
  } catch (err) {
59423
59614
  logger.error("Failed to extract transcript excerpt from buffer", {
59424
- error: err instanceof Error ? err.message : String(err)
59615
+ error: (0, error_utils_js_1.toErrorMessage)(err)
59425
59616
  });
59426
59617
  return {
59427
59618
  content: "",
@@ -59482,6 +59673,14 @@ var require_transcript_excerpt_builder = __commonJS({
59482
59673
  return null;
59483
59674
  }
59484
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
+ }
59485
59684
  default:
59486
59685
  return null;
59487
59686
  }
@@ -62340,6 +62539,7 @@ var require_instrumented_llm_provider = __commonJS({
62340
62539
  var node_path_1 = require("node:path");
62341
62540
  var yaml_1 = __importDefault(require_dist2());
62342
62541
  var types_1 = require_dist();
62542
+ var error_utils_js_1 = require_error_utils();
62343
62543
  var STATE_FILE = "llm-metrics.json";
62344
62544
  var DEFAULT_DEBOUNCE_MS = 500;
62345
62545
  function hasFallbackTracking(provider) {
@@ -62390,7 +62590,7 @@ var require_instrumented_llm_provider = __commonJS({
62390
62590
  }
62391
62591
  } catch (err) {
62392
62592
  this.config.logger.warn("Failed to load LLM metrics, starting fresh", {
62393
- error: err instanceof Error ? err.message : String(err)
62593
+ error: (0, error_utils_js_1.toErrorMessage)(err)
62394
62594
  });
62395
62595
  }
62396
62596
  }
@@ -62477,7 +62677,7 @@ var require_instrumented_llm_provider = __commonJS({
62477
62677
  this.config.logger.debug("Debug dump written", { path: basePath });
62478
62678
  } catch (dumpError) {
62479
62679
  this.config.logger.warn("Failed to write debug dump", {
62480
- error: dumpError instanceof Error ? dumpError.message : String(dumpError)
62680
+ error: (0, error_utils_js_1.toErrorMessage)(dumpError)
62481
62681
  });
62482
62682
  }
62483
62683
  }
@@ -62702,7 +62902,7 @@ var require_instrumented_llm_provider = __commonJS({
62702
62902
  });
62703
62903
  } catch (err) {
62704
62904
  this.config.logger.warn("Failed to persist LLM metrics", {
62705
- error: err instanceof Error ? err.message : String(err)
62905
+ error: (0, error_utils_js_1.toErrorMessage)(err)
62706
62906
  });
62707
62907
  }
62708
62908
  }
@@ -62978,6 +63178,7 @@ var require_daemon_health = __commonJS({
62978
63178
  var fs = __importStar(require("node:fs/promises"));
62979
63179
  var node_path_1 = require("node:path");
62980
63180
  var types_1 = require_dist();
63181
+ var error_utils_js_1 = require_error_utils();
62981
63182
  function healthFilePath(projectDir2) {
62982
63183
  return (0, node_path_1.join)(projectDir2, ".sidekick", "state", "daemon-health.json");
62983
63184
  }
@@ -63036,7 +63237,7 @@ var require_daemon_health = __commonJS({
63036
63237
  logger.warn("Failed to write daemon health", {
63037
63238
  from,
63038
63239
  to,
63039
- error: err instanceof Error ? err.message : String(err)
63240
+ error: (0, error_utils_js_1.toErrorMessage)(err)
63040
63241
  });
63041
63242
  return false;
63042
63243
  }
@@ -63123,6 +63324,7 @@ var require_user_profile_loader = __commonJS({
63123
63324
  var node_path_1 = require("node:path");
63124
63325
  var yaml_1 = require_dist2();
63125
63326
  var types_1 = require_dist();
63327
+ var error_utils_js_1 = require_error_utils();
63126
63328
  function loadUserProfile(options) {
63127
63329
  const home = options?.homeDir ?? (0, node_os_1.homedir)();
63128
63330
  const filePath = (0, node_path_1.join)(home, ".sidekick", "user.yaml");
@@ -63144,7 +63346,7 @@ var require_user_profile_loader = __commonJS({
63144
63346
  } catch (err) {
63145
63347
  options?.logger?.warn("Failed to read user profile", {
63146
63348
  path: filePath,
63147
- error: err instanceof Error ? err.message : String(err)
63349
+ error: (0, error_utils_js_1.toErrorMessage)(err)
63148
63350
  });
63149
63351
  return null;
63150
63352
  }
@@ -63211,9 +63413,9 @@ var require_dist4 = __commonJS({
63211
63413
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p);
63212
63414
  };
63213
63415
  Object.defineProperty(exports2, "__esModule", { value: true });
63214
- 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.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.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;
63215
- 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 = exports2.readKeyFromEnvFile = exports2.determineOverallStatus = void 0;
63216
- 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 = exports2.StateService = exports2.createHookableLogger = 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;
63217
63419
  var types_1 = require_dist();
63218
63420
  Object.defineProperty(exports2, "TaskTypes", { enumerable: true, get: function() {
63219
63421
  return types_1.TaskTypes;
@@ -63258,6 +63460,12 @@ var require_dist4 = __commonJS({
63258
63460
  Object.defineProperty(exports2, "isPreCompactEvent", { enumerable: true, get: function() {
63259
63461
  return types_2.isPreCompactEvent;
63260
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
+ } });
63261
63469
  __exportStar(require_assets(), exports2);
63262
63470
  var claude_paths_1 = require_claude_paths();
63263
63471
  Object.defineProperty(exports2, "encodeProjectPath", { enumerable: true, get: function() {
@@ -63378,9 +63586,6 @@ var require_dist4 = __commonJS({
63378
63586
  Object.defineProperty(exports2, "PROJECT_STATUS_FILENAME", { enumerable: true, get: function() {
63379
63587
  return setup_status_service_1.PROJECT_STATUS_FILENAME;
63380
63588
  } });
63381
- Object.defineProperty(exports2, "LEGACY_USER_STATUS_FILENAME", { enumerable: true, get: function() {
63382
- return setup_status_service_1.LEGACY_USER_STATUS_FILENAME;
63383
- } });
63384
63589
  var api_key_detector_1 = require_api_key_detector();
63385
63590
  Object.defineProperty(exports2, "toScopeStatus", { enumerable: true, get: function() {
63386
63591
  return api_key_detector_1.toScopeStatus;
@@ -63449,12 +63654,21 @@ var require_dist4 = __commonJS({
63449
63654
  Object.defineProperty(exports2, "detectGitignoreStatus", { enumerable: true, get: function() {
63450
63655
  return gitignore_1.detectGitignoreStatus;
63451
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
+ } });
63452
63663
  Object.defineProperty(exports2, "SIDEKICK_SECTION_START", { enumerable: true, get: function() {
63453
63664
  return gitignore_1.SIDEKICK_SECTION_START;
63454
63665
  } });
63455
63666
  Object.defineProperty(exports2, "SIDEKICK_SECTION_END", { enumerable: true, get: function() {
63456
63667
  return gitignore_1.SIDEKICK_SECTION_END;
63457
63668
  } });
63669
+ Object.defineProperty(exports2, "SIDEKICK_GITIGNORE_HEADER", { enumerable: true, get: function() {
63670
+ return gitignore_1.SIDEKICK_GITIGNORE_HEADER;
63671
+ } });
63458
63672
  Object.defineProperty(exports2, "GITIGNORE_ENTRIES", { enumerable: true, get: function() {
63459
63673
  return gitignore_1.GITIGNORE_ENTRIES;
63460
63674
  } });
@@ -63607,6 +63821,10 @@ var require_dist4 = __commonJS({
63607
63821
  Object.defineProperty(exports2, "isInSandbox", { enumerable: true, get: function() {
63608
63822
  return sandbox_1.isInSandbox;
63609
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
+ } });
63610
63828
  var git_status_1 = require_git_status();
63611
63829
  Object.defineProperty(exports2, "getGitFileStatus", { enumerable: true, get: function() {
63612
63830
  return git_status_1.getGitFileStatus;
@@ -70642,6 +70860,7 @@ var require_reminder_utils = __commonJS({
70642
70860
  var node_path_1 = require("node:path");
70643
70861
  var yaml = __importStar(require_js_yaml());
70644
70862
  var zod_1 = require_zod2();
70863
+ var core_1 = require_dist4();
70645
70864
  var ReminderDefinitionSchema = zod_1.z.object({
70646
70865
  id: zod_1.z.string(),
70647
70866
  blocking: zod_1.z.boolean(),
@@ -70694,7 +70913,7 @@ var require_reminder_utils = __commonJS({
70694
70913
  if (logger) {
70695
70914
  logger.error("Failed to load reminder", {
70696
70915
  reminderId,
70697
- error: err instanceof Error ? err.message : String(err)
70916
+ error: (0, core_1.toErrorMessage)(err)
70698
70917
  });
70699
70918
  } else {
70700
70919
  console.error(`Failed to load reminder ${reminderId}:`, err);
@@ -71434,7 +71653,7 @@ var require_stage_pause_and_reflect = __commonJS({
71434
71653
  (0, staging_handler_utils_js_1.createStagingHandler)(context, {
71435
71654
  id: "reminders:stage-pause-and-reflect",
71436
71655
  priority: 80,
71437
- filter: { kind: "transcript", eventTypes: ["ToolCall"] },
71656
+ filter: { kind: "transcript", eventTypes: ["ToolResult"] },
71438
71657
  execute: async (event, ctx) => {
71439
71658
  if (!(0, types_1.isTranscriptEvent)(event))
71440
71659
  return void 0;
@@ -73117,17 +73336,15 @@ var require_track_verification_tools = __commonJS({
73117
73336
  var state_js_1 = require_state4();
73118
73337
  var FILE_EDIT_TOOLS = ["Write", "Edit", "MultiEdit"];
73119
73338
  var VC_TOOL_NAME_SET = new Set(types_js_1.VC_TOOL_REMINDER_IDS);
73120
- function extractToolInput(event) {
73121
- const entry = event.payload.entry;
73122
- return entry?.input;
73123
- }
73339
+ var MAX_PENDING_TOOL_CALLS = 100;
73124
73340
  function registerTrackVerificationTools(context) {
73125
73341
  if (!(0, types_1.isDaemonContext)(context))
73126
73342
  return;
73343
+ const pendingBySession = /* @__PURE__ */ new Map();
73127
73344
  context.handlers.register({
73128
73345
  id: "reminders:track-verification-tools",
73129
73346
  priority: 60,
73130
- filter: { kind: "transcript", eventTypes: ["ToolCall"] },
73347
+ filter: { kind: "transcript", eventTypes: ["ToolCall", "ToolResult"] },
73131
73348
  handler: async (event, ctx) => {
73132
73349
  if (!(0, types_1.isTranscriptEvent)(event))
73133
73350
  return;
@@ -73139,22 +73356,66 @@ var require_track_verification_tools = __commonJS({
73139
73356
  const sessionId = event.context?.sessionId;
73140
73357
  if (!sessionId)
73141
73358
  return;
73142
- const toolName = event.payload.toolName;
73143
- 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 });
73144
73377
  return;
73145
- const config = (0, types_js_1.getRemindersConfig)(context.config);
73146
- const verificationTools = config.verification_tools ?? {};
73147
- const runners = config.command_runners ?? [];
73148
- const remindersState = (0, state_js_1.createRemindersState)(daemonCtx.stateService);
73149
- const stateResult = await remindersState.verificationTools.read(sessionId);
73150
- const toolsState = { ...stateResult.data };
73151
- if (FILE_EDIT_TOOLS.includes(toolName)) {
73152
- await handleFileEdit(event, daemonCtx, sessionId, verificationTools, toolsState, remindersState);
73153
- } else if (toolName === "Bash") {
73154
- 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
+ }
73155
73402
  }
73156
73403
  }
73157
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
+ });
73158
73419
  }
73159
73420
  async function stageToolsForFiles(filePaths, daemonCtx, sessionId, verificationTools, toolsState, remindersState, triggeredBy = "file_edit") {
73160
73421
  const existingReminders = await daemonCtx.staging.listReminders("Stop");
@@ -73259,7 +73520,7 @@ var require_track_verification_tools = __commonJS({
73259
73520
  toolName,
73260
73521
  reminderId,
73261
73522
  sessionId,
73262
- error: error instanceof Error ? error.message : String(error)
73523
+ error: (0, core_1.toErrorMessage)(error)
73263
73524
  });
73264
73525
  }
73265
73526
  }
@@ -73273,8 +73534,8 @@ var require_track_verification_tools = __commonJS({
73273
73534
  await remindersState.verificationTools.write(sessionId, toolsState);
73274
73535
  return anyStaged;
73275
73536
  }
73276
- async function handleFileEdit(event, daemonCtx, sessionId, verificationTools, toolsState, remindersState) {
73277
- const filePath = extractToolInput(event)?.file_path;
73537
+ async function handleFileEdit(input, daemonCtx, sessionId, verificationTools, toolsState, remindersState) {
73538
+ const filePath = input.file_path;
73278
73539
  if (!filePath)
73279
73540
  return;
73280
73541
  const projectDir2 = daemonCtx.paths?.projectDir;
@@ -73282,8 +73543,8 @@ var require_track_verification_tools = __commonJS({
73282
73543
  return;
73283
73544
  await stageToolsForFiles([filePath], daemonCtx, sessionId, verificationTools, toolsState, remindersState);
73284
73545
  }
73285
- async function handleBashCommand(event, daemonCtx, sessionId, verificationTools, toolsState, remindersState, runners = []) {
73286
- const command = extractToolInput(event)?.command;
73546
+ async function handleBashCommand(input, daemonCtx, sessionId, verificationTools, toolsState, remindersState, runners = []) {
73547
+ const command = input.command;
73287
73548
  if (!command)
73288
73549
  return;
73289
73550
  let anyUnstaged = false;
@@ -73712,7 +73973,7 @@ var require_stage_persona_reminders = __commonJS({
73712
73973
  } catch (err) {
73713
73974
  logger.error("Failed to restage persona reminders", {
73714
73975
  sessionId,
73715
- error: err instanceof Error ? err.message : String(err)
73976
+ error: (0, core_1.toErrorMessage)(err)
73716
73977
  });
73717
73978
  }
73718
73979
  }
@@ -73948,6 +74209,38 @@ var require_stage_user_profile_reminders = __commonJS({
73948
74209
  }
73949
74210
  });
73950
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
+
73951
74244
  // ../feature-reminders/dist/handlers/staging/index.js
73952
74245
  var require_staging2 = __commonJS({
73953
74246
  "../feature-reminders/dist/handlers/staging/index.js"(exports2) {
@@ -73961,6 +74254,7 @@ var require_staging2 = __commonJS({
73961
74254
  var unstage_verify_completion_1 = require_unstage_verify_completion();
73962
74255
  var stage_persona_reminders_1 = require_stage_persona_reminders();
73963
74256
  var stage_user_profile_reminders_1 = require_stage_user_profile_reminders();
74257
+ var cleanup_on_stop_1 = require_cleanup_on_stop();
73964
74258
  function registerStagingHandlers(context) {
73965
74259
  (0, stage_default_user_prompt_1.registerStageDefaultUserPrompt)(context);
73966
74260
  (0, stage_pause_and_reflect_1.registerStagePauseAndReflect)(context);
@@ -73969,6 +74263,7 @@ var require_staging2 = __commonJS({
73969
74263
  (0, unstage_verify_completion_1.registerUnstageVerifyCompletion)(context);
73970
74264
  (0, stage_persona_reminders_1.registerStagePersonaReminders)(context);
73971
74265
  (0, stage_user_profile_reminders_1.registerStageUserProfileReminders)(context);
74266
+ (0, cleanup_on_stop_1.registerCleanupOnStop)(context);
73972
74267
  }
73973
74268
  }
73974
74269
  });
@@ -74689,7 +74984,7 @@ var require_orchestrator = __commonJS({
74689
74984
  } catch (err) {
74690
74985
  this.deps.logger.warn("Failed to unstage VC reminders after P&R staged", {
74691
74986
  sessionId,
74692
- error: err instanceof Error ? err.message : String(err)
74987
+ error: (0, core_1.toErrorMessage)(err)
74693
74988
  });
74694
74989
  }
74695
74990
  }
@@ -74713,27 +75008,10 @@ var require_orchestrator = __commonJS({
74713
75008
  } catch (err) {
74714
75009
  this.deps.logger.warn("Failed to reset P&R baseline after VC consumed", {
74715
75010
  sessionId,
74716
- error: err instanceof Error ? err.message : String(err)
74717
- });
74718
- }
74719
- try {
74720
- const staging = this.deps.getStagingService(sessionId);
74721
- const deleted = await staging.deleteReminder("PreToolUse", types_js_1.ReminderIds.PAUSE_AND_REFLECT);
74722
- if (deleted) {
74723
- (0, core_1.logEvent)(this.deps.logger.child({ context: { sessionId } }), events_js_1.ReminderEvents.reminderUnstaged({ sessionId }, {
74724
- reminderName: types_js_1.ReminderIds.PAUSE_AND_REFLECT,
74725
- hookName: "PreToolUse",
74726
- reason: "vc_consumed_cascade",
74727
- triggeredBy: "cascade_from_verify_completion"
74728
- }));
74729
- }
74730
- this.deps.logger.debug("VC unstage: P&R cascade from VC consumed", { sessionId, deleted });
74731
- } catch (err) {
74732
- this.deps.logger.warn("Failed to unstage P&R after VC consumed", {
74733
- sessionId,
74734
- error: err instanceof Error ? err.message : String(err)
75011
+ error: (0, core_1.toErrorMessage)(err)
74735
75012
  });
74736
75013
  }
75014
+ await this.unstagePauseAndReflect(sessionId, "vc_consumed_cascade", "cascade_from_verify_completion");
74737
75015
  }
74738
75016
  }
74739
75017
  /**
@@ -74750,7 +75028,43 @@ var require_orchestrator = __commonJS({
74750
75028
  } catch (err) {
74751
75029
  this.deps.logger.warn("Failed to clear P&R baseline on UserPromptSubmit", {
74752
75030
  sessionId,
74753
- 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)
74754
75068
  });
74755
75069
  }
74756
75070
  }
@@ -75146,7 +75460,7 @@ var require_persona_selection = __commonJS({
75146
75460
  } catch (err) {
75147
75461
  ctx.logger.warn("Failed to ensure persona for session", {
75148
75462
  sessionId,
75149
- error: err instanceof Error ? err.message : String(err)
75463
+ error: (0, core_1.toErrorMessage)(err)
75150
75464
  });
75151
75465
  }
75152
75466
  }
@@ -75906,7 +76220,7 @@ var require_update_summary = __commonJS({
75906
76220
  ctx.logger.error("performAnalysis failed", {
75907
76221
  sessionId,
75908
76222
  reason,
75909
- error: err instanceof Error ? err.message : String(err)
76223
+ error: (0, core_1.toErrorMessage)(err)
75910
76224
  });
75911
76225
  }
75912
76226
  }
@@ -76233,6 +76547,7 @@ var require_config_watcher = __commonJS({
76233
76547
  };
76234
76548
  Object.defineProperty(exports2, "__esModule", { value: true });
76235
76549
  exports2.ConfigWatcher = void 0;
76550
+ var core_1 = require_dist4();
76236
76551
  var chokidar_1 = (init_chokidar(), __toCommonJS(chokidar_exports));
76237
76552
  var os_1 = require("os");
76238
76553
  var path_1 = __importDefault(require("path"));
@@ -76363,7 +76678,7 @@ var require_config_watcher = __commonJS({
76363
76678
  } catch (err) {
76364
76679
  this.logger.error("Error in config change handler", {
76365
76680
  file: filename,
76366
- error: err instanceof Error ? err.message : String(err)
76681
+ error: (0, core_1.toErrorMessage)(err)
76367
76682
  });
76368
76683
  }
76369
76684
  }, this.debounceMs);
@@ -76396,6 +76711,7 @@ var require_session_persona_watcher = __commonJS({
76396
76711
  Object.defineProperty(exports2, "__esModule", { value: true });
76397
76712
  exports2.SessionPersonaWatcher = void 0;
76398
76713
  exports2.extractSessionIdFromPath = extractSessionIdFromPath;
76714
+ var core_1 = require_dist4();
76399
76715
  var chokidar_1 = (init_chokidar(), __toCommonJS(chokidar_exports));
76400
76716
  var path_1 = __importDefault(require("path"));
76401
76717
  var PERSONA_FILENAME = "session-persona.json";
@@ -76516,7 +76832,7 @@ var require_session_persona_watcher = __commonJS({
76516
76832
  } catch (err) {
76517
76833
  this.logger.error("Error in persona change handler", {
76518
76834
  sessionId,
76519
- error: err instanceof Error ? err.message : String(err)
76835
+ error: (0, core_1.toErrorMessage)(err)
76520
76836
  });
76521
76837
  }
76522
76838
  }, this.debounceMs);
@@ -76813,7 +77129,7 @@ var require_context_metrics_service = __commonJS({
76813
77129
  this.logger.info("Triggering async CLI capture for base metrics");
76814
77130
  void this.captureBaseMetrics().catch((err) => {
76815
77131
  this.logger.warn("Failed to capture base metrics via CLI", {
76816
- error: err instanceof Error ? err.message : String(err),
77132
+ error: (0, core_1.toErrorMessage)(err),
76817
77133
  stack: err instanceof Error ? err.stack : void 0
76818
77134
  });
76819
77135
  });
@@ -76939,7 +77255,7 @@ var require_context_metrics_service = __commonJS({
76939
77255
  sessionId
76940
77256
  });
76941
77257
  } catch (err) {
76942
- const errorMessage = err instanceof Error ? err.message : String(err);
77258
+ const errorMessage = (0, core_1.toErrorMessage)(err);
76943
77259
  this.logger.warn("CLI capture failed", {
76944
77260
  error: errorMessage,
76945
77261
  stack: err instanceof Error ? err.stack : void 0
@@ -77231,7 +77547,7 @@ var require_cleanup_handler = __commonJS({
77231
77547
  } catch (statErr) {
77232
77548
  ctx.logger.warn("Failed to stat session directory", {
77233
77549
  session: entry.name,
77234
- error: statErr instanceof Error ? statErr.message : String(statErr)
77550
+ error: (0, core_1.toErrorMessage)(statErr)
77235
77551
  });
77236
77552
  }
77237
77553
  }
@@ -77247,7 +77563,7 @@ var require_cleanup_handler = __commonJS({
77247
77563
  return;
77248
77564
  }
77249
77565
  ctx.logger.error("Cleanup task failed", {
77250
- error: err instanceof Error ? err.message : String(err)
77566
+ error: (0, core_1.toErrorMessage)(err)
77251
77567
  });
77252
77568
  throw err;
77253
77569
  }
@@ -77423,6 +77739,7 @@ var require_task_engine = __commonJS({
77423
77739
  };
77424
77740
  Object.defineProperty(exports2, "__esModule", { value: true });
77425
77741
  exports2.TaskEngine = exports2.TaskTimeoutError = void 0;
77742
+ var core_1 = require_dist4();
77426
77743
  var crypto_1 = __importDefault(require("crypto"));
77427
77744
  var DEFAULT_TASK_TIMEOUT_MS = 5 * 60 * 1e3;
77428
77745
  var TaskTimeoutError = class extends Error {
@@ -77551,7 +77868,7 @@ var require_task_engine = __commonJS({
77551
77868
  this.logger.error("Task failed", {
77552
77869
  type: task.type,
77553
77870
  id: task.id,
77554
- error: err instanceof Error ? err.message : String(err),
77871
+ error: (0, core_1.toErrorMessage)(err),
77555
77872
  stack: err instanceof Error ? err.stack : void 0,
77556
77873
  durationMs
77557
77874
  });
@@ -77871,7 +78188,7 @@ var require_daemon_timer_manager = __commonJS({
77871
78188
  this.deps.logger.info("Project registered for UI discovery", { projectDir: this.deps.projectDir });
77872
78189
  } catch (err) {
77873
78190
  this.deps.logger.warn("Failed to register project", {
77874
- error: err instanceof Error ? err.message : String(err)
78191
+ error: (0, core_1.toErrorMessage)(err)
77875
78192
  });
77876
78193
  }
77877
78194
  }
@@ -78035,7 +78352,7 @@ var require_daemon_log_metrics = __commonJS({
78035
78352
  await this.daemonStatusAccessor.write(status);
78036
78353
  } catch (err) {
78037
78354
  this.logger?.warn("Failed to write heartbeat status", {
78038
- error: err instanceof Error ? err.message : String(err)
78355
+ error: (0, core_1.toErrorMessage)(err)
78039
78356
  });
78040
78357
  }
78041
78358
  await this.persistLogMetrics();
@@ -78077,7 +78394,7 @@ var require_daemon_log_metrics = __commonJS({
78077
78394
  } catch (err) {
78078
78395
  this.logger?.warn("Failed to persist log metrics", {
78079
78396
  sessionId,
78080
- error: err instanceof Error ? err.message : String(err)
78397
+ error: (0, core_1.toErrorMessage)(err)
78081
78398
  });
78082
78399
  }
78083
78400
  }
@@ -78090,7 +78407,7 @@ var require_daemon_log_metrics = __commonJS({
78090
78407
  await this.globalLogMetricsAccessor.write(globalMetrics);
78091
78408
  } catch (err) {
78092
78409
  this.logger?.warn("Failed to persist global log metrics", {
78093
- error: err instanceof Error ? err.message : String(err)
78410
+ error: (0, core_1.toErrorMessage)(err)
78094
78411
  });
78095
78412
  }
78096
78413
  }
@@ -78543,7 +78860,7 @@ var require_daemon = __commonJS({
78543
78860
  this.logger.info("Configuration reloaded successfully");
78544
78861
  } catch (err) {
78545
78862
  this.logger.error("Failed to reload configuration", {
78546
- error: err instanceof Error ? err.message : String(err)
78863
+ error: (0, core_1.toErrorMessage)(err)
78547
78864
  });
78548
78865
  }
78549
78866
  }
@@ -78586,7 +78903,7 @@ var require_daemon = __commonJS({
78586
78903
  } catch (err) {
78587
78904
  this.logger.error("Failed to stage persona reminders on change", {
78588
78905
  sessionId: event.sessionId,
78589
- error: err instanceof Error ? err.message : String(err)
78906
+ error: (0, core_1.toErrorMessage)(err)
78590
78907
  });
78591
78908
  }
78592
78909
  }
@@ -78618,7 +78935,7 @@ var require_daemon = __commonJS({
78618
78935
  } catch (err) {
78619
78936
  this.logger.error("Failed to regenerate messages after persona change", {
78620
78937
  sessionId,
78621
- error: err instanceof Error ? err.message : String(err)
78938
+ error: (0, core_1.toErrorMessage)(err)
78622
78939
  });
78623
78940
  }
78624
78941
  }
@@ -78782,7 +79099,7 @@ var require_daemon = __commonJS({
78782
79099
  }
78783
79100
  } catch (err) {
78784
79101
  log.warn("Failed to cache persona for clear handoff", {
78785
- error: err instanceof Error ? err.message : String(err)
79102
+ error: (0, core_1.toErrorMessage)(err)
78786
79103
  });
78787
79104
  }
78788
79105
  } else {