@scotthamilton77/sidekick 0.1.25 → 0.1.26

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/bin.js CHANGED
@@ -1038,6 +1038,7 @@ var require_hook_events = __commonJS({
1038
1038
  exports2.isPostToolUseEvent = isPostToolUseEvent;
1039
1039
  exports2.isStopEvent = isStopEvent;
1040
1040
  exports2.isPreCompactEvent = isPreCompactEvent;
1041
+ exports2.isPostCompactEvent = isPostCompactEvent;
1041
1042
  exports2.isSubagentStartEvent = isSubagentStartEvent;
1042
1043
  exports2.isSubagentStopEvent = isSubagentStopEvent;
1043
1044
  exports2.HOOK_NAMES = [
@@ -1048,6 +1049,7 @@ var require_hook_events = __commonJS({
1048
1049
  "PostToolUse",
1049
1050
  "Stop",
1050
1051
  "PreCompact",
1052
+ "PostCompact",
1051
1053
  "SubagentStart",
1052
1054
  "SubagentStop"
1053
1055
  ];
@@ -1072,6 +1074,9 @@ var require_hook_events = __commonJS({
1072
1074
  function isPreCompactEvent(event) {
1073
1075
  return event.hook === "PreCompact";
1074
1076
  }
1077
+ function isPostCompactEvent(event) {
1078
+ return event.hook === "PostCompact";
1079
+ }
1075
1080
  function isSubagentStartEvent(event) {
1076
1081
  return event.hook === "SubagentStart";
1077
1082
  }
@@ -17927,7 +17932,8 @@ var require_tasks = __commonJS({
17927
17932
  });
17928
17933
  exports2.CleanupPayloadSchema = zod_1.z.object({
17929
17934
  maxAgeMs: zod_1.z.number().optional(),
17930
- dryRun: zod_1.z.boolean().optional()
17935
+ dryRun: zod_1.z.boolean().optional(),
17936
+ logMaxAgeMs: zod_1.z.number().optional()
17931
17937
  });
17932
17938
  exports2.MetricsPersistPayloadSchema = zod_1.z.object({
17933
17939
  sessionId: zod_1.z.string(),
@@ -17952,7 +17958,7 @@ var require_hook_input = __commonJS({
17952
17958
  "../types/dist/hook-input.js"(exports2) {
17953
17959
  "use strict";
17954
17960
  Object.defineProperty(exports2, "__esModule", { value: true });
17955
- 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;
17961
+ exports2.HookInputSchema = exports2.StatuslineInputSchema = exports2.StatuslineWorkspaceSchema = exports2.StatuslineCostSchema = exports2.StatuslineContextWindowSchema = exports2.StatuslineModelSchema = exports2.SubagentStopInputSchema = exports2.SubagentStartInputSchema = exports2.NotificationInputSchema = exports2.PostCompactInputSchema = exports2.PreCompactInputSchema = exports2.SessionEndInputSchema = exports2.SessionStartInputSchema = exports2.StopInputSchema = exports2.PostToolUseInputSchema = exports2.PreToolUseInputSchema = exports2.UserPromptSubmitInputSchema = exports2.HookInputBaseSchema = void 0;
17956
17962
  var zod_1 = require_zod();
17957
17963
  exports2.HookInputBaseSchema = zod_1.z.object({
17958
17964
  /** Unique identifier for the current Claude session */
@@ -18010,6 +18016,10 @@ var require_hook_input = __commonJS({
18010
18016
  /** Custom instructions from /compact command (empty for auto) */
18011
18017
  custom_instructions: zod_1.z.string().optional()
18012
18018
  });
18019
+ exports2.PostCompactInputSchema = exports2.HookInputBaseSchema.extend({
18020
+ /** 'manual' (user ran /compact) or 'auto' (context window threshold) */
18021
+ compaction_trigger: zod_1.z.enum(["manual", "auto"]).optional()
18022
+ });
18013
18023
  exports2.NotificationInputSchema = exports2.HookInputBaseSchema.extend({
18014
18024
  /** Notification message text */
18015
18025
  message: zod_1.z.string(),
@@ -18098,6 +18108,7 @@ var require_hook_input = __commonJS({
18098
18108
  exports2.PostToolUseInputSchema,
18099
18109
  exports2.StopInputSchema,
18100
18110
  exports2.PreCompactInputSchema,
18111
+ exports2.PostCompactInputSchema,
18101
18112
  exports2.SubagentStartInputSchema,
18102
18113
  exports2.SubagentStopInputSchema,
18103
18114
  exports2.NotificationInputSchema,
@@ -27373,6 +27384,32 @@ var require_claude_paths = __commonJS({
27373
27384
  }
27374
27385
  });
27375
27386
 
27387
+ // ../sidekick-core/dist/sidekick-paths.js
27388
+ var require_sidekick_paths = __commonJS({
27389
+ "../sidekick-core/dist/sidekick-paths.js"(exports2) {
27390
+ "use strict";
27391
+ var __importDefault2 = exports2 && exports2.__importDefault || function(mod) {
27392
+ return mod && mod.__esModule ? mod : { "default": mod };
27393
+ };
27394
+ Object.defineProperty(exports2, "__esModule", { value: true });
27395
+ exports2.resolveHome = resolveHome;
27396
+ exports2.userSidekickRoot = userSidekickRoot;
27397
+ exports2.projectStateDir = projectStateDir;
27398
+ var node_os_1 = __importDefault2(require("node:os"));
27399
+ var node_path_1 = require("node:path");
27400
+ var claude_paths_js_1 = require_claude_paths();
27401
+ function resolveHome(home) {
27402
+ return home && home.trim() ? home : node_os_1.default.homedir();
27403
+ }
27404
+ function userSidekickRoot(home) {
27405
+ return (0, node_path_1.join)(resolveHome(home), ".sidekick");
27406
+ }
27407
+ function projectStateDir(projectRoot, home) {
27408
+ return (0, node_path_1.join)(userSidekickRoot(home), "projects", (0, claude_paths_js_1.encodeProjectPath)(projectRoot));
27409
+ }
27410
+ }
27411
+ });
27412
+
27376
27413
  // ../sidekick-core/dist/persona-loader.js
27377
27414
  var require_persona_loader = __commonJS({
27378
27415
  "../sidekick-core/dist/persona-loader.js"(exports2) {
@@ -28041,10 +28078,19 @@ var require_config2 = __commonJS({
28041
28078
  var ProjectsSchema = v4_1.z.object({
28042
28079
  retentionDays: v4_1.z.number().min(1)
28043
28080
  }).strict();
28081
+ var CleanupSchema = v4_1.z.object({
28082
+ sessionMaxAgeDays: v4_1.z.number().min(1).default(7),
28083
+ logMaxAgeDays: v4_1.z.number().min(1).default(30),
28084
+ intervalHours: v4_1.z.number().min(1).default(4)
28085
+ }).strict();
28044
28086
  var DaemonSchema = v4_1.z.object({
28045
28087
  idleTimeoutMs: v4_1.z.number().min(0),
28046
28088
  shutdownTimeoutMs: v4_1.z.number().min(0),
28047
- projects: ProjectsSchema.default({ retentionDays: 30 })
28089
+ projects: ProjectsSchema.default({ retentionDays: 30 }),
28090
+ // Per-field defaults (see CleanupSchema) make any subset of keys valid —
28091
+ // partial overrides are filled at parse time. The object-level default
28092
+ // covers the case where `cleanup` is omitted entirely.
28093
+ cleanup: CleanupSchema.default({ sessionMaxAgeDays: 7, logMaxAgeDays: 30, intervalHours: 4 })
28048
28094
  }).strict();
28049
28095
  var IpcSchema = v4_1.z.object({
28050
28096
  connectTimeoutMs: v4_1.z.number().min(0),
@@ -29121,6 +29167,7 @@ var require_transport = __commonJS({
29121
29167
  var crypto_1 = __importDefault2(require("crypto"));
29122
29168
  var os_1 = __importDefault2(require("os"));
29123
29169
  var path_1 = __importDefault2(require("path"));
29170
+ var sidekick_paths_js_1 = require_sidekick_paths();
29124
29171
  function getProjectHash(projectDir) {
29125
29172
  return crypto_1.default.createHash("sha256").update(projectDir).digest("hex").substring(0, 16);
29126
29173
  }
@@ -29146,14 +29193,14 @@ var require_transport = __commonJS({
29146
29193
  throw new Error(`Socket path exceeds Unix limit of ${exports2.UNIX_PATH_MAX} characters (got ${socketPath.length}): ${socketPath}`);
29147
29194
  }
29148
29195
  }
29149
- function getTokenPath(projectDir) {
29150
- return path_1.default.join(projectDir, ".sidekick", "sidekickd.token");
29196
+ function getTokenPath(projectDir, home) {
29197
+ return path_1.default.join((0, sidekick_paths_js_1.projectStateDir)(projectDir, home), "sidekickd.token");
29151
29198
  }
29152
- function getPidPath(projectDir) {
29153
- return path_1.default.join(projectDir, ".sidekick", "sidekickd.pid");
29199
+ function getPidPath(projectDir, home) {
29200
+ return path_1.default.join((0, sidekick_paths_js_1.projectStateDir)(projectDir, home), "sidekickd.pid");
29154
29201
  }
29155
- function getLockPath(projectDir) {
29156
- return path_1.default.join(projectDir, ".sidekick", "sidekickd.lock");
29202
+ function getLockPath(projectDir, home) {
29203
+ return path_1.default.join((0, sidekick_paths_js_1.projectStateDir)(projectDir, home), "sidekickd.lock");
29157
29204
  }
29158
29205
  function getUserDaemonsDir() {
29159
29206
  return path_1.default.join(os_1.default.homedir(), ".sidekick", "daemons");
@@ -33976,6 +34023,46 @@ var require_log_events = __commonJS({
33976
34023
  }
33977
34024
  };
33978
34025
  },
34026
+ /** Create a CleanupTimerStarted event (logged when the cleanup timer starts). */
34027
+ cleanupTimerStarted(metadata) {
34028
+ return {
34029
+ type: "cleanup:timer-started",
34030
+ time: Date.now(),
34031
+ source: "daemon",
34032
+ context: EMPTY_CONTEXT,
34033
+ payload: { intervalMs: metadata.intervalMs }
34034
+ };
34035
+ },
34036
+ /** Create a CleanupTaskEnqueued event (logged when a cleanup task is enqueued). */
34037
+ cleanupTaskEnqueued(metadata) {
34038
+ return {
34039
+ type: "cleanup:task-enqueued",
34040
+ time: Date.now(),
34041
+ source: "daemon",
34042
+ context: EMPTY_CONTEXT,
34043
+ payload: { reason: metadata.reason }
34044
+ };
34045
+ },
34046
+ /** Create a CleanupSkippedRecent event (logged when startup cleanup is skipped). */
34047
+ cleanupSkippedRecent(metadata) {
34048
+ return {
34049
+ type: "cleanup:skipped-recent",
34050
+ time: Date.now(),
34051
+ source: "daemon",
34052
+ context: EMPTY_CONTEXT,
34053
+ payload: { lastCleanupAt: metadata.lastCleanupAt, intervalMs: metadata.intervalMs }
34054
+ };
34055
+ },
34056
+ /** Create a CleanupLogCompleted event (logged when log pruning finishes). */
34057
+ cleanupLogCompleted(metadata) {
34058
+ return {
34059
+ type: "cleanup:log-completed",
34060
+ time: Date.now(),
34061
+ source: "daemon",
34062
+ context: EMPTY_CONTEXT,
34063
+ payload: { cleaned: metadata.cleaned, skipped: metadata.skipped, dryRun: metadata.dryRun }
34064
+ };
34065
+ },
33979
34066
  // --- Statusline Events ---
33980
34067
  /**
33981
34068
  * Create a StatuslineRendered event (logged when statusline renders successfully).
@@ -46580,57 +46667,76 @@ var require_sandbox = __commonJS({
46580
46667
  }
46581
46668
  });
46582
46669
 
46583
- // ../../package.json
46584
- var require_package3 = __commonJS({
46585
- "../../package.json"(exports2, module2) {
46586
- module2.exports = {
46587
- name: "claude-code-sidekick",
46588
- private: true,
46589
- version: "0.1.0",
46590
- type: "module",
46591
- packageManager: "pnpm@9.12.2",
46592
- scripts: {
46593
- build: "pnpm -r build",
46594
- clean: "rm -rf packages/*/dist packages/*/*.tsbuildinfo",
46595
- typecheck: "tsc -p tsconfig.lint.json --noEmit",
46596
- test: "pnpm -r test",
46597
- "test:coverage": "vitest run --coverage",
46598
- "test:coverage:full": "INTEGRATION_TESTS=1 vitest run --coverage",
46599
- lint: "NODE_OPTIONS='--max-old-space-size=4096' eslint packages",
46600
- "lint:fix": "NODE_OPTIONS='--max-old-space-size=4096' eslint packages --fix",
46601
- format: 'prettier --write "packages/**/*.ts"',
46602
- sidekick: "node packages/sidekick-cli/dist/bin.js",
46603
- "test:dist:setup": "./scripts/test-dist.sh setup",
46604
- "test:dist:teardown": "./scripts/test-dist.sh teardown",
46605
- "test:dist:rebuild": "./scripts/test-dist.sh rebuild",
46606
- "publish:dist": "./scripts/publish-dist.sh"
46607
- },
46608
- pnpm: {
46609
- overrides: {
46610
- ajv: ">=6.14.0 <7",
46611
- minimatch: ">=10.2.1",
46612
- "vite@^7.0.0": "^7.3.2",
46613
- "picomatch@^4.0.0": "^4.0.4",
46614
- "picomatch@^2.0.0": "^2.3.2",
46615
- "flatted@^3.0.0": "^3.4.2",
46616
- "postcss@^8.0.0": "^8.5.10"
46670
+ // ../sidekick-core/dist/build-identity.js
46671
+ var require_build_identity = __commonJS({
46672
+ "../sidekick-core/dist/build-identity.js"(exports2) {
46673
+ "use strict";
46674
+ var __importDefault2 = exports2 && exports2.__importDefault || function(mod) {
46675
+ return mod && mod.__esModule ? mod : { "default": mod };
46676
+ };
46677
+ Object.defineProperty(exports2, "__esModule", { value: true });
46678
+ exports2.computeBuildIdentity = computeBuildIdentity;
46679
+ exports2.computeDevFingerprint = computeDevFingerprint;
46680
+ exports2.discoverDistDirs = discoverDistDirs;
46681
+ exports2.fingerprintDistDirs = fingerprintDistDirs;
46682
+ var fs_1 = require("fs");
46683
+ var path_1 = __importDefault2(require("path"));
46684
+ var DEV_PREFIX = "dev:";
46685
+ var NO_DIST_SENTINEL = "nodist";
46686
+ function computeBuildIdentity(injectedVersion = true ? "0.1.26" : void 0, devFingerprint = computeDevFingerprint) {
46687
+ return injectedVersion !== void 0 ? injectedVersion : DEV_PREFIX + devFingerprint();
46688
+ }
46689
+ function computeDevFingerprint() {
46690
+ const repoRoot = path_1.default.resolve(__dirname, "../../..");
46691
+ return fingerprintDistDirs(discoverDistDirs(repoRoot));
46692
+ }
46693
+ function discoverDistDirs(repoRoot) {
46694
+ const packagesDir = path_1.default.join(repoRoot, "packages");
46695
+ let entries;
46696
+ try {
46697
+ entries = (0, fs_1.readdirSync)(packagesDir);
46698
+ } catch {
46699
+ return [];
46700
+ }
46701
+ const dirs = [];
46702
+ for (const entry of entries) {
46703
+ const distDir = path_1.default.join(packagesDir, entry, "dist");
46704
+ try {
46705
+ if ((0, fs_1.statSync)(distDir).isDirectory())
46706
+ dirs.push(distDir);
46707
+ } catch {
46617
46708
  }
46618
- },
46619
- devDependencies: {
46620
- "@eslint/js": "^10.0.1",
46621
- "@types/node": "^22.19.17",
46622
- "@typescript-eslint/eslint-plugin": "^8.59.1",
46623
- "@typescript-eslint/parser": "^8.59.1",
46624
- "@vitest/coverage-v8": "^4.1.5",
46625
- eslint: "^10.3.0",
46626
- "eslint-config-prettier": "^9.1.2",
46627
- "eslint-plugin-prettier": "^5.5.5",
46628
- prettier: "^3.8.3",
46629
- typescript: "^5.9.3",
46630
- "typescript-eslint": "^8.59.1",
46631
- vitest: "^4.1.5"
46632
46709
  }
46633
- };
46710
+ return dirs;
46711
+ }
46712
+ function fingerprintDistDirs(distDirs) {
46713
+ let maxMtimeMs = 0;
46714
+ for (const dir of distDirs) {
46715
+ maxMtimeMs = Math.max(maxMtimeMs, maxMtimeInDir(dir));
46716
+ }
46717
+ return maxMtimeMs === 0 ? NO_DIST_SENTINEL : Math.floor(maxMtimeMs).toString(36);
46718
+ }
46719
+ function maxMtimeInDir(dir) {
46720
+ let max = 0;
46721
+ let entries;
46722
+ try {
46723
+ entries = (0, fs_1.readdirSync)(dir, { withFileTypes: true });
46724
+ } catch {
46725
+ return 0;
46726
+ }
46727
+ for (const entry of entries) {
46728
+ const full = path_1.default.join(dir, entry.name);
46729
+ try {
46730
+ if (entry.isDirectory()) {
46731
+ max = Math.max(max, maxMtimeInDir(full));
46732
+ } else if (entry.isFile()) {
46733
+ max = Math.max(max, (0, fs_1.statSync)(full).mtimeMs);
46734
+ }
46735
+ } catch {
46736
+ }
46737
+ }
46738
+ return max;
46739
+ }
46634
46740
  }
46635
46741
  });
46636
46742
 
@@ -46654,10 +46760,11 @@ var require_daemon_client2 = __commonJS({
46654
46760
  var transport_js_1 = require_transport();
46655
46761
  var sandbox_js_1 = require_sandbox();
46656
46762
  var error_utils_js_1 = require_error_utils();
46763
+ var build_identity_js_1 = require_build_identity();
46657
46764
  var LOCK_TIMEOUT_MS = 1e4;
46658
46765
  var LOCK_RETRY_INTERVAL_MS = 100;
46659
46766
  var LOCK_STALE_THRESHOLD_MS = 3e4;
46660
- var CLIENT_VERSION = require_package3().version;
46767
+ var CLIENT_VERSION = (0, build_identity_js_1.computeBuildIdentity)();
46661
46768
  var DaemonClient = class {
46662
46769
  projectDir;
46663
46770
  logger;
@@ -47189,16 +47296,14 @@ var require_gitignore = __commonJS({
47189
47296
  exports2.SIDEKICK_SECTION_START = "# >>> sidekick";
47190
47297
  exports2.SIDEKICK_SECTION_END = "# <<< sidekick";
47191
47298
  exports2.SIDEKICK_GITIGNORE_HEADER = "# Sidekick \u2014 managed file, do not edit manually";
47192
- exports2.GITIGNORE_ENTRIES = [
47299
+ exports2.GITIGNORE_ENTRIES = [".env", ".env.local", "*.local.yaml"];
47300
+ var STALE_GITIGNORE_ENTRIES = [
47193
47301
  "logs/",
47194
47302
  "sessions/",
47195
47303
  "state/",
47196
47304
  "setup-status.json",
47197
- ".env",
47198
- ".env.local",
47199
47305
  "sidekick*.pid",
47200
- "sidekick*.token",
47201
- "*.local.yaml"
47306
+ "sidekick*.token"
47202
47307
  ];
47203
47308
  async function installGitignoreSection(projectDir) {
47204
47309
  let status;
@@ -47229,7 +47334,8 @@ var require_gitignore = __commonJS({
47229
47334
  try {
47230
47335
  const content = await fs.readFile(sidekickGitignorePath, "utf-8");
47231
47336
  const missingEntries = exports2.GITIGNORE_ENTRIES.filter((entry) => !content.includes(entry));
47232
- return missingEntries.length === 0 ? "installed" : "incomplete";
47337
+ const staleEntries = STALE_GITIGNORE_ENTRIES.filter((entry) => content.includes(entry));
47338
+ return missingEntries.length === 0 && staleEntries.length === 0 ? "installed" : "incomplete";
47233
47339
  } catch (err) {
47234
47340
  if (err.code !== "ENOENT") {
47235
47341
  throw err;
@@ -58285,9 +58391,9 @@ var require_setup_status_service = __commonJS({
58285
58391
  exports2.createSetupStatusService = createSetupStatusService;
58286
58392
  var fs = __importStar(require("node:fs/promises"));
58287
58393
  var path = __importStar(require("node:path"));
58288
- var os = __importStar(require("node:os"));
58289
58394
  var types_1 = require_dist();
58290
58395
  var gitignore_js_1 = require_gitignore();
58396
+ var sidekick_paths_js_1 = require_sidekick_paths();
58291
58397
  var api_key_detector_js_1 = require_api_key_detector();
58292
58398
  var plugin_detector_js_1 = require_plugin_detector();
58293
58399
  var doctor_engine_js_1 = require_doctor_engine();
@@ -58299,7 +58405,7 @@ var require_setup_status_service = __commonJS({
58299
58405
  logger;
58300
58406
  constructor(projectDir, options) {
58301
58407
  this.projectDir = projectDir;
58302
- this.homeDir = options?.homeDir ?? os.homedir();
58408
+ this.homeDir = (0, sidekick_paths_js_1.resolveHome)(options?.homeDir);
58303
58409
  this.logger = options?.logger;
58304
58410
  }
58305
58411
  // === Paths ===
@@ -58307,7 +58413,7 @@ var require_setup_status_service = __commonJS({
58307
58413
  return path.join(this.homeDir, ".sidekick", exports2.USER_STATUS_FILENAME);
58308
58414
  }
58309
58415
  get projectStatusPath() {
58310
- return path.join(this.projectDir, ".sidekick", exports2.PROJECT_STATUS_FILENAME);
58416
+ return path.join((0, sidekick_paths_js_1.projectStateDir)(this.projectDir, this.homeDir), exports2.PROJECT_STATUS_FILENAME);
58311
58417
  }
58312
58418
  // === Feature config ===
58313
58419
  /**
@@ -59569,10 +59675,24 @@ var require_path_resolver = __commonJS({
59569
59675
  Object.defineProperty(exports2, "__esModule", { value: true });
59570
59676
  exports2.PathResolver = void 0;
59571
59677
  var node_path_1 = require("node:path");
59678
+ var sidekick_paths_js_1 = require_sidekick_paths();
59572
59679
  var PathResolver = class {
59573
59680
  stateBase;
59574
- constructor(projectRoot, stateDir = ".sidekick") {
59575
- this.stateBase = (0, node_path_1.join)(projectRoot, stateDir);
59681
+ /**
59682
+ * @param projectRoot Project root (project scope) or an absolute state root (user scope).
59683
+ * @param stateDir Scope selector, NOT a path segment. Only two values are
59684
+ * meaningful: `''` selects user scope (use `projectRoot` as the absolute base,
59685
+ * as-is); any other value (default `'.sidekick'`) selects project scope, where
59686
+ * runtime state is redirected to `~/.sidekick/projects/<encoded-id>/` and the
59687
+ * string content is ignored.
59688
+ * @param home Optional override for the user home that anchors the redirected
59689
+ * project state dir. Only consulted in project scope; in user scope the base
59690
+ * is already absolute. Defaults to `os.homedir()` when omitted. Thread this
59691
+ * from an injected home (production: `$HOME` via env; tests: a programmatic
59692
+ * override) so state, logs, and sessions all resolve under the same root.
59693
+ */
59694
+ constructor(projectRoot, stateDir = ".sidekick", home) {
59695
+ this.stateBase = stateDir === "" ? projectRoot : (0, sidekick_paths_js_1.projectStateDir)(projectRoot, home);
59576
59696
  }
59577
59697
  // === Directories ===
59578
59698
  /** Root state directory (.sidekick or user equivalent) */
@@ -59688,7 +59808,7 @@ var require_state_service = __commonJS({
59688
59808
  cache;
59689
59809
  configGetter;
59690
59810
  constructor(projectRoot, options) {
59691
- this.paths = new path_resolver_js_1.PathResolver(projectRoot, options?.stateDir);
59811
+ this.paths = new path_resolver_js_1.PathResolver(projectRoot, options?.stateDir, options?.homeDir);
59692
59812
  this.staleThresholdMs = options?.staleThresholdMs ?? 6e4;
59693
59813
  this.logger = options?.logger;
59694
59814
  this.cache = options?.cache ? /* @__PURE__ */ new Map() : null;
@@ -60712,7 +60832,6 @@ var require_transcript_metrics_engine = __commonJS({
60712
60832
  exports2.extractTokenUsage = extractTokenUsage;
60713
60833
  exports2.processNestedToolUses = processNestedToolUses;
60714
60834
  exports2.processNestedToolResults = processNestedToolResults;
60715
- exports2.handleCompactBoundary = handleCompactBoundary;
60716
60835
  exports2.isToolResultOnlyMessage = isToolResultOnlyMessage;
60717
60836
  exports2.isLocalCommandStdoutMessage = isLocalCommandStdoutMessage;
60718
60837
  exports2.isExcludedBuiltinCommandInvocation = isExcludedBuiltinCommandInvocation;
@@ -60747,13 +60866,8 @@ var require_transcript_metrics_engine = __commonJS({
60747
60866
  await emitEvent("AssistantMessage", entry, lineNumber);
60748
60867
  await processNestedToolUses(entry, lineNumber, metrics, toolUseIdToName, emitEvent);
60749
60868
  break;
60750
- case "system": {
60751
- const subtype = entry.subtype;
60752
- if (subtype === "compact_boundary") {
60753
- await handleCompactBoundary(entry, lineNumber, metrics, emitEvent);
60754
- }
60869
+ case "system":
60755
60870
  break;
60756
- }
60757
60871
  }
60758
60872
  }
60759
60873
  function extractTokenUsage(entry, metrics) {
@@ -60831,11 +60945,6 @@ var require_transcript_metrics_engine = __commonJS({
60831
60945
  }
60832
60946
  }
60833
60947
  }
60834
- async function handleCompactBoundary(entry, lineNumber, metrics, emitEvent) {
60835
- metrics.currentContextTokens = null;
60836
- metrics.isPostCompactIndeterminate = true;
60837
- await emitEvent("Compact", entry, lineNumber);
60838
- }
60839
60948
  function isToolResultOnlyMessage(entry) {
60840
60949
  const message = entry.message;
60841
60950
  if (!message?.content)
@@ -63216,6 +63325,13 @@ var require_transcript_service = __commonJS({
63216
63325
  // ============================================================================
63217
63326
  // Compaction Management
63218
63327
  // ============================================================================
63328
+ async signalCompaction() {
63329
+ this.metrics.currentContextTokens = null;
63330
+ this.metrics.isPostCompactIndeterminate = true;
63331
+ await this.emitEvent("Compact", {}, this.metrics.lastProcessedLine);
63332
+ this.notifyMetricsChange();
63333
+ this.schedulePersistence();
63334
+ }
63219
63335
  async capturePreCompactState(snapshotPath) {
63220
63336
  if (!this.transcriptPath) {
63221
63337
  throw new Error("TranscriptService not initialized");
@@ -63424,6 +63540,18 @@ var require_service_factory2 = __commonJS({
63424
63540
  }
63425
63541
  return service;
63426
63542
  }
63543
+ /**
63544
+ * Get the cached TranscriptService for a session if it exists.
63545
+ * Returns undefined if no service has been prepared for this session yet.
63546
+ * Touches the session access time if the service exists.
63547
+ */
63548
+ getTranscriptService(sessionId) {
63549
+ const service = this.transcriptServices.get(sessionId);
63550
+ if (service) {
63551
+ this.touchSession(sessionId);
63552
+ }
63553
+ return service;
63554
+ }
63427
63555
  /**
63428
63556
  * Shutdown a session's services (called on SessionEnd).
63429
63557
  */
@@ -64006,28 +64134,69 @@ var require_project_registry = __commonJS({
64006
64134
  return mod && mod.__esModule ? mod : { "default": mod };
64007
64135
  };
64008
64136
  Object.defineProperty(exports2, "__esModule", { value: true });
64009
- exports2.ProjectRegistryService = void 0;
64010
- exports2.encodeProjectDir = encodeProjectDir;
64137
+ exports2.ProjectRegistryService = exports2.encodeProjectDir = void 0;
64011
64138
  var node_fs_1 = require("node:fs");
64012
64139
  var promises_12 = __importDefault2(require("node:fs/promises"));
64013
64140
  var node_crypto_1 = require("node:crypto");
64014
64141
  var node_path_1 = require("node:path");
64015
64142
  var types_1 = require_dist();
64016
- function encodeProjectDir(absPath) {
64017
- return absPath.replace(/\//g, "-");
64018
- }
64143
+ var claude_paths_js_1 = require_claude_paths();
64144
+ var error_utils_js_1 = require_error_utils();
64145
+ exports2.encodeProjectDir = claude_paths_js_1.encodeProjectPath;
64019
64146
  var REGISTRY_FILE = "registry.json";
64020
64147
  var ProjectRegistryService = class {
64021
64148
  registryRoot;
64022
- constructor(registryRoot) {
64149
+ logger;
64150
+ constructor(registryRoot, logger) {
64023
64151
  this.registryRoot = registryRoot;
64152
+ this.logger = logger;
64153
+ }
64154
+ /**
64155
+ * Read and validate a single registry entry, returning null when it cannot
64156
+ * be used.
64157
+ *
64158
+ * Two unreadable cases are deliberately distinguished:
64159
+ * - **Missing** `registry.json` (ENOENT) is expected: a CLI hook can create
64160
+ * the project dir with live runtime state (sessions/, state/, logs/) before
64161
+ * the daemon writes registry.json. Logged at debug only — routine, not a
64162
+ * fault.
64163
+ * - **Corrupt** (unreadable/unparseable/schema-invalid) is unexpected and
64164
+ * warned: a persistently-bad registry.json silently excludes the dir from
64165
+ * both listing and pruning, so it must leave a trace.
64166
+ *
64167
+ * Callers treat null as "skip this dir" — never as "safe to delete".
64168
+ */
64169
+ async readEntry(entryFile) {
64170
+ let raw;
64171
+ try {
64172
+ raw = await promises_12.default.readFile(entryFile, "utf-8");
64173
+ } catch (err) {
64174
+ if (err.code === "ENOENT") {
64175
+ this.logger?.debug("Project registry dir has no registry.json; skipping", { entryFile });
64176
+ } else {
64177
+ this.logger?.warn("Failed to read project registry entry; skipping", {
64178
+ entryFile,
64179
+ error: (0, error_utils_js_1.toErrorMessage)(err)
64180
+ });
64181
+ }
64182
+ return null;
64183
+ }
64184
+ try {
64185
+ return types_1.ProjectRegistryEntrySchema.parse(JSON.parse(raw));
64186
+ } catch (err) {
64187
+ this.logger?.warn("Project registry entry is corrupt; skipping", {
64188
+ entryFile,
64189
+ error: (0, error_utils_js_1.toErrorMessage)(err)
64190
+ });
64191
+ return null;
64192
+ }
64024
64193
  }
64025
64194
  /**
64026
64195
  * Register or update a project in the registry.
64027
64196
  * Creates the directory and writes registry.json with current timestamp.
64028
64197
  */
64029
64198
  async register(projectDir) {
64030
- const encoded = encodeProjectDir(projectDir);
64199
+ const encoded = (0, exports2.encodeProjectDir)(projectDir);
64031
64200
  const entryDir = (0, node_path_1.join)(this.registryRoot, encoded);
64032
64201
  const entryFile = (0, node_path_1.join)(entryDir, REGISTRY_FILE);
64033
64202
  await promises_12.default.mkdir(entryDir, { recursive: true });
@@ -64060,12 +64229,9 @@ var require_project_registry = __commonJS({
64060
64229
  if (!dirent.isDirectory())
64061
64230
  continue;
64062
64231
  const entryFile = (0, node_path_1.join)(this.registryRoot, dirent.name, REGISTRY_FILE);
64063
- try {
64064
- const raw = await promises_12.default.readFile(entryFile, "utf-8");
64065
- const parsed = types_1.ProjectRegistryEntrySchema.parse(JSON.parse(raw));
64066
- entries.push(parsed);
64067
- } catch {
64068
- }
64232
+ const entry = await this.readEntry(entryFile);
64233
+ if (entry)
64234
+ entries.push(entry);
64069
64235
  }
64070
64236
  return entries;
64071
64237
  }
@@ -64086,14 +64252,9 @@ var require_project_registry = __commonJS({
64086
64252
  continue;
64087
64253
  const entryDir = (0, node_path_1.join)(this.registryRoot, dirent.name);
64088
64254
  const entryFile = (0, node_path_1.join)(entryDir, REGISTRY_FILE);
64089
- let entry;
64090
- try {
64091
- const raw = await promises_12.default.readFile(entryFile, "utf-8");
64092
- entry = types_1.ProjectRegistryEntrySchema.parse(JSON.parse(raw));
64093
- } catch {
64094
- await promises_12.default.rm(entryDir, { recursive: true, force: true });
64255
+ const entry = await this.readEntry(entryFile);
64256
+ if (!entry)
64095
64257
  continue;
64096
- }
64097
64258
  let reason = null;
64098
64259
  if (!(0, node_fs_1.existsSync)(entry.path)) {
64099
64260
  reason = "path-missing";
@@ -64160,8 +64321,9 @@ var require_daemon_health = __commonJS({
64160
64321
  var node_path_1 = require("node:path");
64161
64322
  var types_1 = require_dist();
64162
64323
  var error_utils_js_1 = require_error_utils();
64163
- function healthFilePath(projectDir) {
64164
- return (0, node_path_1.join)(projectDir, ".sidekick", "state", "daemon-health.json");
64324
+ var sidekick_paths_js_1 = require_sidekick_paths();
64325
+ function healthFilePath(projectDir, home) {
64326
+ return (0, node_path_1.join)((0, sidekick_paths_js_1.projectStateDir)(projectDir, home), "state", "daemon-health.json");
64165
64327
  }
64166
64328
  function defaultHealth() {
64167
64329
  return {
@@ -64169,8 +64331,8 @@ var require_daemon_health = __commonJS({
64169
64331
  lastCheckedAt: (/* @__PURE__ */ new Date(0)).toISOString()
64170
64332
  };
64171
64333
  }
64172
- async function readDaemonHealth(projectDir) {
64173
- const path = healthFilePath(projectDir);
64334
+ async function readDaemonHealth(projectDir, home) {
64335
+ const path = healthFilePath(projectDir, home);
64174
64336
  try {
64175
64337
  const content = await fs.readFile(path, "utf-8");
64176
64338
  const json = JSON.parse(content);
@@ -64183,8 +64345,8 @@ var require_daemon_health = __commonJS({
64183
64345
  return defaultHealth();
64184
64346
  }
64185
64347
  }
64186
- async function writeDaemonHealth(projectDir, health) {
64187
- const path = healthFilePath(projectDir);
64348
+ async function writeDaemonHealth(projectDir, health, home) {
64349
+ const path = healthFilePath(projectDir, home);
64188
64350
  const dir = (0, node_path_1.dirname)(path);
64189
64351
  await fs.mkdir(dir, { recursive: true });
64190
64352
  const tmpPath = `${path}.${Date.now()}.${Math.random().toString(36).slice(2, 8)}.tmp`;
@@ -64200,8 +64362,8 @@ var require_daemon_health = __commonJS({
64200
64362
  throw err;
64201
64363
  }
64202
64364
  }
64203
- async function updateDaemonHealth(projectDir, newStatus, logger, error) {
64204
- const current = await readDaemonHealth(projectDir);
64365
+ async function updateDaemonHealth(projectDir, newStatus, logger, error, home) {
64366
+ const current = await readDaemonHealth(projectDir, home);
64205
64367
  if (current.status === newStatus) {
64206
64368
  return false;
64207
64369
  }
@@ -64213,7 +64375,7 @@ var require_daemon_health = __commonJS({
64213
64375
  ...error !== void 0 && { error }
64214
64376
  };
64215
64377
  try {
64216
- await writeDaemonHealth(projectDir, health);
64378
+ await writeDaemonHealth(projectDir, health, home);
64217
64379
  } catch (err) {
64218
64380
  logger.warn("Failed to write daemon health", {
64219
64381
  from,
@@ -64396,7 +64558,7 @@ var require_dist4 = __commonJS({
64396
64558
  Object.defineProperty(exports2, "__esModule", { value: true });
64397
64559
  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;
64398
64560
  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;
64399
- 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;
64561
+ exports2.computeBuildIdentity = 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;
64400
64562
  var types_1 = require_dist();
64401
64563
  Object.defineProperty(exports2, "TaskTypes", { enumerable: true, get: function() {
64402
64564
  return types_1.TaskTypes;
@@ -64455,6 +64617,7 @@ var require_dist4 = __commonJS({
64455
64617
  Object.defineProperty(exports2, "reconstructTranscriptPath", { enumerable: true, get: function() {
64456
64618
  return claude_paths_1.reconstructTranscriptPath;
64457
64619
  } });
64620
+ __exportStar(require_sidekick_paths(), exports2);
64458
64621
  var persona_loader_1 = require_persona_loader();
64459
64622
  Object.defineProperty(exports2, "createPersonaLoader", { enumerable: true, get: function() {
64460
64623
  return persona_loader_1.createPersonaLoader;
@@ -64821,6 +64984,10 @@ var require_dist4 = __commonJS({
64821
64984
  Object.defineProperty(exports2, "CoalescingGuard", { enumerable: true, get: function() {
64822
64985
  return coalescing_guard_1.CoalescingGuard;
64823
64986
  } });
64987
+ var build_identity_1 = require_build_identity();
64988
+ Object.defineProperty(exports2, "computeBuildIdentity", { enumerable: true, get: function() {
64989
+ return build_identity_1.computeBuildIdentity;
64990
+ } });
64824
64991
  }
64825
64992
  });
64826
64993
 
@@ -64833,13 +65000,12 @@ var require_runtime = __commonJS({
64833
65000
  var core_1 = require_dist4();
64834
65001
  var types_1 = require_dist();
64835
65002
  var node_crypto_1 = require("node:crypto");
64836
- var node_os_1 = require("node:os");
64837
65003
  var node_path_1 = require("node:path");
64838
- function getLogFilePath(projectRoot) {
65004
+ function getLogFilePath(projectRoot, homeDir) {
64839
65005
  if (projectRoot) {
64840
- return (0, node_path_1.join)(projectRoot, ".sidekick", "logs", "sidekick.log");
65006
+ return (0, node_path_1.join)((0, core_1.projectStateDir)(projectRoot, homeDir), "logs", "sidekick.log");
64841
65007
  }
64842
- return (0, node_path_1.join)((0, node_os_1.homedir)(), ".sidekick", "logs", "sidekick.log");
65008
+ return (0, node_path_1.join)((0, core_1.userSidekickRoot)(homeDir), "logs", "sidekick.log");
64843
65009
  }
64844
65010
  function bootstrapRuntime(options) {
64845
65011
  const correlationId = options.correlationId ?? (0, node_crypto_1.randomUUID)();
@@ -64873,7 +65039,7 @@ var require_runtime = __commonJS({
64873
65039
  correlationId,
64874
65040
  command: options.command
64875
65041
  };
64876
- const logFilePath = getLogFilePath(projectRoot);
65042
+ const logFilePath = getLogFilePath(projectRoot, options.homeDir);
64877
65043
  const isInteractive = options.interactive ?? process.env.SIDEKICK_INTERACTIVE === "1";
64878
65044
  const enableFileLogging = options.enableFileLogging ?? true;
64879
65045
  const rotation = config.core.logging.rotation;
@@ -64923,7 +65089,7 @@ var require_runtime = __commonJS({
64923
65089
  }
64924
65090
  });
64925
65091
  const telemetry = logManager.getTelemetry();
64926
- const sessionsDir = projectRoot ? (0, node_path_1.join)(projectRoot, ".sidekick", "sessions") : (0, node_path_1.join)((0, node_os_1.homedir)(), ".sidekick", "sessions");
65092
+ const sessionsDir = projectRoot ? (0, node_path_1.join)((0, core_1.projectStateDir)(projectRoot, options.homeDir), "sessions") : (0, node_path_1.join)((0, core_1.userSidekickRoot)(options.homeDir), "sessions");
64927
65093
  const sessionLogWriter = new core_1.SessionLogWriter({
64928
65094
  sessionsDir,
64929
65095
  maxHandles: 2,
@@ -64940,14 +65106,14 @@ var require_runtime = __commonJS({
64940
65106
  logger.debug("Configuration sources loaded", { sources: config.sources });
64941
65107
  }
64942
65108
  logger.debug("Asset resolver initialized", { cascadeLayers: assets.cascadeLayers });
64943
- const stateRoot = projectRoot ?? (0, node_path_1.join)((0, node_os_1.homedir)(), ".claude");
64944
- const stateService = new core_1.StateService(stateRoot, { logger });
65109
+ const stateService = projectRoot ? new core_1.StateService(projectRoot, { logger, homeDir: options.homeDir }) : new core_1.StateService((0, core_1.userSidekickRoot)(options.homeDir), { stateDir: "", logger });
64945
65110
  return {
64946
65111
  get logger() {
64947
65112
  return logger;
64948
65113
  },
64949
65114
  telemetry,
64950
65115
  projectRoot,
65116
+ homeDir: options.homeDir,
64951
65117
  config,
64952
65118
  assets,
64953
65119
  stateService,
@@ -65019,10 +65185,10 @@ var require_dev_mode_guard = __commonJS({
65019
65185
  Object.defineProperty(exports2, "__esModule", { value: true });
65020
65186
  exports2.checkDevModeConflict = checkDevModeConflict;
65021
65187
  var core_1 = require_dist4();
65022
- async function checkDevModeConflict(projectRoot, forceDevMode, logger, callerLabel) {
65188
+ async function checkDevModeConflict(projectRoot, forceDevMode, logger, callerLabel, home) {
65023
65189
  if (forceDevMode) {
65024
65190
  try {
65025
- const setupService = new core_1.SetupStatusService(projectRoot);
65191
+ const setupService = new core_1.SetupStatusService(projectRoot, { homeDir: home });
65026
65192
  const devMode = await setupService.getDevMode();
65027
65193
  if (!devMode) {
65028
65194
  logger.warn(`Dev-mode ${callerLabel} running but devMode flag is off \u2014 auto-correcting`, {
@@ -65039,7 +65205,7 @@ var require_dev_mode_guard = __commonJS({
65039
65205
  return "proceed";
65040
65206
  }
65041
65207
  try {
65042
- const setupService = new core_1.SetupStatusService(projectRoot);
65208
+ const setupService = new core_1.SetupStatusService(projectRoot, { homeDir: home });
65043
65209
  const devMode = await setupService.getDevMode();
65044
65210
  if (devMode) {
65045
65211
  logger.debug(`Dev-mode active, ${callerLabel} bailing early (let dev-mode hooks win)`, {
@@ -75173,6 +75339,7 @@ var require_stage_persona_reminders = __commonJS({
75173
75339
  Object.defineProperty(exports2, "__esModule", { value: true });
75174
75340
  exports2.restagePersonaRemindersForActiveSessions = restagePersonaRemindersForActiveSessions;
75175
75341
  exports2.stagePersonaRemindersForSession = stagePersonaRemindersForSession;
75342
+ exports2.resolvePersonaContextForSnapshot = resolvePersonaContextForSnapshot;
75176
75343
  exports2.registerStagePersonaReminders = registerStagePersonaReminders;
75177
75344
  var core_1 = require_dist4();
75178
75345
  var events_js_1 = require_events2();
@@ -75336,6 +75503,20 @@ var require_stage_persona_reminders = __commonJS({
75336
75503
  includeChanged: options?.includeChangedReminder ?? false
75337
75504
  });
75338
75505
  }
75506
+ async function resolvePersonaContextForSnapshot(ctx, sessionId) {
75507
+ if (!isPersonaInjectionEnabled(ctx))
75508
+ return void 0;
75509
+ const persona = await loadPersonaForSession(ctx, sessionId);
75510
+ if (!persona)
75511
+ return void 0;
75512
+ const templateContext = buildPersonaTemplateContext(persona);
75513
+ const reminder = (0, reminder_utils_js_1.resolveReminder)(types_js_1.ReminderIds.REMEMBER_YOUR_PERSONA, {
75514
+ context: templateContext,
75515
+ assets: ctx.assets,
75516
+ logger: ctx.logger
75517
+ });
75518
+ return reminder?.additionalContext ?? void 0;
75519
+ }
75339
75520
  function registerStagePersonaReminders(context) {
75340
75521
  if (!(0, types_1.isDaemonContext)(context))
75341
75522
  return;
@@ -75364,6 +75545,7 @@ var require_stage_user_profile_reminders = __commonJS({
75364
75545
  "use strict";
75365
75546
  Object.defineProperty(exports2, "__esModule", { value: true });
75366
75547
  exports2.stageUserProfileRemindersForSession = stageUserProfileRemindersForSession;
75548
+ exports2.resolveUserProfileContextForSnapshot = resolveUserProfileContextForSnapshot;
75367
75549
  exports2.registerStageUserProfileReminders = registerStageUserProfileReminders;
75368
75550
  var core_1 = require_dist4();
75369
75551
  var events_js_1 = require_events2();
@@ -75403,6 +75585,21 @@ var require_stage_user_profile_reminders = __commonJS({
75403
75585
  ctx.logger.warn("Failed to resolve user-profile reminder", { sessionId });
75404
75586
  }
75405
75587
  }
75588
+ function resolveUserProfileContextForSnapshot(ctx) {
75589
+ const profile = (0, core_1.loadUserProfile)({ logger: ctx.logger });
75590
+ if (!profile)
75591
+ return void 0;
75592
+ const templateContext = {
75593
+ user_name: profile.name,
75594
+ user_role: profile.role,
75595
+ user_interests: profile.interests.join(", ")
75596
+ };
75597
+ const reminder = (0, reminder_utils_js_1.resolveReminder)(types_js_1.ReminderIds.USER_PROFILE, {
75598
+ context: templateContext,
75599
+ assets: ctx.assets
75600
+ });
75601
+ return reminder?.additionalContext ?? void 0;
75602
+ }
75406
75603
  function registerStageUserProfileReminders(context) {
75407
75604
  if (!(0, types_1.isDaemonContext)(context))
75408
75605
  return;
@@ -75498,10 +75695,10 @@ var require_cli_staging_reader = __commonJS({
75498
75695
  stateDir;
75499
75696
  sessionId;
75500
75697
  constructor(options) {
75501
- if (!options.paths.projectConfigDir) {
75502
- throw new Error("CLIStagingReader requires project scope (projectConfigDir must be defined)");
75698
+ if (!options.paths.projectStateDir) {
75699
+ throw new Error("CLIStagingReader requires project scope (projectStateDir must be defined)");
75503
75700
  }
75504
- this.stateDir = options.paths.projectConfigDir;
75701
+ this.stateDir = options.paths.projectStateDir;
75505
75702
  this.sessionId = options.sessionId;
75506
75703
  }
75507
75704
  /**
@@ -75865,6 +76062,22 @@ var require_inject_session_start = __commonJS({
75865
76062
  }
75866
76063
  });
75867
76064
 
76065
+ // ../feature-reminders/dist/handlers/consumption/inject-post-compact.js
76066
+ var require_inject_post_compact = __commonJS({
76067
+ "../feature-reminders/dist/handlers/consumption/inject-post-compact.js"(exports2) {
76068
+ "use strict";
76069
+ Object.defineProperty(exports2, "__esModule", { value: true });
76070
+ exports2.registerInjectPostCompact = registerInjectPostCompact;
76071
+ var consumption_handler_factory_js_1 = require_consumption_handler_factory();
76072
+ function registerInjectPostCompact(context) {
76073
+ (0, consumption_handler_factory_js_1.createConsumptionHandler)(context, {
76074
+ id: "reminders:inject-post-compact",
76075
+ hook: "PostCompact"
76076
+ });
76077
+ }
76078
+ }
76079
+ });
76080
+
75868
76081
  // ../feature-reminders/dist/handlers/consumption/index.js
75869
76082
  var require_consumption = __commonJS({
75870
76083
  "../feature-reminders/dist/handlers/consumption/index.js"(exports2) {
@@ -75876,12 +76089,14 @@ var require_consumption = __commonJS({
75876
76089
  var inject_post_tool_use_1 = require_inject_post_tool_use();
75877
76090
  var inject_stop_1 = require_inject_stop();
75878
76091
  var inject_session_start_1 = require_inject_session_start();
76092
+ var inject_post_compact_js_1 = require_inject_post_compact();
75879
76093
  function registerConsumptionHandlers(context) {
75880
76094
  (0, inject_user_prompt_submit_1.registerInjectUserPromptSubmit)(context);
75881
76095
  (0, inject_pre_tool_use_1.registerInjectPreToolUse)(context);
75882
76096
  (0, inject_post_tool_use_1.registerInjectPostToolUse)(context);
75883
76097
  (0, inject_stop_1.registerInjectStop)(context);
75884
76098
  (0, inject_session_start_1.registerInjectSessionStart)(context);
76099
+ (0, inject_post_compact_js_1.registerInjectPostCompact)(context);
75885
76100
  }
75886
76101
  }
75887
76102
  });
@@ -76326,7 +76541,7 @@ var require_dist5 = __commonJS({
76326
76541
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p);
76327
76542
  };
76328
76543
  Object.defineProperty(exports2, "__esModule", { value: true });
76329
- exports2.createRemindersState = exports2.ReminderOrchestrator = exports2.ReminderEvents = exports2.handleVCUnverifiedClear = exports2.handleVCUnverifiedSet = exports2.handleReminderConsumed = exports2.classifyCompletion = exports2.restagePersonaRemindersForActiveSessions = exports2.stagePersonaRemindersForSession = exports2.registerStagingHandlers = exports2.registerConsumptionHandlers = exports2.manifest = void 0;
76544
+ exports2.createRemindersState = exports2.ReminderOrchestrator = exports2.ReminderEvents = exports2.handleVCUnverifiedClear = exports2.handleVCUnverifiedSet = exports2.handleReminderConsumed = exports2.classifyCompletion = exports2.resolveUserProfileContextForSnapshot = exports2.resolvePersonaContextForSnapshot = exports2.restagePersonaRemindersForActiveSessions = exports2.stagePersonaRemindersForSession = exports2.registerStagingHandlers = exports2.registerConsumptionHandlers = exports2.manifest = void 0;
76330
76545
  exports2.register = register;
76331
76546
  var staging_1 = require_staging2();
76332
76547
  var consumption_1 = require_consumption();
@@ -76360,6 +76575,13 @@ var require_dist5 = __commonJS({
76360
76575
  Object.defineProperty(exports2, "restagePersonaRemindersForActiveSessions", { enumerable: true, get: function() {
76361
76576
  return stage_persona_reminders_1.restagePersonaRemindersForActiveSessions;
76362
76577
  } });
76578
+ Object.defineProperty(exports2, "resolvePersonaContextForSnapshot", { enumerable: true, get: function() {
76579
+ return stage_persona_reminders_1.resolvePersonaContextForSnapshot;
76580
+ } });
76581
+ var stage_user_profile_reminders_1 = require_stage_user_profile_reminders();
76582
+ Object.defineProperty(exports2, "resolveUserProfileContextForSnapshot", { enumerable: true, get: function() {
76583
+ return stage_user_profile_reminders_1.resolveUserProfileContextForSnapshot;
76584
+ } });
76363
76585
  var completion_classifier_1 = require_completion_classifier();
76364
76586
  Object.defineProperty(exports2, "classifyCompletion", { enumerable: true, get: function() {
76365
76587
  return completion_classifier_1.classifyCompletion;
@@ -76397,7 +76619,6 @@ var require_context2 = __commonJS({
76397
76619
  exports2.buildCLIContext = buildCLIContext;
76398
76620
  exports2.registerCLIFeatures = registerCLIFeatures;
76399
76621
  var node_path_1 = require("node:path");
76400
- var node_os_1 = require("node:os");
76401
76622
  var core_1 = require_dist4();
76402
76623
  var feature_reminders_1 = require_dist5();
76403
76624
  function buildCLIContext(options) {
@@ -76408,8 +76629,11 @@ var require_context2 = __commonJS({
76408
76629
  const projectRoot = runtime.projectRoot;
76409
76630
  const paths = {
76410
76631
  projectDir: projectRoot,
76411
- userConfigDir: (0, node_path_1.join)((0, node_os_1.homedir)(), ".sidekick"),
76412
- projectConfigDir: (0, node_path_1.join)(projectRoot, ".sidekick")
76632
+ userConfigDir: (0, core_1.userSidekickRoot)(runtime.homeDir),
76633
+ projectConfigDir: (0, node_path_1.join)(projectRoot, ".sidekick"),
76634
+ // Single source: the runtime's StateService already resolves the project
76635
+ // state dir under the injected home — don't recompute and risk drift.
76636
+ projectStateDir: runtime.stateService.rootDir()
76413
76637
  };
76414
76638
  const handlers = new core_1.HandlerRegistryImpl({
76415
76639
  logger: runtime.logger,
@@ -76593,6 +76817,18 @@ var require_hook = __commonJS({
76593
76817
  }
76594
76818
  };
76595
76819
  }
76820
+ function buildPostCompactEvent(context, input) {
76821
+ const trigger = input.raw.compaction_trigger;
76822
+ return {
76823
+ kind: "hook",
76824
+ hook: "PostCompact",
76825
+ context,
76826
+ payload: {
76827
+ compactionTrigger: trigger === "manual" ? "manual" : "auto",
76828
+ transcriptPath: input.transcriptPath
76829
+ }
76830
+ };
76831
+ }
76596
76832
  function buildSubagentStartEvent(context, input) {
76597
76833
  return {
76598
76834
  kind: "hook",
@@ -76649,6 +76885,8 @@ var require_hook = __commonJS({
76649
76885
  return buildStopEvent(context, input);
76650
76886
  case "PreCompact":
76651
76887
  return buildPreCompactEvent(context, input);
76888
+ case "PostCompact":
76889
+ return buildPostCompactEvent(context, input);
76652
76890
  case "SubagentStart": {
76653
76891
  const subagentContext = {
76654
76892
  ...context,
@@ -76892,6 +77130,17 @@ var require_hook_command = __commonJS({
76892
77130
  addUserMessage(response, internal.userMessage);
76893
77131
  return response;
76894
77132
  }
77133
+ function translatePostCompact(internal) {
77134
+ const response = {};
77135
+ if (internal.additionalContext) {
77136
+ response.hookSpecificOutput = {
77137
+ hookEventName: "PostCompact",
77138
+ additionalContext: internal.additionalContext
77139
+ };
77140
+ }
77141
+ addUserMessage(response, internal.userMessage);
77142
+ return response;
77143
+ }
76895
77144
  var TRANSLATORS = {
76896
77145
  SessionStart: translateSessionStart,
76897
77146
  SessionEnd: () => ({}),
@@ -76900,6 +77149,7 @@ var require_hook_command = __commonJS({
76900
77149
  PostToolUse: translatePostToolUse,
76901
77150
  Stop: translateStop,
76902
77151
  PreCompact: () => ({}),
77152
+ PostCompact: translatePostCompact,
76903
77153
  SubagentStart: translateSubagentStart,
76904
77154
  // SubagentStop shares Stop's blocking semantics verbatim per Claude Code docs.
76905
77155
  SubagentStop: translateStop
@@ -76915,6 +77165,7 @@ var require_hook_command = __commonJS({
76915
77165
  "post-tool-use": "PostToolUse",
76916
77166
  stop: "Stop",
76917
77167
  "pre-compact": "PreCompact",
77168
+ "post-compact": "PostCompact",
76918
77169
  "subagent-start": "SubagentStart",
76919
77170
  "subagent-stop": "SubagentStop",
76920
77171
  SessionStart: "SessionStart",
@@ -76924,6 +77175,7 @@ var require_hook_command = __commonJS({
76924
77175
  PostToolUse: "PostToolUse",
76925
77176
  Stop: "Stop",
76926
77177
  PreCompact: "PreCompact",
77178
+ PostCompact: "PostCompact",
76927
77179
  SubagentStart: "SubagentStart",
76928
77180
  SubagentStop: "SubagentStop"
76929
77181
  };
@@ -76945,9 +77197,9 @@ var require_hook_command = __commonJS({
76945
77197
  }
76946
77198
  };
76947
77199
  var VERBOSE_DEGRADED_HOOKS = /* @__PURE__ */ new Set(["SessionStart", "UserPromptSubmit"]);
76948
- async function maybeAutoConfigureProject(projectRoot, logger) {
77200
+ async function maybeAutoConfigureProject(projectRoot, logger, home) {
76949
77201
  try {
76950
- const setupService = new core_1.SetupStatusService(projectRoot, { logger });
77202
+ const setupService = new core_1.SetupStatusService(projectRoot, { logger, homeDir: home });
76951
77203
  const shouldAuto = await setupService.shouldAutoConfigureProject();
76952
77204
  if (!shouldAuto)
76953
77205
  return false;
@@ -76964,10 +77216,10 @@ var require_hook_command = __commonJS({
76964
77216
  return false;
76965
77217
  }
76966
77218
  }
76967
- async function checkSetupState(projectRoot, hookName, logger) {
77219
+ async function checkSetupState(projectRoot, hookName, logger, home) {
76968
77220
  let state;
76969
77221
  try {
76970
- const setupService = new core_1.SetupStatusService(projectRoot);
77222
+ const setupService = new core_1.SetupStatusService(projectRoot, { homeDir: home });
76971
77223
  state = await setupService.getSetupState();
76972
77224
  } catch (err) {
76973
77225
  logger.warn("Failed to check setup state, assuming healthy", {
@@ -76995,13 +77247,13 @@ var require_hook_command = __commonJS({
76995
77247
  userMessage: messages.userMessage
76996
77248
  };
76997
77249
  }
76998
- async function ensureDaemonForHook(projectRoot, logger) {
77250
+ async function ensureDaemonForHook(projectRoot, logger, home) {
76999
77251
  if ((0, core_1.isInSandbox)()) {
77000
77252
  logger.debug("Skipping daemon start \u2014 sandbox mode");
77001
77253
  return false;
77002
77254
  }
77003
77255
  try {
77004
- const setupService = new core_1.SetupStatusService(projectRoot);
77256
+ const setupService = new core_1.SetupStatusService(projectRoot, { homeDir: home });
77005
77257
  const setupState = await setupService.getSetupState();
77006
77258
  if (setupState !== "healthy") {
77007
77259
  logger.debug("Skipping daemon start - setup not healthy", { setupState });
@@ -77016,11 +77268,11 @@ var require_hook_command = __commonJS({
77016
77268
  const daemonClient = new core_1.DaemonClient(projectRoot, logger);
77017
77269
  await daemonClient.start();
77018
77270
  logger.debug("Daemon started for hook execution");
77019
- await (0, core_1.updateDaemonHealth)(projectRoot, "healthy", logger);
77271
+ await (0, core_1.updateDaemonHealth)(projectRoot, "healthy", logger, void 0, home);
77020
77272
  return true;
77021
77273
  } catch (err) {
77022
77274
  const errorMessage = (0, core_1.toErrorMessage)(err);
77023
- await (0, core_1.updateDaemonHealth)(projectRoot, "failed", logger, errorMessage);
77275
+ await (0, core_1.updateDaemonHealth)(projectRoot, "failed", logger, errorMessage, home);
77024
77276
  return false;
77025
77277
  }
77026
77278
  }
@@ -77045,17 +77297,17 @@ var require_hook_command = __commonJS({
77045
77297
  }
77046
77298
  const { projectRoot, hookInput, correlationId, runtime, forceDevMode } = options;
77047
77299
  logger.debug("Unified hook command invoked", { hookName, sessionId: hookInput.sessionId });
77048
- const devModeGuard = await (0, dev_mode_guard_js_1.checkDevModeConflict)(projectRoot, forceDevMode, logger, hookName);
77300
+ const devModeGuard = await (0, dev_mode_guard_js_1.checkDevModeConflict)(projectRoot, forceDevMode, logger, hookName, runtime.homeDir);
77049
77301
  if (devModeGuard === "bail") {
77050
77302
  stdout.write("{}\n");
77051
77303
  return { exitCode: 0, output: "{}" };
77052
77304
  }
77053
77305
  if (hookName === "SessionStart") {
77054
- await maybeAutoConfigureProject(projectRoot, logger);
77306
+ await maybeAutoConfigureProject(projectRoot, logger, runtime.homeDir);
77055
77307
  }
77056
- const daemonAvailable = await ensureDaemonForHook(projectRoot, logger);
77308
+ const daemonAvailable = await ensureDaemonForHook(projectRoot, logger, runtime.homeDir);
77057
77309
  const isLivenessCheck = !!process.env.SIDEKICK_LIVENESS_CHECK;
77058
- const degradedResponse = isLivenessCheck ? null : await checkSetupState(projectRoot, hookName, logger);
77310
+ const degradedResponse = isLivenessCheck ? null : await checkSetupState(projectRoot, hookName, logger, runtime.homeDir);
77059
77311
  if (degradedResponse !== null) {
77060
77312
  const claudeResponse2 = translateToClaudeCodeFormat(hookName, degradedResponse);
77061
77313
  const outputStr2 = JSON.stringify(claudeResponse2);
@@ -78932,9 +79184,7 @@ var require_resume_discovery = __commonJS({
78932
79184
  })();
78933
79185
  Object.defineProperty(exports2, "__esModule", { value: true });
78934
79186
  exports2.discoverPreviousResumeMessage = discoverPreviousResumeMessage;
78935
- exports2.projectRootFromSessionsDir = projectRootFromSessionsDir;
78936
79187
  var fs = __importStar(require("node:fs/promises"));
78937
- var path = __importStar(require("node:path"));
78938
79188
  var core_1 = require_dist4();
78939
79189
  var feature_session_summary_1 = require_dist6();
78940
79190
  async function discoverPreviousResumeMessage(config, stateService) {
@@ -78981,9 +79231,6 @@ var require_resume_discovery = __commonJS({
78981
79231
  function isNodeError(error) {
78982
79232
  return error instanceof Error && "code" in error;
78983
79233
  }
78984
- function projectRootFromSessionsDir(sessionsDir) {
78985
- return path.dirname(path.dirname(sessionsDir));
78986
- }
78987
79234
  }
78988
79235
  });
78989
79236
 
@@ -78994,7 +79241,6 @@ var require_state_reader = __commonJS({
78994
79241
  Object.defineProperty(exports2, "__esModule", { value: true });
78995
79242
  exports2.StateReader = void 0;
78996
79243
  exports2.createStateReader = createStateReader;
78997
- exports2.discoverPreviousResumeMessage = discoverPreviousResumeMessage;
78998
79244
  var core_1 = require_dist4();
78999
79245
  var feature_session_summary_1 = require_dist6();
79000
79246
  var types_js_1 = require_types3();
@@ -79213,12 +79459,6 @@ var require_state_reader = __commonJS({
79213
79459
  staleThresholdMs: options?.staleThresholdMs
79214
79460
  });
79215
79461
  }
79216
- var resume_discovery_js_1 = require_resume_discovery();
79217
- async function discoverPreviousResumeMessage(sessionsDir, currentSessionId) {
79218
- const projectRoot = (0, resume_discovery_js_1.projectRootFromSessionsDir)(sessionsDir);
79219
- const stateService = new core_1.StateService(projectRoot);
79220
- return (0, resume_discovery_js_1.discoverPreviousResumeMessage)({ sessionsDir, currentSessionId }, stateService);
79221
- }
79222
79462
  }
79223
79463
  });
79224
79464
 
@@ -79784,8 +80024,8 @@ var require_context_overhead_reader = __commonJS({
79784
80024
  const result = await stateService.read(filePath, types_1.BaseTokenMetricsStateSchema, types_1.DEFAULT_BASE_METRICS);
79785
80025
  return result.data;
79786
80026
  }
79787
- async function readProjectMetrics(projectDir) {
79788
- const stateService = new core_1.StateService(projectDir);
80027
+ async function readProjectMetrics(projectDir, home) {
80028
+ const stateService = new core_1.StateService(projectDir, { homeDir: home });
79789
80029
  const filePath = stateService.globalStatePath(PROJECT_METRICS_FILE);
79790
80030
  const result = await stateService.read(filePath, types_1.ProjectContextMetricsSchema, types_1.DEFAULT_PROJECT_METRICS);
79791
80031
  return result.data;
@@ -79806,7 +80046,7 @@ var require_context_overhead_reader = __commonJS({
79806
80046
  async function readContextOverhead(config) {
79807
80047
  const [base, project] = await Promise.all([
79808
80048
  readBaseMetrics(config.userConfigDir),
79809
- readProjectMetrics(config.projectDir)
80049
+ readProjectMetrics(config.projectDir, config.homeDir)
79810
80050
  ]);
79811
80051
  return buildOverhead(base, project);
79812
80052
  }
@@ -79866,6 +80106,7 @@ var require_statusline_service = __commonJS({
79866
80106
  var formatter_js_1 = require_formatter();
79867
80107
  var git_provider_js_1 = require_git_provider();
79868
80108
  var state_reader_js_1 = require_state_reader();
80109
+ var resume_discovery_js_1 = require_resume_discovery();
79869
80110
  var context_overhead_reader_js_1 = require_context_overhead_reader();
79870
80111
  var token_resolution_js_1 = require_token_resolution();
79871
80112
  var types_js_1 = require_types3();
@@ -79895,6 +80136,7 @@ var require_statusline_service = __commonJS({
79895
80136
  personaName: ""
79896
80137
  };
79897
80138
  var StatuslineService = class {
80139
+ stateService;
79898
80140
  stateReader;
79899
80141
  gitProvider;
79900
80142
  formatter;
@@ -79928,6 +80170,7 @@ var require_statusline_service = __commonJS({
79928
80170
  this.projectDir = serviceConfig.projectDir;
79929
80171
  this.assets = serviceConfig.assets;
79930
80172
  this.resumeFreshnessHours = serviceConfig.personaConfig?.resumeFreshnessHours ?? 4;
80173
+ this.stateService = serviceConfig.stateService;
79931
80174
  this.stateReader = (0, state_reader_js_1.createStateReader)(serviceConfig.stateService, serviceConfig.sessionId);
79932
80175
  this.gitProvider = (0, git_provider_js_1.createGitProvider)(serviceConfig.cwd);
79933
80176
  this.formatter = (0, formatter_js_1.createFormatter)({
@@ -80110,7 +80353,7 @@ var require_statusline_service = __commonJS({
80110
80353
  return this.buildWarningResult(setupCheck.warning);
80111
80354
  }
80112
80355
  if (this.projectDir) {
80113
- const daemonHealth = await (0, core_1.readDaemonHealth)(this.projectDir);
80356
+ const daemonHealth = await (0, core_1.readDaemonHealth)(this.projectDir, this.homeDir);
80114
80357
  if (daemonHealth.status === "failed") {
80115
80358
  const warning = daemonHealth.error ? `Daemon not running: ${daemonHealth.error}. Sidekick features limited.` : "Daemon not running. Sidekick features limited.";
80116
80359
  return this.buildWarningResult(warning);
@@ -80138,7 +80381,7 @@ var require_statusline_service = __commonJS({
80138
80381
  let effectiveResumeData = resumeResult.data;
80139
80382
  const hasNoMeaningfulSummary = !summaryResult.data.session_title || summaryResult.data.session_title === "" || (summaryResult.data.session_title_confidence ?? 0) === 0;
80140
80383
  if (hasNoMeaningfulSummary && !effectiveResumeData && this.sessionsDir && this.sessionId) {
80141
- const discovery = await (0, state_reader_js_1.discoverPreviousResumeMessage)(this.sessionsDir, this.sessionId);
80384
+ const discovery = await (0, resume_discovery_js_1.discoverPreviousResumeMessage)({ sessionsDir: this.sessionsDir, currentSessionId: this.sessionId, logger: this.logger }, this.stateService);
80142
80385
  if (discovery.source === "discovered" && discovery.data) {
80143
80386
  effectiveResumeData = discovery.data;
80144
80387
  }
@@ -80204,7 +80447,8 @@ var require_statusline_service = __commonJS({
80204
80447
  });
80205
80448
  const overhead = await (0, context_overhead_reader_js_1.readContextOverhead)({
80206
80449
  userConfigDir: this.userConfigDir,
80207
- projectDir: this.projectDir
80450
+ projectDir: this.projectDir,
80451
+ homeDir: this.homeDir
80208
80452
  });
80209
80453
  this.logger?.debug("Successfully read baseline context overhead metrics", { overhead });
80210
80454
  return overhead;
@@ -80408,7 +80652,7 @@ var require_dist7 = __commonJS({
80408
80652
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p);
80409
80653
  };
80410
80654
  Object.defineProperty(exports2, "__esModule", { value: true });
80411
- exports2.getDefaultOverhead = exports2.readContextOverhead = exports2.createStatuslineService = exports2.StatuslineService = exports2.getThresholdStatus = exports2.formatBranch = exports2.formatDuration = exports2.formatCost = exports2.formatTokens = exports2.createFormatter = exports2.Formatter = exports2.createGitProvider = exports2.GitProvider = exports2.createStateReader = exports2.StateReader = exports2.projectRootFromSessionsDir = exports2.discoverPreviousResumeMessageDI = exports2.resolveEffectiveTokens = exports2.truncatePath = exports2.truncatePrefix = exports2.truncateSuffix = exports2.visibleLength = exports2.stripAnsi = void 0;
80655
+ exports2.getDefaultOverhead = exports2.readContextOverhead = exports2.createStatuslineService = exports2.StatuslineService = exports2.getThresholdStatus = exports2.formatBranch = exports2.formatDuration = exports2.formatCost = exports2.formatTokens = exports2.createFormatter = exports2.Formatter = exports2.createGitProvider = exports2.GitProvider = exports2.createStateReader = exports2.StateReader = exports2.discoverPreviousResumeMessageDI = exports2.resolveEffectiveTokens = exports2.truncatePath = exports2.truncatePrefix = exports2.truncateSuffix = exports2.visibleLength = exports2.stripAnsi = void 0;
80412
80656
  __exportStar(require_types3(), exports2);
80413
80657
  var ansi_utils_js_1 = require_ansi_utils();
80414
80658
  Object.defineProperty(exports2, "stripAnsi", { enumerable: true, get: function() {
@@ -80435,9 +80679,6 @@ var require_dist7 = __commonJS({
80435
80679
  Object.defineProperty(exports2, "discoverPreviousResumeMessageDI", { enumerable: true, get: function() {
80436
80680
  return resume_discovery_js_1.discoverPreviousResumeMessage;
80437
80681
  } });
80438
- Object.defineProperty(exports2, "projectRootFromSessionsDir", { enumerable: true, get: function() {
80439
- return resume_discovery_js_1.projectRootFromSessionsDir;
80440
- } });
80441
80682
  var state_reader_js_1 = require_state_reader();
80442
80683
  Object.defineProperty(exports2, "StateReader", { enumerable: true, get: function() {
80443
80684
  return state_reader_js_1.StateReader;
@@ -80627,7 +80868,8 @@ Examples:
80627
80868
  stdout.write(USAGE_TEXT);
80628
80869
  return { exitCode: 0 };
80629
80870
  }
80630
- const devModeGuard = await (0, dev_mode_guard_js_1.checkDevModeConflict)(projectDir, options.forceDevMode, logger, "statusline");
80871
+ const homeDir = options.homeDir ?? process.env.HOME;
80872
+ const devModeGuard = await (0, dev_mode_guard_js_1.checkDevModeConflict)(projectDir, options.forceDevMode, logger, "statusline", homeDir);
80631
80873
  if (devModeGuard === "bail") {
80632
80874
  stdout.write("\n");
80633
80875
  return { exitCode: 0 };
@@ -80637,7 +80879,7 @@ Examples:
80637
80879
  const startTime = performance.now();
80638
80880
  const { createStatuslineService, stripAnsi } = await Promise.resolve().then(() => __importStar(require_dist7()));
80639
80881
  const sessionId = options.sessionId ?? "current";
80640
- const stateService = new core_1.StateService(projectDir);
80882
+ const stateService = new core_1.StateService(projectDir, { homeDir });
80641
80883
  if (sessionId !== "current") {
80642
80884
  const personaStatePath = stateService.sessionStatePath(sessionId, "session-persona.json");
80643
80885
  if (!(0, node_fs_1.existsSync)(personaStatePath)) {
@@ -80667,7 +80909,7 @@ Examples:
80667
80909
  if (options.hookInput?.context_window) {
80668
80910
  logger.debug("ClaudeCodeContextWindow", { context_window: options.hookInput.context_window });
80669
80911
  }
80670
- const userConfigDir = process.env.HOME ? path.join(process.env.HOME, ".sidekick") : void 0;
80912
+ const userConfigDir = homeDir ? path.join(homeDir, ".sidekick") : void 0;
80671
80913
  const sessionsDir = stateService.sessionsDir();
80672
80914
  const sessionSummaryConfig = options.configService?.getFeature("session-summary");
80673
80915
  const resumeFreshnessHours = sessionSummaryConfig?.settings?.personas?.resumeFreshnessHours;
@@ -80675,7 +80917,7 @@ Examples:
80675
80917
  stateService,
80676
80918
  sessionId,
80677
80919
  cwd,
80678
- homeDir: process.env.HOME,
80920
+ homeDir,
80679
80921
  isResumedSession: options.isResumed ?? false,
80680
80922
  useColors,
80681
80923
  // Pass hook input directly - service will use these instead of reading state files
@@ -81060,7 +81302,7 @@ var require_persona2 = __commonJS({
81060
81302
  if (validation.result)
81061
81303
  return validation.result;
81062
81304
  const personas = validation.personas;
81063
- const stateService = new core_1.StateService(projectRoot, { cache: false, logger });
81305
+ const stateService = new core_1.StateService(projectRoot, { cache: false, logger, homeDir: options.homeDir });
81064
81306
  const personaAccessor = new core_1.SessionStateAccessor(stateService, SessionPersonaDescriptor);
81065
81307
  try {
81066
81308
  const existingResult = await personaAccessor.read(sessionId);
@@ -81098,7 +81340,7 @@ var require_persona2 = __commonJS({
81098
81340
  return { exitCode: 1, output: error };
81099
81341
  }
81100
81342
  logger.info("Clearing persona", { sessionId });
81101
- const stateService = new core_1.StateService(projectRoot, { cache: false, logger });
81343
+ const stateService = new core_1.StateService(projectRoot, { cache: false, logger, homeDir: options.homeDir });
81102
81344
  const personaAccessor = new core_1.SessionStateAccessor(stateService, SessionPersonaDescriptor);
81103
81345
  try {
81104
81346
  const existingResult = await personaAccessor.read(sessionId);
@@ -81143,7 +81385,7 @@ var require_persona2 = __commonJS({
81143
81385
  return writeJsonResponse(stdout, { error: errorMsg }, 1);
81144
81386
  }
81145
81387
  const stateFileName = testType === "snarky" ? "snarky-message.json" : "resume-message.json";
81146
- const stateService = new core_1.StateService(projectRoot, { cache: false, logger });
81388
+ const stateService = new core_1.StateService(projectRoot, { cache: false, logger, homeDir: options.homeDir });
81147
81389
  const statePath = stateService.sessionStatePath(sessionId, stateFileName);
81148
81390
  try {
81149
81391
  const content = await (0, promises_12.readFile)(statePath, "utf-8");
@@ -81577,7 +81819,7 @@ Examples:
81577
81819
  return { exitCode: 0, output: "" };
81578
81820
  }
81579
81821
  const format3 = options.format ?? "table";
81580
- const stateService = new core_1.StateService(projectRoot);
81822
+ const stateService = new core_1.StateService(projectRoot, { homeDir: options.homeDir });
81581
81823
  const sessionsDir = stateService.sessionsDir();
81582
81824
  logger.debug("Listing sessions", { sessionsDir });
81583
81825
  try {
@@ -81887,7 +82129,8 @@ var require_dev_mode = __commonJS({
81887
82129
  "PreToolUse",
81888
82130
  "PostToolUse",
81889
82131
  "Stop",
81890
- "PreCompact"
82132
+ "PreCompact",
82133
+ "PostCompact"
81891
82134
  ];
81892
82135
  var HOOK_SCRIPTS = [
81893
82136
  "session-start",
@@ -81897,6 +82140,7 @@ var require_dev_mode = __commonJS({
81897
82140
  "post-tool-use",
81898
82141
  "stop",
81899
82142
  "pre-compact",
82143
+ "post-compact",
81900
82144
  "statusline"
81901
82145
  ];
81902
82146
  async function collectMdFiles(dir) {
@@ -82007,7 +82251,7 @@ var require_dev_mode = __commonJS({
82007
82251
  await (0, promises_12.writeFile)(backupPath, content);
82008
82252
  log(stdout, "info", `Backup created: ${backupPath}`);
82009
82253
  }
82010
- async function doEnable(projectDir, stdout) {
82254
+ async function doEnable(projectDir, stdout, home) {
82011
82255
  log(stdout, "step", "Enabling dev-mode hooks...");
82012
82256
  const devHooksDir = node_path_1.default.join(projectDir, "scripts", "dev-sidekick");
82013
82257
  const settingsPath = node_path_1.default.join(projectDir, ".claude", "settings.local.json");
@@ -82048,7 +82292,8 @@ var require_dev_mode = __commonJS({
82048
82292
  { type: "PreToolUse", script: "pre-tool-use" },
82049
82293
  { type: "PostToolUse", script: "post-tool-use", matcher: "*" },
82050
82294
  { type: "Stop", script: "stop" },
82051
- { type: "PreCompact", script: "pre-compact" }
82295
+ { type: "PreCompact", script: "pre-compact" },
82296
+ { type: "PostCompact", script: "post-compact" }
82052
82297
  ];
82053
82298
  for (const { type, script, matcher } of hookConfig) {
82054
82299
  const command = `${devHooksPath}/${script}`;
@@ -82064,7 +82309,7 @@ var require_dev_mode = __commonJS({
82064
82309
  }
82065
82310
  settings.statusLine = { type: "command", command: `${devHooksPath}/statusline` };
82066
82311
  await (0, settings_js_1.writeSettingsFile)(settingsPath, settings);
82067
- const setupService = new core_1.SetupStatusService(projectDir);
82312
+ const setupService = new core_1.SetupStatusService(projectDir, { homeDir: home });
82068
82313
  await setupService.setDevMode(true);
82069
82314
  await setupService.updateProjectStatus({ statusline: "local", gitignore: "installed" });
82070
82315
  log(stdout, "info", `Dev-mode hooks enabled in ${settingsPath}`);
@@ -82079,7 +82324,7 @@ var require_dev_mode = __commonJS({
82079
82324
  log(stdout, "info", " 2. Verify sidekick is active (check statusline or run: pnpm sidekick doctor)");
82080
82325
  return { exitCode: 0 };
82081
82326
  }
82082
- async function doDisable(projectDir, logger, stdout) {
82327
+ async function doDisable(projectDir, logger, stdout, home) {
82083
82328
  log(stdout, "step", "Disabling dev-mode hooks...");
82084
82329
  const settingsPath = node_path_1.default.join(projectDir, ".claude", "settings.local.json");
82085
82330
  if (!await (0, fs_js_1.fileExists)(settingsPath)) {
@@ -82111,7 +82356,7 @@ var require_dev_mode = __commonJS({
82111
82356
  if (isDevHookCommand(settings.statusLine?.command)) {
82112
82357
  delete settings.statusLine;
82113
82358
  }
82114
- const setupService = new core_1.SetupStatusService(projectDir);
82359
+ const setupService = new core_1.SetupStatusService(projectDir, { homeDir: home });
82115
82360
  await setupService.setDevMode(false);
82116
82361
  const writeResult = await (0, settings_js_1.writeSettingsFile)(settingsPath, settings);
82117
82362
  if (writeResult === "deleted") {
@@ -82203,8 +82448,8 @@ var require_dev_mode = __commonJS({
82203
82448
  async function doClean(projectDir, logger, stdout, options = {}) {
82204
82449
  const { force = false, stdin = process.stdin } = options;
82205
82450
  log(stdout, "step", "Cleaning up sidekick state...");
82206
- const sidekickDir = node_path_1.default.join(projectDir, ".sidekick");
82207
- const logsDir = node_path_1.default.join(sidekickDir, "logs");
82451
+ const stateDir = (0, core_1.projectStateDir)(projectDir, options.homeDir);
82452
+ const logsDir = node_path_1.default.join(stateDir, "logs");
82208
82453
  const daemonClient = new core_1.DaemonClient(projectDir, logger);
82209
82454
  const killResult = await daemonClient.kill();
82210
82455
  if (killResult.killed) {
@@ -82231,7 +82476,7 @@ var require_dev_mode = __commonJS({
82231
82476
  } else {
82232
82477
  log(stdout, "info", "No logs directory found");
82233
82478
  }
82234
- await cleanStateFolder(node_path_1.default.join(sidekickDir, "state"), "Project", stdout);
82479
+ await cleanStateFolder(node_path_1.default.join(stateDir, "state"), "Project", stdout);
82235
82480
  await cleanStateFolder(node_path_1.default.join(node_os_1.default.homedir(), ".sidekick", "state"), "Global", stdout);
82236
82481
  stdout.write("\n");
82237
82482
  log(stdout, "step", "Checking for zombie daemon processes...");
@@ -82263,11 +82508,11 @@ var require_dev_mode = __commonJS({
82263
82508
  async function doCleanAll(projectDir, logger, stdout, options = {}) {
82264
82509
  const { force = false, stdin = process.stdin } = options;
82265
82510
  await doClean(projectDir, logger, stdout, options);
82266
- const sidekickDir = node_path_1.default.join(projectDir, ".sidekick");
82511
+ const stateDir = (0, core_1.projectStateDir)(projectDir, options.homeDir);
82267
82512
  stdout.write("\n");
82268
82513
  log(stdout, "step", "Removing logs, sessions, and state directories...");
82269
- await removeDirectory(node_path_1.default.join(sidekickDir, "logs"), "logs", stdout);
82270
- const sessionsDir = node_path_1.default.join(sidekickDir, "sessions");
82514
+ await removeDirectory(node_path_1.default.join(stateDir, "logs"), "logs", stdout);
82515
+ const sessionsDir = node_path_1.default.join(stateDir, "sessions");
82271
82516
  if (await (0, fs_js_1.fileExists)(sessionsDir)) {
82272
82517
  try {
82273
82518
  const sessions = await (0, promises_12.readdir)(sessionsDir);
@@ -82291,8 +82536,8 @@ var require_dev_mode = __commonJS({
82291
82536
  } else {
82292
82537
  log(stdout, "info", "No sessions directory found");
82293
82538
  }
82294
- await removeDirectory(node_path_1.default.join(sidekickDir, "state"), "state", stdout);
82295
- const setupStatusPath = node_path_1.default.join(sidekickDir, core_1.PROJECT_STATUS_FILENAME);
82539
+ await removeDirectory(node_path_1.default.join(stateDir, "state"), "state", stdout);
82540
+ const setupStatusPath = node_path_1.default.join(stateDir, core_1.PROJECT_STATUS_FILENAME);
82296
82541
  if (await (0, fs_js_1.fileExists)(setupStatusPath)) {
82297
82542
  await (0, promises_12.unlink)(setupStatusPath);
82298
82543
  log(stdout, "info", `Removed ${setupStatusPath}`);
@@ -82316,7 +82561,7 @@ var require_dev_mode = __commonJS({
82316
82561
  async function doCleanAllProjects(logger, stdout, options = {}) {
82317
82562
  const { force = false, stdin = process.stdin } = options;
82318
82563
  const registryRoot = node_path_1.default.join(node_os_1.default.homedir(), ".sidekick", "projects");
82319
- const registry = new core_1.ProjectRegistryService(registryRoot);
82564
+ const registry = new core_1.ProjectRegistryService(registryRoot, logger);
82320
82565
  const projects = await registry.list();
82321
82566
  if (projects.length === 0) {
82322
82567
  log(stdout, "info", `No registered projects found in ${registryRoot}`);
@@ -82377,9 +82622,9 @@ Options:
82377
82622
  async function handleDevModeCommand(subcommand, projectDir, logger, stdout, options = {}) {
82378
82623
  switch (subcommand) {
82379
82624
  case "enable":
82380
- return doEnable(projectDir, stdout);
82625
+ return doEnable(projectDir, stdout, options.homeDir);
82381
82626
  case "disable":
82382
- return doDisable(projectDir, logger, stdout);
82627
+ return doDisable(projectDir, logger, stdout, options.homeDir);
82383
82628
  case "status":
82384
82629
  return doStatus(projectDir, stdout);
82385
82630
  case "clean":
@@ -83109,6 +83354,71 @@ ${MARKER_END}
83109
83354
  }
83110
83355
  });
83111
83356
 
83357
+ // ../sidekick-cli/dist/commands/setup/legacy-state-cleanup.js
83358
+ var require_legacy_state_cleanup = __commonJS({
83359
+ "../sidekick-cli/dist/commands/setup/legacy-state-cleanup.js"(exports2) {
83360
+ "use strict";
83361
+ Object.defineProperty(exports2, "__esModule", { value: true });
83362
+ exports2.isLegacyDaemonAlive = isLegacyDaemonAlive;
83363
+ exports2.detectLegacyState = detectLegacyState;
83364
+ exports2.cleanLegacyState = cleanLegacyState;
83365
+ var node_path_1 = require("node:path");
83366
+ var promises_12 = require("node:fs/promises");
83367
+ var fs_js_1 = require_fs();
83368
+ var LEGACY_STATE_ENTRIES = [
83369
+ "sessions",
83370
+ "state",
83371
+ "logs",
83372
+ "setup-status.json",
83373
+ "sidekickd.pid",
83374
+ "sidekickd.token",
83375
+ "sidekickd.lock"
83376
+ ];
83377
+ async function isLegacyDaemonAlive(projectDir) {
83378
+ const legacyPid = (0, node_path_1.join)(projectDir, ".sidekick", "sidekickd.pid");
83379
+ try {
83380
+ const pid = parseInt(await (0, promises_12.readFile)(legacyPid, "utf-8"), 10);
83381
+ if (!Number.isInteger(pid) || pid <= 0)
83382
+ return false;
83383
+ process.kill(pid, 0);
83384
+ return true;
83385
+ } catch (err) {
83386
+ if (err.code === "EPERM")
83387
+ return true;
83388
+ return false;
83389
+ }
83390
+ }
83391
+ async function detectLegacyState(projectDir) {
83392
+ const sk = (0, node_path_1.join)(projectDir, ".sidekick");
83393
+ const present = [];
83394
+ for (const entry of LEGACY_STATE_ENTRIES) {
83395
+ if (await (0, fs_js_1.fileExists)((0, node_path_1.join)(sk, entry)))
83396
+ present.push(entry);
83397
+ }
83398
+ return present;
83399
+ }
83400
+ async function cleanLegacyState(projectDir) {
83401
+ const present = await detectLegacyState(projectDir);
83402
+ if (present.length === 0)
83403
+ return { removed: [], refused: false };
83404
+ if (await isLegacyDaemonAlive(projectDir)) {
83405
+ return {
83406
+ removed: [],
83407
+ refused: true,
83408
+ reason: "A pre-upgrade Sidekick daemon is still running against the old paths. Stop it first ('sidekick daemon stop' or 'sidekick daemon kill'), then re-run."
83409
+ };
83410
+ }
83411
+ const sk = (0, node_path_1.join)(projectDir, ".sidekick");
83412
+ const removed = [];
83413
+ for (const entry of present) {
83414
+ await (0, promises_12.rm)((0, node_path_1.join)(sk, entry), { recursive: true, force: true });
83415
+ removed.push(entry);
83416
+ }
83417
+ return { removed, refused: false };
83418
+ }
83419
+ }
83420
+ });
83421
+
83112
83422
  // ../sidekick-cli/dist/commands/setup/helpers.js
83113
83423
  var require_helpers = __commonJS({
83114
83424
  "../sidekick-cli/dist/commands/setup/helpers.js"(exports2) {
@@ -83372,6 +83682,7 @@ var require_doctor = __commonJS({
83372
83682
  var core_1 = require_dist4();
83373
83683
  var plugin_installer_js_1 = require_plugin_installer();
83374
83684
  var shell_alias_js_1 = require_shell_alias();
83685
+ var legacy_state_cleanup_js_1 = require_legacy_state_cleanup();
83375
83686
  var helpers_js_1 = require_helpers();
83376
83687
  var DOCTOR_CHECK_NAMES = [
83377
83688
  "api-keys",
@@ -83382,7 +83693,8 @@ var require_doctor = __commonJS({
83382
83693
  "zombies",
83383
83694
  "auto-config",
83384
83695
  "shell-alias",
83385
- "llm-config"
83696
+ "llm-config",
83697
+ "legacy-state"
83386
83698
  ];
83387
83699
  var DEPRECATED_LLM_MODELS = [
83388
83700
  {
@@ -83467,7 +83779,7 @@ var require_doctor = __commonJS({
83467
83779
  }
83468
83780
  }
83469
83781
  async function runDoctorFixes(projectDir, logger, stdout, context) {
83470
- const { homeDir, filter, doctorResult, gitignore, pluginStatus, liveness } = context;
83782
+ const { homeDir, filter, doctorResult, gitignore, pluginStatus, liveness, legacyState } = context;
83471
83783
  const isFullMode = filter === null;
83472
83784
  const shouldFix = (check) => isFullMode || filter.has(check);
83473
83785
  logger.info("Starting doctor fix mode", { homeDir, isFullMode, gitignore, pluginStatus, liveness });
@@ -83583,6 +83895,20 @@ var require_doctor = __commonJS({
83583
83895
  }
83584
83896
  }
83585
83897
  }
83898
+ if (shouldFix("legacy-state") && legacyState.length > 0) {
83899
+ const res = await (0, legacy_state_cleanup_js_1.cleanLegacyState)(projectDir);
83900
+ if (res.refused) {
83901
+ stdout.write(`Fixing: Legacy State
83902
+ \u26A0 Skipped \u2014 ${res.reason}
83903
+ `);
83904
+ unfixable.push("legacy-state");
83905
+ } else if (res.removed.length > 0) {
83906
+ stdout.write(`Fixing: Legacy State
83907
+ \u2713 Removed ${res.removed.join(", ")}
83908
+ `);
83909
+ fixedCount++;
83910
+ }
83911
+ }
83586
83912
  if (shouldFix("shell-alias")) {
83587
83913
  const shellInfo = (0, shell_alias_js_1.detectShell)(process.env.SHELL);
83588
83914
  if (shellInfo) {
@@ -83720,6 +84046,19 @@ var require_doctor = __commonJS({
83720
84046
  const zombieIcon = zombies.length === 0 ? "\u2713" : "\u26A0";
83721
84047
  const label = zombies.length === 0 ? "none detected" : `${zombies.length} found (run 'sidekick daemon kill-zombies' or 'sidekick doctor --fix --only=zombies')`;
83722
84048
  stdout.write(`${zombieIcon} Zombie Daemons: ${label}
84049
+ `);
84050
+ }));
84051
+ }
84052
+ let legacyState = [];
84053
+ if (shouldRun("legacy-state")) {
84054
+ promises.push((0, legacy_state_cleanup_js_1.detectLegacyState)(projectDir).then((found) => {
84055
+ legacyState = found;
84056
+ const icon = found.length === 0 ? "\u2713" : "\u26A0";
84057
+ const label = found.length === 0 ? "none \u2014 .sidekick is config-only" : `${found.length} legacy state entr${found.length === 1 ? "y" : "ies"} in .sidekick (run sidekick doctor --fix --only=legacy-state)`;
84058
+ stdout.write(`${icon} Legacy State: ${label}
84059
+ `);
84060
+ }).catch((err) => {
84061
+ stdout.write(`\u26A0 Legacy State: could not read \u2014 ${err.message}
83723
84062
  `);
83724
84063
  }));
83725
84064
  }
@@ -83754,7 +84093,7 @@ var require_doctor = __commonJS({
83754
84093
  if (filter === null) {
83755
84094
  const isPluginOk = (0, helpers_js_1.isPluginPresent)(pluginStatus);
83756
84095
  const isPluginLive = liveness === null || liveness === "active";
83757
- const isHealthy = doctorResult.overallHealth === "healthy" && gitignore === "installed" && isPluginOk && isPluginLive && zombieCount === 0;
84096
+ const isHealthy = doctorResult.overallHealth === "healthy" && gitignore === "installed" && isPluginOk && isPluginLive && zombieCount === 0 && legacyState.length === 0;
83758
84097
  const overallIcon = isHealthy ? "\u2713" : "\u26A0";
83759
84098
  stdout.write(`${overallIcon} Overall: ${isHealthy ? "healthy" : "needs attention"}
83760
84099
  `);
@@ -83765,7 +84104,8 @@ var require_doctor = __commonJS({
83765
84104
  doctorResult,
83766
84105
  gitignore,
83767
84106
  pluginStatus,
83768
- liveness
84107
+ liveness,
84108
+ legacyState
83769
84109
  });
83770
84110
  }
83771
84111
  if (!isHealthy) {
@@ -83780,7 +84120,8 @@ var require_doctor = __commonJS({
83780
84120
  doctorResult,
83781
84121
  gitignore,
83782
84122
  pluginStatus,
83783
- liveness
84123
+ liveness,
84124
+ legacyState
83784
84125
  });
83785
84126
  }
83786
84127
  return { exitCode: 0 };
@@ -84598,9 +84939,10 @@ var require_uninstall = __commonJS({
84598
84939
  var fs_js_1 = require_fs();
84599
84940
  var settings_js_1 = require_settings();
84600
84941
  async function handleUninstallCommand(projectDir, logger, stdout, options = {}) {
84601
- const { force = false, dryRun = false, scope, userHome = process.env.HOME || "", stdin = process.stdin } = options;
84942
+ const { force = false, dryRun = false, scope, stdin = process.stdin } = options;
84943
+ const userHome = (0, core_1.resolveHome)(options.userHome ?? process.env.HOME);
84602
84944
  const actions = [];
84603
- const projectDetected = scope !== "user" && await detectProjectScope(projectDir);
84945
+ const projectDetected = scope !== "user" && await detectProjectScope(projectDir, userHome);
84604
84946
  const userDetected = scope !== "project" && await detectUserScope(userHome);
84605
84947
  if (!projectDetected && !userDetected) {
84606
84948
  stdout.write("No sidekick installation detected.\n");
@@ -84608,7 +84950,7 @@ var require_uninstall = __commonJS({
84608
84950
  }
84609
84951
  let devModeActive = false;
84610
84952
  if (projectDetected) {
84611
- const setupService = new core_1.SetupStatusService(projectDir);
84953
+ const setupService = new core_1.SetupStatusService(projectDir, { homeDir: userHome });
84612
84954
  devModeActive = await setupService.getDevMode();
84613
84955
  if (devModeActive) {
84614
84956
  logger.info("Dev-mode active \u2014 skipping dev-mode-managed artifacts");
@@ -84659,15 +85001,16 @@ var require_uninstall = __commonJS({
84659
85001
  });
84660
85002
  }
84661
85003
  if (projectDetected) {
85004
+ const projectStatusPath = path.join((0, core_1.projectStateDir)(projectDir, userHome), core_1.PROJECT_STATUS_FILENAME);
84662
85005
  if (devModeActive) {
84663
85006
  actions.push({
84664
85007
  scope: "project",
84665
85008
  artifact: core_1.PROJECT_STATUS_FILENAME,
84666
- path: path.join(projectDir, ".sidekick", core_1.PROJECT_STATUS_FILENAME),
85009
+ path: projectStatusPath,
84667
85010
  action: "skipped"
84668
85011
  });
84669
85012
  } else {
84670
- await removeFile(path.join(projectDir, ".sidekick", core_1.PROJECT_STATUS_FILENAME), "project", core_1.PROJECT_STATUS_FILENAME, actions, {
85013
+ await removeFile(projectStatusPath, "project", core_1.PROJECT_STATUS_FILENAME, actions, {
84671
85014
  dryRun
84672
85015
  });
84673
85016
  }
@@ -84689,18 +85032,13 @@ var require_uninstall = __commonJS({
84689
85032
  await handleEnvFile(path.join(userHome, ".sidekick", ".env"), "user", stdout, actions, { force, dryRun, stdin });
84690
85033
  }
84691
85034
  if (projectDetected) {
84692
- await removeDir(path.join(projectDir, ".sidekick", "logs"), "project", "logs/", actions, { dryRun });
84693
- await removeDir(path.join(projectDir, ".sidekick", "sessions"), "project", "sessions/", actions, { dryRun });
84694
- await removeDir(path.join(projectDir, ".sidekick", "state"), "project", "state/", actions, { dryRun });
84695
- await removeFile(path.join(projectDir, ".sidekick", "sidekickd.pid"), "project", "sidekickd.pid", actions, {
84696
- dryRun
84697
- });
84698
- await removeFile(path.join(projectDir, ".sidekick", "sidekickd.token"), "project", "sidekickd.token", actions, {
84699
- dryRun
84700
- });
84701
- await removeFile(path.join(projectDir, ".sidekick", "sidekickd.lock"), "project", "sidekickd.lock", actions, {
84702
- dryRun
84703
- });
85035
+ const stateDir = (0, core_1.projectStateDir)(projectDir, userHome);
85036
+ await removeDir(path.join(stateDir, "logs"), "project", "logs/", actions, { dryRun });
85037
+ await removeDir(path.join(stateDir, "sessions"), "project", "sessions/", actions, { dryRun });
85038
+ await removeDir(path.join(stateDir, "state"), "project", "state/", actions, { dryRun });
85039
+ await removeFile((0, core_1.getPidPath)(projectDir, userHome), "project", "sidekickd.pid", actions, { dryRun });
85040
+ await removeFile((0, core_1.getTokenPath)(projectDir, userHome), "project", "sidekickd.token", actions, { dryRun });
85041
+ await removeFile((0, core_1.getLockPath)(projectDir, userHome), "project", "sidekickd.lock", actions, { dryRun });
84704
85042
  }
84705
85043
  if (userDetected) {
84706
85044
  await removeDir(path.join(userHome, ".sidekick", "state"), "user", "state/", actions, { dryRun });
@@ -84752,9 +85090,9 @@ var require_uninstall = __commonJS({
84752
85090
  printReport(stdout, actions, dryRun);
84753
85091
  return { exitCode: 0, output: "" };
84754
85092
  }
84755
- async function detectProjectScope(projectDir) {
85093
+ async function detectProjectScope(projectDir, userHome) {
84756
85094
  try {
84757
- await fs.access(path.join(projectDir, ".sidekick", core_1.PROJECT_STATUS_FILENAME));
85095
+ await fs.access(path.join((0, core_1.projectStateDir)(projectDir, userHome), core_1.PROJECT_STATUS_FILENAME));
84758
85096
  return true;
84759
85097
  } catch {
84760
85098
  for (const file of ["settings.local.json", "settings.json"]) {
@@ -84824,13 +85162,13 @@ var require_uninstall = __commonJS({
84824
85162
  if (settingsDetails.length > 0) {
84825
85163
  summary.project.push({ label: "Settings", details: [...new Set(settingsDetails)].join(", ") });
84826
85164
  }
84827
- if (await (0, fs_js_1.fileExists)(path.join(projectDir, ".sidekick", "sidekickd.pid"))) {
85165
+ if (await (0, fs_js_1.fileExists)((0, core_1.getPidPath)(projectDir, userHome))) {
84828
85166
  summary.project.push({ label: "Daemon", details: "pid file found" });
84829
85167
  }
84830
85168
  if (!devModeActive) {
84831
- const configFiles = await detectExistingItems(projectDir, [core_1.PROJECT_STATUS_FILENAME]);
84832
- if (configFiles.length > 0) {
84833
- summary.project.push({ label: "Config", details: configFiles.join(", ") });
85169
+ const setupStatusPath = path.join((0, core_1.projectStateDir)(projectDir, userHome), core_1.PROJECT_STATUS_FILENAME);
85170
+ if (await (0, fs_js_1.fileExists)(setupStatusPath)) {
85171
+ summary.project.push({ label: "Config", details: core_1.PROJECT_STATUS_FILENAME });
84834
85172
  }
84835
85173
  }
84836
85174
  const dataItems = await detectExistingItems(projectDir, ["logs", "sessions", "state"], "/");
@@ -85242,7 +85580,7 @@ var require_cli = __commonJS({
85242
85580
  var promises_12 = require("node:fs/promises");
85243
85581
  var node_stream_1 = require("node:stream");
85244
85582
  var yargs_parser_1 = __importDefault2(require_build());
85245
- var VERSION = true ? "0.1.25" : "dev";
85583
+ var VERSION = true ? "0.1.26" : "dev";
85246
85584
  var SANDBOX_ERROR_MESSAGE = `Error: Daemon commands cannot run in sandbox mode.
85247
85585
 
85248
85586
  Claude Code's sandbox blocks Unix socket operations required for daemon IPC.
@@ -85554,7 +85892,8 @@ Run 'sidekick hook --help' for available hooks.
85554
85892
  configService: runtime.config,
85555
85893
  assets: runtime.assets,
85556
85894
  help: parsed.help,
85557
- forceDevMode: parsed.forceDevMode
85895
+ forceDevMode: parsed.forceDevMode,
85896
+ homeDir: runtime.homeDir
85558
85897
  });
85559
85898
  return { exitCode: result.exitCode, stdout: "", stderr: "" };
85560
85899
  }
@@ -85577,7 +85916,8 @@ Run 'sidekick hook --help' for available hooks.
85577
85916
  testType: parsed.messageType,
85578
85917
  width: parsed.width,
85579
85918
  scope: parsed.scope === "user" || parsed.scope === "project" ? parsed.scope : void 0,
85580
- assets: runtime.assets
85919
+ assets: runtime.assets,
85920
+ homeDir: runtime.homeDir
85581
85921
  });
85582
85922
  return { exitCode: result.exitCode, stdout: result.output, stderr: "" };
85583
85923
  }
@@ -85597,14 +85937,15 @@ Run 'sidekick hook --help' for available hooks.
85597
85937
  const result = await handleSessionsCommand(runtime.projectRoot || process.cwd(), runtime.logger, stdout, {
85598
85938
  format: parsed.format === "json" || parsed.format === "table" ? parsed.format : void 0,
85599
85939
  help: parsed.help,
85600
- width: parsed.width
85940
+ width: parsed.width,
85941
+ homeDir: runtime.homeDir
85601
85942
  });
85602
85943
  return { exitCode: result.exitCode, stdout: result.output, stderr: "" };
85603
85944
  }
85604
85945
  if (parsed.command === "dev-mode") {
85605
85946
  const subcommand = parsed.help ? "--help" : parsed._ && parsed._[1] || "status";
85606
85947
  const { handleDevModeCommand } = await Promise.resolve().then(() => __importStar(require_dev_mode()));
85607
- const result = await handleDevModeCommand(subcommand, runtime.projectRoot || process.cwd(), runtime.logger, stdout, { force: Boolean(parsed.force) });
85948
+ const result = await handleDevModeCommand(subcommand, runtime.projectRoot || process.cwd(), runtime.logger, stdout, { force: Boolean(parsed.force), homeDir: runtime.homeDir });
85608
85949
  return { exitCode: result.exitCode, stdout: "", stderr: "" };
85609
85950
  }
85610
85951
  if (parsed.command === "setup" || parsed.command === "install") {