@scotthamilton77/sidekick 0.0.8-alpha.7 → 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.
Files changed (3) hide show
  1. package/dist/bin.js +476 -48
  2. package/dist/daemon.js +27 -4
  3. 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.local.json
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 both (project overrides user)
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()) {
@@ -57524,7 +57543,7 @@ var require_dist4 = __commonJS({
57524
57543
  };
57525
57544
  Object.defineProperty(exports2, "__esModule", { value: true });
57526
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;
57527
- 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;
57528
57547
  var types_1 = require_dist();
57529
57548
  Object.defineProperty(exports2, "TaskTypes", { enumerable: true, get: function() {
57530
57549
  return types_1.TaskTypes;
@@ -57821,6 +57840,10 @@ var require_dist4 = __commonJS({
57821
57840
  Object.defineProperty(exports2, "DaemonGlobalLogMetricsDescriptor", { enumerable: true, get: function() {
57822
57841
  return index_js_1.DaemonGlobalLogMetricsDescriptor;
57823
57842
  } });
57843
+ var sandbox_1 = require_sandbox();
57844
+ Object.defineProperty(exports2, "isInSandbox", { enumerable: true, get: function() {
57845
+ return sandbox_1.isInSandbox;
57846
+ } });
57824
57847
  }
57825
57848
  });
57826
57849
 
@@ -68286,6 +68309,10 @@ var require_hook_command = __commonJS({
68286
68309
  };
68287
68310
  }
68288
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
+ }
68289
68316
  try {
68290
68317
  const setupService = new core_1.SetupStatusService(projectRoot);
68291
68318
  const setupState = await setupService.getSetupState();
@@ -72730,6 +72757,341 @@ var require_prompts = __commonJS({
72730
72757
  }
72731
72758
  });
72732
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
+
72733
73095
  // ../sidekick-cli/dist/commands/setup/index.js
72734
73096
  var require_setup = __commonJS({
72735
73097
  "../sidekick-cli/dist/commands/setup/index.js"(exports2) {
@@ -72778,6 +73140,7 @@ var require_setup = __commonJS({
72778
73140
  var os = __importStar(require("node:os"));
72779
73141
  var core_1 = require_dist4();
72780
73142
  var prompts_js_1 = require_prompts();
73143
+ var plugin_installer_js_1 = require_plugin_installer();
72781
73144
  var USAGE_TEXT = `Usage: sidekick setup [options]
72782
73145
 
72783
73146
  Run the interactive setup wizard to configure sidekick for Claude Code.
@@ -72791,7 +73154,9 @@ Options:
72791
73154
  --help Show this help message
72792
73155
 
72793
73156
  Scripting Flags (for non-interactive/partial setup):
72794
- --statusline-scope=<scope> Configure statusline: user | project
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
72795
73160
  --gitignore Update .gitignore to exclude sidekick files
72796
73161
  --no-gitignore Skip .gitignore configuration
72797
73162
  --personas Enable persona features
@@ -72809,6 +73174,16 @@ Examples:
72809
73174
  OPENROUTER_API_KEY=sk-xxx sidekick setup --personas --api-key-scope=user
72810
73175
  `;
72811
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
+ }
72812
73187
  function getPluginStatusLabel(status) {
72813
73188
  switch (status) {
72814
73189
  case "plugin":
@@ -72966,27 +73341,36 @@ Examples:
72966
73341
  stdout.write("\u2502 Run 'sidekick setup' again anytime to reconfigure. \u2502\n");
72967
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");
72968
73343
  }
72969
- async function runStep1Statusline(wctx) {
73344
+ async function runStep2Statusline(wctx, pluginScope) {
72970
73345
  const { ctx, homeDir, projectDir, logger } = wctx;
72971
- (0, prompts_js_1.printHeader)(ctx, "Step 1: Statusline Configuration", "Claude Code plugins cannot provide statusline config directly.");
72972
- const statuslineScope = await (0, prompts_js_1.promptSelect)(ctx, "Where should sidekick configure your statusline?", [
72973
- { value: "user", label: "User-level (~/.claude/settings.json)", description: "Works in all projects" },
72974
- {
72975
- value: "project",
72976
- label: "Project-level (.claude/settings.local.json)",
72977
- description: "This project only"
72978
- }
72979
- ]);
72980
- const statuslinePath = statuslineScope === "user" ? path.join(homeDir, ".claude", "settings.json") : path.join(projectDir, ".claude", "settings.local.json");
72981
- const wrote = await configureStatusline(statuslinePath, logger);
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);
72982
73366
  if (wrote) {
72983
- (0, prompts_js_1.printStatus)(ctx, "success", `Statusline configured in ${statuslinePath}`);
73367
+ (0, prompts_js_1.printStatus)(ctx, "success", `Statusline configured in ${settingsPath}`);
72984
73368
  } else {
72985
73369
  (0, prompts_js_1.printStatus)(ctx, "warning", "Statusline managed by dev-mode (skipped)");
72986
73370
  }
72987
73371
  return statuslineScope;
72988
73372
  }
72989
- async function runStep2Gitignore(wctx, force) {
73373
+ async function runStep3Gitignore(wctx, force) {
72990
73374
  const { ctx, projectDir } = wctx;
72991
73375
  const currentStatus = await (0, core_1.detectGitignoreStatus)(projectDir);
72992
73376
  if (currentStatus === "installed") {
@@ -73000,7 +73384,7 @@ Examples:
73000
73384
  const result2 = await (0, core_1.installGitignoreSection)(projectDir);
73001
73385
  return result2.status === "error" ? "missing" : "installed";
73002
73386
  }
73003
- (0, prompts_js_1.printHeader)(ctx, "Step 2: Git Configuration", "Sidekick creates logs and session data that should not be committed.");
73387
+ (0, prompts_js_1.printHeader)(ctx, "Step 3: Git Configuration", "Sidekick creates logs and session data that should not be committed.");
73004
73388
  if (needsRepair) {
73005
73389
  (0, prompts_js_1.printStatus)(ctx, "warning", "Existing .gitignore section is incomplete and needs repair");
73006
73390
  }
@@ -73026,10 +73410,10 @@ Examples:
73026
73410
  (0, prompts_js_1.printStatus)(ctx, "success", message);
73027
73411
  return "installed";
73028
73412
  }
73029
- async function runStep3Personas(wctx) {
73413
+ async function runStep4Personas(wctx) {
73030
73414
  const { ctx, homeDir } = wctx;
73031
73415
  const stdout = ctx.stdout;
73032
- (0, prompts_js_1.printHeader)(ctx, "Step 3: Persona Features", "Sidekick includes AI personas (Marvin, Skippy, etc.) that add\npersonality to your coding sessions with snarky messages and contextual nudges.");
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.");
73033
73417
  stdout.write("These require an OpenRouter API key (small cost per message).\n\n");
73034
73418
  const wantPersonas = await (0, prompts_js_1.promptConfirm)(ctx, "Enable persona features?", true);
73035
73419
  let apiKeyHealth = "not-required";
@@ -73105,9 +73489,9 @@ Examples:
73105
73489
  const postDetection = await setupService.detectAllApiKeys("OPENROUTER_API_KEY", true);
73106
73490
  return { health: result.valid ? "healthy" : "invalid", detection: postDetection };
73107
73491
  }
73108
- async function runStep4AutoConfig(wctx) {
73492
+ async function runStep5AutoConfig(wctx) {
73109
73493
  const { ctx } = wctx;
73110
- (0, prompts_js_1.printHeader)(ctx, "Step 4: Project Auto-Configuration");
73494
+ (0, prompts_js_1.printHeader)(ctx, "Step 5: Project Auto-Configuration");
73111
73495
  const autoConfig = await (0, prompts_js_1.promptSelect)(ctx, "When sidekick runs in a new project for the first time:", [
73112
73496
  { value: "auto", label: "Auto-configure using my defaults", description: "Recommended" },
73113
73497
  { value: "manual", label: "Do nothing", description: "Manual setup only" }
@@ -73153,7 +73537,8 @@ Examples:
73153
73537
  const { statuslineScope, gitignoreStatus, wantPersonas, apiKeyHealth, autoConfig } = state;
73154
73538
  const stdout = ctx.stdout;
73155
73539
  (0, prompts_js_1.printHeader)(ctx, "Summary");
73156
- (0, prompts_js_1.printStatus)(ctx, "success", `Statusline: ${statuslineScope === "user" ? "User-level" : "Project-level"}`);
73540
+ const scopeLabel = { user: "User-level", project: "Project-level", local: "Local" }[statuslineScope];
73541
+ (0, prompts_js_1.printStatus)(ctx, "success", `Statusline: ${scopeLabel}`);
73157
73542
  let gitignoreStatusType;
73158
73543
  let gitignoreLabel;
73159
73544
  switch (gitignoreStatus) {
@@ -73202,13 +73587,26 @@ Examples:
73202
73587
  if (!force) {
73203
73588
  printWizardHeader(stdout);
73204
73589
  }
73205
- const statuslineScope = force ? "user" : await runStep1Statusline(wctx);
73206
- const gitignoreStatus = await runStep2Gitignore(wctx, force);
73207
- const { wantPersonas, apiKeyHealth, apiKeyDetection } = force ? { wantPersonas: true, apiKeyHealth: "not-required", apiKeyDetection: null } : await runStep3Personas(wctx);
73208
- const autoConfig = force ? "auto" : await runStep4AutoConfig(wctx);
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);
73209
73607
  if (force) {
73210
- const statuslinePath = path.join(homeDir, ".claude", "settings.json");
73211
- const wrote = await configureStatusline(statuslinePath, logger);
73608
+ const settingsPath = statuslineSettingsPath(forceStatuslineScope, homeDir, projectDir);
73609
+ const wrote = await configureStatusline(settingsPath, logger);
73212
73610
  if (!wrote) {
73213
73611
  stdout.write("\u26A0 Statusline managed by dev-mode (skipped)\n");
73214
73612
  }
@@ -73226,7 +73624,9 @@ Examples:
73226
73624
  printSummary(wctx, state);
73227
73625
  } else {
73228
73626
  stdout.write("Setup complete (force mode):\n");
73229
- stdout.write(` Statusline: user-level (~/.claude/settings.json)
73627
+ stdout.write(` Plugin: ${pluginResult.pluginAction} (${pluginResult.pluginScope})
73628
+ `);
73629
+ stdout.write(` Statusline: ${forceStatuslineScope} (${statuslineSettingsPath(forceStatuslineScope, homeDir, projectDir)})
73230
73630
  `);
73231
73631
  stdout.write(` Gitignore: ${gitignoreStatus === "installed" ? "configured" : "skipped"}
73232
73632
  `);
@@ -73238,15 +73638,32 @@ Examples:
73238
73638
  return { exitCode: 0 };
73239
73639
  }
73240
73640
  function hasScriptingFlags(options) {
73241
- 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;
73242
73642
  }
73243
73643
  async function runScripted(projectDir, logger, stdout, options) {
73244
73644
  const homeDir = options.homeDir ?? os.homedir();
73245
73645
  const setupService = new core_1.SetupStatusService(projectDir, { homeDir, logger });
73246
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
+ }
73247
73664
  if (options.statuslineScope) {
73248
- const statuslinePath = options.statuslineScope === "user" ? path.join(homeDir, ".claude", "settings.json") : path.join(projectDir, ".claude", "settings.local.json");
73249
- const wrote = await configureStatusline(statuslinePath, logger);
73665
+ const settingsPath = statuslineSettingsPath(options.statuslineScope, homeDir, projectDir);
73666
+ const wrote = await configureStatusline(settingsPath, logger);
73250
73667
  if (wrote) {
73251
73668
  stdout.write(`\u2713 Statusline configured (${options.statuslineScope}-level)
73252
73669
  `);
@@ -73549,6 +73966,10 @@ var require_uninstall = __commonJS({
73549
73966
  dryRun,
73550
73967
  removeHooks: true
73551
73968
  });
73969
+ await cleanSettingsFile(path.join(projectDir, ".claude", "settings.json"), "project", logger, actions, {
73970
+ dryRun,
73971
+ removeHooks: true
73972
+ });
73552
73973
  }
73553
73974
  if (userDetected) {
73554
73975
  await cleanSettingsFile(path.join(userHome, ".claude", "settings.json"), "user", logger, actions, {
@@ -73621,12 +74042,15 @@ var require_uninstall = __commonJS({
73621
74042
  await fs.access(path.join(projectDir, ".sidekick", "setup-status.json"));
73622
74043
  return true;
73623
74044
  } catch {
73624
- try {
73625
- const content = await fs.readFile(path.join(projectDir, ".claude", "settings.local.json"), "utf-8");
73626
- return content.includes("sidekick");
73627
- } catch {
73628
- return false;
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
+ }
73629
74052
  }
74053
+ return false;
73630
74054
  }
73631
74055
  }
73632
74056
  async function detectUserScope(userHome) {
@@ -73943,10 +74367,7 @@ var require_cli = __commonJS({
73943
74367
  var promises_12 = require("node:fs/promises");
73944
74368
  var node_stream_1 = require("node:stream");
73945
74369
  var yargs_parser_1 = __importDefault2(require_build());
73946
- var VERSION = true ? "0.0.8-alpha.7" : "dev";
73947
- function isInSandbox() {
73948
- return process.env.SANDBOX_RUNTIME === "1";
73949
- }
74370
+ var VERSION = true ? "0.0.8-alpha.8" : "dev";
73950
74371
  var SANDBOX_ERROR_MESSAGE = `Error: Daemon commands cannot run in sandbox mode.
73951
74372
 
73952
74373
  Claude Code's sandbox blocks Unix socket operations required for daemon IPC.
@@ -73955,6 +74376,7 @@ To run this command, use dangerouslyDisableSandbox: true in the Bash tool call.
73955
74376
  Example: { "command": "pnpm sidekick daemon status", "dangerouslyDisableSandbox": true }
73956
74377
  `;
73957
74378
  var types_1 = require_dist();
74379
+ var core_1 = require_dist4();
73958
74380
  var runtime_1 = require_runtime();
73959
74381
  var UnknownOptionError = class extends Error {
73960
74382
  constructor(unknownOptions) {
@@ -73990,7 +74412,9 @@ Example: { "command": "pnpm sidekick daemon status", "dangerouslyDisableSandbox"
73990
74412
  "statusline-scope",
73991
74413
  "api-key-scope",
73992
74414
  "auto-config",
73993
- "only"
74415
+ "only",
74416
+ "marketplace-scope",
74417
+ "plugin-scope"
73994
74418
  ],
73995
74419
  number: ["port", "width"],
73996
74420
  alias: { h: "help", v: "version" }
@@ -74045,7 +74469,9 @@ Example: { "command": "pnpm sidekick daemon status", "dangerouslyDisableSandbox"
74045
74469
  personas: hasPersonasFlag ? Boolean(parsed.personas) : void 0,
74046
74470
  apiKeyScope: parsed["api-key-scope"],
74047
74471
  autoConfig: parsed["auto-config"],
74048
- only: parsed.only
74472
+ only: parsed.only,
74473
+ marketplaceScope: parsed["marketplace-scope"],
74474
+ pluginScope: parsed["plugin-scope"]
74049
74475
  };
74050
74476
  }
74051
74477
  function parseHookInput(stdinData) {
@@ -74209,7 +74635,7 @@ Run 'sidekick hook --help' for available hooks.
74209
74635
  }
74210
74636
  if (parsed.command === "daemon") {
74211
74637
  const subcommand = parsed.help ? "--help" : parsed.kill ? "kill" : parsed._ && parsed._[1] || "status";
74212
- if (isInSandbox() && subcommand !== "--help") {
74638
+ if ((0, core_1.isInSandbox)() && subcommand !== "--help") {
74213
74639
  stdout.write(SANDBOX_ERROR_MESSAGE);
74214
74640
  return { exitCode: 1, stdout: SANDBOX_ERROR_MESSAGE, stderr: "" };
74215
74641
  }
@@ -74283,7 +74709,9 @@ Run 'sidekick hook --help' for available hooks.
74283
74709
  gitignore: parsed.gitignore,
74284
74710
  personas: parsed.personas,
74285
74711
  apiKeyScope: parsed.apiKeyScope,
74286
- autoConfig: parsed.autoConfig
74712
+ autoConfig: parsed.autoConfig,
74713
+ marketplaceScope: parsed.marketplaceScope,
74714
+ pluginScope: parsed.pluginScope
74287
74715
  });
74288
74716
  return { exitCode: result.exitCode, stdout: "", stderr: "" };
74289
74717
  }
package/dist/daemon.js CHANGED
@@ -16866,9 +16866,11 @@ var require_setup_status = __commonJS({
16866
16866
  "user",
16867
16867
  // Configured in ~/.claude/settings.json
16868
16868
  "project",
16869
- // Configured in .claude/settings.local.json
16869
+ // Configured in .claude/settings.json (shared via git)
16870
+ "local",
16871
+ // Configured in .claude/settings.local.json (not shared)
16870
16872
  "both",
16871
- // Configured in both (project overrides user)
16873
+ // Configured in multiple locations
16872
16874
  "none"
16873
16875
  // Not configured anywhere
16874
16876
  ]);
@@ -16879,7 +16881,7 @@ var require_setup_status = __commonJS({
16879
16881
  // ISO timestamp
16880
16882
  preferences: zod_1.z.object({
16881
16883
  autoConfigureProjects: zod_1.z.boolean(),
16882
- defaultStatuslineScope: zod_1.z.enum(["user", "project"]),
16884
+ defaultStatuslineScope: zod_1.z.enum(["user", "project", "local"]),
16883
16885
  defaultApiKeyScope: zod_1.z.enum(["user", "project", "skip"])
16884
16886
  }),
16885
16887
  statusline: exports2.StatuslineStatusSchema,
@@ -32974,6 +32976,18 @@ var require_structured_logging = __commonJS({
32974
32976
  }
32975
32977
  });
32976
32978
 
32979
+ // ../sidekick-core/dist/sandbox.js
32980
+ var require_sandbox = __commonJS({
32981
+ "../sidekick-core/dist/sandbox.js"(exports2) {
32982
+ "use strict";
32983
+ Object.defineProperty(exports2, "__esModule", { value: true });
32984
+ exports2.isInSandbox = isInSandbox;
32985
+ function isInSandbox() {
32986
+ return process.env.SANDBOX_RUNTIME === "1";
32987
+ }
32988
+ }
32989
+ });
32990
+
32977
32991
  // ../../package.json
32978
32992
  var require_package3 = __commonJS({
32979
32993
  "../../package.json"(exports2, module2) {
@@ -33033,6 +33047,7 @@ var require_daemon_client2 = __commonJS({
33033
33047
  var path_1 = __importDefault(require("path"));
33034
33048
  var client_js_1 = require_client();
33035
33049
  var transport_js_1 = require_transport();
33050
+ var sandbox_js_1 = require_sandbox();
33036
33051
  var LOCK_TIMEOUT_MS = 1e4;
33037
33052
  var LOCK_RETRY_INTERVAL_MS = 100;
33038
33053
  var LOCK_STALE_THRESHOLD_MS = 3e4;
@@ -33045,6 +33060,10 @@ var require_daemon_client2 = __commonJS({
33045
33060
  this.ipcClient = new client_js_1.IpcClient((0, transport_js_1.getSocketPath)(projectDir2), logger);
33046
33061
  }
33047
33062
  async start() {
33063
+ if ((0, sandbox_js_1.isInSandbox)()) {
33064
+ this.logger.debug("Skipping daemon start \u2014 sandbox mode detected");
33065
+ return;
33066
+ }
33048
33067
  await this.withStartupLock(async () => {
33049
33068
  await this.cleanupStaleFiles();
33050
33069
  if (await this.isRunning()) {
@@ -56548,7 +56567,7 @@ var require_dist4 = __commonJS({
56548
56567
  };
56549
56568
  Object.defineProperty(exports2, "__esModule", { value: true });
56550
56569
  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;
56551
- 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;
56570
+ 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;
56552
56571
  var types_1 = require_dist();
56553
56572
  Object.defineProperty(exports2, "TaskTypes", { enumerable: true, get: function() {
56554
56573
  return types_1.TaskTypes;
@@ -56845,6 +56864,10 @@ var require_dist4 = __commonJS({
56845
56864
  Object.defineProperty(exports2, "DaemonGlobalLogMetricsDescriptor", { enumerable: true, get: function() {
56846
56865
  return index_js_1.DaemonGlobalLogMetricsDescriptor;
56847
56866
  } });
56867
+ var sandbox_1 = require_sandbox();
56868
+ Object.defineProperty(exports2, "isInSandbox", { enumerable: true, get: function() {
56869
+ return sandbox_1.isInSandbox;
56870
+ } });
56848
56871
  }
56849
56872
  });
56850
56873
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scotthamilton77/sidekick",
3
- "version": "0.0.8-alpha.7",
3
+ "version": "0.0.8-alpha.8",
4
4
  "description": "AI pair programming assistant with personas, session tracking, and contextual nudges",
5
5
  "bin": {
6
6
  "sidekick": "dist/bin.js"