@scotthamilton77/sidekick 0.1.25 → 0.1.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/daemon.js
CHANGED
|
@@ -62,6 +62,7 @@ var require_hook_events = __commonJS({
|
|
|
62
62
|
exports2.isPostToolUseEvent = isPostToolUseEvent;
|
|
63
63
|
exports2.isStopEvent = isStopEvent;
|
|
64
64
|
exports2.isPreCompactEvent = isPreCompactEvent;
|
|
65
|
+
exports2.isPostCompactEvent = isPostCompactEvent;
|
|
65
66
|
exports2.isSubagentStartEvent = isSubagentStartEvent;
|
|
66
67
|
exports2.isSubagentStopEvent = isSubagentStopEvent;
|
|
67
68
|
exports2.HOOK_NAMES = [
|
|
@@ -72,6 +73,7 @@ var require_hook_events = __commonJS({
|
|
|
72
73
|
"PostToolUse",
|
|
73
74
|
"Stop",
|
|
74
75
|
"PreCompact",
|
|
76
|
+
"PostCompact",
|
|
75
77
|
"SubagentStart",
|
|
76
78
|
"SubagentStop"
|
|
77
79
|
];
|
|
@@ -96,6 +98,9 @@ var require_hook_events = __commonJS({
|
|
|
96
98
|
function isPreCompactEvent(event) {
|
|
97
99
|
return event.hook === "PreCompact";
|
|
98
100
|
}
|
|
101
|
+
function isPostCompactEvent(event) {
|
|
102
|
+
return event.hook === "PostCompact";
|
|
103
|
+
}
|
|
99
104
|
function isSubagentStartEvent(event) {
|
|
100
105
|
return event.hook === "SubagentStart";
|
|
101
106
|
}
|
|
@@ -16951,7 +16956,8 @@ var require_tasks = __commonJS({
|
|
|
16951
16956
|
});
|
|
16952
16957
|
exports2.CleanupPayloadSchema = zod_1.z.object({
|
|
16953
16958
|
maxAgeMs: zod_1.z.number().optional(),
|
|
16954
|
-
dryRun: zod_1.z.boolean().optional()
|
|
16959
|
+
dryRun: zod_1.z.boolean().optional(),
|
|
16960
|
+
logMaxAgeMs: zod_1.z.number().optional()
|
|
16955
16961
|
});
|
|
16956
16962
|
exports2.MetricsPersistPayloadSchema = zod_1.z.object({
|
|
16957
16963
|
sessionId: zod_1.z.string(),
|
|
@@ -16976,7 +16982,7 @@ var require_hook_input = __commonJS({
|
|
|
16976
16982
|
"../types/dist/hook-input.js"(exports2) {
|
|
16977
16983
|
"use strict";
|
|
16978
16984
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
16979
|
-
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;
|
|
16985
|
+
exports2.HookInputSchema = exports2.StatuslineInputSchema = exports2.StatuslineWorkspaceSchema = exports2.StatuslineCostSchema = exports2.StatuslineContextWindowSchema = exports2.StatuslineModelSchema = exports2.SubagentStopInputSchema = exports2.SubagentStartInputSchema = exports2.NotificationInputSchema = exports2.PostCompactInputSchema = exports2.PreCompactInputSchema = exports2.SessionEndInputSchema = exports2.SessionStartInputSchema = exports2.StopInputSchema = exports2.PostToolUseInputSchema = exports2.PreToolUseInputSchema = exports2.UserPromptSubmitInputSchema = exports2.HookInputBaseSchema = void 0;
|
|
16980
16986
|
var zod_1 = require_zod();
|
|
16981
16987
|
exports2.HookInputBaseSchema = zod_1.z.object({
|
|
16982
16988
|
/** Unique identifier for the current Claude session */
|
|
@@ -17034,6 +17040,10 @@ var require_hook_input = __commonJS({
|
|
|
17034
17040
|
/** Custom instructions from /compact command (empty for auto) */
|
|
17035
17041
|
custom_instructions: zod_1.z.string().optional()
|
|
17036
17042
|
});
|
|
17043
|
+
exports2.PostCompactInputSchema = exports2.HookInputBaseSchema.extend({
|
|
17044
|
+
/** 'manual' (user ran /compact) or 'auto' (context window threshold) */
|
|
17045
|
+
compaction_trigger: zod_1.z.enum(["manual", "auto"]).optional()
|
|
17046
|
+
});
|
|
17037
17047
|
exports2.NotificationInputSchema = exports2.HookInputBaseSchema.extend({
|
|
17038
17048
|
/** Notification message text */
|
|
17039
17049
|
message: zod_1.z.string(),
|
|
@@ -17122,6 +17132,7 @@ var require_hook_input = __commonJS({
|
|
|
17122
17132
|
exports2.PostToolUseInputSchema,
|
|
17123
17133
|
exports2.StopInputSchema,
|
|
17124
17134
|
exports2.PreCompactInputSchema,
|
|
17135
|
+
exports2.PostCompactInputSchema,
|
|
17125
17136
|
exports2.SubagentStartInputSchema,
|
|
17126
17137
|
exports2.SubagentStopInputSchema,
|
|
17127
17138
|
exports2.NotificationInputSchema,
|
|
@@ -26397,6 +26408,32 @@ var require_claude_paths = __commonJS({
|
|
|
26397
26408
|
}
|
|
26398
26409
|
});
|
|
26399
26410
|
|
|
26411
|
+
// ../sidekick-core/dist/sidekick-paths.js
|
|
26412
|
+
var require_sidekick_paths = __commonJS({
|
|
26413
|
+
"../sidekick-core/dist/sidekick-paths.js"(exports2) {
|
|
26414
|
+
"use strict";
|
|
26415
|
+
var __importDefault = exports2 && exports2.__importDefault || function(mod) {
|
|
26416
|
+
return mod && mod.__esModule ? mod : { "default": mod };
|
|
26417
|
+
};
|
|
26418
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
26419
|
+
exports2.resolveHome = resolveHome;
|
|
26420
|
+
exports2.userSidekickRoot = userSidekickRoot;
|
|
26421
|
+
exports2.projectStateDir = projectStateDir;
|
|
26422
|
+
var node_os_1 = __importDefault(require("node:os"));
|
|
26423
|
+
var node_path_1 = require("node:path");
|
|
26424
|
+
var claude_paths_js_1 = require_claude_paths();
|
|
26425
|
+
function resolveHome(home) {
|
|
26426
|
+
return home && home.trim() ? home : node_os_1.default.homedir();
|
|
26427
|
+
}
|
|
26428
|
+
function userSidekickRoot(home) {
|
|
26429
|
+
return (0, node_path_1.join)(resolveHome(home), ".sidekick");
|
|
26430
|
+
}
|
|
26431
|
+
function projectStateDir(projectRoot, home) {
|
|
26432
|
+
return (0, node_path_1.join)(userSidekickRoot(home), "projects", (0, claude_paths_js_1.encodeProjectPath)(projectRoot));
|
|
26433
|
+
}
|
|
26434
|
+
}
|
|
26435
|
+
});
|
|
26436
|
+
|
|
26400
26437
|
// ../sidekick-core/dist/persona-loader.js
|
|
26401
26438
|
var require_persona_loader = __commonJS({
|
|
26402
26439
|
"../sidekick-core/dist/persona-loader.js"(exports2) {
|
|
@@ -27065,10 +27102,19 @@ var require_config2 = __commonJS({
|
|
|
27065
27102
|
var ProjectsSchema = v4_1.z.object({
|
|
27066
27103
|
retentionDays: v4_1.z.number().min(1)
|
|
27067
27104
|
}).strict();
|
|
27105
|
+
var CleanupSchema = v4_1.z.object({
|
|
27106
|
+
sessionMaxAgeDays: v4_1.z.number().min(1).default(7),
|
|
27107
|
+
logMaxAgeDays: v4_1.z.number().min(1).default(30),
|
|
27108
|
+
intervalHours: v4_1.z.number().min(1).default(4)
|
|
27109
|
+
}).strict();
|
|
27068
27110
|
var DaemonSchema = v4_1.z.object({
|
|
27069
27111
|
idleTimeoutMs: v4_1.z.number().min(0),
|
|
27070
27112
|
shutdownTimeoutMs: v4_1.z.number().min(0),
|
|
27071
|
-
projects: ProjectsSchema.default({ retentionDays: 30 })
|
|
27113
|
+
projects: ProjectsSchema.default({ retentionDays: 30 }),
|
|
27114
|
+
// Per-field defaults (see CleanupSchema) make any subset of keys valid —
|
|
27115
|
+
// partial overrides are filled at parse time. The object-level default
|
|
27116
|
+
// covers the case where `cleanup` is omitted entirely.
|
|
27117
|
+
cleanup: CleanupSchema.default({ sessionMaxAgeDays: 7, logMaxAgeDays: 30, intervalHours: 4 })
|
|
27072
27118
|
}).strict();
|
|
27073
27119
|
var IpcSchema = v4_1.z.object({
|
|
27074
27120
|
connectTimeoutMs: v4_1.z.number().min(0),
|
|
@@ -28145,6 +28191,7 @@ var require_transport = __commonJS({
|
|
|
28145
28191
|
var crypto_1 = __importDefault(require("crypto"));
|
|
28146
28192
|
var os_1 = __importDefault(require("os"));
|
|
28147
28193
|
var path_1 = __importDefault(require("path"));
|
|
28194
|
+
var sidekick_paths_js_1 = require_sidekick_paths();
|
|
28148
28195
|
function getProjectHash(projectDir2) {
|
|
28149
28196
|
return crypto_1.default.createHash("sha256").update(projectDir2).digest("hex").substring(0, 16);
|
|
28150
28197
|
}
|
|
@@ -28170,14 +28217,14 @@ var require_transport = __commonJS({
|
|
|
28170
28217
|
throw new Error(`Socket path exceeds Unix limit of ${exports2.UNIX_PATH_MAX} characters (got ${socketPath.length}): ${socketPath}`);
|
|
28171
28218
|
}
|
|
28172
28219
|
}
|
|
28173
|
-
function getTokenPath(projectDir2) {
|
|
28174
|
-
return path_1.default.join(
|
|
28220
|
+
function getTokenPath(projectDir2, home) {
|
|
28221
|
+
return path_1.default.join((0, sidekick_paths_js_1.projectStateDir)(projectDir2, home), "sidekickd.token");
|
|
28175
28222
|
}
|
|
28176
|
-
function getPidPath(projectDir2) {
|
|
28177
|
-
return path_1.default.join(
|
|
28223
|
+
function getPidPath(projectDir2, home) {
|
|
28224
|
+
return path_1.default.join((0, sidekick_paths_js_1.projectStateDir)(projectDir2, home), "sidekickd.pid");
|
|
28178
28225
|
}
|
|
28179
|
-
function getLockPath(projectDir2) {
|
|
28180
|
-
return path_1.default.join(
|
|
28226
|
+
function getLockPath(projectDir2, home) {
|
|
28227
|
+
return path_1.default.join((0, sidekick_paths_js_1.projectStateDir)(projectDir2, home), "sidekickd.lock");
|
|
28181
28228
|
}
|
|
28182
28229
|
function getUserDaemonsDir() {
|
|
28183
28230
|
return path_1.default.join(os_1.default.homedir(), ".sidekick", "daemons");
|
|
@@ -33000,6 +33047,46 @@ var require_log_events = __commonJS({
|
|
|
33000
33047
|
}
|
|
33001
33048
|
};
|
|
33002
33049
|
},
|
|
33050
|
+
/** Create a CleanupTimerStarted event (logged when the cleanup timer starts). */
|
|
33051
|
+
cleanupTimerStarted(metadata) {
|
|
33052
|
+
return {
|
|
33053
|
+
type: "cleanup:timer-started",
|
|
33054
|
+
time: Date.now(),
|
|
33055
|
+
source: "daemon",
|
|
33056
|
+
context: EMPTY_CONTEXT,
|
|
33057
|
+
payload: { intervalMs: metadata.intervalMs }
|
|
33058
|
+
};
|
|
33059
|
+
},
|
|
33060
|
+
/** Create a CleanupTaskEnqueued event (logged when a cleanup task is enqueued). */
|
|
33061
|
+
cleanupTaskEnqueued(metadata) {
|
|
33062
|
+
return {
|
|
33063
|
+
type: "cleanup:task-enqueued",
|
|
33064
|
+
time: Date.now(),
|
|
33065
|
+
source: "daemon",
|
|
33066
|
+
context: EMPTY_CONTEXT,
|
|
33067
|
+
payload: { reason: metadata.reason }
|
|
33068
|
+
};
|
|
33069
|
+
},
|
|
33070
|
+
/** Create a CleanupSkippedRecent event (logged when startup cleanup is skipped). */
|
|
33071
|
+
cleanupSkippedRecent(metadata) {
|
|
33072
|
+
return {
|
|
33073
|
+
type: "cleanup:skipped-recent",
|
|
33074
|
+
time: Date.now(),
|
|
33075
|
+
source: "daemon",
|
|
33076
|
+
context: EMPTY_CONTEXT,
|
|
33077
|
+
payload: { lastCleanupAt: metadata.lastCleanupAt, intervalMs: metadata.intervalMs }
|
|
33078
|
+
};
|
|
33079
|
+
},
|
|
33080
|
+
/** Create a CleanupLogCompleted event (logged when log pruning finishes). */
|
|
33081
|
+
cleanupLogCompleted(metadata) {
|
|
33082
|
+
return {
|
|
33083
|
+
type: "cleanup:log-completed",
|
|
33084
|
+
time: Date.now(),
|
|
33085
|
+
source: "daemon",
|
|
33086
|
+
context: EMPTY_CONTEXT,
|
|
33087
|
+
payload: { cleaned: metadata.cleaned, skipped: metadata.skipped, dryRun: metadata.dryRun }
|
|
33088
|
+
};
|
|
33089
|
+
},
|
|
33003
33090
|
// --- Statusline Events ---
|
|
33004
33091
|
/**
|
|
33005
33092
|
* Create a StatuslineRendered event (logged when statusline renders successfully).
|
|
@@ -45604,57 +45691,76 @@ var require_sandbox = __commonJS({
|
|
|
45604
45691
|
}
|
|
45605
45692
|
});
|
|
45606
45693
|
|
|
45607
|
-
//
|
|
45608
|
-
var
|
|
45609
|
-
"
|
|
45610
|
-
|
|
45611
|
-
|
|
45612
|
-
|
|
45613
|
-
|
|
45614
|
-
|
|
45615
|
-
|
|
45616
|
-
|
|
45617
|
-
|
|
45618
|
-
|
|
45619
|
-
|
|
45620
|
-
|
|
45621
|
-
|
|
45622
|
-
|
|
45623
|
-
|
|
45624
|
-
|
|
45625
|
-
|
|
45626
|
-
|
|
45627
|
-
|
|
45628
|
-
|
|
45629
|
-
|
|
45630
|
-
|
|
45631
|
-
|
|
45632
|
-
|
|
45633
|
-
|
|
45634
|
-
|
|
45635
|
-
|
|
45636
|
-
|
|
45637
|
-
|
|
45638
|
-
|
|
45639
|
-
|
|
45640
|
-
|
|
45694
|
+
// ../sidekick-core/dist/build-identity.js
|
|
45695
|
+
var require_build_identity = __commonJS({
|
|
45696
|
+
"../sidekick-core/dist/build-identity.js"(exports2) {
|
|
45697
|
+
"use strict";
|
|
45698
|
+
var __importDefault = exports2 && exports2.__importDefault || function(mod) {
|
|
45699
|
+
return mod && mod.__esModule ? mod : { "default": mod };
|
|
45700
|
+
};
|
|
45701
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
45702
|
+
exports2.computeBuildIdentity = computeBuildIdentity;
|
|
45703
|
+
exports2.computeDevFingerprint = computeDevFingerprint;
|
|
45704
|
+
exports2.discoverDistDirs = discoverDistDirs;
|
|
45705
|
+
exports2.fingerprintDistDirs = fingerprintDistDirs;
|
|
45706
|
+
var fs_1 = require("fs");
|
|
45707
|
+
var path_1 = __importDefault(require("path"));
|
|
45708
|
+
var DEV_PREFIX = "dev:";
|
|
45709
|
+
var NO_DIST_SENTINEL = "nodist";
|
|
45710
|
+
function computeBuildIdentity(injectedVersion = true ? "0.1.26" : void 0, devFingerprint = computeDevFingerprint) {
|
|
45711
|
+
return injectedVersion !== void 0 ? injectedVersion : DEV_PREFIX + devFingerprint();
|
|
45712
|
+
}
|
|
45713
|
+
function computeDevFingerprint() {
|
|
45714
|
+
const repoRoot = path_1.default.resolve(__dirname, "../../..");
|
|
45715
|
+
return fingerprintDistDirs(discoverDistDirs(repoRoot));
|
|
45716
|
+
}
|
|
45717
|
+
function discoverDistDirs(repoRoot) {
|
|
45718
|
+
const packagesDir = path_1.default.join(repoRoot, "packages");
|
|
45719
|
+
let entries;
|
|
45720
|
+
try {
|
|
45721
|
+
entries = (0, fs_1.readdirSync)(packagesDir);
|
|
45722
|
+
} catch {
|
|
45723
|
+
return [];
|
|
45724
|
+
}
|
|
45725
|
+
const dirs = [];
|
|
45726
|
+
for (const entry of entries) {
|
|
45727
|
+
const distDir = path_1.default.join(packagesDir, entry, "dist");
|
|
45728
|
+
try {
|
|
45729
|
+
if ((0, fs_1.statSync)(distDir).isDirectory())
|
|
45730
|
+
dirs.push(distDir);
|
|
45731
|
+
} catch {
|
|
45641
45732
|
}
|
|
45642
|
-
},
|
|
45643
|
-
devDependencies: {
|
|
45644
|
-
"@eslint/js": "^10.0.1",
|
|
45645
|
-
"@types/node": "^22.19.17",
|
|
45646
|
-
"@typescript-eslint/eslint-plugin": "^8.59.1",
|
|
45647
|
-
"@typescript-eslint/parser": "^8.59.1",
|
|
45648
|
-
"@vitest/coverage-v8": "^4.1.5",
|
|
45649
|
-
eslint: "^10.3.0",
|
|
45650
|
-
"eslint-config-prettier": "^9.1.2",
|
|
45651
|
-
"eslint-plugin-prettier": "^5.5.5",
|
|
45652
|
-
prettier: "^3.8.3",
|
|
45653
|
-
typescript: "^5.9.3",
|
|
45654
|
-
"typescript-eslint": "^8.59.1",
|
|
45655
|
-
vitest: "^4.1.5"
|
|
45656
45733
|
}
|
|
45657
|
-
|
|
45734
|
+
return dirs;
|
|
45735
|
+
}
|
|
45736
|
+
function fingerprintDistDirs(distDirs) {
|
|
45737
|
+
let maxMtimeMs = 0;
|
|
45738
|
+
for (const dir of distDirs) {
|
|
45739
|
+
maxMtimeMs = Math.max(maxMtimeMs, maxMtimeInDir(dir));
|
|
45740
|
+
}
|
|
45741
|
+
return maxMtimeMs === 0 ? NO_DIST_SENTINEL : Math.floor(maxMtimeMs).toString(36);
|
|
45742
|
+
}
|
|
45743
|
+
function maxMtimeInDir(dir) {
|
|
45744
|
+
let max = 0;
|
|
45745
|
+
let entries;
|
|
45746
|
+
try {
|
|
45747
|
+
entries = (0, fs_1.readdirSync)(dir, { withFileTypes: true });
|
|
45748
|
+
} catch {
|
|
45749
|
+
return 0;
|
|
45750
|
+
}
|
|
45751
|
+
for (const entry of entries) {
|
|
45752
|
+
const full = path_1.default.join(dir, entry.name);
|
|
45753
|
+
try {
|
|
45754
|
+
if (entry.isDirectory()) {
|
|
45755
|
+
max = Math.max(max, maxMtimeInDir(full));
|
|
45756
|
+
} else if (entry.isFile()) {
|
|
45757
|
+
max = Math.max(max, (0, fs_1.statSync)(full).mtimeMs);
|
|
45758
|
+
}
|
|
45759
|
+
} catch {
|
|
45760
|
+
}
|
|
45761
|
+
}
|
|
45762
|
+
return max;
|
|
45763
|
+
}
|
|
45658
45764
|
}
|
|
45659
45765
|
});
|
|
45660
45766
|
|
|
@@ -45678,10 +45784,11 @@ var require_daemon_client2 = __commonJS({
|
|
|
45678
45784
|
var transport_js_1 = require_transport();
|
|
45679
45785
|
var sandbox_js_1 = require_sandbox();
|
|
45680
45786
|
var error_utils_js_1 = require_error_utils();
|
|
45787
|
+
var build_identity_js_1 = require_build_identity();
|
|
45681
45788
|
var LOCK_TIMEOUT_MS = 1e4;
|
|
45682
45789
|
var LOCK_RETRY_INTERVAL_MS = 100;
|
|
45683
45790
|
var LOCK_STALE_THRESHOLD_MS = 3e4;
|
|
45684
|
-
var CLIENT_VERSION =
|
|
45791
|
+
var CLIENT_VERSION = (0, build_identity_js_1.computeBuildIdentity)();
|
|
45685
45792
|
var DaemonClient = class {
|
|
45686
45793
|
projectDir;
|
|
45687
45794
|
logger;
|
|
@@ -46213,16 +46320,14 @@ var require_gitignore = __commonJS({
|
|
|
46213
46320
|
exports2.SIDEKICK_SECTION_START = "# >>> sidekick";
|
|
46214
46321
|
exports2.SIDEKICK_SECTION_END = "# <<< sidekick";
|
|
46215
46322
|
exports2.SIDEKICK_GITIGNORE_HEADER = "# Sidekick \u2014 managed file, do not edit manually";
|
|
46216
|
-
exports2.GITIGNORE_ENTRIES = [
|
|
46323
|
+
exports2.GITIGNORE_ENTRIES = [".env", ".env.local", "*.local.yaml"];
|
|
46324
|
+
var STALE_GITIGNORE_ENTRIES = [
|
|
46217
46325
|
"logs/",
|
|
46218
46326
|
"sessions/",
|
|
46219
46327
|
"state/",
|
|
46220
46328
|
"setup-status.json",
|
|
46221
|
-
".env",
|
|
46222
|
-
".env.local",
|
|
46223
46329
|
"sidekick*.pid",
|
|
46224
|
-
"sidekick*.token"
|
|
46225
|
-
"*.local.yaml"
|
|
46330
|
+
"sidekick*.token"
|
|
46226
46331
|
];
|
|
46227
46332
|
async function installGitignoreSection(projectDir2) {
|
|
46228
46333
|
let status;
|
|
@@ -46253,7 +46358,8 @@ var require_gitignore = __commonJS({
|
|
|
46253
46358
|
try {
|
|
46254
46359
|
const content = await fs.readFile(sidekickGitignorePath, "utf-8");
|
|
46255
46360
|
const missingEntries = exports2.GITIGNORE_ENTRIES.filter((entry) => !content.includes(entry));
|
|
46256
|
-
|
|
46361
|
+
const staleEntries = STALE_GITIGNORE_ENTRIES.filter((entry) => content.includes(entry));
|
|
46362
|
+
return missingEntries.length === 0 && staleEntries.length === 0 ? "installed" : "incomplete";
|
|
46257
46363
|
} catch (err) {
|
|
46258
46364
|
if (err.code !== "ENOENT") {
|
|
46259
46365
|
throw err;
|
|
@@ -57309,9 +57415,9 @@ var require_setup_status_service = __commonJS({
|
|
|
57309
57415
|
exports2.createSetupStatusService = createSetupStatusService;
|
|
57310
57416
|
var fs = __importStar(require("node:fs/promises"));
|
|
57311
57417
|
var path = __importStar(require("node:path"));
|
|
57312
|
-
var os = __importStar(require("node:os"));
|
|
57313
57418
|
var types_1 = require_dist();
|
|
57314
57419
|
var gitignore_js_1 = require_gitignore();
|
|
57420
|
+
var sidekick_paths_js_1 = require_sidekick_paths();
|
|
57315
57421
|
var api_key_detector_js_1 = require_api_key_detector();
|
|
57316
57422
|
var plugin_detector_js_1 = require_plugin_detector();
|
|
57317
57423
|
var doctor_engine_js_1 = require_doctor_engine();
|
|
@@ -57323,7 +57429,7 @@ var require_setup_status_service = __commonJS({
|
|
|
57323
57429
|
logger;
|
|
57324
57430
|
constructor(projectDir2, options) {
|
|
57325
57431
|
this.projectDir = projectDir2;
|
|
57326
|
-
this.homeDir = options?.homeDir
|
|
57432
|
+
this.homeDir = (0, sidekick_paths_js_1.resolveHome)(options?.homeDir);
|
|
57327
57433
|
this.logger = options?.logger;
|
|
57328
57434
|
}
|
|
57329
57435
|
// === Paths ===
|
|
@@ -57331,7 +57437,7 @@ var require_setup_status_service = __commonJS({
|
|
|
57331
57437
|
return path.join(this.homeDir, ".sidekick", exports2.USER_STATUS_FILENAME);
|
|
57332
57438
|
}
|
|
57333
57439
|
get projectStatusPath() {
|
|
57334
|
-
return path.join(this.projectDir,
|
|
57440
|
+
return path.join((0, sidekick_paths_js_1.projectStateDir)(this.projectDir, this.homeDir), exports2.PROJECT_STATUS_FILENAME);
|
|
57335
57441
|
}
|
|
57336
57442
|
// === Feature config ===
|
|
57337
57443
|
/**
|
|
@@ -58593,10 +58699,24 @@ var require_path_resolver = __commonJS({
|
|
|
58593
58699
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
58594
58700
|
exports2.PathResolver = void 0;
|
|
58595
58701
|
var node_path_1 = require("node:path");
|
|
58702
|
+
var sidekick_paths_js_1 = require_sidekick_paths();
|
|
58596
58703
|
var PathResolver = class {
|
|
58597
58704
|
stateBase;
|
|
58598
|
-
|
|
58599
|
-
|
|
58705
|
+
/**
|
|
58706
|
+
* @param projectRoot Project root (project scope) or an absolute state root (user scope).
|
|
58707
|
+
* @param stateDir Scope selector, NOT a path segment. Only two values are
|
|
58708
|
+
* meaningful: `''` selects user scope (use `projectRoot` as the absolute base,
|
|
58709
|
+
* as-is); any other value (default `'.sidekick'`) selects project scope, where
|
|
58710
|
+
* runtime state is redirected to `~/.sidekick/projects/<encoded-id>/` and the
|
|
58711
|
+
* string content is ignored.
|
|
58712
|
+
* @param home Optional override for the user home that anchors the redirected
|
|
58713
|
+
* project state dir. Only consulted in project scope; in user scope the base
|
|
58714
|
+
* is already absolute. Defaults to `os.homedir()` when omitted. Thread this
|
|
58715
|
+
* from an injected home (production: `$HOME` via env; tests: a programmatic
|
|
58716
|
+
* override) so state, logs, and sessions all resolve under the same root.
|
|
58717
|
+
*/
|
|
58718
|
+
constructor(projectRoot, stateDir = ".sidekick", home) {
|
|
58719
|
+
this.stateBase = stateDir === "" ? projectRoot : (0, sidekick_paths_js_1.projectStateDir)(projectRoot, home);
|
|
58600
58720
|
}
|
|
58601
58721
|
// === Directories ===
|
|
58602
58722
|
/** Root state directory (.sidekick or user equivalent) */
|
|
@@ -58712,7 +58832,7 @@ var require_state_service = __commonJS({
|
|
|
58712
58832
|
cache;
|
|
58713
58833
|
configGetter;
|
|
58714
58834
|
constructor(projectRoot, options) {
|
|
58715
|
-
this.paths = new path_resolver_js_1.PathResolver(projectRoot, options?.stateDir);
|
|
58835
|
+
this.paths = new path_resolver_js_1.PathResolver(projectRoot, options?.stateDir, options?.homeDir);
|
|
58716
58836
|
this.staleThresholdMs = options?.staleThresholdMs ?? 6e4;
|
|
58717
58837
|
this.logger = options?.logger;
|
|
58718
58838
|
this.cache = options?.cache ? /* @__PURE__ */ new Map() : null;
|
|
@@ -59736,7 +59856,6 @@ var require_transcript_metrics_engine = __commonJS({
|
|
|
59736
59856
|
exports2.extractTokenUsage = extractTokenUsage;
|
|
59737
59857
|
exports2.processNestedToolUses = processNestedToolUses;
|
|
59738
59858
|
exports2.processNestedToolResults = processNestedToolResults;
|
|
59739
|
-
exports2.handleCompactBoundary = handleCompactBoundary;
|
|
59740
59859
|
exports2.isToolResultOnlyMessage = isToolResultOnlyMessage;
|
|
59741
59860
|
exports2.isLocalCommandStdoutMessage = isLocalCommandStdoutMessage;
|
|
59742
59861
|
exports2.isExcludedBuiltinCommandInvocation = isExcludedBuiltinCommandInvocation;
|
|
@@ -59771,13 +59890,8 @@ var require_transcript_metrics_engine = __commonJS({
|
|
|
59771
59890
|
await emitEvent("AssistantMessage", entry, lineNumber);
|
|
59772
59891
|
await processNestedToolUses(entry, lineNumber, metrics, toolUseIdToName, emitEvent);
|
|
59773
59892
|
break;
|
|
59774
|
-
case "system":
|
|
59775
|
-
const subtype = entry.subtype;
|
|
59776
|
-
if (subtype === "compact_boundary") {
|
|
59777
|
-
await handleCompactBoundary(entry, lineNumber, metrics, emitEvent);
|
|
59778
|
-
}
|
|
59893
|
+
case "system":
|
|
59779
59894
|
break;
|
|
59780
|
-
}
|
|
59781
59895
|
}
|
|
59782
59896
|
}
|
|
59783
59897
|
function extractTokenUsage(entry, metrics) {
|
|
@@ -59855,11 +59969,6 @@ var require_transcript_metrics_engine = __commonJS({
|
|
|
59855
59969
|
}
|
|
59856
59970
|
}
|
|
59857
59971
|
}
|
|
59858
|
-
async function handleCompactBoundary(entry, lineNumber, metrics, emitEvent) {
|
|
59859
|
-
metrics.currentContextTokens = null;
|
|
59860
|
-
metrics.isPostCompactIndeterminate = true;
|
|
59861
|
-
await emitEvent("Compact", entry, lineNumber);
|
|
59862
|
-
}
|
|
59863
59972
|
function isToolResultOnlyMessage(entry) {
|
|
59864
59973
|
const message = entry.message;
|
|
59865
59974
|
if (!message?.content)
|
|
@@ -62240,6 +62349,13 @@ var require_transcript_service = __commonJS({
|
|
|
62240
62349
|
// ============================================================================
|
|
62241
62350
|
// Compaction Management
|
|
62242
62351
|
// ============================================================================
|
|
62352
|
+
async signalCompaction() {
|
|
62353
|
+
this.metrics.currentContextTokens = null;
|
|
62354
|
+
this.metrics.isPostCompactIndeterminate = true;
|
|
62355
|
+
await this.emitEvent("Compact", {}, this.metrics.lastProcessedLine);
|
|
62356
|
+
this.notifyMetricsChange();
|
|
62357
|
+
this.schedulePersistence();
|
|
62358
|
+
}
|
|
62243
62359
|
async capturePreCompactState(snapshotPath) {
|
|
62244
62360
|
if (!this.transcriptPath) {
|
|
62245
62361
|
throw new Error("TranscriptService not initialized");
|
|
@@ -62448,6 +62564,18 @@ var require_service_factory2 = __commonJS({
|
|
|
62448
62564
|
}
|
|
62449
62565
|
return service;
|
|
62450
62566
|
}
|
|
62567
|
+
/**
|
|
62568
|
+
* Get the cached TranscriptService for a session if it exists.
|
|
62569
|
+
* Returns undefined if no service has been prepared for this session yet.
|
|
62570
|
+
* Touches the session access time if the service exists.
|
|
62571
|
+
*/
|
|
62572
|
+
getTranscriptService(sessionId) {
|
|
62573
|
+
const service = this.transcriptServices.get(sessionId);
|
|
62574
|
+
if (service) {
|
|
62575
|
+
this.touchSession(sessionId);
|
|
62576
|
+
}
|
|
62577
|
+
return service;
|
|
62578
|
+
}
|
|
62451
62579
|
/**
|
|
62452
62580
|
* Shutdown a session's services (called on SessionEnd).
|
|
62453
62581
|
*/
|
|
@@ -63030,28 +63158,69 @@ var require_project_registry = __commonJS({
|
|
|
63030
63158
|
return mod && mod.__esModule ? mod : { "default": mod };
|
|
63031
63159
|
};
|
|
63032
63160
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
63033
|
-
exports2.ProjectRegistryService = void 0;
|
|
63034
|
-
exports2.encodeProjectDir = encodeProjectDir;
|
|
63161
|
+
exports2.ProjectRegistryService = exports2.encodeProjectDir = void 0;
|
|
63035
63162
|
var node_fs_1 = require("node:fs");
|
|
63036
63163
|
var promises_1 = __importDefault(require("node:fs/promises"));
|
|
63037
63164
|
var node_crypto_1 = require("node:crypto");
|
|
63038
63165
|
var node_path_1 = require("node:path");
|
|
63039
63166
|
var types_1 = require_dist();
|
|
63040
|
-
|
|
63041
|
-
|
|
63042
|
-
|
|
63167
|
+
var claude_paths_js_1 = require_claude_paths();
|
|
63168
|
+
var error_utils_js_1 = require_error_utils();
|
|
63169
|
+
exports2.encodeProjectDir = claude_paths_js_1.encodeProjectPath;
|
|
63043
63170
|
var REGISTRY_FILE = "registry.json";
|
|
63044
63171
|
var ProjectRegistryService = class {
|
|
63045
63172
|
registryRoot;
|
|
63046
|
-
|
|
63173
|
+
logger;
|
|
63174
|
+
constructor(registryRoot, logger) {
|
|
63047
63175
|
this.registryRoot = registryRoot;
|
|
63176
|
+
this.logger = logger;
|
|
63177
|
+
}
|
|
63178
|
+
/**
|
|
63179
|
+
* Read and validate a single registry entry, returning null when it cannot
|
|
63180
|
+
* be used.
|
|
63181
|
+
*
|
|
63182
|
+
* Two unreadable cases are deliberately distinguished:
|
|
63183
|
+
* - **Missing** `registry.json` (ENOENT) is expected: a CLI hook can create
|
|
63184
|
+
* the project dir with live runtime state (sessions/, state/, logs/) before
|
|
63185
|
+
* the daemon writes registry.json. Logged at debug only — routine, not a
|
|
63186
|
+
* fault.
|
|
63187
|
+
* - **Corrupt** (unreadable/unparseable/schema-invalid) is unexpected and
|
|
63188
|
+
* warned: a persistently-bad registry.json silently excludes the dir from
|
|
63189
|
+
* both listing and pruning, so it must leave a trace.
|
|
63190
|
+
*
|
|
63191
|
+
* Callers treat null as "skip this dir" — never as "safe to delete".
|
|
63192
|
+
*/
|
|
63193
|
+
async readEntry(entryFile) {
|
|
63194
|
+
let raw;
|
|
63195
|
+
try {
|
|
63196
|
+
raw = await promises_1.default.readFile(entryFile, "utf-8");
|
|
63197
|
+
} catch (err) {
|
|
63198
|
+
if (err.code === "ENOENT") {
|
|
63199
|
+
this.logger?.debug("Project registry dir has no registry.json; skipping", { entryFile });
|
|
63200
|
+
} else {
|
|
63201
|
+
this.logger?.warn("Failed to read project registry entry; skipping", {
|
|
63202
|
+
entryFile,
|
|
63203
|
+
error: (0, error_utils_js_1.toErrorMessage)(err)
|
|
63204
|
+
});
|
|
63205
|
+
}
|
|
63206
|
+
return null;
|
|
63207
|
+
}
|
|
63208
|
+
try {
|
|
63209
|
+
return types_1.ProjectRegistryEntrySchema.parse(JSON.parse(raw));
|
|
63210
|
+
} catch (err) {
|
|
63211
|
+
this.logger?.warn("Project registry entry is corrupt; skipping", {
|
|
63212
|
+
entryFile,
|
|
63213
|
+
error: (0, error_utils_js_1.toErrorMessage)(err)
|
|
63214
|
+
});
|
|
63215
|
+
return null;
|
|
63216
|
+
}
|
|
63048
63217
|
}
|
|
63049
63218
|
/**
|
|
63050
63219
|
* Register or update a project in the registry.
|
|
63051
63220
|
* Creates the directory and writes registry.json with current timestamp.
|
|
63052
63221
|
*/
|
|
63053
63222
|
async register(projectDir2) {
|
|
63054
|
-
const encoded = encodeProjectDir(projectDir2);
|
|
63223
|
+
const encoded = (0, exports2.encodeProjectDir)(projectDir2);
|
|
63055
63224
|
const entryDir = (0, node_path_1.join)(this.registryRoot, encoded);
|
|
63056
63225
|
const entryFile = (0, node_path_1.join)(entryDir, REGISTRY_FILE);
|
|
63057
63226
|
await promises_1.default.mkdir(entryDir, { recursive: true });
|
|
@@ -63084,12 +63253,9 @@ var require_project_registry = __commonJS({
|
|
|
63084
63253
|
if (!dirent.isDirectory())
|
|
63085
63254
|
continue;
|
|
63086
63255
|
const entryFile = (0, node_path_1.join)(this.registryRoot, dirent.name, REGISTRY_FILE);
|
|
63087
|
-
|
|
63088
|
-
|
|
63089
|
-
|
|
63090
|
-
entries.push(parsed);
|
|
63091
|
-
} catch {
|
|
63092
|
-
}
|
|
63256
|
+
const entry = await this.readEntry(entryFile);
|
|
63257
|
+
if (entry)
|
|
63258
|
+
entries.push(entry);
|
|
63093
63259
|
}
|
|
63094
63260
|
return entries;
|
|
63095
63261
|
}
|
|
@@ -63110,14 +63276,9 @@ var require_project_registry = __commonJS({
|
|
|
63110
63276
|
continue;
|
|
63111
63277
|
const entryDir = (0, node_path_1.join)(this.registryRoot, dirent.name);
|
|
63112
63278
|
const entryFile = (0, node_path_1.join)(entryDir, REGISTRY_FILE);
|
|
63113
|
-
|
|
63114
|
-
|
|
63115
|
-
const raw = await promises_1.default.readFile(entryFile, "utf-8");
|
|
63116
|
-
entry = types_1.ProjectRegistryEntrySchema.parse(JSON.parse(raw));
|
|
63117
|
-
} catch {
|
|
63118
|
-
await promises_1.default.rm(entryDir, { recursive: true, force: true });
|
|
63279
|
+
const entry = await this.readEntry(entryFile);
|
|
63280
|
+
if (!entry)
|
|
63119
63281
|
continue;
|
|
63120
|
-
}
|
|
63121
63282
|
let reason = null;
|
|
63122
63283
|
if (!(0, node_fs_1.existsSync)(entry.path)) {
|
|
63123
63284
|
reason = "path-missing";
|
|
@@ -63184,8 +63345,9 @@ var require_daemon_health = __commonJS({
|
|
|
63184
63345
|
var node_path_1 = require("node:path");
|
|
63185
63346
|
var types_1 = require_dist();
|
|
63186
63347
|
var error_utils_js_1 = require_error_utils();
|
|
63187
|
-
|
|
63188
|
-
|
|
63348
|
+
var sidekick_paths_js_1 = require_sidekick_paths();
|
|
63349
|
+
function healthFilePath(projectDir2, home) {
|
|
63350
|
+
return (0, node_path_1.join)((0, sidekick_paths_js_1.projectStateDir)(projectDir2, home), "state", "daemon-health.json");
|
|
63189
63351
|
}
|
|
63190
63352
|
function defaultHealth() {
|
|
63191
63353
|
return {
|
|
@@ -63193,8 +63355,8 @@ var require_daemon_health = __commonJS({
|
|
|
63193
63355
|
lastCheckedAt: (/* @__PURE__ */ new Date(0)).toISOString()
|
|
63194
63356
|
};
|
|
63195
63357
|
}
|
|
63196
|
-
async function readDaemonHealth(projectDir2) {
|
|
63197
|
-
const path = healthFilePath(projectDir2);
|
|
63358
|
+
async function readDaemonHealth(projectDir2, home) {
|
|
63359
|
+
const path = healthFilePath(projectDir2, home);
|
|
63198
63360
|
try {
|
|
63199
63361
|
const content = await fs.readFile(path, "utf-8");
|
|
63200
63362
|
const json = JSON.parse(content);
|
|
@@ -63207,8 +63369,8 @@ var require_daemon_health = __commonJS({
|
|
|
63207
63369
|
return defaultHealth();
|
|
63208
63370
|
}
|
|
63209
63371
|
}
|
|
63210
|
-
async function writeDaemonHealth(projectDir2, health) {
|
|
63211
|
-
const path = healthFilePath(projectDir2);
|
|
63372
|
+
async function writeDaemonHealth(projectDir2, health, home) {
|
|
63373
|
+
const path = healthFilePath(projectDir2, home);
|
|
63212
63374
|
const dir = (0, node_path_1.dirname)(path);
|
|
63213
63375
|
await fs.mkdir(dir, { recursive: true });
|
|
63214
63376
|
const tmpPath = `${path}.${Date.now()}.${Math.random().toString(36).slice(2, 8)}.tmp`;
|
|
@@ -63224,8 +63386,8 @@ var require_daemon_health = __commonJS({
|
|
|
63224
63386
|
throw err;
|
|
63225
63387
|
}
|
|
63226
63388
|
}
|
|
63227
|
-
async function updateDaemonHealth(projectDir2, newStatus, logger, error) {
|
|
63228
|
-
const current = await readDaemonHealth(projectDir2);
|
|
63389
|
+
async function updateDaemonHealth(projectDir2, newStatus, logger, error, home) {
|
|
63390
|
+
const current = await readDaemonHealth(projectDir2, home);
|
|
63229
63391
|
if (current.status === newStatus) {
|
|
63230
63392
|
return false;
|
|
63231
63393
|
}
|
|
@@ -63237,7 +63399,7 @@ var require_daemon_health = __commonJS({
|
|
|
63237
63399
|
...error !== void 0 && { error }
|
|
63238
63400
|
};
|
|
63239
63401
|
try {
|
|
63240
|
-
await writeDaemonHealth(projectDir2, health);
|
|
63402
|
+
await writeDaemonHealth(projectDir2, health, home);
|
|
63241
63403
|
} catch (err) {
|
|
63242
63404
|
logger.warn("Failed to write daemon health", {
|
|
63243
63405
|
from,
|
|
@@ -63420,7 +63582,7 @@ var require_dist4 = __commonJS({
|
|
|
63420
63582
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
63421
63583
|
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;
|
|
63422
63584
|
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;
|
|
63423
|
-
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;
|
|
63585
|
+
exports2.computeBuildIdentity = 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;
|
|
63424
63586
|
var types_1 = require_dist();
|
|
63425
63587
|
Object.defineProperty(exports2, "TaskTypes", { enumerable: true, get: function() {
|
|
63426
63588
|
return types_1.TaskTypes;
|
|
@@ -63479,6 +63641,7 @@ var require_dist4 = __commonJS({
|
|
|
63479
63641
|
Object.defineProperty(exports2, "reconstructTranscriptPath", { enumerable: true, get: function() {
|
|
63480
63642
|
return claude_paths_1.reconstructTranscriptPath;
|
|
63481
63643
|
} });
|
|
63644
|
+
__exportStar(require_sidekick_paths(), exports2);
|
|
63482
63645
|
var persona_loader_1 = require_persona_loader();
|
|
63483
63646
|
Object.defineProperty(exports2, "createPersonaLoader", { enumerable: true, get: function() {
|
|
63484
63647
|
return persona_loader_1.createPersonaLoader;
|
|
@@ -63845,6 +64008,10 @@ var require_dist4 = __commonJS({
|
|
|
63845
64008
|
Object.defineProperty(exports2, "CoalescingGuard", { enumerable: true, get: function() {
|
|
63846
64009
|
return coalescing_guard_1.CoalescingGuard;
|
|
63847
64010
|
} });
|
|
64011
|
+
var build_identity_1 = require_build_identity();
|
|
64012
|
+
Object.defineProperty(exports2, "computeBuildIdentity", { enumerable: true, get: function() {
|
|
64013
|
+
return build_identity_1.computeBuildIdentity;
|
|
64014
|
+
} });
|
|
63848
64015
|
}
|
|
63849
64016
|
});
|
|
63850
64017
|
|
|
@@ -73962,6 +74129,7 @@ var require_stage_persona_reminders = __commonJS({
|
|
|
73962
74129
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
73963
74130
|
exports2.restagePersonaRemindersForActiveSessions = restagePersonaRemindersForActiveSessions;
|
|
73964
74131
|
exports2.stagePersonaRemindersForSession = stagePersonaRemindersForSession;
|
|
74132
|
+
exports2.resolvePersonaContextForSnapshot = resolvePersonaContextForSnapshot;
|
|
73965
74133
|
exports2.registerStagePersonaReminders = registerStagePersonaReminders;
|
|
73966
74134
|
var core_1 = require_dist4();
|
|
73967
74135
|
var events_js_1 = require_events2();
|
|
@@ -74125,6 +74293,20 @@ var require_stage_persona_reminders = __commonJS({
|
|
|
74125
74293
|
includeChanged: options?.includeChangedReminder ?? false
|
|
74126
74294
|
});
|
|
74127
74295
|
}
|
|
74296
|
+
async function resolvePersonaContextForSnapshot(ctx, sessionId) {
|
|
74297
|
+
if (!isPersonaInjectionEnabled(ctx))
|
|
74298
|
+
return void 0;
|
|
74299
|
+
const persona = await loadPersonaForSession(ctx, sessionId);
|
|
74300
|
+
if (!persona)
|
|
74301
|
+
return void 0;
|
|
74302
|
+
const templateContext = buildPersonaTemplateContext(persona);
|
|
74303
|
+
const reminder = (0, reminder_utils_js_1.resolveReminder)(types_js_1.ReminderIds.REMEMBER_YOUR_PERSONA, {
|
|
74304
|
+
context: templateContext,
|
|
74305
|
+
assets: ctx.assets,
|
|
74306
|
+
logger: ctx.logger
|
|
74307
|
+
});
|
|
74308
|
+
return reminder?.additionalContext ?? void 0;
|
|
74309
|
+
}
|
|
74128
74310
|
function registerStagePersonaReminders(context) {
|
|
74129
74311
|
if (!(0, types_1.isDaemonContext)(context))
|
|
74130
74312
|
return;
|
|
@@ -74153,6 +74335,7 @@ var require_stage_user_profile_reminders = __commonJS({
|
|
|
74153
74335
|
"use strict";
|
|
74154
74336
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
74155
74337
|
exports2.stageUserProfileRemindersForSession = stageUserProfileRemindersForSession;
|
|
74338
|
+
exports2.resolveUserProfileContextForSnapshot = resolveUserProfileContextForSnapshot;
|
|
74156
74339
|
exports2.registerStageUserProfileReminders = registerStageUserProfileReminders;
|
|
74157
74340
|
var core_1 = require_dist4();
|
|
74158
74341
|
var events_js_1 = require_events2();
|
|
@@ -74192,6 +74375,21 @@ var require_stage_user_profile_reminders = __commonJS({
|
|
|
74192
74375
|
ctx.logger.warn("Failed to resolve user-profile reminder", { sessionId });
|
|
74193
74376
|
}
|
|
74194
74377
|
}
|
|
74378
|
+
function resolveUserProfileContextForSnapshot(ctx) {
|
|
74379
|
+
const profile = (0, core_1.loadUserProfile)({ logger: ctx.logger });
|
|
74380
|
+
if (!profile)
|
|
74381
|
+
return void 0;
|
|
74382
|
+
const templateContext = {
|
|
74383
|
+
user_name: profile.name,
|
|
74384
|
+
user_role: profile.role,
|
|
74385
|
+
user_interests: profile.interests.join(", ")
|
|
74386
|
+
};
|
|
74387
|
+
const reminder = (0, reminder_utils_js_1.resolveReminder)(types_js_1.ReminderIds.USER_PROFILE, {
|
|
74388
|
+
context: templateContext,
|
|
74389
|
+
assets: ctx.assets
|
|
74390
|
+
});
|
|
74391
|
+
return reminder?.additionalContext ?? void 0;
|
|
74392
|
+
}
|
|
74195
74393
|
function registerStageUserProfileReminders(context) {
|
|
74196
74394
|
if (!(0, types_1.isDaemonContext)(context))
|
|
74197
74395
|
return;
|
|
@@ -74287,10 +74485,10 @@ var require_cli_staging_reader = __commonJS({
|
|
|
74287
74485
|
stateDir;
|
|
74288
74486
|
sessionId;
|
|
74289
74487
|
constructor(options) {
|
|
74290
|
-
if (!options.paths.
|
|
74291
|
-
throw new Error("CLIStagingReader requires project scope (
|
|
74488
|
+
if (!options.paths.projectStateDir) {
|
|
74489
|
+
throw new Error("CLIStagingReader requires project scope (projectStateDir must be defined)");
|
|
74292
74490
|
}
|
|
74293
|
-
this.stateDir = options.paths.
|
|
74491
|
+
this.stateDir = options.paths.projectStateDir;
|
|
74294
74492
|
this.sessionId = options.sessionId;
|
|
74295
74493
|
}
|
|
74296
74494
|
/**
|
|
@@ -74654,6 +74852,22 @@ var require_inject_session_start = __commonJS({
|
|
|
74654
74852
|
}
|
|
74655
74853
|
});
|
|
74656
74854
|
|
|
74855
|
+
// ../feature-reminders/dist/handlers/consumption/inject-post-compact.js
|
|
74856
|
+
var require_inject_post_compact = __commonJS({
|
|
74857
|
+
"../feature-reminders/dist/handlers/consumption/inject-post-compact.js"(exports2) {
|
|
74858
|
+
"use strict";
|
|
74859
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
74860
|
+
exports2.registerInjectPostCompact = registerInjectPostCompact;
|
|
74861
|
+
var consumption_handler_factory_js_1 = require_consumption_handler_factory();
|
|
74862
|
+
function registerInjectPostCompact(context) {
|
|
74863
|
+
(0, consumption_handler_factory_js_1.createConsumptionHandler)(context, {
|
|
74864
|
+
id: "reminders:inject-post-compact",
|
|
74865
|
+
hook: "PostCompact"
|
|
74866
|
+
});
|
|
74867
|
+
}
|
|
74868
|
+
}
|
|
74869
|
+
});
|
|
74870
|
+
|
|
74657
74871
|
// ../feature-reminders/dist/handlers/consumption/index.js
|
|
74658
74872
|
var require_consumption = __commonJS({
|
|
74659
74873
|
"../feature-reminders/dist/handlers/consumption/index.js"(exports2) {
|
|
@@ -74665,12 +74879,14 @@ var require_consumption = __commonJS({
|
|
|
74665
74879
|
var inject_post_tool_use_1 = require_inject_post_tool_use();
|
|
74666
74880
|
var inject_stop_1 = require_inject_stop();
|
|
74667
74881
|
var inject_session_start_1 = require_inject_session_start();
|
|
74882
|
+
var inject_post_compact_js_1 = require_inject_post_compact();
|
|
74668
74883
|
function registerConsumptionHandlers(context) {
|
|
74669
74884
|
(0, inject_user_prompt_submit_1.registerInjectUserPromptSubmit)(context);
|
|
74670
74885
|
(0, inject_pre_tool_use_1.registerInjectPreToolUse)(context);
|
|
74671
74886
|
(0, inject_post_tool_use_1.registerInjectPostToolUse)(context);
|
|
74672
74887
|
(0, inject_stop_1.registerInjectStop)(context);
|
|
74673
74888
|
(0, inject_session_start_1.registerInjectSessionStart)(context);
|
|
74889
|
+
(0, inject_post_compact_js_1.registerInjectPostCompact)(context);
|
|
74674
74890
|
}
|
|
74675
74891
|
}
|
|
74676
74892
|
});
|
|
@@ -75115,7 +75331,7 @@ var require_dist5 = __commonJS({
|
|
|
75115
75331
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p);
|
|
75116
75332
|
};
|
|
75117
75333
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
75118
|
-
exports2.createRemindersState = exports2.ReminderOrchestrator = exports2.ReminderEvents = exports2.handleVCUnverifiedClear = exports2.handleVCUnverifiedSet = exports2.handleReminderConsumed = exports2.classifyCompletion = exports2.restagePersonaRemindersForActiveSessions = exports2.stagePersonaRemindersForSession = exports2.registerStagingHandlers = exports2.registerConsumptionHandlers = exports2.manifest = void 0;
|
|
75334
|
+
exports2.createRemindersState = exports2.ReminderOrchestrator = exports2.ReminderEvents = exports2.handleVCUnverifiedClear = exports2.handleVCUnverifiedSet = exports2.handleReminderConsumed = exports2.classifyCompletion = exports2.resolveUserProfileContextForSnapshot = exports2.resolvePersonaContextForSnapshot = exports2.restagePersonaRemindersForActiveSessions = exports2.stagePersonaRemindersForSession = exports2.registerStagingHandlers = exports2.registerConsumptionHandlers = exports2.manifest = void 0;
|
|
75119
75335
|
exports2.register = register;
|
|
75120
75336
|
var staging_1 = require_staging2();
|
|
75121
75337
|
var consumption_1 = require_consumption();
|
|
@@ -75149,6 +75365,13 @@ var require_dist5 = __commonJS({
|
|
|
75149
75365
|
Object.defineProperty(exports2, "restagePersonaRemindersForActiveSessions", { enumerable: true, get: function() {
|
|
75150
75366
|
return stage_persona_reminders_1.restagePersonaRemindersForActiveSessions;
|
|
75151
75367
|
} });
|
|
75368
|
+
Object.defineProperty(exports2, "resolvePersonaContextForSnapshot", { enumerable: true, get: function() {
|
|
75369
|
+
return stage_persona_reminders_1.resolvePersonaContextForSnapshot;
|
|
75370
|
+
} });
|
|
75371
|
+
var stage_user_profile_reminders_1 = require_stage_user_profile_reminders();
|
|
75372
|
+
Object.defineProperty(exports2, "resolveUserProfileContextForSnapshot", { enumerable: true, get: function() {
|
|
75373
|
+
return stage_user_profile_reminders_1.resolveUserProfileContextForSnapshot;
|
|
75374
|
+
} });
|
|
75152
75375
|
var completion_classifier_1 = require_completion_classifier();
|
|
75153
75376
|
Object.defineProperty(exports2, "classifyCompletion", { enumerable: true, get: function() {
|
|
75154
75377
|
return completion_classifier_1.classifyCompletion;
|
|
@@ -77502,6 +77725,7 @@ var require_cleanup_handler = __commonJS({
|
|
|
77502
77725
|
var promises_1 = __importDefault(require("fs/promises"));
|
|
77503
77726
|
var path_1 = __importDefault(require("path"));
|
|
77504
77727
|
var DEFAULT_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
77728
|
+
var DEFAULT_LOG_MAX_AGE_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
77505
77729
|
function createCleanupHandler(deps) {
|
|
77506
77730
|
return async (payload, ctx) => {
|
|
77507
77731
|
const result = core_1.CleanupPayloadSchema.safeParse(payload);
|
|
@@ -77522,6 +77746,55 @@ var require_cleanup_handler = __commonJS({
|
|
|
77522
77746
|
const now = Date.now();
|
|
77523
77747
|
let cleaned = 0;
|
|
77524
77748
|
let skipped = 0;
|
|
77749
|
+
const pruneLogs = async () => {
|
|
77750
|
+
const logMaxAgeMs = p.logMaxAgeMs ?? DEFAULT_LOG_MAX_AGE_MS;
|
|
77751
|
+
const logsDir = deps.stateService.logsDir();
|
|
77752
|
+
let logsCleaned = 0;
|
|
77753
|
+
let logsSkipped = 0;
|
|
77754
|
+
try {
|
|
77755
|
+
const logEntries = await promises_1.default.readdir(logsDir, { withFileTypes: true });
|
|
77756
|
+
for (const entry of logEntries) {
|
|
77757
|
+
if (ctx.signal.aborted) {
|
|
77758
|
+
ctx.logger.info("Log cleanup cancelled mid-execution");
|
|
77759
|
+
return;
|
|
77760
|
+
}
|
|
77761
|
+
if (!entry.isFile())
|
|
77762
|
+
continue;
|
|
77763
|
+
const filePath = path_1.default.join(logsDir, entry.name);
|
|
77764
|
+
try {
|
|
77765
|
+
const stats = await promises_1.default.stat(filePath);
|
|
77766
|
+
const age = now - stats.mtimeMs;
|
|
77767
|
+
if (age > logMaxAgeMs) {
|
|
77768
|
+
if (dryRun) {
|
|
77769
|
+
ctx.logger.debug("Would clean log file (dry-run)", { file: entry.name, ageMs: age });
|
|
77770
|
+
} else {
|
|
77771
|
+
await promises_1.default.rm(filePath, { force: true });
|
|
77772
|
+
ctx.logger.debug("Cleaned log file", { file: entry.name, ageMs: age });
|
|
77773
|
+
}
|
|
77774
|
+
logsCleaned++;
|
|
77775
|
+
} else {
|
|
77776
|
+
logsSkipped++;
|
|
77777
|
+
}
|
|
77778
|
+
} catch (statErr) {
|
|
77779
|
+
ctx.logger.warn("Failed to stat log file", {
|
|
77780
|
+
file: entry.name,
|
|
77781
|
+
error: (0, core_1.toErrorMessage)(statErr)
|
|
77782
|
+
});
|
|
77783
|
+
}
|
|
77784
|
+
}
|
|
77785
|
+
if (logsCleaned === 0 && logsSkipped === 0) {
|
|
77786
|
+
ctx.logger.debug("No log files eligible for cleanup");
|
|
77787
|
+
}
|
|
77788
|
+
ctx.logger.info("Log cleanup completed", { cleaned: logsCleaned, skipped: logsSkipped, dryRun });
|
|
77789
|
+
(0, core_1.logEvent)(ctx.logger, core_1.LogEvents.cleanupLogCompleted({ cleaned: logsCleaned, skipped: logsSkipped, dryRun }));
|
|
77790
|
+
} catch (logErr) {
|
|
77791
|
+
if (logErr.code === "ENOENT") {
|
|
77792
|
+
ctx.logger.debug("Logs directory does not exist, nothing to clean");
|
|
77793
|
+
} else {
|
|
77794
|
+
ctx.logger.warn("Log cleanup phase failed", { error: (0, core_1.toErrorMessage)(logErr) });
|
|
77795
|
+
}
|
|
77796
|
+
}
|
|
77797
|
+
};
|
|
77525
77798
|
try {
|
|
77526
77799
|
const entries = await promises_1.default.readdir(sessionsDir, { withFileTypes: true });
|
|
77527
77800
|
for (const entry of entries) {
|
|
@@ -77560,11 +77833,22 @@ var require_cleanup_handler = __commonJS({
|
|
|
77560
77833
|
ctx.logger.info("Cleanup task cancelled mid-execution, not updating lastCleanup");
|
|
77561
77834
|
return;
|
|
77562
77835
|
}
|
|
77836
|
+
await pruneLogs();
|
|
77837
|
+
if (ctx.signal.aborted) {
|
|
77838
|
+
ctx.logger.info("Cleanup task cancelled mid-execution, not updating lastCleanup");
|
|
77839
|
+
return;
|
|
77840
|
+
}
|
|
77563
77841
|
await deps.taskRegistry.updateLastCleanup();
|
|
77564
77842
|
ctx.logger.info("Cleanup task completed", { cleaned, skipped, dryRun });
|
|
77565
77843
|
} catch (err) {
|
|
77566
77844
|
if (err.code === "ENOENT") {
|
|
77567
77845
|
ctx.logger.debug("Sessions directory does not exist, nothing to clean");
|
|
77846
|
+
await pruneLogs();
|
|
77847
|
+
if (ctx.signal.aborted) {
|
|
77848
|
+
ctx.logger.info("Cleanup task cancelled mid-execution, not updating lastCleanup");
|
|
77849
|
+
return;
|
|
77850
|
+
}
|
|
77851
|
+
await deps.taskRegistry.updateLastCleanup();
|
|
77568
77852
|
return;
|
|
77569
77853
|
}
|
|
77570
77854
|
ctx.logger.error("Cleanup task failed", {
|
|
@@ -78006,9 +78290,10 @@ var require_daemon_helpers = __commonJS({
|
|
|
78006
78290
|
exports2.REGISTRY_HEARTBEAT_INTERVAL_MS = exports2.EVICTION_INTERVAL_MS = exports2.HEARTBEAT_INTERVAL_MS = exports2.IDLE_CHECK_INTERVAL_MS = exports2.VERSION = void 0;
|
|
78007
78291
|
exports2.diffConfigs = diffConfigs;
|
|
78008
78292
|
exports2.resolveTranscriptPath = resolveTranscriptPath;
|
|
78293
|
+
exports2.shouldRunStartupCleanup = shouldRunStartupCleanup;
|
|
78009
78294
|
exports2.getPersonaInjectionEnabled = getPersonaInjectionEnabled;
|
|
78010
78295
|
var core_1 = require_dist4();
|
|
78011
|
-
exports2.VERSION =
|
|
78296
|
+
exports2.VERSION = (0, core_1.computeBuildIdentity)();
|
|
78012
78297
|
exports2.IDLE_CHECK_INTERVAL_MS = 30 * 1e3;
|
|
78013
78298
|
exports2.HEARTBEAT_INTERVAL_MS = 5 * 1e3;
|
|
78014
78299
|
exports2.EVICTION_INTERVAL_MS = 5 * 60 * 1e3;
|
|
@@ -78040,6 +78325,11 @@ var require_daemon_helpers = __commonJS({
|
|
|
78040
78325
|
}
|
|
78041
78326
|
return transcriptPath;
|
|
78042
78327
|
}
|
|
78328
|
+
function shouldRunStartupCleanup(lastCleanupAt, intervalMs, now) {
|
|
78329
|
+
if (lastCleanupAt === void 0)
|
|
78330
|
+
return true;
|
|
78331
|
+
return now - lastCleanupAt >= intervalMs;
|
|
78332
|
+
}
|
|
78043
78333
|
function getPersonaInjectionEnabled(config) {
|
|
78044
78334
|
return config.getFeature("session-summary").settings?.personas?.injectPersonaIntoClaude ?? true;
|
|
78045
78335
|
}
|
|
@@ -78135,6 +78425,7 @@ var require_daemon_timer_manager = __commonJS({
|
|
|
78135
78425
|
heartbeatInterval = null;
|
|
78136
78426
|
evictionTimer = null;
|
|
78137
78427
|
registryHeartbeatInterval = null;
|
|
78428
|
+
cleanupTimer = null;
|
|
78138
78429
|
constructor(deps) {
|
|
78139
78430
|
this.deps = deps;
|
|
78140
78431
|
this.startTime = deps.startTime;
|
|
@@ -78186,6 +78477,19 @@ var require_daemon_timer_manager = __commonJS({
|
|
|
78186
78477
|
stopEvictionTimer() {
|
|
78187
78478
|
this.clearTimer("evictionTimer");
|
|
78188
78479
|
}
|
|
78480
|
+
/** Start periodic cleanup timer (runs every config.core.daemon.cleanup.intervalHours hours). */
|
|
78481
|
+
startCleanupTimer() {
|
|
78482
|
+
const intervalMs = this.deps.configService.core.daemon.cleanup.intervalHours * 60 * 60 * 1e3;
|
|
78483
|
+
this.cleanupTimer = setInterval(() => {
|
|
78484
|
+
void this.deps.onCleanup();
|
|
78485
|
+
}, intervalMs);
|
|
78486
|
+
this.cleanupTimer.unref();
|
|
78487
|
+
this.deps.logger.info("Cleanup timer started", { intervalMs });
|
|
78488
|
+
(0, core_1.logEvent)(this.deps.logger, core_1.LogEvents.cleanupTimerStarted({ intervalMs }));
|
|
78489
|
+
}
|
|
78490
|
+
stopCleanupTimer() {
|
|
78491
|
+
this.clearTimer("cleanupTimer");
|
|
78492
|
+
}
|
|
78189
78493
|
/** Register this project in the user-level registry for UI discovery. */
|
|
78190
78494
|
async registerProject() {
|
|
78191
78495
|
try {
|
|
@@ -78211,6 +78515,7 @@ var require_daemon_timer_manager = __commonJS({
|
|
|
78211
78515
|
this.startIdleCheck();
|
|
78212
78516
|
this.startHeartbeat();
|
|
78213
78517
|
this.startEvictionTimer();
|
|
78518
|
+
this.startCleanupTimer();
|
|
78214
78519
|
await this.registerProject();
|
|
78215
78520
|
this.startRegistryHeartbeat();
|
|
78216
78521
|
}
|
|
@@ -78218,6 +78523,7 @@ var require_daemon_timer_manager = __commonJS({
|
|
|
78218
78523
|
this.stopIdleCheck();
|
|
78219
78524
|
this.stopHeartbeat();
|
|
78220
78525
|
this.stopEvictionTimer();
|
|
78526
|
+
this.stopCleanupTimer();
|
|
78221
78527
|
this.stopRegistryHeartbeat();
|
|
78222
78528
|
}
|
|
78223
78529
|
clearTimer(field) {
|
|
@@ -78619,6 +78925,8 @@ var require_daemon = __commonJS({
|
|
|
78619
78925
|
registryService;
|
|
78620
78926
|
timerManager;
|
|
78621
78927
|
sessionLogWriter;
|
|
78928
|
+
/** In-memory compaction snapshots keyed by sessionId. Populated by PreCompact, consumed by PostCompact. */
|
|
78929
|
+
compactionSnapshots = /* @__PURE__ */ new Map();
|
|
78622
78930
|
/** Cache persona for handoff on clear. */
|
|
78623
78931
|
cachePersonaForClear(personaId) {
|
|
78624
78932
|
this.lastClearedPersona = { personaId, timestamp: Date.now() };
|
|
@@ -78642,6 +78950,14 @@ var require_daemon = __commonJS({
|
|
|
78642
78950
|
this.logger.debug("Consumed persona from clear handoff", { personaId, age });
|
|
78643
78951
|
return personaId;
|
|
78644
78952
|
}
|
|
78953
|
+
buildRuntimePaths() {
|
|
78954
|
+
return {
|
|
78955
|
+
projectDir: this.projectDir,
|
|
78956
|
+
userConfigDir: this.userStateService.rootDir(),
|
|
78957
|
+
projectConfigDir: path_1.default.join(this.projectDir, ".sidekick"),
|
|
78958
|
+
projectStateDir: this.stateService.rootDir()
|
|
78959
|
+
};
|
|
78960
|
+
}
|
|
78645
78961
|
constructor(projectDir2) {
|
|
78646
78962
|
const startTime = Date.now();
|
|
78647
78963
|
this.projectDir = projectDir2;
|
|
@@ -78653,7 +78969,7 @@ var require_daemon = __commonJS({
|
|
|
78653
78969
|
projectRoot: projectDir2,
|
|
78654
78970
|
assets: this.assetResolver
|
|
78655
78971
|
});
|
|
78656
|
-
const logDir = path_1.default.join(
|
|
78972
|
+
const logDir = path_1.default.join((0, core_1.projectStateDir)(projectDir2), "logs");
|
|
78657
78973
|
this.logManager = (0, core_1.createLogManager)({
|
|
78658
78974
|
name: "sidekickd",
|
|
78659
78975
|
level: this.configService.core.logging.level,
|
|
@@ -78675,7 +78991,7 @@ var require_daemon = __commonJS({
|
|
|
78675
78991
|
getStartTime: () => this.timerManager.startTime
|
|
78676
78992
|
});
|
|
78677
78993
|
this.logger = this.logMetrics.createCountingLogger();
|
|
78678
|
-
const sessionsDir = path_1.default.join(
|
|
78994
|
+
const sessionsDir = path_1.default.join((0, core_1.projectStateDir)(projectDir2), "sessions");
|
|
78679
78995
|
this.sessionLogWriter = new core_1.SessionLogWriter({
|
|
78680
78996
|
sessionsDir,
|
|
78681
78997
|
maxHandles: 10,
|
|
@@ -78695,7 +79011,7 @@ var require_daemon = __commonJS({
|
|
|
78695
79011
|
config: () => this.configService.getAll()
|
|
78696
79012
|
});
|
|
78697
79013
|
const registryRoot = path_1.default.join((0, os_1.homedir)(), ".sidekick", "projects");
|
|
78698
|
-
this.registryService = new core_1.ProjectRegistryService(registryRoot);
|
|
79014
|
+
this.registryService = new core_1.ProjectRegistryService(registryRoot, this.logger);
|
|
78699
79015
|
this.stagingStateService = new core_1.StateService(projectDir2, {
|
|
78700
79016
|
cache: false,
|
|
78701
79017
|
logger: this.logger,
|
|
@@ -78704,7 +79020,7 @@ var require_daemon = __commonJS({
|
|
|
78704
79020
|
this.taskEngine = new task_engine_js_1.TaskEngine(this.logger, this.getContextForTask.bind(this));
|
|
78705
79021
|
this.taskRegistry = new task_registry_js_1.TaskRegistry(this.stateService, this.logger);
|
|
78706
79022
|
this.configWatcher = new config_watcher_js_1.ConfigWatcher({
|
|
78707
|
-
projectDir: this.
|
|
79023
|
+
projectDir: path_1.default.join(this.projectDir, ".sidekick"),
|
|
78708
79024
|
devAssetsDir: this.configService.core.development.enabled ? (0, core_1.getDefaultAssetsDir)() : void 0
|
|
78709
79025
|
}, this.logger, this.handleConfigChange.bind(this));
|
|
78710
79026
|
this.personaWatcher = new session_persona_watcher_js_1.SessionPersonaWatcher({ sidekickDir: this.stateService.rootDir() }, this.logger, this.handlePersonaChange.bind(this));
|
|
@@ -78730,7 +79046,8 @@ var require_daemon = __commonJS({
|
|
|
78730
79046
|
projectDir: this.projectDir,
|
|
78731
79047
|
startTime,
|
|
78732
79048
|
onIdle: () => this.stop(),
|
|
78733
|
-
onHeartbeat: () => this.logMetrics.writeHeartbeat()
|
|
79049
|
+
onHeartbeat: () => this.logMetrics.writeHeartbeat(),
|
|
79050
|
+
onCleanup: () => this.enqueueCleanup("timer")
|
|
78734
79051
|
});
|
|
78735
79052
|
this.contextMetricsService = (0, index_js_1.createContextMetricsService)({
|
|
78736
79053
|
projectDir: projectDir2,
|
|
@@ -78771,12 +79088,25 @@ var require_daemon = __commonJS({
|
|
|
78771
79088
|
(0, core_1.logEvent)(this.logger, core_1.LogEvents.ipcServerStarted({ socketPath: (0, core_1.getSocketPath)(this.projectDir) }));
|
|
78772
79089
|
this.configWatcher.start();
|
|
78773
79090
|
const watchedFiles = [
|
|
78774
|
-
this.
|
|
79091
|
+
path_1.default.join(this.projectDir, ".sidekick"),
|
|
78775
79092
|
path_1.default.join((0, os_1.homedir)(), ".sidekick"),
|
|
78776
79093
|
...this.configService.core.development.enabled ? [(0, core_1.getDefaultAssetsDir)()] : []
|
|
78777
79094
|
];
|
|
78778
79095
|
(0, core_1.logEvent)(this.logger, core_1.LogEvents.configWatcherStarted({ projectDir: this.projectDir, watchedFiles }));
|
|
78779
79096
|
this.personaWatcher.start();
|
|
79097
|
+
const cleanupCfg = this.configService.core.daemon.cleanup;
|
|
79098
|
+
const cleanupIntervalMs = cleanupCfg.intervalHours * 60 * 60 * 1e3;
|
|
79099
|
+
const registryState = await this.taskRegistry.getState();
|
|
79100
|
+
const lastCleanupAt = registryState.lastCleanupAt;
|
|
79101
|
+
if ((0, daemon_helpers_js_1.shouldRunStartupCleanup)(lastCleanupAt, cleanupIntervalMs, Date.now())) {
|
|
79102
|
+
await this.enqueueCleanup("startup");
|
|
79103
|
+
} else if (lastCleanupAt !== void 0) {
|
|
79104
|
+
this.logger.info("Cleanup skipped \u2014 ran recently", {
|
|
79105
|
+
lastCleanupAt,
|
|
79106
|
+
intervalMs: cleanupIntervalMs
|
|
79107
|
+
});
|
|
79108
|
+
(0, core_1.logEvent)(this.logger, core_1.LogEvents.cleanupSkippedRecent({ lastCleanupAt, intervalMs: cleanupIntervalMs }));
|
|
79109
|
+
}
|
|
78780
79110
|
await this.timerManager.startAll();
|
|
78781
79111
|
this.logger.info("Daemon started successfully");
|
|
78782
79112
|
(0, core_1.logEvent)(this.logger, core_1.LogEvents.daemonStarted({ startupDurationMs: Date.now() - this.timerManager.startTime }));
|
|
@@ -79025,13 +79355,120 @@ var require_daemon = __commonJS({
|
|
|
79025
79355
|
if (hook === "UserPromptSubmit") {
|
|
79026
79356
|
await this.handleUserPromptSubmitCleanup(event, { logger: requestLogger });
|
|
79027
79357
|
}
|
|
79358
|
+
if (hook === "PreCompact") {
|
|
79359
|
+
await this.handlePreCompact(event, { logger: requestLogger });
|
|
79360
|
+
}
|
|
79361
|
+
let postCompactResponse;
|
|
79362
|
+
if (hook === "PostCompact") {
|
|
79363
|
+
postCompactResponse = await this.handlePostCompact(event, { logger: requestLogger });
|
|
79364
|
+
}
|
|
79028
79365
|
if (sessionId && !this.logMetrics.hasSession(sessionId)) {
|
|
79029
79366
|
await this.logMetrics.initSessionCounters(sessionId, false);
|
|
79030
79367
|
requestLogger.debug("Log counters initialized from file for hook", { hook });
|
|
79031
79368
|
}
|
|
79032
79369
|
const response = await this.handlerRegistry.invokeHook(hook, event, { logger: requestLogger });
|
|
79370
|
+
if (postCompactResponse?.additionalContext) {
|
|
79371
|
+
const registryContext = response.additionalContext;
|
|
79372
|
+
response.additionalContext = registryContext ? `${registryContext}
|
|
79373
|
+
|
|
79374
|
+
${postCompactResponse.additionalContext}` : postCompactResponse.additionalContext;
|
|
79375
|
+
}
|
|
79033
79376
|
return response;
|
|
79034
79377
|
}
|
|
79378
|
+
/**
|
|
79379
|
+
* Handle PostCompact: signal compaction to the session's TranscriptService (UC1)
|
|
79380
|
+
* and return the pre-compact session context snapshot for re-injection (UC2).
|
|
79381
|
+
*/
|
|
79382
|
+
async handlePostCompact(event, options) {
|
|
79383
|
+
const log = options?.logger ?? this.logger;
|
|
79384
|
+
const sessionId = event.context?.sessionId;
|
|
79385
|
+
if (!sessionId) {
|
|
79386
|
+
log.warn("PostCompact event missing sessionId");
|
|
79387
|
+
return {};
|
|
79388
|
+
}
|
|
79389
|
+
const transcriptService = this.serviceFactory.getTranscriptService(sessionId);
|
|
79390
|
+
if (transcriptService) {
|
|
79391
|
+
await transcriptService.signalCompaction();
|
|
79392
|
+
log.info("PostCompact: compaction signaled to transcript service", { sessionId });
|
|
79393
|
+
} else {
|
|
79394
|
+
log.warn("PostCompact: no transcript service for session", { sessionId });
|
|
79395
|
+
}
|
|
79396
|
+
const snapshot = this.compactionSnapshots.get(sessionId);
|
|
79397
|
+
if (snapshot) {
|
|
79398
|
+
this.compactionSnapshots.delete(sessionId);
|
|
79399
|
+
log.info("PostCompact: re-injecting compaction snapshot", {
|
|
79400
|
+
sessionId,
|
|
79401
|
+
snapshotLength: snapshot.length
|
|
79402
|
+
});
|
|
79403
|
+
return { additionalContext: snapshot };
|
|
79404
|
+
}
|
|
79405
|
+
return {};
|
|
79406
|
+
}
|
|
79407
|
+
/**
|
|
79408
|
+
* Handle PreCompact: capture staged SessionStart reminders as a compaction snapshot.
|
|
79409
|
+
* The snapshot is returned by the next PostCompact call for context re-injection.
|
|
79410
|
+
*/
|
|
79411
|
+
async handlePreCompact(event, options) {
|
|
79412
|
+
const log = options?.logger ?? this.logger;
|
|
79413
|
+
const sessionId = event.context?.sessionId;
|
|
79414
|
+
if (!sessionId)
|
|
79415
|
+
return;
|
|
79416
|
+
try {
|
|
79417
|
+
const minimalCtx = {
|
|
79418
|
+
role: "daemon",
|
|
79419
|
+
config: {
|
|
79420
|
+
core: {
|
|
79421
|
+
logging: {
|
|
79422
|
+
level: this.configService.core.logging.level,
|
|
79423
|
+
components: this.configService.core.logging.components
|
|
79424
|
+
},
|
|
79425
|
+
development: { enabled: this.configService.core.development.enabled }
|
|
79426
|
+
},
|
|
79427
|
+
llm: {
|
|
79428
|
+
defaultProfile: this.configService.llm.defaultProfile,
|
|
79429
|
+
defaultFallbackProfileId: this.configService.llm.defaultFallbackProfileId,
|
|
79430
|
+
profiles: this.configService.llm.profiles,
|
|
79431
|
+
fallbackProfiles: this.configService.llm.fallbackProfiles
|
|
79432
|
+
},
|
|
79433
|
+
getAll: () => this.configService.getAll(),
|
|
79434
|
+
getFeature: (name) => this.configService.getFeature(name)
|
|
79435
|
+
},
|
|
79436
|
+
logger: log,
|
|
79437
|
+
assets: this.assetResolver,
|
|
79438
|
+
paths: this.buildRuntimePaths(),
|
|
79439
|
+
stateService: this.stateService,
|
|
79440
|
+
// Remaining DaemonContext fields are not needed by the resolve functions
|
|
79441
|
+
handlers: this.handlerRegistry,
|
|
79442
|
+
staging: this.serviceFactory.getStagingService(sessionId),
|
|
79443
|
+
transcript: void 0,
|
|
79444
|
+
llm: void 0,
|
|
79445
|
+
profileFactory: void 0,
|
|
79446
|
+
orchestrator: this.orchestrator,
|
|
79447
|
+
personaClearCache: { consume: () => this.consumeCachedPersona() }
|
|
79448
|
+
};
|
|
79449
|
+
const [personaContext, userProfileContext] = await Promise.all([
|
|
79450
|
+
(0, feature_reminders_1.resolvePersonaContextForSnapshot)(minimalCtx, sessionId),
|
|
79451
|
+
Promise.resolve((0, feature_reminders_1.resolveUserProfileContextForSnapshot)(minimalCtx))
|
|
79452
|
+
]);
|
|
79453
|
+
const contextParts = [personaContext, userProfileContext].filter((c) => typeof c === "string" && c.trim().length > 0);
|
|
79454
|
+
if (contextParts.length === 0) {
|
|
79455
|
+
log.debug("PreCompact: no context to snapshot", { sessionId });
|
|
79456
|
+
return;
|
|
79457
|
+
}
|
|
79458
|
+
const snapshot = ["Context was compacted. Re-establishing session context:", "", ...contextParts].join("\n");
|
|
79459
|
+
this.compactionSnapshots.set(sessionId, snapshot);
|
|
79460
|
+
log.info("PreCompact: compaction snapshot captured", {
|
|
79461
|
+
sessionId,
|
|
79462
|
+
reminderCount: contextParts.length,
|
|
79463
|
+
snapshotLength: snapshot.length
|
|
79464
|
+
});
|
|
79465
|
+
} catch (err) {
|
|
79466
|
+
log.warn("PreCompact: failed to capture snapshot", {
|
|
79467
|
+
sessionId,
|
|
79468
|
+
error: (0, core_1.toErrorMessage)(err)
|
|
79469
|
+
});
|
|
79470
|
+
}
|
|
79471
|
+
}
|
|
79035
79472
|
/**
|
|
79036
79473
|
* Handle SessionStart-specific logic: clear staging on startup/clear.
|
|
79037
79474
|
*
|
|
@@ -79115,6 +79552,7 @@ var require_daemon = __commonJS({
|
|
|
79115
79552
|
}
|
|
79116
79553
|
await this.llmManager.shutdownSessionProvider(sessionId, log);
|
|
79117
79554
|
this.logMetrics.deleteSessionCounters(sessionId);
|
|
79555
|
+
this.compactionSnapshots.delete(sessionId);
|
|
79118
79556
|
await this.serviceFactory.shutdownSession(sessionId);
|
|
79119
79557
|
await this.sessionLogWriter.closeSession(sessionId);
|
|
79120
79558
|
log.info("Session ended");
|
|
@@ -79226,11 +79664,7 @@ var require_daemon = __commonJS({
|
|
|
79226
79664
|
this.logger.info("Completion classification requested", { sessionId });
|
|
79227
79665
|
const resolvedTranscriptPath = transcriptPath ?? (0, core_1.reconstructTranscriptPath)(this.projectDir, sessionId);
|
|
79228
79666
|
this.logger.debug("Resolved transcript path for classification", { transcriptPath: resolvedTranscriptPath });
|
|
79229
|
-
const paths =
|
|
79230
|
-
projectDir: this.projectDir,
|
|
79231
|
-
userConfigDir: this.userStateService.rootDir(),
|
|
79232
|
-
projectConfigDir: this.stateService.rootDir()
|
|
79233
|
-
};
|
|
79667
|
+
const paths = this.buildRuntimePaths();
|
|
79234
79668
|
const sessionDir = this.stateService.sessionRootDir(sessionId);
|
|
79235
79669
|
const instrumentedProfileFactory = this.llmManager.createInstrumentedProfileFactory(sessionId, sessionDir);
|
|
79236
79670
|
const stagingService = this.serviceFactory.getStagingService(sessionId);
|
|
@@ -79298,11 +79732,7 @@ var require_daemon = __commonJS({
|
|
|
79298
79732
|
* @param sessionId - Optional session ID for session-specific context
|
|
79299
79733
|
*/
|
|
79300
79734
|
async getContextForTask(sessionId) {
|
|
79301
|
-
const paths =
|
|
79302
|
-
projectDir: this.projectDir,
|
|
79303
|
-
userConfigDir: this.userStateService.rootDir(),
|
|
79304
|
-
projectConfigDir: this.stateService.rootDir()
|
|
79305
|
-
};
|
|
79735
|
+
const paths = this.buildRuntimePaths();
|
|
79306
79736
|
let llmProvider = this.llmManager.getBaseProvider();
|
|
79307
79737
|
let profileFactory = this.llmManager.getProfileFactory();
|
|
79308
79738
|
if (sessionId) {
|
|
@@ -79368,6 +79798,8 @@ var require_daemon = __commonJS({
|
|
|
79368
79798
|
},
|
|
79369
79799
|
onThreshold: () => () => {
|
|
79370
79800
|
},
|
|
79801
|
+
signalCompaction: async () => {
|
|
79802
|
+
},
|
|
79371
79803
|
capturePreCompactState: async () => {
|
|
79372
79804
|
},
|
|
79373
79805
|
getCompactionHistory: () => []
|
|
@@ -79422,11 +79854,7 @@ var require_daemon = __commonJS({
|
|
|
79422
79854
|
if (!(this.handlerRegistry instanceof core_1.HandlerRegistryImpl)) {
|
|
79423
79855
|
return;
|
|
79424
79856
|
}
|
|
79425
|
-
const paths =
|
|
79426
|
-
projectDir: this.projectDir,
|
|
79427
|
-
userConfigDir: this.userStateService.rootDir(),
|
|
79428
|
-
projectConfigDir: this.stateService.rootDir()
|
|
79429
|
-
};
|
|
79857
|
+
const paths = this.buildRuntimePaths();
|
|
79430
79858
|
const sessionDir = this.stateService.sessionRootDir(sessionId);
|
|
79431
79859
|
const instrumentedProvider = await this.llmManager.getOrCreateInstrumentedProvider(sessionId, sessionDir, log);
|
|
79432
79860
|
const instrumentedProfileFactory = this.llmManager.createInstrumentedProfileFactory(sessionId, sessionDir);
|
|
@@ -79495,6 +79923,19 @@ var require_daemon = __commonJS({
|
|
|
79495
79923
|
log.debug("Cleared staged reminders on UserPromptSubmit", { hooks: hooksToClear });
|
|
79496
79924
|
await this.orchestrator.onUserPromptSubmit(sessionId);
|
|
79497
79925
|
}
|
|
79926
|
+
/** Build the cleanup payload from config and enqueue a cleanup task. */
|
|
79927
|
+
enqueueCleanup(reason) {
|
|
79928
|
+
const cleanup = this.configService.core.daemon.cleanup;
|
|
79929
|
+
const payload = {
|
|
79930
|
+
maxAgeMs: cleanup.sessionMaxAgeDays * 24 * 60 * 60 * 1e3,
|
|
79931
|
+
logMaxAgeMs: cleanup.logMaxAgeDays * 24 * 60 * 60 * 1e3,
|
|
79932
|
+
dryRun: false
|
|
79933
|
+
};
|
|
79934
|
+
this.taskEngine.enqueue(core_1.TaskTypes.CLEANUP, payload);
|
|
79935
|
+
this.logger.info("Cleanup task enqueued", { reason });
|
|
79936
|
+
(0, core_1.logEvent)(this.logger, core_1.LogEvents.cleanupTaskEnqueued({ reason }));
|
|
79937
|
+
return Promise.resolve();
|
|
79938
|
+
}
|
|
79498
79939
|
// ── Delegation shims — existing tests type-cast to call these ─────────
|
|
79499
79940
|
startEvictionTimer() {
|
|
79500
79941
|
this.timerManager.startEvictionTimer();
|
|
@@ -79536,11 +79977,7 @@ var require_daemon = __commonJS({
|
|
|
79536
79977
|
* @see docs/design/FEATURE-REMINDERS.md §3.1 Staging Handlers
|
|
79537
79978
|
*/
|
|
79538
79979
|
registerStagingHandlers() {
|
|
79539
|
-
const paths =
|
|
79540
|
-
projectDir: this.projectDir,
|
|
79541
|
-
userConfigDir: this.userStateService.rootDir(),
|
|
79542
|
-
projectConfigDir: this.stateService.rootDir()
|
|
79543
|
-
};
|
|
79980
|
+
const paths = this.buildRuntimePaths();
|
|
79544
79981
|
const registrationContext = {
|
|
79545
79982
|
role: "daemon",
|
|
79546
79983
|
config: {
|