agileflow 4.0.0-alpha.14 → 4.0.0-alpha.15
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/runtime/launch/tmux.js +73 -44
package/package.json
CHANGED
|
@@ -203,47 +203,76 @@ function applyTabFormat(sessionName, runner, opts = {}) {
|
|
|
203
203
|
// ignores invalid status-format expressions on some versions, which
|
|
204
204
|
// makes overrides hard to debug. window-status-format works on every
|
|
205
205
|
// tmux 2.0+.
|
|
206
|
-
|
|
206
|
+
// jakobwesthoff/tmux-from-scratch inspired styling: active tab is a
|
|
207
|
+
// rounded "pill" (Powerline half-round glyphs) over a lighter
|
|
208
|
+
// background, with brand-orange accent on the index:name separator
|
|
209
|
+
// colon. Inactive tabs are plain text with the same accent colon.
|
|
210
|
+
// Session name appears as a rounded pill on the left, hostname as
|
|
211
|
+
// a rounded pill on the right.
|
|
212
|
+
//
|
|
213
|
+
// Requires a Nerd Font / Powerline-patched font in the user's
|
|
214
|
+
// terminal. Without one the glyphs render as tofu boxes; users on
|
|
215
|
+
// a vanilla font can switch back via a future `tabStyle: "flat"`
|
|
216
|
+
// pref.
|
|
217
|
+
const HALF_ROUND_OPEN = ""; //
|
|
218
|
+
const HALF_ROUND_CLOSE = ""; //
|
|
219
|
+
const TRIANGLE_OPEN = ""; //
|
|
220
|
+
const TRIANGLE_CLOSE = ""; //
|
|
221
|
+
const BG = theme.stripBg;
|
|
222
|
+
const PILL_BG = theme.activeNameBg;
|
|
223
|
+
const ACCENT = theme.activeBg;
|
|
224
|
+
const FG = theme.activeNameFg;
|
|
225
|
+
|
|
226
|
+
const inactiveFormat = ` #I#[fg=${ACCENT}]:#[fg=default]#W `;
|
|
207
227
|
const activeFormat =
|
|
208
|
-
`#[fg=${
|
|
209
|
-
`#[fg=${
|
|
210
|
-
`#[fg=${
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
"
|
|
225
|
-
"-
|
|
226
|
-
|
|
227
|
-
"
|
|
228
|
-
"",
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
"
|
|
232
|
-
"-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
])
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
228
|
+
`#[fg=${PILL_BG},bg=${BG}]${HALF_ROUND_OPEN}` +
|
|
229
|
+
`#[bg=${PILL_BG},fg=${FG},bold]#I#[fg=${ACCENT}]:#[fg=${FG},nobold]#W` +
|
|
230
|
+
`#[fg=${PILL_BG},bg=${BG}]${HALF_ROUND_CLOSE}`;
|
|
231
|
+
const statusLeft =
|
|
232
|
+
`#[fg=${PILL_BG},bg=${BG}]${HALF_ROUND_OPEN}` +
|
|
233
|
+
`#[bg=${PILL_BG},fg=${ACCENT}] #S ` +
|
|
234
|
+
`#[fg=${PILL_BG},bg=${BG}]${TRIANGLE_CLOSE}`;
|
|
235
|
+
const statusRight =
|
|
236
|
+
`#[fg=${PILL_BG},bg=${BG}]${TRIANGLE_OPEN}` +
|
|
237
|
+
`#[bg=${PILL_BG},fg=${ACCENT}] #h ` +
|
|
238
|
+
`#[fg=${PILL_BG},bg=${BG}]${HALF_ROUND_CLOSE}`;
|
|
239
|
+
|
|
240
|
+
// Apply each option and collect failures. If ANYTHING fails we surface
|
|
241
|
+
// it on stderr so users debugging "why doesn't my tab strip look right"
|
|
242
|
+
// can see the tmux complaint instead of staring at default formatting.
|
|
243
|
+
const ops = [
|
|
244
|
+
["status-style", `bg=${BG},fg=${theme.inactiveFg}`],
|
|
245
|
+
["status-justify", "centre"],
|
|
246
|
+
["status-left", statusLeft],
|
|
247
|
+
["status-left-length", "100"],
|
|
248
|
+
["status-right", statusRight],
|
|
249
|
+
["status-right-length", "100"],
|
|
250
|
+
["window-status-separator", ""],
|
|
251
|
+
["window-status-format", inactiveFormat],
|
|
252
|
+
["window-status-current-format", activeFormat],
|
|
253
|
+
];
|
|
254
|
+
let lastResult = { status: 0, stderr: "" };
|
|
255
|
+
const failures = [];
|
|
256
|
+
for (const [option, value] of ops) {
|
|
257
|
+
const r = runner.runSync(["set-option", "-t", sessionName, option, value]);
|
|
258
|
+
lastResult = r;
|
|
259
|
+
if (r.status !== 0) {
|
|
260
|
+
failures.push({ option, stderr: (r.stderr || "").trim() });
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
if (failures.length > 0) {
|
|
264
|
+
// eslint-disable-next-line no-console
|
|
265
|
+
console.error(
|
|
266
|
+
`agileflow launch: tab strip styling — ${failures.length} of ${ops.length} options rejected by tmux:`,
|
|
267
|
+
);
|
|
268
|
+
for (const f of failures) {
|
|
269
|
+
// eslint-disable-next-line no-console
|
|
270
|
+
console.error(` ${f.option}: ${f.stderr || "(no error message)"}`);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
244
273
|
return {
|
|
245
|
-
applied:
|
|
246
|
-
stderr:
|
|
274
|
+
applied: lastResult.status === 0,
|
|
275
|
+
stderr: lastResult.stderr || "",
|
|
247
276
|
};
|
|
248
277
|
}
|
|
249
278
|
|
|
@@ -349,15 +378,15 @@ const KEYBIND_PRESET_BINDINGS = {
|
|
|
349
378
|
},
|
|
350
379
|
{
|
|
351
380
|
// Prompt for a worktree name, then spawn. tmux's command-prompt
|
|
352
|
-
//
|
|
353
|
-
//
|
|
354
|
-
//
|
|
355
|
-
//
|
|
381
|
+
// natively cancels on Escape (or Ctrl+G) without firing the
|
|
382
|
+
// deferred command — the prompt label calls that out so users
|
|
383
|
+
// know they can back out. The agileflow CLI also bails cleanly
|
|
384
|
+
// if `%%` came in empty (user hit Enter with no input).
|
|
356
385
|
key: "M-n",
|
|
357
386
|
action: [
|
|
358
387
|
"command-prompt",
|
|
359
388
|
"-p",
|
|
360
|
-
"worktree name:",
|
|
389
|
+
"worktree name (esc to cancel):",
|
|
361
390
|
"run-shell '%AGILEFLOW% launch new \"%%\"'",
|
|
362
391
|
],
|
|
363
392
|
hint: "Alt+n → prompt for a name, create a worktree, spawn there",
|