agileflow 4.0.0-alpha.25 → 4.0.0-alpha.26
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/package.json +1 -1
- package/src/cli/commands/launch.js +14 -2
- package/src/runtime/launch/tmux.js +10 -1
package/package.json
CHANGED
|
@@ -983,7 +983,13 @@ async function runInternalCloseWindow(deps = {}) {
|
|
|
983
983
|
const exit = deps.exit || ((code) => process.exit(code));
|
|
984
984
|
// ASCII Unit Separator — never appears in a session/window name or
|
|
985
985
|
// filesystem path, so splitting on it is unambiguous.
|
|
986
|
-
|
|
986
|
+
// tmux's format-string parser escape-encodes control bytes (0x00-0x1F)
|
|
987
|
+
// into the literal 4-char `\OOO` octal sequence in output, so a
|
|
988
|
+
// 0x1f byte delimiter comes back as the text "\037" and split()
|
|
989
|
+
// never finds it. Use TAB instead — it survives format-string
|
|
990
|
+
// processing untouched, and is impossible in tmux session/window
|
|
991
|
+
// names (tmux rejects them) and rare-to-impossible in cwd paths.
|
|
992
|
+
const DELIM = "\t";
|
|
987
993
|
// When the tmux keybind passes session+index positionally, target
|
|
988
994
|
// that exact window. This avoids a wrong-window kill if focus shifts
|
|
989
995
|
// between Alt+w being pressed and this subprocess starting.
|
|
@@ -1153,7 +1159,13 @@ async function runInternalRestoreWindow(deps = {}) {
|
|
|
1153
1159
|
async function runInternalSnapshotSession(sessionName, deps = {}) {
|
|
1154
1160
|
if (!sessionName) return;
|
|
1155
1161
|
const runner = deps.runner || defaultTmuxRunner();
|
|
1156
|
-
|
|
1162
|
+
// tmux's format-string parser escape-encodes control bytes (0x00-0x1F)
|
|
1163
|
+
// into the literal 4-char `\OOO` octal sequence in output, so a
|
|
1164
|
+
// 0x1f byte delimiter comes back as the text "\037" and split()
|
|
1165
|
+
// never finds it. Use TAB instead — it survives format-string
|
|
1166
|
+
// processing untouched, and is impossible in tmux session/window
|
|
1167
|
+
// names (tmux rejects them) and rare-to-impossible in cwd paths.
|
|
1168
|
+
const DELIM = "\t";
|
|
1157
1169
|
const fmt = `#{window_index}${DELIM}#{window_name}${DELIM}#{pane_current_path}`;
|
|
1158
1170
|
// Capture timestamp BEFORE list-windows so concurrent subprocesses
|
|
1159
1171
|
// produce a stable ordering. The registry rejects writes whose
|
|
@@ -352,7 +352,16 @@ function installSessionHooks(sessionName, runner, opts = {}) {
|
|
|
352
352
|
const snapshotCmd = `run-shell -b "${shellCmd.replace(/"/g, '\\"')}"`;
|
|
353
353
|
/** @type {Array<{ event: string, stderr: string }>} */
|
|
354
354
|
const failures = [];
|
|
355
|
-
|
|
355
|
+
// tmux 3.x hook names: `window-linked` and `window-unlinked` fire
|
|
356
|
+
// on add/remove. There is NO `window-renamed` event — that name is
|
|
357
|
+
// silently accepted by set-hook but never fires. The correct hook
|
|
358
|
+
// for rename is `after-rename-window` (the "after-<command>" family
|
|
359
|
+
// fires whenever the named command runs from any source).
|
|
360
|
+
for (const event of [
|
|
361
|
+
"window-linked",
|
|
362
|
+
"window-unlinked",
|
|
363
|
+
"after-rename-window",
|
|
364
|
+
]) {
|
|
356
365
|
const r = runner.runSync([
|
|
357
366
|
"set-hook",
|
|
358
367
|
"-t",
|