noninteractive 0.3.25 → 0.3.27

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.
@@ -194,8 +194,10 @@ function runDaemon(sessionName, executable, args) {
194
194
  }
195
195
  const binDir = sessionBinDir2(sessionName);
196
196
  const ptyBridge = getPtyBridge();
197
+ const spawnCwd = process.env.NI_CWD || process.cwd();
197
198
  const proc = spawn(ptyBridge, [executable, ...args], {
198
199
  stdio: ["pipe", "pipe", "pipe"],
200
+ cwd: spawnCwd,
199
201
  env: {
200
202
  ...process.env,
201
203
  TERM: "xterm-256color",
@@ -377,7 +379,7 @@ var init_daemon = __esm(() => {
377
379
  var require_package = __commonJS((exports, module) => {
378
380
  module.exports = {
379
381
  name: "noninteractive",
380
- version: "0.3.25",
382
+ version: "0.3.27",
381
383
  type: "module",
382
384
  bin: {
383
385
  noninteractive: "./bin/noninteractive.js"
@@ -477,15 +479,18 @@ commands:
477
479
  read <session> [--wait] [--timeout N] read terminal output (--wait blocks until new output)
478
480
  stop <session> stop a session
479
481
  list show active sessions
480
- start <cmd> [args...] explicit start (for non-npx commands)
482
+ start [--name N] [--cwd D] <cmd> [args...] explicit start (for non-npx commands)
481
483
 
482
484
  flags:
485
+ --name <session> set session name (default: auto-derived from tool name)
486
+ --cwd <dir> set working directory for the command
483
487
  --no-wait fire-and-forget mode for send (don't wait for output)
484
488
  --wait, -w block until new output appears (for read)
485
489
  --timeout <ms> max wait time in ms (default: 30000)
486
490
  --no-open don't auto-open URLs in browser (still shown in output)
487
491
 
488
492
  the session name is auto-derived from the tool (e.g. "workos" \u2192 session "workos").
493
+ use --name to override, --cwd to set the working directory.
489
494
 
490
495
  text is sent raw \u2014 no auto-appended enter. escape sequences are parsed:
491
496
  \\r = Enter, \\n = newline, \\t = tab, \\x1b = escape (for arrow keys)
@@ -504,6 +509,9 @@ more examples:
504
509
  npx noninteractive supabase init # session "supabase"
505
510
  npx noninteractive start vercel login # explicit start for non-npx commands`;
506
511
  function stripAnsi(s) {
512
+ const lastClear = Math.max(s.lastIndexOf("\x1B[2J"), s.lastIndexOf("\x1B[H\x1B[2J"));
513
+ if (lastClear !== -1)
514
+ s = s.slice(lastClear);
507
515
  s = s.replace(/\x1b\[[012]?K/g, `
508
516
  `);
509
517
  let result = "";
@@ -644,10 +652,10 @@ function deriveSessionName(cmd, args) {
644
652
  const stripped = name.replace(/(?<=.)@[^/].*$/, "");
645
653
  return (stripped || name).replace(/^@[^/]+\//, "").replace(/[^a-zA-Z0-9_-]/g, "");
646
654
  }
647
- async function start(cmdArgs, noOpen = false) {
655
+ async function start(cmdArgs, noOpen = false, sessionName, cwd) {
648
656
  const executable = cmdArgs[0];
649
657
  const args = cmdArgs.slice(1);
650
- const baseName = deriveSessionName(executable, args);
658
+ const baseName = sessionName || deriveSessionName(executable, args);
651
659
  let name = baseName;
652
660
  let suffix = 1;
653
661
  while (true) {
@@ -677,7 +685,8 @@ async function start(cmdArgs, noOpen = false) {
677
685
  const self = getSelfCommand();
678
686
  const child = spawn2(self[0], [...self.slice(1), "__daemon__", name, executable, ...args], {
679
687
  detached: true,
680
- stdio: "ignore"
688
+ stdio: "ignore",
689
+ ...cwd ? { env: { ...process.env, NI_CWD: cwd } } : {}
681
690
  });
682
691
  child.unref();
683
692
  for (let i = 0;i < 50; i++) {
@@ -694,12 +703,13 @@ make sure the command exists. examples:`);
694
703
  console.error(` npx noninteractive start vercel login # run a command directly`);
695
704
  process.exit(1);
696
705
  }
697
- for (let i = 0;i < 50; i++) {
706
+ const stripSpinners = (s) => s.replace(/[\u280B\u2819\u2839\u2838\u283C\u2834\u2826\u2827\u2807\u280F\u281B\u2833\u281E\u283D\u283B\u283F\u283E\u2837\u282F\u281F]/g, "").trim();
707
+ for (let i = 0;i < 150; i++) {
698
708
  await new Promise((r) => setTimeout(r, 200));
699
709
  try {
700
710
  const res = await sendMessage(sock, { action: "read" });
701
711
  handleUrls(res, noOpen);
702
- const clean = stripAnsi(res.output ?? "").trim();
712
+ const clean = stripSpinners(stripAnsi(res.output ?? ""));
703
713
  if (clean.length > 10) {
704
714
  process.stdout.write(stripAnsi(res.output));
705
715
  if (res.exited) {
@@ -828,17 +838,30 @@ async function main() {
828
838
  const cmd = args[0];
829
839
  switch (cmd) {
830
840
  case "start": {
831
- const startArgs = args.slice(1).filter((a) => a !== "--no-open");
832
- const noOpen = args.includes("--no-open");
833
- if (startArgs.length < 1) {
834
- console.error(`usage: noninteractive start <cmd> [args...]
841
+ const startArgs = args.slice(1);
842
+ const noOpen = startArgs.includes("--no-open");
843
+ let sessionName;
844
+ let cwd;
845
+ const nameIdx = startArgs.indexOf("--name");
846
+ if (nameIdx !== -1) {
847
+ sessionName = startArgs[nameIdx + 1];
848
+ startArgs.splice(nameIdx, 2);
849
+ }
850
+ const cwdIdx = startArgs.indexOf("--cwd");
851
+ if (cwdIdx !== -1) {
852
+ cwd = startArgs[cwdIdx + 1];
853
+ startArgs.splice(cwdIdx, 2);
854
+ }
855
+ const filtered = startArgs.filter((a) => a !== "--no-open");
856
+ if (filtered.length < 1) {
857
+ console.error(`usage: noninteractive start [--name <session>] [--cwd <dir>] <cmd> [args...]
835
858
 
836
859
  examples:
837
860
  npx noninteractive start npx eslint --init
838
- npx noninteractive eslint --init # shorthand (auto-starts with npx)`);
861
+ npx noninteractive start --name myeslint --cwd /tmp/project npx eslint --init`);
839
862
  process.exit(1);
840
863
  }
841
- return start(startArgs, noOpen);
864
+ return start(filtered, noOpen, sessionName, cwd);
842
865
  }
843
866
  case "read": {
844
867
  const readArgs = args.slice(1);
@@ -901,24 +924,33 @@ example: npx noninteractive stop vercel`);
901
924
  console.log(HELP);
902
925
  break;
903
926
  default: {
904
- const niFlags = ["--name", "--cwd", "--dir", "--session"];
905
- const firstPositional = args.findIndex((a) => !a.startsWith("-") && a !== "--");
906
- const flagsBefore = firstPositional === -1 ? args : args.slice(0, firstPositional);
907
- const wrongFlag = flagsBefore.find((a) => niFlags.includes(a.split("=")[0]));
927
+ let sessionName;
928
+ let cwd;
929
+ const mutableArgs = [...args];
930
+ const nameIdx = mutableArgs.indexOf("--name");
931
+ if (nameIdx !== -1) {
932
+ sessionName = mutableArgs[nameIdx + 1];
933
+ mutableArgs.splice(nameIdx, 2);
934
+ }
935
+ const cwdIdx = mutableArgs.indexOf("--cwd");
936
+ if (cwdIdx !== -1) {
937
+ cwd = mutableArgs[cwdIdx + 1];
938
+ mutableArgs.splice(cwdIdx, 2);
939
+ }
940
+ const wrongFlags = ["--dir", "--session"];
941
+ const firstPositional = mutableArgs.findIndex((a) => !a.startsWith("-") && a !== "--");
942
+ const flagsBefore = firstPositional === -1 ? mutableArgs : mutableArgs.slice(0, firstPositional);
943
+ const wrongFlag = flagsBefore.find((a) => wrongFlags.includes(a.split("=")[0]));
908
944
  if (wrongFlag) {
909
945
  console.error(`unknown flag: ${wrongFlag}
910
946
 
911
- hint: ${wrongFlag} is not supported. the session name is auto-derived from the command.`);
912
- console.error(`
913
- examples:
914
- npx noninteractive eslint --init # auto-start, session = "eslint"
915
- npx noninteractive start npx eslint --init # explicit start`);
947
+ hint: use --name for session name, --cwd for working directory.`);
916
948
  process.exit(1);
917
949
  }
918
- const noOpen = args.includes("--no-open");
919
- const filteredArgs = args.filter((a) => a !== "--no-open");
950
+ const noOpen = mutableArgs.includes("--no-open");
951
+ const filteredArgs = mutableArgs.filter((a) => a !== "--no-open");
920
952
  console.log(`[installing and running: npx ${filteredArgs.join(" ")}]`);
921
- return start(["npx", "--yes", ...filteredArgs], noOpen);
953
+ return start(["npx", "--yes", ...filteredArgs], noOpen, sessionName, cwd);
922
954
  }
923
955
  }
924
956
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "noninteractive",
3
- "version": "0.3.25",
3
+ "version": "0.3.27",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "noninteractive": "./bin/noninteractive.js"