@scotthamilton77/sidekick 0.0.5-alpha → 0.0.6-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin.js CHANGED
@@ -33485,7 +33485,9 @@ var require_gitignore = __commonJS({
33485
33485
  ".sidekick/sessions/",
33486
33486
  ".sidekick/state/",
33487
33487
  ".sidekick/.env",
33488
- ".sidekick/.env.local"
33488
+ ".sidekick/.env.local",
33489
+ ".sidekick/sidekick*.pid",
33490
+ ".sidekick/sidekick*.token"
33489
33491
  ];
33490
33492
  async function installGitignoreSection(projectDir) {
33491
33493
  const gitignorePath = path.join(projectDir, ".gitignore");
@@ -53829,6 +53831,32 @@ var require_setup = __commonJS({
53829
53831
  var core_1 = require_dist3();
53830
53832
  var prompts_js_1 = require_prompts();
53831
53833
  var validate_api_key_js_1 = require_validate_api_key();
53834
+ var USAGE_TEXT = `Usage: sidekick setup [options]
53835
+
53836
+ Run the interactive setup wizard to configure sidekick for Claude Code.
53837
+ When scripting flags are provided, runs non-interactively for those settings only.
53838
+
53839
+ Options:
53840
+ --check Check configuration status (alias: sidekick doctor)
53841
+ --force Apply all defaults non-interactively
53842
+ --help Show this help message
53843
+
53844
+ Scripting Flags (for non-interactive/partial setup):
53845
+ --statusline-scope=<scope> Configure statusline: user | project
53846
+ --gitignore Update .gitignore to exclude sidekick files
53847
+ --no-gitignore Skip .gitignore configuration
53848
+ --personas Enable persona features
53849
+ --no-personas Disable persona features
53850
+ --api-key-scope=<scope> Save API key from OPENROUTER_API_KEY env: user | project
53851
+ --auto-config=<mode> Auto-configure preference: auto | ask | manual
53852
+
53853
+ Examples:
53854
+ sidekick setup Interactive wizard
53855
+ sidekick setup --check Check current status
53856
+ sidekick setup --statusline-scope=user Configure statusline only
53857
+ sidekick setup --gitignore --personas Configure gitignore and enable personas
53858
+ OPENROUTER_API_KEY=sk-xxx sidekick setup --personas --api-key-scope=user
53859
+ `;
53832
53860
  var STATUSLINE_COMMAND = "npx @scotthamilton77/sidekick statusline --project-dir=$CLAUDE_PROJECT_DIR";
53833
53861
  function getApiKeyStatusType(health) {
53834
53862
  switch (health) {
@@ -53902,17 +53930,16 @@ var require_setup = __commonJS({
53902
53930
  }
53903
53931
  async function writePersonaConfig(_projectDir, homeDir, enabled) {
53904
53932
  const configDir = path.join(homeDir, ".sidekick");
53905
- const configPath = path.join(configDir, "config.yaml");
53933
+ const featuresPath = path.join(configDir, "features.yaml");
53906
53934
  await fs.mkdir(configDir, { recursive: true });
53907
53935
  let content = "";
53908
53936
  try {
53909
- content = await fs.readFile(configPath, "utf-8");
53937
+ content = await fs.readFile(featuresPath, "utf-8");
53910
53938
  } catch {
53911
53939
  }
53912
- const personasRegex = /^features:\s*\n\s*personas:\s*\n\s*enabled:\s*(true|false)/m;
53913
- const newPersonasBlock = `features:
53914
- personas:
53915
- enabled: ${enabled}`;
53940
+ const personasRegex = /^personas:\s*\n\s*enabled:\s*(true|false)/m;
53941
+ const newPersonasBlock = `personas:
53942
+ enabled: ${enabled}`;
53916
53943
  if (personasRegex.test(content)) {
53917
53944
  content = content.replace(personasRegex, newPersonasBlock);
53918
53945
  } else {
@@ -53921,7 +53948,7 @@ var require_setup = __commonJS({
53921
53948
  }
53922
53949
  content += newPersonasBlock + "\n";
53923
53950
  }
53924
- await fs.writeFile(configPath, content);
53951
+ await fs.writeFile(featuresPath, content);
53925
53952
  }
53926
53953
  function printWizardHeader(stdout) {
53927
53954
  stdout.write("\n\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n");
@@ -54125,6 +54152,96 @@ var require_setup = __commonJS({
54125
54152
  stdout.write(` Personas: enabled (API key not configured)
54126
54153
  `);
54127
54154
  stdout.write(` Auto-configure: enabled
54155
+ `);
54156
+ }
54157
+ return { exitCode: 0 };
54158
+ }
54159
+ function hasScriptingFlags(options) {
54160
+ return options.statuslineScope !== void 0 || options.gitignore !== void 0 || options.personas !== void 0 || options.apiKeyScope !== void 0 || options.autoConfig !== void 0;
54161
+ }
54162
+ async function runScripted(projectDir, logger, stdout, options) {
54163
+ const homeDir = os.homedir();
54164
+ const setupService = new core_1.SetupStatusService(projectDir, { homeDir, logger });
54165
+ let configuredCount = 0;
54166
+ if (options.statuslineScope) {
54167
+ const statuslinePath = options.statuslineScope === "user" ? path.join(homeDir, ".claude", "settings.json") : path.join(projectDir, ".claude", "settings.local.json");
54168
+ await configureStatusline(statuslinePath, logger);
54169
+ stdout.write(`\u2713 Statusline configured (${options.statuslineScope}-level)
54170
+ `);
54171
+ configuredCount++;
54172
+ }
54173
+ if (options.gitignore === true) {
54174
+ const result = await (0, core_1.installGitignoreSection)(projectDir);
54175
+ if (result.status === "error") {
54176
+ stdout.write(`\u26A0 Failed to update .gitignore: ${result.error}
54177
+ `);
54178
+ } else if (result.status === "already-installed") {
54179
+ stdout.write("\u2713 Gitignore already configured\n");
54180
+ } else {
54181
+ stdout.write("\u2713 Gitignore configured\n");
54182
+ }
54183
+ configuredCount++;
54184
+ } else if (options.gitignore === false) {
54185
+ stdout.write("- Gitignore skipped\n");
54186
+ }
54187
+ if (options.personas !== void 0) {
54188
+ await writePersonaConfig(projectDir, homeDir, options.personas);
54189
+ stdout.write(`\u2713 Personas ${options.personas ? "enabled" : "disabled"}
54190
+ `);
54191
+ configuredCount++;
54192
+ }
54193
+ if (options.apiKeyScope) {
54194
+ const apiKey = process.env.OPENROUTER_API_KEY;
54195
+ if (apiKey) {
54196
+ const envPath = options.apiKeyScope === "user" ? path.join(homeDir, ".sidekick", ".env") : path.join(projectDir, ".sidekick", ".env");
54197
+ stdout.write("Validating API key... ");
54198
+ const result = await (0, validate_api_key_js_1.validateOpenRouterKey)(apiKey, logger);
54199
+ if (result.valid) {
54200
+ stdout.write("valid\n");
54201
+ await writeApiKeyToEnv(envPath, "OPENROUTER_API_KEY", apiKey);
54202
+ stdout.write(`\u2713 API key saved (${options.apiKeyScope}-level)
54203
+ `);
54204
+ } else {
54205
+ stdout.write(`invalid (${result.error})
54206
+ `);
54207
+ stdout.write(`\u26A0 API key saved anyway (${options.apiKeyScope}-level)
54208
+ `);
54209
+ await writeApiKeyToEnv(envPath, "OPENROUTER_API_KEY", apiKey);
54210
+ }
54211
+ configuredCount++;
54212
+ } else {
54213
+ stdout.write("\u26A0 --api-key-scope specified but OPENROUTER_API_KEY not set in environment\n");
54214
+ }
54215
+ }
54216
+ if (options.autoConfig) {
54217
+ const existingUserStatus = await setupService.getUserStatus();
54218
+ const userStatus = existingUserStatus ?? {
54219
+ version: 1,
54220
+ lastUpdatedAt: (/* @__PURE__ */ new Date()).toISOString(),
54221
+ preferences: {
54222
+ autoConfigureProjects: options.autoConfig === "auto",
54223
+ defaultStatuslineScope: "user",
54224
+ defaultApiKeyScope: "user"
54225
+ },
54226
+ statusline: "skipped",
54227
+ // Default to skipped if no prior setup
54228
+ apiKeys: {
54229
+ OPENROUTER_API_KEY: "not-required",
54230
+ OPENAI_API_KEY: "not-required"
54231
+ }
54232
+ };
54233
+ userStatus.preferences.autoConfigureProjects = options.autoConfig === "auto";
54234
+ userStatus.lastUpdatedAt = (/* @__PURE__ */ new Date()).toISOString();
54235
+ await setupService.writeUserStatus(userStatus);
54236
+ stdout.write(`\u2713 Auto-config set to '${options.autoConfig}'
54237
+ `);
54238
+ configuredCount++;
54239
+ }
54240
+ if (configuredCount === 0) {
54241
+ stdout.write("No configuration changes made. Use --help to see available options.\n");
54242
+ } else {
54243
+ stdout.write(`
54244
+ Configured ${configuredCount} setting${configuredCount === 1 ? "" : "s"}.
54128
54245
  `);
54129
54246
  }
54130
54247
  return { exitCode: 0 };
@@ -54156,9 +54273,16 @@ var require_setup = __commonJS({
54156
54273
  return { exitCode: isHealthy && gitignore === "installed" ? 0 : 1 };
54157
54274
  }
54158
54275
  async function handleSetupCommand(projectDir, logger, stdout, options = {}) {
54276
+ if (options.help) {
54277
+ stdout.write(USAGE_TEXT);
54278
+ return { exitCode: 0 };
54279
+ }
54159
54280
  if (options.checkOnly) {
54160
54281
  return runDoctor(projectDir, logger, stdout);
54161
54282
  }
54283
+ if (hasScriptingFlags(options)) {
54284
+ return runScripted(projectDir, logger, stdout, options);
54285
+ }
54162
54286
  return runWizard(projectDir, logger, stdout, options);
54163
54287
  }
54164
54288
  }
@@ -54231,7 +54355,7 @@ var require_cli = __commonJS({
54231
54355
  var promises_12 = require("node:fs/promises");
54232
54356
  var node_stream_1 = require("node:stream");
54233
54357
  var yargs_parser_1 = __importDefault2(require_build());
54234
- var VERSION = true ? "0.0.5-alpha" : "dev";
54358
+ var VERSION = true ? "0.0.6-alpha" : "dev";
54235
54359
  function isInSandbox() {
54236
54360
  return process.env.SANDBOX_RUNTIME === "1";
54237
54361
  }
@@ -54246,8 +54370,18 @@ Example: { "command": "pnpm sidekick daemon status", "dangerouslyDisableSandbox"
54246
54370
  var runtime_1 = require_runtime();
54247
54371
  function parseArgs(argv) {
54248
54372
  const parsed = (0, yargs_parser_1.default)(argv, {
54249
- boolean: ["wait", "open", "prefer-project", "help", "version", "kill", "force"],
54250
- string: ["project-dir", "log-level", "format", "host", "session-id", "type"],
54373
+ boolean: ["wait", "open", "prefer-project", "help", "version", "kill", "force", "gitignore", "personas"],
54374
+ string: [
54375
+ "project-dir",
54376
+ "log-level",
54377
+ "format",
54378
+ "host",
54379
+ "session-id",
54380
+ "type",
54381
+ "statusline-scope",
54382
+ "api-key-scope",
54383
+ "auto-config"
54384
+ ],
54251
54385
  number: ["port", "width"],
54252
54386
  alias: {
54253
54387
  h: "help",
@@ -54258,6 +54392,8 @@ Example: { "command": "pnpm sidekick daemon status", "dangerouslyDisableSandbox"
54258
54392
  }
54259
54393
  });
54260
54394
  const command = parsed._[0];
54395
+ const hasGitignoreFlag = argv.some((arg) => arg === "--gitignore" || arg === "--no-gitignore");
54396
+ const hasPersonasFlag = argv.some((arg) => arg === "--personas" || arg === "--no-personas");
54261
54397
  return {
54262
54398
  command,
54263
54399
  projectDir: parsed["project-dir"],
@@ -54275,7 +54411,13 @@ Example: { "command": "pnpm sidekick daemon status", "dangerouslyDisableSandbox"
54275
54411
  version: Boolean(parsed.version),
54276
54412
  kill: Boolean(parsed.kill),
54277
54413
  force: Boolean(parsed.force),
54278
- _: parsed._
54414
+ _: parsed._,
54415
+ // Setup command scripting flags - only set if explicitly provided
54416
+ statuslineScope: parsed["statusline-scope"],
54417
+ gitignore: hasGitignoreFlag ? Boolean(parsed.gitignore) : void 0,
54418
+ personas: hasPersonasFlag ? Boolean(parsed.personas) : void 0,
54419
+ apiKeyScope: parsed["api-key-scope"],
54420
+ autoConfig: parsed["auto-config"]
54279
54421
  };
54280
54422
  }
54281
54423
  function parseHookInput(stdinData) {
@@ -54535,8 +54677,15 @@ Run 'sidekick hook --help' for available hooks.
54535
54677
  if (parsed.command === "setup") {
54536
54678
  const { handleSetupCommand } = await Promise.resolve().then(() => __importStar(require_setup2()));
54537
54679
  const result = await handleSetupCommand(runtime.projectRoot || process.cwd(), runtime.logger, stdout, {
54538
- checkOnly: parsed.help ? false : parsed._?.[1] === "--check",
54539
- stdin: process.stdin
54680
+ help: parsed.help,
54681
+ checkOnly: parsed._?.[1] === "--check",
54682
+ stdin: process.stdin,
54683
+ // Scripting flags for non-interactive setup
54684
+ statuslineScope: parsed.statuslineScope,
54685
+ gitignore: parsed.gitignore,
54686
+ personas: parsed.personas,
54687
+ apiKeyScope: parsed.apiKeyScope,
54688
+ autoConfig: parsed.autoConfig
54540
54689
  });
54541
54690
  return { exitCode: result.exitCode, stdout: "", stderr: "" };
54542
54691
  }
package/dist/daemon.js CHANGED
@@ -32509,7 +32509,9 @@ var require_gitignore = __commonJS({
32509
32509
  ".sidekick/sessions/",
32510
32510
  ".sidekick/state/",
32511
32511
  ".sidekick/.env",
32512
- ".sidekick/.env.local"
32512
+ ".sidekick/.env.local",
32513
+ ".sidekick/sidekick*.pid",
32514
+ ".sidekick/sidekick*.token"
32513
32515
  ];
32514
32516
  async function installGitignoreSection(projectDir2) {
32515
32517
  const gitignorePath = path.join(projectDir2, ".gitignore");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scotthamilton77/sidekick",
3
- "version": "0.0.5-alpha",
3
+ "version": "0.0.6-alpha",
4
4
  "description": "AI pair programming assistant with personas, session tracking, and contextual nudges",
5
5
  "bin": {
6
6
  "sidekick": "dist/bin.js"