@scotthamilton77/sidekick 0.0.8-alpha.3 → 0.0.8-alpha.5
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 +496 -13
- package/dist/daemon.js +12 -4
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -51667,6 +51667,7 @@ var require_setup_status_service = __commonJS({
|
|
|
51667
51667
|
}
|
|
51668
51668
|
};
|
|
51669
51669
|
const child = (0, node_child_process_1.spawn)("claude", ["plugin", "list", "--json"], {
|
|
51670
|
+
cwd: this.projectDir,
|
|
51670
51671
|
stdio: ["ignore", "pipe", "pipe"]
|
|
51671
51672
|
});
|
|
51672
51673
|
let stdout = "";
|
|
@@ -51875,6 +51876,7 @@ var require_setup_status_service = __commonJS({
|
|
|
51875
51876
|
this.logger?.info("Auto-configuring project with user defaults", {
|
|
51876
51877
|
projectDir: this.projectDir
|
|
51877
51878
|
});
|
|
51879
|
+
const existing = await this.getProjectStatus();
|
|
51878
51880
|
const projectStatus = {
|
|
51879
51881
|
version: 1,
|
|
51880
51882
|
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -51884,7 +51886,8 @@ var require_setup_status_service = __commonJS({
|
|
|
51884
51886
|
OPENROUTER_API_KEY: "user",
|
|
51885
51887
|
OPENAI_API_KEY: "user"
|
|
51886
51888
|
},
|
|
51887
|
-
gitignore: "unknown"
|
|
51889
|
+
gitignore: "unknown",
|
|
51890
|
+
...existing?.devMode !== void 0 && { devMode: existing.devMode }
|
|
51888
51891
|
};
|
|
51889
51892
|
await this.writeProjectStatus(projectStatus);
|
|
51890
51893
|
this.logger?.info("Project auto-configured successfully", {
|
|
@@ -51928,6 +51931,7 @@ var require_setup_status_service = __commonJS({
|
|
|
51928
51931
|
if (projectStatus) {
|
|
51929
51932
|
await this.updateProjectStatus({ statusline: actualStatusline });
|
|
51930
51933
|
} else {
|
|
51934
|
+
const existingForDevMode = await this.getProjectStatus();
|
|
51931
51935
|
await this.writeProjectStatus({
|
|
51932
51936
|
version: 1,
|
|
51933
51937
|
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -51937,7 +51941,8 @@ var require_setup_status_service = __commonJS({
|
|
|
51937
51941
|
OPENROUTER_API_KEY: "user",
|
|
51938
51942
|
OPENAI_API_KEY: "user"
|
|
51939
51943
|
},
|
|
51940
|
-
gitignore: "unknown"
|
|
51944
|
+
gitignore: "unknown",
|
|
51945
|
+
...existingForDevMode?.devMode !== void 0 && { devMode: existingForDevMode.devMode }
|
|
51941
51946
|
});
|
|
51942
51947
|
}
|
|
51943
51948
|
} else {
|
|
@@ -51987,6 +51992,7 @@ var require_setup_status_service = __commonJS({
|
|
|
51987
51992
|
});
|
|
51988
51993
|
} else {
|
|
51989
51994
|
const userApiKeyStatus = this.buildUserApiKeyStatus(detection);
|
|
51995
|
+
const existingForDevMode = await this.getProjectStatus();
|
|
51990
51996
|
await this.writeProjectStatus({
|
|
51991
51997
|
version: 1,
|
|
51992
51998
|
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -51996,7 +52002,8 @@ var require_setup_status_service = __commonJS({
|
|
|
51996
52002
|
OPENROUTER_API_KEY: keyName === "OPENROUTER_API_KEY" ? projectApiKeyStatus : "user",
|
|
51997
52003
|
OPENAI_API_KEY: keyName === "OPENAI_API_KEY" ? projectApiKeyStatus : "user"
|
|
51998
52004
|
},
|
|
51999
|
-
gitignore: "unknown"
|
|
52005
|
+
gitignore: "unknown",
|
|
52006
|
+
...existingForDevMode?.devMode !== void 0 && { devMode: existingForDevMode.devMode }
|
|
52000
52007
|
});
|
|
52001
52008
|
const userStatus = await this.getUserStatus();
|
|
52002
52009
|
if (!userStatus) {
|
|
@@ -52086,7 +52093,8 @@ var require_setup_status_service = __commonJS({
|
|
|
52086
52093
|
}
|
|
52087
52094
|
};
|
|
52088
52095
|
const child = (0, node_child_process_1.spawn)("claude", ["-p", prompt], {
|
|
52089
|
-
|
|
52096
|
+
cwd: this.projectDir,
|
|
52097
|
+
env: { ...process.env, SIDEKICK_LIVENESS_CHECK: safeWord },
|
|
52090
52098
|
stdio: ["ignore", "pipe", "pipe"]
|
|
52091
52099
|
});
|
|
52092
52100
|
let stdout = "";
|
|
@@ -68288,9 +68296,23 @@ var require_hook_command = __commonJS({
|
|
|
68288
68296
|
}
|
|
68289
68297
|
}
|
|
68290
68298
|
async function handleUnifiedHookCommand(hookName, options, logger, stdout) {
|
|
68291
|
-
const { projectRoot, hookInput, correlationId, runtime,
|
|
68299
|
+
const { projectRoot, hookInput, correlationId, runtime, forceDevMode } = options;
|
|
68292
68300
|
logger.debug("Unified hook command invoked", { hookName, sessionId: hookInput.sessionId });
|
|
68293
|
-
if (
|
|
68301
|
+
if (forceDevMode) {
|
|
68302
|
+
try {
|
|
68303
|
+
const setupService = new core_1.SetupStatusService(projectRoot);
|
|
68304
|
+
const devMode = await setupService.getDevMode();
|
|
68305
|
+
if (!devMode) {
|
|
68306
|
+
logger.warn("Dev-mode hooks running but devMode flag is off \u2014 auto-correcting", { hookName });
|
|
68307
|
+
await setupService.setDevMode(true);
|
|
68308
|
+
}
|
|
68309
|
+
} catch (err) {
|
|
68310
|
+
logger.warn("Failed to auto-correct devMode flag", {
|
|
68311
|
+
error: err instanceof Error ? err.message : String(err),
|
|
68312
|
+
hookName
|
|
68313
|
+
});
|
|
68314
|
+
}
|
|
68315
|
+
} else {
|
|
68294
68316
|
try {
|
|
68295
68317
|
const setupService = new core_1.SetupStatusService(projectRoot);
|
|
68296
68318
|
const devMode = await setupService.getDevMode();
|
|
@@ -68313,7 +68335,8 @@ var require_hook_command = __commonJS({
|
|
|
68313
68335
|
await maybeAutoConfigureProject(projectRoot, logger);
|
|
68314
68336
|
}
|
|
68315
68337
|
await ensureDaemonForHook(projectRoot, logger);
|
|
68316
|
-
const
|
|
68338
|
+
const isLivenessCheck = !!process.env.SIDEKICK_LIVENESS_CHECK;
|
|
68339
|
+
const degradedResponse = isLivenessCheck ? null : await checkSetupState(projectRoot, hookName, logger);
|
|
68317
68340
|
if (degradedResponse !== null) {
|
|
68318
68341
|
const claudeResponse2 = translateToClaudeCodeFormat(hookName, degradedResponse);
|
|
68319
68342
|
const outputStr2 = JSON.stringify(claudeResponse2);
|
|
@@ -68338,7 +68361,7 @@ var require_hook_command = __commonJS({
|
|
|
68338
68361
|
}, logger, captureStream);
|
|
68339
68362
|
const internalResponse = parseInternalResponse(internalOutput.trim(), hookName, logger);
|
|
68340
68363
|
if (hookName === "SessionStart") {
|
|
68341
|
-
const safeWord = process.env.
|
|
68364
|
+
const safeWord = process.env.SIDEKICK_LIVENESS_CHECK ?? "nope";
|
|
68342
68365
|
const safeWordContext = loadSafeWordContext(safeWord, projectRoot, logger);
|
|
68343
68366
|
if (safeWordContext) {
|
|
68344
68367
|
internalResponse.additionalContext = internalResponse.additionalContext ? `${internalResponse.additionalContext}
|
|
@@ -71155,7 +71178,20 @@ Examples:
|
|
|
71155
71178
|
stdout.write(USAGE_TEXT);
|
|
71156
71179
|
return { exitCode: 0 };
|
|
71157
71180
|
}
|
|
71158
|
-
if (
|
|
71181
|
+
if (options.forceDevMode) {
|
|
71182
|
+
try {
|
|
71183
|
+
const setupService = new core_1.SetupStatusService(projectDir);
|
|
71184
|
+
const devMode = await setupService.getDevMode();
|
|
71185
|
+
if (!devMode) {
|
|
71186
|
+
logger.warn("Dev-mode statusline running but devMode flag is off \u2014 auto-correcting");
|
|
71187
|
+
await setupService.setDevMode(true);
|
|
71188
|
+
}
|
|
71189
|
+
} catch (err) {
|
|
71190
|
+
logger.warn("Failed to auto-correct devMode flag in statusline", {
|
|
71191
|
+
error: err instanceof Error ? err.message : String(err)
|
|
71192
|
+
});
|
|
71193
|
+
}
|
|
71194
|
+
} else {
|
|
71159
71195
|
try {
|
|
71160
71196
|
const setupService = new core_1.SetupStatusService(projectDir);
|
|
71161
71197
|
const devMode = await setupService.getDevMode();
|
|
@@ -73245,6 +73281,22 @@ Examples:
|
|
|
73245
73281
|
`);
|
|
73246
73282
|
configuredCount++;
|
|
73247
73283
|
}
|
|
73284
|
+
if (configuredCount > 0) {
|
|
73285
|
+
const existingProject = await setupService.getProjectStatus();
|
|
73286
|
+
const projectStatus = {
|
|
73287
|
+
version: 1,
|
|
73288
|
+
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
73289
|
+
autoConfigured: false,
|
|
73290
|
+
statusline: options.statuslineScope ?? existingProject?.statusline ?? "none",
|
|
73291
|
+
apiKeys: existingProject?.apiKeys ?? {
|
|
73292
|
+
OPENROUTER_API_KEY: core_1.SetupStatusService.projectApiKeyStatusFromHealth("not-required"),
|
|
73293
|
+
OPENAI_API_KEY: core_1.SetupStatusService.projectApiKeyStatusFromHealth("not-required")
|
|
73294
|
+
},
|
|
73295
|
+
gitignore: options.gitignore ? "installed" : existingProject?.gitignore ?? "unknown",
|
|
73296
|
+
...existingProject?.devMode !== void 0 && { devMode: existingProject.devMode }
|
|
73297
|
+
};
|
|
73298
|
+
await setupService.writeProjectStatus(projectStatus);
|
|
73299
|
+
}
|
|
73248
73300
|
if (configuredCount === 0) {
|
|
73249
73301
|
stdout.write("No configuration changes made. Use --help to see available options.\n");
|
|
73250
73302
|
} else {
|
|
@@ -73342,6 +73394,413 @@ var require_setup2 = __commonJS({
|
|
|
73342
73394
|
}
|
|
73343
73395
|
});
|
|
73344
73396
|
|
|
73397
|
+
// ../sidekick-cli/dist/commands/uninstall.js
|
|
73398
|
+
var require_uninstall = __commonJS({
|
|
73399
|
+
"../sidekick-cli/dist/commands/uninstall.js"(exports2) {
|
|
73400
|
+
"use strict";
|
|
73401
|
+
var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
73402
|
+
if (k2 === void 0) k2 = k;
|
|
73403
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
73404
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
73405
|
+
desc = { enumerable: true, get: function() {
|
|
73406
|
+
return m[k];
|
|
73407
|
+
} };
|
|
73408
|
+
}
|
|
73409
|
+
Object.defineProperty(o, k2, desc);
|
|
73410
|
+
}) : (function(o, m, k, k2) {
|
|
73411
|
+
if (k2 === void 0) k2 = k;
|
|
73412
|
+
o[k2] = m[k];
|
|
73413
|
+
}));
|
|
73414
|
+
var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) {
|
|
73415
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
73416
|
+
}) : function(o, v) {
|
|
73417
|
+
o["default"] = v;
|
|
73418
|
+
});
|
|
73419
|
+
var __importStar = exports2 && exports2.__importStar || /* @__PURE__ */ (function() {
|
|
73420
|
+
var ownKeys = function(o) {
|
|
73421
|
+
ownKeys = Object.getOwnPropertyNames || function(o2) {
|
|
73422
|
+
var ar = [];
|
|
73423
|
+
for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
|
|
73424
|
+
return ar;
|
|
73425
|
+
};
|
|
73426
|
+
return ownKeys(o);
|
|
73427
|
+
};
|
|
73428
|
+
return function(mod) {
|
|
73429
|
+
if (mod && mod.__esModule) return mod;
|
|
73430
|
+
var result = {};
|
|
73431
|
+
if (mod != null) {
|
|
73432
|
+
for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
73433
|
+
}
|
|
73434
|
+
__setModuleDefault(result, mod);
|
|
73435
|
+
return result;
|
|
73436
|
+
};
|
|
73437
|
+
})();
|
|
73438
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
73439
|
+
exports2.handleUninstallCommand = handleUninstallCommand;
|
|
73440
|
+
var fs = __importStar(require("node:fs/promises"));
|
|
73441
|
+
var path = __importStar(require("node:path"));
|
|
73442
|
+
var node_child_process_1 = require("node:child_process");
|
|
73443
|
+
var core_1 = require_dist4();
|
|
73444
|
+
async function handleUninstallCommand(projectDir, logger, stdout, options = {}) {
|
|
73445
|
+
const { force = false, dryRun = false, scope, userHome = process.env.HOME || "", stdin = process.stdin } = options;
|
|
73446
|
+
const actions = [];
|
|
73447
|
+
const projectDetected = scope !== "user" && await detectProjectScope(projectDir);
|
|
73448
|
+
const userDetected = scope !== "project" && await detectUserScope(userHome);
|
|
73449
|
+
if (!projectDetected && !userDetected) {
|
|
73450
|
+
stdout.write("No sidekick installation detected.\n");
|
|
73451
|
+
return { exitCode: 0, output: "" };
|
|
73452
|
+
}
|
|
73453
|
+
if (userDetected || projectDetected) {
|
|
73454
|
+
await uninstallPlugin(logger, stdout, actions, { force, dryRun });
|
|
73455
|
+
}
|
|
73456
|
+
if (projectDetected) {
|
|
73457
|
+
await killDaemon(projectDir, logger, stdout, actions, { dryRun });
|
|
73458
|
+
}
|
|
73459
|
+
if (projectDetected) {
|
|
73460
|
+
await cleanSettingsFile(path.join(projectDir, ".claude", "settings.local.json"), "project", logger, actions, {
|
|
73461
|
+
dryRun,
|
|
73462
|
+
removeHooks: true
|
|
73463
|
+
});
|
|
73464
|
+
}
|
|
73465
|
+
if (userDetected) {
|
|
73466
|
+
await cleanSettingsFile(path.join(userHome, ".claude", "settings.json"), "user", logger, actions, {
|
|
73467
|
+
dryRun,
|
|
73468
|
+
removeHooks: false
|
|
73469
|
+
});
|
|
73470
|
+
}
|
|
73471
|
+
if (projectDetected) {
|
|
73472
|
+
await removeFile(path.join(projectDir, ".sidekick", "setup-status.json"), "project", "setup-status.json", actions, {
|
|
73473
|
+
dryRun
|
|
73474
|
+
});
|
|
73475
|
+
}
|
|
73476
|
+
if (userDetected) {
|
|
73477
|
+
await removeFile(path.join(userHome, ".sidekick", "setup-status.json"), "user", "setup-status.json", actions, {
|
|
73478
|
+
dryRun
|
|
73479
|
+
});
|
|
73480
|
+
await removeFile(path.join(userHome, ".sidekick", "features.yaml"), "user", "features.yaml", actions, { dryRun });
|
|
73481
|
+
}
|
|
73482
|
+
if (projectDetected) {
|
|
73483
|
+
await handleEnvFile(path.join(projectDir, ".sidekick", ".env"), "project", stdout, actions, {
|
|
73484
|
+
force,
|
|
73485
|
+
dryRun,
|
|
73486
|
+
stdin
|
|
73487
|
+
});
|
|
73488
|
+
}
|
|
73489
|
+
if (userDetected) {
|
|
73490
|
+
await handleEnvFile(path.join(userHome, ".sidekick", ".env"), "user", stdout, actions, { force, dryRun, stdin });
|
|
73491
|
+
}
|
|
73492
|
+
if (projectDetected) {
|
|
73493
|
+
await removeDir(path.join(projectDir, ".sidekick", "logs"), "project", "logs/", actions, { dryRun });
|
|
73494
|
+
await removeDir(path.join(projectDir, ".sidekick", "sessions"), "project", "sessions/", actions, { dryRun });
|
|
73495
|
+
await removeDir(path.join(projectDir, ".sidekick", "state"), "project", "state/", actions, { dryRun });
|
|
73496
|
+
await removeFile(path.join(projectDir, ".sidekick", "sidekickd.pid"), "project", "sidekickd.pid", actions, {
|
|
73497
|
+
dryRun
|
|
73498
|
+
});
|
|
73499
|
+
await removeFile(path.join(projectDir, ".sidekick", "sidekickd.token"), "project", "sidekickd.token", actions, {
|
|
73500
|
+
dryRun
|
|
73501
|
+
});
|
|
73502
|
+
await removeFile(path.join(projectDir, ".sidekick", "sidekickd.lock"), "project", "sidekickd.lock", actions, {
|
|
73503
|
+
dryRun
|
|
73504
|
+
});
|
|
73505
|
+
}
|
|
73506
|
+
if (userDetected) {
|
|
73507
|
+
await removeDir(path.join(userHome, ".sidekick", "state"), "user", "state/", actions, { dryRun });
|
|
73508
|
+
await removeDir(path.join(userHome, ".sidekick", "daemons"), "user", "daemons/", actions, { dryRun });
|
|
73509
|
+
}
|
|
73510
|
+
if (projectDetected) {
|
|
73511
|
+
if (dryRun) {
|
|
73512
|
+
actions.push({
|
|
73513
|
+
scope: "project",
|
|
73514
|
+
artifact: ".gitignore section",
|
|
73515
|
+
path: path.join(projectDir, ".gitignore"),
|
|
73516
|
+
action: "would-remove"
|
|
73517
|
+
});
|
|
73518
|
+
} else {
|
|
73519
|
+
const removed = await (0, core_1.removeGitignoreSection)(projectDir);
|
|
73520
|
+
actions.push({
|
|
73521
|
+
scope: "project",
|
|
73522
|
+
artifact: ".gitignore section",
|
|
73523
|
+
path: path.join(projectDir, ".gitignore"),
|
|
73524
|
+
action: removed ? "removed" : "not-found"
|
|
73525
|
+
});
|
|
73526
|
+
}
|
|
73527
|
+
}
|
|
73528
|
+
printReport(stdout, actions, dryRun);
|
|
73529
|
+
return { exitCode: 0, output: "" };
|
|
73530
|
+
}
|
|
73531
|
+
async function detectProjectScope(projectDir) {
|
|
73532
|
+
try {
|
|
73533
|
+
await fs.access(path.join(projectDir, ".sidekick", "setup-status.json"));
|
|
73534
|
+
return true;
|
|
73535
|
+
} catch {
|
|
73536
|
+
try {
|
|
73537
|
+
const content = await fs.readFile(path.join(projectDir, ".claude", "settings.local.json"), "utf-8");
|
|
73538
|
+
return content.includes("sidekick");
|
|
73539
|
+
} catch {
|
|
73540
|
+
return false;
|
|
73541
|
+
}
|
|
73542
|
+
}
|
|
73543
|
+
}
|
|
73544
|
+
async function detectUserScope(userHome) {
|
|
73545
|
+
try {
|
|
73546
|
+
await fs.access(path.join(userHome, ".sidekick", "setup-status.json"));
|
|
73547
|
+
return true;
|
|
73548
|
+
} catch {
|
|
73549
|
+
try {
|
|
73550
|
+
const content = await fs.readFile(path.join(userHome, ".claude", "settings.json"), "utf-8");
|
|
73551
|
+
return content.includes("sidekick");
|
|
73552
|
+
} catch {
|
|
73553
|
+
return false;
|
|
73554
|
+
}
|
|
73555
|
+
}
|
|
73556
|
+
}
|
|
73557
|
+
async function uninstallPlugin(logger, stdout, actions, options) {
|
|
73558
|
+
try {
|
|
73559
|
+
const plugins = await execFileAsync("claude", ["plugin", "list", "--json"]);
|
|
73560
|
+
const pluginList = JSON.parse(plugins);
|
|
73561
|
+
const sidekickPlugin = pluginList.find((p) => p.id.startsWith("sidekick@"));
|
|
73562
|
+
if (!sidekickPlugin) {
|
|
73563
|
+
logger.debug("No sidekick plugin found in claude plugin list");
|
|
73564
|
+
return;
|
|
73565
|
+
}
|
|
73566
|
+
if (options.dryRun) {
|
|
73567
|
+
actions.push({
|
|
73568
|
+
scope: sidekickPlugin.scope,
|
|
73569
|
+
artifact: `Plugin (${sidekickPlugin.id})`,
|
|
73570
|
+
path: "claude plugin",
|
|
73571
|
+
action: "would-remove"
|
|
73572
|
+
});
|
|
73573
|
+
return;
|
|
73574
|
+
}
|
|
73575
|
+
logger.info("Uninstalling sidekick plugin", { id: sidekickPlugin.id, scope: sidekickPlugin.scope });
|
|
73576
|
+
await execFileAsync("claude", ["plugin", "uninstall", "sidekick", "--scope", sidekickPlugin.scope]);
|
|
73577
|
+
actions.push({
|
|
73578
|
+
scope: sidekickPlugin.scope,
|
|
73579
|
+
artifact: `Plugin (${sidekickPlugin.id})`,
|
|
73580
|
+
path: "claude plugin",
|
|
73581
|
+
action: "removed"
|
|
73582
|
+
});
|
|
73583
|
+
stdout.write(`Plugin ${sidekickPlugin.id} uninstalled.
|
|
73584
|
+
`);
|
|
73585
|
+
} catch (err) {
|
|
73586
|
+
logger.warn("Could not detect/uninstall claude plugin (claude CLI may not be available)", {
|
|
73587
|
+
error: err.message
|
|
73588
|
+
});
|
|
73589
|
+
}
|
|
73590
|
+
}
|
|
73591
|
+
function execFileAsync(cmd, args) {
|
|
73592
|
+
return new Promise((resolve3, reject) => {
|
|
73593
|
+
(0, node_child_process_1.execFile)(cmd, args, (error, stdout) => {
|
|
73594
|
+
if (error)
|
|
73595
|
+
reject(error);
|
|
73596
|
+
else
|
|
73597
|
+
resolve3(stdout);
|
|
73598
|
+
});
|
|
73599
|
+
});
|
|
73600
|
+
}
|
|
73601
|
+
async function killDaemon(projectDir, logger, _stdout, actions, options) {
|
|
73602
|
+
if (options.dryRun) {
|
|
73603
|
+
actions.push({ scope: "project", artifact: "Daemon process", path: projectDir, action: "would-remove" });
|
|
73604
|
+
return;
|
|
73605
|
+
}
|
|
73606
|
+
try {
|
|
73607
|
+
const client = new core_1.DaemonClient(projectDir, logger);
|
|
73608
|
+
const result = await client.kill();
|
|
73609
|
+
logger.info("Daemon kill result", { result });
|
|
73610
|
+
} catch (err) {
|
|
73611
|
+
logger.debug("Daemon kill failed (may not be running)", { error: err.message });
|
|
73612
|
+
}
|
|
73613
|
+
}
|
|
73614
|
+
async function cleanSettingsFile(settingsPath, scope, logger, actions, options) {
|
|
73615
|
+
let content;
|
|
73616
|
+
try {
|
|
73617
|
+
content = await fs.readFile(settingsPath, "utf-8");
|
|
73618
|
+
} catch {
|
|
73619
|
+
return;
|
|
73620
|
+
}
|
|
73621
|
+
let settings;
|
|
73622
|
+
try {
|
|
73623
|
+
settings = JSON.parse(content);
|
|
73624
|
+
} catch {
|
|
73625
|
+
logger.warn("Could not parse settings file", { path: settingsPath });
|
|
73626
|
+
return;
|
|
73627
|
+
}
|
|
73628
|
+
let modified = false;
|
|
73629
|
+
const statusLine = settings.statusLine;
|
|
73630
|
+
if (statusLine?.command?.includes("sidekick")) {
|
|
73631
|
+
if (options.dryRun) {
|
|
73632
|
+
actions.push({ scope, artifact: "statusLine", path: settingsPath, action: "would-remove" });
|
|
73633
|
+
} else {
|
|
73634
|
+
delete settings.statusLine;
|
|
73635
|
+
modified = true;
|
|
73636
|
+
actions.push({ scope, artifact: "statusLine", path: settingsPath, action: "removed" });
|
|
73637
|
+
}
|
|
73638
|
+
}
|
|
73639
|
+
if (options.removeHooks && settings.hooks) {
|
|
73640
|
+
const hooks = settings.hooks;
|
|
73641
|
+
let hooksModified = false;
|
|
73642
|
+
for (const [eventName, eventHandlers] of Object.entries(hooks)) {
|
|
73643
|
+
if (!Array.isArray(eventHandlers))
|
|
73644
|
+
continue;
|
|
73645
|
+
const filtered = eventHandlers.filter((handler) => {
|
|
73646
|
+
const h = handler;
|
|
73647
|
+
if (!h.hooks?.length)
|
|
73648
|
+
return true;
|
|
73649
|
+
return h.hooks.some((hook) => !hook.command?.includes("sidekick") && !hook.command?.includes("dev-sidekick"));
|
|
73650
|
+
});
|
|
73651
|
+
if (filtered.length !== eventHandlers.length) {
|
|
73652
|
+
if (options.dryRun) {
|
|
73653
|
+
actions.push({ scope, artifact: `hooks.${eventName}`, path: settingsPath, action: "would-remove" });
|
|
73654
|
+
} else {
|
|
73655
|
+
if (filtered.length === 0) {
|
|
73656
|
+
delete hooks[eventName];
|
|
73657
|
+
} else {
|
|
73658
|
+
hooks[eventName] = filtered;
|
|
73659
|
+
}
|
|
73660
|
+
hooksModified = true;
|
|
73661
|
+
}
|
|
73662
|
+
}
|
|
73663
|
+
}
|
|
73664
|
+
if (hooksModified) {
|
|
73665
|
+
if (Object.keys(hooks).length === 0) {
|
|
73666
|
+
delete settings.hooks;
|
|
73667
|
+
}
|
|
73668
|
+
modified = true;
|
|
73669
|
+
actions.push({ scope, artifact: "hooks", path: settingsPath, action: "removed" });
|
|
73670
|
+
}
|
|
73671
|
+
}
|
|
73672
|
+
if (modified && !options.dryRun) {
|
|
73673
|
+
if (Object.keys(settings).length === 0) {
|
|
73674
|
+
await fs.unlink(settingsPath);
|
|
73675
|
+
logger.info("Deleted empty settings file", { path: settingsPath });
|
|
73676
|
+
} else {
|
|
73677
|
+
await fs.writeFile(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
73678
|
+
logger.info("Updated settings file", { path: settingsPath });
|
|
73679
|
+
}
|
|
73680
|
+
}
|
|
73681
|
+
}
|
|
73682
|
+
async function removeFile(filePath, scope, artifact, actions, options) {
|
|
73683
|
+
try {
|
|
73684
|
+
await fs.access(filePath);
|
|
73685
|
+
} catch {
|
|
73686
|
+
return;
|
|
73687
|
+
}
|
|
73688
|
+
if (options.dryRun) {
|
|
73689
|
+
actions.push({ scope, artifact, path: filePath, action: "would-remove" });
|
|
73690
|
+
return;
|
|
73691
|
+
}
|
|
73692
|
+
try {
|
|
73693
|
+
await fs.unlink(filePath);
|
|
73694
|
+
actions.push({ scope, artifact, path: filePath, action: "removed" });
|
|
73695
|
+
} catch {
|
|
73696
|
+
actions.push({ scope, artifact, path: filePath, action: "skipped" });
|
|
73697
|
+
}
|
|
73698
|
+
}
|
|
73699
|
+
async function removeDir(dirPath, scope, artifact, actions, options) {
|
|
73700
|
+
try {
|
|
73701
|
+
await fs.access(dirPath);
|
|
73702
|
+
} catch {
|
|
73703
|
+
return;
|
|
73704
|
+
}
|
|
73705
|
+
if (options.dryRun) {
|
|
73706
|
+
actions.push({ scope, artifact, path: dirPath, action: "would-remove" });
|
|
73707
|
+
return;
|
|
73708
|
+
}
|
|
73709
|
+
try {
|
|
73710
|
+
await fs.rm(dirPath, { recursive: true, force: true });
|
|
73711
|
+
actions.push({ scope, artifact, path: dirPath, action: "removed" });
|
|
73712
|
+
} catch {
|
|
73713
|
+
actions.push({ scope, artifact, path: dirPath, action: "skipped" });
|
|
73714
|
+
}
|
|
73715
|
+
}
|
|
73716
|
+
async function handleEnvFile(envPath, scope, stdout, actions, options) {
|
|
73717
|
+
let content;
|
|
73718
|
+
try {
|
|
73719
|
+
content = await fs.readFile(envPath, "utf-8");
|
|
73720
|
+
} catch {
|
|
73721
|
+
return;
|
|
73722
|
+
}
|
|
73723
|
+
if (options.dryRun) {
|
|
73724
|
+
actions.push({ scope, artifact: ".env", path: envPath, action: "would-remove" });
|
|
73725
|
+
return;
|
|
73726
|
+
}
|
|
73727
|
+
const keyNames = content.split("\n").filter((line) => line.includes("=") && !line.startsWith("#")).map((line) => {
|
|
73728
|
+
const [key, val] = line.split("=", 2);
|
|
73729
|
+
const masked = val ? val.slice(0, 4) + "****" : "****";
|
|
73730
|
+
return ` ${key}=${masked}`;
|
|
73731
|
+
});
|
|
73732
|
+
if (keyNames.length > 0 && !options.force) {
|
|
73733
|
+
stdout.write(`
|
|
73734
|
+
${scope} scope .env contains API keys:
|
|
73735
|
+
`);
|
|
73736
|
+
stdout.write(keyNames.join("\n") + "\n");
|
|
73737
|
+
const answer = await promptYesNo(`Remove ${scope} .env file?`, stdout, options.stdin);
|
|
73738
|
+
if (!answer) {
|
|
73739
|
+
actions.push({ scope, artifact: ".env", path: envPath, action: "kept" });
|
|
73740
|
+
return;
|
|
73741
|
+
}
|
|
73742
|
+
}
|
|
73743
|
+
await fs.unlink(envPath);
|
|
73744
|
+
actions.push({ scope, artifact: ".env", path: envPath, action: "removed" });
|
|
73745
|
+
}
|
|
73746
|
+
function promptYesNo(question, stdout, stdin) {
|
|
73747
|
+
return new Promise((resolve3) => {
|
|
73748
|
+
stdout.write(`${question} [y/N] `);
|
|
73749
|
+
let data = "";
|
|
73750
|
+
const onData = (chunk) => {
|
|
73751
|
+
data += chunk.toString();
|
|
73752
|
+
if (data.includes("\n")) {
|
|
73753
|
+
stdin.removeListener("data", onData);
|
|
73754
|
+
const answer = data.trim().toLowerCase();
|
|
73755
|
+
resolve3(answer === "y" || answer === "yes");
|
|
73756
|
+
}
|
|
73757
|
+
};
|
|
73758
|
+
stdin.on("data", onData);
|
|
73759
|
+
});
|
|
73760
|
+
}
|
|
73761
|
+
function printReport(stdout, actions, dryRun) {
|
|
73762
|
+
if (actions.length === 0)
|
|
73763
|
+
return;
|
|
73764
|
+
const sortByArtifact = (a, b) => a.artifact.localeCompare(b.artifact);
|
|
73765
|
+
if (dryRun) {
|
|
73766
|
+
stdout.write("\n[dry-run] Would perform the following actions:\n");
|
|
73767
|
+
printScopeGrouped(stdout, actions, (a) => a.artifact, sortByArtifact);
|
|
73768
|
+
return;
|
|
73769
|
+
}
|
|
73770
|
+
const removed = actions.filter((a) => a.action === "removed");
|
|
73771
|
+
const kept = actions.filter((a) => a.action === "kept");
|
|
73772
|
+
const skipped = actions.filter((a) => a.action === "skipped");
|
|
73773
|
+
if (removed.length > 0) {
|
|
73774
|
+
stdout.write("\nRemoved:\n");
|
|
73775
|
+
printScopeGrouped(stdout, removed, (a) => a.artifact, sortByArtifact);
|
|
73776
|
+
}
|
|
73777
|
+
if (kept.length > 0) {
|
|
73778
|
+
stdout.write("\nKept (by request):\n");
|
|
73779
|
+
printScopeGrouped(stdout, kept, (a) => a.artifact, sortByArtifact);
|
|
73780
|
+
}
|
|
73781
|
+
if (skipped.length > 0) {
|
|
73782
|
+
stdout.write("\nSkipped (errors):\n");
|
|
73783
|
+
printScopeGrouped(stdout, skipped, (a) => a.artifact, sortByArtifact);
|
|
73784
|
+
}
|
|
73785
|
+
stdout.write("\nSidekick uninstalled. Restart Claude Code to apply changes.\n");
|
|
73786
|
+
}
|
|
73787
|
+
function printScopeGrouped(stdout, actions, label, sort) {
|
|
73788
|
+
const scopes = ["user", "project"];
|
|
73789
|
+
for (const scope of scopes) {
|
|
73790
|
+
const group = actions.filter((a) => a.scope === scope).sort(sort);
|
|
73791
|
+
if (group.length === 0)
|
|
73792
|
+
continue;
|
|
73793
|
+
stdout.write(` ${scope}:
|
|
73794
|
+
`);
|
|
73795
|
+
for (const action of group) {
|
|
73796
|
+
stdout.write(` ${label(action)}
|
|
73797
|
+
`);
|
|
73798
|
+
}
|
|
73799
|
+
}
|
|
73800
|
+
}
|
|
73801
|
+
}
|
|
73802
|
+
});
|
|
73803
|
+
|
|
73345
73804
|
// ../sidekick-cli/dist/cli.js
|
|
73346
73805
|
var require_cli = __commonJS({
|
|
73347
73806
|
"../sidekick-cli/dist/cli.js"(exports2) {
|
|
@@ -73396,7 +73855,7 @@ var require_cli = __commonJS({
|
|
|
73396
73855
|
var promises_12 = require("node:fs/promises");
|
|
73397
73856
|
var node_stream_1 = require("node:stream");
|
|
73398
73857
|
var yargs_parser_1 = __importDefault2(require_build());
|
|
73399
|
-
var VERSION = true ? "0.0.8-alpha.
|
|
73858
|
+
var VERSION = true ? "0.0.8-alpha.5" : "dev";
|
|
73400
73859
|
function isInSandbox() {
|
|
73401
73860
|
return process.env.SANDBOX_RUNTIME === "1";
|
|
73402
73861
|
}
|
|
@@ -73419,7 +73878,19 @@ Example: { "command": "pnpm sidekick daemon status", "dangerouslyDisableSandbox"
|
|
|
73419
73878
|
};
|
|
73420
73879
|
exports2.UnknownOptionError = UnknownOptionError;
|
|
73421
73880
|
var CLI_OPTIONS = {
|
|
73422
|
-
boolean: [
|
|
73881
|
+
boolean: [
|
|
73882
|
+
"wait",
|
|
73883
|
+
"open",
|
|
73884
|
+
"prefer-project",
|
|
73885
|
+
"help",
|
|
73886
|
+
"version",
|
|
73887
|
+
"kill",
|
|
73888
|
+
"force",
|
|
73889
|
+
"force-dev-mode",
|
|
73890
|
+
"dry-run",
|
|
73891
|
+
"gitignore",
|
|
73892
|
+
"personas"
|
|
73893
|
+
],
|
|
73423
73894
|
string: [
|
|
73424
73895
|
"project-dir",
|
|
73425
73896
|
"log-level",
|
|
@@ -73427,6 +73898,7 @@ Example: { "command": "pnpm sidekick daemon status", "dangerouslyDisableSandbox"
|
|
|
73427
73898
|
"host",
|
|
73428
73899
|
"session-id",
|
|
73429
73900
|
"type",
|
|
73901
|
+
"scope",
|
|
73430
73902
|
"statusline-scope",
|
|
73431
73903
|
"api-key-scope",
|
|
73432
73904
|
"auto-config"
|
|
@@ -73476,6 +73948,7 @@ Example: { "command": "pnpm sidekick daemon status", "dangerouslyDisableSandbox"
|
|
|
73476
73948
|
version: Boolean(parsed.version),
|
|
73477
73949
|
kill: Boolean(parsed.kill),
|
|
73478
73950
|
force: Boolean(parsed.force),
|
|
73951
|
+
forceDevMode: Boolean(parsed["force-dev-mode"]),
|
|
73479
73952
|
_: parsed._,
|
|
73480
73953
|
// Setup command scripting flags - only set if explicitly provided
|
|
73481
73954
|
statuslineScope: parsed["statusline-scope"],
|
|
@@ -73640,7 +74113,7 @@ Run 'sidekick hook --help' for available hooks.
|
|
|
73640
74113
|
hookInput,
|
|
73641
74114
|
correlationId: runtime.correlationId,
|
|
73642
74115
|
runtime,
|
|
73643
|
-
|
|
74116
|
+
forceDevMode: parsed.forceDevMode
|
|
73644
74117
|
}, runtime.logger, stdout);
|
|
73645
74118
|
return { exitCode: result.exitCode, stdout: result.output, stderr: "" };
|
|
73646
74119
|
}
|
|
@@ -73668,7 +74141,7 @@ Run 'sidekick hook --help' for available hooks.
|
|
|
73668
74141
|
configService: runtime.config,
|
|
73669
74142
|
assets: runtime.assets,
|
|
73670
74143
|
help: parsed.help,
|
|
73671
|
-
|
|
74144
|
+
forceDevMode: parsed.forceDevMode
|
|
73672
74145
|
});
|
|
73673
74146
|
return { exitCode: result.exitCode, stdout: "", stderr: "" };
|
|
73674
74147
|
}
|
|
@@ -73724,6 +74197,16 @@ Run 'sidekick hook --help' for available hooks.
|
|
|
73724
74197
|
});
|
|
73725
74198
|
return { exitCode: result.exitCode, stdout: "", stderr: "" };
|
|
73726
74199
|
}
|
|
74200
|
+
if (parsed.command === "uninstall") {
|
|
74201
|
+
const { handleUninstallCommand } = await Promise.resolve().then(() => __importStar(require_uninstall()));
|
|
74202
|
+
const result = await handleUninstallCommand(runtime.projectRoot || process.cwd(), runtime.logger, stdout, {
|
|
74203
|
+
force: Boolean(parsed.force),
|
|
74204
|
+
dryRun: Boolean(parsed["dry-run"]),
|
|
74205
|
+
scope: parsed.scope,
|
|
74206
|
+
stdin: process.stdin
|
|
74207
|
+
});
|
|
74208
|
+
return { exitCode: result.exitCode, stdout: "", stderr: "" };
|
|
74209
|
+
}
|
|
73727
74210
|
if (parsed.command === "doctor") {
|
|
73728
74211
|
const { handleSetupCommand } = await Promise.resolve().then(() => __importStar(require_setup2()));
|
|
73729
74212
|
const result = await handleSetupCommand(runtime.projectRoot || process.cwd(), runtime.logger, stdout, {
|
package/dist/daemon.js
CHANGED
|
@@ -50691,6 +50691,7 @@ var require_setup_status_service = __commonJS({
|
|
|
50691
50691
|
}
|
|
50692
50692
|
};
|
|
50693
50693
|
const child = (0, node_child_process_1.spawn)("claude", ["plugin", "list", "--json"], {
|
|
50694
|
+
cwd: this.projectDir,
|
|
50694
50695
|
stdio: ["ignore", "pipe", "pipe"]
|
|
50695
50696
|
});
|
|
50696
50697
|
let stdout = "";
|
|
@@ -50899,6 +50900,7 @@ var require_setup_status_service = __commonJS({
|
|
|
50899
50900
|
this.logger?.info("Auto-configuring project with user defaults", {
|
|
50900
50901
|
projectDir: this.projectDir
|
|
50901
50902
|
});
|
|
50903
|
+
const existing = await this.getProjectStatus();
|
|
50902
50904
|
const projectStatus = {
|
|
50903
50905
|
version: 1,
|
|
50904
50906
|
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -50908,7 +50910,8 @@ var require_setup_status_service = __commonJS({
|
|
|
50908
50910
|
OPENROUTER_API_KEY: "user",
|
|
50909
50911
|
OPENAI_API_KEY: "user"
|
|
50910
50912
|
},
|
|
50911
|
-
gitignore: "unknown"
|
|
50913
|
+
gitignore: "unknown",
|
|
50914
|
+
...existing?.devMode !== void 0 && { devMode: existing.devMode }
|
|
50912
50915
|
};
|
|
50913
50916
|
await this.writeProjectStatus(projectStatus);
|
|
50914
50917
|
this.logger?.info("Project auto-configured successfully", {
|
|
@@ -50952,6 +50955,7 @@ var require_setup_status_service = __commonJS({
|
|
|
50952
50955
|
if (projectStatus) {
|
|
50953
50956
|
await this.updateProjectStatus({ statusline: actualStatusline });
|
|
50954
50957
|
} else {
|
|
50958
|
+
const existingForDevMode = await this.getProjectStatus();
|
|
50955
50959
|
await this.writeProjectStatus({
|
|
50956
50960
|
version: 1,
|
|
50957
50961
|
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -50961,7 +50965,8 @@ var require_setup_status_service = __commonJS({
|
|
|
50961
50965
|
OPENROUTER_API_KEY: "user",
|
|
50962
50966
|
OPENAI_API_KEY: "user"
|
|
50963
50967
|
},
|
|
50964
|
-
gitignore: "unknown"
|
|
50968
|
+
gitignore: "unknown",
|
|
50969
|
+
...existingForDevMode?.devMode !== void 0 && { devMode: existingForDevMode.devMode }
|
|
50965
50970
|
});
|
|
50966
50971
|
}
|
|
50967
50972
|
} else {
|
|
@@ -51011,6 +51016,7 @@ var require_setup_status_service = __commonJS({
|
|
|
51011
51016
|
});
|
|
51012
51017
|
} else {
|
|
51013
51018
|
const userApiKeyStatus = this.buildUserApiKeyStatus(detection);
|
|
51019
|
+
const existingForDevMode = await this.getProjectStatus();
|
|
51014
51020
|
await this.writeProjectStatus({
|
|
51015
51021
|
version: 1,
|
|
51016
51022
|
lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -51020,7 +51026,8 @@ var require_setup_status_service = __commonJS({
|
|
|
51020
51026
|
OPENROUTER_API_KEY: keyName === "OPENROUTER_API_KEY" ? projectApiKeyStatus : "user",
|
|
51021
51027
|
OPENAI_API_KEY: keyName === "OPENAI_API_KEY" ? projectApiKeyStatus : "user"
|
|
51022
51028
|
},
|
|
51023
|
-
gitignore: "unknown"
|
|
51029
|
+
gitignore: "unknown",
|
|
51030
|
+
...existingForDevMode?.devMode !== void 0 && { devMode: existingForDevMode.devMode }
|
|
51024
51031
|
});
|
|
51025
51032
|
const userStatus = await this.getUserStatus();
|
|
51026
51033
|
if (!userStatus) {
|
|
@@ -51110,7 +51117,8 @@ var require_setup_status_service = __commonJS({
|
|
|
51110
51117
|
}
|
|
51111
51118
|
};
|
|
51112
51119
|
const child = (0, node_child_process_1.spawn)("claude", ["-p", prompt], {
|
|
51113
|
-
|
|
51120
|
+
cwd: this.projectDir,
|
|
51121
|
+
env: { ...process.env, SIDEKICK_LIVENESS_CHECK: safeWord },
|
|
51114
51122
|
stdio: ["ignore", "pipe", "pipe"]
|
|
51115
51123
|
});
|
|
51116
51124
|
let stdout = "";
|
package/package.json
CHANGED