noninteractive 0.3.0 → 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.
- package/package.json +1 -1
- package/src/index.ts +39 -16
- package/src/__pycache__/pty.cpython-314.pyc +0 -0
package/package.json
CHANGED
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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
136
|
-
|
|
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 <
|
|
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 <
|
|
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 <
|
|
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":
|
|
Binary file
|