@dmsdc-ai/aigentry-devkit 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 dmsdc-ai
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,500 @@
1
+ # aigentry-devkit
2
+
3
+ **Your AI development environment, packaged.**
4
+
5
+ A comprehensive development kit that bundles skills, hooks, MCP servers, HUD/statusline, and configuration templates for Claude Code, Codex CLI, and other MCP-compatible CLIs. Install once, use everywhere.
6
+
7
+ ## Features
8
+
9
+ ### Skills (Reusable AI Capabilities)
10
+
11
+ Five production-ready skills that extend Claude Code, Codex CLI, and other MCP-compatible CLIs:
12
+
13
+ - **Clipboard Image Viewer** - Capture and analyze clipboard images directly from your terminal
14
+ - **AI Deliberation** - Multi-session parallel debates across arbitrary CLI participants with structured turn-taking and synthesis
15
+ - **Deliberation Executor** - Convert deliberation synthesis into concrete implementation tasks and execute them
16
+ - **Environment Manager** - direnv-based hierarchical environment variable management with global and project-scoped variables
17
+ - **YouTube Analyzer** - Extract and analyze YouTube video metadata, captions, and transcripts without downloading
18
+
19
+ ### MCP Deliberation Server
20
+
21
+ A dedicated MCP (Model Context Protocol) server enabling multi-session AI debates with:
22
+
23
+ - Parallel deliberation sessions with independent state management
24
+ - Structured response formats (evaluation, core position, reasoning, risks, synthesis)
25
+ - Automatic session monitoring with optional tmux integration
26
+ - State persistence and session history archiving
27
+
28
+ ### HUD/Statusline
29
+
30
+ Custom statusline display for Claude Code that shows real-time context from stdin, with support for extended context windows (up to 1M tokens on Claude Opus).
31
+
32
+ ### Hooks
33
+
34
+ Session-start bootstrap hooks that automatically load skill indices and prepare your environment when Claude Code starts.
35
+
36
+ ### Configuration Templates
37
+
38
+ Pre-configured settings with template substitution:
39
+
40
+ - `settings.json.template` - Claude Code settings with `{{HOME}}` substitution
41
+ - `global.envrc` - direnv configuration for hierarchical environment management
42
+ - `CLAUDE.md` - AI agent instructions (oh-my-claudecode compatible)
43
+
44
+ ## Installation
45
+
46
+ ### Prerequisites
47
+
48
+ - Node.js 18+
49
+ - npm (included with Node.js)
50
+ - Optional: Claude Code CLI (`npm install -g @anthropic-ai/claude-code`)
51
+ - Optional: tmux (for deliberation monitoring)
52
+ - Optional: direnv (for environment management)
53
+
54
+ ### Quick Start
55
+
56
+ All OS (recommended):
57
+
58
+ ```bash
59
+ npx -y @dmsdc-ai/aigentry-devkit install
60
+ ```
61
+
62
+ Force reinstall:
63
+
64
+ ```bash
65
+ npx -y @dmsdc-ai/aigentry-devkit install --force
66
+ ```
67
+
68
+ Manual install (local clone) is still available:
69
+
70
+ macOS / Linux:
71
+
72
+ ```bash
73
+ git clone https://github.com/dmsdc-ai/aigentry-devkit.git
74
+ cd aigentry-devkit
75
+ bash install.sh
76
+ ```
77
+
78
+ Windows (PowerShell):
79
+
80
+ ```powershell
81
+ git clone https://github.com/dmsdc-ai/aigentry-devkit.git
82
+ cd aigentry-devkit
83
+ powershell -ExecutionPolicy Bypass -File .\install.ps1
84
+ ```
85
+
86
+ The installer will:
87
+
88
+ 1. Verify Node.js and optional dependencies (Claude Code CLI, tmux, direnv)
89
+ 2. Link skills to `~/.claude/skills/`
90
+ 3. Install HUD statusline to `~/.claude/hud/`
91
+ 4. Set up MCP Deliberation Server at `~/.local/lib/mcp-deliberation/`
92
+ 5. Register MCP server in `~/.claude/.mcp.json`
93
+ 6. Create configuration templates from templates
94
+ 7. Attempt Codex CLI integration (if available)
95
+ 8. Print cross-platform browser scan/fallback notes
96
+
97
+ ### Post-Installation
98
+
99
+ After installation, restart Claude/Codex for changes to take effect:
100
+
101
+ ```bash
102
+ # Restart your CLI process to load new MCP settings
103
+ ```
104
+
105
+ To verify installation:
106
+
107
+ ```bash
108
+ ls -la ~/.claude/skills/ # Check skills are linked
109
+ ls -la ~/.claude/hud/ # Check HUD is installed
110
+ ls -la ~/.local/lib/mcp-deliberation/ # Check MCP server
111
+ cat ~/.claude/.mcp.json # Verify MCP registration
112
+ ```
113
+
114
+ ## Usage
115
+
116
+ ### Skills
117
+
118
+ Skills are automatically available in Claude Code, Codex CLI, and compatible MCP clients. They activate based on keywords:
119
+
120
+ #### Clipboard Image
121
+ Triggers: "clipboard", "paste image", "캡처 확인"
122
+
123
+ View and analyze images from your clipboard:
124
+ ```
125
+ "Analyze this screenshot: [image in clipboard]"
126
+ "What's on my clipboard?"
127
+ ```
128
+
129
+ #### AI Deliberation
130
+ Triggers: "deliberation", "토론", "debate", "deliberate"
131
+
132
+ Start a multi-perspective debate:
133
+ ```
134
+ "deliberation: Should we use microservices or monolith?"
135
+ "토론 시작: API 설계 전략"
136
+ ```
137
+
138
+ Multiple sessions run in parallel. Use `deliberation_start` to get a session ID, then reference it in subsequent calls.
139
+
140
+ #### Deliberation Executor
141
+ Triggers: "합의안 구현", "토론 결과 구현", "deliberation 구현", "synthesis 구현", "executor"
142
+
143
+ Execute implementation from synthesis:
144
+ ```
145
+ "session_id abc123 합의안 구현해줘"
146
+ "토론 결과를 코드로 반영하고 테스트까지 진행해줘"
147
+ ```
148
+
149
+ Use this after `deliberation_synthesize` when you want implementation, not just discussion.
150
+
151
+ #### Environment Manager
152
+ Triggers: "env", "환경변수", "environment", ".env", "direnv"
153
+
154
+ Manage environment variables hierarchically:
155
+ ```
156
+ "env check" - Audit environment setup
157
+ "env init /path/to/project" - Initialize new project
158
+ "env add API_KEY value" - Add global or project variable
159
+ ```
160
+
161
+ #### YouTube Analyzer
162
+ Triggers: "youtube", "유튜브", "영상 분석", "video analysis"
163
+
164
+ Extract and analyze YouTube content:
165
+ ```
166
+ "Analyze this video: https://youtube.com/watch?v=xxx"
167
+ "유튜브 영상 요약: https://youtu.be/xxx"
168
+ ```
169
+
170
+ ### MCP Deliberation Server
171
+
172
+ The deliberation server provides these tools:
173
+
174
+ | Tool | Purpose |
175
+ |------|---------|
176
+ | `deliberation_speaker_candidates` | List selectable speakers from local CLIs and open browser LLM tabs |
177
+ | `deliberation_start` | Start new debate session with user-selected speakers, returns session_id (`participant_types` override supported) |
178
+ | `deliberation_route_turn` | Resolve current speaker transport and next action (`cli_respond` / `clipboard` / `browser_auto`) |
179
+ | `deliberation_browser_auto_turn` | Send turn to browser LLM automatically via CDP and collect response |
180
+ | `deliberation_respond` | Submit turn response |
181
+ | `deliberation_browser_llm_tabs` | Inspect open browser LLM tabs |
182
+ | `deliberation_clipboard_prepare_turn` | Copy current-turn prompt for browser LLM |
183
+ | `deliberation_clipboard_submit_turn` | Submit clipboard/browser response as a turn |
184
+ | `deliberation_context` | Load project context |
185
+ | `deliberation_list_active` | List active sessions |
186
+ | `deliberation_status` | Check session status |
187
+ | `deliberation_synthesize` | Generate synthesis report |
188
+ | `deliberation_history` | View full debate transcript |
189
+ | `deliberation_list` | Browse past sessions |
190
+ | `deliberation_reset` | Clear sessions |
191
+
192
+ Example workflow:
193
+
194
+ ```bash
195
+ # Start any CLI with MCP deliberation enabled
196
+ <your-cli>
197
+
198
+ # In CLI A:
199
+ # > "deliberation: API design - REST vs GraphQL?"
200
+ # 1) Find selectable participants (CLI + browser LLM tabs)
201
+ # deliberation_speaker_candidates()
202
+ # 2) Start with manually selected speakers
203
+ # deliberation_start(topic="...", speakers=["codex","web-claude-1","web-chatgpt-1"], first_speaker="codex")
204
+ # optional: force transport profile per speaker
205
+ # deliberation_start(topic="...", speakers=["codex","chatgpt"], participant_types={"chatgpt":"browser_auto"})
206
+ # 3) Route the current turn
207
+ # deliberation_route_turn session_id=sess_12345
208
+ # Submit turns with deliberate speakers:
209
+ # deliberation_respond session_id=sess_12345 speaker=codex
210
+ # Browser turn flow:
211
+ # deliberation_clipboard_prepare_turn session_id=sess_12345 speaker=web-claude-1
212
+ # (paste into browser LLM, copy response)
213
+ # deliberation_clipboard_submit_turn session_id=sess_12345 speaker=web-claude-1
214
+ # Browser auto flow (CDP):
215
+ # deliberation_browser_auto_turn session_id=sess_12345 provider=chatgpt
216
+ # After rounds complete:
217
+ # deliberation_synthesize session_id=sess_12345
218
+ ```
219
+
220
+ ### HUD Statusline
221
+
222
+ The simple-status.sh script displays context in your shell prompt. Configure in `~/.claude/settings.json`:
223
+
224
+ ```json
225
+ {
226
+ "hud": {
227
+ "enabled": true,
228
+ "script": "~/.claude/hud/simple-status.sh",
229
+ "contextWindow": 1000000
230
+ }
231
+ }
232
+ ```
233
+
234
+ ## Project Structure
235
+
236
+ ```
237
+ aigentry-devkit/
238
+ ├── bin/ # npx entrypoint
239
+ │ └── aigentry-devkit.js
240
+ ├── .claude-plugin/ # Claude Code plugin manifests
241
+ │ ├── plugin.json # Plugin metadata
242
+ │ └── marketplace.json # Marketplace listing
243
+ ├── config/ # Configuration templates
244
+ │ ├── CLAUDE.md # AI agent instructions
245
+ │ ├── settings.json.template
246
+ │ └── envrc/global.envrc
247
+ ├── hooks/ # Session lifecycle hooks
248
+ │ ├── hooks.json # Hook definitions
249
+ │ └── session-start # Bootstrap script
250
+ ├── hud/ # Statusline/HUD
251
+ │ └── simple-status.sh
252
+ ├── mcp-servers/ # Model Context Protocol servers
253
+ │ └── deliberation/ # AI deliberation server
254
+ │ ├── index.js # Main server implementation
255
+ │ ├── package.json
256
+ │ └── session-monitor.sh
257
+ ├── skills/ # Reusable AI skills
258
+ │ ├── clipboard-image/ # Image clipboard capture
259
+ │ ├── deliberation/ # Debate management
260
+ │ ├── deliberation-executor/ # Synthesis-to-implementation execution
261
+ │ ├── env-manager/ # Environment variables
262
+ │ └── youtube-analyzer/ # YouTube content analysis
263
+ ├── install.sh # Installation script (macOS/Linux)
264
+ ├── install.ps1 # Installation script (Windows PowerShell)
265
+ ├── package.json # npm package metadata (@dmsdc-ai/aigentry-devkit)
266
+ ├── LICENSE # MIT License
267
+ └── README.md # This file
268
+ ```
269
+
270
+ ## Configuration
271
+
272
+ ### Claude Code Integration
273
+
274
+ After installation, skills and MCP servers are automatically available. Configuration is stored in:
275
+
276
+ - `~/.claude/skills/` - Skill definitions
277
+ - `~/.claude/.mcp.json` - MCP server registration
278
+ - `~/.claude/settings.json` - Claude Code settings
279
+
280
+ ### Codex CLI Integration
281
+
282
+ If Codex CLI is installed, the installer attempts to register the MCP deliberation server. Manual registration:
283
+
284
+ ```bash
285
+ codex mcp add deliberation -- node ~/.local/lib/mcp-deliberation/index.js
286
+ ```
287
+
288
+ Important: Codex is a participant CLI in deliberation, not a separate MCP server you must install.
289
+
290
+ Other CLIs can join deliberation by registering the same MCP server command in their MCP/client configuration:
291
+
292
+ ```bash
293
+ node ~/.local/lib/mcp-deliberation/index.js
294
+ ```
295
+
296
+ ### Environment Management
297
+
298
+ direnv integration (requires direnv):
299
+
300
+ ```bash
301
+ # Global configuration
302
+ cp config/envrc/global.envrc ~/.envrc
303
+ direnv allow
304
+
305
+ # Per-project
306
+ cd ~/my-project
307
+ echo 'source_up_if_exists' > .envrc
308
+ echo 'dotenv_if_exists .env.local' >> .envrc
309
+ direnv allow
310
+ ```
311
+
312
+ ## Troubleshooting
313
+
314
+ ### Skills not loading
315
+
316
+ 1. Verify skills are linked: `ls -la ~/.claude/skills/`
317
+ 2. Restart your MCP client process (Claude/Codex/etc.)
318
+ 3. Check for keyword matches in skill definitions
319
+
320
+ ### MCP Deliberation not available
321
+
322
+ 1. Verify MCP registration: `cat ~/.claude/.mcp.json`
323
+ 2. Check installation: `ls ~/.local/lib/mcp-deliberation/`
324
+ 3. Restart your MCP client process (Claude/Codex/etc.)
325
+ 4. Review MCP server logs in Claude Code console
326
+
327
+ ### MCP `Transport closed` in multi-session use
328
+
329
+ 1. Restart the current CLI session first (stdio transport is session-bound).
330
+ 2. Avoid killing deliberation with `pkill -f mcp-deliberation`; this can terminate other active sessions.
331
+ 3. Keep one active CLI tab per long-running deliberation workflow when possible.
332
+ 4. Check runtime log: `tail -n 120 ~/.local/lib/mcp-deliberation/runtime.log`
333
+ 5. Confirm lock directory exists: `ls ~/.local/lib/mcp-deliberation/state/<project>/.locks`
334
+
335
+ Multi-session stability in v2.4 uses:
336
+ - Session/project lock files (`.locks/`) to serialize writes
337
+ - Atomic file writes for session/markdown persistence
338
+ - Safe tool handlers + uncaught error logging to keep server process alive
339
+
340
+ ### Browser LLM tabs not detected (Linux/Windows)
341
+
342
+ Browser tab scan is cross-platform, but Linux/Windows rely on CDP endpoints. Start your browser with a remote debugging port:
343
+
344
+ Linux/macOS:
345
+ ```bash
346
+ google-chrome --remote-debugging-port=9222
347
+ ```
348
+
349
+ Windows (PowerShell):
350
+ ```powershell
351
+ & "$Env:ProgramFiles\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222
352
+ ```
353
+
354
+ Then run:
355
+ ```bash
356
+ deliberation_browser_llm_tabs
357
+ ```
358
+
359
+ If auto-scan is still unavailable, use the clipboard fallback:
360
+ - `deliberation_clipboard_prepare_turn`
361
+ - paste into browser LLM and copy response
362
+ - `deliberation_clipboard_submit_turn`
363
+
364
+ ### Environment variables not loading
365
+
366
+ 1. Check direnv installation: `command -v direnv`
367
+ 2. Verify .envrc files: `cat ~/.envrc` and `cat ~/project/.envrc`
368
+ 3. Allow the directory: `direnv allow`
369
+ 4. Test: `direnv exec /bin/bash 'echo $VARIABLE_NAME'`
370
+
371
+ ### YouTube Analyzer errors
372
+
373
+ 1. Verify Python 3.8+: `python3 --version`
374
+ 2. Check yt-dlp: `python3 -c "import yt_dlp; print('OK')"`
375
+ 3. Install if missing: `pip install yt-dlp`
376
+
377
+ ## Development
378
+
379
+ ### Adding new skills
380
+
381
+ 1. Create directory: `skills/my-skill/`
382
+ 2. Add `SKILL.md` with metadata and implementation
383
+ 3. Reinstall: `bash install.sh --force`
384
+
385
+ ### Customizing MCP server
386
+
387
+ Edit `mcp-servers/deliberation/index.js` and reinstall:
388
+
389
+ ```bash
390
+ cd ~/.local/lib/mcp-deliberation
391
+ npm install
392
+ ```
393
+
394
+ ### Extending configuration
395
+
396
+ Add templates to `config/` and update both `install.sh` and `install.ps1` to deploy them.
397
+
398
+ ## Requirements
399
+
400
+ - **Node.js**: 18+ (for MCP server)
401
+ - **npm**: Latest (included with Node.js)
402
+ - **Claude Code CLI**: v1.0+ (optional, for full integration)
403
+ - **Codex CLI**: Latest (optional, for Codex integration)
404
+ - **tmux**: Latest (optional, for deliberation monitoring)
405
+ - **direnv**: Latest (optional, for environment management)
406
+ - **PowerShell**: 7+ recommended on Windows
407
+
408
+ Language-specific requirements for skills:
409
+
410
+ - **YouTube Analyzer**: Python 3.8+, yt-dlp
411
+ - **Clipboard Image**: xclip or pbpaste (platform-dependent)
412
+
413
+ ## Architecture
414
+
415
+ ### Installation Flow
416
+
417
+ ```
418
+ npx @dmsdc-ai/aigentry-devkit install
419
+ ├─ dispatches to install.sh (macOS/Linux) or install.ps1 (Windows)
420
+ ├─ Check prerequisites (Node.js, npm, optional tools)
421
+ ├─ Link skills to ~/.claude/skills/
422
+ ├─ Install HUD to ~/.claude/hud/
423
+ ├─ Deploy MCP server to ~/.local/lib/mcp-deliberation/
424
+ ├─ Register MCP in ~/.claude/.mcp.json
425
+ ├─ Create config from templates (settings.json, .envrc)
426
+ └─ Integrate with Codex CLI (if available)
427
+ ```
428
+
429
+ ### Runtime Flow
430
+
431
+ ```
432
+ MCP Client Start (Claude/Codex/others)
433
+ ├─ Load plugins from .claude-plugin/
434
+ ├─ Execute SessionStart hooks
435
+ │ └─ Run hooks/session-start (load skill index)
436
+ ├─ Register MCP servers from ~/.claude/.mcp.json
437
+ │ └─ Connect to MCP Deliberation Server
438
+ ├─ Load skills from ~/.claude/skills/
439
+ └─ Ready for interaction
440
+ ```
441
+
442
+ ### Skill Activation
443
+
444
+ ```
445
+ User message with keywords
446
+ ├─ Match against skill trigger patterns
447
+ ├─ Load appropriate skill SKILL.md
448
+ ├─ Execute skill workflow
449
+ └─ Return results
450
+ ```
451
+
452
+ ## Performance
453
+
454
+ - Skills load on-demand (no performance impact until triggered)
455
+ - MCP server runs in separate process (non-blocking)
456
+ - direnv setup is cached after first load
457
+ - HUD statusline updates asynchronously
458
+
459
+ ## Compatibility
460
+
461
+ | Tool | Supported | Tested |
462
+ |------|-----------|--------|
463
+ | Claude Code | 1.0+ | Yes |
464
+ | Codex CLI | Latest | Yes |
465
+ | Node.js | 18+ | 20 LTS, 22 |
466
+ | macOS | Ventura+ | Yes |
467
+ | Linux | Ubuntu 22.04+ | Yes |
468
+ | Windows | 10/11 + PowerShell | Yes |
469
+
470
+ ## Contributing
471
+
472
+ Contributions welcome. Please follow these guidelines:
473
+
474
+ 1. Test skills locally before submitting
475
+ 2. Update SKILL.md documentation
476
+ 3. Ensure installer remains idempotent
477
+ 4. Follow existing code style
478
+
479
+ ## License
480
+
481
+ MIT License - See LICENSE file for details.
482
+
483
+ Copyright 2026 dmsdc-ai
484
+
485
+ ## Support
486
+
487
+ - Report issues: [GitHub Issues](https://github.com/dmsdc-ai/aigentry-devkit/issues)
488
+ - Documentation: [GitHub Wiki](https://github.com/dmsdc-ai/aigentry-devkit/wiki)
489
+ - Community: [dmsdc-ai Organization](https://github.com/dmsdc-ai)
490
+
491
+ ## Acknowledgments
492
+
493
+ Built with:
494
+ - [Claude Code](https://github.com/anthropic-ai/claude-code) by Anthropic
495
+ - [Model Context Protocol](https://modelcontextprotocol.io/) by Anthropic
496
+ - [oh-my-claudecode](https://github.com/Yeachan-Heo/oh-my-claudecode) - Multi-agent orchestration framework
497
+
498
+ ---
499
+
500
+ **aigentry-devkit** - Streamline your AI development workflow.
@@ -0,0 +1,94 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require("fs");
4
+ const path = require("path");
5
+ const { spawnSync } = require("child_process");
6
+
7
+ const rootDir = path.resolve(__dirname, "..");
8
+
9
+ function printHelp() {
10
+ const text = [
11
+ "aigentry-devkit CLI",
12
+ "",
13
+ "Usage:",
14
+ " aigentry-devkit install [--force]",
15
+ " aigentry-devkit --help",
16
+ "",
17
+ "Examples:",
18
+ " npx -y @dmsdc-ai/aigentry-devkit install",
19
+ " npx -y @dmsdc-ai/aigentry-devkit install --force",
20
+ ].join("\n");
21
+ process.stdout.write(`${text}\n`);
22
+ }
23
+
24
+ function commandExists(command) {
25
+ const checker = process.platform === "win32" ? "where" : "which";
26
+ const result = spawnSync(checker, [command], { stdio: "ignore" });
27
+ return result.status === 0;
28
+ }
29
+
30
+ function run(command, args) {
31
+ const result = spawnSync(command, args, { stdio: "inherit" });
32
+ if (result.error) {
33
+ process.stderr.write(`Failed to run "${command}": ${result.error.message}\n`);
34
+ process.exit(1);
35
+ }
36
+ process.exit(result.status == null ? 1 : result.status);
37
+ }
38
+
39
+ function runInstall(flags) {
40
+ const force = flags.has("--force") || flags.has("-f");
41
+
42
+ if (process.platform === "win32") {
43
+ const scriptPath = path.join(rootDir, "install.ps1");
44
+ if (!fs.existsSync(scriptPath)) {
45
+ process.stderr.write(`Missing installer: ${scriptPath}\n`);
46
+ process.exit(1);
47
+ }
48
+
49
+ const shell = ["pwsh.exe", "pwsh", "powershell.exe", "powershell"].find(commandExists);
50
+ if (!shell) {
51
+ process.stderr.write("PowerShell not found. Install PowerShell and retry.\n");
52
+ process.exit(1);
53
+ }
54
+
55
+ const args = ["-NoProfile", "-ExecutionPolicy", "Bypass", "-File", scriptPath];
56
+ if (force) args.push("-Force");
57
+ run(shell, args);
58
+ return;
59
+ }
60
+
61
+ const scriptPath = path.join(rootDir, "install.sh");
62
+ if (!fs.existsSync(scriptPath)) {
63
+ process.stderr.write(`Missing installer: ${scriptPath}\n`);
64
+ process.exit(1);
65
+ }
66
+ if (!commandExists("bash")) {
67
+ process.stderr.write("bash not found. Install bash and retry.\n");
68
+ process.exit(1);
69
+ }
70
+
71
+ const args = [scriptPath];
72
+ if (force) args.push("--force");
73
+ run("bash", args);
74
+ }
75
+
76
+ const argv = process.argv.slice(2);
77
+ let command = "install";
78
+ if (argv.length > 0 && !argv[0].startsWith("-")) {
79
+ command = argv.shift();
80
+ }
81
+ const flags = new Set(argv);
82
+
83
+ if (command === "help" || flags.has("--help") || flags.has("-h")) {
84
+ printHelp();
85
+ process.exit(0);
86
+ }
87
+
88
+ if (command !== "install") {
89
+ process.stderr.write(`Unknown command: ${command}\n\n`);
90
+ printHelp();
91
+ process.exit(1);
92
+ }
93
+
94
+ runInstall(flags);