@scotthamilton77/sidekick 0.0.1-alpha → 0.0.4-alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +1310 -294
- package/dist/daemon.js +70160 -0
- package/package.json +2 -5
package/dist/bin.js
CHANGED
|
@@ -16699,6 +16699,72 @@ var require_hook_input = __commonJS({
|
|
|
16699
16699
|
}
|
|
16700
16700
|
});
|
|
16701
16701
|
|
|
16702
|
+
// ../types/dist/setup-status.js
|
|
16703
|
+
var require_setup_status = __commonJS({
|
|
16704
|
+
"../types/dist/setup-status.js"(exports2) {
|
|
16705
|
+
"use strict";
|
|
16706
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
16707
|
+
exports2.ProjectSetupStatusSchema = exports2.GitignoreStatusSchema = exports2.UserSetupStatusSchema = exports2.ProjectApiKeyHealthSchema = exports2.ApiKeyHealthSchema = void 0;
|
|
16708
|
+
var zod_1 = require_zod();
|
|
16709
|
+
exports2.ApiKeyHealthSchema = zod_1.z.enum([
|
|
16710
|
+
"missing",
|
|
16711
|
+
// Key needed but not found
|
|
16712
|
+
"not-required",
|
|
16713
|
+
// No LLM profiles configured for provider
|
|
16714
|
+
"pending-validation",
|
|
16715
|
+
// Key exists but not validated
|
|
16716
|
+
"invalid",
|
|
16717
|
+
// Validation failed
|
|
16718
|
+
"healthy"
|
|
16719
|
+
// Validation succeeded
|
|
16720
|
+
]);
|
|
16721
|
+
exports2.ProjectApiKeyHealthSchema = zod_1.z.enum([
|
|
16722
|
+
"missing",
|
|
16723
|
+
"not-required",
|
|
16724
|
+
"pending-validation",
|
|
16725
|
+
"invalid",
|
|
16726
|
+
"healthy",
|
|
16727
|
+
"user"
|
|
16728
|
+
// Deferring to user-level
|
|
16729
|
+
]);
|
|
16730
|
+
exports2.UserSetupStatusSchema = zod_1.z.object({
|
|
16731
|
+
version: zod_1.z.literal(1),
|
|
16732
|
+
lastUpdatedAt: zod_1.z.string(),
|
|
16733
|
+
// ISO timestamp
|
|
16734
|
+
preferences: zod_1.z.object({
|
|
16735
|
+
autoConfigureProjects: zod_1.z.boolean(),
|
|
16736
|
+
defaultStatuslineScope: zod_1.z.enum(["user", "project"]),
|
|
16737
|
+
defaultApiKeyScope: zod_1.z.enum(["user", "project", "skip"])
|
|
16738
|
+
}),
|
|
16739
|
+
statusline: zod_1.z.enum(["configured", "skipped"]),
|
|
16740
|
+
apiKeys: zod_1.z.object({
|
|
16741
|
+
OPENROUTER_API_KEY: exports2.ApiKeyHealthSchema,
|
|
16742
|
+
OPENAI_API_KEY: exports2.ApiKeyHealthSchema
|
|
16743
|
+
})
|
|
16744
|
+
});
|
|
16745
|
+
exports2.GitignoreStatusSchema = zod_1.z.enum([
|
|
16746
|
+
"unknown",
|
|
16747
|
+
// Setup hasn't checked yet (legacy projects)
|
|
16748
|
+
"missing",
|
|
16749
|
+
// User declined or entries not present
|
|
16750
|
+
"installed"
|
|
16751
|
+
// Sidekick section present in .gitignore
|
|
16752
|
+
]);
|
|
16753
|
+
exports2.ProjectSetupStatusSchema = zod_1.z.object({
|
|
16754
|
+
version: zod_1.z.literal(1),
|
|
16755
|
+
lastUpdatedAt: zod_1.z.string(),
|
|
16756
|
+
// ISO timestamp
|
|
16757
|
+
autoConfigured: zod_1.z.boolean(),
|
|
16758
|
+
statusline: zod_1.z.enum(["configured", "skipped", "user"]),
|
|
16759
|
+
apiKeys: zod_1.z.object({
|
|
16760
|
+
OPENROUTER_API_KEY: exports2.ProjectApiKeyHealthSchema,
|
|
16761
|
+
OPENAI_API_KEY: exports2.ProjectApiKeyHealthSchema
|
|
16762
|
+
}),
|
|
16763
|
+
gitignore: exports2.GitignoreStatusSchema.optional().default("unknown")
|
|
16764
|
+
});
|
|
16765
|
+
}
|
|
16766
|
+
});
|
|
16767
|
+
|
|
16702
16768
|
// ../types/dist/index.js
|
|
16703
16769
|
var require_dist = __commonJS({
|
|
16704
16770
|
"../types/dist/index.js"(exports2) {
|
|
@@ -16729,6 +16795,7 @@ var require_dist = __commonJS({
|
|
|
16729
16795
|
__exportStar(require_context(), exports2);
|
|
16730
16796
|
__exportStar(require_tasks(), exports2);
|
|
16731
16797
|
__exportStar(require_hook_input(), exports2);
|
|
16798
|
+
__exportStar(require_setup_status(), exports2);
|
|
16732
16799
|
}
|
|
16733
16800
|
});
|
|
16734
16801
|
|
|
@@ -27684,134 +27751,19 @@ var require_runtime_context = __commonJS({
|
|
|
27684
27751
|
}
|
|
27685
27752
|
});
|
|
27686
27753
|
|
|
27687
|
-
// ../sidekick-core/dist/
|
|
27688
|
-
var
|
|
27689
|
-
"../sidekick-core/dist/
|
|
27754
|
+
// ../sidekick-core/dist/project-root.js
|
|
27755
|
+
var require_project_root = __commonJS({
|
|
27756
|
+
"../sidekick-core/dist/project-root.js"(exports2) {
|
|
27690
27757
|
"use strict";
|
|
27691
27758
|
var __importDefault2 = exports2 && exports2.__importDefault || function(mod) {
|
|
27692
27759
|
return mod && mod.__esModule ? mod : { "default": mod };
|
|
27693
27760
|
};
|
|
27694
27761
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
27695
|
-
exports2.
|
|
27696
|
-
var node_fs_1 = require("node:fs");
|
|
27697
|
-
var node_os_1 = require("node:os");
|
|
27762
|
+
exports2.resolveProjectRoot = resolveProjectRoot;
|
|
27698
27763
|
var node_path_1 = __importDefault2(require("node:path"));
|
|
27699
|
-
|
|
27700
|
-
|
|
27701
|
-
|
|
27702
|
-
return (0, node_fs_1.realpathSync)(hookScriptPath);
|
|
27703
|
-
} catch {
|
|
27704
|
-
return node_path_1.default.resolve(hookScriptPath);
|
|
27705
|
-
}
|
|
27706
|
-
}
|
|
27707
|
-
function deriveProjectRootFromHook(hookScriptPath) {
|
|
27708
|
-
const index = hookScriptPath.lastIndexOf(SIDEKICK_HOOK_SEGMENT);
|
|
27709
|
-
if (index === -1) {
|
|
27710
|
-
return void 0;
|
|
27711
|
-
}
|
|
27712
|
-
return hookScriptPath.slice(0, index);
|
|
27713
|
-
}
|
|
27714
|
-
function findNearestSidekickDir(startDir) {
|
|
27715
|
-
let current = node_path_1.default.resolve(startDir);
|
|
27716
|
-
while (true) {
|
|
27717
|
-
const candidate = node_path_1.default.join(current, ".claude", "hooks", "sidekick");
|
|
27718
|
-
if ((0, node_fs_1.existsSync)(candidate)) {
|
|
27719
|
-
return candidate;
|
|
27720
|
-
}
|
|
27721
|
-
const parent = node_path_1.default.dirname(current);
|
|
27722
|
-
if (parent === current) {
|
|
27723
|
-
return void 0;
|
|
27724
|
-
}
|
|
27725
|
-
current = parent;
|
|
27726
|
-
}
|
|
27727
|
-
}
|
|
27728
|
-
function projectHasSidekickInstall(projectDir) {
|
|
27729
|
-
const targets = [
|
|
27730
|
-
node_path_1.default.join(projectDir, ".claude", "settings.json"),
|
|
27731
|
-
node_path_1.default.join(projectDir, ".claude", "settings.json.local")
|
|
27732
|
-
];
|
|
27733
|
-
return targets.some((filePath) => {
|
|
27734
|
-
if (!(0, node_fs_1.existsSync)(filePath)) {
|
|
27735
|
-
return false;
|
|
27736
|
-
}
|
|
27737
|
-
try {
|
|
27738
|
-
const contents = (0, node_fs_1.readFileSync)(filePath, "utf8");
|
|
27739
|
-
return contents.toLowerCase().includes("sidekick");
|
|
27740
|
-
} catch {
|
|
27741
|
-
return false;
|
|
27742
|
-
}
|
|
27743
|
-
});
|
|
27744
|
-
}
|
|
27745
|
-
function normalizeDir(dir) {
|
|
27746
|
-
try {
|
|
27747
|
-
return (0, node_fs_1.realpathSync)(node_path_1.default.resolve(dir));
|
|
27748
|
-
} catch {
|
|
27749
|
-
return node_path_1.default.resolve(dir);
|
|
27750
|
-
}
|
|
27751
|
-
}
|
|
27752
|
-
function resolveScope(input) {
|
|
27753
|
-
const warnings = [];
|
|
27754
|
-
const cwd = input.cwd ? node_path_1.default.resolve(input.cwd) : process.cwd();
|
|
27755
|
-
const hookScriptPath = input.hookScriptPath ? normalizeHookPath(input.hookScriptPath) : void 0;
|
|
27756
|
-
const providedProjectDir = input.projectDir ? node_path_1.default.resolve(input.projectDir) : void 0;
|
|
27757
|
-
const resolvedHomeDir = input.homeDir ? normalizeDir(input.homeDir) : normalizeDir((0, node_os_1.homedir)());
|
|
27758
|
-
if (input.scopeOverride) {
|
|
27759
|
-
return {
|
|
27760
|
-
scope: input.scopeOverride,
|
|
27761
|
-
source: "override",
|
|
27762
|
-
hookScriptPath,
|
|
27763
|
-
projectRoot: input.scopeOverride === "project" ? providedProjectDir : void 0,
|
|
27764
|
-
warnings,
|
|
27765
|
-
dualInstallDetected: false
|
|
27766
|
-
};
|
|
27767
|
-
}
|
|
27768
|
-
if (hookScriptPath) {
|
|
27769
|
-
if (hookScriptPath.startsWith(node_path_1.default.join(resolvedHomeDir, ".claude", "hooks", "sidekick"))) {
|
|
27770
|
-
const dualInstallDetected2 = Boolean(providedProjectDir && projectHasSidekickInstall(providedProjectDir));
|
|
27771
|
-
return {
|
|
27772
|
-
scope: "user",
|
|
27773
|
-
source: "hook-script-path",
|
|
27774
|
-
hookScriptPath,
|
|
27775
|
-
projectRoot: void 0,
|
|
27776
|
-
warnings,
|
|
27777
|
-
dualInstallDetected: dualInstallDetected2
|
|
27778
|
-
};
|
|
27779
|
-
}
|
|
27780
|
-
const projectRoot = deriveProjectRootFromHook(hookScriptPath);
|
|
27781
|
-
if (projectRoot) {
|
|
27782
|
-
if (providedProjectDir && node_path_1.default.resolve(projectRoot) !== providedProjectDir) {
|
|
27783
|
-
warnings.push("Project directory hint from --project-dir does not match path derived from --hook-script-path. Using hook-script-path.");
|
|
27784
|
-
}
|
|
27785
|
-
return {
|
|
27786
|
-
scope: "project",
|
|
27787
|
-
source: "hook-script-path",
|
|
27788
|
-
hookScriptPath,
|
|
27789
|
-
projectRoot,
|
|
27790
|
-
warnings,
|
|
27791
|
-
dualInstallDetected: false
|
|
27792
|
-
};
|
|
27793
|
-
}
|
|
27794
|
-
}
|
|
27795
|
-
const sidekickDir = findNearestSidekickDir(cwd);
|
|
27796
|
-
if (sidekickDir && !sidekickDir.startsWith(node_path_1.default.join(resolvedHomeDir, ".claude", "hooks", "sidekick"))) {
|
|
27797
|
-
return {
|
|
27798
|
-
scope: "project",
|
|
27799
|
-
source: "cwd-fallback",
|
|
27800
|
-
hookScriptPath,
|
|
27801
|
-
projectRoot: node_path_1.default.resolve(sidekickDir, "..", "..", ".."),
|
|
27802
|
-
warnings,
|
|
27803
|
-
dualInstallDetected: false
|
|
27804
|
-
};
|
|
27805
|
-
}
|
|
27806
|
-
const dualInstallDetected = Boolean(providedProjectDir && projectHasSidekickInstall(providedProjectDir));
|
|
27807
|
-
return {
|
|
27808
|
-
scope: "user",
|
|
27809
|
-
source: "default",
|
|
27810
|
-
hookScriptPath,
|
|
27811
|
-
projectRoot: void 0,
|
|
27812
|
-
warnings,
|
|
27813
|
-
dualInstallDetected
|
|
27814
|
-
};
|
|
27764
|
+
function resolveProjectRoot(input) {
|
|
27765
|
+
const projectRoot = input.projectDir ? node_path_1.default.resolve(input.projectDir) : void 0;
|
|
27766
|
+
return { projectRoot };
|
|
27815
27767
|
}
|
|
27816
27768
|
}
|
|
27817
27769
|
});
|
|
@@ -32460,7 +32412,6 @@ var require_structured_logging = __commonJS({
|
|
|
32460
32412
|
source: "cli",
|
|
32461
32413
|
context: {
|
|
32462
32414
|
sessionId: context.sessionId,
|
|
32463
|
-
scope: context.scope,
|
|
32464
32415
|
correlationId: context.correlationId,
|
|
32465
32416
|
traceId: context.traceId,
|
|
32466
32417
|
hook: context.hook
|
|
@@ -32480,7 +32431,6 @@ var require_structured_logging = __commonJS({
|
|
|
32480
32431
|
source: "cli",
|
|
32481
32432
|
context: {
|
|
32482
32433
|
sessionId: context.sessionId,
|
|
32483
|
-
scope: context.scope,
|
|
32484
32434
|
correlationId: context.correlationId,
|
|
32485
32435
|
traceId: context.traceId,
|
|
32486
32436
|
hook: context.hook
|
|
@@ -32502,7 +32452,6 @@ var require_structured_logging = __commonJS({
|
|
|
32502
32452
|
source: "daemon",
|
|
32503
32453
|
context: {
|
|
32504
32454
|
sessionId: context.sessionId,
|
|
32505
|
-
scope: context.scope,
|
|
32506
32455
|
correlationId: context.correlationId,
|
|
32507
32456
|
traceId: context.traceId,
|
|
32508
32457
|
hook: context.hook,
|
|
@@ -32524,7 +32473,6 @@ var require_structured_logging = __commonJS({
|
|
|
32524
32473
|
source: "daemon",
|
|
32525
32474
|
context: {
|
|
32526
32475
|
sessionId: context.sessionId,
|
|
32527
|
-
scope: context.scope,
|
|
32528
32476
|
correlationId: context.correlationId,
|
|
32529
32477
|
traceId: context.traceId,
|
|
32530
32478
|
hook: context.hook,
|
|
@@ -32546,7 +32494,6 @@ var require_structured_logging = __commonJS({
|
|
|
32546
32494
|
source: "daemon",
|
|
32547
32495
|
context: {
|
|
32548
32496
|
sessionId: context.sessionId,
|
|
32549
|
-
scope: context.scope,
|
|
32550
32497
|
correlationId: context.correlationId,
|
|
32551
32498
|
traceId: context.traceId,
|
|
32552
32499
|
hook: context.hook,
|
|
@@ -32568,8 +32515,7 @@ var require_structured_logging = __commonJS({
|
|
|
32568
32515
|
time: Date.now(),
|
|
32569
32516
|
source: "daemon",
|
|
32570
32517
|
context: {
|
|
32571
|
-
sessionId: ""
|
|
32572
|
-
scope: "project"
|
|
32518
|
+
sessionId: ""
|
|
32573
32519
|
},
|
|
32574
32520
|
payload: {
|
|
32575
32521
|
metadata
|
|
@@ -32585,8 +32531,7 @@ var require_structured_logging = __commonJS({
|
|
|
32585
32531
|
time: Date.now(),
|
|
32586
32532
|
source: "daemon",
|
|
32587
32533
|
context: {
|
|
32588
|
-
sessionId: ""
|
|
32589
|
-
scope: "project"
|
|
32534
|
+
sessionId: ""
|
|
32590
32535
|
},
|
|
32591
32536
|
payload: {
|
|
32592
32537
|
metadata
|
|
@@ -32602,8 +32547,7 @@ var require_structured_logging = __commonJS({
|
|
|
32602
32547
|
time: Date.now(),
|
|
32603
32548
|
source: "daemon",
|
|
32604
32549
|
context: {
|
|
32605
|
-
sessionId: ""
|
|
32606
|
-
scope: "project"
|
|
32550
|
+
sessionId: ""
|
|
32607
32551
|
},
|
|
32608
32552
|
payload: {
|
|
32609
32553
|
metadata
|
|
@@ -32619,8 +32563,7 @@ var require_structured_logging = __commonJS({
|
|
|
32619
32563
|
time: Date.now(),
|
|
32620
32564
|
source: "daemon",
|
|
32621
32565
|
context: {
|
|
32622
|
-
sessionId: ""
|
|
32623
|
-
scope: "project"
|
|
32566
|
+
sessionId: ""
|
|
32624
32567
|
},
|
|
32625
32568
|
payload: {
|
|
32626
32569
|
metadata
|
|
@@ -32636,8 +32579,7 @@ var require_structured_logging = __commonJS({
|
|
|
32636
32579
|
time: Date.now(),
|
|
32637
32580
|
source: "daemon",
|
|
32638
32581
|
context: {
|
|
32639
|
-
sessionId: ""
|
|
32640
|
-
scope: "project"
|
|
32582
|
+
sessionId: ""
|
|
32641
32583
|
},
|
|
32642
32584
|
payload: {
|
|
32643
32585
|
metadata
|
|
@@ -32656,7 +32598,6 @@ var require_structured_logging = __commonJS({
|
|
|
32656
32598
|
source: "cli",
|
|
32657
32599
|
context: {
|
|
32658
32600
|
sessionId: context.sessionId,
|
|
32659
|
-
scope: context.scope,
|
|
32660
32601
|
correlationId: context.correlationId,
|
|
32661
32602
|
traceId: context.traceId,
|
|
32662
32603
|
hook: context.hook,
|
|
@@ -32679,7 +32620,6 @@ var require_structured_logging = __commonJS({
|
|
|
32679
32620
|
source: "cli",
|
|
32680
32621
|
context: {
|
|
32681
32622
|
sessionId: context.sessionId,
|
|
32682
|
-
scope: context.scope,
|
|
32683
32623
|
correlationId: context.correlationId,
|
|
32684
32624
|
traceId: context.traceId,
|
|
32685
32625
|
hook: context.hook,
|
|
@@ -32703,7 +32643,6 @@ var require_structured_logging = __commonJS({
|
|
|
32703
32643
|
source: "daemon",
|
|
32704
32644
|
context: {
|
|
32705
32645
|
sessionId: context.sessionId,
|
|
32706
|
-
scope: context.scope,
|
|
32707
32646
|
correlationId: context.correlationId,
|
|
32708
32647
|
traceId: context.traceId,
|
|
32709
32648
|
hook: context.hook,
|
|
@@ -32726,7 +32665,6 @@ var require_structured_logging = __commonJS({
|
|
|
32726
32665
|
source: "daemon",
|
|
32727
32666
|
context: {
|
|
32728
32667
|
sessionId: context.sessionId,
|
|
32729
|
-
scope: context.scope,
|
|
32730
32668
|
correlationId: context.correlationId,
|
|
32731
32669
|
traceId: context.traceId,
|
|
32732
32670
|
hook: context.hook,
|
|
@@ -32749,7 +32687,6 @@ var require_structured_logging = __commonJS({
|
|
|
32749
32687
|
source: "daemon",
|
|
32750
32688
|
context: {
|
|
32751
32689
|
sessionId: context.sessionId,
|
|
32752
|
-
scope: context.scope,
|
|
32753
32690
|
correlationId: context.correlationId,
|
|
32754
32691
|
traceId: context.traceId,
|
|
32755
32692
|
hook: context.hook,
|
|
@@ -32773,7 +32710,6 @@ var require_structured_logging = __commonJS({
|
|
|
32773
32710
|
source: "transcript",
|
|
32774
32711
|
context: {
|
|
32775
32712
|
sessionId: context.sessionId,
|
|
32776
|
-
scope: context.scope,
|
|
32777
32713
|
correlationId: context.correlationId,
|
|
32778
32714
|
traceId: context.traceId,
|
|
32779
32715
|
hook: context.hook,
|
|
@@ -32796,7 +32732,6 @@ var require_structured_logging = __commonJS({
|
|
|
32796
32732
|
source: "transcript",
|
|
32797
32733
|
context: {
|
|
32798
32734
|
sessionId: context.sessionId,
|
|
32799
|
-
scope: context.scope,
|
|
32800
32735
|
correlationId: context.correlationId,
|
|
32801
32736
|
traceId: context.traceId,
|
|
32802
32737
|
hook: context.hook,
|
|
@@ -32854,7 +32789,10 @@ var require_package3 = __commonJS({
|
|
|
32854
32789
|
lint: "eslint packages",
|
|
32855
32790
|
"lint:fix": "eslint packages --fix",
|
|
32856
32791
|
format: 'prettier --write "packages/**/*.ts"',
|
|
32857
|
-
sidekick: "node packages/sidekick-cli/dist/bin.js"
|
|
32792
|
+
sidekick: "node packages/sidekick-cli/dist/bin.js",
|
|
32793
|
+
"test:dist:setup": "./scripts/test-dist.sh setup",
|
|
32794
|
+
"test:dist:teardown": "./scripts/test-dist.sh teardown",
|
|
32795
|
+
"test:dist:rebuild": "./scripts/test-dist.sh rebuild"
|
|
32858
32796
|
},
|
|
32859
32797
|
devDependencies: {
|
|
32860
32798
|
"@eslint/js": "^9.39.1",
|
|
@@ -32917,15 +32855,7 @@ var require_daemon_client2 = __commonJS({
|
|
|
32917
32855
|
await this.waitForShutdown();
|
|
32918
32856
|
}
|
|
32919
32857
|
this.logger.info("Starting daemon...");
|
|
32920
|
-
|
|
32921
|
-
try {
|
|
32922
|
-
const pkgPath = require.resolve("@sidekick/daemon/package.json");
|
|
32923
|
-
const pkg = require(pkgPath);
|
|
32924
|
-
const binPath = pkg.bin ? typeof pkg.bin === "string" ? pkg.bin : pkg.bin["sidekickd"] : pkg.main;
|
|
32925
|
-
daemonPath = path_1.default.resolve(path_1.default.dirname(pkgPath), binPath ?? "dist/index.js");
|
|
32926
|
-
} catch {
|
|
32927
|
-
daemonPath = path_1.default.resolve(__dirname, "../../sidekick-daemon/dist/index.js");
|
|
32928
|
-
}
|
|
32858
|
+
const daemonPath = await this.resolveDaemonPath();
|
|
32929
32859
|
const child = (0, child_process_1.spawn)("node", [daemonPath, this.projectDir], {
|
|
32930
32860
|
detached: true,
|
|
32931
32861
|
stdio: "ignore",
|
|
@@ -33004,6 +32934,33 @@ var require_daemon_client2 = __commonJS({
|
|
|
33004
32934
|
} catch {
|
|
33005
32935
|
}
|
|
33006
32936
|
}
|
|
32937
|
+
/**
|
|
32938
|
+
* Resolve the daemon entry point path.
|
|
32939
|
+
* Checks in order:
|
|
32940
|
+
* 1. Bundled context: daemon.js as sibling file (npm distribution)
|
|
32941
|
+
* 2. Dev mode: workspace package resolution
|
|
32942
|
+
*/
|
|
32943
|
+
async resolveDaemonPath() {
|
|
32944
|
+
const bundledPath = path_1.default.resolve(__dirname, "daemon.js");
|
|
32945
|
+
try {
|
|
32946
|
+
await promises_12.default.access(bundledPath);
|
|
32947
|
+
this.logger.debug("Using bundled daemon", { path: bundledPath });
|
|
32948
|
+
return bundledPath;
|
|
32949
|
+
} catch {
|
|
32950
|
+
}
|
|
32951
|
+
try {
|
|
32952
|
+
const pkgPath = require.resolve("@sidekick/daemon/package.json");
|
|
32953
|
+
const pkg = require(pkgPath);
|
|
32954
|
+
const binPath = pkg.bin ? typeof pkg.bin === "string" ? pkg.bin : pkg.bin["sidekickd"] : pkg.main;
|
|
32955
|
+
const daemonPath = path_1.default.resolve(path_1.default.dirname(pkgPath), binPath ?? "dist/index.js");
|
|
32956
|
+
this.logger.debug("Using workspace daemon", { path: daemonPath });
|
|
32957
|
+
return daemonPath;
|
|
32958
|
+
} catch {
|
|
32959
|
+
const fallbackPath = path_1.default.resolve(__dirname, "../../sidekick-daemon/dist/index.js");
|
|
32960
|
+
this.logger.debug("Using fallback daemon path", { path: fallbackPath });
|
|
32961
|
+
return fallbackPath;
|
|
32962
|
+
}
|
|
32963
|
+
}
|
|
33007
32964
|
/**
|
|
33008
32965
|
* Request daemon shutdown (fire-and-forget).
|
|
33009
32966
|
* Sends shutdown request, receives ack, closes connection immediately.
|
|
@@ -33245,6 +33202,346 @@ var require_daemon_client2 = __commonJS({
|
|
|
33245
33202
|
}
|
|
33246
33203
|
});
|
|
33247
33204
|
|
|
33205
|
+
// ../sidekick-core/dist/setup-status-service.js
|
|
33206
|
+
var require_setup_status_service = __commonJS({
|
|
33207
|
+
"../sidekick-core/dist/setup-status-service.js"(exports2) {
|
|
33208
|
+
"use strict";
|
|
33209
|
+
var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) {
|
|
33210
|
+
if (k2 === void 0) k2 = k;
|
|
33211
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
33212
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
33213
|
+
desc = { enumerable: true, get: function() {
|
|
33214
|
+
return m[k];
|
|
33215
|
+
} };
|
|
33216
|
+
}
|
|
33217
|
+
Object.defineProperty(o, k2, desc);
|
|
33218
|
+
} : function(o, m, k, k2) {
|
|
33219
|
+
if (k2 === void 0) k2 = k;
|
|
33220
|
+
o[k2] = m[k];
|
|
33221
|
+
});
|
|
33222
|
+
var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) {
|
|
33223
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
33224
|
+
} : function(o, v) {
|
|
33225
|
+
o["default"] = v;
|
|
33226
|
+
});
|
|
33227
|
+
var __importStar = exports2 && exports2.__importStar || /* @__PURE__ */ function() {
|
|
33228
|
+
var ownKeys = function(o) {
|
|
33229
|
+
ownKeys = Object.getOwnPropertyNames || function(o2) {
|
|
33230
|
+
var ar = [];
|
|
33231
|
+
for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
|
|
33232
|
+
return ar;
|
|
33233
|
+
};
|
|
33234
|
+
return ownKeys(o);
|
|
33235
|
+
};
|
|
33236
|
+
return function(mod) {
|
|
33237
|
+
if (mod && mod.__esModule) return mod;
|
|
33238
|
+
var result = {};
|
|
33239
|
+
if (mod != null) {
|
|
33240
|
+
for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
33241
|
+
}
|
|
33242
|
+
__setModuleDefault(result, mod);
|
|
33243
|
+
return result;
|
|
33244
|
+
};
|
|
33245
|
+
}();
|
|
33246
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
33247
|
+
exports2.SetupStatusService = void 0;
|
|
33248
|
+
exports2.createSetupStatusService = createSetupStatusService;
|
|
33249
|
+
var fs = __importStar(require("node:fs/promises"));
|
|
33250
|
+
var path = __importStar(require("node:path"));
|
|
33251
|
+
var os = __importStar(require("node:os"));
|
|
33252
|
+
var types_1 = require_dist();
|
|
33253
|
+
var SetupStatusService = class {
|
|
33254
|
+
constructor(projectDir, options) {
|
|
33255
|
+
this.projectDir = projectDir;
|
|
33256
|
+
this.homeDir = options?.homeDir ?? os.homedir();
|
|
33257
|
+
this.logger = options?.logger;
|
|
33258
|
+
}
|
|
33259
|
+
// === Paths ===
|
|
33260
|
+
get userStatusPath() {
|
|
33261
|
+
return path.join(this.homeDir, ".sidekick", "setup-status.json");
|
|
33262
|
+
}
|
|
33263
|
+
get projectStatusPath() {
|
|
33264
|
+
return path.join(this.projectDir, ".sidekick", "setup-status.json");
|
|
33265
|
+
}
|
|
33266
|
+
// === Low-level read/write ===
|
|
33267
|
+
async getUserStatus() {
|
|
33268
|
+
try {
|
|
33269
|
+
const content = await fs.readFile(this.userStatusPath, "utf-8");
|
|
33270
|
+
const parsed = types_1.UserSetupStatusSchema.safeParse(JSON.parse(content));
|
|
33271
|
+
if (!parsed.success) {
|
|
33272
|
+
this.logger?.warn("Invalid user setup status", { error: parsed.error });
|
|
33273
|
+
return null;
|
|
33274
|
+
}
|
|
33275
|
+
return parsed.data;
|
|
33276
|
+
} catch (err) {
|
|
33277
|
+
if (err.code === "ENOENT") {
|
|
33278
|
+
return null;
|
|
33279
|
+
}
|
|
33280
|
+
throw err;
|
|
33281
|
+
}
|
|
33282
|
+
}
|
|
33283
|
+
async getProjectStatus() {
|
|
33284
|
+
try {
|
|
33285
|
+
const content = await fs.readFile(this.projectStatusPath, "utf-8");
|
|
33286
|
+
const parsed = types_1.ProjectSetupStatusSchema.safeParse(JSON.parse(content));
|
|
33287
|
+
if (!parsed.success) {
|
|
33288
|
+
this.logger?.warn("Invalid project setup status", { error: parsed.error });
|
|
33289
|
+
return null;
|
|
33290
|
+
}
|
|
33291
|
+
return parsed.data;
|
|
33292
|
+
} catch (err) {
|
|
33293
|
+
if (err.code === "ENOENT") {
|
|
33294
|
+
return null;
|
|
33295
|
+
}
|
|
33296
|
+
throw err;
|
|
33297
|
+
}
|
|
33298
|
+
}
|
|
33299
|
+
async writeUserStatus(status) {
|
|
33300
|
+
const validated = types_1.UserSetupStatusSchema.parse(status);
|
|
33301
|
+
const dir = path.dirname(this.userStatusPath);
|
|
33302
|
+
await fs.mkdir(dir, { recursive: true });
|
|
33303
|
+
await fs.writeFile(this.userStatusPath, JSON.stringify(validated, null, 2) + "\n");
|
|
33304
|
+
this.logger?.debug("User setup status written", { path: this.userStatusPath });
|
|
33305
|
+
}
|
|
33306
|
+
async writeProjectStatus(status) {
|
|
33307
|
+
const validated = types_1.ProjectSetupStatusSchema.parse(status);
|
|
33308
|
+
const dir = path.dirname(this.projectStatusPath);
|
|
33309
|
+
await fs.mkdir(dir, { recursive: true });
|
|
33310
|
+
await fs.writeFile(this.projectStatusPath, JSON.stringify(validated, null, 2) + "\n");
|
|
33311
|
+
this.logger?.debug("Project setup status written", { path: this.projectStatusPath });
|
|
33312
|
+
}
|
|
33313
|
+
async updateUserStatus(updates) {
|
|
33314
|
+
const current = await this.getUserStatus();
|
|
33315
|
+
if (!current) {
|
|
33316
|
+
throw new Error("Cannot update user status: no existing status found");
|
|
33317
|
+
}
|
|
33318
|
+
const updated = {
|
|
33319
|
+
...current,
|
|
33320
|
+
...updates,
|
|
33321
|
+
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
33322
|
+
};
|
|
33323
|
+
await this.writeUserStatus(updated);
|
|
33324
|
+
}
|
|
33325
|
+
async updateProjectStatus(updates) {
|
|
33326
|
+
const current = await this.getProjectStatus();
|
|
33327
|
+
if (!current) {
|
|
33328
|
+
throw new Error("Cannot update project status: no existing status found");
|
|
33329
|
+
}
|
|
33330
|
+
const updated = {
|
|
33331
|
+
...current,
|
|
33332
|
+
...updates,
|
|
33333
|
+
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
33334
|
+
};
|
|
33335
|
+
await this.writeProjectStatus(updated);
|
|
33336
|
+
}
|
|
33337
|
+
// === Merged getters ===
|
|
33338
|
+
async getStatuslineHealth() {
|
|
33339
|
+
const project = await this.getProjectStatus();
|
|
33340
|
+
if (project?.statusline === "configured")
|
|
33341
|
+
return "configured";
|
|
33342
|
+
if (project?.statusline === "skipped")
|
|
33343
|
+
return "skipped";
|
|
33344
|
+
if (project?.statusline === "user") {
|
|
33345
|
+
const user2 = await this.getUserStatus();
|
|
33346
|
+
return user2?.statusline ?? "not-setup";
|
|
33347
|
+
}
|
|
33348
|
+
const user = await this.getUserStatus();
|
|
33349
|
+
return user?.statusline ?? "not-setup";
|
|
33350
|
+
}
|
|
33351
|
+
async getApiKeyHealth(key) {
|
|
33352
|
+
const project = await this.getProjectStatus();
|
|
33353
|
+
const projectHealth = project?.apiKeys[key];
|
|
33354
|
+
if (projectHealth && projectHealth !== "user") {
|
|
33355
|
+
return projectHealth;
|
|
33356
|
+
}
|
|
33357
|
+
const user = await this.getUserStatus();
|
|
33358
|
+
return user?.apiKeys[key] ?? "missing";
|
|
33359
|
+
}
|
|
33360
|
+
async getEffectiveApiKeyHealth(key) {
|
|
33361
|
+
const health = await this.getApiKeyHealth(key);
|
|
33362
|
+
return health === "user" ? "missing" : health;
|
|
33363
|
+
}
|
|
33364
|
+
async isHealthy() {
|
|
33365
|
+
const statusline = await this.getStatuslineHealth();
|
|
33366
|
+
const openrouterKey = await this.getEffectiveApiKeyHealth("OPENROUTER_API_KEY");
|
|
33367
|
+
return statusline === "configured" && (openrouterKey === "healthy" || openrouterKey === "not-required");
|
|
33368
|
+
}
|
|
33369
|
+
// === Auto-config helpers ===
|
|
33370
|
+
async isUserSetupComplete() {
|
|
33371
|
+
const user = await this.getUserStatus();
|
|
33372
|
+
return user !== null;
|
|
33373
|
+
}
|
|
33374
|
+
async isProjectConfigured() {
|
|
33375
|
+
const project = await this.getProjectStatus();
|
|
33376
|
+
return project !== null;
|
|
33377
|
+
}
|
|
33378
|
+
async shouldAutoConfigureProject() {
|
|
33379
|
+
const user = await this.getUserStatus();
|
|
33380
|
+
if (!user?.preferences.autoConfigureProjects) {
|
|
33381
|
+
return false;
|
|
33382
|
+
}
|
|
33383
|
+
return !await this.isProjectConfigured();
|
|
33384
|
+
}
|
|
33385
|
+
async setApiKeyHealth(key, health, scope) {
|
|
33386
|
+
if (scope === "user") {
|
|
33387
|
+
const current = await this.getUserStatus();
|
|
33388
|
+
if (!current) {
|
|
33389
|
+
throw new Error("Cannot update API key health: no user status found");
|
|
33390
|
+
}
|
|
33391
|
+
await this.updateUserStatus({
|
|
33392
|
+
apiKeys: { ...current.apiKeys, [key]: health }
|
|
33393
|
+
});
|
|
33394
|
+
} else {
|
|
33395
|
+
const current = await this.getProjectStatus();
|
|
33396
|
+
if (!current) {
|
|
33397
|
+
throw new Error("Cannot update API key health: no project status found");
|
|
33398
|
+
}
|
|
33399
|
+
await this.updateProjectStatus({
|
|
33400
|
+
apiKeys: { ...current.apiKeys, [key]: health }
|
|
33401
|
+
});
|
|
33402
|
+
}
|
|
33403
|
+
}
|
|
33404
|
+
// === Backward compatibility (for statusline service) ===
|
|
33405
|
+
/**
|
|
33406
|
+
* Get the overall setup state for statusline display.
|
|
33407
|
+
*
|
|
33408
|
+
* - `not-run` - Setup has never been run
|
|
33409
|
+
* - `partial` - User setup done, project not configured
|
|
33410
|
+
* - `healthy` - All configured and working
|
|
33411
|
+
* - `unhealthy` - Setup exists but has issues (invalid keys, etc)
|
|
33412
|
+
*/
|
|
33413
|
+
async getSetupState() {
|
|
33414
|
+
const userStatus = await this.getUserStatus();
|
|
33415
|
+
const projectStatus = await this.getProjectStatus();
|
|
33416
|
+
if (!userStatus) {
|
|
33417
|
+
return "not-run";
|
|
33418
|
+
}
|
|
33419
|
+
if (!projectStatus) {
|
|
33420
|
+
return "partial";
|
|
33421
|
+
}
|
|
33422
|
+
const isHealthy = await this.isHealthy();
|
|
33423
|
+
return isHealthy ? "healthy" : "unhealthy";
|
|
33424
|
+
}
|
|
33425
|
+
};
|
|
33426
|
+
exports2.SetupStatusService = SetupStatusService;
|
|
33427
|
+
function createSetupStatusService(projectDir, homeDir) {
|
|
33428
|
+
return new SetupStatusService(projectDir, { homeDir });
|
|
33429
|
+
}
|
|
33430
|
+
}
|
|
33431
|
+
});
|
|
33432
|
+
|
|
33433
|
+
// ../sidekick-core/dist/gitignore.js
|
|
33434
|
+
var require_gitignore = __commonJS({
|
|
33435
|
+
"../sidekick-core/dist/gitignore.js"(exports2) {
|
|
33436
|
+
"use strict";
|
|
33437
|
+
var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) {
|
|
33438
|
+
if (k2 === void 0) k2 = k;
|
|
33439
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
33440
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
33441
|
+
desc = { enumerable: true, get: function() {
|
|
33442
|
+
return m[k];
|
|
33443
|
+
} };
|
|
33444
|
+
}
|
|
33445
|
+
Object.defineProperty(o, k2, desc);
|
|
33446
|
+
} : function(o, m, k, k2) {
|
|
33447
|
+
if (k2 === void 0) k2 = k;
|
|
33448
|
+
o[k2] = m[k];
|
|
33449
|
+
});
|
|
33450
|
+
var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) {
|
|
33451
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
33452
|
+
} : function(o, v) {
|
|
33453
|
+
o["default"] = v;
|
|
33454
|
+
});
|
|
33455
|
+
var __importStar = exports2 && exports2.__importStar || /* @__PURE__ */ function() {
|
|
33456
|
+
var ownKeys = function(o) {
|
|
33457
|
+
ownKeys = Object.getOwnPropertyNames || function(o2) {
|
|
33458
|
+
var ar = [];
|
|
33459
|
+
for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
|
|
33460
|
+
return ar;
|
|
33461
|
+
};
|
|
33462
|
+
return ownKeys(o);
|
|
33463
|
+
};
|
|
33464
|
+
return function(mod) {
|
|
33465
|
+
if (mod && mod.__esModule) return mod;
|
|
33466
|
+
var result = {};
|
|
33467
|
+
if (mod != null) {
|
|
33468
|
+
for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
33469
|
+
}
|
|
33470
|
+
__setModuleDefault(result, mod);
|
|
33471
|
+
return result;
|
|
33472
|
+
};
|
|
33473
|
+
}();
|
|
33474
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
33475
|
+
exports2.GITIGNORE_ENTRIES = exports2.SIDEKICK_SECTION_END = exports2.SIDEKICK_SECTION_START = void 0;
|
|
33476
|
+
exports2.installGitignoreSection = installGitignoreSection;
|
|
33477
|
+
exports2.removeGitignoreSection = removeGitignoreSection;
|
|
33478
|
+
exports2.detectGitignoreStatus = detectGitignoreStatus;
|
|
33479
|
+
var fs = __importStar(require("node:fs/promises"));
|
|
33480
|
+
var path = __importStar(require("node:path"));
|
|
33481
|
+
exports2.SIDEKICK_SECTION_START = "# >>> sidekick";
|
|
33482
|
+
exports2.SIDEKICK_SECTION_END = "# <<< sidekick";
|
|
33483
|
+
exports2.GITIGNORE_ENTRIES = [
|
|
33484
|
+
".sidekick/logs/",
|
|
33485
|
+
".sidekick/sessions/",
|
|
33486
|
+
".sidekick/state/",
|
|
33487
|
+
".sidekick/.env",
|
|
33488
|
+
".sidekick/.env.local"
|
|
33489
|
+
];
|
|
33490
|
+
async function installGitignoreSection(projectDir) {
|
|
33491
|
+
const gitignorePath = path.join(projectDir, ".gitignore");
|
|
33492
|
+
let content = "";
|
|
33493
|
+
try {
|
|
33494
|
+
content = await fs.readFile(gitignorePath, "utf-8");
|
|
33495
|
+
} catch (err) {
|
|
33496
|
+
if (err.code !== "ENOENT") {
|
|
33497
|
+
return { status: "error", error: `Failed to read .gitignore: ${err.message}` };
|
|
33498
|
+
}
|
|
33499
|
+
}
|
|
33500
|
+
if (content.includes(exports2.SIDEKICK_SECTION_START)) {
|
|
33501
|
+
return { status: "already-installed" };
|
|
33502
|
+
}
|
|
33503
|
+
const section = ["", exports2.SIDEKICK_SECTION_START, ...exports2.GITIGNORE_ENTRIES, exports2.SIDEKICK_SECTION_END].join("\n");
|
|
33504
|
+
const newContent = content.trimEnd() + section + "\n";
|
|
33505
|
+
try {
|
|
33506
|
+
await fs.writeFile(gitignorePath, newContent);
|
|
33507
|
+
return { status: "installed", entriesAdded: exports2.GITIGNORE_ENTRIES };
|
|
33508
|
+
} catch (err) {
|
|
33509
|
+
return { status: "error", error: `Failed to write .gitignore: ${err.message}` };
|
|
33510
|
+
}
|
|
33511
|
+
}
|
|
33512
|
+
async function removeGitignoreSection(projectDir) {
|
|
33513
|
+
const gitignorePath = path.join(projectDir, ".gitignore");
|
|
33514
|
+
try {
|
|
33515
|
+
const content = await fs.readFile(gitignorePath, "utf-8");
|
|
33516
|
+
const startIdx = content.indexOf(exports2.SIDEKICK_SECTION_START);
|
|
33517
|
+
const endIdx = content.indexOf(exports2.SIDEKICK_SECTION_END);
|
|
33518
|
+
if (startIdx === -1 || endIdx === -1 || endIdx < startIdx) {
|
|
33519
|
+
return false;
|
|
33520
|
+
}
|
|
33521
|
+
const lineStartIdx = content.lastIndexOf("\n", startIdx - 1) + 1;
|
|
33522
|
+
const lineEndIdx = content.indexOf("\n", endIdx);
|
|
33523
|
+
const actualEndIdx = lineEndIdx === -1 ? content.length : lineEndIdx + 1;
|
|
33524
|
+
const before = content.slice(0, lineStartIdx).trimEnd();
|
|
33525
|
+
const after = content.slice(actualEndIdx).trimStart();
|
|
33526
|
+
const newContent = before + (after ? "\n" + after : "") + "\n";
|
|
33527
|
+
await fs.writeFile(gitignorePath, newContent);
|
|
33528
|
+
return true;
|
|
33529
|
+
} catch {
|
|
33530
|
+
return false;
|
|
33531
|
+
}
|
|
33532
|
+
}
|
|
33533
|
+
async function detectGitignoreStatus(projectDir) {
|
|
33534
|
+
const gitignorePath = path.join(projectDir, ".gitignore");
|
|
33535
|
+
try {
|
|
33536
|
+
const content = await fs.readFile(gitignorePath, "utf-8");
|
|
33537
|
+
return content.includes(exports2.SIDEKICK_SECTION_START) ? "installed" : "missing";
|
|
33538
|
+
} catch {
|
|
33539
|
+
return "missing";
|
|
33540
|
+
}
|
|
33541
|
+
}
|
|
33542
|
+
}
|
|
33543
|
+
});
|
|
33544
|
+
|
|
33248
33545
|
// ../sidekick-core/dist/state/errors.js
|
|
33249
33546
|
var require_errors4 = __commonJS({
|
|
33250
33547
|
"../sidekick-core/dist/state/errors.js"(exports2) {
|
|
@@ -33395,7 +33692,6 @@ var require_staging_service = __commonJS({
|
|
|
33395
33692
|
await this.options.stateService.write(reminderPath, data, types_1.StagedReminderSchema);
|
|
33396
33693
|
const event = structured_logging_1.LogEvents.reminderStaged({
|
|
33397
33694
|
sessionId,
|
|
33398
|
-
scope: this.options.scope,
|
|
33399
33695
|
hook: hookName
|
|
33400
33696
|
}, {
|
|
33401
33697
|
reminderName: data.name,
|
|
@@ -33541,10 +33837,9 @@ var require_staging_service = __commonJS({
|
|
|
33541
33837
|
};
|
|
33542
33838
|
exports2.StagingServiceCore = StagingServiceCore;
|
|
33543
33839
|
var SessionScopedStagingService = class {
|
|
33544
|
-
constructor(core, sessionId
|
|
33840
|
+
constructor(core, sessionId) {
|
|
33545
33841
|
this.core = core;
|
|
33546
33842
|
this.sessionId = sessionId;
|
|
33547
|
-
this.scope = scope;
|
|
33548
33843
|
}
|
|
33549
33844
|
// ============================================================================
|
|
33550
33845
|
// StagingService Interface Implementation (delegates to core)
|
|
@@ -33585,12 +33880,6 @@ var require_staging_service = __commonJS({
|
|
|
33585
33880
|
getSessionId() {
|
|
33586
33881
|
return this.sessionId;
|
|
33587
33882
|
}
|
|
33588
|
-
/**
|
|
33589
|
-
* Get the scope (for testing/debugging).
|
|
33590
|
-
*/
|
|
33591
|
-
getScope() {
|
|
33592
|
-
return this.scope;
|
|
33593
|
-
}
|
|
33594
33883
|
};
|
|
33595
33884
|
exports2.SessionScopedStagingService = SessionScopedStagingService;
|
|
33596
33885
|
}
|
|
@@ -33685,8 +33974,7 @@ var require_handler_registry2 = __commonJS({
|
|
|
33685
33974
|
this.handlers = [];
|
|
33686
33975
|
this.context = {
|
|
33687
33976
|
sessionId: options.sessionId,
|
|
33688
|
-
transcriptPath: options.transcriptPath
|
|
33689
|
-
scope: options.scope
|
|
33977
|
+
transcriptPath: options.transcriptPath
|
|
33690
33978
|
};
|
|
33691
33979
|
}
|
|
33692
33980
|
/**
|
|
@@ -33802,7 +34090,7 @@ var require_handler_registry2 = __commonJS({
|
|
|
33802
34090
|
const event = this.buildTranscriptEvent(eventType, entry, lineNumber, isBulkProcessing);
|
|
33803
34091
|
const metrics = this.options.getMetrics?.();
|
|
33804
34092
|
if (metrics) {
|
|
33805
|
-
(0, structured_logging_js_1.logEvent)(this.options.logger, structured_logging_js_1.LogEvents.transcriptEventEmitted({ sessionId: this.options.sessionId
|
|
34093
|
+
(0, structured_logging_js_1.logEvent)(this.options.logger, structured_logging_js_1.LogEvents.transcriptEventEmitted({ sessionId: this.options.sessionId }, {
|
|
33806
34094
|
eventType,
|
|
33807
34095
|
lineNumber,
|
|
33808
34096
|
uuid: entry.uuid,
|
|
@@ -33828,8 +34116,7 @@ var require_handler_registry2 = __commonJS({
|
|
|
33828
34116
|
async invokeTranscriptHandler(handler, event) {
|
|
33829
34117
|
const startTime = Date.now();
|
|
33830
34118
|
const logContext = {
|
|
33831
|
-
sessionId: this.options.sessionId
|
|
33832
|
-
scope: this.options.scope
|
|
34119
|
+
sessionId: this.options.sessionId
|
|
33833
34120
|
};
|
|
33834
34121
|
try {
|
|
33835
34122
|
await handler.handler(event, this.context);
|
|
@@ -33875,8 +34162,7 @@ var require_handler_registry2 = __commonJS({
|
|
|
33875
34162
|
buildTranscriptEvent(eventType, entry, lineNumber, isBulkProcessing = false) {
|
|
33876
34163
|
const context = {
|
|
33877
34164
|
sessionId: this.options.sessionId,
|
|
33878
|
-
timestamp: Date.now()
|
|
33879
|
-
scope: this.options.scope
|
|
34165
|
+
timestamp: Date.now()
|
|
33880
34166
|
};
|
|
33881
34167
|
const metrics = this.options.getMetrics?.() ?? this.createEmptyMetrics();
|
|
33882
34168
|
return {
|
|
@@ -37247,7 +37533,7 @@ var require_transcript_service = __commonJS({
|
|
|
37247
37533
|
await this.persistCompactionHistory();
|
|
37248
37534
|
if (this.sessionId) {
|
|
37249
37535
|
const lineCount = (0, node_fs_1.statSync)(snapshotPath).size > 0 ? this.metrics.lastProcessedLine : 0;
|
|
37250
|
-
(0, structured_logging_js_1.logEvent)(this.options.logger, structured_logging_js_1.LogEvents.preCompactCaptured({ sessionId: this.sessionId
|
|
37536
|
+
(0, structured_logging_js_1.logEvent)(this.options.logger, structured_logging_js_1.LogEvents.preCompactCaptured({ sessionId: this.sessionId }, { snapshotPath, lineCount }, { transcriptPath: this.transcriptPath ?? "", metrics: this.deepCloneMetrics() }));
|
|
37251
37537
|
}
|
|
37252
37538
|
this.options.logger.info("Captured pre-compact state", { sessionId: this.sessionId, snapshotPath });
|
|
37253
37539
|
}
|
|
@@ -37831,7 +38117,6 @@ var require_service_factory2 = __commonJS({
|
|
|
37831
38117
|
this.stagingCore = new staging_service_js_1.StagingServiceCore({
|
|
37832
38118
|
stateDir: options.stateDir,
|
|
37833
38119
|
logger: options.logger,
|
|
37834
|
-
scope: options.scope,
|
|
37835
38120
|
stateService: stagingStateService
|
|
37836
38121
|
});
|
|
37837
38122
|
}
|
|
@@ -37841,7 +38126,7 @@ var require_service_factory2 = __commonJS({
|
|
|
37841
38126
|
*/
|
|
37842
38127
|
getStagingService(sessionId) {
|
|
37843
38128
|
this.touchSession(sessionId);
|
|
37844
|
-
return new staging_service_js_1.SessionScopedStagingService(this.stagingCore, sessionId
|
|
38129
|
+
return new staging_service_js_1.SessionScopedStagingService(this.stagingCore, sessionId);
|
|
37845
38130
|
}
|
|
37846
38131
|
/**
|
|
37847
38132
|
* Prepare a session-scoped TranscriptService without starting event emission.
|
|
@@ -38447,8 +38732,8 @@ var require_dist3 = __commonJS({
|
|
|
38447
38732
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p);
|
|
38448
38733
|
};
|
|
38449
38734
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
38450
|
-
exports2.
|
|
38451
|
-
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 = exports2.createDefaultTokenUsage = exports2.createDefaultMetrics = exports2.copyWithTimestampSync = exports2.renameWithTimestampSync = exports2.renameWithTimestamp = exports2.copyWithTimestamp = exports2.getTimestampedPath = exports2.extractToolResultPreview = exports2.extractToolCallPreview = exports2.extractTextFromContent = exports2.extractContentPreview = void 0;
|
|
38735
|
+
exports2.getHookDir = exports2.getStagingRoot = exports2.SessionScopedStagingService = exports2.StagingServiceCore = exports2.GITIGNORE_ENTRIES = exports2.SIDEKICK_SECTION_END = exports2.SIDEKICK_SECTION_START = exports2.detectGitignoreStatus = exports2.removeGitignoreSection = exports2.installGitignoreSection = exports2.createSetupStatusService = exports2.SetupStatusService = exports2.DaemonClient = exports2.killAllDaemons = exports2.logEvent = exports2.LogEvents = 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.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;
|
|
38736
|
+
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 = 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 = void 0;
|
|
38452
38737
|
var types_1 = require_dist();
|
|
38453
38738
|
Object.defineProperty(exports2, "TaskTypes", { enumerable: true, get: function() {
|
|
38454
38739
|
return types_1.TaskTypes;
|
|
@@ -38554,7 +38839,7 @@ var require_dist3 = __commonJS({
|
|
|
38554
38839
|
return logger_1.createConsoleLogger;
|
|
38555
38840
|
} });
|
|
38556
38841
|
__exportStar(require_runtime_context(), exports2);
|
|
38557
|
-
__exportStar(
|
|
38842
|
+
__exportStar(require_project_root(), exports2);
|
|
38558
38843
|
var structured_logging_1 = require_structured_logging();
|
|
38559
38844
|
Object.defineProperty(exports2, "createLogManager", { enumerable: true, get: function() {
|
|
38560
38845
|
return structured_logging_1.createLogManager;
|
|
@@ -38581,6 +38866,32 @@ var require_dist3 = __commonJS({
|
|
|
38581
38866
|
Object.defineProperty(exports2, "DaemonClient", { enumerable: true, get: function() {
|
|
38582
38867
|
return daemon_client_1.DaemonClient;
|
|
38583
38868
|
} });
|
|
38869
|
+
var setup_status_service_1 = require_setup_status_service();
|
|
38870
|
+
Object.defineProperty(exports2, "SetupStatusService", { enumerable: true, get: function() {
|
|
38871
|
+
return setup_status_service_1.SetupStatusService;
|
|
38872
|
+
} });
|
|
38873
|
+
Object.defineProperty(exports2, "createSetupStatusService", { enumerable: true, get: function() {
|
|
38874
|
+
return setup_status_service_1.createSetupStatusService;
|
|
38875
|
+
} });
|
|
38876
|
+
var gitignore_1 = require_gitignore();
|
|
38877
|
+
Object.defineProperty(exports2, "installGitignoreSection", { enumerable: true, get: function() {
|
|
38878
|
+
return gitignore_1.installGitignoreSection;
|
|
38879
|
+
} });
|
|
38880
|
+
Object.defineProperty(exports2, "removeGitignoreSection", { enumerable: true, get: function() {
|
|
38881
|
+
return gitignore_1.removeGitignoreSection;
|
|
38882
|
+
} });
|
|
38883
|
+
Object.defineProperty(exports2, "detectGitignoreStatus", { enumerable: true, get: function() {
|
|
38884
|
+
return gitignore_1.detectGitignoreStatus;
|
|
38885
|
+
} });
|
|
38886
|
+
Object.defineProperty(exports2, "SIDEKICK_SECTION_START", { enumerable: true, get: function() {
|
|
38887
|
+
return gitignore_1.SIDEKICK_SECTION_START;
|
|
38888
|
+
} });
|
|
38889
|
+
Object.defineProperty(exports2, "SIDEKICK_SECTION_END", { enumerable: true, get: function() {
|
|
38890
|
+
return gitignore_1.SIDEKICK_SECTION_END;
|
|
38891
|
+
} });
|
|
38892
|
+
Object.defineProperty(exports2, "GITIGNORE_ENTRIES", { enumerable: true, get: function() {
|
|
38893
|
+
return gitignore_1.GITIGNORE_ENTRIES;
|
|
38894
|
+
} });
|
|
38584
38895
|
var staging_service_1 = require_staging_service();
|
|
38585
38896
|
Object.defineProperty(exports2, "StagingServiceCore", { enumerable: true, get: function() {
|
|
38586
38897
|
return staging_service_1.StagingServiceCore;
|
|
@@ -38726,9 +39037,9 @@ var require_runtime = __commonJS({
|
|
|
38726
39037
|
var node_crypto_1 = require("node:crypto");
|
|
38727
39038
|
var node_os_1 = require("node:os");
|
|
38728
39039
|
var node_path_1 = require("node:path");
|
|
38729
|
-
function getLogFilePath(
|
|
38730
|
-
if (
|
|
38731
|
-
return (0, node_path_1.join)(
|
|
39040
|
+
function getLogFilePath(projectRoot) {
|
|
39041
|
+
if (projectRoot) {
|
|
39042
|
+
return (0, node_path_1.join)(projectRoot, ".sidekick", "logs", "sidekick.log");
|
|
38732
39043
|
}
|
|
38733
39044
|
return (0, node_path_1.join)((0, node_os_1.homedir)(), ".sidekick", "logs", "sidekick.log");
|
|
38734
39045
|
}
|
|
@@ -38739,17 +39050,17 @@ var require_runtime = __commonJS({
|
|
|
38739
39050
|
bootstrapSink: options.stderrSink ?? process.stderr,
|
|
38740
39051
|
bufferPreUpgrade: true
|
|
38741
39052
|
});
|
|
38742
|
-
const
|
|
39053
|
+
const { projectRoot } = (0, core_1.resolveProjectRoot)(options);
|
|
38743
39054
|
const defaultAssetsDir = options.defaultAssetsDir ?? (0, core_1.getDefaultAssetsDir)();
|
|
38744
39055
|
const assets = (0, core_1.createAssetResolver)({
|
|
38745
39056
|
defaultAssetsDir,
|
|
38746
|
-
projectRoot
|
|
39057
|
+
projectRoot,
|
|
38747
39058
|
homeDir: options.homeDir
|
|
38748
39059
|
});
|
|
38749
39060
|
let config;
|
|
38750
39061
|
try {
|
|
38751
39062
|
config = (0, core_1.createConfigService)({
|
|
38752
|
-
projectRoot
|
|
39063
|
+
projectRoot,
|
|
38753
39064
|
homeDir: options.homeDir,
|
|
38754
39065
|
assets
|
|
38755
39066
|
});
|
|
@@ -38761,15 +39072,14 @@ var require_runtime = __commonJS({
|
|
|
38761
39072
|
}
|
|
38762
39073
|
const effectiveLogLevel = options.logLevel ?? config.core.logging.level;
|
|
38763
39074
|
let logContext = {
|
|
38764
|
-
scope: scope.scope,
|
|
38765
39075
|
correlationId,
|
|
38766
39076
|
command: options.command
|
|
38767
39077
|
};
|
|
38768
|
-
const logFilePath = getLogFilePath(
|
|
39078
|
+
const logFilePath = getLogFilePath(projectRoot);
|
|
38769
39079
|
const isInteractive = options.interactive ?? process.env.SIDEKICK_INTERACTIVE === "1";
|
|
38770
39080
|
const enableFileLogging = options.enableFileLogging ?? true;
|
|
38771
39081
|
const logManager = (0, core_1.createLogManager)({
|
|
38772
|
-
name:
|
|
39082
|
+
name: "sidekick:cli",
|
|
38773
39083
|
level: effectiveLogLevel,
|
|
38774
39084
|
context: logContext,
|
|
38775
39085
|
destinations: {
|
|
@@ -38782,7 +39092,7 @@ var require_runtime = __commonJS({
|
|
|
38782
39092
|
}
|
|
38783
39093
|
});
|
|
38784
39094
|
loggerFacade.upgrade({
|
|
38785
|
-
name:
|
|
39095
|
+
name: "sidekick:cli",
|
|
38786
39096
|
level: effectiveLogLevel,
|
|
38787
39097
|
context: logContext,
|
|
38788
39098
|
destinations: {
|
|
@@ -38810,28 +39120,21 @@ var require_runtime = __commonJS({
|
|
|
38810
39120
|
const telemetry = logManager.getTelemetry();
|
|
38811
39121
|
const cleanupErrorHandlers = (0, core_1.setupGlobalErrorHandlers)(logger);
|
|
38812
39122
|
logger.debug("Runtime bootstrap complete", {
|
|
38813
|
-
|
|
38814
|
-
projectRoot: scope.projectRoot ?? null,
|
|
38815
|
-
source: scope.source,
|
|
38816
|
-
warnings: scope.warnings,
|
|
39123
|
+
projectRoot: projectRoot ?? null,
|
|
38817
39124
|
logFile: enableFileLogging ? logFilePath : null
|
|
38818
39125
|
});
|
|
38819
39126
|
if (config.sources.length > 0) {
|
|
38820
39127
|
logger.debug("Configuration sources loaded", { sources: config.sources });
|
|
38821
39128
|
}
|
|
38822
39129
|
logger.debug("Asset resolver initialized", { cascadeLayers: assets.cascadeLayers });
|
|
38823
|
-
|
|
38824
|
-
logger.warn("Detected project-scope installation while running from user hooks. Deferring to project scope.");
|
|
38825
|
-
telemetry.increment("dual_install_detected", { scope: scope.scope });
|
|
38826
|
-
}
|
|
38827
|
-
const stateRoot = scope.projectRoot ?? (0, node_path_1.join)((0, node_os_1.homedir)(), ".claude");
|
|
39130
|
+
const stateRoot = projectRoot ?? (0, node_path_1.join)((0, node_os_1.homedir)(), ".claude");
|
|
38828
39131
|
const stateService = new core_1.StateService(stateRoot, { logger });
|
|
38829
39132
|
return {
|
|
38830
39133
|
get logger() {
|
|
38831
39134
|
return logger;
|
|
38832
39135
|
},
|
|
38833
39136
|
telemetry,
|
|
38834
|
-
|
|
39137
|
+
projectRoot,
|
|
38835
39138
|
config,
|
|
38836
39139
|
assets,
|
|
38837
39140
|
stateService,
|
|
@@ -38842,7 +39145,7 @@ var require_runtime = __commonJS({
|
|
|
38842
39145
|
bindSessionId: (sessionId) => {
|
|
38843
39146
|
logContext = { ...logContext, sessionId };
|
|
38844
39147
|
const newLogManager = (0, core_1.createLogManager)({
|
|
38845
|
-
name:
|
|
39148
|
+
name: "sidekick:cli",
|
|
38846
39149
|
level: effectiveLogLevel,
|
|
38847
39150
|
context: logContext,
|
|
38848
39151
|
destinations: {
|
|
@@ -47929,7 +48232,6 @@ var require_events2 = __commonJS({
|
|
|
47929
48232
|
source: "cli",
|
|
47930
48233
|
context: {
|
|
47931
48234
|
sessionId: context.sessionId,
|
|
47932
|
-
scope: context.scope,
|
|
47933
48235
|
correlationId: context.correlationId,
|
|
47934
48236
|
traceId: context.traceId,
|
|
47935
48237
|
hook: context.hook,
|
|
@@ -47952,7 +48254,6 @@ var require_events2 = __commonJS({
|
|
|
47952
48254
|
source: "daemon",
|
|
47953
48255
|
context: {
|
|
47954
48256
|
sessionId: context.sessionId,
|
|
47955
|
-
scope: context.scope,
|
|
47956
48257
|
correlationId: context.correlationId,
|
|
47957
48258
|
traceId: context.traceId,
|
|
47958
48259
|
hook: context.hook,
|
|
@@ -48095,7 +48396,6 @@ var require_consumption_handler_factory = __commonJS({
|
|
|
48095
48396
|
}
|
|
48096
48397
|
(0, core_1.logEvent)(cliCtx.logger, events_js_1.ReminderEvents.reminderConsumed({
|
|
48097
48398
|
sessionId,
|
|
48098
|
-
scope: cliCtx.paths.projectDir ? "project" : "user",
|
|
48099
48399
|
hook
|
|
48100
48400
|
}, {
|
|
48101
48401
|
reminderName: reminder.name,
|
|
@@ -48204,7 +48504,7 @@ var require_inject_stop = __commonJS({
|
|
|
48204
48504
|
}
|
|
48205
48505
|
return (0, consumption_handler_factory_js_1.buildDefaultResponse)(reminder, supportsBlocking);
|
|
48206
48506
|
} else {
|
|
48207
|
-
const metrics = reminder.stagedAt ?? { turnCount: 0, toolsThisTurn: 0 };
|
|
48507
|
+
const metrics = reminder.stagedAt ?? { turnCount: 0, toolsThisTurn: 0, toolCount: 0 };
|
|
48208
48508
|
try {
|
|
48209
48509
|
await ipc.send("vc-unverified.set", {
|
|
48210
48510
|
sessionId,
|
|
@@ -48214,7 +48514,8 @@ var require_inject_stop = __commonJS({
|
|
|
48214
48514
|
},
|
|
48215
48515
|
metrics: {
|
|
48216
48516
|
turnCount: metrics.turnCount,
|
|
48217
|
-
toolsThisTurn: metrics.toolsThisTurn
|
|
48517
|
+
toolsThisTurn: metrics.toolsThisTurn,
|
|
48518
|
+
toolCount: metrics.toolCount
|
|
48218
48519
|
}
|
|
48219
48520
|
});
|
|
48220
48521
|
} catch (setErr) {
|
|
@@ -48243,13 +48544,14 @@ var require_inject_stop = __commonJS({
|
|
|
48243
48544
|
if (projectDir) {
|
|
48244
48545
|
const ipc = new core_1.IpcService(projectDir, cliCtx.logger);
|
|
48245
48546
|
try {
|
|
48246
|
-
const metrics = reminder.stagedAt ?? { turnCount: 0, toolsThisTurn: 0 };
|
|
48547
|
+
const metrics = reminder.stagedAt ?? { turnCount: 0, toolsThisTurn: 0, toolCount: 0 };
|
|
48247
48548
|
await ipc.send("reminder.consumed", {
|
|
48248
48549
|
sessionId,
|
|
48249
48550
|
reminderName: reminder.name,
|
|
48250
48551
|
metrics: {
|
|
48251
48552
|
turnCount: metrics.turnCount,
|
|
48252
|
-
toolsThisTurn: metrics.toolsThisTurn
|
|
48553
|
+
toolsThisTurn: metrics.toolsThisTurn,
|
|
48554
|
+
toolCount: metrics.toolCount
|
|
48253
48555
|
}
|
|
48254
48556
|
});
|
|
48255
48557
|
} finally {
|
|
@@ -48702,21 +49004,19 @@ var require_context2 = __commonJS({
|
|
|
48702
49004
|
var feature_reminders_1 = require_dist4();
|
|
48703
49005
|
function buildCLIContext(options) {
|
|
48704
49006
|
const { runtime, sessionId, transcriptPath } = options;
|
|
48705
|
-
if (!runtime.
|
|
48706
|
-
throw new Error("Cannot build CLIContext without project root - reminder consumption requires project
|
|
49007
|
+
if (!runtime.projectRoot) {
|
|
49008
|
+
throw new Error("Cannot build CLIContext without project root - reminder consumption requires project root");
|
|
48707
49009
|
}
|
|
48708
|
-
const projectRoot = runtime.
|
|
49010
|
+
const projectRoot = runtime.projectRoot;
|
|
48709
49011
|
const paths = {
|
|
48710
49012
|
projectDir: projectRoot,
|
|
48711
49013
|
userConfigDir: (0, node_path_1.join)((0, node_os_1.homedir)(), ".sidekick"),
|
|
48712
|
-
projectConfigDir: (0, node_path_1.join)(projectRoot, ".sidekick")
|
|
48713
|
-
hookScriptPath: runtime.scope.hookScriptPath
|
|
49014
|
+
projectConfigDir: (0, node_path_1.join)(projectRoot, ".sidekick")
|
|
48714
49015
|
};
|
|
48715
49016
|
const handlers = new core_1.HandlerRegistryImpl({
|
|
48716
49017
|
logger: runtime.logger,
|
|
48717
49018
|
sessionId,
|
|
48718
|
-
transcriptPath
|
|
48719
|
-
scope: runtime.scope.scope
|
|
49019
|
+
transcriptPath
|
|
48720
49020
|
});
|
|
48721
49021
|
const daemon = new core_1.DaemonClient(projectRoot, runtime.logger);
|
|
48722
49022
|
const context = {
|
|
@@ -48871,11 +49171,10 @@ var require_hook = __commonJS({
|
|
|
48871
49171
|
}
|
|
48872
49172
|
};
|
|
48873
49173
|
}
|
|
48874
|
-
function buildHookEvent(hookName, input, correlationId
|
|
49174
|
+
function buildHookEvent(hookName, input, correlationId) {
|
|
48875
49175
|
const context = {
|
|
48876
49176
|
sessionId: input.sessionId,
|
|
48877
49177
|
timestamp: Date.now(),
|
|
48878
|
-
scope,
|
|
48879
49178
|
correlationId
|
|
48880
49179
|
};
|
|
48881
49180
|
switch (hookName) {
|
|
@@ -48914,16 +49213,15 @@ ${daemonResponse.additionalContext}` : cliResponse.additionalContext;
|
|
|
48914
49213
|
return merged;
|
|
48915
49214
|
}
|
|
48916
49215
|
async function handleHookCommand(hookName, options, logger, stdout) {
|
|
48917
|
-
const { projectRoot, hookInput, correlationId,
|
|
49216
|
+
const { projectRoot, hookInput, correlationId, runtime } = options;
|
|
48918
49217
|
const startTime = Date.now();
|
|
48919
49218
|
const logContext = {
|
|
48920
49219
|
sessionId: hookInput.sessionId,
|
|
48921
|
-
scope,
|
|
48922
49220
|
correlationId,
|
|
48923
49221
|
hook: hookName
|
|
48924
49222
|
};
|
|
48925
49223
|
(0, core_1.logEvent)(logger, core_1.LogEvents.hookReceived(logContext, { cwd: hookInput.cwd, mode: "hook" }));
|
|
48926
|
-
const event = buildHookEvent(hookName, hookInput, correlationId
|
|
49224
|
+
const event = buildHookEvent(hookName, hookInput, correlationId);
|
|
48927
49225
|
logger.debug("Dispatching hook event to daemon", {
|
|
48928
49226
|
hook: hookName,
|
|
48929
49227
|
sessionId: hookInput.sessionId
|
|
@@ -49125,7 +49423,7 @@ var require_hook_command = __commonJS({
|
|
|
49125
49423
|
}
|
|
49126
49424
|
}
|
|
49127
49425
|
async function handleUnifiedHookCommand(hookName, options, logger, stdout) {
|
|
49128
|
-
const { projectRoot, hookInput, correlationId,
|
|
49426
|
+
const { projectRoot, hookInput, correlationId, runtime } = options;
|
|
49129
49427
|
logger.debug("Unified hook command invoked", { hookName, sessionId: hookInput.sessionId });
|
|
49130
49428
|
let internalOutput = "";
|
|
49131
49429
|
const captureStream = {
|
|
@@ -49139,7 +49437,6 @@ var require_hook_command = __commonJS({
|
|
|
49139
49437
|
sessionId: hookInput.sessionId,
|
|
49140
49438
|
hookInput,
|
|
49141
49439
|
correlationId,
|
|
49142
|
-
scope,
|
|
49143
49440
|
runtime
|
|
49144
49441
|
}, logger, captureStream);
|
|
49145
49442
|
const internalResponse = parseInternalResponse(internalOutput.trim(), hookName, logger);
|
|
@@ -49672,7 +49969,6 @@ var require_events3 = __commonJS({
|
|
|
49672
49969
|
source: "daemon",
|
|
49673
49970
|
context: {
|
|
49674
49971
|
sessionId: context.sessionId,
|
|
49675
|
-
scope: context.scope,
|
|
49676
49972
|
correlationId: context.correlationId,
|
|
49677
49973
|
traceId: context.traceId,
|
|
49678
49974
|
hook: context.hook,
|
|
@@ -49696,7 +49992,6 @@ var require_events3 = __commonJS({
|
|
|
49696
49992
|
source: "daemon",
|
|
49697
49993
|
context: {
|
|
49698
49994
|
sessionId: context.sessionId,
|
|
49699
|
-
scope: context.scope,
|
|
49700
49995
|
correlationId: context.correlationId,
|
|
49701
49996
|
traceId: context.traceId,
|
|
49702
49997
|
hook: context.hook,
|
|
@@ -50097,7 +50392,7 @@ var require_update_summary = __commonJS({
|
|
|
50097
50392
|
async function generateResumeMessage(ctx, summaryState, eventContext, summary, transcriptExcerpt, config) {
|
|
50098
50393
|
const { sessionId } = eventContext;
|
|
50099
50394
|
if (summary.session_title_confidence < types_js_1.RESUME_MIN_CONFIDENCE || summary.latest_intent_confidence < types_js_1.RESUME_MIN_CONFIDENCE) {
|
|
50100
|
-
(0, core_1.logEvent)(ctx.logger, core_1.LogEvents.resumeSkipped({ sessionId
|
|
50395
|
+
(0, core_1.logEvent)(ctx.logger, core_1.LogEvents.resumeSkipped({ sessionId }, {
|
|
50101
50396
|
title_confidence: summary.session_title_confidence,
|
|
50102
50397
|
intent_confidence: summary.latest_intent_confidence,
|
|
50103
50398
|
min_confidence: types_js_1.RESUME_MIN_CONFIDENCE
|
|
@@ -50114,7 +50409,7 @@ var require_update_summary = __commonJS({
|
|
|
50114
50409
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
50115
50410
|
};
|
|
50116
50411
|
await summaryState.resumeMessage.write(sessionId, resumeState);
|
|
50117
|
-
(0, core_1.logEvent)(ctx.logger, core_1.LogEvents.resumeUpdated({ sessionId
|
|
50412
|
+
(0, core_1.logEvent)(ctx.logger, core_1.LogEvents.resumeUpdated({ sessionId }, {
|
|
50118
50413
|
snarky_comment: resumeState.snarky_comment,
|
|
50119
50414
|
timestamp: resumeState.timestamp
|
|
50120
50415
|
}));
|
|
@@ -50125,7 +50420,7 @@ var require_update_summary = __commonJS({
|
|
|
50125
50420
|
ctx.logger.warn("Resume message prompt not found", { path: RESUME_PROMPT_FILE });
|
|
50126
50421
|
return;
|
|
50127
50422
|
}
|
|
50128
|
-
(0, core_1.logEvent)(ctx.logger, core_1.LogEvents.resumeGenerating({ sessionId
|
|
50423
|
+
(0, core_1.logEvent)(ctx.logger, core_1.LogEvents.resumeGenerating({ sessionId }, {
|
|
50129
50424
|
title_confidence: summary.session_title_confidence,
|
|
50130
50425
|
intent_confidence: summary.latest_intent_confidence
|
|
50131
50426
|
}));
|
|
@@ -50154,7 +50449,7 @@ var require_update_summary = __commonJS({
|
|
|
50154
50449
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
50155
50450
|
};
|
|
50156
50451
|
await summaryState.resumeMessage.write(sessionId, resumeState);
|
|
50157
|
-
(0, core_1.logEvent)(ctx.logger, core_1.LogEvents.resumeUpdated({ sessionId
|
|
50452
|
+
(0, core_1.logEvent)(ctx.logger, core_1.LogEvents.resumeUpdated({ sessionId }, {
|
|
50158
50453
|
snarky_comment: resumeState.snarky_comment,
|
|
50159
50454
|
timestamp: resumeState.timestamp
|
|
50160
50455
|
}));
|
|
@@ -51276,6 +51571,10 @@ var require_statusline_service = __commonJS({
|
|
|
51276
51571
|
theme: this.config.theme,
|
|
51277
51572
|
useColors: this.useColors
|
|
51278
51573
|
});
|
|
51574
|
+
this.setupService = serviceConfig.setupService ?? new core_1.SetupStatusService(serviceConfig.projectDir ?? serviceConfig.cwd, {
|
|
51575
|
+
homeDir: serviceConfig.homeDir,
|
|
51576
|
+
logger: serviceConfig.logger
|
|
51577
|
+
});
|
|
51279
51578
|
}
|
|
51280
51579
|
/**
|
|
51281
51580
|
* Load persona definition for the session.
|
|
@@ -51365,6 +51664,74 @@ var require_statusline_service = __commonJS({
|
|
|
51365
51664
|
}
|
|
51366
51665
|
return { ...types_js_2.DEFAULT_STATUSLINE_CONFIG, ...serviceConfig.config };
|
|
51367
51666
|
}
|
|
51667
|
+
/**
|
|
51668
|
+
* Check setup status and return warning message if unhealthy.
|
|
51669
|
+
* Returns empty warning for healthy state.
|
|
51670
|
+
*/
|
|
51671
|
+
async checkSetupStatus() {
|
|
51672
|
+
const state = await this.setupService.getSetupState();
|
|
51673
|
+
switch (state) {
|
|
51674
|
+
case "not-run":
|
|
51675
|
+
return {
|
|
51676
|
+
warning: "Sidekick not configured. Run 'sidekick setup' to get started.",
|
|
51677
|
+
state
|
|
51678
|
+
};
|
|
51679
|
+
case "partial":
|
|
51680
|
+
return {
|
|
51681
|
+
warning: "Project not configured. Run 'sidekick setup' for this project.",
|
|
51682
|
+
state
|
|
51683
|
+
};
|
|
51684
|
+
case "unhealthy": {
|
|
51685
|
+
const keyHealth = await this.setupService.getEffectiveApiKeyHealth("OPENROUTER_API_KEY");
|
|
51686
|
+
if (keyHealth === "missing") {
|
|
51687
|
+
return {
|
|
51688
|
+
warning: "OPENROUTER_API_KEY not found. Run 'sidekick doctor' or /sidekick-config",
|
|
51689
|
+
state
|
|
51690
|
+
};
|
|
51691
|
+
}
|
|
51692
|
+
if (keyHealth === "invalid") {
|
|
51693
|
+
return {
|
|
51694
|
+
warning: "API key invalid. Run 'sidekick doctor' to fix.",
|
|
51695
|
+
state
|
|
51696
|
+
};
|
|
51697
|
+
}
|
|
51698
|
+
return {
|
|
51699
|
+
warning: "Setup issue detected. Run 'sidekick doctor'.",
|
|
51700
|
+
state
|
|
51701
|
+
};
|
|
51702
|
+
}
|
|
51703
|
+
default:
|
|
51704
|
+
return { warning: "", state: "healthy" };
|
|
51705
|
+
}
|
|
51706
|
+
}
|
|
51707
|
+
/**
|
|
51708
|
+
* Build minimal view model for setup_warning display mode.
|
|
51709
|
+
* Only includes fields needed for warning display.
|
|
51710
|
+
*/
|
|
51711
|
+
buildMinimalViewModel(setupCheck) {
|
|
51712
|
+
return {
|
|
51713
|
+
model: "",
|
|
51714
|
+
contextWindow: "",
|
|
51715
|
+
tokenUsageActual: "",
|
|
51716
|
+
tokenUsageEffective: "",
|
|
51717
|
+
tokenPercentageActual: "",
|
|
51718
|
+
tokenPercentageEffective: "",
|
|
51719
|
+
tokensStatus: "normal",
|
|
51720
|
+
cost: "",
|
|
51721
|
+
costStatus: "normal",
|
|
51722
|
+
duration: "",
|
|
51723
|
+
cwd: "",
|
|
51724
|
+
branch: "",
|
|
51725
|
+
branchColor: "",
|
|
51726
|
+
displayMode: "setup_warning",
|
|
51727
|
+
summary: setupCheck.warning,
|
|
51728
|
+
title: "",
|
|
51729
|
+
warningCount: 0,
|
|
51730
|
+
errorCount: 0,
|
|
51731
|
+
logStatus: "normal",
|
|
51732
|
+
personaName: ""
|
|
51733
|
+
};
|
|
51734
|
+
}
|
|
51368
51735
|
/**
|
|
51369
51736
|
* Render the statusline by fetching all data in parallel and formatting.
|
|
51370
51737
|
*
|
|
@@ -51374,6 +51741,19 @@ var require_statusline_service = __commonJS({
|
|
|
51374
51741
|
* for model/tokens/cost/duration instead of reading from state files.
|
|
51375
51742
|
*/
|
|
51376
51743
|
async render() {
|
|
51744
|
+
const setupCheck = await this.checkSetupStatus();
|
|
51745
|
+
if (setupCheck.state !== "healthy") {
|
|
51746
|
+
const viewModel2 = this.buildMinimalViewModel(setupCheck);
|
|
51747
|
+
const ANSI_YELLOW = "\x1B[33m";
|
|
51748
|
+
const ANSI_RESET = "\x1B[0m";
|
|
51749
|
+
const text2 = this.useColors ? `${ANSI_YELLOW}${setupCheck.warning}${ANSI_RESET}` : setupCheck.warning;
|
|
51750
|
+
return {
|
|
51751
|
+
text: text2,
|
|
51752
|
+
displayMode: "setup_warning",
|
|
51753
|
+
staleData: false,
|
|
51754
|
+
viewModel: viewModel2
|
|
51755
|
+
};
|
|
51756
|
+
}
|
|
51377
51757
|
const hasHookInput = !!this.hookInput;
|
|
51378
51758
|
const [transcriptResult, summaryResult, resumeResult, snarkyResult, branchResult, baseline, logMetricsResult, personaResult] = await Promise.all([
|
|
51379
51759
|
this.stateReader.getTranscriptMetrics(),
|
|
@@ -51855,8 +52235,7 @@ Examples:
|
|
|
51855
52235
|
const sessionId = options.sessionId ?? "current";
|
|
51856
52236
|
const stateService = new core_1.StateService(projectDir);
|
|
51857
52237
|
const eventContext = {
|
|
51858
|
-
sessionId
|
|
51859
|
-
scope: "project"
|
|
52238
|
+
sessionId
|
|
51860
52239
|
};
|
|
51861
52240
|
const cwd = options.hookInput?.cwd ?? process.cwd();
|
|
51862
52241
|
logger.debug("Statusline hookInput received", { hookInput: options.hookInput });
|
|
@@ -52735,6 +53114,38 @@ var require_dev_mode = __commonJS({
|
|
|
52735
53114
|
}
|
|
52736
53115
|
return zombies;
|
|
52737
53116
|
}
|
|
53117
|
+
async function cleanupStalePidFiles(logger) {
|
|
53118
|
+
const daemonsDir = (0, core_1.getUserDaemonsDir)();
|
|
53119
|
+
let cleanedCount = 0;
|
|
53120
|
+
let files;
|
|
53121
|
+
try {
|
|
53122
|
+
files = await (0, promises_12.readdir)(daemonsDir);
|
|
53123
|
+
} catch {
|
|
53124
|
+
return 0;
|
|
53125
|
+
}
|
|
53126
|
+
const pidFiles = files.filter((f) => f.endsWith(".pid"));
|
|
53127
|
+
for (const pidFile of pidFiles) {
|
|
53128
|
+
const pidPath = node_path_1.default.join(daemonsDir, pidFile);
|
|
53129
|
+
try {
|
|
53130
|
+
const content = await (0, promises_12.readFile)(pidPath, "utf-8");
|
|
53131
|
+
const info = JSON.parse(content);
|
|
53132
|
+
try {
|
|
53133
|
+
process.kill(info.pid, 0);
|
|
53134
|
+
} catch {
|
|
53135
|
+
await (0, promises_12.unlink)(pidPath).catch(() => {
|
|
53136
|
+
});
|
|
53137
|
+
logger.debug("Removed stale PID file", { pidFile, pid: info.pid });
|
|
53138
|
+
cleanedCount++;
|
|
53139
|
+
}
|
|
53140
|
+
} catch {
|
|
53141
|
+
await (0, promises_12.unlink)(pidPath).catch(() => {
|
|
53142
|
+
});
|
|
53143
|
+
logger.debug("Removed corrupt PID file", { pidFile });
|
|
53144
|
+
cleanedCount++;
|
|
53145
|
+
}
|
|
53146
|
+
}
|
|
53147
|
+
return cleanedCount;
|
|
53148
|
+
}
|
|
52738
53149
|
function isDevHookCommand(command) {
|
|
52739
53150
|
return command?.includes("dev-hooks") ?? false;
|
|
52740
53151
|
}
|
|
@@ -53007,13 +53418,42 @@ var require_dev_mode = __commonJS({
|
|
|
53007
53418
|
stdout.write("\n");
|
|
53008
53419
|
const shouldKill = force || await promptConfirm("Kill these processes?", stdout, stdin);
|
|
53009
53420
|
if (shouldKill) {
|
|
53010
|
-
|
|
53011
|
-
const
|
|
53421
|
+
let killedCount = 0;
|
|
53422
|
+
for (const zombie of zombies) {
|
|
53423
|
+
const filesToRemove = [
|
|
53424
|
+
(0, core_1.getUserPidPath)(zombie.projectDir),
|
|
53425
|
+
(0, core_1.getPidPath)(zombie.projectDir),
|
|
53426
|
+
(0, core_1.getSocketPath)(zombie.projectDir),
|
|
53427
|
+
(0, core_1.getTokenPath)(zombie.projectDir)
|
|
53428
|
+
];
|
|
53429
|
+
try {
|
|
53430
|
+
process.kill(zombie.pid, "SIGKILL");
|
|
53431
|
+
logger.info("Killed zombie daemon", { pid: zombie.pid, projectDir: zombie.projectDir });
|
|
53432
|
+
killedCount++;
|
|
53433
|
+
} catch (err) {
|
|
53434
|
+
const code = err.code;
|
|
53435
|
+
if (code === "ESRCH") {
|
|
53436
|
+
logger.info("Zombie daemon already exited", { pid: zombie.pid, projectDir: zombie.projectDir });
|
|
53437
|
+
killedCount++;
|
|
53438
|
+
} else {
|
|
53439
|
+
logger.warn("Failed to kill zombie daemon", {
|
|
53440
|
+
pid: zombie.pid,
|
|
53441
|
+
error: err instanceof Error ? err.message : String(err)
|
|
53442
|
+
});
|
|
53443
|
+
}
|
|
53444
|
+
}
|
|
53445
|
+
await Promise.all(filesToRemove.map((f) => (0, promises_12.unlink)(f).catch(() => {
|
|
53446
|
+
})));
|
|
53447
|
+
}
|
|
53012
53448
|
log(stdout, "info", `Killed ${killedCount} zombie daemon(s)`);
|
|
53013
53449
|
} else {
|
|
53014
53450
|
log(stdout, "info", "Skipping zombie cleanup");
|
|
53015
53451
|
}
|
|
53016
53452
|
}
|
|
53453
|
+
const staleCount = await cleanupStalePidFiles(logger);
|
|
53454
|
+
if (staleCount > 0) {
|
|
53455
|
+
log(stdout, "info", `Cleaned up ${staleCount} stale PID file(s)`);
|
|
53456
|
+
}
|
|
53017
53457
|
stdout.write("\n");
|
|
53018
53458
|
log(stdout, "info", "Clean complete. Restart Claude Code with: claude --continue");
|
|
53019
53459
|
return { exitCode: 0 };
|
|
@@ -53105,6 +53545,582 @@ ${USAGE_TEXT}`);
|
|
|
53105
53545
|
}
|
|
53106
53546
|
});
|
|
53107
53547
|
|
|
53548
|
+
// ../sidekick-cli/dist/commands/setup/prompts.js
|
|
53549
|
+
var require_prompts = __commonJS({
|
|
53550
|
+
"../sidekick-cli/dist/commands/setup/prompts.js"(exports2) {
|
|
53551
|
+
"use strict";
|
|
53552
|
+
var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) {
|
|
53553
|
+
if (k2 === void 0) k2 = k;
|
|
53554
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
53555
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
53556
|
+
desc = { enumerable: true, get: function() {
|
|
53557
|
+
return m[k];
|
|
53558
|
+
} };
|
|
53559
|
+
}
|
|
53560
|
+
Object.defineProperty(o, k2, desc);
|
|
53561
|
+
} : function(o, m, k, k2) {
|
|
53562
|
+
if (k2 === void 0) k2 = k;
|
|
53563
|
+
o[k2] = m[k];
|
|
53564
|
+
});
|
|
53565
|
+
var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) {
|
|
53566
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
53567
|
+
} : function(o, v) {
|
|
53568
|
+
o["default"] = v;
|
|
53569
|
+
});
|
|
53570
|
+
var __importStar = exports2 && exports2.__importStar || /* @__PURE__ */ function() {
|
|
53571
|
+
var ownKeys = function(o) {
|
|
53572
|
+
ownKeys = Object.getOwnPropertyNames || function(o2) {
|
|
53573
|
+
var ar = [];
|
|
53574
|
+
for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
|
|
53575
|
+
return ar;
|
|
53576
|
+
};
|
|
53577
|
+
return ownKeys(o);
|
|
53578
|
+
};
|
|
53579
|
+
return function(mod) {
|
|
53580
|
+
if (mod && mod.__esModule) return mod;
|
|
53581
|
+
var result = {};
|
|
53582
|
+
if (mod != null) {
|
|
53583
|
+
for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
53584
|
+
}
|
|
53585
|
+
__setModuleDefault(result, mod);
|
|
53586
|
+
return result;
|
|
53587
|
+
};
|
|
53588
|
+
}();
|
|
53589
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
53590
|
+
exports2.printHeader = printHeader;
|
|
53591
|
+
exports2.printStatus = printStatus;
|
|
53592
|
+
exports2.promptSelect = promptSelect;
|
|
53593
|
+
exports2.promptConfirm = promptConfirm;
|
|
53594
|
+
exports2.promptInput = promptInput;
|
|
53595
|
+
var readline = __importStar(require("node:readline"));
|
|
53596
|
+
var colors = {
|
|
53597
|
+
reset: "\x1B[0m",
|
|
53598
|
+
bold: "\x1B[1m",
|
|
53599
|
+
dim: "\x1B[2m",
|
|
53600
|
+
green: "\x1B[32m",
|
|
53601
|
+
yellow: "\x1B[33m",
|
|
53602
|
+
blue: "\x1B[34m",
|
|
53603
|
+
cyan: "\x1B[36m"
|
|
53604
|
+
};
|
|
53605
|
+
function printHeader(ctx, title, description) {
|
|
53606
|
+
ctx.stdout.write("\n");
|
|
53607
|
+
ctx.stdout.write(`${colors.bold}${title}${colors.reset}
|
|
53608
|
+
`);
|
|
53609
|
+
ctx.stdout.write("\u2500".repeat(Math.min(title.length + 10, 60)) + "\n");
|
|
53610
|
+
if (description) {
|
|
53611
|
+
ctx.stdout.write(`${colors.dim}${description}${colors.reset}
|
|
53612
|
+
`);
|
|
53613
|
+
}
|
|
53614
|
+
ctx.stdout.write("\n");
|
|
53615
|
+
}
|
|
53616
|
+
function printStatus(ctx, type, message) {
|
|
53617
|
+
const icons = { success: "\u2713", warning: "\u26A0", info: "\u2022", error: "\u2717" };
|
|
53618
|
+
const colorMap = { success: colors.green, warning: colors.yellow, info: colors.blue, error: "\x1B[31m" };
|
|
53619
|
+
ctx.stdout.write(`${colorMap[type]}${icons[type]}${colors.reset} ${message}
|
|
53620
|
+
`);
|
|
53621
|
+
}
|
|
53622
|
+
async function promptSelect(ctx, question, options) {
|
|
53623
|
+
ctx.stdout.write(`${question}
|
|
53624
|
+
|
|
53625
|
+
`);
|
|
53626
|
+
options.forEach((opt, i) => {
|
|
53627
|
+
ctx.stdout.write(` ${colors.cyan}${i + 1})${colors.reset} ${opt.label}
|
|
53628
|
+
`);
|
|
53629
|
+
if (opt.description) {
|
|
53630
|
+
ctx.stdout.write(` ${colors.dim}${opt.description}${colors.reset}
|
|
53631
|
+
`);
|
|
53632
|
+
}
|
|
53633
|
+
});
|
|
53634
|
+
ctx.stdout.write("\n");
|
|
53635
|
+
const rl = readline.createInterface({
|
|
53636
|
+
input: ctx.stdin,
|
|
53637
|
+
output: ctx.stdout,
|
|
53638
|
+
terminal: false
|
|
53639
|
+
});
|
|
53640
|
+
return new Promise((resolve3) => {
|
|
53641
|
+
ctx.stdout.write(`Enter choice (1-${options.length}): `);
|
|
53642
|
+
rl.once("line", (answer) => {
|
|
53643
|
+
rl.close();
|
|
53644
|
+
const num = parseInt(answer.trim(), 10);
|
|
53645
|
+
if (num >= 1 && num <= options.length) {
|
|
53646
|
+
resolve3(options[num - 1].value);
|
|
53647
|
+
} else {
|
|
53648
|
+
resolve3(options[0].value);
|
|
53649
|
+
}
|
|
53650
|
+
});
|
|
53651
|
+
});
|
|
53652
|
+
}
|
|
53653
|
+
async function promptConfirm(ctx, question, defaultYes = true) {
|
|
53654
|
+
const hint = defaultYes ? "[Y/n]" : "[y/N]";
|
|
53655
|
+
const rl = readline.createInterface({
|
|
53656
|
+
input: ctx.stdin,
|
|
53657
|
+
output: ctx.stdout,
|
|
53658
|
+
terminal: false
|
|
53659
|
+
});
|
|
53660
|
+
return new Promise((resolve3) => {
|
|
53661
|
+
ctx.stdout.write(`${question} ${hint} `);
|
|
53662
|
+
rl.once("line", (answer) => {
|
|
53663
|
+
rl.close();
|
|
53664
|
+
const normalized = answer.trim().toLowerCase();
|
|
53665
|
+
if (normalized === "") {
|
|
53666
|
+
resolve3(defaultYes);
|
|
53667
|
+
} else {
|
|
53668
|
+
resolve3(normalized === "y" || normalized === "yes");
|
|
53669
|
+
}
|
|
53670
|
+
});
|
|
53671
|
+
});
|
|
53672
|
+
}
|
|
53673
|
+
async function promptInput(ctx, question) {
|
|
53674
|
+
const rl = readline.createInterface({
|
|
53675
|
+
input: ctx.stdin,
|
|
53676
|
+
output: ctx.stdout,
|
|
53677
|
+
terminal: false
|
|
53678
|
+
});
|
|
53679
|
+
return new Promise((resolve3) => {
|
|
53680
|
+
ctx.stdout.write(`${question}: `);
|
|
53681
|
+
rl.once("line", (answer) => {
|
|
53682
|
+
rl.close();
|
|
53683
|
+
resolve3(answer.trim());
|
|
53684
|
+
});
|
|
53685
|
+
});
|
|
53686
|
+
}
|
|
53687
|
+
}
|
|
53688
|
+
});
|
|
53689
|
+
|
|
53690
|
+
// ../sidekick-cli/dist/commands/setup/validate-api-key.js
|
|
53691
|
+
var require_validate_api_key = __commonJS({
|
|
53692
|
+
"../sidekick-cli/dist/commands/setup/validate-api-key.js"(exports2) {
|
|
53693
|
+
"use strict";
|
|
53694
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
53695
|
+
exports2.validateOpenRouterKey = validateOpenRouterKey;
|
|
53696
|
+
exports2.validateOpenAIKey = validateOpenAIKey;
|
|
53697
|
+
var API_ENDPOINTS = {
|
|
53698
|
+
openrouter: "https://openrouter.ai/api/v1/models",
|
|
53699
|
+
openai: "https://api.openai.com/v1/models"
|
|
53700
|
+
};
|
|
53701
|
+
async function validateApiKey(provider, apiKey, logger) {
|
|
53702
|
+
try {
|
|
53703
|
+
const response = await fetch(API_ENDPOINTS[provider], {
|
|
53704
|
+
headers: { Authorization: `Bearer ${apiKey}` }
|
|
53705
|
+
});
|
|
53706
|
+
if (response.ok) {
|
|
53707
|
+
return { valid: true };
|
|
53708
|
+
}
|
|
53709
|
+
if (response.status === 401) {
|
|
53710
|
+
return { valid: false, error: "Invalid API key" };
|
|
53711
|
+
}
|
|
53712
|
+
return { valid: false, error: `API returned status ${response.status}` };
|
|
53713
|
+
} catch (err) {
|
|
53714
|
+
logger?.warn("API key validation failed", { error: err });
|
|
53715
|
+
return { valid: false, error: err instanceof Error ? err.message : "Network error" };
|
|
53716
|
+
}
|
|
53717
|
+
}
|
|
53718
|
+
function validateOpenRouterKey(apiKey, logger) {
|
|
53719
|
+
return validateApiKey("openrouter", apiKey, logger);
|
|
53720
|
+
}
|
|
53721
|
+
function validateOpenAIKey(apiKey, logger) {
|
|
53722
|
+
return validateApiKey("openai", apiKey, logger);
|
|
53723
|
+
}
|
|
53724
|
+
}
|
|
53725
|
+
});
|
|
53726
|
+
|
|
53727
|
+
// ../sidekick-cli/dist/commands/setup/index.js
|
|
53728
|
+
var require_setup = __commonJS({
|
|
53729
|
+
"../sidekick-cli/dist/commands/setup/index.js"(exports2) {
|
|
53730
|
+
"use strict";
|
|
53731
|
+
var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) {
|
|
53732
|
+
if (k2 === void 0) k2 = k;
|
|
53733
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
53734
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
53735
|
+
desc = { enumerable: true, get: function() {
|
|
53736
|
+
return m[k];
|
|
53737
|
+
} };
|
|
53738
|
+
}
|
|
53739
|
+
Object.defineProperty(o, k2, desc);
|
|
53740
|
+
} : function(o, m, k, k2) {
|
|
53741
|
+
if (k2 === void 0) k2 = k;
|
|
53742
|
+
o[k2] = m[k];
|
|
53743
|
+
});
|
|
53744
|
+
var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) {
|
|
53745
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
53746
|
+
} : function(o, v) {
|
|
53747
|
+
o["default"] = v;
|
|
53748
|
+
});
|
|
53749
|
+
var __importStar = exports2 && exports2.__importStar || /* @__PURE__ */ function() {
|
|
53750
|
+
var ownKeys = function(o) {
|
|
53751
|
+
ownKeys = Object.getOwnPropertyNames || function(o2) {
|
|
53752
|
+
var ar = [];
|
|
53753
|
+
for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
|
|
53754
|
+
return ar;
|
|
53755
|
+
};
|
|
53756
|
+
return ownKeys(o);
|
|
53757
|
+
};
|
|
53758
|
+
return function(mod) {
|
|
53759
|
+
if (mod && mod.__esModule) return mod;
|
|
53760
|
+
var result = {};
|
|
53761
|
+
if (mod != null) {
|
|
53762
|
+
for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
53763
|
+
}
|
|
53764
|
+
__setModuleDefault(result, mod);
|
|
53765
|
+
return result;
|
|
53766
|
+
};
|
|
53767
|
+
}();
|
|
53768
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
53769
|
+
exports2.handleSetupCommand = handleSetupCommand;
|
|
53770
|
+
var fs = __importStar(require("node:fs/promises"));
|
|
53771
|
+
var path = __importStar(require("node:path"));
|
|
53772
|
+
var os = __importStar(require("node:os"));
|
|
53773
|
+
var core_1 = require_dist3();
|
|
53774
|
+
var prompts_js_1 = require_prompts();
|
|
53775
|
+
var validate_api_key_js_1 = require_validate_api_key();
|
|
53776
|
+
var STATUSLINE_COMMAND = "npx @scotthamilton77/sidekick statusline --project-dir=$CLAUDE_PROJECT_DIR";
|
|
53777
|
+
function getApiKeyStatusType(health) {
|
|
53778
|
+
switch (health) {
|
|
53779
|
+
case "healthy":
|
|
53780
|
+
return "success";
|
|
53781
|
+
case "not-required":
|
|
53782
|
+
return "info";
|
|
53783
|
+
default:
|
|
53784
|
+
return "warning";
|
|
53785
|
+
}
|
|
53786
|
+
}
|
|
53787
|
+
async function configureStatusline(settingsPath, logger) {
|
|
53788
|
+
let settings = {};
|
|
53789
|
+
try {
|
|
53790
|
+
const content = await fs.readFile(settingsPath, "utf-8");
|
|
53791
|
+
settings = JSON.parse(content);
|
|
53792
|
+
} catch (err) {
|
|
53793
|
+
if (err.code !== "ENOENT") {
|
|
53794
|
+
throw err;
|
|
53795
|
+
}
|
|
53796
|
+
}
|
|
53797
|
+
settings.statusLine = {
|
|
53798
|
+
type: "command",
|
|
53799
|
+
command: STATUSLINE_COMMAND
|
|
53800
|
+
};
|
|
53801
|
+
const dir = path.dirname(settingsPath);
|
|
53802
|
+
await fs.mkdir(dir, { recursive: true });
|
|
53803
|
+
await fs.writeFile(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
53804
|
+
logger?.info("Statusline configured", { path: settingsPath });
|
|
53805
|
+
}
|
|
53806
|
+
async function writeApiKeyToEnv(envPath, key, value) {
|
|
53807
|
+
const dir = path.dirname(envPath);
|
|
53808
|
+
await fs.mkdir(dir, { recursive: true });
|
|
53809
|
+
let content = "";
|
|
53810
|
+
try {
|
|
53811
|
+
content = await fs.readFile(envPath, "utf-8");
|
|
53812
|
+
} catch {
|
|
53813
|
+
}
|
|
53814
|
+
const keyRegex = new RegExp(`^${key}=.*$`, "m");
|
|
53815
|
+
if (keyRegex.test(content)) {
|
|
53816
|
+
content = content.replace(keyRegex, `${key}=${value}`);
|
|
53817
|
+
} else {
|
|
53818
|
+
if (content && !content.endsWith("\n")) {
|
|
53819
|
+
content += "\n";
|
|
53820
|
+
}
|
|
53821
|
+
content += `${key}=${value}
|
|
53822
|
+
`;
|
|
53823
|
+
}
|
|
53824
|
+
await fs.writeFile(envPath, content);
|
|
53825
|
+
}
|
|
53826
|
+
async function findExistingApiKey(keyName, homeDir, projectDir) {
|
|
53827
|
+
if (process.env[keyName]) {
|
|
53828
|
+
return process.env[keyName];
|
|
53829
|
+
}
|
|
53830
|
+
const envPaths = [
|
|
53831
|
+
path.join(homeDir, ".sidekick", ".env"),
|
|
53832
|
+
path.join(projectDir, ".sidekick", ".env"),
|
|
53833
|
+
path.join(projectDir, ".sidekick", ".env.local")
|
|
53834
|
+
];
|
|
53835
|
+
for (const envPath of envPaths) {
|
|
53836
|
+
try {
|
|
53837
|
+
const content = await fs.readFile(envPath, "utf-8");
|
|
53838
|
+
const match = content.match(new RegExp(`^${keyName}=(.+)$`, "m"));
|
|
53839
|
+
if (match) {
|
|
53840
|
+
return match[1];
|
|
53841
|
+
}
|
|
53842
|
+
} catch {
|
|
53843
|
+
}
|
|
53844
|
+
}
|
|
53845
|
+
return null;
|
|
53846
|
+
}
|
|
53847
|
+
async function writePersonaConfig(_projectDir, homeDir, enabled) {
|
|
53848
|
+
const configDir = path.join(homeDir, ".sidekick");
|
|
53849
|
+
const configPath = path.join(configDir, "config.yaml");
|
|
53850
|
+
await fs.mkdir(configDir, { recursive: true });
|
|
53851
|
+
let content = "";
|
|
53852
|
+
try {
|
|
53853
|
+
content = await fs.readFile(configPath, "utf-8");
|
|
53854
|
+
} catch {
|
|
53855
|
+
}
|
|
53856
|
+
const personasRegex = /^features:\s*\n\s*personas:\s*\n\s*enabled:\s*(true|false)/m;
|
|
53857
|
+
const newPersonasBlock = `features:
|
|
53858
|
+
personas:
|
|
53859
|
+
enabled: ${enabled}`;
|
|
53860
|
+
if (personasRegex.test(content)) {
|
|
53861
|
+
content = content.replace(personasRegex, newPersonasBlock);
|
|
53862
|
+
} else {
|
|
53863
|
+
if (content && !content.endsWith("\n")) {
|
|
53864
|
+
content += "\n";
|
|
53865
|
+
}
|
|
53866
|
+
content += newPersonasBlock + "\n";
|
|
53867
|
+
}
|
|
53868
|
+
await fs.writeFile(configPath, content);
|
|
53869
|
+
}
|
|
53870
|
+
function printWizardHeader(stdout) {
|
|
53871
|
+
stdout.write("\n\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n");
|
|
53872
|
+
stdout.write("\u2502 Sidekick Setup Wizard \u2502\n");
|
|
53873
|
+
stdout.write("\u2502 \u2502\n");
|
|
53874
|
+
stdout.write("\u2502 This wizard configures sidekick for Claude Code. \u2502\n");
|
|
53875
|
+
stdout.write("\u2502 Run 'sidekick setup' again anytime to reconfigure. \u2502\n");
|
|
53876
|
+
stdout.write("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n");
|
|
53877
|
+
}
|
|
53878
|
+
async function runStep1Statusline(wctx) {
|
|
53879
|
+
const { ctx, homeDir, projectDir, logger } = wctx;
|
|
53880
|
+
(0, prompts_js_1.printHeader)(ctx, "Step 1: Statusline Configuration", "Claude Code plugins cannot provide statusline config directly.");
|
|
53881
|
+
const statuslineScope = await (0, prompts_js_1.promptSelect)(ctx, "Where should sidekick configure your statusline?", [
|
|
53882
|
+
{ value: "user", label: "User-level (~/.claude/settings.json)", description: "Works in all projects" },
|
|
53883
|
+
{ value: "project", label: "Project-level (.claude/settings.local.json)", description: "This project only" }
|
|
53884
|
+
]);
|
|
53885
|
+
const statuslinePath = statuslineScope === "user" ? path.join(homeDir, ".claude", "settings.json") : path.join(projectDir, ".claude", "settings.local.json");
|
|
53886
|
+
await configureStatusline(statuslinePath, logger);
|
|
53887
|
+
(0, prompts_js_1.printStatus)(ctx, "success", `Statusline configured in ${statuslinePath}`);
|
|
53888
|
+
return statuslineScope;
|
|
53889
|
+
}
|
|
53890
|
+
async function runStep2Gitignore(wctx, force) {
|
|
53891
|
+
const { ctx, projectDir } = wctx;
|
|
53892
|
+
const currentStatus = await (0, core_1.detectGitignoreStatus)(projectDir);
|
|
53893
|
+
if (currentStatus === "installed") {
|
|
53894
|
+
if (!force) {
|
|
53895
|
+
(0, prompts_js_1.printStatus)(ctx, "success", "Sidekick entries already present in .gitignore");
|
|
53896
|
+
}
|
|
53897
|
+
return "installed";
|
|
53898
|
+
}
|
|
53899
|
+
if (force) {
|
|
53900
|
+
const result2 = await (0, core_1.installGitignoreSection)(projectDir);
|
|
53901
|
+
return result2.status === "error" ? "missing" : "installed";
|
|
53902
|
+
}
|
|
53903
|
+
(0, prompts_js_1.printHeader)(ctx, "Step 2: Git Configuration", "Sidekick creates logs and session data that should not be committed.");
|
|
53904
|
+
const shouldInstall = await (0, prompts_js_1.promptConfirm)(ctx, "Update .gitignore to exclude sidekick transient files?", true);
|
|
53905
|
+
if (!shouldInstall) {
|
|
53906
|
+
(0, prompts_js_1.printStatus)(ctx, "info", "Skipping .gitignore configuration (you can manage it manually)");
|
|
53907
|
+
return "missing";
|
|
53908
|
+
}
|
|
53909
|
+
const result = await (0, core_1.installGitignoreSection)(projectDir);
|
|
53910
|
+
if (result.status === "error") {
|
|
53911
|
+
(0, prompts_js_1.printStatus)(ctx, "warning", `Failed to update .gitignore: ${result.error}`);
|
|
53912
|
+
return "missing";
|
|
53913
|
+
}
|
|
53914
|
+
const message = result.status === "already-installed" ? "Sidekick entries already present in .gitignore" : "Added sidekick section to .gitignore";
|
|
53915
|
+
(0, prompts_js_1.printStatus)(ctx, "success", message);
|
|
53916
|
+
return "installed";
|
|
53917
|
+
}
|
|
53918
|
+
async function runStep3Personas(wctx) {
|
|
53919
|
+
const { ctx, homeDir, projectDir } = wctx;
|
|
53920
|
+
const stdout = ctx.stdout;
|
|
53921
|
+
(0, prompts_js_1.printHeader)(ctx, "Step 3: Persona Features", "Sidekick includes AI personas (Marvin, GLaDOS, Skippy, etc.) that add\npersonality to your coding sessions with snarky messages and contextual nudges.");
|
|
53922
|
+
stdout.write("These require an OpenRouter API key (small cost per message).\n\n");
|
|
53923
|
+
const wantPersonas = await (0, prompts_js_1.promptConfirm)(ctx, "Enable persona features?", true);
|
|
53924
|
+
let apiKeyHealth = "not-required";
|
|
53925
|
+
if (!wantPersonas) {
|
|
53926
|
+
await writePersonaConfig(projectDir, homeDir, false);
|
|
53927
|
+
(0, prompts_js_1.printStatus)(ctx, "info", "Personas disabled");
|
|
53928
|
+
} else {
|
|
53929
|
+
await writePersonaConfig(projectDir, homeDir, true);
|
|
53930
|
+
apiKeyHealth = await configureApiKey(wctx);
|
|
53931
|
+
}
|
|
53932
|
+
return { wantPersonas, apiKeyHealth };
|
|
53933
|
+
}
|
|
53934
|
+
async function configureApiKey(wctx) {
|
|
53935
|
+
const { ctx, homeDir, projectDir, logger } = wctx;
|
|
53936
|
+
const stdout = ctx.stdout;
|
|
53937
|
+
const existingKey = await findExistingApiKey("OPENROUTER_API_KEY", homeDir, projectDir);
|
|
53938
|
+
if (existingKey) {
|
|
53939
|
+
(0, prompts_js_1.printStatus)(ctx, "success", "OPENROUTER_API_KEY found");
|
|
53940
|
+
stdout.write("Validating... ");
|
|
53941
|
+
const result2 = await (0, validate_api_key_js_1.validateOpenRouterKey)(existingKey, logger);
|
|
53942
|
+
if (result2.valid) {
|
|
53943
|
+
stdout.write("valid!\n");
|
|
53944
|
+
return "healthy";
|
|
53945
|
+
} else {
|
|
53946
|
+
stdout.write(`invalid (${result2.error})
|
|
53947
|
+
`);
|
|
53948
|
+
return "invalid";
|
|
53949
|
+
}
|
|
53950
|
+
}
|
|
53951
|
+
(0, prompts_js_1.printStatus)(ctx, "warning", "OPENROUTER_API_KEY not found");
|
|
53952
|
+
const configureNow = await (0, prompts_js_1.promptConfirm)(ctx, "Configure API key now?", true);
|
|
53953
|
+
if (!configureNow) {
|
|
53954
|
+
stdout.write("\n");
|
|
53955
|
+
(0, prompts_js_1.printStatus)(ctx, "warning", "Persona features will show warnings in the statusline until an API key is configured.");
|
|
53956
|
+
stdout.write("Run 'sidekick setup' again or ask Claude to help configure API keys using /sidekick-config.\n");
|
|
53957
|
+
return "missing";
|
|
53958
|
+
}
|
|
53959
|
+
const keyScope = await (0, prompts_js_1.promptSelect)(ctx, "Where should the API key be stored?", [
|
|
53960
|
+
{ value: "user", label: "User-level (~/.sidekick/.env)", description: "Works in all projects" },
|
|
53961
|
+
{ value: "project", label: "Project-level (.sidekick/.env)", description: "This project only" }
|
|
53962
|
+
]);
|
|
53963
|
+
const apiKey = await (0, prompts_js_1.promptInput)(ctx, "Paste your OpenRouter API key");
|
|
53964
|
+
stdout.write("Validating... ");
|
|
53965
|
+
const result = await (0, validate_api_key_js_1.validateOpenRouterKey)(apiKey, logger);
|
|
53966
|
+
const envPath = keyScope === "user" ? path.join(homeDir, ".sidekick", ".env") : path.join(projectDir, ".sidekick", ".env");
|
|
53967
|
+
if (result.valid) {
|
|
53968
|
+
stdout.write("valid!\n");
|
|
53969
|
+
await writeApiKeyToEnv(envPath, "OPENROUTER_API_KEY", apiKey);
|
|
53970
|
+
(0, prompts_js_1.printStatus)(ctx, "success", `API key saved to ${envPath}`);
|
|
53971
|
+
return "healthy";
|
|
53972
|
+
} else {
|
|
53973
|
+
stdout.write(`invalid (${result.error})
|
|
53974
|
+
`);
|
|
53975
|
+
(0, prompts_js_1.printStatus)(ctx, "warning", "API key validation failed, saving anyway");
|
|
53976
|
+
await writeApiKeyToEnv(envPath, "OPENROUTER_API_KEY", apiKey);
|
|
53977
|
+
return "invalid";
|
|
53978
|
+
}
|
|
53979
|
+
}
|
|
53980
|
+
async function runStep4AutoConfig(wctx) {
|
|
53981
|
+
const { ctx } = wctx;
|
|
53982
|
+
(0, prompts_js_1.printHeader)(ctx, "Step 4: Project Auto-Configuration");
|
|
53983
|
+
const autoConfig = await (0, prompts_js_1.promptSelect)(ctx, "When sidekick runs in a new project for the first time:", [
|
|
53984
|
+
{ value: "auto", label: "Auto-configure using my defaults", description: "Recommended" },
|
|
53985
|
+
{ value: "ask", label: "Ask me each time" },
|
|
53986
|
+
{ value: "manual", label: "Do nothing", description: "Manual setup only" }
|
|
53987
|
+
]);
|
|
53988
|
+
return autoConfig;
|
|
53989
|
+
}
|
|
53990
|
+
async function writeStatusFiles(wctx, state) {
|
|
53991
|
+
const { setupService } = wctx;
|
|
53992
|
+
const { statuslineScope, gitignoreStatus, wantPersonas, apiKeyHealth, autoConfig } = state;
|
|
53993
|
+
const userStatus = {
|
|
53994
|
+
version: 1,
|
|
53995
|
+
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
53996
|
+
preferences: {
|
|
53997
|
+
autoConfigureProjects: autoConfig === "auto",
|
|
53998
|
+
defaultStatuslineScope: statuslineScope,
|
|
53999
|
+
defaultApiKeyScope: wantPersonas ? "user" : "skip"
|
|
54000
|
+
},
|
|
54001
|
+
statusline: "configured",
|
|
54002
|
+
apiKeys: {
|
|
54003
|
+
OPENROUTER_API_KEY: apiKeyHealth,
|
|
54004
|
+
OPENAI_API_KEY: "not-required"
|
|
54005
|
+
}
|
|
54006
|
+
};
|
|
54007
|
+
await setupService.writeUserStatus(userStatus);
|
|
54008
|
+
const projectStatus = {
|
|
54009
|
+
version: 1,
|
|
54010
|
+
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
54011
|
+
autoConfigured: false,
|
|
54012
|
+
statusline: statuslineScope === "project" ? "configured" : "user",
|
|
54013
|
+
apiKeys: {
|
|
54014
|
+
OPENROUTER_API_KEY: apiKeyHealth === "healthy" ? "user" : apiKeyHealth,
|
|
54015
|
+
OPENAI_API_KEY: "not-required"
|
|
54016
|
+
},
|
|
54017
|
+
gitignore: gitignoreStatus
|
|
54018
|
+
};
|
|
54019
|
+
await setupService.writeProjectStatus(projectStatus);
|
|
54020
|
+
}
|
|
54021
|
+
function printSummary(wctx, state) {
|
|
54022
|
+
const { ctx } = wctx;
|
|
54023
|
+
const { statuslineScope, gitignoreStatus, wantPersonas, apiKeyHealth, autoConfig } = state;
|
|
54024
|
+
const stdout = ctx.stdout;
|
|
54025
|
+
(0, prompts_js_1.printHeader)(ctx, "Summary");
|
|
54026
|
+
(0, prompts_js_1.printStatus)(ctx, "success", `Statusline: ${statuslineScope === "user" ? "User-level" : "Project-level"}`);
|
|
54027
|
+
(0, prompts_js_1.printStatus)(ctx, gitignoreStatus === "installed" ? "success" : "info", `Gitignore: ${gitignoreStatus === "installed" ? "Configured" : "Skipped"}`);
|
|
54028
|
+
(0, prompts_js_1.printStatus)(ctx, wantPersonas ? "success" : "info", `Personas: ${wantPersonas ? "Enabled" : "Disabled"}`);
|
|
54029
|
+
const apiKeyStatusType = getApiKeyStatusType(apiKeyHealth);
|
|
54030
|
+
(0, prompts_js_1.printStatus)(ctx, apiKeyStatusType, `API Key: ${apiKeyHealth}`);
|
|
54031
|
+
(0, prompts_js_1.printStatus)(ctx, "success", `Auto-configure: ${autoConfig === "auto" ? "Enabled" : "Disabled"}`);
|
|
54032
|
+
stdout.write("\n");
|
|
54033
|
+
stdout.write("Restart Claude Code to see your statusline: claude --continue\n");
|
|
54034
|
+
}
|
|
54035
|
+
async function runWizard(projectDir, logger, stdout, options) {
|
|
54036
|
+
const homeDir = os.homedir();
|
|
54037
|
+
const wctx = {
|
|
54038
|
+
ctx: {
|
|
54039
|
+
stdin: options.stdin ?? process.stdin,
|
|
54040
|
+
stdout
|
|
54041
|
+
},
|
|
54042
|
+
homeDir,
|
|
54043
|
+
projectDir,
|
|
54044
|
+
logger,
|
|
54045
|
+
setupService: new core_1.SetupStatusService(projectDir, { homeDir, logger })
|
|
54046
|
+
};
|
|
54047
|
+
const force = options.force ?? false;
|
|
54048
|
+
if (!force) {
|
|
54049
|
+
printWizardHeader(stdout);
|
|
54050
|
+
}
|
|
54051
|
+
const statuslineScope = force ? "user" : await runStep1Statusline(wctx);
|
|
54052
|
+
const gitignoreStatus = await runStep2Gitignore(wctx, force);
|
|
54053
|
+
const { wantPersonas, apiKeyHealth } = force ? { wantPersonas: true, apiKeyHealth: "not-required" } : await runStep3Personas(wctx);
|
|
54054
|
+
const autoConfig = force ? "auto" : await runStep4AutoConfig(wctx);
|
|
54055
|
+
if (force) {
|
|
54056
|
+
const statuslinePath = path.join(homeDir, ".claude", "settings.json");
|
|
54057
|
+
await configureStatusline(statuslinePath, logger);
|
|
54058
|
+
}
|
|
54059
|
+
const state = { statuslineScope, gitignoreStatus, wantPersonas, apiKeyHealth, autoConfig };
|
|
54060
|
+
await writeStatusFiles(wctx, state);
|
|
54061
|
+
if (!force) {
|
|
54062
|
+
printSummary(wctx, state);
|
|
54063
|
+
} else {
|
|
54064
|
+
stdout.write("Setup complete (force mode):\n");
|
|
54065
|
+
stdout.write(` Statusline: user-level (~/.claude/settings.json)
|
|
54066
|
+
`);
|
|
54067
|
+
stdout.write(` Gitignore: ${gitignoreStatus === "installed" ? "configured" : "skipped"}
|
|
54068
|
+
`);
|
|
54069
|
+
stdout.write(` Personas: enabled (API key not configured)
|
|
54070
|
+
`);
|
|
54071
|
+
stdout.write(` Auto-configure: enabled
|
|
54072
|
+
`);
|
|
54073
|
+
}
|
|
54074
|
+
return { exitCode: 0 };
|
|
54075
|
+
}
|
|
54076
|
+
async function runDoctor(projectDir, logger, stdout) {
|
|
54077
|
+
const homeDir = os.homedir();
|
|
54078
|
+
const setupService = new core_1.SetupStatusService(projectDir, { homeDir, logger });
|
|
54079
|
+
stdout.write("\nSidekick Doctor\n");
|
|
54080
|
+
stdout.write("===============\n\n");
|
|
54081
|
+
const statusline = await setupService.getStatuslineHealth();
|
|
54082
|
+
const gitignore = await (0, core_1.detectGitignoreStatus)(projectDir);
|
|
54083
|
+
const apiKey = await setupService.getEffectiveApiKeyHealth("OPENROUTER_API_KEY");
|
|
54084
|
+
const isHealthy = await setupService.isHealthy();
|
|
54085
|
+
const statuslineIcon = statusline === "configured" ? "\u2713" : "\u26A0";
|
|
54086
|
+
const gitignoreIcon = gitignore === "installed" ? "\u2713" : "\u26A0";
|
|
54087
|
+
const apiKeyIcon = apiKey === "healthy" || apiKey === "not-required" ? "\u2713" : "\u26A0";
|
|
54088
|
+
const overallIcon = isHealthy && gitignore === "installed" ? "\u2713" : "\u26A0";
|
|
54089
|
+
stdout.write(`${statuslineIcon} Statusline: ${statusline}
|
|
54090
|
+
`);
|
|
54091
|
+
stdout.write(`${gitignoreIcon} Gitignore: ${gitignore}
|
|
54092
|
+
`);
|
|
54093
|
+
stdout.write(`${apiKeyIcon} OpenRouter API Key: ${apiKey}
|
|
54094
|
+
`);
|
|
54095
|
+
stdout.write(`${overallIcon} Overall: ${isHealthy && gitignore === "installed" ? "healthy" : "needs attention"}
|
|
54096
|
+
`);
|
|
54097
|
+
if (!isHealthy || gitignore !== "installed") {
|
|
54098
|
+
stdout.write("\nRun 'sidekick setup' to configure.\n");
|
|
54099
|
+
}
|
|
54100
|
+
return { exitCode: isHealthy && gitignore === "installed" ? 0 : 1 };
|
|
54101
|
+
}
|
|
54102
|
+
async function handleSetupCommand(projectDir, logger, stdout, options = {}) {
|
|
54103
|
+
if (options.checkOnly) {
|
|
54104
|
+
return runDoctor(projectDir, logger, stdout);
|
|
54105
|
+
}
|
|
54106
|
+
return runWizard(projectDir, logger, stdout, options);
|
|
54107
|
+
}
|
|
54108
|
+
}
|
|
54109
|
+
});
|
|
54110
|
+
|
|
54111
|
+
// ../sidekick-cli/dist/commands/setup.js
|
|
54112
|
+
var require_setup2 = __commonJS({
|
|
54113
|
+
"../sidekick-cli/dist/commands/setup.js"(exports2) {
|
|
54114
|
+
"use strict";
|
|
54115
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
54116
|
+
exports2.handleSetupCommand = void 0;
|
|
54117
|
+
var index_js_1 = require_setup();
|
|
54118
|
+
Object.defineProperty(exports2, "handleSetupCommand", { enumerable: true, get: function() {
|
|
54119
|
+
return index_js_1.handleSetupCommand;
|
|
54120
|
+
} });
|
|
54121
|
+
}
|
|
54122
|
+
});
|
|
54123
|
+
|
|
53108
54124
|
// ../sidekick-cli/dist/cli.js
|
|
53109
54125
|
var require_cli = __commonJS({
|
|
53110
54126
|
"../sidekick-cli/dist/cli.js"(exports2) {
|
|
@@ -53159,6 +54175,7 @@ var require_cli = __commonJS({
|
|
|
53159
54175
|
var promises_12 = require("node:fs/promises");
|
|
53160
54176
|
var node_stream_1 = require("node:stream");
|
|
53161
54177
|
var yargs_parser_1 = __importDefault2(require_build());
|
|
54178
|
+
var VERSION = true ? "0.0.4-alpha" : "dev";
|
|
53162
54179
|
function isInSandbox() {
|
|
53163
54180
|
return process.env.SANDBOX_RUNTIME === "1";
|
|
53164
54181
|
}
|
|
@@ -53171,26 +54188,23 @@ Example: { "command": "pnpm sidekick daemon status", "dangerouslyDisableSandbox"
|
|
|
53171
54188
|
`;
|
|
53172
54189
|
var types_1 = require_dist();
|
|
53173
54190
|
var runtime_1 = require_runtime();
|
|
53174
|
-
var hook_js_1 = require_hook();
|
|
53175
54191
|
function parseArgs(argv) {
|
|
53176
54192
|
const parsed = (0, yargs_parser_1.default)(argv, {
|
|
53177
|
-
boolean: ["
|
|
53178
|
-
string: ["
|
|
54193
|
+
boolean: ["wait", "open", "prefer-project", "help", "version", "kill", "force"],
|
|
54194
|
+
string: ["project-dir", "log-level", "format", "host", "session-id", "type"],
|
|
53179
54195
|
number: ["port", "width"],
|
|
53180
54196
|
alias: {
|
|
53181
|
-
h: "help"
|
|
54197
|
+
h: "help",
|
|
54198
|
+
v: "version"
|
|
53182
54199
|
},
|
|
53183
54200
|
configuration: {
|
|
53184
54201
|
"camel-case-expansion": false
|
|
53185
54202
|
}
|
|
53186
54203
|
});
|
|
53187
|
-
const command = parsed._[0]
|
|
54204
|
+
const command = parsed._[0];
|
|
53188
54205
|
return {
|
|
53189
54206
|
command,
|
|
53190
|
-
hookMode: Boolean(parsed.hook),
|
|
53191
|
-
hookScriptPath: parsed["hook-script-path"],
|
|
53192
54207
|
projectDir: parsed["project-dir"],
|
|
53193
|
-
scopeOverride: parsed.scope,
|
|
53194
54208
|
logLevel: parsed["log-level"],
|
|
53195
54209
|
wait: Boolean(parsed.wait),
|
|
53196
54210
|
format: parsed.format,
|
|
@@ -53202,6 +54216,7 @@ Example: { "command": "pnpm sidekick daemon status", "dangerouslyDisableSandbox"
|
|
|
53202
54216
|
sessionIdArg: parsed["session-id"],
|
|
53203
54217
|
messageType: parsed.type,
|
|
53204
54218
|
help: Boolean(parsed.help),
|
|
54219
|
+
version: Boolean(parsed.version),
|
|
53205
54220
|
kill: Boolean(parsed.kill),
|
|
53206
54221
|
force: Boolean(parsed.force),
|
|
53207
54222
|
_: parsed._
|
|
@@ -53240,12 +54255,9 @@ Example: { "command": "pnpm sidekick daemon status", "dangerouslyDisableSandbox"
|
|
|
53240
54255
|
const homeDir = options.homeDir ?? options.env?.HOME;
|
|
53241
54256
|
const hookInput = parseHookInput(options.stdinData);
|
|
53242
54257
|
const runtime = (0, runtime_1.bootstrapRuntime)({
|
|
53243
|
-
hookScriptPath: parsed.hookScriptPath,
|
|
53244
54258
|
projectDir: parsed.projectDir,
|
|
53245
|
-
scopeOverride: parsed.scopeOverride,
|
|
53246
54259
|
logLevel: parsed.logLevel,
|
|
53247
54260
|
stderrSink: stderr,
|
|
53248
|
-
cwd: options.cwd,
|
|
53249
54261
|
homeDir,
|
|
53250
54262
|
command: parsed.command,
|
|
53251
54263
|
interactive: options.interactive ?? false,
|
|
@@ -53254,15 +54266,12 @@ Example: { "command": "pnpm sidekick daemon status", "dangerouslyDisableSandbox"
|
|
|
53254
54266
|
if (hookInput) {
|
|
53255
54267
|
runtime.logger.debug("Hook input received", { hookInput: hookInput.raw });
|
|
53256
54268
|
}
|
|
53257
|
-
const shouldExit = runtime.scope.dualInstallDetected && parsed.scopeOverride !== "project";
|
|
53258
|
-
if (shouldExit) {
|
|
53259
|
-
runtime.logger.warn("User-scope hook detected project installation. Exiting to prevent duplicate execution.");
|
|
53260
|
-
}
|
|
53261
54269
|
return {
|
|
53262
54270
|
runtime,
|
|
53263
54271
|
hookInput,
|
|
53264
54272
|
parsed,
|
|
53265
|
-
shouldExit
|
|
54273
|
+
shouldExit: false
|
|
54274
|
+
// No longer needed - Claude Code handles deduplication
|
|
53266
54275
|
};
|
|
53267
54276
|
}
|
|
53268
54277
|
async function initializeSession(options) {
|
|
@@ -53308,9 +54317,12 @@ Commands:
|
|
|
53308
54317
|
statusline Render the status line (used by hooks)
|
|
53309
54318
|
dev-mode <subcommand> Manage development hooks (enable, disable, status, clean)
|
|
53310
54319
|
ui Launch the web UI
|
|
54320
|
+
setup Run the setup wizard (configure statusline, API keys)
|
|
54321
|
+
doctor Check sidekick health (alias: setup --check)
|
|
53311
54322
|
|
|
53312
54323
|
Global Options:
|
|
53313
54324
|
--help, -h Show this help message
|
|
54325
|
+
--version, -v Show version number
|
|
53314
54326
|
--format=<format> Output format: json or table (command-specific)
|
|
53315
54327
|
--width=<n> Table width in characters (default: 100)
|
|
53316
54328
|
--project-dir=<path> Override project directory
|
|
@@ -53327,36 +54339,10 @@ Examples:
|
|
|
53327
54339
|
return { exitCode: 0, stdout: GLOBAL_HELP_TEXT, stderr: "" };
|
|
53328
54340
|
}
|
|
53329
54341
|
async function routeCommand(context) {
|
|
53330
|
-
const { parsed, runtime, hookInput, stdout
|
|
54342
|
+
const { parsed, runtime, hookInput, stdout } = context;
|
|
53331
54343
|
runtime.logger.debug("Raw hook input", { hookInput });
|
|
53332
|
-
if (parsed.
|
|
53333
|
-
|
|
53334
|
-
if (hookName) {
|
|
53335
|
-
const result = await (0, hook_js_1.handleHookCommand)(hookName, {
|
|
53336
|
-
projectRoot: runtime.scope.projectRoot,
|
|
53337
|
-
sessionId: hookInput.sessionId,
|
|
53338
|
-
hookInput,
|
|
53339
|
-
correlationId: runtime.correlationId,
|
|
53340
|
-
scope: runtime.scope.scope,
|
|
53341
|
-
runtime
|
|
53342
|
-
}, runtime.logger, stdout);
|
|
53343
|
-
return { exitCode: result.exitCode, stdout: result.output, stderr: "" };
|
|
53344
|
-
}
|
|
53345
|
-
}
|
|
53346
|
-
if (!parsed.hookMode) {
|
|
53347
|
-
const isDefaultCommand = parsed.command === "session-start";
|
|
53348
|
-
const isHelpCommand = parsed.command === "help" || parsed.command === "--help" || parsed.command === "-h";
|
|
53349
|
-
if (parsed.help && isDefaultCommand || isHelpCommand) {
|
|
53350
|
-
return showGlobalHelp(stdout);
|
|
53351
|
-
}
|
|
53352
|
-
}
|
|
53353
|
-
if (parsed.hookMode && !hookInput) {
|
|
53354
|
-
runtime.logger.warn("Hook mode invoked without valid hook input, returning empty response", {
|
|
53355
|
-
command: parsed.command,
|
|
53356
|
-
daemonStarted
|
|
53357
|
-
});
|
|
53358
|
-
stdout.write("{}\n");
|
|
53359
|
-
return { exitCode: 0, stdout: "{}", stderr: "" };
|
|
54344
|
+
if (!parsed.command || parsed.command === "help") {
|
|
54345
|
+
return showGlobalHelp(stdout);
|
|
53360
54346
|
}
|
|
53361
54347
|
if (parsed.command === "hook") {
|
|
53362
54348
|
const { parseHookArg, handleUnifiedHookCommand } = await Promise.resolve().then(() => __importStar(require_hook_command()));
|
|
@@ -53384,27 +54370,31 @@ Examples:
|
|
|
53384
54370
|
return { exitCode: 0, stdout: helpText, stderr: "" };
|
|
53385
54371
|
}
|
|
53386
54372
|
if (!hookName) {
|
|
53387
|
-
const
|
|
54373
|
+
const errorMsg2 = `Error: Unknown hook name '${hookArg}'
|
|
53388
54374
|
Run 'sidekick hook --help' for available hooks.
|
|
53389
54375
|
`;
|
|
53390
|
-
stdout.write(
|
|
53391
|
-
return { exitCode: 1, stdout:
|
|
54376
|
+
stdout.write(errorMsg2);
|
|
54377
|
+
return { exitCode: 1, stdout: errorMsg2, stderr: "" };
|
|
54378
|
+
}
|
|
54379
|
+
if (!parsed.projectDir) {
|
|
54380
|
+
const errorMsg2 = "Hook command requires --project-dir to be specified\n";
|
|
54381
|
+
stdout.write(errorMsg2);
|
|
54382
|
+
return { exitCode: 1, stdout: errorMsg2, stderr: "" };
|
|
53392
54383
|
}
|
|
53393
54384
|
if (!hookInput) {
|
|
53394
54385
|
runtime.logger.warn("Hook command invoked without valid hook input", { hookName });
|
|
53395
54386
|
stdout.write("{}\n");
|
|
53396
54387
|
return { exitCode: 0, stdout: "{}", stderr: "" };
|
|
53397
54388
|
}
|
|
53398
|
-
if (!runtime.
|
|
54389
|
+
if (!runtime.projectRoot) {
|
|
53399
54390
|
runtime.logger.warn("Hook command invoked without project root", { hookName });
|
|
53400
54391
|
stdout.write("{}\n");
|
|
53401
54392
|
return { exitCode: 0, stdout: "{}", stderr: "" };
|
|
53402
54393
|
}
|
|
53403
54394
|
const result = await handleUnifiedHookCommand(hookName, {
|
|
53404
|
-
projectRoot: runtime.
|
|
54395
|
+
projectRoot: runtime.projectRoot,
|
|
53405
54396
|
hookInput,
|
|
53406
54397
|
correlationId: runtime.correlationId,
|
|
53407
|
-
scope: runtime.scope.scope,
|
|
53408
54398
|
runtime
|
|
53409
54399
|
}, runtime.logger, stdout);
|
|
53410
54400
|
return { exitCode: result.exitCode, stdout: result.output, stderr: "" };
|
|
@@ -53416,7 +54406,9 @@ Run 'sidekick hook --help' for available hooks.
|
|
|
53416
54406
|
return { exitCode: 1, stdout: SANDBOX_ERROR_MESSAGE, stderr: "" };
|
|
53417
54407
|
}
|
|
53418
54408
|
const { handleDaemonCommand } = await Promise.resolve().then(() => __importStar(require_daemon()));
|
|
53419
|
-
const result = await handleDaemonCommand(subcommand, runtime.
|
|
54409
|
+
const result = await handleDaemonCommand(subcommand, runtime.projectRoot || process.cwd(), runtime.logger, stdout, {
|
|
54410
|
+
wait: parsed.wait
|
|
54411
|
+
});
|
|
53420
54412
|
return { exitCode: result.exitCode, stdout: "", stderr: "" };
|
|
53421
54413
|
}
|
|
53422
54414
|
if (parsed.command === "statusline") {
|
|
@@ -53424,7 +54416,7 @@ Run 'sidekick hook --help' for available hooks.
|
|
|
53424
54416
|
const sessionId = parsed.sessionIdArg ?? hookInput?.sessionId;
|
|
53425
54417
|
const parsedHookInput = hookInput?.raw ? parseStatuslineInput(hookInput.raw) : void 0;
|
|
53426
54418
|
const statuslineFormat = parsed.format === "text" || parsed.format === "json" ? parsed.format : void 0;
|
|
53427
|
-
const result = await handleStatuslineCommand(runtime.
|
|
54419
|
+
const result = await handleStatuslineCommand(runtime.projectRoot || process.cwd(), runtime.logger, stdout, {
|
|
53428
54420
|
format: statuslineFormat,
|
|
53429
54421
|
sessionId,
|
|
53430
54422
|
hookInput: parsedHookInput,
|
|
@@ -53436,7 +54428,7 @@ Run 'sidekick hook --help' for available hooks.
|
|
|
53436
54428
|
}
|
|
53437
54429
|
if (parsed.command === "ui") {
|
|
53438
54430
|
const { handleUiCommand } = await Promise.resolve().then(() => __importStar(require_ui()));
|
|
53439
|
-
const result = await handleUiCommand(runtime.
|
|
54431
|
+
const result = await handleUiCommand(runtime.projectRoot || process.cwd(), runtime.logger, stdout, {
|
|
53440
54432
|
port: parsed.port,
|
|
53441
54433
|
host: parsed.host,
|
|
53442
54434
|
open: parsed.open,
|
|
@@ -53448,7 +54440,7 @@ Run 'sidekick hook --help' for available hooks.
|
|
|
53448
54440
|
const { handlePersonaCommand } = await Promise.resolve().then(() => __importStar(require_persona2()));
|
|
53449
54441
|
const subcommand = parsed.help ? "--help" : parsed._?.[1];
|
|
53450
54442
|
const args = parsed._?.slice(2) ?? [];
|
|
53451
|
-
const result = await handlePersonaCommand(subcommand, args, runtime.
|
|
54443
|
+
const result = await handlePersonaCommand(subcommand, args, runtime.projectRoot || process.cwd(), runtime.logger, stdout, {
|
|
53452
54444
|
sessionId: parsed.sessionIdArg,
|
|
53453
54445
|
format: parsed.format === "json" || parsed.format === "table" ? parsed.format : void 0,
|
|
53454
54446
|
testType: parsed.messageType,
|
|
@@ -53458,7 +54450,7 @@ Run 'sidekick hook --help' for available hooks.
|
|
|
53458
54450
|
}
|
|
53459
54451
|
if (parsed.command === "sessions") {
|
|
53460
54452
|
const { handleSessionsCommand } = await Promise.resolve().then(() => __importStar(require_sessions()));
|
|
53461
|
-
const result = await handleSessionsCommand(runtime.
|
|
54453
|
+
const result = await handleSessionsCommand(runtime.projectRoot || process.cwd(), runtime.logger, stdout, {
|
|
53462
54454
|
format: parsed.format === "json" || parsed.format === "table" ? parsed.format : void 0,
|
|
53463
54455
|
help: parsed.help,
|
|
53464
54456
|
width: parsed.width
|
|
@@ -53468,14 +54460,29 @@ Run 'sidekick hook --help' for available hooks.
|
|
|
53468
54460
|
if (parsed.command === "dev-mode") {
|
|
53469
54461
|
const subcommand = parsed.help ? "--help" : parsed._ && parsed._[1] || "status";
|
|
53470
54462
|
const { handleDevModeCommand } = await Promise.resolve().then(() => __importStar(require_dev_mode()));
|
|
53471
|
-
const result = await handleDevModeCommand(subcommand, runtime.
|
|
54463
|
+
const result = await handleDevModeCommand(subcommand, runtime.projectRoot || process.cwd(), runtime.logger, stdout, { force: Boolean(parsed.force) });
|
|
53472
54464
|
return { exitCode: result.exitCode, stdout: "", stderr: "" };
|
|
53473
54465
|
}
|
|
53474
|
-
if (
|
|
53475
|
-
|
|
53476
|
-
|
|
54466
|
+
if (parsed.command === "setup") {
|
|
54467
|
+
const { handleSetupCommand } = await Promise.resolve().then(() => __importStar(require_setup2()));
|
|
54468
|
+
const result = await handleSetupCommand(runtime.projectRoot || process.cwd(), runtime.logger, stdout, {
|
|
54469
|
+
checkOnly: parsed.help ? false : parsed._?.[1] === "--check",
|
|
54470
|
+
stdin: process.stdin
|
|
54471
|
+
});
|
|
54472
|
+
return { exitCode: result.exitCode, stdout: "", stderr: "" };
|
|
54473
|
+
}
|
|
54474
|
+
if (parsed.command === "doctor") {
|
|
54475
|
+
const { handleSetupCommand } = await Promise.resolve().then(() => __importStar(require_setup2()));
|
|
54476
|
+
const result = await handleSetupCommand(runtime.projectRoot || process.cwd(), runtime.logger, stdout, {
|
|
54477
|
+
checkOnly: true
|
|
54478
|
+
});
|
|
54479
|
+
return { exitCode: result.exitCode, stdout: "", stderr: "" };
|
|
53477
54480
|
}
|
|
53478
|
-
|
|
54481
|
+
const errorMsg = `Unknown command: ${parsed.command}
|
|
54482
|
+
Run 'sidekick help' for available commands.
|
|
54483
|
+
`;
|
|
54484
|
+
stdout.write(errorMsg);
|
|
54485
|
+
return { exitCode: 1, stdout: errorMsg, stderr: "" };
|
|
53479
54486
|
}
|
|
53480
54487
|
async function persistCliLogMetrics(stateService, sessionId, counts, logger) {
|
|
53481
54488
|
const logMetricsPath = stateService.sessionStatePath(sessionId, "cli-log-metrics.json");
|
|
@@ -53497,6 +54504,16 @@ Run 'sidekick hook --help' for available hooks.
|
|
|
53497
54504
|
}
|
|
53498
54505
|
async function runCli(options) {
|
|
53499
54506
|
const stdout = options.stdout ?? new node_stream_1.PassThrough();
|
|
54507
|
+
const quickParsed = (0, yargs_parser_1.default)(options.argv, {
|
|
54508
|
+
boolean: ["version"],
|
|
54509
|
+
alias: { v: "version" }
|
|
54510
|
+
});
|
|
54511
|
+
if (quickParsed.version) {
|
|
54512
|
+
const versionOutput = `${VERSION}
|
|
54513
|
+
`;
|
|
54514
|
+
stdout.write(versionOutput);
|
|
54515
|
+
return { exitCode: 0, stdout: versionOutput, stderr: "" };
|
|
54516
|
+
}
|
|
53500
54517
|
const initResult = initializeRuntime(options);
|
|
53501
54518
|
if (initResult.shouldExit) {
|
|
53502
54519
|
return { exitCode: 0, stdout: "", stderr: "" };
|
|
@@ -53512,18 +54529,17 @@ Run 'sidekick hook --help' for available hooks.
|
|
|
53512
54529
|
stateService: runtime.stateService,
|
|
53513
54530
|
logger: runtime.logger
|
|
53514
54531
|
});
|
|
53515
|
-
const isHookExecution = parsed.
|
|
53516
|
-
|
|
54532
|
+
const isHookExecution = parsed.command === "hook" && Boolean(parsed.projectDir);
|
|
54533
|
+
await ensureDaemon({
|
|
53517
54534
|
hookMode: isHookExecution,
|
|
53518
|
-
projectRoot: runtime.
|
|
54535
|
+
projectRoot: runtime.projectRoot,
|
|
53519
54536
|
logger: runtime.logger
|
|
53520
54537
|
});
|
|
53521
54538
|
const result = await routeCommand({
|
|
53522
54539
|
parsed,
|
|
53523
54540
|
runtime,
|
|
53524
54541
|
hookInput,
|
|
53525
|
-
stdout
|
|
53526
|
-
daemonStarted
|
|
54542
|
+
stdout
|
|
53527
54543
|
});
|
|
53528
54544
|
if (sessionId) {
|
|
53529
54545
|
await persistCliLogMetrics(runtime.stateService, sessionId, runtime.getLogCounts(), runtime.logger);
|