triflux 6.0.10 → 6.0.12
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/hub/team/headless.mjs +48 -8
- package/hud/hud-qos-status.mjs +12 -10
- package/package.json +1 -1
package/hub/team/headless.mjs
CHANGED
|
@@ -280,7 +280,30 @@ export function applyTrifluxTheme(sessionName) {
|
|
|
280
280
|
* 반투명 + 비포커스 시 더 투명 + Catppuccin 테마.
|
|
281
281
|
* @returns {boolean} 성공 여부
|
|
282
282
|
*/
|
|
283
|
-
|
|
283
|
+
/**
|
|
284
|
+
* WT 기본 프로필의 폰트 크기를 읽는다.
|
|
285
|
+
* @returns {number} 기본 폰트 크기 (못 읽으면 12)
|
|
286
|
+
*/
|
|
287
|
+
function getWtDefaultFontSize() {
|
|
288
|
+
const settingsPaths = [
|
|
289
|
+
join(process.env.LOCALAPPDATA || "", "Packages/Microsoft.WindowsTerminal_8wekyb3d8bbwe/LocalState/settings.json"),
|
|
290
|
+
join(process.env.LOCALAPPDATA || "", "Microsoft/Windows Terminal/settings.json"),
|
|
291
|
+
];
|
|
292
|
+
for (const p of settingsPaths) {
|
|
293
|
+
if (!existsSync(p)) continue;
|
|
294
|
+
try {
|
|
295
|
+
const settings = JSON.parse(readFileSync(p, "utf8").replace(/^\s*\/\/.*$/gm, ""));
|
|
296
|
+
// 기본 프로필 or 첫 프로필의 폰트
|
|
297
|
+
const defaultGuid = settings.defaultProfile;
|
|
298
|
+
const profiles = settings.profiles?.list || [];
|
|
299
|
+
const defaultProfile = profiles.find(pr => pr.guid === defaultGuid) || profiles[0];
|
|
300
|
+
return defaultProfile?.font?.size || settings.profiles?.defaults?.font?.size || 12;
|
|
301
|
+
} catch { /* 다음 */ }
|
|
302
|
+
}
|
|
303
|
+
return 12;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
export function ensureWtProfile(workerCount = 2) {
|
|
284
307
|
const settingsPaths = [
|
|
285
308
|
join(process.env.LOCALAPPDATA || "", "Packages/Microsoft.WindowsTerminal_8wekyb3d8bbwe/LocalState/settings.json"),
|
|
286
309
|
join(process.env.LOCALAPPDATA || "", "Microsoft/Windows Terminal/settings.json"),
|
|
@@ -306,7 +329,7 @@ export function ensureWtProfile() {
|
|
|
306
329
|
useAcrylic: true,
|
|
307
330
|
unfocusedAppearance: { opacity: 20 },
|
|
308
331
|
colorScheme: "One Half Dark",
|
|
309
|
-
font: { size:
|
|
332
|
+
font: { size: Math.max(6, getWtDefaultFontSize() - 1 - Math.floor(workerCount / 2)) },
|
|
310
333
|
hidden: true, // 프로필 목록에는 숨김 (triflux에서만 사용)
|
|
311
334
|
};
|
|
312
335
|
|
|
@@ -334,7 +357,7 @@ export function ensureWtProfile() {
|
|
|
334
357
|
* @param {string} [opts.position] — "right" | "left" | 없으면 기본 위치
|
|
335
358
|
* @returns {boolean} 성공 여부
|
|
336
359
|
*/
|
|
337
|
-
export function autoAttachTerminal(sessionName, opts = {}) {
|
|
360
|
+
export function autoAttachTerminal(sessionName, opts = {}, workerCount = 2) {
|
|
338
361
|
try {
|
|
339
362
|
// Windows Terminal이 설치되어 있는지 확인
|
|
340
363
|
execSync("where wt.exe", { stdio: "ignore" });
|
|
@@ -342,11 +365,28 @@ export function autoAttachTerminal(sessionName, opts = {}) {
|
|
|
342
365
|
return false; // wt.exe 미설치 — 사용자에게 수동 attach 안내 필요
|
|
343
366
|
}
|
|
344
367
|
|
|
345
|
-
// triflux WT 프로필 확보 (투명도 + 테마)
|
|
346
|
-
ensureWtProfile();
|
|
368
|
+
// triflux WT 프로필 확보 (투명도 + 테마 + 폰트 크기)
|
|
369
|
+
ensureWtProfile(workerCount);
|
|
347
370
|
|
|
348
|
-
// PowerShell 래핑 + "--" 구분자 + 포커스 비탈취
|
|
349
371
|
const shells = ["pwsh.exe", "powershell.exe"];
|
|
372
|
+
// 방법 1: split-pane — 같은 WT 창에서 가로 분할
|
|
373
|
+
// 워커 수에 따라 split 비율 조정: 1-2→30%, 3-4→40%, 5-6→50%, 7+→60%
|
|
374
|
+
const splitSize = Math.min(0.6, 0.2 + workerCount * 0.05).toFixed(2);
|
|
375
|
+
if (process.env.WT_SESSION) {
|
|
376
|
+
for (const shell of shells) {
|
|
377
|
+
try {
|
|
378
|
+
// 1) 하단 분할 생성
|
|
379
|
+
execSync(
|
|
380
|
+
`wt.exe -w 0 sp -H --size ${splitSize} --profile triflux --title triflux -- ${shell} -Command "psmux attach -t ${sessionName}"`,
|
|
381
|
+
{ stdio: "ignore", timeout: 5000 },
|
|
382
|
+
);
|
|
383
|
+
// 2) 포커스를 Claude Code(위 pane)로 되돌림
|
|
384
|
+
try { execSync(`wt.exe -w 0 mf up`, { stdio: "ignore", timeout: 2000 }); } catch { /* 무시 */ }
|
|
385
|
+
return true;
|
|
386
|
+
} catch { /* 다음 shell */ }
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
// 방법 2 fallback: 새 탭 (WT_SESSION 없거나 sp 실패 시)
|
|
350
390
|
for (const shell of shells) {
|
|
351
391
|
try {
|
|
352
392
|
execSync(
|
|
@@ -354,7 +394,7 @@ export function autoAttachTerminal(sessionName, opts = {}) {
|
|
|
354
394
|
{ stdio: "ignore", shell: true, timeout: 5000 },
|
|
355
395
|
);
|
|
356
396
|
return true;
|
|
357
|
-
} catch { /* 다음 shell
|
|
397
|
+
} catch { /* 다음 shell */ }
|
|
358
398
|
}
|
|
359
399
|
return false;
|
|
360
400
|
}
|
|
@@ -420,7 +460,7 @@ export async function runHeadlessInteractive(sessionName, assignments, opts = {}
|
|
|
420
460
|
runOpts.onProgress = (event) => {
|
|
421
461
|
if (autoAttach && event.type === "session_created" && !terminalAttached) {
|
|
422
462
|
terminalAttached = true;
|
|
423
|
-
autoAttachTerminal(sessionName);
|
|
463
|
+
autoAttachTerminal(sessionName, {}, assignments.length);
|
|
424
464
|
}
|
|
425
465
|
if (userOnProgress) userOnProgress(event);
|
|
426
466
|
};
|
package/hud/hud-qos-status.mjs
CHANGED
|
@@ -449,26 +449,28 @@ function getTeamRow() {
|
|
|
449
449
|
? `${Math.round((Date.now() - teamState.startedAt) / 60000)}m`
|
|
450
450
|
: "";
|
|
451
451
|
|
|
452
|
-
//
|
|
452
|
+
// CLI 브랜드 이모지 매핑
|
|
453
|
+
const cliBrand = { codex: "\u{1F7E2}", gemini: "\u{1F535}", claude: "\u{1F7E0}" }; // 🟢🔵🟠
|
|
454
|
+
// 멤버 상태: 이모지 + 상태기호 (60col 이상)
|
|
453
455
|
const memberIcons = (CURRENT_TIER === "full" || CURRENT_TIER === "compact" || CURRENT_TIER === "minimal") ? workers.map((m) => {
|
|
454
456
|
const task = tasks.find((t) => t.owner === m.name);
|
|
455
|
-
const
|
|
456
|
-
: task?.status === "in_progress" ? yellow("
|
|
457
|
+
const status = task?.status === "completed" ? green("✓")
|
|
458
|
+
: task?.status === "in_progress" ? yellow("⋯")
|
|
457
459
|
: task?.status === "failed" ? red("✗")
|
|
458
|
-
: dim("
|
|
459
|
-
const
|
|
460
|
-
return `${
|
|
460
|
+
: dim("◌");
|
|
461
|
+
const emoji = cliBrand[m.cli] || dim("●");
|
|
462
|
+
return `${emoji}${status}`;
|
|
461
463
|
}).join(" ") : "";
|
|
462
464
|
|
|
463
|
-
//
|
|
465
|
+
// 진행 텍스트 — "team" 제거, 숫자만
|
|
464
466
|
const doneText = failed > 0
|
|
465
467
|
? `${completed}/${total} ${red(`${failed}✗`)}`
|
|
466
|
-
: `${completed}/${total}
|
|
468
|
+
: `${completed}/${total}`;
|
|
467
469
|
|
|
468
|
-
const leftText = elapsed ?
|
|
470
|
+
const leftText = elapsed ? `${doneText} ${dim(elapsed)}` : doneText;
|
|
469
471
|
|
|
470
472
|
return {
|
|
471
|
-
prefix: bold(claudeOrange("
|
|
473
|
+
prefix: bold(claudeOrange("▲")),
|
|
472
474
|
left: leftText,
|
|
473
475
|
right: memberIcons,
|
|
474
476
|
};
|