noninteractive 0.3.1 → 0.3.2

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 +39 -16
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "noninteractive",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "noninteractive": "./src/index.ts"
package/src/index.ts CHANGED
@@ -7,11 +7,23 @@ import { sendMessage } from "./client";
7
7
 
8
8
  const HELP = `usage: noninteractive <command> [args]
9
9
 
10
- start <name> [args...] start a session (runs npx <name>)
11
- read <name> read terminal output
12
- send <name> <text> send keystrokes to session
13
- stop <name> stop a session
14
- list show active sessions`;
10
+ 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)
14
+ stop <session> stop a session
15
+ list show active sessions
16
+
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
24
+
25
+ session name is derived from the command automatically.
26
+ use read/send/stop with that name to interact with the session.`;
15
27
 
16
28
  function getSelfCommand(): string[] {
17
29
  if (process.argv[1] && /\.(ts|js)$/.test(process.argv[1])) {
@@ -20,7 +32,22 @@ function getSelfCommand(): string[] {
20
32
  return [process.argv[0]];
21
33
  }
22
34
 
23
- async function start(name: string, args: string[]) {
35
+ function deriveSessionName(cmd: string, args: string[]): string {
36
+ const parts = [cmd, ...args];
37
+ // skip npx/bunx prefix to get the real command name
38
+ let i = 0;
39
+ if (parts[i] === "npx" || parts[i] === "bunx") i++;
40
+ // skip flags like -y, --yes
41
+ while (i < parts.length && parts[i].startsWith("-")) i++;
42
+ const name = parts[i] || cmd;
43
+ // strip npm scope @foo/bar -> bar
44
+ return name.replace(/^@[^/]+\//, "").replace(/[^a-zA-Z0-9_-]/g, "");
45
+ }
46
+
47
+ async function start(cmdArgs: string[]) {
48
+ const executable = cmdArgs[0];
49
+ const args = cmdArgs.slice(1);
50
+ const name = deriveSessionName(executable, args);
24
51
  const sock = socketPath(name);
25
52
 
26
53
  try {
@@ -36,7 +63,7 @@ async function start(name: string, args: string[]) {
36
63
  try { const { unlinkSync } = await import("node:fs"); unlinkSync(sock); } catch {}
37
64
 
38
65
  const self = getSelfCommand();
39
- const child = spawn(self[0], [...self.slice(1), "__daemon__", name, "npx", name, ...args], {
66
+ const child = spawn(self[0], [...self.slice(1), "__daemon__", name, executable, ...args], {
40
67
  detached: true,
41
68
  stdio: "ignore",
42
69
  });
@@ -74,9 +101,6 @@ async function start(name: string, args: string[]) {
74
101
  }
75
102
 
76
103
  console.log(`[session '${name}' started]`);
77
-
78
- console.error("timeout: failed to start session");
79
- process.exit(1);
80
104
  }
81
105
 
82
106
  async function read(name: string) {
@@ -132,24 +156,23 @@ async function main() {
132
156
 
133
157
  switch (cmd) {
134
158
  case "start": {
135
- const name = args[1];
136
- if (!name) { console.error("usage: noninteractive start <name> [args...]"); process.exit(1); }
137
- return start(name, args.slice(2));
159
+ if (args.length < 2) { console.error("usage: noninteractive start <cmd> [args...]\n\nexample: npx noninteractive start npx vercel"); process.exit(1); }
160
+ return start(args.slice(1));
138
161
  }
139
162
  case "read": {
140
163
  const name = args[1];
141
- if (!name) { console.error("usage: noninteractive read <name>"); process.exit(1); }
164
+ if (!name) { console.error("usage: noninteractive read <session>\n\nexample: npx noninteractive read vercel"); process.exit(1); }
142
165
  return read(name);
143
166
  }
144
167
  case "send": {
145
168
  const name = args[1];
146
169
  const text = args[2];
147
- if (!name || text === undefined) { console.error("usage: noninteractive send <name> <text>"); process.exit(1); }
170
+ if (!name || text === undefined) { console.error("usage: noninteractive send <session> <text>\n\nexample: npx noninteractive send vercel \"y\""); process.exit(1); }
148
171
  return send(name, text);
149
172
  }
150
173
  case "stop": {
151
174
  const name = args[1];
152
- if (!name) { console.error("usage: noninteractive stop <name>"); process.exit(1); }
175
+ if (!name) { console.error("usage: noninteractive stop <session>\n\nexample: npx noninteractive stop vercel"); process.exit(1); }
153
176
  return stop(name);
154
177
  }
155
178
  case "list":