noninteractive 0.3.2 → 0.3.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.ts +56 -19
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "noninteractive",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "noninteractive": "./src/index.ts"
package/src/index.ts CHANGED
@@ -5,25 +5,32 @@ import { existsSync } from "node:fs";
5
5
  import { socketPath, ensureSessionsDir } from "./paths";
6
6
  import { sendMessage } from "./client";
7
7
 
8
- const HELP = `usage: noninteractive <command> [args]
8
+ const HELP = `noninteractive run interactive CLI commands non-interactively.
9
+
10
+ usage: npx noninteractive <command> [args]
9
11
 
10
12
  commands:
11
- start <cmd> [args...] start a session running <cmd>
12
- read <session> read terminal output
13
- send <session> <text> send keystrokes (empty string for Enter)
13
+ start <cmd> [args...] start a session running <cmd>
14
+ read <session> read current terminal output
15
+ send <session> <text> send keystrokes (use "" for Enter)
14
16
  stop <session> stop a session
15
17
  list show active sessions
16
18
 
17
- examples:
18
- npx noninteractive start npx vercel
19
- npx noninteractive start vercel login
20
- npx noninteractive read vercel
21
- npx noninteractive send vercel ""
22
- npx noninteractive send vercel "y"
23
- npx noninteractive stop vercel
19
+ the first argument to "start" is the command to run, NOT a session name.
20
+ the session name is auto-derived from the command (e.g. "npx vercel" → session "vercel").
21
+
22
+ example workflow:
23
+ npx noninteractive start npx vercel # starts "npx vercel", session name = "vercel"
24
+ npx noninteractive read vercel # see what's on screen
25
+ npx noninteractive send vercel "" # press Enter
26
+ npx noninteractive send vercel "y" # type "y" and press Enter
27
+ npx noninteractive read vercel # see updated output
28
+ npx noninteractive stop vercel # done, stop the session
24
29
 
25
- session name is derived from the command automatically.
26
- use read/send/stop with that name to interact with the session.`;
30
+ more examples:
31
+ npx noninteractive start npx workos # session "workos"
32
+ npx noninteractive start vercel login # session "vercel"
33
+ npx noninteractive start npx supabase init # session "supabase"`;
27
34
 
28
35
  function getSelfCommand(): string[] {
29
36
  if (process.argv[1] && /\.(ts|js)$/.test(process.argv[1])) {
@@ -54,8 +61,17 @@ async function start(cmdArgs: string[]) {
54
61
  const res = await sendMessage(sock, { action: "read" });
55
62
  if (res.ok) {
56
63
  process.stdout.write(res.output ?? "");
57
- console.log(`\n[session '${name}' already running]`);
58
- return;
64
+ if (res.exited) {
65
+ console.log(`\n[session '${name}' already exists but exited ${res.exitCode} — stopping it]`);
66
+ try { await sendMessage(sock, { action: "stop" }); } catch {}
67
+ // fall through to start a new session
68
+ } else {
69
+ console.log(`\n[session '${name}' already running — read the output above, then use:]`);
70
+ console.log(` npx noninteractive send ${name} "<text>" # send keystrokes (use "" for Enter)`);
71
+ console.log(` npx noninteractive read ${name} # read updated output`);
72
+ console.log(` npx noninteractive stop ${name} # stop the session`);
73
+ return;
74
+ }
59
75
  }
60
76
  } catch {}
61
77
 
@@ -76,7 +92,11 @@ async function start(cmdArgs: string[]) {
76
92
  }
77
93
 
78
94
  if (!existsSync(sock)) {
79
- console.error("timeout: failed to start session");
95
+ console.error(`error: failed to start session '${name}'.`);
96
+ console.error(`the command was: ${executable} ${args.join(" ")}`);
97
+ console.error(`\nmake sure the command exists. examples:`);
98
+ console.error(` npx noninteractive start npx vercel # run an npx package`);
99
+ console.error(` npx noninteractive start vercel login # run a command directly`);
80
100
  process.exit(1);
81
101
  }
82
102
 
@@ -89,18 +109,34 @@ async function start(cmdArgs: string[]) {
89
109
  const clean = stripAnsi(res.output ?? "").trim();
90
110
  if (clean.length > 10) {
91
111
  process.stdout.write(res.output);
92
- console.log(`\n[session '${name}' started]`);
112
+ if (res.exited) {
113
+ console.log(`\n[session '${name}' exited ${res.exitCode} — the command failed]`);
114
+ console.log(`hint: the first argument to "start" is the command to run, NOT a session name.`);
115
+ console.log(` npx noninteractive start npx vercel # run an npx package`);
116
+ console.log(` npx noninteractive start vercel login # run a command directly`);
117
+ } else {
118
+ console.log(`\n[session '${name}' started — read the output above, then use:]`);
119
+ console.log(` npx noninteractive send ${name} "<text>" # send keystrokes (use "" for Enter)`);
120
+ console.log(` npx noninteractive read ${name} # read updated output`);
121
+ console.log(` npx noninteractive stop ${name} # stop the session`);
122
+ }
93
123
  return;
94
124
  }
95
125
  if (res.exited) {
96
126
  process.stdout.write(res.output ?? "");
97
- console.log(`\n[session '${name}' exited ${res.exitCode}]`);
127
+ console.log(`\n[session '${name}' exited ${res.exitCode} — the command failed]`);
128
+ console.log(`hint: the first argument to "start" is the command to run, NOT a session name.`);
129
+ console.log(` npx noninteractive start npx vercel # run an npx package`);
130
+ console.log(` npx noninteractive start vercel login # run a command directly`);
98
131
  return;
99
132
  }
100
133
  } catch {}
101
134
  }
102
135
 
103
- console.log(`[session '${name}' started]`);
136
+ console.log(`[session '${name}' started but no output yet — use:]`);
137
+ console.log(` npx noninteractive read ${name} # read output`);
138
+ console.log(` npx noninteractive send ${name} "<text>" # send keystrokes (use "" for Enter)`);
139
+ console.log(` npx noninteractive stop ${name} # stop the session`);
104
140
  }
105
141
 
106
142
  async function read(name: string) {
@@ -113,6 +149,7 @@ async function read(name: string) {
113
149
  async function send(name: string, text: string) {
114
150
  const sock = socketPath(name);
115
151
  await sendMessage(sock, { action: "send", data: text });
152
+ console.log(`[sent to '${name}' — run "npx noninteractive read ${name}" to see the result]`);
116
153
  }
117
154
 
118
155
  async function stop(name: string) {