triflux 10.3.0 → 10.3.2

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.
Files changed (56) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +22 -22
  3. package/LICENSE +21 -21
  4. package/hooks/hook-registry.json +256 -256
  5. package/hub/adaptive-inject.mjs +1 -1
  6. package/hub/assign-callbacks.mjs +120 -120
  7. package/hub/delegator/index.mjs +14 -14
  8. package/hub/delegator/tool-definitions.mjs +35 -35
  9. package/hub/hitl.mjs +143 -143
  10. package/hub/router.mjs +791 -791
  11. package/hub/session-fingerprint.mjs +1 -1
  12. package/hub/team/ansi.mjs +44 -28
  13. package/hub/team/cli/commands/attach.mjs +37 -37
  14. package/hub/team/cli/commands/debug.mjs +74 -74
  15. package/hub/team/cli/commands/focus.mjs +53 -53
  16. package/hub/team/cli/commands/list.mjs +24 -24
  17. package/hub/team/cli/commands/start/start-in-process.mjs +40 -40
  18. package/hub/team/cli/commands/start/start-mux.mjs +73 -73
  19. package/hub/team/cli/commands/start/start-wt.mjs +69 -69
  20. package/hub/team/cli/commands/tasks.mjs +13 -13
  21. package/hub/team/cli/render.mjs +30 -30
  22. package/hub/team/cli/services/attach-fallback.mjs +54 -54
  23. package/hub/team/cli/services/member-selector.mjs +30 -30
  24. package/hub/team/cli/services/native-control.mjs +116 -116
  25. package/hub/team/cli/services/task-model.mjs +30 -30
  26. package/hub/team/conductor.mjs +2 -2
  27. package/hub/team/notify.mjs +1 -1
  28. package/hub/team/orchestrator.mjs +161 -161
  29. package/hub/team/session.mjs +611 -611
  30. package/hub/team/shared.mjs +13 -13
  31. package/hub/team/tui-lite.mjs +4 -4
  32. package/hub/team/tui.mjs +16 -12
  33. package/hub/tray.mjs +368 -368
  34. package/hub/workers/codex-mcp.mjs +507 -507
  35. package/hub/workers/factory.mjs +21 -21
  36. package/hud/constants.mjs +8 -2
  37. package/hud/providers/codex.mjs +11 -0
  38. package/hud/providers/gemini.mjs +21 -0
  39. package/package.json +1 -1
  40. package/scripts/claudemd-sync.mjs +11 -13
  41. package/scripts/completions/tfx.bash +47 -47
  42. package/scripts/completions/tfx.fish +44 -44
  43. package/scripts/completions/tfx.zsh +83 -83
  44. package/scripts/hub-ensure.mjs +120 -120
  45. package/scripts/keyword-detector.mjs +272 -272
  46. package/scripts/keyword-rules-expander.mjs +521 -521
  47. package/scripts/lib/mcp-server-catalog.mjs +118 -118
  48. package/scripts/notion-read.mjs +553 -553
  49. package/scripts/setup.mjs +23 -0
  50. package/scripts/test-tfx-route-no-claude-native.mjs +57 -57
  51. package/scripts/tfx-batch-stats.mjs +96 -96
  52. package/skills/.omc/state/agent-replay-8f0e10a9-9693-4410-96f5-a6b07e8ed995.jsonl +1 -0
  53. package/skills/.omc/state/idle-notif-cooldown.json +3 -0
  54. package/skills/.omc/state/last-tool-error.json +7 -0
  55. package/skills/.omc/state/subagent-tracking.json +7 -0
  56. package/skills/tfx-remote-spawn/references/hosts.json +16 -0
@@ -1,21 +1,21 @@
1
- // hub/workers/factory.mjs — Worker 생성 팩토리
2
-
3
- import { GeminiWorker } from './gemini-worker.mjs';
4
- import { ClaudeWorker } from './claude-worker.mjs';
5
- import { CodexMcpWorker } from './codex-mcp.mjs';
6
- import { DelegatorMcpWorker } from './delegator-mcp.mjs';
7
-
8
- export function createWorker(type, opts = {}) {
9
- switch (type) {
10
- case 'gemini':
11
- return new GeminiWorker(opts);
12
- case 'claude':
13
- return new ClaudeWorker(opts);
14
- case 'codex':
15
- return new CodexMcpWorker(opts);
16
- case 'delegator':
17
- return new DelegatorMcpWorker(opts);
18
- default:
19
- throw new Error(`Unknown worker type: ${type}`);
20
- }
21
- }
1
+ // hub/workers/factory.mjs — Worker 생성 팩토리
2
+
3
+ import { GeminiWorker } from './gemini-worker.mjs';
4
+ import { ClaudeWorker } from './claude-worker.mjs';
5
+ import { CodexMcpWorker } from './codex-mcp.mjs';
6
+ import { DelegatorMcpWorker } from './delegator-mcp.mjs';
7
+
8
+ export function createWorker(type, opts = {}) {
9
+ switch (type) {
10
+ case 'gemini':
11
+ return new GeminiWorker(opts);
12
+ case 'claude':
13
+ return new ClaudeWorker(opts);
14
+ case 'codex':
15
+ return new CodexMcpWorker(opts);
16
+ case 'delegator':
17
+ return new DelegatorMcpWorker(opts);
18
+ default:
19
+ throw new Error(`Unknown worker type: ${type}`);
20
+ }
21
+ }
package/hud/constants.mjs CHANGED
@@ -39,9 +39,15 @@ export const DEFAULT_OAUTH_CLIENT_ID = "9d1c250a-e61b-44d9-88ed-5944d1962f5e";
39
39
 
40
40
  export const CODEX_AUTH_PATH = join(homedir(), ".codex", "auth.json");
41
41
  export const CODEX_QUOTA_CACHE_PATH = join(homedir(), ".claude", "cache", "codex-rate-limits-cache.json");
42
- export const CODEX_QUOTA_STALE_MS = 15 * 1000; // 15
42
+ export const CODEX_QUOTA_STALE_MS = 30 * 1000; // 30
43
43
  export const CODEX_MIN_BUCKETS = 2;
44
44
 
45
+ // Spawn lock (중복 refresh 방지)
46
+ export const CODEX_REFRESH_LOCK_PATH = join(homedir(), ".claude", "cache", ".codex-refresh-lock");
47
+ export const GEMINI_QUOTA_REFRESH_LOCK_PATH = join(homedir(), ".claude", "cache", ".gemini-quota-refresh-lock");
48
+ export const GEMINI_SESSION_REFRESH_LOCK_PATH = join(homedir(), ".claude", "cache", ".gemini-session-refresh-lock");
49
+ export const SPAWN_LOCK_TTL_MS = 30 * 1000; // 30초 spawn dedup
50
+
45
51
  // Gemini 쿼터 API 관련
46
52
  export const GEMINI_OAUTH_PATH = join(homedir(), ".gemini", "oauth_creds.json");
47
53
  export const GEMINI_QUOTA_CACHE_PATH = join(homedir(), ".claude", "cache", "gemini-quota-cache.json");
@@ -58,7 +64,7 @@ export const LEGACY_SV_ACCUMULATOR = join(homedir(), ".omc", "state", "sv-accumu
58
64
 
59
65
  export const GEMINI_RPM_WINDOW_MS = 60 * 1000; // 60초 슬라이딩 윈도우
60
66
  export const GEMINI_QUOTA_STALE_MS = 5 * 60 * 1000; // 5분
61
- export const GEMINI_SESSION_STALE_MS = 15 * 1000; // 15
67
+ export const GEMINI_SESSION_STALE_MS = 30 * 1000; // 30
62
68
  export const GEMINI_API_TIMEOUT_MS = 3000; // 3초
63
69
 
64
70
  export const ACCOUNT_LABEL_WIDTH = 10;
@@ -8,6 +8,7 @@ import { spawn } from "node:child_process";
8
8
  import {
9
9
  CODEX_AUTH_PATH, CODEX_QUOTA_CACHE_PATH, CODEX_QUOTA_STALE_MS,
10
10
  CODEX_MIN_BUCKETS, CODEX_REFRESH_FLAG,
11
+ CODEX_REFRESH_LOCK_PATH, SPAWN_LOCK_TTL_MS,
11
12
  } from "../constants.mjs";
12
13
  import { readJson, writeJsonSafe, decodeJwtEmail } from "../utils.mjs";
13
14
 
@@ -154,6 +155,16 @@ export function refreshCodexRateLimitsCache() {
154
155
  export function scheduleCodexRateLimitRefresh() {
155
156
  const scriptPath = process.argv[1];
156
157
  if (!scriptPath) return;
158
+
159
+ // 스폰 락: 30초 내 이미 스폰했으면 중복 방지
160
+ try {
161
+ if (existsSync(CODEX_REFRESH_LOCK_PATH)) {
162
+ const lockAge = Date.now() - readJson(CODEX_REFRESH_LOCK_PATH, {}).t;
163
+ if (lockAge < SPAWN_LOCK_TTL_MS) return;
164
+ }
165
+ writeJsonSafe(CODEX_REFRESH_LOCK_PATH, { t: Date.now() });
166
+ } catch { /* 락 실패 무시 — 스폰 진행 */ }
167
+
157
168
  try {
158
169
  const child = spawn(process.execPath, [scriptPath, CODEX_REFRESH_FLAG], {
159
170
  detached: true,
@@ -14,6 +14,7 @@ import {
14
14
  GEMINI_RPM_WINDOW_MS, GEMINI_QUOTA_STALE_MS, GEMINI_SESSION_STALE_MS,
15
15
  GEMINI_API_TIMEOUT_MS,
16
16
  GEMINI_REFRESH_FLAG, GEMINI_SESSION_REFRESH_FLAG,
17
+ GEMINI_QUOTA_REFRESH_LOCK_PATH, GEMINI_SESSION_REFRESH_LOCK_PATH, SPAWN_LOCK_TTL_MS,
17
18
  } from "../constants.mjs";
18
19
  import {
19
20
  readJson, writeJsonSafe, readJsonMigrate, makeHash, clampPercent,
@@ -233,6 +234,16 @@ export function readGeminiQuotaSnapshot(accountId, authContext) {
233
234
  export function scheduleGeminiQuotaRefresh(accountId) {
234
235
  const scriptPath = process.argv[1];
235
236
  if (!scriptPath) return;
237
+
238
+ // 스폰 락: 30초 내 이미 스폰했으면 중복 방지
239
+ try {
240
+ if (existsSync(GEMINI_QUOTA_REFRESH_LOCK_PATH)) {
241
+ const lockAge = Date.now() - readJson(GEMINI_QUOTA_REFRESH_LOCK_PATH, {}).t;
242
+ if (lockAge < SPAWN_LOCK_TTL_MS) return;
243
+ }
244
+ writeJsonSafe(GEMINI_QUOTA_REFRESH_LOCK_PATH, { t: Date.now() });
245
+ } catch { /* 락 실패 무시 — 스폰 진행 */ }
246
+
236
247
  try {
237
248
  const child = spawn(
238
249
  process.execPath,
@@ -275,6 +286,16 @@ export function refreshGeminiSessionCache() {
275
286
  export function scheduleGeminiSessionRefresh() {
276
287
  const scriptPath = process.argv[1];
277
288
  if (!scriptPath) return;
289
+
290
+ // 스폰 락: 30초 내 이미 스폰했으면 중복 방지
291
+ try {
292
+ if (existsSync(GEMINI_SESSION_REFRESH_LOCK_PATH)) {
293
+ const lockAge = Date.now() - readJson(GEMINI_SESSION_REFRESH_LOCK_PATH, {}).t;
294
+ if (lockAge < SPAWN_LOCK_TTL_MS) return;
295
+ }
296
+ writeJsonSafe(GEMINI_SESSION_REFRESH_LOCK_PATH, { t: Date.now() });
297
+ } catch { /* 락 실패 무시 — 스폰 진행 */ }
298
+
278
299
  try {
279
300
  const child = spawn(process.execPath, [scriptPath, GEMINI_SESSION_REFRESH_FLAG], {
280
301
  detached: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "triflux",
3
- "version": "10.3.0",
3
+ "version": "10.3.2",
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": {
@@ -1,10 +1,12 @@
1
1
  import { existsSync, readFileSync, writeFileSync } from "node:fs";
2
2
  import { join, resolve } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
+ import { homedir } from "node:os";
4
5
  import { TFX_START, OMC_END, writeSection } from "./lib/claudemd-scanner.mjs";
5
6
 
6
- const PROJECT_ROOT = fileURLToPath(new URL("..", import.meta.url));
7
- const PROJECT_CLAUDE_MD_PATH = join(PROJECT_ROOT, "CLAUDE.md");
7
+ const PKG_ROOT = fileURLToPath(new URL("..", import.meta.url));
8
+ const GLOBAL_CLAUDE_MD_PATH = join(homedir(), ".claude", "CLAUDE.md");
9
+ const PKG_CLAUDE_MD_PATH = join(PKG_ROOT, "CLAUDE.md");
8
10
  const ROUTING_TAG_OPEN = "<routing>";
9
11
  const ROUTING_TAG_CLOSE = "</routing>";
10
12
  // Legacy heading fallback
@@ -73,18 +75,14 @@ function toSkippedResult(path, reason) {
73
75
  }
74
76
 
75
77
  export function getLatestRoutingTable() {
76
- if (!existsSync(PROJECT_CLAUDE_MD_PATH)) {
77
- throw new Error(`project CLAUDE.md not found: ${PROJECT_CLAUDE_MD_PATH}`);
78
+ // 1차: 사용자 글로벌 ~/.claude/CLAUDE.md (어디서든 접근 가능한 공통 경로)
79
+ for (const candidate of [GLOBAL_CLAUDE_MD_PATH, PKG_CLAUDE_MD_PATH]) {
80
+ if (!existsSync(candidate)) continue;
81
+ const section = findRoutingSection(readFileSync(candidate, "utf8"));
82
+ if (section.found) return section.section.trim();
78
83
  }
79
-
80
- const projectMarkdown = readFileSync(PROJECT_CLAUDE_MD_PATH, "utf8");
81
- const section = findRoutingSection(projectMarkdown);
82
-
83
- if (!section.found) {
84
- throw new Error(`routing section not found in: ${PROJECT_CLAUDE_MD_PATH}`);
85
- }
86
-
87
- return section.section.trim();
84
+ // 2차 fallback: 패키지 CLAUDE.md도 없으면 에러
85
+ throw new Error(`routing section not found in: ${GLOBAL_CLAUDE_MD_PATH} or ${PKG_CLAUDE_MD_PATH}`);
88
86
  }
89
87
 
90
88
  export function ensureTfxSection(claudeMdPath, routingTable) {
@@ -1,47 +1,47 @@
1
- #!/usr/bin/env bash
2
- # Installation: source /path/to/tfx.bash 또는 ~/.bashrc에 추가
3
-
4
- _tfx_completion() {
5
- local cur prev words cword
6
- COMPREPLY=()
7
- cur="${COMP_WORDS[COMP_CWORD]}"
8
- prev="${COMP_WORDS[COMP_CWORD-1]}"
9
- words=("${COMP_WORDS[@]}")
10
- cword=$COMP_CWORD
11
-
12
- local commands="setup doctor multi hub auto codex gemini"
13
- local multi_cmds="status stop kill attach list"
14
- local hub_cmds="start stop status restart"
15
- local flags="--thorough --quick --tmux --psmux --agents --no-attach --timeout"
16
-
17
- if [[ $cword -eq 1 ]]; then
18
- COMPREPLY=( $(compgen -W "${commands}" -- "$cur") )
19
- return 0
20
- fi
21
-
22
- local cmd="${words[1]}"
23
- case "${cmd}" in
24
- multi)
25
- if [[ $cword -eq 2 && ! "$cur" == -* ]]; then
26
- COMPREPLY=( $(compgen -W "${multi_cmds}" -- "$cur") )
27
- else
28
- COMPREPLY=( $(compgen -W "${flags}" -- "$cur") )
29
- fi
30
- ;;
31
- hub)
32
- if [[ $cword -eq 2 ]]; then
33
- COMPREPLY=( $(compgen -W "${hub_cmds}" -- "$cur") )
34
- fi
35
- ;;
36
- doctor)
37
- COMPREPLY=( $(compgen -W "--fix --reset" -- "$cur") )
38
- ;;
39
- setup|auto|codex|gemini)
40
- if [[ "$cur" == -* ]]; then
41
- COMPREPLY=( $(compgen -W "${flags}" -- "$cur") )
42
- fi
43
- ;;
44
- esac
45
- }
46
-
47
- complete -F _tfx_completion tfx
1
+ #!/usr/bin/env bash
2
+ # Installation: source /path/to/tfx.bash 또는 ~/.bashrc에 추가
3
+
4
+ _tfx_completion() {
5
+ local cur prev words cword
6
+ COMPREPLY=()
7
+ cur="${COMP_WORDS[COMP_CWORD]}"
8
+ prev="${COMP_WORDS[COMP_CWORD-1]}"
9
+ words=("${COMP_WORDS[@]}")
10
+ cword=$COMP_CWORD
11
+
12
+ local commands="setup doctor multi hub auto codex gemini"
13
+ local multi_cmds="status stop kill attach list"
14
+ local hub_cmds="start stop status restart"
15
+ local flags="--thorough --quick --tmux --psmux --agents --no-attach --timeout"
16
+
17
+ if [[ $cword -eq 1 ]]; then
18
+ COMPREPLY=( $(compgen -W "${commands}" -- "$cur") )
19
+ return 0
20
+ fi
21
+
22
+ local cmd="${words[1]}"
23
+ case "${cmd}" in
24
+ multi)
25
+ if [[ $cword -eq 2 && ! "$cur" == -* ]]; then
26
+ COMPREPLY=( $(compgen -W "${multi_cmds}" -- "$cur") )
27
+ else
28
+ COMPREPLY=( $(compgen -W "${flags}" -- "$cur") )
29
+ fi
30
+ ;;
31
+ hub)
32
+ if [[ $cword -eq 2 ]]; then
33
+ COMPREPLY=( $(compgen -W "${hub_cmds}" -- "$cur") )
34
+ fi
35
+ ;;
36
+ doctor)
37
+ COMPREPLY=( $(compgen -W "--fix --reset" -- "$cur") )
38
+ ;;
39
+ setup|auto|codex|gemini)
40
+ if [[ "$cur" == -* ]]; then
41
+ COMPREPLY=( $(compgen -W "${flags}" -- "$cur") )
42
+ fi
43
+ ;;
44
+ esac
45
+ }
46
+
47
+ complete -F _tfx_completion tfx
@@ -1,44 +1,44 @@
1
- # Installation: ~/.config/fish/completions/에 복사
2
- # e.g., cp /path/to/tfx.fish ~/.config/fish/completions/tfx.fish
3
-
4
- set -l commands setup doctor multi hub auto codex gemini
5
- set -l multi_cmds status stop kill attach list
6
- set -l hub_cmds start stop status restart
7
-
8
- complete -c tfx -f
9
-
10
- # Subcommands
11
- complete -c tfx -n "not __fish_seen_subcommand_from $commands" -a "setup" -d "Setup and sync files"
12
- complete -c tfx -n "not __fish_seen_subcommand_from $commands" -a "doctor" -d "Diagnose CLI and issues"
13
- complete -c tfx -n "not __fish_seen_subcommand_from $commands" -a "multi" -d "Multi-CLI team mode"
14
- complete -c tfx -n "not __fish_seen_subcommand_from $commands" -a "hub" -d "MCP message bus management"
15
- complete -c tfx -n "not __fish_seen_subcommand_from $commands" -a "auto" -d "Auto mode"
16
- complete -c tfx -n "not __fish_seen_subcommand_from $commands" -a "codex" -d "Codex mode"
17
- complete -c tfx -n "not __fish_seen_subcommand_from $commands" -a "gemini" -d "Gemini mode"
18
-
19
- # Doctor flags
20
- complete -c tfx -n "__fish_seen_subcommand_from doctor" -l fix -d "Auto fix issues"
21
- complete -c tfx -n "__fish_seen_subcommand_from doctor" -l reset -d "Reset all caches"
22
-
23
- # Multi subcommands
24
- complete -c tfx -n "__fish_seen_subcommand_from multi; and not __fish_seen_subcommand_from $multi_cmds" -a "status"
25
- complete -c tfx -n "__fish_seen_subcommand_from multi; and not __fish_seen_subcommand_from $multi_cmds" -a "stop"
26
- complete -c tfx -n "__fish_seen_subcommand_from multi; and not __fish_seen_subcommand_from $multi_cmds" -a "kill"
27
- complete -c tfx -n "__fish_seen_subcommand_from multi; and not __fish_seen_subcommand_from $multi_cmds" -a "attach"
28
- complete -c tfx -n "__fish_seen_subcommand_from multi; and not __fish_seen_subcommand_from $multi_cmds" -a "list"
29
-
30
- # Hub subcommands
31
- complete -c tfx -n "__fish_seen_subcommand_from hub; and not __fish_seen_subcommand_from $hub_cmds" -a "start"
32
- complete -c tfx -n "__fish_seen_subcommand_from hub; and not __fish_seen_subcommand_from $hub_cmds" -a "stop"
33
- complete -c tfx -n "__fish_seen_subcommand_from hub; and not __fish_seen_subcommand_from $hub_cmds" -a "status"
34
- complete -c tfx -n "__fish_seen_subcommand_from hub; and not __fish_seen_subcommand_from $hub_cmds" -a "restart"
35
-
36
- # Global or multi flags
37
- set -l flags_cond "__fish_seen_subcommand_from setup multi auto codex gemini"
38
- complete -c tfx -n "$flags_cond" -l thorough -d "Thorough execution"
39
- complete -c tfx -n "$flags_cond" -l quick -d "Quick execution"
40
- complete -c tfx -n "$flags_cond" -l tmux -d "Use tmux"
41
- complete -c tfx -n "$flags_cond" -l psmux -d "Use psmux"
42
- complete -c tfx -n "$flags_cond" -l agents -d "Specify agents"
43
- complete -c tfx -n "$flags_cond" -l no-attach -d "Do not attach"
44
- complete -c tfx -n "$flags_cond" -l timeout -d "Set timeout"
1
+ # Installation: ~/.config/fish/completions/에 복사
2
+ # e.g., cp /path/to/tfx.fish ~/.config/fish/completions/tfx.fish
3
+
4
+ set -l commands setup doctor multi hub auto codex gemini
5
+ set -l multi_cmds status stop kill attach list
6
+ set -l hub_cmds start stop status restart
7
+
8
+ complete -c tfx -f
9
+
10
+ # Subcommands
11
+ complete -c tfx -n "not __fish_seen_subcommand_from $commands" -a "setup" -d "Setup and sync files"
12
+ complete -c tfx -n "not __fish_seen_subcommand_from $commands" -a "doctor" -d "Diagnose CLI and issues"
13
+ complete -c tfx -n "not __fish_seen_subcommand_from $commands" -a "multi" -d "Multi-CLI team mode"
14
+ complete -c tfx -n "not __fish_seen_subcommand_from $commands" -a "hub" -d "MCP message bus management"
15
+ complete -c tfx -n "not __fish_seen_subcommand_from $commands" -a "auto" -d "Auto mode"
16
+ complete -c tfx -n "not __fish_seen_subcommand_from $commands" -a "codex" -d "Codex mode"
17
+ complete -c tfx -n "not __fish_seen_subcommand_from $commands" -a "gemini" -d "Gemini mode"
18
+
19
+ # Doctor flags
20
+ complete -c tfx -n "__fish_seen_subcommand_from doctor" -l fix -d "Auto fix issues"
21
+ complete -c tfx -n "__fish_seen_subcommand_from doctor" -l reset -d "Reset all caches"
22
+
23
+ # Multi subcommands
24
+ complete -c tfx -n "__fish_seen_subcommand_from multi; and not __fish_seen_subcommand_from $multi_cmds" -a "status"
25
+ complete -c tfx -n "__fish_seen_subcommand_from multi; and not __fish_seen_subcommand_from $multi_cmds" -a "stop"
26
+ complete -c tfx -n "__fish_seen_subcommand_from multi; and not __fish_seen_subcommand_from $multi_cmds" -a "kill"
27
+ complete -c tfx -n "__fish_seen_subcommand_from multi; and not __fish_seen_subcommand_from $multi_cmds" -a "attach"
28
+ complete -c tfx -n "__fish_seen_subcommand_from multi; and not __fish_seen_subcommand_from $multi_cmds" -a "list"
29
+
30
+ # Hub subcommands
31
+ complete -c tfx -n "__fish_seen_subcommand_from hub; and not __fish_seen_subcommand_from $hub_cmds" -a "start"
32
+ complete -c tfx -n "__fish_seen_subcommand_from hub; and not __fish_seen_subcommand_from $hub_cmds" -a "stop"
33
+ complete -c tfx -n "__fish_seen_subcommand_from hub; and not __fish_seen_subcommand_from $hub_cmds" -a "status"
34
+ complete -c tfx -n "__fish_seen_subcommand_from hub; and not __fish_seen_subcommand_from $hub_cmds" -a "restart"
35
+
36
+ # Global or multi flags
37
+ set -l flags_cond "__fish_seen_subcommand_from setup multi auto codex gemini"
38
+ complete -c tfx -n "$flags_cond" -l thorough -d "Thorough execution"
39
+ complete -c tfx -n "$flags_cond" -l quick -d "Quick execution"
40
+ complete -c tfx -n "$flags_cond" -l tmux -d "Use tmux"
41
+ complete -c tfx -n "$flags_cond" -l psmux -d "Use psmux"
42
+ complete -c tfx -n "$flags_cond" -l agents -d "Specify agents"
43
+ complete -c tfx -n "$flags_cond" -l no-attach -d "Do not attach"
44
+ complete -c tfx -n "$flags_cond" -l timeout -d "Set timeout"
@@ -1,83 +1,83 @@
1
- #compdef tfx
2
- # Installation: fpath에 추가 후 compinit
3
- # e.g., fpath=(/path/to/dir $fpath) && compinit
4
-
5
- _tfx() {
6
- local line state
7
- local -a commands multi_cmds hub_cmds flags
8
-
9
- commands=(
10
- 'setup:Setup and sync files'
11
- 'doctor:Diagnose CLI and issues'
12
- 'multi:Multi-CLI team mode'
13
- 'hub:MCP message bus management'
14
- 'auto:Auto mode'
15
- 'codex:Codex mode'
16
- 'gemini:Gemini mode'
17
- )
18
-
19
- multi_cmds=(
20
- 'status:Show status'
21
- 'stop:Stop multi'
22
- 'kill:Kill multi'
23
- 'attach:Attach to multi'
24
- 'list:List multi sessions'
25
- )
26
-
27
- hub_cmds=(
28
- 'start:Start hub'
29
- 'stop:Stop hub'
30
- 'status:Show hub status'
31
- 'restart:Restart hub'
32
- )
33
-
34
- _arguments -C \
35
- '1: :->cmds' \
36
- '*: :->args'
37
-
38
- case $state in
39
- cmds)
40
- _describe -t commands 'tfx commands' commands
41
- ;;
42
- args)
43
- case $words[2] in
44
- multi)
45
- if (( CURRENT == 3 )) && [[ $words[CURRENT] != -* ]]; then
46
- _describe -t multi_cmds 'multi commands' multi_cmds
47
- else
48
- _arguments \
49
- '--thorough[Thorough execution]' \
50
- '--quick[Quick execution]' \
51
- '--tmux[Use tmux]' \
52
- '--psmux[Use psmux]' \
53
- '--agents[Specify agents]' \
54
- '--no-attach[Do not attach]' \
55
- '--timeout[Set timeout]'
56
- fi
57
- ;;
58
- hub)
59
- if (( CURRENT == 3 )); then
60
- _describe -t hub_cmds 'hub commands' hub_cmds
61
- fi
62
- ;;
63
- doctor)
64
- _arguments \
65
- '--fix[Auto fix issues]' \
66
- '--reset[Reset all caches]'
67
- ;;
68
- *)
69
- _arguments \
70
- '--thorough[Thorough execution]' \
71
- '--quick[Quick execution]' \
72
- '--tmux[Use tmux]' \
73
- '--psmux[Use psmux]' \
74
- '--agents[Specify agents]' \
75
- '--no-attach[Do not attach]' \
76
- '--timeout[Set timeout]'
77
- ;;
78
- esac
79
- ;;
80
- esac
81
- }
82
-
83
- _tfx "$@"
1
+ #compdef tfx
2
+ # Installation: fpath에 추가 후 compinit
3
+ # e.g., fpath=(/path/to/dir $fpath) && compinit
4
+
5
+ _tfx() {
6
+ local line state
7
+ local -a commands multi_cmds hub_cmds flags
8
+
9
+ commands=(
10
+ 'setup:Setup and sync files'
11
+ 'doctor:Diagnose CLI and issues'
12
+ 'multi:Multi-CLI team mode'
13
+ 'hub:MCP message bus management'
14
+ 'auto:Auto mode'
15
+ 'codex:Codex mode'
16
+ 'gemini:Gemini mode'
17
+ )
18
+
19
+ multi_cmds=(
20
+ 'status:Show status'
21
+ 'stop:Stop multi'
22
+ 'kill:Kill multi'
23
+ 'attach:Attach to multi'
24
+ 'list:List multi sessions'
25
+ )
26
+
27
+ hub_cmds=(
28
+ 'start:Start hub'
29
+ 'stop:Stop hub'
30
+ 'status:Show hub status'
31
+ 'restart:Restart hub'
32
+ )
33
+
34
+ _arguments -C \
35
+ '1: :->cmds' \
36
+ '*: :->args'
37
+
38
+ case $state in
39
+ cmds)
40
+ _describe -t commands 'tfx commands' commands
41
+ ;;
42
+ args)
43
+ case $words[2] in
44
+ multi)
45
+ if (( CURRENT == 3 )) && [[ $words[CURRENT] != -* ]]; then
46
+ _describe -t multi_cmds 'multi commands' multi_cmds
47
+ else
48
+ _arguments \
49
+ '--thorough[Thorough execution]' \
50
+ '--quick[Quick execution]' \
51
+ '--tmux[Use tmux]' \
52
+ '--psmux[Use psmux]' \
53
+ '--agents[Specify agents]' \
54
+ '--no-attach[Do not attach]' \
55
+ '--timeout[Set timeout]'
56
+ fi
57
+ ;;
58
+ hub)
59
+ if (( CURRENT == 3 )); then
60
+ _describe -t hub_cmds 'hub commands' hub_cmds
61
+ fi
62
+ ;;
63
+ doctor)
64
+ _arguments \
65
+ '--fix[Auto fix issues]' \
66
+ '--reset[Reset all caches]'
67
+ ;;
68
+ *)
69
+ _arguments \
70
+ '--thorough[Thorough execution]' \
71
+ '--quick[Quick execution]' \
72
+ '--tmux[Use tmux]' \
73
+ '--psmux[Use psmux]' \
74
+ '--agents[Specify agents]' \
75
+ '--no-attach[Do not attach]' \
76
+ '--timeout[Set timeout]'
77
+ ;;
78
+ esac
79
+ ;;
80
+ esac
81
+ }
82
+
83
+ _tfx "$@"