@scotthamilton77/sidekick 0.1.19 → 0.1.21

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);
@@ -45557,22 +45632,27 @@ var require_package3 = __commonJS({
45557
45632
  pnpm: {
45558
45633
  overrides: {
45559
45634
  ajv: ">=6.14.0 <7",
45560
- minimatch: ">=10.2.1"
45635
+ minimatch: ">=10.2.1",
45636
+ "vite@^7.0.0": "^7.3.2",
45637
+ "picomatch@^4.0.0": "^4.0.4",
45638
+ "picomatch@^2.0.0": "^2.3.2",
45639
+ "flatted@^3.0.0": "^3.4.2",
45640
+ "postcss@^8.0.0": "^8.5.10"
45561
45641
  }
45562
45642
  },
45563
45643
  devDependencies: {
45564
45644
  "@eslint/js": "^10.0.1",
45565
- "@types/node": "^22.7.4",
45566
- "@typescript-eslint/eslint-plugin": "^8.56.0",
45567
- "@typescript-eslint/parser": "^8.56.0",
45568
- "@vitest/coverage-v8": "^4.0.18",
45569
- eslint: "^10.0.1",
45570
- "eslint-config-prettier": "^9.1.0",
45571
- "eslint-plugin-prettier": "^5.1.3",
45572
- prettier: "^3.2.5",
45645
+ "@types/node": "^22.19.17",
45646
+ "@typescript-eslint/eslint-plugin": "^8.59.1",
45647
+ "@typescript-eslint/parser": "^8.59.1",
45648
+ "@vitest/coverage-v8": "^4.1.5",
45649
+ eslint: "^10.3.0",
45650
+ "eslint-config-prettier": "^9.1.2",
45651
+ "eslint-plugin-prettier": "^5.5.5",
45652
+ prettier: "^3.8.3",
45573
45653
  typescript: "^5.9.3",
45574
- "typescript-eslint": "^8.56.0",
45575
- vitest: "^4.0.18"
45654
+ "typescript-eslint": "^8.59.1",
45655
+ vitest: "^4.1.5"
45576
45656
  }
45577
45657
  };
45578
45658
  }
@@ -45597,13 +45677,11 @@ var require_daemon_client2 = __commonJS({
45597
45677
  var client_js_1 = require_client();
45598
45678
  var transport_js_1 = require_transport();
45599
45679
  var sandbox_js_1 = require_sandbox();
45680
+ var error_utils_js_1 = require_error_utils();
45600
45681
  var LOCK_TIMEOUT_MS = 1e4;
45601
45682
  var LOCK_RETRY_INTERVAL_MS = 100;
45602
45683
  var LOCK_STALE_THRESHOLD_MS = 3e4;
45603
45684
  var CLIENT_VERSION = require_package3().version;
45604
- function toErrorMsg(err) {
45605
- return err instanceof Error ? err.message : String(err);
45606
- }
45607
45685
  var DaemonClient = class {
45608
45686
  projectDir;
45609
45687
  logger;
@@ -45969,7 +46047,7 @@ var require_daemon_client2 = __commonJS({
45969
46047
  } catch (err) {
45970
46048
  logger.debug("Graceful stop failed, falling back to SIGKILL", {
45971
46049
  pid: info.pid,
45972
- error: toErrorMsg(err)
46050
+ error: (0, error_utils_js_1.toErrorMessage)(err)
45973
46051
  });
45974
46052
  }
45975
46053
  }
@@ -45978,7 +46056,7 @@ var require_daemon_client2 = __commonJS({
45978
46056
  logger.info("Killed daemon", { pid: info.pid, projectDir: info.projectDir });
45979
46057
  results.push({ projectDir: info.projectDir, pid: info.pid, killed: true });
45980
46058
  } catch (err) {
45981
- const msg = toErrorMsg(err);
46059
+ const msg = (0, error_utils_js_1.toErrorMessage)(err);
45982
46060
  logger.warn("Failed to kill daemon", { pid: info.pid, error: msg });
45983
46061
  results.push({ projectDir: info.projectDir, pid: info.pid, killed: false, error: msg });
45984
46062
  }
@@ -45990,7 +46068,7 @@ var require_daemon_client2 = __commonJS({
45990
46068
  });
45991
46069
  }
45992
46070
  } catch (err) {
45993
- logger.warn("Invalid PID file, removing", { pidFile, error: toErrorMsg(err) });
46071
+ logger.warn("Invalid PID file, removing", { pidFile, error: (0, error_utils_js_1.toErrorMessage)(err) });
45994
46072
  await promises_1.default.unlink(pidPath).catch(() => {
45995
46073
  });
45996
46074
  }
@@ -46011,7 +46089,7 @@ var require_daemon_client2 = __commonJS({
46011
46089
  });
46012
46090
  } catch (err) {
46013
46091
  logger.warn("Failed to run ps \u2014 cannot detect zombie daemons", {
46014
- error: toErrorMsg(err)
46092
+ error: (0, error_utils_js_1.toErrorMessage)(err)
46015
46093
  });
46016
46094
  return [];
46017
46095
  }
@@ -46072,7 +46150,7 @@ var require_daemon_client2 = __commonJS({
46072
46150
  logger.info("Killed zombie daemon", { pid: zombie.pid, command: zombie.command });
46073
46151
  results.push({ projectDir: "unknown", pid: zombie.pid, killed: true });
46074
46152
  } catch (err) {
46075
- const msg = toErrorMsg(err);
46153
+ const msg = (0, error_utils_js_1.toErrorMessage)(err);
46076
46154
  logger.warn("Failed to kill zombie daemon", { pid: zombie.pid, error: msg });
46077
46155
  results.push({ projectDir: "unknown", pid: zombie.pid, killed: false, error: msg });
46078
46156
  }
@@ -46124,60 +46202,94 @@ var require_gitignore = __commonJS({
46124
46202
  };
46125
46203
  })();
46126
46204
  Object.defineProperty(exports2, "__esModule", { value: true });
46127
- exports2.GITIGNORE_ENTRIES = exports2.SIDEKICK_SECTION_END = exports2.SIDEKICK_SECTION_START = void 0;
46205
+ exports2.GITIGNORE_ENTRIES = exports2.SIDEKICK_GITIGNORE_HEADER = exports2.SIDEKICK_SECTION_END = exports2.SIDEKICK_SECTION_START = void 0;
46128
46206
  exports2.installGitignoreSection = installGitignoreSection;
46129
- exports2.removeGitignoreSection = removeGitignoreSection;
46130
46207
  exports2.detectGitignoreStatus = detectGitignoreStatus;
46208
+ exports2.removeGitignoreSection = removeGitignoreSection;
46209
+ exports2.detectLegacyGitignoreSection = detectLegacyGitignoreSection;
46210
+ exports2.removeLegacyGitignoreSection = removeLegacyGitignoreSection;
46131
46211
  var fs = __importStar(require("node:fs/promises"));
46132
46212
  var path = __importStar(require("node:path"));
46133
46213
  exports2.SIDEKICK_SECTION_START = "# >>> sidekick";
46134
46214
  exports2.SIDEKICK_SECTION_END = "# <<< sidekick";
46215
+ exports2.SIDEKICK_GITIGNORE_HEADER = "# Sidekick \u2014 managed file, do not edit manually";
46135
46216
  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"
46217
+ "logs/",
46218
+ "sessions/",
46219
+ "state/",
46220
+ "setup-status.json",
46221
+ ".env",
46222
+ ".env.local",
46223
+ "sidekick*.pid",
46224
+ "sidekick*.token",
46225
+ "*.local.yaml"
46145
46226
  ];
46146
46227
  async function installGitignoreSection(projectDir2) {
46147
- const gitignorePath = path.join(projectDir2, ".gitignore");
46148
- let content = "";
46228
+ let status;
46149
46229
  try {
46150
- content = await fs.readFile(gitignorePath, "utf-8");
46230
+ status = await detectGitignoreStatus(projectDir2);
46151
46231
  } catch (err) {
46152
- if (err.code !== "ENOENT") {
46153
- return { status: "error", error: `Failed to read .gitignore: ${err.message}` };
46154
- }
46232
+ return { status: "error", error: `Failed to check gitignore status: ${err.message}` };
46155
46233
  }
46156
- const status = await detectGitignoreStatus(projectDir2);
46157
46234
  if (status === "installed") {
46158
46235
  return { status: "already-installed" };
46159
46236
  }
46160
- if (status === "incomplete") {
46161
- await removeGitignoreSection(projectDir2);
46162
- try {
46163
- content = await fs.readFile(gitignorePath, "utf-8");
46164
- } catch {
46165
- content = "";
46166
- }
46237
+ const sidekickDir = path.join(projectDir2, ".sidekick");
46238
+ try {
46239
+ await fs.mkdir(sidekickDir, { recursive: true });
46240
+ } catch (err) {
46241
+ return { status: "error", error: `Failed to create .sidekick directory: ${err.message}` };
46167
46242
  }
46168
- const section = ["", exports2.SIDEKICK_SECTION_START, ...exports2.GITIGNORE_ENTRIES, exports2.SIDEKICK_SECTION_END].join("\n");
46169
- const newContent = content.trimEnd() + section + "\n";
46243
+ const content = [exports2.SIDEKICK_GITIGNORE_HEADER, ...exports2.GITIGNORE_ENTRIES].join("\n") + "\n";
46170
46244
  try {
46171
- await fs.writeFile(gitignorePath, newContent);
46245
+ await fs.writeFile(path.join(sidekickDir, ".gitignore"), content);
46172
46246
  return { status: "installed", entriesAdded: exports2.GITIGNORE_ENTRIES };
46173
46247
  } catch (err) {
46174
- return { status: "error", error: `Failed to write .gitignore: ${err.message}` };
46248
+ return { status: "error", error: `Failed to write .sidekick/.gitignore: ${err.message}` };
46249
+ }
46250
+ }
46251
+ async function detectGitignoreStatus(projectDir2) {
46252
+ const sidekickGitignorePath = path.join(projectDir2, ".sidekick", ".gitignore");
46253
+ try {
46254
+ const content = await fs.readFile(sidekickGitignorePath, "utf-8");
46255
+ const missingEntries = exports2.GITIGNORE_ENTRIES.filter((entry) => !content.includes(entry));
46256
+ return missingEntries.length === 0 ? "installed" : "incomplete";
46257
+ } catch (err) {
46258
+ if (err.code !== "ENOENT") {
46259
+ throw err;
46260
+ }
46175
46261
  }
46262
+ const hasLegacy = await detectLegacyGitignoreSection(projectDir2);
46263
+ return hasLegacy ? "legacy" : "missing";
46176
46264
  }
46177
46265
  async function removeGitignoreSection(projectDir2) {
46178
- const gitignorePath = path.join(projectDir2, ".gitignore");
46266
+ let removed = false;
46267
+ try {
46268
+ await fs.unlink(path.join(projectDir2, ".sidekick", ".gitignore"));
46269
+ removed = true;
46270
+ } catch (err) {
46271
+ if (err.code !== "ENOENT") {
46272
+ throw err;
46273
+ }
46274
+ }
46275
+ const legacyRemoved = await removeLegacyGitignoreSection(projectDir2);
46276
+ return removed || legacyRemoved;
46277
+ }
46278
+ async function detectLegacyGitignoreSection(projectDir2) {
46279
+ try {
46280
+ const content = await fs.readFile(path.join(projectDir2, ".gitignore"), "utf-8");
46281
+ return content.includes(exports2.SIDEKICK_SECTION_START);
46282
+ } catch (err) {
46283
+ if (err.code === "ENOENT") {
46284
+ return false;
46285
+ }
46286
+ throw err;
46287
+ }
46288
+ }
46289
+ async function removeLegacyGitignoreSection(projectDir2) {
46290
+ const rootGitignorePath = path.join(projectDir2, ".gitignore");
46179
46291
  try {
46180
- const content = await fs.readFile(gitignorePath, "utf-8");
46292
+ const content = await fs.readFile(rootGitignorePath, "utf-8");
46181
46293
  const startIdx = content.indexOf(exports2.SIDEKICK_SECTION_START);
46182
46294
  const endIdx = content.indexOf(exports2.SIDEKICK_SECTION_END);
46183
46295
  if (startIdx === -1 || endIdx === -1 || endIdx < startIdx) {
@@ -46189,37 +46301,13 @@ var require_gitignore = __commonJS({
46189
46301
  const before = content.slice(0, lineStartIdx).trimEnd();
46190
46302
  const after = content.slice(actualEndIdx).trimStart();
46191
46303
  const newContent = before + (after ? "\n" + after : "") + "\n";
46192
- await fs.writeFile(gitignorePath, newContent);
46304
+ await fs.writeFile(rootGitignorePath, newContent);
46193
46305
  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";
46306
+ } catch (err) {
46307
+ if (err.code === "ENOENT") {
46308
+ return false;
46219
46309
  }
46220
- return "installed";
46221
- } catch {
46222
- return "missing";
46310
+ throw err;
46223
46311
  }
46224
46312
  }
46225
46313
  }
@@ -46230,7 +46318,7 @@ var require_errors4 = __commonJS({
46230
46318
  "../shared-providers/dist/errors.js"(exports2) {
46231
46319
  "use strict";
46232
46320
  Object.defineProperty(exports2, "__esModule", { value: true });
46233
- exports2.TimeoutError = exports2.AuthError = exports2.RateLimitError = exports2.ProviderError = void 0;
46321
+ exports2.MalformedResponseError = exports2.TimeoutError = exports2.AuthError = exports2.RateLimitError = exports2.ProviderError = void 0;
46234
46322
  var ProviderError = class _ProviderError extends Error {
46235
46323
  provider;
46236
46324
  retryable;
@@ -46271,6 +46359,18 @@ var require_errors4 = __commonJS({
46271
46359
  }
46272
46360
  };
46273
46361
  exports2.TimeoutError = TimeoutError;
46362
+ var MalformedResponseError = class _MalformedResponseError extends ProviderError {
46363
+ code;
46364
+ providerMessage;
46365
+ constructor(provider, code, providerMessage, cause) {
46366
+ super(`Malformed response from ${provider}: ${code ?? "unknown"} - ${providerMessage ?? "no message"}`, provider, false, cause);
46367
+ this.name = "MalformedResponseError";
46368
+ this.code = code;
46369
+ this.providerMessage = providerMessage;
46370
+ Object.setPrototypeOf(this, _MalformedResponseError.prototype);
46371
+ }
46372
+ };
46373
+ exports2.MalformedResponseError = MalformedResponseError;
46274
46374
  }
46275
46375
  });
46276
46376
 
@@ -55249,6 +55349,7 @@ var require_base = __commonJS({
55249
55349
  model: response.model,
55250
55350
  durationMs,
55251
55351
  usage: response.usage,
55352
+ finishReason: response.finishReason,
55252
55353
  status: response.rawResponse.status,
55253
55354
  contentLength: response.content.length
55254
55355
  });
@@ -55296,6 +55397,7 @@ var require_openai_native = __commonJS({
55296
55397
  maxTokens;
55297
55398
  providerAllowlist;
55298
55399
  providerBlocklist;
55400
+ reasoning;
55299
55401
  constructor(config, logger) {
55300
55402
  super(logger);
55301
55403
  this.id = config.baseURL?.includes("openrouter") ? "openrouter" : "openai";
@@ -55304,6 +55406,7 @@ var require_openai_native = __commonJS({
55304
55406
  this.maxTokens = config.maxTokens;
55305
55407
  this.providerAllowlist = config.providerAllowlist;
55306
55408
  this.providerBlocklist = config.providerBlocklist;
55409
+ this.reasoning = config.reasoning;
55307
55410
  this.client = new openai_1.default({
55308
55411
  apiKey: config.apiKey,
55309
55412
  baseURL: config.baseURL,
@@ -55319,6 +55422,7 @@ var require_openai_native = __commonJS({
55319
55422
  maxTokens: this.maxTokens,
55320
55423
  providerAllowlist: this.providerAllowlist,
55321
55424
  providerBlocklist: this.providerBlocklist,
55425
+ reasoning: this.reasoning,
55322
55426
  apiKey: this.redactApiKey(config.apiKey)
55323
55427
  });
55324
55428
  }
@@ -55336,6 +55440,7 @@ var require_openai_native = __commonJS({
55336
55440
  }
55337
55441
  } : void 0;
55338
55442
  const providerRouting = this.buildProviderRouting();
55443
+ const reasoningParam = this.buildReasoningParam();
55339
55444
  const completion = await this.client.chat.completions.create({
55340
55445
  model: request.model ?? this.defaultModel,
55341
55446
  messages,
@@ -55343,8 +55448,13 @@ var require_openai_native = __commonJS({
55343
55448
  max_tokens: this.maxTokens,
55344
55449
  response_format: responseFormat,
55345
55450
  ...providerRouting,
55451
+ ...reasoningParam,
55346
55452
  ...request.additionalParams
55347
55453
  });
55454
+ if (!completion.choices || completion.choices.length === 0) {
55455
+ const errorPayload = completion.error;
55456
+ throw new errors_1.MalformedResponseError(this.id, errorPayload?.code, errorPayload?.message);
55457
+ }
55348
55458
  const response = {
55349
55459
  content: completion.choices[0]?.message?.content ?? "",
55350
55460
  model: completion.model,
@@ -55352,6 +55462,7 @@ var require_openai_native = __commonJS({
55352
55462
  inputTokens: completion.usage.prompt_tokens,
55353
55463
  outputTokens: completion.usage.completion_tokens
55354
55464
  } : void 0,
55465
+ finishReason: completion.choices[0]?.finish_reason ?? void 0,
55355
55466
  rawResponse: {
55356
55467
  status: 200,
55357
55468
  body: JSON.stringify(completion)
@@ -55387,7 +55498,25 @@ var require_openai_native = __commonJS({
55387
55498
  }
55388
55499
  return { provider: providerObj };
55389
55500
  }
55501
+ /**
55502
+ * Build OpenRouter reasoning param object.
55503
+ * Returns empty object if reasoning is unset or provider is not OpenRouter.
55504
+ * Maps `reasoning?: boolean` to OpenRouter's `reasoning: { enabled: <bool> }`.
55505
+ * @see https://openrouter.ai/docs/use-cases/reasoning-tokens
55506
+ */
55507
+ buildReasoningParam() {
55508
+ if (this.id !== "openrouter") {
55509
+ return {};
55510
+ }
55511
+ if (this.reasoning === void 0) {
55512
+ return {};
55513
+ }
55514
+ return { reasoning: { enabled: this.reasoning } };
55515
+ }
55390
55516
  mapError(error) {
55517
+ if (error instanceof errors_1.ProviderError) {
55518
+ return error;
55519
+ }
55391
55520
  if (error instanceof openai_1.default.APIError) {
55392
55521
  if (error.status === 401 || error.status === 403) {
55393
55522
  return new errors_1.AuthError(this.id, error);
@@ -55481,7 +55610,13 @@ var require_claude_cli_spawn = __commonJS({
55481
55610
  });
55482
55611
  const child = (0, node_child_process_1.spawn)(cliPath, args, {
55483
55612
  cwd,
55484
- stdio: ["pipe", "pipe", "pipe"]
55613
+ stdio: ["pipe", "pipe", "pipe"],
55614
+ // Recursion guard: Sidekick's own Claude Code hooks fire inside any
55615
+ // `claude -p` subprocess we spawn. Without this flag, the subprocess
55616
+ // hook handler would dispatch to the daemon, trigger another LLM call,
55617
+ // spawn another subprocess, and so on. handleHookCommand short-circuits
55618
+ // when SIDEKICK_SUBPROCESS=1 is set. See packages/sidekick-cli/src/commands/hook.ts.
55619
+ env: { ...process.env, SIDEKICK_SUBPROCESS: "1" }
55485
55620
  });
55486
55621
  let stdout = "";
55487
55622
  let stderr = "";
@@ -55543,6 +55678,31 @@ var require_claude_cli_spawn = __commonJS({
55543
55678
  }
55544
55679
  });
55545
55680
 
55681
+ // ../shared-providers/dist/providers/anthropic-stop-reason.js
55682
+ var require_anthropic_stop_reason = __commonJS({
55683
+ "../shared-providers/dist/providers/anthropic-stop-reason.js"(exports2) {
55684
+ "use strict";
55685
+ Object.defineProperty(exports2, "__esModule", { value: true });
55686
+ exports2.mapAnthropicStopReason = mapAnthropicStopReason;
55687
+ function mapAnthropicStopReason(stopReason) {
55688
+ if (!stopReason)
55689
+ return void 0;
55690
+ switch (stopReason) {
55691
+ case "end_turn":
55692
+ return "stop";
55693
+ case "max_tokens":
55694
+ return "length";
55695
+ case "stop_sequence":
55696
+ return "stop";
55697
+ case "tool_use":
55698
+ return "tool_calls";
55699
+ default:
55700
+ return stopReason;
55701
+ }
55702
+ }
55703
+ }
55704
+ });
55705
+
55546
55706
  // ../shared-providers/dist/providers/anthropic-cli.js
55547
55707
  var require_anthropic_cli = __commonJS({
55548
55708
  "../shared-providers/dist/providers/anthropic-cli.js"(exports2) {
@@ -55551,6 +55711,7 @@ var require_anthropic_cli = __commonJS({
55551
55711
  exports2.AnthropicCliProvider = void 0;
55552
55712
  var base_1 = require_base();
55553
55713
  var claude_cli_spawn_1 = require_claude_cli_spawn();
55714
+ var anthropic_stop_reason_1 = require_anthropic_stop_reason();
55554
55715
  var AnthropicCliProvider = class extends base_1.AbstractProvider {
55555
55716
  id = "claude-cli";
55556
55717
  defaultModel;
@@ -55612,6 +55773,7 @@ var require_anthropic_cli = __commonJS({
55612
55773
  inputTokens: parsed.usage.input_tokens ?? 0,
55613
55774
  outputTokens: parsed.usage.output_tokens ?? 0
55614
55775
  } : void 0,
55776
+ finishReason: (0, anthropic_stop_reason_1.mapAnthropicStopReason)(parsed.stop_reason),
55615
55777
  rawResponse: {
55616
55778
  status: 200,
55617
55779
  body: stdout
@@ -55883,6 +56045,7 @@ var require_openai_emulator = __commonJS({
55883
56045
  inputTokens,
55884
56046
  outputTokens
55885
56047
  },
56048
+ finishReason: "stop",
55886
56049
  rawResponse: {
55887
56050
  status: 200,
55888
56051
  body: JSON.stringify(rawBody)
@@ -55937,6 +56100,7 @@ var require_openrouter_emulator = __commonJS({
55937
56100
  inputTokens,
55938
56101
  outputTokens
55939
56102
  },
56103
+ finishReason: "stop",
55940
56104
  rawResponse: {
55941
56105
  status: 200,
55942
56106
  body: JSON.stringify(rawBody)
@@ -55957,6 +56121,7 @@ var require_claude_cli_emulator = __commonJS({
55957
56121
  var node_child_process_1 = require("node:child_process");
55958
56122
  var node_path_1 = require("node:path");
55959
56123
  var base_1 = require_base();
56124
+ var anthropic_stop_reason_1 = require_anthropic_stop_reason();
55960
56125
  var EMULATOR_SCRIPT = `#!/bin/bash
55961
56126
  # Claude CLI Emulator Script
55962
56127
  STATE_FILE="\${SIDEKICK_EMULATOR_STATE_PATH:-.sidekick/emulator-state/call-counts.json}"
@@ -56044,6 +56209,7 @@ echo "{\\"content\\":\\"\${CONTENT}\\",\\"message\\":\\"\${CONTENT}\\",\\"model\
56044
56209
  inputTokens,
56045
56210
  outputTokens
56046
56211
  },
56212
+ finishReason: (0, anthropic_stop_reason_1.mapAnthropicStopReason)(parsed.stop_reason),
56047
56213
  rawResponse: {
56048
56214
  status: 0,
56049
56215
  // Exit code
@@ -56180,7 +56346,8 @@ var require_factory = __commonJS({
56180
56346
  temperature: this.config.temperature,
56181
56347
  maxTokens: this.config.maxTokens,
56182
56348
  providerAllowlist: this.config.providerAllowlist,
56183
- providerBlocklist: this.config.providerBlocklist
56349
+ providerBlocklist: this.config.providerBlocklist,
56350
+ reasoning: this.config.reasoning
56184
56351
  };
56185
56352
  return new openai_native_1.OpenAINativeProvider(openrouterConfig, this.logger);
56186
56353
  }
@@ -56357,7 +56524,9 @@ var require_profile_factory = __commonJS({
56357
56524
  maxTokens: profile.maxTokens,
56358
56525
  // OpenRouter-specific provider routing
56359
56526
  providerAllowlist: profile.providerAllowlist ? [...profile.providerAllowlist] : void 0,
56360
- providerBlocklist: profile.providerBlocklist ? [...profile.providerBlocklist] : void 0
56527
+ providerBlocklist: profile.providerBlocklist ? [...profile.providerBlocklist] : void 0,
56528
+ // OpenRouter-specific reasoning toggle
56529
+ reasoning: profile.reasoning
56361
56530
  }, this.logger);
56362
56531
  return factory.create();
56363
56532
  }
@@ -56412,7 +56581,7 @@ var require_dist3 = __commonJS({
56412
56581
  "../shared-providers/dist/index.js"(exports2) {
56413
56582
  "use strict";
56414
56583
  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;
56584
+ 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
56585
  var errors_1 = require_errors4();
56417
56586
  Object.defineProperty(exports2, "ProviderError", { enumerable: true, get: function() {
56418
56587
  return errors_1.ProviderError;
@@ -56426,6 +56595,9 @@ var require_dist3 = __commonJS({
56426
56595
  Object.defineProperty(exports2, "TimeoutError", { enumerable: true, get: function() {
56427
56596
  return errors_1.TimeoutError;
56428
56597
  } });
56598
+ Object.defineProperty(exports2, "MalformedResponseError", { enumerable: true, get: function() {
56599
+ return errors_1.MalformedResponseError;
56600
+ } });
56429
56601
  var factory_1 = require_factory();
56430
56602
  Object.defineProperty(exports2, "ProviderFactory", { enumerable: true, get: function() {
56431
56603
  return factory_1.ProviderFactory;
@@ -56715,6 +56887,7 @@ var require_plugin_detector = __commonJS({
56715
56887
  var crypto2 = __importStar(require("node:crypto"));
56716
56888
  var node_child_process_1 = require("node:child_process");
56717
56889
  var api_key_detector_js_1 = require_api_key_detector();
56890
+ var error_utils_js_1 = require_error_utils();
56718
56891
  function isSidekickStatuslineCommand(command) {
56719
56892
  return command?.toLowerCase().includes("sidekick") ?? false;
56720
56893
  }
@@ -56844,7 +57017,7 @@ var require_plugin_detector = __commonJS({
56844
57017
  return result;
56845
57018
  } catch (err) {
56846
57019
  logger?.warn("Failed to parse plugin list JSON", {
56847
- error: err instanceof Error ? err.message : String(err)
57020
+ error: (0, error_utils_js_1.toErrorMessage)(err)
56848
57021
  });
56849
57022
  logger?.info("Plugin detection completed", { result: "error" });
56850
57023
  return "error";
@@ -57048,7 +57221,16 @@ var require_doctor_engine = __commonJS({
57048
57221
  const expectedUserStatus = (0, api_key_detector_js_1.buildUserApiKeyStatus)(detection);
57049
57222
  const currentUserEntry = currentUserStatus.apiKeys[keyName];
57050
57223
  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)) {
57224
+ if (currentStatus === "not-required")
57225
+ continue;
57226
+ const isLegacyString = typeof currentUserEntry === "string";
57227
+ if (isLegacyString) {
57228
+ updatedUserApiKeys[keyName] = expectedUserStatus;
57229
+ userNeedsUpdate = true;
57230
+ } else if ((0, api_key_detector_js_1.toScopeStatus)(currentStatus) !== (0, api_key_detector_js_1.toScopeStatus)(expectedUserStatus.status)) {
57231
+ updatedUserApiKeys[keyName] = expectedUserStatus;
57232
+ userNeedsUpdate = true;
57233
+ } else if (typeof currentUserEntry === "object" && (currentUserEntry.used !== expectedUserStatus.used || JSON.stringify(currentUserEntry.scopes) !== JSON.stringify(expectedUserStatus.scopes))) {
57052
57234
  updatedUserApiKeys[keyName] = expectedUserStatus;
57053
57235
  userNeedsUpdate = true;
57054
57236
  }
@@ -57123,7 +57305,7 @@ var require_setup_status_service = __commonJS({
57123
57305
  };
57124
57306
  })();
57125
57307
  Object.defineProperty(exports2, "__esModule", { value: true });
57126
- exports2.SetupStatusService = exports2.LEGACY_USER_STATUS_FILENAME = exports2.PROJECT_STATUS_FILENAME = exports2.USER_STATUS_FILENAME = void 0;
57308
+ exports2.SetupStatusService = exports2.PROJECT_STATUS_FILENAME = exports2.USER_STATUS_FILENAME = void 0;
57127
57309
  exports2.createSetupStatusService = createSetupStatusService;
57128
57310
  var fs = __importStar(require("node:fs/promises"));
57129
57311
  var path = __importStar(require("node:path"));
@@ -57135,7 +57317,6 @@ var require_setup_status_service = __commonJS({
57135
57317
  var doctor_engine_js_1 = require_doctor_engine();
57136
57318
  exports2.USER_STATUS_FILENAME = "user-setup-status.json";
57137
57319
  exports2.PROJECT_STATUS_FILENAME = "setup-status.json";
57138
- exports2.LEGACY_USER_STATUS_FILENAME = exports2.PROJECT_STATUS_FILENAME;
57139
57320
  var SetupStatusService = class {
57140
57321
  projectDir;
57141
57322
  homeDir;
@@ -57149,10 +57330,6 @@ var require_setup_status_service = __commonJS({
57149
57330
  get userStatusPath() {
57150
57331
  return path.join(this.homeDir, ".sidekick", exports2.USER_STATUS_FILENAME);
57151
57332
  }
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
57333
  get projectStatusPath() {
57157
57334
  return path.join(this.projectDir, ".sidekick", exports2.PROJECT_STATUS_FILENAME);
57158
57335
  }
@@ -57186,7 +57363,7 @@ var require_setup_status_service = __commonJS({
57186
57363
  return parsed.data;
57187
57364
  } catch (err) {
57188
57365
  if (err.code === "ENOENT") {
57189
- return this.migrateFromLegacyUserStatus();
57366
+ return null;
57190
57367
  }
57191
57368
  if (err instanceof SyntaxError) {
57192
57369
  this.logger?.warn(`Corrupt ${exports2.USER_STATUS_FILENAME}, treating as missing`, {
@@ -57198,54 +57375,6 @@ var require_setup_status_service = __commonJS({
57198
57375
  throw err;
57199
57376
  }
57200
57377
  }
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
57378
  async getProjectStatus() {
57250
57379
  if (path.resolve(this.projectDir) === path.resolve(this.homeDir)) {
57251
57380
  this.logger?.debug("Skipping project status read: projectDir is the home directory", {
@@ -57626,6 +57755,7 @@ var require_staging_service = __commonJS({
57626
57755
  var structured_logging_1 = require_structured_logging();
57627
57756
  var errors_js_1 = require_errors6();
57628
57757
  var staging_paths_js_1 = require_staging_paths();
57758
+ var error_utils_js_1 = require_error_utils();
57629
57759
  var StagingServiceCore = class {
57630
57760
  options;
57631
57761
  constructor(options) {
@@ -57729,7 +57859,7 @@ var require_staging_service = __commonJS({
57729
57859
  hookName,
57730
57860
  reminderName,
57731
57861
  path: reminderPath,
57732
- error: err instanceof Error ? err.message : String(err)
57862
+ error: (0, error_utils_js_1.toErrorMessage)(err)
57733
57863
  });
57734
57864
  return null;
57735
57865
  }
@@ -57760,7 +57890,7 @@ var require_staging_service = __commonJS({
57760
57890
  }
57761
57891
  this.options.logger.warn("Skipping invalid reminder file", {
57762
57892
  path: reminderPath,
57763
- error: err instanceof Error ? err.message : String(err)
57893
+ error: (0, error_utils_js_1.toErrorMessage)(err)
57764
57894
  });
57765
57895
  }
57766
57896
  }
@@ -57821,7 +57951,7 @@ var require_staging_service = __commonJS({
57821
57951
  }
57822
57952
  this.options.logger.warn("Skipping invalid consumed reminder file", {
57823
57953
  path: reminderPath,
57824
- error: err instanceof Error ? err.message : String(err)
57954
+ error: (0, error_utils_js_1.toErrorMessage)(err)
57825
57955
  });
57826
57956
  }
57827
57957
  }
@@ -57973,6 +58103,7 @@ var require_handler_registry2 = __commonJS({
57973
58103
  exports2.HandlerRegistryImpl = void 0;
57974
58104
  var transcript_content_js_1 = require_transcript_content();
57975
58105
  var structured_logging_js_1 = require_structured_logging();
58106
+ var error_utils_js_1 = require_error_utils();
57976
58107
  var HandlerRegistryImpl = class {
57977
58108
  options;
57978
58109
  handlers = [];
@@ -58083,7 +58214,7 @@ var require_handler_registry2 = __commonJS({
58083
58214
  log.error("Handler execution failed", {
58084
58215
  handlerId: handler.id,
58085
58216
  hook,
58086
- error: err instanceof Error ? err.message : String(err)
58217
+ error: (0, error_utils_js_1.toErrorMessage)(err)
58087
58218
  });
58088
58219
  }
58089
58220
  }
@@ -58129,7 +58260,7 @@ var require_handler_registry2 = __commonJS({
58129
58260
  (0, structured_logging_js_1.logEvent)(this.options.logger, structured_logging_js_1.LogEvents.eventProcessed(logContext, { handlerId: handler.id, success: true }, { durationMs }));
58130
58261
  } catch (err) {
58131
58262
  const durationMs = Date.now() - startTime;
58132
- const errorMsg = err instanceof Error ? err.message : String(err);
58263
+ const errorMsg = (0, error_utils_js_1.toErrorMessage)(err);
58133
58264
  (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
58265
  this.options.logger.error("Transcript handler failed", {
58135
58266
  handlerId: handler.id,
@@ -58560,6 +58691,7 @@ var require_state_service = __commonJS({
58560
58691
  var node_path_1 = require("node:path");
58561
58692
  var path_resolver_js_1 = require_path_resolver();
58562
58693
  var errors_js_1 = require_errors6();
58694
+ var error_utils_js_1 = require_error_utils();
58563
58695
  var errors_js_2 = require_errors6();
58564
58696
  Object.defineProperty(exports2, "StateNotFoundError", { enumerable: true, get: function() {
58565
58697
  return errors_js_2.StateNotFoundError;
@@ -58671,7 +58803,7 @@ var require_state_service = __commonJS({
58671
58803
  } catch (cleanupErr) {
58672
58804
  this.logger?.trace("Failed to cleanup temp file", {
58673
58805
  tmpPath,
58674
- error: cleanupErr instanceof Error ? cleanupErr.message : String(cleanupErr)
58806
+ error: (0, error_utils_js_1.toErrorMessage)(cleanupErr)
58675
58807
  });
58676
58808
  }
58677
58809
  throw err;
@@ -58797,7 +58929,7 @@ var require_state_service = __commonJS({
58797
58929
  } catch (err) {
58798
58930
  this.logger?.warn("Failed to preload state file", {
58799
58931
  file,
58800
- error: err instanceof Error ? err.message : String(err)
58932
+ error: (0, error_utils_js_1.toErrorMessage)(err)
58801
58933
  });
58802
58934
  }
58803
58935
  }
@@ -58823,7 +58955,7 @@ var require_state_service = __commonJS({
58823
58955
  this.logger?.warn("Corrupt state file detected", {
58824
58956
  path,
58825
58957
  reason,
58826
- error: error instanceof Error ? error.message : String(error)
58958
+ error: (0, error_utils_js_1.toErrorMessage)(error)
58827
58959
  });
58828
58960
  try {
58829
58961
  await fs.rename(path, bakPath);
@@ -58853,7 +58985,7 @@ var require_state_service = __commonJS({
58853
58985
  } catch (err) {
58854
58986
  this.logger?.warn("Failed to create dev mode backup", {
58855
58987
  path,
58856
- error: err instanceof Error ? err.message : String(err)
58988
+ error: (0, error_utils_js_1.toErrorMessage)(err)
58857
58989
  });
58858
58990
  }
58859
58991
  }
@@ -58916,12 +59048,17 @@ var require_typed_accessor = __commonJS({
58916
59048
  var SessionStateAccessor = class {
58917
59049
  stateService;
58918
59050
  descriptor;
58919
- constructor(stateService, descriptor) {
59051
+ journal;
59052
+ /** Descriptor filename without .json extension — used as journal file key */
59053
+ fileKey;
59054
+ constructor(stateService, descriptor, journal) {
58920
59055
  this.stateService = stateService;
58921
59056
  this.descriptor = descriptor;
59057
+ this.journal = journal;
58922
59058
  if (descriptor.scope !== "session") {
58923
59059
  throw new Error(`SessionStateAccessor requires a session-scoped descriptor, got: ${descriptor.scope}`);
58924
59060
  }
59061
+ this.fileKey = descriptor.filename.replace(/\.json$/, "");
58925
59062
  }
58926
59063
  /**
58927
59064
  * Read session state file.
@@ -58939,9 +59076,15 @@ var require_typed_accessor = __commonJS({
58939
59076
  */
58940
59077
  async write(sessionId, data) {
58941
59078
  const path = this.stateService.sessionStatePath(sessionId, this.descriptor.filename);
58942
- return this.stateService.write(path, data, this.descriptor.schema, {
59079
+ await this.stateService.write(path, data, this.descriptor.schema, {
58943
59080
  trackHistory: this.descriptor.trackHistory
58944
59081
  });
59082
+ if (this.journal) {
59083
+ try {
59084
+ await this.journal.appendIfChanged(sessionId, this.fileKey, data);
59085
+ } catch {
59086
+ }
59087
+ }
58945
59088
  }
58946
59089
  /**
58947
59090
  * Delete session state file.
@@ -58949,6 +59092,12 @@ var require_typed_accessor = __commonJS({
58949
59092
  async delete(sessionId) {
58950
59093
  const path = this.stateService.sessionStatePath(sessionId, this.descriptor.filename);
58951
59094
  await this.stateService.delete(path);
59095
+ if (this.journal) {
59096
+ try {
59097
+ await this.journal.appendDeletion(sessionId, this.fileKey);
59098
+ } catch {
59099
+ }
59100
+ }
58952
59101
  }
58953
59102
  /**
58954
59103
  * Get the path for a session state file.
@@ -59214,8 +59363,51 @@ var require_transcript_normalizer = __commonJS({
59214
59363
  exports2.parseUuid = parseUuid;
59215
59364
  exports2.renderTranscriptString = renderTranscriptString;
59216
59365
  var index_js_1 = require_state3();
59366
+ function buildRecapEntry(params) {
59367
+ const text = typeof params.rawText === "string" ? params.rawText.trim() : "";
59368
+ if (!text)
59369
+ return null;
59370
+ return {
59371
+ id: params.uuid ?? `line-${params.lineNumber}`,
59372
+ timestamp: new Date(params.timestamp ?? Date.now()),
59373
+ role: "system",
59374
+ type: "recap",
59375
+ content: text,
59376
+ metadata: {
59377
+ provider: "claude",
59378
+ lineNumber: params.lineNumber,
59379
+ recapSource: params.recapSource,
59380
+ leafUuid: params.leafUuid
59381
+ }
59382
+ };
59383
+ }
59217
59384
  function normalizeEntry(rawEntry, lineNumber) {
59218
59385
  const entryType = rawEntry.type;
59386
+ if (entryType === "summary") {
59387
+ const raw = rawEntry;
59388
+ const recap = buildRecapEntry({
59389
+ rawText: raw.summary,
59390
+ uuid: raw.uuid,
59391
+ timestamp: raw.timestamp,
59392
+ lineNumber,
59393
+ recapSource: "compaction",
59394
+ leafUuid: typeof raw.leafUuid === "string" ? raw.leafUuid : void 0
59395
+ });
59396
+ return recap ? [recap] : null;
59397
+ }
59398
+ if (entryType === "system") {
59399
+ const raw = rawEntry;
59400
+ if (raw.subtype !== "away_summary")
59401
+ return null;
59402
+ const recap = buildRecapEntry({
59403
+ rawText: raw.content,
59404
+ uuid: raw.uuid,
59405
+ timestamp: raw.timestamp,
59406
+ lineNumber,
59407
+ recapSource: "away"
59408
+ });
59409
+ return recap ? [recap] : null;
59410
+ }
59219
59411
  if (entryType !== "user" && entryType !== "assistant") {
59220
59412
  return null;
59221
59413
  }
@@ -59349,6 +59541,9 @@ var require_transcript_normalizer = __commonJS({
59349
59541
  return `[${timestamp}] ${role} TOOL_USE: ${String(toolContent.name)}`;
59350
59542
  } else if (type === "tool_result") {
59351
59543
  return `[${timestamp}] ${role} TOOL_RESULT`;
59544
+ } else if (type === "recap") {
59545
+ const content = typeof entry.content === "string" ? entry.content : "";
59546
+ return `[${timestamp}] RECAP: ${content}`;
59352
59547
  }
59353
59548
  return `[${timestamp}] ${role}: ${JSON.stringify(entry.content)}`;
59354
59549
  }).join("\n");
@@ -59367,6 +59562,7 @@ var require_transcript_excerpt_builder = __commonJS({
59367
59562
  exports2.extractTextContent = extractTextContent;
59368
59563
  exports2.getRawContentString = getRawContentString;
59369
59564
  var transcript_helpers_js_1 = require_transcript_helpers();
59565
+ var error_utils_js_1 = require_error_utils();
59370
59566
  function getBufferedEntries(buffer, head, count, bufferSize) {
59371
59567
  if (count === 0)
59372
59568
  return [];
@@ -59421,7 +59617,7 @@ var require_transcript_excerpt_builder = __commonJS({
59421
59617
  };
59422
59618
  } catch (err) {
59423
59619
  logger.error("Failed to extract transcript excerpt from buffer", {
59424
- error: err instanceof Error ? err.message : String(err)
59620
+ error: (0, error_utils_js_1.toErrorMessage)(err)
59425
59621
  });
59426
59622
  return {
59427
59623
  content: "",
@@ -59482,6 +59678,14 @@ var require_transcript_excerpt_builder = __commonJS({
59482
59678
  return null;
59483
59679
  }
59484
59680
  return `[SESSION_HINT]: ${entry.summary ?? ""}`;
59681
+ case "system": {
59682
+ if (entry.subtype !== "away_summary")
59683
+ return null;
59684
+ const content = entry.content;
59685
+ if (typeof content !== "string" || !content.trim())
59686
+ return null;
59687
+ return `[SESSION_RECAP]: ${content}`;
59688
+ }
59485
59689
  default:
59486
59690
  return null;
59487
59691
  }
@@ -62340,6 +62544,7 @@ var require_instrumented_llm_provider = __commonJS({
62340
62544
  var node_path_1 = require("node:path");
62341
62545
  var yaml_1 = __importDefault(require_dist2());
62342
62546
  var types_1 = require_dist();
62547
+ var error_utils_js_1 = require_error_utils();
62343
62548
  var STATE_FILE = "llm-metrics.json";
62344
62549
  var DEFAULT_DEBOUNCE_MS = 500;
62345
62550
  function hasFallbackTracking(provider) {
@@ -62390,7 +62595,7 @@ var require_instrumented_llm_provider = __commonJS({
62390
62595
  }
62391
62596
  } catch (err) {
62392
62597
  this.config.logger.warn("Failed to load LLM metrics, starting fresh", {
62393
- error: err instanceof Error ? err.message : String(err)
62598
+ error: (0, error_utils_js_1.toErrorMessage)(err)
62394
62599
  });
62395
62600
  }
62396
62601
  }
@@ -62477,7 +62682,7 @@ var require_instrumented_llm_provider = __commonJS({
62477
62682
  this.config.logger.debug("Debug dump written", { path: basePath });
62478
62683
  } catch (dumpError) {
62479
62684
  this.config.logger.warn("Failed to write debug dump", {
62480
- error: dumpError instanceof Error ? dumpError.message : String(dumpError)
62685
+ error: (0, error_utils_js_1.toErrorMessage)(dumpError)
62481
62686
  });
62482
62687
  }
62483
62688
  }
@@ -62702,7 +62907,7 @@ var require_instrumented_llm_provider = __commonJS({
62702
62907
  });
62703
62908
  } catch (err) {
62704
62909
  this.config.logger.warn("Failed to persist LLM metrics", {
62705
- error: err instanceof Error ? err.message : String(err)
62910
+ error: (0, error_utils_js_1.toErrorMessage)(err)
62706
62911
  });
62707
62912
  }
62708
62913
  }
@@ -62978,6 +63183,7 @@ var require_daemon_health = __commonJS({
62978
63183
  var fs = __importStar(require("node:fs/promises"));
62979
63184
  var node_path_1 = require("node:path");
62980
63185
  var types_1 = require_dist();
63186
+ var error_utils_js_1 = require_error_utils();
62981
63187
  function healthFilePath(projectDir2) {
62982
63188
  return (0, node_path_1.join)(projectDir2, ".sidekick", "state", "daemon-health.json");
62983
63189
  }
@@ -63036,7 +63242,7 @@ var require_daemon_health = __commonJS({
63036
63242
  logger.warn("Failed to write daemon health", {
63037
63243
  from,
63038
63244
  to,
63039
- error: err instanceof Error ? err.message : String(err)
63245
+ error: (0, error_utils_js_1.toErrorMessage)(err)
63040
63246
  });
63041
63247
  return false;
63042
63248
  }
@@ -63123,6 +63329,7 @@ var require_user_profile_loader = __commonJS({
63123
63329
  var node_path_1 = require("node:path");
63124
63330
  var yaml_1 = require_dist2();
63125
63331
  var types_1 = require_dist();
63332
+ var error_utils_js_1 = require_error_utils();
63126
63333
  function loadUserProfile(options) {
63127
63334
  const home = options?.homeDir ?? (0, node_os_1.homedir)();
63128
63335
  const filePath = (0, node_path_1.join)(home, ".sidekick", "user.yaml");
@@ -63144,7 +63351,7 @@ var require_user_profile_loader = __commonJS({
63144
63351
  } catch (err) {
63145
63352
  options?.logger?.warn("Failed to read user profile", {
63146
63353
  path: filePath,
63147
- error: err instanceof Error ? err.message : String(err)
63354
+ error: (0, error_utils_js_1.toErrorMessage)(err)
63148
63355
  });
63149
63356
  return null;
63150
63357
  }
@@ -63211,9 +63418,9 @@ var require_dist4 = __commonJS({
63211
63418
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p);
63212
63419
  };
63213
63420
  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;
63421
+ 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;
63422
+ 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;
63423
+ 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
63424
  var types_1 = require_dist();
63218
63425
  Object.defineProperty(exports2, "TaskTypes", { enumerable: true, get: function() {
63219
63426
  return types_1.TaskTypes;
@@ -63258,6 +63465,12 @@ var require_dist4 = __commonJS({
63258
63465
  Object.defineProperty(exports2, "isPreCompactEvent", { enumerable: true, get: function() {
63259
63466
  return types_2.isPreCompactEvent;
63260
63467
  } });
63468
+ Object.defineProperty(exports2, "isSubagentStartEvent", { enumerable: true, get: function() {
63469
+ return types_2.isSubagentStartEvent;
63470
+ } });
63471
+ Object.defineProperty(exports2, "isSubagentStopEvent", { enumerable: true, get: function() {
63472
+ return types_2.isSubagentStopEvent;
63473
+ } });
63261
63474
  __exportStar(require_assets(), exports2);
63262
63475
  var claude_paths_1 = require_claude_paths();
63263
63476
  Object.defineProperty(exports2, "encodeProjectPath", { enumerable: true, get: function() {
@@ -63378,9 +63591,6 @@ var require_dist4 = __commonJS({
63378
63591
  Object.defineProperty(exports2, "PROJECT_STATUS_FILENAME", { enumerable: true, get: function() {
63379
63592
  return setup_status_service_1.PROJECT_STATUS_FILENAME;
63380
63593
  } });
63381
- Object.defineProperty(exports2, "LEGACY_USER_STATUS_FILENAME", { enumerable: true, get: function() {
63382
- return setup_status_service_1.LEGACY_USER_STATUS_FILENAME;
63383
- } });
63384
63594
  var api_key_detector_1 = require_api_key_detector();
63385
63595
  Object.defineProperty(exports2, "toScopeStatus", { enumerable: true, get: function() {
63386
63596
  return api_key_detector_1.toScopeStatus;
@@ -63449,12 +63659,21 @@ var require_dist4 = __commonJS({
63449
63659
  Object.defineProperty(exports2, "detectGitignoreStatus", { enumerable: true, get: function() {
63450
63660
  return gitignore_1.detectGitignoreStatus;
63451
63661
  } });
63662
+ Object.defineProperty(exports2, "detectLegacyGitignoreSection", { enumerable: true, get: function() {
63663
+ return gitignore_1.detectLegacyGitignoreSection;
63664
+ } });
63665
+ Object.defineProperty(exports2, "removeLegacyGitignoreSection", { enumerable: true, get: function() {
63666
+ return gitignore_1.removeLegacyGitignoreSection;
63667
+ } });
63452
63668
  Object.defineProperty(exports2, "SIDEKICK_SECTION_START", { enumerable: true, get: function() {
63453
63669
  return gitignore_1.SIDEKICK_SECTION_START;
63454
63670
  } });
63455
63671
  Object.defineProperty(exports2, "SIDEKICK_SECTION_END", { enumerable: true, get: function() {
63456
63672
  return gitignore_1.SIDEKICK_SECTION_END;
63457
63673
  } });
63674
+ Object.defineProperty(exports2, "SIDEKICK_GITIGNORE_HEADER", { enumerable: true, get: function() {
63675
+ return gitignore_1.SIDEKICK_GITIGNORE_HEADER;
63676
+ } });
63458
63677
  Object.defineProperty(exports2, "GITIGNORE_ENTRIES", { enumerable: true, get: function() {
63459
63678
  return gitignore_1.GITIGNORE_ENTRIES;
63460
63679
  } });
@@ -63607,6 +63826,10 @@ var require_dist4 = __commonJS({
63607
63826
  Object.defineProperty(exports2, "isInSandbox", { enumerable: true, get: function() {
63608
63827
  return sandbox_1.isInSandbox;
63609
63828
  } });
63829
+ var error_utils_1 = require_error_utils();
63830
+ Object.defineProperty(exports2, "toErrorMessage", { enumerable: true, get: function() {
63831
+ return error_utils_1.toErrorMessage;
63832
+ } });
63610
63833
  var git_status_1 = require_git_status();
63611
63834
  Object.defineProperty(exports2, "getGitFileStatus", { enumerable: true, get: function() {
63612
63835
  return git_status_1.getGitFileStatus;
@@ -70642,6 +70865,7 @@ var require_reminder_utils = __commonJS({
70642
70865
  var node_path_1 = require("node:path");
70643
70866
  var yaml = __importStar(require_js_yaml());
70644
70867
  var zod_1 = require_zod2();
70868
+ var core_1 = require_dist4();
70645
70869
  var ReminderDefinitionSchema = zod_1.z.object({
70646
70870
  id: zod_1.z.string(),
70647
70871
  blocking: zod_1.z.boolean(),
@@ -70694,7 +70918,7 @@ var require_reminder_utils = __commonJS({
70694
70918
  if (logger) {
70695
70919
  logger.error("Failed to load reminder", {
70696
70920
  reminderId,
70697
- error: err instanceof Error ? err.message : String(err)
70921
+ error: (0, core_1.toErrorMessage)(err)
70698
70922
  });
70699
70923
  } else {
70700
70924
  console.error(`Failed to load reminder ${reminderId}:`, err);
@@ -71434,7 +71658,7 @@ var require_stage_pause_and_reflect = __commonJS({
71434
71658
  (0, staging_handler_utils_js_1.createStagingHandler)(context, {
71435
71659
  id: "reminders:stage-pause-and-reflect",
71436
71660
  priority: 80,
71437
- filter: { kind: "transcript", eventTypes: ["ToolCall"] },
71661
+ filter: { kind: "transcript", eventTypes: ["ToolResult"] },
71438
71662
  execute: async (event, ctx) => {
71439
71663
  if (!(0, types_1.isTranscriptEvent)(event))
71440
71664
  return void 0;
@@ -73117,17 +73341,15 @@ var require_track_verification_tools = __commonJS({
73117
73341
  var state_js_1 = require_state4();
73118
73342
  var FILE_EDIT_TOOLS = ["Write", "Edit", "MultiEdit"];
73119
73343
  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
- }
73344
+ var MAX_PENDING_TOOL_CALLS = 100;
73124
73345
  function registerTrackVerificationTools(context) {
73125
73346
  if (!(0, types_1.isDaemonContext)(context))
73126
73347
  return;
73348
+ const pendingBySession = /* @__PURE__ */ new Map();
73127
73349
  context.handlers.register({
73128
73350
  id: "reminders:track-verification-tools",
73129
73351
  priority: 60,
73130
- filter: { kind: "transcript", eventTypes: ["ToolCall"] },
73352
+ filter: { kind: "transcript", eventTypes: ["ToolCall", "ToolResult"] },
73131
73353
  handler: async (event, ctx) => {
73132
73354
  if (!(0, types_1.isTranscriptEvent)(event))
73133
73355
  return;
@@ -73139,22 +73361,66 @@ var require_track_verification_tools = __commonJS({
73139
73361
  const sessionId = event.context?.sessionId;
73140
73362
  if (!sessionId)
73141
73363
  return;
73142
- const toolName = event.payload.toolName;
73143
- if (!toolName)
73364
+ if (event.eventType === "ToolCall") {
73365
+ const toolUseId = event.payload.entry.id;
73366
+ const toolName = event.payload.toolName;
73367
+ if (!toolUseId || !toolName)
73368
+ return;
73369
+ const entry = event.payload.entry;
73370
+ const input = entry?.input ?? {};
73371
+ let sessionMap = pendingBySession.get(sessionId);
73372
+ if (!sessionMap) {
73373
+ sessionMap = /* @__PURE__ */ new Map();
73374
+ pendingBySession.set(sessionId, sessionMap);
73375
+ }
73376
+ if (sessionMap.size >= MAX_PENDING_TOOL_CALLS) {
73377
+ const oldest = sessionMap.keys().next().value;
73378
+ if (oldest)
73379
+ sessionMap.delete(oldest);
73380
+ }
73381
+ sessionMap.set(toolUseId, { toolName, input });
73144
73382
  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);
73383
+ }
73384
+ if (event.eventType === "ToolResult") {
73385
+ const toolUseId = event.payload.entry.tool_use_id;
73386
+ if (!toolUseId)
73387
+ return;
73388
+ const sessionMap = pendingBySession.get(sessionId);
73389
+ const pending = sessionMap?.get(toolUseId);
73390
+ if (!pending)
73391
+ return;
73392
+ sessionMap.delete(toolUseId);
73393
+ if (sessionMap.size === 0)
73394
+ pendingBySession.delete(sessionId);
73395
+ const { toolName, input } = pending;
73396
+ const config = (0, types_js_1.getRemindersConfig)(context.config);
73397
+ const verificationTools = config.verification_tools ?? {};
73398
+ const runners = config.command_runners ?? [];
73399
+ const remindersState = (0, state_js_1.createRemindersState)(daemonCtx.stateService);
73400
+ const stateResult = await remindersState.verificationTools.read(sessionId);
73401
+ const toolsState = { ...stateResult.data };
73402
+ if (FILE_EDIT_TOOLS.includes(toolName)) {
73403
+ await handleFileEdit(input, daemonCtx, sessionId, verificationTools, toolsState, remindersState);
73404
+ } else if (toolName === "Bash") {
73405
+ await handleBashCommand(input, daemonCtx, sessionId, verificationTools, toolsState, remindersState, runners);
73406
+ }
73155
73407
  }
73156
73408
  }
73157
73409
  });
73410
+ context.handlers.register({
73411
+ id: "reminders:track-verification-tools-cleanup",
73412
+ priority: 60,
73413
+ filter: { kind: "hook", hooks: ["UserPromptSubmit", "Stop"] },
73414
+ // eslint-disable-next-line @typescript-eslint/require-await -- sync cleanup, async required by EventHandler type
73415
+ handler: async (event, _ctx) => {
73416
+ if (!(0, types_1.isHookEvent)(event))
73417
+ return;
73418
+ const sessionId = event.context?.sessionId;
73419
+ if (!sessionId)
73420
+ return;
73421
+ pendingBySession.delete(sessionId);
73422
+ }
73423
+ });
73158
73424
  }
73159
73425
  async function stageToolsForFiles(filePaths, daemonCtx, sessionId, verificationTools, toolsState, remindersState, triggeredBy = "file_edit") {
73160
73426
  const existingReminders = await daemonCtx.staging.listReminders("Stop");
@@ -73259,7 +73525,7 @@ var require_track_verification_tools = __commonJS({
73259
73525
  toolName,
73260
73526
  reminderId,
73261
73527
  sessionId,
73262
- error: error instanceof Error ? error.message : String(error)
73528
+ error: (0, core_1.toErrorMessage)(error)
73263
73529
  });
73264
73530
  }
73265
73531
  }
@@ -73273,8 +73539,8 @@ var require_track_verification_tools = __commonJS({
73273
73539
  await remindersState.verificationTools.write(sessionId, toolsState);
73274
73540
  return anyStaged;
73275
73541
  }
73276
- async function handleFileEdit(event, daemonCtx, sessionId, verificationTools, toolsState, remindersState) {
73277
- const filePath = extractToolInput(event)?.file_path;
73542
+ async function handleFileEdit(input, daemonCtx, sessionId, verificationTools, toolsState, remindersState) {
73543
+ const filePath = input.file_path;
73278
73544
  if (!filePath)
73279
73545
  return;
73280
73546
  const projectDir2 = daemonCtx.paths?.projectDir;
@@ -73282,8 +73548,8 @@ var require_track_verification_tools = __commonJS({
73282
73548
  return;
73283
73549
  await stageToolsForFiles([filePath], daemonCtx, sessionId, verificationTools, toolsState, remindersState);
73284
73550
  }
73285
- async function handleBashCommand(event, daemonCtx, sessionId, verificationTools, toolsState, remindersState, runners = []) {
73286
- const command = extractToolInput(event)?.command;
73551
+ async function handleBashCommand(input, daemonCtx, sessionId, verificationTools, toolsState, remindersState, runners = []) {
73552
+ const command = input.command;
73287
73553
  if (!command)
73288
73554
  return;
73289
73555
  let anyUnstaged = false;
@@ -73712,7 +73978,7 @@ var require_stage_persona_reminders = __commonJS({
73712
73978
  } catch (err) {
73713
73979
  logger.error("Failed to restage persona reminders", {
73714
73980
  sessionId,
73715
- error: err instanceof Error ? err.message : String(err)
73981
+ error: (0, core_1.toErrorMessage)(err)
73716
73982
  });
73717
73983
  }
73718
73984
  }
@@ -73948,6 +74214,38 @@ var require_stage_user_profile_reminders = __commonJS({
73948
74214
  }
73949
74215
  });
73950
74216
 
74217
+ // ../feature-reminders/dist/handlers/staging/cleanup-on-stop.js
74218
+ var require_cleanup_on_stop = __commonJS({
74219
+ "../feature-reminders/dist/handlers/staging/cleanup-on-stop.js"(exports2) {
74220
+ "use strict";
74221
+ Object.defineProperty(exports2, "__esModule", { value: true });
74222
+ exports2.registerCleanupOnStop = registerCleanupOnStop;
74223
+ var types_1 = require_dist();
74224
+ function registerCleanupOnStop(context) {
74225
+ if (!(0, types_1.isDaemonContext)(context))
74226
+ return;
74227
+ context.handlers.register({
74228
+ id: "reminders:cleanup-on-stop",
74229
+ priority: 50,
74230
+ filter: { kind: "hook", hooks: ["Stop"] },
74231
+ handler: async (event, ctx) => {
74232
+ if (!(0, types_1.isHookEvent)(event))
74233
+ return;
74234
+ if (!(0, types_1.isDaemonContext)(ctx))
74235
+ return;
74236
+ const daemonCtx = ctx;
74237
+ const sessionId = event.context?.sessionId;
74238
+ if (!sessionId)
74239
+ return;
74240
+ if (daemonCtx.orchestrator) {
74241
+ await daemonCtx.orchestrator.onStop(sessionId);
74242
+ }
74243
+ }
74244
+ });
74245
+ }
74246
+ }
74247
+ });
74248
+
73951
74249
  // ../feature-reminders/dist/handlers/staging/index.js
73952
74250
  var require_staging2 = __commonJS({
73953
74251
  "../feature-reminders/dist/handlers/staging/index.js"(exports2) {
@@ -73961,6 +74259,7 @@ var require_staging2 = __commonJS({
73961
74259
  var unstage_verify_completion_1 = require_unstage_verify_completion();
73962
74260
  var stage_persona_reminders_1 = require_stage_persona_reminders();
73963
74261
  var stage_user_profile_reminders_1 = require_stage_user_profile_reminders();
74262
+ var cleanup_on_stop_1 = require_cleanup_on_stop();
73964
74263
  function registerStagingHandlers(context) {
73965
74264
  (0, stage_default_user_prompt_1.registerStageDefaultUserPrompt)(context);
73966
74265
  (0, stage_pause_and_reflect_1.registerStagePauseAndReflect)(context);
@@ -73969,6 +74268,7 @@ var require_staging2 = __commonJS({
73969
74268
  (0, unstage_verify_completion_1.registerUnstageVerifyCompletion)(context);
73970
74269
  (0, stage_persona_reminders_1.registerStagePersonaReminders)(context);
73971
74270
  (0, stage_user_profile_reminders_1.registerStageUserProfileReminders)(context);
74271
+ (0, cleanup_on_stop_1.registerCleanupOnStop)(context);
73972
74272
  }
73973
74273
  }
73974
74274
  });
@@ -74689,7 +74989,7 @@ var require_orchestrator = __commonJS({
74689
74989
  } catch (err) {
74690
74990
  this.deps.logger.warn("Failed to unstage VC reminders after P&R staged", {
74691
74991
  sessionId,
74692
- error: err instanceof Error ? err.message : String(err)
74992
+ error: (0, core_1.toErrorMessage)(err)
74693
74993
  });
74694
74994
  }
74695
74995
  }
@@ -74713,27 +75013,10 @@ var require_orchestrator = __commonJS({
74713
75013
  } catch (err) {
74714
75014
  this.deps.logger.warn("Failed to reset P&R baseline after VC consumed", {
74715
75015
  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)
75016
+ error: (0, core_1.toErrorMessage)(err)
74735
75017
  });
74736
75018
  }
75019
+ await this.unstagePauseAndReflect(sessionId, "vc_consumed_cascade", "cascade_from_verify_completion");
74737
75020
  }
74738
75021
  }
74739
75022
  /**
@@ -74750,7 +75033,43 @@ var require_orchestrator = __commonJS({
74750
75033
  } catch (err) {
74751
75034
  this.deps.logger.warn("Failed to clear P&R baseline on UserPromptSubmit", {
74752
75035
  sessionId,
74753
- error: err instanceof Error ? err.message : String(err)
75036
+ error: (0, core_1.toErrorMessage)(err)
75037
+ });
75038
+ }
75039
+ }
75040
+ /**
75041
+ * Called when Stop hook fires.
75042
+ *
75043
+ * P&R is designed to interrupt runaway execution — once the agent stops,
75044
+ * it's irrelevant. This is defensive: Rule 4 (VC consumed → unstage P&R)
75045
+ * covers the VC case, but this handles the no-VC case where P&R would
75046
+ * otherwise linger on PreToolUse.
75047
+ */
75048
+ async onStop(sessionId) {
75049
+ await this.unstagePauseAndReflect(sessionId, "agent_stopping", "stop_hook");
75050
+ }
75051
+ /**
75052
+ * Delete P&R from PreToolUse staging and log the event.
75053
+ * Shared by Rule 4 (VC consumed → unstage P&R) and onStop (agent stopping).
75054
+ */
75055
+ async unstagePauseAndReflect(sessionId, reason, triggeredBy) {
75056
+ try {
75057
+ const staging = this.deps.getStagingService(sessionId);
75058
+ const deleted = await staging.deleteReminder("PreToolUse", types_js_1.ReminderIds.PAUSE_AND_REFLECT);
75059
+ if (deleted) {
75060
+ (0, core_1.logEvent)(this.deps.logger.child({ context: { sessionId } }), events_js_1.ReminderEvents.reminderUnstaged({ sessionId }, {
75061
+ reminderName: types_js_1.ReminderIds.PAUSE_AND_REFLECT,
75062
+ hookName: "PreToolUse",
75063
+ reason,
75064
+ triggeredBy
75065
+ }));
75066
+ }
75067
+ this.deps.logger.debug("P&R unstaged", { sessionId, deleted, reason });
75068
+ } catch (err) {
75069
+ this.deps.logger.warn("Failed to unstage P&R", {
75070
+ sessionId,
75071
+ reason,
75072
+ error: (0, core_1.toErrorMessage)(err)
74754
75073
  });
74755
75074
  }
74756
75075
  }
@@ -75146,7 +75465,7 @@ var require_persona_selection = __commonJS({
75146
75465
  } catch (err) {
75147
75466
  ctx.logger.warn("Failed to ensure persona for session", {
75148
75467
  sessionId,
75149
- error: err instanceof Error ? err.message : String(err)
75468
+ error: (0, core_1.toErrorMessage)(err)
75150
75469
  });
75151
75470
  }
75152
75471
  }
@@ -75906,7 +76225,7 @@ var require_update_summary = __commonJS({
75906
76225
  ctx.logger.error("performAnalysis failed", {
75907
76226
  sessionId,
75908
76227
  reason,
75909
- error: err instanceof Error ? err.message : String(err)
76228
+ error: (0, core_1.toErrorMessage)(err)
75910
76229
  });
75911
76230
  }
75912
76231
  }
@@ -76233,6 +76552,7 @@ var require_config_watcher = __commonJS({
76233
76552
  };
76234
76553
  Object.defineProperty(exports2, "__esModule", { value: true });
76235
76554
  exports2.ConfigWatcher = void 0;
76555
+ var core_1 = require_dist4();
76236
76556
  var chokidar_1 = (init_chokidar(), __toCommonJS(chokidar_exports));
76237
76557
  var os_1 = require("os");
76238
76558
  var path_1 = __importDefault(require("path"));
@@ -76363,7 +76683,7 @@ var require_config_watcher = __commonJS({
76363
76683
  } catch (err) {
76364
76684
  this.logger.error("Error in config change handler", {
76365
76685
  file: filename,
76366
- error: err instanceof Error ? err.message : String(err)
76686
+ error: (0, core_1.toErrorMessage)(err)
76367
76687
  });
76368
76688
  }
76369
76689
  }, this.debounceMs);
@@ -76396,6 +76716,7 @@ var require_session_persona_watcher = __commonJS({
76396
76716
  Object.defineProperty(exports2, "__esModule", { value: true });
76397
76717
  exports2.SessionPersonaWatcher = void 0;
76398
76718
  exports2.extractSessionIdFromPath = extractSessionIdFromPath;
76719
+ var core_1 = require_dist4();
76399
76720
  var chokidar_1 = (init_chokidar(), __toCommonJS(chokidar_exports));
76400
76721
  var path_1 = __importDefault(require("path"));
76401
76722
  var PERSONA_FILENAME = "session-persona.json";
@@ -76516,7 +76837,7 @@ var require_session_persona_watcher = __commonJS({
76516
76837
  } catch (err) {
76517
76838
  this.logger.error("Error in persona change handler", {
76518
76839
  sessionId,
76519
- error: err instanceof Error ? err.message : String(err)
76840
+ error: (0, core_1.toErrorMessage)(err)
76520
76841
  });
76521
76842
  }
76522
76843
  }, this.debounceMs);
@@ -76813,7 +77134,7 @@ var require_context_metrics_service = __commonJS({
76813
77134
  this.logger.info("Triggering async CLI capture for base metrics");
76814
77135
  void this.captureBaseMetrics().catch((err) => {
76815
77136
  this.logger.warn("Failed to capture base metrics via CLI", {
76816
- error: err instanceof Error ? err.message : String(err),
77137
+ error: (0, core_1.toErrorMessage)(err),
76817
77138
  stack: err instanceof Error ? err.stack : void 0
76818
77139
  });
76819
77140
  });
@@ -76939,7 +77260,7 @@ var require_context_metrics_service = __commonJS({
76939
77260
  sessionId
76940
77261
  });
76941
77262
  } catch (err) {
76942
- const errorMessage = err instanceof Error ? err.message : String(err);
77263
+ const errorMessage = (0, core_1.toErrorMessage)(err);
76943
77264
  this.logger.warn("CLI capture failed", {
76944
77265
  error: errorMessage,
76945
77266
  stack: err instanceof Error ? err.stack : void 0
@@ -77231,7 +77552,7 @@ var require_cleanup_handler = __commonJS({
77231
77552
  } catch (statErr) {
77232
77553
  ctx.logger.warn("Failed to stat session directory", {
77233
77554
  session: entry.name,
77234
- error: statErr instanceof Error ? statErr.message : String(statErr)
77555
+ error: (0, core_1.toErrorMessage)(statErr)
77235
77556
  });
77236
77557
  }
77237
77558
  }
@@ -77247,7 +77568,7 @@ var require_cleanup_handler = __commonJS({
77247
77568
  return;
77248
77569
  }
77249
77570
  ctx.logger.error("Cleanup task failed", {
77250
- error: err instanceof Error ? err.message : String(err)
77571
+ error: (0, core_1.toErrorMessage)(err)
77251
77572
  });
77252
77573
  throw err;
77253
77574
  }
@@ -77423,6 +77744,7 @@ var require_task_engine = __commonJS({
77423
77744
  };
77424
77745
  Object.defineProperty(exports2, "__esModule", { value: true });
77425
77746
  exports2.TaskEngine = exports2.TaskTimeoutError = void 0;
77747
+ var core_1 = require_dist4();
77426
77748
  var crypto_1 = __importDefault(require("crypto"));
77427
77749
  var DEFAULT_TASK_TIMEOUT_MS = 5 * 60 * 1e3;
77428
77750
  var TaskTimeoutError = class extends Error {
@@ -77551,7 +77873,7 @@ var require_task_engine = __commonJS({
77551
77873
  this.logger.error("Task failed", {
77552
77874
  type: task.type,
77553
77875
  id: task.id,
77554
- error: err instanceof Error ? err.message : String(err),
77876
+ error: (0, core_1.toErrorMessage)(err),
77555
77877
  stack: err instanceof Error ? err.stack : void 0,
77556
77878
  durationMs
77557
77879
  });
@@ -77871,7 +78193,7 @@ var require_daemon_timer_manager = __commonJS({
77871
78193
  this.deps.logger.info("Project registered for UI discovery", { projectDir: this.deps.projectDir });
77872
78194
  } catch (err) {
77873
78195
  this.deps.logger.warn("Failed to register project", {
77874
- error: err instanceof Error ? err.message : String(err)
78196
+ error: (0, core_1.toErrorMessage)(err)
77875
78197
  });
77876
78198
  }
77877
78199
  }
@@ -78035,7 +78357,7 @@ var require_daemon_log_metrics = __commonJS({
78035
78357
  await this.daemonStatusAccessor.write(status);
78036
78358
  } catch (err) {
78037
78359
  this.logger?.warn("Failed to write heartbeat status", {
78038
- error: err instanceof Error ? err.message : String(err)
78360
+ error: (0, core_1.toErrorMessage)(err)
78039
78361
  });
78040
78362
  }
78041
78363
  await this.persistLogMetrics();
@@ -78077,7 +78399,7 @@ var require_daemon_log_metrics = __commonJS({
78077
78399
  } catch (err) {
78078
78400
  this.logger?.warn("Failed to persist log metrics", {
78079
78401
  sessionId,
78080
- error: err instanceof Error ? err.message : String(err)
78402
+ error: (0, core_1.toErrorMessage)(err)
78081
78403
  });
78082
78404
  }
78083
78405
  }
@@ -78090,7 +78412,7 @@ var require_daemon_log_metrics = __commonJS({
78090
78412
  await this.globalLogMetricsAccessor.write(globalMetrics);
78091
78413
  } catch (err) {
78092
78414
  this.logger?.warn("Failed to persist global log metrics", {
78093
- error: err instanceof Error ? err.message : String(err)
78415
+ error: (0, core_1.toErrorMessage)(err)
78094
78416
  });
78095
78417
  }
78096
78418
  }
@@ -78543,7 +78865,7 @@ var require_daemon = __commonJS({
78543
78865
  this.logger.info("Configuration reloaded successfully");
78544
78866
  } catch (err) {
78545
78867
  this.logger.error("Failed to reload configuration", {
78546
- error: err instanceof Error ? err.message : String(err)
78868
+ error: (0, core_1.toErrorMessage)(err)
78547
78869
  });
78548
78870
  }
78549
78871
  }
@@ -78586,7 +78908,7 @@ var require_daemon = __commonJS({
78586
78908
  } catch (err) {
78587
78909
  this.logger.error("Failed to stage persona reminders on change", {
78588
78910
  sessionId: event.sessionId,
78589
- error: err instanceof Error ? err.message : String(err)
78911
+ error: (0, core_1.toErrorMessage)(err)
78590
78912
  });
78591
78913
  }
78592
78914
  }
@@ -78618,7 +78940,7 @@ var require_daemon = __commonJS({
78618
78940
  } catch (err) {
78619
78941
  this.logger.error("Failed to regenerate messages after persona change", {
78620
78942
  sessionId,
78621
- error: err instanceof Error ? err.message : String(err)
78943
+ error: (0, core_1.toErrorMessage)(err)
78622
78944
  });
78623
78945
  }
78624
78946
  }
@@ -78782,7 +79104,7 @@ var require_daemon = __commonJS({
78782
79104
  }
78783
79105
  } catch (err) {
78784
79106
  log.warn("Failed to cache persona for clear handoff", {
78785
- error: err instanceof Error ? err.message : String(err)
79107
+ error: (0, core_1.toErrorMessage)(err)
78786
79108
  });
78787
79109
  }
78788
79110
  } else {