@indianic/dialout 1.1.2 → 1.2.0
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 +420 -24
- package/bin/AGENTS.md +44 -0
- package/bin/devdash-agent.js +2 -0
- package/dist/ai-adapters/claude.d.ts +3 -0
- package/dist/ai-adapters/claude.d.ts.map +1 -0
- package/dist/ai-adapters/claude.js +98 -0
- package/dist/ai-adapters/claude.js.map +1 -0
- package/dist/ai-adapters/codex.d.ts +3 -0
- package/dist/ai-adapters/codex.d.ts.map +1 -0
- package/dist/ai-adapters/codex.js +147 -0
- package/dist/ai-adapters/codex.js.map +1 -0
- package/dist/ai-adapters/grok.d.ts +3 -0
- package/dist/ai-adapters/grok.d.ts.map +1 -0
- package/dist/ai-adapters/grok.js +164 -0
- package/dist/ai-adapters/grok.js.map +1 -0
- package/dist/ai-adapters/index.d.ts +5 -0
- package/dist/ai-adapters/index.d.ts.map +1 -0
- package/dist/ai-adapters/index.js +30 -0
- package/dist/ai-adapters/index.js.map +1 -0
- package/dist/ai-adapters/types.d.ts +3 -0
- package/dist/ai-adapters/types.d.ts.map +1 -0
- package/dist/ai-adapters/types.js +7 -0
- package/dist/ai-adapters/types.js.map +1 -0
- package/dist/ai-capabilities/claude.d.ts +4 -0
- package/dist/ai-capabilities/claude.d.ts.map +1 -0
- package/dist/ai-capabilities/claude.js +174 -0
- package/dist/ai-capabilities/claude.js.map +1 -0
- package/dist/ai-capabilities/describe.d.ts +2 -0
- package/dist/ai-capabilities/describe.d.ts.map +1 -0
- package/dist/ai-capabilities/describe.js +31 -0
- package/dist/ai-capabilities/describe.js.map +1 -0
- package/dist/ai-capabilities/fsdeps.d.ts +3 -0
- package/dist/ai-capabilities/fsdeps.d.ts.map +1 -0
- package/dist/ai-capabilities/fsdeps.js +71 -0
- package/dist/ai-capabilities/fsdeps.js.map +1 -0
- package/dist/ai-capabilities/grok.d.ts +5 -0
- package/dist/ai-capabilities/grok.d.ts.map +1 -0
- package/dist/ai-capabilities/grok.js +145 -0
- package/dist/ai-capabilities/grok.js.map +1 -0
- package/dist/ai-capabilities/index.d.ts +4 -0
- package/dist/ai-capabilities/index.d.ts.map +1 -0
- package/dist/ai-capabilities/index.js +94 -0
- package/dist/ai-capabilities/index.js.map +1 -0
- package/dist/ai-capabilities/redact.d.ts +2 -0
- package/dist/ai-capabilities/redact.d.ts.map +1 -0
- package/dist/ai-capabilities/redact.js +27 -0
- package/dist/ai-capabilities/redact.js.map +1 -0
- package/dist/ai-capabilities/types.d.ts +11 -0
- package/dist/ai-capabilities/types.d.ts.map +1 -0
- package/dist/ai-capabilities/types.js +3 -0
- package/dist/ai-capabilities/types.js.map +1 -0
- package/dist/ai-launch.d.ts +35 -0
- package/dist/ai-launch.d.ts.map +1 -0
- package/dist/ai-launch.js +211 -0
- package/dist/ai-launch.js.map +1 -0
- package/dist/ai-session-detector.d.ts +19 -0
- package/dist/ai-session-detector.d.ts.map +1 -0
- package/dist/ai-session-detector.js +79 -0
- package/dist/ai-session-detector.js.map +1 -0
- package/dist/ai-sessions.d.ts +36 -0
- package/dist/ai-sessions.d.ts.map +1 -0
- package/dist/ai-sessions.js +309 -0
- package/dist/ai-sessions.js.map +1 -0
- package/dist/ai-status.d.ts +6 -0
- package/dist/ai-status.d.ts.map +1 -0
- package/dist/ai-status.js +40 -0
- package/dist/ai-status.js.map +1 -0
- package/dist/ai-transcript-locator.d.ts +35 -0
- package/dist/ai-transcript-locator.d.ts.map +1 -0
- package/dist/ai-transcript-locator.js +268 -0
- package/dist/ai-transcript-locator.js.map +1 -0
- package/dist/ai-transcript-tail.d.ts +17 -0
- package/dist/ai-transcript-tail.d.ts.map +1 -0
- package/dist/ai-transcript-tail.js +120 -0
- package/dist/ai-transcript-tail.js.map +1 -0
- package/dist/checklist.d.ts +20 -0
- package/dist/checklist.d.ts.map +1 -0
- package/dist/checklist.js +51 -0
- package/dist/checklist.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +1427 -0
- package/dist/cli.js.map +1 -0
- package/dist/command-runner.d.ts +15 -0
- package/dist/command-runner.d.ts.map +1 -0
- package/dist/command-runner.js +84 -0
- package/dist/command-runner.js.map +1 -0
- package/dist/config.d.ts +41 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +152 -0
- package/dist/config.js.map +1 -0
- package/dist/cowork.d.ts +26 -0
- package/dist/cowork.d.ts.map +1 -0
- package/dist/cowork.js +370 -0
- package/dist/cowork.js.map +1 -0
- package/dist/fs-browser.d.ts +6 -0
- package/dist/fs-browser.d.ts.map +1 -0
- package/dist/fs-browser.js +61 -0
- package/dist/fs-browser.js.map +1 -0
- package/dist/has-command.d.ts +12 -0
- package/dist/has-command.d.ts.map +1 -0
- package/dist/has-command.js +24 -0
- package/dist/has-command.js.map +1 -0
- package/dist/heartbeat.d.ts +7 -0
- package/dist/heartbeat.d.ts.map +1 -0
- package/dist/heartbeat.js +50 -0
- package/dist/heartbeat.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/port-scanner.d.ts +4 -0
- package/dist/port-scanner.d.ts.map +1 -0
- package/dist/port-scanner.js +75 -0
- package/dist/port-scanner.js.map +1 -0
- package/dist/project-scanner.d.ts +15 -0
- package/dist/project-scanner.d.ts.map +1 -0
- package/dist/project-scanner.js +333 -0
- package/dist/project-scanner.js.map +1 -0
- package/dist/pty-manager.d.ts +28 -0
- package/dist/pty-manager.d.ts.map +1 -0
- package/dist/pty-manager.js +506 -0
- package/dist/pty-manager.js.map +1 -0
- package/dist/service-installer.d.ts +95 -0
- package/dist/service-installer.d.ts.map +1 -0
- package/dist/service-installer.js +911 -0
- package/dist/service-installer.js.map +1 -0
- package/dist/single-instance.d.ts +20 -0
- package/dist/single-instance.d.ts.map +1 -0
- package/dist/single-instance.js +151 -0
- package/dist/single-instance.js.map +1 -0
- package/dist/ssh-local-network.d.ts +26 -0
- package/dist/ssh-local-network.d.ts.map +1 -0
- package/dist/ssh-local-network.js +169 -0
- package/dist/ssh-local-network.js.map +1 -0
- package/dist/terminal-detect.d.ts +52 -0
- package/dist/terminal-detect.d.ts.map +1 -0
- package/dist/terminal-detect.js +147 -0
- package/dist/terminal-detect.js.map +1 -0
- package/dist/terminal-markers.d.ts +52 -0
- package/dist/terminal-markers.d.ts.map +1 -0
- package/dist/terminal-markers.js +174 -0
- package/dist/terminal-markers.js.map +1 -0
- package/dist/tmux-manager.d.ts +35 -0
- package/dist/tmux-manager.d.ts.map +1 -0
- package/dist/tmux-manager.js +274 -0
- package/dist/tmux-manager.js.map +1 -0
- package/dist/update-check.d.ts +3 -0
- package/dist/update-check.d.ts.map +1 -0
- package/dist/update-check.js +202 -0
- package/dist/update-check.js.map +1 -0
- package/dist/websocket.d.ts +8 -0
- package/dist/websocket.d.ts.map +1 -0
- package/dist/websocket.js +472 -0
- package/dist/websocket.js.map +1 -0
- package/node_modules/@dialout/shared/README.md +16 -0
- package/node_modules/@dialout/shared/dist/ai-chat-prefs.d.ts +8 -0
- package/node_modules/@dialout/shared/dist/ai-chat-prefs.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/ai-chat-prefs.js +41 -0
- package/node_modules/@dialout/shared/dist/capabilities.d.ts +25 -0
- package/node_modules/@dialout/shared/dist/capabilities.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/capabilities.js +2 -0
- package/node_modules/@dialout/shared/dist/chat-blocks.d.ts +33 -0
- package/node_modules/@dialout/shared/dist/chat-blocks.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/chat-blocks.js +61 -0
- package/node_modules/@dialout/shared/dist/command-filter.d.ts +4 -0
- package/node_modules/@dialout/shared/dist/command-filter.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/command-filter.js +49 -0
- package/node_modules/@dialout/shared/dist/composer-behaviour.d.ts +6 -0
- package/node_modules/@dialout/shared/dist/composer-behaviour.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/composer-behaviour.js +24 -0
- package/node_modules/@dialout/shared/dist/events.d.ts +37 -0
- package/node_modules/@dialout/shared/dist/events.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/events.js +13 -0
- package/node_modules/@dialout/shared/dist/index.d.ts +21 -0
- package/node_modules/@dialout/shared/dist/index.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/index.js +37 -0
- package/node_modules/@dialout/shared/dist/kinds.d.ts +2 -0
- package/node_modules/@dialout/shared/dist/kinds.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/kinds.js +2 -0
- package/node_modules/@dialout/shared/dist/notify.d.ts +3 -0
- package/node_modules/@dialout/shared/dist/notify.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/notify.js +31 -0
- package/node_modules/@dialout/shared/dist/permission.d.ts +4 -0
- package/node_modules/@dialout/shared/dist/permission.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/permission.js +8 -0
- package/node_modules/@dialout/shared/dist/scroll-pin.d.ts +3 -0
- package/node_modules/@dialout/shared/dist/scroll-pin.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/scroll-pin.js +11 -0
- package/node_modules/@dialout/shared/dist/session.d.ts +19 -0
- package/node_modules/@dialout/shared/dist/session.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/session.js +6 -0
- package/node_modules/@dialout/shared/dist/terminal-name.d.ts +25 -0
- package/node_modules/@dialout/shared/dist/terminal-name.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/terminal-name.js +63 -0
- package/node_modules/@dialout/shared/dist/tool-appearance.d.ts +9 -0
- package/node_modules/@dialout/shared/dist/tool-appearance.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/tool-appearance.js +30 -0
- package/node_modules/@dialout/shared/package.json +37 -0
- package/node_modules/@dialout/shared/src/ai-chat-prefs.test.ts +40 -0
- package/node_modules/@dialout/shared/src/ai-chat-prefs.ts +39 -0
- package/node_modules/@dialout/shared/src/capabilities.ts +30 -0
- package/node_modules/@dialout/shared/src/chat-blocks.test.ts +65 -0
- package/node_modules/@dialout/shared/src/chat-blocks.ts +79 -0
- package/node_modules/@dialout/shared/src/command-filter.test.ts +76 -0
- package/node_modules/@dialout/shared/src/command-filter.ts +45 -0
- package/node_modules/@dialout/shared/src/composer-behaviour.test.ts +31 -0
- package/node_modules/@dialout/shared/src/composer-behaviour.ts +22 -0
- package/node_modules/@dialout/shared/src/events.ts +27 -0
- package/node_modules/@dialout/shared/src/index.ts +32 -0
- package/node_modules/@dialout/shared/src/kinds.ts +5 -0
- package/node_modules/@dialout/shared/src/notify.test.ts +49 -0
- package/node_modules/@dialout/shared/src/notify.ts +30 -0
- package/node_modules/@dialout/shared/src/permission.ts +10 -0
- package/node_modules/@dialout/shared/src/scroll-pin.test.ts +23 -0
- package/node_modules/@dialout/shared/src/scroll-pin.ts +13 -0
- package/node_modules/@dialout/shared/src/session.ts +25 -0
- package/node_modules/@dialout/shared/src/terminal-name.ts +82 -0
- package/node_modules/@dialout/shared/src/tool-appearance.test.ts +41 -0
- package/node_modules/@dialout/shared/src/tool-appearance.ts +39 -0
- package/package.json +54 -14
- package/scripts/postinstall.js +79 -0
- package/scripts/prepack.js +45 -0
- package/bin/dialout.js +0 -13
|
@@ -0,0 +1,506 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.setActiveSocket = setActiveSocket;
|
|
37
|
+
exports.isPtyAvailable = isPtyAvailable;
|
|
38
|
+
exports.openSession = openSession;
|
|
39
|
+
exports.clipboardCommand = clipboardCommand;
|
|
40
|
+
exports.copyVerb = copyVerb;
|
|
41
|
+
exports.clipboardBindings = clipboardBindings;
|
|
42
|
+
exports.applyNativeTmuxOptions = applyNativeTmuxOptions;
|
|
43
|
+
exports.tmuxSessionExists = tmuxSessionExists;
|
|
44
|
+
exports.applyBrowserSessionOptions = applyBrowserSessionOptions;
|
|
45
|
+
exports.openAttach = openAttach;
|
|
46
|
+
exports.writeToSession = writeToSession;
|
|
47
|
+
exports.resizeSession = resizeSession;
|
|
48
|
+
exports.closeSession = closeSession;
|
|
49
|
+
exports.detachPtySession = detachPtySession;
|
|
50
|
+
exports.closeAllSessions = closeAllSessions;
|
|
51
|
+
exports.getActiveSessions = getActiveSessions;
|
|
52
|
+
const os = __importStar(require("os"));
|
|
53
|
+
const fs = __importStar(require("fs"));
|
|
54
|
+
const child_process_1 = require("child_process");
|
|
55
|
+
const tmux_manager_1 = require("./tmux-manager");
|
|
56
|
+
const has_command_1 = require("./has-command");
|
|
57
|
+
// node-pty is optional — only loaded when terminal sessions are used
|
|
58
|
+
let pty = null;
|
|
59
|
+
try {
|
|
60
|
+
pty = require('node-pty');
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// node-pty not available — terminal features disabled
|
|
64
|
+
}
|
|
65
|
+
const sessions = new Map();
|
|
66
|
+
// PTY output is routed through the currently active server socket rather
|
|
67
|
+
// than the one captured at spawn time, so sessions survive daemon
|
|
68
|
+
// reconnects: on reconnect the new socket takes over the stream.
|
|
69
|
+
let activeWs = null;
|
|
70
|
+
function setActiveSocket(ws) {
|
|
71
|
+
activeWs = ws;
|
|
72
|
+
}
|
|
73
|
+
function isPtyAvailable() {
|
|
74
|
+
return pty !== null;
|
|
75
|
+
}
|
|
76
|
+
function openSession(id, command, cwd, cols = 80, rows = 24, opts = {}) {
|
|
77
|
+
if (!pty)
|
|
78
|
+
return false;
|
|
79
|
+
// Idempotent: if session already exists, skip
|
|
80
|
+
if (sessions.has(id)) {
|
|
81
|
+
console.log(`[dialout] Session ${id} already exists, skipping`);
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
const shell = process.env.SHELL || '/bin/zsh';
|
|
85
|
+
// Resolve ~ and validate cwd
|
|
86
|
+
let resolvedCwd = cwd;
|
|
87
|
+
if (resolvedCwd === '~' || resolvedCwd.startsWith('~/')) {
|
|
88
|
+
resolvedCwd = resolvedCwd.replace('~', os.homedir());
|
|
89
|
+
}
|
|
90
|
+
if (!resolvedCwd || !fs.existsSync(resolvedCwd)) {
|
|
91
|
+
resolvedCwd = os.homedir();
|
|
92
|
+
}
|
|
93
|
+
let proc;
|
|
94
|
+
let tmuxMeta;
|
|
95
|
+
// Set when we attached to a session that was already running. The startup
|
|
96
|
+
// command must NOT be replayed into it — see the guard at the bottom.
|
|
97
|
+
let resumed = false;
|
|
98
|
+
if (opts.coworkWrap) {
|
|
99
|
+
// Wrap the browser shell in tmux so it survives the tab closing and other
|
|
100
|
+
// devices can attach to it.
|
|
101
|
+
// Fail open: any tmux error falls back to the plain shell below.
|
|
102
|
+
const tmuxName = (0, tmux_manager_1.tmuxSessionName)(id);
|
|
103
|
+
// Only true once WE created this session — the cleanup below must never
|
|
104
|
+
// kill a session that already existed under this name.
|
|
105
|
+
let createdByUs = false;
|
|
106
|
+
try {
|
|
107
|
+
const tmuxRun = (args) => {
|
|
108
|
+
(0, child_process_1.execFileSync)('tmux', args, { timeout: 5000, stdio: 'pipe' });
|
|
109
|
+
};
|
|
110
|
+
// Resume path. tmuxSessionName() is deterministic, so the same browser
|
|
111
|
+
// sessionId always maps to the same tmux session — which is exactly what
|
|
112
|
+
// makes a web terminal resumable: reopening the dock (or the Web tab's
|
|
113
|
+
// Resume) re-runs openSession with the stored id and lands back in the
|
|
114
|
+
// running shell. Without this check `new-session -s` would fail on the
|
|
115
|
+
// duplicate name, fall into the catch, and silently hand the user a
|
|
116
|
+
// fresh plain shell while their work sat in the orphaned session.
|
|
117
|
+
if (tmuxSessionExists(tmuxName)) {
|
|
118
|
+
console.log(`[dialout] Resuming existing tmux session ${tmuxName}`);
|
|
119
|
+
resumed = true;
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
tmuxRun(['new-session', '-d', '-s', tmuxName, '-x', String(cols), '-y', String(rows), '-c', resolvedCwd]);
|
|
123
|
+
createdByUs = true;
|
|
124
|
+
tmuxRun(['set-option', '-t', tmuxName, '@devdash_origin', 'browser']);
|
|
125
|
+
tmuxRun(['set-option', '-t', tmuxName, '@term_program', 'DevDash']);
|
|
126
|
+
tmuxRun(['set-window-option', '-t', tmuxName, 'window-size', 'latest']);
|
|
127
|
+
tmuxRun(['set-window-option', '-t', tmuxName, 'aggressive-resize', 'on']);
|
|
128
|
+
const base = resolvedCwd.split('/').filter(Boolean).pop() || '';
|
|
129
|
+
const nowIso = new Date().toISOString().replace(/\.\d+Z$/, '').replace('Z', '');
|
|
130
|
+
tmuxRun(['set-option', '-t', tmuxName, '@devdash_folder', base]);
|
|
131
|
+
tmuxRun(['set-option', '-t', tmuxName, '@devdash_folder_path', resolvedCwd]);
|
|
132
|
+
tmuxRun(['set-option', '-t', tmuxName, '@devdash_created', nowIso]);
|
|
133
|
+
let branch = '';
|
|
134
|
+
try {
|
|
135
|
+
branch = (0, child_process_1.execFileSync)('git', ['-C', resolvedCwd, 'rev-parse', '--abbrev-ref', 'HEAD'], { timeout: 3000, stdio: 'pipe' }).toString().trim();
|
|
136
|
+
}
|
|
137
|
+
catch { }
|
|
138
|
+
tmuxRun(['set-option', '-t', tmuxName, '@devdash_git', branch]);
|
|
139
|
+
}
|
|
140
|
+
applyNativeTmuxOptions();
|
|
141
|
+
// Re-applied on resume too, so sessions created before this shipped pick
|
|
142
|
+
// it up on their next attach.
|
|
143
|
+
applyBrowserSessionOptions(tmuxName);
|
|
144
|
+
proc = pty.spawn('tmux', ['attach-session', '-t', tmuxName], {
|
|
145
|
+
name: 'xterm-256color',
|
|
146
|
+
cols,
|
|
147
|
+
rows,
|
|
148
|
+
cwd: resolvedCwd,
|
|
149
|
+
env: { ...process.env, TERM: 'xterm-256color' },
|
|
150
|
+
});
|
|
151
|
+
tmuxMeta = { name: tmuxName, creator: true, readOnly: false };
|
|
152
|
+
}
|
|
153
|
+
catch (err) {
|
|
154
|
+
console.error(`[dialout] cowork wrap failed, plain shell fallback: ${err.message}`);
|
|
155
|
+
// new-session may have succeeded before a later step threw — clean up the
|
|
156
|
+
// half-created session so it doesn't linger untracked. Guard on
|
|
157
|
+
// createdByUs: if new-session ITSELF failed (e.g. duplicate name) the
|
|
158
|
+
// session belongs to someone else and killing it would destroy their
|
|
159
|
+
// running work.
|
|
160
|
+
if (createdByUs) {
|
|
161
|
+
try {
|
|
162
|
+
(0, child_process_1.execFileSync)('tmux', ['kill-session', '-t', tmuxName], { timeout: 5000, stdio: 'pipe' });
|
|
163
|
+
}
|
|
164
|
+
catch { }
|
|
165
|
+
}
|
|
166
|
+
proc = undefined;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (!proc) {
|
|
170
|
+
try {
|
|
171
|
+
proc = pty.spawn(shell, [], {
|
|
172
|
+
name: 'xterm-256color',
|
|
173
|
+
cols,
|
|
174
|
+
rows,
|
|
175
|
+
cwd: resolvedCwd,
|
|
176
|
+
env: { ...process.env, TERM: 'xterm-256color' },
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
catch (err) {
|
|
180
|
+
console.error(`[dialout] PTY spawn failed: ${err.message}`);
|
|
181
|
+
console.error(`[dialout] shell: ${shell}, cwd: ${resolvedCwd}`);
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
proc.onData((data) => {
|
|
186
|
+
if (activeWs && activeWs.readyState === activeWs.OPEN) {
|
|
187
|
+
activeWs.send(JSON.stringify({ type: 'pty_data', id, data }));
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
proc.onExit(({ exitCode }) => {
|
|
191
|
+
sessions.delete(id);
|
|
192
|
+
if (activeWs && activeWs.readyState === activeWs.OPEN) {
|
|
193
|
+
activeWs.send(JSON.stringify({ type: 'pty_exit', id, code: exitCode }));
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
sessions.set(id, { id, process: proc, tmux: tmuxMeta });
|
|
197
|
+
// If a command was specified, send it to the shell after a brief delay.
|
|
198
|
+
//
|
|
199
|
+
// Never on a resume. The browser replays the tab's original command on every
|
|
200
|
+
// open, which is right for a fresh shell and destructive for a running one:
|
|
201
|
+
// resuming a tab that launched `claude` would type "claude\n" straight into
|
|
202
|
+
// the live Claude Code session it just reattached to. A resumed session is
|
|
203
|
+
// already running whatever the user started — it needs no input from us.
|
|
204
|
+
if (command && !resumed) {
|
|
205
|
+
setTimeout(() => {
|
|
206
|
+
proc.write(command + '\n');
|
|
207
|
+
}, 300);
|
|
208
|
+
}
|
|
209
|
+
return true;
|
|
210
|
+
}
|
|
211
|
+
// Attach to an existing tmux session inside a fresh PTY. The tmux client
|
|
212
|
+
// merges input and broadcasts output to all clients — this is the sharing.
|
|
213
|
+
// Make DevDash tmux sessions behave like a plain OS terminal. Applied globally
|
|
214
|
+
// (server-wide) so every session — including native ones the agent never
|
|
215
|
+
// attaches to (e.g. a Hyper window) — is covered, and new sessions inherit it.
|
|
216
|
+
// Each command is best-effort: a no-op or unsupported option never throws out.
|
|
217
|
+
const NATIVE_TMUX_COMMANDS = [
|
|
218
|
+
// Mouse ON — the native-terminal model (iTerm2/Hyper/VSCode all do this):
|
|
219
|
+
// the wheel scrolls back through output/history instead of the shell reading
|
|
220
|
+
// it as up/down arrows (which navigated command history). Plain drag is
|
|
221
|
+
// tmux's own select-and-copy, routed to the system clipboard by
|
|
222
|
+
// clipboardBindings() below.
|
|
223
|
+
//
|
|
224
|
+
// The modifier that BYPASSES mouse reporting for a real OS-level highlight
|
|
225
|
+
// is NOT Shift everywhere, and an earlier version of this comment said it
|
|
226
|
+
// was. Measured against the xterm.js we ship:
|
|
227
|
+
// shouldForceSelection(e) =>
|
|
228
|
+
// isMac ? e.altKey && rawOptions.macOptionClickForcesSelection
|
|
229
|
+
// : e.shiftKey
|
|
230
|
+
// So Shift-drag only works on Linux/xterm/VTE. On macOS it is OPTION-drag,
|
|
231
|
+
// and only when macOptionClickForcesSelection is on — it defaults to FALSE,
|
|
232
|
+
// which left Mac users of Hyper and of our own browser terminal with no
|
|
233
|
+
// working bypass gesture at all. src/components/Terminal.tsx now sets it
|
|
234
|
+
// true; Apple Terminal uses Fn-drag and iTerm2 uses Option-drag natively.
|
|
235
|
+
['set-option', '-g', 'mouse', 'on'],
|
|
236
|
+
// set-clipboard on = tmux emits OSC 52 on every copy. That escape is what
|
|
237
|
+
// carries the text to a REMOTE client's clipboard (the browser tab), and it
|
|
238
|
+
// is the only thing that can — pbcopy below only reaches the clipboard of
|
|
239
|
+
// the machine the agent runs on. Verified: tmux emits OSC 52 on both the
|
|
240
|
+
// piped (pbcopy) and plain copy paths, and `clipboard` is already in
|
|
241
|
+
// terminal-features by default for xterm* (our TERM), so it needs no help.
|
|
242
|
+
['set-option', '-s', 'set-clipboard', 'on'],
|
|
243
|
+
// NOTE: pane-scrollbars (tmux 3.5+) is deliberately NOT enabled. On 3.6a it
|
|
244
|
+
// drove the server to 100% CPU (redraw loop) when multiple differently-sized
|
|
245
|
+
// clients were attached (Hyper + browser PTY) alongside window-size latest /
|
|
246
|
+
// aggressive-resize. Mouse-on already gives native wheel scrolling; the
|
|
247
|
+
// scrollbar is cosmetic and not worth wedging the server.
|
|
248
|
+
// Keep the status line on (user preference).
|
|
249
|
+
['set-option', '-g', 'status', 'on'],
|
|
250
|
+
// Large scrollback (applies to new sessions) + low escape lag.
|
|
251
|
+
['set-option', '-g', 'history-limit', '100000'],
|
|
252
|
+
['set-option', '-sg', 'escape-time', '10'],
|
|
253
|
+
// NOTE: no WheelUpPane binding here on purpose. tmux's own default already
|
|
254
|
+
// is `if-shell "#{||:#{alternate_on},#{pane_in_mode},#{mouse_any_flag}}"
|
|
255
|
+
// { send-keys -M } { copy-mode -e }` — it already uses copy-mode -e (auto-
|
|
256
|
+
// exit at the bottom, so scrolling never leaves you unable to type) AND it
|
|
257
|
+
// also guards on alternate_on, which a hand-rolled binding misses: that
|
|
258
|
+
// check is what lets less/vim scroll natively instead of being hijacked
|
|
259
|
+
// into copy-mode. Overriding it is a regression. Verified on tmux 3.7b.
|
|
260
|
+
// Let apps (Claude Code image paste, graphics/OSC protocols) pass sequences
|
|
261
|
+
// through tmux untouched, and receive focus in/out events.
|
|
262
|
+
['set-option', '-g', 'allow-passthrough', 'on'],
|
|
263
|
+
['set-option', '-g', 'focus-events', 'on'],
|
|
264
|
+
// Remove tmux's right-click context menus so the OS/terminal menu wins.
|
|
265
|
+
['unbind-key', '-n', 'MouseDown3Pane'],
|
|
266
|
+
['unbind-key', '-n', 'MouseDown3Status'],
|
|
267
|
+
['unbind-key', '-n', 'MouseDown3StatusLeft'],
|
|
268
|
+
['unbind-key', '-n', 'MouseDown3StatusRight'],
|
|
269
|
+
['unbind-key', '-n', 'M-MouseDown3Pane'],
|
|
270
|
+
['unbind-key', '-n', 'M-MouseDown3Status'],
|
|
271
|
+
['unbind-key', '-n', 'M-MouseDown3StatusLeft'],
|
|
272
|
+
];
|
|
273
|
+
// Priority order: wl-copy wins when several are present. Each `command` is
|
|
274
|
+
// what gets piped the copy-mode selection, exactly as typed at a shell — see
|
|
275
|
+
// the note on LINUX_CLIPBOARD_TOOLS's caller for why a multi-word entry must
|
|
276
|
+
// stay a single array element.
|
|
277
|
+
const LINUX_CLIPBOARD_TOOLS = [
|
|
278
|
+
{ bin: 'wl-copy', command: 'wl-copy' },
|
|
279
|
+
{ bin: 'xclip', command: 'xclip -selection clipboard' },
|
|
280
|
+
{ bin: 'xsel', command: 'xsel --clipboard --input' },
|
|
281
|
+
];
|
|
282
|
+
// The single shell command that copies stdin to the system clipboard on this
|
|
283
|
+
// machine, or null when there is none. Split out of copyVerb() because two
|
|
284
|
+
// different tmux surfaces need the SAME answer: the explicit bind-keys below,
|
|
285
|
+
// and the `copy-command` server option (see clipboardBindings). Deriving both
|
|
286
|
+
// from one probe is what keeps them from disagreeing.
|
|
287
|
+
function clipboardCommand(deps = {}) {
|
|
288
|
+
const platform = deps.platform ?? process.platform;
|
|
289
|
+
if (platform === 'darwin') {
|
|
290
|
+
return 'pbcopy';
|
|
291
|
+
}
|
|
292
|
+
if (platform === 'linux') {
|
|
293
|
+
const hasCommand = deps.hasCommand ?? has_command_1.hasCommand;
|
|
294
|
+
for (const tool of LINUX_CLIPBOARD_TOOLS) {
|
|
295
|
+
// The command MUST be returned as ONE array element, never split into
|
|
296
|
+
// separate ones (e.g. 'xclip', '-selection', 'clipboard'): tmux's
|
|
297
|
+
// `send-keys -X copy-pipe-and-cancel <arg>` only accepts a single
|
|
298
|
+
// trailing argument, which it then runs through the pane's shell. Extra
|
|
299
|
+
// argv positions are misparsed by tmux as a second command reference
|
|
300
|
+
// ("no current client") and the copy silently never fires — measured
|
|
301
|
+
// directly against tmux 3.7b. A single string like
|
|
302
|
+
// "xclip -selection clipboard" is correctly word-split back apart by
|
|
303
|
+
// the shell that runs it.
|
|
304
|
+
if (hasCommand(tool.bin))
|
|
305
|
+
return tool.command;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
return null;
|
|
309
|
+
}
|
|
310
|
+
function copyVerb(deps = {}) {
|
|
311
|
+
const command = clipboardCommand(deps);
|
|
312
|
+
return command ? ['copy-pipe-and-cancel', command] : ['copy-selection-and-cancel'];
|
|
313
|
+
}
|
|
314
|
+
// Mouse-driven copy, server-wide so every session inherits it.
|
|
315
|
+
//
|
|
316
|
+
// Deliberately minimal. tmux 3.x already binds DoubleClick1Pane (select-word)
|
|
317
|
+
// and TripleClick1Pane (select-line) in the root and copy-mode tables, and
|
|
318
|
+
// those defaults auto-copy AND carry `if-shell` guards on
|
|
319
|
+
// #{pane_in_mode}/#{mouse_any_flag} plus a `run-shell -d 0.3` dwell so the
|
|
320
|
+
// selection is visible before it clears. Re-binding them by hand loses the
|
|
321
|
+
// guards — a double-click inside vim would be swallowed into copy-mode instead
|
|
322
|
+
// of reaching the app. So we leave word/line click alone and override only the
|
|
323
|
+
// copy VERB on drag-release and the keyboard copies, purely to route the copy
|
|
324
|
+
// through pbcopy on macOS. The -and-cancel semantics match tmux's own default;
|
|
325
|
+
// see copyVerb above for why -no-clear is not an option.
|
|
326
|
+
function clipboardBindings() {
|
|
327
|
+
const copy = copyVerb();
|
|
328
|
+
const command = clipboardCommand();
|
|
329
|
+
const cmds = [];
|
|
330
|
+
// `copy-command` is what makes the UNARGUMENTED `copy-pipe-and-cancel` in
|
|
331
|
+
// tmux's OWN DoubleClick1Pane/TripleClick1Pane defaults reach the system
|
|
332
|
+
// clipboard. Leaving those defaults alone (above) preserved their if-shell
|
|
333
|
+
// guards but also left them un-piped: with copy-command empty, a
|
|
334
|
+
// double-clicked word or triple-clicked line went ONLY into the tmux paste
|
|
335
|
+
// buffer plus an OSC 52 escape, and xterm.js — Hyper, and our own browser
|
|
336
|
+
// terminal — does not act on OSC 52. Measured on tmux 3.6a/macOS:
|
|
337
|
+
//
|
|
338
|
+
// copy-pipe-and-cancel -> pasteboard unchanged
|
|
339
|
+
// copy-pipe-and-cancel pbcopy -> pasteboard updated
|
|
340
|
+
// copy-command pbcopy, then
|
|
341
|
+
// copy-pipe-and-cancel -> pasteboard updated
|
|
342
|
+
//
|
|
343
|
+
// So set the option rather than rebinding double/triple-click, which would
|
|
344
|
+
// lose the guards for exactly the reason described above.
|
|
345
|
+
if (command)
|
|
346
|
+
cmds.push(['set-option', '-g', 'copy-command', command]);
|
|
347
|
+
cmds.push(['bind-key', '-T', 'copy-mode', 'MouseDragEnd1Pane', 'send-keys', '-X', ...copy], ['bind-key', '-T', 'copy-mode-vi', 'MouseDragEnd1Pane', 'send-keys', '-X', ...copy], ['bind-key', '-T', 'copy-mode', 'Enter', 'send-keys', '-X', ...copy], ['bind-key', '-T', 'copy-mode-vi', 'y', 'send-keys', '-X', ...copy]);
|
|
348
|
+
return cmds;
|
|
349
|
+
}
|
|
350
|
+
function applyNativeTmuxOptions() {
|
|
351
|
+
for (const args of NATIVE_TMUX_COMMANDS) {
|
|
352
|
+
try {
|
|
353
|
+
(0, child_process_1.execFileSync)('tmux', args, { timeout: 5000, stdio: 'pipe' });
|
|
354
|
+
}
|
|
355
|
+
catch { /* option/key unsupported or no server yet — keep going */ }
|
|
356
|
+
}
|
|
357
|
+
for (const args of clipboardBindings()) {
|
|
358
|
+
try {
|
|
359
|
+
(0, child_process_1.execFileSync)('tmux', args, { timeout: 5000, stdio: 'pipe' });
|
|
360
|
+
}
|
|
361
|
+
catch { /* binding unsupported or no server yet — keep going */ }
|
|
362
|
+
}
|
|
363
|
+
// RGB / 24-bit true color — append the feature only if absent, so repeated
|
|
364
|
+
// calls (every connect/attach) never pile up duplicate entries.
|
|
365
|
+
try {
|
|
366
|
+
const feats = (0, child_process_1.execFileSync)('tmux', ['show-options', '-g', 'terminal-features'], { timeout: 5000, stdio: 'pipe' }).toString();
|
|
367
|
+
if (!/RGB/.test(feats)) {
|
|
368
|
+
(0, child_process_1.execFileSync)('tmux', ['set-option', '-sa', 'terminal-features', '*:RGB'], { timeout: 5000, stdio: 'pipe' });
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
catch { /* no server yet */ }
|
|
372
|
+
}
|
|
373
|
+
function tmuxSessionExists(name, deps = {}) {
|
|
374
|
+
const list = deps.list ?? (() => (0, child_process_1.execFileSync)('tmux', ['list-sessions', '-F', '#{session_name}'], { timeout: 5000, stdio: 'pipe' }).toString());
|
|
375
|
+
try {
|
|
376
|
+
return list().split('\n').some((line) => line.trim() === name);
|
|
377
|
+
}
|
|
378
|
+
catch {
|
|
379
|
+
return false;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
// Per-session appearance for browser-origin (dd-*) sessions.
|
|
383
|
+
//
|
|
384
|
+
// Scoped with -t, never -g: these sessions render inside a browser tab that
|
|
385
|
+
// already has DevDash's own chrome around it, so tmux's status bar is a
|
|
386
|
+
// duplicate row of UI stealing a line of the viewport. Native sessions keep
|
|
387
|
+
// their status bar — the user reads it in their terminal app, where it is the
|
|
388
|
+
// only indicator there is. That split is the whole reason this is per-session.
|
|
389
|
+
function applyBrowserSessionOptions(name) {
|
|
390
|
+
try {
|
|
391
|
+
(0, child_process_1.execFileSync)('tmux', ['set-option', '-t', name, 'status', 'off'], { timeout: 5000, stdio: 'pipe' });
|
|
392
|
+
}
|
|
393
|
+
catch { /* session gone or option unsupported — cosmetic, never fatal */ }
|
|
394
|
+
}
|
|
395
|
+
function openAttach(id, tmuxName, readOnly, cols = 80, rows = 24) {
|
|
396
|
+
if (!pty)
|
|
397
|
+
return false;
|
|
398
|
+
if (sessions.has(id))
|
|
399
|
+
return true; // idempotent reattach
|
|
400
|
+
applyNativeTmuxOptions();
|
|
401
|
+
const args = ['attach-session', '-t', tmuxName];
|
|
402
|
+
if (readOnly)
|
|
403
|
+
args.push('-r', '-f', 'ignore-size'); // Peek: don't drive window size (tmux ≥3.2)
|
|
404
|
+
let proc;
|
|
405
|
+
try {
|
|
406
|
+
proc = pty.spawn('tmux', args, {
|
|
407
|
+
name: 'xterm-256color',
|
|
408
|
+
cols,
|
|
409
|
+
rows,
|
|
410
|
+
cwd: os.homedir(),
|
|
411
|
+
env: { ...process.env, TERM: 'xterm-256color' },
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
catch (err) {
|
|
415
|
+
console.error(`[dialout] tmux attach failed: ${err.message}`);
|
|
416
|
+
return false;
|
|
417
|
+
}
|
|
418
|
+
proc.onData((data) => {
|
|
419
|
+
if (activeWs && activeWs.readyState === activeWs.OPEN) {
|
|
420
|
+
activeWs.send(JSON.stringify({ type: 'pty_data', id, data }));
|
|
421
|
+
}
|
|
422
|
+
});
|
|
423
|
+
proc.onExit(({ exitCode }) => {
|
|
424
|
+
sessions.delete(id);
|
|
425
|
+
if (activeWs && activeWs.readyState === activeWs.OPEN) {
|
|
426
|
+
activeWs.send(JSON.stringify({ type: 'pty_exit', id, code: exitCode }));
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
sessions.set(id, { id, process: proc, tmux: { name: tmuxName, creator: false, readOnly } });
|
|
430
|
+
return true;
|
|
431
|
+
}
|
|
432
|
+
function writeToSession(id, data) {
|
|
433
|
+
const session = sessions.get(id);
|
|
434
|
+
if (session) {
|
|
435
|
+
session.process.write(data);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
function resizeSession(id, cols, rows) {
|
|
439
|
+
const session = sessions.get(id);
|
|
440
|
+
if (session) {
|
|
441
|
+
session.process.resize(cols, rows);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
async function closeSession(id) {
|
|
445
|
+
const session = sessions.get(id);
|
|
446
|
+
if (!session)
|
|
447
|
+
return;
|
|
448
|
+
sessions.delete(id);
|
|
449
|
+
const { tmux } = session;
|
|
450
|
+
session.process.kill();
|
|
451
|
+
if (tmux?.creator) {
|
|
452
|
+
// The user closed the tab that created this session. Kill the tmux
|
|
453
|
+
// session too — unless another client (phone, second browser) is still
|
|
454
|
+
// attached, in which case the session lives on for them.
|
|
455
|
+
// countClients runs after our own client died with a small delay so we
|
|
456
|
+
// don't count ourselves.
|
|
457
|
+
setTimeout(async () => {
|
|
458
|
+
const clients = await (0, tmux_manager_1.countClients)(tmux.name);
|
|
459
|
+
if (clients === 0)
|
|
460
|
+
await (0, tmux_manager_1.killTmuxSession)(tmux.name);
|
|
461
|
+
}, 500);
|
|
462
|
+
}
|
|
463
|
+
// Native-origin attach clients (tmux.creator === false): killing the
|
|
464
|
+
// attach PTY only detaches — the shared session is never killed here.
|
|
465
|
+
}
|
|
466
|
+
// Give up the client PTY without ending the work.
|
|
467
|
+
//
|
|
468
|
+
// This is what the detach grace period now expires into. It used to expire
|
|
469
|
+
// into closeSession(), which killed the tmux session too — so a browser tab
|
|
470
|
+
// closed for more than the grace window took a multi-hour Claude Code session
|
|
471
|
+
// down with it. Detach frees the node-pty (the browser is gone; nothing is
|
|
472
|
+
// reading its output) while tmux keeps the shell and its process tree running,
|
|
473
|
+
// so a later openSession() with the same id resumes straight back into it.
|
|
474
|
+
//
|
|
475
|
+
// A session with no tmux behind it cannot be resumed by anything, so detaching
|
|
476
|
+
// one would strand an unreachable shell forever — those are killed, matching
|
|
477
|
+
// the old behavior exactly for the non-cowork case.
|
|
478
|
+
function detachPtySession(id) {
|
|
479
|
+
const session = sessions.get(id);
|
|
480
|
+
if (!session)
|
|
481
|
+
return;
|
|
482
|
+
sessions.delete(id);
|
|
483
|
+
try {
|
|
484
|
+
session.process.kill();
|
|
485
|
+
}
|
|
486
|
+
catch { }
|
|
487
|
+
if (!session.tmux) {
|
|
488
|
+
console.log(`[dialout] Session ${id} has no tmux backing — killed on detach`);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
// Agent shutdown: kill only our client PTYs. tmux-backed sessions stay
|
|
492
|
+
// alive on purpose — they're re-enumerated after restart and browsers
|
|
493
|
+
// reattach; a deploy must never destroy the user's running work.
|
|
494
|
+
function closeAllSessions() {
|
|
495
|
+
for (const [id, session] of sessions) {
|
|
496
|
+
sessions.delete(id);
|
|
497
|
+
try {
|
|
498
|
+
session.process.kill();
|
|
499
|
+
}
|
|
500
|
+
catch { }
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
function getActiveSessions() {
|
|
504
|
+
return Array.from(sessions.keys());
|
|
505
|
+
}
|
|
506
|
+
//# sourceMappingURL=pty-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pty-manager.js","sourceRoot":"","sources":["../src/pty-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
export declare function serviceUser(env?: NodeJS.ProcessEnv, info?: () => string): string;
|
|
2
|
+
export interface UninstallDeps {
|
|
3
|
+
platform?: NodeJS.Platform;
|
|
4
|
+
existsSync?: (p: string) => boolean;
|
|
5
|
+
isRoot?: () => boolean;
|
|
6
|
+
canPromptSudo?: () => boolean;
|
|
7
|
+
run?: (cmd: string, opts?: object) => void;
|
|
8
|
+
log?: (msg: string) => void;
|
|
9
|
+
}
|
|
10
|
+
export interface UninstallResult {
|
|
11
|
+
/** Something was actually removed from disk. */
|
|
12
|
+
removed: boolean;
|
|
13
|
+
/** Manual steps the caller must still run, because we could not escalate. */
|
|
14
|
+
pending: string[];
|
|
15
|
+
}
|
|
16
|
+
export interface LingerDeps {
|
|
17
|
+
run?: (cmd: string) => void;
|
|
18
|
+
isEnabled?: (user: string) => boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface LingerResult {
|
|
21
|
+
ok: boolean;
|
|
22
|
+
alreadyOn: boolean;
|
|
23
|
+
error?: string;
|
|
24
|
+
}
|
|
25
|
+
export declare function isLingerEnabled(user: string): boolean;
|
|
26
|
+
export declare function enableLinger(user: string, deps?: LingerDeps): LingerResult;
|
|
27
|
+
export interface LinuxScopeDeps {
|
|
28
|
+
isRoot?: () => boolean;
|
|
29
|
+
}
|
|
30
|
+
export declare function defaultLinuxScope(deps?: LinuxScopeDeps): 'system' | 'user';
|
|
31
|
+
export type ServiceKind = 'launchd-agent' | 'launchd-daemon' | 'systemd-user' | 'systemd-system';
|
|
32
|
+
export interface ServiceStatus {
|
|
33
|
+
installed: boolean;
|
|
34
|
+
running: boolean;
|
|
35
|
+
pid: number | null;
|
|
36
|
+
kind: ServiceKind | null;
|
|
37
|
+
atBoot: boolean;
|
|
38
|
+
}
|
|
39
|
+
export interface InstallOptions {
|
|
40
|
+
system?: boolean;
|
|
41
|
+
}
|
|
42
|
+
export declare function installService(opts?: InstallOptions): void;
|
|
43
|
+
export declare function uninstallService(deps?: UninstallDeps): UninstallResult;
|
|
44
|
+
export declare function isServiceInstalled(): boolean;
|
|
45
|
+
export declare function getServiceStatus(): ServiceStatus;
|
|
46
|
+
export declare function getWatchdogScript(): string;
|
|
47
|
+
export declare function installCron(intervalMinutes?: number): void;
|
|
48
|
+
export declare function uninstallCron(): void;
|
|
49
|
+
export declare function isCronInstalled(): boolean;
|
|
50
|
+
export interface SupervisorInfo {
|
|
51
|
+
kind: ServiceKind | 'cron';
|
|
52
|
+
path: string;
|
|
53
|
+
running: boolean;
|
|
54
|
+
pid: number | null;
|
|
55
|
+
atBoot: boolean;
|
|
56
|
+
/** For cron: the SCRIPT= path its watchdog will launch. Else ''. */
|
|
57
|
+
targetScript: string;
|
|
58
|
+
/** True when targetScript does not match this install's agent script. */
|
|
59
|
+
stale: boolean;
|
|
60
|
+
}
|
|
61
|
+
/** Injectable dependencies so listSupervisors() never touches a real unit file, the real crontab, or the real $HOME in tests. */
|
|
62
|
+
export interface ListSupervisorsDeps {
|
|
63
|
+
platform?: NodeJS.Platform;
|
|
64
|
+
homedir?: string;
|
|
65
|
+
existsSync?: (p: string) => boolean;
|
|
66
|
+
readFileSync?: (p: string) => string;
|
|
67
|
+
launchdPid?: (domainTarget: string) => number | null;
|
|
68
|
+
systemdActive?: (scope: 'user' | 'system') => {
|
|
69
|
+
active: boolean;
|
|
70
|
+
pid: number | null;
|
|
71
|
+
};
|
|
72
|
+
isCronInstalled?: () => boolean;
|
|
73
|
+
/** Override for getAgentScript() — the "correct" script path to compare against. */
|
|
74
|
+
agentScript?: string;
|
|
75
|
+
/** Override for fs.realpathSync — used to canonicalize paths before the staleness compare. */
|
|
76
|
+
realpathSync?: (p: string) => string;
|
|
77
|
+
}
|
|
78
|
+
/** Every supervisor present, not just the first match. */
|
|
79
|
+
export declare function listSupervisors(deps?: ListSupervisorsDeps): SupervisorInfo[];
|
|
80
|
+
export interface WatchdogRepairResult {
|
|
81
|
+
repaired: boolean;
|
|
82
|
+
/** The SCRIPT= path the watchdog pointed at before repair (empty if there was nothing to repair). */
|
|
83
|
+
from: string;
|
|
84
|
+
/** The current agent script path repair rewrites SCRIPT= to. */
|
|
85
|
+
to: string;
|
|
86
|
+
}
|
|
87
|
+
export declare function staleSupervisorAdvice(s: SupervisorInfo): string[];
|
|
88
|
+
/**
|
|
89
|
+
* Rewrite `~/.dialout/watchdog.sh` if its SCRIPT= line has drifted from
|
|
90
|
+
* the current agent script. No-op (repaired: false) when the watchdog is
|
|
91
|
+
* absent or already correct — in particular, an already-correct watchdog is
|
|
92
|
+
* left byte-for-byte and mtime-untouched, and no backup is created.
|
|
93
|
+
*/
|
|
94
|
+
export declare function repairWatchdog(): WatchdogRepairResult;
|
|
95
|
+
//# sourceMappingURL=service-installer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-installer.d.ts","sourceRoot":"","sources":["../src/service-installer.ts"],"names":[],"mappings":"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"}
|