@scotthamilton77/sidekick 0.1.3 → 0.1.5

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
@@ -17213,7 +17213,7 @@ var require_state = __commonJS({
17213
17213
  "../types/dist/services/state.js"(exports2) {
17214
17214
  "use strict";
17215
17215
  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.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;
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;
17217
17217
  exports2.createDefaultLLMMetrics = createDefaultLLMMetrics;
17218
17218
  var zod_1 = require_zod();
17219
17219
  exports2.SessionSummaryStateSchema = zod_1.z.object({
@@ -17362,6 +17362,25 @@ var require_state = __commonJS({
17362
17362
  confidence: zod_1.z.number()
17363
17363
  })
17364
17364
  });
17365
+ exports2.VerificationToolStatusSchema = zod_1.z.object({
17366
+ /** Current state: staged (needs run), verified (recently run), cooldown (post-verified, counting edits) */
17367
+ status: zod_1.z.enum(["staged", "verified", "cooldown"]),
17368
+ /** Number of qualifying file edits since last verification */
17369
+ editsSinceVerified: zod_1.z.number(),
17370
+ /** Unix timestamp (ms) when last verified, null if never */
17371
+ lastVerifiedAt: zod_1.z.number().nullable(),
17372
+ /** Unix timestamp (ms) when last staged, null if never */
17373
+ lastStagedAt: zod_1.z.number().nullable(),
17374
+ /** tool_id of the pattern that last matched (metadata for future scope-aware logic) */
17375
+ lastMatchedToolId: zod_1.z.string().nullable().optional(),
17376
+ /** Scope of the last matched pattern */
17377
+ lastMatchedScope: zod_1.z.enum(["project", "package", "file"]).nullable().optional()
17378
+ });
17379
+ exports2.VerificationToolsStateSchema = zod_1.z.record(zod_1.z.string(), exports2.VerificationToolStatusSchema);
17380
+ exports2.UPSThrottleStateSchema = zod_1.z.object({
17381
+ /** Number of conversation messages since the reminder was last staged */
17382
+ messagesSinceLastStaging: zod_1.z.number()
17383
+ });
17365
17384
  exports2.BaseTokenMetricsStateSchema = zod_1.z.object({
17366
17385
  /** System prompt tokens (~3.2k) */
17367
17386
  systemPromptTokens: zod_1.z.number(),
@@ -45250,7 +45269,10 @@ var require_structured_logging = __commonJS({
45250
45269
  mkdir: true
45251
45270
  }).then((stream) => {
45252
45271
  this.realStream = stream;
45253
- this.drainPending((chunk, cb) => stream.write(chunk, cb));
45272
+ this.drainPending((chunk, cb) => {
45273
+ stream.write(chunk);
45274
+ cb();
45275
+ });
45254
45276
  }).catch((err) => {
45255
45277
  process.stderr.write(`[sidekick] pino-roll init failed, using appendFileSync fallback: ${err}
45256
45278
  `);
@@ -45259,7 +45281,8 @@ var require_structured_logging = __commonJS({
45259
45281
  }
45260
45282
  _write(chunk, _encoding, callback) {
45261
45283
  if (this.realStream) {
45262
- this.realStream.write(chunk, callback);
45284
+ this.realStream.write(chunk);
45285
+ callback();
45263
45286
  } else if (this.initPending) {
45264
45287
  this.pending.push({ chunk, callback });
45265
45288
  } else {
@@ -71078,7 +71101,154 @@ var require_types2 = __commonJS({
71078
71101
  "../feature-reminders/dist/types.js"(exports2) {
71079
71102
  "use strict";
71080
71103
  Object.defineProperty(exports2, "__esModule", { value: true });
71081
- exports2.ReminderIds = exports2.DEFAULT_REMINDERS_SETTINGS = exports2.DEFAULT_COMPLETION_DETECTION_SETTINGS = exports2.DEFAULT_SOURCE_CODE_PATTERNS = void 0;
71104
+ exports2.ALL_VC_REMINDER_IDS = exports2.VC_TOOL_REMINDER_IDS = exports2.ReminderIds = exports2.DEFAULT_REMINDERS_SETTINGS = exports2.DEFAULT_COMPLETION_DETECTION_SETTINGS = exports2.DEFAULT_SOURCE_CODE_PATTERNS = exports2.DEFAULT_VERIFICATION_TOOLS = exports2.VerificationToolsMapSchema = exports2.VerificationToolConfigSchema = exports2.ToolPatternSchema = exports2.ToolPatternScopeSchema = void 0;
71105
+ var zod_1 = require_zod2();
71106
+ exports2.ToolPatternScopeSchema = zod_1.z.enum(["project", "package", "file"]);
71107
+ exports2.ToolPatternSchema = zod_1.z.object({
71108
+ tool_id: zod_1.z.string(),
71109
+ tool: zod_1.z.string().nullable(),
71110
+ scope: exports2.ToolPatternScopeSchema.default("project")
71111
+ });
71112
+ exports2.VerificationToolConfigSchema = zod_1.z.object({
71113
+ enabled: zod_1.z.boolean(),
71114
+ patterns: zod_1.z.array(exports2.ToolPatternSchema).min(1),
71115
+ clearing_threshold: zod_1.z.number().int().positive(),
71116
+ clearing_patterns: zod_1.z.array(zod_1.z.string()).min(1)
71117
+ });
71118
+ exports2.VerificationToolsMapSchema = zod_1.z.record(zod_1.z.string(), exports2.VerificationToolConfigSchema);
71119
+ exports2.DEFAULT_VERIFICATION_TOOLS = {
71120
+ build: {
71121
+ enabled: true,
71122
+ patterns: [
71123
+ // TypeScript/JavaScript
71124
+ { tool_id: "tsc", tool: "tsc", scope: "project" },
71125
+ { tool_id: "esbuild", tool: "esbuild", scope: "file" },
71126
+ { tool_id: "pnpm-filter-build", tool: "pnpm --filter * build", scope: "package" },
71127
+ { tool_id: "pnpm-build", tool: "pnpm build", scope: "project" },
71128
+ { tool_id: "npm-build", tool: "npm run build", scope: "project" },
71129
+ { tool_id: "yarn-workspace-build", tool: "yarn workspace * build", scope: "package" },
71130
+ { tool_id: "yarn-build", tool: "yarn build", scope: "project" },
71131
+ // Python
71132
+ { tool_id: "python-setup-build", tool: "python setup.py build", scope: "project" },
71133
+ { tool_id: "pip-install", tool: "pip install", scope: "project" },
71134
+ { tool_id: "poetry-build", tool: "poetry build", scope: "project" },
71135
+ // JVM
71136
+ { tool_id: "mvn-compile", tool: "mvn compile", scope: "project" },
71137
+ { tool_id: "mvn-package", tool: "mvn package", scope: "project" },
71138
+ { tool_id: "gradle-build", tool: "gradle build", scope: "project" },
71139
+ { tool_id: "gradlew-build", tool: "./gradlew build", scope: "project" },
71140
+ // Go
71141
+ { tool_id: "go-build", tool: "go build", scope: "project" },
71142
+ // Rust
71143
+ { tool_id: "cargo-build", tool: "cargo build", scope: "project" },
71144
+ // C/C++
71145
+ { tool_id: "make-build", tool: "make build", scope: "project" },
71146
+ { tool_id: "make-default", tool: "make", scope: "project" },
71147
+ { tool_id: "cmake-build", tool: "cmake --build", scope: "project" },
71148
+ // Containers
71149
+ { tool_id: "docker-build", tool: "docker build", scope: "project" }
71150
+ ],
71151
+ clearing_threshold: 3,
71152
+ clearing_patterns: [
71153
+ "**/*.ts",
71154
+ "**/*.tsx",
71155
+ "**/*.js",
71156
+ "**/*.jsx",
71157
+ "**/*.py",
71158
+ "**/*.java",
71159
+ "**/*.kt",
71160
+ "**/*.go",
71161
+ "**/*.rs",
71162
+ "**/*.c",
71163
+ "**/*.cpp",
71164
+ "**/*.cs"
71165
+ ]
71166
+ },
71167
+ typecheck: {
71168
+ enabled: true,
71169
+ patterns: [
71170
+ { tool_id: "tsc-noEmit", tool: "tsc --noEmit", scope: "project" },
71171
+ { tool_id: "pnpm-filter-typecheck", tool: "pnpm --filter * typecheck", scope: "package" },
71172
+ { tool_id: "pnpm-typecheck", tool: "pnpm typecheck", scope: "project" },
71173
+ { tool_id: "npm-typecheck", tool: "npm run typecheck", scope: "project" },
71174
+ { tool_id: "yarn-workspace-typecheck", tool: "yarn workspace * typecheck", scope: "package" },
71175
+ { tool_id: "yarn-typecheck", tool: "yarn typecheck", scope: "project" },
71176
+ { tool_id: "mypy", tool: "mypy", scope: "project" },
71177
+ { tool_id: "pyright", tool: "pyright", scope: "project" },
71178
+ { tool_id: "pytype", tool: "pytype", scope: "project" },
71179
+ { tool_id: "go-vet", tool: "go vet", scope: "project" }
71180
+ ],
71181
+ clearing_threshold: 3,
71182
+ clearing_patterns: ["**/*.ts", "**/*.tsx", "**/*.py", "**/*.go"]
71183
+ },
71184
+ test: {
71185
+ enabled: true,
71186
+ patterns: [
71187
+ { tool_id: "vitest", tool: "vitest", scope: "project" },
71188
+ { tool_id: "jest", tool: "jest", scope: "project" },
71189
+ { tool_id: "pnpm-filter-test", tool: "pnpm --filter * test", scope: "package" },
71190
+ { tool_id: "pnpm-test", tool: "pnpm test", scope: "project" },
71191
+ { tool_id: "npm-test", tool: "npm test", scope: "project" },
71192
+ { tool_id: "yarn-workspace-test", tool: "yarn workspace * test", scope: "package" },
71193
+ { tool_id: "yarn-test", tool: "yarn test", scope: "project" },
71194
+ { tool_id: "pytest", tool: "pytest", scope: "project" },
71195
+ { tool_id: "python-pytest", tool: "python -m pytest", scope: "project" },
71196
+ { tool_id: "python-unittest", tool: "python -m unittest", scope: "project" },
71197
+ { tool_id: "mvn-test", tool: "mvn test", scope: "project" },
71198
+ { tool_id: "gradle-test", tool: "gradle test", scope: "project" },
71199
+ { tool_id: "gradlew-test", tool: "./gradlew test", scope: "project" },
71200
+ { tool_id: "go-test", tool: "go test", scope: "project" },
71201
+ { tool_id: "cargo-test", tool: "cargo test", scope: "project" },
71202
+ { tool_id: "dotnet-test", tool: "dotnet test", scope: "project" },
71203
+ { tool_id: "make-test", tool: "make test", scope: "project" }
71204
+ ],
71205
+ clearing_threshold: 3,
71206
+ clearing_patterns: [
71207
+ "**/*.ts",
71208
+ "**/*.tsx",
71209
+ "**/*.js",
71210
+ "**/*.jsx",
71211
+ "**/*.py",
71212
+ "**/*.java",
71213
+ "**/*.kt",
71214
+ "**/*.go",
71215
+ "**/*.rs",
71216
+ "**/*.test.*",
71217
+ "**/*.spec.*",
71218
+ "**/test_*"
71219
+ ]
71220
+ },
71221
+ lint: {
71222
+ enabled: true,
71223
+ patterns: [
71224
+ { tool_id: "eslint", tool: "eslint", scope: "project" },
71225
+ { tool_id: "pnpm-filter-lint", tool: "pnpm --filter * lint", scope: "package" },
71226
+ { tool_id: "pnpm-lint", tool: "pnpm lint", scope: "project" },
71227
+ { tool_id: "npm-lint", tool: "npm run lint", scope: "project" },
71228
+ { tool_id: "yarn-workspace-lint", tool: "yarn workspace * lint", scope: "package" },
71229
+ { tool_id: "yarn-lint", tool: "yarn lint", scope: "project" },
71230
+ { tool_id: "ruff", tool: "ruff", scope: "project" },
71231
+ { tool_id: "flake8", tool: "flake8", scope: "project" },
71232
+ { tool_id: "pylint", tool: "pylint", scope: "project" },
71233
+ { tool_id: "golangci-lint", tool: "golangci-lint", scope: "project" },
71234
+ { tool_id: "cargo-clippy", tool: "cargo clippy", scope: "project" },
71235
+ { tool_id: "ktlint", tool: "ktlint", scope: "project" },
71236
+ { tool_id: "dotnet-format", tool: "dotnet format", scope: "project" }
71237
+ ],
71238
+ clearing_threshold: 5,
71239
+ clearing_patterns: [
71240
+ "**/*.ts",
71241
+ "**/*.tsx",
71242
+ "**/*.js",
71243
+ "**/*.jsx",
71244
+ "**/*.py",
71245
+ "**/*.java",
71246
+ "**/*.kt",
71247
+ "**/*.go",
71248
+ "**/*.rs"
71249
+ ]
71250
+ }
71251
+ };
71082
71252
  exports2.DEFAULT_SOURCE_CODE_PATTERNS = [
71083
71253
  // TypeScript/JavaScript
71084
71254
  "**/*.ts",
@@ -71128,17 +71298,65 @@ var require_types2 = __commonJS({
71128
71298
  exports2.DEFAULT_REMINDERS_SETTINGS = {
71129
71299
  pause_and_reflect_threshold: 60,
71130
71300
  source_code_patterns: exports2.DEFAULT_SOURCE_CODE_PATTERNS,
71131
- max_verification_cycles: -1
71301
+ max_verification_cycles: -1,
71132
71302
  // -1 = unlimited, 0 = disabled
71303
+ verification_tools: exports2.DEFAULT_VERIFICATION_TOOLS,
71304
+ user_prompt_submit_threshold: 10
71133
71305
  };
71134
71306
  exports2.ReminderIds = {
71135
71307
  USER_PROMPT_SUBMIT: "user-prompt-submit",
71136
71308
  PAUSE_AND_REFLECT: "pause-and-reflect",
71137
71309
  VERIFY_COMPLETION: "verify-completion",
71310
+ VC_BUILD: "vc-build",
71311
+ VC_TYPECHECK: "vc-typecheck",
71312
+ VC_TEST: "vc-test",
71313
+ VC_LINT: "vc-lint",
71138
71314
  REMEMBER_YOUR_PERSONA: "remember-your-persona",
71139
71315
  PERSONA_CHANGED: "persona-changed",
71140
71316
  USER_PROFILE: "user-profile"
71141
71317
  };
71318
+ exports2.VC_TOOL_REMINDER_IDS = [
71319
+ exports2.ReminderIds.VC_BUILD,
71320
+ exports2.ReminderIds.VC_TYPECHECK,
71321
+ exports2.ReminderIds.VC_TEST,
71322
+ exports2.ReminderIds.VC_LINT
71323
+ ];
71324
+ exports2.ALL_VC_REMINDER_IDS = [exports2.ReminderIds.VERIFY_COMPLETION, ...exports2.VC_TOOL_REMINDER_IDS];
71325
+ }
71326
+ });
71327
+
71328
+ // ../feature-reminders/dist/state.js
71329
+ var require_state3 = __commonJS({
71330
+ "../feature-reminders/dist/state.js"(exports2) {
71331
+ "use strict";
71332
+ Object.defineProperty(exports2, "__esModule", { value: true });
71333
+ exports2.createRemindersState = createRemindersState;
71334
+ var core_1 = require_dist4();
71335
+ var types_1 = require_dist();
71336
+ var PRBaselineDescriptor = (0, core_1.sessionState)("pr-baseline.json", types_1.PRBaselineStateSchema, {
71337
+ defaultValue: null,
71338
+ trackHistory: true
71339
+ });
71340
+ var VCUnverifiedDescriptor = (0, core_1.sessionState)("vc-unverified.json", types_1.VCUnverifiedStateSchema, {
71341
+ defaultValue: null,
71342
+ trackHistory: true
71343
+ });
71344
+ var VerificationToolsDescriptor = (0, core_1.sessionState)("verification-tools.json", types_1.VerificationToolsStateSchema, {
71345
+ defaultValue: {},
71346
+ trackHistory: false
71347
+ });
71348
+ var UPSThrottleDescriptor = (0, core_1.sessionState)("ups-throttle.json", types_1.UPSThrottleStateSchema, {
71349
+ defaultValue: { messagesSinceLastStaging: 0 },
71350
+ trackHistory: false
71351
+ });
71352
+ function createRemindersState(stateService) {
71353
+ return {
71354
+ prBaseline: new core_1.SessionStateAccessor(stateService, PRBaselineDescriptor),
71355
+ vcUnverified: new core_1.SessionStateAccessor(stateService, VCUnverifiedDescriptor),
71356
+ verificationTools: new core_1.SessionStateAccessor(stateService, VerificationToolsDescriptor),
71357
+ upsThrottle: new core_1.SessionStateAccessor(stateService, UPSThrottleDescriptor)
71358
+ };
71359
+ }
71142
71360
  }
71143
71361
  });
71144
71362
 
@@ -71151,6 +71369,8 @@ var require_stage_default_user_prompt = __commonJS({
71151
71369
  var types_1 = require_dist();
71152
71370
  var staging_handler_utils_js_1 = require_staging_handler_utils();
71153
71371
  var types_js_1 = require_types2();
71372
+ var reminder_utils_js_1 = require_reminder_utils();
71373
+ var state_js_1 = require_state3();
71154
71374
  function registerStageDefaultUserPrompt(context) {
71155
71375
  (0, staging_handler_utils_js_1.createStagingHandler)(context, {
71156
71376
  id: "reminders:stage-default-user-prompt",
@@ -71168,6 +71388,23 @@ var require_stage_default_user_prompt = __commonJS({
71168
71388
  };
71169
71389
  }
71170
71390
  });
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
+ }
71171
71408
  (0, staging_handler_utils_js_1.createStagingHandler)(context, {
71172
71409
  id: "reminders:stage-default-user-prompt-after-bulk",
71173
71410
  priority: 50,
@@ -71184,31 +71421,68 @@ var require_stage_default_user_prompt = __commonJS({
71184
71421
  };
71185
71422
  }
71186
71423
  });
71187
- }
71188
- }
71189
- });
71190
-
71191
- // ../feature-reminders/dist/state.js
71192
- var require_state3 = __commonJS({
71193
- "../feature-reminders/dist/state.js"(exports2) {
71194
- "use strict";
71195
- Object.defineProperty(exports2, "__esModule", { value: true });
71196
- exports2.createRemindersState = createRemindersState;
71197
- var core_1 = require_dist4();
71198
- var types_1 = require_dist();
71199
- var PRBaselineDescriptor = (0, core_1.sessionState)("pr-baseline.json", types_1.PRBaselineStateSchema, {
71200
- defaultValue: null,
71201
- trackHistory: true
71202
- });
71203
- var VCUnverifiedDescriptor = (0, core_1.sessionState)("vc-unverified.json", types_1.VCUnverifiedStateSchema, {
71204
- defaultValue: null,
71205
- trackHistory: true
71206
- });
71207
- function createRemindersState(stateService) {
71208
- return {
71209
- prBaseline: new core_1.SessionStateAccessor(stateService, PRBaselineDescriptor),
71210
- vcUnverified: new core_1.SessionStateAccessor(stateService, VCUnverifiedDescriptor)
71211
- };
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
+ if (!(0, types_1.isDaemonContext)(context))
71444
+ return;
71445
+ context.handlers.register({
71446
+ id: "reminders:ups-throttle-restage",
71447
+ priority: 50,
71448
+ filter: { kind: "transcript", eventTypes: ["UserPrompt", "AssistantMessage"] },
71449
+ handler: async (event, ctx) => {
71450
+ if (!(0, types_1.isTranscriptEvent)(event))
71451
+ return;
71452
+ if (!(0, types_1.isDaemonContext)(ctx))
71453
+ return;
71454
+ if (event.metadata.isBulkProcessing)
71455
+ return;
71456
+ const sessionId = event.context?.sessionId;
71457
+ if (!sessionId)
71458
+ return;
71459
+ const handlerCtx = ctx;
71460
+ const remindersState = (0, state_js_1.createRemindersState)(handlerCtx.stateService);
71461
+ const result = await remindersState.upsThrottle.read(sessionId);
71462
+ const current = result.data.messagesSinceLastStaging;
71463
+ const featureConfig = handlerCtx.config.getFeature("reminders");
71464
+ 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", {
71475
+ sessionId,
71476
+ messageCount: newCount,
71477
+ threshold
71478
+ });
71479
+ }
71480
+ await remindersState.upsThrottle.write(sessionId, { messagesSinceLastStaging: 0 });
71481
+ } else {
71482
+ await remindersState.upsThrottle.write(sessionId, { messagesSinceLastStaging: newCount });
71483
+ }
71484
+ }
71485
+ });
71212
71486
  }
71213
71487
  }
71214
71488
  });
@@ -72788,73 +73062,228 @@ var require_picomatch2 = __commonJS({
72788
73062
  }
72789
73063
  });
72790
73064
 
72791
- // ../feature-reminders/dist/handlers/staging/stage-stop-reminders.js
72792
- var require_stage_stop_reminders = __commonJS({
72793
- "../feature-reminders/dist/handlers/staging/stage-stop-reminders.js"(exports2) {
73065
+ // ../feature-reminders/dist/tool-pattern-matcher.js
73066
+ var require_tool_pattern_matcher = __commonJS({
73067
+ "../feature-reminders/dist/tool-pattern-matcher.js"(exports2) {
73068
+ "use strict";
73069
+ Object.defineProperty(exports2, "__esModule", { value: true });
73070
+ exports2.matchesToolPattern = matchesToolPattern;
73071
+ exports2.findMatchingPattern = findMatchingPattern;
73072
+ var SHELL_OPERATOR_RE = /\s*(?:&&|\|\||[;|])\s*/;
73073
+ function matchesToolPattern(command, pattern) {
73074
+ if (!command || !pattern)
73075
+ return false;
73076
+ const segments = command.split(SHELL_OPERATOR_RE);
73077
+ const patternTokens = pattern.trim().split(/\s+/).filter(Boolean);
73078
+ if (patternTokens.length === 0)
73079
+ return false;
73080
+ return segments.some((segment) => {
73081
+ const cmdTokens = segment.trim().split(/\s+/);
73082
+ if (cmdTokens.length === 0 || cmdTokens[0] === "")
73083
+ return false;
73084
+ if (cmdTokens[0] !== patternTokens[0])
73085
+ return false;
73086
+ let pi = 1;
73087
+ for (let ci = 1; ci < cmdTokens.length && pi < patternTokens.length; ci++) {
73088
+ if (patternTokens[pi] === "*" || patternTokens[pi] === cmdTokens[ci]) {
73089
+ pi++;
73090
+ }
73091
+ }
73092
+ return pi === patternTokens.length;
73093
+ });
73094
+ }
73095
+ function findMatchingPattern(command, patterns) {
73096
+ for (const pattern of patterns) {
73097
+ if (pattern.tool === null)
73098
+ continue;
73099
+ if (matchesToolPattern(command, pattern.tool))
73100
+ return pattern;
73101
+ }
73102
+ return null;
73103
+ }
73104
+ }
73105
+ });
73106
+
73107
+ // ../feature-reminders/dist/handlers/staging/track-verification-tools.js
73108
+ var require_track_verification_tools = __commonJS({
73109
+ "../feature-reminders/dist/handlers/staging/track-verification-tools.js"(exports2) {
72794
73110
  "use strict";
72795
73111
  var __importDefault2 = exports2 && exports2.__importDefault || function(mod) {
72796
73112
  return mod && mod.__esModule ? mod : { "default": mod };
72797
73113
  };
72798
73114
  Object.defineProperty(exports2, "__esModule", { value: true });
72799
- exports2.registerStageStopReminders = registerStageStopReminders;
73115
+ exports2.registerTrackVerificationTools = registerTrackVerificationTools;
73116
+ exports2.stageToolsForFiles = stageToolsForFiles;
72800
73117
  var types_1 = require_dist();
72801
73118
  var picomatch_1 = __importDefault2(require_picomatch2());
72802
- var staging_handler_utils_js_1 = require_staging_handler_utils();
73119
+ var tool_pattern_matcher_js_1 = require_tool_pattern_matcher();
73120
+ var reminder_utils_js_1 = require_reminder_utils();
72803
73121
  var types_js_1 = require_types2();
73122
+ var state_js_1 = require_state3();
72804
73123
  var FILE_EDIT_TOOLS = ["Write", "Edit", "MultiEdit"];
72805
- function registerStageStopReminders(context) {
72806
- (0, staging_handler_utils_js_1.createStagingHandler)(context, {
72807
- id: "reminders:stage-stop-reminders",
73124
+ var TOOL_REMINDER_MAP = {
73125
+ build: types_js_1.ReminderIds.VC_BUILD,
73126
+ typecheck: types_js_1.ReminderIds.VC_TYPECHECK,
73127
+ test: types_js_1.ReminderIds.VC_TEST,
73128
+ lint: types_js_1.ReminderIds.VC_LINT
73129
+ };
73130
+ var VC_TOOL_NAME_SET = new Set(types_js_1.VC_TOOL_REMINDER_IDS);
73131
+ function extractToolInput(event) {
73132
+ const entry = event.payload.entry;
73133
+ return entry?.input;
73134
+ }
73135
+ function registerTrackVerificationTools(context) {
73136
+ if (!(0, types_1.isDaemonContext)(context))
73137
+ return;
73138
+ context.handlers.register({
73139
+ id: "reminders:track-verification-tools",
72808
73140
  priority: 60,
72809
73141
  filter: { kind: "transcript", eventTypes: ["ToolCall"] },
72810
- execute: async (event, ctx) => {
73142
+ handler: async (event, ctx) => {
72811
73143
  if (!(0, types_1.isTranscriptEvent)(event))
72812
- return void 0;
73144
+ return;
73145
+ if (event.metadata.isBulkProcessing)
73146
+ return;
73147
+ if (!(0, types_1.isDaemonContext)(ctx))
73148
+ return;
73149
+ const daemonCtx = ctx;
73150
+ const sessionId = event.context?.sessionId;
73151
+ if (!sessionId)
73152
+ return;
72813
73153
  const toolName = event.payload.toolName;
72814
- if (!toolName || !FILE_EDIT_TOOLS.includes(toolName))
72815
- return void 0;
73154
+ if (!toolName)
73155
+ return;
72816
73156
  const featureConfig = context.config.getFeature("reminders");
72817
73157
  const config = { ...types_js_1.DEFAULT_REMINDERS_SETTINGS, ...featureConfig.settings };
72818
- const entry = event.payload.entry;
72819
- const filePath = entry?.input?.file_path;
72820
- if (!filePath)
72821
- return void 0;
72822
- const isMatch = picomatch_1.default.isMatch(filePath, config.source_code_patterns);
72823
- if (!isMatch) {
72824
- ctx.logger.debug("VC staging: file edit skipped (no pattern match)", {
72825
- toolName,
72826
- filePath
72827
- });
72828
- return void 0;
73158
+ const verificationTools = config.verification_tools ?? {};
73159
+ const remindersState = (0, state_js_1.createRemindersState)(daemonCtx.stateService);
73160
+ const stateResult = await remindersState.verificationTools.read(sessionId);
73161
+ const toolsState = { ...stateResult.data };
73162
+ if (FILE_EDIT_TOOLS.includes(toolName)) {
73163
+ await handleFileEdit(event, daemonCtx, sessionId, verificationTools, toolsState, remindersState);
73164
+ } else if (toolName === "Bash") {
73165
+ await handleBashCommand(event, daemonCtx, sessionId, verificationTools, toolsState, remindersState);
72829
73166
  }
72830
- const metrics = event.metadata.metrics;
72831
- const lastConsumed = await ctx.staging.getLastConsumed("Stop", types_js_1.ReminderIds.VERIFY_COMPLETION);
72832
- if (lastConsumed?.stagedAt) {
72833
- const shouldReactivate = metrics.turnCount > lastConsumed.stagedAt.turnCount;
72834
- if (!shouldReactivate) {
72835
- ctx.logger.debug("VC staging: skipped (already consumed this turn)", {
72836
- currentTurn: metrics.turnCount,
72837
- lastConsumedTurn: lastConsumed.stagedAt.turnCount
72838
- });
72839
- return void 0;
73167
+ }
73168
+ });
73169
+ }
73170
+ async function stageToolsForFiles(filePaths, daemonCtx, sessionId, verificationTools, toolsState, remindersState) {
73171
+ const existingReminders = await daemonCtx.staging.listReminders("Stop");
73172
+ const stagedNames = new Set(existingReminders.map((r) => r.name));
73173
+ let anyStaged = false;
73174
+ for (const filePath of filePaths) {
73175
+ for (const [toolName, toolConfig] of Object.entries(verificationTools)) {
73176
+ if (!toolConfig.enabled)
73177
+ continue;
73178
+ const reminderId = TOOL_REMINDER_MAP[toolName];
73179
+ if (!reminderId)
73180
+ continue;
73181
+ if (!picomatch_1.default.isMatch(filePath, toolConfig.clearing_patterns))
73182
+ continue;
73183
+ const current = toolsState[toolName];
73184
+ 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
+ };
73192
+ }
73193
+ await stageToolReminderIfNeeded(daemonCtx, reminderId, stagedNames);
73194
+ anyStaged = true;
73195
+ } else {
73196
+ const newEdits = current.editsSinceVerified + 1;
73197
+ 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;
73206
+ } else {
73207
+ toolsState[toolName] = {
73208
+ ...current,
73209
+ status: "cooldown",
73210
+ editsSinceVerified: newEdits
73211
+ };
72840
73212
  }
72841
- ctx.logger.info("VC staging: reactivating on new turn", {
72842
- currentTurn: metrics.turnCount,
72843
- lastConsumedTurn: lastConsumed.stagedAt.turnCount
72844
- });
72845
73213
  }
72846
- ctx.logger.info("VC staging: staging verify-completion", {
72847
- toolName,
72848
- filePath,
72849
- turnCount: metrics.turnCount,
72850
- toolCount: metrics.toolCount,
72851
- firstTimeThisSession: !lastConsumed
72852
- });
72853
- return {
72854
- reminderId: types_js_1.ReminderIds.VERIFY_COMPLETION,
72855
- targetHook: "Stop"
72856
- };
72857
73214
  }
73215
+ }
73216
+ if (anyStaged) {
73217
+ await stageToolReminderIfNeeded(daemonCtx, types_js_1.ReminderIds.VERIFY_COMPLETION, stagedNames);
73218
+ }
73219
+ await remindersState.verificationTools.write(sessionId, toolsState);
73220
+ return anyStaged;
73221
+ }
73222
+ async function handleFileEdit(event, daemonCtx, sessionId, verificationTools, toolsState, remindersState) {
73223
+ const filePath = extractToolInput(event)?.file_path;
73224
+ if (!filePath)
73225
+ return;
73226
+ const projectDir = daemonCtx.paths?.projectDir;
73227
+ if (projectDir && !filePath.startsWith(projectDir))
73228
+ return;
73229
+ await stageToolsForFiles([filePath], daemonCtx, sessionId, verificationTools, toolsState, remindersState);
73230
+ }
73231
+ async function handleBashCommand(event, daemonCtx, sessionId, verificationTools, toolsState, remindersState) {
73232
+ const command = extractToolInput(event)?.command;
73233
+ if (!command)
73234
+ return;
73235
+ let anyUnstaged = false;
73236
+ for (const [toolName, toolConfig] of Object.entries(verificationTools)) {
73237
+ if (!toolConfig.enabled)
73238
+ continue;
73239
+ const reminderId = TOOL_REMINDER_MAP[toolName];
73240
+ if (!reminderId)
73241
+ continue;
73242
+ const match = (0, tool_pattern_matcher_js_1.findMatchingPattern)(command, toolConfig.patterns);
73243
+ if (!match)
73244
+ continue;
73245
+ toolsState[toolName] = {
73246
+ status: "verified",
73247
+ editsSinceVerified: 0,
73248
+ lastVerifiedAt: Date.now(),
73249
+ lastStagedAt: toolsState[toolName]?.lastStagedAt ?? null,
73250
+ lastMatchedToolId: match.tool_id,
73251
+ lastMatchedScope: match.scope
73252
+ };
73253
+ await daemonCtx.staging.deleteReminder("Stop", reminderId);
73254
+ anyUnstaged = true;
73255
+ daemonCtx.logger.debug("VC tool verified", {
73256
+ toolName,
73257
+ reminderId,
73258
+ matchedToolId: match.tool_id,
73259
+ matchedScope: match.scope,
73260
+ command: command.slice(0, 100)
73261
+ });
73262
+ }
73263
+ if (anyUnstaged) {
73264
+ const remaining = await daemonCtx.staging.listReminders("Stop");
73265
+ const hasPerToolReminders = remaining.some((r) => VC_TOOL_NAME_SET.has(r.name));
73266
+ if (!hasPerToolReminders) {
73267
+ await daemonCtx.staging.deleteReminder("Stop", types_js_1.ReminderIds.VERIFY_COMPLETION);
73268
+ daemonCtx.logger.info("All VC tools verified, unstaged wrapper", { sessionId });
73269
+ }
73270
+ await remindersState.verificationTools.write(sessionId, toolsState);
73271
+ }
73272
+ }
73273
+ async function stageToolReminderIfNeeded(daemonCtx, reminderId, stagedNames) {
73274
+ if (stagedNames.has(reminderId))
73275
+ return;
73276
+ const reminder = (0, reminder_utils_js_1.resolveReminder)(reminderId, {
73277
+ context: {},
73278
+ assets: daemonCtx.assets
73279
+ });
73280
+ if (!reminder) {
73281
+ daemonCtx.logger.warn("Failed to resolve VC tool reminder", { reminderId });
73282
+ return;
73283
+ }
73284
+ await (0, reminder_utils_js_1.stageReminder)(daemonCtx, "Stop", {
73285
+ ...reminder,
73286
+ stagedAt: { timestamp: Date.now(), turnCount: 0, toolsThisTurn: 0, toolCount: 0 }
72858
73287
  });
72859
73288
  }
72860
73289
  }
@@ -72872,8 +73301,9 @@ var require_stage_stop_bash_changes = __commonJS({
72872
73301
  var core_1 = require_dist4();
72873
73302
  var types_1 = require_dist();
72874
73303
  var picomatch_1 = __importDefault2(require_picomatch2());
72875
- var staging_handler_utils_js_1 = require_staging_handler_utils();
73304
+ var track_verification_tools_js_1 = require_track_verification_tools();
72876
73305
  var types_js_1 = require_types2();
73306
+ var state_js_1 = require_state3();
72877
73307
  var GIT_STATUS_TIMEOUT_MS = 200;
72878
73308
  var MAX_BASELINES = 50;
72879
73309
  function registerStageBashChanges(context) {
@@ -72910,65 +73340,69 @@ var require_stage_stop_bash_changes = __commonJS({
72910
73340
  });
72911
73341
  }
72912
73342
  });
72913
- (0, staging_handler_utils_js_1.createStagingHandler)(context, {
73343
+ context.handlers.register({
72914
73344
  id: "reminders:stage-stop-bash-changes",
72915
73345
  priority: 55,
72916
73346
  filter: { kind: "transcript", eventTypes: ["ToolResult"] },
72917
- execute: async (event, ctx) => {
73347
+ handler: async (event, ctx) => {
72918
73348
  if (!(0, types_1.isTranscriptEvent)(event))
72919
- return void 0;
73349
+ return;
73350
+ if (event.metadata.isBulkProcessing)
73351
+ return;
73352
+ if (!(0, types_1.isDaemonContext)(ctx))
73353
+ return;
73354
+ const daemonCtx = ctx;
72920
73355
  const toolName = event.payload.toolName;
72921
73356
  if (toolName !== "Bash")
72922
- return void 0;
73357
+ return;
72923
73358
  const sessionId = event.context?.sessionId;
72924
73359
  if (!sessionId)
72925
- return void 0;
73360
+ return;
72926
73361
  const baseline = baselines.get(sessionId);
72927
73362
  if (!baseline) {
72928
- ctx.logger.debug("Bash VC: no baseline for session, skipping", { sessionId });
72929
- return void 0;
73363
+ daemonCtx.logger.debug("Bash VC: no baseline for session, skipping", { sessionId });
73364
+ return;
72930
73365
  }
72931
73366
  const metrics = event.metadata.metrics;
72932
- const lastConsumed = await ctx.staging.getLastConsumed("Stop", types_js_1.ReminderIds.VERIFY_COMPLETION);
73367
+ const lastConsumed = await daemonCtx.staging.getLastConsumed("Stop", types_js_1.ReminderIds.VERIFY_COMPLETION);
72933
73368
  if (lastConsumed?.stagedAt) {
72934
73369
  const shouldReactivate = metrics.turnCount > lastConsumed.stagedAt.turnCount;
72935
73370
  if (!shouldReactivate) {
72936
- ctx.logger.debug("Bash VC: skipped (already consumed this turn)", {
73371
+ daemonCtx.logger.debug("Bash VC: skipped (already consumed this turn)", {
72937
73372
  currentTurn: metrics.turnCount,
72938
73373
  lastConsumedTurn: lastConsumed.stagedAt.turnCount
72939
73374
  });
72940
- return void 0;
73375
+ return;
72941
73376
  }
72942
73377
  }
72943
73378
  const current = await (0, core_1.getGitFileStatus)(cwd, GIT_STATUS_TIMEOUT_MS);
72944
73379
  const baselineSet = new Set(baseline);
72945
73380
  const newFiles = current.filter((f) => !baselineSet.has(f));
72946
- ctx.logger.debug("Bash VC: git status diff", {
73381
+ daemonCtx.logger.debug("Bash VC: git status diff", {
72947
73382
  baselineCount: baseline.length,
72948
73383
  currentCount: current.length,
72949
73384
  newFileCount: newFiles.length
72950
73385
  });
72951
73386
  if (newFiles.length === 0)
72952
- return void 0;
73387
+ return;
72953
73388
  const featureConfig = context.config.getFeature("reminders");
72954
73389
  const config = { ...types_js_1.DEFAULT_REMINDERS_SETTINGS, ...featureConfig.settings };
72955
73390
  const sourceMatches = newFiles.filter((f) => picomatch_1.default.isMatch(f, config.source_code_patterns));
72956
73391
  if (sourceMatches.length === 0) {
72957
- ctx.logger.debug("Bash VC: new files found but no source code matches", {
72958
- newFiles
72959
- });
72960
- return void 0;
73392
+ daemonCtx.logger.debug("Bash VC: new files found but no source code matches", { newFiles });
73393
+ return;
72961
73394
  }
72962
- ctx.logger.info("Bash VC: staging verify-completion", {
73395
+ daemonCtx.logger.info("Bash VC: staging per-tool reminders for source changes", {
72963
73396
  sourceMatches,
72964
73397
  turnCount: metrics.turnCount,
72965
73398
  toolCount: metrics.toolCount
72966
73399
  });
72967
73400
  baselines.set(sessionId, current);
72968
- return {
72969
- reminderId: types_js_1.ReminderIds.VERIFY_COMPLETION,
72970
- targetHook: "Stop"
72971
- };
73401
+ const verificationTools = config.verification_tools ?? {};
73402
+ const remindersState = (0, state_js_1.createRemindersState)(daemonCtx.stateService);
73403
+ const stateResult = await remindersState.verificationTools.read(sessionId);
73404
+ const toolsState = { ...stateResult.data };
73405
+ await (0, track_verification_tools_js_1.stageToolsForFiles)(sourceMatches, daemonCtx, sessionId, verificationTools, toolsState, remindersState);
72972
73406
  }
72973
73407
  });
72974
73408
  }
@@ -73022,28 +73456,52 @@ var require_unstage_verify_completion = __commonJS({
73022
73456
  setAtToolCount: unverifiedState.setAt.toolCount
73023
73457
  });
73024
73458
  if (maxCycles < 0 || unverifiedState.cycleCount < maxCycles) {
73025
- const reminder = (0, reminder_utils_js_1.resolveReminder)(types_js_1.ReminderIds.VERIFY_COMPLETION, {
73026
- context: {},
73027
- assets: daemonCtx.assets
73459
+ const verificationToolsResult = await remindersState.verificationTools.read(sessionId);
73460
+ const toolsState = verificationToolsResult.data;
73461
+ const verificationTools = config.verification_tools ?? {};
73462
+ const hasToolsNeedingVerification = Object.entries(verificationTools).some(([toolName, toolConfig]) => {
73463
+ if (!toolConfig.enabled)
73464
+ return false;
73465
+ const state = toolsState[toolName];
73466
+ if (!state)
73467
+ return true;
73468
+ if (state.status === "staged")
73469
+ return true;
73470
+ if (state.status === "verified" || state.status === "cooldown") {
73471
+ return state.editsSinceVerified >= toolConfig.clearing_threshold;
73472
+ }
73473
+ return false;
73028
73474
  });
73029
- if (reminder) {
73030
- await (0, reminder_utils_js_1.stageReminder)(daemonCtx, "Stop", {
73031
- ...reminder,
73032
- stagedAt: {
73033
- timestamp: Date.now(),
73034
- turnCount: unverifiedState.setAt.turnCount,
73035
- toolsThisTurn: unverifiedState.setAt.toolsThisTurn,
73036
- toolCount: unverifiedState.setAt.toolCount
73037
- }
73038
- });
73039
- daemonCtx.logger.info("VC unstage: re-staged for next Stop", {
73475
+ if (!hasToolsNeedingVerification) {
73476
+ daemonCtx.logger.info("VC unstage: all tools verified, skipping wrapper re-stage", {
73040
73477
  sessionId,
73041
- cycleCount: unverifiedState.cycleCount,
73042
- lastCategory: unverifiedState.lastClassification.category
73478
+ cycleCount: unverifiedState.cycleCount
73043
73479
  });
73044
- return;
73480
+ await remindersState.vcUnverified.delete(sessionId);
73045
73481
  } else {
73046
- daemonCtx.logger.warn("VC unstage: failed to resolve reminder for re-staging");
73482
+ const reminder = (0, reminder_utils_js_1.resolveReminder)(types_js_1.ReminderIds.VERIFY_COMPLETION, {
73483
+ context: {},
73484
+ assets: daemonCtx.assets
73485
+ });
73486
+ if (reminder) {
73487
+ await (0, reminder_utils_js_1.stageReminder)(daemonCtx, "Stop", {
73488
+ ...reminder,
73489
+ stagedAt: {
73490
+ timestamp: Date.now(),
73491
+ turnCount: unverifiedState.setAt.turnCount,
73492
+ toolsThisTurn: unverifiedState.setAt.toolsThisTurn,
73493
+ toolCount: unverifiedState.setAt.toolCount
73494
+ }
73495
+ });
73496
+ daemonCtx.logger.info("VC unstage: re-staged for next Stop", {
73497
+ sessionId,
73498
+ cycleCount: unverifiedState.cycleCount,
73499
+ lastCategory: unverifiedState.lastClassification.category
73500
+ });
73501
+ return;
73502
+ } else {
73503
+ daemonCtx.logger.warn("VC unstage: failed to resolve reminder for re-staging");
73504
+ }
73047
73505
  }
73048
73506
  } else {
73049
73507
  daemonCtx.logger.info("VC unstage: cycle limit reached, clearing", {
@@ -73059,8 +73517,10 @@ var require_unstage_verify_completion = __commonJS({
73059
73517
  hadState: unverifiedState !== null
73060
73518
  });
73061
73519
  }
73062
- await daemonCtx.staging.deleteReminder("Stop", types_js_1.ReminderIds.VERIFY_COMPLETION);
73063
- daemonCtx.logger.debug("VC unstage: deleted staged verify-completion reminder");
73520
+ for (const vcId of types_js_1.ALL_VC_REMINDER_IDS) {
73521
+ await daemonCtx.staging.deleteReminder("Stop", vcId);
73522
+ }
73523
+ daemonCtx.logger.debug("VC unstage: deleted all VC reminders");
73064
73524
  }
73065
73525
  });
73066
73526
  }
@@ -73291,15 +73751,15 @@ var require_staging2 = __commonJS({
73291
73751
  exports2.registerStagingHandlers = registerStagingHandlers;
73292
73752
  var stage_default_user_prompt_1 = require_stage_default_user_prompt();
73293
73753
  var stage_pause_and_reflect_1 = require_stage_pause_and_reflect();
73294
- var stage_stop_reminders_1 = require_stage_stop_reminders();
73295
73754
  var stage_stop_bash_changes_1 = require_stage_stop_bash_changes();
73755
+ var track_verification_tools_1 = require_track_verification_tools();
73296
73756
  var unstage_verify_completion_1 = require_unstage_verify_completion();
73297
73757
  var stage_persona_reminders_1 = require_stage_persona_reminders();
73298
73758
  var stage_user_profile_reminders_1 = require_stage_user_profile_reminders();
73299
73759
  function registerStagingHandlers(context) {
73300
73760
  (0, stage_default_user_prompt_1.registerStageDefaultUserPrompt)(context);
73301
73761
  (0, stage_pause_and_reflect_1.registerStagePauseAndReflect)(context);
73302
- (0, stage_stop_reminders_1.registerStageStopReminders)(context);
73762
+ (0, track_verification_tools_1.registerTrackVerificationTools)(context);
73303
73763
  (0, stage_stop_bash_changes_1.registerStageBashChanges)(context);
73304
73764
  (0, unstage_verify_completion_1.registerUnstageVerifyCompletion)(context);
73305
73765
  (0, stage_persona_reminders_1.registerStagePersonaReminders)(context);
@@ -74011,10 +74471,12 @@ var require_orchestrator = __commonJS({
74011
74471
  if (reminder.name === types_js_1.ReminderIds.PAUSE_AND_REFLECT) {
74012
74472
  try {
74013
74473
  const staging = this.deps.getStagingService(sessionId);
74014
- await staging.deleteReminder("Stop", types_js_1.ReminderIds.VERIFY_COMPLETION);
74015
- this.deps.logger.debug("Unstaged VC after P&R staged", { sessionId });
74474
+ for (const vcId of types_js_1.ALL_VC_REMINDER_IDS) {
74475
+ await staging.deleteReminder("Stop", vcId);
74476
+ }
74477
+ this.deps.logger.debug("Unstaged all VC reminders after P&R staged", { sessionId });
74016
74478
  } catch (err) {
74017
- this.deps.logger.warn("Failed to unstage VC after P&R staged", {
74479
+ this.deps.logger.warn("Failed to unstage VC reminders after P&R staged", {
74018
74480
  sessionId,
74019
74481
  error: err instanceof Error ? err.message : String(err)
74020
74482
  });
@@ -74408,6 +74870,7 @@ ${daemonResponse.additionalContext}` : cliResponse.additionalContext;
74408
74870
  hook: hookName
74409
74871
  };
74410
74872
  (0, core_1.logEvent)(logger, core_1.LogEvents.hookReceived(logContext, { cwd: hookInput.cwd, mode: "hook" }));
74873
+ logger.debug("Hook invocation received", { hook: hookName, sessionId: hookInput.sessionId });
74411
74874
  const event = buildHookEvent(hookName, hookInput, correlationId);
74412
74875
  logger.debug("Dispatching hook event to daemon", {
74413
74876
  hook: hookName,
@@ -75213,7 +75676,8 @@ var require_types4 = __commonJS({
75213
75676
  injectPersonaIntoClaude: true,
75214
75677
  defaultLlmProfile: "",
75215
75678
  llmProfiles: {},
75216
- weights: {}
75679
+ weights: {},
75680
+ persistThroughClear: true
75217
75681
  }
75218
75682
  };
75219
75683
  exports2.RESUME_MIN_CONFIDENCE = 0.7;
@@ -75288,7 +75752,7 @@ var require_persona_selection = __commonJS({
75288
75752
  }
75289
75753
  return weighted[weighted.length - 1].persona;
75290
75754
  }
75291
- async function selectPersonaForSession(sessionId, config, ctx) {
75755
+ async function selectPersonaForSession(sessionId, config, ctx, options) {
75292
75756
  const personaConfig = {
75293
75757
  ...types_js_1.DEFAULT_SESSION_SUMMARY_CONFIG.personas,
75294
75758
  ...config.personas
@@ -75327,6 +75791,38 @@ var require_persona_selection = __commonJS({
75327
75791
  availablePersonas: Array.from(allPersonas.keys())
75328
75792
  });
75329
75793
  }
75794
+ const persistThroughClear = personaConfig.persistThroughClear ?? true;
75795
+ ctx.logger.debug("Persona clear handoff check", {
75796
+ persistThroughClear,
75797
+ startType: options?.startType,
75798
+ hasClearCache: !!ctx.personaClearCache
75799
+ });
75800
+ if (persistThroughClear && options?.startType === "clear" && ctx.personaClearCache) {
75801
+ const cachedPersonaId = ctx.personaClearCache.consume();
75802
+ if (cachedPersonaId) {
75803
+ const cachedPersona = allPersonas.get(cachedPersonaId);
75804
+ if (cachedPersona) {
75805
+ const personaState2 = {
75806
+ persona_id: cachedPersona.id,
75807
+ selected_from: [cachedPersona.id],
75808
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
75809
+ };
75810
+ const summaryState2 = (0, state_js_1.createSessionSummaryState)(ctx.stateService);
75811
+ await summaryState2.sessionPersona.write(sessionId, personaState2);
75812
+ ctx.logger.info("Preserved persona through clear", {
75813
+ sessionId,
75814
+ personaId: cachedPersona.id,
75815
+ personaName: cachedPersona.display_name
75816
+ });
75817
+ return cachedPersona.id;
75818
+ } else {
75819
+ ctx.logger.warn("Cached persona from clear not found in available personas, falling back to selection", {
75820
+ sessionId,
75821
+ cachedPersonaId
75822
+ });
75823
+ }
75824
+ }
75825
+ }
75330
75826
  const allowList = parsePersonaList(personaConfig.allowList ?? "");
75331
75827
  const blockList = parsePersonaList(personaConfig.blockList ?? "");
75332
75828
  const eligiblePersonas = filterPersonas(allPersonas, allowList, blockList, ctx.logger);
@@ -75413,7 +75909,7 @@ var require_create_first_summary = __commonJS({
75413
75909
  const summaryState = (0, state_js_1.createSessionSummaryState)(ctx.stateService);
75414
75910
  await summaryState.sessionSummary.write(sessionId, placeholder);
75415
75911
  ctx.logger.info("Created placeholder session summary", { sessionId });
75416
- await (0, persona_selection_js_1.selectPersonaForSession)(sessionId, config, ctx);
75912
+ await (0, persona_selection_js_1.selectPersonaForSession)(sessionId, config, ctx, { startType });
75417
75913
  }
75418
75914
  }
75419
75915
  });
@@ -76273,10 +76769,10 @@ var require_handlers = __commonJS({
76273
76769
  id: "session-summary:init",
76274
76770
  priority: 80,
76275
76771
  filter: { kind: "hook", hooks: ["SessionStart"] },
76276
- handler: async (event) => {
76772
+ handler: async (event, context2) => {
76277
76773
  if (!(0, core_1.isHookEvent)(event) || !(0, core_1.isSessionStartEvent)(event))
76278
76774
  return;
76279
- await (0, create_first_summary_js_1.createFirstSessionSummary)(event, ctx);
76775
+ await (0, create_first_summary_js_1.createFirstSessionSummary)(event, context2);
76280
76776
  }
76281
76777
  });
76282
76778
  ctx.handlers.register({
@@ -77532,7 +78028,7 @@ var require_statusline_service = __commonJS({
77532
78028
  if (this.hookInput) {
77533
78029
  const usage = this.hookInput.context_window.current_usage;
77534
78030
  if (usage) {
77535
- effectiveTokens = usage.input_tokens + usage.cache_creation_input_tokens + usage.cache_read_input_tokens;
78031
+ effectiveTokens = usage.input_tokens + usage.output_tokens + usage.cache_creation_input_tokens + usage.cache_read_input_tokens;
77536
78032
  } else {
77537
78033
  const transcriptTokens = state.currentContextTokens;
77538
78034
  if (transcriptTokens != null && transcriptTokens > 0) {
@@ -77542,8 +78038,9 @@ var require_statusline_service = __commonJS({
77542
78038
  effectiveTokens = 0;
77543
78039
  }
77544
78040
  }
77545
- if (effectiveTokens === 0) {
77546
- effectiveTokens = baseline.systemPromptTokens + baseline.systemToolsTokens + baseline.mcpToolsTokens + baseline.customAgentsTokens + baseline.memoryFilesTokens;
78041
+ const baselineMinimum = baseline.totalOverhead - baseline.autocompactBufferTokens;
78042
+ if (effectiveTokens < baselineMinimum) {
78043
+ effectiveTokens = baselineMinimum;
77547
78044
  usingBaseline = true;
77548
78045
  }
77549
78046
  } else {
@@ -82184,7 +82681,7 @@ var require_cli = __commonJS({
82184
82681
  var promises_12 = require("node:fs/promises");
82185
82682
  var node_stream_1 = require("node:stream");
82186
82683
  var yargs_parser_1 = __importDefault2(require_build());
82187
- var VERSION = true ? "0.1.3" : "dev";
82684
+ var VERSION = true ? "0.1.5" : "dev";
82188
82685
  var SANDBOX_ERROR_MESSAGE = `Error: Daemon commands cannot run in sandbox mode.
82189
82686
 
82190
82687
  Claude Code's sandbox blocks Unix socket operations required for daemon IPC.