@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,274 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SEP = void 0;
4
+ exports.tmuxLocaleEnv = tmuxLocaleEnv;
5
+ exports.tmuxAvailable = tmuxAvailable;
6
+ exports.resetTmuxAvailableCache = resetTmuxAvailableCache;
7
+ exports.parseSessionLine = parseSessionLine;
8
+ exports.getSessionOption = getSessionOption;
9
+ exports.listSessions = listSessions;
10
+ exports.tmuxSessionName = tmuxSessionName;
11
+ exports.killTmuxSession = killTmuxSession;
12
+ exports.countClients = countClients;
13
+ exports.tailLines = tailLines;
14
+ exports.capturePane = capturePane;
15
+ const child_process_1 = require("child_process");
16
+ // Field separator for list-sessions output. '|' was ambiguous: it is legal in
17
+ // BOTH a session name and a filesystem path, which forced a right-anchored
18
+ // parse and made adding a path field unparseable. \x1f (ASCII unit separator)
19
+ // cannot occur in either, so fields are read positionally.
20
+ exports.SEP = '\x1f';
21
+ // pane_current_path is the session's LIVE working directory, straight from
22
+ // tmux. The @devdash_folder_path option is written once at session creation and
23
+ // never updated, so it lies the moment the user cds — and native sessions
24
+ // (created outside DevDash) may not carry it at all.
25
+ const LIST_FORMAT = [
26
+ '#{session_name}',
27
+ '#{session_created}',
28
+ '#{session_attached}',
29
+ '#{session_activity}',
30
+ '#{window_width}',
31
+ '#{window_height}',
32
+ '#{pane_current_path}',
33
+ ].join(exports.SEP);
34
+ // Last path segment, ignoring trailing slashes. '/' and '' both yield ''.
35
+ function basename(path) {
36
+ const trimmed = path.replace(/\/+$/, '');
37
+ if (!trimmed)
38
+ return '';
39
+ return trimmed.split('/').pop() || '';
40
+ }
41
+ // tmux replaces every non-printable byte in -F output with a literal '_'
42
+ // unless it is running in a UTF-8 locale. Measured on tmux 3.7b: with
43
+ // LANG=en_US.UTF-8 the \x1f separator comes back intact; with LANG=C, or with
44
+ // no locale variable set at all, `A\x1fB` arrives as `A_B`. launchd hands a
45
+ // daemon an environment containing no LANG, so under the installed service
46
+ // every list-sessions line arrived as ONE unsplittable field,
47
+ // parseSessionLine() returned null for all of them, and the agent reported
48
+ // zero tmux sessions forever — connected, authenticated, online and blind.
49
+ // Picking a different separator does not help: tab and \x01 are sanitized the
50
+ // same way. 'C.UTF-8' is accepted by both macOS and glibc. LC_ALL is the one
51
+ // that has to be set, since an explicit LC_ALL=C would override LC_CTYPE — and
52
+ // it is only set when the inherited locale is not UTF-8 already, so a user's
53
+ // own locale is left alone.
54
+ function tmuxLocaleEnv(env) {
55
+ const current = env.LC_ALL || env.LC_CTYPE || env.LANG || '';
56
+ if (/utf-?8/i.test(current))
57
+ return env;
58
+ return { ...env, LC_ALL: 'C.UTF-8' };
59
+ }
60
+ function run(args) {
61
+ return new Promise((resolve, reject) => {
62
+ (0, child_process_1.execFile)('tmux', args, { timeout: 5000, env: tmuxLocaleEnv(process.env) }, (err, stdout) => {
63
+ if (err)
64
+ reject(err);
65
+ else
66
+ resolve(stdout);
67
+ });
68
+ });
69
+ }
70
+ // A positive answer is cached forever — tmux does not get uninstalled under a
71
+ // running agent, and re-probing on every 5s poll is pure waste.
72
+ //
73
+ // A NEGATIVE answer is cached only briefly. It used to be permanent, and that
74
+ // turned "tmux was missing when the agent started" into a dead agent for the
75
+ // rest of its life: install tmux, and nothing came back until someone thought
76
+ // to restart the daemon. Nothing logged, either — pollTmuxSessions() just
77
+ // returned early — so the agent showed ONLINE while reporting no terminals and
78
+ // no AI sessions at all, with no way to tell why from the outside.
79
+ let available = null;
80
+ let lastProbeMs = 0;
81
+ let warnedUnavailable = false;
82
+ let warnedUnparsed = false;
83
+ const UNAVAILABLE_RECHECK_MS = 60_000;
84
+ async function tmuxAvailable(now = Date.now) {
85
+ if (available === true)
86
+ return true;
87
+ if (available === false && now() - lastProbeMs < UNAVAILABLE_RECHECK_MS)
88
+ return false;
89
+ lastProbeMs = now();
90
+ try {
91
+ await run(['-V']);
92
+ available = true;
93
+ if (warnedUnavailable) {
94
+ console.log('[dialout] tmux is now available — resuming session reporting.');
95
+ warnedUnavailable = false;
96
+ }
97
+ }
98
+ catch {
99
+ available = false;
100
+ // Say it once, with the PATH, because this is the single most common
101
+ // reason an online agent reports nothing.
102
+ if (!warnedUnavailable) {
103
+ warnedUnavailable = true;
104
+ console.error('[dialout] tmux not found on PATH — terminal sessions and AI sessions '
105
+ + 'CANNOT be reported. Install tmux, or make it reachable from this PATH: '
106
+ + (process.env.PATH || '(empty)'));
107
+ }
108
+ }
109
+ return available;
110
+ }
111
+ /** Test seam: forget the cached probe result. */
112
+ function resetTmuxAvailableCache() {
113
+ available = null;
114
+ lastProbeMs = 0;
115
+ warnedUnavailable = false;
116
+ }
117
+ // Pure parser for one list-sessions line (kept separate for tests).
118
+ // Fields are \x1f-separated, so they can be read positionally — a session name
119
+ // or path containing '|' is no longer a problem.
120
+ function parseSessionLine(line) {
121
+ const parts = line.split(exports.SEP);
122
+ if (parts.length < 7)
123
+ return null;
124
+ const name = parts[0];
125
+ if (!name)
126
+ return null;
127
+ const nums = parts.slice(1, 6).map((n) => parseInt(n, 10));
128
+ if (nums.some((n) => Number.isNaN(n)))
129
+ return null;
130
+ const [createdAt, attached, lastActivity, width, height] = nums;
131
+ const folderPath = parts[6] || '';
132
+ return {
133
+ name, createdAt, attached, lastActivity, width, height,
134
+ folder: basename(folderPath), folderPath,
135
+ createdLocal: '', gitBranch: '',
136
+ };
137
+ }
138
+ async function getSessionOption(name, option) {
139
+ try {
140
+ const out = await run(['show-options', '-t', name, '-qv', option]);
141
+ return out.trim();
142
+ }
143
+ catch {
144
+ return '';
145
+ }
146
+ }
147
+ // These @-options are written once at session creation and never change, so
148
+ // they are safe to cache. folder/folderPath are deliberately NOT cached here:
149
+ // they now come live from #{pane_current_path} on every poll. The cached
150
+ // folder* entries are only the creation-time fallback for sessions that have
151
+ // no pane path.
152
+ const optionCache = new Map();
153
+ async function listSessions() {
154
+ if (!(await tmuxAvailable()))
155
+ return [];
156
+ let out;
157
+ try {
158
+ out = await run(['list-sessions', '-F', LIST_FORMAT]);
159
+ }
160
+ catch {
161
+ return []; // no tmux server running = no sessions
162
+ }
163
+ const sessions = [];
164
+ const liveNames = new Set();
165
+ let unparsed = 0;
166
+ for (const line of out.split('\n')) {
167
+ const base = parseSessionLine(line.trim());
168
+ if (!base) {
169
+ if (line.trim())
170
+ unparsed++;
171
+ continue;
172
+ }
173
+ liveNames.add(base.name);
174
+ let opts = optionCache.get(base.name);
175
+ if (!opts) {
176
+ const [termProgram, originRaw, folder, folderPath, createdLocal, gitBranch] = await Promise.all([
177
+ getSessionOption(base.name, '@term_program'),
178
+ getSessionOption(base.name, '@devdash_origin'),
179
+ getSessionOption(base.name, '@devdash_folder'),
180
+ getSessionOption(base.name, '@devdash_folder_path'),
181
+ getSessionOption(base.name, '@devdash_created'),
182
+ getSessionOption(base.name, '@devdash_git'),
183
+ ]);
184
+ opts = {
185
+ termProgram: termProgram || 'unknown',
186
+ origin: originRaw === 'browser' ? 'browser' : 'native',
187
+ createdLocal, gitBranch,
188
+ folderFallback: folder, folderPathFallback: folderPath,
189
+ };
190
+ optionCache.set(base.name, opts);
191
+ }
192
+ // Live pane path wins. The @devdash_* options are a creation-time snapshot
193
+ // that goes stale as soon as the user cds, so they only fill in when tmux
194
+ // reports no pane path at all.
195
+ sessions.push({
196
+ ...base,
197
+ folder: base.folder || opts.folderFallback,
198
+ folderPath: base.folderPath || opts.folderPathFallback,
199
+ termProgram: opts.termProgram,
200
+ origin: opts.origin,
201
+ createdLocal: opts.createdLocal,
202
+ gitBranch: opts.gitBranch,
203
+ });
204
+ }
205
+ // tmux listed sessions but not one line survived the parse. That is a broken
206
+ // agent, not an empty machine, and it used to be indistinguishable from one:
207
+ // the poll reported an empty list forever with nothing on stdout to say why.
208
+ // Say it once per process, with the offending line, so the next occurrence is
209
+ // one log line rather than a day of measurement.
210
+ if (unparsed > 0 && sessions.length === 0 && !warnedUnparsed) {
211
+ warnedUnparsed = true;
212
+ console.error(`[dialout] tmux listed ${unparsed} session(s) but none could be parsed —`
213
+ + ' reporting no terminals. First line was:'
214
+ + ` ${JSON.stringify(out.split('\n')[0])}`);
215
+ }
216
+ for (const key of optionCache.keys()) {
217
+ if (!liveNames.has(key))
218
+ optionCache.delete(key);
219
+ }
220
+ return sessions;
221
+ }
222
+ // tmux name for a server-issued session id. The id must survive intact: ids are
223
+ // `ses_` + random + Date.now().toString(36), and the base36 timestamp is exactly
224
+ // 8 chars — so keying off the last 8 chars would discard the random part and
225
+ // collide for any two sessions opened in the same millisecond.
226
+ function tmuxSessionName(id) {
227
+ return `dd-${id.replace(/[^a-zA-Z0-9_-]/g, '')}`;
228
+ }
229
+ // A missing session is success — the caller wanted it gone and it is gone.
230
+ const GONE_RE = /can't find session|session not found|no such session/i;
231
+ async function killTmuxSession(name, deps = {}) {
232
+ const exec = deps.run || run;
233
+ try {
234
+ await exec(['kill-session', '-t', name]);
235
+ return { ok: true };
236
+ }
237
+ catch (err) {
238
+ const message = err?.message || 'kill-session failed';
239
+ if (GONE_RE.test(message))
240
+ return { ok: true };
241
+ return { ok: false, error: message };
242
+ }
243
+ }
244
+ async function countClients(name) {
245
+ try {
246
+ const out = await run(['list-clients', '-t', name]);
247
+ return out.split('\n').filter((l) => l.trim()).length;
248
+ }
249
+ catch {
250
+ return 0;
251
+ }
252
+ }
253
+ // Exported for unit testing the tail slice without shelling out.
254
+ function tailLines(text, lines) {
255
+ if (lines <= 0)
256
+ return '';
257
+ const rows = text.replace(/\n+$/, '').split('\n');
258
+ return rows.slice(-lines).join('\n');
259
+ }
260
+ // Last `lines` lines of a session's active pane, for the preview description.
261
+ // Best-effort: '' on any failure or empty pane.
262
+ async function capturePane(name, lines) {
263
+ if (lines <= 0)
264
+ return '';
265
+ try {
266
+ // -p prints to stdout, -t targets the session (its active pane).
267
+ const out = await run(['capture-pane', '-p', '-t', name]);
268
+ return tailLines(out, lines);
269
+ }
270
+ catch {
271
+ return '';
272
+ }
273
+ }
274
+ //# sourceMappingURL=tmux-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tmux-manager.js","sourceRoot":"","sources":["../src/tmux-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function checkForUpdate(): Promise<void>;
2
+ export declare function performUpdate(): Promise<void>;
3
+ //# sourceMappingURL=update-check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-check.d.ts","sourceRoot":"","sources":["../src/update-check.ts"],"names":[],"mappings":"AA8EA,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAkBpD;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CA6EnD"}
@@ -0,0 +1,202 @@
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.checkForUpdate = checkForUpdate;
37
+ exports.performUpdate = performUpdate;
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ const os = __importStar(require("os"));
41
+ const child_process_1 = require("child_process");
42
+ const config_1 = require("./config");
43
+ // Public npm. The package used to live on a private registry, which meant
44
+ // nobody outside the company could install or self-update it — the single
45
+ // hardest blocker to releasing this openly.
46
+ const REGISTRY = 'https://registry.npmjs.org';
47
+ // The npm package name, which is NOT the command name: the binary stays
48
+ // `dialout` so nothing a user types changes, while the package moved under
49
+ // the organisation's scope.
50
+ const PACKAGE_NAME = '@indianic/dialout';
51
+ const CHECK_INTERVAL_MS = 4 * 60 * 60 * 1000; // 4 hours
52
+ const GREEN = '\x1b[32m';
53
+ const YELLOW = '\x1b[33m';
54
+ const CYAN = '\x1b[36m';
55
+ const BOLD = '\x1b[1m';
56
+ const NC = '\x1b[0m';
57
+ function getLocalVersion() {
58
+ try {
59
+ const pkg = JSON.parse(fs.readFileSync(path.resolve(__dirname, '../package.json'), 'utf-8'));
60
+ return pkg.version;
61
+ }
62
+ catch {
63
+ return '0.0.0';
64
+ }
65
+ }
66
+ async function getLatestVersion() {
67
+ try {
68
+ const resp = await fetch(`${REGISTRY}/${PACKAGE_NAME}`, {
69
+ headers: { accept: 'application/json' },
70
+ signal: AbortSignal.timeout(5000),
71
+ });
72
+ if (!resp.ok)
73
+ return null;
74
+ const data = (await resp.json());
75
+ return data['dist-tags']?.latest || null;
76
+ }
77
+ catch {
78
+ return null;
79
+ }
80
+ }
81
+ function compareVersions(current, latest) {
82
+ const c = current.split('.').map(Number);
83
+ const l = latest.split('.').map(Number);
84
+ for (let i = 0; i < 3; i++) {
85
+ if ((l[i] || 0) > (c[i] || 0))
86
+ return true;
87
+ if ((l[i] || 0) < (c[i] || 0))
88
+ return false;
89
+ }
90
+ return false;
91
+ }
92
+ function getLastCheckFile() {
93
+ return path.join((0, config_1.configDirFor)(os.homedir()), 'last-update-check');
94
+ }
95
+ function shouldCheck() {
96
+ try {
97
+ const lastCheck = fs.readFileSync(getLastCheckFile(), 'utf-8').trim();
98
+ return Date.now() - parseInt(lastCheck, 10) > CHECK_INTERVAL_MS;
99
+ }
100
+ catch {
101
+ return true;
102
+ }
103
+ }
104
+ function markChecked() {
105
+ try {
106
+ const dir = path.dirname(getLastCheckFile());
107
+ if (!fs.existsSync(dir))
108
+ fs.mkdirSync(dir, { recursive: true });
109
+ fs.writeFileSync(getLastCheckFile(), String(Date.now()));
110
+ }
111
+ catch { }
112
+ }
113
+ async function checkForUpdate() {
114
+ if (!shouldCheck())
115
+ return;
116
+ markChecked();
117
+ const current = getLocalVersion();
118
+ const latest = await getLatestVersion();
119
+ if (!latest)
120
+ return;
121
+ if (compareVersions(current, latest)) {
122
+ console.log('');
123
+ console.log(`${YELLOW}╔══════════════════════════════════════════════════════════╗${NC}`);
124
+ console.log(`${YELLOW}║${NC} ${BOLD}Update available!${NC} ${current} → ${GREEN}${latest}${NC} ${YELLOW}║${NC}`);
125
+ console.log(`${YELLOW}║${NC} ${YELLOW}║${NC}`);
126
+ console.log(`${YELLOW}║${NC} Run: ${CYAN}dialout update${NC} ${YELLOW}║${NC}`);
127
+ console.log(`${YELLOW}╚══════════════════════════════════════════════════════════╝${NC}`);
128
+ console.log('');
129
+ }
130
+ }
131
+ async function performUpdate() {
132
+ const current = getLocalVersion();
133
+ const latest = await getLatestVersion();
134
+ console.log('');
135
+ console.log(`${BOLD}Dialout Agent Update${NC}`);
136
+ console.log('─'.repeat(40));
137
+ console.log(` Current version: ${current}`);
138
+ if (!latest) {
139
+ console.log(` ${YELLOW}Could not reach registry. Check your internet connection.${NC}`);
140
+ console.log('');
141
+ return;
142
+ }
143
+ console.log(` Latest version: ${latest}`);
144
+ if (!compareVersions(current, latest)) {
145
+ console.log(`\n ${GREEN}Already up to date!${NC}`);
146
+ console.log('');
147
+ return;
148
+ }
149
+ console.log(`\n Updating ${current} → ${GREEN}${latest}${NC}...`);
150
+ console.log('');
151
+ try {
152
+ (0, child_process_1.execSync)(`npm install -g ${PACKAGE_NAME}@${latest}`, { stdio: 'inherit' });
153
+ console.log('');
154
+ console.log(` ${GREEN}Updated to v${latest}!${NC}`);
155
+ console.log('');
156
+ // Self-heal: a watchdog written by a prior version (or before a package
157
+ // rename) can be left with a SCRIPT= line pointing at the old install.
158
+ // Repair it on every successful upgrade so machines don't need a manual
159
+ // "dialout repair" to notice — this is exactly the incident this
160
+ // release was built to fix (see docs/supervisor-hygiene-2.4.1.md).
161
+ try {
162
+ const { repairWatchdog } = require('./service-installer');
163
+ const { repaired, from, to } = repairWatchdog();
164
+ if (repaired) {
165
+ console.log(` ${YELLOW}Fixed a stale cron watchdog (was pointing at ${from}):${NC}`);
166
+ console.log(` now targets ${to}`);
167
+ console.log('');
168
+ }
169
+ }
170
+ catch (e) {
171
+ // Never let a failed self-heal fail (or roll back) the update itself —
172
+ // but a silent catch here is exactly the class of invisible drift this
173
+ // feature exists to close: a machine whose repair keeps failing (e.g.
174
+ // permission denied on the backup copy, a symlinked watchdog path,
175
+ // disk full) would otherwise print a clean "Updated to vX!" forever,
176
+ // with nothing to show the self-heal never actually landed.
177
+ console.error(` (watchdog repair skipped: ${e.message})`);
178
+ }
179
+ // Check if running as service or cron — suggest restart
180
+ try {
181
+ const { isServiceInstalled, isCronInstalled } = require('./service-installer');
182
+ if (isServiceInstalled()) {
183
+ console.log(` ${YELLOW}Service detected — restart to use new version:${NC}`);
184
+ console.log(` dialout uninstall-service`);
185
+ console.log(` dialout install-service`);
186
+ console.log('');
187
+ }
188
+ else if (isCronInstalled()) {
189
+ console.log(` ${YELLOW}Cron watchdog will auto-restart with new version.${NC}`);
190
+ console.log(` Or restart now: dialout stop && dialout start --daemon`);
191
+ console.log('');
192
+ }
193
+ }
194
+ catch { }
195
+ }
196
+ catch (err) {
197
+ console.error(` ${YELLOW}Update failed: ${err.message}${NC}`);
198
+ console.error(` Try manually: npm install -g ${PACKAGE_NAME}`);
199
+ console.log('');
200
+ }
201
+ }
202
+ //# sourceMappingURL=update-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-check.js","sourceRoot":"","sources":["../src/update-check.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { AgentConfig } from './config';
2
+ export declare const RECONNECT_BASE_MS = 1000;
3
+ export declare const RECONNECT_MAX_MS = 60000;
4
+ export declare function reconnectDelay(attempt: number, rand?: () => number): number;
5
+ export declare function connect(config: AgentConfig, onConnected?: () => void): void;
6
+ export declare function disconnect(): void;
7
+ export declare function isConnected(): boolean;
8
+ //# sourceMappingURL=websocket.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../src/websocket.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AA+BvC,eAAO,MAAM,iBAAiB,OAAO,CAAC;AACtC,eAAO,MAAM,gBAAgB,QAAS,CAAC;AAKvC,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,MAAoB,GAAG,MAAM,CAGxF;AAyGD,wBAAgB,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,CAAC,EAAE,MAAM,IAAI,GAAG,IAAI,CAqD3E;AAED,wBAAgB,UAAU,IAAI,IAAI,CAcjC;AAED,wBAAgB,WAAW,IAAI,OAAO,CAErC"}