@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.
Files changed (224) hide show
  1. package/README.md +420 -24
  2. package/bin/AGENTS.md +44 -0
  3. package/bin/devdash-agent.js +2 -0
  4. package/dist/ai-adapters/claude.d.ts +3 -0
  5. package/dist/ai-adapters/claude.d.ts.map +1 -0
  6. package/dist/ai-adapters/claude.js +98 -0
  7. package/dist/ai-adapters/claude.js.map +1 -0
  8. package/dist/ai-adapters/codex.d.ts +3 -0
  9. package/dist/ai-adapters/codex.d.ts.map +1 -0
  10. package/dist/ai-adapters/codex.js +147 -0
  11. package/dist/ai-adapters/codex.js.map +1 -0
  12. package/dist/ai-adapters/grok.d.ts +3 -0
  13. package/dist/ai-adapters/grok.d.ts.map +1 -0
  14. package/dist/ai-adapters/grok.js +164 -0
  15. package/dist/ai-adapters/grok.js.map +1 -0
  16. package/dist/ai-adapters/index.d.ts +5 -0
  17. package/dist/ai-adapters/index.d.ts.map +1 -0
  18. package/dist/ai-adapters/index.js +30 -0
  19. package/dist/ai-adapters/index.js.map +1 -0
  20. package/dist/ai-adapters/types.d.ts +3 -0
  21. package/dist/ai-adapters/types.d.ts.map +1 -0
  22. package/dist/ai-adapters/types.js +7 -0
  23. package/dist/ai-adapters/types.js.map +1 -0
  24. package/dist/ai-capabilities/claude.d.ts +4 -0
  25. package/dist/ai-capabilities/claude.d.ts.map +1 -0
  26. package/dist/ai-capabilities/claude.js +174 -0
  27. package/dist/ai-capabilities/claude.js.map +1 -0
  28. package/dist/ai-capabilities/describe.d.ts +2 -0
  29. package/dist/ai-capabilities/describe.d.ts.map +1 -0
  30. package/dist/ai-capabilities/describe.js +31 -0
  31. package/dist/ai-capabilities/describe.js.map +1 -0
  32. package/dist/ai-capabilities/fsdeps.d.ts +3 -0
  33. package/dist/ai-capabilities/fsdeps.d.ts.map +1 -0
  34. package/dist/ai-capabilities/fsdeps.js +71 -0
  35. package/dist/ai-capabilities/fsdeps.js.map +1 -0
  36. package/dist/ai-capabilities/grok.d.ts +5 -0
  37. package/dist/ai-capabilities/grok.d.ts.map +1 -0
  38. package/dist/ai-capabilities/grok.js +145 -0
  39. package/dist/ai-capabilities/grok.js.map +1 -0
  40. package/dist/ai-capabilities/index.d.ts +4 -0
  41. package/dist/ai-capabilities/index.d.ts.map +1 -0
  42. package/dist/ai-capabilities/index.js +94 -0
  43. package/dist/ai-capabilities/index.js.map +1 -0
  44. package/dist/ai-capabilities/redact.d.ts +2 -0
  45. package/dist/ai-capabilities/redact.d.ts.map +1 -0
  46. package/dist/ai-capabilities/redact.js +27 -0
  47. package/dist/ai-capabilities/redact.js.map +1 -0
  48. package/dist/ai-capabilities/types.d.ts +11 -0
  49. package/dist/ai-capabilities/types.d.ts.map +1 -0
  50. package/dist/ai-capabilities/types.js +3 -0
  51. package/dist/ai-capabilities/types.js.map +1 -0
  52. package/dist/ai-launch.d.ts +35 -0
  53. package/dist/ai-launch.d.ts.map +1 -0
  54. package/dist/ai-launch.js +211 -0
  55. package/dist/ai-launch.js.map +1 -0
  56. package/dist/ai-session-detector.d.ts +19 -0
  57. package/dist/ai-session-detector.d.ts.map +1 -0
  58. package/dist/ai-session-detector.js +79 -0
  59. package/dist/ai-session-detector.js.map +1 -0
  60. package/dist/ai-sessions.d.ts +36 -0
  61. package/dist/ai-sessions.d.ts.map +1 -0
  62. package/dist/ai-sessions.js +309 -0
  63. package/dist/ai-sessions.js.map +1 -0
  64. package/dist/ai-status.d.ts +6 -0
  65. package/dist/ai-status.d.ts.map +1 -0
  66. package/dist/ai-status.js +40 -0
  67. package/dist/ai-status.js.map +1 -0
  68. package/dist/ai-transcript-locator.d.ts +35 -0
  69. package/dist/ai-transcript-locator.d.ts.map +1 -0
  70. package/dist/ai-transcript-locator.js +268 -0
  71. package/dist/ai-transcript-locator.js.map +1 -0
  72. package/dist/ai-transcript-tail.d.ts +17 -0
  73. package/dist/ai-transcript-tail.d.ts.map +1 -0
  74. package/dist/ai-transcript-tail.js +120 -0
  75. package/dist/ai-transcript-tail.js.map +1 -0
  76. package/dist/checklist.d.ts +20 -0
  77. package/dist/checklist.d.ts.map +1 -0
  78. package/dist/checklist.js +51 -0
  79. package/dist/checklist.js.map +1 -0
  80. package/dist/cli.d.ts +2 -0
  81. package/dist/cli.d.ts.map +1 -0
  82. package/dist/cli.js +1427 -0
  83. package/dist/cli.js.map +1 -0
  84. package/dist/command-runner.d.ts +15 -0
  85. package/dist/command-runner.d.ts.map +1 -0
  86. package/dist/command-runner.js +84 -0
  87. package/dist/command-runner.js.map +1 -0
  88. package/dist/config.d.ts +41 -0
  89. package/dist/config.d.ts.map +1 -0
  90. package/dist/config.js +152 -0
  91. package/dist/config.js.map +1 -0
  92. package/dist/cowork.d.ts +26 -0
  93. package/dist/cowork.d.ts.map +1 -0
  94. package/dist/cowork.js +370 -0
  95. package/dist/cowork.js.map +1 -0
  96. package/dist/fs-browser.d.ts +6 -0
  97. package/dist/fs-browser.d.ts.map +1 -0
  98. package/dist/fs-browser.js +61 -0
  99. package/dist/fs-browser.js.map +1 -0
  100. package/dist/has-command.d.ts +12 -0
  101. package/dist/has-command.d.ts.map +1 -0
  102. package/dist/has-command.js +24 -0
  103. package/dist/has-command.js.map +1 -0
  104. package/dist/heartbeat.d.ts +7 -0
  105. package/dist/heartbeat.d.ts.map +1 -0
  106. package/dist/heartbeat.js +50 -0
  107. package/dist/heartbeat.js.map +1 -0
  108. package/dist/index.d.ts +2 -0
  109. package/dist/index.d.ts.map +1 -0
  110. package/dist/index.js +56 -0
  111. package/dist/index.js.map +1 -0
  112. package/dist/port-scanner.d.ts +4 -0
  113. package/dist/port-scanner.d.ts.map +1 -0
  114. package/dist/port-scanner.js +75 -0
  115. package/dist/port-scanner.js.map +1 -0
  116. package/dist/project-scanner.d.ts +15 -0
  117. package/dist/project-scanner.d.ts.map +1 -0
  118. package/dist/project-scanner.js +333 -0
  119. package/dist/project-scanner.js.map +1 -0
  120. package/dist/pty-manager.d.ts +28 -0
  121. package/dist/pty-manager.d.ts.map +1 -0
  122. package/dist/pty-manager.js +506 -0
  123. package/dist/pty-manager.js.map +1 -0
  124. package/dist/service-installer.d.ts +95 -0
  125. package/dist/service-installer.d.ts.map +1 -0
  126. package/dist/service-installer.js +911 -0
  127. package/dist/service-installer.js.map +1 -0
  128. package/dist/single-instance.d.ts +20 -0
  129. package/dist/single-instance.d.ts.map +1 -0
  130. package/dist/single-instance.js +151 -0
  131. package/dist/single-instance.js.map +1 -0
  132. package/dist/ssh-local-network.d.ts +26 -0
  133. package/dist/ssh-local-network.d.ts.map +1 -0
  134. package/dist/ssh-local-network.js +169 -0
  135. package/dist/ssh-local-network.js.map +1 -0
  136. package/dist/terminal-detect.d.ts +52 -0
  137. package/dist/terminal-detect.d.ts.map +1 -0
  138. package/dist/terminal-detect.js +147 -0
  139. package/dist/terminal-detect.js.map +1 -0
  140. package/dist/terminal-markers.d.ts +52 -0
  141. package/dist/terminal-markers.d.ts.map +1 -0
  142. package/dist/terminal-markers.js +174 -0
  143. package/dist/terminal-markers.js.map +1 -0
  144. package/dist/tmux-manager.d.ts +35 -0
  145. package/dist/tmux-manager.d.ts.map +1 -0
  146. package/dist/tmux-manager.js +274 -0
  147. package/dist/tmux-manager.js.map +1 -0
  148. package/dist/update-check.d.ts +3 -0
  149. package/dist/update-check.d.ts.map +1 -0
  150. package/dist/update-check.js +202 -0
  151. package/dist/update-check.js.map +1 -0
  152. package/dist/websocket.d.ts +8 -0
  153. package/dist/websocket.d.ts.map +1 -0
  154. package/dist/websocket.js +472 -0
  155. package/dist/websocket.js.map +1 -0
  156. package/node_modules/@dialout/shared/README.md +16 -0
  157. package/node_modules/@dialout/shared/dist/ai-chat-prefs.d.ts +8 -0
  158. package/node_modules/@dialout/shared/dist/ai-chat-prefs.d.ts.map +1 -0
  159. package/node_modules/@dialout/shared/dist/ai-chat-prefs.js +41 -0
  160. package/node_modules/@dialout/shared/dist/capabilities.d.ts +25 -0
  161. package/node_modules/@dialout/shared/dist/capabilities.d.ts.map +1 -0
  162. package/node_modules/@dialout/shared/dist/capabilities.js +2 -0
  163. package/node_modules/@dialout/shared/dist/chat-blocks.d.ts +33 -0
  164. package/node_modules/@dialout/shared/dist/chat-blocks.d.ts.map +1 -0
  165. package/node_modules/@dialout/shared/dist/chat-blocks.js +61 -0
  166. package/node_modules/@dialout/shared/dist/command-filter.d.ts +4 -0
  167. package/node_modules/@dialout/shared/dist/command-filter.d.ts.map +1 -0
  168. package/node_modules/@dialout/shared/dist/command-filter.js +49 -0
  169. package/node_modules/@dialout/shared/dist/composer-behaviour.d.ts +6 -0
  170. package/node_modules/@dialout/shared/dist/composer-behaviour.d.ts.map +1 -0
  171. package/node_modules/@dialout/shared/dist/composer-behaviour.js +24 -0
  172. package/node_modules/@dialout/shared/dist/events.d.ts +37 -0
  173. package/node_modules/@dialout/shared/dist/events.d.ts.map +1 -0
  174. package/node_modules/@dialout/shared/dist/events.js +13 -0
  175. package/node_modules/@dialout/shared/dist/index.d.ts +21 -0
  176. package/node_modules/@dialout/shared/dist/index.d.ts.map +1 -0
  177. package/node_modules/@dialout/shared/dist/index.js +37 -0
  178. package/node_modules/@dialout/shared/dist/kinds.d.ts +2 -0
  179. package/node_modules/@dialout/shared/dist/kinds.d.ts.map +1 -0
  180. package/node_modules/@dialout/shared/dist/kinds.js +2 -0
  181. package/node_modules/@dialout/shared/dist/notify.d.ts +3 -0
  182. package/node_modules/@dialout/shared/dist/notify.d.ts.map +1 -0
  183. package/node_modules/@dialout/shared/dist/notify.js +31 -0
  184. package/node_modules/@dialout/shared/dist/permission.d.ts +4 -0
  185. package/node_modules/@dialout/shared/dist/permission.d.ts.map +1 -0
  186. package/node_modules/@dialout/shared/dist/permission.js +8 -0
  187. package/node_modules/@dialout/shared/dist/scroll-pin.d.ts +3 -0
  188. package/node_modules/@dialout/shared/dist/scroll-pin.d.ts.map +1 -0
  189. package/node_modules/@dialout/shared/dist/scroll-pin.js +11 -0
  190. package/node_modules/@dialout/shared/dist/session.d.ts +19 -0
  191. package/node_modules/@dialout/shared/dist/session.d.ts.map +1 -0
  192. package/node_modules/@dialout/shared/dist/session.js +6 -0
  193. package/node_modules/@dialout/shared/dist/terminal-name.d.ts +25 -0
  194. package/node_modules/@dialout/shared/dist/terminal-name.d.ts.map +1 -0
  195. package/node_modules/@dialout/shared/dist/terminal-name.js +63 -0
  196. package/node_modules/@dialout/shared/dist/tool-appearance.d.ts +9 -0
  197. package/node_modules/@dialout/shared/dist/tool-appearance.d.ts.map +1 -0
  198. package/node_modules/@dialout/shared/dist/tool-appearance.js +30 -0
  199. package/node_modules/@dialout/shared/package.json +37 -0
  200. package/node_modules/@dialout/shared/src/ai-chat-prefs.test.ts +40 -0
  201. package/node_modules/@dialout/shared/src/ai-chat-prefs.ts +39 -0
  202. package/node_modules/@dialout/shared/src/capabilities.ts +30 -0
  203. package/node_modules/@dialout/shared/src/chat-blocks.test.ts +65 -0
  204. package/node_modules/@dialout/shared/src/chat-blocks.ts +79 -0
  205. package/node_modules/@dialout/shared/src/command-filter.test.ts +76 -0
  206. package/node_modules/@dialout/shared/src/command-filter.ts +45 -0
  207. package/node_modules/@dialout/shared/src/composer-behaviour.test.ts +31 -0
  208. package/node_modules/@dialout/shared/src/composer-behaviour.ts +22 -0
  209. package/node_modules/@dialout/shared/src/events.ts +27 -0
  210. package/node_modules/@dialout/shared/src/index.ts +32 -0
  211. package/node_modules/@dialout/shared/src/kinds.ts +5 -0
  212. package/node_modules/@dialout/shared/src/notify.test.ts +49 -0
  213. package/node_modules/@dialout/shared/src/notify.ts +30 -0
  214. package/node_modules/@dialout/shared/src/permission.ts +10 -0
  215. package/node_modules/@dialout/shared/src/scroll-pin.test.ts +23 -0
  216. package/node_modules/@dialout/shared/src/scroll-pin.ts +13 -0
  217. package/node_modules/@dialout/shared/src/session.ts +25 -0
  218. package/node_modules/@dialout/shared/src/terminal-name.ts +82 -0
  219. package/node_modules/@dialout/shared/src/tool-appearance.test.ts +41 -0
  220. package/node_modules/@dialout/shared/src/tool-appearance.ts +39 -0
  221. package/package.json +54 -14
  222. package/scripts/postinstall.js +79 -0
  223. package/scripts/prepack.js +45 -0
  224. 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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"}