@scotthamilton77/sidekick 0.1.18 → 0.1.20
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/assets/sidekick/defaults/core.defaults.yaml +2 -2
- package/assets/sidekick/defaults/llm.defaults.yaml +7 -3
- package/dist/bin.js +1072 -351
- package/dist/daemon.js +779 -292
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -1038,6 +1038,8 @@ var require_hook_events = __commonJS({
|
|
|
1038
1038
|
exports2.isPostToolUseEvent = isPostToolUseEvent;
|
|
1039
1039
|
exports2.isStopEvent = isStopEvent;
|
|
1040
1040
|
exports2.isPreCompactEvent = isPreCompactEvent;
|
|
1041
|
+
exports2.isSubagentStartEvent = isSubagentStartEvent;
|
|
1042
|
+
exports2.isSubagentStopEvent = isSubagentStopEvent;
|
|
1041
1043
|
exports2.HOOK_NAMES = [
|
|
1042
1044
|
"SessionStart",
|
|
1043
1045
|
"SessionEnd",
|
|
@@ -1045,7 +1047,9 @@ var require_hook_events = __commonJS({
|
|
|
1045
1047
|
"PreToolUse",
|
|
1046
1048
|
"PostToolUse",
|
|
1047
1049
|
"Stop",
|
|
1048
|
-
"PreCompact"
|
|
1050
|
+
"PreCompact",
|
|
1051
|
+
"SubagentStart",
|
|
1052
|
+
"SubagentStop"
|
|
1049
1053
|
];
|
|
1050
1054
|
function isSessionStartEvent(event) {
|
|
1051
1055
|
return event.hook === "SessionStart";
|
|
@@ -1068,6 +1072,12 @@ var require_hook_events = __commonJS({
|
|
|
1068
1072
|
function isPreCompactEvent(event) {
|
|
1069
1073
|
return event.hook === "PreCompact";
|
|
1070
1074
|
}
|
|
1075
|
+
function isSubagentStartEvent(event) {
|
|
1076
|
+
return event.hook === "SubagentStart";
|
|
1077
|
+
}
|
|
1078
|
+
function isSubagentStopEvent(event) {
|
|
1079
|
+
return event.hook === "SubagentStop";
|
|
1080
|
+
}
|
|
1071
1081
|
}
|
|
1072
1082
|
});
|
|
1073
1083
|
|
|
@@ -17942,7 +17952,7 @@ var require_hook_input = __commonJS({
|
|
|
17942
17952
|
"../types/dist/hook-input.js"(exports2) {
|
|
17943
17953
|
"use strict";
|
|
17944
17954
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
17945
|
-
exports2.HookInputSchema = exports2.StatuslineInputSchema = exports2.StatuslineWorkspaceSchema = exports2.StatuslineCostSchema = exports2.StatuslineContextWindowSchema = exports2.StatuslineModelSchema = exports2.NotificationInputSchema = exports2.PreCompactInputSchema = exports2.SessionEndInputSchema = exports2.SessionStartInputSchema = exports2.StopInputSchema = exports2.PostToolUseInputSchema = exports2.PreToolUseInputSchema = exports2.UserPromptSubmitInputSchema = exports2.HookInputBaseSchema = void 0;
|
|
17955
|
+
exports2.HookInputSchema = exports2.StatuslineInputSchema = exports2.StatuslineWorkspaceSchema = exports2.StatuslineCostSchema = exports2.StatuslineContextWindowSchema = exports2.StatuslineModelSchema = exports2.SubagentStopInputSchema = exports2.SubagentStartInputSchema = exports2.NotificationInputSchema = exports2.PreCompactInputSchema = exports2.SessionEndInputSchema = exports2.SessionStartInputSchema = exports2.StopInputSchema = exports2.PostToolUseInputSchema = exports2.PreToolUseInputSchema = exports2.UserPromptSubmitInputSchema = exports2.HookInputBaseSchema = void 0;
|
|
17946
17956
|
var zod_1 = require_zod();
|
|
17947
17957
|
exports2.HookInputBaseSchema = zod_1.z.object({
|
|
17948
17958
|
/** Unique identifier for the current Claude session */
|
|
@@ -17954,7 +17964,11 @@ var require_hook_input = __commonJS({
|
|
|
17954
17964
|
/** Current permission level: "default", "plan", "acceptEdits", or "bypassPermissions" */
|
|
17955
17965
|
permission_mode: zod_1.z.string().optional(),
|
|
17956
17966
|
/** Name of the triggered hook (e.g., "UserPromptSubmit", "SessionStart") */
|
|
17957
|
-
hook_event_name: zod_1.z.string()
|
|
17967
|
+
hook_event_name: zod_1.z.string(),
|
|
17968
|
+
/** Unique identifier for the subagent (present when hook fires inside a subagent) */
|
|
17969
|
+
agent_id: zod_1.z.string().optional(),
|
|
17970
|
+
/** Agent type/name: "Bash", "Explore", "Plan", or custom (present when inside a subagent) */
|
|
17971
|
+
agent_type: zod_1.z.string().optional()
|
|
17958
17972
|
});
|
|
17959
17973
|
exports2.UserPromptSubmitInputSchema = exports2.HookInputBaseSchema.extend({
|
|
17960
17974
|
/** The user's message text */
|
|
@@ -18002,6 +18016,26 @@ var require_hook_input = __commonJS({
|
|
|
18002
18016
|
/** Type: "permission_prompt", "idle_prompt", "auth_success", or "elicitation_dialog" */
|
|
18003
18017
|
notification_type: zod_1.z.string()
|
|
18004
18018
|
});
|
|
18019
|
+
exports2.SubagentStartInputSchema = exports2.HookInputBaseSchema.extend({
|
|
18020
|
+
/** Unique identifier for the subagent (required per official docs) */
|
|
18021
|
+
agent_id: zod_1.z.string(),
|
|
18022
|
+
/** Agent name: "Bash", "Explore", "Plan", or custom agent name */
|
|
18023
|
+
agent_type: zod_1.z.string()
|
|
18024
|
+
});
|
|
18025
|
+
exports2.SubagentStopInputSchema = exports2.HookInputBaseSchema.extend({
|
|
18026
|
+
/** Unique identifier for the subagent */
|
|
18027
|
+
agent_id: zod_1.z.string(),
|
|
18028
|
+
/** Agent name */
|
|
18029
|
+
agent_type: zod_1.z.string(),
|
|
18030
|
+
/** Path to subagent's own transcript JSONL */
|
|
18031
|
+
agent_transcript_path: zod_1.z.string(),
|
|
18032
|
+
/** Text content of the subagent's final response */
|
|
18033
|
+
last_assistant_message: zod_1.z.string(),
|
|
18034
|
+
/** Permission mode for the subagent session */
|
|
18035
|
+
permission_mode: zod_1.z.string(),
|
|
18036
|
+
/** Optional: whether stop hook is active (probe doc says never populated; official docs show false) */
|
|
18037
|
+
stop_hook_active: zod_1.z.boolean().optional()
|
|
18038
|
+
});
|
|
18005
18039
|
exports2.StatuslineModelSchema = zod_1.z.object({
|
|
18006
18040
|
/** Full model identifier (e.g., "claude-opus-4-1") */
|
|
18007
18041
|
id: zod_1.z.string(),
|
|
@@ -18057,13 +18091,15 @@ var require_hook_input = __commonJS({
|
|
|
18057
18091
|
output_style: zod_1.z.object({ name: zod_1.z.string() }).optional()
|
|
18058
18092
|
});
|
|
18059
18093
|
exports2.HookInputSchema = zod_1.z.union([
|
|
18094
|
+
exports2.SessionStartInputSchema,
|
|
18095
|
+
exports2.SessionEndInputSchema,
|
|
18060
18096
|
exports2.UserPromptSubmitInputSchema,
|
|
18061
18097
|
exports2.PreToolUseInputSchema,
|
|
18062
18098
|
exports2.PostToolUseInputSchema,
|
|
18063
18099
|
exports2.StopInputSchema,
|
|
18064
|
-
exports2.SessionStartInputSchema,
|
|
18065
|
-
exports2.SessionEndInputSchema,
|
|
18066
18100
|
exports2.PreCompactInputSchema,
|
|
18101
|
+
exports2.SubagentStartInputSchema,
|
|
18102
|
+
exports2.SubagentStopInputSchema,
|
|
18067
18103
|
exports2.NotificationInputSchema,
|
|
18068
18104
|
exports2.HookInputBaseSchema
|
|
18069
18105
|
// Fallback for hooks without extra fields
|
|
@@ -18160,9 +18196,11 @@ var require_setup_status = __commonJS({
|
|
|
18160
18196
|
"missing",
|
|
18161
18197
|
// User declined or entries not present
|
|
18162
18198
|
"incomplete",
|
|
18163
|
-
//
|
|
18164
|
-
"installed"
|
|
18165
|
-
//
|
|
18199
|
+
// .sidekick/.gitignore exists but missing required entries (legacy: partial root section)
|
|
18200
|
+
"installed",
|
|
18201
|
+
// .sidekick/.gitignore present with all entries (new format)
|
|
18202
|
+
"legacy"
|
|
18203
|
+
// Root .gitignore has old marked section — functional, migrate recommended
|
|
18166
18204
|
]);
|
|
18167
18205
|
exports2.ProjectApiKeyValueSchema = zod_1.z.union([exports2.ProjectApiKeyHealthSchema, exports2.ProjectApiKeyStatusSchema]);
|
|
18168
18206
|
exports2.ProjectSetupStatusSchema = zod_1.z.object({
|
|
@@ -27199,6 +27237,18 @@ var require_dist2 = __commonJS({
|
|
|
27199
27237
|
}
|
|
27200
27238
|
});
|
|
27201
27239
|
|
|
27240
|
+
// ../sidekick-core/dist/error-utils.js
|
|
27241
|
+
var require_error_utils = __commonJS({
|
|
27242
|
+
"../sidekick-core/dist/error-utils.js"(exports2) {
|
|
27243
|
+
"use strict";
|
|
27244
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
27245
|
+
exports2.toErrorMessage = toErrorMessage;
|
|
27246
|
+
function toErrorMessage(error) {
|
|
27247
|
+
return error instanceof Error ? error.message : String(error);
|
|
27248
|
+
}
|
|
27249
|
+
}
|
|
27250
|
+
});
|
|
27251
|
+
|
|
27202
27252
|
// ../sidekick-core/dist/assets.js
|
|
27203
27253
|
var require_assets = __commonJS({
|
|
27204
27254
|
"../sidekick-core/dist/assets.js"(exports2) {
|
|
@@ -27212,6 +27262,7 @@ var require_assets = __commonJS({
|
|
|
27212
27262
|
var yaml_1 = require_dist2();
|
|
27213
27263
|
var node_os_1 = require("node:os");
|
|
27214
27264
|
var node_path_1 = require("node:path");
|
|
27265
|
+
var error_utils_js_1 = require_error_utils();
|
|
27215
27266
|
function createCascadingResolver(options) {
|
|
27216
27267
|
const { cascadeLayers } = options;
|
|
27217
27268
|
const findFile = (relativePath) => {
|
|
@@ -27261,7 +27312,7 @@ var require_assets = __commonJS({
|
|
|
27261
27312
|
try {
|
|
27262
27313
|
return (0, yaml_1.parse)(content);
|
|
27263
27314
|
} catch (error) {
|
|
27264
|
-
throw new Error(`Failed to parse YAML file ${relativePath}: ${
|
|
27315
|
+
throw new Error(`Failed to parse YAML file ${relativePath}: ${(0, error_utils_js_1.toErrorMessage)(error)}`, { cause: error });
|
|
27265
27316
|
}
|
|
27266
27317
|
},
|
|
27267
27318
|
cascadeLayers
|
|
@@ -27336,6 +27387,7 @@ var require_persona_loader = __commonJS({
|
|
|
27336
27387
|
var node_path_1 = require("node:path");
|
|
27337
27388
|
var types_1 = require_dist();
|
|
27338
27389
|
var assets_js_1 = require_assets();
|
|
27390
|
+
var error_utils_js_1 = require_error_utils();
|
|
27339
27391
|
function buildPersonaCascadeLayers(defaultPersonasDir, homeDir, projectRoot) {
|
|
27340
27392
|
const layers = [];
|
|
27341
27393
|
layers.push(defaultPersonasDir);
|
|
@@ -27363,7 +27415,7 @@ var require_persona_loader = __commonJS({
|
|
|
27363
27415
|
}
|
|
27364
27416
|
return result.data;
|
|
27365
27417
|
} catch (error) {
|
|
27366
|
-
const message =
|
|
27418
|
+
const message = (0, error_utils_js_1.toErrorMessage)(error);
|
|
27367
27419
|
logger?.warn(`Failed to load persona file ${filename}: ${message}`);
|
|
27368
27420
|
return null;
|
|
27369
27421
|
}
|
|
@@ -27946,6 +27998,7 @@ var require_config2 = __commonJS({
|
|
|
27946
27998
|
var node_path_1 = require("node:path");
|
|
27947
27999
|
var yaml_1 = require_dist2();
|
|
27948
28000
|
var v4_1 = require_v4();
|
|
28001
|
+
var error_utils_js_1 = require_error_utils();
|
|
27949
28002
|
function deepFreeze(obj) {
|
|
27950
28003
|
if (obj === null || typeof obj !== "object") {
|
|
27951
28004
|
return obj;
|
|
@@ -27972,7 +28025,7 @@ var require_config2 = __commonJS({
|
|
|
27972
28025
|
consoleEnabled: v4_1.z.boolean(),
|
|
27973
28026
|
/** Per-component log level overrides. Keys are component names (e.g., 'reminders', 'statusline'). */
|
|
27974
28027
|
components: v4_1.z.record(v4_1.z.string(), LogLevelSchema).optional(),
|
|
27975
|
-
/** Log rotation settings. Defaults
|
|
28028
|
+
/** Log rotation settings. Defaults come from core.defaults.yaml (2MB/2 files). */
|
|
27976
28029
|
rotation: v4_1.z.object({
|
|
27977
28030
|
maxSizeBytes: v4_1.z.number().min(1),
|
|
27978
28031
|
maxFiles: v4_1.z.number().min(1)
|
|
@@ -28022,7 +28075,10 @@ var require_config2 = __commonJS({
|
|
|
28022
28075
|
fallbackProfileId: v4_1.z.string().optional(),
|
|
28023
28076
|
// OpenRouter-specific provider routing (ignored for other providers)
|
|
28024
28077
|
providerAllowlist: v4_1.z.array(v4_1.z.string()).optional(),
|
|
28025
|
-
providerBlocklist: v4_1.z.array(v4_1.z.string()).optional()
|
|
28078
|
+
providerBlocklist: v4_1.z.array(v4_1.z.string()).optional(),
|
|
28079
|
+
// OpenRouter-specific: toggle the model's reasoning mode (maps to reasoning.enabled).
|
|
28080
|
+
// Ignored for non-openrouter providers.
|
|
28081
|
+
reasoning: v4_1.z.boolean().optional()
|
|
28026
28082
|
});
|
|
28027
28083
|
exports2.LlmConfigSchema = v4_1.z.object({
|
|
28028
28084
|
defaultProfile: v4_1.z.string(),
|
|
@@ -28138,7 +28194,7 @@ var require_config2 = __commonJS({
|
|
|
28138
28194
|
const parsed = (0, yaml_1.parse)(content);
|
|
28139
28195
|
return parsed ?? {};
|
|
28140
28196
|
} catch (err) {
|
|
28141
|
-
const message =
|
|
28197
|
+
const message = (0, error_utils_js_1.toErrorMessage)(err);
|
|
28142
28198
|
throw new Error(`Failed to parse YAML at ${filePath}: ${message}`, { cause: err });
|
|
28143
28199
|
}
|
|
28144
28200
|
}
|
|
@@ -28446,6 +28502,7 @@ var require_config_writer = __commonJS({
|
|
|
28446
28502
|
var node_os_1 = require("node:os");
|
|
28447
28503
|
var node_path_1 = require("node:path");
|
|
28448
28504
|
var yaml_1 = __importDefault2(require_dist2());
|
|
28505
|
+
var error_utils_js_1 = require_error_utils();
|
|
28449
28506
|
var config_1 = require_config2();
|
|
28450
28507
|
var VALID_DOMAINS = /* @__PURE__ */ new Set(["core", "llm", "transcript", "features"]);
|
|
28451
28508
|
var FORBIDDEN_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
@@ -28572,7 +28629,7 @@ var require_config_writer = __commonJS({
|
|
|
28572
28629
|
} catch {
|
|
28573
28630
|
}
|
|
28574
28631
|
}
|
|
28575
|
-
const message =
|
|
28632
|
+
const message = (0, error_utils_js_1.toErrorMessage)(err);
|
|
28576
28633
|
throw new Error(`Configuration validation failed after setting "${dotPath}": ${message}`, { cause: err });
|
|
28577
28634
|
}
|
|
28578
28635
|
return {
|
|
@@ -33736,7 +33793,12 @@ var require_log_events = __commonJS({
|
|
|
33736
33793
|
"use strict";
|
|
33737
33794
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
33738
33795
|
exports2.LogEvents = void 0;
|
|
33796
|
+
exports2.setSessionLogWriter = setSessionLogWriter;
|
|
33739
33797
|
exports2.logEvent = logEvent;
|
|
33798
|
+
var sessionLogWriter = null;
|
|
33799
|
+
function setSessionLogWriter(writer) {
|
|
33800
|
+
sessionLogWriter = writer;
|
|
33801
|
+
}
|
|
33740
33802
|
function buildContext(ctx) {
|
|
33741
33803
|
return {
|
|
33742
33804
|
sessionId: ctx.sessionId,
|
|
@@ -34143,10 +34205,219 @@ var require_log_events = __commonJS({
|
|
|
34143
34205
|
source: event.source,
|
|
34144
34206
|
...meta
|
|
34145
34207
|
});
|
|
34208
|
+
if (sessionLogWriter && event.context.sessionId) {
|
|
34209
|
+
const logFile = event.source === "cli" ? "sidekick.log" : "sidekickd.log";
|
|
34210
|
+
const line = JSON.stringify({
|
|
34211
|
+
time: event.time,
|
|
34212
|
+
type: event.type,
|
|
34213
|
+
source: event.source,
|
|
34214
|
+
context: event.context,
|
|
34215
|
+
...meta
|
|
34216
|
+
}) + "\n";
|
|
34217
|
+
sessionLogWriter.write(event.context.sessionId, logFile, line).catch(() => {
|
|
34218
|
+
});
|
|
34219
|
+
}
|
|
34146
34220
|
}
|
|
34147
34221
|
}
|
|
34148
34222
|
});
|
|
34149
34223
|
|
|
34224
|
+
// ../sidekick-core/dist/staging-paths.js
|
|
34225
|
+
var require_staging_paths = __commonJS({
|
|
34226
|
+
"../sidekick-core/dist/staging-paths.js"(exports2) {
|
|
34227
|
+
"use strict";
|
|
34228
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
34229
|
+
exports2.CONSUMED_FILE_PATTERN = void 0;
|
|
34230
|
+
exports2.getStagingRoot = getStagingRoot;
|
|
34231
|
+
exports2.getHookDir = getHookDir;
|
|
34232
|
+
exports2.getReminderPath = getReminderPath;
|
|
34233
|
+
exports2.isValidPathSegment = isValidPathSegment;
|
|
34234
|
+
exports2.validatePathSegment = validatePathSegment;
|
|
34235
|
+
exports2.filterActiveReminderFiles = filterActiveReminderFiles;
|
|
34236
|
+
exports2.createConsumedFilePattern = createConsumedFilePattern;
|
|
34237
|
+
exports2.extractConsumedTimestamp = extractConsumedTimestamp;
|
|
34238
|
+
var node_path_1 = require("node:path");
|
|
34239
|
+
function getStagingRoot(stateDir, sessionId) {
|
|
34240
|
+
return (0, node_path_1.join)(stateDir, "sessions", sessionId, "stage");
|
|
34241
|
+
}
|
|
34242
|
+
function getHookDir(stateDir, sessionId, hookName) {
|
|
34243
|
+
return (0, node_path_1.join)(getStagingRoot(stateDir, sessionId), hookName);
|
|
34244
|
+
}
|
|
34245
|
+
function getReminderPath(stateDir, sessionId, hookName, reminderName) {
|
|
34246
|
+
return (0, node_path_1.join)(getHookDir(stateDir, sessionId, hookName), `${reminderName}.json`);
|
|
34247
|
+
}
|
|
34248
|
+
function isValidPathSegment(s) {
|
|
34249
|
+
if (s === "")
|
|
34250
|
+
return false;
|
|
34251
|
+
if (s === "." || s === "..")
|
|
34252
|
+
return false;
|
|
34253
|
+
if (s.includes("/") || s.includes("\\"))
|
|
34254
|
+
return false;
|
|
34255
|
+
if ((0, node_path_1.basename)(s) !== s)
|
|
34256
|
+
return false;
|
|
34257
|
+
return /^[a-zA-Z0-9._-]+$/.test(s);
|
|
34258
|
+
}
|
|
34259
|
+
function validatePathSegment(segment, name) {
|
|
34260
|
+
if (!isValidPathSegment(segment)) {
|
|
34261
|
+
throw new Error(`Invalid ${name}: must be a non-empty alphanumeric string without path separators`);
|
|
34262
|
+
}
|
|
34263
|
+
}
|
|
34264
|
+
exports2.CONSUMED_FILE_PATTERN = /\.\d+\.json$/;
|
|
34265
|
+
function filterActiveReminderFiles(files) {
|
|
34266
|
+
return files.filter((f) => f.endsWith(".json") && !exports2.CONSUMED_FILE_PATTERN.test(f));
|
|
34267
|
+
}
|
|
34268
|
+
function createConsumedFilePattern(reminderName) {
|
|
34269
|
+
return new RegExp(`^${reminderName}\\.(\\d+)\\.json$`);
|
|
34270
|
+
}
|
|
34271
|
+
function extractConsumedTimestamp(filename, reminderName) {
|
|
34272
|
+
const pattern = createConsumedFilePattern(reminderName);
|
|
34273
|
+
const match = pattern.exec(filename);
|
|
34274
|
+
return match ? parseInt(match[1], 10) : null;
|
|
34275
|
+
}
|
|
34276
|
+
}
|
|
34277
|
+
});
|
|
34278
|
+
|
|
34279
|
+
// ../sidekick-core/dist/session-log-writer.js
|
|
34280
|
+
var require_session_log_writer = __commonJS({
|
|
34281
|
+
"../sidekick-core/dist/session-log-writer.js"(exports2) {
|
|
34282
|
+
"use strict";
|
|
34283
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
34284
|
+
exports2.SessionLogWriter = void 0;
|
|
34285
|
+
var promises_12 = require("node:fs/promises");
|
|
34286
|
+
var node_path_1 = require("node:path");
|
|
34287
|
+
var node_fs_1 = require("node:fs");
|
|
34288
|
+
var staging_paths_js_1 = require_staging_paths();
|
|
34289
|
+
var SessionLogWriter = class {
|
|
34290
|
+
sessionsDir;
|
|
34291
|
+
maxHandles;
|
|
34292
|
+
idleTimeoutMs;
|
|
34293
|
+
/** Map key: `${sessionId}/${logFile}` */
|
|
34294
|
+
handles = /* @__PURE__ */ new Map();
|
|
34295
|
+
/** Sentinel map to prevent duplicate handle creation on concurrent writes */
|
|
34296
|
+
pendingCreation = /* @__PURE__ */ new Map();
|
|
34297
|
+
constructor(options) {
|
|
34298
|
+
this.sessionsDir = options.sessionsDir;
|
|
34299
|
+
this.maxHandles = options.maxHandles ?? 10;
|
|
34300
|
+
this.idleTimeoutMs = options.idleTimeoutMs ?? 30 * 60 * 1e3;
|
|
34301
|
+
}
|
|
34302
|
+
get handleCount() {
|
|
34303
|
+
return this.handles.size;
|
|
34304
|
+
}
|
|
34305
|
+
/**
|
|
34306
|
+
* Write an NDJSON line to a per-session log file.
|
|
34307
|
+
* Creates the directory and file handle lazily.
|
|
34308
|
+
* Skips if sessionId is empty (daemon lifecycle events before session exists).
|
|
34309
|
+
*/
|
|
34310
|
+
async write(sessionId, logFile, line) {
|
|
34311
|
+
if (!sessionId)
|
|
34312
|
+
return;
|
|
34313
|
+
if (!(0, staging_paths_js_1.isValidPathSegment)(sessionId) || !(0, staging_paths_js_1.isValidPathSegment)(logFile))
|
|
34314
|
+
return;
|
|
34315
|
+
const key = `${sessionId}/${logFile}`;
|
|
34316
|
+
const pending = this.pendingCreation.get(key);
|
|
34317
|
+
if (pending) {
|
|
34318
|
+
try {
|
|
34319
|
+
await pending;
|
|
34320
|
+
} catch {
|
|
34321
|
+
}
|
|
34322
|
+
}
|
|
34323
|
+
let entry = this.handles.get(key);
|
|
34324
|
+
if (!entry) {
|
|
34325
|
+
if (this.handles.size >= this.maxHandles) {
|
|
34326
|
+
this.evictLRU();
|
|
34327
|
+
}
|
|
34328
|
+
const creationPromise = this.createHandle(sessionId, logFile);
|
|
34329
|
+
this.pendingCreation.set(key, creationPromise);
|
|
34330
|
+
try {
|
|
34331
|
+
entry = await creationPromise;
|
|
34332
|
+
this.handles.set(key, entry);
|
|
34333
|
+
} finally {
|
|
34334
|
+
this.pendingCreation.delete(key);
|
|
34335
|
+
}
|
|
34336
|
+
}
|
|
34337
|
+
await entry.ready;
|
|
34338
|
+
entry.lastUsed = Date.now();
|
|
34339
|
+
this.resetIdleTimer(key, entry);
|
|
34340
|
+
return new Promise((resolve3, reject) => {
|
|
34341
|
+
entry.stream.write(line, (err) => {
|
|
34342
|
+
if (err) {
|
|
34343
|
+
void this.closeHandle(key);
|
|
34344
|
+
reject(err);
|
|
34345
|
+
} else {
|
|
34346
|
+
resolve3();
|
|
34347
|
+
}
|
|
34348
|
+
});
|
|
34349
|
+
});
|
|
34350
|
+
}
|
|
34351
|
+
async createHandle(sessionId, logFile) {
|
|
34352
|
+
const logDir = (0, node_path_1.join)(this.sessionsDir, sessionId, "logs");
|
|
34353
|
+
await (0, promises_12.mkdir)(logDir, { recursive: true });
|
|
34354
|
+
const filePath = (0, node_path_1.join)(logDir, logFile);
|
|
34355
|
+
const stream = (0, node_fs_1.createWriteStream)(filePath, { flags: "a" });
|
|
34356
|
+
const ready = new Promise((resolve3, reject) => {
|
|
34357
|
+
stream.once("open", () => resolve3());
|
|
34358
|
+
stream.once("error", (err) => {
|
|
34359
|
+
stream.destroy();
|
|
34360
|
+
reject(err);
|
|
34361
|
+
});
|
|
34362
|
+
});
|
|
34363
|
+
return {
|
|
34364
|
+
stream,
|
|
34365
|
+
lastUsed: Date.now(),
|
|
34366
|
+
timer: null,
|
|
34367
|
+
ready
|
|
34368
|
+
};
|
|
34369
|
+
}
|
|
34370
|
+
/** Close all handles for a specific session. */
|
|
34371
|
+
async closeSession(sessionId) {
|
|
34372
|
+
const prefix = `${sessionId}/`;
|
|
34373
|
+
const toClose = [];
|
|
34374
|
+
for (const key of this.handles.keys()) {
|
|
34375
|
+
if (key.startsWith(prefix)) {
|
|
34376
|
+
toClose.push(key);
|
|
34377
|
+
}
|
|
34378
|
+
}
|
|
34379
|
+
await Promise.all(toClose.map((key) => this.closeHandle(key)));
|
|
34380
|
+
}
|
|
34381
|
+
/** Close all open handles. */
|
|
34382
|
+
async closeAll() {
|
|
34383
|
+
const keys = [...this.handles.keys()];
|
|
34384
|
+
await Promise.all(keys.map((key) => this.closeHandle(key)));
|
|
34385
|
+
}
|
|
34386
|
+
async closeHandle(key) {
|
|
34387
|
+
const entry = this.handles.get(key);
|
|
34388
|
+
if (!entry)
|
|
34389
|
+
return;
|
|
34390
|
+
if (entry.timer)
|
|
34391
|
+
clearTimeout(entry.timer);
|
|
34392
|
+
this.handles.delete(key);
|
|
34393
|
+
return new Promise((resolve3) => {
|
|
34394
|
+
entry.stream.end(() => resolve3());
|
|
34395
|
+
});
|
|
34396
|
+
}
|
|
34397
|
+
evictLRU() {
|
|
34398
|
+
let oldestKey = "";
|
|
34399
|
+
let oldestTime = Infinity;
|
|
34400
|
+
for (const [key, entry] of this.handles) {
|
|
34401
|
+
if (entry.lastUsed < oldestTime) {
|
|
34402
|
+
oldestTime = entry.lastUsed;
|
|
34403
|
+
oldestKey = key;
|
|
34404
|
+
}
|
|
34405
|
+
}
|
|
34406
|
+
void this.closeHandle(oldestKey);
|
|
34407
|
+
}
|
|
34408
|
+
resetIdleTimer(key, entry) {
|
|
34409
|
+
if (entry.timer)
|
|
34410
|
+
clearTimeout(entry.timer);
|
|
34411
|
+
entry.timer = setTimeout(() => {
|
|
34412
|
+
void this.closeHandle(key);
|
|
34413
|
+
}, this.idleTimeoutMs);
|
|
34414
|
+
entry.timer.unref();
|
|
34415
|
+
}
|
|
34416
|
+
};
|
|
34417
|
+
exports2.SessionLogWriter = SessionLogWriter;
|
|
34418
|
+
}
|
|
34419
|
+
});
|
|
34420
|
+
|
|
34150
34421
|
// ../../node_modules/.pnpm/date-fns@4.1.0/node_modules/date-fns/constants.cjs
|
|
34151
34422
|
var require_constants2 = __commonJS({
|
|
34152
34423
|
"../../node_modules/.pnpm/date-fns@4.1.0/node_modules/date-fns/constants.cjs"(exports2) {
|
|
@@ -45886,7 +46157,7 @@ var require_structured_logging = __commonJS({
|
|
|
45886
46157
|
return mod && mod.__esModule ? mod : { "default": mod };
|
|
45887
46158
|
};
|
|
45888
46159
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
45889
|
-
exports2.DEFAULT_MAX_FILES = exports2.DEFAULT_ROTATE_SIZE_BYTES = exports2.LOG_LEVELS = exports2.logEvent = exports2.LogEvents = void 0;
|
|
46160
|
+
exports2.DEFAULT_MAX_FILES = exports2.DEFAULT_ROTATE_SIZE_BYTES = exports2.LOG_LEVELS = exports2.SessionLogWriter = exports2.setSessionLogWriter = exports2.logEvent = exports2.LogEvents = void 0;
|
|
45890
46161
|
exports2.getComponentLogLevel = getComponentLogLevel;
|
|
45891
46162
|
exports2.createLogManager = createLogManager;
|
|
45892
46163
|
exports2.createContextLogger = createContextLogger;
|
|
@@ -45896,6 +46167,7 @@ var require_structured_logging = __commonJS({
|
|
|
45896
46167
|
var node_fs_1 = require("node:fs");
|
|
45897
46168
|
var node_path_1 = require("node:path");
|
|
45898
46169
|
var node_stream_1 = require("node:stream");
|
|
46170
|
+
var error_utils_js_1 = require_error_utils();
|
|
45899
46171
|
var log_events_1 = require_log_events();
|
|
45900
46172
|
Object.defineProperty(exports2, "LogEvents", { enumerable: true, get: function() {
|
|
45901
46173
|
return log_events_1.LogEvents;
|
|
@@ -45903,6 +46175,13 @@ var require_structured_logging = __commonJS({
|
|
|
45903
46175
|
Object.defineProperty(exports2, "logEvent", { enumerable: true, get: function() {
|
|
45904
46176
|
return log_events_1.logEvent;
|
|
45905
46177
|
} });
|
|
46178
|
+
Object.defineProperty(exports2, "setSessionLogWriter", { enumerable: true, get: function() {
|
|
46179
|
+
return log_events_1.setSessionLogWriter;
|
|
46180
|
+
} });
|
|
46181
|
+
var session_log_writer_1 = require_session_log_writer();
|
|
46182
|
+
Object.defineProperty(exports2, "SessionLogWriter", { enumerable: true, get: function() {
|
|
46183
|
+
return session_log_writer_1.SessionLogWriter;
|
|
46184
|
+
} });
|
|
45906
46185
|
exports2.LOG_LEVELS = {
|
|
45907
46186
|
trace: 10,
|
|
45908
46187
|
debug: 20,
|
|
@@ -45918,8 +46197,8 @@ var require_structured_logging = __commonJS({
|
|
|
45918
46197
|
}
|
|
45919
46198
|
return defaultLevel;
|
|
45920
46199
|
}
|
|
45921
|
-
exports2.DEFAULT_ROTATE_SIZE_BYTES =
|
|
45922
|
-
exports2.DEFAULT_MAX_FILES =
|
|
46200
|
+
exports2.DEFAULT_ROTATE_SIZE_BYTES = 2 * 1024 * 1024;
|
|
46201
|
+
exports2.DEFAULT_MAX_FILES = 2;
|
|
45923
46202
|
var DEFAULT_REDACT_KEYS = [
|
|
45924
46203
|
"apiKey",
|
|
45925
46204
|
"token",
|
|
@@ -46260,7 +46539,7 @@ var require_structured_logging = __commonJS({
|
|
|
46260
46539
|
upgradeOptions.onUpgradeError(err);
|
|
46261
46540
|
}
|
|
46262
46541
|
activeLogger.error("Failed to upgrade to Pino logger", {
|
|
46263
|
-
error:
|
|
46542
|
+
error: (0, error_utils_js_1.toErrorMessage)(err)
|
|
46264
46543
|
});
|
|
46265
46544
|
}
|
|
46266
46545
|
},
|
|
@@ -46276,7 +46555,7 @@ var require_structured_logging = __commonJS({
|
|
|
46276
46555
|
};
|
|
46277
46556
|
const rejectionHandler = (reason) => {
|
|
46278
46557
|
logger.fatal("Unhandled promise rejection", {
|
|
46279
|
-
reason:
|
|
46558
|
+
reason: (0, error_utils_js_1.toErrorMessage)(reason)
|
|
46280
46559
|
});
|
|
46281
46560
|
};
|
|
46282
46561
|
process.on("uncaughtException", uncaughtHandler);
|
|
@@ -46369,13 +46648,11 @@ var require_daemon_client2 = __commonJS({
|
|
|
46369
46648
|
var client_js_1 = require_client();
|
|
46370
46649
|
var transport_js_1 = require_transport();
|
|
46371
46650
|
var sandbox_js_1 = require_sandbox();
|
|
46651
|
+
var error_utils_js_1 = require_error_utils();
|
|
46372
46652
|
var LOCK_TIMEOUT_MS = 1e4;
|
|
46373
46653
|
var LOCK_RETRY_INTERVAL_MS = 100;
|
|
46374
46654
|
var LOCK_STALE_THRESHOLD_MS = 3e4;
|
|
46375
46655
|
var CLIENT_VERSION = require_package3().version;
|
|
46376
|
-
function toErrorMsg(err) {
|
|
46377
|
-
return err instanceof Error ? err.message : String(err);
|
|
46378
|
-
}
|
|
46379
46656
|
var DaemonClient = class {
|
|
46380
46657
|
projectDir;
|
|
46381
46658
|
logger;
|
|
@@ -46741,7 +47018,7 @@ var require_daemon_client2 = __commonJS({
|
|
|
46741
47018
|
} catch (err) {
|
|
46742
47019
|
logger.debug("Graceful stop failed, falling back to SIGKILL", {
|
|
46743
47020
|
pid: info.pid,
|
|
46744
|
-
error:
|
|
47021
|
+
error: (0, error_utils_js_1.toErrorMessage)(err)
|
|
46745
47022
|
});
|
|
46746
47023
|
}
|
|
46747
47024
|
}
|
|
@@ -46750,7 +47027,7 @@ var require_daemon_client2 = __commonJS({
|
|
|
46750
47027
|
logger.info("Killed daemon", { pid: info.pid, projectDir: info.projectDir });
|
|
46751
47028
|
results.push({ projectDir: info.projectDir, pid: info.pid, killed: true });
|
|
46752
47029
|
} catch (err) {
|
|
46753
|
-
const msg =
|
|
47030
|
+
const msg = (0, error_utils_js_1.toErrorMessage)(err);
|
|
46754
47031
|
logger.warn("Failed to kill daemon", { pid: info.pid, error: msg });
|
|
46755
47032
|
results.push({ projectDir: info.projectDir, pid: info.pid, killed: false, error: msg });
|
|
46756
47033
|
}
|
|
@@ -46762,7 +47039,7 @@ var require_daemon_client2 = __commonJS({
|
|
|
46762
47039
|
});
|
|
46763
47040
|
}
|
|
46764
47041
|
} catch (err) {
|
|
46765
|
-
logger.warn("Invalid PID file, removing", { pidFile, error:
|
|
47042
|
+
logger.warn("Invalid PID file, removing", { pidFile, error: (0, error_utils_js_1.toErrorMessage)(err) });
|
|
46766
47043
|
await promises_12.default.unlink(pidPath).catch(() => {
|
|
46767
47044
|
});
|
|
46768
47045
|
}
|
|
@@ -46783,7 +47060,7 @@ var require_daemon_client2 = __commonJS({
|
|
|
46783
47060
|
});
|
|
46784
47061
|
} catch (err) {
|
|
46785
47062
|
logger.warn("Failed to run ps \u2014 cannot detect zombie daemons", {
|
|
46786
|
-
error:
|
|
47063
|
+
error: (0, error_utils_js_1.toErrorMessage)(err)
|
|
46787
47064
|
});
|
|
46788
47065
|
return [];
|
|
46789
47066
|
}
|
|
@@ -46844,7 +47121,7 @@ var require_daemon_client2 = __commonJS({
|
|
|
46844
47121
|
logger.info("Killed zombie daemon", { pid: zombie.pid, command: zombie.command });
|
|
46845
47122
|
results.push({ projectDir: "unknown", pid: zombie.pid, killed: true });
|
|
46846
47123
|
} catch (err) {
|
|
46847
|
-
const msg =
|
|
47124
|
+
const msg = (0, error_utils_js_1.toErrorMessage)(err);
|
|
46848
47125
|
logger.warn("Failed to kill zombie daemon", { pid: zombie.pid, error: msg });
|
|
46849
47126
|
results.push({ projectDir: "unknown", pid: zombie.pid, killed: false, error: msg });
|
|
46850
47127
|
}
|
|
@@ -46896,60 +47173,94 @@ var require_gitignore = __commonJS({
|
|
|
46896
47173
|
};
|
|
46897
47174
|
})();
|
|
46898
47175
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
46899
|
-
exports2.GITIGNORE_ENTRIES = exports2.SIDEKICK_SECTION_END = exports2.SIDEKICK_SECTION_START = void 0;
|
|
47176
|
+
exports2.GITIGNORE_ENTRIES = exports2.SIDEKICK_GITIGNORE_HEADER = exports2.SIDEKICK_SECTION_END = exports2.SIDEKICK_SECTION_START = void 0;
|
|
46900
47177
|
exports2.installGitignoreSection = installGitignoreSection;
|
|
46901
|
-
exports2.removeGitignoreSection = removeGitignoreSection;
|
|
46902
47178
|
exports2.detectGitignoreStatus = detectGitignoreStatus;
|
|
47179
|
+
exports2.removeGitignoreSection = removeGitignoreSection;
|
|
47180
|
+
exports2.detectLegacyGitignoreSection = detectLegacyGitignoreSection;
|
|
47181
|
+
exports2.removeLegacyGitignoreSection = removeLegacyGitignoreSection;
|
|
46903
47182
|
var fs = __importStar(require("node:fs/promises"));
|
|
46904
47183
|
var path = __importStar(require("node:path"));
|
|
46905
47184
|
exports2.SIDEKICK_SECTION_START = "# >>> sidekick";
|
|
46906
47185
|
exports2.SIDEKICK_SECTION_END = "# <<< sidekick";
|
|
47186
|
+
exports2.SIDEKICK_GITIGNORE_HEADER = "# Sidekick \u2014 managed file, do not edit manually";
|
|
46907
47187
|
exports2.GITIGNORE_ENTRIES = [
|
|
46908
|
-
"
|
|
46909
|
-
"
|
|
46910
|
-
"
|
|
46911
|
-
"
|
|
46912
|
-
".
|
|
46913
|
-
".
|
|
46914
|
-
"
|
|
46915
|
-
"
|
|
46916
|
-
"
|
|
47188
|
+
"logs/",
|
|
47189
|
+
"sessions/",
|
|
47190
|
+
"state/",
|
|
47191
|
+
"setup-status.json",
|
|
47192
|
+
".env",
|
|
47193
|
+
".env.local",
|
|
47194
|
+
"sidekick*.pid",
|
|
47195
|
+
"sidekick*.token",
|
|
47196
|
+
"*.local.yaml"
|
|
46917
47197
|
];
|
|
46918
47198
|
async function installGitignoreSection(projectDir) {
|
|
46919
|
-
|
|
46920
|
-
let content = "";
|
|
47199
|
+
let status;
|
|
46921
47200
|
try {
|
|
46922
|
-
|
|
47201
|
+
status = await detectGitignoreStatus(projectDir);
|
|
46923
47202
|
} catch (err) {
|
|
46924
|
-
|
|
46925
|
-
return { status: "error", error: `Failed to read .gitignore: ${err.message}` };
|
|
46926
|
-
}
|
|
47203
|
+
return { status: "error", error: `Failed to check gitignore status: ${err.message}` };
|
|
46927
47204
|
}
|
|
46928
|
-
const status = await detectGitignoreStatus(projectDir);
|
|
46929
47205
|
if (status === "installed") {
|
|
46930
47206
|
return { status: "already-installed" };
|
|
46931
47207
|
}
|
|
46932
|
-
|
|
46933
|
-
|
|
46934
|
-
|
|
46935
|
-
|
|
46936
|
-
|
|
46937
|
-
content = "";
|
|
46938
|
-
}
|
|
47208
|
+
const sidekickDir = path.join(projectDir, ".sidekick");
|
|
47209
|
+
try {
|
|
47210
|
+
await fs.mkdir(sidekickDir, { recursive: true });
|
|
47211
|
+
} catch (err) {
|
|
47212
|
+
return { status: "error", error: `Failed to create .sidekick directory: ${err.message}` };
|
|
46939
47213
|
}
|
|
46940
|
-
const
|
|
46941
|
-
const newContent = content.trimEnd() + section + "\n";
|
|
47214
|
+
const content = [exports2.SIDEKICK_GITIGNORE_HEADER, ...exports2.GITIGNORE_ENTRIES].join("\n") + "\n";
|
|
46942
47215
|
try {
|
|
46943
|
-
await fs.writeFile(
|
|
47216
|
+
await fs.writeFile(path.join(sidekickDir, ".gitignore"), content);
|
|
46944
47217
|
return { status: "installed", entriesAdded: exports2.GITIGNORE_ENTRIES };
|
|
46945
47218
|
} catch (err) {
|
|
46946
|
-
return { status: "error", error: `Failed to write .gitignore: ${err.message}` };
|
|
47219
|
+
return { status: "error", error: `Failed to write .sidekick/.gitignore: ${err.message}` };
|
|
46947
47220
|
}
|
|
46948
47221
|
}
|
|
47222
|
+
async function detectGitignoreStatus(projectDir) {
|
|
47223
|
+
const sidekickGitignorePath = path.join(projectDir, ".sidekick", ".gitignore");
|
|
47224
|
+
try {
|
|
47225
|
+
const content = await fs.readFile(sidekickGitignorePath, "utf-8");
|
|
47226
|
+
const missingEntries = exports2.GITIGNORE_ENTRIES.filter((entry) => !content.includes(entry));
|
|
47227
|
+
return missingEntries.length === 0 ? "installed" : "incomplete";
|
|
47228
|
+
} catch (err) {
|
|
47229
|
+
if (err.code !== "ENOENT") {
|
|
47230
|
+
throw err;
|
|
47231
|
+
}
|
|
47232
|
+
}
|
|
47233
|
+
const hasLegacy = await detectLegacyGitignoreSection(projectDir);
|
|
47234
|
+
return hasLegacy ? "legacy" : "missing";
|
|
47235
|
+
}
|
|
46949
47236
|
async function removeGitignoreSection(projectDir) {
|
|
46950
|
-
|
|
47237
|
+
let removed = false;
|
|
46951
47238
|
try {
|
|
46952
|
-
|
|
47239
|
+
await fs.unlink(path.join(projectDir, ".sidekick", ".gitignore"));
|
|
47240
|
+
removed = true;
|
|
47241
|
+
} catch (err) {
|
|
47242
|
+
if (err.code !== "ENOENT") {
|
|
47243
|
+
throw err;
|
|
47244
|
+
}
|
|
47245
|
+
}
|
|
47246
|
+
const legacyRemoved = await removeLegacyGitignoreSection(projectDir);
|
|
47247
|
+
return removed || legacyRemoved;
|
|
47248
|
+
}
|
|
47249
|
+
async function detectLegacyGitignoreSection(projectDir) {
|
|
47250
|
+
try {
|
|
47251
|
+
const content = await fs.readFile(path.join(projectDir, ".gitignore"), "utf-8");
|
|
47252
|
+
return content.includes(exports2.SIDEKICK_SECTION_START);
|
|
47253
|
+
} catch (err) {
|
|
47254
|
+
if (err.code === "ENOENT") {
|
|
47255
|
+
return false;
|
|
47256
|
+
}
|
|
47257
|
+
throw err;
|
|
47258
|
+
}
|
|
47259
|
+
}
|
|
47260
|
+
async function removeLegacyGitignoreSection(projectDir) {
|
|
47261
|
+
const rootGitignorePath = path.join(projectDir, ".gitignore");
|
|
47262
|
+
try {
|
|
47263
|
+
const content = await fs.readFile(rootGitignorePath, "utf-8");
|
|
46953
47264
|
const startIdx = content.indexOf(exports2.SIDEKICK_SECTION_START);
|
|
46954
47265
|
const endIdx = content.indexOf(exports2.SIDEKICK_SECTION_END);
|
|
46955
47266
|
if (startIdx === -1 || endIdx === -1 || endIdx < startIdx) {
|
|
@@ -46961,37 +47272,13 @@ var require_gitignore = __commonJS({
|
|
|
46961
47272
|
const before = content.slice(0, lineStartIdx).trimEnd();
|
|
46962
47273
|
const after = content.slice(actualEndIdx).trimStart();
|
|
46963
47274
|
const newContent = before + (after ? "\n" + after : "") + "\n";
|
|
46964
|
-
await fs.writeFile(
|
|
47275
|
+
await fs.writeFile(rootGitignorePath, newContent);
|
|
46965
47276
|
return true;
|
|
46966
|
-
} catch {
|
|
46967
|
-
|
|
46968
|
-
|
|
46969
|
-
}
|
|
46970
|
-
async function detectGitignoreStatus(projectDir) {
|
|
46971
|
-
const gitignorePath = path.join(projectDir, ".gitignore");
|
|
46972
|
-
try {
|
|
46973
|
-
const content = await fs.readFile(gitignorePath, "utf-8");
|
|
46974
|
-
const hasStart = content.includes(exports2.SIDEKICK_SECTION_START);
|
|
46975
|
-
const hasEnd = content.includes(exports2.SIDEKICK_SECTION_END);
|
|
46976
|
-
if (!hasStart && !hasEnd) {
|
|
46977
|
-
return "missing";
|
|
46978
|
-
}
|
|
46979
|
-
if (!hasStart || !hasEnd) {
|
|
46980
|
-
return "incomplete";
|
|
46981
|
-
}
|
|
46982
|
-
const startIdx = content.indexOf(exports2.SIDEKICK_SECTION_START);
|
|
46983
|
-
const endIdx = content.indexOf(exports2.SIDEKICK_SECTION_END);
|
|
46984
|
-
if (endIdx <= startIdx) {
|
|
46985
|
-
return "incomplete";
|
|
46986
|
-
}
|
|
46987
|
-
const sectionContent = content.slice(startIdx, endIdx + exports2.SIDEKICK_SECTION_END.length);
|
|
46988
|
-
const missingEntries = exports2.GITIGNORE_ENTRIES.filter((entry) => !sectionContent.includes(entry));
|
|
46989
|
-
if (missingEntries.length > 0) {
|
|
46990
|
-
return "incomplete";
|
|
47277
|
+
} catch (err) {
|
|
47278
|
+
if (err.code === "ENOENT") {
|
|
47279
|
+
return false;
|
|
46991
47280
|
}
|
|
46992
|
-
|
|
46993
|
-
} catch {
|
|
46994
|
-
return "missing";
|
|
47281
|
+
throw err;
|
|
46995
47282
|
}
|
|
46996
47283
|
}
|
|
46997
47284
|
}
|
|
@@ -47002,7 +47289,7 @@ var require_errors4 = __commonJS({
|
|
|
47002
47289
|
"../shared-providers/dist/errors.js"(exports2) {
|
|
47003
47290
|
"use strict";
|
|
47004
47291
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
47005
|
-
exports2.TimeoutError = exports2.AuthError = exports2.RateLimitError = exports2.ProviderError = void 0;
|
|
47292
|
+
exports2.MalformedResponseError = exports2.TimeoutError = exports2.AuthError = exports2.RateLimitError = exports2.ProviderError = void 0;
|
|
47006
47293
|
var ProviderError = class _ProviderError extends Error {
|
|
47007
47294
|
provider;
|
|
47008
47295
|
retryable;
|
|
@@ -47043,6 +47330,18 @@ var require_errors4 = __commonJS({
|
|
|
47043
47330
|
}
|
|
47044
47331
|
};
|
|
47045
47332
|
exports2.TimeoutError = TimeoutError;
|
|
47333
|
+
var MalformedResponseError = class _MalformedResponseError extends ProviderError {
|
|
47334
|
+
code;
|
|
47335
|
+
providerMessage;
|
|
47336
|
+
constructor(provider, code, providerMessage, cause) {
|
|
47337
|
+
super(`Malformed response from ${provider}: ${code ?? "unknown"} - ${providerMessage ?? "no message"}`, provider, false, cause);
|
|
47338
|
+
this.name = "MalformedResponseError";
|
|
47339
|
+
this.code = code;
|
|
47340
|
+
this.providerMessage = providerMessage;
|
|
47341
|
+
Object.setPrototypeOf(this, _MalformedResponseError.prototype);
|
|
47342
|
+
}
|
|
47343
|
+
};
|
|
47344
|
+
exports2.MalformedResponseError = MalformedResponseError;
|
|
47046
47345
|
}
|
|
47047
47346
|
});
|
|
47048
47347
|
|
|
@@ -56021,6 +56320,7 @@ var require_base = __commonJS({
|
|
|
56021
56320
|
model: response.model,
|
|
56022
56321
|
durationMs,
|
|
56023
56322
|
usage: response.usage,
|
|
56323
|
+
finishReason: response.finishReason,
|
|
56024
56324
|
status: response.rawResponse.status,
|
|
56025
56325
|
contentLength: response.content.length
|
|
56026
56326
|
});
|
|
@@ -56068,6 +56368,7 @@ var require_openai_native = __commonJS({
|
|
|
56068
56368
|
maxTokens;
|
|
56069
56369
|
providerAllowlist;
|
|
56070
56370
|
providerBlocklist;
|
|
56371
|
+
reasoning;
|
|
56071
56372
|
constructor(config, logger) {
|
|
56072
56373
|
super(logger);
|
|
56073
56374
|
this.id = config.baseURL?.includes("openrouter") ? "openrouter" : "openai";
|
|
@@ -56076,6 +56377,7 @@ var require_openai_native = __commonJS({
|
|
|
56076
56377
|
this.maxTokens = config.maxTokens;
|
|
56077
56378
|
this.providerAllowlist = config.providerAllowlist;
|
|
56078
56379
|
this.providerBlocklist = config.providerBlocklist;
|
|
56380
|
+
this.reasoning = config.reasoning;
|
|
56079
56381
|
this.client = new openai_1.default({
|
|
56080
56382
|
apiKey: config.apiKey,
|
|
56081
56383
|
baseURL: config.baseURL,
|
|
@@ -56091,6 +56393,7 @@ var require_openai_native = __commonJS({
|
|
|
56091
56393
|
maxTokens: this.maxTokens,
|
|
56092
56394
|
providerAllowlist: this.providerAllowlist,
|
|
56093
56395
|
providerBlocklist: this.providerBlocklist,
|
|
56396
|
+
reasoning: this.reasoning,
|
|
56094
56397
|
apiKey: this.redactApiKey(config.apiKey)
|
|
56095
56398
|
});
|
|
56096
56399
|
}
|
|
@@ -56108,6 +56411,7 @@ var require_openai_native = __commonJS({
|
|
|
56108
56411
|
}
|
|
56109
56412
|
} : void 0;
|
|
56110
56413
|
const providerRouting = this.buildProviderRouting();
|
|
56414
|
+
const reasoningParam = this.buildReasoningParam();
|
|
56111
56415
|
const completion = await this.client.chat.completions.create({
|
|
56112
56416
|
model: request.model ?? this.defaultModel,
|
|
56113
56417
|
messages,
|
|
@@ -56115,8 +56419,13 @@ var require_openai_native = __commonJS({
|
|
|
56115
56419
|
max_tokens: this.maxTokens,
|
|
56116
56420
|
response_format: responseFormat,
|
|
56117
56421
|
...providerRouting,
|
|
56422
|
+
...reasoningParam,
|
|
56118
56423
|
...request.additionalParams
|
|
56119
56424
|
});
|
|
56425
|
+
if (!completion.choices || completion.choices.length === 0) {
|
|
56426
|
+
const errorPayload = completion.error;
|
|
56427
|
+
throw new errors_1.MalformedResponseError(this.id, errorPayload?.code, errorPayload?.message);
|
|
56428
|
+
}
|
|
56120
56429
|
const response = {
|
|
56121
56430
|
content: completion.choices[0]?.message?.content ?? "",
|
|
56122
56431
|
model: completion.model,
|
|
@@ -56124,6 +56433,7 @@ var require_openai_native = __commonJS({
|
|
|
56124
56433
|
inputTokens: completion.usage.prompt_tokens,
|
|
56125
56434
|
outputTokens: completion.usage.completion_tokens
|
|
56126
56435
|
} : void 0,
|
|
56436
|
+
finishReason: completion.choices[0]?.finish_reason ?? void 0,
|
|
56127
56437
|
rawResponse: {
|
|
56128
56438
|
status: 200,
|
|
56129
56439
|
body: JSON.stringify(completion)
|
|
@@ -56159,7 +56469,25 @@ var require_openai_native = __commonJS({
|
|
|
56159
56469
|
}
|
|
56160
56470
|
return { provider: providerObj };
|
|
56161
56471
|
}
|
|
56472
|
+
/**
|
|
56473
|
+
* Build OpenRouter reasoning param object.
|
|
56474
|
+
* Returns empty object if reasoning is unset or provider is not OpenRouter.
|
|
56475
|
+
* Maps `reasoning?: boolean` to OpenRouter's `reasoning: { enabled: <bool> }`.
|
|
56476
|
+
* @see https://openrouter.ai/docs/use-cases/reasoning-tokens
|
|
56477
|
+
*/
|
|
56478
|
+
buildReasoningParam() {
|
|
56479
|
+
if (this.id !== "openrouter") {
|
|
56480
|
+
return {};
|
|
56481
|
+
}
|
|
56482
|
+
if (this.reasoning === void 0) {
|
|
56483
|
+
return {};
|
|
56484
|
+
}
|
|
56485
|
+
return { reasoning: { enabled: this.reasoning } };
|
|
56486
|
+
}
|
|
56162
56487
|
mapError(error) {
|
|
56488
|
+
if (error instanceof errors_1.ProviderError) {
|
|
56489
|
+
return error;
|
|
56490
|
+
}
|
|
56163
56491
|
if (error instanceof openai_1.default.APIError) {
|
|
56164
56492
|
if (error.status === 401 || error.status === 403) {
|
|
56165
56493
|
return new errors_1.AuthError(this.id, error);
|
|
@@ -56253,7 +56581,13 @@ var require_claude_cli_spawn = __commonJS({
|
|
|
56253
56581
|
});
|
|
56254
56582
|
const child = (0, node_child_process_1.spawn)(cliPath, args, {
|
|
56255
56583
|
cwd,
|
|
56256
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
56584
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
56585
|
+
// Recursion guard: Sidekick's own Claude Code hooks fire inside any
|
|
56586
|
+
// `claude -p` subprocess we spawn. Without this flag, the subprocess
|
|
56587
|
+
// hook handler would dispatch to the daemon, trigger another LLM call,
|
|
56588
|
+
// spawn another subprocess, and so on. handleHookCommand short-circuits
|
|
56589
|
+
// when SIDEKICK_SUBPROCESS=1 is set. See packages/sidekick-cli/src/commands/hook.ts.
|
|
56590
|
+
env: { ...process.env, SIDEKICK_SUBPROCESS: "1" }
|
|
56257
56591
|
});
|
|
56258
56592
|
let stdout = "";
|
|
56259
56593
|
let stderr = "";
|
|
@@ -56315,6 +56649,31 @@ var require_claude_cli_spawn = __commonJS({
|
|
|
56315
56649
|
}
|
|
56316
56650
|
});
|
|
56317
56651
|
|
|
56652
|
+
// ../shared-providers/dist/providers/anthropic-stop-reason.js
|
|
56653
|
+
var require_anthropic_stop_reason = __commonJS({
|
|
56654
|
+
"../shared-providers/dist/providers/anthropic-stop-reason.js"(exports2) {
|
|
56655
|
+
"use strict";
|
|
56656
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
56657
|
+
exports2.mapAnthropicStopReason = mapAnthropicStopReason;
|
|
56658
|
+
function mapAnthropicStopReason(stopReason) {
|
|
56659
|
+
if (!stopReason)
|
|
56660
|
+
return void 0;
|
|
56661
|
+
switch (stopReason) {
|
|
56662
|
+
case "end_turn":
|
|
56663
|
+
return "stop";
|
|
56664
|
+
case "max_tokens":
|
|
56665
|
+
return "length";
|
|
56666
|
+
case "stop_sequence":
|
|
56667
|
+
return "stop";
|
|
56668
|
+
case "tool_use":
|
|
56669
|
+
return "tool_calls";
|
|
56670
|
+
default:
|
|
56671
|
+
return stopReason;
|
|
56672
|
+
}
|
|
56673
|
+
}
|
|
56674
|
+
}
|
|
56675
|
+
});
|
|
56676
|
+
|
|
56318
56677
|
// ../shared-providers/dist/providers/anthropic-cli.js
|
|
56319
56678
|
var require_anthropic_cli = __commonJS({
|
|
56320
56679
|
"../shared-providers/dist/providers/anthropic-cli.js"(exports2) {
|
|
@@ -56323,6 +56682,7 @@ var require_anthropic_cli = __commonJS({
|
|
|
56323
56682
|
exports2.AnthropicCliProvider = void 0;
|
|
56324
56683
|
var base_1 = require_base();
|
|
56325
56684
|
var claude_cli_spawn_1 = require_claude_cli_spawn();
|
|
56685
|
+
var anthropic_stop_reason_1 = require_anthropic_stop_reason();
|
|
56326
56686
|
var AnthropicCliProvider = class extends base_1.AbstractProvider {
|
|
56327
56687
|
id = "claude-cli";
|
|
56328
56688
|
defaultModel;
|
|
@@ -56384,6 +56744,7 @@ var require_anthropic_cli = __commonJS({
|
|
|
56384
56744
|
inputTokens: parsed.usage.input_tokens ?? 0,
|
|
56385
56745
|
outputTokens: parsed.usage.output_tokens ?? 0
|
|
56386
56746
|
} : void 0,
|
|
56747
|
+
finishReason: (0, anthropic_stop_reason_1.mapAnthropicStopReason)(parsed.stop_reason),
|
|
56387
56748
|
rawResponse: {
|
|
56388
56749
|
status: 200,
|
|
56389
56750
|
body: stdout
|
|
@@ -56655,6 +57016,7 @@ var require_openai_emulator = __commonJS({
|
|
|
56655
57016
|
inputTokens,
|
|
56656
57017
|
outputTokens
|
|
56657
57018
|
},
|
|
57019
|
+
finishReason: "stop",
|
|
56658
57020
|
rawResponse: {
|
|
56659
57021
|
status: 200,
|
|
56660
57022
|
body: JSON.stringify(rawBody)
|
|
@@ -56709,6 +57071,7 @@ var require_openrouter_emulator = __commonJS({
|
|
|
56709
57071
|
inputTokens,
|
|
56710
57072
|
outputTokens
|
|
56711
57073
|
},
|
|
57074
|
+
finishReason: "stop",
|
|
56712
57075
|
rawResponse: {
|
|
56713
57076
|
status: 200,
|
|
56714
57077
|
body: JSON.stringify(rawBody)
|
|
@@ -56729,6 +57092,7 @@ var require_claude_cli_emulator = __commonJS({
|
|
|
56729
57092
|
var node_child_process_1 = require("node:child_process");
|
|
56730
57093
|
var node_path_1 = require("node:path");
|
|
56731
57094
|
var base_1 = require_base();
|
|
57095
|
+
var anthropic_stop_reason_1 = require_anthropic_stop_reason();
|
|
56732
57096
|
var EMULATOR_SCRIPT = `#!/bin/bash
|
|
56733
57097
|
# Claude CLI Emulator Script
|
|
56734
57098
|
STATE_FILE="\${SIDEKICK_EMULATOR_STATE_PATH:-.sidekick/emulator-state/call-counts.json}"
|
|
@@ -56816,6 +57180,7 @@ echo "{\\"content\\":\\"\${CONTENT}\\",\\"message\\":\\"\${CONTENT}\\",\\"model\
|
|
|
56816
57180
|
inputTokens,
|
|
56817
57181
|
outputTokens
|
|
56818
57182
|
},
|
|
57183
|
+
finishReason: (0, anthropic_stop_reason_1.mapAnthropicStopReason)(parsed.stop_reason),
|
|
56819
57184
|
rawResponse: {
|
|
56820
57185
|
status: 0,
|
|
56821
57186
|
// Exit code
|
|
@@ -56952,7 +57317,8 @@ var require_factory = __commonJS({
|
|
|
56952
57317
|
temperature: this.config.temperature,
|
|
56953
57318
|
maxTokens: this.config.maxTokens,
|
|
56954
57319
|
providerAllowlist: this.config.providerAllowlist,
|
|
56955
|
-
providerBlocklist: this.config.providerBlocklist
|
|
57320
|
+
providerBlocklist: this.config.providerBlocklist,
|
|
57321
|
+
reasoning: this.config.reasoning
|
|
56956
57322
|
};
|
|
56957
57323
|
return new openai_native_1.OpenAINativeProvider(openrouterConfig, this.logger);
|
|
56958
57324
|
}
|
|
@@ -57129,7 +57495,9 @@ var require_profile_factory = __commonJS({
|
|
|
57129
57495
|
maxTokens: profile.maxTokens,
|
|
57130
57496
|
// OpenRouter-specific provider routing
|
|
57131
57497
|
providerAllowlist: profile.providerAllowlist ? [...profile.providerAllowlist] : void 0,
|
|
57132
|
-
providerBlocklist: profile.providerBlocklist ? [...profile.providerBlocklist] : void 0
|
|
57498
|
+
providerBlocklist: profile.providerBlocklist ? [...profile.providerBlocklist] : void 0,
|
|
57499
|
+
// OpenRouter-specific reasoning toggle
|
|
57500
|
+
reasoning: profile.reasoning
|
|
57133
57501
|
}, this.logger);
|
|
57134
57502
|
return factory.create();
|
|
57135
57503
|
}
|
|
@@ -57184,7 +57552,7 @@ var require_dist3 = __commonJS({
|
|
|
57184
57552
|
"../shared-providers/dist/index.js"(exports2) {
|
|
57185
57553
|
"use strict";
|
|
57186
57554
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
57187
|
-
exports2.spawnClaudeCli = exports2.ClaudeCliEmulator = exports2.OpenRouterEmulator = exports2.OpenAIEmulator = exports2.EmulatorStateManager = exports2.AbstractEmulator = exports2.validateOpenAIKey = exports2.validateOpenRouterKey = exports2.AbstractProvider = exports2.AnthropicCliProvider = exports2.OpenAINativeProvider = exports2.FallbackProvider = exports2.ProfileProviderFactory = exports2.ProviderFactory = exports2.TimeoutError = exports2.AuthError = exports2.RateLimitError = exports2.ProviderError = void 0;
|
|
57555
|
+
exports2.spawnClaudeCli = exports2.ClaudeCliEmulator = exports2.OpenRouterEmulator = exports2.OpenAIEmulator = exports2.EmulatorStateManager = exports2.AbstractEmulator = exports2.validateOpenAIKey = exports2.validateOpenRouterKey = exports2.AbstractProvider = exports2.AnthropicCliProvider = exports2.OpenAINativeProvider = exports2.FallbackProvider = exports2.ProfileProviderFactory = exports2.ProviderFactory = exports2.MalformedResponseError = exports2.TimeoutError = exports2.AuthError = exports2.RateLimitError = exports2.ProviderError = void 0;
|
|
57188
57556
|
var errors_1 = require_errors4();
|
|
57189
57557
|
Object.defineProperty(exports2, "ProviderError", { enumerable: true, get: function() {
|
|
57190
57558
|
return errors_1.ProviderError;
|
|
@@ -57198,6 +57566,9 @@ var require_dist3 = __commonJS({
|
|
|
57198
57566
|
Object.defineProperty(exports2, "TimeoutError", { enumerable: true, get: function() {
|
|
57199
57567
|
return errors_1.TimeoutError;
|
|
57200
57568
|
} });
|
|
57569
|
+
Object.defineProperty(exports2, "MalformedResponseError", { enumerable: true, get: function() {
|
|
57570
|
+
return errors_1.MalformedResponseError;
|
|
57571
|
+
} });
|
|
57201
57572
|
var factory_1 = require_factory();
|
|
57202
57573
|
Object.defineProperty(exports2, "ProviderFactory", { enumerable: true, get: function() {
|
|
57203
57574
|
return factory_1.ProviderFactory;
|
|
@@ -57487,6 +57858,7 @@ var require_plugin_detector = __commonJS({
|
|
|
57487
57858
|
var crypto2 = __importStar(require("node:crypto"));
|
|
57488
57859
|
var node_child_process_1 = require("node:child_process");
|
|
57489
57860
|
var api_key_detector_js_1 = require_api_key_detector();
|
|
57861
|
+
var error_utils_js_1 = require_error_utils();
|
|
57490
57862
|
function isSidekickStatuslineCommand(command) {
|
|
57491
57863
|
return command?.toLowerCase().includes("sidekick") ?? false;
|
|
57492
57864
|
}
|
|
@@ -57616,7 +57988,7 @@ var require_plugin_detector = __commonJS({
|
|
|
57616
57988
|
return result;
|
|
57617
57989
|
} catch (err) {
|
|
57618
57990
|
logger?.warn("Failed to parse plugin list JSON", {
|
|
57619
|
-
error:
|
|
57991
|
+
error: (0, error_utils_js_1.toErrorMessage)(err)
|
|
57620
57992
|
});
|
|
57621
57993
|
logger?.info("Plugin detection completed", { result: "error" });
|
|
57622
57994
|
return "error";
|
|
@@ -57820,7 +58192,16 @@ var require_doctor_engine = __commonJS({
|
|
|
57820
58192
|
const expectedUserStatus = (0, api_key_detector_js_1.buildUserApiKeyStatus)(detection);
|
|
57821
58193
|
const currentUserEntry = currentUserStatus.apiKeys[keyName];
|
|
57822
58194
|
const currentStatus = typeof currentUserEntry === "object" ? currentUserEntry.status : currentUserEntry ?? "missing";
|
|
57823
|
-
if (currentStatus
|
|
58195
|
+
if (currentStatus === "not-required")
|
|
58196
|
+
continue;
|
|
58197
|
+
const isLegacyString = typeof currentUserEntry === "string";
|
|
58198
|
+
if (isLegacyString) {
|
|
58199
|
+
updatedUserApiKeys[keyName] = expectedUserStatus;
|
|
58200
|
+
userNeedsUpdate = true;
|
|
58201
|
+
} else if ((0, api_key_detector_js_1.toScopeStatus)(currentStatus) !== (0, api_key_detector_js_1.toScopeStatus)(expectedUserStatus.status)) {
|
|
58202
|
+
updatedUserApiKeys[keyName] = expectedUserStatus;
|
|
58203
|
+
userNeedsUpdate = true;
|
|
58204
|
+
} else if (typeof currentUserEntry === "object" && (currentUserEntry.used !== expectedUserStatus.used || JSON.stringify(currentUserEntry.scopes) !== JSON.stringify(expectedUserStatus.scopes))) {
|
|
57824
58205
|
updatedUserApiKeys[keyName] = expectedUserStatus;
|
|
57825
58206
|
userNeedsUpdate = true;
|
|
57826
58207
|
}
|
|
@@ -57895,7 +58276,7 @@ var require_setup_status_service = __commonJS({
|
|
|
57895
58276
|
};
|
|
57896
58277
|
})();
|
|
57897
58278
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
57898
|
-
exports2.SetupStatusService = exports2.
|
|
58279
|
+
exports2.SetupStatusService = exports2.PROJECT_STATUS_FILENAME = exports2.USER_STATUS_FILENAME = void 0;
|
|
57899
58280
|
exports2.createSetupStatusService = createSetupStatusService;
|
|
57900
58281
|
var fs = __importStar(require("node:fs/promises"));
|
|
57901
58282
|
var path = __importStar(require("node:path"));
|
|
@@ -57907,7 +58288,6 @@ var require_setup_status_service = __commonJS({
|
|
|
57907
58288
|
var doctor_engine_js_1 = require_doctor_engine();
|
|
57908
58289
|
exports2.USER_STATUS_FILENAME = "user-setup-status.json";
|
|
57909
58290
|
exports2.PROJECT_STATUS_FILENAME = "setup-status.json";
|
|
57910
|
-
exports2.LEGACY_USER_STATUS_FILENAME = exports2.PROJECT_STATUS_FILENAME;
|
|
57911
58291
|
var SetupStatusService = class {
|
|
57912
58292
|
projectDir;
|
|
57913
58293
|
homeDir;
|
|
@@ -57921,10 +58301,6 @@ var require_setup_status_service = __commonJS({
|
|
|
57921
58301
|
get userStatusPath() {
|
|
57922
58302
|
return path.join(this.homeDir, ".sidekick", exports2.USER_STATUS_FILENAME);
|
|
57923
58303
|
}
|
|
57924
|
-
/** Legacy path for migration: old user-scope file that collided with project-scope */
|
|
57925
|
-
get legacyUserStatusPath() {
|
|
57926
|
-
return path.join(this.homeDir, ".sidekick", exports2.LEGACY_USER_STATUS_FILENAME);
|
|
57927
|
-
}
|
|
57928
58304
|
get projectStatusPath() {
|
|
57929
58305
|
return path.join(this.projectDir, ".sidekick", exports2.PROJECT_STATUS_FILENAME);
|
|
57930
58306
|
}
|
|
@@ -57958,7 +58334,7 @@ var require_setup_status_service = __commonJS({
|
|
|
57958
58334
|
return parsed.data;
|
|
57959
58335
|
} catch (err) {
|
|
57960
58336
|
if (err.code === "ENOENT") {
|
|
57961
|
-
return
|
|
58337
|
+
return null;
|
|
57962
58338
|
}
|
|
57963
58339
|
if (err instanceof SyntaxError) {
|
|
57964
58340
|
this.logger?.warn(`Corrupt ${exports2.USER_STATUS_FILENAME}, treating as missing`, {
|
|
@@ -57970,54 +58346,6 @@ var require_setup_status_service = __commonJS({
|
|
|
57970
58346
|
throw err;
|
|
57971
58347
|
}
|
|
57972
58348
|
}
|
|
57973
|
-
/**
|
|
57974
|
-
* Migration: read user status from the legacy `setup-status.json` location,
|
|
57975
|
-
* write it to the new `user-setup-status.json`, and remove the old file.
|
|
57976
|
-
*
|
|
57977
|
-
* Only migrates if the legacy file contains valid UserSetupStatus data
|
|
57978
|
-
* (not project-format data that may have been written by the collision bug).
|
|
57979
|
-
*/
|
|
57980
|
-
async migrateFromLegacyUserStatus() {
|
|
57981
|
-
try {
|
|
57982
|
-
const legacyContent = await fs.readFile(this.legacyUserStatusPath, "utf-8");
|
|
57983
|
-
const parsed = types_1.UserSetupStatusSchema.safeParse(JSON.parse(legacyContent));
|
|
57984
|
-
if (!parsed.success) {
|
|
57985
|
-
this.logger?.debug("Legacy user status file exists but is not valid user format, skipping migration", {
|
|
57986
|
-
path: this.legacyUserStatusPath
|
|
57987
|
-
});
|
|
57988
|
-
return null;
|
|
57989
|
-
}
|
|
57990
|
-
this.logger?.info("Migrating user status from legacy location", {
|
|
57991
|
-
from: this.legacyUserStatusPath,
|
|
57992
|
-
to: this.userStatusPath
|
|
57993
|
-
});
|
|
57994
|
-
await this.writeUserStatus(parsed.data);
|
|
57995
|
-
try {
|
|
57996
|
-
await fs.unlink(this.legacyUserStatusPath);
|
|
57997
|
-
} catch (unlinkErr) {
|
|
57998
|
-
if (unlinkErr.code !== "ENOENT") {
|
|
57999
|
-
this.logger?.warn("Migrated user status but failed to remove legacy file", {
|
|
58000
|
-
path: this.legacyUserStatusPath,
|
|
58001
|
-
error: unlinkErr instanceof Error ? unlinkErr.message : String(unlinkErr)
|
|
58002
|
-
});
|
|
58003
|
-
}
|
|
58004
|
-
}
|
|
58005
|
-
this.logger?.info("Legacy user status migration complete");
|
|
58006
|
-
return parsed.data;
|
|
58007
|
-
} catch (err) {
|
|
58008
|
-
if (err.code === "ENOENT") {
|
|
58009
|
-
return null;
|
|
58010
|
-
}
|
|
58011
|
-
if (err instanceof SyntaxError) {
|
|
58012
|
-
this.logger?.warn(`Corrupt legacy ${exports2.LEGACY_USER_STATUS_FILENAME}, treating as missing`, {
|
|
58013
|
-
path: this.legacyUserStatusPath,
|
|
58014
|
-
error: err.message
|
|
58015
|
-
});
|
|
58016
|
-
return null;
|
|
58017
|
-
}
|
|
58018
|
-
throw err;
|
|
58019
|
-
}
|
|
58020
|
-
}
|
|
58021
58349
|
async getProjectStatus() {
|
|
58022
58350
|
if (path.resolve(this.projectDir) === path.resolve(this.homeDir)) {
|
|
58023
58351
|
this.logger?.debug("Skipping project status read: projectDir is the home directory", {
|
|
@@ -58385,61 +58713,6 @@ var require_errors6 = __commonJS({
|
|
|
58385
58713
|
}
|
|
58386
58714
|
});
|
|
58387
58715
|
|
|
58388
|
-
// ../sidekick-core/dist/staging-paths.js
|
|
58389
|
-
var require_staging_paths = __commonJS({
|
|
58390
|
-
"../sidekick-core/dist/staging-paths.js"(exports2) {
|
|
58391
|
-
"use strict";
|
|
58392
|
-
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
58393
|
-
exports2.CONSUMED_FILE_PATTERN = void 0;
|
|
58394
|
-
exports2.getStagingRoot = getStagingRoot;
|
|
58395
|
-
exports2.getHookDir = getHookDir;
|
|
58396
|
-
exports2.getReminderPath = getReminderPath;
|
|
58397
|
-
exports2.isValidPathSegment = isValidPathSegment;
|
|
58398
|
-
exports2.validatePathSegment = validatePathSegment;
|
|
58399
|
-
exports2.filterActiveReminderFiles = filterActiveReminderFiles;
|
|
58400
|
-
exports2.createConsumedFilePattern = createConsumedFilePattern;
|
|
58401
|
-
exports2.extractConsumedTimestamp = extractConsumedTimestamp;
|
|
58402
|
-
var node_path_1 = require("node:path");
|
|
58403
|
-
function getStagingRoot(stateDir, sessionId) {
|
|
58404
|
-
return (0, node_path_1.join)(stateDir, "sessions", sessionId, "stage");
|
|
58405
|
-
}
|
|
58406
|
-
function getHookDir(stateDir, sessionId, hookName) {
|
|
58407
|
-
return (0, node_path_1.join)(getStagingRoot(stateDir, sessionId), hookName);
|
|
58408
|
-
}
|
|
58409
|
-
function getReminderPath(stateDir, sessionId, hookName, reminderName) {
|
|
58410
|
-
return (0, node_path_1.join)(getHookDir(stateDir, sessionId, hookName), `${reminderName}.json`);
|
|
58411
|
-
}
|
|
58412
|
-
function isValidPathSegment(s) {
|
|
58413
|
-
if (s === "")
|
|
58414
|
-
return false;
|
|
58415
|
-
if (s === "." || s === "..")
|
|
58416
|
-
return false;
|
|
58417
|
-
if (s.includes("/") || s.includes("\\"))
|
|
58418
|
-
return false;
|
|
58419
|
-
if ((0, node_path_1.basename)(s) !== s)
|
|
58420
|
-
return false;
|
|
58421
|
-
return /^[a-zA-Z0-9._-]+$/.test(s);
|
|
58422
|
-
}
|
|
58423
|
-
function validatePathSegment(segment, name) {
|
|
58424
|
-
if (!isValidPathSegment(segment)) {
|
|
58425
|
-
throw new Error(`Invalid ${name}: must be a non-empty alphanumeric string without path separators`);
|
|
58426
|
-
}
|
|
58427
|
-
}
|
|
58428
|
-
exports2.CONSUMED_FILE_PATTERN = /\.\d+\.json$/;
|
|
58429
|
-
function filterActiveReminderFiles(files) {
|
|
58430
|
-
return files.filter((f) => f.endsWith(".json") && !exports2.CONSUMED_FILE_PATTERN.test(f));
|
|
58431
|
-
}
|
|
58432
|
-
function createConsumedFilePattern(reminderName) {
|
|
58433
|
-
return new RegExp(`^${reminderName}\\.(\\d+)\\.json$`);
|
|
58434
|
-
}
|
|
58435
|
-
function extractConsumedTimestamp(filename, reminderName) {
|
|
58436
|
-
const pattern = createConsumedFilePattern(reminderName);
|
|
58437
|
-
const match = pattern.exec(filename);
|
|
58438
|
-
return match ? parseInt(match[1], 10) : null;
|
|
58439
|
-
}
|
|
58440
|
-
}
|
|
58441
|
-
});
|
|
58442
|
-
|
|
58443
58716
|
// ../sidekick-core/dist/staging-service.js
|
|
58444
58717
|
var require_staging_service = __commonJS({
|
|
58445
58718
|
"../sidekick-core/dist/staging-service.js"(exports2) {
|
|
@@ -58453,6 +58726,7 @@ var require_staging_service = __commonJS({
|
|
|
58453
58726
|
var structured_logging_1 = require_structured_logging();
|
|
58454
58727
|
var errors_js_1 = require_errors6();
|
|
58455
58728
|
var staging_paths_js_1 = require_staging_paths();
|
|
58729
|
+
var error_utils_js_1 = require_error_utils();
|
|
58456
58730
|
var StagingServiceCore = class {
|
|
58457
58731
|
options;
|
|
58458
58732
|
constructor(options) {
|
|
@@ -58556,7 +58830,7 @@ var require_staging_service = __commonJS({
|
|
|
58556
58830
|
hookName,
|
|
58557
58831
|
reminderName,
|
|
58558
58832
|
path: reminderPath,
|
|
58559
|
-
error:
|
|
58833
|
+
error: (0, error_utils_js_1.toErrorMessage)(err)
|
|
58560
58834
|
});
|
|
58561
58835
|
return null;
|
|
58562
58836
|
}
|
|
@@ -58587,7 +58861,7 @@ var require_staging_service = __commonJS({
|
|
|
58587
58861
|
}
|
|
58588
58862
|
this.options.logger.warn("Skipping invalid reminder file", {
|
|
58589
58863
|
path: reminderPath,
|
|
58590
|
-
error:
|
|
58864
|
+
error: (0, error_utils_js_1.toErrorMessage)(err)
|
|
58591
58865
|
});
|
|
58592
58866
|
}
|
|
58593
58867
|
}
|
|
@@ -58648,7 +58922,7 @@ var require_staging_service = __commonJS({
|
|
|
58648
58922
|
}
|
|
58649
58923
|
this.options.logger.warn("Skipping invalid consumed reminder file", {
|
|
58650
58924
|
path: reminderPath,
|
|
58651
|
-
error:
|
|
58925
|
+
error: (0, error_utils_js_1.toErrorMessage)(err)
|
|
58652
58926
|
});
|
|
58653
58927
|
}
|
|
58654
58928
|
}
|
|
@@ -58800,6 +59074,7 @@ var require_handler_registry2 = __commonJS({
|
|
|
58800
59074
|
exports2.HandlerRegistryImpl = void 0;
|
|
58801
59075
|
var transcript_content_js_1 = require_transcript_content();
|
|
58802
59076
|
var structured_logging_js_1 = require_structured_logging();
|
|
59077
|
+
var error_utils_js_1 = require_error_utils();
|
|
58803
59078
|
var HandlerRegistryImpl = class {
|
|
58804
59079
|
options;
|
|
58805
59080
|
handlers = [];
|
|
@@ -58910,7 +59185,7 @@ var require_handler_registry2 = __commonJS({
|
|
|
58910
59185
|
log.error("Handler execution failed", {
|
|
58911
59186
|
handlerId: handler.id,
|
|
58912
59187
|
hook,
|
|
58913
|
-
error:
|
|
59188
|
+
error: (0, error_utils_js_1.toErrorMessage)(err)
|
|
58914
59189
|
});
|
|
58915
59190
|
}
|
|
58916
59191
|
}
|
|
@@ -58956,7 +59231,7 @@ var require_handler_registry2 = __commonJS({
|
|
|
58956
59231
|
(0, structured_logging_js_1.logEvent)(this.options.logger, structured_logging_js_1.LogEvents.eventProcessed(logContext, { handlerId: handler.id, success: true }, { durationMs }));
|
|
58957
59232
|
} catch (err) {
|
|
58958
59233
|
const durationMs = Date.now() - startTime;
|
|
58959
|
-
const errorMsg =
|
|
59234
|
+
const errorMsg = (0, error_utils_js_1.toErrorMessage)(err);
|
|
58960
59235
|
(0, structured_logging_js_1.logEvent)(this.options.logger, structured_logging_js_1.LogEvents.eventProcessed(logContext, { handlerId: handler.id, success: false }, { durationMs, error: errorMsg }));
|
|
58961
59236
|
this.options.logger.error("Transcript handler failed", {
|
|
58962
59237
|
handlerId: handler.id,
|
|
@@ -59315,6 +59590,9 @@ var require_path_resolver = __commonJS({
|
|
|
59315
59590
|
sessionStagingDir(sessionId) {
|
|
59316
59591
|
return (0, node_path_1.join)(this.sessionRootDir(sessionId), "stage");
|
|
59317
59592
|
}
|
|
59593
|
+
sessionLogsDir(sessionId) {
|
|
59594
|
+
return (0, node_path_1.join)(this.sessionRootDir(sessionId), "logs");
|
|
59595
|
+
}
|
|
59318
59596
|
hookStagingDir(sessionId, hookName) {
|
|
59319
59597
|
return (0, node_path_1.join)(this.sessionStagingDir(sessionId), hookName);
|
|
59320
59598
|
}
|
|
@@ -59384,6 +59662,7 @@ var require_state_service = __commonJS({
|
|
|
59384
59662
|
var node_path_1 = require("node:path");
|
|
59385
59663
|
var path_resolver_js_1 = require_path_resolver();
|
|
59386
59664
|
var errors_js_1 = require_errors6();
|
|
59665
|
+
var error_utils_js_1 = require_error_utils();
|
|
59387
59666
|
var errors_js_2 = require_errors6();
|
|
59388
59667
|
Object.defineProperty(exports2, "StateNotFoundError", { enumerable: true, get: function() {
|
|
59389
59668
|
return errors_js_2.StateNotFoundError;
|
|
@@ -59495,7 +59774,7 @@ var require_state_service = __commonJS({
|
|
|
59495
59774
|
} catch (cleanupErr) {
|
|
59496
59775
|
this.logger?.trace("Failed to cleanup temp file", {
|
|
59497
59776
|
tmpPath,
|
|
59498
|
-
error:
|
|
59777
|
+
error: (0, error_utils_js_1.toErrorMessage)(cleanupErr)
|
|
59499
59778
|
});
|
|
59500
59779
|
}
|
|
59501
59780
|
throw err;
|
|
@@ -59621,7 +59900,7 @@ var require_state_service = __commonJS({
|
|
|
59621
59900
|
} catch (err) {
|
|
59622
59901
|
this.logger?.warn("Failed to preload state file", {
|
|
59623
59902
|
file,
|
|
59624
|
-
error:
|
|
59903
|
+
error: (0, error_utils_js_1.toErrorMessage)(err)
|
|
59625
59904
|
});
|
|
59626
59905
|
}
|
|
59627
59906
|
}
|
|
@@ -59647,7 +59926,7 @@ var require_state_service = __commonJS({
|
|
|
59647
59926
|
this.logger?.warn("Corrupt state file detected", {
|
|
59648
59927
|
path,
|
|
59649
59928
|
reason,
|
|
59650
|
-
error:
|
|
59929
|
+
error: (0, error_utils_js_1.toErrorMessage)(error)
|
|
59651
59930
|
});
|
|
59652
59931
|
try {
|
|
59653
59932
|
await fs.rename(path, bakPath);
|
|
@@ -59677,7 +59956,7 @@ var require_state_service = __commonJS({
|
|
|
59677
59956
|
} catch (err) {
|
|
59678
59957
|
this.logger?.warn("Failed to create dev mode backup", {
|
|
59679
59958
|
path,
|
|
59680
|
-
error:
|
|
59959
|
+
error: (0, error_utils_js_1.toErrorMessage)(err)
|
|
59681
59960
|
});
|
|
59682
59961
|
}
|
|
59683
59962
|
}
|
|
@@ -59740,12 +60019,17 @@ var require_typed_accessor = __commonJS({
|
|
|
59740
60019
|
var SessionStateAccessor = class {
|
|
59741
60020
|
stateService;
|
|
59742
60021
|
descriptor;
|
|
59743
|
-
|
|
60022
|
+
journal;
|
|
60023
|
+
/** Descriptor filename without .json extension — used as journal file key */
|
|
60024
|
+
fileKey;
|
|
60025
|
+
constructor(stateService, descriptor, journal) {
|
|
59744
60026
|
this.stateService = stateService;
|
|
59745
60027
|
this.descriptor = descriptor;
|
|
60028
|
+
this.journal = journal;
|
|
59746
60029
|
if (descriptor.scope !== "session") {
|
|
59747
60030
|
throw new Error(`SessionStateAccessor requires a session-scoped descriptor, got: ${descriptor.scope}`);
|
|
59748
60031
|
}
|
|
60032
|
+
this.fileKey = descriptor.filename.replace(/\.json$/, "");
|
|
59749
60033
|
}
|
|
59750
60034
|
/**
|
|
59751
60035
|
* Read session state file.
|
|
@@ -59763,9 +60047,15 @@ var require_typed_accessor = __commonJS({
|
|
|
59763
60047
|
*/
|
|
59764
60048
|
async write(sessionId, data) {
|
|
59765
60049
|
const path = this.stateService.sessionStatePath(sessionId, this.descriptor.filename);
|
|
59766
|
-
|
|
60050
|
+
await this.stateService.write(path, data, this.descriptor.schema, {
|
|
59767
60051
|
trackHistory: this.descriptor.trackHistory
|
|
59768
60052
|
});
|
|
60053
|
+
if (this.journal) {
|
|
60054
|
+
try {
|
|
60055
|
+
await this.journal.appendIfChanged(sessionId, this.fileKey, data);
|
|
60056
|
+
} catch {
|
|
60057
|
+
}
|
|
60058
|
+
}
|
|
59769
60059
|
}
|
|
59770
60060
|
/**
|
|
59771
60061
|
* Delete session state file.
|
|
@@ -59773,6 +60063,12 @@ var require_typed_accessor = __commonJS({
|
|
|
59773
60063
|
async delete(sessionId) {
|
|
59774
60064
|
const path = this.stateService.sessionStatePath(sessionId, this.descriptor.filename);
|
|
59775
60065
|
await this.stateService.delete(path);
|
|
60066
|
+
if (this.journal) {
|
|
60067
|
+
try {
|
|
60068
|
+
await this.journal.appendDeletion(sessionId, this.fileKey);
|
|
60069
|
+
} catch {
|
|
60070
|
+
}
|
|
60071
|
+
}
|
|
59776
60072
|
}
|
|
59777
60073
|
/**
|
|
59778
60074
|
* Get the path for a session state file.
|
|
@@ -60038,8 +60334,51 @@ var require_transcript_normalizer = __commonJS({
|
|
|
60038
60334
|
exports2.parseUuid = parseUuid;
|
|
60039
60335
|
exports2.renderTranscriptString = renderTranscriptString;
|
|
60040
60336
|
var index_js_1 = require_state3();
|
|
60337
|
+
function buildRecapEntry(params) {
|
|
60338
|
+
const text = typeof params.rawText === "string" ? params.rawText.trim() : "";
|
|
60339
|
+
if (!text)
|
|
60340
|
+
return null;
|
|
60341
|
+
return {
|
|
60342
|
+
id: params.uuid ?? `line-${params.lineNumber}`,
|
|
60343
|
+
timestamp: new Date(params.timestamp ?? Date.now()),
|
|
60344
|
+
role: "system",
|
|
60345
|
+
type: "recap",
|
|
60346
|
+
content: text,
|
|
60347
|
+
metadata: {
|
|
60348
|
+
provider: "claude",
|
|
60349
|
+
lineNumber: params.lineNumber,
|
|
60350
|
+
recapSource: params.recapSource,
|
|
60351
|
+
leafUuid: params.leafUuid
|
|
60352
|
+
}
|
|
60353
|
+
};
|
|
60354
|
+
}
|
|
60041
60355
|
function normalizeEntry(rawEntry, lineNumber) {
|
|
60042
60356
|
const entryType = rawEntry.type;
|
|
60357
|
+
if (entryType === "summary") {
|
|
60358
|
+
const raw = rawEntry;
|
|
60359
|
+
const recap = buildRecapEntry({
|
|
60360
|
+
rawText: raw.summary,
|
|
60361
|
+
uuid: raw.uuid,
|
|
60362
|
+
timestamp: raw.timestamp,
|
|
60363
|
+
lineNumber,
|
|
60364
|
+
recapSource: "compaction",
|
|
60365
|
+
leafUuid: typeof raw.leafUuid === "string" ? raw.leafUuid : void 0
|
|
60366
|
+
});
|
|
60367
|
+
return recap ? [recap] : null;
|
|
60368
|
+
}
|
|
60369
|
+
if (entryType === "system") {
|
|
60370
|
+
const raw = rawEntry;
|
|
60371
|
+
if (raw.subtype !== "away_summary")
|
|
60372
|
+
return null;
|
|
60373
|
+
const recap = buildRecapEntry({
|
|
60374
|
+
rawText: raw.content,
|
|
60375
|
+
uuid: raw.uuid,
|
|
60376
|
+
timestamp: raw.timestamp,
|
|
60377
|
+
lineNumber,
|
|
60378
|
+
recapSource: "away"
|
|
60379
|
+
});
|
|
60380
|
+
return recap ? [recap] : null;
|
|
60381
|
+
}
|
|
60043
60382
|
if (entryType !== "user" && entryType !== "assistant") {
|
|
60044
60383
|
return null;
|
|
60045
60384
|
}
|
|
@@ -60173,6 +60512,9 @@ var require_transcript_normalizer = __commonJS({
|
|
|
60173
60512
|
return `[${timestamp}] ${role} TOOL_USE: ${String(toolContent.name)}`;
|
|
60174
60513
|
} else if (type === "tool_result") {
|
|
60175
60514
|
return `[${timestamp}] ${role} TOOL_RESULT`;
|
|
60515
|
+
} else if (type === "recap") {
|
|
60516
|
+
const content = typeof entry.content === "string" ? entry.content : "";
|
|
60517
|
+
return `[${timestamp}] RECAP: ${content}`;
|
|
60176
60518
|
}
|
|
60177
60519
|
return `[${timestamp}] ${role}: ${JSON.stringify(entry.content)}`;
|
|
60178
60520
|
}).join("\n");
|
|
@@ -60191,6 +60533,7 @@ var require_transcript_excerpt_builder = __commonJS({
|
|
|
60191
60533
|
exports2.extractTextContent = extractTextContent;
|
|
60192
60534
|
exports2.getRawContentString = getRawContentString;
|
|
60193
60535
|
var transcript_helpers_js_1 = require_transcript_helpers();
|
|
60536
|
+
var error_utils_js_1 = require_error_utils();
|
|
60194
60537
|
function getBufferedEntries(buffer, head, count, bufferSize) {
|
|
60195
60538
|
if (count === 0)
|
|
60196
60539
|
return [];
|
|
@@ -60245,7 +60588,7 @@ var require_transcript_excerpt_builder = __commonJS({
|
|
|
60245
60588
|
};
|
|
60246
60589
|
} catch (err) {
|
|
60247
60590
|
logger.error("Failed to extract transcript excerpt from buffer", {
|
|
60248
|
-
error:
|
|
60591
|
+
error: (0, error_utils_js_1.toErrorMessage)(err)
|
|
60249
60592
|
});
|
|
60250
60593
|
return {
|
|
60251
60594
|
content: "",
|
|
@@ -60306,6 +60649,14 @@ var require_transcript_excerpt_builder = __commonJS({
|
|
|
60306
60649
|
return null;
|
|
60307
60650
|
}
|
|
60308
60651
|
return `[SESSION_HINT]: ${entry.summary ?? ""}`;
|
|
60652
|
+
case "system": {
|
|
60653
|
+
if (entry.subtype !== "away_summary")
|
|
60654
|
+
return null;
|
|
60655
|
+
const content = entry.content;
|
|
60656
|
+
if (typeof content !== "string" || !content.trim())
|
|
60657
|
+
return null;
|
|
60658
|
+
return `[SESSION_RECAP]: ${content}`;
|
|
60659
|
+
}
|
|
60309
60660
|
default:
|
|
60310
60661
|
return null;
|
|
60311
60662
|
}
|
|
@@ -63164,6 +63515,7 @@ var require_instrumented_llm_provider = __commonJS({
|
|
|
63164
63515
|
var node_path_1 = require("node:path");
|
|
63165
63516
|
var yaml_1 = __importDefault2(require_dist2());
|
|
63166
63517
|
var types_1 = require_dist();
|
|
63518
|
+
var error_utils_js_1 = require_error_utils();
|
|
63167
63519
|
var STATE_FILE = "llm-metrics.json";
|
|
63168
63520
|
var DEFAULT_DEBOUNCE_MS = 500;
|
|
63169
63521
|
function hasFallbackTracking(provider) {
|
|
@@ -63214,7 +63566,7 @@ var require_instrumented_llm_provider = __commonJS({
|
|
|
63214
63566
|
}
|
|
63215
63567
|
} catch (err) {
|
|
63216
63568
|
this.config.logger.warn("Failed to load LLM metrics, starting fresh", {
|
|
63217
|
-
error:
|
|
63569
|
+
error: (0, error_utils_js_1.toErrorMessage)(err)
|
|
63218
63570
|
});
|
|
63219
63571
|
}
|
|
63220
63572
|
}
|
|
@@ -63301,7 +63653,7 @@ var require_instrumented_llm_provider = __commonJS({
|
|
|
63301
63653
|
this.config.logger.debug("Debug dump written", { path: basePath });
|
|
63302
63654
|
} catch (dumpError) {
|
|
63303
63655
|
this.config.logger.warn("Failed to write debug dump", {
|
|
63304
|
-
error:
|
|
63656
|
+
error: (0, error_utils_js_1.toErrorMessage)(dumpError)
|
|
63305
63657
|
});
|
|
63306
63658
|
}
|
|
63307
63659
|
}
|
|
@@ -63526,7 +63878,7 @@ var require_instrumented_llm_provider = __commonJS({
|
|
|
63526
63878
|
});
|
|
63527
63879
|
} catch (err) {
|
|
63528
63880
|
this.config.logger.warn("Failed to persist LLM metrics", {
|
|
63529
|
-
error:
|
|
63881
|
+
error: (0, error_utils_js_1.toErrorMessage)(err)
|
|
63530
63882
|
});
|
|
63531
63883
|
}
|
|
63532
63884
|
}
|
|
@@ -63802,6 +64154,7 @@ var require_daemon_health = __commonJS({
|
|
|
63802
64154
|
var fs = __importStar(require("node:fs/promises"));
|
|
63803
64155
|
var node_path_1 = require("node:path");
|
|
63804
64156
|
var types_1 = require_dist();
|
|
64157
|
+
var error_utils_js_1 = require_error_utils();
|
|
63805
64158
|
function healthFilePath(projectDir) {
|
|
63806
64159
|
return (0, node_path_1.join)(projectDir, ".sidekick", "state", "daemon-health.json");
|
|
63807
64160
|
}
|
|
@@ -63860,7 +64213,7 @@ var require_daemon_health = __commonJS({
|
|
|
63860
64213
|
logger.warn("Failed to write daemon health", {
|
|
63861
64214
|
from,
|
|
63862
64215
|
to,
|
|
63863
|
-
error:
|
|
64216
|
+
error: (0, error_utils_js_1.toErrorMessage)(err)
|
|
63864
64217
|
});
|
|
63865
64218
|
return false;
|
|
63866
64219
|
}
|
|
@@ -63947,6 +64300,7 @@ var require_user_profile_loader = __commonJS({
|
|
|
63947
64300
|
var node_path_1 = require("node:path");
|
|
63948
64301
|
var yaml_1 = require_dist2();
|
|
63949
64302
|
var types_1 = require_dist();
|
|
64303
|
+
var error_utils_js_1 = require_error_utils();
|
|
63950
64304
|
function loadUserProfile(options) {
|
|
63951
64305
|
const home = options?.homeDir ?? (0, node_os_1.homedir)();
|
|
63952
64306
|
const filePath = (0, node_path_1.join)(home, ".sidekick", "user.yaml");
|
|
@@ -63968,7 +64322,7 @@ var require_user_profile_loader = __commonJS({
|
|
|
63968
64322
|
} catch (err) {
|
|
63969
64323
|
options?.logger?.warn("Failed to read user profile", {
|
|
63970
64324
|
path: filePath,
|
|
63971
|
-
error:
|
|
64325
|
+
error: (0, error_utils_js_1.toErrorMessage)(err)
|
|
63972
64326
|
});
|
|
63973
64327
|
return null;
|
|
63974
64328
|
}
|
|
@@ -64035,9 +64389,9 @@ var require_dist4 = __commonJS({
|
|
|
64035
64389
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p);
|
|
64036
64390
|
};
|
|
64037
64391
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
64038
|
-
exports2.
|
|
64039
|
-
exports2.
|
|
64040
|
-
exports2.CoalescingGuard = exports2.loadUserProfile = exports2.parseGitStatusOutput = exports2.getGitFileStatus = exports2.isInSandbox = exports2.updateDaemonHealth = exports2.readDaemonHealth = exports2.ProjectRegistryService = exports2.encodeProjectDir = exports2.DaemonGlobalLogMetricsDescriptor = exports2.CliLogMetricsDescriptor = exports2.DaemonLogMetricsDescriptor = exports2.CompactionHistoryDescriptor = exports2.TranscriptMetricsDescriptor = exports2.GlobalStateAccessor = exports2.SessionStateAccessor = exports2.globalState = exports2.sessionState = exports2.StateCorruptError = exports2.StateNotFoundError = void 0;
|
|
64392
|
+
exports2.PROJECT_STATUS_FILENAME = exports2.USER_STATUS_FILENAME = exports2.createSetupStatusService = exports2.SetupStatusService = exports2.DaemonClient = exports2.findZombieDaemons = exports2.killZombieDaemons = exports2.killAllDaemons = exports2.SessionLogWriter = exports2.setSessionLogWriter = exports2.logEvent = exports2.LogEvents = exports2.DEFAULT_MAX_FILES = exports2.DEFAULT_ROTATE_SIZE_BYTES = exports2.getComponentLogLevel = exports2.setupGlobalErrorHandlers = exports2.createLoggerFacade = exports2.createLogManager = exports2.createConsoleLogger = exports2.getUserDaemonsDir = exports2.getUserPidPath = exports2.getTokenPath = exports2.getSocketPath = exports2.getProjectHash = exports2.getPidPath = exports2.getLockPath = exports2.IpcService = exports2.IpcServer = exports2.loadPersonaFile = exports2.getDefaultPersonasDir = exports2.discoverPersonas = exports2.createPersonaLoader = exports2.reconstructTranscriptPath = exports2.encodeProjectPath = exports2.isSubagentStopEvent = exports2.isSubagentStartEvent = exports2.isPreCompactEvent = exports2.isStopEvent = exports2.isPostToolUseEvent = exports2.isPreToolUseEvent = exports2.isUserPromptSubmitEvent = exports2.isSessionEndEvent = exports2.isSessionStartEvent = exports2.isTranscriptEvent = exports2.isHookEvent = exports2.MetricsPersistPayloadSchema = exports2.CleanupPayloadSchema = exports2.ResumeGenerationPayloadSchema = exports2.SessionSummaryPayloadSchema = exports2.TaskTypes = void 0;
|
|
64393
|
+
exports2.createDefaultTokenUsage = exports2.createDefaultMetrics = exports2.copyWithTimestampSync = exports2.renameWithTimestampSync = exports2.renameWithTimestamp = exports2.copyWithTimestamp = exports2.getTimestampedPath = exports2.extractToolResultPreview = exports2.extractToolCallPreview = exports2.extractTextFromContent = exports2.extractContentPreview = exports2.HandlerRegistryImpl = exports2.extractConsumedTimestamp = exports2.createConsumedFilePattern = exports2.CONSUMED_FILE_PATTERN = exports2.filterActiveReminderFiles = exports2.validatePathSegment = exports2.isValidPathSegment = exports2.getReminderPath = exports2.getHookDir = exports2.getStagingRoot = exports2.SessionScopedStagingService = exports2.StagingServiceCore = exports2.GITIGNORE_ENTRIES = exports2.SIDEKICK_GITIGNORE_HEADER = exports2.SIDEKICK_SECTION_END = exports2.SIDEKICK_SECTION_START = exports2.removeLegacyGitignoreSection = exports2.detectLegacyGitignoreSection = exports2.detectGitignoreStatus = exports2.removeGitignoreSection = exports2.installGitignoreSection = exports2.validateOpenAIKey = exports2.validateOpenRouterKey = exports2.runDoctorCheck = exports2.detectPluginLiveness = exports2.detectPluginInstallation = exports2.detectActualStatusline = exports2.spawnWithTimeout = exports2.getDoctorTimeout = exports2.DOCTOR_TIMEOUTS = exports2.projectApiKeyStatusFromHealth = exports2.userApiKeyStatusFromHealth = exports2.buildProjectApiKeyStatus = exports2.buildUserApiKeyStatus = exports2.detectAllApiKeys = exports2.detectActualApiKey = exports2.readKeyFromEnvFile = exports2.determineOverallStatus = exports2.toScopeStatus = void 0;
|
|
64394
|
+
exports2.CoalescingGuard = exports2.loadUserProfile = exports2.parseGitStatusOutput = exports2.getGitFileStatus = exports2.toErrorMessage = exports2.isInSandbox = exports2.updateDaemonHealth = exports2.readDaemonHealth = exports2.ProjectRegistryService = exports2.encodeProjectDir = exports2.DaemonGlobalLogMetricsDescriptor = exports2.CliLogMetricsDescriptor = exports2.DaemonLogMetricsDescriptor = exports2.CompactionHistoryDescriptor = exports2.TranscriptMetricsDescriptor = exports2.GlobalStateAccessor = exports2.SessionStateAccessor = exports2.globalState = exports2.sessionState = exports2.StateCorruptError = exports2.StateNotFoundError = exports2.StateService = exports2.createHookableLogger = exports2.InstrumentedProfileProviderFactory = exports2.InstrumentedLLMProvider = exports2.ServiceFactoryImpl = exports2.TranscriptServiceImpl = void 0;
|
|
64041
64395
|
var types_1 = require_dist();
|
|
64042
64396
|
Object.defineProperty(exports2, "TaskTypes", { enumerable: true, get: function() {
|
|
64043
64397
|
return types_1.TaskTypes;
|
|
@@ -64082,6 +64436,12 @@ var require_dist4 = __commonJS({
|
|
|
64082
64436
|
Object.defineProperty(exports2, "isPreCompactEvent", { enumerable: true, get: function() {
|
|
64083
64437
|
return types_2.isPreCompactEvent;
|
|
64084
64438
|
} });
|
|
64439
|
+
Object.defineProperty(exports2, "isSubagentStartEvent", { enumerable: true, get: function() {
|
|
64440
|
+
return types_2.isSubagentStartEvent;
|
|
64441
|
+
} });
|
|
64442
|
+
Object.defineProperty(exports2, "isSubagentStopEvent", { enumerable: true, get: function() {
|
|
64443
|
+
return types_2.isSubagentStopEvent;
|
|
64444
|
+
} });
|
|
64085
64445
|
__exportStar(require_assets(), exports2);
|
|
64086
64446
|
var claude_paths_1 = require_claude_paths();
|
|
64087
64447
|
Object.defineProperty(exports2, "encodeProjectPath", { enumerable: true, get: function() {
|
|
@@ -64170,6 +64530,12 @@ var require_dist4 = __commonJS({
|
|
|
64170
64530
|
Object.defineProperty(exports2, "logEvent", { enumerable: true, get: function() {
|
|
64171
64531
|
return structured_logging_1.logEvent;
|
|
64172
64532
|
} });
|
|
64533
|
+
Object.defineProperty(exports2, "setSessionLogWriter", { enumerable: true, get: function() {
|
|
64534
|
+
return structured_logging_1.setSessionLogWriter;
|
|
64535
|
+
} });
|
|
64536
|
+
Object.defineProperty(exports2, "SessionLogWriter", { enumerable: true, get: function() {
|
|
64537
|
+
return structured_logging_1.SessionLogWriter;
|
|
64538
|
+
} });
|
|
64173
64539
|
var daemon_client_1 = require_daemon_client2();
|
|
64174
64540
|
Object.defineProperty(exports2, "killAllDaemons", { enumerable: true, get: function() {
|
|
64175
64541
|
return daemon_client_1.killAllDaemons;
|
|
@@ -64196,9 +64562,6 @@ var require_dist4 = __commonJS({
|
|
|
64196
64562
|
Object.defineProperty(exports2, "PROJECT_STATUS_FILENAME", { enumerable: true, get: function() {
|
|
64197
64563
|
return setup_status_service_1.PROJECT_STATUS_FILENAME;
|
|
64198
64564
|
} });
|
|
64199
|
-
Object.defineProperty(exports2, "LEGACY_USER_STATUS_FILENAME", { enumerable: true, get: function() {
|
|
64200
|
-
return setup_status_service_1.LEGACY_USER_STATUS_FILENAME;
|
|
64201
|
-
} });
|
|
64202
64565
|
var api_key_detector_1 = require_api_key_detector();
|
|
64203
64566
|
Object.defineProperty(exports2, "toScopeStatus", { enumerable: true, get: function() {
|
|
64204
64567
|
return api_key_detector_1.toScopeStatus;
|
|
@@ -64267,12 +64630,21 @@ var require_dist4 = __commonJS({
|
|
|
64267
64630
|
Object.defineProperty(exports2, "detectGitignoreStatus", { enumerable: true, get: function() {
|
|
64268
64631
|
return gitignore_1.detectGitignoreStatus;
|
|
64269
64632
|
} });
|
|
64633
|
+
Object.defineProperty(exports2, "detectLegacyGitignoreSection", { enumerable: true, get: function() {
|
|
64634
|
+
return gitignore_1.detectLegacyGitignoreSection;
|
|
64635
|
+
} });
|
|
64636
|
+
Object.defineProperty(exports2, "removeLegacyGitignoreSection", { enumerable: true, get: function() {
|
|
64637
|
+
return gitignore_1.removeLegacyGitignoreSection;
|
|
64638
|
+
} });
|
|
64270
64639
|
Object.defineProperty(exports2, "SIDEKICK_SECTION_START", { enumerable: true, get: function() {
|
|
64271
64640
|
return gitignore_1.SIDEKICK_SECTION_START;
|
|
64272
64641
|
} });
|
|
64273
64642
|
Object.defineProperty(exports2, "SIDEKICK_SECTION_END", { enumerable: true, get: function() {
|
|
64274
64643
|
return gitignore_1.SIDEKICK_SECTION_END;
|
|
64275
64644
|
} });
|
|
64645
|
+
Object.defineProperty(exports2, "SIDEKICK_GITIGNORE_HEADER", { enumerable: true, get: function() {
|
|
64646
|
+
return gitignore_1.SIDEKICK_GITIGNORE_HEADER;
|
|
64647
|
+
} });
|
|
64276
64648
|
Object.defineProperty(exports2, "GITIGNORE_ENTRIES", { enumerable: true, get: function() {
|
|
64277
64649
|
return gitignore_1.GITIGNORE_ENTRIES;
|
|
64278
64650
|
} });
|
|
@@ -64425,6 +64797,10 @@ var require_dist4 = __commonJS({
|
|
|
64425
64797
|
Object.defineProperty(exports2, "isInSandbox", { enumerable: true, get: function() {
|
|
64426
64798
|
return sandbox_1.isInSandbox;
|
|
64427
64799
|
} });
|
|
64800
|
+
var error_utils_1 = require_error_utils();
|
|
64801
|
+
Object.defineProperty(exports2, "toErrorMessage", { enumerable: true, get: function() {
|
|
64802
|
+
return error_utils_1.toErrorMessage;
|
|
64803
|
+
} });
|
|
64428
64804
|
var git_status_1 = require_git_status();
|
|
64429
64805
|
Object.defineProperty(exports2, "getGitFileStatus", { enumerable: true, get: function() {
|
|
64430
64806
|
return git_status_1.getGitFileStatus;
|
|
@@ -64483,7 +64859,7 @@ var require_runtime = __commonJS({
|
|
|
64483
64859
|
});
|
|
64484
64860
|
} catch (err) {
|
|
64485
64861
|
loggerFacade.error("Failed to load configuration", {
|
|
64486
|
-
error:
|
|
64862
|
+
error: (0, core_1.toErrorMessage)(err)
|
|
64487
64863
|
});
|
|
64488
64864
|
throw err;
|
|
64489
64865
|
}
|
|
@@ -64498,8 +64874,9 @@ var require_runtime = __commonJS({
|
|
|
64498
64874
|
const rotation = config.core.logging.rotation;
|
|
64499
64875
|
const fileDestination = enableFileLogging ? {
|
|
64500
64876
|
path: logFilePath,
|
|
64501
|
-
maxSizeBytes: rotation?.maxSizeBytes ??
|
|
64502
|
-
|
|
64877
|
+
maxSizeBytes: rotation?.maxSizeBytes ?? 2097152,
|
|
64878
|
+
// 2MB (ephemeral debug window)
|
|
64879
|
+
maxFiles: rotation?.maxFiles ?? 2
|
|
64503
64880
|
} : void 0;
|
|
64504
64881
|
const logManager = (0, core_1.createLogManager)({
|
|
64505
64882
|
name: "sidekick:cli",
|
|
@@ -64541,6 +64918,14 @@ var require_runtime = __commonJS({
|
|
|
64541
64918
|
}
|
|
64542
64919
|
});
|
|
64543
64920
|
const telemetry = logManager.getTelemetry();
|
|
64921
|
+
const sessionsDir = projectRoot ? (0, node_path_1.join)(projectRoot, ".sidekick", "sessions") : (0, node_path_1.join)((0, node_os_1.homedir)(), ".sidekick", "sessions");
|
|
64922
|
+
const sessionLogWriter = new core_1.SessionLogWriter({
|
|
64923
|
+
sessionsDir,
|
|
64924
|
+
maxHandles: 2,
|
|
64925
|
+
// CLI typically has 1 session
|
|
64926
|
+
idleTimeoutMs: 10 * 60 * 1e3
|
|
64927
|
+
});
|
|
64928
|
+
(0, core_1.setSessionLogWriter)(sessionLogWriter);
|
|
64544
64929
|
const cleanupErrorHandlers = (0, core_1.setupGlobalErrorHandlers)(logger);
|
|
64545
64930
|
logger.debug("Runtime bootstrap complete", {
|
|
64546
64931
|
projectRoot: projectRoot ?? null,
|
|
@@ -64563,6 +64948,8 @@ var require_runtime = __commonJS({
|
|
|
64563
64948
|
stateService,
|
|
64564
64949
|
correlationId,
|
|
64565
64950
|
cleanup: () => {
|
|
64951
|
+
(0, core_1.setSessionLogWriter)(null);
|
|
64952
|
+
void sessionLogWriter.closeAll();
|
|
64566
64953
|
cleanupErrorHandlers();
|
|
64567
64954
|
},
|
|
64568
64955
|
bindSessionId: (sessionId) => {
|
|
@@ -64640,7 +65027,7 @@ var require_dev_mode_guard = __commonJS({
|
|
|
64640
65027
|
}
|
|
64641
65028
|
} catch (err) {
|
|
64642
65029
|
logger.warn(`Failed to auto-correct devMode flag for ${callerLabel}`, {
|
|
64643
|
-
error:
|
|
65030
|
+
error: (0, core_1.toErrorMessage)(err),
|
|
64644
65031
|
caller: callerLabel
|
|
64645
65032
|
});
|
|
64646
65033
|
}
|
|
@@ -64658,7 +65045,7 @@ var require_dev_mode_guard = __commonJS({
|
|
|
64658
65045
|
}
|
|
64659
65046
|
} catch (err) {
|
|
64660
65047
|
logger.warn(`Failed to check plugin/dev-mode status for ${callerLabel}, proceeding normally`, {
|
|
64661
|
-
error:
|
|
65048
|
+
error: (0, core_1.toErrorMessage)(err),
|
|
64662
65049
|
caller: callerLabel
|
|
64663
65050
|
});
|
|
64664
65051
|
}
|
|
@@ -71684,6 +72071,7 @@ var require_reminder_utils = __commonJS({
|
|
|
71684
72071
|
var node_path_1 = require("node:path");
|
|
71685
72072
|
var yaml = __importStar(require_js_yaml());
|
|
71686
72073
|
var zod_1 = require_zod2();
|
|
72074
|
+
var core_1 = require_dist4();
|
|
71687
72075
|
var ReminderDefinitionSchema = zod_1.z.object({
|
|
71688
72076
|
id: zod_1.z.string(),
|
|
71689
72077
|
blocking: zod_1.z.boolean(),
|
|
@@ -71736,7 +72124,7 @@ var require_reminder_utils = __commonJS({
|
|
|
71736
72124
|
if (logger) {
|
|
71737
72125
|
logger.error("Failed to load reminder", {
|
|
71738
72126
|
reminderId,
|
|
71739
|
-
error:
|
|
72127
|
+
error: (0, core_1.toErrorMessage)(err)
|
|
71740
72128
|
});
|
|
71741
72129
|
} else {
|
|
71742
72130
|
console.error(`Failed to load reminder ${reminderId}:`, err);
|
|
@@ -72476,7 +72864,7 @@ var require_stage_pause_and_reflect = __commonJS({
|
|
|
72476
72864
|
(0, staging_handler_utils_js_1.createStagingHandler)(context, {
|
|
72477
72865
|
id: "reminders:stage-pause-and-reflect",
|
|
72478
72866
|
priority: 80,
|
|
72479
|
-
filter: { kind: "transcript", eventTypes: ["
|
|
72867
|
+
filter: { kind: "transcript", eventTypes: ["ToolResult"] },
|
|
72480
72868
|
execute: async (event, ctx) => {
|
|
72481
72869
|
if (!(0, types_1.isTranscriptEvent)(event))
|
|
72482
72870
|
return void 0;
|
|
@@ -74159,17 +74547,15 @@ var require_track_verification_tools = __commonJS({
|
|
|
74159
74547
|
var state_js_1 = require_state4();
|
|
74160
74548
|
var FILE_EDIT_TOOLS = ["Write", "Edit", "MultiEdit"];
|
|
74161
74549
|
var VC_TOOL_NAME_SET = new Set(types_js_1.VC_TOOL_REMINDER_IDS);
|
|
74162
|
-
|
|
74163
|
-
const entry = event.payload.entry;
|
|
74164
|
-
return entry?.input;
|
|
74165
|
-
}
|
|
74550
|
+
var MAX_PENDING_TOOL_CALLS = 100;
|
|
74166
74551
|
function registerTrackVerificationTools(context) {
|
|
74167
74552
|
if (!(0, types_1.isDaemonContext)(context))
|
|
74168
74553
|
return;
|
|
74554
|
+
const pendingBySession = /* @__PURE__ */ new Map();
|
|
74169
74555
|
context.handlers.register({
|
|
74170
74556
|
id: "reminders:track-verification-tools",
|
|
74171
74557
|
priority: 60,
|
|
74172
|
-
filter: { kind: "transcript", eventTypes: ["ToolCall"] },
|
|
74558
|
+
filter: { kind: "transcript", eventTypes: ["ToolCall", "ToolResult"] },
|
|
74173
74559
|
handler: async (event, ctx) => {
|
|
74174
74560
|
if (!(0, types_1.isTranscriptEvent)(event))
|
|
74175
74561
|
return;
|
|
@@ -74181,22 +74567,66 @@ var require_track_verification_tools = __commonJS({
|
|
|
74181
74567
|
const sessionId = event.context?.sessionId;
|
|
74182
74568
|
if (!sessionId)
|
|
74183
74569
|
return;
|
|
74184
|
-
|
|
74185
|
-
|
|
74570
|
+
if (event.eventType === "ToolCall") {
|
|
74571
|
+
const toolUseId = event.payload.entry.id;
|
|
74572
|
+
const toolName = event.payload.toolName;
|
|
74573
|
+
if (!toolUseId || !toolName)
|
|
74574
|
+
return;
|
|
74575
|
+
const entry = event.payload.entry;
|
|
74576
|
+
const input = entry?.input ?? {};
|
|
74577
|
+
let sessionMap = pendingBySession.get(sessionId);
|
|
74578
|
+
if (!sessionMap) {
|
|
74579
|
+
sessionMap = /* @__PURE__ */ new Map();
|
|
74580
|
+
pendingBySession.set(sessionId, sessionMap);
|
|
74581
|
+
}
|
|
74582
|
+
if (sessionMap.size >= MAX_PENDING_TOOL_CALLS) {
|
|
74583
|
+
const oldest = sessionMap.keys().next().value;
|
|
74584
|
+
if (oldest)
|
|
74585
|
+
sessionMap.delete(oldest);
|
|
74586
|
+
}
|
|
74587
|
+
sessionMap.set(toolUseId, { toolName, input });
|
|
74186
74588
|
return;
|
|
74187
|
-
|
|
74188
|
-
|
|
74189
|
-
|
|
74190
|
-
|
|
74191
|
-
|
|
74192
|
-
|
|
74193
|
-
|
|
74194
|
-
|
|
74195
|
-
|
|
74196
|
-
|
|
74589
|
+
}
|
|
74590
|
+
if (event.eventType === "ToolResult") {
|
|
74591
|
+
const toolUseId = event.payload.entry.tool_use_id;
|
|
74592
|
+
if (!toolUseId)
|
|
74593
|
+
return;
|
|
74594
|
+
const sessionMap = pendingBySession.get(sessionId);
|
|
74595
|
+
const pending = sessionMap?.get(toolUseId);
|
|
74596
|
+
if (!pending)
|
|
74597
|
+
return;
|
|
74598
|
+
sessionMap.delete(toolUseId);
|
|
74599
|
+
if (sessionMap.size === 0)
|
|
74600
|
+
pendingBySession.delete(sessionId);
|
|
74601
|
+
const { toolName, input } = pending;
|
|
74602
|
+
const config = (0, types_js_1.getRemindersConfig)(context.config);
|
|
74603
|
+
const verificationTools = config.verification_tools ?? {};
|
|
74604
|
+
const runners = config.command_runners ?? [];
|
|
74605
|
+
const remindersState = (0, state_js_1.createRemindersState)(daemonCtx.stateService);
|
|
74606
|
+
const stateResult = await remindersState.verificationTools.read(sessionId);
|
|
74607
|
+
const toolsState = { ...stateResult.data };
|
|
74608
|
+
if (FILE_EDIT_TOOLS.includes(toolName)) {
|
|
74609
|
+
await handleFileEdit(input, daemonCtx, sessionId, verificationTools, toolsState, remindersState);
|
|
74610
|
+
} else if (toolName === "Bash") {
|
|
74611
|
+
await handleBashCommand(input, daemonCtx, sessionId, verificationTools, toolsState, remindersState, runners);
|
|
74612
|
+
}
|
|
74197
74613
|
}
|
|
74198
74614
|
}
|
|
74199
74615
|
});
|
|
74616
|
+
context.handlers.register({
|
|
74617
|
+
id: "reminders:track-verification-tools-cleanup",
|
|
74618
|
+
priority: 60,
|
|
74619
|
+
filter: { kind: "hook", hooks: ["UserPromptSubmit", "Stop"] },
|
|
74620
|
+
// eslint-disable-next-line @typescript-eslint/require-await -- sync cleanup, async required by EventHandler type
|
|
74621
|
+
handler: async (event, _ctx) => {
|
|
74622
|
+
if (!(0, types_1.isHookEvent)(event))
|
|
74623
|
+
return;
|
|
74624
|
+
const sessionId = event.context?.sessionId;
|
|
74625
|
+
if (!sessionId)
|
|
74626
|
+
return;
|
|
74627
|
+
pendingBySession.delete(sessionId);
|
|
74628
|
+
}
|
|
74629
|
+
});
|
|
74200
74630
|
}
|
|
74201
74631
|
async function stageToolsForFiles(filePaths, daemonCtx, sessionId, verificationTools, toolsState, remindersState, triggeredBy = "file_edit") {
|
|
74202
74632
|
const existingReminders = await daemonCtx.staging.listReminders("Stop");
|
|
@@ -74301,7 +74731,7 @@ var require_track_verification_tools = __commonJS({
|
|
|
74301
74731
|
toolName,
|
|
74302
74732
|
reminderId,
|
|
74303
74733
|
sessionId,
|
|
74304
|
-
error:
|
|
74734
|
+
error: (0, core_1.toErrorMessage)(error)
|
|
74305
74735
|
});
|
|
74306
74736
|
}
|
|
74307
74737
|
}
|
|
@@ -74315,8 +74745,8 @@ var require_track_verification_tools = __commonJS({
|
|
|
74315
74745
|
await remindersState.verificationTools.write(sessionId, toolsState);
|
|
74316
74746
|
return anyStaged;
|
|
74317
74747
|
}
|
|
74318
|
-
async function handleFileEdit(
|
|
74319
|
-
const filePath =
|
|
74748
|
+
async function handleFileEdit(input, daemonCtx, sessionId, verificationTools, toolsState, remindersState) {
|
|
74749
|
+
const filePath = input.file_path;
|
|
74320
74750
|
if (!filePath)
|
|
74321
74751
|
return;
|
|
74322
74752
|
const projectDir = daemonCtx.paths?.projectDir;
|
|
@@ -74324,8 +74754,8 @@ var require_track_verification_tools = __commonJS({
|
|
|
74324
74754
|
return;
|
|
74325
74755
|
await stageToolsForFiles([filePath], daemonCtx, sessionId, verificationTools, toolsState, remindersState);
|
|
74326
74756
|
}
|
|
74327
|
-
async function handleBashCommand(
|
|
74328
|
-
const command =
|
|
74757
|
+
async function handleBashCommand(input, daemonCtx, sessionId, verificationTools, toolsState, remindersState, runners = []) {
|
|
74758
|
+
const command = input.command;
|
|
74329
74759
|
if (!command)
|
|
74330
74760
|
return;
|
|
74331
74761
|
let anyUnstaged = false;
|
|
@@ -74754,7 +75184,7 @@ var require_stage_persona_reminders = __commonJS({
|
|
|
74754
75184
|
} catch (err) {
|
|
74755
75185
|
logger.error("Failed to restage persona reminders", {
|
|
74756
75186
|
sessionId,
|
|
74757
|
-
error:
|
|
75187
|
+
error: (0, core_1.toErrorMessage)(err)
|
|
74758
75188
|
});
|
|
74759
75189
|
}
|
|
74760
75190
|
}
|
|
@@ -74990,6 +75420,38 @@ var require_stage_user_profile_reminders = __commonJS({
|
|
|
74990
75420
|
}
|
|
74991
75421
|
});
|
|
74992
75422
|
|
|
75423
|
+
// ../feature-reminders/dist/handlers/staging/cleanup-on-stop.js
|
|
75424
|
+
var require_cleanup_on_stop = __commonJS({
|
|
75425
|
+
"../feature-reminders/dist/handlers/staging/cleanup-on-stop.js"(exports2) {
|
|
75426
|
+
"use strict";
|
|
75427
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
75428
|
+
exports2.registerCleanupOnStop = registerCleanupOnStop;
|
|
75429
|
+
var types_1 = require_dist();
|
|
75430
|
+
function registerCleanupOnStop(context) {
|
|
75431
|
+
if (!(0, types_1.isDaemonContext)(context))
|
|
75432
|
+
return;
|
|
75433
|
+
context.handlers.register({
|
|
75434
|
+
id: "reminders:cleanup-on-stop",
|
|
75435
|
+
priority: 50,
|
|
75436
|
+
filter: { kind: "hook", hooks: ["Stop"] },
|
|
75437
|
+
handler: async (event, ctx) => {
|
|
75438
|
+
if (!(0, types_1.isHookEvent)(event))
|
|
75439
|
+
return;
|
|
75440
|
+
if (!(0, types_1.isDaemonContext)(ctx))
|
|
75441
|
+
return;
|
|
75442
|
+
const daemonCtx = ctx;
|
|
75443
|
+
const sessionId = event.context?.sessionId;
|
|
75444
|
+
if (!sessionId)
|
|
75445
|
+
return;
|
|
75446
|
+
if (daemonCtx.orchestrator) {
|
|
75447
|
+
await daemonCtx.orchestrator.onStop(sessionId);
|
|
75448
|
+
}
|
|
75449
|
+
}
|
|
75450
|
+
});
|
|
75451
|
+
}
|
|
75452
|
+
}
|
|
75453
|
+
});
|
|
75454
|
+
|
|
74993
75455
|
// ../feature-reminders/dist/handlers/staging/index.js
|
|
74994
75456
|
var require_staging2 = __commonJS({
|
|
74995
75457
|
"../feature-reminders/dist/handlers/staging/index.js"(exports2) {
|
|
@@ -75003,6 +75465,7 @@ var require_staging2 = __commonJS({
|
|
|
75003
75465
|
var unstage_verify_completion_1 = require_unstage_verify_completion();
|
|
75004
75466
|
var stage_persona_reminders_1 = require_stage_persona_reminders();
|
|
75005
75467
|
var stage_user_profile_reminders_1 = require_stage_user_profile_reminders();
|
|
75468
|
+
var cleanup_on_stop_1 = require_cleanup_on_stop();
|
|
75006
75469
|
function registerStagingHandlers(context) {
|
|
75007
75470
|
(0, stage_default_user_prompt_1.registerStageDefaultUserPrompt)(context);
|
|
75008
75471
|
(0, stage_pause_and_reflect_1.registerStagePauseAndReflect)(context);
|
|
@@ -75011,6 +75474,7 @@ var require_staging2 = __commonJS({
|
|
|
75011
75474
|
(0, unstage_verify_completion_1.registerUnstageVerifyCompletion)(context);
|
|
75012
75475
|
(0, stage_persona_reminders_1.registerStagePersonaReminders)(context);
|
|
75013
75476
|
(0, stage_user_profile_reminders_1.registerStageUserProfileReminders)(context);
|
|
75477
|
+
(0, cleanup_on_stop_1.registerCleanupOnStop)(context);
|
|
75014
75478
|
}
|
|
75015
75479
|
}
|
|
75016
75480
|
});
|
|
@@ -75731,7 +76195,7 @@ var require_orchestrator = __commonJS({
|
|
|
75731
76195
|
} catch (err) {
|
|
75732
76196
|
this.deps.logger.warn("Failed to unstage VC reminders after P&R staged", {
|
|
75733
76197
|
sessionId,
|
|
75734
|
-
error:
|
|
76198
|
+
error: (0, core_1.toErrorMessage)(err)
|
|
75735
76199
|
});
|
|
75736
76200
|
}
|
|
75737
76201
|
}
|
|
@@ -75755,27 +76219,10 @@ var require_orchestrator = __commonJS({
|
|
|
75755
76219
|
} catch (err) {
|
|
75756
76220
|
this.deps.logger.warn("Failed to reset P&R baseline after VC consumed", {
|
|
75757
76221
|
sessionId,
|
|
75758
|
-
error:
|
|
75759
|
-
});
|
|
75760
|
-
}
|
|
75761
|
-
try {
|
|
75762
|
-
const staging = this.deps.getStagingService(sessionId);
|
|
75763
|
-
const deleted = await staging.deleteReminder("PreToolUse", types_js_1.ReminderIds.PAUSE_AND_REFLECT);
|
|
75764
|
-
if (deleted) {
|
|
75765
|
-
(0, core_1.logEvent)(this.deps.logger.child({ context: { sessionId } }), events_js_1.ReminderEvents.reminderUnstaged({ sessionId }, {
|
|
75766
|
-
reminderName: types_js_1.ReminderIds.PAUSE_AND_REFLECT,
|
|
75767
|
-
hookName: "PreToolUse",
|
|
75768
|
-
reason: "vc_consumed_cascade",
|
|
75769
|
-
triggeredBy: "cascade_from_verify_completion"
|
|
75770
|
-
}));
|
|
75771
|
-
}
|
|
75772
|
-
this.deps.logger.debug("VC unstage: P&R cascade from VC consumed", { sessionId, deleted });
|
|
75773
|
-
} catch (err) {
|
|
75774
|
-
this.deps.logger.warn("Failed to unstage P&R after VC consumed", {
|
|
75775
|
-
sessionId,
|
|
75776
|
-
error: err instanceof Error ? err.message : String(err)
|
|
76222
|
+
error: (0, core_1.toErrorMessage)(err)
|
|
75777
76223
|
});
|
|
75778
76224
|
}
|
|
76225
|
+
await this.unstagePauseAndReflect(sessionId, "vc_consumed_cascade", "cascade_from_verify_completion");
|
|
75779
76226
|
}
|
|
75780
76227
|
}
|
|
75781
76228
|
/**
|
|
@@ -75792,7 +76239,43 @@ var require_orchestrator = __commonJS({
|
|
|
75792
76239
|
} catch (err) {
|
|
75793
76240
|
this.deps.logger.warn("Failed to clear P&R baseline on UserPromptSubmit", {
|
|
75794
76241
|
sessionId,
|
|
75795
|
-
error:
|
|
76242
|
+
error: (0, core_1.toErrorMessage)(err)
|
|
76243
|
+
});
|
|
76244
|
+
}
|
|
76245
|
+
}
|
|
76246
|
+
/**
|
|
76247
|
+
* Called when Stop hook fires.
|
|
76248
|
+
*
|
|
76249
|
+
* P&R is designed to interrupt runaway execution — once the agent stops,
|
|
76250
|
+
* it's irrelevant. This is defensive: Rule 4 (VC consumed → unstage P&R)
|
|
76251
|
+
* covers the VC case, but this handles the no-VC case where P&R would
|
|
76252
|
+
* otherwise linger on PreToolUse.
|
|
76253
|
+
*/
|
|
76254
|
+
async onStop(sessionId) {
|
|
76255
|
+
await this.unstagePauseAndReflect(sessionId, "agent_stopping", "stop_hook");
|
|
76256
|
+
}
|
|
76257
|
+
/**
|
|
76258
|
+
* Delete P&R from PreToolUse staging and log the event.
|
|
76259
|
+
* Shared by Rule 4 (VC consumed → unstage P&R) and onStop (agent stopping).
|
|
76260
|
+
*/
|
|
76261
|
+
async unstagePauseAndReflect(sessionId, reason, triggeredBy) {
|
|
76262
|
+
try {
|
|
76263
|
+
const staging = this.deps.getStagingService(sessionId);
|
|
76264
|
+
const deleted = await staging.deleteReminder("PreToolUse", types_js_1.ReminderIds.PAUSE_AND_REFLECT);
|
|
76265
|
+
if (deleted) {
|
|
76266
|
+
(0, core_1.logEvent)(this.deps.logger.child({ context: { sessionId } }), events_js_1.ReminderEvents.reminderUnstaged({ sessionId }, {
|
|
76267
|
+
reminderName: types_js_1.ReminderIds.PAUSE_AND_REFLECT,
|
|
76268
|
+
hookName: "PreToolUse",
|
|
76269
|
+
reason,
|
|
76270
|
+
triggeredBy
|
|
76271
|
+
}));
|
|
76272
|
+
}
|
|
76273
|
+
this.deps.logger.debug("P&R unstaged", { sessionId, deleted, reason });
|
|
76274
|
+
} catch (err) {
|
|
76275
|
+
this.deps.logger.warn("Failed to unstage P&R", {
|
|
76276
|
+
sessionId,
|
|
76277
|
+
reason,
|
|
76278
|
+
error: (0, core_1.toErrorMessage)(err)
|
|
75796
76279
|
});
|
|
75797
76280
|
}
|
|
75798
76281
|
}
|
|
@@ -75961,6 +76444,7 @@ var require_hook = __commonJS({
|
|
|
75961
76444
|
exports2.isHookCommand = isHookCommand;
|
|
75962
76445
|
exports2.getHookName = getHookName;
|
|
75963
76446
|
var core_1 = require_dist4();
|
|
76447
|
+
var types_1 = require_dist();
|
|
75964
76448
|
var context_js_1 = require_context2();
|
|
75965
76449
|
function truncateForLog(raw) {
|
|
75966
76450
|
const entries = Object.entries(raw);
|
|
@@ -75989,15 +76473,7 @@ var require_hook = __commonJS({
|
|
|
75989
76473
|
}
|
|
75990
76474
|
return truncateForLog(filtered);
|
|
75991
76475
|
}
|
|
75992
|
-
var VALID_HOOK_NAMES =
|
|
75993
|
-
"SessionStart",
|
|
75994
|
-
"SessionEnd",
|
|
75995
|
-
"UserPromptSubmit",
|
|
75996
|
-
"PreToolUse",
|
|
75997
|
-
"PostToolUse",
|
|
75998
|
-
"Stop",
|
|
75999
|
-
"PreCompact"
|
|
76000
|
-
]);
|
|
76476
|
+
var VALID_HOOK_NAMES = new Set(types_1.HOOK_NAMES);
|
|
76001
76477
|
function validateHookName(hookEventName) {
|
|
76002
76478
|
return VALID_HOOK_NAMES.has(hookEventName) ? hookEventName : void 0;
|
|
76003
76479
|
}
|
|
@@ -76008,7 +76484,9 @@ var require_hook = __commonJS({
|
|
|
76008
76484
|
"pre-tool-use": "PreToolUse",
|
|
76009
76485
|
"post-tool-use": "PostToolUse",
|
|
76010
76486
|
stop: "Stop",
|
|
76011
|
-
"pre-compact": "PreCompact"
|
|
76487
|
+
"pre-compact": "PreCompact",
|
|
76488
|
+
"subagent-start": "SubagentStart",
|
|
76489
|
+
"subagent-stop": "SubagentStop"
|
|
76012
76490
|
};
|
|
76013
76491
|
function extractToolFields(raw) {
|
|
76014
76492
|
const toolName = typeof raw.tool_name === "string" ? raw.tool_name : "unknown";
|
|
@@ -76110,11 +76588,46 @@ var require_hook = __commonJS({
|
|
|
76110
76588
|
}
|
|
76111
76589
|
};
|
|
76112
76590
|
}
|
|
76591
|
+
function buildSubagentStartEvent(context, input) {
|
|
76592
|
+
return {
|
|
76593
|
+
kind: "hook",
|
|
76594
|
+
hook: "SubagentStart",
|
|
76595
|
+
context,
|
|
76596
|
+
payload: {
|
|
76597
|
+
transcriptPath: input.transcriptPath,
|
|
76598
|
+
agentId: context.agentId,
|
|
76599
|
+
agentType: context.agentType
|
|
76600
|
+
}
|
|
76601
|
+
};
|
|
76602
|
+
}
|
|
76603
|
+
function buildSubagentStopEvent(context, input) {
|
|
76604
|
+
const raw = input.raw;
|
|
76605
|
+
const agentTranscriptPath = typeof raw.agent_transcript_path === "string" ? raw.agent_transcript_path : "";
|
|
76606
|
+
const lastAssistantMessage = typeof raw.last_assistant_message === "string" ? raw.last_assistant_message : "";
|
|
76607
|
+
const permissionMode = input.permissionMode ?? "default";
|
|
76608
|
+
const stopHookActive = typeof raw.stop_hook_active === "boolean" ? raw.stop_hook_active : void 0;
|
|
76609
|
+
return {
|
|
76610
|
+
kind: "hook",
|
|
76611
|
+
hook: "SubagentStop",
|
|
76612
|
+
context,
|
|
76613
|
+
payload: {
|
|
76614
|
+
transcriptPath: input.transcriptPath,
|
|
76615
|
+
permissionMode,
|
|
76616
|
+
agentId: context.agentId,
|
|
76617
|
+
agentType: context.agentType,
|
|
76618
|
+
agentTranscriptPath,
|
|
76619
|
+
lastAssistantMessage,
|
|
76620
|
+
...stopHookActive !== void 0 && { stopHookActive }
|
|
76621
|
+
}
|
|
76622
|
+
};
|
|
76623
|
+
}
|
|
76113
76624
|
function buildHookEvent(hookName, input, correlationId) {
|
|
76114
76625
|
const context = {
|
|
76115
76626
|
sessionId: input.sessionId,
|
|
76116
76627
|
timestamp: Date.now(),
|
|
76117
|
-
correlationId
|
|
76628
|
+
correlationId,
|
|
76629
|
+
...input.agentId !== void 0 && { agentId: input.agentId },
|
|
76630
|
+
...input.agentType !== void 0 && { agentType: input.agentType }
|
|
76118
76631
|
};
|
|
76119
76632
|
switch (hookName) {
|
|
76120
76633
|
case "SessionStart":
|
|
@@ -76131,6 +76644,22 @@ var require_hook = __commonJS({
|
|
|
76131
76644
|
return buildStopEvent(context, input);
|
|
76132
76645
|
case "PreCompact":
|
|
76133
76646
|
return buildPreCompactEvent(context, input);
|
|
76647
|
+
case "SubagentStart": {
|
|
76648
|
+
const subagentContext = {
|
|
76649
|
+
...context,
|
|
76650
|
+
agentId: input.agentId ?? "",
|
|
76651
|
+
agentType: input.agentType ?? ""
|
|
76652
|
+
};
|
|
76653
|
+
return buildSubagentStartEvent(subagentContext, input);
|
|
76654
|
+
}
|
|
76655
|
+
case "SubagentStop": {
|
|
76656
|
+
const subagentContext = {
|
|
76657
|
+
...context,
|
|
76658
|
+
agentId: input.agentId ?? "",
|
|
76659
|
+
agentType: input.agentType ?? ""
|
|
76660
|
+
};
|
|
76661
|
+
return buildSubagentStopEvent(subagentContext, input);
|
|
76662
|
+
}
|
|
76134
76663
|
}
|
|
76135
76664
|
}
|
|
76136
76665
|
function mergeHookResponses(daemonResponse, cliResponse) {
|
|
@@ -76152,6 +76681,10 @@ ${daemonResponse.additionalContext}` : cliResponse.additionalContext;
|
|
|
76152
76681
|
return merged;
|
|
76153
76682
|
}
|
|
76154
76683
|
async function handleHookCommand(hookName, options, logger, stdout) {
|
|
76684
|
+
if (process.env.SIDEKICK_SUBPROCESS === "1") {
|
|
76685
|
+
stdout.write("{}\n");
|
|
76686
|
+
return { exitCode: 0, output: "{}" };
|
|
76687
|
+
}
|
|
76155
76688
|
const { projectRoot, hookInput, correlationId, runtime } = options;
|
|
76156
76689
|
const startTime = Date.now();
|
|
76157
76690
|
const logContext = {
|
|
@@ -76260,7 +76793,7 @@ var require_hook_command = __commonJS({
|
|
|
76260
76793
|
return void 0;
|
|
76261
76794
|
} catch (err) {
|
|
76262
76795
|
logger.error("Failed to load safe-word-liveness.yaml", {
|
|
76263
|
-
error:
|
|
76796
|
+
error: (0, core_1.toErrorMessage)(err),
|
|
76264
76797
|
projectRoot
|
|
76265
76798
|
});
|
|
76266
76799
|
return void 0;
|
|
@@ -76343,6 +76876,17 @@ var require_hook_command = __commonJS({
|
|
|
76343
76876
|
addUserMessage(response, internal.userMessage);
|
|
76344
76877
|
return response;
|
|
76345
76878
|
}
|
|
76879
|
+
function translateSubagentStart(internal) {
|
|
76880
|
+
const response = {};
|
|
76881
|
+
if (internal.additionalContext) {
|
|
76882
|
+
response.hookSpecificOutput = {
|
|
76883
|
+
hookEventName: "SubagentStart",
|
|
76884
|
+
additionalContext: internal.additionalContext
|
|
76885
|
+
};
|
|
76886
|
+
}
|
|
76887
|
+
addUserMessage(response, internal.userMessage);
|
|
76888
|
+
return response;
|
|
76889
|
+
}
|
|
76346
76890
|
var TRANSLATORS = {
|
|
76347
76891
|
SessionStart: translateSessionStart,
|
|
76348
76892
|
SessionEnd: () => ({}),
|
|
@@ -76350,7 +76894,10 @@ var require_hook_command = __commonJS({
|
|
|
76350
76894
|
PreToolUse: translatePreToolUse,
|
|
76351
76895
|
PostToolUse: translatePostToolUse,
|
|
76352
76896
|
Stop: translateStop,
|
|
76353
|
-
PreCompact: () => ({})
|
|
76897
|
+
PreCompact: () => ({}),
|
|
76898
|
+
SubagentStart: translateSubagentStart,
|
|
76899
|
+
// SubagentStop shares Stop's blocking semantics verbatim per Claude Code docs.
|
|
76900
|
+
SubagentStop: translateStop
|
|
76354
76901
|
};
|
|
76355
76902
|
function translateToClaudeCodeFormat(hookName, internal) {
|
|
76356
76903
|
return TRANSLATORS[hookName](internal);
|
|
@@ -76363,13 +76910,17 @@ var require_hook_command = __commonJS({
|
|
|
76363
76910
|
"post-tool-use": "PostToolUse",
|
|
76364
76911
|
stop: "Stop",
|
|
76365
76912
|
"pre-compact": "PreCompact",
|
|
76913
|
+
"subagent-start": "SubagentStart",
|
|
76914
|
+
"subagent-stop": "SubagentStop",
|
|
76366
76915
|
SessionStart: "SessionStart",
|
|
76367
76916
|
SessionEnd: "SessionEnd",
|
|
76368
76917
|
UserPromptSubmit: "UserPromptSubmit",
|
|
76369
76918
|
PreToolUse: "PreToolUse",
|
|
76370
76919
|
PostToolUse: "PostToolUse",
|
|
76371
76920
|
Stop: "Stop",
|
|
76372
|
-
PreCompact: "PreCompact"
|
|
76921
|
+
PreCompact: "PreCompact",
|
|
76922
|
+
SubagentStart: "SubagentStart",
|
|
76923
|
+
SubagentStop: "SubagentStop"
|
|
76373
76924
|
};
|
|
76374
76925
|
function parseHookArg(arg) {
|
|
76375
76926
|
return arg ? HOOK_ARG_TO_NAME[arg] : void 0;
|
|
@@ -76402,7 +76953,7 @@ var require_hook_command = __commonJS({
|
|
|
76402
76953
|
return configured;
|
|
76403
76954
|
} catch (err) {
|
|
76404
76955
|
logger.warn("Failed to auto-configure project", {
|
|
76405
|
-
error:
|
|
76956
|
+
error: (0, core_1.toErrorMessage)(err),
|
|
76406
76957
|
projectRoot
|
|
76407
76958
|
});
|
|
76408
76959
|
return false;
|
|
@@ -76415,7 +76966,7 @@ var require_hook_command = __commonJS({
|
|
|
76415
76966
|
state = await setupService.getSetupState();
|
|
76416
76967
|
} catch (err) {
|
|
76417
76968
|
logger.warn("Failed to check setup state, assuming healthy", {
|
|
76418
|
-
error:
|
|
76969
|
+
error: (0, core_1.toErrorMessage)(err),
|
|
76419
76970
|
hookName,
|
|
76420
76971
|
projectRoot
|
|
76421
76972
|
});
|
|
@@ -76453,7 +77004,7 @@ var require_hook_command = __commonJS({
|
|
|
76453
77004
|
}
|
|
76454
77005
|
} catch (err) {
|
|
76455
77006
|
logger.warn("Failed to check setup status for daemon start, proceeding anyway", {
|
|
76456
|
-
error:
|
|
77007
|
+
error: (0, core_1.toErrorMessage)(err)
|
|
76457
77008
|
});
|
|
76458
77009
|
}
|
|
76459
77010
|
try {
|
|
@@ -76463,7 +77014,7 @@ var require_hook_command = __commonJS({
|
|
|
76463
77014
|
await (0, core_1.updateDaemonHealth)(projectRoot, "healthy", logger);
|
|
76464
77015
|
return true;
|
|
76465
77016
|
} catch (err) {
|
|
76466
|
-
const errorMessage =
|
|
77017
|
+
const errorMessage = (0, core_1.toErrorMessage)(err);
|
|
76467
77018
|
await (0, core_1.updateDaemonHealth)(projectRoot, "failed", logger, errorMessage);
|
|
76468
77019
|
return false;
|
|
76469
77020
|
}
|
|
@@ -76476,13 +77027,17 @@ var require_hook_command = __commonJS({
|
|
|
76476
77027
|
} catch (err) {
|
|
76477
77028
|
logger.warn("Failed to parse internal hook response", {
|
|
76478
77029
|
hookName,
|
|
76479
|
-
error:
|
|
77030
|
+
error: (0, core_1.toErrorMessage)(err),
|
|
76480
77031
|
output
|
|
76481
77032
|
});
|
|
76482
77033
|
return {};
|
|
76483
77034
|
}
|
|
76484
77035
|
}
|
|
76485
77036
|
async function handleUnifiedHookCommand(hookName, options, logger, stdout) {
|
|
77037
|
+
if (process.env.SIDEKICK_SUBPROCESS === "1") {
|
|
77038
|
+
stdout.write("{}\n");
|
|
77039
|
+
return { exitCode: 0, output: "{}" };
|
|
77040
|
+
}
|
|
76486
77041
|
const { projectRoot, hookInput, correlationId, runtime, forceDevMode } = options;
|
|
76487
77042
|
logger.debug("Unified hook command invoked", { hookName, sessionId: hookInput.sessionId });
|
|
76488
77043
|
const devModeGuard = await (0, dev_mode_guard_js_1.checkDevModeConflict)(projectRoot, forceDevMode, logger, hookName);
|
|
@@ -77251,7 +77806,7 @@ var require_persona_selection = __commonJS({
|
|
|
77251
77806
|
} catch (err) {
|
|
77252
77807
|
ctx.logger.warn("Failed to ensure persona for session", {
|
|
77253
77808
|
sessionId,
|
|
77254
|
-
error:
|
|
77809
|
+
error: (0, core_1.toErrorMessage)(err)
|
|
77255
77810
|
});
|
|
77256
77811
|
}
|
|
77257
77812
|
}
|
|
@@ -78011,7 +78566,7 @@ var require_update_summary = __commonJS({
|
|
|
78011
78566
|
ctx.logger.error("performAnalysis failed", {
|
|
78012
78567
|
sessionId,
|
|
78013
78568
|
reason,
|
|
78014
|
-
error:
|
|
78569
|
+
error: (0, core_1.toErrorMessage)(err)
|
|
78015
78570
|
});
|
|
78016
78571
|
}
|
|
78017
78572
|
}
|
|
@@ -78413,7 +78968,7 @@ var require_resume_discovery = __commonJS({
|
|
|
78413
78968
|
}
|
|
78414
78969
|
config.logger?.warn("Failed to discover previous resume message", {
|
|
78415
78970
|
sessionsDir: config.sessionsDir,
|
|
78416
|
-
error:
|
|
78971
|
+
error: (0, core_1.toErrorMessage)(error)
|
|
78417
78972
|
});
|
|
78418
78973
|
return NOT_FOUND;
|
|
78419
78974
|
}
|
|
@@ -80170,7 +80725,7 @@ Examples:
|
|
|
80170
80725
|
}
|
|
80171
80726
|
const event = core_1.LogEvents.statuslineError(eventContext, "unknown", {
|
|
80172
80727
|
fallbackUsed: true,
|
|
80173
|
-
error:
|
|
80728
|
+
error: (0, core_1.toErrorMessage)(error)
|
|
80174
80729
|
});
|
|
80175
80730
|
(0, core_1.logEvent)(logger, event);
|
|
80176
80731
|
logger.warn("Statusline render failed", { durationMs });
|
|
@@ -80188,6 +80743,7 @@ var require_ui = __commonJS({
|
|
|
80188
80743
|
exports2.handleUiCommand = handleUiCommand;
|
|
80189
80744
|
var node_child_process_1 = require("node:child_process");
|
|
80190
80745
|
var node_path_1 = require("node:path");
|
|
80746
|
+
var core_1 = require_dist4();
|
|
80191
80747
|
function resolveUiPackageDir() {
|
|
80192
80748
|
const cliCommandsDir = __dirname;
|
|
80193
80749
|
const cliPackageDir = (0, node_path_1.resolve)(cliCommandsDir, "..", "..");
|
|
@@ -80217,7 +80773,7 @@ var require_ui = __commonJS({
|
|
|
80217
80773
|
logger.debug("Browser open command executed", { command, url });
|
|
80218
80774
|
} catch (err) {
|
|
80219
80775
|
logger.warn("Failed to open browser", {
|
|
80220
|
-
error:
|
|
80776
|
+
error: (0, core_1.toErrorMessage)(err)
|
|
80221
80777
|
});
|
|
80222
80778
|
}
|
|
80223
80779
|
}
|
|
@@ -80523,7 +81079,7 @@ var require_persona2 = __commonJS({
|
|
|
80523
81079
|
}
|
|
80524
81080
|
return writeJsonResponse(stdout, { success: true, personaId, previousPersonaId }, 0);
|
|
80525
81081
|
} catch (err) {
|
|
80526
|
-
const errorMsg =
|
|
81082
|
+
const errorMsg = (0, core_1.toErrorMessage)(err);
|
|
80527
81083
|
logger.error("Failed to set persona", { error: errorMsg });
|
|
80528
81084
|
return writeJsonResponse(stdout, { success: false, error: errorMsg }, 1);
|
|
80529
81085
|
}
|
|
@@ -80547,7 +81103,7 @@ var require_persona2 = __commonJS({
|
|
|
80547
81103
|
logger.info("Persona cleared", { previousPersonaId: previousPersonaId ?? "(none)" });
|
|
80548
81104
|
return writeJsonResponse(stdout, { success: true, personaId: null, previousPersonaId }, 0);
|
|
80549
81105
|
} catch (err) {
|
|
80550
|
-
const errorMsg =
|
|
81106
|
+
const errorMsg = (0, core_1.toErrorMessage)(err);
|
|
80551
81107
|
logger.error("Failed to clear persona", { error: errorMsg });
|
|
80552
81108
|
return writeJsonResponse(stdout, { success: false, error: errorMsg }, 1);
|
|
80553
81109
|
}
|
|
@@ -80592,7 +81148,7 @@ var require_persona2 = __commonJS({
|
|
|
80592
81148
|
return writeJsonResponse(stdout, { error: `Failed to read generated file: ${statePath}` }, 1);
|
|
80593
81149
|
}
|
|
80594
81150
|
} catch (err) {
|
|
80595
|
-
const errorMsg =
|
|
81151
|
+
const errorMsg = (0, core_1.toErrorMessage)(err);
|
|
80596
81152
|
logger.error("Persona test failed", { error: errorMsg });
|
|
80597
81153
|
return writeJsonResponse(stdout, { error: errorMsg }, 1);
|
|
80598
81154
|
} finally {
|
|
@@ -80620,7 +81176,7 @@ var require_persona2 = __commonJS({
|
|
|
80620
81176
|
filePath: result.filePath
|
|
80621
81177
|
}, 0);
|
|
80622
81178
|
} catch (err) {
|
|
80623
|
-
const errorMsg =
|
|
81179
|
+
const errorMsg = (0, core_1.toErrorMessage)(err);
|
|
80624
81180
|
logger.error("Failed to pin persona", { error: errorMsg });
|
|
80625
81181
|
return writeJsonResponse(stdout, { success: false, error: errorMsg }, 1);
|
|
80626
81182
|
}
|
|
@@ -80644,7 +81200,7 @@ var require_persona2 = __commonJS({
|
|
|
80644
81200
|
previousPersonaId
|
|
80645
81201
|
}, 0);
|
|
80646
81202
|
} catch (err) {
|
|
80647
|
-
const errorMsg =
|
|
81203
|
+
const errorMsg = (0, core_1.toErrorMessage)(err);
|
|
80648
81204
|
logger.error("Failed to unpin persona", { error: errorMsg });
|
|
80649
81205
|
return writeJsonResponse(stdout, { success: false, error: errorMsg }, 1);
|
|
80650
81206
|
}
|
|
@@ -80755,7 +81311,7 @@ var require_config3 = __commonJS({
|
|
|
80755
81311
|
logger
|
|
80756
81312
|
});
|
|
80757
81313
|
} catch (err) {
|
|
80758
|
-
const message =
|
|
81314
|
+
const message = (0, core_1.toErrorMessage)(err);
|
|
80759
81315
|
const error = `Error: ${message}`;
|
|
80760
81316
|
stdout.write(error + "\n");
|
|
80761
81317
|
return { exitCode: 1, output: error };
|
|
@@ -80801,7 +81357,7 @@ var require_config3 = __commonJS({
|
|
|
80801
81357
|
stdout.write(output + "\n");
|
|
80802
81358
|
return { exitCode: 0, output };
|
|
80803
81359
|
} catch (err) {
|
|
80804
|
-
const message =
|
|
81360
|
+
const message = (0, core_1.toErrorMessage)(err);
|
|
80805
81361
|
const error = `Error: ${message}`;
|
|
80806
81362
|
stdout.write(error + "\n");
|
|
80807
81363
|
return { exitCode: 1, output: error };
|
|
@@ -80830,7 +81386,7 @@ var require_config3 = __commonJS({
|
|
|
80830
81386
|
stdout.write(output + "\n");
|
|
80831
81387
|
return { exitCode: 0, output };
|
|
80832
81388
|
} catch (err) {
|
|
80833
|
-
const message =
|
|
81389
|
+
const message = (0, core_1.toErrorMessage)(err);
|
|
80834
81390
|
const error = `Error: ${message}`;
|
|
80835
81391
|
stdout.write(error + "\n");
|
|
80836
81392
|
return { exitCode: 1, output: error };
|
|
@@ -80859,7 +81415,7 @@ var require_config3 = __commonJS({
|
|
|
80859
81415
|
stdout.write(output + "\n");
|
|
80860
81416
|
return { exitCode: 0, output };
|
|
80861
81417
|
} catch (err) {
|
|
80862
|
-
const message =
|
|
81418
|
+
const message = (0, core_1.toErrorMessage)(err);
|
|
80863
81419
|
const error = `Error: ${message}`;
|
|
80864
81420
|
stdout.write(error + "\n");
|
|
80865
81421
|
return { exitCode: 1, output: error };
|
|
@@ -81085,7 +81641,7 @@ Examples:
|
|
|
81085
81641
|
logger.info("Listed sessions", { count: sessions.length });
|
|
81086
81642
|
return { exitCode: 0, output: JSON.stringify({ count: sessions.length }) };
|
|
81087
81643
|
} catch (err) {
|
|
81088
|
-
const errorMsg =
|
|
81644
|
+
const errorMsg = (0, core_1.toErrorMessage)(err);
|
|
81089
81645
|
logger.error("Failed to list sessions", { error: errorMsg });
|
|
81090
81646
|
stdout.write(JSON.stringify({ error: errorMsg }, null, 2) + "\n");
|
|
81091
81647
|
return { exitCode: 1, output: errorMsg };
|
|
@@ -81738,14 +82294,63 @@ var require_dev_mode = __commonJS({
|
|
|
81738
82294
|
log(stdout, "info", "Full clean complete.");
|
|
81739
82295
|
return { exitCode: 0 };
|
|
81740
82296
|
}
|
|
82297
|
+
async function doCleanAllProjects(logger, stdout, options = {}) {
|
|
82298
|
+
const { force = false, stdin = process.stdin } = options;
|
|
82299
|
+
const registryRoot = node_path_1.default.join(node_os_1.default.homedir(), ".sidekick", "projects");
|
|
82300
|
+
const registry = new core_1.ProjectRegistryService(registryRoot);
|
|
82301
|
+
const projects = await registry.list();
|
|
82302
|
+
if (projects.length === 0) {
|
|
82303
|
+
log(stdout, "info", `No registered projects found in ${registryRoot}`);
|
|
82304
|
+
return { exitCode: 0 };
|
|
82305
|
+
}
|
|
82306
|
+
log(stdout, "step", `Found ${projects.length} registered project(s):`);
|
|
82307
|
+
for (const project of projects) {
|
|
82308
|
+
stdout.write(` - ${project.displayName} (${project.path})
|
|
82309
|
+
`);
|
|
82310
|
+
}
|
|
82311
|
+
stdout.write("\n");
|
|
82312
|
+
let cleanedCount = 0;
|
|
82313
|
+
let skippedCount = 0;
|
|
82314
|
+
for (const project of projects) {
|
|
82315
|
+
let projectStats;
|
|
82316
|
+
try {
|
|
82317
|
+
projectStats = await (0, promises_12.stat)(project.path);
|
|
82318
|
+
} catch {
|
|
82319
|
+
log(stdout, "warn", `${project.displayName}: directory not found at ${project.path}, skipping`);
|
|
82320
|
+
skippedCount++;
|
|
82321
|
+
continue;
|
|
82322
|
+
}
|
|
82323
|
+
if (!projectStats.isDirectory()) {
|
|
82324
|
+
log(stdout, "warn", `${project.displayName}: path is not a directory at ${project.path}, skipping`);
|
|
82325
|
+
skippedCount++;
|
|
82326
|
+
continue;
|
|
82327
|
+
}
|
|
82328
|
+
if (!force) {
|
|
82329
|
+
const shouldClean = await (0, prompt_js_1.promptConfirm)({ stdin, stdout }, `Clean ${project.displayName} (${project.path})?`);
|
|
82330
|
+
if (!shouldClean) {
|
|
82331
|
+
log(stdout, "info", `Skipping ${project.displayName}`);
|
|
82332
|
+
skippedCount++;
|
|
82333
|
+
continue;
|
|
82334
|
+
}
|
|
82335
|
+
}
|
|
82336
|
+
stdout.write("\n");
|
|
82337
|
+
log(stdout, "step", `Cleaning ${project.displayName}...`);
|
|
82338
|
+
await doClean(project.path, logger, stdout, { force, stdin });
|
|
82339
|
+
cleanedCount++;
|
|
82340
|
+
}
|
|
82341
|
+
stdout.write("\n");
|
|
82342
|
+
log(stdout, "info", `Clean-all-projects complete: cleaned ${cleanedCount} project(s), skipped ${skippedCount}.`);
|
|
82343
|
+
return { exitCode: 0 };
|
|
82344
|
+
}
|
|
81741
82345
|
var USAGE_TEXT = `Usage: sidekick dev-mode <command> [options]
|
|
81742
82346
|
|
|
81743
82347
|
Commands:
|
|
81744
|
-
enable
|
|
81745
|
-
disable
|
|
81746
|
-
status
|
|
81747
|
-
clean
|
|
81748
|
-
clean-all
|
|
82348
|
+
enable Add dev-sidekick to .claude/settings.local.json
|
|
82349
|
+
disable Remove dev-sidekick from settings.local.json
|
|
82350
|
+
status Show current dev-mode state
|
|
82351
|
+
clean Truncate logs, kill daemon, clean state folders
|
|
82352
|
+
clean-all Full cleanup: clean + remove logs/sessions/state dirs
|
|
82353
|
+
clean-all-projects Clean all registered projects in ~/.sidekick/projects/
|
|
81749
82354
|
|
|
81750
82355
|
Options:
|
|
81751
82356
|
--force Skip confirmation prompts for destructive operations
|
|
@@ -81762,6 +82367,8 @@ Options:
|
|
|
81762
82367
|
return doClean(projectDir, logger, stdout, options);
|
|
81763
82368
|
case "clean-all":
|
|
81764
82369
|
return doCleanAll(projectDir, logger, stdout, options);
|
|
82370
|
+
case "clean-all-projects":
|
|
82371
|
+
return doCleanAllProjects(logger, stdout, options);
|
|
81765
82372
|
case "help":
|
|
81766
82373
|
case "--help":
|
|
81767
82374
|
case "-h":
|
|
@@ -82533,6 +83140,7 @@ var require_helpers = __commonJS({
|
|
|
82533
83140
|
exports2.getPluginStatusLabel = getPluginStatusLabel;
|
|
82534
83141
|
exports2.getApiKeyStatusType = getApiKeyStatusType;
|
|
82535
83142
|
exports2.getPluginStatusIcon = getPluginStatusIcon;
|
|
83143
|
+
exports2.isPluginPresent = isPluginPresent;
|
|
82536
83144
|
exports2.getLivenessIcon = getLivenessIcon;
|
|
82537
83145
|
exports2.getLivenessLabel = getLivenessLabel;
|
|
82538
83146
|
exports2.formatApiKeyScopes = formatApiKeyScopes;
|
|
@@ -82615,7 +83223,7 @@ var require_helpers = __commonJS({
|
|
|
82615
83223
|
case "dev-mode":
|
|
82616
83224
|
return "dev-mode (local)";
|
|
82617
83225
|
case "both":
|
|
82618
|
-
return "
|
|
83226
|
+
return "plugin and dev-mode both active";
|
|
82619
83227
|
case "none":
|
|
82620
83228
|
return "not installed";
|
|
82621
83229
|
case "timeout":
|
|
@@ -82640,6 +83248,7 @@ var require_helpers = __commonJS({
|
|
|
82640
83248
|
case "dev-mode":
|
|
82641
83249
|
return "\u2713";
|
|
82642
83250
|
case "both":
|
|
83251
|
+
return "\u2022";
|
|
82643
83252
|
case "timeout":
|
|
82644
83253
|
case "error":
|
|
82645
83254
|
return "\u26A0";
|
|
@@ -82647,6 +83256,9 @@ var require_helpers = __commonJS({
|
|
|
82647
83256
|
return "\u2717";
|
|
82648
83257
|
}
|
|
82649
83258
|
}
|
|
83259
|
+
function isPluginPresent(status) {
|
|
83260
|
+
return status === "plugin" || status === "dev-mode" || status === "both";
|
|
83261
|
+
}
|
|
82650
83262
|
function getLivenessIcon(status) {
|
|
82651
83263
|
switch (status) {
|
|
82652
83264
|
case "active":
|
|
@@ -82750,8 +83362,74 @@ var require_doctor = __commonJS({
|
|
|
82750
83362
|
"liveness",
|
|
82751
83363
|
"zombies",
|
|
82752
83364
|
"auto-config",
|
|
82753
|
-
"shell-alias"
|
|
83365
|
+
"shell-alias",
|
|
83366
|
+
"llm-config"
|
|
82754
83367
|
];
|
|
83368
|
+
var DEPRECATED_LLM_MODELS = [
|
|
83369
|
+
{
|
|
83370
|
+
model: "google/gemini-2.0-flash-lite-001",
|
|
83371
|
+
message: "Your llm.yaml references google/gemini-2.0-flash-lite-001, which Google deprecates in June 2026. Sidekick's default has moved to google/gemini-2.5-flash-lite. Update your override or accept the new default."
|
|
83372
|
+
}
|
|
83373
|
+
];
|
|
83374
|
+
function collectLlmYamlModels(parsed) {
|
|
83375
|
+
if (!parsed)
|
|
83376
|
+
return [];
|
|
83377
|
+
const models = [];
|
|
83378
|
+
for (const key of ["profiles", "fallbackProfiles"]) {
|
|
83379
|
+
const section = parsed[key];
|
|
83380
|
+
if (!section || typeof section !== "object")
|
|
83381
|
+
continue;
|
|
83382
|
+
for (const profile of Object.values(section)) {
|
|
83383
|
+
if (profile && typeof profile === "object") {
|
|
83384
|
+
const model = profile.model;
|
|
83385
|
+
if (typeof model === "string") {
|
|
83386
|
+
models.push(model);
|
|
83387
|
+
}
|
|
83388
|
+
}
|
|
83389
|
+
}
|
|
83390
|
+
}
|
|
83391
|
+
return models;
|
|
83392
|
+
}
|
|
83393
|
+
function runLlmConfigCheck(projectDir, homeDir, stdout, logger) {
|
|
83394
|
+
const candidatePaths = [path.join(homeDir, ".sidekick", "llm.yaml"), path.join(projectDir, ".sidekick", "llm.yaml")];
|
|
83395
|
+
const matched = /* @__PURE__ */ new Set();
|
|
83396
|
+
const parseFailures = [];
|
|
83397
|
+
for (const yamlPath of candidatePaths) {
|
|
83398
|
+
let parsed;
|
|
83399
|
+
try {
|
|
83400
|
+
parsed = (0, core_1.tryReadYaml)(yamlPath);
|
|
83401
|
+
} catch (err) {
|
|
83402
|
+
logger.warn("Failed to parse llm.yaml during migration check", {
|
|
83403
|
+
path: yamlPath,
|
|
83404
|
+
error: (0, core_1.toErrorMessage)(err)
|
|
83405
|
+
});
|
|
83406
|
+
parseFailures.push(yamlPath);
|
|
83407
|
+
continue;
|
|
83408
|
+
}
|
|
83409
|
+
if (!parsed)
|
|
83410
|
+
continue;
|
|
83411
|
+
const models = collectLlmYamlModels(parsed);
|
|
83412
|
+
for (const { model, message } of DEPRECATED_LLM_MODELS) {
|
|
83413
|
+
if (models.includes(model) && !matched.has(model)) {
|
|
83414
|
+
matched.add(model);
|
|
83415
|
+
logger.warn("Deprecated LLM model referenced in user override", {
|
|
83416
|
+
path: yamlPath,
|
|
83417
|
+
model
|
|
83418
|
+
});
|
|
83419
|
+
stdout.write(`\u26A0 ${message}
|
|
83420
|
+
`);
|
|
83421
|
+
}
|
|
83422
|
+
}
|
|
83423
|
+
}
|
|
83424
|
+
if (parseFailures.length > 0) {
|
|
83425
|
+
stdout.write(`\u26A0 LLM Config: could not be parsed (${parseFailures.join(", ")}) \u2014 deprecation check skipped
|
|
83426
|
+
`);
|
|
83427
|
+
return;
|
|
83428
|
+
}
|
|
83429
|
+
if (matched.size === 0) {
|
|
83430
|
+
stdout.write("\u2713 LLM Config: no deprecated models referenced\n");
|
|
83431
|
+
}
|
|
83432
|
+
}
|
|
82755
83433
|
function parseDoctorOnly(only) {
|
|
82756
83434
|
if (!only)
|
|
82757
83435
|
return null;
|
|
@@ -82762,6 +83440,13 @@ var require_doctor = __commonJS({
|
|
|
82762
83440
|
}
|
|
82763
83441
|
return new Set(requested);
|
|
82764
83442
|
}
|
|
83443
|
+
async function tryRemoveLegacySection(projectDir) {
|
|
83444
|
+
try {
|
|
83445
|
+
return await (0, core_1.removeLegacyGitignoreSection)(projectDir);
|
|
83446
|
+
} catch {
|
|
83447
|
+
return false;
|
|
83448
|
+
}
|
|
83449
|
+
}
|
|
82765
83450
|
async function runDoctorFixes(projectDir, logger, stdout, context) {
|
|
82766
83451
|
const { homeDir, filter, doctorResult, gitignore, pluginStatus, liveness } = context;
|
|
82767
83452
|
const isFullMode = filter === null;
|
|
@@ -82803,15 +83488,40 @@ var require_doctor = __commonJS({
|
|
|
82803
83488
|
stdout.write(" \u26A0 Statusline managed by dev-mode (skipped)\n");
|
|
82804
83489
|
}
|
|
82805
83490
|
}
|
|
82806
|
-
if (shouldFix("gitignore") && gitignore !== null
|
|
82807
|
-
|
|
82808
|
-
|
|
82809
|
-
|
|
82810
|
-
|
|
83491
|
+
if (shouldFix("gitignore") && gitignore !== null) {
|
|
83492
|
+
if (gitignore === "legacy") {
|
|
83493
|
+
stdout.write("Fixing: Gitignore (migrating legacy format)\n");
|
|
83494
|
+
const result = await (0, core_1.installGitignoreSection)(projectDir);
|
|
83495
|
+
if (result.status === "error") {
|
|
83496
|
+
stdout.write(` \u26A0 Failed to create .sidekick/.gitignore: ${result.error}
|
|
82811
83497
|
`);
|
|
83498
|
+
} else {
|
|
83499
|
+
const legacyRemoved = await tryRemoveLegacySection(projectDir);
|
|
83500
|
+
stdout.write(legacyRemoved ? " \u2713 Migrated to .sidekick/.gitignore and removed legacy root section\n" : " \u26A0 Created .sidekick/.gitignore, but legacy root section could not be removed\n");
|
|
83501
|
+
fixedCount++;
|
|
83502
|
+
}
|
|
83503
|
+
} else if (gitignore === "installed") {
|
|
83504
|
+
const hasLegacy = await (0, core_1.detectLegacyGitignoreSection)(projectDir);
|
|
83505
|
+
if (hasLegacy) {
|
|
83506
|
+
stdout.write("Fixing: Gitignore (removing redundant legacy section)\n");
|
|
83507
|
+
const legacyRemoved = await tryRemoveLegacySection(projectDir);
|
|
83508
|
+
if (legacyRemoved) {
|
|
83509
|
+
stdout.write(" \u2713 Removed legacy section from root .gitignore\n");
|
|
83510
|
+
fixedCount++;
|
|
83511
|
+
} else {
|
|
83512
|
+
stdout.write(" \u26A0 Legacy section detected but could not be removed from root .gitignore\n");
|
|
83513
|
+
}
|
|
83514
|
+
}
|
|
82812
83515
|
} else {
|
|
82813
|
-
stdout.write("
|
|
82814
|
-
|
|
83516
|
+
stdout.write("Fixing: Gitignore\n");
|
|
83517
|
+
const result = await (0, core_1.installGitignoreSection)(projectDir);
|
|
83518
|
+
if (result.status === "error") {
|
|
83519
|
+
stdout.write(` \u26A0 Failed to update .sidekick/.gitignore: ${result.error}
|
|
83520
|
+
`);
|
|
83521
|
+
} else {
|
|
83522
|
+
stdout.write(" \u2713 Gitignore configured\n");
|
|
83523
|
+
fixedCount++;
|
|
83524
|
+
}
|
|
82815
83525
|
}
|
|
82816
83526
|
}
|
|
82817
83527
|
if (shouldFix("plugin") && pluginStatus === "none") {
|
|
@@ -82833,7 +83543,7 @@ var require_doctor = __commonJS({
|
|
|
82833
83543
|
fixedCount++;
|
|
82834
83544
|
}
|
|
82835
83545
|
} catch (err) {
|
|
82836
|
-
stdout.write(` \u26A0 Plugin installation failed: ${
|
|
83546
|
+
stdout.write(` \u26A0 Plugin installation failed: ${(0, core_1.toErrorMessage)(err)}
|
|
82837
83547
|
`);
|
|
82838
83548
|
}
|
|
82839
83549
|
}
|
|
@@ -82903,7 +83613,7 @@ var require_doctor = __commonJS({
|
|
|
82903
83613
|
try {
|
|
82904
83614
|
filter = parseDoctorOnly(options?.only);
|
|
82905
83615
|
} catch (err) {
|
|
82906
|
-
stdout.write(`${
|
|
83616
|
+
stdout.write(`${(0, core_1.toErrorMessage)(err)}
|
|
82907
83617
|
`);
|
|
82908
83618
|
return { exitCode: 1 };
|
|
82909
83619
|
}
|
|
@@ -82953,7 +83663,12 @@ var require_doctor = __commonJS({
|
|
|
82953
83663
|
promises.push((0, core_1.detectGitignoreStatus)(projectDir).then((result) => {
|
|
82954
83664
|
gitignore = result;
|
|
82955
83665
|
const gitignoreIcon = result === "installed" ? "\u2713" : "\u26A0";
|
|
82956
|
-
|
|
83666
|
+
const gitignoreMessage = result === "legacy" ? `legacy section found in root .gitignore \u2014 run sidekick doctor --fix --only=gitignore to migrate` : result;
|
|
83667
|
+
stdout.write(`${gitignoreIcon} Gitignore: ${gitignoreMessage}
|
|
83668
|
+
`);
|
|
83669
|
+
}).catch((err) => {
|
|
83670
|
+
gitignore = "unknown";
|
|
83671
|
+
stdout.write(`\u26A0 Gitignore: could not read status \u2014 ${err.message}
|
|
82957
83672
|
`);
|
|
82958
83673
|
}));
|
|
82959
83674
|
}
|
|
@@ -82968,8 +83683,7 @@ var require_doctor = __commonJS({
|
|
|
82968
83683
|
stdout.write(`${pluginIcon} Plugin: ${pluginLabel}
|
|
82969
83684
|
`);
|
|
82970
83685
|
}
|
|
82971
|
-
|
|
82972
|
-
if (shouldRun("liveness") && isPluginPresent) {
|
|
83686
|
+
if (shouldRun("liveness") && (0, helpers_js_1.isPluginPresent)(status)) {
|
|
82973
83687
|
logger.info("Starting plugin liveness check");
|
|
82974
83688
|
liveness = await setupService.detectPluginLiveness();
|
|
82975
83689
|
const livenessIcon = (0, helpers_js_1.getLivenessIcon)(liveness);
|
|
@@ -82991,6 +83705,9 @@ var require_doctor = __commonJS({
|
|
|
82991
83705
|
}));
|
|
82992
83706
|
}
|
|
82993
83707
|
await Promise.all(promises);
|
|
83708
|
+
if (shouldRun("llm-config")) {
|
|
83709
|
+
runLlmConfigCheck(projectDir, homeDir, stdout, logger);
|
|
83710
|
+
}
|
|
82994
83711
|
if (shouldRun("auto-config")) {
|
|
82995
83712
|
const userStatus = await setupService.getUserStatus();
|
|
82996
83713
|
if (userStatus?.preferences.autoConfigureProjects) {
|
|
@@ -83016,7 +83733,7 @@ var require_doctor = __commonJS({
|
|
|
83016
83733
|
}
|
|
83017
83734
|
}
|
|
83018
83735
|
if (filter === null) {
|
|
83019
|
-
const isPluginOk =
|
|
83736
|
+
const isPluginOk = (0, helpers_js_1.isPluginPresent)(pluginStatus);
|
|
83020
83737
|
const isPluginLive = liveness === null || liveness === "active";
|
|
83021
83738
|
const isHealthy = doctorResult.overallHealth === "healthy" && gitignore === "installed" && isPluginOk && isPluginLive && zombieCount === 0;
|
|
83022
83739
|
const overallIcon = isHealthy ? "\u2713" : "\u26A0";
|
|
@@ -83456,12 +84173,18 @@ Examples:
|
|
|
83456
84173
|
}
|
|
83457
84174
|
async function runStep3Gitignore(wctx, force) {
|
|
83458
84175
|
const { ctx, projectDir } = wctx;
|
|
83459
|
-
|
|
83460
|
-
|
|
84176
|
+
let currentStatus;
|
|
84177
|
+
try {
|
|
84178
|
+
currentStatus = await (0, core_1.detectGitignoreStatus)(projectDir);
|
|
84179
|
+
} catch {
|
|
84180
|
+
currentStatus = "missing";
|
|
84181
|
+
}
|
|
84182
|
+
if (currentStatus === "installed" || currentStatus === "legacy") {
|
|
83461
84183
|
if (!force) {
|
|
83462
|
-
|
|
84184
|
+
const message2 = currentStatus === "legacy" ? "Sidekick entries already present in root .gitignore (legacy \u2014 run doctor --fix to migrate)" : "Sidekick already configured (.sidekick/.gitignore)";
|
|
84185
|
+
(0, prompts_js_1.printStatus)(ctx, "success", message2);
|
|
83463
84186
|
}
|
|
83464
|
-
return
|
|
84187
|
+
return currentStatus;
|
|
83465
84188
|
}
|
|
83466
84189
|
const needsRepair = currentStatus === "incomplete";
|
|
83467
84190
|
if (force) {
|
|
@@ -83934,7 +84657,6 @@ var require_uninstall = __commonJS({
|
|
|
83934
84657
|
await removeFile(path.join(userHome, ".sidekick", core_1.USER_STATUS_FILENAME), "user", core_1.USER_STATUS_FILENAME, actions, {
|
|
83935
84658
|
dryRun
|
|
83936
84659
|
});
|
|
83937
|
-
await removeFile(path.join(userHome, ".sidekick", core_1.LEGACY_USER_STATUS_FILENAME), "user", core_1.LEGACY_USER_STATUS_FILENAME, actions, { dryRun });
|
|
83938
84660
|
await removeFile(path.join(userHome, ".sidekick", "features.yaml"), "user", "features.yaml", actions, { dryRun });
|
|
83939
84661
|
}
|
|
83940
84662
|
if (projectDetected) {
|
|
@@ -84031,11 +84753,6 @@ var require_uninstall = __commonJS({
|
|
|
84031
84753
|
try {
|
|
84032
84754
|
await fs.access(path.join(userHome, ".sidekick", core_1.USER_STATUS_FILENAME));
|
|
84033
84755
|
return true;
|
|
84034
|
-
} catch {
|
|
84035
|
-
}
|
|
84036
|
-
try {
|
|
84037
|
-
await fs.access(path.join(userHome, ".sidekick", core_1.LEGACY_USER_STATUS_FILENAME));
|
|
84038
|
-
return true;
|
|
84039
84756
|
} catch {
|
|
84040
84757
|
try {
|
|
84041
84758
|
const content = await fs.readFile(path.join(userHome, ".claude", "settings.json"), "utf-8");
|
|
@@ -84106,8 +84823,12 @@ var require_uninstall = __commonJS({
|
|
|
84106
84823
|
summary.project.push({ label: ".env", details: envDetail });
|
|
84107
84824
|
}
|
|
84108
84825
|
if (!devModeActive) {
|
|
84109
|
-
const
|
|
84110
|
-
|
|
84826
|
+
const sidekickGitignore = await (0, fs_js_1.readFileOrNull)(path.join(projectDir, ".sidekick", ".gitignore"));
|
|
84827
|
+
const rootGitignore = await (0, fs_js_1.readFileOrNull)(path.join(projectDir, ".gitignore"));
|
|
84828
|
+
if (sidekickGitignore !== null) {
|
|
84829
|
+
summary.project.push({ label: ".sidekick/.gitignore", details: "sidekick managed file" });
|
|
84830
|
+
}
|
|
84831
|
+
if (rootGitignore?.includes("# >>> sidekick")) {
|
|
84111
84832
|
summary.project.push({ label: ".gitignore", details: "sidekick section" });
|
|
84112
84833
|
}
|
|
84113
84834
|
}
|
|
@@ -84124,11 +84845,7 @@ var require_uninstall = __commonJS({
|
|
|
84124
84845
|
} catch {
|
|
84125
84846
|
}
|
|
84126
84847
|
}
|
|
84127
|
-
const userConfigFiles = await detectExistingItems(userHome, [
|
|
84128
|
-
core_1.USER_STATUS_FILENAME,
|
|
84129
|
-
core_1.LEGACY_USER_STATUS_FILENAME,
|
|
84130
|
-
"features.yaml"
|
|
84131
|
-
]);
|
|
84848
|
+
const userConfigFiles = await detectExistingItems(userHome, [core_1.USER_STATUS_FILENAME, "features.yaml"]);
|
|
84132
84849
|
if (userConfigFiles.length > 0) {
|
|
84133
84850
|
summary.user.push({ label: "Config", details: userConfigFiles.join(", ") });
|
|
84134
84851
|
}
|
|
@@ -84506,7 +85223,7 @@ var require_cli = __commonJS({
|
|
|
84506
85223
|
var promises_12 = require("node:fs/promises");
|
|
84507
85224
|
var node_stream_1 = require("node:stream");
|
|
84508
85225
|
var yargs_parser_1 = __importDefault2(require_build());
|
|
84509
|
-
var VERSION = true ? "0.1.
|
|
85226
|
+
var VERSION = true ? "0.1.20" : "dev";
|
|
84510
85227
|
var SANDBOX_ERROR_MESSAGE = `Error: Daemon commands cannot run in sandbox mode.
|
|
84511
85228
|
|
|
84512
85229
|
Claude Code's sandbox blocks Unix socket operations required for daemon IPC.
|
|
@@ -84639,6 +85356,8 @@ Example: { "command": "pnpm sidekick daemon status", "dangerouslyDisableSandbox"
|
|
|
84639
85356
|
const cwd = typeof raw.cwd === "string" ? raw.cwd : void 0;
|
|
84640
85357
|
const hookEventName = typeof raw.hook_event_name === "string" ? raw.hook_event_name : void 0;
|
|
84641
85358
|
const permissionMode = typeof raw.permission_mode === "string" ? raw.permission_mode : void 0;
|
|
85359
|
+
const agentId = typeof raw.agent_id === "string" ? raw.agent_id : void 0;
|
|
85360
|
+
const agentType = typeof raw.agent_type === "string" ? raw.agent_type : void 0;
|
|
84642
85361
|
if (!sessionId) {
|
|
84643
85362
|
return void 0;
|
|
84644
85363
|
}
|
|
@@ -84649,6 +85368,8 @@ Example: { "command": "pnpm sidekick daemon status", "dangerouslyDisableSandbox"
|
|
|
84649
85368
|
// Optional - some hooks (Stop, SessionStart) may not include cwd
|
|
84650
85369
|
hookEventName: hookEventName ?? "unknown",
|
|
84651
85370
|
permissionMode,
|
|
85371
|
+
agentId,
|
|
85372
|
+
agentType,
|
|
84652
85373
|
raw
|
|
84653
85374
|
};
|
|
84654
85375
|
} catch {
|
|
@@ -84946,7 +85667,7 @@ Run 'sidekick help' for available commands.
|
|
|
84946
85667
|
} catch (err) {
|
|
84947
85668
|
logger.warn("Failed to persist CLI log metrics", {
|
|
84948
85669
|
sessionId,
|
|
84949
|
-
error:
|
|
85670
|
+
error: (0, core_1.toErrorMessage)(err)
|
|
84950
85671
|
});
|
|
84951
85672
|
}
|
|
84952
85673
|
}
|