@m14i/sith 1.22.0 → 1.23.1

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/README.md CHANGED
@@ -8,163 +8,146 @@
8
8
 
9
9
  Standardize and share your OpenCode setup with a fully dockerized environment, designed for seamless collaboration and CI integration.
10
10
 
11
- ## Usage
11
+ ---
12
12
 
13
- ### Installation
13
+ ## Quick Start
14
14
 
15
- **Install globally (recommended):**
16
15
  ```bash
17
- npm install -g @m14i/sith
16
+ npm install -g @m14i/sith # Install CLI
17
+ sith --pull # Pull prebuilt Docker image
18
+ sith # Launch TUI
18
19
  ```
19
20
 
20
- **Or use npx (slower, pulls image every time):**
21
+ No Docker? Use native Nix:
22
+
21
23
  ```bash
22
- npx @m14i/sith@latest
24
+ sith --nix-install && sith --nix
23
25
  ```
24
26
 
25
- ### Quick Start
27
+ ---
26
28
 
27
- ```bash
28
- # Interactive terminal UI (default)
29
- sith
30
- # Type your prompt to start OpenCode with that task
31
- # Or use slash commands: /shell, /config, /help
32
-
33
- # Direct commands
34
- sith --it # Launch Docker shell immediately
35
- sith --pull # Pull prebuilt image
36
- sith --build # Build from scratch
37
- sith --legacy # Use legacy menu interface
38
- ```
29
+ ## Why?
39
30
 
40
- ### Distribution Options
31
+ AI coding tools are powerful in isolation. They become fragile at scale:
41
32
 
42
- | Method | Command | Speed | Trust Model | Use Case |
43
- |--------|---------|-------|-------------|----------|
44
- | **Prebuilt (Recommended)** | `sith --pull` | Fast | GitHub Actions + Cosign | Production, CI/CD |
45
- | **Local Build** | `sith --build` | 🐌 Slow | Your machine | Air-gapped, custom builds |
33
+ - **Context drift** every developer has a different CLAUDE.md, different tool versions, different configs. The AI sees a different project depending on who's running it.
34
+ - **No CI path** — running `opencode` or `claude` in a pipeline requires wiring tokens, installing tools, and hoping the environment matches local.
35
+ - **Multiple tools** Claude Code and OpenCode serve different use cases (Anthropic auth vs GitHub Copilot). Switching between them shouldn't require manual setup.
46
36
 
47
- ### Commands
37
+ Sith solves this by packaging both tools, all config, and your team's context into a single Docker image. One pull, same environment, everywhere.
48
38
 
49
- | Command | Description |
39
+ | Problem | Sith answer |
50
40
  |---------|-------------|
51
- | `sith` | Interactive terminal UI (Claude Code style) |
52
- | `sith --it` | Launch Docker shell immediately |
53
- | `sith --pull` | Pull prebuilt image from GHCR |
54
- | `sith --build` | Build Docker image from scratch |
55
- | `sith --legacy` | Use legacy menu interface |
56
- | `sith --help` | Show all available commands |
57
-
58
- ### Terminal UI Usage
41
+ | Inconsistent context across team | Shared `~/.sith/` skills + CLAUDE.md, mounted at runtime |
42
+ | AI tools hard to run in CI | Prebuilt signed image + token injection via env vars |
43
+ | Claude Code vs OpenCode friction | Both available, same container, same command |
44
+ | "Works on my machine" builds | Nix-pinned dependencies inside Docker |
45
+
46
+ ---
47
+
48
+ ## How?
49
+
50
+ Three modes. Pick based on your trust model, infra constraints, and whether Docker is available. The Docker path is recommended for teams and CI — native Nix is for when you want no container overhead on a machine you control.
51
+
52
+ | | `sith --pull` | `sith --build` | `sith --nix` |
53
+ |---|---|---|---|
54
+ | **Setup time** | ~1 min (pull) | ~5–10 min (build) | ~2 min (first run) |
55
+ | **Reproducibility** | Pinned image digest | Dockerfile-pinned | Nix-pinned (`nixos-23.11`) |
56
+ | **Trust model** | GitHub Actions + Cosign | Your machine only | Your machine only |
57
+ | **SBOM included** | ✅ | ❌ | ❌ |
58
+ | **CI/CD ready** | ✅ drop-in | ⚠️ needs build step | ❌ |
59
+ | **Requires Docker** | ✅ | ✅ | ❌ |
60
+ | **Requires Nix** | ❌ | ❌ | ✅ |
61
+ | **Disk usage** | ~2–3 GB (image) | ~2–3 GB (image) | ~500 MB (store) |
62
+ | **Cold start** | ~1–2s (container spin-up) | ~1–2s (container spin-up) | ~200ms (native) |
63
+ | **Runtime overhead** | Low (Linux containers) | Low (Linux containers) | None |
64
+ | **File I/O (macOS)** | ⚠️ Slow (volume mounts) | ⚠️ Slow (volume mounts) | ✅ Native speed |
65
+ | **File I/O (Linux)** | ✅ Native speed | ✅ Native speed | ✅ Native speed |
66
+ | **Memory overhead** | ~50–100MB (Docker daemon) | ~50–100MB (Docker daemon) | None |
67
+ | **Works offline** | ✅ after pull | ✅ after build | ⚠️ after store populated |
68
+ | **macOS support** | ✅ (amd64 + arm64) | ✅ | ✅ |
69
+ | **Linux support** | ✅ | ✅ | ✅ |
70
+ | **Windows support** | ✅ Docker Desktop | ✅ Docker Desktop | ❌ |
71
+ | **Ideal for** | Teams, CI, daily use | Air-gapped, custom | Local dev, no Docker |
72
+
73
+ ---
74
+
75
+ ## Docker
76
+
77
+ The recommended path. One image, works locally and in CI.
78
+
79
+ ### Install the CLI
59
80
 
60
- When you run `sith`, you get an interactive terminal interface:
81
+ ```bash
82
+ npm install -g @m14i/sith
83
+ ```
61
84
 
62
- **Prompt input:**
63
- - Type any text → Starts OpenCode with that prompt using Claude Sonnet 4.6
64
- - Example: `Fix authentication bug` → OpenCode launches with this task
85
+ Or without installing:
65
86
 
66
- **Slash commands:**
67
- - `/shell` → Start Docker shell only (no OpenCode)
68
- - `/config` → Open configuration menu (pull/build options)
69
- - `/help` → Show available commands
87
+ ```bash
88
+ npx @m14i/sith@latest
89
+ ```
70
90
 
71
- **Navigation:**
72
- - `Ctrl+C` or `Esc` → Exit terminal UI
91
+ ### Get the image
73
92
 
74
- ### Prebuilt Image Details
93
+ **Prebuilt (recommended) — pull a signed image from GHCR:**
75
94
 
76
- **Pull and verify:**
77
95
  ```bash
78
- # Pull (supports linux/amd64 and linux/arm64)
79
96
  sith --pull
97
+ ```
98
+
99
+ Supports `linux/amd64` and `linux/arm64`. Images are signed with cosign and include an SBOM.
80
100
 
81
- # Or use Docker directly
82
- docker pull ghcr.io/merzoukemanouri/sith:latest
101
+ **Verify the signature (optional):**
83
102
 
84
- # Verify signature (optional)
103
+ ```bash
85
104
  cosign verify \
86
105
  --certificate-identity-regexp="https://github.com/MerzoukeMansouri/sith" \
87
106
  --certificate-oidc-issuer="https://token.actions.githubusercontent.com" \
88
- ghcr.io/merzoukemanouri/sith:latest
107
+ ghcr.io/merzoukemansouri/sith:latest
89
108
  ```
90
109
 
91
- **Benefits:**
92
- - ✅ Fast - no build time
93
- - ✅ Multi-platform - amd64 and arm64
94
- - ✅ Signed - cosign verification
95
- - ✅ SBOM - supply chain transparency
96
- - ✅ Auto-updated - tracks releases
97
-
98
- ## Authentication
99
-
100
- Sith supports two AI providers: **Claude Code** (via Anthropic) and **OpenCode** (via GitHub Copilot).
110
+ **Build from scratch — full control, no external trust:**
101
111
 
102
- ### Claude Code (claude CLI)
103
-
104
- Sith ships with the `claude` CLI. Authenticate it with your Anthropic account using a long-lived OAuth token — no API key required.
105
-
106
- **Step 1 — Generate the token (once, on your local machine):**
107
112
  ```bash
108
- claude setup-token
113
+ sith --build
109
114
  ```
110
- Follow the browser prompt, then copy the printed token. It is valid for one year and scoped to inference only.
111
115
 
112
- **Step 2 — Export it:**
113
- ```bash
114
- export CLAUDE_CODE_OAUTH_TOKEN=your_token_here
115
- ```
116
+ ### Use it
116
117
 
117
- **Make it persistent (add to ~/.zshrc or ~/.bashrc):**
118
- ```bash
119
- export CLAUDE_CODE_OAUTH_TOKEN=your_token_here
120
- ```
118
+ **Interactive TUI** type a prompt or use slash commands:
121
119
 
122
- **Verify:**
123
120
  ```bash
124
- claude auth status
125
- # Should show: "loggedIn": true, "authMethod": "claude.ai"
121
+ sith
126
122
  ```
127
123
 
128
- **Requirements:** Claude Pro, Max, Team, or Enterprise subscription.
129
-
130
- ### GitHub Copilot (opencode CLI)
124
+ | In the TUI | What it does |
125
+ |------------|-------------|
126
+ | Type any text + Enter | Starts OpenCode with that prompt |
127
+ | `/shell` | Drop into Docker shell (no AI) |
128
+ | `/claude` | Switch active tool to Claude Code |
129
+ | `/opencode` | Switch active tool to OpenCode |
130
+ | `/config` | Pull / build options |
131
+ | `/help` | Show commands |
132
+ | `Ctrl+C` / `Esc` | Exit |
131
133
 
132
- Sith uses **Claude Sonnet 4.6 via GitHub Copilot** by default for OpenCode. Requires a GitHub token with Copilot access.
134
+ **Direct commands** skip the TUI:
133
135
 
134
- **Automatic (recommended):**
135
- If you have GitHub CLI (`gh`) installed and authenticated, Sith automatically fetches your token:
136
136
  ```bash
137
- sith # Auto-detects token via gh auth token
137
+ sith shell # Raw Nix shell inside Docker (alias: sith --it)
138
+ sith opencode -p "fix the bug" # OpenCode starts immediately with your task
139
+ sith claude -p "fix the bug" # Claude Code starts immediately with your task
138
140
  ```
139
141
 
140
- **Manual token:**
141
- If you don't have `gh` CLI or prefer manual setup:
142
+ ### Cleanup
142
143
 
143
- 1. Ensure you have GitHub Copilot access
144
- 2. Create a token at https://github.com/settings/tokens
145
- 3. Required scopes: `copilot`, `repo`, `read:org`
146
- 4. Export it:
147
144
  ```bash
148
- export GITHUB_TOKEN=gho_your_token_here
149
- sith
150
- ```
151
-
152
- **Make it persistent (add to ~/.zshrc or ~/.bashrc):**
153
- ```bash
154
- export GITHUB_TOKEN=$(gh auth token)
155
- ```
156
-
157
- **Inside container:**
158
- Once OpenCode starts, authenticate with GitHub Copilot:
159
- ```bash
160
- opencode providers login
161
- # Follow prompts to authenticate with GitHub
145
+ sith --docker-cleanup # Remove sith Docker images (sith:latest + prebuilt GHCR image)
146
+ sith --uninstall # Remove ~/.sith/ (skills, config, nix files)
162
147
  ```
163
148
 
164
149
  ### CI / GitHub Actions
165
150
 
166
- Add both tokens as repository secrets, then pass them to the container:
167
-
168
151
  ```yaml
169
152
  - name: Run sith
170
153
  env:
@@ -174,101 +157,117 @@ Add both tokens as repository secrets, then pass them to the container:
174
157
  docker run --rm \
175
158
  -e CLAUDE_CODE_OAUTH_TOKEN=$CLAUDE_CODE_OAUTH_TOKEN \
176
159
  -e GITHUB_TOKEN=$GITHUB_TOKEN \
177
- ghcr.io/merzoukemanouri/sith:latest "claude auth status"
160
+ ghcr.io/merzoukemansouri/sith:latest "claude auth status"
178
161
  ```
179
162
 
180
- Generate `CLAUDE_CODE_OAUTH_TOKEN` once with `claude setup-token` and store it in **Settings → Secrets → Actions** as `CLAUDE_CODE_OAUTH_TOKEN`.
163
+ See [Authentication](./doc/AUTH_CLAUDE.md) for how to generate the tokens.
181
164
 
182
- ## Features
165
+ ---
183
166
 
184
- - **Claude Code-style UI**: Interactive terminal interface with prompt input and slash commands
185
- - **OpenCode Integration**: Start coding with a simple text prompt
186
- - **Model Selection**: Uses Claude Sonnet 4.6 via GitHub Copilot by default
187
- - **Prebuilt Images**: Pull verified images from GitHub Container Registry
188
- - **Image Signing**: All images signed with cosign for supply chain security
189
- - **SBOM Attestation**: Software Bill of Materials included with every image
190
- - **Dockerized Environment**: Consistent setup across machines
191
- - **Nix Integration**: Full development environment with all tools
192
- - **CI-Ready**: Standardize builds across local and CI pipelines
193
- - **Non-root User**: Images run as non-root user (UID 1000) for better security
167
+ ## Direct Nix
194
168
 
195
- ## Security
169
+ No Docker. Runs the same Nix environment natively on your machine.
196
170
 
197
- ### Image Verification
171
+ ```bash
172
+ sith --nix-install # Install Nix package manager (once)
173
+ sith --nix # Launch Nix shell directly
174
+ ```
198
175
 
199
- All Docker images published to `ghcr.io/merzoukemanouri/sith` are:
200
- - **Signed with cosign** using keyless signing (OIDC)
201
- - **Include SBOM** (Software Bill of Materials) for transparency
202
- - **Built automatically** via GitHub Actions with provenance
176
+ Or via the `nix` subcommand:
203
177
 
204
- See [SECURITY.md](./SECURITY.md) for detailed security practices and considerations.
178
+ ```bash
179
+ sith nix --install # Install Nix
180
+ sith nix --shell # Run Nix shell
181
+ ```
205
182
 
206
- ### Trust Model
183
+ **Maintenance:**
207
184
 
208
- **Prebuilt Images:**
209
- - Built by GitHub Actions on public infrastructure
210
- - Signed with Sigstore keyless signing
211
- - Verifiable provenance chain from source to image
212
- - Trade-off: Trust GitHub's build infrastructure
185
+ ```bash
186
+ sith --nix-update # Update Nix channels and upgrade installed packages
187
+ sith --nix-cleanup # Remove ~/.sith/nix/ + run nix-collect-garbage -d
188
+ sith --nix-uninstall # Fully remove Nix from system (daemon, /nix/store) — needs sudo
189
+ ```
213
190
 
214
- **Local Builds:**
215
- - Full control over build environment
216
- - Can inspect Dockerfile before building
217
- - No dependency on external registries
218
- - Trade-off: Slower, manual security updates
191
+ See [doc/NIX_INSTALLATION.md](./doc/NIX_INSTALLATION.md) for full setup guide.
219
192
 
220
- For more details, see the [Docker Distribution Guide](./doc/QUICKSTART.md#docker-distribution).
193
+ ---
221
194
 
222
- ## Development
195
+ ## Skills
223
196
 
224
- For contributors working on the CLI:
197
+ Skills are AI instruction sets installed to `~/.sith/skills/` and automatically mounted into the container at runtime. They shape how Claude Code and OpenCode behave — tone, workflow, shortcuts.
225
198
 
226
199
  ```bash
227
- # Install dependencies
228
- pnpm install
200
+ sith skills # Browse and install / uninstall skills from catalog
201
+ ```
229
202
 
230
- # Run in development mode (no build)
231
- pnpm dev
203
+ Installed skills are synced to `~/.sith/CLAUDE.md` (Claude Code) and `~/.sith/opencode.json` (OpenCode) automatically.
232
204
 
233
- # Build and test
234
- pnpm dev:build # Build and run CLI
235
- pnpm dev:shell # Build and launch shell
205
+ | Skill | What it does | Auto-loaded |
206
+ |-------|-------------|-------------|
207
+ | `caveman` | Ultra-compressed responses (~75% token reduction) | ✅ |
236
208
 
237
- # Type checking
238
- pnpm typecheck
209
+ Skills are loaded from `~/.sith/skills/<name>/` and can be toggled individually. Community skills can be installed from any Git URL.
239
210
 
240
- # Clean build artifacts
241
- pnpm clean
242
- ```
211
+ ---
243
212
 
244
- ## Publishing
213
+ ## Authentication
214
+
215
+ Two AI providers, two token setups:
245
216
 
246
- Automated releases using semantic-release and conventional commits.
217
+ - **Claude Code** (Anthropic OAuth) [doc/AUTH_CLAUDE.md](./doc/AUTH_CLAUDE.md)
218
+ - **OpenCode** (GitHub Copilot) → [doc/AUTH_OPENCODE.md](./doc/AUTH_OPENCODE.md)
247
219
 
248
- ### For Maintainers
220
+ ---
249
221
 
250
- **Commit Format:**
251
- - `feat:` - New feature (triggers minor version bump)
252
- - `fix:` - Bug fix (triggers patch version bump)
253
- - `BREAKING CHANGE:` - Breaking change (triggers major version bump)
254
- - `chore:`, `docs:`, `style:` - No release
222
+ ## Command Reference
255
223
 
256
- **Release Process:**
257
- 1. Commit changes following conventional commit format
258
- 2. Push to `main` branch
259
- 3. GitHub Action automatically:
260
- - Analyzes commits and determines version bump
261
- - Generates CHANGELOG.md
262
- - Creates GitHub release
263
- - Publishes to npm
224
+ | Command / Flag | Description |
225
+ |---|---|
226
+ | `sith` | Launch interactive TUI |
227
+ | `sith shell` | Raw Nix shell inside Docker |
228
+ | `sith opencode -p "<prompt>"` | Launch OpenCode with prompt |
229
+ | `sith claude -p "<prompt>"` | Launch Claude Code with prompt |
230
+ | `sith skills` | Manage skills from catalog |
231
+ | `sith nix --install` | Install Nix package manager |
232
+ | `sith nix --shell` | Run Nix shell |
233
+ | `sith --pull` | Pull prebuilt Docker image from GHCR |
234
+ | `sith --build` | Build Docker image from scratch |
235
+ | `sith --it` | Interactive shell in Docker container |
236
+ | `sith --nix` | Launch native Nix shell (no Docker) |
237
+ | `sith --nix-install` | Install Nix package manager |
238
+ | `sith --nix-update` | Update Nix channels + upgrade packages |
239
+ | `sith --nix-cleanup` | Remove `~/.sith/nix/` + garbage collect store |
240
+ | `sith --nix-uninstall` | Fully remove Nix from system (needs sudo) |
241
+ | `sith --docker-cleanup` | Remove sith Docker images from local machine |
242
+ | `sith --uninstall` | Remove `~/.sith/` config directory |
243
+ | `sith --update` | Check for CLI updates |
244
+
245
+ ---
246
+
247
+ ## Development
264
248
 
265
- **Example:**
266
249
  ```bash
267
- git commit -m "feat: add new interactive menu option"
268
- git push origin main
269
- # Automatic release triggered!
250
+ pnpm install # Install dependencies
251
+ pnpm dev # Run in development mode (no build)
252
+ pnpm dev:build # Build and run CLI
253
+ pnpm dev:shell # Build and launch shell
254
+ pnpm typecheck # Type checking
255
+ pnpm clean # Clean build artifacts
270
256
  ```
271
257
 
272
- **Requirements:**
273
- - `NPM_TOKEN` secret configured in GitHub repository settings
274
- - Commits must follow conventional commit format
258
+ ---
259
+
260
+ ## Publishing
261
+
262
+ Automated via semantic-release and conventional commits.
263
+
264
+ | Prefix | Effect |
265
+ |--------|--------|
266
+ | `feat:` | Minor version bump |
267
+ | `fix:` | Patch version bump |
268
+ | `BREAKING CHANGE:` | Major version bump |
269
+ | `chore:` `docs:` `style:` | No release |
270
+
271
+ Push to `main` → GitHub Action bumps version, generates CHANGELOG, publishes to npm.
272
+
273
+ **Requirements:** `NPM_TOKEN` secret in repository settings.
@@ -1,4 +1,3 @@
1
1
  import type { DockerCommandOptions } from "../types.js";
2
2
  export declare function dockerCommand(options: DockerCommandOptions): Promise<void>;
3
- export declare function runShellDirect(): Promise<void>;
4
3
  //# sourceMappingURL=docker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"docker.d.ts","sourceRoot":"","sources":["file:///home/runner/work/sith/sith/src/commands/docker.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAEX,oBAAoB,EAEpB,MAAM,aAAa,CAAC;AAqTrB,wBAAsB,aAAa,CAClC,OAAO,EAAE,oBAAoB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAEpD"}
1
+ {"version":3,"file":"docker.d.ts","sourceRoot":"","sources":["file:///home/runner/work/sith/sith/src/commands/docker.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAwBxD,wBAAsB,aAAa,CAClC,OAAO,EAAE,oBAAoB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAUf"}
@@ -0,0 +1,6 @@
1
+ export declare function dockerCleanupCommand(): Promise<void>;
2
+ export declare function nixCleanupCommand(): Promise<void>;
3
+ export declare function nixUpdateCommand(): Promise<void>;
4
+ export declare function nixUninstallCommand(): Promise<void>;
5
+ export declare function uninstallCommand(): Promise<void>;
6
+ //# sourceMappingURL=maintenance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"maintenance.d.ts","sourceRoot":"","sources":["file:///home/runner/work/sith/sith/src/commands/maintenance.ts"],"names":[],"mappings":"AAkBA,wBAAsB,oBAAoB,kBAwBzC;AAED,wBAAsB,iBAAiB,kBAqBtC;AAED,wBAAsB,gBAAgB,kBAmBrC;AAED,wBAAsB,mBAAmB,kBAmExC;AAED,wBAAsB,gBAAgB,kBAwBrC"}
@@ -1 +1 @@
1
- {"version":3,"file":"nix.d.ts","sourceRoot":"","sources":["file:///home/runner/work/sith/sith/src/commands/nix.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAsBrD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAQ7D;AAED,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC,CAO1D;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CA0ChD;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAuClD;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAoDjD;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAc1E"}
1
+ {"version":3,"file":"nix.d.ts","sourceRoot":"","sources":["file:///home/runner/work/sith/sith/src/commands/nix.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAsBrD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAQ7D;AAED,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC,CAO1D;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CA0ChD;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAuClD;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CA8DjD;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAc1E"}
package/dist/index.js CHANGED
@@ -42961,35 +42961,20 @@ which.sync = whichSync
42961
42961
 
42962
42962
  /***/ }),
42963
42963
 
42964
- /***/ 5515:
42965
- /***/ ((module, __webpack_exports__, __nccwpck_require__) => {
42964
+ /***/ 3361:
42965
+ /***/ ((__unused_webpack_module, __webpack_exports__, __nccwpck_require__) => {
42966
42966
 
42967
- __nccwpck_require__.a(module, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
42968
42967
  /* harmony export */ __nccwpck_require__.d(__webpack_exports__, {
42969
42968
  /* harmony export */ Q: () => (/* binding */ dockerCommand)
42970
42969
  /* harmony export */ });
42971
- /* unused harmony export runShellDirect */
42972
42970
  /* harmony import */ var node_fs__WEBPACK_IMPORTED_MODULE_0__ = __nccwpck_require__(3024);
42973
42971
  /* harmony import */ var node_fs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__nccwpck_require__.n(node_fs__WEBPACK_IMPORTED_MODULE_0__);
42974
42972
  /* harmony import */ var node_path__WEBPACK_IMPORTED_MODULE_1__ = __nccwpck_require__(6760);
42975
42973
  /* harmony import */ var node_path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__nccwpck_require__.n(node_path__WEBPACK_IMPORTED_MODULE_1__);
42976
42974
  /* harmony import */ var node_url__WEBPACK_IMPORTED_MODULE_2__ = __nccwpck_require__(3136);
42977
42975
  /* harmony import */ var node_url__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__nccwpck_require__.n(node_url__WEBPACK_IMPORTED_MODULE_2__);
42978
- /* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_9__ = __nccwpck_require__(6181);
42979
- /* harmony import */ var ink__WEBPACK_IMPORTED_MODULE_3__ = __nccwpck_require__(3816);
42980
- /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_4__ = __nccwpck_require__(2864);
42981
- /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__nccwpck_require__.n(react__WEBPACK_IMPORTED_MODULE_4__);
42982
- /* harmony import */ var _config_js__WEBPACK_IMPORTED_MODULE_5__ = __nccwpck_require__(6878);
42983
- /* harmony import */ var _utils_launcher_js__WEBPACK_IMPORTED_MODULE_6__ = __nccwpck_require__(5800);
42984
- /* harmony import */ var _nix_js__WEBPACK_IMPORTED_MODULE_7__ = __nccwpck_require__(9922);
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_3__, _skills_js__WEBPACK_IMPORTED_MODULE_8__]);
42987
- ([ink__WEBPACK_IMPORTED_MODULE_3__, _skills_js__WEBPACK_IMPORTED_MODULE_8__] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__);
42988
-
42989
-
42990
-
42991
-
42992
-
42976
+ /* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_4__ = __nccwpck_require__(6181);
42977
+ /* harmony import */ var _config_js__WEBPACK_IMPORTED_MODULE_3__ = __nccwpck_require__(6878);
42993
42978
 
42994
42979
 
42995
42980
 
@@ -43001,217 +42986,15 @@ function findProjectRoot(startDir) {
43001
42986
  let currentDir = startDir;
43002
42987
  const rootPath = node_path__WEBPACK_IMPORTED_MODULE_1___default().parse(currentDir).root;
43003
42988
  while (currentDir !== rootPath) {
43004
- const dockerPath = node_path__WEBPACK_IMPORTED_MODULE_1___default().join(currentDir, _config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.folderName);
42989
+ const dockerPath = node_path__WEBPACK_IMPORTED_MODULE_1___default().join(currentDir, _config_js__WEBPACK_IMPORTED_MODULE_3__/* .DOCKER_CONFIG */ .e6.folderName);
43005
42990
  if (node_fs__WEBPACK_IMPORTED_MODULE_0___default().existsSync(dockerPath) && node_fs__WEBPACK_IMPORTED_MODULE_0___default().statSync(dockerPath).isDirectory()) {
43006
42991
  return currentDir;
43007
42992
  }
43008
42993
  currentDir = node_path__WEBPACK_IMPORTED_MODULE_1___default().dirname(currentDir);
43009
42994
  }
43010
- throw new Error(`Could not find project root (${_config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.folderName}/ folder not found)`);
42995
+ throw new Error(`Could not find project root (${_config_js__WEBPACK_IMPORTED_MODULE_3__/* .DOCKER_CONFIG */ .e6.folderName}/ folder not found)`);
43011
42996
  }
43012
42997
  const rootDir = findProjectRoot(__dirname);
43013
- const menuItems = [
43014
- { label: "Enter Shell", value: "shell", icon: "🚀" },
43015
- { label: "Manage Skills", value: "skills", icon: "🧠" },
43016
- { label: "Configuration", value: "config", icon: "⚙️" },
43017
- ];
43018
- const configMenuItems = [
43019
- { label: "Pull prebuilt image (recommended)", value: "pull", icon: "📦" },
43020
- { label: "Build Docker image from scratch", value: "build", icon: "🔨" },
43021
- { label: "Install Nix locally (no Docker)", value: "nix", icon: "❄️" },
43022
- { label: "Back", value: "back", icon: "◀️" },
43023
- ];
43024
- function Logo() {
43025
- return (react__WEBPACK_IMPORTED_MODULE_4___default().createElement(ink__WEBPACK_IMPORTED_MODULE_3__/* .Box */ .az, { flexDirection: "column", marginBottom: 1 },
43026
- react__WEBPACK_IMPORTED_MODULE_4___default().createElement(ink__WEBPACK_IMPORTED_MODULE_3__/* .Box */ .az, { flexDirection: "column" }, _config_js__WEBPACK_IMPORTED_MODULE_5__/* .ASCII_LOGO */ .mF.map((line, index) => (
43027
- // biome-ignore lint/suspicious/noArrayIndexKey: static array, order never changes
43028
- react__WEBPACK_IMPORTED_MODULE_4___default().createElement(ink__WEBPACK_IMPORTED_MODULE_3__/* .Text */ .EY, { key: index, color: "red", bold: true }, line)))),
43029
- react__WEBPACK_IMPORTED_MODULE_4___default().createElement(ink__WEBPACK_IMPORTED_MODULE_3__/* .Box */ .az, { borderStyle: "double", borderColor: "red", paddingX: 2, marginTop: 1 },
43030
- react__WEBPACK_IMPORTED_MODULE_4___default().createElement(ink__WEBPACK_IMPORTED_MODULE_3__/* .Text */ .EY, { color: "red", bold: true }, "SITH - Docker Manager"))));
43031
- }
43032
- function BuildingSpinner({ step }) {
43033
- const [frame, setFrame] = (0,react__WEBPACK_IMPORTED_MODULE_4__.useState)(0);
43034
- (0,react__WEBPACK_IMPORTED_MODULE_4__.useEffect)(() => {
43035
- const timer = setInterval(() => {
43036
- setFrame((prev) => (prev + 1) % _config_js__WEBPACK_IMPORTED_MODULE_5__/* .SPINNER_CONFIG */ .ZC.frames.length);
43037
- }, _config_js__WEBPACK_IMPORTED_MODULE_5__/* .SPINNER_CONFIG */ .ZC.interval);
43038
- return () => clearInterval(timer);
43039
- }, []);
43040
- return (react__WEBPACK_IMPORTED_MODULE_4___default().createElement(ink__WEBPACK_IMPORTED_MODULE_3__/* .Box */ .az, { flexDirection: "column", marginTop: 1 },
43041
- react__WEBPACK_IMPORTED_MODULE_4___default().createElement(ink__WEBPACK_IMPORTED_MODULE_3__/* .Text */ .EY, { color: "cyan" },
43042
- _config_js__WEBPACK_IMPORTED_MODULE_5__/* .SPINNER_CONFIG */ .ZC.frames[frame],
43043
- " ",
43044
- step)));
43045
- }
43046
- function Menu() {
43047
- const { exit } = (0,ink__WEBPACK_IMPORTED_MODULE_3__/* .useApp */ .nm)();
43048
- const [selectedIndex, setSelectedIndex] = (0,react__WEBPACK_IMPORTED_MODULE_4__.useState)(0);
43049
- const [isProcessing, setIsProcessing] = (0,react__WEBPACK_IMPORTED_MODULE_4__.useState)(false);
43050
- const [processStep, setProcessStep] = (0,react__WEBPACK_IMPORTED_MODULE_4__.useState)("");
43051
- const [processComplete, setProcessComplete] = (0,react__WEBPACK_IMPORTED_MODULE_4__.useState)(false);
43052
- const [processError, setProcessError] = (0,react__WEBPACK_IMPORTED_MODULE_4__.useState)(null);
43053
- const [currentMenu, setCurrentMenu] = (0,react__WEBPACK_IMPORTED_MODULE_4__.useState)("main");
43054
- (0,ink__WEBPACK_IMPORTED_MODULE_3__/* .useInput */ .Ge)((_input, key) => {
43055
- if (isProcessing) {
43056
- return;
43057
- }
43058
- // Exit on any key press when process is complete or errored
43059
- if (processComplete || processError) {
43060
- exit();
43061
- return;
43062
- }
43063
- const items = currentMenu === "main" ? menuItems : configMenuItems;
43064
- if (key.upArrow) {
43065
- setSelectedIndex((prev) => (prev > 0 ? prev - 1 : items.length - 1));
43066
- }
43067
- else if (key.downArrow) {
43068
- setSelectedIndex((prev) => (prev < items.length - 1 ? prev + 1 : 0));
43069
- }
43070
- else if (key.return) {
43071
- handleSelection(items[selectedIndex].value);
43072
- }
43073
- });
43074
- async function handleSelection(value) {
43075
- switch (value) {
43076
- case "shell":
43077
- exit();
43078
- await (0,_utils_launcher_js__WEBPACK_IMPORTED_MODULE_6__/* .launchShell */ .k1)();
43079
- return;
43080
- case "skills":
43081
- exit();
43082
- (0,_skills_js__WEBPACK_IMPORTED_MODULE_8__/* .skillsCommand */ .a)();
43083
- return;
43084
- case "config":
43085
- setCurrentMenu("config");
43086
- setSelectedIndex(0);
43087
- return;
43088
- case "back":
43089
- setCurrentMenu("main");
43090
- setSelectedIndex(0);
43091
- return;
43092
- case "pull":
43093
- await handlePullCommand();
43094
- break;
43095
- case "build":
43096
- await handleBuildCommand();
43097
- break;
43098
- case "nix":
43099
- await handleNixCommand();
43100
- break;
43101
- default:
43102
- break;
43103
- }
43104
- }
43105
- async function handlePullCommand() {
43106
- setIsProcessing(true);
43107
- setProcessStep("Pulling prebuilt Docker image...");
43108
- try {
43109
- await (0,execa__WEBPACK_IMPORTED_MODULE_9__/* .execa */ .Ho)("docker", ["pull", _config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.prebuiltImage], {
43110
- stdio: "inherit",
43111
- });
43112
- // Tag the pulled image with local name for compatibility
43113
- 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], {
43114
- stdio: "inherit",
43115
- });
43116
- setIsProcessing(false);
43117
- setProcessComplete(true);
43118
- setProcessStep("");
43119
- }
43120
- catch (error) {
43121
- setIsProcessing(false);
43122
- setProcessError(error instanceof Error ? error.message : "Pull failed");
43123
- }
43124
- }
43125
- async function handleNixCommand() {
43126
- setIsProcessing(true);
43127
- setProcessStep("Installing Nix locally...");
43128
- try {
43129
- await (0,_nix_js__WEBPACK_IMPORTED_MODULE_7__/* .installNix */ .Fh)();
43130
- await (0,_nix_js__WEBPACK_IMPORTED_MODULE_7__/* .copyNixFiles */ .Qi)();
43131
- setIsProcessing(false);
43132
- setProcessComplete(true);
43133
- setProcessStep("");
43134
- }
43135
- catch (error) {
43136
- setIsProcessing(false);
43137
- setProcessError(error instanceof Error ? error.message : "Nix installation failed");
43138
- }
43139
- }
43140
- async function handleBuildCommand() {
43141
- setIsProcessing(true);
43142
- setProcessStep("Building Docker image from scratch...");
43143
- try {
43144
- const dockerfilePath = node_path__WEBPACK_IMPORTED_MODULE_1___default().join(rootDir, _config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.folderName, _config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.dockerfileName);
43145
- if (!node_fs__WEBPACK_IMPORTED_MODULE_0___default().existsSync(dockerfilePath)) {
43146
- throw new Error(`Dockerfile not found at: ${dockerfilePath}`);
43147
- }
43148
- 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], {
43149
- stdio: "inherit",
43150
- });
43151
- setIsProcessing(false);
43152
- setProcessComplete(true);
43153
- setProcessStep("");
43154
- }
43155
- catch (error) {
43156
- setIsProcessing(false);
43157
- setProcessError(error instanceof Error ? error.message : "Operation failed");
43158
- }
43159
- }
43160
- // Render error state
43161
- if (processError) {
43162
- return (react__WEBPACK_IMPORTED_MODULE_4___default().createElement(ink__WEBPACK_IMPORTED_MODULE_3__/* .Box */ .az, { flexDirection: "column" },
43163
- react__WEBPACK_IMPORTED_MODULE_4___default().createElement(Logo, null),
43164
- react__WEBPACK_IMPORTED_MODULE_4___default().createElement(ink__WEBPACK_IMPORTED_MODULE_3__/* .Box */ .az, { marginTop: 1 },
43165
- react__WEBPACK_IMPORTED_MODULE_4___default().createElement(ink__WEBPACK_IMPORTED_MODULE_3__/* .Text */ .EY, { color: "red" },
43166
- "\u274C Operation failed: ",
43167
- processError)),
43168
- react__WEBPACK_IMPORTED_MODULE_4___default().createElement(ink__WEBPACK_IMPORTED_MODULE_3__/* .Box */ .az, { marginTop: 1 },
43169
- react__WEBPACK_IMPORTED_MODULE_4___default().createElement(ink__WEBPACK_IMPORTED_MODULE_3__/* .Text */ .EY, { dimColor: true }, "Press any key to exit..."))));
43170
- }
43171
- // Render success state
43172
- if (processComplete) {
43173
- return (react__WEBPACK_IMPORTED_MODULE_4___default().createElement(ink__WEBPACK_IMPORTED_MODULE_3__/* .Box */ .az, { flexDirection: "column" },
43174
- react__WEBPACK_IMPORTED_MODULE_4___default().createElement(Logo, null),
43175
- react__WEBPACK_IMPORTED_MODULE_4___default().createElement(ink__WEBPACK_IMPORTED_MODULE_3__/* .Box */ .az, { marginTop: 1 },
43176
- react__WEBPACK_IMPORTED_MODULE_4___default().createElement(ink__WEBPACK_IMPORTED_MODULE_3__/* .Text */ .EY, { color: "green" }, "\u2705 Docker image ready!")),
43177
- react__WEBPACK_IMPORTED_MODULE_4___default().createElement(ink__WEBPACK_IMPORTED_MODULE_3__/* .Box */ .az, { marginTop: 1 },
43178
- react__WEBPACK_IMPORTED_MODULE_4___default().createElement(ink__WEBPACK_IMPORTED_MODULE_3__/* .Text */ .EY, { dimColor: true },
43179
- "Image: ",
43180
- _config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.imageName)),
43181
- react__WEBPACK_IMPORTED_MODULE_4___default().createElement(ink__WEBPACK_IMPORTED_MODULE_3__/* .Box */ .az, { marginTop: 1 },
43182
- react__WEBPACK_IMPORTED_MODULE_4___default().createElement(ink__WEBPACK_IMPORTED_MODULE_3__/* .Text */ .EY, { dimColor: true }, "Run: sith --it")),
43183
- react__WEBPACK_IMPORTED_MODULE_4___default().createElement(ink__WEBPACK_IMPORTED_MODULE_3__/* .Box */ .az, { marginTop: 1 },
43184
- react__WEBPACK_IMPORTED_MODULE_4___default().createElement(ink__WEBPACK_IMPORTED_MODULE_3__/* .Text */ .EY, { dimColor: true }, "Press any key to exit..."))));
43185
- }
43186
- // Render processing state
43187
- if (isProcessing) {
43188
- return (react__WEBPACK_IMPORTED_MODULE_4___default().createElement(ink__WEBPACK_IMPORTED_MODULE_3__/* .Box */ .az, { flexDirection: "column" },
43189
- react__WEBPACK_IMPORTED_MODULE_4___default().createElement(Logo, null),
43190
- react__WEBPACK_IMPORTED_MODULE_4___default().createElement(BuildingSpinner, { step: processStep }),
43191
- react__WEBPACK_IMPORTED_MODULE_4___default().createElement(ink__WEBPACK_IMPORTED_MODULE_3__/* .Box */ .az, { marginTop: 1 },
43192
- react__WEBPACK_IMPORTED_MODULE_4___default().createElement(ink__WEBPACK_IMPORTED_MODULE_3__/* .Text */ .EY, { dimColor: true },
43193
- "Root: ",
43194
- rootDir))));
43195
- }
43196
- // Render menu state
43197
- const items = currentMenu === "main" ? menuItems : configMenuItems;
43198
- const menuTitle = currentMenu === "main" ? "What would you like to do?" : "Configuration";
43199
- return (react__WEBPACK_IMPORTED_MODULE_4___default().createElement(ink__WEBPACK_IMPORTED_MODULE_3__/* .Box */ .az, { flexDirection: "column" },
43200
- react__WEBPACK_IMPORTED_MODULE_4___default().createElement(Logo, null),
43201
- react__WEBPACK_IMPORTED_MODULE_4___default().createElement(ink__WEBPACK_IMPORTED_MODULE_3__/* .Box */ .az, { flexDirection: "column", marginTop: 1 },
43202
- react__WEBPACK_IMPORTED_MODULE_4___default().createElement(ink__WEBPACK_IMPORTED_MODULE_3__/* .Text */ .EY, { bold: true }, menuTitle),
43203
- react__WEBPACK_IMPORTED_MODULE_4___default().createElement(ink__WEBPACK_IMPORTED_MODULE_3__/* .Box */ .az, { flexDirection: "column", marginTop: 1 }, items.map((item, index) => {
43204
- const isSelected = index === selectedIndex;
43205
- return (react__WEBPACK_IMPORTED_MODULE_4___default().createElement(ink__WEBPACK_IMPORTED_MODULE_3__/* .Box */ .az, { key: item.value, marginY: 0 },
43206
- react__WEBPACK_IMPORTED_MODULE_4___default().createElement(ink__WEBPACK_IMPORTED_MODULE_3__/* .Text */ .EY, { color: isSelected ? "cyan" : undefined },
43207
- isSelected ? "❯ " : " ",
43208
- item.icon,
43209
- " ",
43210
- item.label)));
43211
- }))),
43212
- react__WEBPACK_IMPORTED_MODULE_4___default().createElement(ink__WEBPACK_IMPORTED_MODULE_3__/* .Box */ .az, { marginTop: 1 },
43213
- react__WEBPACK_IMPORTED_MODULE_4___default().createElement(ink__WEBPACK_IMPORTED_MODULE_3__/* .Text */ .EY, { dimColor: true }, "Use arrow keys to navigate, Enter to select"))));
43214
- }
43215
42998
  async function dockerCommand(options) {
43216
42999
  if (options.build) {
43217
43000
  await buildDocker();
@@ -43221,36 +43004,25 @@ async function dockerCommand(options) {
43221
43004
  await pullDocker();
43222
43005
  return;
43223
43006
  }
43224
- // Check if stdin supports raw mode (interactive terminal)
43225
- if (!process.stdin.isTTY) {
43226
- console.error("Error: Interactive mode requires a TTY terminal");
43227
- console.error("Use --build or --pull flag for non-interactive mode");
43228
- process.exit(1);
43229
- }
43230
- // Render the interactive menu
43231
- (0,ink__WEBPACK_IMPORTED_MODULE_3__/* .render */ .XX)(react__WEBPACK_IMPORTED_MODULE_4___default().createElement(Menu, null));
43232
- }
43233
- async function runShellDirect() {
43234
- await launchShell();
43235
43007
  }
43236
43008
  async function pullDocker() {
43237
43009
  console.log("📦 Pulling prebuilt Docker image...");
43238
43010
  console.log();
43239
43011
  try {
43240
- console.log(`Source: ${_config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.prebuiltImage}`);
43241
- console.log(`Target: ${_config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.imageName}`);
43012
+ console.log(`Source: ${_config_js__WEBPACK_IMPORTED_MODULE_3__/* .DOCKER_CONFIG */ .e6.prebuiltImage}`);
43013
+ console.log(`Target: ${_config_js__WEBPACK_IMPORTED_MODULE_3__/* .DOCKER_CONFIG */ .e6.imageName}`);
43242
43014
  console.log();
43243
- await (0,execa__WEBPACK_IMPORTED_MODULE_9__/* .execa */ .Ho)("docker", ["pull", _config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.prebuiltImage], {
43015
+ await (0,execa__WEBPACK_IMPORTED_MODULE_4__/* .execa */ .Ho)("docker", ["pull", _config_js__WEBPACK_IMPORTED_MODULE_3__/* .DOCKER_CONFIG */ .e6.prebuiltImage], {
43244
43016
  stdio: "inherit",
43245
43017
  });
43246
43018
  console.log();
43247
43019
  console.log("🏷️ Tagging image for local use...");
43248
- 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], {
43020
+ await (0,execa__WEBPACK_IMPORTED_MODULE_4__/* .execa */ .Ho)("docker", ["tag", _config_js__WEBPACK_IMPORTED_MODULE_3__/* .DOCKER_CONFIG */ .e6.prebuiltImage, _config_js__WEBPACK_IMPORTED_MODULE_3__/* .DOCKER_CONFIG */ .e6.imageName], {
43249
43021
  stdio: "inherit",
43250
43022
  });
43251
43023
  console.log();
43252
43024
  console.log("✅ Docker image ready!");
43253
- console.log(`Image: ${_config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.imageName}`);
43025
+ console.log(`Image: ${_config_js__WEBPACK_IMPORTED_MODULE_3__/* .DOCKER_CONFIG */ .e6.imageName}`);
43254
43026
  console.log();
43255
43027
  console.log("Run: sith --it");
43256
43028
  }
@@ -43266,19 +43038,19 @@ async function buildDocker() {
43266
43038
  console.log("🔨 Building Docker image from scratch...");
43267
43039
  console.log();
43268
43040
  try {
43269
- const dockerfilePath = node_path__WEBPACK_IMPORTED_MODULE_1___default().join(rootDir, _config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.folderName, _config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.dockerfileName);
43041
+ const dockerfilePath = node_path__WEBPACK_IMPORTED_MODULE_1___default().join(rootDir, _config_js__WEBPACK_IMPORTED_MODULE_3__/* .DOCKER_CONFIG */ .e6.folderName, _config_js__WEBPACK_IMPORTED_MODULE_3__/* .DOCKER_CONFIG */ .e6.dockerfileName);
43270
43042
  if (!node_fs__WEBPACK_IMPORTED_MODULE_0___default().existsSync(dockerfilePath)) {
43271
43043
  throw new Error(`Dockerfile not found at: ${dockerfilePath}`);
43272
43044
  }
43273
43045
  console.log(`Root: ${rootDir}`);
43274
43046
  console.log(`Dockerfile: ${dockerfilePath}`);
43275
43047
  console.log();
43276
- 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], {
43048
+ await (0,execa__WEBPACK_IMPORTED_MODULE_4__/* .execa */ .Ho)("docker", ["build", "-f", dockerfilePath, "-t", _config_js__WEBPACK_IMPORTED_MODULE_3__/* .DOCKER_CONFIG */ .e6.imageName, rootDir], {
43277
43049
  stdio: "inherit",
43278
43050
  });
43279
43051
  console.log();
43280
43052
  console.log("✅ Docker image built successfully!");
43281
- console.log(`Image: ${_config_js__WEBPACK_IMPORTED_MODULE_5__/* .DOCKER_CONFIG */ .e6.imageName}`);
43053
+ console.log(`Image: ${_config_js__WEBPACK_IMPORTED_MODULE_3__/* .DOCKER_CONFIG */ .e6.imageName}`);
43282
43054
  console.log();
43283
43055
  console.log("Run: sith --it");
43284
43056
  }
@@ -43291,8 +43063,182 @@ async function buildDocker() {
43291
43063
  }
43292
43064
  }
43293
43065
 
43294
- __webpack_async_result__();
43295
- } catch(e) { __webpack_async_result__(e); } });
43066
+
43067
+ /***/ }),
43068
+
43069
+ /***/ 6656:
43070
+ /***/ ((__unused_webpack_module, __webpack_exports__, __nccwpck_require__) => {
43071
+
43072
+
43073
+ // EXPORTS
43074
+ __nccwpck_require__.d(__webpack_exports__, {
43075
+ Yb: () => (/* binding */ dockerCleanupCommand),
43076
+ V: () => (/* binding */ nixCleanupCommand),
43077
+ be: () => (/* binding */ nixUninstallCommand),
43078
+ m9: () => (/* binding */ nixUpdateCommand),
43079
+ Wd: () => (/* binding */ uninstallCommand)
43080
+ });
43081
+
43082
+ // EXTERNAL MODULE: external "node:child_process"
43083
+ var external_node_child_process_ = __nccwpck_require__(1421);
43084
+ // EXTERNAL MODULE: external "node:fs"
43085
+ var external_node_fs_ = __nccwpck_require__(3024);
43086
+ // EXTERNAL MODULE: external "node:os"
43087
+ var external_node_os_ = __nccwpck_require__(8161);
43088
+ // EXTERNAL MODULE: external "node:path"
43089
+ var external_node_path_ = __nccwpck_require__(6760);
43090
+ ;// CONCATENATED MODULE: external "node:readline"
43091
+ const external_node_readline_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:readline");
43092
+ // EXTERNAL MODULE: ./node_modules/.pnpm/chalk@5.6.2/node_modules/chalk/source/index.js + 3 modules
43093
+ var source = __nccwpck_require__(9611);
43094
+ // EXTERNAL MODULE: ./src/config.ts
43095
+ var config = __nccwpck_require__(6878);
43096
+ ;// CONCATENATED MODULE: ./src/commands/maintenance.ts
43097
+
43098
+
43099
+
43100
+
43101
+
43102
+
43103
+
43104
+ async function maintenance_confirm(question) {
43105
+ const rl = (0,external_node_readline_namespaceObject.createInterface)({ input: process.stdin, output: process.stdout });
43106
+ return new Promise((resolve) => {
43107
+ rl.question(question, (answer) => {
43108
+ rl.close();
43109
+ resolve(answer.toLowerCase() === "y");
43110
+ });
43111
+ });
43112
+ }
43113
+ async function dockerCleanupCommand() {
43114
+ console.log(source/* default */.Ay.cyan("Cleaning up sith Docker images..."));
43115
+ const images = [config/* DOCKER_CONFIG */.e6.imageName, config/* DOCKER_CONFIG */.e6.prebuiltImage];
43116
+ let removed = 0;
43117
+ for (const image of images) {
43118
+ try {
43119
+ (0,external_node_child_process_.execSync)(`docker image inspect ${image} 2>/dev/null`, {
43120
+ stdio: "ignore",
43121
+ });
43122
+ console.log(source/* default */.Ay.dim(` Removing ${image}...`));
43123
+ (0,external_node_child_process_.execSync)(`docker rmi ${image}`, { stdio: "inherit" });
43124
+ removed++;
43125
+ }
43126
+ catch {
43127
+ // image not present
43128
+ }
43129
+ }
43130
+ if (removed === 0) {
43131
+ console.log(source/* default */.Ay.yellow("No sith Docker images found."));
43132
+ }
43133
+ else {
43134
+ console.log(source/* default */.Ay.green(`✓ Removed ${removed} image(s).`));
43135
+ }
43136
+ }
43137
+ async function nixCleanupCommand() {
43138
+ const nixDir = (0,external_node_path_.join)((0,external_node_os_.homedir)(), ".sith", "nix");
43139
+ console.log(source/* default */.Ay.cyan("Cleaning up sith Nix files..."));
43140
+ if ((0,external_node_fs_.existsSync)(nixDir)) {
43141
+ (0,external_node_fs_.rmSync)(nixDir, { recursive: true, force: true });
43142
+ console.log(source/* default */.Ay.green(`✓ Removed ${nixDir}`));
43143
+ }
43144
+ else {
43145
+ console.log(source/* default */.Ay.yellow(`${nixDir} not found — nothing to remove.`));
43146
+ }
43147
+ console.log(source/* default */.Ay.cyan("Running nix-collect-garbage..."));
43148
+ try {
43149
+ (0,external_node_child_process_.execSync)("nix-collect-garbage -d", { stdio: "inherit" });
43150
+ console.log(source/* default */.Ay.green("✓ Nix store garbage collected."));
43151
+ }
43152
+ catch {
43153
+ console.log(source/* default */.Ay.yellow("nix-collect-garbage failed — Nix may not be installed."));
43154
+ }
43155
+ }
43156
+ async function nixUpdateCommand() {
43157
+ console.log(source/* default */.Ay.cyan("Updating Nix channels..."));
43158
+ try {
43159
+ (0,external_node_child_process_.execSync)("nix-channel --update", { stdio: "inherit" });
43160
+ console.log(source/* default */.Ay.green("✓ Channels updated."));
43161
+ }
43162
+ catch {
43163
+ console.log(source/* default */.Ay.yellow("nix-channel failed — Nix may not be installed."));
43164
+ return;
43165
+ }
43166
+ console.log(source/* default */.Ay.cyan("Upgrading Nix packages..."));
43167
+ try {
43168
+ (0,external_node_child_process_.execSync)("nix-env -u '*'", { stdio: "inherit" });
43169
+ console.log(source/* default */.Ay.green("✓ Packages upgraded."));
43170
+ }
43171
+ catch {
43172
+ console.log(source/* default */.Ay.yellow("nix-env upgrade failed — no user packages or error above."));
43173
+ }
43174
+ }
43175
+ async function nixUninstallCommand() {
43176
+ console.log(source/* default */.Ay.yellow("This will fully remove Nix from your system:"));
43177
+ console.log(source/* default */.Ay.dim(" /nix/store, Nix daemon, shell profile entries"));
43178
+ console.log();
43179
+ const ok = await maintenance_confirm(source/* default */.Ay.red("Continue? [y/N] "));
43180
+ if (!ok) {
43181
+ console.log(source/* default */.Ay.dim("Aborted."));
43182
+ return;
43183
+ }
43184
+ const platform = process.platform;
43185
+ if (platform === "darwin") {
43186
+ console.log(source/* default */.Ay.cyan("Uninstalling Nix (macOS multi-user)..."));
43187
+ try {
43188
+ // Official macOS uninstall sequence
43189
+ (0,external_node_child_process_.execSync)("sudo launchctl unload /Library/LaunchDaemons/org.nixos.nix-daemon.plist 2>/dev/null || true", { stdio: "inherit" });
43190
+ (0,external_node_child_process_.execSync)("sudo rm -f /Library/LaunchDaemons/org.nixos.nix-daemon.plist", {
43191
+ stdio: "inherit",
43192
+ });
43193
+ (0,external_node_child_process_.execSync)("sudo diskutil apfs deleteVolume /nix 2>/dev/null || sudo rm -rf /nix", { stdio: "inherit" });
43194
+ (0,external_node_child_process_.execSync)("sudo rm -rf /etc/nix /etc/profile.d/nix.sh /etc/bashrc.d/nix.sh", { stdio: "inherit" });
43195
+ console.log(source/* default */.Ay.green("✓ Nix removed. Remove nix lines from ~/.zshrc / ~/.bashrc manually if present."));
43196
+ }
43197
+ catch (_e) {
43198
+ console.log(source/* default */.Ay.red("Uninstall failed. Run with sudo or check errors above."));
43199
+ }
43200
+ }
43201
+ else if (platform === "linux") {
43202
+ console.log(source/* default */.Ay.cyan("Uninstalling Nix (Linux)..."));
43203
+ try {
43204
+ (0,external_node_child_process_.execSync)("sudo systemctl stop nix-daemon 2>/dev/null || true", {
43205
+ stdio: "inherit",
43206
+ });
43207
+ (0,external_node_child_process_.execSync)("sudo systemctl disable nix-daemon 2>/dev/null || true", {
43208
+ stdio: "inherit",
43209
+ });
43210
+ (0,external_node_child_process_.execSync)("sudo rm -rf /nix /etc/nix", { stdio: "inherit" });
43211
+ console.log(source/* default */.Ay.green("✓ Nix removed. Remove nix lines from ~/.profile / ~/.bashrc manually if present."));
43212
+ }
43213
+ catch {
43214
+ console.log(source/* default */.Ay.red("Uninstall failed. Run with sudo or check errors above."));
43215
+ }
43216
+ }
43217
+ else {
43218
+ console.log(source/* default */.Ay.red(`Unsupported platform: ${platform}. Uninstall manually.`));
43219
+ }
43220
+ }
43221
+ async function uninstallCommand() {
43222
+ const sithDir = (0,external_node_path_.join)((0,external_node_os_.homedir)(), ".sith");
43223
+ console.log(source/* default */.Ay.yellow("This will delete:"));
43224
+ console.log(source/* default */.Ay.dim(` ${sithDir} (skills, config, nix files)`));
43225
+ console.log();
43226
+ const ok = await maintenance_confirm(source/* default */.Ay.red("Continue? [y/N] "));
43227
+ if (!ok) {
43228
+ console.log(source/* default */.Ay.dim("Aborted."));
43229
+ return;
43230
+ }
43231
+ if ((0,external_node_fs_.existsSync)(sithDir)) {
43232
+ (0,external_node_fs_.rmSync)(sithDir, { recursive: true, force: true });
43233
+ console.log(source/* default */.Ay.green(`✓ Removed ${sithDir}`));
43234
+ }
43235
+ else {
43236
+ console.log(source/* default */.Ay.yellow(`${sithDir} not found — nothing to remove.`));
43237
+ }
43238
+ console.log();
43239
+ console.log(source/* default */.Ay.dim(`Run ${source/* default */.Ay.bold("npm uninstall -g sith")} to remove the CLI.`));
43240
+ }
43241
+
43296
43242
 
43297
43243
  /***/ }),
43298
43244
 
@@ -43301,11 +43247,9 @@ __webpack_async_result__();
43301
43247
 
43302
43248
  /* harmony export */ __nccwpck_require__.d(__webpack_exports__, {
43303
43249
  /* harmony export */ Dv: () => (/* binding */ nixCommand),
43304
- /* harmony export */ Fh: () => (/* binding */ installNix),
43305
- /* harmony export */ Qi: () => (/* binding */ copyNixFiles),
43306
43250
  /* harmony export */ nb: () => (/* binding */ runNixShell)
43307
43251
  /* harmony export */ });
43308
- /* unused harmony exports parseNixVersionOutput, checkNixInstalled */
43252
+ /* unused harmony exports parseNixVersionOutput, checkNixInstalled, installNix, copyNixFiles */
43309
43253
  /* harmony import */ var node_fs__WEBPACK_IMPORTED_MODULE_0__ = __nccwpck_require__(3024);
43310
43254
  /* harmony import */ var node_fs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__nccwpck_require__.n(node_fs__WEBPACK_IMPORTED_MODULE_0__);
43311
43255
  /* harmony import */ var node_os__WEBPACK_IMPORTED_MODULE_1__ = __nccwpck_require__(8161);
@@ -43427,13 +43371,11 @@ async function runNixShell() {
43427
43371
  console.error("Run: sith --nix-install");
43428
43372
  process.exit(1);
43429
43373
  }
43430
- // Copy files if not already present
43374
+ // Always copy to pick up source changes
43431
43375
  const homeDir = node_os__WEBPACK_IMPORTED_MODULE_1___default().homedir();
43432
43376
  const localConfigDir = node_path__WEBPACK_IMPORTED_MODULE_2___default().join(homeDir, _config_js__WEBPACK_IMPORTED_MODULE_4__/* .NIX_CONFIG */ .Z3.localConfigDir);
43433
43377
  const shellNixPath = node_path__WEBPACK_IMPORTED_MODULE_2___default().join(localConfigDir, "shell.nix");
43434
- if (!node_fs__WEBPACK_IMPORTED_MODULE_0___default().existsSync(shellNixPath)) {
43435
- await copyNixFiles();
43436
- }
43378
+ await copyNixFiles();
43437
43379
  console.log("🚀 Starting Nix shell...");
43438
43380
  console.log(`Configuration: ${shellNixPath}`);
43439
43381
  console.log('Press Ctrl+D or type "exit" to leave');
@@ -43455,7 +43397,15 @@ async function runNixShell() {
43455
43397
  }
43456
43398
  // Run nix-shell
43457
43399
  try {
43458
- await (0,execa__WEBPACK_IMPORTED_MODULE_5__/* .execa */ .Ho)("nix-shell", [shellNixPath], {
43400
+ await (0,execa__WEBPACK_IMPORTED_MODULE_5__/* .execa */ .Ho)("nix-shell", [
43401
+ "--option",
43402
+ "substituters",
43403
+ "https://cache.nixos.org",
43404
+ "--option",
43405
+ "trusted-public-keys",
43406
+ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=",
43407
+ shellNixPath,
43408
+ ], {
43459
43409
  stdio: "inherit",
43460
43410
  env,
43461
43411
  cwd: process.cwd(),
@@ -44018,10 +43968,10 @@ __webpack_async_result__();
44018
43968
  /* harmony export */ __nccwpck_require__.d(__webpack_exports__, {
44019
43969
  /* harmony export */ XI: () => (/* binding */ SKILLS_CATALOG),
44020
43970
  /* harmony export */ Z3: () => (/* binding */ NIX_CONFIG),
44021
- /* harmony export */ ZC: () => (/* binding */ SPINNER_CONFIG),
44022
43971
  /* harmony export */ e6: () => (/* binding */ DOCKER_CONFIG),
44023
43972
  /* harmony export */ mF: () => (/* binding */ ASCII_LOGO)
44024
43973
  /* harmony export */ });
43974
+ /* unused harmony export SPINNER_CONFIG */
44025
43975
  // Predefined skill catalog — skills are installed to ~/.sith/skills/<name>/
44026
43976
  const SKILLS_CATALOG = [
44027
43977
  {
@@ -44119,16 +44069,18 @@ __nccwpck_require__.a(module, async (__webpack_handle_async_dependencies__, __we
44119
44069
  /* harmony import */ var node_path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__nccwpck_require__.n(node_path__WEBPACK_IMPORTED_MODULE_1__);
44120
44070
  /* harmony import */ var node_url__WEBPACK_IMPORTED_MODULE_2__ = __nccwpck_require__(3136);
44121
44071
  /* harmony import */ var node_url__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__nccwpck_require__.n(node_url__WEBPACK_IMPORTED_MODULE_2__);
44122
- /* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_10__ = __nccwpck_require__(9611);
44072
+ /* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_11__ = __nccwpck_require__(9611);
44123
44073
  /* harmony import */ var commander__WEBPACK_IMPORTED_MODULE_3__ = __nccwpck_require__(2202);
44124
- /* harmony import */ var update_notifier__WEBPACK_IMPORTED_MODULE_9__ = __nccwpck_require__(6213);
44125
- /* harmony import */ var _commands_docker_js__WEBPACK_IMPORTED_MODULE_4__ = __nccwpck_require__(5515);
44126
- /* harmony import */ var _commands_nix_js__WEBPACK_IMPORTED_MODULE_5__ = __nccwpck_require__(9922);
44127
- /* harmony import */ var _commands_skills_js__WEBPACK_IMPORTED_MODULE_6__ = __nccwpck_require__(9805);
44128
- /* harmony import */ var _components_TerminalUI_js__WEBPACK_IMPORTED_MODULE_7__ = __nccwpck_require__(3535);
44129
- /* harmony import */ var _utils_launcher_js__WEBPACK_IMPORTED_MODULE_8__ = __nccwpck_require__(5800);
44130
- var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([_commands_docker_js__WEBPACK_IMPORTED_MODULE_4__, _commands_skills_js__WEBPACK_IMPORTED_MODULE_6__, _components_TerminalUI_js__WEBPACK_IMPORTED_MODULE_7__]);
44131
- ([_commands_docker_js__WEBPACK_IMPORTED_MODULE_4__, _commands_skills_js__WEBPACK_IMPORTED_MODULE_6__, _components_TerminalUI_js__WEBPACK_IMPORTED_MODULE_7__] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__);
44074
+ /* harmony import */ var update_notifier__WEBPACK_IMPORTED_MODULE_10__ = __nccwpck_require__(6213);
44075
+ /* harmony import */ var _commands_docker_js__WEBPACK_IMPORTED_MODULE_4__ = __nccwpck_require__(3361);
44076
+ /* harmony import */ var _commands_maintenance_js__WEBPACK_IMPORTED_MODULE_5__ = __nccwpck_require__(6656);
44077
+ /* harmony import */ var _commands_nix_js__WEBPACK_IMPORTED_MODULE_6__ = __nccwpck_require__(9922);
44078
+ /* harmony import */ var _commands_skills_js__WEBPACK_IMPORTED_MODULE_7__ = __nccwpck_require__(9805);
44079
+ /* harmony import */ var _components_TerminalUI_js__WEBPACK_IMPORTED_MODULE_8__ = __nccwpck_require__(3535);
44080
+ /* harmony import */ var _utils_launcher_js__WEBPACK_IMPORTED_MODULE_9__ = __nccwpck_require__(5800);
44081
+ var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([_commands_skills_js__WEBPACK_IMPORTED_MODULE_7__, _components_TerminalUI_js__WEBPACK_IMPORTED_MODULE_8__]);
44082
+ ([_commands_skills_js__WEBPACK_IMPORTED_MODULE_7__, _components_TerminalUI_js__WEBPACK_IMPORTED_MODULE_8__] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__);
44083
+
44132
44084
 
44133
44085
 
44134
44086
 
@@ -44148,12 +44100,12 @@ const PROGRAM_NAME = "sith";
44148
44100
  const PROGRAM_VERSION = pkg.version;
44149
44101
  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.";
44150
44102
  // Check for updates (automatic background check)
44151
- const notifier = (0,update_notifier__WEBPACK_IMPORTED_MODULE_9__/* ["default"] */ .A)({ pkg });
44103
+ const notifier = (0,update_notifier__WEBPACK_IMPORTED_MODULE_10__/* ["default"] */ .A)({ pkg });
44152
44104
  notifier.notify();
44153
44105
  async function checkForUpdates() {
44154
- console.log(chalk__WEBPACK_IMPORTED_MODULE_10__/* ["default"] */ .Ay.cyan("Checking for updates..."));
44106
+ console.log(chalk__WEBPACK_IMPORTED_MODULE_11__/* ["default"] */ .Ay.cyan("Checking for updates..."));
44155
44107
  // Force update check by setting updateCheckInterval to 0
44156
- const notifier = (0,update_notifier__WEBPACK_IMPORTED_MODULE_9__/* ["default"] */ .A)({
44108
+ const notifier = (0,update_notifier__WEBPACK_IMPORTED_MODULE_10__/* ["default"] */ .A)({
44157
44109
  pkg,
44158
44110
  updateCheckInterval: 0,
44159
44111
  });
@@ -44162,12 +44114,12 @@ async function checkForUpdates() {
44162
44114
  const update = notifier.update;
44163
44115
  if (update && update.latest !== pkg.version) {
44164
44116
  console.log();
44165
- console.log(chalk__WEBPACK_IMPORTED_MODULE_10__/* ["default"] */ .Ay.green(`Update available: ${chalk__WEBPACK_IMPORTED_MODULE_10__/* ["default"] */ .Ay.dim(pkg.version)} → ${chalk__WEBPACK_IMPORTED_MODULE_10__/* ["default"] */ .Ay.bold(update.latest)}`));
44166
- console.log(chalk__WEBPACK_IMPORTED_MODULE_10__/* ["default"] */ .Ay.cyan(`Run ${chalk__WEBPACK_IMPORTED_MODULE_10__/* ["default"] */ .Ay.bold(`npm install -g ${pkg.name}`)} to update`));
44117
+ console.log(chalk__WEBPACK_IMPORTED_MODULE_11__/* ["default"] */ .Ay.green(`Update available: ${chalk__WEBPACK_IMPORTED_MODULE_11__/* ["default"] */ .Ay.dim(pkg.version)} → ${chalk__WEBPACK_IMPORTED_MODULE_11__/* ["default"] */ .Ay.bold(update.latest)}`));
44118
+ console.log(chalk__WEBPACK_IMPORTED_MODULE_11__/* ["default"] */ .Ay.cyan(`Run ${chalk__WEBPACK_IMPORTED_MODULE_11__/* ["default"] */ .Ay.bold(`npm install -g ${pkg.name}`)} to update`));
44167
44119
  console.log();
44168
44120
  }
44169
44121
  else {
44170
- console.log(chalk__WEBPACK_IMPORTED_MODULE_10__/* ["default"] */ .Ay.green(`✓ You're on the latest version (${pkg.version})`));
44122
+ console.log(chalk__WEBPACK_IMPORTED_MODULE_11__/* ["default"] */ .Ay.green(`✓ You're on the latest version (${pkg.version})`));
44171
44123
  }
44172
44124
  }
44173
44125
  function createProgram() {
@@ -44182,52 +44134,61 @@ function createProgram() {
44182
44134
  .option("--nix", "Use native Nix shell (no Docker)")
44183
44135
  .option("--nix-install", "Install Nix package manager locally")
44184
44136
  .option("--update", "Check for updates")
44185
- .option("--legacy", "Use legacy menu interface");
44186
- // Default action - show terminal UI or legacy menu
44137
+ .option("--docker-cleanup", "Remove sith Docker images from local machine")
44138
+ .option("--nix-cleanup", "Remove ~/.sith/nix and run nix-collect-garbage")
44139
+ .option("--nix-update", "Update Nix channels and upgrade installed packages")
44140
+ .option("--nix-uninstall", "Fully remove Nix from the system (daemon, /nix/store)")
44141
+ .option("--uninstall", "Remove ~/.sith config directory");
44142
+ // Default action - show terminal UI
44187
44143
  program.action(async (options) => {
44188
- if (options.update) {
44144
+ if (options.dockerCleanup) {
44145
+ await (0,_commands_maintenance_js__WEBPACK_IMPORTED_MODULE_5__/* .dockerCleanupCommand */ .Yb)();
44146
+ }
44147
+ else if (options.nixCleanup) {
44148
+ await (0,_commands_maintenance_js__WEBPACK_IMPORTED_MODULE_5__/* .nixCleanupCommand */ .V)();
44149
+ }
44150
+ else if (options.nixUpdate) {
44151
+ await (0,_commands_maintenance_js__WEBPACK_IMPORTED_MODULE_5__/* .nixUpdateCommand */ .m9)();
44152
+ }
44153
+ else if (options.nixUninstall) {
44154
+ await (0,_commands_maintenance_js__WEBPACK_IMPORTED_MODULE_5__/* .nixUninstallCommand */ .be)();
44155
+ }
44156
+ else if (options.uninstall) {
44157
+ await (0,_commands_maintenance_js__WEBPACK_IMPORTED_MODULE_5__/* .uninstallCommand */ .Wd)();
44158
+ }
44159
+ else if (options.update) {
44189
44160
  await checkForUpdates();
44190
44161
  }
44191
44162
  else if (options.nix) {
44192
- await (0,_commands_nix_js__WEBPACK_IMPORTED_MODULE_5__/* .runNixShell */ .nb)();
44163
+ await (0,_commands_nix_js__WEBPACK_IMPORTED_MODULE_6__/* .runNixShell */ .nb)();
44193
44164
  }
44194
44165
  else if (options.nixInstall) {
44195
- await (0,_commands_nix_js__WEBPACK_IMPORTED_MODULE_5__/* .nixCommand */ .Dv)({ install: true });
44166
+ await (0,_commands_nix_js__WEBPACK_IMPORTED_MODULE_6__/* .nixCommand */ .Dv)({ install: true });
44196
44167
  }
44197
44168
  else if (options.it) {
44198
- await (0,_utils_launcher_js__WEBPACK_IMPORTED_MODULE_8__/* .launchShell */ .k1)();
44169
+ await (0,_utils_launcher_js__WEBPACK_IMPORTED_MODULE_9__/* .launchShell */ .k1)();
44199
44170
  }
44200
- else if (options.legacy || options.pull || options.build) {
44201
- // Use legacy menu for explicit pull/build or --legacy flag
44171
+ else if (options.pull || options.build) {
44202
44172
  await (0,_commands_docker_js__WEBPACK_IMPORTED_MODULE_4__/* .dockerCommand */ .Q)(options);
44203
44173
  }
44204
44174
  else {
44205
44175
  // Default: show new terminal UI
44206
- (0,_components_TerminalUI_js__WEBPACK_IMPORTED_MODULE_7__/* .renderTerminalUI */ .t)();
44176
+ (0,_components_TerminalUI_js__WEBPACK_IMPORTED_MODULE_8__/* .renderTerminalUI */ .t)();
44207
44177
  }
44208
44178
  });
44209
- // Docker command - explicit Docker management
44210
- program
44211
- .command("docker")
44212
- .description("Manage Docker environment")
44213
- .option("--pull", "Pull prebuilt Docker image (recommended)")
44214
- .option("--build", "Build the Docker image from scratch")
44215
- .action(async (options) => {
44216
- await (0,_commands_docker_js__WEBPACK_IMPORTED_MODULE_4__/* .dockerCommand */ .Q)(options);
44217
- });
44218
44179
  // Shell command - direct interactive shell (bypasses menu)
44219
44180
  program
44220
44181
  .command("shell")
44221
44182
  .description("Run interactive shell in Docker container")
44222
44183
  .action(async () => {
44223
- await (0,_utils_launcher_js__WEBPACK_IMPORTED_MODULE_8__/* .launchShell */ .k1)();
44184
+ await (0,_utils_launcher_js__WEBPACK_IMPORTED_MODULE_9__/* .launchShell */ .k1)();
44224
44185
  });
44225
44186
  // Skills command - install/uninstall skills from catalog
44226
44187
  program
44227
44188
  .command("skills")
44228
44189
  .description("Manage skills (~/.sith/skills/)")
44229
44190
  .action(() => {
44230
- (0,_commands_skills_js__WEBPACK_IMPORTED_MODULE_6__/* .skillsCommand */ .a)();
44191
+ (0,_commands_skills_js__WEBPACK_IMPORTED_MODULE_7__/* .skillsCommand */ .a)();
44231
44192
  });
44232
44193
  // Nix command - native Nix environment
44233
44194
  program
@@ -44236,7 +44197,7 @@ function createProgram() {
44236
44197
  .option("--install", "Install Nix package manager")
44237
44198
  .option("--shell", "Run Nix shell")
44238
44199
  .action(async (options) => {
44239
- await (0,_commands_nix_js__WEBPACK_IMPORTED_MODULE_5__/* .nixCommand */ .Dv)(options);
44200
+ await (0,_commands_nix_js__WEBPACK_IMPORTED_MODULE_6__/* .nixCommand */ .Dv)(options);
44240
44201
  });
44241
44202
  // OpenCode command - launch OpenCode in Docker
44242
44203
  program
@@ -44244,7 +44205,7 @@ function createProgram() {
44244
44205
  .description("Launch OpenCode in Docker")
44245
44206
  .option("-p, --prompt <prompt>", "Prompt to pass to OpenCode")
44246
44207
  .action(async (options) => {
44247
- await (0,_utils_launcher_js__WEBPACK_IMPORTED_MODULE_8__/* .launchOpencode */ .Tg)(options.prompt);
44208
+ await (0,_utils_launcher_js__WEBPACK_IMPORTED_MODULE_9__/* .launchOpencode */ .Tg)(options.prompt);
44248
44209
  });
44249
44210
  // Claude command - launch Claude Code in Docker
44250
44211
  program
@@ -44252,7 +44213,7 @@ function createProgram() {
44252
44213
  .description("Launch Claude Code in Docker")
44253
44214
  .option("-p, --prompt <prompt>", "Prompt to pass to Claude Code")
44254
44215
  .action(async (options) => {
44255
- await (0,_utils_launcher_js__WEBPACK_IMPORTED_MODULE_8__/* .launchClaude */ .Q7)(options.prompt);
44216
+ await (0,_utils_launcher_js__WEBPACK_IMPORTED_MODULE_9__/* .launchClaude */ .Q7)(options.prompt);
44256
44217
  });
44257
44218
  return program;
44258
44219
  }
@@ -15,14 +15,15 @@
15
15
  let
16
16
  # Load packages from external configuration
17
17
  packages = import ./nix-config/packages.nix { inherit pkgs; lib = pkgs.lib; };
18
+ isLinux = pkgs.stdenv.isLinux;
18
19
  in
19
20
 
20
21
  pkgs.mkShell {
21
22
  name = "sith-environment";
22
-
23
+
23
24
  # Packages loaded from nix-config/packages.json
24
25
  buildInputs = packages;
25
-
26
+
26
27
  # Variables d'environnement
27
28
  shellHook = ''
28
29
  # Source external setup script (not bash, so exports persist)
@@ -34,9 +35,9 @@ pkgs.mkShell {
34
35
  # setup.sh sets -e for safety; unset for interactive session
35
36
  set +e
36
37
  '';
37
-
38
+
38
39
  # Variables d'environnement persistantes
39
- LOCALE_ARCHIVE = "${pkgs.glibcLocales}/lib/locale/locale-archive";
40
+ LOCALE_ARCHIVE = pkgs.lib.optionalString isLinux "${pkgs.glibcLocales}/lib/locale/locale-archive";
40
41
  LANG = "en_US.UTF-8";
41
42
  LC_ALL = "en_US.UTF-8";
42
43
  LC_CTYPE = "en_US.UTF-8";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@m14i/sith",
3
- "version": "1.22.0",
3
+ "version": "1.23.1",
4
4
  "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.",
5
5
  "type": "module",
6
6
  "repository": {