triflux 3.2.0-dev.6 → 3.2.0-dev.7

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/README.ko.md CHANGED
@@ -212,11 +212,13 @@ tfx doctor
212
212
  |--------|------|
213
213
  | `tfx setup` | 스크립트 + HUD + 스킬 동기화 |
214
214
  | `tfx doctor` | CLI 진단 + 이슈 추적 |
215
- | `tfx update` | 최신 버전으로 업데이트 |
216
- | `tfx list` | 설치된 스킬 목록 |
217
- | `tfx version` | 버전 표시 |
218
-
219
- 축약: `tfx` = `triflux`, `tfl` = `triflux`
215
+ | `tfx update` | 최신 안정 버전으로 업데이트 |
216
+ | `tfx list` | 설치된 스킬 목록 |
217
+ | `tfx version` | 버전 표시 |
218
+
219
+ 축약: `tfx` = `triflux`, `tfl` = `triflux`
220
+
221
+ dev 채널 업데이트: `tfx update --dev` (`dev` 별칭 지원)
220
222
 
221
223
  ### HUD 상태 표시줄
222
224
 
package/README.md CHANGED
@@ -212,11 +212,13 @@ tfx doctor
212
212
  |---------|-------------|
213
213
  | `tfx setup` | Sync scripts + HUD + skills |
214
214
  | `tfx doctor` | CLI diagnostics + issue tracker |
215
- | `tfx update` | Update to latest version |
216
- | `tfx list` | List installed skills |
217
- | `tfx version` | Show version info |
218
-
219
- Shortcuts: `tfx` = `triflux`, `tfl` = `triflux`
215
+ | `tfx update` | Update to latest stable version |
216
+ | `tfx list` | List installed skills |
217
+ | `tfx version` | Show version info |
218
+
219
+ Shortcuts: `tfx` = `triflux`, `tfl` = `triflux`
220
+
221
+ Dev channel update: `tfx update --dev` (`dev` alias supported)
220
222
 
221
223
  ### HUD Status Bar
222
224
 
package/bin/triflux.mjs CHANGED
@@ -3,9 +3,10 @@
3
3
  import { copyFileSync, existsSync, readFileSync, writeFileSync, mkdirSync, chmodSync, readdirSync, unlinkSync } from "fs";
4
4
  import { join, dirname } from "path";
5
5
  import { homedir } from "os";
6
- import { execSync, spawn } from "child_process";
7
-
8
- const PKG_ROOT = dirname(dirname(new URL(import.meta.url).pathname)).replace(/^\/([A-Z]:)/, "$1");
6
+ import { execSync, spawn } from "child_process";
7
+ import { fileURLToPath } from "url";
8
+
9
+ const PKG_ROOT = dirname(dirname(fileURLToPath(import.meta.url)));
9
10
  const CLAUDE_DIR = join(homedir(), ".claude");
10
11
  const CODEX_DIR = join(homedir(), ".codex");
11
12
  const CODEX_CONFIG_PATH = join(CODEX_DIR, "config.toml");
@@ -67,7 +68,7 @@ function which(cmd) {
67
68
  } catch { return null; }
68
69
  }
69
70
 
70
- function whichInShell(cmd, shell) {
71
+ function whichInShell(cmd, shell) {
71
72
  const cmds = {
72
73
  bash: `bash -c "source ~/.bashrc 2>/dev/null && command -v ${cmd} 2>/dev/null"`,
73
74
  cmd: `cmd /c where ${cmd} 2>nul`,
@@ -82,8 +83,12 @@ function whichInShell(cmd, shell) {
82
83
  stdio: ["pipe", "pipe", "ignore"],
83
84
  }).trim();
84
85
  return result.split(/\r?\n/)[0] || null;
85
- } catch { return null; }
86
- }
86
+ } catch { return null; }
87
+ }
88
+
89
+ function isDevUpdateRequested(argv = process.argv) {
90
+ return argv.includes("--dev") || argv.includes("@dev") || argv.includes("dev");
91
+ }
87
92
 
88
93
  function checkShellAvailable(shell) {
89
94
  const cmds = { bash: "bash --version", cmd: "cmd /c echo ok", pwsh: "pwsh -NoProfile -c echo ok" };
@@ -676,9 +681,9 @@ function cmdDoctor(options = {}) {
676
681
  }
677
682
  }
678
683
 
679
- function cmdUpdate() {
680
- const isDev = process.argv.includes("--dev");
681
- const tagLabel = isDev ? ` ${YELLOW}@dev${RESET}` : "";
684
+ function cmdUpdate() {
685
+ const isDev = isDevUpdateRequested(process.argv);
686
+ const tagLabel = isDev ? ` ${YELLOW}--dev${RESET}` : "";
682
687
  console.log(`\n${BOLD}triflux update${RESET}${tagLabel}\n`);
683
688
 
684
689
  // 1. 설치 방식 감지
@@ -755,7 +760,7 @@ function cmdUpdate() {
755
760
  timeout: 60000,
756
761
  stdio: ["pipe", "pipe", "ignore"],
757
762
  }).trim().split(/\r?\n/)[0];
758
- ok(`${isDev ? "npm install -g @dev" : "npm update -g"} — ${result || "완료"}`);
763
+ ok(`${isDev ? "npm install -g triflux@dev" : "npm update -g triflux"} — ${result || "완료"}`);
759
764
  updated = true;
760
765
  break;
761
766
  }
@@ -767,7 +772,7 @@ function cmdUpdate() {
767
772
  cwd: process.cwd(),
768
773
  stdio: ["pipe", "pipe", "ignore"],
769
774
  }).trim().split(/\r?\n/)[0];
770
- ok(`npm update — ${result || "완료"}`);
775
+ ok(`${isDev ? "npm install triflux@dev" : "npm update triflux"} — ${result || "완료"}`);
771
776
  updated = true;
772
777
  break;
773
778
  }
@@ -914,8 +919,8 @@ ${updateNotice}
914
919
  ${WHITE_BRIGHT}tfx doctor${RESET} ${GRAY}CLI 진단 + 이슈 확인${RESET}
915
920
  ${DIM} --fix${RESET} ${GRAY}진단 + 자동 수정${RESET}
916
921
  ${DIM} --reset${RESET} ${GRAY}캐시 전체 초기화${RESET}
917
- ${WHITE_BRIGHT}tfx update${RESET} ${GRAY}최신 버전으로 업데이트${RESET}
918
- ${DIM} --dev${RESET} ${GRAY}dev 태그로 업데이트${RESET}
922
+ ${WHITE_BRIGHT}tfx update${RESET} ${GRAY}최신 안정 버전으로 업데이트${RESET}
923
+ ${DIM} --dev / dev${RESET} ${GRAY}dev 태그로 업데이트${RESET}
919
924
  ${WHITE_BRIGHT}tfx list${RESET} ${GRAY}설치된 스킬 목록${RESET}
920
925
  ${WHITE_BRIGHT}tfx hub${RESET} ${GRAY}MCP 메시지 버스 관리 (start/stop/status)${RESET}
921
926
  ${WHITE_BRIGHT}tfx team${RESET} ${GRAY}멀티-CLI 팀 모드 (tmux + Hub)${RESET}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "triflux",
3
- "version": "3.2.0-dev.6",
3
+ "version": "3.2.0-dev.7",
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": {
@@ -7,9 +7,10 @@ import { existsSync, readFileSync } from "fs";
7
7
  import { join, dirname } from "path";
8
8
  import { homedir } from "os";
9
9
  import { spawn } from "child_process";
10
+ import { fileURLToPath } from "url";
10
11
 
11
12
  const LOOPBACK_HOSTS = new Set(["127.0.0.1", "localhost", "::1"]);
12
- const PLUGIN_ROOT = dirname(dirname(new URL(import.meta.url).pathname)).replace(/^\/([A-Z]:)/, "$1");
13
+ const PLUGIN_ROOT = dirname(dirname(fileURLToPath(import.meta.url)));
13
14
  const HUB_PID_FILE = join(homedir(), ".claude", "cache", "tfx-hub", "hub.pid");
14
15
 
15
16
  function formatHostForUrl(host) {
package/scripts/setup.mjs CHANGED
@@ -8,8 +8,9 @@ import { copyFileSync, mkdirSync, readFileSync, writeFileSync, readdirSync, exis
8
8
  import { join, dirname } from "path";
9
9
  import { homedir } from "os";
10
10
  import { spawn } from "child_process";
11
-
12
- const PLUGIN_ROOT = dirname(dirname(new URL(import.meta.url).pathname)).replace(/^\/([A-Z]:)/, "$1");
11
+ import { fileURLToPath } from "url";
12
+
13
+ const PLUGIN_ROOT = dirname(dirname(fileURLToPath(import.meta.url)));
13
14
  const CLAUDE_DIR = join(homedir(), ".claude");
14
15
  const CODEX_DIR = join(homedir(), ".codex");
15
16
  const CODEX_CONFIG_PATH = join(CODEX_DIR, "config.toml");
@@ -51,15 +52,24 @@ const SYNC_MAP = [
51
52
  },
52
53
  ];
53
54
 
54
- function getVersion(filePath) {
55
- try {
56
- const content = readFileSync(filePath, "utf8");
57
- const match = content.match(/VERSION\s*=\s*"([^"]+)"/);
58
- return match ? match[1] : null;
59
- } catch {
60
- return null;
61
- }
62
- }
55
+ function getVersion(filePath) {
56
+ try {
57
+ const content = readFileSync(filePath, "utf8");
58
+ const match = content.match(/VERSION\s*=\s*"([^"]+)"/);
59
+ return match ? match[1] : null;
60
+ } catch {
61
+ return null;
62
+ }
63
+ }
64
+
65
+ function shouldSyncTextFile(src, dst) {
66
+ if (!existsSync(dst)) return true;
67
+ try {
68
+ return readFileSync(src, "utf8") !== readFileSync(dst, "utf8");
69
+ } catch {
70
+ return true;
71
+ }
72
+ }
63
73
 
64
74
  function escapeRegExp(value) {
65
75
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -114,15 +124,13 @@ for (const { src, dst, label } of SYNC_MAP) {
114
124
  copyFileSync(src, dst);
115
125
  try { chmodSync(dst, 0o755); } catch {}
116
126
  synced++;
117
- } else {
118
- const srcVersion = getVersion(src);
119
- const dstVersion = getVersion(dst);
120
- if (srcVersion && dstVersion && srcVersion !== dstVersion) {
121
- copyFileSync(src, dst);
122
- try { chmodSync(dst, 0o755); } catch {}
123
- synced++;
124
- }
125
- }
127
+ } else {
128
+ if (shouldSyncTextFile(src, dst)) {
129
+ copyFileSync(src, dst);
130
+ try { chmodSync(dst, 0o755); } catch {}
131
+ synced++;
132
+ }
133
+ }
126
134
  }
127
135
 
128
136
  // ── 스킬 동기화 ──
@@ -349,11 +357,12 @@ ${B}╚════════════════════════
349
357
  ${G}✓${R} ${synced > 0 ? synced + " files synced" : "all files up to date"}
350
358
  ${G}✓${R} HUD statusLine → settings.json
351
359
 
352
- ${B}Commands:${R}
353
- ${C}triflux${R} setup 파일 동기화 + HUD 설정
354
- ${C}triflux${R} doctor CLI 진단 (Codex/Gemini 확인)
355
- ${C}triflux${R} list 설치된 스킬 목록
356
- ${C}triflux${R} update 최신 버전으로 업데이트
360
+ ${B}Commands:${R}
361
+ ${C}triflux${R} setup 파일 동기화 + HUD 설정
362
+ ${C}triflux${R} doctor CLI 진단 (Codex/Gemini 확인)
363
+ ${C}triflux${R} list 설치된 스킬 목록
364
+ ${C}triflux${R} update 최신 안정 버전으로 업데이트
365
+ ${C}triflux${R} update --dev dev 채널로 업데이트 (${D}dev 별칭 지원${R})
357
366
 
358
367
  ${B}Shortcuts:${R}
359
368
  ${C}tfx${R} triflux 축약