@darkrei08/setup-ai 3.0.1 → 3.0.3

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
@@ -10,30 +10,24 @@ skill — each via its **official, current** method for your OS.
10
10
 
11
11
  ## Quick start
12
12
 
13
+ One command. No install, no clone. It opens a menu to choose what to set up:
14
+
13
15
  ```bash
14
- # no install needed — runs the launcher once, then discards it
15
16
  npx github:darkrei08/setup-ai
16
17
  ```
17
18
 
18
- or, once published to npm:
19
+ Prefer non-interactive? Same command, add a flag:
19
20
 
20
21
  ```bash
21
- npx @darkrei08/setup-ai # interactive module menu
22
- npx @darkrei08/setup-ai --only pi,codex,opencode
23
- npx @darkrei08/setup-ai --all # everything incl. optional GUI apps
24
- npm i -g @darkrei08/setup-ai && setup-ai # global command
22
+ npx github:darkrei08/setup-ai --only pi,codex,opencode # just these
23
+ npx github:darkrei08/setup-ai --all # everything
25
24
  ```
26
25
 
27
- The launcher (`bin/setup-ai.mjs`, zero dependencies) detects your OS and runs
28
- the right script: `setup-ai.ps1` on Windows (via `pwsh`), `setup-ai.sh` on
29
- macOS/Linux (via `bash`). With no selection flag on an interactive terminal it
30
- opens an arrow-key **multi-select menu** (↑/↓ move · Space toggle · `a` all ·
31
- Enter confirm); on a non-interactive shell it installs the core set.
26
+ That's the whole thing. Three details worth knowing:
32
27
 
33
- > **Windows / PowerShell**: paste each command on a **single line** the bash
34
- > `\` line-continuation is not valid in PowerShell. If a runtime (node, git) was
35
- > just installed this run, open a **new terminal** before re-running so the
36
- > updated PATH is picked up.
28
+ - **Windows PowerShell**: one command per line (no bash `\`). If node or git was just installed, open a **new terminal** so PATH refreshes.
29
+ - **What it does**: detects your OS and runs `setup-ai.sh` (macOS/Linux) or `setup-ai.ps1` (Windows). Menu keys: ↑/↓ move · Space toggle · `a` all · Enter.
30
+ - **Shorter name**: once it's on npm, drop `github:` `npx @darkrei08/setup-ai` (run it from any folder except the repo's own source dir).
37
31
 
38
32
  ### npm vs npx
39
33
 
package/bin/setup-ai.mjs CHANGED
@@ -106,7 +106,7 @@ function toScriptArgs(mode, csv) {
106
106
 
107
107
  // ---- interactive multi-select (gentle-ai style) ---------------------------
108
108
  function interactiveMenu() {
109
- return new Promise((resolve) => {
109
+ return new Promise((resolve, reject) => {
110
110
  const items = menuModules.map((m) => ({ ...m, checked: m.core }));
111
111
  let cursor = 0;
112
112
  const out = process.stdout;
@@ -125,17 +125,29 @@ function interactiveMenu() {
125
125
  };
126
126
 
127
127
  const stdin = process.stdin;
128
- stdin.setRawMode(true);
128
+ if (typeof stdin.setRawMode !== "function") {
129
+ return reject(new Error("stdin is not a raw-capable TTY"));
130
+ }
131
+ try {
132
+ stdin.setRawMode(true);
133
+ } catch (err) {
134
+ return reject(err);
135
+ }
129
136
  stdin.resume();
130
137
  stdin.setEncoding("utf8");
131
138
  render(true);
132
139
 
133
140
  const cleanup = () => {
134
- stdin.setRawMode(false);
141
+ try { stdin.setRawMode(false); } catch { /* ignore */ }
135
142
  stdin.pause();
136
143
  stdin.removeListener("data", onData);
144
+ stdin.removeListener("end", onEnd);
137
145
  };
138
146
 
147
+ // If stdin closes before a choice (e.g. npx consumed it), fall back instead
148
+ // of hanging or exiting silently.
149
+ const onEnd = () => { cleanup(); reject(new Error("stdin closed before a choice was made")); };
150
+
139
151
  const onData = (key) => {
140
152
  if (key === "\x03" || key === "q") { // ctrl-c / q
141
153
  cleanup();
@@ -156,6 +168,7 @@ function interactiveMenu() {
156
168
  }
157
169
  };
158
170
  stdin.on("data", onData);
171
+ stdin.on("end", onEnd);
159
172
  });
160
173
  }
161
174
 
@@ -165,6 +178,11 @@ function defaultSelection() {
165
178
  }
166
179
 
167
180
  async function main() {
181
+ // Always emit a first line so the user sees the launcher started, even if
182
+ // something downstream fails (this is what "npx returns to prompt silently"
183
+ // needed).
184
+ console.log(`setup-ai launcher · ${process.platform}`);
185
+
168
186
  if (has("--help") || has("-h")) return runScript(toScriptArgs("help"));
169
187
  if (has("--list")) return runScript(toScriptArgs("list"));
170
188
  if (has("--all")) return runScript(toScriptArgs("all"));
@@ -174,18 +192,36 @@ async function main() {
174
192
 
175
193
  if (has("--yes") || has("-y")) return runScript(toScriptArgs("yes"));
176
194
 
177
- // No selection flag: interactive menu if we have a TTY, else core defaults.
195
+ // No selection flag: try the interactive menu; fall back cleanly if the
196
+ // terminal/stdin can't drive it (common under some npx/CI shells).
197
+ let chosen = null;
178
198
  if (process.stdin.isTTY && process.stdout.isTTY) {
179
- const chosen = await interactiveMenu();
180
- if (!chosen.length) {
181
- console.log("Nothing selected exiting.");
182
- process.exit(0);
199
+ try {
200
+ chosen = await interactiveMenu();
201
+ } catch (err) {
202
+ console.log(`\n(interactive menu unavailable: ${err.message})`);
203
+ chosen = null;
183
204
  }
184
- return runScript(toScriptArgs("only", chosen.join(",")));
205
+ } else {
206
+ console.log("No interactive terminal detected.");
207
+ }
208
+
209
+ if (!chosen) {
210
+ console.log("Installing the CORE set. Customize with:");
211
+ console.log(" npx github:darkrei08/setup-ai --only pi,codex,opencode");
212
+ console.log(" npx github:darkrei08/setup-ai --all (everything)");
213
+ console.log(" npx github:darkrei08/setup-ai --list (see modules)\n");
214
+ chosen = defaultSelection();
185
215
  }
186
216
 
187
- console.log("No TTY detected — installing the core module set. Use --only/--all to customize.");
188
- return runScript(toScriptArgs("only", defaultSelection().join(",")));
217
+ if (!chosen.length) {
218
+ console.log("Nothing selected — exiting.");
219
+ process.exit(0);
220
+ }
221
+ return runScript(toScriptArgs("only", chosen.join(",")));
189
222
  }
190
223
 
191
- main();
224
+ main().catch((err) => {
225
+ console.error(`setup-ai launcher error: ${err?.message || err}`);
226
+ process.exit(1);
227
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@darkrei08/setup-ai",
3
- "version": "3.0.1",
3
+ "version": "3.0.3",
4
4
  "description": "Cross-OS installer for an AI coding toolchain (pi, codex, antigravity, opencode, herdr, gentle-ai, engram, Engineering Excellence) with an interactive module menu.",
5
5
  "type": "module",
6
6
  "bin": {
package/setup-ai.ps1 CHANGED
@@ -33,7 +33,15 @@ param(
33
33
  $ErrorActionPreference = 'Stop'
34
34
  Set-StrictMode -Version Latest
35
35
 
36
- $ScriptVersion = "3.0.1"
36
+ # Render child-process UTF-8 output (npx skills box-drawing, banners) correctly
37
+ # instead of mojibake on the default Windows console codepage.
38
+ try {
39
+ [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
40
+ $OutputEncoding = [System.Text.Encoding]::UTF8
41
+ if (Get-Command chcp -ErrorAction SilentlyContinue) { chcp 65001 | Out-Null }
42
+ } catch { }
43
+
44
+ $ScriptVersion = "3.0.3"
37
45
  $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
38
46
  $LogDir = Join-Path $ScriptDir "logs"
39
47
  New-Item -ItemType Directory -Force -Path $LogDir | Out-Null
@@ -208,9 +216,10 @@ function Mod-Go {
208
216
  function Mod-Ee {
209
217
  Write-Log INFO "ee" "start" "Engineering Excellence"
210
218
  if (-not (Test-Cmd npx)) { Write-Log WARN "ee" "npx_missing" "npx not found; install node first"; return }
211
- $agents = @{ pi = ".pi"; claude = ".claude"; gemini = ".gemini"; cursor = ".cursor"; antigravity = ".antigravity" }
219
+ # Keys are `skills` CLI agent names (claude-code, gemini-cli), not dir names.
220
+ $agents = @{ pi = ".pi"; 'claude-code' = ".claude"; 'gemini-cli' = ".gemini"; cursor = ".cursor"; antigravity = ".antigravity"; codex = ".codex"; opencode = ".config\opencode" }
212
221
  $any = $false
213
- foreach ($a in @('pi','claude','gemini','cursor','antigravity')) {
222
+ foreach ($a in @('pi','claude-code','gemini-cli','cursor','antigravity','codex','opencode')) {
214
223
  if (Test-Path (Join-Path $HOME $agents[$a])) {
215
224
  Invoke-Step -Phase "ee" -Optional -Action {
216
225
  npx --yes skills@latest add $EE_Slug --skill $EE_Skill --global --agent $a --copy --yes
package/setup-ai.sh CHANGED
@@ -26,7 +26,7 @@
26
26
  set -Eeuo pipefail
27
27
  IFS=$'\n\t'
28
28
 
29
- SCRIPT_VERSION="3.0.1"
29
+ SCRIPT_VERSION="3.0.3"
30
30
 
31
31
  SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
32
32
  LOG_DIR="${SCRIPT_DIR}/logs"
@@ -602,16 +602,20 @@ mod_ee() {
602
602
 
603
603
  # Install the skill for every detected agent using the modern skills CLI
604
604
  # (replaces the old git-clone-and-move). Agents are detected by their config dir.
605
+ # Keys are the `skills` CLI agent names (claude-code, gemini-cli, ...), which
606
+ # differ from the config-dir basename; values are the dir we detect them by.
605
607
  local agent dir
606
608
  local -A agent_dir=(
607
609
  [pi]="${HOME}/.pi"
608
- [claude]="${HOME}/.claude"
609
- [gemini]="${HOME}/.gemini"
610
+ [claude-code]="${HOME}/.claude"
611
+ [gemini-cli]="${HOME}/.gemini"
610
612
  [cursor]="${HOME}/.cursor"
611
613
  [antigravity]="${HOME}/.antigravity"
614
+ [codex]="${HOME}/.codex"
615
+ [opencode]="${HOME}/.config/opencode"
612
616
  )
613
617
  local installed_any=0
614
- for agent in pi claude gemini cursor antigravity; do
618
+ for agent in pi claude-code gemini-cli cursor antigravity codex opencode; do
615
619
  dir="${agent_dir[$agent]}"
616
620
  [[ -d "${dir}" ]] || continue
617
621
  run_optional "engineering-excellence" \