@scotthamilton77/sidekick 0.1.5 → 0.1.7

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
@@ -1030,6 +1030,7 @@ var require_events = __commonJS({
1030
1030
  "../types/dist/events.js"(exports2) {
1031
1031
  "use strict";
1032
1032
  Object.defineProperty(exports2, "__esModule", { value: true });
1033
+ exports2.HOOK_NAMES = void 0;
1033
1034
  exports2.isHookEvent = isHookEvent;
1034
1035
  exports2.isTranscriptEvent = isTranscriptEvent;
1035
1036
  exports2.isSessionStartEvent = isSessionStartEvent;
@@ -1043,6 +1044,15 @@ var require_events = __commonJS({
1043
1044
  exports2.isCLILoggingEvent = isCLILoggingEvent;
1044
1045
  exports2.isDaemonLoggingEvent = isDaemonLoggingEvent;
1045
1046
  exports2.isTranscriptLoggingEvent = isTranscriptLoggingEvent;
1047
+ exports2.HOOK_NAMES = [
1048
+ "SessionStart",
1049
+ "SessionEnd",
1050
+ "UserPromptSubmit",
1051
+ "PreToolUse",
1052
+ "PostToolUse",
1053
+ "Stop",
1054
+ "PreCompact"
1055
+ ];
1046
1056
  function isHookEvent(event) {
1047
1057
  return event.kind === "hook";
1048
1058
  }
@@ -17203,6 +17213,7 @@ var require_staging = __commonJS({
17203
17213
  userMessage: zod_1.z.string().optional(),
17204
17214
  additionalContext: zod_1.z.string().optional(),
17205
17215
  reason: zod_1.z.string().optional(),
17216
+ throttle: zod_1.z.boolean().optional(),
17206
17217
  stagedAt: exports2.StagingMetricsSchema.optional()
17207
17218
  });
17208
17219
  }
@@ -17213,9 +17224,10 @@ var require_state = __commonJS({
17213
17224
  "../types/dist/services/state.js"(exports2) {
17214
17225
  "use strict";
17215
17226
  Object.defineProperty(exports2, "__esModule", { value: true });
17216
- exports2.DEFAULT_LATENCY_STATS = exports2.LLMMetricsStateSchema = exports2.LLMSessionTotalsSchema = exports2.LLMProviderMetricsSchema = exports2.LLMModelMetricsSchema = exports2.LLMLatencyStatsSchema = exports2.DEFAULT_PROJECT_METRICS = exports2.DEFAULT_BASE_METRICS = exports2.SessionContextMetricsSchema = exports2.ProjectContextMetricsSchema = exports2.BaseTokenMetricsStateSchema = exports2.UPSThrottleStateSchema = exports2.VerificationToolsStateSchema = exports2.VerificationToolStatusSchema = exports2.VCUnverifiedStateSchema = exports2.PRBaselineStateSchema = exports2.EMPTY_LOG_METRICS = exports2.LogMetricsStateSchema = exports2.TranscriptMetricsStateSchema = exports2.ResumeMessageStateSchema = exports2.SnarkyMessageStateSchema = exports2.SummaryCountdownStateSchema = exports2.LastStagedPersonaSchema = exports2.SessionPersonaStateSchema = exports2.SESSION_SUMMARY_PLACEHOLDERS = exports2.SessionSummaryStateSchema = void 0;
17227
+ exports2.DEFAULT_LATENCY_STATS = exports2.LLMMetricsStateSchema = exports2.LLMSessionTotalsSchema = exports2.LLMProviderMetricsSchema = exports2.LLMModelMetricsSchema = exports2.LLMLatencyStatsSchema = exports2.DEFAULT_PROJECT_METRICS = exports2.DEFAULT_BASE_METRICS = exports2.SessionContextMetricsSchema = exports2.ProjectContextMetricsSchema = exports2.BaseTokenMetricsStateSchema = exports2.ReminderThrottleStateSchema = exports2.ReminderThrottleEntrySchema = exports2.CachedReminderSchema = exports2.VerificationToolsStateSchema = exports2.VerificationToolStatusSchema = exports2.VCUnverifiedStateSchema = exports2.PRBaselineStateSchema = exports2.EMPTY_LOG_METRICS = exports2.LogMetricsStateSchema = exports2.TranscriptMetricsStateSchema = exports2.ResumeMessageStateSchema = exports2.SnarkyMessageStateSchema = exports2.SummaryCountdownStateSchema = exports2.LastStagedPersonaSchema = exports2.SessionPersonaStateSchema = exports2.SESSION_SUMMARY_PLACEHOLDERS = exports2.SessionSummaryStateSchema = void 0;
17217
17228
  exports2.createDefaultLLMMetrics = createDefaultLLMMetrics;
17218
17229
  var zod_1 = require_zod();
17230
+ var events_js_1 = require_events();
17219
17231
  exports2.SessionSummaryStateSchema = zod_1.z.object({
17220
17232
  /** Session identifier */
17221
17233
  session_id: zod_1.z.string(),
@@ -17377,10 +17389,25 @@ var require_state = __commonJS({
17377
17389
  lastMatchedScope: zod_1.z.enum(["project", "package", "file"]).nullable().optional()
17378
17390
  });
17379
17391
  exports2.VerificationToolsStateSchema = zod_1.z.record(zod_1.z.string(), exports2.VerificationToolStatusSchema);
17380
- exports2.UPSThrottleStateSchema = zod_1.z.object({
17392
+ exports2.CachedReminderSchema = zod_1.z.object({
17393
+ name: zod_1.z.string(),
17394
+ blocking: zod_1.z.boolean(),
17395
+ priority: zod_1.z.number(),
17396
+ persistent: zod_1.z.boolean(),
17397
+ throttle: zod_1.z.boolean().optional(),
17398
+ userMessage: zod_1.z.string().optional(),
17399
+ additionalContext: zod_1.z.string().optional(),
17400
+ reason: zod_1.z.string().optional()
17401
+ });
17402
+ exports2.ReminderThrottleEntrySchema = zod_1.z.object({
17381
17403
  /** Number of conversation messages since the reminder was last staged */
17382
- messagesSinceLastStaging: zod_1.z.number()
17404
+ messagesSinceLastStaging: zod_1.z.number().int().nonnegative(),
17405
+ /** Hook to re-stage the reminder for */
17406
+ targetHook: zod_1.z.enum(events_js_1.HOOK_NAMES),
17407
+ /** Cached resolved reminder content for re-staging */
17408
+ cachedReminder: exports2.CachedReminderSchema
17383
17409
  });
17410
+ exports2.ReminderThrottleStateSchema = zod_1.z.record(zod_1.z.string(), exports2.ReminderThrottleEntrySchema);
17384
17411
  exports2.BaseTokenMetricsStateSchema = zod_1.z.object({
17385
17412
  /** System prompt tokens (~3.2k) */
17386
17413
  systemPromptTokens: zod_1.z.number(),
@@ -70955,6 +70982,7 @@ var require_reminder_utils = __commonJS({
70955
70982
  blocking: zod_1.z.boolean(),
70956
70983
  priority: zod_1.z.number(),
70957
70984
  persistent: zod_1.z.boolean(),
70985
+ throttle: zod_1.z.boolean().optional(),
70958
70986
  userMessage: zod_1.z.string().optional(),
70959
70987
  additionalContext: zod_1.z.string().optional(),
70960
70988
  reason: zod_1.z.string().optional()
@@ -71005,6 +71033,7 @@ var require_reminder_utils = __commonJS({
71005
71033
  blocking: def.blocking,
71006
71034
  priority: def.priority,
71007
71035
  persistent: def.persistent,
71036
+ throttle: def.throttle,
71008
71037
  userMessage: def.userMessage ? interpolateTemplate(def.userMessage, context) : void 0,
71009
71038
  additionalContext: def.additionalContext ? interpolateTemplate(def.additionalContext, context) : void 0,
71010
71039
  reason: def.reason ? interpolateTemplate(def.reason, context) : void 0
@@ -71301,7 +71330,10 @@ var require_types2 = __commonJS({
71301
71330
  max_verification_cycles: -1,
71302
71331
  // -1 = unlimited, 0 = disabled
71303
71332
  verification_tools: exports2.DEFAULT_VERIFICATION_TOOLS,
71304
- user_prompt_submit_threshold: 10
71333
+ reminder_thresholds: {
71334
+ "user-prompt-submit": 10,
71335
+ "remember-your-persona": 5
71336
+ }
71305
71337
  };
71306
71338
  exports2.ReminderIds = {
71307
71339
  USER_PROMPT_SUBMIT: "user-prompt-submit",
@@ -71345,8 +71377,8 @@ var require_state3 = __commonJS({
71345
71377
  defaultValue: {},
71346
71378
  trackHistory: false
71347
71379
  });
71348
- var UPSThrottleDescriptor = (0, core_1.sessionState)("ups-throttle.json", types_1.UPSThrottleStateSchema, {
71349
- defaultValue: { messagesSinceLastStaging: 0 },
71380
+ var ReminderThrottleDescriptor = (0, core_1.sessionState)("reminder-throttle.json", types_1.ReminderThrottleStateSchema, {
71381
+ defaultValue: {},
71350
71382
  trackHistory: false
71351
71383
  });
71352
71384
  function createRemindersState(stateService) {
@@ -71354,12 +71386,44 @@ var require_state3 = __commonJS({
71354
71386
  prBaseline: new core_1.SessionStateAccessor(stateService, PRBaselineDescriptor),
71355
71387
  vcUnverified: new core_1.SessionStateAccessor(stateService, VCUnverifiedDescriptor),
71356
71388
  verificationTools: new core_1.SessionStateAccessor(stateService, VerificationToolsDescriptor),
71357
- upsThrottle: new core_1.SessionStateAccessor(stateService, UPSThrottleDescriptor)
71389
+ reminderThrottle: new core_1.SessionStateAccessor(stateService, ReminderThrottleDescriptor)
71358
71390
  };
71359
71391
  }
71360
71392
  }
71361
71393
  });
71362
71394
 
71395
+ // ../feature-reminders/dist/handlers/staging/throttle-utils.js
71396
+ var require_throttle_utils = __commonJS({
71397
+ "../feature-reminders/dist/handlers/staging/throttle-utils.js"(exports2) {
71398
+ "use strict";
71399
+ Object.defineProperty(exports2, "__esModule", { value: true });
71400
+ exports2.registerThrottledReminder = registerThrottledReminder;
71401
+ exports2.resetThrottleCounters = resetThrottleCounters;
71402
+ var state_js_1 = require_state3();
71403
+ async function registerThrottledReminder(ctx, sessionId, reminderId, targetHook, resolvedReminder) {
71404
+ const remindersState = (0, state_js_1.createRemindersState)(ctx.stateService);
71405
+ const result = await remindersState.reminderThrottle.read(sessionId);
71406
+ const state = { ...result.data };
71407
+ const { stagedAt: _stagedAt, ...cachedReminder } = resolvedReminder;
71408
+ state[reminderId] = {
71409
+ messagesSinceLastStaging: 0,
71410
+ targetHook,
71411
+ cachedReminder
71412
+ };
71413
+ await remindersState.reminderThrottle.write(sessionId, state);
71414
+ }
71415
+ async function resetThrottleCounters(ctx, sessionId) {
71416
+ const remindersState = (0, state_js_1.createRemindersState)(ctx.stateService);
71417
+ const result = await remindersState.reminderThrottle.read(sessionId);
71418
+ const state = { ...result.data };
71419
+ for (const key of Object.keys(state)) {
71420
+ state[key] = { ...state[key], messagesSinceLastStaging: 0 };
71421
+ }
71422
+ await remindersState.reminderThrottle.write(sessionId, state);
71423
+ }
71424
+ }
71425
+ });
71426
+
71363
71427
  // ../feature-reminders/dist/handlers/staging/stage-default-user-prompt.js
71364
71428
  var require_stage_default_user_prompt = __commonJS({
71365
71429
  "../feature-reminders/dist/handlers/staging/stage-default-user-prompt.js"(exports2) {
@@ -71371,6 +71435,7 @@ var require_stage_default_user_prompt = __commonJS({
71371
71435
  var types_js_1 = require_types2();
71372
71436
  var reminder_utils_js_1 = require_reminder_utils();
71373
71437
  var state_js_1 = require_state3();
71438
+ var throttle_utils_js_1 = require_throttle_utils();
71374
71439
  function registerStageDefaultUserPrompt(context) {
71375
71440
  (0, staging_handler_utils_js_1.createStagingHandler)(context, {
71376
71441
  id: "reminders:stage-default-user-prompt",
@@ -71388,23 +71453,6 @@ var require_stage_default_user_prompt = __commonJS({
71388
71453
  };
71389
71454
  }
71390
71455
  });
71391
- if ((0, types_1.isDaemonContext)(context)) {
71392
- const startCtx = context;
71393
- context.handlers.register({
71394
- id: "reminders:ups-throttle-reset-session-start",
71395
- priority: 49,
71396
- filter: { kind: "hook", hooks: ["SessionStart"] },
71397
- handler: async (event) => {
71398
- if (!(0, types_1.isHookEvent)(event) || !(0, types_1.isSessionStartEvent)(event))
71399
- return;
71400
- const sessionId = event.context.sessionId;
71401
- if (!sessionId)
71402
- return;
71403
- const remindersState = (0, state_js_1.createRemindersState)(startCtx.stateService);
71404
- await remindersState.upsThrottle.write(sessionId, { messagesSinceLastStaging: 0 });
71405
- }
71406
- });
71407
- }
71408
71456
  (0, staging_handler_utils_js_1.createStagingHandler)(context, {
71409
71457
  id: "reminders:stage-default-user-prompt-after-bulk",
71410
71458
  priority: 50,
@@ -71421,65 +71469,120 @@ var require_stage_default_user_prompt = __commonJS({
71421
71469
  };
71422
71470
  }
71423
71471
  });
71424
- if ((0, types_1.isDaemonContext)(context)) {
71425
- const bulkCtx = context;
71426
- context.handlers.register({
71427
- id: "reminders:ups-throttle-reset-bulk",
71428
- priority: 49,
71429
- filter: { kind: "transcript", eventTypes: ["BulkProcessingComplete"] },
71430
- handler: async (event) => {
71431
- if (!(0, types_1.isTranscriptEvent)(event))
71432
- return;
71433
- if (event.metadata.isBulkProcessing)
71434
- return;
71435
- const sessionId = event.context?.sessionId;
71436
- if (!sessionId)
71437
- return;
71438
- const remindersState = (0, state_js_1.createRemindersState)(bulkCtx.stateService);
71439
- await remindersState.upsThrottle.write(sessionId, { messagesSinceLastStaging: 0 });
71440
- }
71441
- });
71442
- }
71443
71472
  if (!(0, types_1.isDaemonContext)(context))
71444
71473
  return;
71445
71474
  context.handlers.register({
71446
- id: "reminders:ups-throttle-restage",
71447
- priority: 50,
71448
- filter: { kind: "transcript", eventTypes: ["UserPrompt", "AssistantMessage"] },
71475
+ id: "reminders:throttle-register-ups-session-start",
71476
+ priority: 49,
71477
+ filter: { kind: "hook", hooks: ["SessionStart"] },
71449
71478
  handler: async (event, ctx) => {
71450
- if (!(0, types_1.isTranscriptEvent)(event))
71479
+ if (!(0, types_1.isHookEvent)(event) || !(0, types_1.isSessionStartEvent)(event))
71480
+ return;
71481
+ if (!(0, types_1.isDaemonContext)(ctx))
71482
+ return;
71483
+ const handlerCtx = ctx;
71484
+ const sessionId = event.context.sessionId;
71485
+ if (!sessionId)
71486
+ return;
71487
+ const reminder = (0, reminder_utils_js_1.resolveReminder)(types_js_1.ReminderIds.USER_PROMPT_SUBMIT, {
71488
+ context: { sessionId },
71489
+ assets: handlerCtx.assets
71490
+ });
71491
+ if (reminder) {
71492
+ await (0, throttle_utils_js_1.registerThrottledReminder)(handlerCtx, sessionId, types_js_1.ReminderIds.USER_PROMPT_SUBMIT, "UserPromptSubmit", reminder);
71493
+ }
71494
+ }
71495
+ });
71496
+ context.handlers.register({
71497
+ id: "reminders:throttle-reset-session-start",
71498
+ priority: 48,
71499
+ filter: { kind: "hook", hooks: ["SessionStart"] },
71500
+ handler: async (event, ctx) => {
71501
+ if (!(0, types_1.isHookEvent)(event) || !(0, types_1.isSessionStartEvent)(event))
71451
71502
  return;
71452
71503
  if (!(0, types_1.isDaemonContext)(ctx))
71453
71504
  return;
71505
+ const handlerCtx = ctx;
71506
+ const sessionId = event.context.sessionId;
71507
+ if (!sessionId)
71508
+ return;
71509
+ await (0, throttle_utils_js_1.resetThrottleCounters)(handlerCtx, sessionId);
71510
+ }
71511
+ });
71512
+ context.handlers.register({
71513
+ id: "reminders:throttle-reset-bulk",
71514
+ priority: 49,
71515
+ filter: { kind: "transcript", eventTypes: ["BulkProcessingComplete"] },
71516
+ handler: async (event, ctx) => {
71517
+ if (!(0, types_1.isTranscriptEvent)(event))
71518
+ return;
71454
71519
  if (event.metadata.isBulkProcessing)
71455
71520
  return;
71521
+ if (!(0, types_1.isDaemonContext)(ctx))
71522
+ return;
71523
+ const handlerCtx = ctx;
71456
71524
  const sessionId = event.context?.sessionId;
71457
71525
  if (!sessionId)
71458
71526
  return;
71527
+ await (0, throttle_utils_js_1.resetThrottleCounters)(handlerCtx, sessionId);
71528
+ }
71529
+ });
71530
+ context.handlers.register({
71531
+ id: "reminders:throttle-restage",
71532
+ priority: 50,
71533
+ filter: { kind: "transcript", eventTypes: ["UserPrompt", "AssistantMessage"] },
71534
+ handler: async (event, ctx) => {
71535
+ if (!(0, types_1.isTranscriptEvent)(event))
71536
+ return;
71537
+ if (event.metadata.isBulkProcessing)
71538
+ return;
71539
+ if (!(0, types_1.isDaemonContext)(ctx))
71540
+ return;
71459
71541
  const handlerCtx = ctx;
71542
+ const sessionId = event.context?.sessionId;
71543
+ if (!sessionId)
71544
+ return;
71460
71545
  const remindersState = (0, state_js_1.createRemindersState)(handlerCtx.stateService);
71461
- const result = await remindersState.upsThrottle.read(sessionId);
71462
- const current = result.data.messagesSinceLastStaging;
71546
+ const result = await remindersState.reminderThrottle.read(sessionId);
71547
+ const state = { ...result.data };
71548
+ if (Object.keys(state).length === 0)
71549
+ return;
71463
71550
  const featureConfig = handlerCtx.config.getFeature("reminders");
71464
71551
  const config = { ...types_js_1.DEFAULT_REMINDERS_SETTINGS, ...featureConfig.settings };
71465
- const threshold = config.user_prompt_submit_threshold ?? 10;
71466
- const newCount = current + 1;
71467
- if (newCount >= threshold) {
71468
- const reminder = (0, reminder_utils_js_1.resolveReminder)(types_js_1.ReminderIds.USER_PROMPT_SUBMIT, {
71469
- context: { sessionId },
71470
- assets: handlerCtx.assets
71471
- });
71472
- if (reminder) {
71473
- await (0, reminder_utils_js_1.stageReminder)(handlerCtx, "UserPromptSubmit", reminder);
71474
- handlerCtx.logger.debug("UPS throttle: re-staged reminder", {
71552
+ const thresholds = config.reminder_thresholds ?? {};
71553
+ let changed = false;
71554
+ for (const [reminderId, entry] of Object.entries(state)) {
71555
+ const typedEntry = entry;
71556
+ const threshold = thresholds[reminderId];
71557
+ if (threshold === void 0)
71558
+ continue;
71559
+ const newCount = typedEntry.messagesSinceLastStaging + 1;
71560
+ if (newCount >= threshold) {
71561
+ const metrics = event.metadata.metrics;
71562
+ const stagedAt = {
71563
+ timestamp: Date.now(),
71564
+ turnCount: metrics.turnCount,
71565
+ toolsThisTurn: metrics.toolsThisTurn,
71566
+ toolCount: metrics.toolCount
71567
+ };
71568
+ await (0, reminder_utils_js_1.stageReminder)(handlerCtx, typedEntry.targetHook, {
71569
+ ...typedEntry.cachedReminder,
71570
+ stagedAt
71571
+ });
71572
+ state[reminderId] = { ...typedEntry, messagesSinceLastStaging: 0 };
71573
+ handlerCtx.logger.debug("Throttle: re-staged reminder", {
71475
71574
  sessionId,
71575
+ reminderId,
71476
71576
  messageCount: newCount,
71477
71577
  threshold
71478
71578
  });
71579
+ } else {
71580
+ state[reminderId] = { ...typedEntry, messagesSinceLastStaging: newCount };
71479
71581
  }
71480
- await remindersState.upsThrottle.write(sessionId, { messagesSinceLastStaging: 0 });
71481
- } else {
71482
- await remindersState.upsThrottle.write(sessionId, { messagesSinceLastStaging: newCount });
71582
+ changed = true;
71583
+ }
71584
+ if (changed) {
71585
+ await remindersState.reminderThrottle.write(sessionId, state);
71483
71586
  }
71484
71587
  }
71485
71588
  });
@@ -73182,27 +73285,33 @@ var require_track_verification_tools = __commonJS({
73182
73285
  continue;
73183
73286
  const current = toolsState[toolName];
73184
73287
  if (!current || current.status === "staged") {
73185
- if (!current) {
73186
- toolsState[toolName] = {
73187
- status: "staged",
73188
- editsSinceVerified: 0,
73189
- lastVerifiedAt: null,
73190
- lastStagedAt: Date.now()
73191
- };
73288
+ const staged = await ensureToolReminderStaged(daemonCtx, reminderId, stagedNames);
73289
+ if (staged) {
73290
+ if (!current) {
73291
+ toolsState[toolName] = {
73292
+ status: "staged",
73293
+ editsSinceVerified: 0,
73294
+ lastVerifiedAt: null,
73295
+ lastStagedAt: Date.now()
73296
+ };
73297
+ }
73298
+ stagedNames.add(reminderId);
73299
+ anyStaged = true;
73192
73300
  }
73193
- await stageToolReminderIfNeeded(daemonCtx, reminderId, stagedNames);
73194
- anyStaged = true;
73195
73301
  } else {
73196
73302
  const newEdits = current.editsSinceVerified + 1;
73197
73303
  if (newEdits >= toolConfig.clearing_threshold) {
73198
- toolsState[toolName] = {
73199
- ...current,
73200
- status: "staged",
73201
- editsSinceVerified: 0,
73202
- lastStagedAt: Date.now()
73203
- };
73204
- await stageToolReminderIfNeeded(daemonCtx, reminderId, stagedNames);
73205
- anyStaged = true;
73304
+ const staged = await ensureToolReminderStaged(daemonCtx, reminderId, stagedNames);
73305
+ if (staged) {
73306
+ toolsState[toolName] = {
73307
+ ...current,
73308
+ status: "staged",
73309
+ editsSinceVerified: 0,
73310
+ lastStagedAt: Date.now()
73311
+ };
73312
+ stagedNames.add(reminderId);
73313
+ anyStaged = true;
73314
+ }
73206
73315
  } else {
73207
73316
  toolsState[toolName] = {
73208
73317
  ...current,
@@ -73214,7 +73323,10 @@ var require_track_verification_tools = __commonJS({
73214
73323
  }
73215
73324
  }
73216
73325
  if (anyStaged) {
73217
- await stageToolReminderIfNeeded(daemonCtx, types_js_1.ReminderIds.VERIFY_COMPLETION, stagedNames);
73326
+ const wrapperStaged = await ensureToolReminderStaged(daemonCtx, types_js_1.ReminderIds.VERIFY_COMPLETION, stagedNames);
73327
+ if (!wrapperStaged) {
73328
+ daemonCtx.logger.warn("Failed to stage verify-completion wrapper reminder", { sessionId });
73329
+ }
73218
73330
  }
73219
73331
  await remindersState.verificationTools.write(sessionId, toolsState);
73220
73332
  return anyStaged;
@@ -73270,21 +73382,22 @@ var require_track_verification_tools = __commonJS({
73270
73382
  await remindersState.verificationTools.write(sessionId, toolsState);
73271
73383
  }
73272
73384
  }
73273
- async function stageToolReminderIfNeeded(daemonCtx, reminderId, stagedNames) {
73385
+ async function ensureToolReminderStaged(daemonCtx, reminderId, stagedNames) {
73274
73386
  if (stagedNames.has(reminderId))
73275
- return;
73387
+ return true;
73276
73388
  const reminder = (0, reminder_utils_js_1.resolveReminder)(reminderId, {
73277
73389
  context: {},
73278
73390
  assets: daemonCtx.assets
73279
73391
  });
73280
73392
  if (!reminder) {
73281
73393
  daemonCtx.logger.warn("Failed to resolve VC tool reminder", { reminderId });
73282
- return;
73394
+ return false;
73283
73395
  }
73284
73396
  await (0, reminder_utils_js_1.stageReminder)(daemonCtx, "Stop", {
73285
73397
  ...reminder,
73286
73398
  stagedAt: { timestamp: Date.now(), turnCount: 0, toolsThisTurn: 0, toolCount: 0 }
73287
73399
  });
73400
+ return true;
73288
73401
  }
73289
73402
  }
73290
73403
  });
@@ -73539,6 +73652,7 @@ var require_stage_persona_reminders = __commonJS({
73539
73652
  var types_1 = require_dist();
73540
73653
  var reminder_utils_js_1 = require_reminder_utils();
73541
73654
  var types_js_1 = require_types2();
73655
+ var throttle_utils_js_1 = require_throttle_utils();
73542
73656
  async function restagePersonaRemindersForActiveSessions(ctxFactory, sessionIds, logger) {
73543
73657
  logger.info("Re-staging persona reminders for active sessions", { count: sessionIds.length });
73544
73658
  for (const sessionId of sessionIds) {
@@ -73621,6 +73735,9 @@ var require_stage_persona_reminders = __commonJS({
73621
73735
  if (reminder) {
73622
73736
  for (const targetHook of PERSONA_REMINDER_HOOKS) {
73623
73737
  await (0, reminder_utils_js_1.stageReminder)(ctx, targetHook, reminder);
73738
+ if (targetHook === "UserPromptSubmit") {
73739
+ await (0, throttle_utils_js_1.registerThrottledReminder)(ctx, sessionId, types_js_1.ReminderIds.REMEMBER_YOUR_PERSONA, "UserPromptSubmit", reminder);
73740
+ }
73624
73741
  }
73625
73742
  } else {
73626
73743
  ctx.logger.warn("Failed to resolve persona reminder", {
@@ -75481,7 +75598,7 @@ var require_types3 = __commonJS({
75481
75598
  });
75482
75599
  exports2.DEFAULT_STATUSLINE_CONFIG = {
75483
75600
  enabled: true,
75484
- format: "[{model}] | {contextBar} {tokenPercentageActual} | {logs} | {cwd}{branch}\n{title} | {summary}",
75601
+ format: "{personaName,prefix='[',suffix='] | '}{model,prefix='[',suffix='] | '}{contextBar} {tokenPercentageActual} | {logs} | {cwd,maxLength=40,truncateStyle='path'}{branch,prefix=' \u2217 ',maxLength=40}{title,wrapAt=80,prefix=' | ',wrapPrefix='\\n'}\n{summary}",
75485
75602
  thresholds: {
75486
75603
  tokens: { warning: 1e5, critical: 16e4 },
75487
75604
  cost: { warning: 0.5, critical: 1 },
@@ -75493,7 +75610,7 @@ var require_types3 = __commonJS({
75493
75610
  colors: {
75494
75611
  model: "blue",
75495
75612
  tokens: "green",
75496
- title: "blue",
75613
+ title: "cyan",
75497
75614
  summary: "magenta",
75498
75615
  cwd: "white",
75499
75616
  duration: "white"
@@ -75589,6 +75706,76 @@ var require_types3 = __commonJS({
75589
75706
  }
75590
75707
  });
75591
75708
 
75709
+ // ../feature-statusline/dist/ansi-utils.js
75710
+ var require_ansi_utils = __commonJS({
75711
+ "../feature-statusline/dist/ansi-utils.js"(exports2) {
75712
+ "use strict";
75713
+ Object.defineProperty(exports2, "__esModule", { value: true });
75714
+ exports2.stripAnsi = stripAnsi;
75715
+ exports2.visibleLength = visibleLength;
75716
+ var ANSI_REGEX = /\x1b\[[0-9;?]*[0-9A-PR-TZcf-nqry=><~]|\x1b\][^\x07]*\x07/g;
75717
+ function stripAnsi(str) {
75718
+ return str.replace(ANSI_REGEX, "");
75719
+ }
75720
+ function visibleLength(str) {
75721
+ return stripAnsi(str).length;
75722
+ }
75723
+ }
75724
+ });
75725
+
75726
+ // ../feature-statusline/dist/truncation.js
75727
+ var require_truncation = __commonJS({
75728
+ "../feature-statusline/dist/truncation.js"(exports2) {
75729
+ "use strict";
75730
+ Object.defineProperty(exports2, "__esModule", { value: true });
75731
+ exports2.truncateSuffix = truncateSuffix;
75732
+ exports2.truncatePrefix = truncatePrefix;
75733
+ exports2.truncatePath = truncatePath;
75734
+ var ansi_utils_js_1 = require_ansi_utils();
75735
+ function truncateSuffix(str, maxLength) {
75736
+ if ((0, ansi_utils_js_1.visibleLength)(str) <= maxLength)
75737
+ return str;
75738
+ const plain = (0, ansi_utils_js_1.stripAnsi)(str);
75739
+ if (maxLength <= 1)
75740
+ return "\u2026";
75741
+ return plain.slice(0, maxLength - 1) + "\u2026";
75742
+ }
75743
+ function truncatePrefix(str, maxLength) {
75744
+ if ((0, ansi_utils_js_1.visibleLength)(str) <= maxLength)
75745
+ return str;
75746
+ const plain = (0, ansi_utils_js_1.stripAnsi)(str);
75747
+ if (maxLength <= 1)
75748
+ return "\u2026";
75749
+ return "\u2026" + plain.slice(-(maxLength - 1));
75750
+ }
75751
+ function truncatePath(str, maxLength) {
75752
+ const plain = (0, ansi_utils_js_1.stripAnsi)(str);
75753
+ if (plain.length <= maxLength)
75754
+ return str;
75755
+ const parts = plain.split("/");
75756
+ if (parts.length === 1) {
75757
+ return truncatePrefix(plain, maxLength);
75758
+ }
75759
+ if (parts.length === 2) {
75760
+ return truncatePrefix(plain, maxLength);
75761
+ }
75762
+ const first = parts[0];
75763
+ const last = parts[parts.length - 1];
75764
+ const candidate = `${first}/\u2026/${last}`;
75765
+ if (candidate.length <= maxLength) {
75766
+ return candidate;
75767
+ }
75768
+ const fixedPart = `/\u2026/${last}`;
75769
+ const availableForFirst = maxLength - fixedPart.length;
75770
+ if (availableForFirst <= 1) {
75771
+ return truncatePrefix(plain, maxLength);
75772
+ }
75773
+ const truncatedFirst = truncatePrefix(first, availableForFirst);
75774
+ return `${truncatedFirst}${fixedPart}`;
75775
+ }
75776
+ }
75777
+ });
75778
+
75592
75779
  // ../feature-session-summary/dist/state.js
75593
75780
  var require_state4 = __commonJS({
75594
75781
  "../feature-session-summary/dist/state.js"(exports2) {
@@ -77245,7 +77432,6 @@ var require_formatter = __commonJS({
77245
77432
  exports2.formatTokens = formatTokens;
77246
77433
  exports2.formatCost = formatCost;
77247
77434
  exports2.formatDuration = formatDuration;
77248
- exports2.shortenPath = shortenPath;
77249
77435
  exports2.formatCwd = formatCwd;
77250
77436
  exports2.formatBranch = formatBranch;
77251
77437
  exports2.formatLogs = formatLogs;
@@ -77255,6 +77441,8 @@ var require_formatter = __commonJS({
77255
77441
  exports2.formatContextBar = formatContextBar;
77256
77442
  exports2.getContextBarStatus = getContextBarStatus;
77257
77443
  exports2.calculateContextUsage = calculateContextUsage;
77444
+ var ansi_utils_js_1 = require_ansi_utils();
77445
+ var truncation_js_1 = require_truncation();
77258
77446
  var types_js_1 = require_types3();
77259
77447
  var ANSI = {
77260
77448
  reset: "\x1B[0m",
@@ -77296,6 +77484,59 @@ var require_formatter = __commonJS({
77296
77484
  const colorName = name;
77297
77485
  return ANSI[colorName] ?? "";
77298
77486
  }
77487
+ function parseTokenOptions(optionsStr) {
77488
+ if (!optionsStr)
77489
+ return {};
77490
+ const options = {};
77491
+ const stringPattern = /(\w+)='((?:[^'\\]|\\.)*)'/g;
77492
+ let match;
77493
+ while ((match = stringPattern.exec(optionsStr)) !== null) {
77494
+ const key = match[1];
77495
+ const val = match[2].replace(/\\'/g, "'").replace(/\\\\/g, "\\");
77496
+ switch (key) {
77497
+ case "prefix":
77498
+ options.prefix = val;
77499
+ break;
77500
+ case "suffix":
77501
+ options.suffix = val;
77502
+ break;
77503
+ case "truncateStyle":
77504
+ options.truncateStyle = val;
77505
+ break;
77506
+ case "wrapPrefix":
77507
+ options.wrapPrefix = val;
77508
+ break;
77509
+ case "wrapSuffix":
77510
+ options.wrapSuffix = val;
77511
+ break;
77512
+ }
77513
+ }
77514
+ const numPattern = /(\w+)=(\d+)(?=[,}]|$)/g;
77515
+ while ((match = numPattern.exec(optionsStr)) !== null) {
77516
+ const key = match[1];
77517
+ const val = parseInt(match[2], 10);
77518
+ switch (key) {
77519
+ case "maxLength":
77520
+ options.maxLength = val;
77521
+ break;
77522
+ case "wrapAt":
77523
+ options.wrapAt = val;
77524
+ break;
77525
+ }
77526
+ }
77527
+ return options;
77528
+ }
77529
+ function applyTruncation(value, maxLength, style) {
77530
+ switch (style) {
77531
+ case "prefix":
77532
+ return (0, truncation_js_1.truncatePrefix)(value, maxLength);
77533
+ case "path":
77534
+ return (0, truncation_js_1.truncatePath)(value, maxLength);
77535
+ case "suffix":
77536
+ default:
77537
+ return (0, truncation_js_1.truncateSuffix)(value, maxLength);
77538
+ }
77539
+ }
77299
77540
  var Formatter = class {
77300
77541
  theme;
77301
77542
  useColors;
@@ -77311,50 +77552,121 @@ var require_formatter = __commonJS({
77311
77552
  * (e.g., a snarky comment containing "|") are preserved.
77312
77553
  */
77313
77554
  format(template, viewModel) {
77555
+ template = template.replace(/\\n/g, "\n");
77314
77556
  const branchColor = this.theme.colors.branch ?? viewModel.branchColor;
77315
77557
  const symbolMode = (0, types_js_1.normalizeSymbolMode)(this.theme.useNerdFonts);
77316
77558
  const logsText = formatLogs(viewModel.warningCount, viewModel.errorCount, symbolMode);
77317
77559
  const convertedSummary = this.convertMarkdown(viewModel.summary);
77318
77560
  const convertedTitle = this.convertMarkdown(viewModel.title);
77319
- const tokens = {
77320
- model: this.colorize(viewModel.model, this.theme.colors.model),
77321
- // Atomic token placeholders - each can be used independently in templates
77322
- contextWindow: this.colorize(viewModel.contextWindow, this.theme.colors.tokens),
77323
- tokenUsageActual: this.colorizeByStatus(viewModel.tokenUsageActual, viewModel.tokensStatus),
77324
- tokenUsageEffective: this.colorizeByStatus(viewModel.tokenUsageEffective, viewModel.tokensStatus),
77325
- tokenPercentageActual: this.colorizeByStatus(viewModel.tokenPercentageActual, viewModel.tokensStatus),
77326
- tokenPercentageEffective: this.colorizeByStatus(viewModel.tokenPercentageEffective, viewModel.tokensStatus),
77327
- cost: this.colorizeByStatus(viewModel.cost, viewModel.costStatus),
77328
- duration: this.colorize(viewModel.duration, this.theme.colors.duration),
77329
- cwd: this.colorize(viewModel.cwd, this.theme.colors.cwd),
77330
- branch: viewModel.branch ? ` ${this.colorize(viewModel.branch, branchColor)}` : "",
77331
- summary: this.colorize(convertedSummary, this.theme.colors.summary),
77332
- title: this.colorize(convertedTitle, this.theme.colors.title),
77333
- contextBar: formatContextBar(viewModel.contextUsage, this.useColors, symbolMode),
77334
- logs: this.colorizeByStatus(logsText, viewModel.logStatus),
77335
- // Persona name token - empty string when no persona or disabled
77336
- personaName: viewModel.personaName ? this.colorize(viewModel.personaName, this.theme.colors.persona ?? "cyan") : ""
77561
+ const rawTokens = {
77562
+ model: viewModel.model,
77563
+ contextWindow: viewModel.contextWindow,
77564
+ tokenUsageActual: viewModel.tokenUsageActual,
77565
+ tokenUsageEffective: viewModel.tokenUsageEffective,
77566
+ tokenPercentageActual: viewModel.tokenPercentageActual,
77567
+ tokenPercentageEffective: viewModel.tokenPercentageEffective,
77568
+ cost: viewModel.cost,
77569
+ duration: viewModel.duration,
77570
+ cwd: viewModel.cwd,
77571
+ branch: viewModel.branch,
77572
+ projectDirShort: viewModel.projectDirShort,
77573
+ projectDirFull: viewModel.projectDirFull,
77574
+ worktreeName: viewModel.worktreeName,
77575
+ worktreeOrBranch: viewModel.worktreeOrBranch,
77576
+ summary: convertedSummary,
77577
+ title: convertedTitle,
77578
+ logs: logsText,
77579
+ personaName: viewModel.personaName,
77580
+ // Pre-formatted tokens (already contain ANSI if colors enabled)
77581
+ contextBar: formatContextBar(viewModel.contextUsage, this.useColors, symbolMode)
77582
+ };
77583
+ const personaColor = this.theme.colors.persona ?? "cyan";
77584
+ const colorizeToken = (tokenName, value) => {
77585
+ switch (tokenName) {
77586
+ case "tokenUsageActual":
77587
+ case "tokenUsageEffective":
77588
+ case "tokenPercentageActual":
77589
+ case "tokenPercentageEffective":
77590
+ return this.colorizeByStatus(value, viewModel.tokensStatus);
77591
+ case "cost":
77592
+ return this.colorizeByStatus(value, viewModel.costStatus);
77593
+ case "logs":
77594
+ return this.colorizeByStatus(value, viewModel.logStatus);
77595
+ case "model":
77596
+ return this.colorize(value, this.theme.colors.model);
77597
+ case "contextWindow":
77598
+ return this.colorize(value, this.theme.colors.tokens);
77599
+ case "duration":
77600
+ return this.colorize(value, this.theme.colors.duration);
77601
+ case "cwd":
77602
+ case "projectDirShort":
77603
+ case "projectDirFull":
77604
+ return this.colorize(value, this.theme.colors.cwd);
77605
+ case "branch":
77606
+ case "worktreeOrBranch":
77607
+ case "worktreeName":
77608
+ return this.colorize(value, branchColor);
77609
+ case "summary":
77610
+ return this.colorize(value, this.theme.colors.summary);
77611
+ case "title":
77612
+ return this.colorize(value, this.theme.colors.title);
77613
+ case "personaName":
77614
+ return this.colorize(value, personaColor);
77615
+ case "contextBar":
77616
+ return value;
77617
+ // already formatted with colors
77618
+ default:
77619
+ return value;
77620
+ }
77337
77621
  };
77338
77622
  const EMPTY_MARKER = "\0EMPTY\0";
77339
- let result = template.replace(/\{(\w+)(?:,([^}]*))?\}/g, (_match, tokenName, optionsStr) => {
77340
- const value = tokens[tokenName] ?? "";
77341
- let prefix = "";
77342
- let suffix = "";
77343
- if (optionsStr) {
77344
- const prefixMatch = optionsStr.match(/prefix='((?:[^'\\]|\\.)*)'/);
77345
- if (prefixMatch) {
77346
- prefix = prefixMatch[1].replace(/\\'/g, "'").replace(/\\\\/g, "\\");
77347
- }
77348
- const suffixMatch = optionsStr.match(/suffix='((?:[^'\\]|\\.)*)'/);
77349
- if (suffixMatch) {
77350
- suffix = suffixMatch[1].replace(/\\'/g, "'").replace(/\\\\/g, "\\");
77351
- }
77623
+ let currentLineWidth = 0;
77624
+ const TOKEN_REGEX = /\{(\w+)(?:,([^}]*))?\}/g;
77625
+ let result = "";
77626
+ let lastIndex = 0;
77627
+ let match;
77628
+ while ((match = TOKEN_REGEX.exec(template)) !== null) {
77629
+ const literal = template.slice(lastIndex, match.index);
77630
+ result += literal;
77631
+ const literalNewline = literal.lastIndexOf("\n");
77632
+ if (literalNewline >= 0) {
77633
+ currentLineWidth = (0, ansi_utils_js_1.visibleLength)(literal.slice(literalNewline + 1));
77634
+ } else {
77635
+ currentLineWidth += (0, ansi_utils_js_1.visibleLength)(literal);
77352
77636
  }
77637
+ const tokenName = match[1];
77638
+ const optionsStr = match[2];
77639
+ let value = rawTokens[tokenName] ?? "";
77353
77640
  if (!value) {
77354
- return EMPTY_MARKER;
77641
+ result += EMPTY_MARKER;
77642
+ lastIndex = TOKEN_REGEX.lastIndex;
77643
+ continue;
77355
77644
  }
77356
- return prefix + value + suffix;
77357
- });
77645
+ const options = parseTokenOptions(optionsStr);
77646
+ if (options.maxLength !== void 0 && tokenName !== "contextBar") {
77647
+ value = applyTruncation(value, options.maxLength, options.truncateStyle ?? "suffix");
77648
+ }
77649
+ const colorized = colorizeToken(tokenName, value);
77650
+ let prefix = options.prefix ?? "";
77651
+ let suffix = options.suffix ?? "";
77652
+ if (options.wrapAt !== void 0) {
77653
+ const candidateWidth = currentLineWidth + (0, ansi_utils_js_1.visibleLength)(prefix) + (0, ansi_utils_js_1.visibleLength)(value);
77654
+ if (candidateWidth > options.wrapAt) {
77655
+ prefix = options.wrapPrefix ?? prefix;
77656
+ suffix = options.wrapSuffix ?? suffix;
77657
+ }
77658
+ }
77659
+ const segment = prefix + colorized + suffix;
77660
+ const lastNewlineInSegment = segment.lastIndexOf("\n");
77661
+ if (lastNewlineInSegment >= 0) {
77662
+ currentLineWidth = (0, ansi_utils_js_1.visibleLength)(segment.slice(lastNewlineInSegment + 1));
77663
+ } else {
77664
+ currentLineWidth += (0, ansi_utils_js_1.visibleLength)(segment);
77665
+ }
77666
+ result += segment;
77667
+ lastIndex = TOKEN_REGEX.lastIndex;
77668
+ }
77669
+ result += template.slice(lastIndex);
77358
77670
  result = result.replace(new RegExp(`\\s*[|\\n]\\s*${EMPTY_MARKER}\\s*[|\\n]\\s*`, "g"), " | ");
77359
77671
  result = result.replace(new RegExp(`^${EMPTY_MARKER}\\s*[|\\n]\\s*`), "");
77360
77672
  result = result.replace(new RegExp(`\\s*[|\\n]\\s*${EMPTY_MARKER}$`), "");
@@ -77431,41 +77743,14 @@ var require_formatter = __commonJS({
77431
77743
  }
77432
77744
  return `${seconds}s`;
77433
77745
  }
77434
- function shortenPath(fullPath, homeDir) {
77435
- const MAX_LENGTH = 20;
77436
- let path = fullPath;
77437
- if (homeDir && path.startsWith(homeDir)) {
77438
- path = "~" + path.slice(homeDir.length);
77746
+ function formatCwd(fullPath, homeDir) {
77747
+ if (homeDir && fullPath.startsWith(homeDir)) {
77748
+ return "~" + fullPath.slice(homeDir.length);
77439
77749
  }
77440
- if (path.length <= MAX_LENGTH) {
77441
- return path;
77442
- }
77443
- const parts = path.split("/");
77444
- if (parts.length >= 2) {
77445
- let shortened = "\u2026/" + parts.slice(-2).join("/");
77446
- if (shortened.length > MAX_LENGTH) {
77447
- shortened = "\u2026/" + parts.slice(-1)[0];
77448
- }
77449
- if (shortened.length > MAX_LENGTH) {
77450
- return shortened.slice(0, MAX_LENGTH);
77451
- }
77452
- return shortened;
77453
- }
77454
- return "\u2026" + path.slice(-(MAX_LENGTH - 1));
77750
+ return fullPath;
77455
77751
  }
77456
- function formatCwd(fullPath, homeDir, symbolMode = "full") {
77457
- const icon = symbolMode === "full" ? "\u{1F4C1} " : "";
77458
- return `${icon}${shortenPath(fullPath, homeDir)}`;
77459
- }
77460
- function formatBranch(branch, symbolMode) {
77461
- if (!branch)
77462
- return "";
77463
- const icons = {
77464
- full: "\u2387",
77465
- safe: "\u2217",
77466
- ascii: "*"
77467
- };
77468
- return `${icons[symbolMode]} ${branch}`;
77752
+ function formatBranch(branch) {
77753
+ return branch;
77469
77754
  }
77470
77755
  function formatLogs(warningCount, errorCount, symbolMode = "full") {
77471
77756
  const symbols = {
@@ -77655,11 +77940,49 @@ var require_context_overhead_reader = __commonJS({
77655
77940
  var require_statusline_service = __commonJS({
77656
77941
  "../feature-statusline/dist/statusline-service.js"(exports2) {
77657
77942
  "use strict";
77943
+ var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
77944
+ if (k2 === void 0) k2 = k;
77945
+ var desc = Object.getOwnPropertyDescriptor(m, k);
77946
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
77947
+ desc = { enumerable: true, get: function() {
77948
+ return m[k];
77949
+ } };
77950
+ }
77951
+ Object.defineProperty(o, k2, desc);
77952
+ }) : (function(o, m, k, k2) {
77953
+ if (k2 === void 0) k2 = k;
77954
+ o[k2] = m[k];
77955
+ }));
77956
+ var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) {
77957
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
77958
+ }) : function(o, v) {
77959
+ o["default"] = v;
77960
+ });
77961
+ var __importStar = exports2 && exports2.__importStar || /* @__PURE__ */ (function() {
77962
+ var ownKeys = function(o) {
77963
+ ownKeys = Object.getOwnPropertyNames || function(o2) {
77964
+ var ar = [];
77965
+ for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
77966
+ return ar;
77967
+ };
77968
+ return ownKeys(o);
77969
+ };
77970
+ return function(mod) {
77971
+ if (mod && mod.__esModule) return mod;
77972
+ var result = {};
77973
+ if (mod != null) {
77974
+ for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
77975
+ }
77976
+ __setModuleDefault(result, mod);
77977
+ return result;
77978
+ };
77979
+ })();
77658
77980
  Object.defineProperty(exports2, "__esModule", { value: true });
77659
77981
  exports2.StatuslineService = void 0;
77660
77982
  exports2.createStatuslineService = createStatuslineService;
77661
77983
  exports2.deterministicIndex = deterministicIndex;
77662
77984
  var core_1 = require_dist4();
77985
+ var path = __importStar(require("node:path"));
77663
77986
  var formatter_js_1 = require_formatter();
77664
77987
  var git_provider_js_1 = require_git_provider();
77665
77988
  var state_reader_js_1 = require_state_reader();
@@ -77681,6 +78004,10 @@ var require_statusline_service = __commonJS({
77681
78004
  branchColor: "",
77682
78005
  displayMode: "setup_warning",
77683
78006
  title: "",
78007
+ projectDirShort: "",
78008
+ projectDirFull: "",
78009
+ worktreeName: "",
78010
+ worktreeOrBranch: "",
77684
78011
  warningCount: 0,
77685
78012
  errorCount: 0,
77686
78013
  logStatus: "normal",
@@ -78079,6 +78406,10 @@ var require_statusline_service = __commonJS({
78079
78406
  const effectivePercentage = Math.round(totalWithBuffer / contextWindowSize * 100);
78080
78407
  const logStatus = logMetrics.errorCount >= this.config.thresholds.logs.critical ? "critical" : logMetrics.warningCount >= this.config.thresholds.logs.warning ? "warning" : "normal";
78081
78408
  const personaName = persona && persona.id !== "disabled" ? persona.display_name : "";
78409
+ const worktree = this.hookInput?.worktree;
78410
+ const projectRoot = worktree?.original_cwd || this.hookInput?.workspace?.project_dir || this.cwd;
78411
+ const projectDirShort = path.basename(projectRoot);
78412
+ const homeShorten = (p) => this.homeDir && p.startsWith(this.homeDir) ? "~" + p.slice(this.homeDir.length) : p;
78082
78413
  return {
78083
78414
  model: this.formatModelName(modelName),
78084
78415
  contextWindow: (0, formatter_js_1.formatTokens)(contextWindowSize),
@@ -78090,9 +78421,13 @@ var require_statusline_service = __commonJS({
78090
78421
  cost: (0, formatter_js_1.formatCost)(costUsd),
78091
78422
  costStatus: (0, formatter_js_1.getThresholdStatus)(costUsd, this.config.thresholds.cost),
78092
78423
  duration: (0, formatter_js_1.formatDuration)(durationMs),
78093
- cwd: (0, formatter_js_1.formatCwd)(this.cwd, this.homeDir, (0, types_js_1.normalizeSymbolMode)(this.config.theme.useNerdFonts)),
78094
- branch: (0, formatter_js_1.formatBranch)(branch, (0, types_js_1.normalizeSymbolMode)(this.config.theme.useNerdFonts)),
78424
+ cwd: (0, formatter_js_1.formatCwd)(this.cwd, this.homeDir),
78425
+ branch: (0, formatter_js_1.formatBranch)(branch),
78095
78426
  branchColor: (0, formatter_js_1.getBranchColor)(branch),
78427
+ projectDirShort,
78428
+ projectDirFull: homeShorten(projectRoot),
78429
+ worktreeName: worktree?.name ?? "",
78430
+ worktreeOrBranch: worktree?.name ?? branch,
78096
78431
  displayMode,
78097
78432
  summary: summaryText,
78098
78433
  title,
@@ -78215,8 +78550,25 @@ var require_dist7 = __commonJS({
78215
78550
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p);
78216
78551
  };
78217
78552
  Object.defineProperty(exports2, "__esModule", { value: true });
78218
- exports2.getDefaultOverhead = exports2.readContextOverhead = exports2.createStatuslineService = exports2.StatuslineService = exports2.getThresholdStatus = exports2.formatBranch = exports2.shortenPath = exports2.formatDuration = exports2.formatCost = exports2.formatTokens = exports2.createFormatter = exports2.Formatter = exports2.createGitProvider = exports2.GitProvider = exports2.createStateReader = exports2.StateReader = void 0;
78553
+ 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.truncatePath = exports2.truncatePrefix = exports2.truncateSuffix = exports2.visibleLength = exports2.stripAnsi = void 0;
78219
78554
  __exportStar(require_types3(), exports2);
78555
+ var ansi_utils_js_1 = require_ansi_utils();
78556
+ Object.defineProperty(exports2, "stripAnsi", { enumerable: true, get: function() {
78557
+ return ansi_utils_js_1.stripAnsi;
78558
+ } });
78559
+ Object.defineProperty(exports2, "visibleLength", { enumerable: true, get: function() {
78560
+ return ansi_utils_js_1.visibleLength;
78561
+ } });
78562
+ var truncation_js_1 = require_truncation();
78563
+ Object.defineProperty(exports2, "truncateSuffix", { enumerable: true, get: function() {
78564
+ return truncation_js_1.truncateSuffix;
78565
+ } });
78566
+ Object.defineProperty(exports2, "truncatePrefix", { enumerable: true, get: function() {
78567
+ return truncation_js_1.truncatePrefix;
78568
+ } });
78569
+ Object.defineProperty(exports2, "truncatePath", { enumerable: true, get: function() {
78570
+ return truncation_js_1.truncatePath;
78571
+ } });
78220
78572
  var state_reader_js_1 = require_state_reader();
78221
78573
  Object.defineProperty(exports2, "StateReader", { enumerable: true, get: function() {
78222
78574
  return state_reader_js_1.StateReader;
@@ -78247,9 +78599,6 @@ var require_dist7 = __commonJS({
78247
78599
  Object.defineProperty(exports2, "formatDuration", { enumerable: true, get: function() {
78248
78600
  return formatter_js_1.formatDuration;
78249
78601
  } });
78250
- Object.defineProperty(exports2, "shortenPath", { enumerable: true, get: function() {
78251
- return formatter_js_1.shortenPath;
78252
- } });
78253
78602
  Object.defineProperty(exports2, "formatBranch", { enumerable: true, get: function() {
78254
78603
  return formatter_js_1.formatBranch;
78255
78604
  } });
@@ -78389,7 +78738,18 @@ Examples:
78389
78738
  cache_creation_input_tokens: num(currentUsage.cache_creation_input_tokens, 0),
78390
78739
  cache_read_input_tokens: num(currentUsage.cache_read_input_tokens, 0)
78391
78740
  } : null
78392
- }
78741
+ },
78742
+ // Parse optional worktree data (only present in worktree sessions)
78743
+ worktree: raw.worktree ? (() => {
78744
+ const wt = raw.worktree;
78745
+ return {
78746
+ name: typeof wt.name === "string" ? wt.name : "",
78747
+ path: typeof wt.path === "string" ? wt.path : "",
78748
+ branch: typeof wt.branch === "string" ? wt.branch : "",
78749
+ original_cwd: typeof wt.original_cwd === "string" ? wt.original_cwd : void 0,
78750
+ original_branch: typeof wt.original_branch === "string" ? wt.original_branch : void 0
78751
+ };
78752
+ })() : void 0
78393
78753
  };
78394
78754
  }
78395
78755
  async function handleStatuslineCommand(projectDir, logger, stdout, options = {}) {
@@ -82681,7 +83041,7 @@ var require_cli = __commonJS({
82681
83041
  var promises_12 = require("node:fs/promises");
82682
83042
  var node_stream_1 = require("node:stream");
82683
83043
  var yargs_parser_1 = __importDefault2(require_build());
82684
- var VERSION = true ? "0.1.5" : "dev";
83044
+ var VERSION = true ? "0.1.7" : "dev";
82685
83045
  var SANDBOX_ERROR_MESSAGE = `Error: Daemon commands cannot run in sandbox mode.
82686
83046
 
82687
83047
  Claude Code's sandbox blocks Unix socket operations required for daemon IPC.