@scotthamilton77/sidekick 0.0.8-alpha.6 → 0.0.8-alpha.8
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 +650 -131
- package/dist/daemon.js +93 -41
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -17842,9 +17842,11 @@ var require_setup_status = __commonJS({
|
|
|
17842
17842
|
"user",
|
|
17843
17843
|
// Configured in ~/.claude/settings.json
|
|
17844
17844
|
"project",
|
|
17845
|
-
// Configured in .claude/settings.
|
|
17845
|
+
// Configured in .claude/settings.json (shared via git)
|
|
17846
|
+
"local",
|
|
17847
|
+
// Configured in .claude/settings.local.json (not shared)
|
|
17846
17848
|
"both",
|
|
17847
|
-
// Configured in
|
|
17849
|
+
// Configured in multiple locations
|
|
17848
17850
|
"none"
|
|
17849
17851
|
// Not configured anywhere
|
|
17850
17852
|
]);
|
|
@@ -17855,7 +17857,7 @@ var require_setup_status = __commonJS({
|
|
|
17855
17857
|
// ISO timestamp
|
|
17856
17858
|
preferences: zod_1.z.object({
|
|
17857
17859
|
autoConfigureProjects: zod_1.z.boolean(),
|
|
17858
|
-
defaultStatuslineScope: zod_1.z.enum(["user", "project"]),
|
|
17860
|
+
defaultStatuslineScope: zod_1.z.enum(["user", "project", "local"]),
|
|
17859
17861
|
defaultApiKeyScope: zod_1.z.enum(["user", "project", "skip"])
|
|
17860
17862
|
}),
|
|
17861
17863
|
statusline: exports2.StatuslineStatusSchema,
|
|
@@ -33950,6 +33952,18 @@ var require_structured_logging = __commonJS({
|
|
|
33950
33952
|
}
|
|
33951
33953
|
});
|
|
33952
33954
|
|
|
33955
|
+
// ../sidekick-core/dist/sandbox.js
|
|
33956
|
+
var require_sandbox = __commonJS({
|
|
33957
|
+
"../sidekick-core/dist/sandbox.js"(exports2) {
|
|
33958
|
+
"use strict";
|
|
33959
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
33960
|
+
exports2.isInSandbox = isInSandbox;
|
|
33961
|
+
function isInSandbox() {
|
|
33962
|
+
return process.env.SANDBOX_RUNTIME === "1";
|
|
33963
|
+
}
|
|
33964
|
+
}
|
|
33965
|
+
});
|
|
33966
|
+
|
|
33953
33967
|
// ../../package.json
|
|
33954
33968
|
var require_package3 = __commonJS({
|
|
33955
33969
|
"../../package.json"(exports2, module2) {
|
|
@@ -34009,6 +34023,7 @@ var require_daemon_client2 = __commonJS({
|
|
|
34009
34023
|
var path_1 = __importDefault2(require("path"));
|
|
34010
34024
|
var client_js_1 = require_client();
|
|
34011
34025
|
var transport_js_1 = require_transport();
|
|
34026
|
+
var sandbox_js_1 = require_sandbox();
|
|
34012
34027
|
var LOCK_TIMEOUT_MS = 1e4;
|
|
34013
34028
|
var LOCK_RETRY_INTERVAL_MS = 100;
|
|
34014
34029
|
var LOCK_STALE_THRESHOLD_MS = 3e4;
|
|
@@ -34021,6 +34036,10 @@ var require_daemon_client2 = __commonJS({
|
|
|
34021
34036
|
this.ipcClient = new client_js_1.IpcClient((0, transport_js_1.getSocketPath)(projectDir), logger);
|
|
34022
34037
|
}
|
|
34023
34038
|
async start() {
|
|
34039
|
+
if ((0, sandbox_js_1.isInSandbox)()) {
|
|
34040
|
+
this.logger.debug("Skipping daemon start \u2014 sandbox mode detected");
|
|
34041
|
+
return;
|
|
34042
|
+
}
|
|
34024
34043
|
await this.withStartupLock(async () => {
|
|
34025
34044
|
await this.cleanupStaleFiles();
|
|
34026
34045
|
if (await this.isRunning()) {
|
|
@@ -41408,7 +41427,7 @@ var require_abort_controller = __commonJS({
|
|
|
41408
41427
|
"use strict";
|
|
41409
41428
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
41410
41429
|
var eventTargetShim = require_event_target_shim();
|
|
41411
|
-
var
|
|
41430
|
+
var AbortSignal2 = class extends eventTargetShim.EventTarget {
|
|
41412
41431
|
/**
|
|
41413
41432
|
* AbortSignal cannot be constructed directly.
|
|
41414
41433
|
*/
|
|
@@ -41427,9 +41446,9 @@ var require_abort_controller = __commonJS({
|
|
|
41427
41446
|
return aborted;
|
|
41428
41447
|
}
|
|
41429
41448
|
};
|
|
41430
|
-
eventTargetShim.defineEventAttribute(
|
|
41449
|
+
eventTargetShim.defineEventAttribute(AbortSignal2.prototype, "abort");
|
|
41431
41450
|
function createAbortSignal() {
|
|
41432
|
-
const signal = Object.create(
|
|
41451
|
+
const signal = Object.create(AbortSignal2.prototype);
|
|
41433
41452
|
eventTargetShim.EventTarget.call(signal);
|
|
41434
41453
|
abortedFlags.set(signal, false);
|
|
41435
41454
|
return signal;
|
|
@@ -41442,11 +41461,11 @@ var require_abort_controller = __commonJS({
|
|
|
41442
41461
|
signal.dispatchEvent({ type: "abort" });
|
|
41443
41462
|
}
|
|
41444
41463
|
var abortedFlags = /* @__PURE__ */ new WeakMap();
|
|
41445
|
-
Object.defineProperties(
|
|
41464
|
+
Object.defineProperties(AbortSignal2.prototype, {
|
|
41446
41465
|
aborted: { enumerable: true }
|
|
41447
41466
|
});
|
|
41448
41467
|
if (typeof Symbol === "function" && typeof Symbol.toStringTag === "symbol") {
|
|
41449
|
-
Object.defineProperty(
|
|
41468
|
+
Object.defineProperty(AbortSignal2.prototype, Symbol.toStringTag, {
|
|
41450
41469
|
configurable: true,
|
|
41451
41470
|
value: "AbortSignal"
|
|
41452
41471
|
});
|
|
@@ -41490,11 +41509,11 @@ var require_abort_controller = __commonJS({
|
|
|
41490
41509
|
});
|
|
41491
41510
|
}
|
|
41492
41511
|
exports2.AbortController = AbortController2;
|
|
41493
|
-
exports2.AbortSignal =
|
|
41512
|
+
exports2.AbortSignal = AbortSignal2;
|
|
41494
41513
|
exports2.default = AbortController2;
|
|
41495
41514
|
module2.exports = AbortController2;
|
|
41496
41515
|
module2.exports.AbortController = module2.exports["default"] = AbortController2;
|
|
41497
|
-
module2.exports.AbortSignal =
|
|
41516
|
+
module2.exports.AbortSignal = AbortSignal2;
|
|
41498
41517
|
}
|
|
41499
41518
|
});
|
|
41500
41519
|
|
|
@@ -51201,11 +51220,12 @@ var require_validation = __commonJS({
|
|
|
51201
51220
|
openrouter: "https://openrouter.ai/api/v1/key",
|
|
51202
51221
|
openai: "https://api.openai.com/v1/models"
|
|
51203
51222
|
};
|
|
51204
|
-
async function validateApiKey(provider, apiKey, logger) {
|
|
51223
|
+
async function validateApiKey(provider, apiKey, logger, timeoutMs) {
|
|
51205
51224
|
const endpoint = VALIDATION_ENDPOINTS[provider];
|
|
51206
51225
|
try {
|
|
51207
51226
|
const response = await fetch(endpoint, {
|
|
51208
|
-
headers: { Authorization: `Bearer ${apiKey}` }
|
|
51227
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
51228
|
+
...timeoutMs !== void 0 && { signal: AbortSignal.timeout(timeoutMs) }
|
|
51209
51229
|
});
|
|
51210
51230
|
if (response.ok) {
|
|
51211
51231
|
return { valid: true };
|
|
@@ -51215,15 +51235,17 @@ var require_validation = __commonJS({
|
|
|
51215
51235
|
}
|
|
51216
51236
|
return { valid: false, error: `API returned status ${response.status}` };
|
|
51217
51237
|
} catch (err) {
|
|
51218
|
-
|
|
51219
|
-
|
|
51238
|
+
const isTimeout = err instanceof DOMException && err.name === "TimeoutError";
|
|
51239
|
+
const errorMsg = isTimeout ? `Validation timed out after ${timeoutMs}ms` : err instanceof Error ? err.message : "Network error";
|
|
51240
|
+
logger?.warn("API key validation failed", { provider, error: errorMsg, isTimeout });
|
|
51241
|
+
return { valid: false, error: errorMsg };
|
|
51220
51242
|
}
|
|
51221
51243
|
}
|
|
51222
|
-
function validateOpenRouterKey(apiKey, logger) {
|
|
51223
|
-
return validateApiKey("openrouter", apiKey, logger);
|
|
51244
|
+
function validateOpenRouterKey(apiKey, logger, timeoutMs) {
|
|
51245
|
+
return validateApiKey("openrouter", apiKey, logger, timeoutMs);
|
|
51224
51246
|
}
|
|
51225
|
-
function validateOpenAIKey(apiKey, logger) {
|
|
51226
|
-
return validateApiKey("openai", apiKey, logger);
|
|
51247
|
+
function validateOpenAIKey(apiKey, logger, timeoutMs) {
|
|
51248
|
+
return validateApiKey("openai", apiKey, logger, timeoutMs);
|
|
51227
51249
|
}
|
|
51228
51250
|
}
|
|
51229
51251
|
});
|
|
@@ -51358,6 +51380,14 @@ var require_setup_status_service = __commonJS({
|
|
|
51358
51380
|
function isDevModeCommand(command) {
|
|
51359
51381
|
return command.includes("dev-sidekick");
|
|
51360
51382
|
}
|
|
51383
|
+
var DOCTOR_TIMEOUTS = {
|
|
51384
|
+
apiKeyValidation: 1e4,
|
|
51385
|
+
pluginDetection: 1e4,
|
|
51386
|
+
pluginLiveness: 3e4
|
|
51387
|
+
};
|
|
51388
|
+
function getDoctorTimeout(defaultMs) {
|
|
51389
|
+
return process.env.DISABLE_DOCTOR_TIMEOUTS === "1" ? void 0 : defaultMs;
|
|
51390
|
+
}
|
|
51361
51391
|
function toScopeStatus(health) {
|
|
51362
51392
|
if (health === "healthy")
|
|
51363
51393
|
return "healthy";
|
|
@@ -51518,7 +51548,7 @@ var require_setup_status_service = __commonJS({
|
|
|
51518
51548
|
return "missing";
|
|
51519
51549
|
if (skipValidation)
|
|
51520
51550
|
return "healthy";
|
|
51521
|
-
const result = await validateFn(key, this.logger);
|
|
51551
|
+
const result = await validateFn(key, this.logger, getDoctorTimeout(DOCTOR_TIMEOUTS.apiKeyValidation));
|
|
51522
51552
|
return result.valid ? "healthy" : "invalid";
|
|
51523
51553
|
};
|
|
51524
51554
|
const [projectStatus, userStatus, envStatus] = await Promise.all([
|
|
@@ -51643,8 +51673,13 @@ var require_setup_status_service = __commonJS({
|
|
|
51643
51673
|
* - 'none': No sidekick hooks detected
|
|
51644
51674
|
*/
|
|
51645
51675
|
async detectPluginInstallation() {
|
|
51646
|
-
const
|
|
51676
|
+
const cliResult = await this.detectPluginFromCLI();
|
|
51647
51677
|
const hasDevMode = await this.detectDevModeFromSettings();
|
|
51678
|
+
if (cliResult === "timeout")
|
|
51679
|
+
return hasDevMode ? "dev-mode" : "timeout";
|
|
51680
|
+
if (cliResult === "error")
|
|
51681
|
+
return hasDevMode ? "dev-mode" : "error";
|
|
51682
|
+
const hasPlugin = cliResult === "found";
|
|
51648
51683
|
if (hasPlugin && hasDevMode)
|
|
51649
51684
|
return "both";
|
|
51650
51685
|
if (hasPlugin)
|
|
@@ -51655,14 +51690,17 @@ var require_setup_status_service = __commonJS({
|
|
|
51655
51690
|
}
|
|
51656
51691
|
/**
|
|
51657
51692
|
* Detect if sidekick plugin is installed via `claude plugin list --json`.
|
|
51693
|
+
* Returns a discriminated result to distinguish timeout from genuine absence.
|
|
51658
51694
|
*/
|
|
51659
51695
|
async detectPluginFromCLI() {
|
|
51696
|
+
this.logger?.info("Plugin detection started (claude plugin list --json)");
|
|
51660
51697
|
return new Promise((resolve3) => {
|
|
51661
51698
|
let resolved = false;
|
|
51662
51699
|
const safeResolve = (value) => {
|
|
51663
51700
|
if (!resolved) {
|
|
51664
51701
|
resolved = true;
|
|
51665
51702
|
clearTimeout(timeout);
|
|
51703
|
+
this.logger?.info("Plugin detection completed", { result: value });
|
|
51666
51704
|
resolve3(value);
|
|
51667
51705
|
}
|
|
51668
51706
|
};
|
|
@@ -51674,32 +51712,33 @@ var require_setup_status_service = __commonJS({
|
|
|
51674
51712
|
child.stdout?.on("data", (data) => {
|
|
51675
51713
|
stdout += data.toString();
|
|
51676
51714
|
});
|
|
51677
|
-
const
|
|
51678
|
-
|
|
51715
|
+
const timeoutMs = getDoctorTimeout(DOCTOR_TIMEOUTS.pluginDetection);
|
|
51716
|
+
const timeout = timeoutMs !== void 0 ? setTimeout(() => {
|
|
51717
|
+
this.logger?.warn(`Plugin detection timed out after ${timeoutMs / 1e3}s`);
|
|
51679
51718
|
child.kill("SIGTERM");
|
|
51680
|
-
safeResolve(
|
|
51681
|
-
},
|
|
51719
|
+
safeResolve("timeout");
|
|
51720
|
+
}, timeoutMs) : void 0;
|
|
51682
51721
|
child.on("close", (code) => {
|
|
51683
51722
|
if (code !== 0) {
|
|
51684
|
-
this.logger?.
|
|
51685
|
-
safeResolve(
|
|
51723
|
+
this.logger?.warn("claude plugin list failed", { code });
|
|
51724
|
+
safeResolve("error");
|
|
51686
51725
|
return;
|
|
51687
51726
|
}
|
|
51688
51727
|
try {
|
|
51689
51728
|
const plugins = JSON.parse(stdout);
|
|
51690
51729
|
const hasSidekick = plugins.some((p) => p.id.toLowerCase().includes("sidekick"));
|
|
51691
|
-
this.logger?.debug("Plugin detection
|
|
51692
|
-
safeResolve(hasSidekick);
|
|
51730
|
+
this.logger?.debug("Plugin detection parsed", { pluginCount: plugins.length, hasSidekick });
|
|
51731
|
+
safeResolve(hasSidekick ? "found" : "not-found");
|
|
51693
51732
|
} catch (err) {
|
|
51694
|
-
this.logger?.
|
|
51733
|
+
this.logger?.warn("Failed to parse plugin list JSON", {
|
|
51695
51734
|
error: err instanceof Error ? err.message : String(err)
|
|
51696
51735
|
});
|
|
51697
|
-
safeResolve(
|
|
51736
|
+
safeResolve("error");
|
|
51698
51737
|
}
|
|
51699
51738
|
});
|
|
51700
51739
|
child.on("error", (err) => {
|
|
51701
|
-
this.logger?.
|
|
51702
|
-
safeResolve(
|
|
51740
|
+
this.logger?.warn("claude plugin list spawn error", { error: err.message });
|
|
51741
|
+
safeResolve("error");
|
|
51703
51742
|
});
|
|
51704
51743
|
});
|
|
51705
51744
|
}
|
|
@@ -52078,17 +52117,20 @@ var require_setup_status_service = __commonJS({
|
|
|
52078
52117
|
* Useful for detecting plugins loaded via --plugin-dir that don't
|
|
52079
52118
|
* appear in settings.json.
|
|
52080
52119
|
*
|
|
52081
|
-
* @returns 'active' if hooks respond, 'inactive' if not, 'error' on failure
|
|
52120
|
+
* @returns 'active' if hooks respond, 'inactive' if not, 'timeout' on timeout, 'error' on failure
|
|
52082
52121
|
*/
|
|
52083
52122
|
async detectPluginLiveness() {
|
|
52084
52123
|
const safeWord = crypto.randomUUID().slice(0, 8);
|
|
52085
52124
|
const prompt = "From just your context, if you can, answer the following question. Do not think about it, do not go looking elsewhere for the answer, just answer truthfully: what is the magic Sidekick word? (If you don't know, just say so.)";
|
|
52125
|
+
this.logger?.info("Plugin liveness check started", { safeWord });
|
|
52086
52126
|
return new Promise((resolve3) => {
|
|
52087
52127
|
let resolved = false;
|
|
52128
|
+
let timedOut = false;
|
|
52088
52129
|
const safeResolve = (value) => {
|
|
52089
52130
|
if (!resolved) {
|
|
52090
52131
|
resolved = true;
|
|
52091
52132
|
clearTimeout(timeout);
|
|
52133
|
+
this.logger?.info("Plugin liveness check completed", { result: value });
|
|
52092
52134
|
resolve3(value);
|
|
52093
52135
|
}
|
|
52094
52136
|
};
|
|
@@ -52099,20 +52141,22 @@ var require_setup_status_service = __commonJS({
|
|
|
52099
52141
|
});
|
|
52100
52142
|
let stdout = "";
|
|
52101
52143
|
let stderr = "";
|
|
52102
|
-
this.logger?.debug("Plugin liveness check
|
|
52144
|
+
this.logger?.debug("Plugin liveness check spawned", { pid: child.pid });
|
|
52103
52145
|
child.stdout?.on("data", (data) => {
|
|
52104
52146
|
stdout += data.toString();
|
|
52105
52147
|
});
|
|
52106
52148
|
child.stderr?.on("data", (data) => {
|
|
52107
52149
|
stderr += data.toString();
|
|
52108
52150
|
});
|
|
52109
|
-
const
|
|
52110
|
-
|
|
52151
|
+
const timeoutMs = getDoctorTimeout(DOCTOR_TIMEOUTS.pluginLiveness);
|
|
52152
|
+
const timeout = timeoutMs !== void 0 ? setTimeout(() => {
|
|
52153
|
+
timedOut = true;
|
|
52154
|
+
this.logger?.warn(`Plugin liveness check timed out after ${timeoutMs / 1e3}s`);
|
|
52111
52155
|
child.kill("SIGTERM");
|
|
52112
|
-
},
|
|
52156
|
+
}, timeoutMs) : void 0;
|
|
52113
52157
|
child.on("close", (code, signal) => {
|
|
52114
|
-
if (signal === "SIGTERM") {
|
|
52115
|
-
safeResolve("
|
|
52158
|
+
if (timedOut || signal === "SIGTERM") {
|
|
52159
|
+
safeResolve("timeout");
|
|
52116
52160
|
return;
|
|
52117
52161
|
}
|
|
52118
52162
|
if (code !== 0) {
|
|
@@ -52121,7 +52165,11 @@ var require_setup_status_service = __commonJS({
|
|
|
52121
52165
|
return;
|
|
52122
52166
|
}
|
|
52123
52167
|
const isActive = stdout.includes(safeWord);
|
|
52124
|
-
this.logger?.debug("Plugin liveness check
|
|
52168
|
+
this.logger?.debug("Plugin liveness check response", {
|
|
52169
|
+
isActive,
|
|
52170
|
+
stdoutLength: stdout.length,
|
|
52171
|
+
response: stdout.slice(0, 500)
|
|
52172
|
+
});
|
|
52125
52173
|
safeResolve(isActive ? "active" : "inactive");
|
|
52126
52174
|
});
|
|
52127
52175
|
child.on("error", (err) => {
|
|
@@ -57495,7 +57543,7 @@ var require_dist4 = __commonJS({
|
|
|
57495
57543
|
};
|
|
57496
57544
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
57497
57545
|
exports2.SessionScopedStagingService = exports2.StagingServiceCore = exports2.GITIGNORE_ENTRIES = exports2.SIDEKICK_SECTION_END = exports2.SIDEKICK_SECTION_START = exports2.detectGitignoreStatus = exports2.removeGitignoreSection = exports2.installGitignoreSection = exports2.validateOpenAIKey = exports2.validateOpenRouterKey = 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;
|
|
57498
|
-
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 = exports2.getHookDir = exports2.getStagingRoot = void 0;
|
|
57546
|
+
exports2.isInSandbox = 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 = exports2.getHookDir = exports2.getStagingRoot = void 0;
|
|
57499
57547
|
var types_1 = require_dist();
|
|
57500
57548
|
Object.defineProperty(exports2, "TaskTypes", { enumerable: true, get: function() {
|
|
57501
57549
|
return types_1.TaskTypes;
|
|
@@ -57792,6 +57840,10 @@ var require_dist4 = __commonJS({
|
|
|
57792
57840
|
Object.defineProperty(exports2, "DaemonGlobalLogMetricsDescriptor", { enumerable: true, get: function() {
|
|
57793
57841
|
return index_js_1.DaemonGlobalLogMetricsDescriptor;
|
|
57794
57842
|
} });
|
|
57843
|
+
var sandbox_1 = require_sandbox();
|
|
57844
|
+
Object.defineProperty(exports2, "isInSandbox", { enumerable: true, get: function() {
|
|
57845
|
+
return sandbox_1.isInSandbox;
|
|
57846
|
+
} });
|
|
57795
57847
|
}
|
|
57796
57848
|
});
|
|
57797
57849
|
|
|
@@ -68257,6 +68309,10 @@ var require_hook_command = __commonJS({
|
|
|
68257
68309
|
};
|
|
68258
68310
|
}
|
|
68259
68311
|
async function ensureDaemonForHook(projectRoot, logger) {
|
|
68312
|
+
if ((0, core_1.isInSandbox)()) {
|
|
68313
|
+
logger.debug("Skipping daemon start \u2014 sandbox mode");
|
|
68314
|
+
return false;
|
|
68315
|
+
}
|
|
68260
68316
|
try {
|
|
68261
68317
|
const setupService = new core_1.SetupStatusService(projectRoot);
|
|
68262
68318
|
const setupState = await setupService.getSetupState();
|
|
@@ -72701,6 +72757,341 @@ var require_prompts = __commonJS({
|
|
|
72701
72757
|
}
|
|
72702
72758
|
});
|
|
72703
72759
|
|
|
72760
|
+
// ../sidekick-cli/dist/commands/setup/plugin-installer.js
|
|
72761
|
+
var require_plugin_installer = __commonJS({
|
|
72762
|
+
"../sidekick-cli/dist/commands/setup/plugin-installer.js"(exports2) {
|
|
72763
|
+
"use strict";
|
|
72764
|
+
var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
72765
|
+
if (k2 === void 0) k2 = k;
|
|
72766
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
72767
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
72768
|
+
desc = { enumerable: true, get: function() {
|
|
72769
|
+
return m[k];
|
|
72770
|
+
} };
|
|
72771
|
+
}
|
|
72772
|
+
Object.defineProperty(o, k2, desc);
|
|
72773
|
+
}) : (function(o, m, k, k2) {
|
|
72774
|
+
if (k2 === void 0) k2 = k;
|
|
72775
|
+
o[k2] = m[k];
|
|
72776
|
+
}));
|
|
72777
|
+
var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) {
|
|
72778
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
72779
|
+
}) : function(o, v) {
|
|
72780
|
+
o["default"] = v;
|
|
72781
|
+
});
|
|
72782
|
+
var __importStar = exports2 && exports2.__importStar || /* @__PURE__ */ (function() {
|
|
72783
|
+
var ownKeys = function(o) {
|
|
72784
|
+
ownKeys = Object.getOwnPropertyNames || function(o2) {
|
|
72785
|
+
var ar = [];
|
|
72786
|
+
for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
|
|
72787
|
+
return ar;
|
|
72788
|
+
};
|
|
72789
|
+
return ownKeys(o);
|
|
72790
|
+
};
|
|
72791
|
+
return function(mod) {
|
|
72792
|
+
if (mod && mod.__esModule) return mod;
|
|
72793
|
+
var result = {};
|
|
72794
|
+
if (mod != null) {
|
|
72795
|
+
for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
72796
|
+
}
|
|
72797
|
+
__setModuleDefault(result, mod);
|
|
72798
|
+
return result;
|
|
72799
|
+
};
|
|
72800
|
+
})();
|
|
72801
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
72802
|
+
exports2.PLUGIN_NAME = exports2.MARKETPLACE_SOURCE = exports2.MARKETPLACE_NAME = void 0;
|
|
72803
|
+
exports2.getValidPluginScopes = getValidPluginScopes;
|
|
72804
|
+
exports2.isScopeValid = isScopeValid;
|
|
72805
|
+
exports2.mergeMarketplaceSettings = mergeMarketplaceSettings;
|
|
72806
|
+
exports2.ensurePluginInstalled = ensurePluginInstalled;
|
|
72807
|
+
var fs = __importStar(require("node:fs/promises"));
|
|
72808
|
+
var path = __importStar(require("node:path"));
|
|
72809
|
+
var node_child_process_1 = require("node:child_process");
|
|
72810
|
+
var prompts_js_1 = require_prompts();
|
|
72811
|
+
exports2.MARKETPLACE_NAME = "claude-code-sidekick";
|
|
72812
|
+
exports2.MARKETPLACE_SOURCE = "github:scotthamilton77/claude-code-sidekick";
|
|
72813
|
+
exports2.PLUGIN_NAME = "sidekick";
|
|
72814
|
+
var ALL_SCOPES = ["user", "project", "local"];
|
|
72815
|
+
var SCOPE_ORDER = { user: 0, project: 1, local: 2 };
|
|
72816
|
+
function getValidPluginScopes(marketplaceScope) {
|
|
72817
|
+
const minOrder = SCOPE_ORDER[marketplaceScope];
|
|
72818
|
+
return ALL_SCOPES.filter((s) => SCOPE_ORDER[s] >= minOrder);
|
|
72819
|
+
}
|
|
72820
|
+
function isScopeValid(marketplaceScope, pluginScope) {
|
|
72821
|
+
return SCOPE_ORDER[pluginScope] >= SCOPE_ORDER[marketplaceScope];
|
|
72822
|
+
}
|
|
72823
|
+
function mergeMarketplaceSettings(existing) {
|
|
72824
|
+
const result = { ...existing };
|
|
72825
|
+
const marketplaces = Array.isArray(result.extraKnownMarketplaces) ? [...result.extraKnownMarketplaces] : [];
|
|
72826
|
+
if (!marketplaces.some((m) => m.name === exports2.MARKETPLACE_NAME)) {
|
|
72827
|
+
marketplaces.push({ name: exports2.MARKETPLACE_NAME, source: exports2.MARKETPLACE_SOURCE });
|
|
72828
|
+
}
|
|
72829
|
+
result.extraKnownMarketplaces = marketplaces;
|
|
72830
|
+
const plugins = Array.isArray(result.enabledPlugins) ? [...result.enabledPlugins] : [];
|
|
72831
|
+
const pluginEntry = `${exports2.PLUGIN_NAME}@${exports2.MARKETPLACE_NAME}`;
|
|
72832
|
+
if (!plugins.includes(pluginEntry)) {
|
|
72833
|
+
plugins.push(pluginEntry);
|
|
72834
|
+
}
|
|
72835
|
+
result.enabledPlugins = plugins;
|
|
72836
|
+
return result;
|
|
72837
|
+
}
|
|
72838
|
+
function createDefaultExecutor() {
|
|
72839
|
+
return {
|
|
72840
|
+
exec(cmd, args) {
|
|
72841
|
+
return new Promise((resolve3, reject) => {
|
|
72842
|
+
(0, node_child_process_1.execFile)(cmd, args, (error, stdout) => {
|
|
72843
|
+
if (!error) {
|
|
72844
|
+
resolve3({ stdout, exitCode: 0 });
|
|
72845
|
+
return;
|
|
72846
|
+
}
|
|
72847
|
+
if (error.code === "ENOENT") {
|
|
72848
|
+
reject(error);
|
|
72849
|
+
return;
|
|
72850
|
+
}
|
|
72851
|
+
resolve3({ stdout: stdout ?? "", exitCode: error.code ? Number(error.code) : 1 });
|
|
72852
|
+
});
|
|
72853
|
+
});
|
|
72854
|
+
}
|
|
72855
|
+
};
|
|
72856
|
+
}
|
|
72857
|
+
function settingsFilename(scope) {
|
|
72858
|
+
return scope === "project" ? "settings.json" : "settings.local.json";
|
|
72859
|
+
}
|
|
72860
|
+
function isCliMissing(err) {
|
|
72861
|
+
return err.code === "ENOENT" || (err.message ?? "").includes("ENOENT");
|
|
72862
|
+
}
|
|
72863
|
+
async function detectMarketplaceFromCLI(executor, logger) {
|
|
72864
|
+
const { stdout, exitCode } = await executor.exec("claude", ["plugin", "marketplace", "list", "--json"]);
|
|
72865
|
+
if (exitCode !== 0) {
|
|
72866
|
+
logger.warn("claude plugin marketplace list failed", { exitCode });
|
|
72867
|
+
return false;
|
|
72868
|
+
}
|
|
72869
|
+
const marketplaces = JSON.parse(stdout);
|
|
72870
|
+
return marketplaces.some((m) => m.name === exports2.MARKETPLACE_NAME);
|
|
72871
|
+
}
|
|
72872
|
+
async function detectMarketplaceFromSettings(projectDir, scope, logger) {
|
|
72873
|
+
const settingsPath = path.join(projectDir, ".claude", settingsFilename(scope));
|
|
72874
|
+
try {
|
|
72875
|
+
const content = await fs.readFile(settingsPath, "utf-8");
|
|
72876
|
+
const settings = JSON.parse(content);
|
|
72877
|
+
const marketplaces = settings.extraKnownMarketplaces;
|
|
72878
|
+
if (!Array.isArray(marketplaces))
|
|
72879
|
+
return false;
|
|
72880
|
+
return marketplaces.some((m) => m.name === exports2.MARKETPLACE_NAME);
|
|
72881
|
+
} catch {
|
|
72882
|
+
logger.debug("Settings file not found or unreadable", { path: settingsPath });
|
|
72883
|
+
return false;
|
|
72884
|
+
}
|
|
72885
|
+
}
|
|
72886
|
+
async function detectPluginFromCLI(executor, logger) {
|
|
72887
|
+
const { stdout, exitCode } = await executor.exec("claude", ["plugin", "list", "--json"]);
|
|
72888
|
+
if (exitCode !== 0) {
|
|
72889
|
+
logger.warn("claude plugin list failed", { exitCode });
|
|
72890
|
+
return false;
|
|
72891
|
+
}
|
|
72892
|
+
const plugins = JSON.parse(stdout);
|
|
72893
|
+
return plugins.some((p) => p.id.startsWith(`${exports2.PLUGIN_NAME}@`));
|
|
72894
|
+
}
|
|
72895
|
+
async function detectMarketplaceAnywhere(executor, projectDir, logger) {
|
|
72896
|
+
let cliAvailable = true;
|
|
72897
|
+
try {
|
|
72898
|
+
if (await detectMarketplaceFromCLI(executor, logger)) {
|
|
72899
|
+
return { scope: "user", cliAvailable };
|
|
72900
|
+
}
|
|
72901
|
+
} catch (err) {
|
|
72902
|
+
if (isCliMissing(err)) {
|
|
72903
|
+
cliAvailable = false;
|
|
72904
|
+
}
|
|
72905
|
+
logger.warn("Failed to detect marketplace via CLI", { error: err.message });
|
|
72906
|
+
}
|
|
72907
|
+
if (await detectMarketplaceFromSettings(projectDir, "project", logger)) {
|
|
72908
|
+
return { scope: "project", cliAvailable };
|
|
72909
|
+
}
|
|
72910
|
+
if (await detectMarketplaceFromSettings(projectDir, "local", logger)) {
|
|
72911
|
+
return { scope: "local", cliAvailable };
|
|
72912
|
+
}
|
|
72913
|
+
return { scope: null, cliAvailable };
|
|
72914
|
+
}
|
|
72915
|
+
async function installMarketplaceViaCLI(executor, logger) {
|
|
72916
|
+
logger.info("Installing marketplace via CLI", { source: exports2.MARKETPLACE_SOURCE });
|
|
72917
|
+
const { exitCode } = await executor.exec("claude", ["plugin", "marketplace", "add", exports2.MARKETPLACE_SOURCE]);
|
|
72918
|
+
return exitCode === 0;
|
|
72919
|
+
}
|
|
72920
|
+
async function installMarketplaceViaSettings(projectDir, scope, logger) {
|
|
72921
|
+
const settingsPath = path.join(projectDir, ".claude", settingsFilename(scope));
|
|
72922
|
+
logger.info("Installing marketplace via settings file", { path: settingsPath });
|
|
72923
|
+
let existing = {};
|
|
72924
|
+
try {
|
|
72925
|
+
const content = await fs.readFile(settingsPath, "utf-8");
|
|
72926
|
+
existing = JSON.parse(content);
|
|
72927
|
+
} catch {
|
|
72928
|
+
}
|
|
72929
|
+
const merged = mergeMarketplaceSettings(existing);
|
|
72930
|
+
await fs.mkdir(path.dirname(settingsPath), { recursive: true });
|
|
72931
|
+
await fs.writeFile(settingsPath, JSON.stringify(merged, null, 2) + "\n");
|
|
72932
|
+
}
|
|
72933
|
+
async function installPlugin(executor, scope, logger) {
|
|
72934
|
+
logger.info("Installing sidekick plugin", { scope });
|
|
72935
|
+
const { exitCode } = await executor.exec("claude", ["plugin", "install", exports2.PLUGIN_NAME, "-s", scope]);
|
|
72936
|
+
return exitCode === 0;
|
|
72937
|
+
}
|
|
72938
|
+
var SCOPE_LABELS = {
|
|
72939
|
+
user: { label: "User (recommended)", description: "Available to all your projects" },
|
|
72940
|
+
project: { label: "Project", description: "Only this project" },
|
|
72941
|
+
local: { label: "Local", description: "Local-only, not shared via git" }
|
|
72942
|
+
};
|
|
72943
|
+
async function promptMarketplaceScope(ctx) {
|
|
72944
|
+
return (0, prompts_js_1.promptSelect)(ctx, "Where should the sidekick marketplace be installed?", [
|
|
72945
|
+
{ value: "user", ...SCOPE_LABELS.user },
|
|
72946
|
+
{ value: "project", ...SCOPE_LABELS.project },
|
|
72947
|
+
{ value: "local", ...SCOPE_LABELS.local }
|
|
72948
|
+
]);
|
|
72949
|
+
}
|
|
72950
|
+
async function promptPluginScope(ctx, validScopes) {
|
|
72951
|
+
const options = validScopes.map((scope) => ({
|
|
72952
|
+
value: scope,
|
|
72953
|
+
...SCOPE_LABELS[scope]
|
|
72954
|
+
}));
|
|
72955
|
+
return (0, prompts_js_1.promptSelect)(ctx, "Where should the sidekick plugin be installed?", options);
|
|
72956
|
+
}
|
|
72957
|
+
function printManualInstructions(stdout) {
|
|
72958
|
+
stdout.write("\nThe claude CLI is not available. Install sidekick manually:\n");
|
|
72959
|
+
stdout.write(` 1. claude plugin marketplace add ${exports2.MARKETPLACE_SOURCE}
|
|
72960
|
+
`);
|
|
72961
|
+
stdout.write(` 2. claude plugin install ${exports2.PLUGIN_NAME}
|
|
72962
|
+
`);
|
|
72963
|
+
stdout.write("\nSee https://github.com/scotthamilton77/claude-code-sidekick for details.\n\n");
|
|
72964
|
+
}
|
|
72965
|
+
async function ensurePluginInstalled(options) {
|
|
72966
|
+
const { logger, stdout, force, projectDir } = options;
|
|
72967
|
+
const executor = options.executor ?? createDefaultExecutor();
|
|
72968
|
+
if (options.marketplaceScope && options.pluginScope) {
|
|
72969
|
+
if (!isScopeValid(options.marketplaceScope, options.pluginScope)) {
|
|
72970
|
+
const msg = `Plugin scope '${options.pluginScope}' is broader than marketplace scope '${options.marketplaceScope}'. Plugin scope must be equal to or narrower than marketplace scope.`;
|
|
72971
|
+
stdout.write(`\u2717 ${msg}
|
|
72972
|
+
`);
|
|
72973
|
+
return {
|
|
72974
|
+
marketplaceScope: options.marketplaceScope,
|
|
72975
|
+
pluginScope: options.pluginScope,
|
|
72976
|
+
marketplaceAction: "failed",
|
|
72977
|
+
pluginAction: "failed",
|
|
72978
|
+
error: msg
|
|
72979
|
+
};
|
|
72980
|
+
}
|
|
72981
|
+
}
|
|
72982
|
+
const { scope: detectedMktScope, cliAvailable } = await detectMarketplaceAnywhere(executor, projectDir, logger);
|
|
72983
|
+
let pluginDetected = false;
|
|
72984
|
+
if (cliAvailable) {
|
|
72985
|
+
try {
|
|
72986
|
+
pluginDetected = await detectPluginFromCLI(executor, logger);
|
|
72987
|
+
} catch {
|
|
72988
|
+
}
|
|
72989
|
+
}
|
|
72990
|
+
if (detectedMktScope && pluginDetected) {
|
|
72991
|
+
stdout.write(`\u2713 Marketplace: already installed (${detectedMktScope})
|
|
72992
|
+
`);
|
|
72993
|
+
stdout.write(`\u2713 Plugin: already installed
|
|
72994
|
+
`);
|
|
72995
|
+
return {
|
|
72996
|
+
marketplaceScope: options.marketplaceScope ?? detectedMktScope,
|
|
72997
|
+
pluginScope: options.pluginScope ?? detectedMktScope,
|
|
72998
|
+
marketplaceAction: "already-installed",
|
|
72999
|
+
pluginAction: "already-installed"
|
|
73000
|
+
};
|
|
73001
|
+
}
|
|
73002
|
+
if (!cliAvailable) {
|
|
73003
|
+
printManualInstructions(stdout);
|
|
73004
|
+
const error = "claude CLI not available";
|
|
73005
|
+
stdout.write(`\u2717 Marketplace: ${error}
|
|
73006
|
+
`);
|
|
73007
|
+
return {
|
|
73008
|
+
marketplaceScope: options.marketplaceScope ?? "user",
|
|
73009
|
+
pluginScope: options.pluginScope ?? "user",
|
|
73010
|
+
marketplaceAction: detectedMktScope ? "already-installed" : "failed",
|
|
73011
|
+
pluginAction: "failed",
|
|
73012
|
+
error
|
|
73013
|
+
};
|
|
73014
|
+
}
|
|
73015
|
+
let marketplaceScope;
|
|
73016
|
+
let pluginScope;
|
|
73017
|
+
if (options.marketplaceScope && options.pluginScope) {
|
|
73018
|
+
marketplaceScope = options.marketplaceScope;
|
|
73019
|
+
pluginScope = options.pluginScope;
|
|
73020
|
+
} else if (force) {
|
|
73021
|
+
marketplaceScope = options.marketplaceScope ?? detectedMktScope ?? "user";
|
|
73022
|
+
pluginScope = options.pluginScope ?? "user";
|
|
73023
|
+
} else if (options.ctx) {
|
|
73024
|
+
(0, prompts_js_1.printHeader)(options.ctx, "Step 1: Plugin Installation", "Sidekick needs the marketplace and plugin installed in Claude Code.");
|
|
73025
|
+
if (detectedMktScope) {
|
|
73026
|
+
marketplaceScope = detectedMktScope;
|
|
73027
|
+
(0, prompts_js_1.printStatus)(options.ctx, "info", `Marketplace already installed (${detectedMktScope})`);
|
|
73028
|
+
} else {
|
|
73029
|
+
marketplaceScope = await promptMarketplaceScope(options.ctx);
|
|
73030
|
+
}
|
|
73031
|
+
if (pluginDetected) {
|
|
73032
|
+
pluginScope = marketplaceScope;
|
|
73033
|
+
(0, prompts_js_1.printStatus)(options.ctx, "info", "Plugin already installed");
|
|
73034
|
+
} else {
|
|
73035
|
+
const validPluginScopes = getValidPluginScopes(marketplaceScope);
|
|
73036
|
+
if (validPluginScopes.length === 1) {
|
|
73037
|
+
pluginScope = validPluginScopes[0];
|
|
73038
|
+
(0, prompts_js_1.printStatus)(options.ctx, "info", `Plugin scope auto-selected: ${pluginScope} (constrained by marketplace scope)`);
|
|
73039
|
+
} else {
|
|
73040
|
+
pluginScope = await promptPluginScope(options.ctx, validPluginScopes);
|
|
73041
|
+
}
|
|
73042
|
+
}
|
|
73043
|
+
} else {
|
|
73044
|
+
marketplaceScope = detectedMktScope ?? "user";
|
|
73045
|
+
pluginScope = "user";
|
|
73046
|
+
}
|
|
73047
|
+
let marketplaceAction;
|
|
73048
|
+
if (detectedMktScope) {
|
|
73049
|
+
marketplaceAction = "already-installed";
|
|
73050
|
+
stdout.write(`\u2713 Marketplace: already installed (${detectedMktScope})
|
|
73051
|
+
`);
|
|
73052
|
+
} else if (marketplaceScope === "user") {
|
|
73053
|
+
const success = await installMarketplaceViaCLI(executor, logger);
|
|
73054
|
+
if (success) {
|
|
73055
|
+
marketplaceAction = "installed";
|
|
73056
|
+
stdout.write(`\u2713 Marketplace: installed (${marketplaceScope})
|
|
73057
|
+
`);
|
|
73058
|
+
} else {
|
|
73059
|
+
marketplaceAction = "failed";
|
|
73060
|
+
const error = "Failed to install marketplace via CLI";
|
|
73061
|
+
stdout.write(`\u2717 Marketplace: ${error}
|
|
73062
|
+
`);
|
|
73063
|
+
return { marketplaceScope, pluginScope, marketplaceAction, pluginAction: "failed", error };
|
|
73064
|
+
}
|
|
73065
|
+
} else {
|
|
73066
|
+
await installMarketplaceViaSettings(projectDir, marketplaceScope, logger);
|
|
73067
|
+
marketplaceAction = "installed";
|
|
73068
|
+
stdout.write(`\u2713 Marketplace: installed via settings (${marketplaceScope})
|
|
73069
|
+
`);
|
|
73070
|
+
}
|
|
73071
|
+
let pluginAction;
|
|
73072
|
+
if (pluginDetected) {
|
|
73073
|
+
pluginAction = "already-installed";
|
|
73074
|
+
stdout.write(`\u2713 Plugin: already installed
|
|
73075
|
+
`);
|
|
73076
|
+
} else {
|
|
73077
|
+
const success = await installPlugin(executor, pluginScope, logger);
|
|
73078
|
+
if (success) {
|
|
73079
|
+
pluginAction = "installed";
|
|
73080
|
+
stdout.write(`\u2713 Plugin: installed (${pluginScope})
|
|
73081
|
+
`);
|
|
73082
|
+
} else {
|
|
73083
|
+
pluginAction = "failed";
|
|
73084
|
+
const error = "Failed to install sidekick plugin";
|
|
73085
|
+
stdout.write(`\u2717 Plugin: ${error}
|
|
73086
|
+
`);
|
|
73087
|
+
return { marketplaceScope, pluginScope, marketplaceAction, pluginAction, error };
|
|
73088
|
+
}
|
|
73089
|
+
}
|
|
73090
|
+
return { marketplaceScope, pluginScope, marketplaceAction, pluginAction };
|
|
73091
|
+
}
|
|
73092
|
+
}
|
|
73093
|
+
});
|
|
73094
|
+
|
|
72704
73095
|
// ../sidekick-cli/dist/commands/setup/index.js
|
|
72705
73096
|
var require_setup = __commonJS({
|
|
72706
73097
|
"../sidekick-cli/dist/commands/setup/index.js"(exports2) {
|
|
@@ -72749,6 +73140,7 @@ var require_setup = __commonJS({
|
|
|
72749
73140
|
var os = __importStar(require("node:os"));
|
|
72750
73141
|
var core_1 = require_dist4();
|
|
72751
73142
|
var prompts_js_1 = require_prompts();
|
|
73143
|
+
var plugin_installer_js_1 = require_plugin_installer();
|
|
72752
73144
|
var USAGE_TEXT = `Usage: sidekick setup [options]
|
|
72753
73145
|
|
|
72754
73146
|
Run the interactive setup wizard to configure sidekick for Claude Code.
|
|
@@ -72756,11 +73148,15 @@ When scripting flags are provided, runs non-interactively for those settings onl
|
|
|
72756
73148
|
|
|
72757
73149
|
Options:
|
|
72758
73150
|
--check Check configuration status (alias: sidekick doctor)
|
|
73151
|
+
--only=<checks> Run only specific doctor checks (comma-separated)
|
|
73152
|
+
Valid checks: api-keys, statusline, gitignore, plugin, liveness
|
|
72759
73153
|
--force Apply all defaults non-interactively
|
|
72760
73154
|
--help Show this help message
|
|
72761
73155
|
|
|
72762
73156
|
Scripting Flags (for non-interactive/partial setup):
|
|
72763
|
-
--
|
|
73157
|
+
--marketplace-scope=<scope> Install marketplace: user | project | local
|
|
73158
|
+
--plugin-scope=<scope> Install plugin: user | project | local
|
|
73159
|
+
--statusline-scope=<scope> Configure statusline: user | project | local
|
|
72764
73160
|
--gitignore Update .gitignore to exclude sidekick files
|
|
72765
73161
|
--no-gitignore Skip .gitignore configuration
|
|
72766
73162
|
--personas Enable persona features
|
|
@@ -72771,11 +73167,23 @@ Scripting Flags (for non-interactive/partial setup):
|
|
|
72771
73167
|
Examples:
|
|
72772
73168
|
sidekick setup Interactive wizard
|
|
72773
73169
|
sidekick setup --check Check current status
|
|
73170
|
+
sidekick doctor --only=liveness Run only the liveness check
|
|
73171
|
+
sidekick doctor --only=plugin,liveness Run plugin and liveness checks
|
|
72774
73172
|
sidekick setup --statusline-scope=user Configure statusline only
|
|
72775
73173
|
sidekick setup --gitignore --personas Configure gitignore and enable personas
|
|
72776
73174
|
OPENROUTER_API_KEY=sk-xxx sidekick setup --personas --api-key-scope=user
|
|
72777
73175
|
`;
|
|
72778
73176
|
var STATUSLINE_COMMAND = "npx @scotthamilton77/sidekick statusline --project-dir=$CLAUDE_PROJECT_DIR";
|
|
73177
|
+
function statuslineSettingsPath(scope, homeDir, projectDir) {
|
|
73178
|
+
switch (scope) {
|
|
73179
|
+
case "user":
|
|
73180
|
+
return path.join(homeDir, ".claude", "settings.json");
|
|
73181
|
+
case "project":
|
|
73182
|
+
return path.join(projectDir, ".claude", "settings.json");
|
|
73183
|
+
case "local":
|
|
73184
|
+
return path.join(projectDir, ".claude", "settings.local.json");
|
|
73185
|
+
}
|
|
73186
|
+
}
|
|
72779
73187
|
function getPluginStatusLabel(status) {
|
|
72780
73188
|
switch (status) {
|
|
72781
73189
|
case "plugin":
|
|
@@ -72786,6 +73194,10 @@ Examples:
|
|
|
72786
73194
|
return "conflict (both plugin and dev-mode detected!)";
|
|
72787
73195
|
case "none":
|
|
72788
73196
|
return "not installed";
|
|
73197
|
+
case "timeout":
|
|
73198
|
+
return "check timed out";
|
|
73199
|
+
case "error":
|
|
73200
|
+
return "check failed";
|
|
72789
73201
|
}
|
|
72790
73202
|
}
|
|
72791
73203
|
function getApiKeyStatusType(health) {
|
|
@@ -72804,6 +73216,8 @@ Examples:
|
|
|
72804
73216
|
case "dev-mode":
|
|
72805
73217
|
return "\u2713";
|
|
72806
73218
|
case "both":
|
|
73219
|
+
case "timeout":
|
|
73220
|
+
case "error":
|
|
72807
73221
|
return "\u26A0";
|
|
72808
73222
|
case "none":
|
|
72809
73223
|
return "\u2717";
|
|
@@ -72815,6 +73229,7 @@ Examples:
|
|
|
72815
73229
|
return "\u2713";
|
|
72816
73230
|
case "inactive":
|
|
72817
73231
|
return "\u2717";
|
|
73232
|
+
case "timeout":
|
|
72818
73233
|
case "error":
|
|
72819
73234
|
return "\u26A0";
|
|
72820
73235
|
}
|
|
@@ -72825,6 +73240,8 @@ Examples:
|
|
|
72825
73240
|
return "hooks responding";
|
|
72826
73241
|
case "inactive":
|
|
72827
73242
|
return "hooks not detected";
|
|
73243
|
+
case "timeout":
|
|
73244
|
+
return "check timed out";
|
|
72828
73245
|
case "error":
|
|
72829
73246
|
return "check failed";
|
|
72830
73247
|
}
|
|
@@ -72924,27 +73341,36 @@ Examples:
|
|
|
72924
73341
|
stdout.write("\u2502 Run 'sidekick setup' again anytime to reconfigure. \u2502\n");
|
|
72925
73342
|
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");
|
|
72926
73343
|
}
|
|
72927
|
-
async function
|
|
73344
|
+
async function runStep2Statusline(wctx, pluginScope) {
|
|
72928
73345
|
const { ctx, homeDir, projectDir, logger } = wctx;
|
|
72929
|
-
(0, prompts_js_1.printHeader)(ctx, "Step
|
|
72930
|
-
const
|
|
72931
|
-
|
|
72932
|
-
{
|
|
72933
|
-
|
|
72934
|
-
|
|
72935
|
-
|
|
72936
|
-
|
|
72937
|
-
|
|
72938
|
-
|
|
72939
|
-
|
|
73346
|
+
(0, prompts_js_1.printHeader)(ctx, "Step 2: Statusline Configuration", "Claude Code plugins cannot provide statusline config directly.");
|
|
73347
|
+
const STATUSLINE_SCOPE_OPTIONS = {
|
|
73348
|
+
user: { label: "User-level (~/.claude/settings.json)", description: "Works in all projects" },
|
|
73349
|
+
project: { label: "Project-level (.claude/settings.json)", description: "Shared via git" },
|
|
73350
|
+
local: { label: "Local (.claude/settings.local.json)", description: "This machine only, not shared via git" }
|
|
73351
|
+
};
|
|
73352
|
+
const validScopes = (0, plugin_installer_js_1.getValidPluginScopes)(pluginScope);
|
|
73353
|
+
let statuslineScope;
|
|
73354
|
+
if (validScopes.length === 1) {
|
|
73355
|
+
statuslineScope = validScopes[0];
|
|
73356
|
+
(0, prompts_js_1.printStatus)(ctx, "info", `Statusline scope auto-selected: ${statuslineScope} (constrained by plugin scope)`);
|
|
73357
|
+
} else {
|
|
73358
|
+
const options = validScopes.map((scope) => ({
|
|
73359
|
+
value: scope,
|
|
73360
|
+
...STATUSLINE_SCOPE_OPTIONS[scope]
|
|
73361
|
+
}));
|
|
73362
|
+
statuslineScope = await (0, prompts_js_1.promptSelect)(ctx, "Where should sidekick configure your statusline?", options);
|
|
73363
|
+
}
|
|
73364
|
+
const settingsPath = statuslineSettingsPath(statuslineScope, homeDir, projectDir);
|
|
73365
|
+
const wrote = await configureStatusline(settingsPath, logger);
|
|
72940
73366
|
if (wrote) {
|
|
72941
|
-
(0, prompts_js_1.printStatus)(ctx, "success", `Statusline configured in ${
|
|
73367
|
+
(0, prompts_js_1.printStatus)(ctx, "success", `Statusline configured in ${settingsPath}`);
|
|
72942
73368
|
} else {
|
|
72943
73369
|
(0, prompts_js_1.printStatus)(ctx, "warning", "Statusline managed by dev-mode (skipped)");
|
|
72944
73370
|
}
|
|
72945
73371
|
return statuslineScope;
|
|
72946
73372
|
}
|
|
72947
|
-
async function
|
|
73373
|
+
async function runStep3Gitignore(wctx, force) {
|
|
72948
73374
|
const { ctx, projectDir } = wctx;
|
|
72949
73375
|
const currentStatus = await (0, core_1.detectGitignoreStatus)(projectDir);
|
|
72950
73376
|
if (currentStatus === "installed") {
|
|
@@ -72958,7 +73384,7 @@ Examples:
|
|
|
72958
73384
|
const result2 = await (0, core_1.installGitignoreSection)(projectDir);
|
|
72959
73385
|
return result2.status === "error" ? "missing" : "installed";
|
|
72960
73386
|
}
|
|
72961
|
-
(0, prompts_js_1.printHeader)(ctx, "Step
|
|
73387
|
+
(0, prompts_js_1.printHeader)(ctx, "Step 3: Git Configuration", "Sidekick creates logs and session data that should not be committed.");
|
|
72962
73388
|
if (needsRepair) {
|
|
72963
73389
|
(0, prompts_js_1.printStatus)(ctx, "warning", "Existing .gitignore section is incomplete and needs repair");
|
|
72964
73390
|
}
|
|
@@ -72984,10 +73410,10 @@ Examples:
|
|
|
72984
73410
|
(0, prompts_js_1.printStatus)(ctx, "success", message);
|
|
72985
73411
|
return "installed";
|
|
72986
73412
|
}
|
|
72987
|
-
async function
|
|
73413
|
+
async function runStep4Personas(wctx) {
|
|
72988
73414
|
const { ctx, homeDir } = wctx;
|
|
72989
73415
|
const stdout = ctx.stdout;
|
|
72990
|
-
(0, prompts_js_1.printHeader)(ctx, "Step
|
|
73416
|
+
(0, prompts_js_1.printHeader)(ctx, "Step 4: Persona Features", "Sidekick includes AI personas (Marvin, Skippy, etc.) that add\npersonality to your coding sessions with snarky messages and contextual nudges.");
|
|
72991
73417
|
stdout.write("These require an OpenRouter API key (small cost per message).\n\n");
|
|
72992
73418
|
const wantPersonas = await (0, prompts_js_1.promptConfirm)(ctx, "Enable persona features?", true);
|
|
72993
73419
|
let apiKeyHealth = "not-required";
|
|
@@ -73063,9 +73489,9 @@ Examples:
|
|
|
73063
73489
|
const postDetection = await setupService.detectAllApiKeys("OPENROUTER_API_KEY", true);
|
|
73064
73490
|
return { health: result.valid ? "healthy" : "invalid", detection: postDetection };
|
|
73065
73491
|
}
|
|
73066
|
-
async function
|
|
73492
|
+
async function runStep5AutoConfig(wctx) {
|
|
73067
73493
|
const { ctx } = wctx;
|
|
73068
|
-
(0, prompts_js_1.printHeader)(ctx, "Step
|
|
73494
|
+
(0, prompts_js_1.printHeader)(ctx, "Step 5: Project Auto-Configuration");
|
|
73069
73495
|
const autoConfig = await (0, prompts_js_1.promptSelect)(ctx, "When sidekick runs in a new project for the first time:", [
|
|
73070
73496
|
{ value: "auto", label: "Auto-configure using my defaults", description: "Recommended" },
|
|
73071
73497
|
{ value: "manual", label: "Do nothing", description: "Manual setup only" }
|
|
@@ -73111,7 +73537,8 @@ Examples:
|
|
|
73111
73537
|
const { statuslineScope, gitignoreStatus, wantPersonas, apiKeyHealth, autoConfig } = state;
|
|
73112
73538
|
const stdout = ctx.stdout;
|
|
73113
73539
|
(0, prompts_js_1.printHeader)(ctx, "Summary");
|
|
73114
|
-
|
|
73540
|
+
const scopeLabel = { user: "User-level", project: "Project-level", local: "Local" }[statuslineScope];
|
|
73541
|
+
(0, prompts_js_1.printStatus)(ctx, "success", `Statusline: ${scopeLabel}`);
|
|
73115
73542
|
let gitignoreStatusType;
|
|
73116
73543
|
let gitignoreLabel;
|
|
73117
73544
|
switch (gitignoreStatus) {
|
|
@@ -73160,13 +73587,26 @@ Examples:
|
|
|
73160
73587
|
if (!force) {
|
|
73161
73588
|
printWizardHeader(stdout);
|
|
73162
73589
|
}
|
|
73163
|
-
const
|
|
73164
|
-
|
|
73165
|
-
|
|
73166
|
-
|
|
73590
|
+
const pluginResult = await (0, plugin_installer_js_1.ensurePluginInstalled)({
|
|
73591
|
+
logger,
|
|
73592
|
+
stdout,
|
|
73593
|
+
force,
|
|
73594
|
+
projectDir,
|
|
73595
|
+
ctx: wctx.ctx,
|
|
73596
|
+
marketplaceScope: options.marketplaceScope,
|
|
73597
|
+
pluginScope: options.pluginScope
|
|
73598
|
+
});
|
|
73599
|
+
if (pluginResult.error) {
|
|
73600
|
+
logger.warn("Plugin installation had issues, continuing with setup", { error: pluginResult.error });
|
|
73601
|
+
}
|
|
73602
|
+
const forceStatuslineScope = pluginResult.pluginScope;
|
|
73603
|
+
const statuslineScope = force ? forceStatuslineScope : await runStep2Statusline(wctx, pluginResult.pluginScope);
|
|
73604
|
+
const gitignoreStatus = await runStep3Gitignore(wctx, force);
|
|
73605
|
+
const { wantPersonas, apiKeyHealth, apiKeyDetection } = force ? { wantPersonas: true, apiKeyHealth: "not-required", apiKeyDetection: null } : await runStep4Personas(wctx);
|
|
73606
|
+
const autoConfig = force ? "auto" : await runStep5AutoConfig(wctx);
|
|
73167
73607
|
if (force) {
|
|
73168
|
-
const
|
|
73169
|
-
const wrote = await configureStatusline(
|
|
73608
|
+
const settingsPath = statuslineSettingsPath(forceStatuslineScope, homeDir, projectDir);
|
|
73609
|
+
const wrote = await configureStatusline(settingsPath, logger);
|
|
73170
73610
|
if (!wrote) {
|
|
73171
73611
|
stdout.write("\u26A0 Statusline managed by dev-mode (skipped)\n");
|
|
73172
73612
|
}
|
|
@@ -73184,7 +73624,9 @@ Examples:
|
|
|
73184
73624
|
printSummary(wctx, state);
|
|
73185
73625
|
} else {
|
|
73186
73626
|
stdout.write("Setup complete (force mode):\n");
|
|
73187
|
-
stdout.write(`
|
|
73627
|
+
stdout.write(` Plugin: ${pluginResult.pluginAction} (${pluginResult.pluginScope})
|
|
73628
|
+
`);
|
|
73629
|
+
stdout.write(` Statusline: ${forceStatuslineScope} (${statuslineSettingsPath(forceStatuslineScope, homeDir, projectDir)})
|
|
73188
73630
|
`);
|
|
73189
73631
|
stdout.write(` Gitignore: ${gitignoreStatus === "installed" ? "configured" : "skipped"}
|
|
73190
73632
|
`);
|
|
@@ -73196,15 +73638,32 @@ Examples:
|
|
|
73196
73638
|
return { exitCode: 0 };
|
|
73197
73639
|
}
|
|
73198
73640
|
function hasScriptingFlags(options) {
|
|
73199
|
-
return options.statuslineScope !== void 0 || options.gitignore !== void 0 || options.personas !== void 0 || options.apiKeyScope !== void 0 || options.autoConfig !== void 0;
|
|
73641
|
+
return options.marketplaceScope !== void 0 || options.pluginScope !== void 0 || options.statuslineScope !== void 0 || options.gitignore !== void 0 || options.personas !== void 0 || options.apiKeyScope !== void 0 || options.autoConfig !== void 0;
|
|
73200
73642
|
}
|
|
73201
73643
|
async function runScripted(projectDir, logger, stdout, options) {
|
|
73202
73644
|
const homeDir = options.homeDir ?? os.homedir();
|
|
73203
73645
|
const setupService = new core_1.SetupStatusService(projectDir, { homeDir, logger });
|
|
73204
73646
|
let configuredCount = 0;
|
|
73647
|
+
if (options.marketplaceScope !== void 0 || options.pluginScope !== void 0) {
|
|
73648
|
+
const pluginResult = await (0, plugin_installer_js_1.ensurePluginInstalled)({
|
|
73649
|
+
logger,
|
|
73650
|
+
stdout,
|
|
73651
|
+
force: true,
|
|
73652
|
+
// scripted mode never prompts
|
|
73653
|
+
projectDir,
|
|
73654
|
+
marketplaceScope: options.marketplaceScope,
|
|
73655
|
+
pluginScope: options.pluginScope
|
|
73656
|
+
});
|
|
73657
|
+
if (pluginResult.error) {
|
|
73658
|
+
stdout.write(`\u26A0 Plugin installation issue: ${pluginResult.error}
|
|
73659
|
+
`);
|
|
73660
|
+
} else {
|
|
73661
|
+
configuredCount++;
|
|
73662
|
+
}
|
|
73663
|
+
}
|
|
73205
73664
|
if (options.statuslineScope) {
|
|
73206
|
-
const
|
|
73207
|
-
const wrote = await configureStatusline(
|
|
73665
|
+
const settingsPath = statuslineSettingsPath(options.statuslineScope, homeDir, projectDir);
|
|
73666
|
+
const wrote = await configureStatusline(settingsPath, logger);
|
|
73208
73667
|
if (wrote) {
|
|
73209
73668
|
stdout.write(`\u2713 Statusline configured (${options.statuslineScope}-level)
|
|
73210
73669
|
`);
|
|
@@ -73306,64 +73765,110 @@ Configured ${configuredCount} setting${configuredCount === 1 ? "" : "s"}.
|
|
|
73306
73765
|
}
|
|
73307
73766
|
return { exitCode: 0 };
|
|
73308
73767
|
}
|
|
73768
|
+
var DOCTOR_CHECK_NAMES = ["api-keys", "statusline", "gitignore", "plugin", "liveness"];
|
|
73769
|
+
function parseDoctorOnly(only) {
|
|
73770
|
+
if (!only)
|
|
73771
|
+
return null;
|
|
73772
|
+
const requested = only.split(",").map((s) => s.trim());
|
|
73773
|
+
const invalid = requested.filter((s) => !DOCTOR_CHECK_NAMES.includes(s));
|
|
73774
|
+
if (invalid.length > 0) {
|
|
73775
|
+
throw new Error(`Unknown doctor check(s): ${invalid.join(", ")}. Valid: ${DOCTOR_CHECK_NAMES.join(", ")}`);
|
|
73776
|
+
}
|
|
73777
|
+
return new Set(requested);
|
|
73778
|
+
}
|
|
73309
73779
|
async function runDoctor(projectDir, logger, stdout, options) {
|
|
73310
73780
|
const homeDir = options?.homeDir ?? os.homedir();
|
|
73311
|
-
const skipLiveness = options?.skipLiveness ?? false;
|
|
73312
73781
|
const setupService = new core_1.SetupStatusService(projectDir, { homeDir, logger });
|
|
73782
|
+
let filter;
|
|
73783
|
+
try {
|
|
73784
|
+
filter = parseDoctorOnly(options?.only);
|
|
73785
|
+
} catch (err) {
|
|
73786
|
+
stdout.write(`${err instanceof Error ? err.message : String(err)}
|
|
73787
|
+
`);
|
|
73788
|
+
return { exitCode: 1 };
|
|
73789
|
+
}
|
|
73790
|
+
const shouldRun = (check) => filter === null || filter.has(check);
|
|
73313
73791
|
stdout.write("\nSidekick Doctor\n");
|
|
73314
73792
|
stdout.write("===============\n\n");
|
|
73315
|
-
|
|
73316
|
-
|
|
73317
|
-
|
|
73318
|
-
|
|
73319
|
-
|
|
73320
|
-
|
|
73321
|
-
|
|
73322
|
-
|
|
73793
|
+
const promises = [];
|
|
73794
|
+
let doctorResult = null;
|
|
73795
|
+
if (shouldRun("api-keys") || shouldRun("statusline")) {
|
|
73796
|
+
promises.push(setupService.runDoctorCheck().then((result) => {
|
|
73797
|
+
doctorResult = result;
|
|
73798
|
+
if (result.fixes.length > 0) {
|
|
73799
|
+
stdout.write("Cache corrections:\n");
|
|
73800
|
+
for (const fix of result.fixes) {
|
|
73801
|
+
stdout.write(` \u2713 ${fix}
|
|
73323
73802
|
`);
|
|
73324
|
-
|
|
73325
|
-
|
|
73326
|
-
|
|
73327
|
-
|
|
73328
|
-
|
|
73329
|
-
|
|
73330
|
-
|
|
73331
|
-
|
|
73332
|
-
|
|
73333
|
-
|
|
73334
|
-
|
|
73335
|
-
|
|
73336
|
-
|
|
73337
|
-
|
|
73338
|
-
const apiKeyIcon = openRouterHealth === "healthy" || openRouterHealth === "not-required" ? "\u2713" : "\u26A0";
|
|
73339
|
-
const scopeBreakdown = formatApiKeyScopes(openRouterResult.scopes);
|
|
73340
|
-
const usedToSource = { project: "project-env", user: "user-env", env: "env-var" };
|
|
73341
|
-
const sourceLabel = formatApiKeySource(openRouterResult.used ? usedToSource[openRouterResult.used] ?? null : null);
|
|
73342
|
-
stdout.write("\n");
|
|
73343
|
-
stdout.write(`${pluginIcon} Plugin: ${pluginLabel}
|
|
73803
|
+
}
|
|
73804
|
+
}
|
|
73805
|
+
if (shouldRun("api-keys")) {
|
|
73806
|
+
const openRouterResult = result.apiKeys.OPENROUTER_API_KEY;
|
|
73807
|
+
const openRouterHealth = openRouterResult.actual;
|
|
73808
|
+
const apiKeyIcon = openRouterHealth === "healthy" || openRouterHealth === "not-required" ? "\u2713" : "\u26A0";
|
|
73809
|
+
const scopeBreakdown = formatApiKeyScopes(openRouterResult.scopes);
|
|
73810
|
+
const usedToSource = {
|
|
73811
|
+
project: "project-env",
|
|
73812
|
+
user: "user-env",
|
|
73813
|
+
env: "env-var"
|
|
73814
|
+
};
|
|
73815
|
+
const sourceLabel = formatApiKeySource(openRouterResult.used ? usedToSource[openRouterResult.used] ?? null : null);
|
|
73816
|
+
stdout.write(`${apiKeyIcon} OpenRouter API Key: ${openRouterHealth}${sourceLabel} ${scopeBreakdown}
|
|
73344
73817
|
`);
|
|
73345
|
-
|
|
73346
|
-
|
|
73347
|
-
|
|
73348
|
-
|
|
73818
|
+
}
|
|
73819
|
+
if (shouldRun("statusline")) {
|
|
73820
|
+
const statuslineIcon = result.statusline.actual !== "none" ? "\u2713" : "\u26A0";
|
|
73821
|
+
stdout.write(`${statuslineIcon} Statusline: ${result.statusline.actual}
|
|
73349
73822
|
`);
|
|
73823
|
+
}
|
|
73824
|
+
}));
|
|
73350
73825
|
}
|
|
73351
|
-
|
|
73826
|
+
let gitignore = null;
|
|
73827
|
+
if (shouldRun("gitignore")) {
|
|
73828
|
+
promises.push((0, core_1.detectGitignoreStatus)(projectDir).then((result) => {
|
|
73829
|
+
gitignore = result;
|
|
73830
|
+
const gitignoreIcon = result === "installed" ? "\u2713" : "\u26A0";
|
|
73831
|
+
stdout.write(`${gitignoreIcon} Gitignore: ${result}
|
|
73352
73832
|
`);
|
|
73353
|
-
|
|
73833
|
+
}));
|
|
73834
|
+
}
|
|
73835
|
+
let pluginStatus = null;
|
|
73836
|
+
let liveness = null;
|
|
73837
|
+
if (shouldRun("plugin") || shouldRun("liveness")) {
|
|
73838
|
+
promises.push(setupService.detectPluginInstallation().then(async (status) => {
|
|
73839
|
+
pluginStatus = status;
|
|
73840
|
+
if (shouldRun("plugin")) {
|
|
73841
|
+
const pluginIcon = getPluginStatusIcon(status);
|
|
73842
|
+
const pluginLabel = getPluginStatusLabel(status);
|
|
73843
|
+
stdout.write(`${pluginIcon} Plugin: ${pluginLabel}
|
|
73354
73844
|
`);
|
|
73355
|
-
|
|
73845
|
+
}
|
|
73846
|
+
const isPluginPresent = status === "plugin" || status === "dev-mode" || status === "both";
|
|
73847
|
+
if (shouldRun("liveness") && isPluginPresent) {
|
|
73848
|
+
logger.info("Starting plugin liveness check");
|
|
73849
|
+
liveness = await setupService.detectPluginLiveness();
|
|
73850
|
+
const livenessIcon = getLivenessIcon(liveness);
|
|
73851
|
+
const livenessLabel = getLivenessLabel(liveness);
|
|
73852
|
+
stdout.write(`${livenessIcon} Plugin Liveness: ${livenessLabel}
|
|
73356
73853
|
`);
|
|
73357
|
-
|
|
73358
|
-
|
|
73359
|
-
|
|
73360
|
-
|
|
73361
|
-
|
|
73854
|
+
logger.info("Plugin liveness check reported", { status: liveness });
|
|
73855
|
+
}
|
|
73856
|
+
}));
|
|
73857
|
+
}
|
|
73858
|
+
await Promise.all(promises);
|
|
73859
|
+
if (filter === null) {
|
|
73860
|
+
const isPluginOk = pluginStatus === "plugin" || pluginStatus === "dev-mode";
|
|
73861
|
+
const isPluginLive = liveness === null || liveness === "active";
|
|
73862
|
+
const isHealthy = doctorResult.overallHealth === "healthy" && gitignore === "installed" && isPluginOk && isPluginLive;
|
|
73863
|
+
const overallIcon = isHealthy ? "\u2713" : "\u26A0";
|
|
73864
|
+
stdout.write(`${overallIcon} Overall: ${isHealthy ? "healthy" : "needs attention"}
|
|
73362
73865
|
`);
|
|
73363
|
-
|
|
73364
|
-
|
|
73866
|
+
if (!isHealthy) {
|
|
73867
|
+
stdout.write("\nRun 'sidekick setup' to configure.\n");
|
|
73868
|
+
}
|
|
73869
|
+
return { exitCode: isHealthy ? 0 : 1 };
|
|
73365
73870
|
}
|
|
73366
|
-
return { exitCode:
|
|
73871
|
+
return { exitCode: 0 };
|
|
73367
73872
|
}
|
|
73368
73873
|
async function handleSetupCommand(projectDir, logger, stdout, options = {}) {
|
|
73369
73874
|
if (options.help) {
|
|
@@ -73371,7 +73876,7 @@ Configured ${configuredCount} setting${configuredCount === 1 ? "" : "s"}.
|
|
|
73371
73876
|
return { exitCode: 0 };
|
|
73372
73877
|
}
|
|
73373
73878
|
if (options.checkOnly) {
|
|
73374
|
-
return runDoctor(projectDir, logger, stdout, { homeDir: options.homeDir });
|
|
73879
|
+
return runDoctor(projectDir, logger, stdout, { homeDir: options.homeDir, only: options.only });
|
|
73375
73880
|
}
|
|
73376
73881
|
if (hasScriptingFlags(options)) {
|
|
73377
73882
|
return runScripted(projectDir, logger, stdout, options);
|
|
@@ -73461,6 +73966,10 @@ var require_uninstall = __commonJS({
|
|
|
73461
73966
|
dryRun,
|
|
73462
73967
|
removeHooks: true
|
|
73463
73968
|
});
|
|
73969
|
+
await cleanSettingsFile(path.join(projectDir, ".claude", "settings.json"), "project", logger, actions, {
|
|
73970
|
+
dryRun,
|
|
73971
|
+
removeHooks: true
|
|
73972
|
+
});
|
|
73464
73973
|
}
|
|
73465
73974
|
if (userDetected) {
|
|
73466
73975
|
await cleanSettingsFile(path.join(userHome, ".claude", "settings.json"), "user", logger, actions, {
|
|
@@ -73533,12 +74042,15 @@ var require_uninstall = __commonJS({
|
|
|
73533
74042
|
await fs.access(path.join(projectDir, ".sidekick", "setup-status.json"));
|
|
73534
74043
|
return true;
|
|
73535
74044
|
} catch {
|
|
73536
|
-
|
|
73537
|
-
|
|
73538
|
-
|
|
73539
|
-
|
|
73540
|
-
|
|
74045
|
+
for (const file of ["settings.local.json", "settings.json"]) {
|
|
74046
|
+
try {
|
|
74047
|
+
const content = await fs.readFile(path.join(projectDir, ".claude", file), "utf-8");
|
|
74048
|
+
if (content.includes("sidekick"))
|
|
74049
|
+
return true;
|
|
74050
|
+
} catch {
|
|
74051
|
+
}
|
|
73541
74052
|
}
|
|
74053
|
+
return false;
|
|
73542
74054
|
}
|
|
73543
74055
|
}
|
|
73544
74056
|
async function detectUserScope(userHome) {
|
|
@@ -73855,10 +74367,7 @@ var require_cli = __commonJS({
|
|
|
73855
74367
|
var promises_12 = require("node:fs/promises");
|
|
73856
74368
|
var node_stream_1 = require("node:stream");
|
|
73857
74369
|
var yargs_parser_1 = __importDefault2(require_build());
|
|
73858
|
-
var VERSION = true ? "0.0.8-alpha.
|
|
73859
|
-
function isInSandbox() {
|
|
73860
|
-
return process.env.SANDBOX_RUNTIME === "1";
|
|
73861
|
-
}
|
|
74370
|
+
var VERSION = true ? "0.0.8-alpha.8" : "dev";
|
|
73862
74371
|
var SANDBOX_ERROR_MESSAGE = `Error: Daemon commands cannot run in sandbox mode.
|
|
73863
74372
|
|
|
73864
74373
|
Claude Code's sandbox blocks Unix socket operations required for daemon IPC.
|
|
@@ -73867,6 +74376,7 @@ To run this command, use dangerouslyDisableSandbox: true in the Bash tool call.
|
|
|
73867
74376
|
Example: { "command": "pnpm sidekick daemon status", "dangerouslyDisableSandbox": true }
|
|
73868
74377
|
`;
|
|
73869
74378
|
var types_1 = require_dist();
|
|
74379
|
+
var core_1 = require_dist4();
|
|
73870
74380
|
var runtime_1 = require_runtime();
|
|
73871
74381
|
var UnknownOptionError = class extends Error {
|
|
73872
74382
|
constructor(unknownOptions) {
|
|
@@ -73901,7 +74411,10 @@ Example: { "command": "pnpm sidekick daemon status", "dangerouslyDisableSandbox"
|
|
|
73901
74411
|
"scope",
|
|
73902
74412
|
"statusline-scope",
|
|
73903
74413
|
"api-key-scope",
|
|
73904
|
-
"auto-config"
|
|
74414
|
+
"auto-config",
|
|
74415
|
+
"only",
|
|
74416
|
+
"marketplace-scope",
|
|
74417
|
+
"plugin-scope"
|
|
73905
74418
|
],
|
|
73906
74419
|
number: ["port", "width"],
|
|
73907
74420
|
alias: { h: "help", v: "version" }
|
|
@@ -73955,7 +74468,10 @@ Example: { "command": "pnpm sidekick daemon status", "dangerouslyDisableSandbox"
|
|
|
73955
74468
|
gitignore: hasGitignoreFlag ? Boolean(parsed.gitignore) : void 0,
|
|
73956
74469
|
personas: hasPersonasFlag ? Boolean(parsed.personas) : void 0,
|
|
73957
74470
|
apiKeyScope: parsed["api-key-scope"],
|
|
73958
|
-
autoConfig: parsed["auto-config"]
|
|
74471
|
+
autoConfig: parsed["auto-config"],
|
|
74472
|
+
only: parsed.only,
|
|
74473
|
+
marketplaceScope: parsed["marketplace-scope"],
|
|
74474
|
+
pluginScope: parsed["plugin-scope"]
|
|
73959
74475
|
};
|
|
73960
74476
|
}
|
|
73961
74477
|
function parseHookInput(stdinData) {
|
|
@@ -74119,7 +74635,7 @@ Run 'sidekick hook --help' for available hooks.
|
|
|
74119
74635
|
}
|
|
74120
74636
|
if (parsed.command === "daemon") {
|
|
74121
74637
|
const subcommand = parsed.help ? "--help" : parsed.kill ? "kill" : parsed._ && parsed._[1] || "status";
|
|
74122
|
-
if (isInSandbox() && subcommand !== "--help") {
|
|
74638
|
+
if ((0, core_1.isInSandbox)() && subcommand !== "--help") {
|
|
74123
74639
|
stdout.write(SANDBOX_ERROR_MESSAGE);
|
|
74124
74640
|
return { exitCode: 1, stdout: SANDBOX_ERROR_MESSAGE, stderr: "" };
|
|
74125
74641
|
}
|
|
@@ -74193,7 +74709,9 @@ Run 'sidekick hook --help' for available hooks.
|
|
|
74193
74709
|
gitignore: parsed.gitignore,
|
|
74194
74710
|
personas: parsed.personas,
|
|
74195
74711
|
apiKeyScope: parsed.apiKeyScope,
|
|
74196
|
-
autoConfig: parsed.autoConfig
|
|
74712
|
+
autoConfig: parsed.autoConfig,
|
|
74713
|
+
marketplaceScope: parsed.marketplaceScope,
|
|
74714
|
+
pluginScope: parsed.pluginScope
|
|
74197
74715
|
});
|
|
74198
74716
|
return { exitCode: result.exitCode, stdout: "", stderr: "" };
|
|
74199
74717
|
}
|
|
@@ -74210,7 +74728,8 @@ Run 'sidekick hook --help' for available hooks.
|
|
|
74210
74728
|
if (parsed.command === "doctor") {
|
|
74211
74729
|
const { handleSetupCommand } = await Promise.resolve().then(() => __importStar(require_setup2()));
|
|
74212
74730
|
const result = await handleSetupCommand(runtime.projectRoot || process.cwd(), runtime.logger, stdout, {
|
|
74213
|
-
checkOnly: true
|
|
74731
|
+
checkOnly: true,
|
|
74732
|
+
only: parsed.only
|
|
74214
74733
|
});
|
|
74215
74734
|
return { exitCode: result.exitCode, stdout: "", stderr: "" };
|
|
74216
74735
|
}
|