@termfleet/terminal 0.1.0 → 0.1.1
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/README.md +4 -0
- package/dist/tmux.d.ts +6 -1
- package/dist/tmux.js +15 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -29,3 +29,7 @@ Created sessions can carry an app-namespaced ownership mark; discovery does not
|
|
|
29
29
|
claim or terminate unmarked sessions. Terminal attachment is intentionally
|
|
30
30
|
separate from session termination: disposing a viewer only detaches its
|
|
31
31
|
ephemeral PTY client and releases all handles.
|
|
32
|
+
|
|
33
|
+
`createSession` accepts a structured `{ program, arguments }` command plus an
|
|
34
|
+
environment map. Arguments are passed directly without constructing a shell
|
|
35
|
+
command, and the credential bootstrap deletes itself before the command starts.
|
package/dist/tmux.d.ts
CHANGED
|
@@ -9,7 +9,12 @@ export type TmuxWindowSize = {
|
|
|
9
9
|
width: number;
|
|
10
10
|
height: number;
|
|
11
11
|
};
|
|
12
|
+
export type TmuxCommand = {
|
|
13
|
+
arguments?: string[];
|
|
14
|
+
program: string;
|
|
15
|
+
};
|
|
12
16
|
export type CreateSessionOptions = {
|
|
17
|
+
command?: TmuxCommand;
|
|
13
18
|
cwd?: string;
|
|
14
19
|
env?: Record<string, string>;
|
|
15
20
|
name: string;
|
|
@@ -21,7 +26,7 @@ export type CreateSessionOptions = {
|
|
|
21
26
|
export declare function assertTmux(): void;
|
|
22
27
|
export declare function targetForSession(sessionName: string): string;
|
|
23
28
|
export declare function assertSession(name: string, socket?: string): void;
|
|
24
|
-
export declare function createSession({ cwd, env, name, owner, ownerOption: ownershipOption, panes, socket }: CreateSessionOptions): Promise<{
|
|
29
|
+
export declare function createSession({ command, cwd, env, name, owner, ownerOption: ownershipOption, panes, socket }: CreateSessionOptions): Promise<{
|
|
25
30
|
name: string;
|
|
26
31
|
panes: number;
|
|
27
32
|
}>;
|
package/dist/tmux.js
CHANGED
|
@@ -40,7 +40,7 @@ export function assertSession(name, socket) {
|
|
|
40
40
|
// createWindowSession), so every tmux invocation here uses runAsync (spawn, not
|
|
41
41
|
// spawnSync) and the pane-ready poll below uses sleepAsync — see waitForPanesReady.
|
|
42
42
|
// Nothing in this function may block the loop.
|
|
43
|
-
export async function createSession({ cwd, env, name, owner, ownerOption: ownershipOption = ownerOption, panes, socket }) {
|
|
43
|
+
export async function createSession({ command, cwd, env, name, owner, ownerOption: ownershipOption = ownerOption, panes, socket }) {
|
|
44
44
|
assertTmux();
|
|
45
45
|
if (!name) {
|
|
46
46
|
throw new Error("--name is required.");
|
|
@@ -48,6 +48,9 @@ export async function createSession({ cwd, env, name, owner, ownerOption: owners
|
|
|
48
48
|
if (!Number.isInteger(panes) || panes < 1) {
|
|
49
49
|
throw new Error("--panes must be a positive integer.");
|
|
50
50
|
}
|
|
51
|
+
if (command !== undefined && !command.program) {
|
|
52
|
+
throw new Error("A command program is required.");
|
|
53
|
+
}
|
|
51
54
|
// Global server options must be in place before the first pane spawns —
|
|
52
55
|
// history-limit is read at pane creation. On a fresh dedicated `-L` socket no
|
|
53
56
|
// server exists yet and `set-option -g` will NOT start one (only commands like
|
|
@@ -58,11 +61,13 @@ export async function createSession({ cwd, env, name, owner, ownerOption: owners
|
|
|
58
61
|
const sessionEnv = env ?? {};
|
|
59
62
|
const bootstrapDirectories = [];
|
|
60
63
|
const paneBootstrapArgs = (pane) => {
|
|
64
|
+
const commandArgs = command === undefined ? [] : [command.program, ...(command.arguments ?? [])];
|
|
61
65
|
if (Object.keys(sessionEnv).length === 0)
|
|
62
|
-
return
|
|
66
|
+
return commandArgs;
|
|
63
67
|
const directory = mkdtempSync(join(tmpdir(), "tmux-session-env-"));
|
|
64
68
|
bootstrapDirectories.push(directory);
|
|
65
|
-
|
|
69
|
+
const shell = process.env.SHELL ?? "/bin/sh";
|
|
70
|
+
return writeSessionEnvironmentBootstrap(directory, pane, sessionEnv, commandArgs.length === 0 ? [shell, "-l"] : commandArgs);
|
|
66
71
|
};
|
|
67
72
|
try {
|
|
68
73
|
const startArgs = [...sessionServerOptionArgs(), "new-session", "-d", "-s", name];
|
|
@@ -271,10 +276,9 @@ function tmuxClientEnvironment(source = process.env) {
|
|
|
271
276
|
}
|
|
272
277
|
return environment;
|
|
273
278
|
}
|
|
274
|
-
function writeSessionEnvironmentBootstrap(directory, pane, environment) {
|
|
279
|
+
function writeSessionEnvironmentBootstrap(directory, pane, environment, command) {
|
|
275
280
|
const environmentPath = join(directory, `pane-${pane}.env`);
|
|
276
281
|
const wrapperPath = join(directory, `pane-${pane}.sh`);
|
|
277
|
-
const shell = process.env.SHELL ?? "/bin/sh";
|
|
278
282
|
const lines = Object.entries(environment).map(([name, value]) => {
|
|
279
283
|
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name)) {
|
|
280
284
|
throw new Error(`Invalid session environment variable name: ${JSON.stringify(name)}.`);
|
|
@@ -284,15 +288,17 @@ function writeSessionEnvironmentBootstrap(directory, pane, environment) {
|
|
|
284
288
|
writeFileSync(environmentPath, `${lines.join("\n")}\n`, { flag: "wx", mode: 0o600 });
|
|
285
289
|
writeFileSync(wrapperPath, [
|
|
286
290
|
"#!/bin/sh",
|
|
291
|
+
'environment_path="$1"',
|
|
292
|
+
"shift",
|
|
287
293
|
"set -a",
|
|
288
|
-
'. "$
|
|
294
|
+
'. "$environment_path"',
|
|
289
295
|
"set +a",
|
|
290
|
-
'rm -f -- "$
|
|
296
|
+
'rm -f -- "$environment_path" "$0"',
|
|
291
297
|
'rmdir -- "$(dirname -- "$0")" 2>/dev/null || true',
|
|
292
|
-
'exec "
|
|
298
|
+
'exec "$@"',
|
|
293
299
|
""
|
|
294
300
|
].join("\n"), { flag: "wx", mode: 0o700 });
|
|
295
|
-
return [wrapperPath, environmentPath,
|
|
301
|
+
return [wrapperPath, environmentPath, ...command];
|
|
296
302
|
}
|
|
297
303
|
function shellQuote(value) {
|
|
298
304
|
return `'${value.replaceAll("'", `'"'"'`)}'`;
|