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.
@@ -280,7 +280,30 @@ export function applyTrifluxTheme(sessionName) {
280
280
  * 반투명 + 비포커스 시 더 투명 + Catppuccin 테마.
281
281
  * @returns {boolean} 성공 여부
282
282
  */
283
- export function ensureWtProfile() {
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: 11 },
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
  };
@@ -449,26 +449,28 @@ function getTeamRow() {
449
449
  ? `${Math.round((Date.now() - teamState.startedAt) / 60000)}m`
450
450
  : "";
451
451
 
452
- // 멤버 상태 아이콘 요약 (60col 이상에서만 표시)
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 icon = task?.status === "completed" ? green("✓")
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 tag = m.cli ? m.cli.charAt(0) : "?";
460
- return `${tag}${icon}`;
460
+ : dim("");
461
+ const emoji = cliBrand[m.cli] || dim("");
462
+ return `${emoji}${status}`;
461
463
  }).join(" ") : "";
462
464
 
463
- // done / failed 상태 텍스트
465
+ // 진행 텍스트 "team" 제거, 숫자만
464
466
  const doneText = failed > 0
465
467
  ? `${completed}/${total} ${red(`${failed}✗`)}`
466
- : `${completed}/${total} done`;
468
+ : `${completed}/${total}`;
467
469
 
468
- const leftText = elapsed ? `team ${doneText} ${dim(elapsed)}` : `team ${doneText}`;
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
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "triflux",
3
- "version": "6.0.10",
3
+ "version": "6.0.12",
4
4
  "description": "CLI-first multi-model orchestrator for Claude Code — route tasks to Codex, Gemini, and Claude",
5
5
  "type": "module",
6
6
  "bin": {