cli-jaw 2.17.22 → 2.17.23

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.
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Non-interactive shell PATH reachability (#479).
3
+ *
4
+ * `ssh host 'jaw serve ...'` runs a non-login, non-interactive shell. That
5
+ * shell reads none of the files the installer writes to: bash skips
6
+ * `.bash_profile`/`.profile` (login-only) and Debian's stock `.bashrc`
7
+ * returns at its first line when non-interactive; zsh reads only `.zshenv`,
8
+ * which the installer never touches. So a host where `jaw` works
9
+ * interactively can still fail to resolve it over SSH, and the failure
10
+ * surfaces as `nohup: failed to run command 'jaw'` — no PATH in sight.
11
+ *
12
+ * doctor cannot observe this by inspecting its own environment: it runs in
13
+ * the shell that already works. The reachability question has to be asked
14
+ * against the PATH a non-interactive shell would actually get, which is what
15
+ * `getconf PATH` reports.
16
+ */
17
+ import { delimiter, join } from 'node:path';
18
+ /**
19
+ * Install directories to search after the baseline PATH misses.
20
+ *
21
+ * `~/.local/bin` is what `scripts/install.sh` configures and what #479
22
+ * reported. The static list alone is not enough: a Node installed by nvm,
23
+ * fnm, or Homebrew puts global bins under a version-specific prefix that no
24
+ * fixed list can enumerate, and treating those as "not installed" would
25
+ * silently drop exactly the hosts this check exists for. So the caller's own
26
+ * resolved directories (npm prefix, the running binary's dir) are searched
27
+ * first — they are facts about this install, not guesses.
28
+ */
29
+ export function candidateInstallDirs(homeDir, knownBinDirs = []) {
30
+ return [
31
+ ...knownBinDirs.filter(Boolean),
32
+ join(homeDir, '.local', 'bin'),
33
+ join(homeDir, '.npm-global', 'bin'),
34
+ join(homeDir, 'bin'),
35
+ join(homeDir, '.volta', 'bin'),
36
+ join(homeDir, '.bun', 'bin'),
37
+ ];
38
+ }
39
+ function findIn(dirs, binary, probes) {
40
+ for (const dir of dirs) {
41
+ if (!dir)
42
+ continue;
43
+ if (probes.isExecutableFile(join(dir, binary)))
44
+ return dir;
45
+ }
46
+ return null;
47
+ }
48
+ /**
49
+ * Decide whether `binary` resolves in a non-interactive shell.
50
+ *
51
+ * Pure over its probes so the whole matrix is testable without an SSH host.
52
+ */
53
+ export function checkNonInteractivePath(binary, homeDir, probes, knownBinDirs = []) {
54
+ const baseline = probes.baselinePath();
55
+ if (!baseline)
56
+ return { status: 'unknown', foundIn: null, baseline: null };
57
+ const baselineDirs = baseline.split(delimiter).map(s => s.trim()).filter(Boolean);
58
+ const onBaseline = findIn(baselineDirs, binary, probes);
59
+ if (onBaseline)
60
+ return { status: 'reachable', foundIn: onBaseline, baseline };
61
+ // Only search install dirs the baseline did not already cover, so a hit
62
+ // here always means "installed but unreachable" rather than a re-report.
63
+ const extraDirs = candidateInstallDirs(homeDir, knownBinDirs).filter(dir => !baselineDirs.includes(dir));
64
+ const installed = findIn(extraDirs, binary, probes);
65
+ if (installed)
66
+ return { status: 'unreachable', foundIn: installed, baseline };
67
+ return { status: 'not-installed', foundIn: null, baseline };
68
+ }
69
+ /**
70
+ * Operator-facing remedy for an unreachable binary.
71
+ *
72
+ * `~/.zshenv` is named for zsh because it is the only startup file a
73
+ * non-interactive zsh reads; bash has no equivalent (`BASH_ENV` is honored
74
+ * only for non-interactive shells and is not set by default), so bash users
75
+ * get the absolute-path form, which always works.
76
+ */
77
+ export function nonInteractivePathRemedy(binary, foundIn) {
78
+ const absolute = join(foundIn, binary);
79
+ return [
80
+ `call it by absolute path: ${absolute}`,
81
+ `or export PATH in the remote command: ssh host 'export PATH="${foundIn}:$PATH"; ${binary} ...'`,
82
+ `or (zsh) add to ~/.zshenv: export PATH="${foundIn}:$PATH"`,
83
+ ];
84
+ }
85
+ //# sourceMappingURL=noninteractive-path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"noninteractive-path.js","sourceRoot":"","sources":["../../../src/core/noninteractive-path.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AA2B5C;;;;;;;;;;GAUG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAe,EAAE,eAAyB,EAAE;IAC7E,OAAO;QACH,GAAG,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC;QAC9B,IAAI,CAAC,OAAO,EAAE,aAAa,EAAE,KAAK,CAAC;QACnC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC;QACpB,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC;QAC9B,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC;KAC/B,CAAC;AACN,CAAC;AAED,SAAS,MAAM,CAAC,IAAc,EAAE,MAAc,EAAE,MAAgC;IAC5E,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,GAAG;YAAE,SAAS;QACnB,IAAI,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAAE,OAAO,GAAG,CAAC;IAC/D,CAAC;IACD,OAAO,IAAI,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CACnC,MAAc,EACd,OAAe,EACf,MAAgC,EAChC,eAAyB,EAAE;IAE3B,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,EAAE,CAAC;IACvC,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAE3E,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAClF,MAAM,UAAU,GAAG,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACxD,IAAI,UAAU;QAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;IAE9E,wEAAwE;IACxE,yEAAyE;IACzE,MAAM,SAAS,GAAG,oBAAoB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IACzG,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACpD,IAAI,SAAS;QAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;IAE9E,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAChE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,wBAAwB,CAAC,MAAc,EAAE,OAAe;IACpE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACvC,OAAO;QACH,6BAA6B,QAAQ,EAAE;QACvC,gEAAgE,OAAO,YAAY,MAAM,OAAO;QAChG,2CAA2C,OAAO,SAAS;KAC9D,CAAC;AACN,CAAC"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Guidance for hosts with no service manager (#479).
3
+ *
4
+ * `jaw service` can only register autostart where a service manager exists.
5
+ * On a systemd-less container (PID 1 = tini, a common shape) there is nothing
6
+ * to register with, so the command has to hand the operator a working manual
7
+ * recipe instead.
8
+ *
9
+ * The recipe it used to print — "run jaw serve under tmux/screen" — is not one.
10
+ * The reporter's failing command was a one-shot `ssh host '...'`, and a
11
+ * terminal multiplexer cannot be driven from that: it needs an interactive
12
+ * session to attach to, which is what a one-shot SSH command does not have.
13
+ * Worse, tmux inherits the same non-interactive PATH, so the multiplexer would
14
+ * fail to find `jaw` for exactly the reason the operator is already stuck on.
15
+ *
16
+ * What does work is what the reporter arrived at by hand: absolute paths (no
17
+ * PATH lookup to fail), `setsid` to detach from the SSH session so the
18
+ * process outlives the connection, and stdin from /dev/null so it never
19
+ * blocks on a terminal that is about to disappear.
20
+ */
21
+ import { dirname } from 'node:path';
22
+ /** Shell-quote a path only when it needs it, to keep the recipe readable. */
23
+ function q(value) {
24
+ return /[\s"'$`\\]/.test(value) ? `'${value.replace(/'/g, "'\\''")}'` : value;
25
+ }
26
+ /**
27
+ * A copy-pasteable start command that survives a one-shot SSH connection.
28
+ *
29
+ * Absolute node + jaw paths are deliberate: on the hosts that reach this
30
+ * message, a bare `jaw` is precisely what does not resolve.
31
+ */
32
+ export function manualStartCommand(ctx) {
33
+ return `setsid nohup ${q(ctx.nodePath)} ${q(ctx.jawPath)} --home ${q(ctx.home)} `
34
+ + `serve --port ${ctx.port} --no-open >> ${q(ctx.logPath)} 2>&1 < /dev/null &`;
35
+ }
36
+ /**
37
+ * The full operator message for a host with no service manager.
38
+ */
39
+ export function manualSupervisionGuidance(ctx) {
40
+ return [
41
+ 'No service manager available on this host.',
42
+ ' Supported: macOS (launchd), Linux (systemd), Windows (startup), Docker',
43
+ '',
44
+ ' This host has neither, so start it manually. Use absolute paths — a',
45
+ ` non-interactive shell (ssh host '...') does not have ${dirname(ctx.jawPath)} on PATH:`,
46
+ '',
47
+ ` ${manualStartCommand(ctx)}`,
48
+ '',
49
+ ` Verify it started (an empty result means it died): jaw --home ${q(ctx.home)} service status`,
50
+ ` Read the log on failure: tail -n 50 ${q(ctx.logPath)}`,
51
+ '',
52
+ ' To keep it running across crashes, re-run that command from a',
53
+ ' supervisor loop (cron @reboot, a container entrypoint, or a 60s',
54
+ ' while-loop that checks the port before restarting).',
55
+ ];
56
+ }
57
+ //# sourceMappingURL=manual-supervision.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manual-supervision.js","sourceRoot":"","sources":["../../../src/manager/manual-supervision.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,6EAA6E;AAC7E,SAAS,CAAC,CAAC,KAAa;IACpB,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;AAClF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAA6B;IAC5D,OAAO,gBAAgB,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG;UAC3E,gBAAgB,GAAG,CAAC,IAAI,iBAAiB,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,qBAAqB,CAAC;AACvF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,yBAAyB,CAAC,GAA6B;IACnE,OAAO;QACH,4CAA4C;QAC5C,2EAA2E;QAC3E,EAAE;QACF,wEAAwE;QACxE,2DAA2D,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW;QAC1F,EAAE;QACF,QAAQ,kBAAkB,CAAC,GAAG,CAAC,EAAE;QACjC,EAAE;QACF,qEAAqE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,iBAAiB;QACjG,qEAAqE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE;QACrF,EAAE;QACF,kEAAkE;QAClE,oEAAoE;QACpE,wDAAwD;KAC3D,CAAC;AACN,CAAC"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Supervisor backend for hosts with no service manager (#479).
3
+ *
4
+ * A container whose PID 1 is tini has nothing to register autostart with, so
5
+ * `jaw service` previously refused and handed back a manual recipe. That left
6
+ * every operator writing the same loop by hand — the reporter shipped an
7
+ * `ensure-jaw.sh` plus a 60s while-loop to keep `jaw serve` alive.
8
+ *
9
+ * This generates that loop instead. Two properties matter, and are why the
10
+ * generated script is not a naive `while ! pgrep jaw; do start; done`:
11
+ *
12
+ * 1. Liveness is decided by the pidfile's OS start time, the same check
13
+ * `jaw service stop` uses. A pidfile whose PID has been recycled by an
14
+ * unrelated process must read as dead, or the supervisor sits forever
15
+ * beside a server that is not running — the #479 misdiagnosis exactly.
16
+ * 2. Every path is absolute. The supervisor is launched from the same
17
+ * non-interactive context that cannot resolve `jaw` on PATH.
18
+ */
19
+ import { dirname } from 'node:path';
20
+ function shQuote(value) {
21
+ return "'" + String(value).replace(/'/g, "'\\''") + "'";
22
+ }
23
+ /**
24
+ * POSIX sh supervisor loop.
25
+ *
26
+ * Deliberately sh, not bash: the hosts that need this are minimal containers
27
+ * where /bin/sh may be dash and bash may not be installed at all.
28
+ */
29
+ export function renderSupervisorScript(ctx) {
30
+ const node = shQuote(ctx.nodePath);
31
+ const jaw = shQuote(ctx.jawPath);
32
+ const home = shQuote(ctx.home);
33
+ const log = shQuote(ctx.logPath);
34
+ const interval = Math.max(1, Math.floor(ctx.intervalSeconds));
35
+ return [
36
+ '#!/bin/sh',
37
+ '# Generated by `jaw service --backend supervisor` (#479).',
38
+ '# Keeps one `jaw serve` alive on a host with no service manager.',
39
+ '#',
40
+ '# Every path is absolute on purpose: this runs in a non-interactive shell',
41
+ '# that does not have ' + dirname(ctx.jawPath) + ' on PATH.',
42
+ 'set -u',
43
+ '',
44
+ 'NODE=' + node,
45
+ 'JAW=' + jaw,
46
+ 'HOME_DIR=' + home,
47
+ 'PORT=' + ctx.port,
48
+ 'LOG=' + log,
49
+ 'INTERVAL=' + interval,
50
+ '',
51
+ 'log() {',
52
+ ' printf \'%s supervisor: %s\\n\' "$(date -u \'+%Y-%m-%dT%H:%M:%SZ\')" "$1" >> "$LOG" 2>&1',
53
+ '}',
54
+ '',
55
+ '# Ask jaw itself whether the instance is alive. `service status` verifies',
56
+ '# the pidfile against the OS process start time, so a recycled PID reads',
57
+ '# as dead instead of masquerading as a healthy server.',
58
+ 'is_running() {',
59
+ ' "$NODE" "$JAW" --home "$HOME_DIR" service status --port "$PORT" >/dev/null 2>&1',
60
+ '}',
61
+ '',
62
+ 'start_once() {',
63
+ ' log "starting jaw serve on port $PORT"',
64
+ ' # setsid detaches from the controlling terminal so the server outlives',
65
+ ' # the ssh session that started the supervisor. It is util-linux, so it',
66
+ ' # is absent on macOS and on some minimal images; without this guard the',
67
+ ' # loop would fail to start anything at all there. nohup alone still',
68
+ ' # survives SIGHUP, which is the property that matters most.',
69
+ ' if [ -n "$SETSID" ]; then',
70
+ ' "$SETSID" nohup "$NODE" "$JAW" --home "$HOME_DIR" serve --port "$PORT" --no-open \\',
71
+ ' >> "$LOG" 2>&1 < /dev/null &',
72
+ ' else',
73
+ ' nohup "$NODE" "$JAW" --home "$HOME_DIR" serve --port "$PORT" --no-open \\',
74
+ ' >> "$LOG" 2>&1 < /dev/null &',
75
+ ' fi',
76
+ '}',
77
+ '',
78
+ '# Resolved once, not per cycle.',
79
+ 'SETSID="$(command -v setsid 2>/dev/null || true)"',
80
+ '',
81
+ 'mkdir -p "$(dirname "$LOG")" 2>/dev/null || true',
82
+ '',
83
+ '# Stop supervising when the host stops us, rather than leaving an orphan',
84
+ '# loop that would fight the next start.',
85
+ 'trap \'log "supervisor received TERM; exiting"; exit 0\' TERM INT',
86
+ '',
87
+ 'while true; do',
88
+ ' if ! is_running; then',
89
+ ' start_once',
90
+ ' fi',
91
+ ' sleep "$INTERVAL"',
92
+ 'done',
93
+ '',
94
+ ].join('\n');
95
+ }
96
+ /** Operator-facing summary after the supervisor script is written. */
97
+ export function supervisorInstallSummary(scriptPath, ctx) {
98
+ return [
99
+ 'Supervisor script written: ' + scriptPath,
100
+ '',
101
+ ' This host has no service manager, so nothing starts it at boot for you.',
102
+ ' Wire it into whatever does own startup here:',
103
+ '',
104
+ ' container entrypoint / CMD: ' + scriptPath,
105
+ ' cron: @reboot ' + scriptPath + ' &',
106
+ ' ad-hoc over ssh: setsid nohup ' + scriptPath + ' >> ' + ctx.logPath + ' 2>&1 < /dev/null &',
107
+ '',
108
+ ' Log: tail -n 50 ' + ctx.logPath,
109
+ ' Status: ' + ctx.jawPath + ' --home ' + ctx.home + ' service status --port ' + ctx.port,
110
+ ];
111
+ }
112
+ //# sourceMappingURL=supervisor-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supervisor-service.js","sourceRoot":"","sources":["../../../src/manager/supervisor-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC,SAAS,OAAO,CAAC,KAAa;IAC1B,OAAO,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,GAAG,CAAC;AAC5D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,GAAsB;IACzD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACnC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACjC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC;IAE9D,OAAO;QACH,WAAW;QACX,2DAA2D;QAC3D,kEAAkE;QAClE,GAAG;QACH,2EAA2E;QAC3E,uBAAuB,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,WAAW;QAC5D,QAAQ;QACR,EAAE;QACF,OAAO,GAAG,IAAI;QACd,MAAM,GAAG,GAAG;QACZ,WAAW,GAAG,IAAI;QAClB,OAAO,GAAG,GAAG,CAAC,IAAI;QAClB,MAAM,GAAG,GAAG;QACZ,WAAW,GAAG,QAAQ;QACtB,EAAE;QACF,SAAS;QACT,8FAA8F;QAC9F,GAAG;QACH,EAAE;QACF,2EAA2E;QAC3E,0EAA0E;QAC1E,wDAAwD;QACxD,gBAAgB;QAChB,qFAAqF;QACrF,GAAG;QACH,EAAE;QACF,gBAAgB;QAChB,4CAA4C;QAC5C,4EAA4E;QAC5E,4EAA4E;QAC5E,6EAA6E;QAC7E,yEAAyE;QACzE,iEAAiE;QACjE,+BAA+B;QAC/B,6FAA6F;QAC7F,0CAA0C;QAC1C,UAAU;QACV,mFAAmF;QACnF,0CAA0C;QAC1C,QAAQ;QACR,GAAG;QACH,EAAE;QACF,iCAAiC;QACjC,mDAAmD;QACnD,EAAE;QACF,kDAAkD;QAClD,EAAE;QACF,0EAA0E;QAC1E,yCAAyC;QACzC,mEAAmE;QACnE,EAAE;QACF,gBAAgB;QAChB,2BAA2B;QAC3B,oBAAoB;QACpB,QAAQ;QACR,uBAAuB;QACvB,MAAM;QACN,EAAE;KACL,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACjB,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,wBAAwB,CAAC,UAAkB,EAAE,GAAsB;IAC/E,OAAO;QACH,6BAA6B,GAAG,UAAU;QAC1C,EAAE;QACF,4EAA4E;QAC5E,iDAAiD;QACjD,EAAE;QACF,oCAAoC,GAAG,UAAU;QACjD,4CAA4C,GAAG,UAAU,GAAG,IAAI;QAChE,iDAAiD,GAAG,UAAU,GAAG,MAAM,GAAG,GAAG,CAAC,OAAO,GAAG,qBAAqB;QAC7G,EAAE;QACF,wBAAwB,GAAG,GAAG,CAAC,OAAO;QACtC,aAAa,GAAG,GAAG,CAAC,OAAO,GAAG,UAAU,GAAG,GAAG,CAAC,IAAI,GAAG,yBAAyB,GAAG,GAAG,CAAC,IAAI;KAC7F,CAAC;AACN,CAAC"}
@@ -8,6 +8,7 @@ import { getLastActiveTarget, getLatestSeenTarget, clearTargetState, getHomeChan
8
8
  import { slackTargetFromId, slackPeerKind } from './slack-target.js';
9
9
  import { readSlackAllowlist, MALFORMED_SLACK_ALLOWLIST } from '../slack/events.js';
10
10
  import { buildRemoteBindingKey } from './session-key.js';
11
+ import { decodeTurnConversation, turnConversationForChannel } from './turn-conversation.js';
11
12
  import { getRemoteBoundSessionId } from '../core/chat-sessions.js';
12
13
  import { applyOutputPolicy } from '../core/policy-hooks.js';
13
14
  import { redactChannelSecrets } from './redact.js';
@@ -87,6 +88,10 @@ export function normalizeChannelSendRequest(body) {
87
88
  // dropped here and every HTTP keyboard send to a channel without
88
89
  // interactive support would come back unsupported.
89
90
  interactiveFallback: normalizeInteractiveFallback(body["interactive_fallback"] ?? body["interactiveFallback"]),
91
+ // The agent echoes its turn's `reply_to` here. Dropping it in this
92
+ // allowlist normalizer would leave every HTTP send back on the volatile
93
+ // slots, which is the bug (#474).
94
+ turnTarget: decodeTurnConversation(body["turn_conversation"] ?? body["turnConversation"]) ?? undefined,
90
95
  });
91
96
  }
92
97
  // ─── Resolve Target ─────────────────────────────────
@@ -298,6 +303,18 @@ export async function sendChannelOutput(req) {
298
303
  const configuredFirst = req.preferConfiguredTarget ? getConfiguredFallbackTarget(channel) : null;
299
304
  if (configuredFirst)
300
305
  req.target = configuredFirst;
306
+ // The turn's OWN conversation outranks both volatile slots. Those slots
307
+ // answer "who spoke to the bot most recently", which stops being this
308
+ // conversation the moment anyone else writes — so a DM turn that omitted
309
+ // the target was delivering to whichever PUBLIC channel happened to
310
+ // interleave (#474). This answers "who am I replying to", which does not
311
+ // move for the life of the turn.
312
+ //
313
+ // Still allowlist-checked: it narrows the default, it does not widen access.
314
+ const turnTarget = req.target ? null : turnConversationForChannel(req.turnTarget, channel);
315
+ if (turnTarget && validateTarget(turnTarget, channel)) {
316
+ req.target = turnTarget;
317
+ }
301
318
  const last = req.target ? null : getLastActiveTarget(channel);
302
319
  if (last && validateTarget(last, channel)) {
303
320
  req.target = last;
@@ -1 +1 @@
1
- {"version":3,"file":"send.js","sourceRoot":"","sources":["../../../src/messaging/send.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"send.js","sourceRoot":"","sources":["../../../src/messaging/send.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ // ─── Turn Conversation Address ───────────────────────
2
+ // The conversation an agent process is answering FOR, carried in that process's
3
+ // own environment.
4
+ //
5
+ // Why this exists: the two volatile slots (lastActive / latestSeen) hold ONE
6
+ // conversation per channel for the whole server, and every inbound message
7
+ // overwrites them. With multi-session on, a DM turn and a channel turn run
8
+ // concurrently, so by the time the DM's agent posts its answer the slot can
9
+ // already point at the channel that spoke in between — and a send with no
10
+ // explicit target lands in a PUBLIC conversation the user never addressed
11
+ // (#474).
12
+ //
13
+ // The address travels in the PER-TURN prompt and comes back on the send as
14
+ // `turn_conversation`. The obvious alternative — an environment variable on the
15
+ // agent process — is wrong here: `codex-app` leases pooled processes and the
16
+ // pool sets env only at CREATION, so a reused process would keep echoing the
17
+ // address of whichever turn first started it. That is the same misdelivery in a
18
+ // new shape, and with multi-session OFF every conversation shares one scope, so
19
+ // it would fire constantly.
20
+ //
21
+ // Nothing reads this from the server's own environment: the server process
22
+ // answers many conversations at once, so any single value there would be wrong
23
+ // for most of them.
24
+ import { isRemoteTarget } from './types.js';
25
+ /** Serialize a target for the turn prompt. Absent target = nothing to echo. */
26
+ export function encodeTurnConversation(target) {
27
+ if (!isRemoteTarget(target))
28
+ return undefined;
29
+ return JSON.stringify(target);
30
+ }
31
+ /**
32
+ * Read a target back.
33
+ *
34
+ * Anything malformed reads as absent rather than throwing: a broken value must
35
+ * degrade to today's behaviour, never take down the send path.
36
+ */
37
+ export function decodeTurnConversation(raw) {
38
+ if (typeof raw !== 'string' || !raw.trim())
39
+ return null;
40
+ try {
41
+ const parsed = JSON.parse(raw);
42
+ return isRemoteTarget(parsed) ? parsed : null;
43
+ }
44
+ catch {
45
+ return null;
46
+ }
47
+ }
48
+ /**
49
+ * The echoed conversation, accepted only for `channel`.
50
+ *
51
+ * Channel-matched on purpose: a Slack turn must not supply the destination for
52
+ * a Telegram send.
53
+ */
54
+ export function turnConversationForChannel(target, channel) {
55
+ return target && target.channel === channel ? target : null;
56
+ }
57
+ //# sourceMappingURL=turn-conversation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turn-conversation.js","sourceRoot":"","sources":["../../../src/messaging/turn-conversation.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,gFAAgF;AAChF,mBAAmB;AACnB,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,2EAA2E;AAC3E,4EAA4E;AAC5E,0EAA0E;AAC1E,0EAA0E;AAC1E,UAAU;AACV,EAAE;AACF,2EAA2E;AAC3E,gFAAgF;AAChF,6EAA6E;AAC7E,6EAA6E;AAC7E,gFAAgF;AAChF,gFAAgF;AAChF,4BAA4B;AAC5B,EAAE;AACF,2EAA2E;AAC3E,+EAA+E;AAC/E,oBAAoB;AAEpB,OAAO,EAAE,cAAc,EAA4C,MAAM,YAAY,CAAC;AAEtF,+EAA+E;AAC/E,MAAM,UAAU,sBAAsB,CAAC,MAAqB;IACxD,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC;QAAE,OAAO,SAAS,CAAC;IAC9C,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;AAClC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,GAAY;IAC/C,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE;QAAE,OAAO,IAAI,CAAC;IACxD,IAAI,CAAC;QACD,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACxC,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,IAAI,CAAC;IAChB,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,0BAA0B,CACtC,MAAuC,EACvC,OAAyB;IAEzB,OAAO,MAAM,IAAI,MAAM,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AAChE,CAAC"}
@@ -1,3 +1,5 @@
1
+ import { encodeTurnConversation } from '../messaging/turn-conversation.js';
2
+ import { stripUndefined } from '../core/strip-undefined.js';
1
3
  const CONTEXT_VALUE_LIMIT = 200;
2
4
  function promptContextValue(value) {
3
5
  return String(value ?? '')
@@ -18,6 +20,26 @@ export function prependRemoteConversationContext(prompt, target) {
18
20
  if (!channelId)
19
21
  return prompt;
20
22
  const threadTs = promptContextValue(target.threadId) || 'none';
21
- return `Current Slack conversation: channel_id=${channelId}; thread_ts=${threadTs}\n${prompt}`;
23
+ // The same address in the shape /api/channel/send accepts, so an agent that
24
+ // cannot assemble a target has something exact to echo instead of omitting
25
+ // it — omission resolves to whichever conversation spoke last (#474).
26
+ //
27
+ // It rides the PER-TURN prompt rather than the process environment on
28
+ // purpose: `codex-app` leases pooled processes and only sets env at
29
+ // creation, so a reused process would keep answering with the address of
30
+ // the turn that first started it.
31
+ //
32
+ // Built from the SANITIZED ids above, not the raw target: these values reach
33
+ // the prompt, and the line-structure guarantee the sanitizer provides is not
34
+ // something a JSON encoder should be trusted to reproduce.
35
+ const reply = encodeTurnConversation(stripUndefined({
36
+ ...target,
37
+ targetId: channelId,
38
+ threadId: target.threadId ? promptContextValue(target.threadId) : undefined,
39
+ guildId: target.guildId ? promptContextValue(target.guildId) : undefined,
40
+ parentTargetId: target.parentTargetId ? promptContextValue(target.parentTargetId) : undefined,
41
+ }));
42
+ const replyLine = reply ? `; reply_to=${reply}` : '';
43
+ return `Current Slack conversation: channel_id=${channelId}; thread_ts=${threadTs}${replyLine}\n${prompt}`;
22
44
  }
23
45
  //# sourceMappingURL=conversation-context.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"conversation-context.js","sourceRoot":"","sources":["../../../src/prompt/conversation-context.ts"],"names":[],"mappings":"AAEA,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAEhC,SAAS,kBAAkB,CAAC,KAAc;IACtC,OAAO,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;SACrB,OAAO,CAAC,yBAAyB,EAAE,GAAG,CAAC;SACvC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE;SACN,KAAK,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC;AACvC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gCAAgC,CAAC,MAAc,EAAE,MAAqB;IAClF,IAAI,MAAM,EAAE,OAAO,KAAK,OAAO;QAAE,OAAO,MAAM,CAAC;IAC/C,MAAM,SAAS,GAAG,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACtD,IAAI,CAAC,SAAS;QAAE,OAAO,MAAM,CAAC;IAC9B,MAAM,QAAQ,GAAG,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC;IAC/D,OAAO,0CAA0C,SAAS,eAAe,QAAQ,KAAK,MAAM,EAAE,CAAC;AACnG,CAAC"}
1
+ {"version":3,"file":"conversation-context.js","sourceRoot":"","sources":["../../../src/prompt/conversation-context.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAEhC,SAAS,kBAAkB,CAAC,KAAc;IACtC,OAAO,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;SACrB,OAAO,CAAC,yBAAyB,EAAE,GAAG,CAAC;SACvC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE;SACN,KAAK,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC;AACvC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gCAAgC,CAAC,MAAc,EAAE,MAAqB;IAClF,IAAI,MAAM,EAAE,OAAO,KAAK,OAAO;QAAE,OAAO,MAAM,CAAC;IAC/C,MAAM,SAAS,GAAG,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACtD,IAAI,CAAC,SAAS;QAAE,OAAO,MAAM,CAAC;IAC9B,MAAM,QAAQ,GAAG,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC;IAC/D,4EAA4E;IAC5E,2EAA2E;IAC3E,sEAAsE;IACtE,EAAE;IACF,sEAAsE;IACtE,oEAAoE;IACpE,yEAAyE;IACzE,kCAAkC;IAClC,EAAE;IACF,6EAA6E;IAC7E,6EAA6E;IAC7E,2DAA2D;IAC3D,MAAM,KAAK,GAAG,sBAAsB,CAAC,cAAc,CAAC;QAChD,GAAG,MAAM;QACT,QAAQ,EAAE,SAAS;QACnB,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS;QAC3E,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS;QACxE,cAAc,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,SAAS;KAChG,CAAiB,CAAC,CAAC;IACpB,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,cAAc,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACrD,OAAO,0CAA0C,SAAS,eAAe,QAAQ,GAAG,SAAS,KAAK,MAAM,EAAE,CAAC;AAC/G,CAAC"}
@@ -294,7 +294,7 @@ For non-text output, use the canonical channel send endpoint:
294
294
  Primary local endpoint: `POST http://127.0.0.1:{{SERVER_PORT}}/api/channel/send`
295
295
  Legacy endpoints: `POST /api/telegram/send`, `POST /api/discord/send`
296
296
  - Types: `text`, `voice`, `photo`, `document` (requires `file_path`)
297
- - `channel` is `telegram|discord|slack|active`, never a conversation ID. **Send `target` when this turn named a conversation** (Slack turns get `channel_id`/`thread_ts`); omitting it delivers to whoever spoke last — a PUBLIC channel when this turn is a DM. Never drop `target` to fix a refused send; report the refusal, or pass `"turn_conversation"` = raw `JAW_TURN_CONVERSATION` env value. Heartbeats/scheduled jobs omit both and use the active channel: `{"type":"document","file_path":"/path/to/file"}`
297
+ - `channel` is `telegram|discord|slack|active`, never a conversation ID. **Send `target` when this turn named a conversation** (Slack turns get `channel_id`/`thread_ts`); omitting it delivers to whoever spoke last — a PUBLIC channel when this turn is a DM. Never drop `target` to fix a refused send; report the refusal, or pass `"turn_conversation"` = this turn's `reply_to=` value. Heartbeats/scheduled jobs omit both and use the active channel: `{"type":"document","file_path":"/path/to/file"}`
298
298
  - Explicit Slack thread (`threadId` = parent ts, never reply ts): `{"channel":"slack","type":"document","file_path":"/path/to/file","target":{"channel":"slack","targetKind":"channel","peerKind":"channel","targetId":"C123","threadId":"1712345678.123456"}}`
299
299
  - Always provide normal text response alongside file delivery
300
300
  - Do not print token values in logs
@@ -19,7 +19,7 @@ import { addSlackReaction, describeSlackError, removeSlackReaction, slackApi, SL
19
19
  import { createAckHandle, resolveAckConfig, shouldAck, SLACK_ACK_DEFAULTS, } from '../messaging/ack-reaction.js';
20
20
  import { createQueueNotice, QueueNoticeRegistry, } from '../messaging/queue-notice.js';
21
21
  import { OutboundSendRegistry } from '../messaging/outbound-lifecycle.js';
22
- import { recordSlackScopeObservation, getSlackScopeStatus, describeSlackScopeGap, resetSlackScopeStatus, } from './scope-status.js';
22
+ import { recordSlackScopeObservation, getSlackScopeStatus, describeSlackScopeGaps, resetSlackScopeStatus, } from './scope-status.js';
23
23
  import { SlackSocketClient } from './socket.js';
24
24
  import { runSlackAutoJoin, mergeSlackAutoJoin } from './auto-join.js';
25
25
  import { createHash } from 'node:crypto';
@@ -1088,9 +1088,13 @@ async function runSlackInit() {
1088
1088
  // that return would make an unconfigured channel hit the network on every
1089
1089
  // start. Documented as a known limitation rather than silently ignored.
1090
1090
  recordSlackScopeObservation(auth.grantedScopes, null);
1091
- const scopeGap = describeSlackScopeGap(getSlackScopeStatus());
1092
- if (scopeGap)
1093
- log.warn(`[slack:scopes] ${scopeGap}`);
1091
+ for (const gap of describeSlackScopeGaps(getSlackScopeStatus())) {
1092
+ // Each group logs at its own level: a missing required scope is a real
1093
+ // break, a missing optional one is not, and one shared WARN made them
1094
+ // indistinguishable (#478).
1095
+ const emit = gap.level === 'warn' ? log.warn : log.info;
1096
+ emit(`[slack:scopes] ${gap.text}`);
1097
+ }
1094
1098
  if (auth.data?.team_id && !sc.teamId)
1095
1099
  sc.teamId = auth.data.team_id;
1096
1100
  // The team id namespaces every ingress dedup key, and `slackEventKey`