@scotthamilton77/sidekick 0.1.28 → 0.1.30

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.
@@ -2,7 +2,9 @@
2
2
  # This file defines default values for the session summary feature.
3
3
  # Override in ~/.sidekick/features.yaml or .sidekick/features.yaml under features.session-summary
4
4
 
5
- # Enable or disable the session summary feature
5
+ # Master switch for the session-summary feature. When false, NO session-summary
6
+ # LLM generation occurs (analysis/title/intent, snarky comment, resume message).
7
+ # Persona selection/injection is independent and unaffected.
6
8
  enabled: true
7
9
 
8
10
  settings:
@@ -54,6 +56,9 @@ settings:
54
56
 
55
57
  # Enable snarky/humorous comments in summaries
56
58
  snarkyMessages: true
59
+ # Generate resume ("welcome back") messages. Default false — historically more
60
+ # tokens than benefit. Set true to re-enable. Requires `enabled: true`.
61
+ resumeMessages: false
57
62
 
58
63
  # Countdown configuration for summary refresh timing
59
64
  # Counts ToolResult events (each tool use decrements by 1)
@@ -119,3 +124,8 @@ settings:
119
124
  # When non-off, the persona-voice reminder is replaced by a compact caveman
120
125
  # directive and the statusline shows the level.
121
126
  cavemanMode: "off"
127
+ # Inject persona/caveman into non-interactive (claude -p) sessions. Default
128
+ # false — no human reads a programmatic session, so the voice is wasted tokens.
129
+ # Set true to opt back in.
130
+ injectPersonaIntoNonInteractiveSessions: false
131
+ injectCavemanIntoNonInteractiveSessions: false
package/dist/bin.js CHANGED
@@ -47579,7 +47579,7 @@ var require_build_identity = __commonJS({
47579
47579
  var path_1 = __importDefault2(require("path"));
47580
47580
  var DEV_PREFIX = "dev:";
47581
47581
  var NO_DIST_SENTINEL = "nodist";
47582
- function computeBuildIdentity(injectedVersion = true ? "0.1.28" : void 0, devFingerprint = computeDevFingerprint) {
47582
+ function computeBuildIdentity(injectedVersion = true ? "0.1.30" : void 0, devFingerprint = computeDevFingerprint) {
47583
47583
  return injectedVersion !== void 0 ? injectedVersion : DEV_PREFIX + devFingerprint();
47584
47584
  }
47585
47585
  function computeDevFingerprint() {
@@ -76817,6 +76817,7 @@ var require_types3 = __commonJS({
76817
76817
  maxSnarkyWords: 20,
76818
76818
  maxResumeWords: 20,
76819
76819
  snarkyMessages: true,
76820
+ resumeMessages: false,
76820
76821
  countdown: {
76821
76822
  lowConfidence: 5,
76822
76823
  mediumConfidence: 10,
@@ -76836,7 +76837,9 @@ var require_types3 = __commonJS({
76836
76837
  llmProfiles: {},
76837
76838
  weights: {},
76838
76839
  persistThroughClear: true,
76839
- cavemanMode: "off"
76840
+ cavemanMode: "off",
76841
+ injectPersonaIntoNonInteractiveSessions: false,
76842
+ injectCavemanIntoNonInteractiveSessions: false
76840
76843
  }
76841
76844
  };
76842
76845
  exports2.RESUME_MIN_CONFIDENCE = 0.7;
@@ -77498,6 +77501,7 @@ var require_update_summary = __commonJS({
77498
77501
  exports2.resetCountdown = resetCountdown;
77499
77502
  exports2.orchestrateSideEffects = orchestrateSideEffects;
77500
77503
  exports2.emitAnalysisEvents = emitAnalysisEvents;
77504
+ exports2.performAnalysis = performAnalysis;
77501
77505
  var core_1 = require_dist4();
77502
77506
  var events_js_1 = require_events3();
77503
77507
  var types_1 = require_dist();
@@ -77736,7 +77740,7 @@ var require_update_summary = __commonJS({
77736
77740
  sideEffects.push(generateSnarkyMessage(ctx, summaryState, sessionId, updatedSummary, config));
77737
77741
  }
77738
77742
  const hasResume = await resumeMessageExists(summaryState, sessionId);
77739
- if (updatedSummary.pivot_detected || !hasResume) {
77743
+ if (config.resumeMessages && (updatedSummary.pivot_detected || !hasResume)) {
77740
77744
  sideEffects.push(generateResumeMessage(ctx, summaryState, eventContext, updatedSummary, config));
77741
77745
  }
77742
77746
  if (sideEffects.length > 0) {
@@ -77770,6 +77774,14 @@ var require_update_summary = __commonJS({
77770
77774
  async function performAnalysis(event, ctx, summaryState, reason) {
77771
77775
  const { context: eventContext, payload } = event;
77772
77776
  const { sessionId } = eventContext;
77777
+ if (!ctx.config.getFeature("session-summary").enabled) {
77778
+ ctx.logger.debug("Session summary disabled; skipping analysis", { sessionId, reason });
77779
+ return;
77780
+ }
77781
+ if (ctx.sessionType === "non-interactive") {
77782
+ ctx.logger.debug("Non-interactive session; skipping summary analysis", { sessionId, reason });
77783
+ return;
77784
+ }
77773
77785
  try {
77774
77786
  const countdown = await loadCountdownState(summaryState, sessionId);
77775
77787
  const startTime = Date.now();
@@ -78142,6 +78154,28 @@ var require_dist5 = __commonJS({
78142
78154
  }
78143
78155
  });
78144
78156
 
78157
+ // ../feature-reminders/dist/handlers/consumption/session-type-gate.js
78158
+ var require_session_type_gate = __commonJS({
78159
+ "../feature-reminders/dist/handlers/consumption/session-type-gate.js"(exports2) {
78160
+ "use strict";
78161
+ Object.defineProperty(exports2, "__esModule", { value: true });
78162
+ exports2.suppressReminderForSessionType = suppressReminderForSessionType;
78163
+ var types_js_1 = require_types2();
78164
+ var PERSONA_REMINDERS = /* @__PURE__ */ new Set([types_js_1.ReminderIds.REMEMBER_YOUR_PERSONA, types_js_1.ReminderIds.PERSONA_CHANGED]);
78165
+ function suppressReminderForSessionType(reminderName, sessionType, config) {
78166
+ if (sessionType !== "non-interactive")
78167
+ return false;
78168
+ if (PERSONA_REMINDERS.has(reminderName)) {
78169
+ return config.injectPersonaIntoNonInteractiveSessions !== true;
78170
+ }
78171
+ if (reminderName === types_js_1.ReminderIds.CAVEMAN_MODE) {
78172
+ return config.injectCavemanIntoNonInteractiveSessions !== true;
78173
+ }
78174
+ return false;
78175
+ }
78176
+ }
78177
+ });
78178
+
78145
78179
  // ../feature-reminders/dist/handlers/staging/stage-persona-reminders.js
78146
78180
  var require_stage_persona_reminders = __commonJS({
78147
78181
  "../feature-reminders/dist/handlers/staging/stage-persona-reminders.js"(exports2) {
@@ -78157,6 +78191,7 @@ var require_stage_persona_reminders = __commonJS({
78157
78191
  var types_1 = require_dist();
78158
78192
  var reminder_utils_js_1 = require_reminder_utils();
78159
78193
  var types_js_1 = require_types2();
78194
+ var session_type_gate_js_1 = require_session_type_gate();
78160
78195
  var throttle_utils_js_1 = require_throttle_utils();
78161
78196
  async function restagePersonaRemindersForActiveSessions(ctxFactory, sessionIds, logger) {
78162
78197
  logger.info("Re-staging persona reminders for active sessions", { count: sessionIds.length });
@@ -78372,6 +78407,10 @@ var require_stage_persona_reminders = __commonJS({
78372
78407
  async function resolvePersonaContextForSnapshot(ctx, sessionId) {
78373
78408
  if (!isPersonaInjectionEnabled(ctx))
78374
78409
  return void 0;
78410
+ const personaConfig = ctx.config.getFeature("session-summary").settings?.personas ?? {};
78411
+ if ((0, session_type_gate_js_1.suppressReminderForSessionType)(types_js_1.ReminderIds.REMEMBER_YOUR_PERSONA, ctx.sessionType, personaConfig)) {
78412
+ return void 0;
78413
+ }
78375
78414
  const persona = await loadPersonaForSession(ctx, sessionId);
78376
78415
  if (!persona)
78377
78416
  return void 0;
@@ -78768,6 +78807,7 @@ var require_consumption_handler_factory = __commonJS({
78768
78807
  var events_js_1 = require_events2();
78769
78808
  var types_1 = require_dist();
78770
78809
  var cli_staging_reader_js_1 = require_cli_staging_reader();
78810
+ var session_type_gate_js_1 = require_session_type_gate();
78771
78811
  function buildDefaultResponse(reminder, supportsBlocking) {
78772
78812
  const response = {};
78773
78813
  if (supportsBlocking && reminder.blocking) {
@@ -78801,7 +78841,8 @@ var require_consumption_handler_factory = __commonJS({
78801
78841
  paths: cliCtx.paths,
78802
78842
  sessionId
78803
78843
  });
78804
- const reminders = reader.listReminders(hook);
78844
+ const personaConfig = cliCtx.config.getFeature("session-summary").settings?.personas ?? {};
78845
+ const reminders = reader.listReminders(hook).filter((r) => !(0, session_type_gate_js_1.suppressReminderForSessionType)(r.name, event.context.sessionType, personaConfig));
78805
78846
  if (reminders.length === 0) {
78806
78847
  return { response: {} };
78807
78848
  }
@@ -79873,7 +79914,8 @@ var require_hook = __commonJS({
79873
79914
  timestamp: Date.now(),
79874
79915
  correlationId,
79875
79916
  ...input.agentId !== void 0 && { agentId: input.agentId },
79876
- ...input.agentType !== void 0 && { agentType: input.agentType }
79917
+ ...input.agentType !== void 0 && { agentType: input.agentType },
79918
+ sessionType: input.sessionType
79877
79919
  };
79878
79920
  switch (hookName) {
79879
79921
  case "SessionStart":
@@ -85174,8 +85216,11 @@ var require_helpers = __commonJS({
85174
85216
  })();
85175
85217
  Object.defineProperty(exports2, "__esModule", { value: true });
85176
85218
  exports2.STATUSLINE_COMMAND = void 0;
85219
+ exports2.classifyStatusLine = classifyStatusLine;
85177
85220
  exports2.statuslineSettingsPath = statuslineSettingsPath;
85178
85221
  exports2.configureStatusline = configureStatusline;
85222
+ exports2.removeStatusline = removeStatusline;
85223
+ exports2.detectStatuslineScopes = detectStatuslineScopes;
85179
85224
  exports2.writeApiKeyToEnv = writeApiKeyToEnv;
85180
85225
  exports2.writePersonaConfig = writePersonaConfig;
85181
85226
  exports2.getPluginStatusLabel = getPluginStatusLabel;
@@ -85190,6 +85235,16 @@ var require_helpers = __commonJS({
85190
85235
  var path = __importStar(require("node:path"));
85191
85236
  var settings_js_1 = require_settings();
85192
85237
  exports2.STATUSLINE_COMMAND = "npx @scotthamilton77/sidekick statusline --project-dir=$CLAUDE_PROJECT_DIR";
85238
+ function classifyStatusLine(existing) {
85239
+ const command = existing?.command;
85240
+ if (!command)
85241
+ return "none";
85242
+ if (command.includes("dev-sidekick"))
85243
+ return "dev-mode";
85244
+ if (command.includes("@scotthamilton77/sidekick") || command.includes("sidekick statusline"))
85245
+ return "sidekick";
85246
+ return "foreign";
85247
+ }
85193
85248
  function statuslineSettingsPath(scope, homeDir, projectDir) {
85194
85249
  switch (scope) {
85195
85250
  case "user":
@@ -85202,10 +85257,14 @@ var require_helpers = __commonJS({
85202
85257
  }
85203
85258
  async function configureStatusline(settingsPath, logger) {
85204
85259
  const settings = await (0, settings_js_1.readSettingsFile)(settingsPath);
85205
- const existing = settings.statusLine;
85206
- if (existing?.command?.includes("dev-sidekick")) {
85260
+ const kind = classifyStatusLine(settings.statusLine);
85261
+ if (kind === "dev-mode") {
85207
85262
  logger?.warn("Statusline managed by dev-mode, skipping overwrite", { path: settingsPath });
85208
- return false;
85263
+ return "dev-mode";
85264
+ }
85265
+ if (kind === "foreign") {
85266
+ logger?.warn("Foreign statusline present, not overwriting", { path: settingsPath });
85267
+ return "foreign";
85209
85268
  }
85210
85269
  settings.statusLine = {
85211
85270
  type: "command",
@@ -85213,7 +85272,29 @@ var require_helpers = __commonJS({
85213
85272
  };
85214
85273
  await (0, settings_js_1.writeSettingsFile)(settingsPath, settings);
85215
85274
  logger?.info("Statusline configured", { path: settingsPath });
85216
- return true;
85275
+ return "written";
85276
+ }
85277
+ async function removeStatusline(settingsPath, logger) {
85278
+ const settings = await (0, settings_js_1.readSettingsFile)(settingsPath);
85279
+ const kind = classifyStatusLine(settings.statusLine);
85280
+ if (kind === "none")
85281
+ return "absent";
85282
+ if (kind === "dev-mode")
85283
+ return "dev-mode";
85284
+ if (kind === "foreign")
85285
+ return "foreign";
85286
+ delete settings.statusLine;
85287
+ await (0, settings_js_1.writeSettingsFile)(settingsPath, settings);
85288
+ logger?.info("Sidekick statusline removed", { path: settingsPath });
85289
+ return "removed";
85290
+ }
85291
+ async function detectStatuslineScopes(homeDir, projectDir) {
85292
+ const scopes = ["user", "project", "local"];
85293
+ const results = await Promise.all(scopes.map(async (scope) => {
85294
+ const settings = await (0, settings_js_1.readSettingsFile)(statuslineSettingsPath(scope, homeDir, projectDir));
85295
+ return classifyStatusLine(settings.statusLine) === "sidekick";
85296
+ }));
85297
+ return scopes.filter((_, i) => results[i]);
85217
85298
  }
85218
85299
  async function writeApiKeyToEnv(envPath, key, value) {
85219
85300
  const dir = path.dirname(envPath);
@@ -85407,7 +85488,8 @@ var require_doctor = __commonJS({
85407
85488
  "shell-alias",
85408
85489
  "llm-config",
85409
85490
  "legacy-state",
85410
- "build-identity"
85491
+ "build-identity",
85492
+ "session-summary"
85411
85493
  ];
85412
85494
  var DEPRECATED_LLM_MODELS = [
85413
85495
  {
@@ -85525,11 +85607,13 @@ var require_doctor = __commonJS({
85525
85607
  stdout.write("Fixing: Statusline\n");
85526
85608
  const settingsPath = (0, helpers_js_1.statuslineSettingsPath)("user", homeDir, projectDir);
85527
85609
  const wrote = await (0, helpers_js_1.configureStatusline)(settingsPath, logger);
85528
- if (wrote) {
85610
+ if (wrote === "written") {
85529
85611
  stdout.write(" \u2713 Statusline configured at user scope\n");
85530
85612
  fixedCount++;
85531
- } else {
85613
+ } else if (wrote === "dev-mode") {
85532
85614
  stdout.write(" \u26A0 Statusline managed by dev-mode (skipped)\n");
85615
+ } else {
85616
+ stdout.write(" \u26A0 Foreign statusline present, not overwritten (skipped)\n");
85533
85617
  }
85534
85618
  }
85535
85619
  if (shouldFix("gitignore") && gitignore !== null) {
@@ -85793,6 +85877,30 @@ var require_doctor = __commonJS({
85793
85877
  if (shouldRun("llm-config")) {
85794
85878
  runLlmConfigCheck(projectDir, homeDir, stdout, logger);
85795
85879
  }
85880
+ if (shouldRun("session-summary")) {
85881
+ let ss = {};
85882
+ try {
85883
+ const ssResult = (0, core_1.configGet)("features.session-summary", { projectRoot: projectDir, homeDir });
85884
+ ss = ssResult?.value ?? {};
85885
+ } catch {
85886
+ }
85887
+ const enabled = ss.enabled ?? true;
85888
+ const s = ss.settings ?? {};
85889
+ if (!enabled) {
85890
+ stdout.write("\u26A0 Session insights: disabled (reminders-only)\n");
85891
+ } else {
85892
+ const mark = (b, dflt) => b ?? dflt ? "\u2713" : "\u2717";
85893
+ stdout.write(`\u2713 Session insights: analysis \u2713 snarky ${mark(s.snarkyMessages, true)} resume ${mark(s.resumeMessages, false)}
85894
+ `);
85895
+ }
85896
+ }
85897
+ if (shouldRun("statusline")) {
85898
+ const slScopes = await (0, helpers_js_1.detectStatuslineScopes)(homeDir, projectDir);
85899
+ if (slScopes.length > 1) {
85900
+ stdout.write(`\u2022 Sidekick statusline present at multiple scopes (${slScopes.join(", ")}); project/local override user.
85901
+ `);
85902
+ }
85903
+ }
85796
85904
  if (shouldRun("auto-config")) {
85797
85905
  const userStatus = await setupService.getUserStatus();
85798
85906
  if (userStatus?.preferences.autoConfigureProjects) {
@@ -85909,7 +86017,7 @@ var require_scripted = __commonJS({
85909
86017
  var user_profile_setup_js_1 = require_user_profile_setup();
85910
86018
  var helpers_js_1 = require_helpers();
85911
86019
  function hasScriptingFlags(options) {
85912
- return options.marketplaceScope !== void 0 || options.pluginScope !== void 0 || options.statuslineScope !== void 0 || options.gitignore !== void 0 || options.personas !== void 0 || options.apiKeyScope !== void 0 || options.autoConfig !== void 0 || options.alias !== void 0 || options.userProfileName !== void 0 || options.userProfileRole !== void 0 || options.userProfileInterests !== void 0;
86020
+ return options.marketplaceScope !== void 0 || options.pluginScope !== void 0 || options.statuslineScope !== void 0 || options.statusline !== void 0 || options.sessionSummary !== void 0 || options.gitignore !== void 0 || options.personas !== void 0 || options.apiKeyScope !== void 0 || options.autoConfig !== void 0 || options.alias !== void 0 || options.userProfileName !== void 0 || options.userProfileRole !== void 0 || options.userProfileInterests !== void 0;
85913
86021
  }
85914
86022
  async function runScripted(projectDir, logger, stdout, options, isDevMode) {
85915
86023
  const homeDir = options.homeDir ?? os.homedir();
@@ -85951,17 +86059,45 @@ var require_scripted = __commonJS({
85951
86059
  configuredCount++;
85952
86060
  }
85953
86061
  }
85954
- if (options.statuslineScope) {
85955
- const settingsPath = (0, helpers_js_1.statuslineSettingsPath)(options.statuslineScope, homeDir, projectDir);
85956
- const wrote = await (0, helpers_js_1.configureStatusline)(settingsPath, logger);
85957
- if (wrote) {
85958
- stdout.write(`\u2713 Statusline configured (${options.statuslineScope}-level)
86062
+ if (options.statusline === true || options.statusline === void 0 && options.statuslineScope) {
86063
+ const scope = options.statuslineScope ?? "user";
86064
+ const settingsPath = (0, helpers_js_1.statuslineSettingsPath)(scope, homeDir, projectDir);
86065
+ const result = await (0, helpers_js_1.configureStatusline)(settingsPath, logger);
86066
+ if (result === "written") {
86067
+ stdout.write(`\u2713 Statusline configured (${scope}: ${settingsPath})
85959
86068
  `);
85960
86069
  configuredCount++;
86070
+ } else if (result === "dev-mode") {
86071
+ stdout.write(`\u26A0 Statusline managed by dev-mode (skipped) at ${settingsPath}
86072
+ `);
85961
86073
  } else {
85962
- stdout.write(`\u26A0 Statusline managed by dev-mode (skipped)
86074
+ stdout.write(`\u26A0 A non-Sidekick statusline already exists at ${settingsPath}; left unchanged. To use Sidekick's statusline, manually edit or remove the existing one, then re-run setup.
86075
+ `);
86076
+ }
86077
+ } else if (options.statusline === false) {
86078
+ const scope = options.statuslineScope ?? "user";
86079
+ const settingsPath = (0, helpers_js_1.statuslineSettingsPath)(scope, homeDir, projectDir);
86080
+ const result = await (0, helpers_js_1.removeStatusline)(settingsPath, logger);
86081
+ stdout.write(`${result === "removed" ? "\u2713" : "-"} Sidekick statusline ${result} (${scope}: ${settingsPath})
86082
+ `);
86083
+ (0, core_1.configSet)("features.statusline.enabled", "false", { scope, projectRoot: projectDir, homeDir });
86084
+ if (options.sessionSummary === void 0) {
86085
+ (0, core_1.configSet)("features.session-summary.enabled", "false", { scope, projectRoot: projectDir, homeDir });
86086
+ stdout.write(`\u2713 Session insights disabled (they only render in the statusline) \u2014 features.yaml (${scope})
85963
86087
  `);
85964
86088
  }
86089
+ configuredCount++;
86090
+ }
86091
+ if (options.sessionSummary !== void 0) {
86092
+ const scope = options.statuslineScope ?? "user";
86093
+ (0, core_1.configSet)("features.session-summary.enabled", String(options.sessionSummary), {
86094
+ scope,
86095
+ projectRoot: projectDir,
86096
+ homeDir
86097
+ });
86098
+ stdout.write(`\u2713 Session insights ${options.sessionSummary ? "enabled" : "disabled"} \u2014 features.yaml (${scope})
86099
+ `);
86100
+ configuredCount++;
85965
86101
  }
85966
86102
  if (options.gitignore === true) {
85967
86103
  const result = await (0, core_1.installGitignoreSection)(projectDir);
@@ -86296,13 +86432,31 @@ Examples:
86296
86432
  (0, prompts_js_1.printHeader)(ctx, "Step 2: Statusline Configuration", "Claude Code plugins cannot provide statusline config directly.");
86297
86433
  if (isDevMode) {
86298
86434
  const settingsPath2 = (0, helpers_js_1.statuslineSettingsPath)("user", homeDir, projectDir);
86299
- const wrote2 = await (0, helpers_js_1.configureStatusline)(settingsPath2, logger);
86300
- if (wrote2) {
86435
+ const result = await (0, helpers_js_1.configureStatusline)(settingsPath2, logger);
86436
+ if (result === "written") {
86301
86437
  (0, prompts_js_1.printStatus)(ctx, "success", "Statusline configured at user scope (dev-mode active)");
86302
86438
  } else {
86303
86439
  (0, prompts_js_1.printStatus)(ctx, "warning", "Statusline managed by dev-mode (skipped)");
86304
86440
  }
86305
- return "user";
86441
+ return { enabled: true, scope: "user" };
86442
+ }
86443
+ const wantStatusline = await (0, prompts_js_1.promptConfirm)(ctx, "Enable Sidekick statusline?", true);
86444
+ if (!wantStatusline) {
86445
+ (0, prompts_js_1.printStatus)(ctx, "info", "Insights only render in the statusline, so they will be disabled too.");
86446
+ const detected = await (0, helpers_js_1.detectStatuslineScopes)(homeDir, projectDir);
86447
+ for (const scope of detected) {
86448
+ const settingsPath2 = (0, helpers_js_1.statuslineSettingsPath)(scope, homeDir, projectDir);
86449
+ const result = await (0, helpers_js_1.removeStatusline)(settingsPath2, logger);
86450
+ (0, prompts_js_1.printStatus)(ctx, result === "removed" ? "success" : "info", `Statusline ${result} (${scope}: ${settingsPath2})`);
86451
+ }
86452
+ const scopesToDisable = [.../* @__PURE__ */ new Set([...detected, "user"])];
86453
+ for (const scope of scopesToDisable) {
86454
+ (0, core_1.configSet)("features.statusline.enabled", "false", { scope, projectRoot: projectDir, homeDir });
86455
+ (0, core_1.configSet)("features.session-summary.enabled", "false", { scope, projectRoot: projectDir, homeDir });
86456
+ }
86457
+ (0, prompts_js_1.printStatus)(ctx, "success", `Session insights disabled at: ${scopesToDisable.join(", ")}.`);
86458
+ (0, prompts_js_1.printStatus)(ctx, "info", "If you have overrides at another scope, also run: sidekick config set features.session-summary.enabled false --scope=<scope>");
86459
+ return { enabled: false, scope: "user" };
86306
86460
  }
86307
86461
  const STATUSLINE_SCOPE_OPTIONS = {
86308
86462
  user: { label: "User-level (~/.claude/settings.json)", description: "Works in all projects" },
@@ -86322,13 +86476,34 @@ Examples:
86322
86476
  statuslineScope = await (0, prompts_js_1.promptSelect)(ctx, "Where should sidekick configure your statusline?", options);
86323
86477
  }
86324
86478
  const settingsPath = (0, helpers_js_1.statuslineSettingsPath)(statuslineScope, homeDir, projectDir);
86325
- const wrote = await (0, helpers_js_1.configureStatusline)(settingsPath, logger);
86326
- if (wrote) {
86479
+ const writeResult = await (0, helpers_js_1.configureStatusline)(settingsPath, logger);
86480
+ if (writeResult === "written") {
86327
86481
  (0, prompts_js_1.printStatus)(ctx, "success", `Statusline configured in ${settingsPath}`);
86328
- } else {
86482
+ } else if (writeResult === "dev-mode") {
86329
86483
  (0, prompts_js_1.printStatus)(ctx, "warning", "Statusline managed by dev-mode (skipped)");
86484
+ } else {
86485
+ (0, prompts_js_1.printStatus)(ctx, "warning", `A non-Sidekick statusline already exists at ${settingsPath} (left unchanged)`);
86330
86486
  }
86331
- return statuslineScope;
86487
+ (0, prompts_js_1.printHeader)(ctx, "Configure Session Insights");
86488
+ const wantAnalysis = await (0, prompts_js_1.promptConfirm)(ctx, "Enable session analysis (title/intent)?", true);
86489
+ (0, core_1.configSet)("features.session-summary.enabled", String(wantAnalysis), {
86490
+ scope: statuslineScope,
86491
+ projectRoot: projectDir,
86492
+ homeDir
86493
+ });
86494
+ const wantSnarky = await (0, prompts_js_1.promptConfirm)(ctx, "Enable snarky comments?", true);
86495
+ (0, core_1.configSet)("features.session-summary.settings.snarkyMessages", String(wantSnarky), {
86496
+ scope: statuslineScope,
86497
+ projectRoot: projectDir,
86498
+ homeDir
86499
+ });
86500
+ const wantResume = await (0, prompts_js_1.promptConfirm)(ctx, "Enable resume messages?", false);
86501
+ (0, core_1.configSet)("features.session-summary.settings.resumeMessages", String(wantResume), {
86502
+ scope: statuslineScope,
86503
+ projectRoot: projectDir,
86504
+ homeDir
86505
+ });
86506
+ return { enabled: true, scope: statuslineScope };
86332
86507
  }
86333
86508
  async function runStep3Gitignore(wctx, force) {
86334
86509
  const { ctx, projectDir } = wctx;
@@ -86493,7 +86668,8 @@ Examples:
86493
86668
  }
86494
86669
  async function writeStatusFiles(wctx, state) {
86495
86670
  const { setupService } = wctx;
86496
- const { statuslineScope, gitignoreStatus, apiKeyHealth, apiKeyDetection, autoConfig } = state;
86671
+ const { statuslineEnabled, statuslineScope, gitignoreStatus, apiKeyHealth, apiKeyDetection, autoConfig } = state;
86672
+ const statuslineStatus = statuslineEnabled ? statuslineScope : "none";
86497
86673
  const userStatus = {
86498
86674
  version: 1,
86499
86675
  lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -86502,7 +86678,7 @@ Examples:
86502
86678
  defaultStatuslineScope: statuslineScope,
86503
86679
  defaultApiKeyScope: "user"
86504
86680
  },
86505
- statusline: statuslineScope,
86681
+ statusline: statuslineStatus,
86506
86682
  apiKeys: {
86507
86683
  OPENROUTER_API_KEY: apiKeyDetection ? setupService.buildUserApiKeyStatus(apiKeyDetection) : core_1.SetupStatusService.userApiKeyStatusFromHealth(apiKeyHealth),
86508
86684
  OPENAI_API_KEY: core_1.SetupStatusService.userApiKeyStatusFromHealth("not-required")
@@ -86515,7 +86691,7 @@ Examples:
86515
86691
  version: 1,
86516
86692
  lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString(),
86517
86693
  autoConfigured: false,
86518
- statusline: statuslineScope,
86694
+ statusline: statuslineStatus,
86519
86695
  apiKeys: {
86520
86696
  OPENROUTER_API_KEY: projectOpenRouterStatus,
86521
86697
  OPENAI_API_KEY: core_1.SetupStatusService.projectApiKeyStatusFromHealth("not-required")
@@ -86527,11 +86703,15 @@ Examples:
86527
86703
  }
86528
86704
  function printSummary(wctx, state) {
86529
86705
  const { ctx } = wctx;
86530
- const { statuslineScope, gitignoreStatus, wantPersonas, apiKeyHealth, autoConfig } = state;
86706
+ const { statuslineEnabled, statuslineScope, gitignoreStatus, wantPersonas, apiKeyHealth, autoConfig } = state;
86531
86707
  const stdout = ctx.stdout;
86532
86708
  (0, prompts_js_1.printHeader)(ctx, "Summary");
86533
- const scopeLabel = { user: "User-level", project: "Project-level", local: "Local" }[statuslineScope];
86534
- (0, prompts_js_1.printStatus)(ctx, "success", `Statusline: ${scopeLabel}`);
86709
+ if (statuslineEnabled) {
86710
+ const scopeLabel = { user: "User-level", project: "Project-level", local: "Local" }[statuslineScope];
86711
+ (0, prompts_js_1.printStatus)(ctx, "success", `Statusline: ${scopeLabel}`);
86712
+ } else {
86713
+ (0, prompts_js_1.printStatus)(ctx, "info", "Statusline: Disabled (reminders-only mode)");
86714
+ }
86535
86715
  let gitignoreStatusType;
86536
86716
  let gitignoreLabel;
86537
86717
  switch (gitignoreStatus) {
@@ -86609,7 +86789,9 @@ Examples:
86609
86789
  }
86610
86790
  const forceStatuslineScope = pluginResult.pluginScope;
86611
86791
  const forceEffectiveScope = isDevMode ? "user" : forceStatuslineScope;
86612
- const statuslineScope = force ? forceEffectiveScope : await runStep2Statusline(wctx, pluginResult.pluginScope, isDevMode);
86792
+ const statuslineResult = force ? { enabled: true, scope: forceEffectiveScope } : await runStep2Statusline(wctx, pluginResult.pluginScope, isDevMode);
86793
+ const statuslineScope = statuslineResult.scope;
86794
+ const statuslineEnabled = statuslineResult.enabled;
86613
86795
  const gitignoreStatus = await runStep3Gitignore(wctx, force);
86614
86796
  const { apiKeyHealth, apiKeyDetection } = force ? { apiKeyHealth: "missing", apiKeyDetection: null } : await runStep4ApiKey(wctx);
86615
86797
  const wantPersonas = force ? true : await runStep5Personas(wctx);
@@ -86619,12 +86801,13 @@ Examples:
86619
86801
  const _userProfile = force ? { configured: false } : await (0, user_profile_setup_js_1.runUserProfileStep)(wctx.ctx, homeDir);
86620
86802
  if (force) {
86621
86803
  const settingsPath = (0, helpers_js_1.statuslineSettingsPath)(forceEffectiveScope, homeDir, projectDir);
86622
- const wrote = await (0, helpers_js_1.configureStatusline)(settingsPath, logger);
86623
- if (!wrote) {
86804
+ const result = await (0, helpers_js_1.configureStatusline)(settingsPath, logger);
86805
+ if (result !== "written") {
86624
86806
  stdout.write("\u26A0 Statusline managed by dev-mode (skipped)\n");
86625
86807
  }
86626
86808
  }
86627
86809
  const state = {
86810
+ statuslineEnabled,
86628
86811
  statuslineScope,
86629
86812
  gitignoreStatus,
86630
86813
  wantPersonas,
@@ -87375,6 +87558,8 @@ var require_cli = __commonJS({
87375
87558
  };
87376
87559
  Object.defineProperty(exports2, "__esModule", { value: true });
87377
87560
  exports2.UnknownOptionError = void 0;
87561
+ exports2.parseArgs = parseArgs;
87562
+ exports2.resolveSessionType = resolveSessionType;
87378
87563
  exports2.parseHookInput = parseHookInput;
87379
87564
  exports2.initializeRuntime = initializeRuntime;
87380
87565
  exports2.initializeSession = initializeSession;
@@ -87383,7 +87568,7 @@ var require_cli = __commonJS({
87383
87568
  var promises_12 = require("node:fs/promises");
87384
87569
  var node_stream_1 = require("node:stream");
87385
87570
  var yargs_parser_1 = __importDefault2(require_build());
87386
- var VERSION = true ? "0.1.28" : "dev";
87571
+ var VERSION = true ? "0.1.30" : "dev";
87387
87572
  var SANDBOX_ERROR_MESSAGE = `Error: Daemon commands cannot run in sandbox mode.
87388
87573
 
87389
87574
  Claude Code's sandbox blocks Unix socket operations required for daemon IPC.
@@ -87420,7 +87605,9 @@ Example: { "command": "pnpm sidekick daemon status", "dangerouslyDisableSandbox"
87420
87605
  "gitignore",
87421
87606
  "personas",
87422
87607
  "alias",
87423
- "write-status"
87608
+ "write-status",
87609
+ "statusline",
87610
+ "session-summary"
87424
87611
  ],
87425
87612
  string: [
87426
87613
  "project-dir",
@@ -87469,6 +87656,8 @@ Example: { "command": "pnpm sidekick daemon status", "dangerouslyDisableSandbox"
87469
87656
  const hasGitignoreFlag = argv.some((arg) => arg === "--gitignore" || arg === "--no-gitignore");
87470
87657
  const hasPersonasFlag = argv.some((arg) => arg === "--personas" || arg === "--no-personas");
87471
87658
  const hasAliasFlag = argv.some((arg) => arg === "--alias" || arg === "--no-alias");
87659
+ const hasStatuslineFlag = argv.some((arg) => arg === "--statusline" || arg === "--no-statusline");
87660
+ const hasSessionSummaryFlag = argv.some((arg) => arg === "--session-summary" || arg === "--no-session-summary");
87472
87661
  return {
87473
87662
  command,
87474
87663
  projectDir: parsed["project-dir"],
@@ -87501,13 +87690,22 @@ Example: { "command": "pnpm sidekick daemon status", "dangerouslyDisableSandbox"
87501
87690
  marketplaceScope: parsed["marketplace-scope"],
87502
87691
  pluginScope: parsed["plugin-scope"],
87503
87692
  alias: hasAliasFlag ? Boolean(parsed.alias) : void 0,
87693
+ statusline: hasStatuslineFlag ? Boolean(parsed.statusline) : void 0,
87694
+ sessionSummary: hasSessionSummaryFlag ? Boolean(parsed["session-summary"]) : void 0,
87504
87695
  userProfileName: parsed["user-profile-name"],
87505
87696
  userProfileRole: parsed["user-profile-role"],
87506
87697
  userProfileInterests: parsed["user-profile-interests"],
87507
87698
  writeStatus: Boolean(parsed["write-status"])
87508
87699
  };
87509
87700
  }
87510
- function parseHookInput(stdinData) {
87701
+ function resolveSessionType(agentId, entrypoint) {
87702
+ if (agentId)
87703
+ return "agent";
87704
+ if (entrypoint === "sdk-cli")
87705
+ return "non-interactive";
87706
+ return "interactive";
87707
+ }
87708
+ function parseHookInput(stdinData, entrypoint) {
87511
87709
  if (!stdinData?.trim()) {
87512
87710
  return void 0;
87513
87711
  }
@@ -87532,6 +87730,7 @@ Example: { "command": "pnpm sidekick daemon status", "dangerouslyDisableSandbox"
87532
87730
  permissionMode,
87533
87731
  agentId,
87534
87732
  agentType,
87733
+ sessionType: resolveSessionType(agentId, entrypoint),
87535
87734
  raw
87536
87735
  };
87537
87736
  } catch {
@@ -87542,7 +87741,7 @@ Example: { "command": "pnpm sidekick daemon status", "dangerouslyDisableSandbox"
87542
87741
  const stderr = options.stderr ?? new node_stream_1.PassThrough();
87543
87742
  const parsed = parseArgs(options.argv);
87544
87743
  const homeDir = options.homeDir ?? options.env?.HOME;
87545
- const hookInput = parseHookInput(options.stdinData);
87744
+ const hookInput = parseHookInput(options.stdinData, options.env?.CLAUDE_CODE_ENTRYPOINT);
87546
87745
  const runtime = (0, runtime_1.bootstrapRuntime)({
87547
87746
  projectDir: parsed.projectDir,
87548
87747
  logLevel: parsed.logLevel,
@@ -87771,6 +87970,8 @@ Run 'sidekick hook --help' for available hooks.
87771
87970
  marketplaceScope: parsed.marketplaceScope,
87772
87971
  pluginScope: parsed.pluginScope,
87773
87972
  alias: parsed.alias,
87973
+ statusline: parsed.statusline,
87974
+ sessionSummary: parsed.sessionSummary,
87774
87975
  userProfileName: parsed.userProfileName,
87775
87976
  userProfileRole: parsed.userProfileRole,
87776
87977
  userProfileInterests: parsed.userProfileInterests,
package/dist/daemon.js CHANGED
@@ -46603,7 +46603,7 @@ var require_build_identity = __commonJS({
46603
46603
  var path_1 = __importDefault(require("path"));
46604
46604
  var DEV_PREFIX = "dev:";
46605
46605
  var NO_DIST_SENTINEL = "nodist";
46606
- function computeBuildIdentity(injectedVersion = true ? "0.1.28" : void 0, devFingerprint = computeDevFingerprint) {
46606
+ function computeBuildIdentity(injectedVersion = true ? "0.1.30" : void 0, devFingerprint = computeDevFingerprint) {
46607
46607
  return injectedVersion !== void 0 ? injectedVersion : DEV_PREFIX + devFingerprint();
46608
46608
  }
46609
46609
  function computeDevFingerprint() {
@@ -75581,6 +75581,7 @@ var require_types3 = __commonJS({
75581
75581
  maxSnarkyWords: 20,
75582
75582
  maxResumeWords: 20,
75583
75583
  snarkyMessages: true,
75584
+ resumeMessages: false,
75584
75585
  countdown: {
75585
75586
  lowConfidence: 5,
75586
75587
  mediumConfidence: 10,
@@ -75600,7 +75601,9 @@ var require_types3 = __commonJS({
75600
75601
  llmProfiles: {},
75601
75602
  weights: {},
75602
75603
  persistThroughClear: true,
75603
- cavemanMode: "off"
75604
+ cavemanMode: "off",
75605
+ injectPersonaIntoNonInteractiveSessions: false,
75606
+ injectCavemanIntoNonInteractiveSessions: false
75604
75607
  }
75605
75608
  };
75606
75609
  exports2.RESUME_MIN_CONFIDENCE = 0.7;
@@ -76262,6 +76265,7 @@ var require_update_summary = __commonJS({
76262
76265
  exports2.resetCountdown = resetCountdown;
76263
76266
  exports2.orchestrateSideEffects = orchestrateSideEffects;
76264
76267
  exports2.emitAnalysisEvents = emitAnalysisEvents;
76268
+ exports2.performAnalysis = performAnalysis;
76265
76269
  var core_1 = require_dist4();
76266
76270
  var events_js_1 = require_events3();
76267
76271
  var types_1 = require_dist();
@@ -76500,7 +76504,7 @@ var require_update_summary = __commonJS({
76500
76504
  sideEffects.push(generateSnarkyMessage(ctx, summaryState, sessionId, updatedSummary, config));
76501
76505
  }
76502
76506
  const hasResume = await resumeMessageExists(summaryState, sessionId);
76503
- if (updatedSummary.pivot_detected || !hasResume) {
76507
+ if (config.resumeMessages && (updatedSummary.pivot_detected || !hasResume)) {
76504
76508
  sideEffects.push(generateResumeMessage(ctx, summaryState, eventContext, updatedSummary, config));
76505
76509
  }
76506
76510
  if (sideEffects.length > 0) {
@@ -76534,6 +76538,14 @@ var require_update_summary = __commonJS({
76534
76538
  async function performAnalysis(event, ctx, summaryState, reason) {
76535
76539
  const { context: eventContext, payload } = event;
76536
76540
  const { sessionId } = eventContext;
76541
+ if (!ctx.config.getFeature("session-summary").enabled) {
76542
+ ctx.logger.debug("Session summary disabled; skipping analysis", { sessionId, reason });
76543
+ return;
76544
+ }
76545
+ if (ctx.sessionType === "non-interactive") {
76546
+ ctx.logger.debug("Non-interactive session; skipping summary analysis", { sessionId, reason });
76547
+ return;
76548
+ }
76537
76549
  try {
76538
76550
  const countdown = await loadCountdownState(summaryState, sessionId);
76539
76551
  const startTime = Date.now();
@@ -76906,6 +76918,28 @@ var require_dist5 = __commonJS({
76906
76918
  }
76907
76919
  });
76908
76920
 
76921
+ // ../feature-reminders/dist/handlers/consumption/session-type-gate.js
76922
+ var require_session_type_gate = __commonJS({
76923
+ "../feature-reminders/dist/handlers/consumption/session-type-gate.js"(exports2) {
76924
+ "use strict";
76925
+ Object.defineProperty(exports2, "__esModule", { value: true });
76926
+ exports2.suppressReminderForSessionType = suppressReminderForSessionType;
76927
+ var types_js_1 = require_types2();
76928
+ var PERSONA_REMINDERS = /* @__PURE__ */ new Set([types_js_1.ReminderIds.REMEMBER_YOUR_PERSONA, types_js_1.ReminderIds.PERSONA_CHANGED]);
76929
+ function suppressReminderForSessionType(reminderName, sessionType, config) {
76930
+ if (sessionType !== "non-interactive")
76931
+ return false;
76932
+ if (PERSONA_REMINDERS.has(reminderName)) {
76933
+ return config.injectPersonaIntoNonInteractiveSessions !== true;
76934
+ }
76935
+ if (reminderName === types_js_1.ReminderIds.CAVEMAN_MODE) {
76936
+ return config.injectCavemanIntoNonInteractiveSessions !== true;
76937
+ }
76938
+ return false;
76939
+ }
76940
+ }
76941
+ });
76942
+
76909
76943
  // ../feature-reminders/dist/handlers/staging/stage-persona-reminders.js
76910
76944
  var require_stage_persona_reminders = __commonJS({
76911
76945
  "../feature-reminders/dist/handlers/staging/stage-persona-reminders.js"(exports2) {
@@ -76921,6 +76955,7 @@ var require_stage_persona_reminders = __commonJS({
76921
76955
  var types_1 = require_dist();
76922
76956
  var reminder_utils_js_1 = require_reminder_utils();
76923
76957
  var types_js_1 = require_types2();
76958
+ var session_type_gate_js_1 = require_session_type_gate();
76924
76959
  var throttle_utils_js_1 = require_throttle_utils();
76925
76960
  async function restagePersonaRemindersForActiveSessions(ctxFactory, sessionIds, logger) {
76926
76961
  logger.info("Re-staging persona reminders for active sessions", { count: sessionIds.length });
@@ -77136,6 +77171,10 @@ var require_stage_persona_reminders = __commonJS({
77136
77171
  async function resolvePersonaContextForSnapshot(ctx, sessionId) {
77137
77172
  if (!isPersonaInjectionEnabled(ctx))
77138
77173
  return void 0;
77174
+ const personaConfig = ctx.config.getFeature("session-summary").settings?.personas ?? {};
77175
+ if ((0, session_type_gate_js_1.suppressReminderForSessionType)(types_js_1.ReminderIds.REMEMBER_YOUR_PERSONA, ctx.sessionType, personaConfig)) {
77176
+ return void 0;
77177
+ }
77139
77178
  const persona = await loadPersonaForSession(ctx, sessionId);
77140
77179
  if (!persona)
77141
77180
  return void 0;
@@ -77532,6 +77571,7 @@ var require_consumption_handler_factory = __commonJS({
77532
77571
  var events_js_1 = require_events2();
77533
77572
  var types_1 = require_dist();
77534
77573
  var cli_staging_reader_js_1 = require_cli_staging_reader();
77574
+ var session_type_gate_js_1 = require_session_type_gate();
77535
77575
  function buildDefaultResponse(reminder, supportsBlocking) {
77536
77576
  const response = {};
77537
77577
  if (supportsBlocking && reminder.blocking) {
@@ -77565,7 +77605,8 @@ var require_consumption_handler_factory = __commonJS({
77565
77605
  paths: cliCtx.paths,
77566
77606
  sessionId
77567
77607
  });
77568
- const reminders = reader.listReminders(hook);
77608
+ const personaConfig = cliCtx.config.getFeature("session-summary").settings?.personas ?? {};
77609
+ const reminders = reader.listReminders(hook).filter((r) => !(0, session_type_gate_js_1.suppressReminderForSessionType)(r.name, event.context.sessionType, personaConfig));
77569
77610
  if (reminders.length === 0) {
77570
77611
  return { response: {} };
77571
77612
  }
@@ -80012,12 +80053,18 @@ var require_daemon_helpers = __commonJS({
80012
80053
  "use strict";
80013
80054
  Object.defineProperty(exports2, "__esModule", { value: true });
80014
80055
  exports2.REGISTRY_HEARTBEAT_INTERVAL_MS = exports2.EVICTION_INTERVAL_MS = exports2.HEARTBEAT_INTERVAL_MS = exports2.IDLE_CHECK_INTERVAL_MS = exports2.VERSION = void 0;
80056
+ exports2.nextStoredSessionType = nextStoredSessionType;
80015
80057
  exports2.diffConfigs = diffConfigs;
80016
80058
  exports2.resolveTranscriptPath = resolveTranscriptPath;
80017
80059
  exports2.shouldRunStartupCleanup = shouldRunStartupCleanup;
80018
80060
  exports2.getPersonaInjectionEnabled = getPersonaInjectionEnabled;
80019
80061
  exports2.getCavemanConfigDefault = getCavemanConfigDefault;
80020
80062
  var core_1 = require_dist4();
80063
+ function nextStoredSessionType(current, incoming) {
80064
+ if (incoming && incoming !== "agent")
80065
+ return incoming;
80066
+ return current;
80067
+ }
80021
80068
  exports2.VERSION = (0, core_1.computeBuildIdentity)();
80022
80069
  exports2.IDLE_CHECK_INTERVAL_MS = 30 * 1e3;
80023
80070
  exports2.HEARTBEAT_INTERVAL_MS = 5 * 1e3;
@@ -80657,6 +80704,13 @@ var require_daemon = __commonJS({
80657
80704
  sessionLogWriter;
80658
80705
  /** In-memory compaction snapshots keyed by sessionId. Populated by PreCompact, consumed by PostCompact. */
80659
80706
  compactionSnapshots = /* @__PURE__ */ new Map();
80707
+ /**
80708
+ * Parent session type keyed by sessionId. Only updated by parent hooks
80709
+ * (interactive/non-interactive); subagent 'agent' hooks share the parent
80710
+ * sessionId and are ignored so they cannot flip the stored type. Surfaced onto
80711
+ * DaemonContext.sessionType to gate expensive session-summary work.
80712
+ */
80713
+ sessionTypes = /* @__PURE__ */ new Map();
80660
80714
  /** Cache persona for handoff on clear. */
80661
80715
  cachePersonaForClear(personaId) {
80662
80716
  this.lastClearedPersona = { personaId, timestamp: Date.now() };
@@ -81020,6 +81074,10 @@ var require_daemon = __commonJS({
81020
81074
  * Uses the same infrastructure as the IPC handlers for message generation.
81021
81075
  */
81022
81076
  async regenerateMessagesForSession(sessionId) {
81077
+ if (this.sessionTypes.get(sessionId) === "non-interactive") {
81078
+ this.logger.debug("Non-interactive session; skipping message regeneration", { sessionId });
81079
+ return;
81080
+ }
81023
81081
  this.logger.info("Regenerating messages after persona change", { sessionId });
81024
81082
  try {
81025
81083
  await (0, persona_transition_js_1.stagePersonaTransition)(this.stateService, sessionId);
@@ -81105,6 +81163,11 @@ var require_daemon = __commonJS({
81105
81163
  throw new Error("hook.invoke requires hook and event parameters");
81106
81164
  }
81107
81165
  const { sessionId, correlationId } = event.context ?? {};
81166
+ if (sessionId) {
81167
+ const next = (0, daemon_helpers_js_1.nextStoredSessionType)(this.sessionTypes.get(sessionId), event.context?.sessionType);
81168
+ if (next !== void 0)
81169
+ this.sessionTypes.set(sessionId, next);
81170
+ }
81108
81171
  const requestLogger = this.logger.child({
81109
81172
  context: { sessionId, correlationId }
81110
81173
  });
@@ -81215,7 +81278,8 @@ ${postCompactResponse.additionalContext}` : postCompactResponse.additionalContex
81215
81278
  llm: void 0,
81216
81279
  profileFactory: void 0,
81217
81280
  orchestrator: this.orchestrator,
81218
- personaClearCache: { consume: () => this.consumeCachedPersona() }
81281
+ personaClearCache: { consume: () => this.consumeCachedPersona() },
81282
+ sessionType: this.sessionTypes.get(sessionId) ?? "interactive"
81219
81283
  };
81220
81284
  const [personaContext, userProfileContext] = await Promise.all([
81221
81285
  (0, feature_reminders_1.resolvePersonaContextForSnapshot)(minimalCtx, sessionId),
@@ -81284,6 +81348,7 @@ ${postCompactResponse.additionalContext}` : postCompactResponse.additionalContex
81284
81348
  const log = options?.logger ?? this.logger;
81285
81349
  const sessionId = event.context?.sessionId;
81286
81350
  if (sessionId) {
81351
+ this.sessionTypes.delete(sessionId);
81287
81352
  const payload = event.payload;
81288
81353
  log.info("[persona-lifecycle] ClearHandoff: handleSessionEnd entered", {
81289
81354
  sessionId,
@@ -81662,7 +81727,8 @@ ${postCompactResponse.additionalContext}` : postCompactResponse.additionalContex
81662
81727
  orchestrator: this.orchestrator,
81663
81728
  personaClearCache: {
81664
81729
  consume: () => this.consumeCachedPersona()
81665
- }
81730
+ },
81731
+ sessionType: this.sessionTypes.get(sessionId) ?? "interactive"
81666
81732
  };
81667
81733
  this.handlerRegistry.updateSession({ sessionId, transcriptPath });
81668
81734
  this.handlerRegistry.setStagingProvider(() => stagingService);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scotthamilton77/sidekick",
3
- "version": "0.1.28",
3
+ "version": "0.1.30",
4
4
  "description": "AI pair programming assistant with personas, session tracking, and contextual nudges",
5
5
  "bin": {
6
6
  "sidekick": "dist/bin.js"