@indianic/dialout 1.1.1 → 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 +429 -16
- 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
package/dist/cowork.js
ADDED
|
@@ -0,0 +1,370 @@
|
|
|
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.TOKEN_RE = exports.COWORK_END = exports.COWORK_BEGIN = void 0;
|
|
37
|
+
exports.sanitizeTokens = sanitizeTokens;
|
|
38
|
+
exports.renderMatchGate = renderMatchGate;
|
|
39
|
+
exports.renderCoworkBlock = renderCoworkBlock;
|
|
40
|
+
exports.removeCoworkBlock = removeCoworkBlock;
|
|
41
|
+
exports.installCoworkBlock = installCoworkBlock;
|
|
42
|
+
exports.unmatchableTokens = unmatchableTokens;
|
|
43
|
+
exports.coworkViability = coworkViability;
|
|
44
|
+
exports.pickTmuxInstall = pickTmuxInstall;
|
|
45
|
+
const fs = __importStar(require("fs"));
|
|
46
|
+
const terminal_markers_1 = require("./terminal-markers");
|
|
47
|
+
exports.COWORK_BEGIN = '# >>> dialout cowork wrapper >>>';
|
|
48
|
+
exports.COWORK_END = '# <<< dialout cowork wrapper <<<';
|
|
49
|
+
// The markers the agent wrote before the rename. New blocks use the names
|
|
50
|
+
// above, but removal has to recognise these too: the block lives in the user's
|
|
51
|
+
// shell rc, and a marker we no longer match is a block nobody can ever remove.
|
|
52
|
+
const LEGACY_COWORK_BEGIN = '# >>> devdash cowork wrapper >>>';
|
|
53
|
+
const LEGACY_COWORK_END = '# <<< devdash cowork wrapper <<<';
|
|
54
|
+
// Only tokens matching this may reach the shell `case` — rc-file injection
|
|
55
|
+
// defense. TERM_PROGRAM values and our marker tokens are all within this set.
|
|
56
|
+
// Note it also excludes every glob metacharacter, which is what makes a token
|
|
57
|
+
// safe to use as a `case` *pattern* and not just as a quoted value.
|
|
58
|
+
exports.TOKEN_RE = /^[A-Za-z0-9._-]+$/;
|
|
59
|
+
// Env var names are interpolated bare (inside ${...}), so they need the
|
|
60
|
+
// stricter shell-name rule on top of TOKEN_RE — "." and "-" are legal in a
|
|
61
|
+
// token but not in a variable name.
|
|
62
|
+
const ENV_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
63
|
+
function sanitizeTokens(tokens) {
|
|
64
|
+
const seen = new Set();
|
|
65
|
+
const out = [];
|
|
66
|
+
for (const t of tokens) {
|
|
67
|
+
if (exports.TOKEN_RE.test(t) && !seen.has(t)) {
|
|
68
|
+
seen.add(t);
|
|
69
|
+
out.push(t);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return out;
|
|
73
|
+
}
|
|
74
|
+
// One `[ -n "$VAR" ] && _dd_tp="token"` probe per ENV_MARKERS entry, in table
|
|
75
|
+
// order. Each is additionally guarded on _dd_tp still being empty so the FIRST
|
|
76
|
+
// match wins — that is what makes TERM_PROGRAM (assigned above these lines)
|
|
77
|
+
// take precedence and keeps a specific marker from being overwritten by the
|
|
78
|
+
// generic vte catch-all, exactly reproducing tokenFromEnv's precedence.
|
|
79
|
+
function renderEnvProbes() {
|
|
80
|
+
return terminal_markers_1.ENV_MARKERS
|
|
81
|
+
.filter(({ envVar, token }) => ENV_NAME_RE.test(envVar) && exports.TOKEN_RE.test(token))
|
|
82
|
+
.map(({ envVar, token }) => `[ -z "$_dd_tp" ] && [ -n "\${${envVar}:-}" ] && _dd_tp="${token}"`)
|
|
83
|
+
.join('\n');
|
|
84
|
+
}
|
|
85
|
+
// The shell twin of tokenFromProcTree(): walk up from this shell's own pid,
|
|
86
|
+
// at most 10 levels (self + 9 ancestors), matching /proc/<pid>/comm against
|
|
87
|
+
// PROC_NAMES. Reached when no env marker identified the terminal (xterm, foot,
|
|
88
|
+
// st, urxvt set no marker at all) OR when only the generic vte catch-all did —
|
|
89
|
+
// xfce4-terminal is VTE-based, so "vte" is provisional and the walk must still
|
|
90
|
+
// get a chance to name it exactly. See the guard below and GENERIC_ENV_TOKEN.
|
|
91
|
+
//
|
|
92
|
+
// It runs on every interactive shell start, so it must stay cheap: `read`,
|
|
93
|
+
// `case` and parameter expansion are all shell builtins, so the whole walk
|
|
94
|
+
// forks nothing. The `[ -d /proc ]` guard makes it a zero-cost no-op on macOS.
|
|
95
|
+
//
|
|
96
|
+
// Silence on a failed read is enforced by `done 2>/dev/null` on the whole
|
|
97
|
+
// loop, NOT by a per-read `2>/dev/null`. Redirections are applied left to
|
|
98
|
+
// right, so in `read x < file 2>/dev/null` the input redirect fails *before*
|
|
99
|
+
// stderr is redirected and the shell's diagnostic still reaches the user's
|
|
100
|
+
// terminal. Reordering to `read x 2>/dev/null < file` fixes sh/dash/bash but
|
|
101
|
+
// NOT zsh, which reports redirection errors on the original stderr regardless
|
|
102
|
+
// of order — and .zshrc is half the blast radius. Redirecting the compound
|
|
103
|
+
// command is the only form verified silent in all four shells; it also covers
|
|
104
|
+
// the `[ "$_dd_pid" -gt 1 ]` "Illegal number" path. Failed reads still
|
|
105
|
+
// `|| break`, so the walk ends rather than spinning. stdout stays untouched.
|
|
106
|
+
//
|
|
107
|
+
// Not a theoretical path: /proc mounted with hidepid=1/2, or systemd's
|
|
108
|
+
// ProtectProc=, hides root-owned ancestors (login, agetty, gdm-session-worker),
|
|
109
|
+
// and the marker-less terminals that reach this walk are also the ones that
|
|
110
|
+
// run all 10 levels — so an unfixed walk printed an error on every new
|
|
111
|
+
// terminal, forever, until the user hand-edited their rc.
|
|
112
|
+
function renderProcWalk() {
|
|
113
|
+
const arms = Object.entries(terminal_markers_1.PROC_NAMES)
|
|
114
|
+
.filter(([comm, token]) => exports.TOKEN_RE.test(comm) && exports.TOKEN_RE.test(token))
|
|
115
|
+
.map(([comm, token]) => ` ${comm}) _dd_tp="${token}" ;;`)
|
|
116
|
+
.join('\n');
|
|
117
|
+
// The guard admits two states: nothing resolved at all, or ONLY the generic
|
|
118
|
+
// vte catch-all resolved. The second is what makes the walk reachable for
|
|
119
|
+
// VTE-based emulators that are in PROC_NAMES (xfce4-terminal) — see
|
|
120
|
+
// GENERIC_ENV_TOKEN. `_dd_prev` carries the provisional token across the
|
|
121
|
+
// walk so it can be restored when the walk names nothing; the walk itself is
|
|
122
|
+
// unchanged and still writes into an initially-empty `_dd_tp`, so a specific
|
|
123
|
+
// marker above VTE_VERSION in the table is still final. This is the shell
|
|
124
|
+
// twin of currentTerminalToken()'s `tokenFromProcTree(...) || token`.
|
|
125
|
+
return `if { [ -z "$_dd_tp" ] || [ "$_dd_tp" = "${terminal_markers_1.GENERIC_ENV_TOKEN}" ]; } && [ -d /proc ]; then
|
|
126
|
+
_dd_prev="$_dd_tp"
|
|
127
|
+
_dd_tp=""
|
|
128
|
+
_dd_pid=$$
|
|
129
|
+
_dd_lvl=0
|
|
130
|
+
while [ "$_dd_lvl" -lt 10 ]; do
|
|
131
|
+
_dd_lvl=$((_dd_lvl + 1))
|
|
132
|
+
[ "$_dd_pid" -gt 1 ] || break
|
|
133
|
+
read -r _dd_comm < "/proc/$_dd_pid/comm" || break
|
|
134
|
+
case "$_dd_comm" in
|
|
135
|
+
${arms}
|
|
136
|
+
esac
|
|
137
|
+
[ -z "$_dd_tp" ] || break
|
|
138
|
+
read -r _dd_stat < "/proc/$_dd_pid/stat" || break
|
|
139
|
+
# ppid is the 2nd field after the LAST ")" (a comm may contain both).
|
|
140
|
+
_dd_rest="\${_dd_stat##*) }"
|
|
141
|
+
_dd_rest="\${_dd_rest#* }"
|
|
142
|
+
_dd_ppid="\${_dd_rest%% *}"
|
|
143
|
+
case "$_dd_ppid" in
|
|
144
|
+
''|*[!0-9]*) break ;;
|
|
145
|
+
esac
|
|
146
|
+
_dd_pid="$_dd_ppid"
|
|
147
|
+
done 2>/dev/null
|
|
148
|
+
[ -n "$_dd_tp" ] || _dd_tp="$_dd_prev"
|
|
149
|
+
fi
|
|
150
|
+
unset _dd_pid _dd_lvl _dd_comm _dd_stat _dd_rest _dd_ppid _dd_prev`;
|
|
151
|
+
}
|
|
152
|
+
// The _dd_tp resolution + case that sets _dd_match. Column-0 so it can be
|
|
153
|
+
// unit-tested under `sh -c` in isolation; renderCoworkBlock indents it.
|
|
154
|
+
// Resolution order mirrors terminal-markers.ts exactly: TERM_PROGRAM (an Apple
|
|
155
|
+
// convention — unset under every Linux terminal), then ENV_MARKERS in table
|
|
156
|
+
// order, then the /proc process-tree walk.
|
|
157
|
+
function renderMatchGate(tokens) {
|
|
158
|
+
const clean = sanitizeTokens(tokens);
|
|
159
|
+
const arm = clean.length > 0
|
|
160
|
+
? `${clean.join('|')}) _dd_match=1 ;;`
|
|
161
|
+
: '*) ;;';
|
|
162
|
+
return `_dd_tp="\${TERM_PROGRAM:-}"
|
|
163
|
+
${renderEnvProbes()}
|
|
164
|
+
${renderProcWalk()}
|
|
165
|
+
_dd_match=""
|
|
166
|
+
case "$_dd_tp" in
|
|
167
|
+
${arm}
|
|
168
|
+
esac`;
|
|
169
|
+
}
|
|
170
|
+
// The verbatim tmux wrap body (carried over from the pre-gating COWORK_BLOCK).
|
|
171
|
+
// Do NOT add pane-scrollbars here — it wedges tmux at 100% CPU.
|
|
172
|
+
//
|
|
173
|
+
// The clipboard bindings are a SINGLE if/elif chain (pbcopy → wl-copy → xclip
|
|
174
|
+
// → xsel), never a pbcopy branch plus an independent Linux one. xclip and xsel
|
|
175
|
+
// are both installable on macOS via Homebrew, so two independent branches both
|
|
176
|
+
// ran on such a Mac; all four bind-key calls fired twice and the LATER binding
|
|
177
|
+
// won, routing copy-mode copy through `xclip -selection clipboard`, which then
|
|
178
|
+
// fails at runtime with no DISPLAY — macOS clipboard copy silently stops
|
|
179
|
+
// working (Constraint 1). bind-key is server-global, so an affected Mac also
|
|
180
|
+
// flip-flopped between xclip (after a native cowork shell started) and pbcopy
|
|
181
|
+
// (after a browser attach, whose bindings come from copyVerb() in
|
|
182
|
+
// pty-manager.ts — which returns pbcopy on darwin before probing anything).
|
|
183
|
+
// The chain here and copyVerb() must keep the same shape and the same order.
|
|
184
|
+
const WRAP_BODY = `_dd_base=$(basename "$PWD" 2>/dev/null | LC_ALL=C tr -cd 'a-zA-Z0-9_-' | cut -c1-20)
|
|
185
|
+
[ -n "$_dd_base" ] || _dd_base=shell
|
|
186
|
+
_dd_name="\${_dd_base}-$(( \${RANDOM:-$$} % 9000 + 1000 ))"
|
|
187
|
+
if tmux new-session -d -s "$_dd_name" 2>/dev/null; then
|
|
188
|
+
tmux set-option -t "$_dd_name" @term_program "\${TERM_PROGRAM:-\${TERMINAL_EMULATOR:-unknown}}" 2>/dev/null
|
|
189
|
+
tmux set-option -t "$_dd_name" @devdash_origin native 2>/dev/null
|
|
190
|
+
tmux set-window-option -t "$_dd_name" window-size latest 2>/dev/null
|
|
191
|
+
tmux set-window-option -t "$_dd_name" aggressive-resize on 2>/dev/null
|
|
192
|
+
tmux set-option -g mouse on 2>/dev/null
|
|
193
|
+
tmux set-option -s set-clipboard on 2>/dev/null
|
|
194
|
+
tmux set-option -g status on 2>/dev/null
|
|
195
|
+
tmux set-option -g history-limit 50000 2>/dev/null
|
|
196
|
+
tmux set-option -sg escape-time 10 2>/dev/null
|
|
197
|
+
tmux set-option -g allow-passthrough on 2>/dev/null
|
|
198
|
+
tmux set-option -g focus-events on 2>/dev/null
|
|
199
|
+
tmux show-options -g terminal-features 2>/dev/null | grep -q RGB || tmux set-option -sa terminal-features "*:RGB" 2>/dev/null
|
|
200
|
+
tmux unbind-key -n MouseDown3Pane 2>/dev/null
|
|
201
|
+
tmux unbind-key -n MouseDown3Status 2>/dev/null
|
|
202
|
+
# Clipboard: ONE chain, first available wins — pbcopy must EXCLUDE the Linux
|
|
203
|
+
# tools, which are installable on macOS too (see the note in cowork.ts).
|
|
204
|
+
# Each arm sets copy-command as well as the four bind-keys. The bind-keys
|
|
205
|
+
# only cover drag-release and the keyboard copies; copy-command is what makes
|
|
206
|
+
# tmux's own double-click-word / triple-click-line defaults — which call
|
|
207
|
+
# copy-pipe-and-cancel with NO argument — reach the system clipboard instead
|
|
208
|
+
# of stopping at the tmux paste buffer. See clipboardBindings() in
|
|
209
|
+
# pty-manager.ts for the measurements. Both files must stay in the same shape
|
|
210
|
+
# and the same order.
|
|
211
|
+
if command -v pbcopy >/dev/null 2>&1; then
|
|
212
|
+
tmux set-option -g copy-command pbcopy 2>/dev/null
|
|
213
|
+
tmux bind-key -T copy-mode MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel pbcopy 2>/dev/null
|
|
214
|
+
tmux bind-key -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel pbcopy 2>/dev/null
|
|
215
|
+
tmux bind-key -T copy-mode Enter send-keys -X copy-pipe-and-cancel pbcopy 2>/dev/null
|
|
216
|
+
tmux bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel pbcopy 2>/dev/null
|
|
217
|
+
elif command -v wl-copy >/dev/null 2>&1; then
|
|
218
|
+
tmux set-option -g copy-command wl-copy 2>/dev/null
|
|
219
|
+
tmux bind-key -T copy-mode MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel wl-copy 2>/dev/null
|
|
220
|
+
tmux bind-key -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel wl-copy 2>/dev/null
|
|
221
|
+
tmux bind-key -T copy-mode Enter send-keys -X copy-pipe-and-cancel wl-copy 2>/dev/null
|
|
222
|
+
tmux bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel wl-copy 2>/dev/null
|
|
223
|
+
elif command -v xclip >/dev/null 2>&1; then
|
|
224
|
+
tmux set-option -g copy-command "xclip -selection clipboard" 2>/dev/null
|
|
225
|
+
tmux bind-key -T copy-mode MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "xclip -selection clipboard" 2>/dev/null
|
|
226
|
+
tmux bind-key -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "xclip -selection clipboard" 2>/dev/null
|
|
227
|
+
tmux bind-key -T copy-mode Enter send-keys -X copy-pipe-and-cancel "xclip -selection clipboard" 2>/dev/null
|
|
228
|
+
tmux bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "xclip -selection clipboard" 2>/dev/null
|
|
229
|
+
elif command -v xsel >/dev/null 2>&1; then
|
|
230
|
+
tmux set-option -g copy-command "xsel --clipboard --input" 2>/dev/null
|
|
231
|
+
tmux bind-key -T copy-mode MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "xsel --clipboard --input" 2>/dev/null
|
|
232
|
+
tmux bind-key -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "xsel --clipboard --input" 2>/dev/null
|
|
233
|
+
tmux bind-key -T copy-mode Enter send-keys -X copy-pipe-and-cancel "xsel --clipboard --input" 2>/dev/null
|
|
234
|
+
tmux bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "xsel --clipboard --input" 2>/dev/null
|
|
235
|
+
fi
|
|
236
|
+
tmux set-option -t "$_dd_name" @devdash_folder "$(basename "$PWD" 2>/dev/null)" 2>/dev/null
|
|
237
|
+
tmux set-option -t "$_dd_name" @devdash_folder_path "$PWD" 2>/dev/null
|
|
238
|
+
tmux set-option -t "$_dd_name" @devdash_created "$(date +%Y-%m-%dT%H:%M:%S)" 2>/dev/null
|
|
239
|
+
tmux set-option -t "$_dd_name" @devdash_git "$(git rev-parse --abbrev-ref HEAD 2>/dev/null)" 2>/dev/null
|
|
240
|
+
exec tmux new-session -A -s "$_dd_name"
|
|
241
|
+
fi
|
|
242
|
+
unset _dd_base _dd_name`;
|
|
243
|
+
function indent(text, pad) {
|
|
244
|
+
return text.split('\n').map((l) => (l ? pad + l : l)).join('\n');
|
|
245
|
+
}
|
|
246
|
+
// Regenerate the full app-gated rc block from the allowlist. An empty (or
|
|
247
|
+
// fully-sanitized-away) list yields a block that never wraps.
|
|
248
|
+
function renderCoworkBlock(tokens) {
|
|
249
|
+
const gate = indent(renderMatchGate(tokens), ' ');
|
|
250
|
+
const body = indent(WRAP_BODY, ' ');
|
|
251
|
+
return `${exports.COWORK_BEGIN}
|
|
252
|
+
# Managed by "dialout setup-cowork" — do not edit inside the markers.
|
|
253
|
+
case $- in
|
|
254
|
+
*i*)
|
|
255
|
+
if [ -z "$TMUX" ] && [ -z "$DEVDASH_NO_WRAP" ] && [ -z "$SSH_TTY" ] && [ -t 1 ] \\
|
|
256
|
+
&& command -v tmux >/dev/null 2>&1; then
|
|
257
|
+
${gate}
|
|
258
|
+
if [ -n "$_dd_match" ]; then
|
|
259
|
+
${body}
|
|
260
|
+
fi
|
|
261
|
+
unset _dd_tp _dd_match
|
|
262
|
+
fi
|
|
263
|
+
;;
|
|
264
|
+
esac
|
|
265
|
+
${exports.COWORK_END}`;
|
|
266
|
+
}
|
|
267
|
+
function stripBetween(content, begin, end) {
|
|
268
|
+
const b = content.indexOf(begin);
|
|
269
|
+
if (b === -1)
|
|
270
|
+
return content;
|
|
271
|
+
const e = content.indexOf(end);
|
|
272
|
+
if (e === -1)
|
|
273
|
+
return content;
|
|
274
|
+
return (content.slice(0, b) + content.slice(e + end.length)).replace(/\n{3,}/g, '\n\n');
|
|
275
|
+
}
|
|
276
|
+
function removeCoworkBlock(content) {
|
|
277
|
+
// Strip a pre-rename block first, so upgrading and then removing does not
|
|
278
|
+
// leave the old one behind.
|
|
279
|
+
content = stripBetween(content, LEGACY_COWORK_BEGIN, LEGACY_COWORK_END);
|
|
280
|
+
const begin = content.indexOf(exports.COWORK_BEGIN);
|
|
281
|
+
if (begin === -1)
|
|
282
|
+
return content;
|
|
283
|
+
const end = content.indexOf(exports.COWORK_END);
|
|
284
|
+
if (end === -1 || end < begin)
|
|
285
|
+
return content;
|
|
286
|
+
return (content.slice(0, begin) + content.slice(end + exports.COWORK_END.length))
|
|
287
|
+
.replace(/\n{3,}$/g, '\n\n');
|
|
288
|
+
}
|
|
289
|
+
function installCoworkBlock(rcPath, tokens) {
|
|
290
|
+
const existed = fs.existsSync(rcPath);
|
|
291
|
+
const content = existed ? fs.readFileSync(rcPath, 'utf-8') : '';
|
|
292
|
+
const had = content.includes(exports.COWORK_BEGIN) || content.includes(LEGACY_COWORK_BEGIN);
|
|
293
|
+
const cleaned = removeCoworkBlock(content);
|
|
294
|
+
const next = cleaned.replace(/\n*$/, '\n\n') + renderCoworkBlock(tokens) + '\n';
|
|
295
|
+
fs.writeFileSync(rcPath, next);
|
|
296
|
+
return had ? 'updated' : existed ? 'installed' : 'created';
|
|
297
|
+
}
|
|
298
|
+
// Linux package managers in preference order → install command.
|
|
299
|
+
const LINUX_MANAGERS = [
|
|
300
|
+
{ bin: 'apt-get', command: 'sudo apt-get install -y tmux' },
|
|
301
|
+
{ bin: 'dnf', command: 'sudo dnf install -y tmux' },
|
|
302
|
+
{ bin: 'yum', command: 'sudo yum install -y tmux' },
|
|
303
|
+
{ bin: 'pacman', command: 'sudo pacman -S --noconfirm tmux' },
|
|
304
|
+
{ bin: 'zypper', command: 'sudo zypper install -y tmux' },
|
|
305
|
+
];
|
|
306
|
+
// --- unmatchableTokens: the guard rail against the reported silent no-op ---
|
|
307
|
+
//
|
|
308
|
+
// The bug shipped a green "Cowork enabled." for GNOME Terminal on Linux, which
|
|
309
|
+
// then never wrapped because the gate keyed off $TERM_PROGRAM alone (GNOME
|
|
310
|
+
// Terminal never sets it). Tasks 1-5 fixed detection; this makes a selection
|
|
311
|
+
// that STILL can't match on this platform loud instead of silent.
|
|
312
|
+
//
|
|
313
|
+
// Derived from the shared tables (ENV_MARKERS, PROC_NAMES) rather than a
|
|
314
|
+
// second hand-maintained list, so it cannot drift from them the way the shell
|
|
315
|
+
// gate and terminal-detect.ts once drifted from each other.
|
|
316
|
+
//
|
|
317
|
+
// ENV_MARKERS' first three entries (kitty, alacritty, WezTerm) are terminal
|
|
318
|
+
// emulators that ship on both platforms and set the same env var on either —
|
|
319
|
+
// so they're excluded from "linux-only" even though they live in the table.
|
|
320
|
+
// Everything else in ENV_MARKERS (konsole, tilix, terminator, gnome-terminal,
|
|
321
|
+
// vte) and everything in PROC_NAMES (xfce4-terminal, foot, urxvt, xterm, st,
|
|
322
|
+
// plus the overlapping cross-platform entries, which the exclusion above
|
|
323
|
+
// removes again) is Linux desktop-environment-specific and cannot be produced
|
|
324
|
+
// on darwin.
|
|
325
|
+
const CROSS_PLATFORM_TOKENS = new Set(terminal_markers_1.ENV_MARKERS.slice(0, 3).map((m) => m.token));
|
|
326
|
+
const LINUX_ONLY_TOKENS = new Set([...terminal_markers_1.ENV_MARKERS.map((m) => m.token), ...Object.values(terminal_markers_1.PROC_NAMES)]
|
|
327
|
+
.filter((token) => !CROSS_PLATFORM_TOKENS.has(token)));
|
|
328
|
+
// TERM_PROGRAM values with no Linux equivalent. These can't be derived from
|
|
329
|
+
// ENV_MARKERS or PROC_NAMES — TERM_PROGRAM is an Apple convention read
|
|
330
|
+
// directly by tokenFromEnv, not a table entry — so they're named explicitly.
|
|
331
|
+
// Keep this list to exactly these two; anything else must come from the
|
|
332
|
+
// shared tables above.
|
|
333
|
+
const MACOS_ONLY_TOKENS = new Set(['Apple_Terminal', 'iTerm.app']);
|
|
334
|
+
/** Tokens that cannot be produced by tokenFromEnv/proc detection here. */
|
|
335
|
+
function unmatchableTokens(tokens, platform) {
|
|
336
|
+
if (platform === 'darwin')
|
|
337
|
+
return tokens.filter((t) => LINUX_ONLY_TOKENS.has(t));
|
|
338
|
+
if (platform === 'linux')
|
|
339
|
+
return tokens.filter((t) => MACOS_ONLY_TOKENS.has(t));
|
|
340
|
+
return [];
|
|
341
|
+
}
|
|
342
|
+
function coworkViability(env, anyEmulatorInstalled) {
|
|
343
|
+
const reasons = [];
|
|
344
|
+
if (env.SSH_TTY || env.SSH_CONNECTION)
|
|
345
|
+
reasons.push('ssh-session');
|
|
346
|
+
if (!anyEmulatorInstalled)
|
|
347
|
+
reasons.push('no-emulator');
|
|
348
|
+
return { usable: reasons.length === 0, reasons };
|
|
349
|
+
}
|
|
350
|
+
function pickTmuxInstall(platform, hasCommand) {
|
|
351
|
+
if (platform === 'darwin') {
|
|
352
|
+
if (hasCommand('brew'))
|
|
353
|
+
return { command: 'brew install tmux', canAuto: true };
|
|
354
|
+
return {
|
|
355
|
+
command: '',
|
|
356
|
+
canAuto: false,
|
|
357
|
+
manual: 'Homebrew is not installed. Install it from https://brew.sh then run: brew install tmux',
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
for (const m of LINUX_MANAGERS) {
|
|
361
|
+
if (hasCommand(m.bin))
|
|
362
|
+
return { command: m.command, canAuto: true };
|
|
363
|
+
}
|
|
364
|
+
return {
|
|
365
|
+
command: '',
|
|
366
|
+
canAuto: false,
|
|
367
|
+
manual: 'No supported package manager found. Install tmux with your distro\'s package manager (apt/dnf/yum/pacman/zypper).',
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
//# sourceMappingURL=cowork.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cowork.js","sourceRoot":"","sources":["../src/cowork.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs-browser.d.ts","sourceRoot":"","sources":["../src/fs-browser.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,WAAW,GAAG,MAAM,CAAC;CAC5B;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,EAAE,CAwBzD"}
|
|
@@ -0,0 +1,61 @@
|
|
|
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.listDirectory = listDirectory;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
function listDirectory(dirPath) {
|
|
40
|
+
const resolvedPath = path.resolve(dirPath);
|
|
41
|
+
if (!fs.existsSync(resolvedPath)) {
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
const stat = fs.statSync(resolvedPath);
|
|
45
|
+
if (!stat.isDirectory()) {
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
const entries = fs.readdirSync(resolvedPath, { withFileTypes: true });
|
|
49
|
+
return entries
|
|
50
|
+
.filter((entry) => !entry.name.startsWith('.'))
|
|
51
|
+
.map((entry) => ({
|
|
52
|
+
name: entry.name,
|
|
53
|
+
type: entry.isDirectory() ? 'directory' : 'file',
|
|
54
|
+
}))
|
|
55
|
+
.sort((a, b) => {
|
|
56
|
+
if (a.type === b.type)
|
|
57
|
+
return a.name.localeCompare(b.name);
|
|
58
|
+
return a.type === 'directory' ? -1 : 1;
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=fs-browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs-browser.js","sourceRoot":"","sources":["../src/fs-browser.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,sCAwBC;AAhCD,uCAAyB;AACzB,2CAA6B;AAO7B,SAAgB,aAAa,CAAC,OAAe;IAC3C,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAE3C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACjC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IACvC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;QACxB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,YAAY,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAEtE,OAAO,OAAO;SACX,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;SAC9C,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACf,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,IAAI,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,WAAoB,CAAC,CAAC,CAAC,MAAe;KACnE,CAAC,CAAC;SACF,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACb,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI;YAAE,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC3D,OAAO,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* True when `bin` resolves on PATH. Never throws.
|
|
3
|
+
*
|
|
4
|
+
* Deliberately does NOT pass an args array together with a `shell` option —
|
|
5
|
+
* that combination triggers Node 22+'s DEP0190 deprecation warning. Instead
|
|
6
|
+
* `/bin/sh` itself is the program, with a fixed `-c` script; `bin` is handed
|
|
7
|
+
* to the shell as `$1` (via the extra argv positions after the script),
|
|
8
|
+
* never concatenated into the command line, so it can't be interpreted as
|
|
9
|
+
* shell syntax either.
|
|
10
|
+
*/
|
|
11
|
+
export declare function hasCommand(bin: string): boolean;
|
|
12
|
+
//# sourceMappingURL=has-command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"has-command.d.ts","sourceRoot":"","sources":["../src/has-command.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAO/C"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.hasCommand = hasCommand;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
/**
|
|
6
|
+
* True when `bin` resolves on PATH. Never throws.
|
|
7
|
+
*
|
|
8
|
+
* Deliberately does NOT pass an args array together with a `shell` option —
|
|
9
|
+
* that combination triggers Node 22+'s DEP0190 deprecation warning. Instead
|
|
10
|
+
* `/bin/sh` itself is the program, with a fixed `-c` script; `bin` is handed
|
|
11
|
+
* to the shell as `$1` (via the extra argv positions after the script),
|
|
12
|
+
* never concatenated into the command line, so it can't be interpreted as
|
|
13
|
+
* shell syntax either.
|
|
14
|
+
*/
|
|
15
|
+
function hasCommand(bin) {
|
|
16
|
+
try {
|
|
17
|
+
(0, child_process_1.execFileSync)('/bin/sh', ['-c', 'command -v "$1" >/dev/null 2>&1', 'sh', bin], { stdio: 'pipe' });
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=has-command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"has-command.js","sourceRoot":"","sources":["../src/has-command.ts"],"names":[],"mappings":";;AAYA,gCAOC;AAnBD,iDAA6C;AAE7C;;;;;;;;;GASG;AACH,SAAgB,UAAU,CAAC,GAAW;IACpC,IAAI,CAAC;QACH,IAAA,4BAAY,EAAC,SAAS,EAAE,CAAC,IAAI,EAAE,iCAAiC,EAAE,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACjG,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import WebSocket from 'ws';
|
|
2
|
+
export declare const STALE_MULTIPLIER = 2.5;
|
|
3
|
+
export declare function isConnectionStale(lastPong: number | null, now: number, intervalMs: number): boolean;
|
|
4
|
+
export declare function notePong(): void;
|
|
5
|
+
export declare function startHeartbeat(ws: WebSocket, intervalMs: number, onStale?: () => void): void;
|
|
6
|
+
export declare function stopHeartbeat(): void;
|
|
7
|
+
//# sourceMappingURL=heartbeat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heartbeat.d.ts","sourceRoot":"","sources":["../src/heartbeat.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,IAAI,CAAC;AAO3B,eAAO,MAAM,gBAAgB,MAAM,CAAC;AAKpC,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,GACjB,OAAO,CAGT;AAED,wBAAgB,QAAQ,IAAI,IAAI,CAE/B;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,IAAI,GAAG,IAAI,CAa5F;AAED,wBAAgB,aAAa,IAAI,IAAI,CAMpC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.STALE_MULTIPLIER = void 0;
|
|
7
|
+
exports.isConnectionStale = isConnectionStale;
|
|
8
|
+
exports.notePong = notePong;
|
|
9
|
+
exports.startHeartbeat = startHeartbeat;
|
|
10
|
+
exports.stopHeartbeat = stopHeartbeat;
|
|
11
|
+
const ws_1 = __importDefault(require("ws"));
|
|
12
|
+
let heartbeatTimer = null;
|
|
13
|
+
let lastPongAt = null;
|
|
14
|
+
// How many heartbeat intervals of silence before the socket is declared dead.
|
|
15
|
+
// 2.5 tolerates one dropped heartbeat plus jitter without a false positive.
|
|
16
|
+
exports.STALE_MULTIPLIER = 2.5;
|
|
17
|
+
// The server answers every `heartbeat` with a `pong`. If pongs stop arriving
|
|
18
|
+
// the socket is half-open: sends still "succeed" into a dead TCP connection and
|
|
19
|
+
// 'close' may not fire for many minutes, so nothing would trigger a reconnect.
|
|
20
|
+
function isConnectionStale(lastPong, now, intervalMs) {
|
|
21
|
+
if (lastPong === null)
|
|
22
|
+
return false; // no pong expected yet
|
|
23
|
+
return now - lastPong > intervalMs * exports.STALE_MULTIPLIER;
|
|
24
|
+
}
|
|
25
|
+
function notePong() {
|
|
26
|
+
lastPongAt = Date.now();
|
|
27
|
+
}
|
|
28
|
+
function startHeartbeat(ws, intervalMs, onStale) {
|
|
29
|
+
stopHeartbeat();
|
|
30
|
+
lastPongAt = Date.now(); // treat connect as a fresh pong
|
|
31
|
+
heartbeatTimer = setInterval(() => {
|
|
32
|
+
if (ws.readyState !== ws_1.default.OPEN)
|
|
33
|
+
return;
|
|
34
|
+
if (isConnectionStale(lastPongAt, Date.now(), intervalMs)) {
|
|
35
|
+
console.error('[dialout] No pong from server — connection is dead, reconnecting');
|
|
36
|
+
stopHeartbeat();
|
|
37
|
+
onStale?.();
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
ws.send(JSON.stringify({ type: 'heartbeat', ts: Date.now() }));
|
|
41
|
+
}, intervalMs);
|
|
42
|
+
}
|
|
43
|
+
function stopHeartbeat() {
|
|
44
|
+
if (heartbeatTimer) {
|
|
45
|
+
clearInterval(heartbeatTimer);
|
|
46
|
+
heartbeatTimer = null;
|
|
47
|
+
}
|
|
48
|
+
lastPongAt = null;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=heartbeat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heartbeat.js","sourceRoot":"","sources":["../src/heartbeat.ts"],"names":[],"mappings":";;;;;;AAYA,8CAOC;AAED,4BAEC;AAED,wCAaC;AAED,sCAMC;AA9CD,4CAA2B;AAE3B,IAAI,cAAc,GAA0B,IAAI,CAAC;AACjD,IAAI,UAAU,GAAkB,IAAI,CAAC;AAErC,8EAA8E;AAC9E,4EAA4E;AAC/D,QAAA,gBAAgB,GAAG,GAAG,CAAC;AAEpC,6EAA6E;AAC7E,gFAAgF;AAChF,+EAA+E;AAC/E,SAAgB,iBAAiB,CAC/B,QAAuB,EACvB,GAAW,EACX,UAAkB;IAElB,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC,CAAC,uBAAuB;IAC5D,OAAO,GAAG,GAAG,QAAQ,GAAG,UAAU,GAAG,wBAAgB,CAAC;AACxD,CAAC;AAED,SAAgB,QAAQ;IACtB,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AAC1B,CAAC;AAED,SAAgB,cAAc,CAAC,EAAa,EAAE,UAAkB,EAAE,OAAoB;IACpF,aAAa,EAAE,CAAC;IAChB,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,gCAAgC;IACzD,cAAc,GAAG,WAAW,CAAC,GAAG,EAAE;QAChC,IAAI,EAAE,CAAC,UAAU,KAAK,YAAS,CAAC,IAAI;YAAE,OAAO;QAC7C,IAAI,iBAAiB,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC,EAAE,CAAC;YAC1D,OAAO,CAAC,KAAK,CAAC,kEAAkE,CAAC,CAAC;YAClF,aAAa,EAAE,CAAC;YAChB,OAAO,EAAE,EAAE,CAAC;YACZ,OAAO;QACT,CAAC;QACD,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;IACjE,CAAC,EAAE,UAAU,CAAC,CAAC;AACjB,CAAC;AAED,SAAgB,aAAa;IAC3B,IAAI,cAAc,EAAE,CAAC;QACnB,aAAa,CAAC,cAAc,CAAC,CAAC;QAC9B,cAAc,GAAG,IAAI,CAAC;IACxB,CAAC;IACD,UAAU,GAAG,IAAI,CAAC;AACpB,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const path_1 = __importDefault(require("path"));
|
|
7
|
+
const config_1 = require("./config");
|
|
8
|
+
const websocket_1 = require("./websocket");
|
|
9
|
+
const single_instance_1 = require("./single-instance");
|
|
10
|
+
// LaunchDaemons / systemd units start with a bare PATH (/usr/bin:/bin:...) that
|
|
11
|
+
// omits Homebrew and /usr/local/bin, so `tmux` resolves to ENOENT at boot even
|
|
12
|
+
// when installed — breaking cowork wrapping and live-session reporting. Ensure
|
|
13
|
+
// the common tool locations (and our own node dir) are on PATH before any child
|
|
14
|
+
// spawn, regardless of how the agent was launched. Existing entries keep their
|
|
15
|
+
// priority; we only append what's missing.
|
|
16
|
+
(() => {
|
|
17
|
+
const extra = ['/opt/homebrew/bin', '/usr/local/bin', '/usr/bin', '/bin', path_1.default.dirname(process.execPath)];
|
|
18
|
+
const parts = (process.env.PATH || '').split(path_1.default.delimiter).filter(Boolean);
|
|
19
|
+
const seen = new Set(parts);
|
|
20
|
+
for (const p of extra)
|
|
21
|
+
if (p && !seen.has(p)) {
|
|
22
|
+
parts.push(p);
|
|
23
|
+
seen.add(p);
|
|
24
|
+
}
|
|
25
|
+
process.env.PATH = parts.join(path_1.default.delimiter);
|
|
26
|
+
})();
|
|
27
|
+
const config = (0, config_1.loadConfig)();
|
|
28
|
+
if (!config.serverUrl || !config.apiKey) {
|
|
29
|
+
console.error('[dialout] Not configured. Run: dialout init');
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
// Enforce one agent per server URL. A watchdog/service respawn or a stray
|
|
33
|
+
// manual start that lands while a healthy agent is already connected steps
|
|
34
|
+
// aside here instead of opening a second socket on the same key (which the
|
|
35
|
+
// server would drop with close 1006, flapping both). See single-instance.ts.
|
|
36
|
+
if (!(0, single_instance_1.acquireSingleInstanceLock)(config.serverUrl)) {
|
|
37
|
+
console.log(`[dialout] Already running for ${config.serverUrl} — exiting (single instance).`);
|
|
38
|
+
process.exit(0);
|
|
39
|
+
}
|
|
40
|
+
console.log(`[dialout] Starting...`);
|
|
41
|
+
console.log(`[dialout] Server: ${config.serverUrl}`);
|
|
42
|
+
(0, websocket_1.connect)(config, () => {
|
|
43
|
+
console.log('[dialout] Ready');
|
|
44
|
+
});
|
|
45
|
+
// Graceful shutdown
|
|
46
|
+
process.on('SIGINT', () => {
|
|
47
|
+
console.log('\n[dialout] Shutting down...');
|
|
48
|
+
(0, websocket_1.disconnect)();
|
|
49
|
+
process.exit(0);
|
|
50
|
+
});
|
|
51
|
+
process.on('SIGTERM', () => {
|
|
52
|
+
console.log('[dialout] Shutting down...');
|
|
53
|
+
(0, websocket_1.disconnect)();
|
|
54
|
+
process.exit(0);
|
|
55
|
+
});
|
|
56
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;AAAA,gDAAwB;AACxB,qCAAsC;AACtC,2CAAkD;AAClD,uDAA8D;AAE9D,gFAAgF;AAChF,+EAA+E;AAC/E,+EAA+E;AAC/E,gFAAgF;AAChF,+EAA+E;AAC/E,2CAA2C;AAC3C,CAAC,GAAG,EAAE;IACJ,MAAM,KAAK,GAAG,CAAC,mBAAmB,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,EAAE,cAAI,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC1G,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,cAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC7E,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;IAC5B,KAAK,MAAM,CAAC,IAAI,KAAK;QAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAAC,CAAC;IAC7E,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,cAAI,CAAC,SAAS,CAAC,CAAC;AAChD,CAAC,CAAC,EAAE,CAAC;AAEL,MAAM,MAAM,GAAG,IAAA,mBAAU,GAAE,CAAC;AAE5B,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;IACxC,OAAO,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;IAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,0EAA0E;AAC1E,2EAA2E;AAC3E,2EAA2E;AAC3E,6EAA6E;AAC7E,IAAI,CAAC,IAAA,2CAAyB,EAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,iCAAiC,MAAM,CAAC,SAAS,+BAA+B,CAAC,CAAC;IAC9F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;AACrC,OAAO,CAAC,GAAG,CAAC,qBAAqB,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;AAErD,IAAA,mBAAO,EAAC,MAAM,EAAE,GAAG,EAAE;IACnB,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;AACjC,CAAC,CAAC,CAAC;AAEH,oBAAoB;AACpB,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;IACxB,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;IAC5C,IAAA,sBAAU,GAAE,CAAC;IACb,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;IACzB,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;IAC1C,IAAA,sBAAU,GAAE,CAAC;IACb,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|