agileflow 4.0.0-alpha.16 → 4.0.0-alpha.17
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
CHANGED
|
@@ -1182,11 +1182,28 @@ async function maybeOfferAutoRestore(prefs) {
|
|
|
1182
1182
|
if (ap !== bp) return bp - ap;
|
|
1183
1183
|
return 0;
|
|
1184
1184
|
});
|
|
1185
|
-
|
|
1185
|
+
// Synthetic toggles at the top of the picker for users with many
|
|
1186
|
+
// saved sessions — checking one of them rewrites the selection in
|
|
1187
|
+
// bulk after submit (clack's multiselect doesn't natively support
|
|
1188
|
+
// a "select all" shortcut, but synthetic entries are the lightest
|
|
1189
|
+
// path and stay accessible via keyboard).
|
|
1190
|
+
const SELECT_ALL = "__select_all__";
|
|
1191
|
+
const DESELECT_ALL = "__deselect_all__";
|
|
1192
|
+
const allNames = sorted.map((s) => s.name);
|
|
1193
|
+
const sessionOptions = sorted.map((s) => ({
|
|
1186
1194
|
value: s.name,
|
|
1187
1195
|
label: `${s.pinned ? "★ " : " "}${s.name}`,
|
|
1188
1196
|
hint: `${s.cli} — ${s.cwd}${s.worktree && s.worktree.branch ? ` [wt ${s.worktree.branch}]` : ""}`,
|
|
1189
1197
|
}));
|
|
1198
|
+
const options = [
|
|
1199
|
+
{ value: SELECT_ALL, label: "✅ Select all", hint: "check every session" },
|
|
1200
|
+
{
|
|
1201
|
+
value: DESELECT_ALL,
|
|
1202
|
+
label: "⬜ Deselect all",
|
|
1203
|
+
hint: "uncheck every session",
|
|
1204
|
+
},
|
|
1205
|
+
...sessionOptions,
|
|
1206
|
+
];
|
|
1190
1207
|
const anyPinned = sorted.some((s) => s.pinned === true);
|
|
1191
1208
|
const initial = anyPinned
|
|
1192
1209
|
? sorted.filter((s) => s.pinned === true).map((s) => s.name)
|
|
@@ -1210,7 +1227,15 @@ async function maybeOfferAutoRestore(prefs) {
|
|
|
1210
1227
|
process.exit(0);
|
|
1211
1228
|
}
|
|
1212
1229
|
/** @type {string[]} */
|
|
1213
|
-
|
|
1230
|
+
let chosen = Array.isArray(selection) ? selection : [];
|
|
1231
|
+
// Resolve the synthetic select-all / deselect-all toggles. If both
|
|
1232
|
+
// were checked, select-all wins (the safer "do more" interpretation);
|
|
1233
|
+
// either way, strip the synthetic entries from the final list.
|
|
1234
|
+
const wantSelectAll = chosen.includes(SELECT_ALL);
|
|
1235
|
+
const wantDeselectAll = chosen.includes(DESELECT_ALL);
|
|
1236
|
+
chosen = chosen.filter((v) => v !== SELECT_ALL && v !== DESELECT_ALL);
|
|
1237
|
+
if (wantSelectAll) chosen = [...allNames];
|
|
1238
|
+
else if (wantDeselectAll) chosen = [];
|
|
1214
1239
|
if (chosen.length === 0) {
|
|
1215
1240
|
prompts.outro(
|
|
1216
1241
|
"Skipped. Run `agileflow launch restore` later to bring them back.",
|
|
@@ -19,6 +19,8 @@ const {
|
|
|
19
19
|
sessionExists,
|
|
20
20
|
createSession,
|
|
21
21
|
applyKeybindPreset,
|
|
22
|
+
applyTabFormat,
|
|
23
|
+
detectTmuxVersion,
|
|
22
24
|
} = require("./tmux.js");
|
|
23
25
|
const { loadRegistry } = require("./session-registry.js");
|
|
24
26
|
const { resolveAgileflowBin } = require("./alias-installer.js");
|
|
@@ -117,6 +119,14 @@ function runRestore(opts) {
|
|
|
117
119
|
log(`agileflow launch: failed to restore ${entry.name} — ${stderr}`);
|
|
118
120
|
continue;
|
|
119
121
|
}
|
|
122
|
+
// Apply the same per-session styling launchInTmux does for fresh
|
|
123
|
+
// sessions so the tab strip looks consistent on restore. Without
|
|
124
|
+
// this, restored sessions show tmux's default green status bar
|
|
125
|
+
// instead of the AgileFlow dark strip.
|
|
126
|
+
runner.runSync(["set-option", "-t", entry.name, "status", "1"]);
|
|
127
|
+
applyTabFormat(entry.name, runner, {
|
|
128
|
+
tmuxVersion: detectTmuxVersion(runner),
|
|
129
|
+
});
|
|
120
130
|
result.restored++;
|
|
121
131
|
log(`agileflow launch: restored session ${entry.name} (${entry.cwd})`);
|
|
122
132
|
}
|
|
@@ -273,17 +273,15 @@ const TAB_KEYBINDS = [
|
|
|
273
273
|
hint: "Alt+, → rename current tab",
|
|
274
274
|
},
|
|
275
275
|
{
|
|
276
|
-
// Direct
|
|
277
|
-
//
|
|
278
|
-
//
|
|
279
|
-
//
|
|
280
|
-
//
|
|
281
|
-
//
|
|
276
|
+
// Direct kill-window — no CLI roundtrip. The previous
|
|
277
|
+
// run-shell-to-agileflow approach added Node-startup latency
|
|
278
|
+
// (150ms+) and could no-op silently if the binary path resolution
|
|
279
|
+
// returned stale state (e.g. after npx cache cleanup). Killing
|
|
280
|
+
// via tmux directly is instant and bulletproof. Undo is provided
|
|
281
|
+
// by Alt+Shift+T (which reads the closed-windows log populated by
|
|
282
|
+
// the window-unlinked hook installed in applyTabFormat).
|
|
282
283
|
key: "M-w",
|
|
283
|
-
action: [
|
|
284
|
-
"run-shell",
|
|
285
|
-
"%AGILEFLOW% launch __close-window #{session_name} #{window_index}",
|
|
286
|
-
],
|
|
284
|
+
action: ["kill-window"],
|
|
287
285
|
hint: "Alt+w → close current tab (Alt+Shift+T to undo)",
|
|
288
286
|
},
|
|
289
287
|
{
|