@scotthamilton77/sidekick 0.1.9 → 0.1.10
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 +317 -118
- package/dist/daemon.js +326 -117
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -1098,6 +1098,7 @@ var require_events = __commonJS({
|
|
|
1098
1098
|
"reminder:unstaged",
|
|
1099
1099
|
"reminder:consumed",
|
|
1100
1100
|
"reminder:cleared",
|
|
1101
|
+
"reminder:not-staged",
|
|
1101
1102
|
// Decision events
|
|
1102
1103
|
"decision:recorded",
|
|
1103
1104
|
// Session summary events
|
|
@@ -1146,6 +1147,7 @@ var require_events = __commonJS({
|
|
|
1146
1147
|
"reminder:unstaged": "timeline",
|
|
1147
1148
|
"reminder:consumed": "timeline",
|
|
1148
1149
|
"reminder:cleared": "timeline",
|
|
1150
|
+
"reminder:not-staged": "log",
|
|
1149
1151
|
"decision:recorded": "timeline",
|
|
1150
1152
|
"session-summary:start": "timeline",
|
|
1151
1153
|
"session-summary:finish": "timeline",
|
|
@@ -45865,7 +45867,10 @@ var require_structured_logging = __commonJS({
|
|
|
45865
45867
|
hookName: state.hookName,
|
|
45866
45868
|
blocking: state.blocking,
|
|
45867
45869
|
priority: state.priority,
|
|
45868
|
-
persistent: state.persistent
|
|
45870
|
+
persistent: state.persistent,
|
|
45871
|
+
...state.reason !== void 0 && { reason: state.reason },
|
|
45872
|
+
...state.triggeredBy !== void 0 && { triggeredBy: state.triggeredBy },
|
|
45873
|
+
...state.thresholdState !== void 0 && { thresholdState: state.thresholdState }
|
|
45869
45874
|
}
|
|
45870
45875
|
};
|
|
45871
45876
|
},
|
|
@@ -46162,8 +46167,8 @@ var require_structured_logging = __commonJS({
|
|
|
46162
46167
|
},
|
|
46163
46168
|
// --- Error Events ---
|
|
46164
46169
|
/**
|
|
46165
|
-
* Create
|
|
46166
|
-
*
|
|
46170
|
+
* Create a daemon ErrorOccurred event.
|
|
46171
|
+
* @see packages/sidekick-daemon/src/daemon.ts — HookableLogger error hook calls this factory.
|
|
46167
46172
|
*/
|
|
46168
46173
|
daemonErrorOccurred(context, state) {
|
|
46169
46174
|
return {
|
|
@@ -46182,6 +46187,28 @@ var require_structured_logging = __commonJS({
|
|
|
46182
46187
|
errorStack: state.errorStack
|
|
46183
46188
|
}
|
|
46184
46189
|
};
|
|
46190
|
+
},
|
|
46191
|
+
/**
|
|
46192
|
+
* Create a CLI ErrorOccurred event.
|
|
46193
|
+
* Available for CLI error hook implementations.
|
|
46194
|
+
*/
|
|
46195
|
+
cliErrorOccurred(context, state) {
|
|
46196
|
+
return {
|
|
46197
|
+
type: "error:occurred",
|
|
46198
|
+
time: Date.now(),
|
|
46199
|
+
source: "cli",
|
|
46200
|
+
context: {
|
|
46201
|
+
sessionId: context.sessionId,
|
|
46202
|
+
correlationId: context.correlationId,
|
|
46203
|
+
traceId: context.traceId,
|
|
46204
|
+
hook: context.hook,
|
|
46205
|
+
taskId: context.taskId
|
|
46206
|
+
},
|
|
46207
|
+
payload: {
|
|
46208
|
+
errorMessage: state.errorMessage,
|
|
46209
|
+
errorStack: state.errorStack
|
|
46210
|
+
}
|
|
46211
|
+
};
|
|
46185
46212
|
}
|
|
46186
46213
|
};
|
|
46187
46214
|
function logEvent(logger, event) {
|
|
@@ -58228,7 +58255,7 @@ var require_staging_service = __commonJS({
|
|
|
58228
58255
|
*
|
|
58229
58256
|
* @throws Error if hookName or reminderName contain path traversal characters
|
|
58230
58257
|
*/
|
|
58231
|
-
async stageReminder(sessionId, hookName, reminderName, data) {
|
|
58258
|
+
async stageReminder(sessionId, hookName, reminderName, data, enrichment) {
|
|
58232
58259
|
(0, staging_paths_js_1.validatePathSegment)(hookName, "hookName");
|
|
58233
58260
|
(0, staging_paths_js_1.validatePathSegment)(reminderName, "reminderName");
|
|
58234
58261
|
const hookDir = this.getHookDirPath(sessionId, hookName);
|
|
@@ -58257,7 +58284,8 @@ var require_staging_service = __commonJS({
|
|
|
58257
58284
|
hookName,
|
|
58258
58285
|
blocking: data.blocking,
|
|
58259
58286
|
priority: data.priority,
|
|
58260
|
-
persistent: data.persistent
|
|
58287
|
+
persistent: data.persistent,
|
|
58288
|
+
...enrichment
|
|
58261
58289
|
}, { stagingPath: reminderPath });
|
|
58262
58290
|
(0, structured_logging_1.logEvent)(this.options.logger, event);
|
|
58263
58291
|
}
|
|
@@ -58401,8 +58429,8 @@ var require_staging_service = __commonJS({
|
|
|
58401
58429
|
// ============================================================================
|
|
58402
58430
|
// StagingService Interface Implementation (delegates to core)
|
|
58403
58431
|
// ============================================================================
|
|
58404
|
-
async stageReminder(hookName, reminderName, data) {
|
|
58405
|
-
return this.core.stageReminder(this.sessionId, hookName, reminderName, data);
|
|
58432
|
+
async stageReminder(hookName, reminderName, data, enrichment) {
|
|
58433
|
+
return this.core.stageReminder(this.sessionId, hookName, reminderName, data, enrichment);
|
|
58406
58434
|
}
|
|
58407
58435
|
async readReminder(hookName, reminderName) {
|
|
58408
58436
|
return this.core.readReminder(this.sessionId, hookName, reminderName);
|
|
@@ -71350,8 +71378,8 @@ var require_reminder_utils = __commonJS({
|
|
|
71350
71378
|
return null;
|
|
71351
71379
|
}
|
|
71352
71380
|
}
|
|
71353
|
-
async function stageReminder(ctx, hookName, reminder) {
|
|
71354
|
-
await ctx.staging.stageReminder(hookName, reminder.name, reminder);
|
|
71381
|
+
async function stageReminder(ctx, hookName, reminder, enrichment) {
|
|
71382
|
+
await ctx.staging.stageReminder(hookName, reminder.name, reminder, enrichment);
|
|
71355
71383
|
ctx.logger.debug("Staged reminder", { hookName, reminderName: reminder.name, priority: reminder.priority });
|
|
71356
71384
|
}
|
|
71357
71385
|
async function consumeReminder(ctx, hookName) {
|
|
@@ -71897,13 +71925,125 @@ var require_stage_default_user_prompt = __commonJS({
|
|
|
71897
71925
|
}
|
|
71898
71926
|
});
|
|
71899
71927
|
|
|
71928
|
+
// ../feature-reminders/dist/events.js
|
|
71929
|
+
var require_events2 = __commonJS({
|
|
71930
|
+
"../feature-reminders/dist/events.js"(exports2) {
|
|
71931
|
+
"use strict";
|
|
71932
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
71933
|
+
exports2.ReminderEvents = void 0;
|
|
71934
|
+
exports2.ReminderEvents = {
|
|
71935
|
+
/**
|
|
71936
|
+
* Create a ReminderConsumed event (logged when CLI returns a staged reminder).
|
|
71937
|
+
*/
|
|
71938
|
+
reminderConsumed(context, state, _metadata) {
|
|
71939
|
+
return {
|
|
71940
|
+
type: "reminder:consumed",
|
|
71941
|
+
time: Date.now(),
|
|
71942
|
+
source: "cli",
|
|
71943
|
+
context: {
|
|
71944
|
+
sessionId: context.sessionId,
|
|
71945
|
+
correlationId: context.correlationId,
|
|
71946
|
+
traceId: context.traceId,
|
|
71947
|
+
hook: context.hook,
|
|
71948
|
+
taskId: context.taskId
|
|
71949
|
+
},
|
|
71950
|
+
payload: {
|
|
71951
|
+
reminderName: state.reminderName,
|
|
71952
|
+
reminderReturned: state.reminderReturned,
|
|
71953
|
+
blocking: state.blocking,
|
|
71954
|
+
priority: state.priority,
|
|
71955
|
+
persistent: state.persistent,
|
|
71956
|
+
...state.classificationResult !== void 0 && {
|
|
71957
|
+
classificationResult: state.classificationResult
|
|
71958
|
+
}
|
|
71959
|
+
}
|
|
71960
|
+
};
|
|
71961
|
+
},
|
|
71962
|
+
// Note: reminderStaged stays in @sidekick/core (used by staging-service.ts, circular dep)
|
|
71963
|
+
/**
|
|
71964
|
+
* Create a ReminderUnstaged event (logged when a reminder is removed from staging).
|
|
71965
|
+
*/
|
|
71966
|
+
reminderUnstaged(context, state) {
|
|
71967
|
+
return {
|
|
71968
|
+
type: "reminder:unstaged",
|
|
71969
|
+
time: Date.now(),
|
|
71970
|
+
source: "daemon",
|
|
71971
|
+
context: {
|
|
71972
|
+
sessionId: context.sessionId,
|
|
71973
|
+
correlationId: context.correlationId,
|
|
71974
|
+
traceId: context.traceId,
|
|
71975
|
+
hook: context.hook,
|
|
71976
|
+
taskId: context.taskId
|
|
71977
|
+
},
|
|
71978
|
+
payload: {
|
|
71979
|
+
reminderName: state.reminderName,
|
|
71980
|
+
hookName: state.hookName,
|
|
71981
|
+
reason: state.reason,
|
|
71982
|
+
...state.triggeredBy !== void 0 && { triggeredBy: state.triggeredBy },
|
|
71983
|
+
...state.toolState !== void 0 && { toolState: state.toolState }
|
|
71984
|
+
}
|
|
71985
|
+
};
|
|
71986
|
+
},
|
|
71987
|
+
/**
|
|
71988
|
+
* Create a RemindersCleared event (logged when staging directory is cleaned).
|
|
71989
|
+
*/
|
|
71990
|
+
remindersCleared(context, state, reason) {
|
|
71991
|
+
return {
|
|
71992
|
+
type: "reminder:cleared",
|
|
71993
|
+
time: Date.now(),
|
|
71994
|
+
source: "daemon",
|
|
71995
|
+
context: {
|
|
71996
|
+
sessionId: context.sessionId,
|
|
71997
|
+
correlationId: context.correlationId,
|
|
71998
|
+
traceId: context.traceId,
|
|
71999
|
+
hook: context.hook,
|
|
72000
|
+
taskId: context.taskId
|
|
72001
|
+
},
|
|
72002
|
+
payload: {
|
|
72003
|
+
clearedCount: state.clearedCount,
|
|
72004
|
+
hookNames: state.hookNames,
|
|
72005
|
+
reason
|
|
72006
|
+
}
|
|
72007
|
+
};
|
|
72008
|
+
},
|
|
72009
|
+
/**
|
|
72010
|
+
* Create a ReminderNotStaged event (logged when daemon evaluates but decides not to stage).
|
|
72011
|
+
*/
|
|
72012
|
+
reminderNotStaged(context, state) {
|
|
72013
|
+
return {
|
|
72014
|
+
type: "reminder:not-staged",
|
|
72015
|
+
time: Date.now(),
|
|
72016
|
+
source: "daemon",
|
|
72017
|
+
context: {
|
|
72018
|
+
sessionId: context.sessionId,
|
|
72019
|
+
correlationId: context.correlationId,
|
|
72020
|
+
traceId: context.traceId,
|
|
72021
|
+
hook: context.hook,
|
|
72022
|
+
taskId: context.taskId
|
|
72023
|
+
},
|
|
72024
|
+
payload: {
|
|
72025
|
+
reminderName: state.reminderName,
|
|
72026
|
+
hookName: state.hookName,
|
|
72027
|
+
reason: state.reason,
|
|
72028
|
+
...state.threshold !== void 0 && { threshold: state.threshold },
|
|
72029
|
+
...state.currentValue !== void 0 && { currentValue: state.currentValue },
|
|
72030
|
+
...state.triggeredBy !== void 0 && { triggeredBy: state.triggeredBy }
|
|
72031
|
+
}
|
|
72032
|
+
};
|
|
72033
|
+
}
|
|
72034
|
+
};
|
|
72035
|
+
}
|
|
72036
|
+
});
|
|
72037
|
+
|
|
71900
72038
|
// ../feature-reminders/dist/handlers/staging/stage-pause-and-reflect.js
|
|
71901
72039
|
var require_stage_pause_and_reflect = __commonJS({
|
|
71902
72040
|
"../feature-reminders/dist/handlers/staging/stage-pause-and-reflect.js"(exports2) {
|
|
71903
72041
|
"use strict";
|
|
71904
72042
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
71905
72043
|
exports2.registerStagePauseAndReflect = registerStagePauseAndReflect;
|
|
72044
|
+
var core_1 = require_dist4();
|
|
71906
72045
|
var types_1 = require_dist();
|
|
72046
|
+
var events_js_1 = require_events2();
|
|
71907
72047
|
var staging_handler_utils_js_1 = require_staging_handler_utils();
|
|
71908
72048
|
var types_js_1 = require_types2();
|
|
71909
72049
|
var state_js_1 = require_state4();
|
|
@@ -71917,15 +72057,17 @@ var require_stage_pause_and_reflect = __commonJS({
|
|
|
71917
72057
|
return void 0;
|
|
71918
72058
|
const metrics = event.metadata.metrics;
|
|
71919
72059
|
const sessionId = event.context?.sessionId;
|
|
72060
|
+
if (!sessionId) {
|
|
72061
|
+
ctx.logger.warn("[stage-pause-and-reflect] No sessionId available, skipping");
|
|
72062
|
+
return void 0;
|
|
72063
|
+
}
|
|
71920
72064
|
const featureConfig = context.config.getFeature("reminders");
|
|
71921
72065
|
const config = { ...types_js_1.DEFAULT_REMINDERS_SETTINGS, ...featureConfig.settings };
|
|
71922
72066
|
let prBaseline = null;
|
|
71923
|
-
|
|
71924
|
-
|
|
71925
|
-
|
|
71926
|
-
|
|
71927
|
-
prBaseline = result.data;
|
|
71928
|
-
}
|
|
72067
|
+
const remindersState = (0, state_js_1.createRemindersState)(ctx.stateService);
|
|
72068
|
+
const result = await remindersState.prBaseline.read(sessionId);
|
|
72069
|
+
if (result.source !== "default") {
|
|
72070
|
+
prBaseline = result.data;
|
|
71929
72071
|
}
|
|
71930
72072
|
let effectiveBaseline = 0;
|
|
71931
72073
|
if (prBaseline && prBaseline.turnCount === metrics.turnCount) {
|
|
@@ -71937,12 +72079,28 @@ var require_stage_pause_and_reflect = __commonJS({
|
|
|
71937
72079
|
effectiveBaseline = Math.max(effectiveBaseline, lastConsumed.stagedAt.toolsThisTurn);
|
|
71938
72080
|
}
|
|
71939
72081
|
const shouldReactivate = metrics.turnCount > lastConsumed.stagedAt.turnCount || metrics.toolsThisTurn >= effectiveBaseline + config.pause_and_reflect_threshold;
|
|
71940
|
-
if (!shouldReactivate)
|
|
72082
|
+
if (!shouldReactivate) {
|
|
72083
|
+
(0, core_1.logEvent)(ctx.logger, events_js_1.ReminderEvents.reminderNotStaged({ sessionId }, {
|
|
72084
|
+
reminderName: "pause-and-reflect",
|
|
72085
|
+
hookName: "PreToolUse",
|
|
72086
|
+
reason: "same_turn",
|
|
72087
|
+
triggeredBy: "tool_result"
|
|
72088
|
+
}));
|
|
71941
72089
|
return void 0;
|
|
72090
|
+
}
|
|
71942
72091
|
}
|
|
71943
72092
|
const toolsSinceBaseline = metrics.toolsThisTurn - effectiveBaseline;
|
|
71944
|
-
if (toolsSinceBaseline < config.pause_and_reflect_threshold)
|
|
72093
|
+
if (toolsSinceBaseline < config.pause_and_reflect_threshold) {
|
|
72094
|
+
(0, core_1.logEvent)(ctx.logger, events_js_1.ReminderEvents.reminderNotStaged({ sessionId }, {
|
|
72095
|
+
reminderName: "pause-and-reflect",
|
|
72096
|
+
hookName: "PreToolUse",
|
|
72097
|
+
reason: "below_threshold",
|
|
72098
|
+
threshold: config.pause_and_reflect_threshold,
|
|
72099
|
+
currentValue: toolsSinceBaseline,
|
|
72100
|
+
triggeredBy: "tool_result"
|
|
72101
|
+
}));
|
|
71945
72102
|
return void 0;
|
|
72103
|
+
}
|
|
71946
72104
|
return {
|
|
71947
72105
|
reminderId: types_js_1.ReminderIds.PAUSE_AND_REFLECT,
|
|
71948
72106
|
targetHook: "PreToolUse",
|
|
@@ -73472,86 +73630,6 @@ var require_picomatch2 = __commonJS({
|
|
|
73472
73630
|
}
|
|
73473
73631
|
});
|
|
73474
73632
|
|
|
73475
|
-
// ../feature-reminders/dist/events.js
|
|
73476
|
-
var require_events2 = __commonJS({
|
|
73477
|
-
"../feature-reminders/dist/events.js"(exports2) {
|
|
73478
|
-
"use strict";
|
|
73479
|
-
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
73480
|
-
exports2.ReminderEvents = void 0;
|
|
73481
|
-
exports2.ReminderEvents = {
|
|
73482
|
-
/**
|
|
73483
|
-
* Create a ReminderConsumed event (logged when CLI returns a staged reminder).
|
|
73484
|
-
*/
|
|
73485
|
-
reminderConsumed(context, state, _metadata) {
|
|
73486
|
-
return {
|
|
73487
|
-
type: "reminder:consumed",
|
|
73488
|
-
time: Date.now(),
|
|
73489
|
-
source: "cli",
|
|
73490
|
-
context: {
|
|
73491
|
-
sessionId: context.sessionId,
|
|
73492
|
-
correlationId: context.correlationId,
|
|
73493
|
-
traceId: context.traceId,
|
|
73494
|
-
hook: context.hook,
|
|
73495
|
-
taskId: context.taskId
|
|
73496
|
-
},
|
|
73497
|
-
payload: {
|
|
73498
|
-
reminderName: state.reminderName,
|
|
73499
|
-
reminderReturned: state.reminderReturned,
|
|
73500
|
-
blocking: state.blocking,
|
|
73501
|
-
priority: state.priority,
|
|
73502
|
-
persistent: state.persistent
|
|
73503
|
-
}
|
|
73504
|
-
};
|
|
73505
|
-
},
|
|
73506
|
-
// Note: reminderStaged stays in @sidekick/core (used by staging-service.ts, circular dep)
|
|
73507
|
-
/**
|
|
73508
|
-
* Create a ReminderUnstaged event (logged when a reminder is removed from staging).
|
|
73509
|
-
*/
|
|
73510
|
-
reminderUnstaged(context, state) {
|
|
73511
|
-
return {
|
|
73512
|
-
type: "reminder:unstaged",
|
|
73513
|
-
time: Date.now(),
|
|
73514
|
-
source: "daemon",
|
|
73515
|
-
context: {
|
|
73516
|
-
sessionId: context.sessionId,
|
|
73517
|
-
correlationId: context.correlationId,
|
|
73518
|
-
traceId: context.traceId,
|
|
73519
|
-
hook: context.hook,
|
|
73520
|
-
taskId: context.taskId
|
|
73521
|
-
},
|
|
73522
|
-
payload: {
|
|
73523
|
-
reminderName: state.reminderName,
|
|
73524
|
-
hookName: state.hookName,
|
|
73525
|
-
reason: state.reason
|
|
73526
|
-
}
|
|
73527
|
-
};
|
|
73528
|
-
},
|
|
73529
|
-
/**
|
|
73530
|
-
* Create a RemindersCleared event (logged when staging directory is cleaned).
|
|
73531
|
-
*/
|
|
73532
|
-
remindersCleared(context, state, reason) {
|
|
73533
|
-
return {
|
|
73534
|
-
type: "reminder:cleared",
|
|
73535
|
-
time: Date.now(),
|
|
73536
|
-
source: "daemon",
|
|
73537
|
-
context: {
|
|
73538
|
-
sessionId: context.sessionId,
|
|
73539
|
-
correlationId: context.correlationId,
|
|
73540
|
-
traceId: context.traceId,
|
|
73541
|
-
hook: context.hook,
|
|
73542
|
-
taskId: context.taskId
|
|
73543
|
-
},
|
|
73544
|
-
payload: {
|
|
73545
|
-
clearedCount: state.clearedCount,
|
|
73546
|
-
hookNames: state.hookNames,
|
|
73547
|
-
reason
|
|
73548
|
-
}
|
|
73549
|
-
};
|
|
73550
|
-
}
|
|
73551
|
-
};
|
|
73552
|
-
}
|
|
73553
|
-
});
|
|
73554
|
-
|
|
73555
73633
|
// ../feature-reminders/dist/tool-pattern-matcher.js
|
|
73556
73634
|
var require_tool_pattern_matcher = __commonJS({
|
|
73557
73635
|
"../feature-reminders/dist/tool-pattern-matcher.js"(exports2) {
|
|
@@ -73659,22 +73737,48 @@ var require_track_verification_tools = __commonJS({
|
|
|
73659
73737
|
}
|
|
73660
73738
|
});
|
|
73661
73739
|
}
|
|
73662
|
-
async function stageToolsForFiles(filePaths, daemonCtx, sessionId, verificationTools, toolsState, remindersState) {
|
|
73740
|
+
async function stageToolsForFiles(filePaths, daemonCtx, sessionId, verificationTools, toolsState, remindersState, triggeredBy = "file_edit") {
|
|
73663
73741
|
const existingReminders = await daemonCtx.staging.listReminders("Stop");
|
|
73664
73742
|
const stagedNames = new Set(existingReminders.map((r) => r.name));
|
|
73665
73743
|
let anyStaged = false;
|
|
73744
|
+
const emittedNotStaged = /* @__PURE__ */ new Set();
|
|
73666
73745
|
for (const filePath of filePaths) {
|
|
73667
73746
|
for (const [toolName, toolConfig] of Object.entries(verificationTools)) {
|
|
73668
|
-
if (!toolConfig.enabled)
|
|
73669
|
-
continue;
|
|
73670
73747
|
const reminderId = TOOL_REMINDER_MAP[toolName];
|
|
73671
73748
|
if (!reminderId)
|
|
73672
73749
|
continue;
|
|
73673
|
-
if (!
|
|
73750
|
+
if (!toolConfig.enabled) {
|
|
73751
|
+
const emitKey = `${reminderId}:feature_disabled`;
|
|
73752
|
+
if (!emittedNotStaged.has(emitKey)) {
|
|
73753
|
+
emittedNotStaged.add(emitKey);
|
|
73754
|
+
(0, core_1.logEvent)(daemonCtx.logger, events_js_1.ReminderEvents.reminderNotStaged({ sessionId }, {
|
|
73755
|
+
reminderName: reminderId,
|
|
73756
|
+
hookName: "Stop",
|
|
73757
|
+
reason: "feature_disabled",
|
|
73758
|
+
triggeredBy
|
|
73759
|
+
}));
|
|
73760
|
+
}
|
|
73674
73761
|
continue;
|
|
73762
|
+
}
|
|
73763
|
+
if (!picomatch_1.default.isMatch(filePath, toolConfig.clearing_patterns)) {
|
|
73764
|
+
const emitKey = `${reminderId}:pattern_mismatch`;
|
|
73765
|
+
if (!emittedNotStaged.has(emitKey)) {
|
|
73766
|
+
emittedNotStaged.add(emitKey);
|
|
73767
|
+
(0, core_1.logEvent)(daemonCtx.logger, events_js_1.ReminderEvents.reminderNotStaged({ sessionId }, {
|
|
73768
|
+
reminderName: reminderId,
|
|
73769
|
+
hookName: "Stop",
|
|
73770
|
+
reason: "pattern_mismatch",
|
|
73771
|
+
triggeredBy
|
|
73772
|
+
}));
|
|
73773
|
+
}
|
|
73774
|
+
continue;
|
|
73775
|
+
}
|
|
73675
73776
|
const current = toolsState[toolName];
|
|
73676
73777
|
if (!current || current.status === "staged") {
|
|
73677
|
-
const staged = await ensureToolReminderStaged(daemonCtx, reminderId, stagedNames
|
|
73778
|
+
const staged = await ensureToolReminderStaged(daemonCtx, reminderId, stagedNames, {
|
|
73779
|
+
reason: current ? "re-staged" : "initial",
|
|
73780
|
+
triggeredBy: "file_edit"
|
|
73781
|
+
});
|
|
73678
73782
|
if (staged) {
|
|
73679
73783
|
if (!current) {
|
|
73680
73784
|
toolsState[toolName] = {
|
|
@@ -73690,7 +73794,11 @@ var require_track_verification_tools = __commonJS({
|
|
|
73690
73794
|
} else {
|
|
73691
73795
|
const newEdits = current.editsSinceVerified + 1;
|
|
73692
73796
|
if (newEdits >= toolConfig.clearing_threshold) {
|
|
73693
|
-
const staged = await ensureToolReminderStaged(daemonCtx, reminderId, stagedNames
|
|
73797
|
+
const staged = await ensureToolReminderStaged(daemonCtx, reminderId, stagedNames, {
|
|
73798
|
+
reason: "threshold_reached",
|
|
73799
|
+
triggeredBy: "file_edit",
|
|
73800
|
+
thresholdState: { current: newEdits, threshold: toolConfig.clearing_threshold }
|
|
73801
|
+
});
|
|
73694
73802
|
if (staged) {
|
|
73695
73803
|
toolsState[toolName] = {
|
|
73696
73804
|
...current,
|
|
@@ -73707,6 +73815,14 @@ var require_track_verification_tools = __commonJS({
|
|
|
73707
73815
|
status: "cooldown",
|
|
73708
73816
|
editsSinceVerified: newEdits
|
|
73709
73817
|
};
|
|
73818
|
+
(0, core_1.logEvent)(daemonCtx.logger, events_js_1.ReminderEvents.reminderNotStaged({ sessionId }, {
|
|
73819
|
+
reminderName: reminderId,
|
|
73820
|
+
hookName: "Stop",
|
|
73821
|
+
reason: "below_threshold",
|
|
73822
|
+
threshold: toolConfig.clearing_threshold,
|
|
73823
|
+
currentValue: newEdits,
|
|
73824
|
+
triggeredBy
|
|
73825
|
+
}));
|
|
73710
73826
|
}
|
|
73711
73827
|
}
|
|
73712
73828
|
}
|
|
@@ -73752,7 +73868,16 @@ var require_track_verification_tools = __commonJS({
|
|
|
73752
73868
|
lastMatchedScope: match.scope
|
|
73753
73869
|
};
|
|
73754
73870
|
await daemonCtx.staging.deleteReminder("Stop", reminderId);
|
|
73755
|
-
(0, core_1.logEvent)(daemonCtx.logger, events_js_1.ReminderEvents.reminderUnstaged({ sessionId }, {
|
|
73871
|
+
(0, core_1.logEvent)(daemonCtx.logger, events_js_1.ReminderEvents.reminderUnstaged({ sessionId }, {
|
|
73872
|
+
reminderName: reminderId,
|
|
73873
|
+
hookName: "Stop",
|
|
73874
|
+
reason: "tool_verified",
|
|
73875
|
+
triggeredBy: "verification_passed",
|
|
73876
|
+
toolState: {
|
|
73877
|
+
status: toolsState[toolName].status,
|
|
73878
|
+
editsSinceVerified: toolsState[toolName].editsSinceVerified
|
|
73879
|
+
}
|
|
73880
|
+
}));
|
|
73756
73881
|
anyUnstaged = true;
|
|
73757
73882
|
daemonCtx.logger.debug("VC tool verified", {
|
|
73758
73883
|
toolName,
|
|
@@ -73767,13 +73892,18 @@ var require_track_verification_tools = __commonJS({
|
|
|
73767
73892
|
const hasPerToolReminders = remaining.some((r) => VC_TOOL_NAME_SET.has(r.name));
|
|
73768
73893
|
if (!hasPerToolReminders) {
|
|
73769
73894
|
await daemonCtx.staging.deleteReminder("Stop", types_js_1.ReminderIds.VERIFY_COMPLETION);
|
|
73770
|
-
(0, core_1.logEvent)(daemonCtx.logger, events_js_1.ReminderEvents.reminderUnstaged({ sessionId }, {
|
|
73895
|
+
(0, core_1.logEvent)(daemonCtx.logger, events_js_1.ReminderEvents.reminderUnstaged({ sessionId }, {
|
|
73896
|
+
reminderName: types_js_1.ReminderIds.VERIFY_COMPLETION,
|
|
73897
|
+
hookName: "Stop",
|
|
73898
|
+
reason: "all_tools_verified",
|
|
73899
|
+
triggeredBy: "verification_passed"
|
|
73900
|
+
}));
|
|
73771
73901
|
daemonCtx.logger.info("All VC tools verified, unstaged wrapper", { sessionId });
|
|
73772
73902
|
}
|
|
73773
73903
|
await remindersState.verificationTools.write(sessionId, toolsState);
|
|
73774
73904
|
}
|
|
73775
73905
|
}
|
|
73776
|
-
async function ensureToolReminderStaged(daemonCtx, reminderId, stagedNames) {
|
|
73906
|
+
async function ensureToolReminderStaged(daemonCtx, reminderId, stagedNames, enrichment) {
|
|
73777
73907
|
if (stagedNames.has(reminderId))
|
|
73778
73908
|
return true;
|
|
73779
73909
|
const reminder = (0, reminder_utils_js_1.resolveReminder)(reminderId, {
|
|
@@ -73787,7 +73917,7 @@ var require_track_verification_tools = __commonJS({
|
|
|
73787
73917
|
await (0, reminder_utils_js_1.stageReminder)(daemonCtx, "Stop", {
|
|
73788
73918
|
...reminder,
|
|
73789
73919
|
stagedAt: { timestamp: Date.now(), turnCount: 0, toolsThisTurn: 0, toolCount: 0 }
|
|
73790
|
-
});
|
|
73920
|
+
}, enrichment);
|
|
73791
73921
|
return true;
|
|
73792
73922
|
}
|
|
73793
73923
|
}
|
|
@@ -73803,6 +73933,7 @@ var require_stage_stop_bash_changes = __commonJS({
|
|
|
73803
73933
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
73804
73934
|
exports2.registerStageBashChanges = registerStageBashChanges;
|
|
73805
73935
|
var core_1 = require_dist4();
|
|
73936
|
+
var events_js_1 = require_events2();
|
|
73806
73937
|
var types_1 = require_dist();
|
|
73807
73938
|
var picomatch_1 = __importDefault2(require_picomatch2());
|
|
73808
73939
|
var track_verification_tools_js_1 = require_track_verification_tools();
|
|
@@ -73872,6 +74003,12 @@ var require_stage_stop_bash_changes = __commonJS({
|
|
|
73872
74003
|
if (lastConsumed?.stagedAt) {
|
|
73873
74004
|
const shouldReactivate = metrics.turnCount > lastConsumed.stagedAt.turnCount;
|
|
73874
74005
|
if (!shouldReactivate) {
|
|
74006
|
+
(0, core_1.logEvent)(daemonCtx.logger, events_js_1.ReminderEvents.reminderNotStaged({ sessionId }, {
|
|
74007
|
+
reminderName: "verify-completion",
|
|
74008
|
+
hookName: "Stop",
|
|
74009
|
+
reason: "same_turn",
|
|
74010
|
+
triggeredBy: "bash_command"
|
|
74011
|
+
}));
|
|
73875
74012
|
daemonCtx.logger.debug("Bash VC: skipped (already consumed this turn)", {
|
|
73876
74013
|
currentTurn: metrics.turnCount,
|
|
73877
74014
|
lastConsumedTurn: lastConsumed.stagedAt.turnCount
|
|
@@ -73887,12 +74024,25 @@ var require_stage_stop_bash_changes = __commonJS({
|
|
|
73887
74024
|
currentCount: current.length,
|
|
73888
74025
|
newFileCount: newFiles.length
|
|
73889
74026
|
});
|
|
73890
|
-
if (newFiles.length === 0)
|
|
74027
|
+
if (newFiles.length === 0) {
|
|
74028
|
+
(0, core_1.logEvent)(daemonCtx.logger, events_js_1.ReminderEvents.reminderNotStaged({ sessionId }, {
|
|
74029
|
+
reminderName: "verify-completion",
|
|
74030
|
+
hookName: "Stop",
|
|
74031
|
+
reason: "no_changes_detected",
|
|
74032
|
+
triggeredBy: "bash_command"
|
|
74033
|
+
}));
|
|
73891
74034
|
return;
|
|
74035
|
+
}
|
|
73892
74036
|
const featureConfig = context.config.getFeature("reminders");
|
|
73893
74037
|
const config = { ...types_js_1.DEFAULT_REMINDERS_SETTINGS, ...featureConfig.settings };
|
|
73894
74038
|
const sourceMatches = newFiles.filter((f) => picomatch_1.default.isMatch(f, config.source_code_patterns));
|
|
73895
74039
|
if (sourceMatches.length === 0) {
|
|
74040
|
+
(0, core_1.logEvent)(daemonCtx.logger, events_js_1.ReminderEvents.reminderNotStaged({ sessionId }, {
|
|
74041
|
+
reminderName: "verify-completion",
|
|
74042
|
+
hookName: "Stop",
|
|
74043
|
+
reason: "pattern_mismatch",
|
|
74044
|
+
triggeredBy: "bash_command"
|
|
74045
|
+
}));
|
|
73896
74046
|
daemonCtx.logger.debug("Bash VC: new files found but no source code matches", { newFiles });
|
|
73897
74047
|
return;
|
|
73898
74048
|
}
|
|
@@ -73906,7 +74056,7 @@ var require_stage_stop_bash_changes = __commonJS({
|
|
|
73906
74056
|
const remindersState = (0, state_js_1.createRemindersState)(daemonCtx.stateService);
|
|
73907
74057
|
const stateResult = await remindersState.verificationTools.read(sessionId);
|
|
73908
74058
|
const toolsState = { ...stateResult.data };
|
|
73909
|
-
await (0, track_verification_tools_js_1.stageToolsForFiles)(sourceMatches, daemonCtx, sessionId, verificationTools, toolsState, remindersState);
|
|
74059
|
+
await (0, track_verification_tools_js_1.stageToolsForFiles)(sourceMatches, daemonCtx, sessionId, verificationTools, toolsState, remindersState, "bash_command");
|
|
73910
74060
|
}
|
|
73911
74061
|
});
|
|
73912
74062
|
}
|
|
@@ -74019,6 +74169,11 @@ var require_unstage_verify_completion = __commonJS({
|
|
|
74019
74169
|
await remindersState.vcUnverified.delete(sessionId);
|
|
74020
74170
|
}
|
|
74021
74171
|
} else {
|
|
74172
|
+
(0, core_1.logEvent)(daemonCtx.logger, events_js_1.ReminderEvents.reminderNotStaged({ sessionId }, {
|
|
74173
|
+
reminderName: "verify-completion",
|
|
74174
|
+
hookName: "Stop",
|
|
74175
|
+
reason: "no_unverified_changes"
|
|
74176
|
+
}));
|
|
74022
74177
|
daemonCtx.logger.info("VC unstage: no unverified changes, clearing reminder", {
|
|
74023
74178
|
sessionId,
|
|
74024
74179
|
hadState: unverifiedState !== null
|
|
@@ -74028,7 +74183,12 @@ var require_unstage_verify_completion = __commonJS({
|
|
|
74028
74183
|
const reason = unverifiedState?.hasUnverifiedChanges ? "cycle_limit_reached" : "no_unverified_changes";
|
|
74029
74184
|
for (const vcId of types_js_1.ALL_VC_REMINDER_IDS) {
|
|
74030
74185
|
await daemonCtx.staging.deleteReminder("Stop", vcId);
|
|
74031
|
-
(0, core_1.logEvent)(daemonCtx.logger, events_js_1.ReminderEvents.reminderUnstaged(eventContext, {
|
|
74186
|
+
(0, core_1.logEvent)(daemonCtx.logger, events_js_1.ReminderEvents.reminderUnstaged(eventContext, {
|
|
74187
|
+
reminderName: vcId,
|
|
74188
|
+
hookName: "Stop",
|
|
74189
|
+
reason,
|
|
74190
|
+
triggeredBy: unverifiedState?.hasUnverifiedChanges ? "cycle_limit" : "no_unverified_changes"
|
|
74191
|
+
}));
|
|
74032
74192
|
}
|
|
74033
74193
|
daemonCtx.logger.debug("VC unstage: deleted all VC reminders");
|
|
74034
74194
|
}
|
|
@@ -74126,12 +74286,22 @@ var require_stage_persona_reminders = __commonJS({
|
|
|
74126
74286
|
}
|
|
74127
74287
|
async function stagePersonaRemindersForSession(ctx, sessionId, options) {
|
|
74128
74288
|
if (!isPersonaInjectionEnabled(ctx)) {
|
|
74289
|
+
(0, core_1.logEvent)(ctx.logger, events_js_1.ReminderEvents.reminderNotStaged({ sessionId }, {
|
|
74290
|
+
reminderName: "remember-your-persona",
|
|
74291
|
+
hookName: "PreToolUse",
|
|
74292
|
+
reason: "feature_disabled"
|
|
74293
|
+
}));
|
|
74129
74294
|
await clearPersonaReminders(ctx, sessionId);
|
|
74130
74295
|
ctx.logger.debug("Persona injection disabled by config, cleaned up reminders", { sessionId });
|
|
74131
74296
|
return;
|
|
74132
74297
|
}
|
|
74133
74298
|
const persona = await loadPersonaForSession(ctx, sessionId);
|
|
74134
74299
|
if (!persona) {
|
|
74300
|
+
(0, core_1.logEvent)(ctx.logger, events_js_1.ReminderEvents.reminderNotStaged({ sessionId }, {
|
|
74301
|
+
reminderName: "remember-your-persona",
|
|
74302
|
+
hookName: "PreToolUse",
|
|
74303
|
+
reason: "no_persona"
|
|
74304
|
+
}));
|
|
74135
74305
|
await clearPersonaReminders(ctx, sessionId);
|
|
74136
74306
|
ctx.logger.debug("Persona cleared or disabled, unstaged persona reminders", { sessionId });
|
|
74137
74307
|
return;
|
|
@@ -74431,7 +74601,19 @@ var require_consumption_handler_factory = __commonJS({
|
|
|
74431
74601
|
reader.renameReminder(hook, reminder.name);
|
|
74432
74602
|
}
|
|
74433
74603
|
}
|
|
74434
|
-
let
|
|
74604
|
+
let enrichment;
|
|
74605
|
+
let response;
|
|
74606
|
+
if (buildResponse) {
|
|
74607
|
+
const result = await buildResponse({ reminder: primary, reader, cliCtx, sessionId, event, supportsBlocking });
|
|
74608
|
+
if ("response" in result && typeof result.response === "object") {
|
|
74609
|
+
response = result.response;
|
|
74610
|
+
enrichment = result.enrichment;
|
|
74611
|
+
} else {
|
|
74612
|
+
response = result;
|
|
74613
|
+
}
|
|
74614
|
+
} else {
|
|
74615
|
+
response = buildDefaultResponse(primary, supportsBlocking);
|
|
74616
|
+
}
|
|
74435
74617
|
const secondaryContexts = reminders.slice(1).map((r) => r.additionalContext).filter((ctx2) => !!ctx2);
|
|
74436
74618
|
if (secondaryContexts.length > 0) {
|
|
74437
74619
|
const existing = response.additionalContext;
|
|
@@ -74449,7 +74631,8 @@ var require_consumption_handler_factory = __commonJS({
|
|
|
74449
74631
|
reminderReturned: true,
|
|
74450
74632
|
blocking: response.blocking ?? false,
|
|
74451
74633
|
priority: primary.priority,
|
|
74452
|
-
persistent: primary.persistent
|
|
74634
|
+
persistent: primary.persistent,
|
|
74635
|
+
...enrichment
|
|
74453
74636
|
}));
|
|
74454
74637
|
return { response };
|
|
74455
74638
|
}
|
|
@@ -74551,6 +74734,13 @@ var require_inject_stop = __commonJS({
|
|
|
74551
74734
|
shouldBlock: classification.shouldBlock,
|
|
74552
74735
|
reasoning: classification.reasoning?.slice(0, 200)
|
|
74553
74736
|
});
|
|
74737
|
+
const classificationEnrichment = {
|
|
74738
|
+
classificationResult: {
|
|
74739
|
+
category: classification.category,
|
|
74740
|
+
confidence: classification.confidence,
|
|
74741
|
+
shouldBlock: classification.shouldBlock
|
|
74742
|
+
}
|
|
74743
|
+
};
|
|
74554
74744
|
if (classification.shouldBlock) {
|
|
74555
74745
|
cliCtx.logger.info("VC inject-stop: BLOCKING (claiming completion)", { sessionId });
|
|
74556
74746
|
try {
|
|
@@ -74560,7 +74750,10 @@ var require_inject_stop = __commonJS({
|
|
|
74560
74750
|
error: String(clearErr)
|
|
74561
74751
|
});
|
|
74562
74752
|
}
|
|
74563
|
-
return
|
|
74753
|
+
return {
|
|
74754
|
+
response: (0, consumption_handler_factory_js_1.buildDefaultResponse)(reminder, supportsBlocking),
|
|
74755
|
+
enrichment: classificationEnrichment
|
|
74756
|
+
};
|
|
74564
74757
|
} else {
|
|
74565
74758
|
cliCtx.logger.info("VC inject-stop: NOT BLOCKING", {
|
|
74566
74759
|
sessionId,
|
|
@@ -74586,13 +74779,13 @@ var require_inject_stop = __commonJS({
|
|
|
74586
74779
|
});
|
|
74587
74780
|
}
|
|
74588
74781
|
if (classification.category === "ASKING_QUESTION" || classification.category === "ANSWERING_QUESTION") {
|
|
74589
|
-
return {};
|
|
74782
|
+
return { response: {}, enrichment: classificationEnrichment };
|
|
74590
74783
|
} else {
|
|
74591
74784
|
const response = {};
|
|
74592
74785
|
if (classification.userMessage) {
|
|
74593
74786
|
response.userMessage = classification.userMessage;
|
|
74594
74787
|
}
|
|
74595
|
-
return response;
|
|
74788
|
+
return { response, enrichment: classificationEnrichment };
|
|
74596
74789
|
}
|
|
74597
74790
|
}
|
|
74598
74791
|
} catch (err) {
|
|
@@ -74963,7 +75156,8 @@ var require_orchestrator = __commonJS({
|
|
|
74963
75156
|
(0, core_1.logEvent)(this.deps.logger, events_js_1.ReminderEvents.reminderUnstaged(eventContext, {
|
|
74964
75157
|
reminderName: vcId,
|
|
74965
75158
|
hookName: "Stop",
|
|
74966
|
-
reason: "pause_and_reflect_cascade"
|
|
75159
|
+
reason: "pause_and_reflect_cascade",
|
|
75160
|
+
triggeredBy: "cascade_from_pause_and_reflect"
|
|
74967
75161
|
}));
|
|
74968
75162
|
}
|
|
74969
75163
|
this.deps.logger.debug("Unstaged all VC reminders after P&R staged", { sessionId });
|
|
@@ -75000,7 +75194,12 @@ var require_orchestrator = __commonJS({
|
|
|
75000
75194
|
try {
|
|
75001
75195
|
const staging = this.deps.getStagingService(sessionId);
|
|
75002
75196
|
await staging.deleteReminder("PreToolUse", types_js_1.ReminderIds.PAUSE_AND_REFLECT);
|
|
75003
|
-
(0, core_1.logEvent)(this.deps.logger, events_js_1.ReminderEvents.reminderUnstaged({ sessionId }, {
|
|
75197
|
+
(0, core_1.logEvent)(this.deps.logger, events_js_1.ReminderEvents.reminderUnstaged({ sessionId }, {
|
|
75198
|
+
reminderName: types_js_1.ReminderIds.PAUSE_AND_REFLECT,
|
|
75199
|
+
hookName: "PreToolUse",
|
|
75200
|
+
reason: "vc_consumed_cascade",
|
|
75201
|
+
triggeredBy: "cascade_from_verify_completion"
|
|
75202
|
+
}));
|
|
75004
75203
|
this.deps.logger.debug("Unstaged P&R after VC consumed", { sessionId });
|
|
75005
75204
|
} catch (err) {
|
|
75006
75205
|
this.deps.logger.warn("Failed to unstage P&R after VC consumed", {
|
|
@@ -83540,7 +83739,7 @@ var require_cli = __commonJS({
|
|
|
83540
83739
|
var promises_12 = require("node:fs/promises");
|
|
83541
83740
|
var node_stream_1 = require("node:stream");
|
|
83542
83741
|
var yargs_parser_1 = __importDefault2(require_build());
|
|
83543
|
-
var VERSION = true ? "0.1.
|
|
83742
|
+
var VERSION = true ? "0.1.10" : "dev";
|
|
83544
83743
|
var SANDBOX_ERROR_MESSAGE = `Error: Daemon commands cannot run in sandbox mode.
|
|
83545
83744
|
|
|
83546
83745
|
Claude Code's sandbox blocks Unix socket operations required for daemon IPC.
|