@m14i/sith 1.14.1 → 1.16.0

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/index.js CHANGED
@@ -42972,7 +42972,7 @@ __nccwpck_require__.a(module, async (__webpack_handle_async_dependencies__, __we
42972
42972
  /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __nccwpck_require__(2864);
42973
42973
  /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__nccwpck_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
42974
42974
  /* harmony import */ var ink__WEBPACK_IMPORTED_MODULE_1__ = __nccwpck_require__(3816);
42975
- /* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_6__ = __nccwpck_require__(6181);
42975
+ /* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_9__ = __nccwpck_require__(6181);
42976
42976
  /* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_2__ = __nccwpck_require__(9896);
42977
42977
  /* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__nccwpck_require__.n(fs__WEBPACK_IMPORTED_MODULE_2__);
42978
42978
  /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3__ = __nccwpck_require__(6928);
@@ -42980,8 +42980,14 @@ __nccwpck_require__.a(module, async (__webpack_handle_async_dependencies__, __we
42980
42980
  /* harmony import */ var url__WEBPACK_IMPORTED_MODULE_4__ = __nccwpck_require__(7016);
42981
42981
  /* harmony import */ var url__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__nccwpck_require__.n(url__WEBPACK_IMPORTED_MODULE_4__);
42982
42982
  /* harmony import */ var _config_js__WEBPACK_IMPORTED_MODULE_5__ = __nccwpck_require__(6878);
42983
- var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([ink__WEBPACK_IMPORTED_MODULE_1__]);
42984
- ink__WEBPACK_IMPORTED_MODULE_1__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
42983
+ /* harmony import */ var _nix_js__WEBPACK_IMPORTED_MODULE_6__ = __nccwpck_require__(9922);
42984
+ /* harmony import */ var _utils_skills_js__WEBPACK_IMPORTED_MODULE_7__ = __nccwpck_require__(6400);
42985
+ /* harmony import */ var _skills_js__WEBPACK_IMPORTED_MODULE_8__ = __nccwpck_require__(9805);
42986
+ var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([ink__WEBPACK_IMPORTED_MODULE_1__, _skills_js__WEBPACK_IMPORTED_MODULE_8__]);
42987
+ ([ink__WEBPACK_IMPORTED_MODULE_1__, _skills_js__WEBPACK_IMPORTED_MODULE_8__] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__);
42988
+
42989
+
42990
+
42985
42991
 
42986
42992
 
42987
42993
 
@@ -43006,11 +43012,13 @@ function findProjectRoot(startDir) {
43006
43012
  const rootDir = findProjectRoot(__dirname);
43007
43013
  const menuItems = [
43008
43014
  { label: "Enter Shell", value: "shell", icon: "🚀" },
43015
+ { label: "Manage Skills", value: "skills", icon: "🧠" },
43009
43016
  { label: "Configuration", value: "config", icon: "⚙️" },
43010
43017
  ];
43011
43018
  const configMenuItems = [
43012
43019
  { label: "Pull prebuilt image (recommended)", value: "pull", icon: "📦" },
43013
43020
  { label: "Build Docker image from scratch", value: "build", icon: "🔨" },
43021
+ { label: "Install Nix locally (no Docker)", value: "nix", icon: "❄️" },
43014
43022
  { label: "Back", value: "back", icon: "◀️" },
43015
43023
  ];
43016
43024
  function Logo() {
@@ -43067,6 +43075,10 @@ function Menu() {
43067
43075
  exit();
43068
43076
  await runShell();
43069
43077
  return;
43078
+ case "skills":
43079
+ exit();
43080
+ (0,_skills_js__WEBPACK_IMPORTED_MODULE_8__/* .skillsCommand */ .a)();
43081
+ return;
43070
43082
  case "config":
43071
43083
  setCurrentMenu("config");
43072
43084
  setSelectedIndex(0);
@@ -43081,6 +43093,9 @@ function Menu() {
43081
43093
  case "build":
43082
43094
  await handleBuildCommand();
43083
43095
  break;
43096
+ case "nix":
43097
+ await handleNixCommand();
43098
+ break;
43084
43099
  default:
43085
43100
  break;
43086
43101
  }
@@ -43089,11 +43104,11 @@ function Menu() {
43089
43104
  setIsProcessing(true);
43090
43105
  setProcessStep("Pulling prebuilt Docker image...");
43091
43106
  try {
43092
- await (0,execa__WEBPACK_IMPORTED_MODULE_6__/* .execa */ .Ho)("docker", ["pull", _config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.prebuiltImage], {
43107
+ await (0,execa__WEBPACK_IMPORTED_MODULE_9__/* .execa */ .Ho)("docker", ["pull", _config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.prebuiltImage], {
43093
43108
  stdio: "inherit",
43094
43109
  });
43095
43110
  // Tag the pulled image with local name for compatibility
43096
- await (0,execa__WEBPACK_IMPORTED_MODULE_6__/* .execa */ .Ho)("docker", ["tag", _config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.prebuiltImage, _config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.imageName], {
43111
+ await (0,execa__WEBPACK_IMPORTED_MODULE_9__/* .execa */ .Ho)("docker", ["tag", _config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.prebuiltImage, _config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.imageName], {
43097
43112
  stdio: "inherit",
43098
43113
  });
43099
43114
  setIsProcessing(false);
@@ -43105,6 +43120,21 @@ function Menu() {
43105
43120
  setProcessError(error instanceof Error ? error.message : "Pull failed");
43106
43121
  }
43107
43122
  }
43123
+ async function handleNixCommand() {
43124
+ setIsProcessing(true);
43125
+ setProcessStep("Installing Nix locally...");
43126
+ try {
43127
+ await (0,_nix_js__WEBPACK_IMPORTED_MODULE_6__/* .installNix */ .Fh)();
43128
+ await (0,_nix_js__WEBPACK_IMPORTED_MODULE_6__/* .copyNixFiles */ .Qi)();
43129
+ setIsProcessing(false);
43130
+ setProcessComplete(true);
43131
+ setProcessStep("");
43132
+ }
43133
+ catch (error) {
43134
+ setIsProcessing(false);
43135
+ setProcessError(error instanceof Error ? error.message : "Nix installation failed");
43136
+ }
43137
+ }
43108
43138
  async function handleBuildCommand() {
43109
43139
  setIsProcessing(true);
43110
43140
  setProcessStep("Building Docker image from scratch...");
@@ -43113,7 +43143,7 @@ function Menu() {
43113
43143
  if (!fs__WEBPACK_IMPORTED_MODULE_2___default().existsSync(dockerfilePath)) {
43114
43144
  throw new Error(`Dockerfile not found at: ${dockerfilePath}`);
43115
43145
  }
43116
- await (0,execa__WEBPACK_IMPORTED_MODULE_6__/* .execa */ .Ho)("docker", ["build", "-f", dockerfilePath, "-t", _config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.imageName, rootDir], {
43146
+ await (0,execa__WEBPACK_IMPORTED_MODULE_9__/* .execa */ .Ho)("docker", ["build", "-f", dockerfilePath, "-t", _config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.imageName, rootDir], {
43117
43147
  stdio: "inherit",
43118
43148
  });
43119
43149
  setIsProcessing(false);
@@ -43208,12 +43238,12 @@ async function pullDocker() {
43208
43238
  console.log(`Source: ${_config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.prebuiltImage}`);
43209
43239
  console.log(`Target: ${_config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.imageName}`);
43210
43240
  console.log();
43211
- await (0,execa__WEBPACK_IMPORTED_MODULE_6__/* .execa */ .Ho)("docker", ["pull", _config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.prebuiltImage], {
43241
+ await (0,execa__WEBPACK_IMPORTED_MODULE_9__/* .execa */ .Ho)("docker", ["pull", _config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.prebuiltImage], {
43212
43242
  stdio: "inherit",
43213
43243
  });
43214
43244
  console.log();
43215
43245
  console.log("🏷️ Tagging image for local use...");
43216
- await (0,execa__WEBPACK_IMPORTED_MODULE_6__/* .execa */ .Ho)("docker", ["tag", _config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.prebuiltImage, _config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.imageName], {
43246
+ await (0,execa__WEBPACK_IMPORTED_MODULE_9__/* .execa */ .Ho)("docker", ["tag", _config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.prebuiltImage, _config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.imageName], {
43217
43247
  stdio: "inherit",
43218
43248
  });
43219
43249
  console.log();
@@ -43241,7 +43271,7 @@ async function buildDocker() {
43241
43271
  console.log(`Root: ${rootDir}`);
43242
43272
  console.log(`Dockerfile: ${dockerfilePath}`);
43243
43273
  console.log();
43244
- await (0,execa__WEBPACK_IMPORTED_MODULE_6__/* .execa */ .Ho)("docker", ["build", "-f", dockerfilePath, "-t", _config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.imageName, rootDir], {
43274
+ await (0,execa__WEBPACK_IMPORTED_MODULE_9__/* .execa */ .Ho)("docker", ["build", "-f", dockerfilePath, "-t", _config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.imageName, rootDir], {
43245
43275
  stdio: "inherit",
43246
43276
  });
43247
43277
  console.log();
@@ -43259,15 +43289,18 @@ async function buildDocker() {
43259
43289
  }
43260
43290
  }
43261
43291
  async function runShell() {
43292
+ const skillsDir = (0,_utils_skills_js__WEBPACK_IMPORTED_MODULE_7__/* .getSkillsDir */ .YJ)();
43293
+ const opencodeConfigPath = (0,_utils_skills_js__WEBPACK_IMPORTED_MODULE_7__/* .getOpenCodeConfigPath */ .Jn)();
43262
43294
  console.log("🚀 Starting interactive shell...");
43263
- console.log(`Mounting current directory to ${_config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.workspaceMount}`);
43295
+ console.log(`Mounting workspace to ${_config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.workspaceMount}`);
43296
+ console.log(`Mounting skills from ${skillsDir} to ${_config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.skillsMount}`);
43264
43297
  console.log('Press Ctrl+D or type "exit" to leave');
43265
43298
  console.log();
43266
43299
  // Try to get GitHub token from gh CLI if not in env
43267
43300
  let githubToken = process.env.GITHUB_TOKEN || "";
43268
43301
  if (!githubToken) {
43269
43302
  try {
43270
- const { stdout } = await (0,execa__WEBPACK_IMPORTED_MODULE_6__/* .execa */ .Ho)("gh", ["auth", "token"]);
43303
+ const { stdout } = await (0,execa__WEBPACK_IMPORTED_MODULE_9__/* .execa */ .Ho)("gh", ["auth", "token"]);
43271
43304
  githubToken = stdout.trim();
43272
43305
  }
43273
43306
  catch {
@@ -43280,6 +43313,10 @@ async function runShell() {
43280
43313
  "-it",
43281
43314
  "-v",
43282
43315
  `${process.cwd()}:${_config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.workspaceMount}`,
43316
+ "-v",
43317
+ `${skillsDir}:${_config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.skillsMount}`,
43318
+ "-v",
43319
+ `${opencodeConfigPath}:${_config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.opencodeConfigMount}`,
43283
43320
  "-e",
43284
43321
  `GITHUB_TOKEN=${githubToken}`,
43285
43322
  "--entrypoint",
@@ -43288,7 +43325,7 @@ async function runShell() {
43288
43325
  _config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.shellEntrypoint,
43289
43326
  ];
43290
43327
  try {
43291
- await (0,execa__WEBPACK_IMPORTED_MODULE_6__/* .execa */ .Ho)("docker", dockerArgs, {
43328
+ await (0,execa__WEBPACK_IMPORTED_MODULE_9__/* .execa */ .Ho)("docker", dockerArgs, {
43292
43329
  stdio: "inherit",
43293
43330
  });
43294
43331
  }
@@ -43306,6 +43343,294 @@ __webpack_async_result__();
43306
43343
 
43307
43344
  /***/ }),
43308
43345
 
43346
+ /***/ 9922:
43347
+ /***/ ((__unused_webpack_module, __webpack_exports__, __nccwpck_require__) => {
43348
+
43349
+ /* harmony export */ __nccwpck_require__.d(__webpack_exports__, {
43350
+ /* harmony export */ Dv: () => (/* binding */ nixCommand),
43351
+ /* harmony export */ Fh: () => (/* binding */ installNix),
43352
+ /* harmony export */ Qi: () => (/* binding */ copyNixFiles),
43353
+ /* harmony export */ nb: () => (/* binding */ runNixShell)
43354
+ /* harmony export */ });
43355
+ /* unused harmony export checkNixInstalled */
43356
+ /* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_5__ = __nccwpck_require__(6181);
43357
+ /* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __nccwpck_require__(9896);
43358
+ /* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__nccwpck_require__.n(fs__WEBPACK_IMPORTED_MODULE_0__);
43359
+ /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __nccwpck_require__(6928);
43360
+ /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__nccwpck_require__.n(path__WEBPACK_IMPORTED_MODULE_1__);
43361
+ /* harmony import */ var os__WEBPACK_IMPORTED_MODULE_2__ = __nccwpck_require__(857);
43362
+ /* harmony import */ var os__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__nccwpck_require__.n(os__WEBPACK_IMPORTED_MODULE_2__);
43363
+ /* harmony import */ var url__WEBPACK_IMPORTED_MODULE_3__ = __nccwpck_require__(7016);
43364
+ /* harmony import */ var url__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__nccwpck_require__.n(url__WEBPACK_IMPORTED_MODULE_3__);
43365
+ /* harmony import */ var _config_js__WEBPACK_IMPORTED_MODULE_4__ = __nccwpck_require__(6878);
43366
+
43367
+
43368
+
43369
+
43370
+
43371
+
43372
+ const __dirname = path__WEBPACK_IMPORTED_MODULE_1___default().dirname((0,url__WEBPACK_IMPORTED_MODULE_3__.fileURLToPath)(import.meta.url));
43373
+ // Find project root by looking for docker/ folder
43374
+ function findProjectRoot(startDir) {
43375
+ let currentDir = startDir;
43376
+ const rootPath = path__WEBPACK_IMPORTED_MODULE_1___default().parse(currentDir).root;
43377
+ while (currentDir !== rootPath) {
43378
+ const dockerPath = path__WEBPACK_IMPORTED_MODULE_1___default().join(currentDir, "docker");
43379
+ if (fs__WEBPACK_IMPORTED_MODULE_0___default().existsSync(dockerPath) && fs__WEBPACK_IMPORTED_MODULE_0___default().statSync(dockerPath).isDirectory()) {
43380
+ return currentDir;
43381
+ }
43382
+ currentDir = path__WEBPACK_IMPORTED_MODULE_1___default().dirname(currentDir);
43383
+ }
43384
+ throw new Error("Could not find project root (docker/ folder not found)");
43385
+ }
43386
+ const rootDir = findProjectRoot(__dirname);
43387
+ async function checkNixInstalled() {
43388
+ try {
43389
+ const { stdout } = await (0,execa__WEBPACK_IMPORTED_MODULE_5__/* .execa */ .Ho)("nix", ["--version"]);
43390
+ const versionMatch = stdout.match(/nix \(Nix\) (\d+\.\d+)/);
43391
+ if (versionMatch) {
43392
+ const version = versionMatch[1];
43393
+ const [major, minor] = version.split(".").map(Number);
43394
+ const [reqMajor, reqMinor] = _config_js__WEBPACK_IMPORTED_MODULE_4__/* .NIX_CONFIG */ .Z3.requiredVersion.split(".").map(Number);
43395
+ return major > reqMajor || (major === reqMajor && minor >= reqMinor);
43396
+ }
43397
+ return false;
43398
+ }
43399
+ catch {
43400
+ return false;
43401
+ }
43402
+ }
43403
+ async function installNix() {
43404
+ console.log("🔧 Installing Nix package manager...");
43405
+ console.log();
43406
+ // Check if already installed
43407
+ if (await checkNixInstalled()) {
43408
+ console.log("✅ Nix is already installed and meets version requirements");
43409
+ return;
43410
+ }
43411
+ // Detect OS
43412
+ const platform = os__WEBPACK_IMPORTED_MODULE_2___default().platform();
43413
+ if (platform !== "darwin" && platform !== "linux") {
43414
+ throw new Error(`Unsupported platform: ${platform}. Nix only supports macOS and Linux.`);
43415
+ }
43416
+ console.log(`Platform: ${platform}`);
43417
+ console.log(`Installer: ${_config_js__WEBPACK_IMPORTED_MODULE_4__/* .NIX_CONFIG */ .Z3.installerUrl}`);
43418
+ console.log();
43419
+ // Download and run installer
43420
+ console.log("📥 Downloading Nix installer...");
43421
+ try {
43422
+ await (0,execa__WEBPACK_IMPORTED_MODULE_5__/* .execa */ .Ho)("sh", ["-c", `curl -L ${_config_js__WEBPACK_IMPORTED_MODULE_4__/* .NIX_CONFIG */ .Z3.installerUrl} | sh -s -- --daemon`], {
43423
+ stdio: "inherit",
43424
+ });
43425
+ }
43426
+ catch (error) {
43427
+ console.error("❌ Failed to install Nix");
43428
+ throw error;
43429
+ }
43430
+ console.log();
43431
+ console.log("✅ Nix installed successfully!");
43432
+ console.log("⚠️ Please restart your shell or run: source ~/.nix-profile/etc/profile.d/nix.sh");
43433
+ }
43434
+ async function copyNixFiles() {
43435
+ const homeDir = os__WEBPACK_IMPORTED_MODULE_2___default().homedir();
43436
+ const localConfigDir = path__WEBPACK_IMPORTED_MODULE_1___default().join(homeDir, _config_js__WEBPACK_IMPORTED_MODULE_4__/* .NIX_CONFIG */ .Z3.localConfigDir);
43437
+ console.log(`📁 Copying Nix configuration to ${localConfigDir}...`);
43438
+ // Create directory if it doesn't exist
43439
+ if (!fs__WEBPACK_IMPORTED_MODULE_0___default().existsSync(localConfigDir)) {
43440
+ fs__WEBPACK_IMPORTED_MODULE_0___default().mkdirSync(localConfigDir, { recursive: true });
43441
+ }
43442
+ // Copy shell.nix and flake files
43443
+ const sourcePath = path__WEBPACK_IMPORTED_MODULE_1___default().join(rootDir, "docker", "nix");
43444
+ const filesToCopy = ["shell.nix", "flake.nix", "flake.lock"];
43445
+ for (const file of filesToCopy) {
43446
+ const src = path__WEBPACK_IMPORTED_MODULE_1___default().join(sourcePath, file);
43447
+ const dest = path__WEBPACK_IMPORTED_MODULE_1___default().join(localConfigDir, file);
43448
+ if (fs__WEBPACK_IMPORTED_MODULE_0___default().existsSync(src)) {
43449
+ fs__WEBPACK_IMPORTED_MODULE_0___default().copyFileSync(src, dest);
43450
+ console.log(` ✓ Copied ${file}`);
43451
+ }
43452
+ }
43453
+ // Copy nix-config directory
43454
+ const configSrc = path__WEBPACK_IMPORTED_MODULE_1___default().join(sourcePath, "nix-config");
43455
+ const configDest = path__WEBPACK_IMPORTED_MODULE_1___default().join(localConfigDir, "nix-config");
43456
+ if (!fs__WEBPACK_IMPORTED_MODULE_0___default().existsSync(configDest)) {
43457
+ fs__WEBPACK_IMPORTED_MODULE_0___default().mkdirSync(configDest, { recursive: true });
43458
+ }
43459
+ const configFiles = fs__WEBPACK_IMPORTED_MODULE_0___default().readdirSync(configSrc);
43460
+ for (const file of configFiles) {
43461
+ fs__WEBPACK_IMPORTED_MODULE_0___default().copyFileSync(path__WEBPACK_IMPORTED_MODULE_1___default().join(configSrc, file), path__WEBPACK_IMPORTED_MODULE_1___default().join(configDest, file));
43462
+ console.log(` ✓ Copied nix-config/${file}`);
43463
+ }
43464
+ console.log();
43465
+ console.log("✅ Nix files copied successfully!");
43466
+ }
43467
+ async function runNixShell() {
43468
+ // Check if Nix is installed
43469
+ if (!(await checkNixInstalled())) {
43470
+ console.error("❌ Nix is not installed");
43471
+ console.error("Run: sith --nix-install");
43472
+ process.exit(1);
43473
+ }
43474
+ // Copy files if not already present
43475
+ const homeDir = os__WEBPACK_IMPORTED_MODULE_2___default().homedir();
43476
+ const localConfigDir = path__WEBPACK_IMPORTED_MODULE_1___default().join(homeDir, _config_js__WEBPACK_IMPORTED_MODULE_4__/* .NIX_CONFIG */ .Z3.localConfigDir);
43477
+ const shellNixPath = path__WEBPACK_IMPORTED_MODULE_1___default().join(localConfigDir, "shell.nix");
43478
+ if (!fs__WEBPACK_IMPORTED_MODULE_0___default().existsSync(shellNixPath)) {
43479
+ await copyNixFiles();
43480
+ }
43481
+ console.log("🚀 Starting Nix shell...");
43482
+ console.log(`Configuration: ${shellNixPath}`);
43483
+ console.log('Press Ctrl+D or type "exit" to leave');
43484
+ console.log();
43485
+ // Set environment variables
43486
+ const env = {
43487
+ ...process.env,
43488
+ OPENCODE_MODEL: "claude-sonnet-4-5-20241022",
43489
+ };
43490
+ // Try to get GitHub token from gh CLI if not in env
43491
+ if (!env.GITHUB_TOKEN) {
43492
+ try {
43493
+ const { stdout } = await (0,execa__WEBPACK_IMPORTED_MODULE_5__/* .execa */ .Ho)("gh", ["auth", "token"]);
43494
+ env.GITHUB_TOKEN = stdout.trim();
43495
+ }
43496
+ catch {
43497
+ // Ignore if gh CLI not available or not authenticated
43498
+ }
43499
+ }
43500
+ // Run nix-shell
43501
+ try {
43502
+ await (0,execa__WEBPACK_IMPORTED_MODULE_5__/* .execa */ .Ho)("nix-shell", [shellNixPath], {
43503
+ stdio: "inherit",
43504
+ env,
43505
+ cwd: process.cwd(),
43506
+ });
43507
+ }
43508
+ catch (error) {
43509
+ console.error("❌ Failed to start Nix shell");
43510
+ if (error instanceof Error) {
43511
+ console.error(error.message);
43512
+ }
43513
+ process.exit(1);
43514
+ }
43515
+ }
43516
+ async function nixCommand(options) {
43517
+ if (options.install) {
43518
+ await installNix();
43519
+ await copyNixFiles();
43520
+ return;
43521
+ }
43522
+ if (options.shell) {
43523
+ await runNixShell();
43524
+ return;
43525
+ }
43526
+ // Default: run shell
43527
+ await runNixShell();
43528
+ }
43529
+
43530
+
43531
+ /***/ }),
43532
+
43533
+ /***/ 9805:
43534
+ /***/ ((module, __webpack_exports__, __nccwpck_require__) => {
43535
+
43536
+ __nccwpck_require__.a(module, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
43537
+ /* harmony export */ __nccwpck_require__.d(__webpack_exports__, {
43538
+ /* harmony export */ a: () => (/* binding */ skillsCommand)
43539
+ /* harmony export */ });
43540
+ /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __nccwpck_require__(2864);
43541
+ /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__nccwpck_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
43542
+ /* harmony import */ var ink__WEBPACK_IMPORTED_MODULE_1__ = __nccwpck_require__(3816);
43543
+ /* harmony import */ var _config_js__WEBPACK_IMPORTED_MODULE_2__ = __nccwpck_require__(6878);
43544
+ /* harmony import */ var _utils_skills_js__WEBPACK_IMPORTED_MODULE_3__ = __nccwpck_require__(6400);
43545
+ var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([ink__WEBPACK_IMPORTED_MODULE_1__]);
43546
+ ink__WEBPACK_IMPORTED_MODULE_1__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
43547
+
43548
+
43549
+
43550
+
43551
+ function statusIcon(row) {
43552
+ switch (row.status) {
43553
+ case "working":
43554
+ return "⏳";
43555
+ case "error":
43556
+ return "❌";
43557
+ default:
43558
+ return row.installed ? "✅" : "☐";
43559
+ }
43560
+ }
43561
+ function SkillsMenu() {
43562
+ const { exit } = (0,ink__WEBPACK_IMPORTED_MODULE_1__/* .useApp */ .nm)();
43563
+ const [selectedIndex, setSelectedIndex] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(0);
43564
+ const [rows, setRows] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(_config_js__WEBPACK_IMPORTED_MODULE_2__/* .SKILLS_CATALOG */ .XI.map((s) => ({ installed: (0,_utils_skills_js__WEBPACK_IMPORTED_MODULE_3__/* .isInstalled */ .j$)(s.name), status: "idle", message: "" })));
43565
+ function setRow(index, patch) {
43566
+ setRows((prev) => prev.map((r, i) => (i === index ? { ...r, ...patch } : r)));
43567
+ }
43568
+ async function toggleSkill(index, skill, installed) {
43569
+ setRow(index, { status: "working", message: installed ? "Uninstalling..." : "Downloading..." });
43570
+ try {
43571
+ if (installed) {
43572
+ (0,_utils_skills_js__WEBPACK_IMPORTED_MODULE_3__/* .uninstallSkill */ .wW)(skill.name);
43573
+ setRow(index, { installed: false, status: "done", message: "Uninstalled" });
43574
+ }
43575
+ else {
43576
+ await (0,_utils_skills_js__WEBPACK_IMPORTED_MODULE_3__/* .installSkill */ .rP)(skill);
43577
+ setRow(index, { installed: true, status: "done", message: "Installed" });
43578
+ }
43579
+ }
43580
+ catch (e) {
43581
+ setRow(index, { status: "error", message: e instanceof Error ? e.message : "Failed" });
43582
+ }
43583
+ }
43584
+ (0,ink__WEBPACK_IMPORTED_MODULE_1__/* .useInput */ .Ge)((input, key) => {
43585
+ if (key.upArrow) {
43586
+ setSelectedIndex((p) => (p > 0 ? p - 1 : _config_js__WEBPACK_IMPORTED_MODULE_2__/* .SKILLS_CATALOG */ .XI.length - 1));
43587
+ return;
43588
+ }
43589
+ if (key.downArrow) {
43590
+ setSelectedIndex((p) => (p < _config_js__WEBPACK_IMPORTED_MODULE_2__/* .SKILLS_CATALOG */ .XI.length - 1 ? p + 1 : 0));
43591
+ return;
43592
+ }
43593
+ if (key.return) {
43594
+ const row = rows[selectedIndex];
43595
+ if (row.status !== "working") {
43596
+ void toggleSkill(selectedIndex, _config_js__WEBPACK_IMPORTED_MODULE_2__/* .SKILLS_CATALOG */ .XI[selectedIndex], row.installed);
43597
+ }
43598
+ return;
43599
+ }
43600
+ if (input === "q" || key.escape) {
43601
+ exit();
43602
+ }
43603
+ });
43604
+ return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(ink__WEBPACK_IMPORTED_MODULE_1__/* .Box */ .az, { flexDirection: "column", paddingX: 1 },
43605
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(ink__WEBPACK_IMPORTED_MODULE_1__/* .Box */ .az, { marginBottom: 1 },
43606
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(ink__WEBPACK_IMPORTED_MODULE_1__/* .Text */ .EY, { bold: true, color: "red" }, "Skills Manager"),
43607
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(ink__WEBPACK_IMPORTED_MODULE_1__/* .Text */ .EY, { dimColor: true }, " (~/.sith/skills/)")),
43608
+ _config_js__WEBPACK_IMPORTED_MODULE_2__/* .SKILLS_CATALOG */ .XI.map((skill, i) => {
43609
+ const row = rows[i];
43610
+ const isSelected = i === selectedIndex;
43611
+ return (react__WEBPACK_IMPORTED_MODULE_0___default().createElement(ink__WEBPACK_IMPORTED_MODULE_1__/* .Box */ .az, { key: skill.name, marginY: 0 },
43612
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(ink__WEBPACK_IMPORTED_MODULE_1__/* .Text */ .EY, { color: isSelected ? "cyan" : undefined },
43613
+ isSelected ? "❯ " : " ",
43614
+ statusIcon(row),
43615
+ " ",
43616
+ skill.name.padEnd(12)),
43617
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(ink__WEBPACK_IMPORTED_MODULE_1__/* .Text */ .EY, { dimColor: !isSelected }, skill.description),
43618
+ row.message ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement(ink__WEBPACK_IMPORTED_MODULE_1__/* .Text */ .EY, { color: row.status === "error" ? "red" : "green" },
43619
+ " ",
43620
+ row.message) : null));
43621
+ }),
43622
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(ink__WEBPACK_IMPORTED_MODULE_1__/* .Box */ .az, { marginTop: 1 },
43623
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(ink__WEBPACK_IMPORTED_MODULE_1__/* .Text */ .EY, { dimColor: true }, "\u2191\u2193 navigate Enter install/uninstall q quit"))));
43624
+ }
43625
+ function skillsCommand() {
43626
+ (0,ink__WEBPACK_IMPORTED_MODULE_1__/* .render */ .XX)(react__WEBPACK_IMPORTED_MODULE_0___default().createElement(SkillsMenu, null));
43627
+ }
43628
+
43629
+ __webpack_async_result__();
43630
+ } catch(e) { __webpack_async_result__(e); } });
43631
+
43632
+ /***/ }),
43633
+
43309
43634
  /***/ 3636:
43310
43635
  /***/ ((module, __webpack_exports__, __nccwpck_require__) => {
43311
43636
 
@@ -43461,12 +43786,16 @@ __nccwpck_require__.a(module, async (__webpack_handle_async_dependencies__, __we
43461
43786
  /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__nccwpck_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
43462
43787
  /* harmony import */ var ink__WEBPACK_IMPORTED_MODULE_1__ = __nccwpck_require__(3816);
43463
43788
  /* harmony import */ var ink_text_input__WEBPACK_IMPORTED_MODULE_2__ = __nccwpck_require__(9046);
43464
- /* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_5__ = __nccwpck_require__(6181);
43789
+ /* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_7__ = __nccwpck_require__(6181);
43465
43790
  /* harmony import */ var _ConfigModal_js__WEBPACK_IMPORTED_MODULE_3__ = __nccwpck_require__(3636);
43466
- /* harmony import */ var _utils_slashCommands_js__WEBPACK_IMPORTED_MODULE_6__ = __nccwpck_require__(9987);
43791
+ /* harmony import */ var _utils_slashCommands_js__WEBPACK_IMPORTED_MODULE_8__ = __nccwpck_require__(9987);
43467
43792
  /* harmony import */ var _config_js__WEBPACK_IMPORTED_MODULE_4__ = __nccwpck_require__(6878);
43468
- var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([ink__WEBPACK_IMPORTED_MODULE_1__, ink_text_input__WEBPACK_IMPORTED_MODULE_2__, _ConfigModal_js__WEBPACK_IMPORTED_MODULE_3__]);
43469
- ([ink__WEBPACK_IMPORTED_MODULE_1__, ink_text_input__WEBPACK_IMPORTED_MODULE_2__, _ConfigModal_js__WEBPACK_IMPORTED_MODULE_3__] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__);
43793
+ /* harmony import */ var _utils_skills_js__WEBPACK_IMPORTED_MODULE_5__ = __nccwpck_require__(6400);
43794
+ /* harmony import */ var _commands_skills_js__WEBPACK_IMPORTED_MODULE_6__ = __nccwpck_require__(9805);
43795
+ var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([ink__WEBPACK_IMPORTED_MODULE_1__, ink_text_input__WEBPACK_IMPORTED_MODULE_2__, _ConfigModal_js__WEBPACK_IMPORTED_MODULE_3__, _commands_skills_js__WEBPACK_IMPORTED_MODULE_6__]);
43796
+ ([ink__WEBPACK_IMPORTED_MODULE_1__, ink_text_input__WEBPACK_IMPORTED_MODULE_2__, _ConfigModal_js__WEBPACK_IMPORTED_MODULE_3__, _commands_skills_js__WEBPACK_IMPORTED_MODULE_6__] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__);
43797
+
43798
+
43470
43799
 
43471
43800
 
43472
43801
 
@@ -43485,6 +43814,7 @@ function WelcomeScreen() {
43485
43814
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(ink__WEBPACK_IMPORTED_MODULE_1__/* .Text */ .EY, { dimColor: true }, "or use slash commands:")),
43486
43815
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(ink__WEBPACK_IMPORTED_MODULE_1__/* .Box */ .az, { flexDirection: "column", marginTop: 1, marginLeft: 2 },
43487
43816
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(ink__WEBPACK_IMPORTED_MODULE_1__/* .Text */ .EY, { dimColor: true }, " /shell - Start Docker shell"),
43817
+ react__WEBPACK_IMPORTED_MODULE_0___default().createElement(ink__WEBPACK_IMPORTED_MODULE_1__/* .Text */ .EY, { dimColor: true }, " /skills - Install/uninstall skills"),
43488
43818
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(ink__WEBPACK_IMPORTED_MODULE_1__/* .Text */ .EY, { dimColor: true }, " /config - Configuration"),
43489
43819
  react__WEBPACK_IMPORTED_MODULE_0___default().createElement(ink__WEBPACK_IMPORTED_MODULE_1__/* .Text */ .EY, { dimColor: true }, " /help - Show help"))));
43490
43820
  }
@@ -43530,7 +43860,7 @@ async function getGitHubToken() {
43530
43860
  }
43531
43861
  // Try to get token from gh CLI
43532
43862
  try {
43533
- const { stdout } = await (0,execa__WEBPACK_IMPORTED_MODULE_5__/* .execa */ .Ho)("gh", ["auth", "token"]);
43863
+ const { stdout } = await (0,execa__WEBPACK_IMPORTED_MODULE_7__/* .execa */ .Ho)("gh", ["auth", "token"]);
43534
43864
  return stdout.trim();
43535
43865
  }
43536
43866
  catch {
@@ -43545,6 +43875,10 @@ function buildDockerShellCommand(githubToken) {
43545
43875
  "-it",
43546
43876
  "-v",
43547
43877
  `${process.cwd()}:${_config_js__WEBPACK_IMPORTED_MODULE_4__/* .DOCKER_CONFIG */ .e6.workspaceMount}`,
43878
+ "-v",
43879
+ `${(0,_utils_skills_js__WEBPACK_IMPORTED_MODULE_5__/* .getSkillsDir */ .YJ)()}:${_config_js__WEBPACK_IMPORTED_MODULE_4__/* .DOCKER_CONFIG */ .e6.skillsMount}`,
43880
+ "-v",
43881
+ `${(0,_utils_skills_js__WEBPACK_IMPORTED_MODULE_5__/* .getOpenCodeConfigPath */ .Jn)()}:${_config_js__WEBPACK_IMPORTED_MODULE_4__/* .DOCKER_CONFIG */ .e6.opencodeConfigMount}`,
43548
43882
  "-e",
43549
43883
  `GITHUB_TOKEN=${githubToken}`,
43550
43884
  "--entrypoint",
@@ -43560,6 +43894,10 @@ function buildDockerOpencodeCommand(githubToken, prompt) {
43560
43894
  "-it",
43561
43895
  "-v",
43562
43896
  `${process.cwd()}:${_config_js__WEBPACK_IMPORTED_MODULE_4__/* .DOCKER_CONFIG */ .e6.workspaceMount}`,
43897
+ "-v",
43898
+ `${(0,_utils_skills_js__WEBPACK_IMPORTED_MODULE_5__/* .getSkillsDir */ .YJ)()}:${_config_js__WEBPACK_IMPORTED_MODULE_4__/* .DOCKER_CONFIG */ .e6.skillsMount}`,
43899
+ "-v",
43900
+ `${(0,_utils_skills_js__WEBPACK_IMPORTED_MODULE_5__/* .getOpenCodeConfigPath */ .Jn)()}:${_config_js__WEBPACK_IMPORTED_MODULE_4__/* .DOCKER_CONFIG */ .e6.opencodeConfigMount}`,
43563
43901
  "-e",
43564
43902
  `GITHUB_TOKEN=${githubToken}`,
43565
43903
  "--entrypoint",
@@ -43602,7 +43940,7 @@ function TerminalUI() {
43602
43940
  const githubToken = await getGitHubToken();
43603
43941
  const dockerArgs = buildDockerShellCommand(githubToken);
43604
43942
  try {
43605
- await (0,execa__WEBPACK_IMPORTED_MODULE_5__/* .execa */ .Ho)("docker", dockerArgs, { stdio: "inherit" });
43943
+ await (0,execa__WEBPACK_IMPORTED_MODULE_7__/* .execa */ .Ho)("docker", dockerArgs, { stdio: "inherit" });
43606
43944
  console.log();
43607
43945
  console.log("✅ Exited shell");
43608
43946
  }
@@ -43623,7 +43961,7 @@ function TerminalUI() {
43623
43961
  const githubToken = await getGitHubToken();
43624
43962
  const dockerArgs = buildDockerOpencodeCommand(githubToken, prompt);
43625
43963
  try {
43626
- await (0,execa__WEBPACK_IMPORTED_MODULE_5__/* .execa */ .Ho)("docker", dockerArgs, { stdio: "inherit" });
43964
+ await (0,execa__WEBPACK_IMPORTED_MODULE_7__/* .execa */ .Ho)("docker", dockerArgs, { stdio: "inherit" });
43627
43965
  console.log();
43628
43966
  console.log("✅ Exited OpenCode");
43629
43967
  }
@@ -43642,12 +43980,16 @@ function TerminalUI() {
43642
43980
  case "shell":
43643
43981
  await handleDockerShell();
43644
43982
  break;
43983
+ case "skills":
43984
+ exit();
43985
+ (0,_commands_skills_js__WEBPACK_IMPORTED_MODULE_6__/* .skillsCommand */ .a)();
43986
+ break;
43645
43987
  case "config":
43646
43988
  setShowConfigModal(true);
43647
43989
  break;
43648
43990
  case "help":
43649
43991
  addMessage("Available commands:", "info");
43650
- const availableCommands = (0,_utils_slashCommands_js__WEBPACK_IMPORTED_MODULE_6__/* .getAvailableCommands */ .K)();
43992
+ const availableCommands = (0,_utils_slashCommands_js__WEBPACK_IMPORTED_MODULE_8__/* .getAvailableCommands */ .K)();
43651
43993
  for (const cmd of availableCommands) {
43652
43994
  addMessage(` ${cmd.command} - ${cmd.description}`, "info");
43653
43995
  }
@@ -43660,7 +44002,7 @@ function TerminalUI() {
43660
44002
  return;
43661
44003
  }
43662
44004
  setInput("");
43663
- const command = (0,_utils_slashCommands_js__WEBPACK_IMPORTED_MODULE_6__/* .parseSlashCommand */ .M)(trimmedValue);
44005
+ const command = (0,_utils_slashCommands_js__WEBPACK_IMPORTED_MODULE_8__/* .parseSlashCommand */ .M)(trimmedValue);
43664
44006
  if (command) {
43665
44007
  await handleSlashCommand(command, trimmedValue);
43666
44008
  }
@@ -43718,10 +44060,59 @@ __webpack_async_result__();
43718
44060
  /***/ ((__unused_webpack_module, __webpack_exports__, __nccwpck_require__) => {
43719
44061
 
43720
44062
  /* harmony export */ __nccwpck_require__.d(__webpack_exports__, {
44063
+ /* harmony export */ XI: () => (/* binding */ SKILLS_CATALOG),
44064
+ /* harmony export */ Z3: () => (/* binding */ NIX_CONFIG),
43721
44065
  /* harmony export */ ZC: () => (/* binding */ SPINNER_CONFIG),
43722
44066
  /* harmony export */ e6: () => (/* binding */ DOCKER_CONFIG),
43723
44067
  /* harmony export */ mF: () => (/* binding */ ASCII_LOGO)
43724
44068
  /* harmony export */ });
44069
+ // Predefined skill catalog — skills are installed to ~/.sith/skills/<name>/
44070
+ const SKILLS_CATALOG = [
44071
+ {
44072
+ name: "caveman",
44073
+ description: "Ultra-compressed communication (~75% token reduction)",
44074
+ homepage: "https://github.com/JuliusBrussee/caveman",
44075
+ builtinInstructions: `---
44076
+ name: caveman
44077
+ description: Ultra-compressed communication mode (ultra — MAX compression, always active).
44078
+ ---
44079
+
44080
+ Respond terse like smart caveman. All technical substance stay. Only fluff die.
44081
+
44082
+ ## Persistence
44083
+
44084
+ ACTIVE EVERY RESPONSE. No revert. Off only: "stop caveman" / "normal mode".
44085
+
44086
+ Level: **ultra** (fixed).
44087
+
44088
+ ## Rules
44089
+
44090
+ Drop: articles (a/an/the), filler (just/really/basically/actually/simply), pleasantries, hedging. Fragments OK. Short synonyms. Technical terms exact. Code blocks unchanged. Errors quoted exact.
44091
+
44092
+ Pattern: \`[thing] [action] [reason]. [next step].\`
44093
+
44094
+ Not: "Sure! I'd be happy to help you with that. The issue you're experiencing is likely caused by..."
44095
+ Yes: "Bug in auth middleware. Token expiry check use \`<\` not \`<=\`. Fix:"
44096
+
44097
+ ## Ultra intensity
44098
+
44099
+ Abbreviate prose (DB/auth/config/req/res/fn/impl), strip conjunctions, arrows for causality (X → Y), one word when one word enough. Code symbols/fn names/API names/error strings: never abbreviate.
44100
+
44101
+ Example — "Why React re-render?"
44102
+ ultra: "Inline obj prop → new ref → re-render. \`useMemo\`."
44103
+
44104
+ Example — "Explain DB connection pooling."
44105
+ ultra: "Pool = reuse DB conn. Skip handshake → fast under load."
44106
+
44107
+ ## Auto-Clarity
44108
+
44109
+ Drop for: security warnings, irreversible ops, steps where order risks misread. Resume after.
44110
+
44111
+ ## Boundaries
44112
+
44113
+ Code/commits/PRs: write normal. "stop caveman" or "normal mode": revert.`,
44114
+ },
44115
+ ];
43725
44116
  // Docker configuration
43726
44117
  const DOCKER_CONFIG = {
43727
44118
  imageName: "sith:latest",
@@ -43729,8 +44120,18 @@ const DOCKER_CONFIG = {
43729
44120
  folderName: "docker",
43730
44121
  dockerfileName: "Dockerfile",
43731
44122
  workspaceMount: "/workspace",
44123
+ skillsMount: "/root/.opencode/skills",
44124
+ opencodeConfigMount: "/root/.config/opencode/opencode.json",
43732
44125
  shellEntrypoint: "/opt/sith/nix/shell.nix",
43733
44126
  };
44127
+ // Nix configuration
44128
+ const NIX_CONFIG = {
44129
+ shellPath: "docker/nix/shell.nix",
44130
+ flakePath: "docker/nix/flake.nix",
44131
+ installerUrl: "https://nixos.org/nix/install",
44132
+ requiredVersion: "2.19",
44133
+ localConfigDir: ".sith/nix",
44134
+ };
43734
44135
  // Spinner animation configuration
43735
44136
  const SPINNER_CONFIG = {
43736
44137
  frames: ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"],
@@ -43760,12 +44161,16 @@ __nccwpck_require__.a(module, async (__webpack_handle_async_dependencies__, __we
43760
44161
  /* harmony import */ var url__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__nccwpck_require__.n(url__WEBPACK_IMPORTED_MODULE_2__);
43761
44162
  /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3__ = __nccwpck_require__(6928);
43762
44163
  /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__nccwpck_require__.n(path__WEBPACK_IMPORTED_MODULE_3__);
43763
- /* harmony import */ var update_notifier__WEBPACK_IMPORTED_MODULE_6__ = __nccwpck_require__(6213);
43764
- /* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_7__ = __nccwpck_require__(9611);
44164
+ /* harmony import */ var update_notifier__WEBPACK_IMPORTED_MODULE_8__ = __nccwpck_require__(6213);
44165
+ /* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_9__ = __nccwpck_require__(9611);
43765
44166
  /* harmony import */ var _commands_docker_js__WEBPACK_IMPORTED_MODULE_4__ = __nccwpck_require__(5515);
43766
- /* harmony import */ var _components_TerminalUI_js__WEBPACK_IMPORTED_MODULE_5__ = __nccwpck_require__(3535);
43767
- var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([_commands_docker_js__WEBPACK_IMPORTED_MODULE_4__, _components_TerminalUI_js__WEBPACK_IMPORTED_MODULE_5__]);
43768
- ([_commands_docker_js__WEBPACK_IMPORTED_MODULE_4__, _components_TerminalUI_js__WEBPACK_IMPORTED_MODULE_5__] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__);
44167
+ /* harmony import */ var _commands_nix_js__WEBPACK_IMPORTED_MODULE_5__ = __nccwpck_require__(9922);
44168
+ /* harmony import */ var _components_TerminalUI_js__WEBPACK_IMPORTED_MODULE_6__ = __nccwpck_require__(3535);
44169
+ /* harmony import */ var _commands_skills_js__WEBPACK_IMPORTED_MODULE_7__ = __nccwpck_require__(9805);
44170
+ var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([_commands_docker_js__WEBPACK_IMPORTED_MODULE_4__, _components_TerminalUI_js__WEBPACK_IMPORTED_MODULE_6__, _commands_skills_js__WEBPACK_IMPORTED_MODULE_7__]);
44171
+ ([_commands_docker_js__WEBPACK_IMPORTED_MODULE_4__, _components_TerminalUI_js__WEBPACK_IMPORTED_MODULE_6__, _commands_skills_js__WEBPACK_IMPORTED_MODULE_7__] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__);
44172
+
44173
+
43769
44174
 
43770
44175
 
43771
44176
 
@@ -43782,12 +44187,12 @@ const PROGRAM_NAME = 'sith';
43782
44187
  const PROGRAM_VERSION = pkg.version;
43783
44188
  const PROGRAM_DESCRIPTION = 'Turn your context to the dark side. Standardize and share your OpenCode setup with a fully dockerized environment, designed for seamless collaboration and CI integration.';
43784
44189
  // Check for updates (automatic background check)
43785
- const notifier = (0,update_notifier__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A)({ pkg });
44190
+ const notifier = (0,update_notifier__WEBPACK_IMPORTED_MODULE_8__/* ["default"] */ .A)({ pkg });
43786
44191
  notifier.notify();
43787
44192
  async function checkForUpdates() {
43788
- console.log(chalk__WEBPACK_IMPORTED_MODULE_7__/* ["default"] */ .Ay.cyan('Checking for updates...'));
44193
+ console.log(chalk__WEBPACK_IMPORTED_MODULE_9__/* ["default"] */ .Ay.cyan('Checking for updates...'));
43789
44194
  // Force update check by setting updateCheckInterval to 0
43790
- const notifier = (0,update_notifier__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A)({
44195
+ const notifier = (0,update_notifier__WEBPACK_IMPORTED_MODULE_8__/* ["default"] */ .A)({
43791
44196
  pkg,
43792
44197
  updateCheckInterval: 0
43793
44198
  });
@@ -43796,12 +44201,12 @@ async function checkForUpdates() {
43796
44201
  const update = notifier.update;
43797
44202
  if (update && update.latest !== pkg.version) {
43798
44203
  console.log();
43799
- console.log(chalk__WEBPACK_IMPORTED_MODULE_7__/* ["default"] */ .Ay.green(`Update available: ${chalk__WEBPACK_IMPORTED_MODULE_7__/* ["default"] */ .Ay.dim(pkg.version)} → ${chalk__WEBPACK_IMPORTED_MODULE_7__/* ["default"] */ .Ay.bold(update.latest)}`));
43800
- console.log(chalk__WEBPACK_IMPORTED_MODULE_7__/* ["default"] */ .Ay.cyan(`Run ${chalk__WEBPACK_IMPORTED_MODULE_7__/* ["default"] */ .Ay.bold(`npm install -g ${pkg.name}`)} to update`));
44204
+ console.log(chalk__WEBPACK_IMPORTED_MODULE_9__/* ["default"] */ .Ay.green(`Update available: ${chalk__WEBPACK_IMPORTED_MODULE_9__/* ["default"] */ .Ay.dim(pkg.version)} → ${chalk__WEBPACK_IMPORTED_MODULE_9__/* ["default"] */ .Ay.bold(update.latest)}`));
44205
+ console.log(chalk__WEBPACK_IMPORTED_MODULE_9__/* ["default"] */ .Ay.cyan(`Run ${chalk__WEBPACK_IMPORTED_MODULE_9__/* ["default"] */ .Ay.bold(`npm install -g ${pkg.name}`)} to update`));
43801
44206
  console.log();
43802
44207
  }
43803
44208
  else {
43804
- console.log(chalk__WEBPACK_IMPORTED_MODULE_7__/* ["default"] */ .Ay.green(`✓ You're on the latest version (${pkg.version})`));
44209
+ console.log(chalk__WEBPACK_IMPORTED_MODULE_9__/* ["default"] */ .Ay.green(`✓ You're on the latest version (${pkg.version})`));
43805
44210
  }
43806
44211
  }
43807
44212
  function createProgram() {
@@ -43813,6 +44218,8 @@ function createProgram() {
43813
44218
  .option('--pull', 'Pull prebuilt Docker image (recommended)')
43814
44219
  .option('--build', 'Build the Docker image from scratch')
43815
44220
  .option('--it', 'Launch interactive shell in Docker container')
44221
+ .option('--nix', 'Use native Nix shell (no Docker)')
44222
+ .option('--nix-install', 'Install Nix package manager locally')
43816
44223
  .option('--update', 'Check for updates')
43817
44224
  .option('--legacy', 'Use legacy menu interface');
43818
44225
  // Default action - show terminal UI or legacy menu
@@ -43821,6 +44228,12 @@ function createProgram() {
43821
44228
  if (options.update) {
43822
44229
  await checkForUpdates();
43823
44230
  }
44231
+ else if (options.nix) {
44232
+ await (0,_commands_nix_js__WEBPACK_IMPORTED_MODULE_5__/* .runNixShell */ .nb)();
44233
+ }
44234
+ else if (options.nixInstall) {
44235
+ await (0,_commands_nix_js__WEBPACK_IMPORTED_MODULE_5__/* .nixCommand */ .Dv)({ install: true });
44236
+ }
43824
44237
  else if (options.it) {
43825
44238
  await (0,_commands_docker_js__WEBPACK_IMPORTED_MODULE_4__/* .runShellDirect */ .l)();
43826
44239
  }
@@ -43830,7 +44243,7 @@ function createProgram() {
43830
44243
  }
43831
44244
  else {
43832
44245
  // Default: show new terminal UI
43833
- (0,_components_TerminalUI_js__WEBPACK_IMPORTED_MODULE_5__/* .renderTerminalUI */ .t)();
44246
+ (0,_components_TerminalUI_js__WEBPACK_IMPORTED_MODULE_6__/* .renderTerminalUI */ .t)();
43834
44247
  }
43835
44248
  });
43836
44249
  // Docker command - explicit Docker management
@@ -43849,6 +44262,22 @@ function createProgram() {
43849
44262
  .action(async () => {
43850
44263
  await (0,_commands_docker_js__WEBPACK_IMPORTED_MODULE_4__/* .runShellDirect */ .l)();
43851
44264
  });
44265
+ // Skills command - install/uninstall skills from catalog
44266
+ program
44267
+ .command('skills')
44268
+ .description('Manage skills (~/.sith/skills/)')
44269
+ .action(() => {
44270
+ (0,_commands_skills_js__WEBPACK_IMPORTED_MODULE_7__/* .skillsCommand */ .a)();
44271
+ });
44272
+ // Nix command - native Nix environment
44273
+ program
44274
+ .command('nix')
44275
+ .description('Manage native Nix environment')
44276
+ .option('--install', 'Install Nix package manager')
44277
+ .option('--shell', 'Run Nix shell')
44278
+ .action(async (options) => {
44279
+ await (0,_commands_nix_js__WEBPACK_IMPORTED_MODULE_5__/* .nixCommand */ .Dv)(options);
44280
+ });
43852
44281
  return program;
43853
44282
  }
43854
44283
  // Main execution
@@ -43858,6 +44287,134 @@ program.parse();
43858
44287
  __webpack_async_result__();
43859
44288
  } catch(e) { __webpack_async_result__(e); } });
43860
44289
 
44290
+ /***/ }),
44291
+
44292
+ /***/ 6400:
44293
+ /***/ ((__unused_webpack_module, __webpack_exports__, __nccwpck_require__) => {
44294
+
44295
+ /* harmony export */ __nccwpck_require__.d(__webpack_exports__, {
44296
+ /* harmony export */ Jn: () => (/* binding */ getOpenCodeConfigPath),
44297
+ /* harmony export */ YJ: () => (/* binding */ getSkillsDir),
44298
+ /* harmony export */ j$: () => (/* binding */ isInstalled),
44299
+ /* harmony export */ rP: () => (/* binding */ installSkill),
44300
+ /* harmony export */ wW: () => (/* binding */ uninstallSkill)
44301
+ /* harmony export */ });
44302
+ /* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __nccwpck_require__(9896);
44303
+ /* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__nccwpck_require__.n(fs__WEBPACK_IMPORTED_MODULE_0__);
44304
+ /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __nccwpck_require__(6928);
44305
+ /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__nccwpck_require__.n(path__WEBPACK_IMPORTED_MODULE_1__);
44306
+ /* harmony import */ var os__WEBPACK_IMPORTED_MODULE_2__ = __nccwpck_require__(857);
44307
+ /* harmony import */ var os__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__nccwpck_require__.n(os__WEBPACK_IMPORTED_MODULE_2__);
44308
+ /* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_4__ = __nccwpck_require__(6181);
44309
+ /* harmony import */ var _config_js__WEBPACK_IMPORTED_MODULE_3__ = __nccwpck_require__(6878);
44310
+
44311
+
44312
+
44313
+
44314
+
44315
+ const OPENCODE_SCHEMA = "https://opencode.ai/config.json";
44316
+ function defaultConfig() {
44317
+ return { $schema: OPENCODE_SCHEMA, instructions: [] };
44318
+ }
44319
+ function getSkillsDir() {
44320
+ const dir = path__WEBPACK_IMPORTED_MODULE_1___default().join(os__WEBPACK_IMPORTED_MODULE_2___default().homedir(), ".sith", "skills");
44321
+ fs__WEBPACK_IMPORTED_MODULE_0___default().mkdirSync(dir, { recursive: true });
44322
+ return dir;
44323
+ }
44324
+ function getOpenCodeConfigPath() {
44325
+ const configPath = path__WEBPACK_IMPORTED_MODULE_1___default().join(os__WEBPACK_IMPORTED_MODULE_2___default().homedir(), ".sith", "opencode.json");
44326
+ // Docker bind-mount creates a directory if the source doesn't exist; ensure it's a file.
44327
+ if (fs__WEBPACK_IMPORTED_MODULE_0___default().existsSync(configPath) && fs__WEBPACK_IMPORTED_MODULE_0___default().statSync(configPath).isDirectory()) {
44328
+ fs__WEBPACK_IMPORTED_MODULE_0___default().rmSync(configPath, { recursive: true, force: true });
44329
+ }
44330
+ if (!fs__WEBPACK_IMPORTED_MODULE_0___default().existsSync(configPath)) {
44331
+ fs__WEBPACK_IMPORTED_MODULE_0___default().mkdirSync(path__WEBPACK_IMPORTED_MODULE_1___default().dirname(configPath), { recursive: true });
44332
+ fs__WEBPACK_IMPORTED_MODULE_0___default().writeFileSync(configPath, JSON.stringify(defaultConfig(), null, 2));
44333
+ }
44334
+ return configPath;
44335
+ }
44336
+ function readConfig() {
44337
+ const parsed = JSON.parse(fs__WEBPACK_IMPORTED_MODULE_0___default().readFileSync(getOpenCodeConfigPath(), "utf8"));
44338
+ if (!Array.isArray(parsed.instructions))
44339
+ parsed.instructions = [];
44340
+ return parsed;
44341
+ }
44342
+ function writeConfig(config) {
44343
+ fs__WEBPACK_IMPORTED_MODULE_0___default().writeFileSync(getOpenCodeConfigPath(), JSON.stringify(config, null, 2));
44344
+ }
44345
+ function addInstruction(containerPath) {
44346
+ const config = readConfig();
44347
+ if (!config.instructions.includes(containerPath)) {
44348
+ config.instructions.push(containerPath);
44349
+ writeConfig(config);
44350
+ }
44351
+ }
44352
+ function removeInstructionsUnder(skillContainerDir) {
44353
+ const config = readConfig();
44354
+ config.instructions = config.instructions.filter((p) => !p.startsWith(skillContainerDir));
44355
+ writeConfig(config);
44356
+ }
44357
+ function findInstructionsFile(skillDir) {
44358
+ const skillName = path__WEBPACK_IMPORTED_MODULE_1___default().basename(skillDir);
44359
+ const candidates = [
44360
+ "SKILL.md",
44361
+ "CAVEMAN.md",
44362
+ "instructions.md",
44363
+ path__WEBPACK_IMPORTED_MODULE_1___default().join("skills", skillName, "SKILL.md"),
44364
+ "AGENTS.md",
44365
+ ];
44366
+ return candidates.find((name) => fs__WEBPACK_IMPORTED_MODULE_0___default().existsSync(path__WEBPACK_IMPORTED_MODULE_1___default().join(skillDir, name))) ?? null;
44367
+ }
44368
+ function isInstalled(name) {
44369
+ return fs__WEBPACK_IMPORTED_MODULE_0___default().existsSync(path__WEBPACK_IMPORTED_MODULE_1___default().join(getSkillsDir(), name, "skill.json"));
44370
+ }
44371
+ async function installSkill(skill) {
44372
+ const targetDir = path__WEBPACK_IMPORTED_MODULE_1___default().join(getSkillsDir(), skill.name);
44373
+ if (skill.builtinInstructions) {
44374
+ fs__WEBPACK_IMPORTED_MODULE_0___default().mkdirSync(targetDir, { recursive: true });
44375
+ fs__WEBPACK_IMPORTED_MODULE_0___default().writeFileSync(path__WEBPACK_IMPORTED_MODULE_1___default().join(targetDir, "SKILL.md"), skill.builtinInstructions);
44376
+ fs__WEBPACK_IMPORTED_MODULE_0___default().writeFileSync(path__WEBPACK_IMPORTED_MODULE_1___default().join(targetDir, "skill.json"), JSON.stringify({ name: skill.name, version: "builtin" }, null, 2));
44377
+ addInstruction(`${_config_js__WEBPACK_IMPORTED_MODULE_3__/* .DOCKER_CONFIG */ .e6.skillsMount}/${skill.name}/SKILL.md`);
44378
+ return;
44379
+ }
44380
+ if (!skill.source)
44381
+ throw new Error(`Skill "${skill.name}" has no source URL`);
44382
+ const tmpZip = path__WEBPACK_IMPORTED_MODULE_1___default().join(os__WEBPACK_IMPORTED_MODULE_2___default().tmpdir(), `sith-skill-${skill.name}.zip`);
44383
+ const tmpExtract = path__WEBPACK_IMPORTED_MODULE_1___default().join(os__WEBPACK_IMPORTED_MODULE_2___default().tmpdir(), `sith-skill-${skill.name}-extract`);
44384
+ try {
44385
+ await (0,execa__WEBPACK_IMPORTED_MODULE_4__/* .execa */ .Ho)("curl", ["-fsSL", skill.source, "-o", tmpZip]);
44386
+ fs__WEBPACK_IMPORTED_MODULE_0___default().mkdirSync(tmpExtract, { recursive: true });
44387
+ await (0,execa__WEBPACK_IMPORTED_MODULE_4__/* .execa */ .Ho)("unzip", ["-q", "-o", tmpZip, "-d", tmpExtract]);
44388
+ const entries = fs__WEBPACK_IMPORTED_MODULE_0___default().readdirSync(tmpExtract);
44389
+ if (entries.length === 0)
44390
+ throw new Error("Empty archive");
44391
+ const extracted = path__WEBPACK_IMPORTED_MODULE_1___default().join(tmpExtract, entries[0]);
44392
+ if (fs__WEBPACK_IMPORTED_MODULE_0___default().existsSync(targetDir))
44393
+ fs__WEBPACK_IMPORTED_MODULE_0___default().rmSync(targetDir, { recursive: true, force: true });
44394
+ fs__WEBPACK_IMPORTED_MODULE_0___default().cpSync(extracted, targetDir, { recursive: true });
44395
+ const skillJson = path__WEBPACK_IMPORTED_MODULE_1___default().join(targetDir, "skill.json");
44396
+ if (!fs__WEBPACK_IMPORTED_MODULE_0___default().existsSync(skillJson)) {
44397
+ fs__WEBPACK_IMPORTED_MODULE_0___default().writeFileSync(skillJson, JSON.stringify({ name: skill.name, version: "local" }, null, 2));
44398
+ }
44399
+ const instructionsFile = findInstructionsFile(targetDir);
44400
+ if (instructionsFile) {
44401
+ addInstruction(`${_config_js__WEBPACK_IMPORTED_MODULE_3__/* .DOCKER_CONFIG */ .e6.skillsMount}/${skill.name}/${instructionsFile}`);
44402
+ }
44403
+ }
44404
+ finally {
44405
+ fs__WEBPACK_IMPORTED_MODULE_0___default().rmSync(tmpZip, { force: true });
44406
+ fs__WEBPACK_IMPORTED_MODULE_0___default().rmSync(tmpExtract, { recursive: true, force: true });
44407
+ }
44408
+ }
44409
+ function uninstallSkill(name) {
44410
+ removeInstructionsUnder(`${_config_js__WEBPACK_IMPORTED_MODULE_3__/* .DOCKER_CONFIG */ .e6.skillsMount}/${name}/`);
44411
+ const targetDir = path__WEBPACK_IMPORTED_MODULE_1___default().join(getSkillsDir(), name);
44412
+ if (fs__WEBPACK_IMPORTED_MODULE_0___default().existsSync(targetDir)) {
44413
+ fs__WEBPACK_IMPORTED_MODULE_0___default().rmSync(targetDir, { recursive: true, force: true });
44414
+ }
44415
+ }
44416
+
44417
+
43861
44418
  /***/ }),
43862
44419
 
43863
44420
  /***/ 9987:
@@ -43880,6 +44437,8 @@ function parseSlashCommand(input) {
43880
44437
  return { type: "config", raw: trimmed };
43881
44438
  case "help":
43882
44439
  return { type: "help", raw: trimmed };
44440
+ case "skills":
44441
+ return { type: "skills", raw: trimmed };
43883
44442
  default:
43884
44443
  return null;
43885
44444
  }
@@ -43887,6 +44446,7 @@ function parseSlashCommand(input) {
43887
44446
  function getAvailableCommands() {
43888
44447
  return [
43889
44448
  { command: "/shell", description: "Start Docker shell (no OpenCode)" },
44449
+ { command: "/skills", description: "Install/uninstall skills" },
43890
44450
  { command: "/config", description: "Open configuration menu" },
43891
44451
  { command: "/help", description: "Show available commands" },
43892
44452
  ];