@scotthamilton77/sidekick 0.1.14 → 0.1.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin.js
CHANGED
|
@@ -1030,7 +1030,7 @@ var require_events = __commonJS({
|
|
|
1030
1030
|
"../types/dist/events.js"(exports2) {
|
|
1031
1031
|
"use strict";
|
|
1032
1032
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
1033
|
-
exports2.UI_EVENT_VISIBILITY = exports2.UI_EVENT_TYPES = exports2.HOOK_NAMES = void 0;
|
|
1033
|
+
exports2.UI_EVENT_VISIBILITY = exports2.DecisionEvents = exports2.UI_EVENT_TYPES = exports2.HOOK_NAMES = void 0;
|
|
1034
1034
|
exports2.isHookEvent = isHookEvent;
|
|
1035
1035
|
exports2.isTranscriptEvent = isTranscriptEvent;
|
|
1036
1036
|
exports2.isSessionStartEvent = isSessionStartEvent;
|
|
@@ -1138,9 +1138,30 @@ var require_events = __commonJS({
|
|
|
1138
1138
|
// Transcript events
|
|
1139
1139
|
"transcript:emitted",
|
|
1140
1140
|
"transcript:pre-compact",
|
|
1141
|
+
// Bulk processing lifecycle events
|
|
1142
|
+
"bulk-processing:start",
|
|
1143
|
+
"bulk-processing:finish",
|
|
1141
1144
|
// General error
|
|
1142
1145
|
"error:occurred"
|
|
1143
1146
|
];
|
|
1147
|
+
exports2.DecisionEvents = {
|
|
1148
|
+
/** Emitted when a runtime decision is recorded. */
|
|
1149
|
+
decisionRecorded(context, payload) {
|
|
1150
|
+
return {
|
|
1151
|
+
type: "decision:recorded",
|
|
1152
|
+
time: Date.now(),
|
|
1153
|
+
source: "daemon",
|
|
1154
|
+
context: {
|
|
1155
|
+
sessionId: context.sessionId,
|
|
1156
|
+
correlationId: context.correlationId,
|
|
1157
|
+
traceId: context.traceId,
|
|
1158
|
+
hook: context.hook,
|
|
1159
|
+
taskId: context.taskId
|
|
1160
|
+
},
|
|
1161
|
+
payload
|
|
1162
|
+
};
|
|
1163
|
+
}
|
|
1164
|
+
};
|
|
1144
1165
|
exports2.UI_EVENT_VISIBILITY = {
|
|
1145
1166
|
// Timeline events (user-visible state changes)
|
|
1146
1167
|
"reminder:staged": "timeline",
|
|
@@ -1176,7 +1197,9 @@ var require_events = __commonJS({
|
|
|
1176
1197
|
"session-summary:skipped": "log",
|
|
1177
1198
|
"resume-message:skipped": "log",
|
|
1178
1199
|
"transcript:emitted": "log",
|
|
1179
|
-
"transcript:pre-compact": "log"
|
|
1200
|
+
"transcript:pre-compact": "log",
|
|
1201
|
+
"bulk-processing:start": "log",
|
|
1202
|
+
"bulk-processing:finish": "log"
|
|
1180
1203
|
};
|
|
1181
1204
|
}
|
|
1182
1205
|
});
|
|
@@ -45774,7 +45797,8 @@ var require_structured_logging = __commonJS({
|
|
|
45774
45797
|
payload: {
|
|
45775
45798
|
hook: context.hook,
|
|
45776
45799
|
cwd: metadata.cwd,
|
|
45777
|
-
mode: metadata.mode
|
|
45800
|
+
mode: metadata.mode,
|
|
45801
|
+
input: metadata.input
|
|
45778
45802
|
}
|
|
45779
45803
|
};
|
|
45780
45804
|
},
|
|
@@ -45796,7 +45820,8 @@ var require_structured_logging = __commonJS({
|
|
|
45796
45820
|
hook: context.hook,
|
|
45797
45821
|
durationMs: metadata.durationMs,
|
|
45798
45822
|
reminderReturned: state?.reminderReturned,
|
|
45799
|
-
responseType: state?.responseType
|
|
45823
|
+
responseType: state?.responseType,
|
|
45824
|
+
returnValue: state?.returnValue
|
|
45800
45825
|
}
|
|
45801
45826
|
};
|
|
45802
45827
|
},
|
|
@@ -46209,6 +46234,48 @@ var require_structured_logging = __commonJS({
|
|
|
46209
46234
|
errorStack: state.errorStack
|
|
46210
46235
|
}
|
|
46211
46236
|
};
|
|
46237
|
+
},
|
|
46238
|
+
// --- Bulk Processing Lifecycle Events ---
|
|
46239
|
+
/**
|
|
46240
|
+
* Create a BulkProcessingStart event (logged when transcript bulk replay begins).
|
|
46241
|
+
*/
|
|
46242
|
+
bulkProcessingStart(context, metadata) {
|
|
46243
|
+
return {
|
|
46244
|
+
type: "bulk-processing:start",
|
|
46245
|
+
time: Date.now(),
|
|
46246
|
+
source: "transcript",
|
|
46247
|
+
context: {
|
|
46248
|
+
sessionId: context.sessionId,
|
|
46249
|
+
correlationId: context.correlationId,
|
|
46250
|
+
traceId: context.traceId,
|
|
46251
|
+
hook: context.hook,
|
|
46252
|
+
taskId: context.taskId
|
|
46253
|
+
},
|
|
46254
|
+
payload: {
|
|
46255
|
+
fileSize: metadata.fileSize
|
|
46256
|
+
}
|
|
46257
|
+
};
|
|
46258
|
+
},
|
|
46259
|
+
/**
|
|
46260
|
+
* Create a BulkProcessingFinish event (logged when transcript bulk replay completes).
|
|
46261
|
+
*/
|
|
46262
|
+
bulkProcessingFinish(context, metadata) {
|
|
46263
|
+
return {
|
|
46264
|
+
type: "bulk-processing:finish",
|
|
46265
|
+
time: Date.now(),
|
|
46266
|
+
source: "transcript",
|
|
46267
|
+
context: {
|
|
46268
|
+
sessionId: context.sessionId,
|
|
46269
|
+
correlationId: context.correlationId,
|
|
46270
|
+
traceId: context.traceId,
|
|
46271
|
+
hook: context.hook,
|
|
46272
|
+
taskId: context.taskId
|
|
46273
|
+
},
|
|
46274
|
+
payload: {
|
|
46275
|
+
totalLinesProcessed: metadata.totalLinesProcessed,
|
|
46276
|
+
durationMs: metadata.durationMs
|
|
46277
|
+
}
|
|
46278
|
+
};
|
|
46212
46279
|
}
|
|
46213
46280
|
};
|
|
46214
46281
|
function logEvent(logger, event) {
|
|
@@ -46293,7 +46360,7 @@ var require_package3 = __commonJS({
|
|
|
46293
46360
|
"eslint-config-prettier": "^9.1.0",
|
|
46294
46361
|
"eslint-plugin-prettier": "^5.1.3",
|
|
46295
46362
|
prettier: "^3.2.5",
|
|
46296
|
-
typescript: "^5.
|
|
46363
|
+
typescript: "^5.9.3",
|
|
46297
46364
|
"typescript-eslint": "^8.56.0",
|
|
46298
46365
|
vitest: "^4.0.18"
|
|
46299
46366
|
}
|
|
@@ -58257,6 +58324,7 @@ var require_staging_service = __commonJS({
|
|
|
58257
58324
|
const hookDir = this.getHookDirPath(sessionId, hookName);
|
|
58258
58325
|
const reminderPath = this.getReminderFilePath(sessionId, hookName, reminderName);
|
|
58259
58326
|
await this.ensureDir(hookDir);
|
|
58327
|
+
const isRestage = (0, node_fs_1.existsSync)(reminderPath);
|
|
58260
58328
|
try {
|
|
58261
58329
|
await this.options.stateService.write(reminderPath, data, types_1.StagedReminderSchema);
|
|
58262
58330
|
} catch (err) {
|
|
@@ -58272,18 +58340,20 @@ var require_staging_service = __commonJS({
|
|
|
58272
58340
|
throw err;
|
|
58273
58341
|
}
|
|
58274
58342
|
}
|
|
58275
|
-
|
|
58276
|
-
|
|
58277
|
-
|
|
58278
|
-
|
|
58279
|
-
|
|
58280
|
-
|
|
58281
|
-
|
|
58282
|
-
|
|
58283
|
-
|
|
58284
|
-
|
|
58285
|
-
|
|
58286
|
-
|
|
58343
|
+
if (!isRestage) {
|
|
58344
|
+
const event = structured_logging_1.LogEvents.reminderStaged({
|
|
58345
|
+
sessionId,
|
|
58346
|
+
hook: hookName
|
|
58347
|
+
}, {
|
|
58348
|
+
reminderName: data.name,
|
|
58349
|
+
hookName,
|
|
58350
|
+
blocking: data.blocking,
|
|
58351
|
+
priority: data.priority,
|
|
58352
|
+
persistent: data.persistent,
|
|
58353
|
+
...enrichment
|
|
58354
|
+
}, { stagingPath: reminderPath });
|
|
58355
|
+
(0, structured_logging_1.logEvent)(this.options.logger.child({ context: { sessionId } }), event);
|
|
58356
|
+
}
|
|
58287
58357
|
}
|
|
58288
58358
|
/**
|
|
58289
58359
|
* Read a staged reminder.
|
|
@@ -58362,13 +58432,14 @@ var require_staging_service = __commonJS({
|
|
|
58362
58432
|
* Delete a specific staged reminder.
|
|
58363
58433
|
* Used after consumption of one-shot reminders.
|
|
58364
58434
|
*
|
|
58435
|
+
* @returns true if the file was actually deleted, false if it didn't exist
|
|
58365
58436
|
* @throws Error if hookName or reminderName contain path traversal characters
|
|
58366
58437
|
*/
|
|
58367
58438
|
async deleteReminder(sessionId, hookName, reminderName) {
|
|
58368
58439
|
(0, staging_paths_js_1.validatePathSegment)(hookName, "hookName");
|
|
58369
58440
|
(0, staging_paths_js_1.validatePathSegment)(reminderName, "reminderName");
|
|
58370
58441
|
const reminderPath = this.getReminderFilePath(sessionId, hookName, reminderName);
|
|
58371
|
-
|
|
58442
|
+
return this.options.stateService.delete(reminderPath);
|
|
58372
58443
|
}
|
|
58373
58444
|
/**
|
|
58374
58445
|
* List consumed reminder files for a specific reminder ID.
|
|
@@ -60909,7 +60980,7 @@ var require_state_service = __commonJS({
|
|
|
60909
60980
|
}
|
|
60910
60981
|
/**
|
|
60911
60982
|
* Delete state file if it exists.
|
|
60912
|
-
*
|
|
60983
|
+
* @returns true if the file was actually deleted, false if it didn't exist
|
|
60913
60984
|
*/
|
|
60914
60985
|
async delete(path) {
|
|
60915
60986
|
try {
|
|
@@ -60918,10 +60989,12 @@ var require_state_service = __commonJS({
|
|
|
60918
60989
|
this.cache.delete(path);
|
|
60919
60990
|
}
|
|
60920
60991
|
this.logger?.debug("State deleted", { path });
|
|
60992
|
+
return true;
|
|
60921
60993
|
} catch (err) {
|
|
60922
60994
|
if (!isEnoent(err)) {
|
|
60923
60995
|
throw err;
|
|
60924
60996
|
}
|
|
60997
|
+
return false;
|
|
60925
60998
|
}
|
|
60926
60999
|
}
|
|
60927
61000
|
/**
|
|
@@ -61176,7 +61249,7 @@ var require_typed_accessor = __commonJS({
|
|
|
61176
61249
|
*/
|
|
61177
61250
|
async delete(sessionId) {
|
|
61178
61251
|
const path = this.stateService.sessionStatePath(sessionId, this.descriptor.filename);
|
|
61179
|
-
|
|
61252
|
+
await this.stateService.delete(path);
|
|
61180
61253
|
}
|
|
61181
61254
|
/**
|
|
61182
61255
|
* Get the path for a session state file.
|
|
@@ -61222,7 +61295,7 @@ var require_typed_accessor = __commonJS({
|
|
|
61222
61295
|
*/
|
|
61223
61296
|
async delete() {
|
|
61224
61297
|
const path = this.stateService.globalStatePath(this.descriptor.filename);
|
|
61225
|
-
|
|
61298
|
+
await this.stateService.delete(path);
|
|
61226
61299
|
}
|
|
61227
61300
|
/**
|
|
61228
61301
|
* Get the path for the global state file.
|
|
@@ -61544,6 +61617,10 @@ var require_transcript_service = __commonJS({
|
|
|
61544
61617
|
prepared = false;
|
|
61545
61618
|
/** Track whether we're in bulk processing mode (first-time transcript replay) */
|
|
61546
61619
|
isBulkProcessing = false;
|
|
61620
|
+
/** One-shot guard — prevents BulkProcessingComplete from firing more than once per instance */
|
|
61621
|
+
hasFiredBulkComplete = false;
|
|
61622
|
+
/** Timestamp when bulk processing started (for duration calculation in finish event) */
|
|
61623
|
+
bulkStartTime = 0;
|
|
61547
61624
|
/** Map tool_use_id → tool name so ToolResult events can include the tool name */
|
|
61548
61625
|
toolUseIdToName = /* @__PURE__ */ new Map();
|
|
61549
61626
|
// Streaming state for incremental file processing
|
|
@@ -62283,12 +62360,10 @@ var require_transcript_service = __commonJS({
|
|
|
62283
62360
|
}
|
|
62284
62361
|
const startLine = this.metrics.lastProcessedLine;
|
|
62285
62362
|
const isBulkStart = startLine === 0 && this.lastProcessedByteOffset === 0;
|
|
62286
|
-
if (isBulkStart) {
|
|
62363
|
+
if (isBulkStart && !this.hasFiredBulkComplete) {
|
|
62287
62364
|
this.isBulkProcessing = true;
|
|
62288
|
-
this.
|
|
62289
|
-
|
|
62290
|
-
fileSize: currentFileSize
|
|
62291
|
-
});
|
|
62365
|
+
this.bulkStartTime = Date.now();
|
|
62366
|
+
(0, structured_logging_js_1.logEvent)(this.options.logger, structured_logging_js_1.LogEvents.bulkProcessingStart({ sessionId: this.sessionId }, { fileSize: currentFileSize }));
|
|
62292
62367
|
}
|
|
62293
62368
|
const stream = (0, node_fs_1.createReadStream)(this.transcriptPath, {
|
|
62294
62369
|
encoding: "utf-8",
|
|
@@ -62346,13 +62421,12 @@ var require_transcript_service = __commonJS({
|
|
|
62346
62421
|
totalLines: lineNumber,
|
|
62347
62422
|
newByteOffset: bytesRead
|
|
62348
62423
|
});
|
|
62349
|
-
if (isBulkStart && this.isBulkProcessing) {
|
|
62424
|
+
if (isBulkStart && this.isBulkProcessing && !this.hasFiredBulkComplete) {
|
|
62350
62425
|
this.isBulkProcessing = false;
|
|
62426
|
+
this.hasFiredBulkComplete = true;
|
|
62427
|
+
const durationMs = Date.now() - this.bulkStartTime;
|
|
62428
|
+
(0, structured_logging_js_1.logEvent)(this.options.logger, structured_logging_js_1.LogEvents.bulkProcessingFinish({ sessionId: this.sessionId }, { totalLinesProcessed: lineNumber, durationMs }));
|
|
62351
62429
|
await this.emitEvent("BulkProcessingComplete", {}, lineNumber);
|
|
62352
|
-
this.options.logger.info("Bulk processing complete", {
|
|
62353
|
-
sessionId: this.sessionId,
|
|
62354
|
-
totalLinesProcessed: lineNumber
|
|
62355
|
-
});
|
|
62356
62430
|
}
|
|
62357
62431
|
this.notifyMetricsChange();
|
|
62358
62432
|
this.schedulePersistence();
|
|
@@ -71461,7 +71535,7 @@ var require_types2 = __commonJS({
|
|
|
71461
71535
|
"../feature-reminders/dist/types.js"(exports2) {
|
|
71462
71536
|
"use strict";
|
|
71463
71537
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
71464
|
-
exports2.ALL_VC_REMINDER_IDS = exports2.VC_TOOL_REMINDER_IDS = exports2.TOOL_REMINDER_MAP = 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;
|
|
71538
|
+
exports2.ALL_VC_REMINDER_IDS = exports2.VC_TOOL_REMINDER_IDS = exports2.TOOL_REMINDER_MAP = exports2.ReminderIds = exports2.DEFAULT_REMINDERS_SETTINGS = exports2.DEFAULT_COMPLETION_DETECTION_SETTINGS = exports2.DEFAULT_SOURCE_CODE_PATTERNS = exports2.DEFAULT_VERIFICATION_TOOLS = exports2.CommandRunnerSchema = exports2.VerificationToolsMapSchema = exports2.VerificationToolConfigSchema = exports2.ToolPatternSchema = exports2.ToolPatternScopeSchema = void 0;
|
|
71465
71539
|
var zod_1 = require_zod2();
|
|
71466
71540
|
exports2.ToolPatternScopeSchema = zod_1.z.enum(["project", "package", "file"]);
|
|
71467
71541
|
exports2.ToolPatternSchema = zod_1.z.object({
|
|
@@ -71476,6 +71550,9 @@ var require_types2 = __commonJS({
|
|
|
71476
71550
|
clearing_patterns: zod_1.z.array(zod_1.z.string()).min(1)
|
|
71477
71551
|
});
|
|
71478
71552
|
exports2.VerificationToolsMapSchema = zod_1.z.record(zod_1.z.string(), exports2.VerificationToolConfigSchema);
|
|
71553
|
+
exports2.CommandRunnerSchema = zod_1.z.object({
|
|
71554
|
+
prefix: zod_1.z.string().trim().min(1)
|
|
71555
|
+
});
|
|
71479
71556
|
exports2.DEFAULT_VERIFICATION_TOOLS = {
|
|
71480
71557
|
build: {
|
|
71481
71558
|
enabled: true,
|
|
@@ -71664,7 +71741,30 @@ var require_types2 = __commonJS({
|
|
|
71664
71741
|
reminder_thresholds: {
|
|
71665
71742
|
"user-prompt-submit": 10,
|
|
71666
71743
|
"remember-your-persona": 5
|
|
71667
|
-
}
|
|
71744
|
+
},
|
|
71745
|
+
command_runners: [
|
|
71746
|
+
// Python
|
|
71747
|
+
{ prefix: "uv run" },
|
|
71748
|
+
{ prefix: "poetry run" },
|
|
71749
|
+
{ prefix: "pipx run" },
|
|
71750
|
+
{ prefix: "pdm run" },
|
|
71751
|
+
{ prefix: "hatch run" },
|
|
71752
|
+
{ prefix: "conda run" },
|
|
71753
|
+
// Node.js
|
|
71754
|
+
{ prefix: "npx" },
|
|
71755
|
+
{ prefix: "pnpx" },
|
|
71756
|
+
{ prefix: "bunx" },
|
|
71757
|
+
{ prefix: "pnpm dlx" },
|
|
71758
|
+
{ prefix: "pnpm exec" },
|
|
71759
|
+
{ prefix: "bun run" },
|
|
71760
|
+
{ prefix: "yarn dlx" },
|
|
71761
|
+
{ prefix: "yarn exec" },
|
|
71762
|
+
{ prefix: "npm exec" },
|
|
71763
|
+
// Ruby
|
|
71764
|
+
{ prefix: "bundle exec" },
|
|
71765
|
+
// .NET
|
|
71766
|
+
{ prefix: "dotnet tool run" }
|
|
71767
|
+
]
|
|
71668
71768
|
};
|
|
71669
71769
|
exports2.ReminderIds = {
|
|
71670
71770
|
USER_PROMPT_SUBMIT: "user-prompt-submit",
|
|
@@ -71767,6 +71867,7 @@ var require_stage_default_user_prompt = __commonJS({
|
|
|
71767
71867
|
"use strict";
|
|
71768
71868
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
71769
71869
|
exports2.registerStageDefaultUserPrompt = registerStageDefaultUserPrompt;
|
|
71870
|
+
var core_1 = require_dist4();
|
|
71770
71871
|
var types_1 = require_dist();
|
|
71771
71872
|
var staging_handler_utils_js_1 = require_staging_handler_utils();
|
|
71772
71873
|
var types_js_1 = require_types2();
|
|
@@ -71895,6 +71996,16 @@ var require_stage_default_user_prompt = __commonJS({
|
|
|
71895
71996
|
continue;
|
|
71896
71997
|
const newCount = typedEntry.messagesSinceLastStaging + 1;
|
|
71897
71998
|
if (newCount >= threshold) {
|
|
71999
|
+
(0, core_1.logEvent)(handlerCtx.logger, types_1.DecisionEvents.decisionRecorded({ sessionId }, {
|
|
72000
|
+
decision: "staged",
|
|
72001
|
+
reason: [
|
|
72002
|
+
`message count reached threshold (${newCount}/${threshold})`,
|
|
72003
|
+
`target hook: ${typedEntry.targetHook}`,
|
|
72004
|
+
`messages since last staging: ${typedEntry.messagesSinceLastStaging}`
|
|
72005
|
+
].join("; "),
|
|
72006
|
+
subsystem: "reminder-throttle",
|
|
72007
|
+
title: `Re-stage ${reminderId} reminder`
|
|
72008
|
+
}));
|
|
71898
72009
|
const metrics = event.metadata.metrics;
|
|
71899
72010
|
const stagedAt = {
|
|
71900
72011
|
timestamp: Date.now(),
|
|
@@ -71955,6 +72066,9 @@ var require_events2 = __commonJS({
|
|
|
71955
72066
|
blocking: state.blocking,
|
|
71956
72067
|
priority: state.priority,
|
|
71957
72068
|
persistent: state.persistent,
|
|
72069
|
+
...state.renderedText !== void 0 && {
|
|
72070
|
+
renderedText: state.renderedText
|
|
72071
|
+
},
|
|
71958
72072
|
...state.classificationResult !== void 0 && {
|
|
71959
72073
|
classificationResult: state.classificationResult
|
|
71960
72074
|
}
|
|
@@ -72103,6 +72217,12 @@ var require_stage_pause_and_reflect = __commonJS({
|
|
|
72103
72217
|
}));
|
|
72104
72218
|
return void 0;
|
|
72105
72219
|
}
|
|
72220
|
+
(0, core_1.logEvent)(ctx.logger, types_1.DecisionEvents.decisionRecorded({ sessionId }, {
|
|
72221
|
+
decision: "staged",
|
|
72222
|
+
reason: `tools since baseline reached threshold (${toolsSinceBaseline}/${config.pause_and_reflect_threshold})`,
|
|
72223
|
+
subsystem: "pause-reflect",
|
|
72224
|
+
title: "Stage pause-and-reflect reminder"
|
|
72225
|
+
}));
|
|
72106
72226
|
return {
|
|
72107
72227
|
reminderId: types_js_1.ReminderIds.PAUSE_AND_REFLECT,
|
|
72108
72228
|
targetHook: "PreToolUse",
|
|
@@ -73640,17 +73760,51 @@ var require_tool_pattern_matcher = __commonJS({
|
|
|
73640
73760
|
exports2.matchesToolPattern = matchesToolPattern;
|
|
73641
73761
|
exports2.findMatchingPattern = findMatchingPattern;
|
|
73642
73762
|
var SHELL_OPERATOR_RE = /\s*(?:&&|\|\||[;|])\s*/;
|
|
73643
|
-
function
|
|
73763
|
+
function detectRunnerPrefix(segmentTokens, runners) {
|
|
73764
|
+
let longestMatch = 0;
|
|
73765
|
+
for (const runner of runners) {
|
|
73766
|
+
if (typeof runner.prefix !== "string")
|
|
73767
|
+
continue;
|
|
73768
|
+
const prefixTokens = runner.prefix.trim().split(/\s+/);
|
|
73769
|
+
if (prefixTokens.length === 0)
|
|
73770
|
+
continue;
|
|
73771
|
+
if (prefixTokens.length > segmentTokens.length)
|
|
73772
|
+
continue;
|
|
73773
|
+
let matches = true;
|
|
73774
|
+
for (let i = 0; i < prefixTokens.length; i++) {
|
|
73775
|
+
if (segmentTokens[i] !== prefixTokens[i]) {
|
|
73776
|
+
matches = false;
|
|
73777
|
+
break;
|
|
73778
|
+
}
|
|
73779
|
+
}
|
|
73780
|
+
if (matches && prefixTokens.length > longestMatch) {
|
|
73781
|
+
longestMatch = prefixTokens.length;
|
|
73782
|
+
}
|
|
73783
|
+
}
|
|
73784
|
+
return longestMatch;
|
|
73785
|
+
}
|
|
73786
|
+
function matchesToolPattern(command, pattern, runners) {
|
|
73644
73787
|
if (!command || !pattern)
|
|
73645
73788
|
return false;
|
|
73646
73789
|
const segments = command.split(SHELL_OPERATOR_RE);
|
|
73647
73790
|
const patternTokens = pattern.trim().split(/\s+/).filter(Boolean);
|
|
73648
73791
|
if (patternTokens.length === 0)
|
|
73649
73792
|
return false;
|
|
73793
|
+
const activeRunners = runners?.length ? runners : void 0;
|
|
73650
73794
|
return segments.some((segment) => {
|
|
73651
73795
|
const cmdTokens = segment.trim().split(/\s+/);
|
|
73652
73796
|
if (cmdTokens.length === 0 || cmdTokens[0] === "")
|
|
73653
73797
|
return false;
|
|
73798
|
+
const runnerTokenCount = activeRunners ? detectRunnerPrefix(cmdTokens, activeRunners) : 0;
|
|
73799
|
+
if (runnerTokenCount > 0) {
|
|
73800
|
+
let pi2 = 0;
|
|
73801
|
+
for (let ci = runnerTokenCount; ci < cmdTokens.length && pi2 < patternTokens.length; ci++) {
|
|
73802
|
+
if (patternTokens[pi2] === "*" || patternTokens[pi2] === cmdTokens[ci]) {
|
|
73803
|
+
pi2++;
|
|
73804
|
+
}
|
|
73805
|
+
}
|
|
73806
|
+
return pi2 === patternTokens.length;
|
|
73807
|
+
}
|
|
73654
73808
|
if (cmdTokens[0] !== patternTokens[0])
|
|
73655
73809
|
return false;
|
|
73656
73810
|
let pi = 1;
|
|
@@ -73662,11 +73816,11 @@ var require_tool_pattern_matcher = __commonJS({
|
|
|
73662
73816
|
return pi === patternTokens.length;
|
|
73663
73817
|
});
|
|
73664
73818
|
}
|
|
73665
|
-
function findMatchingPattern(command, patterns) {
|
|
73819
|
+
function findMatchingPattern(command, patterns, runners) {
|
|
73666
73820
|
for (const pattern of patterns) {
|
|
73667
73821
|
if (pattern.tool === null)
|
|
73668
73822
|
continue;
|
|
73669
|
-
if (matchesToolPattern(command, pattern.tool))
|
|
73823
|
+
if (matchesToolPattern(command, pattern.tool, runners))
|
|
73670
73824
|
return pattern;
|
|
73671
73825
|
}
|
|
73672
73826
|
return null;
|
|
@@ -73722,13 +73876,14 @@ var require_track_verification_tools = __commonJS({
|
|
|
73722
73876
|
const featureConfig = context.config.getFeature("reminders");
|
|
73723
73877
|
const config = { ...types_js_1.DEFAULT_REMINDERS_SETTINGS, ...featureConfig.settings };
|
|
73724
73878
|
const verificationTools = config.verification_tools ?? {};
|
|
73879
|
+
const runners = config.command_runners ?? [];
|
|
73725
73880
|
const remindersState = (0, state_js_1.createRemindersState)(daemonCtx.stateService);
|
|
73726
73881
|
const stateResult = await remindersState.verificationTools.read(sessionId);
|
|
73727
73882
|
const toolsState = { ...stateResult.data };
|
|
73728
73883
|
if (FILE_EDIT_TOOLS.includes(toolName)) {
|
|
73729
73884
|
await handleFileEdit(event, daemonCtx, sessionId, verificationTools, toolsState, remindersState);
|
|
73730
73885
|
} else if (toolName === "Bash") {
|
|
73731
|
-
await handleBashCommand(event, daemonCtx, sessionId, verificationTools, toolsState, remindersState);
|
|
73886
|
+
await handleBashCommand(event, daemonCtx, sessionId, verificationTools, toolsState, remindersState, runners);
|
|
73732
73887
|
}
|
|
73733
73888
|
}
|
|
73734
73889
|
});
|
|
@@ -73790,12 +73945,21 @@ var require_track_verification_tools = __commonJS({
|
|
|
73790
73945
|
} else {
|
|
73791
73946
|
const newEdits = current.editsSinceVerified + 1;
|
|
73792
73947
|
if (newEdits >= toolConfig.clearing_threshold) {
|
|
73948
|
+
const wasAlreadyStaged = stagedNames.has(reminderId);
|
|
73793
73949
|
const staged = await ensureToolReminderStaged(daemonCtx, reminderId, stagedNames, {
|
|
73794
73950
|
reason: "threshold_reached",
|
|
73795
73951
|
triggeredBy: "file_edit",
|
|
73796
73952
|
thresholdState: { current: newEdits, threshold: toolConfig.clearing_threshold }
|
|
73797
73953
|
});
|
|
73798
73954
|
if (staged) {
|
|
73955
|
+
if (!wasAlreadyStaged) {
|
|
73956
|
+
(0, core_1.logEvent)(daemonCtx.logger, types_1.DecisionEvents.decisionRecorded({ sessionId }, {
|
|
73957
|
+
decision: "staged",
|
|
73958
|
+
reason: `edits reached clearing threshold (${newEdits}/${toolConfig.clearing_threshold})`,
|
|
73959
|
+
subsystem: "vc-reminders",
|
|
73960
|
+
title: "Re-stage VC reminder (threshold reached)"
|
|
73961
|
+
}));
|
|
73962
|
+
}
|
|
73799
73963
|
toolsState[toolName] = {
|
|
73800
73964
|
...current,
|
|
73801
73965
|
status: "staged",
|
|
@@ -73841,7 +74005,7 @@ var require_track_verification_tools = __commonJS({
|
|
|
73841
74005
|
return;
|
|
73842
74006
|
await stageToolsForFiles([filePath], daemonCtx, sessionId, verificationTools, toolsState, remindersState);
|
|
73843
74007
|
}
|
|
73844
|
-
async function handleBashCommand(event, daemonCtx, sessionId, verificationTools, toolsState, remindersState) {
|
|
74008
|
+
async function handleBashCommand(event, daemonCtx, sessionId, verificationTools, toolsState, remindersState, runners = []) {
|
|
73845
74009
|
const command = extractToolInput(event)?.command;
|
|
73846
74010
|
if (!command)
|
|
73847
74011
|
return;
|
|
@@ -73852,7 +74016,7 @@ var require_track_verification_tools = __commonJS({
|
|
|
73852
74016
|
const reminderId = types_js_1.TOOL_REMINDER_MAP[toolName];
|
|
73853
74017
|
if (!reminderId)
|
|
73854
74018
|
continue;
|
|
73855
|
-
const match = (0, tool_pattern_matcher_js_1.findMatchingPattern)(command, toolConfig.patterns);
|
|
74019
|
+
const match = (0, tool_pattern_matcher_js_1.findMatchingPattern)(command, toolConfig.patterns, runners);
|
|
73856
74020
|
if (!match)
|
|
73857
74021
|
continue;
|
|
73858
74022
|
toolsState[toolName] = {
|
|
@@ -73863,7 +74027,15 @@ var require_track_verification_tools = __commonJS({
|
|
|
73863
74027
|
lastMatchedToolId: match.tool_id,
|
|
73864
74028
|
lastMatchedScope: match.scope
|
|
73865
74029
|
};
|
|
73866
|
-
await daemonCtx.staging.deleteReminder("Stop", reminderId);
|
|
74030
|
+
const deleted = await daemonCtx.staging.deleteReminder("Stop", reminderId);
|
|
74031
|
+
if (deleted) {
|
|
74032
|
+
(0, core_1.logEvent)(daemonCtx.logger, types_1.DecisionEvents.decisionRecorded({ sessionId }, {
|
|
74033
|
+
decision: "unstaged",
|
|
74034
|
+
reason: `verification passed for ${toolName} (matched ${match.tool_id})`,
|
|
74035
|
+
subsystem: "vc-reminders",
|
|
74036
|
+
title: "Unstage VC reminder (verified)"
|
|
74037
|
+
}));
|
|
74038
|
+
}
|
|
73867
74039
|
(0, core_1.logEvent)(daemonCtx.logger, events_js_1.ReminderEvents.reminderUnstaged({ sessionId }, {
|
|
73868
74040
|
reminderName: reminderId,
|
|
73869
74041
|
hookName: "Stop",
|
|
@@ -74066,8 +74238,9 @@ var require_unstage_verify_completion = __commonJS({
|
|
|
74066
74238
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
74067
74239
|
exports2.registerUnstageVerifyCompletion = registerUnstageVerifyCompletion;
|
|
74068
74240
|
var core_1 = require_dist4();
|
|
74069
|
-
var events_js_1 = require_events2();
|
|
74070
74241
|
var types_1 = require_dist();
|
|
74242
|
+
var events_js_1 = require_events2();
|
|
74243
|
+
var types_2 = require_dist();
|
|
74071
74244
|
var types_js_1 = require_types2();
|
|
74072
74245
|
var reminder_utils_js_1 = require_reminder_utils();
|
|
74073
74246
|
var state_js_1 = require_state4();
|
|
@@ -74084,7 +74257,7 @@ var require_unstage_verify_completion = __commonJS({
|
|
|
74084
74257
|
return false;
|
|
74085
74258
|
}
|
|
74086
74259
|
function registerUnstageVerifyCompletion(context) {
|
|
74087
|
-
if (!(0,
|
|
74260
|
+
if (!(0, types_2.isDaemonContext)(context))
|
|
74088
74261
|
return;
|
|
74089
74262
|
context.handlers.register({
|
|
74090
74263
|
id: "reminders:unstage-verify-completion",
|
|
@@ -74092,17 +74265,19 @@ var require_unstage_verify_completion = __commonJS({
|
|
|
74092
74265
|
// Before consumption handlers (50)
|
|
74093
74266
|
filter: { kind: "hook", hooks: ["UserPromptSubmit"] },
|
|
74094
74267
|
handler: async (event, ctx) => {
|
|
74095
|
-
if (!(0,
|
|
74268
|
+
if (!(0, types_2.isHookEvent)(event))
|
|
74096
74269
|
return;
|
|
74097
|
-
if (!(0,
|
|
74270
|
+
if (!(0, types_2.isDaemonContext)(ctx))
|
|
74098
74271
|
return;
|
|
74099
74272
|
const daemonCtx = ctx;
|
|
74100
74273
|
const sessionId = event.context?.sessionId;
|
|
74101
74274
|
if (!sessionId) {
|
|
74102
74275
|
daemonCtx.logger.warn("No sessionId in UserPromptSubmit event");
|
|
74103
74276
|
for (const vcId of types_js_1.ALL_VC_REMINDER_IDS) {
|
|
74104
|
-
await daemonCtx.staging.deleteReminder("Stop", vcId);
|
|
74105
|
-
(
|
|
74277
|
+
const deleted = await daemonCtx.staging.deleteReminder("Stop", vcId);
|
|
74278
|
+
if (deleted) {
|
|
74279
|
+
(0, core_1.logEvent)(daemonCtx.logger, events_js_1.ReminderEvents.reminderUnstaged({ sessionId: "" }, { reminderName: vcId, hookName: "Stop", reason: "no_session_id" }));
|
|
74280
|
+
}
|
|
74106
74281
|
}
|
|
74107
74282
|
return;
|
|
74108
74283
|
}
|
|
@@ -74187,6 +74362,12 @@ var require_unstage_verify_completion = __commonJS({
|
|
|
74187
74362
|
maxCycles
|
|
74188
74363
|
});
|
|
74189
74364
|
await remindersState.vcUnverified.delete(sessionId);
|
|
74365
|
+
(0, core_1.logEvent)(daemonCtx.logger, types_1.DecisionEvents.decisionRecorded({ sessionId }, {
|
|
74366
|
+
decision: "unstaged-all",
|
|
74367
|
+
reason: `verification cycle limit reached (${unverifiedState.cycleCount}/${maxCycles})`,
|
|
74368
|
+
subsystem: "vc-reminders",
|
|
74369
|
+
title: "Unstage all VC reminders (cycle limit)"
|
|
74370
|
+
}));
|
|
74190
74371
|
}
|
|
74191
74372
|
} else {
|
|
74192
74373
|
(0, core_1.logEvent)(daemonCtx.logger, events_js_1.ReminderEvents.reminderNotStaged({ sessionId }, {
|
|
@@ -74201,16 +74382,24 @@ var require_unstage_verify_completion = __commonJS({
|
|
|
74201
74382
|
}
|
|
74202
74383
|
const eventContext = { sessionId };
|
|
74203
74384
|
const reason = unverifiedState?.hasUnverifiedChanges ? "cycle_limit_reached" : "no_unverified_changes";
|
|
74385
|
+
let deletedCount = 0;
|
|
74204
74386
|
for (const vcId of types_js_1.ALL_VC_REMINDER_IDS) {
|
|
74205
|
-
await daemonCtx.staging.deleteReminder("Stop", vcId);
|
|
74206
|
-
(
|
|
74207
|
-
|
|
74208
|
-
|
|
74209
|
-
|
|
74210
|
-
|
|
74211
|
-
|
|
74387
|
+
const deleted = await daemonCtx.staging.deleteReminder("Stop", vcId);
|
|
74388
|
+
if (deleted) {
|
|
74389
|
+
deletedCount++;
|
|
74390
|
+
(0, core_1.logEvent)(daemonCtx.logger, events_js_1.ReminderEvents.reminderUnstaged(eventContext, {
|
|
74391
|
+
reminderName: vcId,
|
|
74392
|
+
hookName: "Stop",
|
|
74393
|
+
reason,
|
|
74394
|
+
triggeredBy: unverifiedState?.hasUnverifiedChanges ? "cycle_limit" : "no_unverified_changes"
|
|
74395
|
+
}));
|
|
74396
|
+
}
|
|
74212
74397
|
}
|
|
74213
|
-
daemonCtx.logger.debug("VC unstage:
|
|
74398
|
+
daemonCtx.logger.debug("VC unstage: cleanup complete", {
|
|
74399
|
+
reason,
|
|
74400
|
+
deletedCount,
|
|
74401
|
+
totalChecked: types_js_1.ALL_VC_REMINDER_IDS.length
|
|
74402
|
+
});
|
|
74214
74403
|
}
|
|
74215
74404
|
});
|
|
74216
74405
|
}
|
|
@@ -74643,6 +74832,12 @@ var require_consumption_handler_factory = __commonJS({
|
|
|
74643
74832
|
if (onConsume) {
|
|
74644
74833
|
await onConsume({ reminder: primary, reader, cliCtx, sessionId });
|
|
74645
74834
|
}
|
|
74835
|
+
const renderedParts = [];
|
|
74836
|
+
if (response.userMessage)
|
|
74837
|
+
renderedParts.push(response.userMessage);
|
|
74838
|
+
if (response.additionalContext)
|
|
74839
|
+
renderedParts.push(response.additionalContext);
|
|
74840
|
+
const renderedText = renderedParts.length > 0 ? renderedParts.join("\n\n") : void 0;
|
|
74646
74841
|
(0, core_1.logEvent)(cliCtx.logger, events_js_1.ReminderEvents.reminderConsumed({
|
|
74647
74842
|
sessionId,
|
|
74648
74843
|
hook
|
|
@@ -74652,6 +74847,7 @@ var require_consumption_handler_factory = __commonJS({
|
|
|
74652
74847
|
blocking: response.blocking ?? false,
|
|
74653
74848
|
priority: primary.priority,
|
|
74654
74849
|
persistent: primary.persistent,
|
|
74850
|
+
renderedText,
|
|
74655
74851
|
...enrichment
|
|
74656
74852
|
}));
|
|
74657
74853
|
return { response };
|
|
@@ -75172,16 +75368,24 @@ var require_orchestrator = __commonJS({
|
|
|
75172
75368
|
const staging = this.deps.getStagingService(sessionId);
|
|
75173
75369
|
const eventContext = { sessionId };
|
|
75174
75370
|
const sessionLogger = this.deps.logger.child({ context: { sessionId } });
|
|
75371
|
+
let deletedCount = 0;
|
|
75175
75372
|
for (const vcId of types_js_1.ALL_VC_REMINDER_IDS) {
|
|
75176
|
-
await staging.deleteReminder("Stop", vcId);
|
|
75177
|
-
(
|
|
75178
|
-
|
|
75179
|
-
|
|
75180
|
-
|
|
75181
|
-
|
|
75182
|
-
|
|
75373
|
+
const deleted = await staging.deleteReminder("Stop", vcId);
|
|
75374
|
+
if (deleted) {
|
|
75375
|
+
deletedCount++;
|
|
75376
|
+
(0, core_1.logEvent)(sessionLogger, events_js_1.ReminderEvents.reminderUnstaged(eventContext, {
|
|
75377
|
+
reminderName: vcId,
|
|
75378
|
+
hookName: "Stop",
|
|
75379
|
+
reason: "pause_and_reflect_cascade",
|
|
75380
|
+
triggeredBy: "cascade_from_pause_and_reflect"
|
|
75381
|
+
}));
|
|
75382
|
+
}
|
|
75183
75383
|
}
|
|
75184
|
-
this.deps.logger.debug("
|
|
75384
|
+
this.deps.logger.debug("VC unstage: P&R cascade complete", {
|
|
75385
|
+
sessionId,
|
|
75386
|
+
deletedCount,
|
|
75387
|
+
totalChecked: types_js_1.ALL_VC_REMINDER_IDS.length
|
|
75388
|
+
});
|
|
75185
75389
|
} catch (err) {
|
|
75186
75390
|
this.deps.logger.warn("Failed to unstage VC reminders after P&R staged", {
|
|
75187
75391
|
sessionId,
|
|
@@ -75214,14 +75418,16 @@ var require_orchestrator = __commonJS({
|
|
|
75214
75418
|
}
|
|
75215
75419
|
try {
|
|
75216
75420
|
const staging = this.deps.getStagingService(sessionId);
|
|
75217
|
-
await staging.deleteReminder("PreToolUse", types_js_1.ReminderIds.PAUSE_AND_REFLECT);
|
|
75218
|
-
|
|
75219
|
-
|
|
75220
|
-
|
|
75221
|
-
|
|
75222
|
-
|
|
75223
|
-
|
|
75224
|
-
|
|
75421
|
+
const deleted = await staging.deleteReminder("PreToolUse", types_js_1.ReminderIds.PAUSE_AND_REFLECT);
|
|
75422
|
+
if (deleted) {
|
|
75423
|
+
(0, core_1.logEvent)(this.deps.logger.child({ context: { sessionId } }), events_js_1.ReminderEvents.reminderUnstaged({ sessionId }, {
|
|
75424
|
+
reminderName: types_js_1.ReminderIds.PAUSE_AND_REFLECT,
|
|
75425
|
+
hookName: "PreToolUse",
|
|
75426
|
+
reason: "vc_consumed_cascade",
|
|
75427
|
+
triggeredBy: "cascade_from_verify_completion"
|
|
75428
|
+
}));
|
|
75429
|
+
}
|
|
75430
|
+
this.deps.logger.debug("VC unstage: P&R cascade from VC consumed", { sessionId, deleted });
|
|
75225
75431
|
} catch (err) {
|
|
75226
75432
|
this.deps.logger.warn("Failed to unstage P&R after VC consumed", {
|
|
75227
75433
|
sessionId,
|
|
@@ -75404,6 +75610,8 @@ var require_hook = __commonJS({
|
|
|
75404
75610
|
"../sidekick-cli/dist/commands/hook.js"(exports2) {
|
|
75405
75611
|
"use strict";
|
|
75406
75612
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
75613
|
+
exports2.truncateForLog = truncateForLog;
|
|
75614
|
+
exports2.buildHookInput = buildHookInput;
|
|
75407
75615
|
exports2.validateHookName = validateHookName;
|
|
75408
75616
|
exports2.buildHookEvent = buildHookEvent;
|
|
75409
75617
|
exports2.mergeHookResponses = mergeHookResponses;
|
|
@@ -75412,6 +75620,33 @@ var require_hook = __commonJS({
|
|
|
75412
75620
|
exports2.getHookName = getHookName;
|
|
75413
75621
|
var core_1 = require_dist4();
|
|
75414
75622
|
var context_js_1 = require_context2();
|
|
75623
|
+
function truncateForLog(raw) {
|
|
75624
|
+
const entries = Object.entries(raw);
|
|
75625
|
+
const needsKeyTruncation = entries.length > 20;
|
|
75626
|
+
const result = {};
|
|
75627
|
+
const toProcess = needsKeyTruncation ? entries.slice(0, 20) : entries;
|
|
75628
|
+
for (const [key, value] of toProcess) {
|
|
75629
|
+
if (typeof value === "string" && value.length > 500) {
|
|
75630
|
+
result[key] = value.slice(0, 500) + "\u2026";
|
|
75631
|
+
} else {
|
|
75632
|
+
result[key] = value;
|
|
75633
|
+
}
|
|
75634
|
+
}
|
|
75635
|
+
if (needsKeyTruncation) {
|
|
75636
|
+
result["_truncated"] = true;
|
|
75637
|
+
}
|
|
75638
|
+
return result;
|
|
75639
|
+
}
|
|
75640
|
+
var STRIP_FIELDS = /* @__PURE__ */ new Set(["session_id", "transcript_path", "hook_event_name"]);
|
|
75641
|
+
function buildHookInput(raw) {
|
|
75642
|
+
const filtered = {};
|
|
75643
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
75644
|
+
if (!STRIP_FIELDS.has(key)) {
|
|
75645
|
+
filtered[key] = value;
|
|
75646
|
+
}
|
|
75647
|
+
}
|
|
75648
|
+
return truncateForLog(filtered);
|
|
75649
|
+
}
|
|
75415
75650
|
var VALID_HOOK_NAMES = /* @__PURE__ */ new Set([
|
|
75416
75651
|
"SessionStart",
|
|
75417
75652
|
"SessionEnd",
|
|
@@ -75582,7 +75817,12 @@ ${daemonResponse.additionalContext}` : cliResponse.additionalContext;
|
|
|
75582
75817
|
correlationId,
|
|
75583
75818
|
hook: hookName
|
|
75584
75819
|
};
|
|
75585
|
-
|
|
75820
|
+
const builtInput = buildHookInput(hookInput.raw);
|
|
75821
|
+
(0, core_1.logEvent)(logger, core_1.LogEvents.hookReceived(logContext, {
|
|
75822
|
+
cwd: hookInput.cwd,
|
|
75823
|
+
mode: "hook",
|
|
75824
|
+
...Object.keys(builtInput).length > 0 ? { input: builtInput } : {}
|
|
75825
|
+
}));
|
|
75586
75826
|
logger.debug("Hook invocation received", { hook: hookName, sessionId: hookInput.sessionId });
|
|
75587
75827
|
const event = buildHookEvent(hookName, hookInput, correlationId);
|
|
75588
75828
|
logger.debug("Dispatching hook event to daemon", {
|
|
@@ -75634,7 +75874,8 @@ ${daemonResponse.additionalContext}` : cliResponse.additionalContext;
|
|
|
75634
75874
|
const outputStr = JSON.stringify(mergedResponse);
|
|
75635
75875
|
stdout.write(`${outputStr}
|
|
75636
75876
|
`);
|
|
75637
|
-
|
|
75877
|
+
const returnValue = Object.keys(mergedResponse).length > 0 ? truncateForLog(mergedResponse) : void 0;
|
|
75878
|
+
(0, core_1.logEvent)(logger, core_1.LogEvents.hookCompleted(logContext, { durationMs: Date.now() - startTime }, { reminderReturned: !!mergedResponse.additionalContext, returnValue }));
|
|
75638
75879
|
return { exitCode: 0, output: outputStr };
|
|
75639
75880
|
}
|
|
75640
75881
|
function isHookCommand(command) {
|
|
@@ -76194,7 +76435,7 @@ var require_types3 = __commonJS({
|
|
|
76194
76435
|
});
|
|
76195
76436
|
exports2.DEFAULT_STATUSLINE_CONFIG = {
|
|
76196
76437
|
enabled: true,
|
|
76197
|
-
format: "{personaName,prefix='[',suffix='] | '}{model,prefix='[',suffix='] | '}{contextBar} {tokenPercentageActual} | {logs} | {cwd,maxLength=40,truncateStyle='path'}{
|
|
76438
|
+
format: "{personaName,prefix='[',suffix='] | '}{model,prefix='[',suffix='] | '}{contextBar} {tokenPercentageActual} | {logs} | {cwd,maxLength=40,truncateStyle='path'}{branchWT,prefix=' | ',maxLength=40}{title,wrapAt=80,prefix=' | ',wrapPrefix='\\n'}\n{summary}",
|
|
76198
76439
|
thresholds: {
|
|
76199
76440
|
tokens: { warning: 1e5, critical: 16e4 },
|
|
76200
76441
|
cost: { warning: 0.5, critical: 1 },
|
|
@@ -76706,7 +76947,7 @@ var require_events3 = __commonJS({
|
|
|
76706
76947
|
"../feature-session-summary/dist/events.js"(exports2) {
|
|
76707
76948
|
"use strict";
|
|
76708
76949
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
76709
|
-
exports2.
|
|
76950
|
+
exports2.SessionSummaryEvents = void 0;
|
|
76710
76951
|
exports2.SessionSummaryEvents = {
|
|
76711
76952
|
/** Emitted when summary generation begins. */
|
|
76712
76953
|
summaryStart(context, payload) {
|
|
@@ -76828,24 +77069,6 @@ var require_events3 = __commonJS({
|
|
|
76828
77069
|
};
|
|
76829
77070
|
}
|
|
76830
77071
|
};
|
|
76831
|
-
exports2.DecisionEvents = {
|
|
76832
|
-
/** Emitted when an LLM decision is recorded. */
|
|
76833
|
-
decisionRecorded(context, payload) {
|
|
76834
|
-
return {
|
|
76835
|
-
type: "decision:recorded",
|
|
76836
|
-
time: Date.now(),
|
|
76837
|
-
source: "daemon",
|
|
76838
|
-
context: {
|
|
76839
|
-
sessionId: context.sessionId,
|
|
76840
|
-
correlationId: context.correlationId,
|
|
76841
|
-
traceId: context.traceId,
|
|
76842
|
-
hook: context.hook,
|
|
76843
|
-
taskId: context.taskId
|
|
76844
|
-
},
|
|
76845
|
-
payload
|
|
76846
|
-
};
|
|
76847
|
-
}
|
|
76848
|
-
};
|
|
76849
77072
|
}
|
|
76850
77073
|
});
|
|
76851
77074
|
|
|
@@ -77001,15 +77224,20 @@ var require_update_summary = __commonJS({
|
|
|
77001
77224
|
"use strict";
|
|
77002
77225
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
77003
77226
|
exports2.buildPersonaContext = void 0;
|
|
77227
|
+
exports2.resetAnalysisGuard = resetAnalysisGuard;
|
|
77004
77228
|
exports2.interpolateTemplate = interpolateTemplate;
|
|
77005
77229
|
exports2.updateSessionSummary = updateSessionSummary;
|
|
77006
77230
|
var core_1 = require_dist4();
|
|
77007
77231
|
var events_js_1 = require_events3();
|
|
77232
|
+
var types_1 = require_dist();
|
|
77008
77233
|
var zod_1 = require_zod();
|
|
77009
77234
|
var types_js_1 = require_types4();
|
|
77010
77235
|
var state_js_1 = require_state5();
|
|
77011
77236
|
var persona_utils_js_1 = require_persona_utils();
|
|
77012
77237
|
var persona_selection_js_1 = require_persona_selection();
|
|
77238
|
+
var DECISION_TITLE_SKIP = "Skip session analysis";
|
|
77239
|
+
var DECISION_TITLE_RUN = "Run session analysis";
|
|
77240
|
+
var analysisInFlight = /* @__PURE__ */ new Map();
|
|
77013
77241
|
var PROMPT_FILE = "prompts/session-summary.prompt.txt";
|
|
77014
77242
|
var SNARKY_PROMPT_FILE = "prompts/snarky-message.prompt.txt";
|
|
77015
77243
|
var RESUME_PROMPT_FILE = "prompts/resume-message.prompt.txt";
|
|
@@ -77027,6 +77255,9 @@ var require_update_summary = __commonJS({
|
|
|
77027
77255
|
Object.defineProperty(exports2, "buildPersonaContext", { enumerable: true, get: function() {
|
|
77028
77256
|
return persona_utils_js_2.buildPersonaContext;
|
|
77029
77257
|
} });
|
|
77258
|
+
function resetAnalysisGuard() {
|
|
77259
|
+
analysisInFlight.clear();
|
|
77260
|
+
}
|
|
77030
77261
|
function interpolateTemplate(template, context) {
|
|
77031
77262
|
let result = template;
|
|
77032
77263
|
const conditionalRegex = /\{\{#if\s+(\w+)\}\}([\s\S]*?)\{\{\/if\}\}/g;
|
|
@@ -77060,46 +77291,39 @@ var require_update_summary = __commonJS({
|
|
|
77060
77291
|
await (0, persona_selection_js_1.ensurePersonaForSession)(sessionId, ctx);
|
|
77061
77292
|
const metrics = ctx.transcript.getMetrics();
|
|
77062
77293
|
if (metrics.turnCount === 0) {
|
|
77063
|
-
(0, core_1.logEvent)(ctx.logger,
|
|
77294
|
+
(0, core_1.logEvent)(ctx.logger, types_1.DecisionEvents.decisionRecorded(event.context, {
|
|
77064
77295
|
decision: "skipped",
|
|
77065
77296
|
reason: "BulkProcessingComplete with no user turns (turnCount=0)",
|
|
77066
|
-
|
|
77297
|
+
subsystem: "session-summary",
|
|
77298
|
+
title: DECISION_TITLE_SKIP
|
|
77067
77299
|
}));
|
|
77068
77300
|
return;
|
|
77069
77301
|
}
|
|
77070
|
-
(0, core_1.logEvent)(ctx.logger,
|
|
77302
|
+
(0, core_1.logEvent)(ctx.logger, types_1.DecisionEvents.decisionRecorded(event.context, {
|
|
77071
77303
|
decision: "calling",
|
|
77072
|
-
reason: "
|
|
77073
|
-
|
|
77304
|
+
reason: "Bulk transcript replay complete \u2014 running catch-up analysis",
|
|
77305
|
+
subsystem: "session-summary",
|
|
77306
|
+
title: DECISION_TITLE_RUN
|
|
77074
77307
|
}));
|
|
77075
77308
|
const countdown2 = await loadCountdownState(summaryState, sessionId);
|
|
77076
|
-
void performAnalysis(event, ctx, summaryState, countdown2, "
|
|
77309
|
+
void performAnalysis(event, ctx, summaryState, countdown2, "bulk_replay_complete");
|
|
77077
77310
|
return;
|
|
77078
77311
|
}
|
|
77079
77312
|
const countdown = await loadCountdownState(summaryState, sessionId);
|
|
77080
77313
|
if (isUserPrompt) {
|
|
77081
|
-
(0, core_1.logEvent)(ctx.logger, events_js_1.DecisionEvents.decisionRecorded(event.context, {
|
|
77082
|
-
decision: "calling",
|
|
77083
|
-
reason: "UserPrompt event forces immediate analysis",
|
|
77084
|
-
detail: "session-summary analysis"
|
|
77085
|
-
}));
|
|
77086
77314
|
void performAnalysis(event, ctx, summaryState, countdown, "user_prompt_forced");
|
|
77087
77315
|
return;
|
|
77088
77316
|
}
|
|
77089
77317
|
if (countdown.countdown > 0) {
|
|
77090
|
-
(0, core_1.logEvent)(ctx.logger, events_js_1.DecisionEvents.decisionRecorded(event.context, {
|
|
77091
|
-
decision: "skipped",
|
|
77092
|
-
reason: `countdown not reached (${countdown.countdown} tool results remaining)`,
|
|
77093
|
-
detail: "session-summary analysis"
|
|
77094
|
-
}));
|
|
77095
77318
|
countdown.countdown--;
|
|
77096
77319
|
await saveCountdownState(summaryState, sessionId, countdown);
|
|
77097
77320
|
return;
|
|
77098
77321
|
}
|
|
77099
|
-
(0, core_1.logEvent)(ctx.logger,
|
|
77322
|
+
(0, core_1.logEvent)(ctx.logger, types_1.DecisionEvents.decisionRecorded(event.context, {
|
|
77100
77323
|
decision: "calling",
|
|
77101
|
-
reason: "countdown reached zero
|
|
77102
|
-
|
|
77324
|
+
reason: "Prompt countdown reached zero \u2014 running scheduled analysis",
|
|
77325
|
+
subsystem: "session-summary",
|
|
77326
|
+
title: DECISION_TITLE_RUN
|
|
77103
77327
|
}));
|
|
77104
77328
|
void performAnalysis(event, ctx, summaryState, countdown, "countdown_reached");
|
|
77105
77329
|
}
|
|
@@ -77132,6 +77356,17 @@ var require_update_summary = __commonJS({
|
|
|
77132
77356
|
}
|
|
77133
77357
|
async function performAnalysis(event, ctx, summaryState, countdown, reason) {
|
|
77134
77358
|
const { sessionId } = event.context;
|
|
77359
|
+
if (analysisInFlight.has(sessionId)) {
|
|
77360
|
+
analysisInFlight.set(sessionId, true);
|
|
77361
|
+
(0, core_1.logEvent)(ctx.logger, types_1.DecisionEvents.decisionRecorded(event.context, {
|
|
77362
|
+
decision: "deferred",
|
|
77363
|
+
reason: "Analysis deferred \u2014 will rerun after current analysis completes",
|
|
77364
|
+
subsystem: "session-summary",
|
|
77365
|
+
title: DECISION_TITLE_SKIP
|
|
77366
|
+
}));
|
|
77367
|
+
return;
|
|
77368
|
+
}
|
|
77369
|
+
analysisInFlight.set(sessionId, false);
|
|
77135
77370
|
try {
|
|
77136
77371
|
const startTime = Date.now();
|
|
77137
77372
|
(0, core_1.logEvent)(ctx.logger, events_js_1.SessionSummaryEvents.summaryStart(event.context, {
|
|
@@ -77241,14 +77476,6 @@ var require_update_summary = __commonJS({
|
|
|
77241
77476
|
if (sideEffects.length > 0) {
|
|
77242
77477
|
await Promise.all(sideEffects);
|
|
77243
77478
|
}
|
|
77244
|
-
(0, core_1.logEvent)(ctx.logger, events_js_1.SessionSummaryEvents.summaryFinish(event.context, {
|
|
77245
|
-
session_title: updatedSummary.session_title,
|
|
77246
|
-
session_title_confidence: updatedSummary.session_title_confidence,
|
|
77247
|
-
latest_intent: updatedSummary.latest_intent,
|
|
77248
|
-
latest_intent_confidence: updatedSummary.latest_intent_confidence,
|
|
77249
|
-
processing_time_ms: updatedSummary.stats?.processing_time_ms ?? 0,
|
|
77250
|
-
pivot_detected: updatedSummary.pivot_detected ?? false
|
|
77251
|
-
}));
|
|
77252
77479
|
if (currentSummary && updatedSummary.session_title !== currentSummary.session_title) {
|
|
77253
77480
|
(0, core_1.logEvent)(ctx.logger, events_js_1.SessionSummaryEvents.titleChanged(event.context, {
|
|
77254
77481
|
previousValue: currentSummary.session_title,
|
|
@@ -77263,6 +77490,14 @@ var require_update_summary = __commonJS({
|
|
|
77263
77490
|
confidence: updatedSummary.latest_intent_confidence
|
|
77264
77491
|
}));
|
|
77265
77492
|
}
|
|
77493
|
+
(0, core_1.logEvent)(ctx.logger, events_js_1.SessionSummaryEvents.summaryFinish(event.context, {
|
|
77494
|
+
session_title: updatedSummary.session_title,
|
|
77495
|
+
session_title_confidence: updatedSummary.session_title_confidence,
|
|
77496
|
+
latest_intent: updatedSummary.latest_intent,
|
|
77497
|
+
latest_intent_confidence: updatedSummary.latest_intent_confidence,
|
|
77498
|
+
processing_time_ms: updatedSummary.stats?.processing_time_ms ?? 0,
|
|
77499
|
+
pivot_detected: updatedSummary.pivot_detected ?? false
|
|
77500
|
+
}));
|
|
77266
77501
|
ctx.logger.info("Updated session summary", {
|
|
77267
77502
|
sessionId,
|
|
77268
77503
|
reason,
|
|
@@ -77276,6 +77511,13 @@ var require_update_summary = __commonJS({
|
|
|
77276
77511
|
reason,
|
|
77277
77512
|
error: err instanceof Error ? err.message : String(err)
|
|
77278
77513
|
});
|
|
77514
|
+
} finally {
|
|
77515
|
+
const rerunPending = analysisInFlight.get(sessionId) ?? false;
|
|
77516
|
+
analysisInFlight.delete(sessionId);
|
|
77517
|
+
if (rerunPending) {
|
|
77518
|
+
const freshCountdown = await loadCountdownState(summaryState, sessionId);
|
|
77519
|
+
void performAnalysis(event, ctx, summaryState, freshCountdown, reason);
|
|
77520
|
+
}
|
|
77279
77521
|
}
|
|
77280
77522
|
}
|
|
77281
77523
|
async function loadCurrentSummary(summaryState, sessionId) {
|
|
@@ -77746,7 +77988,7 @@ var require_dist6 = __commonJS({
|
|
|
77746
77988
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p);
|
|
77747
77989
|
};
|
|
77748
77990
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
77749
|
-
exports2.
|
|
77991
|
+
exports2.SessionSummaryEvents = exports2.manifest = void 0;
|
|
77750
77992
|
exports2.register = register;
|
|
77751
77993
|
var index_js_1 = require_handlers();
|
|
77752
77994
|
exports2.manifest = {
|
|
@@ -77768,9 +78010,6 @@ var require_dist6 = __commonJS({
|
|
|
77768
78010
|
Object.defineProperty(exports2, "SessionSummaryEvents", { enumerable: true, get: function() {
|
|
77769
78011
|
return events_js_1.SessionSummaryEvents;
|
|
77770
78012
|
} });
|
|
77771
|
-
Object.defineProperty(exports2, "DecisionEvents", { enumerable: true, get: function() {
|
|
77772
|
-
return events_js_1.DecisionEvents;
|
|
77773
|
-
} });
|
|
77774
78013
|
}
|
|
77775
78014
|
});
|
|
77776
78015
|
|
|
@@ -78284,10 +78523,10 @@ var require_formatter = __commonJS({
|
|
|
78284
78523
|
duration: viewModel.duration,
|
|
78285
78524
|
cwd: viewModel.cwd,
|
|
78286
78525
|
branch: viewModel.branch,
|
|
78526
|
+
branchWT: viewModel.branchWT,
|
|
78287
78527
|
projectDirShort: viewModel.projectDirShort,
|
|
78288
78528
|
projectDirFull: viewModel.projectDirFull,
|
|
78289
78529
|
worktreeName: viewModel.worktreeName,
|
|
78290
|
-
worktreeOrBranch: viewModel.worktreeOrBranch,
|
|
78291
78530
|
summary: convertedSummary,
|
|
78292
78531
|
title: convertedTitle,
|
|
78293
78532
|
logs: logsText,
|
|
@@ -78318,9 +78557,15 @@ var require_formatter = __commonJS({
|
|
|
78318
78557
|
case "projectDirFull":
|
|
78319
78558
|
return this.colorize(value, this.theme.colors.cwd);
|
|
78320
78559
|
case "branch":
|
|
78321
|
-
case "worktreeOrBranch":
|
|
78322
78560
|
case "worktreeName":
|
|
78323
78561
|
return this.colorize(value, branchColor);
|
|
78562
|
+
case "branchWT": {
|
|
78563
|
+
const coloredBranch = this.colorize(value, branchColor);
|
|
78564
|
+
if (!viewModel.worktreeName)
|
|
78565
|
+
return coloredBranch;
|
|
78566
|
+
const wtColor = this.theme.colors.worktreeIndicator ?? "dim";
|
|
78567
|
+
return `${coloredBranch} ${this.colorize("[wt]", wtColor)}`;
|
|
78568
|
+
}
|
|
78324
78569
|
case "summary":
|
|
78325
78570
|
return this.colorize(value, this.theme.colors.summary);
|
|
78326
78571
|
case "title":
|
|
@@ -78732,7 +78977,7 @@ var require_statusline_service = __commonJS({
|
|
|
78732
78977
|
projectDirShort: "",
|
|
78733
78978
|
projectDirFull: "",
|
|
78734
78979
|
worktreeName: "",
|
|
78735
|
-
|
|
78980
|
+
branchWT: "",
|
|
78736
78981
|
warningCount: 0,
|
|
78737
78982
|
errorCount: 0,
|
|
78738
78983
|
logStatus: "normal",
|
|
@@ -79152,7 +79397,7 @@ var require_statusline_service = __commonJS({
|
|
|
79152
79397
|
projectDirShort,
|
|
79153
79398
|
projectDirFull: homeShorten(projectRoot),
|
|
79154
79399
|
worktreeName: worktree?.name ?? "",
|
|
79155
|
-
|
|
79400
|
+
branchWT: (0, formatter_js_1.formatBranch)(branch),
|
|
79156
79401
|
displayMode,
|
|
79157
79402
|
summary: summaryText,
|
|
79158
79403
|
title,
|
|
@@ -79620,11 +79865,11 @@ var require_ui = __commonJS({
|
|
|
79620
79865
|
exports2.handleUiCommand = handleUiCommand;
|
|
79621
79866
|
var node_child_process_1 = require("node:child_process");
|
|
79622
79867
|
var node_path_1 = require("node:path");
|
|
79623
|
-
function
|
|
79868
|
+
function resolveUiPackageDir() {
|
|
79624
79869
|
const cliCommandsDir = __dirname;
|
|
79625
79870
|
const cliPackageDir = (0, node_path_1.resolve)(cliCommandsDir, "..", "..");
|
|
79626
|
-
const
|
|
79627
|
-
return (0, node_path_1.join)(
|
|
79871
|
+
const packagesDir = (0, node_path_1.resolve)(cliPackageDir, "..");
|
|
79872
|
+
return (0, node_path_1.join)(packagesDir, "sidekick-ui");
|
|
79628
79873
|
}
|
|
79629
79874
|
function openBrowser(url, logger) {
|
|
79630
79875
|
const platform = process.platform;
|
|
@@ -79653,29 +79898,26 @@ var require_ui = __commonJS({
|
|
|
79653
79898
|
});
|
|
79654
79899
|
}
|
|
79655
79900
|
}
|
|
79656
|
-
async function handleUiCommand(
|
|
79901
|
+
async function handleUiCommand(logger, stdout, options = {}) {
|
|
79657
79902
|
const port = options.port ?? 3e3;
|
|
79658
79903
|
const host = options.host ?? "localhost";
|
|
79659
79904
|
const shouldOpen = options.open !== false;
|
|
79660
|
-
const
|
|
79661
|
-
const
|
|
79905
|
+
const uiPackageDir = resolveUiPackageDir();
|
|
79906
|
+
const viteBin = (0, node_path_1.join)(uiPackageDir, "node_modules", ".bin", "vite");
|
|
79662
79907
|
const url = `http://${host}:${port}`;
|
|
79663
|
-
const args = ["--port", String(port)];
|
|
79664
|
-
|
|
79665
|
-
|
|
79666
|
-
}
|
|
79667
|
-
logger.info("Starting Sidekick UI server", { port, host, serverScript });
|
|
79668
|
-
const serverProcess = (0, node_child_process_1.spawn)("node", [serverScript, ...args], {
|
|
79908
|
+
const args = ["--port", String(port), "--host", host];
|
|
79909
|
+
logger.info("Starting Sidekick UI server", { port, host, viteBin });
|
|
79910
|
+
const serverProcess = (0, node_child_process_1.spawn)(viteBin, args, {
|
|
79669
79911
|
stdio: ["ignore", "pipe", "pipe"],
|
|
79670
79912
|
// Pipe stdout/stderr so we can capture output
|
|
79671
|
-
cwd:
|
|
79913
|
+
cwd: uiPackageDir
|
|
79672
79914
|
});
|
|
79673
79915
|
let serverStarted = false;
|
|
79674
79916
|
if (serverProcess.stdout) {
|
|
79675
79917
|
serverProcess.stdout.on("data", (data) => {
|
|
79676
79918
|
const output = data.toString();
|
|
79677
79919
|
stdout.write(output);
|
|
79678
|
-
if (!serverStarted && output.includes("
|
|
79920
|
+
if (!serverStarted && output.includes("Local:")) {
|
|
79679
79921
|
serverStarted = true;
|
|
79680
79922
|
stdout.write(`
|
|
79681
79923
|
`);
|
|
@@ -83771,7 +84013,7 @@ var require_cli = __commonJS({
|
|
|
83771
84013
|
var promises_12 = require("node:fs/promises");
|
|
83772
84014
|
var node_stream_1 = require("node:stream");
|
|
83773
84015
|
var yargs_parser_1 = __importDefault2(require_build());
|
|
83774
|
-
var VERSION = true ? "0.1.
|
|
84016
|
+
var VERSION = true ? "0.1.16" : "dev";
|
|
83775
84017
|
var SANDBOX_ERROR_MESSAGE = `Error: Daemon commands cannot run in sandbox mode.
|
|
83776
84018
|
|
|
83777
84019
|
Claude Code's sandbox blocks Unix socket operations required for daemon IPC.
|
|
@@ -83866,7 +84108,6 @@ Example: { "command": "pnpm sidekick daemon status", "dangerouslyDisableSandbox"
|
|
|
83866
84108
|
port: parsed.port,
|
|
83867
84109
|
host: parsed.host,
|
|
83868
84110
|
open: parsed.open,
|
|
83869
|
-
preferProject: parsed["prefer-project"],
|
|
83870
84111
|
sessionIdArg: parsed["session-id"],
|
|
83871
84112
|
messageType: parsed.type,
|
|
83872
84113
|
help: Boolean(parsed.help),
|
|
@@ -84086,11 +84327,10 @@ Run 'sidekick hook --help' for available hooks.
|
|
|
84086
84327
|
}
|
|
84087
84328
|
if (parsed.command === "ui") {
|
|
84088
84329
|
const { handleUiCommand } = await Promise.resolve().then(() => __importStar(require_ui()));
|
|
84089
|
-
const result = await handleUiCommand(runtime.
|
|
84330
|
+
const result = await handleUiCommand(runtime.logger, stdout, {
|
|
84090
84331
|
port: parsed.port,
|
|
84091
84332
|
host: parsed.host,
|
|
84092
|
-
open: parsed.open
|
|
84093
|
-
preferProject: parsed.preferProject
|
|
84333
|
+
open: parsed.open
|
|
84094
84334
|
});
|
|
84095
84335
|
return { exitCode: result.exitCode, stdout: "", stderr: "" };
|
|
84096
84336
|
}
|