komplian 0.3.4 → 0.3.5

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.
@@ -18,6 +18,13 @@ import { homedir } from "node:os";
18
18
 
19
19
  const __dirname = dirname(fileURLToPath(import.meta.url));
20
20
 
21
+ /** Windows: sin esto, CreateProcess no resuelve gh.cmd / git.exe / npm.cmd como la consola. */
22
+ const IS_WIN = process.platform === "win32";
23
+
24
+ function spawnWin(extra = {}) {
25
+ return IS_WIN ? { ...extra, shell: true } : extra;
26
+ }
27
+
21
28
  const c = {
22
29
  reset: "\x1b[0m",
23
30
  dim: "\x1b[2m",
@@ -51,10 +58,14 @@ function banner() {
51
58
  }
52
59
 
53
60
  function ghOk() {
54
- const r = spawnSync("gh", ["auth", "status", "-h", "github.com"], {
55
- encoding: "utf8",
56
- stdio: ["ignore", "pipe", "pipe"],
57
- });
61
+ const r = spawnSync(
62
+ "gh",
63
+ ["auth", "status", "-h", "github.com"],
64
+ spawnWin({
65
+ encoding: "utf8",
66
+ stdio: ["ignore", "pipe", "pipe"],
67
+ })
68
+ );
58
69
  return r.status === 0;
59
70
  }
60
71
 
@@ -65,16 +76,20 @@ function runGhAuth() {
65
76
  const r = spawnSync(
66
77
  "gh",
67
78
  ["auth", "login", "-h", "github.com", "-s", "repo", "-s", "read:org", "-w"],
68
- { stdio: "inherit" }
79
+ spawnWin({ stdio: "inherit" })
69
80
  );
70
81
  return r.status === 0;
71
82
  }
72
83
 
73
84
  function ghApiJson(path) {
74
- const r = spawnSync("gh", ["api", path], {
75
- encoding: "utf8",
76
- stdio: ["ignore", "pipe", "pipe"],
77
- });
85
+ const r = spawnSync(
86
+ "gh",
87
+ ["api", path],
88
+ spawnWin({
89
+ encoding: "utf8",
90
+ stdio: ["ignore", "pipe", "pipe"],
91
+ })
92
+ );
78
93
  return { status: r.status, stdout: r.stdout || "", stderr: r.stderr || "" };
79
94
  }
80
95
 
@@ -128,30 +143,26 @@ function logGhIdentity() {
128
143
  }
129
144
  }
130
145
 
131
- function cmdExists(name) {
132
- const pathEnv = process.env.PATH || process.env.Path || "";
133
- const isWin = process.platform === "win32";
134
- const sep = isWin ? ";" : ":";
135
- const dirs = pathEnv.split(sep).filter(Boolean);
136
- const exts = isWin
137
- ? ["", ...(process.env.PATHEXT || ".COM;.EXE;.BAT;.CMD").split(";")]
138
- : [""];
139
- for (const dir of dirs) {
140
- for (const ext of exts) {
141
- try {
142
- const full = join(dir, name + ext);
143
- if (existsSync(full) && statSync(full).isFile()) return true;
144
- } catch {
145
- continue;
146
- }
147
- }
148
- }
149
- return false;
146
+ /** Misma resolución que los clones: en Windows hace falta shell para gh.cmd / git / npm. */
147
+ function canRun(cmd, args) {
148
+ const r = spawnSync(cmd, args, spawnWin({ stdio: "ignore" }));
149
+ return r.status === 0 && !r.error;
150
150
  }
151
151
 
152
152
  function needCmd(name, hint = "") {
153
- if (!cmdExists(name)) {
154
- log(`${c.red}✗${c.reset} Falta ${c.bold}${name}${c.reset} en el PATH.${hint ? ` ${hint}` : ""}`);
153
+ const ok =
154
+ name === "gh"
155
+ ? canRun("gh", ["version"])
156
+ : name === "git"
157
+ ? canRun("git", ["--version"])
158
+ : canRun(name, ["--version"]);
159
+ if (!ok) {
160
+ log(`${c.red}✗${c.reset} No se puede ejecutar ${c.bold}${name}${c.reset} (¿PATH o instalación?).${hint ? ` ${hint}` : ""}`);
161
+ if (IS_WIN) {
162
+ log(
163
+ `${c.dim} Windows: cierra y abre la terminal tras instalar gh/git, o reinicia para refrescar PATH.${c.reset}`
164
+ );
165
+ }
155
166
  process.exit(1);
156
167
  }
157
168
  }
@@ -164,7 +175,7 @@ function ghRepoList(org) {
164
175
  const r = spawnSync(
165
176
  "gh",
166
177
  ["repo", "list", org, "--limit", "1000", "--json", "name,isArchived,isFork"],
167
- { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }
178
+ spawnWin({ encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] })
168
179
  );
169
180
  if (r.status !== 0) {
170
181
  log(`${c.red}✗${c.reset} gh repo list falló:\n${r.stderr || r.stdout}`);
@@ -246,9 +257,11 @@ function cloneOne(org, name, workspace, useSsh) {
246
257
  : ["repo", "clone", `${org}/${name}`, name];
247
258
  const cmd = useSsh ? "git" : "gh";
248
259
  const r = spawnSync(cmd, args, {
249
- cwd: workspace,
250
- encoding: "utf8",
251
- stdio: ["ignore", "pipe", "pipe"],
260
+ ...spawnWin({
261
+ cwd: workspace,
262
+ encoding: "utf8",
263
+ stdio: ["ignore", "pipe", "pipe"],
264
+ }),
252
265
  });
253
266
  process.stdout.write("\r\x1b[K");
254
267
  if (r.status === 0) {
@@ -266,11 +279,15 @@ function copyCursorPack(workspace, cursorRepoUrl) {
266
279
  const tmp = join(workspace, ".cursor-bootstrap-tmp");
267
280
  rmSync(tmp, { recursive: true, force: true });
268
281
  log(`${c.dim}→${c.reset} Cursor pack (clone superficial)…`);
269
- const r = spawnSync("git", ["clone", "--depth", "1", String(cursorRepoUrl).trim(), tmp], {
270
- cwd: workspace,
271
- stdio: ["ignore", "pipe", "pipe"],
272
- encoding: "utf8",
273
- });
282
+ const r = spawnSync(
283
+ "git",
284
+ ["clone", "--depth", "1", String(cursorRepoUrl).trim(), tmp],
285
+ spawnWin({
286
+ cwd: workspace,
287
+ stdio: ["ignore", "pipe", "pipe"],
288
+ encoding: "utf8",
289
+ })
290
+ );
274
291
  if (r.status === 0 && existsSync(join(tmp, ".cursor"))) {
275
292
  rmSync(rootCursor, { recursive: true, force: true });
276
293
  cpSync(join(tmp, ".cursor"), rootCursor, { recursive: true });
@@ -289,7 +306,7 @@ function copyCursorPack(workspace, cursorRepoUrl) {
289
306
  function npmInstallEach(workspace) {
290
307
  log("");
291
308
  log(`${c.cyan}━━ npm install por repo ━━${c.reset}`);
292
- if (!cmdExists("npm")) {
309
+ if (!canRun("npm", ["--version"])) {
293
310
  log(`${c.yellow}○${c.reset} npm no está en PATH — omito installs`);
294
311
  return;
295
312
  }
@@ -299,7 +316,7 @@ function npmInstallEach(workspace) {
299
316
  const pkg = join(d, "package.json");
300
317
  if (!existsSync(pkg)) continue;
301
318
  log(`${c.dim}→${c.reset} ${ent}`);
302
- const ir = spawnSync("npm", ["install"], { cwd: d, stdio: "inherit" });
319
+ const ir = spawnSync("npm", ["install"], spawnWin({ cwd: d, stdio: "inherit" }));
303
320
  if (ir.status !== 0) {
304
321
  log(`${c.yellow}○${c.reset} npm install con avisos en ${ent}`);
305
322
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "komplian",
3
- "version": "0.3.4",
3
+ "version": "0.3.5",
4
4
  "description": "Komplian developer workspace setup: GitHub CLI (browser login) + git clone by team. Node 18+, git, gh — no OAuth App to register.",
5
5
  "type": "module",
6
6
  "engines": {