triflux 10.3.4 → 10.7.0
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/LICENSE +21 -21
- package/bin/tfx-doctor-tui.mjs +1 -1
- package/bin/tfx-doctor.mjs +6 -1
- package/bin/tfx-profile.mjs +1 -1
- package/bin/tfx-setup-tui.mjs +1 -1
- package/bin/tfx-setup.mjs +6 -1
- package/bin/triflux.mjs +2396 -1140
- package/hooks/agent-route-guard.mjs +12 -8
- package/hooks/cross-review-tracker.mjs +21 -8
- package/hooks/error-context.mjs +19 -7
- package/hooks/hook-adaptive-collector.mjs +18 -16
- package/hooks/hook-manager.mjs +93 -32
- package/hooks/hook-orchestrator.mjs +108 -24
- package/hooks/hook-registry.json +11 -0
- package/hooks/keyword-rules.json +6 -10
- package/hooks/lib/resolve-root.mjs +1 -1
- package/hooks/mcp-config-watcher.mjs +6 -2
- package/hooks/pipeline-stop.mjs +3 -6
- package/hooks/safety-guard.mjs +99 -28
- package/hooks/session-start-fast.mjs +143 -0
- package/hooks/subagent-verifier.mjs +5 -4
- package/hub/account-broker.mjs +256 -60
- package/hub/adaptive-diagnostic.mjs +75 -48
- package/hub/adaptive-inject.mjs +95 -57
- package/hub/adaptive-memory.mjs +156 -42
- package/hub/adaptive.mjs +60 -31
- package/hub/assign-callbacks.mjs +67 -30
- package/hub/bridge.mjs +0 -1
- package/hub/cli-adapter-base.mjs +200 -48
- package/hub/codex-adapter.mjs +76 -96
- package/hub/codex-compat.mjs +3 -3
- package/hub/codex-preflight.mjs +63 -37
- package/hub/delegator/contracts.mjs +19 -23
- package/hub/delegator/index.mjs +3 -3
- package/hub/delegator/service.mjs +88 -64
- package/hub/delegator/tool-definitions.mjs +5 -5
- package/hub/fullcycle.mjs +33 -17
- package/hub/gemini-adapter.mjs +69 -94
- package/hub/hitl.mjs +89 -30
- package/hub/intent.mjs +161 -38
- package/hub/lib/cache-guard.mjs +43 -17
- package/hub/lib/mcp-response-cache.mjs +66 -32
- package/hub/lib/memory-store.mjs +285 -111
- package/hub/lib/path-utils.mjs +35 -37
- package/hub/lib/process-utils.mjs +106 -37
- package/hub/lib/spawn-trace.mjs +527 -0
- package/hub/lib/ssh-command.mjs +34 -4
- package/hub/lib/ssh-retry.mjs +5 -1
- package/hub/lib/uuidv7.mjs +4 -3
- package/hub/memory-doctor.mjs +266 -106
- package/hub/middleware/request-logger.mjs +61 -34
- package/hub/paths.mjs +9 -9
- package/hub/pipeline/gates/confidence.mjs +34 -15
- package/hub/pipeline/gates/consensus.mjs +27 -15
- package/hub/pipeline/gates/index.mjs +7 -3
- package/hub/pipeline/gates/selfcheck.mjs +57 -19
- package/hub/pipeline/index.mjs +77 -42
- package/hub/pipeline/state.mjs +10 -10
- package/hub/pipeline/transitions.mjs +40 -23
- package/hub/platform.mjs +57 -48
- package/hub/promote-penalties.mjs +25 -7
- package/hub/quality/deslop.mjs +70 -49
- package/hub/research.mjs +32 -25
- package/hub/router.mjs +240 -107
- package/hub/routing/complexity.mjs +132 -29
- package/hub/routing/index.mjs +17 -12
- package/hub/routing/q-learning.mjs +76 -28
- package/hub/server.mjs +4 -4
- package/hub/session-fingerprint.mjs +126 -60
- package/hub/state.mjs +84 -43
- package/hub/store-adapter.mjs +59 -26
- package/hub/store.mjs +356 -153
- package/hub/team/agent-map.json +22 -7
- package/hub/team/ansi.mjs +186 -122
- package/hub/team/backend.mjs +28 -10
- package/hub/team/cli/commands/attach.mjs +29 -9
- package/hub/team/cli/commands/control.mjs +29 -8
- package/hub/team/cli/commands/debug.mjs +32 -11
- package/hub/team/cli/commands/focus.mjs +38 -11
- package/hub/team/cli/commands/interrupt.mjs +18 -6
- package/hub/team/cli/commands/kill.mjs +16 -5
- package/hub/team/cli/commands/list.mjs +11 -4
- package/hub/team/cli/commands/send.mjs +19 -6
- package/hub/team/cli/commands/start/index.mjs +154 -31
- package/hub/team/cli/commands/start/parse-args.mjs +38 -11
- package/hub/team/cli/commands/start/start-headless.mjs +112 -36
- package/hub/team/cli/commands/start/start-in-process.mjs +12 -2
- package/hub/team/cli/commands/start/start-mux.mjs +70 -21
- package/hub/team/cli/commands/start/start-wt.mjs +29 -12
- package/hub/team/cli/commands/status.mjs +43 -14
- package/hub/team/cli/commands/stop.mjs +11 -4
- package/hub/team/cli/commands/task.mjs +8 -3
- package/hub/team/cli/commands/tasks.mjs +1 -1
- package/hub/team/cli/index.mjs +2 -2
- package/hub/team/cli/manifest.mjs +38 -8
- package/hub/team/cli/render.mjs +30 -8
- package/hub/team/cli/services/attach-fallback.mjs +31 -11
- package/hub/team/cli/services/hub-client.mjs +42 -14
- package/hub/team/cli/services/member-selector.mjs +11 -4
- package/hub/team/cli/services/native-control.mjs +48 -21
- package/hub/team/cli/services/runtime-mode.mjs +2 -1
- package/hub/team/cli/services/state-store.mjs +25 -8
- package/hub/team/cli/services/task-model.mjs +16 -6
- package/hub/team/conductor-mesh-bridge.mjs +24 -23
- package/hub/team/conductor.mjs +8 -4
- package/hub/team/dashboard-anchor.mjs +4 -5
- package/hub/team/dashboard-layout.mjs +3 -1
- package/hub/team/dashboard-open.mjs +41 -21
- package/hub/team/dashboard.mjs +76 -28
- package/hub/team/event-log.mjs +18 -10
- package/hub/team/handoff.mjs +31 -15
- package/hub/team/headless.mjs +2 -1
- package/hub/team/health-probe.mjs +69 -54
- package/hub/team/launcher-template.mjs +16 -13
- package/hub/team/native-supervisor.mjs +65 -21
- package/hub/team/native.mjs +74 -35
- package/hub/team/nativeProxy.mjs +184 -113
- package/hub/team/notify.mjs +119 -76
- package/hub/team/orchestrator.mjs +9 -4
- package/hub/team/pane.mjs +12 -7
- package/hub/team/process-cleanup.mjs +25 -16
- package/hub/team/psmux.mjs +491 -201
- package/hub/team/remote-probe.mjs +68 -52
- package/hub/team/remote-session.mjs +117 -59
- package/hub/team/remote-watcher.mjs +61 -33
- package/hub/team/routing.mjs +51 -25
- package/hub/team/runtime-strategy.mjs +3 -1
- package/hub/team/session.mjs +98 -34
- package/hub/team/staleState.mjs +72 -30
- package/hub/team/swarm-locks.mjs +15 -13
- package/hub/team/swarm-planner.mjs +32 -21
- package/hub/team/swarm-reconciler.mjs +48 -23
- package/hub/team/tui-lite.mjs +266 -68
- package/hub/team/tui-remote-adapter.mjs +14 -10
- package/hub/team/tui-viewer.mjs +99 -43
- package/hub/team/tui.mjs +708 -271
- package/hub/team/worktree-lifecycle.mjs +152 -58
- package/hub/team/wt-manager.mjs +24 -14
- package/hub/token-mode.mjs +71 -71
- package/hub/tray.mjs +66 -23
- package/hub/workers/claude-worker.mjs +162 -118
- package/hub/workers/codex-mcp.mjs +192 -141
- package/hub/workers/delegator-mcp.mjs +507 -333
- package/hub/workers/factory.mjs +8 -8
- package/hub/workers/gemini-worker.mjs +115 -84
- package/hub/workers/interface.mjs +6 -1
- package/hub/workers/worker-utils.mjs +21 -14
- package/hud/colors.mjs +27 -9
- package/hud/constants.mjs +162 -26
- package/hud/context-monitor.mjs +82 -41
- package/hud/hud-qos-status.mjs +129 -49
- package/hud/mission-board.mjs +6 -3
- package/hud/providers/claude.mjs +226 -115
- package/hud/providers/codex.mjs +62 -22
- package/hud/providers/gemini.mjs +168 -56
- package/hud/renderers.mjs +384 -119
- package/hud/terminal.mjs +101 -31
- package/hud/utils.mjs +78 -38
- package/mesh/index.mjs +11 -5
- package/mesh/mesh-budget.mjs +18 -9
- package/mesh/mesh-heartbeat.mjs +1 -1
- package/mesh/mesh-queue.mjs +3 -5
- package/mesh/mesh-router.mjs +5 -4
- package/package.json +2 -1
- package/scripts/__tests__/gen-skill-docs.test.mjs +36 -7
- package/scripts/__tests__/keyword-detector.test.mjs +77 -28
- package/scripts/__tests__/mcp-guard-engine.test.mjs +58 -20
- package/scripts/__tests__/remote-spawn-transfer.test.mjs +30 -19
- package/scripts/__tests__/remote-spawn.test.mjs +10 -4
- package/scripts/__tests__/session-start-fast.test.mjs +36 -0
- package/scripts/__tests__/skill-template.test.mjs +98 -50
- package/scripts/__tests__/smoke.test.mjs +1 -1
- package/scripts/__tests__/spawn-trace.test.mjs +102 -0
- package/scripts/__tests__/tfx-doctor-diagnose.test.mjs +48 -0
- package/scripts/cache-doctor.mjs +11 -4
- package/scripts/cache-warmup.mjs +96 -37
- package/scripts/claudemd-sync.mjs +27 -17
- package/scripts/codex-gateway-preflight.mjs +52 -37
- package/scripts/codex-mcp-gateway-sync.mjs +59 -39
- package/scripts/completions/tfx.bash +47 -47
- package/scripts/completions/tfx.fish +44 -44
- package/scripts/completions/tfx.zsh +83 -83
- package/scripts/config-audit.mjs +232 -0
- package/scripts/convert-to-tmpl.mjs +54 -0
- package/scripts/cross-review-gate.mjs +35 -12
- package/scripts/cross-review-tracker.mjs +21 -8
- package/scripts/demo.mjs +35 -17
- package/scripts/doctor-diagnose.mjs +284 -0
- package/scripts/gen-skill-docs.mjs +7 -2
- package/scripts/gen-skill-manifest.mjs +2 -1
- package/scripts/headless-guard.mjs +86 -48
- package/scripts/hub-ensure.mjs +45 -26
- package/scripts/keyword-detector.mjs +41 -20
- package/scripts/keyword-rules-expander.mjs +47 -30
- package/scripts/lib/claudemd-scanner.mjs +6 -1
- package/scripts/lib/context.mjs +3 -3
- package/scripts/lib/cross-review-utils.mjs +6 -3
- package/scripts/lib/env-probe.mjs +47 -28
- package/scripts/lib/gemini-profiles.mjs +44 -10
- package/scripts/lib/handoff.mjs +33 -17
- package/scripts/lib/hook-utils.mjs +8 -6
- package/scripts/lib/keyword-rules.mjs +43 -19
- package/scripts/lib/logger.mjs +24 -24
- package/scripts/lib/mcp-filter.mjs +377 -239
- package/scripts/lib/mcp-guard-engine.mjs +194 -79
- package/scripts/lib/mcp-manifest.mjs +23 -13
- package/scripts/lib/mcp-server-catalog.mjs +300 -63
- package/scripts/lib/psmux-info.mjs +11 -6
- package/scripts/lib/remote-spawn-transfer.mjs +44 -14
- package/scripts/lib/skill-template.mjs +30 -7
- package/scripts/mcp-check.mjs +58 -39
- package/scripts/mcp-gateway-config.mjs +83 -39
- package/scripts/mcp-gateway-ensure.mjs +43 -35
- package/scripts/mcp-gateway-integration-test.mjs +70 -58
- package/scripts/mcp-gateway-start.mjs +126 -60
- package/scripts/mcp-gateway-verify.mjs +24 -22
- package/scripts/mcp-safety-guard.mjs +44 -11
- package/scripts/notion-read.mjs +199 -84
- package/scripts/pack.mjs +94 -89
- package/scripts/preflight-cache.mjs +27 -10
- package/scripts/preinstall.mjs +42 -13
- package/scripts/remote-spawn.mjs +309 -94
- package/scripts/run.cjs +8 -5
- package/scripts/session-spawn-helper.mjs +130 -39
- package/scripts/session-stale-cleanup.mjs +123 -0
- package/scripts/setup.mjs +941 -492
- package/scripts/test-lock.mjs +20 -7
- package/scripts/test-tfx-route-no-claude-native.mjs +16 -12
- package/scripts/tfx-batch-stats.mjs +32 -11
- package/scripts/tfx-gate-activate.mjs +11 -4
- package/scripts/tfx-route-post.mjs +87 -20
- package/scripts/tfx-route-worker.mjs +57 -51
- package/scripts/tfx-route.sh +41 -124
- package/scripts/tmp-cleanup.mjs +21 -7
- package/scripts/token-snapshot.mjs +204 -85
- package/skills/.omc/state/agent-replay-8f0e10a9-9693-4410-96f5-a6b07e8ed995.jsonl +1 -0
- package/skills/.omc/state/idle-notif-cooldown.json +3 -0
- package/skills/.omc/state/last-tool-error.json +7 -0
- package/skills/.omc/state/subagent-tracking.json +7 -0
- package/skills/_templates/base.md +1 -6
- package/skills/merge-worktree/SKILL.md.tmpl +144 -0
- package/skills/shared/telemetry-segment.md +6 -0
- package/skills/star-prompt/SKILL.md.tmpl +222 -0
- package/skills/tfx-analysis/SKILL.md.tmpl +107 -0
- package/skills/tfx-analysis/skill.json +1 -6
- package/skills/tfx-auto/SKILL.md +1 -0
- package/skills/tfx-auto-codex/SKILL.md.tmpl +106 -0
- package/skills/tfx-auto-codex/skill.json +1 -3
- package/skills/tfx-autopilot/SKILL.md.tmpl +116 -0
- package/skills/tfx-autopilot/skill.json +1 -5
- package/skills/tfx-autoresearch/SKILL.md.tmpl +136 -0
- package/skills/tfx-autoroute/SKILL.md.tmpl +189 -0
- package/skills/tfx-autoroute/skill.json +1 -7
- package/skills/tfx-codex/SKILL.md +1 -0
- package/skills/tfx-codex/skill.json +1 -3
- package/skills/tfx-codex-swarm/SKILL.md.tmpl +16 -0
- package/skills/tfx-codex-swarm/evals/evals.json +1 -1
- package/skills/tfx-codex-swarm/skill.json +1 -4
- package/skills/tfx-codex-swarm-workspace/iteration-1/benchmark.json +54 -12
- package/skills/tfx-codex-swarm-workspace/iteration-1/full-swarm-all-prds/with_skill/grading.json +35 -7
- package/skills/tfx-codex-swarm-workspace/iteration-1/full-swarm-all-prds/without_skill/grading.json +35 -7
- package/skills/tfx-codex-swarm-workspace/iteration-1/implicit-swarm-no-keywords/with_skill/grading.json +25 -5
- package/skills/tfx-codex-swarm-workspace/iteration-1/implicit-swarm-no-keywords/without_skill/grading.json +25 -5
- package/skills/tfx-codex-swarm-workspace/iteration-1/selective-spawn-with-override/with_skill/grading.json +20 -4
- package/skills/tfx-codex-swarm-workspace/iteration-1/selective-spawn-with-override/without_skill/grading.json +16 -4
- package/skills/tfx-consensus/SKILL.md.tmpl +146 -0
- package/skills/tfx-debate/SKILL.md.tmpl +192 -0
- package/skills/tfx-debate/skill.json +1 -7
- package/skills/tfx-deep-analysis/SKILL.md.tmpl +228 -0
- package/skills/tfx-deep-analysis/skill.json +1 -5
- package/skills/tfx-deep-interview/SKILL.md.tmpl +203 -0
- package/skills/tfx-deep-plan/SKILL.md.tmpl +282 -0
- package/skills/tfx-deep-qa/SKILL.md.tmpl +165 -0
- package/skills/tfx-deep-qa/skill.json +1 -6
- package/skills/tfx-deep-research/SKILL.md.tmpl +217 -0
- package/skills/tfx-deep-review/SKILL.md.tmpl +179 -0
- package/skills/tfx-doctor/SKILL.md +21 -0
- package/skills/tfx-doctor/SKILL.md.tmpl +172 -0
- package/skills/tfx-doctor/skill.json +1 -3
- package/skills/tfx-find/SKILL.md +1 -0
- package/skills/tfx-forge/SKILL.md.tmpl +187 -0
- package/skills/tfx-fullcycle/SKILL.md.tmpl +286 -0
- package/skills/tfx-fullcycle/skill.json +1 -6
- package/skills/tfx-gemini/SKILL.md.tmpl +91 -0
- package/skills/tfx-gemini/skill.json +1 -3
- package/skills/tfx-hooks/SKILL.md.tmpl +216 -0
- package/skills/tfx-hooks/skill.json +1 -3
- package/skills/tfx-hub/SKILL.md.tmpl +212 -0
- package/skills/tfx-hub/skill.json +1 -3
- package/skills/tfx-index/SKILL.md +1 -0
- package/skills/tfx-index/skill.json +1 -6
- package/skills/tfx-interview/SKILL.md.tmpl +285 -0
- package/skills/tfx-multi/SKILL.md.tmpl +183 -0
- package/skills/tfx-multi/skill.json +1 -3
- package/skills/tfx-panel/SKILL.md.tmpl +189 -0
- package/skills/tfx-panel/skill.json +1 -7
- package/skills/tfx-persist/SKILL.md.tmpl +270 -0
- package/skills/tfx-persist/skill.json +1 -7
- package/skills/tfx-plan/SKILL.md +1 -0
- package/skills/tfx-plan/skill.json +1 -6
- package/skills/tfx-profile/SKILL.md.tmpl +239 -0
- package/skills/tfx-profile/skill.json +1 -3
- package/skills/tfx-prune/SKILL.md.tmpl +200 -0
- package/skills/tfx-prune/skill.json +1 -7
- package/skills/tfx-psmux-rules/SKILL.md.tmpl +326 -0
- package/skills/tfx-psmux-rules/skill.json +1 -4
- package/skills/tfx-qa/SKILL.md +1 -0
- package/skills/tfx-qa/skill.json +1 -6
- package/skills/tfx-ralph/SKILL.md.tmpl +28 -0
- package/skills/tfx-ralph/skill.json +1 -4
- package/skills/tfx-remote-setup/SKILL.md.tmpl +576 -0
- package/skills/tfx-remote-setup/skill.json +1 -3
- package/skills/tfx-remote-spawn/SKILL.md.tmpl +263 -0
- package/skills/tfx-remote-spawn/references/hosts.json +16 -0
- package/skills/tfx-remote-spawn/skill.json +1 -4
- package/skills/tfx-research/SKILL.md +1 -0
- package/skills/tfx-review/SKILL.md +1 -0
- package/skills/tfx-review/skill.json +1 -6
- package/skills/tfx-setup/SKILL.md.tmpl +504 -0
- package/skills/tfx-setup/skill.json +1 -3
- package/skills/tfx-swarm/SKILL.md +22 -0
- package/skills/tfx-swarm/SKILL.md.tmpl +218 -0
- package/tui/codex-profile.mjs +88 -33
- package/tui/core.mjs +45 -15
- package/tui/doctor.mjs +75 -28
- package/tui/gemini-profile.mjs +74 -29
- package/tui/monitor-data.mjs +8 -4
- package/tui/monitor.mjs +71 -27
- package/tui/setup.mjs +133 -42
package/hub/team/agent-map.json
CHANGED
|
@@ -1,11 +1,26 @@
|
|
|
1
1
|
{
|
|
2
|
-
"executor": "codex",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
"
|
|
2
|
+
"executor": "codex",
|
|
3
|
+
"build-fixer": "codex",
|
|
4
|
+
"debugger": "codex",
|
|
5
|
+
"deep-executor": "codex",
|
|
6
|
+
"architect": "codex",
|
|
7
|
+
"planner": "codex",
|
|
8
|
+
"critic": "codex",
|
|
9
|
+
"analyst": "codex",
|
|
10
|
+
"code-reviewer": "codex",
|
|
11
|
+
"security-reviewer": "codex",
|
|
12
|
+
"quality-reviewer": "codex",
|
|
13
|
+
"scientist": "codex",
|
|
14
|
+
"scientist-deep": "codex",
|
|
15
|
+
"document-specialist": "codex",
|
|
6
16
|
"spark": "codex",
|
|
7
|
-
"designer": "gemini",
|
|
17
|
+
"designer": "gemini",
|
|
18
|
+
"writer": "gemini",
|
|
8
19
|
"explore": "claude",
|
|
9
|
-
"verifier": "codex",
|
|
10
|
-
"
|
|
20
|
+
"verifier": "codex",
|
|
21
|
+
"test-engineer": "codex",
|
|
22
|
+
"qa-tester": "codex",
|
|
23
|
+
"codex": "codex",
|
|
24
|
+
"gemini": "gemini",
|
|
25
|
+
"claude": "claude"
|
|
11
26
|
}
|
package/hub/team/ansi.mjs
CHANGED
|
@@ -7,54 +7,60 @@
|
|
|
7
7
|
export const ESC = "\x1b";
|
|
8
8
|
|
|
9
9
|
// ── 화면 ──
|
|
10
|
-
export const altScreenOn
|
|
10
|
+
export const altScreenOn = `${ESC}[?1049h`;
|
|
11
11
|
export const altScreenOff = `${ESC}[?1049l`;
|
|
12
|
-
export const clearScreen
|
|
13
|
-
export const cursorHome
|
|
14
|
-
export const cursorHide
|
|
15
|
-
export const cursorShow
|
|
12
|
+
export const clearScreen = `${ESC}[2J`;
|
|
13
|
+
export const cursorHome = `${ESC}[H`;
|
|
14
|
+
export const cursorHide = `${ESC}[?25l`;
|
|
15
|
+
export const cursorShow = `${ESC}[?25h`;
|
|
16
16
|
|
|
17
17
|
// ── 커서 이동 ──
|
|
18
|
-
export function moveTo(row, col) {
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
export function moveTo(row, col) {
|
|
19
|
+
return `${ESC}[${row};${col}H`;
|
|
20
|
+
}
|
|
21
|
+
export function moveUp(n = 1) {
|
|
22
|
+
return `${ESC}[${n}A`;
|
|
23
|
+
}
|
|
24
|
+
export function moveDown(n = 1) {
|
|
25
|
+
return `${ESC}[${n}B`;
|
|
26
|
+
}
|
|
21
27
|
|
|
22
28
|
// ── 줄 제어 ──
|
|
23
|
-
export const clearLine
|
|
24
|
-
export const clearToEnd
|
|
25
|
-
export const eraseBelow
|
|
29
|
+
export const clearLine = `${ESC}[2K`;
|
|
30
|
+
export const clearToEnd = `${ESC}[K`;
|
|
31
|
+
export const eraseBelow = `${ESC}[J`;
|
|
26
32
|
|
|
27
33
|
// ── 색상 (triflux 디자인 시스템) ──
|
|
28
34
|
export const RESET = `${ESC}[0m`;
|
|
29
|
-
export const BOLD
|
|
30
|
-
export const DIM
|
|
35
|
+
export const BOLD = `${ESC}[1m`;
|
|
36
|
+
export const DIM = `${ESC}[2m`;
|
|
31
37
|
|
|
32
38
|
export const FG = {
|
|
33
|
-
white:
|
|
34
|
-
black:
|
|
35
|
-
red:
|
|
36
|
-
green:
|
|
37
|
-
yellow:
|
|
38
|
-
blue:
|
|
39
|
-
magenta:
|
|
40
|
-
cyan:
|
|
41
|
-
gray:
|
|
39
|
+
white: `${ESC}[97m`,
|
|
40
|
+
black: `${ESC}[30m`,
|
|
41
|
+
red: `${ESC}[31m`,
|
|
42
|
+
green: `${ESC}[32m`,
|
|
43
|
+
yellow: `${ESC}[33m`,
|
|
44
|
+
blue: `${ESC}[34m`,
|
|
45
|
+
magenta: `${ESC}[35m`,
|
|
46
|
+
cyan: `${ESC}[36m`,
|
|
47
|
+
gray: `${ESC}[90m`,
|
|
42
48
|
// triflux 브랜드
|
|
43
|
-
codex:
|
|
44
|
-
gemini:
|
|
45
|
-
claude:
|
|
46
|
-
triflux:
|
|
47
|
-
accent:
|
|
48
|
-
muted:
|
|
49
|
+
codex: `${ESC}[38;2;16;163;127m`, // #10a37f codex green
|
|
50
|
+
gemini: `${ESC}[38;5;39m`, // blue
|
|
51
|
+
claude: `${ESC}[38;2;232;112;64m`, // orange
|
|
52
|
+
triflux: `${ESC}[38;5;214m`, // amber
|
|
53
|
+
accent: `${ESC}[38;5;75m`, // light blue (Catppuccin blue)
|
|
54
|
+
muted: `${ESC}[38;5;245m`, // gray
|
|
49
55
|
};
|
|
50
56
|
|
|
51
57
|
export const BG = {
|
|
52
|
-
black:
|
|
53
|
-
red:
|
|
54
|
-
green:
|
|
55
|
-
yellow:
|
|
56
|
-
blue:
|
|
57
|
-
header:
|
|
58
|
+
black: `${ESC}[40m`,
|
|
59
|
+
red: `${ESC}[41m`,
|
|
60
|
+
green: `${ESC}[42m`,
|
|
61
|
+
yellow: `${ESC}[43m`,
|
|
62
|
+
blue: `${ESC}[44m`,
|
|
63
|
+
header: `${ESC}[48;5;236m`, // dark gray
|
|
58
64
|
};
|
|
59
65
|
|
|
60
66
|
// ── 색상 헬퍼 ──
|
|
@@ -63,8 +69,12 @@ export function color(text, fg, bg) {
|
|
|
63
69
|
return prefix ? `${prefix}${text}${RESET}` : text;
|
|
64
70
|
}
|
|
65
71
|
|
|
66
|
-
export function bold(text)
|
|
67
|
-
|
|
72
|
+
export function bold(text) {
|
|
73
|
+
return `${BOLD}${text}${RESET}`;
|
|
74
|
+
}
|
|
75
|
+
export function dim(text) {
|
|
76
|
+
return `${DIM}${text}${RESET}`;
|
|
77
|
+
}
|
|
68
78
|
|
|
69
79
|
export function lerpRgb(a, b, t) {
|
|
70
80
|
return {
|
|
@@ -83,9 +93,10 @@ function brightenRgb(rgb, amount = 0.3) {
|
|
|
83
93
|
}
|
|
84
94
|
|
|
85
95
|
function parseRgbSeq(seq) {
|
|
86
|
-
const match =
|
|
87
|
-
|
|
88
|
-
|
|
96
|
+
const match =
|
|
97
|
+
typeof seq === "string"
|
|
98
|
+
? seq.match(/\x1b\[(?:38|48);2;(\d+);(\d+);(\d+)m/)
|
|
99
|
+
: null;
|
|
89
100
|
if (!match) return null;
|
|
90
101
|
return {
|
|
91
102
|
r: Number.parseInt(match[1], 10),
|
|
@@ -100,7 +111,16 @@ function reapplyBackground(text, bgSeq) {
|
|
|
100
111
|
}
|
|
101
112
|
|
|
102
113
|
// ── 박스 그리기 (유니코드 테두리) ──
|
|
103
|
-
const BOX = {
|
|
114
|
+
const BOX = {
|
|
115
|
+
tl: "┌",
|
|
116
|
+
tr: "┐",
|
|
117
|
+
bl: "└",
|
|
118
|
+
br: "┘",
|
|
119
|
+
h: "─",
|
|
120
|
+
v: "│",
|
|
121
|
+
ml: "├",
|
|
122
|
+
mr: "┤",
|
|
123
|
+
};
|
|
104
124
|
|
|
105
125
|
function borderHighlightCell(width, totalRows, highlightPos) {
|
|
106
126
|
if (!Number.isFinite(highlightPos)) return null;
|
|
@@ -118,7 +138,14 @@ function borderHighlightCell(width, totalRows, highlightPos) {
|
|
|
118
138
|
return { row: totalRows - 1 - pos, col: 0 };
|
|
119
139
|
}
|
|
120
140
|
|
|
121
|
-
function renderBorderChar(
|
|
141
|
+
function renderBorderChar(
|
|
142
|
+
glyph,
|
|
143
|
+
row,
|
|
144
|
+
col,
|
|
145
|
+
highlightCell,
|
|
146
|
+
borderSeq,
|
|
147
|
+
highlightSeq,
|
|
148
|
+
) {
|
|
122
149
|
if (highlightCell && highlightCell.row === row && highlightCell.col === col) {
|
|
123
150
|
return `${highlightSeq}${glyph}${RESET}`;
|
|
124
151
|
}
|
|
@@ -128,7 +155,11 @@ function renderBorderChar(glyph, row, col, highlightCell, borderSeq, highlightSe
|
|
|
128
155
|
export function box(lines, width, borderColor = "", options = {}) {
|
|
129
156
|
const isFn = typeof borderColor === "function";
|
|
130
157
|
const totalRows = lines.length + 2;
|
|
131
|
-
const highlightCell = borderHighlightCell(
|
|
158
|
+
const highlightCell = borderHighlightCell(
|
|
159
|
+
width,
|
|
160
|
+
totalRows,
|
|
161
|
+
options.highlightPos,
|
|
162
|
+
);
|
|
132
163
|
|
|
133
164
|
// Fast path: static border, no highlight — batch border chars (~13x less output)
|
|
134
165
|
if (!highlightCell && !isFn) {
|
|
@@ -139,9 +170,10 @@ export function box(lines, width, borderColor = "", options = {}) {
|
|
|
139
170
|
const bot = `${bc}${BOX.bl}${hLine}${BOX.br}${rst}`;
|
|
140
171
|
const mid = `${bc}${BOX.ml}${hLine}${BOX.mr}${rst}`;
|
|
141
172
|
const body = lines.map((l, i) => {
|
|
142
|
-
const content =
|
|
143
|
-
|
|
144
|
-
|
|
173
|
+
const content =
|
|
174
|
+
options.titleFlashBg && i === 0
|
|
175
|
+
? reapplyBackground(padRight(l, width - 4), options.titleFlashBg)
|
|
176
|
+
: padRight(l, width - 4);
|
|
145
177
|
return `${bc}${BOX.v}${rst} ${content} ${bc}${BOX.v}${rst}`;
|
|
146
178
|
});
|
|
147
179
|
return { top, body, bot, mid };
|
|
@@ -149,26 +181,49 @@ export function box(lines, width, borderColor = "", options = {}) {
|
|
|
149
181
|
|
|
150
182
|
// Slow path: per-character rendering for highlight animation
|
|
151
183
|
const bc = isFn ? (row) => borderColor(row, totalRows) : () => borderColor;
|
|
152
|
-
const rst =
|
|
153
|
-
const highlightSeq =
|
|
154
|
-
||
|
|
155
|
-
|
|
184
|
+
const rst = isFn || borderColor ? RESET : "";
|
|
185
|
+
const highlightSeq =
|
|
186
|
+
options.highlightColor ||
|
|
187
|
+
(() => {
|
|
188
|
+
const parsed = parseRgbSeq(
|
|
189
|
+
typeof borderColor === "string" ? borderColor : "",
|
|
190
|
+
);
|
|
156
191
|
return parsed ? rgbSeq(brightenRgb(parsed, 0.45)) : `${BOLD}${FG.white}`;
|
|
157
192
|
})();
|
|
158
|
-
const topChars = [
|
|
159
|
-
|
|
193
|
+
const topChars = [
|
|
194
|
+
BOX.tl,
|
|
195
|
+
...Array.from({ length: width - 2 }, () => BOX.h),
|
|
196
|
+
BOX.tr,
|
|
197
|
+
];
|
|
198
|
+
const botChars = [
|
|
199
|
+
BOX.bl,
|
|
200
|
+
...Array.from({ length: width - 2 }, () => BOX.h),
|
|
201
|
+
BOX.br,
|
|
202
|
+
];
|
|
160
203
|
const top = topChars
|
|
161
|
-
.map((glyph, col) =>
|
|
204
|
+
.map((glyph, col) =>
|
|
205
|
+
renderBorderChar(glyph, 0, col, highlightCell, bc(0), highlightSeq),
|
|
206
|
+
)
|
|
162
207
|
.join("");
|
|
163
208
|
const bot = botChars
|
|
164
|
-
.map((glyph, col) =>
|
|
209
|
+
.map((glyph, col) =>
|
|
210
|
+
renderBorderChar(
|
|
211
|
+
glyph,
|
|
212
|
+
totalRows - 1,
|
|
213
|
+
col,
|
|
214
|
+
highlightCell,
|
|
215
|
+
bc(totalRows - 1),
|
|
216
|
+
highlightSeq,
|
|
217
|
+
),
|
|
218
|
+
)
|
|
165
219
|
.join("");
|
|
166
220
|
const mid = `${bc(Math.floor(totalRows / 2))}${BOX.ml}${BOX.h.repeat(Math.max(0, width - 2))}${BOX.mr}${rst}`;
|
|
167
221
|
const body = lines.map((l, i) => {
|
|
168
222
|
const row = i + 1;
|
|
169
|
-
const content =
|
|
170
|
-
|
|
171
|
-
|
|
223
|
+
const content =
|
|
224
|
+
options.titleFlashBg && i === 0
|
|
225
|
+
? reapplyBackground(padRight(l, width - 4), options.titleFlashBg)
|
|
226
|
+
: padRight(l, width - 4);
|
|
172
227
|
return `${renderBorderChar(BOX.v, row, 0, highlightCell, bc(row), highlightSeq)} ${content} ${renderBorderChar(BOX.v, row, width - 1, highlightCell, bc(row), highlightSeq)}`;
|
|
173
228
|
});
|
|
174
229
|
return { top, body, bot, mid };
|
|
@@ -179,50 +234,53 @@ export function box(lines, width, borderColor = "", options = {}) {
|
|
|
179
234
|
function charWidth(cp) {
|
|
180
235
|
// combining / zero-width 범위
|
|
181
236
|
if (
|
|
182
|
-
cp === 0 ||
|
|
183
|
-
|
|
184
|
-
(cp >=
|
|
185
|
-
(cp >=
|
|
186
|
-
(cp >=
|
|
187
|
-
(cp >=
|
|
188
|
-
(cp >=
|
|
189
|
-
(cp >=
|
|
190
|
-
|
|
237
|
+
cp === 0 ||
|
|
238
|
+
cp === 0xad ||
|
|
239
|
+
(cp >= 0x0300 && cp <= 0x036f) || // Combining Diacritical Marks
|
|
240
|
+
(cp >= 0x0610 && cp <= 0x061a) ||
|
|
241
|
+
(cp >= 0x064b && cp <= 0x065f) ||
|
|
242
|
+
(cp >= 0x1ab0 && cp <= 0x1aff) ||
|
|
243
|
+
(cp >= 0x1dc0 && cp <= 0x1dff) ||
|
|
244
|
+
(cp >= 0x20d0 && cp <= 0x20ff) || // Combining Diacritical Marks for Symbols
|
|
245
|
+
(cp >= 0xfe20 && cp <= 0xfe2f) // Combining Half Marks
|
|
246
|
+
)
|
|
247
|
+
return 0;
|
|
191
248
|
|
|
192
249
|
// Wide: CJK Unified Ideographs, Hangul, Fullwidth, emoji 주요 블록
|
|
193
250
|
if (
|
|
194
|
-
(cp >= 0x1100 && cp <=
|
|
195
|
-
(cp >=
|
|
196
|
-
(cp >=
|
|
197
|
-
(cp >= 0x3000 && cp <=
|
|
198
|
-
(cp >= 0x3040 && cp <=
|
|
199
|
-
(cp >=
|
|
200
|
-
(cp >= 0x3100 && cp <=
|
|
201
|
-
(cp >= 0x3130 && cp <=
|
|
202
|
-
(cp >= 0x3190 && cp <=
|
|
203
|
-
(cp >=
|
|
204
|
-
(cp >= 0x3200 && cp <=
|
|
205
|
-
(cp >= 0x3300 && cp <=
|
|
206
|
-
(cp >= 0x3400 && cp <=
|
|
207
|
-
(cp >=
|
|
208
|
-
(cp >=
|
|
209
|
-
(cp >=
|
|
210
|
-
(cp >=
|
|
211
|
-
(cp >=
|
|
212
|
-
(cp >=
|
|
213
|
-
(cp >=
|
|
214
|
-
(cp >=
|
|
215
|
-
(cp >=
|
|
216
|
-
(cp >=
|
|
217
|
-
(cp >=
|
|
218
|
-
(cp >=
|
|
219
|
-
(cp >=
|
|
220
|
-
(cp >=
|
|
221
|
-
(cp >=
|
|
222
|
-
(cp >=
|
|
223
|
-
(cp >= 0x20000 && cp <=
|
|
224
|
-
(cp >= 0x30000 && cp <=
|
|
225
|
-
)
|
|
251
|
+
(cp >= 0x1100 && cp <= 0x115f) || // Hangul Jamo
|
|
252
|
+
(cp >= 0x2e80 && cp <= 0x2eff) || // CJK Radicals Supplement
|
|
253
|
+
(cp >= 0x2f00 && cp <= 0x2fff) ||
|
|
254
|
+
(cp >= 0x3000 && cp <= 0x303f) || // CJK Symbols and Punctuation
|
|
255
|
+
(cp >= 0x3040 && cp <= 0x309f) || // Hiragana
|
|
256
|
+
(cp >= 0x30a0 && cp <= 0x30ff) || // Katakana
|
|
257
|
+
(cp >= 0x3100 && cp <= 0x312f) ||
|
|
258
|
+
(cp >= 0x3130 && cp <= 0x318f) || // Hangul Compatibility Jamo
|
|
259
|
+
(cp >= 0x3190 && cp <= 0x319f) ||
|
|
260
|
+
(cp >= 0x31c0 && cp <= 0x31ef) ||
|
|
261
|
+
(cp >= 0x3200 && cp <= 0x32ff) ||
|
|
262
|
+
(cp >= 0x3300 && cp <= 0x33ff) ||
|
|
263
|
+
(cp >= 0x3400 && cp <= 0x4dbf) ||
|
|
264
|
+
(cp >= 0x4e00 && cp <= 0x9fff) || // CJK Unified Ideographs
|
|
265
|
+
(cp >= 0xa000 && cp <= 0xa48f) ||
|
|
266
|
+
(cp >= 0xa490 && cp <= 0xa4cf) ||
|
|
267
|
+
(cp >= 0xa960 && cp <= 0xa97f) ||
|
|
268
|
+
(cp >= 0xac00 && cp <= 0xd7af) || // Hangul Syllables
|
|
269
|
+
(cp >= 0xf900 && cp <= 0xfaff) || // CJK Compatibility Ideographs
|
|
270
|
+
(cp >= 0xfe10 && cp <= 0xfe1f) ||
|
|
271
|
+
(cp >= 0xfe30 && cp <= 0xfe4f) ||
|
|
272
|
+
(cp >= 0xff00 && cp <= 0xff60) || // Fullwidth Forms
|
|
273
|
+
(cp >= 0xffe0 && cp <= 0xffe6) ||
|
|
274
|
+
(cp >= 0x1b000 && cp <= 0x1b0ff) ||
|
|
275
|
+
(cp >= 0x1f004 && cp <= 0x1f0cf) ||
|
|
276
|
+
(cp >= 0x1f200 && cp <= 0x1f2ff) ||
|
|
277
|
+
(cp >= 0x1f300 && cp <= 0x1f64f) || // Misc Symbols, Emoticons
|
|
278
|
+
(cp >= 0x1f680 && cp <= 0x1f6ff) || // Transport & Map
|
|
279
|
+
(cp >= 0x1f900 && cp <= 0x1faff) || // Supplemental Symbols
|
|
280
|
+
(cp >= 0x20000 && cp <= 0x2fffd) ||
|
|
281
|
+
(cp >= 0x30000 && cp <= 0x3fffd)
|
|
282
|
+
)
|
|
283
|
+
return 2;
|
|
226
284
|
|
|
227
285
|
return 1;
|
|
228
286
|
}
|
|
@@ -257,7 +315,7 @@ function ansiSlice(str, maxWidth) {
|
|
|
257
315
|
let i = 0;
|
|
258
316
|
|
|
259
317
|
while (i < str.length) {
|
|
260
|
-
if (str.charCodeAt(i) ===
|
|
318
|
+
if (str.charCodeAt(i) === 0x1b) {
|
|
261
319
|
const rest = str.slice(i);
|
|
262
320
|
const m = rest.match(/^(\x1b(?:\[[0-9;]*[a-zA-Z]|\].*?(?:\x07|\x1b\\)))/);
|
|
263
321
|
if (m) {
|
|
@@ -269,7 +327,7 @@ function ansiSlice(str, maxWidth) {
|
|
|
269
327
|
}
|
|
270
328
|
|
|
271
329
|
const cp = str.codePointAt(i);
|
|
272
|
-
const charLen = cp >
|
|
330
|
+
const charLen = cp > 0xffff ? 2 : 1;
|
|
273
331
|
const cw = charWidth(cp);
|
|
274
332
|
|
|
275
333
|
if (visWidth + cw > maxWidth) break;
|
|
@@ -302,25 +360,25 @@ export function clip(str, width) {
|
|
|
302
360
|
|
|
303
361
|
// ── Catppuccin Mocha 색상 상수 ──
|
|
304
362
|
export const MOCHA = {
|
|
305
|
-
ok:
|
|
306
|
-
partial:
|
|
307
|
-
fail:
|
|
308
|
-
thinking:
|
|
309
|
-
executing: `${ESC}[38;5;117m`,
|
|
310
|
-
border:
|
|
311
|
-
text:
|
|
312
|
-
subtext:
|
|
313
|
-
overlay:
|
|
314
|
-
blue:
|
|
315
|
-
yellow:
|
|
316
|
-
red:
|
|
317
|
-
surface0:
|
|
363
|
+
ok: `${ESC}[38;5;114m`, // #a6e3a1 green
|
|
364
|
+
partial: `${ESC}[38;5;216m`, // #fab387 peach
|
|
365
|
+
fail: `${ESC}[38;5;210m`, // #f38ba8 red
|
|
366
|
+
thinking: `${ESC}[38;5;183m`, // #cba6f7 mauve
|
|
367
|
+
executing: `${ESC}[38;5;117m`, // #74c7ec sky
|
|
368
|
+
border: `${ESC}[38;5;238m`, // #45475a surface1
|
|
369
|
+
text: `${ESC}[38;2;205;214;244m`, // #cdd6f4 catppuccin text
|
|
370
|
+
subtext: `${ESC}[38;2;166;173;200m`, // #a6adc8 subtext0
|
|
371
|
+
overlay: `${ESC}[38;2;108;112;134m`, // #6c7086 overlay0
|
|
372
|
+
blue: `${ESC}[38;2;137;180;250m`, // #89b4fa blue
|
|
373
|
+
yellow: `${ESC}[38;2;249;226;175m`, // #f9e2af yellow
|
|
374
|
+
red: `${ESC}[38;2;243;139;168m`, // #f38ba8 red (truecolor)
|
|
375
|
+
surface0: `${ESC}[38;2;49;50;68m`, // #313244 surface0
|
|
318
376
|
};
|
|
319
377
|
|
|
320
378
|
const MOCHA_RGB = {
|
|
321
|
-
ok:
|
|
322
|
-
partial:
|
|
323
|
-
fail:
|
|
379
|
+
ok: { r: 166, g: 227, b: 161 },
|
|
380
|
+
partial: { r: 250, g: 179, b: 135 },
|
|
381
|
+
fail: { r: 243, g: 139, b: 168 },
|
|
324
382
|
};
|
|
325
383
|
|
|
326
384
|
// ── badge 헬퍼 ──
|
|
@@ -354,7 +412,12 @@ export function progressBar(percent, width = 20, time) {
|
|
|
354
412
|
const ratio = Math.max(0, Math.min(100, percent)) / 100;
|
|
355
413
|
const filled = Math.round(ratio * width);
|
|
356
414
|
const empty = width - filled;
|
|
357
|
-
const fillRgb =
|
|
415
|
+
const fillRgb =
|
|
416
|
+
percent >= 100
|
|
417
|
+
? MOCHA_RGB.ok
|
|
418
|
+
: percent >= 50
|
|
419
|
+
? MOCHA_RGB.partial
|
|
420
|
+
: MOCHA_RGB.fail;
|
|
358
421
|
const fillColor = rgbSeq(fillRgb);
|
|
359
422
|
let fillText = "█".repeat(filled);
|
|
360
423
|
|
|
@@ -365,13 +428,14 @@ export function progressBar(percent, width = 20, time) {
|
|
|
365
428
|
);
|
|
366
429
|
const shineColor = rgbSeq(brightenRgb(fillRgb, 0.3));
|
|
367
430
|
fillText = Array.from({ length: filled }, (_, idx) =>
|
|
368
|
-
idx === shinePos ? `${shineColor}█${RESET}` : `${fillColor}█${RESET}
|
|
431
|
+
idx === shinePos ? `${shineColor}█${RESET}` : `${fillColor}█${RESET}`,
|
|
369
432
|
).join("");
|
|
370
433
|
} else if (filled > 0) {
|
|
371
434
|
fillText = `${fillColor}${fillText}${RESET}`;
|
|
372
435
|
}
|
|
373
436
|
|
|
374
|
-
const emptyText =
|
|
437
|
+
const emptyText =
|
|
438
|
+
empty > 0 ? `${MOCHA.border}${"░".repeat(empty)}${RESET}` : "";
|
|
375
439
|
return `${fillText}${emptyText}`;
|
|
376
440
|
}
|
|
377
441
|
|
|
@@ -395,14 +459,14 @@ export function animatedProgressBar(percent, width = 20, tick = 0) {
|
|
|
395
459
|
|
|
396
460
|
// ── 상태 아이콘 ──
|
|
397
461
|
export const STATUS_ICON = {
|
|
398
|
-
running:
|
|
462
|
+
running: `${MOCHA.partial}⏳${RESET}`,
|
|
399
463
|
completed: `${MOCHA.ok}✓${RESET}`,
|
|
400
|
-
failed:
|
|
401
|
-
pending:
|
|
464
|
+
failed: `${MOCHA.fail}✗${RESET}`,
|
|
465
|
+
pending: `${FG.gray}⏸${RESET}`,
|
|
402
466
|
};
|
|
403
467
|
|
|
404
468
|
export const CLI_ICON = {
|
|
405
|
-
codex:
|
|
469
|
+
codex: `${FG.codex}⚪${RESET}`,
|
|
406
470
|
gemini: `${FG.gemini}🔵${RESET}`,
|
|
407
471
|
claude: `${FG.claude}🟠${RESET}`,
|
|
408
472
|
};
|
package/hub/team/backend.mjs
CHANGED
|
@@ -10,8 +10,12 @@ const _require = createRequire(import.meta.url);
|
|
|
10
10
|
// ── 백엔드 클래스 ──────────────────────────────────────────────────────────
|
|
11
11
|
|
|
12
12
|
export class CodexBackend {
|
|
13
|
-
name() {
|
|
14
|
-
|
|
13
|
+
name() {
|
|
14
|
+
return "codex";
|
|
15
|
+
}
|
|
16
|
+
command() {
|
|
17
|
+
return "codex";
|
|
18
|
+
}
|
|
15
19
|
|
|
16
20
|
/**
|
|
17
21
|
* @param {string} prompt — 프롬프트 (프롬프트 파일 경로가 아닌 PowerShell 표현식)
|
|
@@ -23,36 +27,50 @@ export class CodexBackend {
|
|
|
23
27
|
return buildExecArgs({ prompt, resultFile, ...opts });
|
|
24
28
|
}
|
|
25
29
|
|
|
26
|
-
env() {
|
|
30
|
+
env() {
|
|
31
|
+
return {};
|
|
32
|
+
}
|
|
27
33
|
}
|
|
28
34
|
|
|
29
35
|
export class GeminiBackend {
|
|
30
|
-
name() {
|
|
31
|
-
|
|
36
|
+
name() {
|
|
37
|
+
return "gemini";
|
|
38
|
+
}
|
|
39
|
+
command() {
|
|
40
|
+
return "gemini";
|
|
41
|
+
}
|
|
32
42
|
|
|
33
43
|
buildArgs(prompt, resultFile, opts = {}) {
|
|
34
44
|
return `gemini --prompt ${prompt} --output-format text > '${resultFile}' 2>'${resultFile}.err'`;
|
|
35
45
|
}
|
|
36
46
|
|
|
37
|
-
env() {
|
|
47
|
+
env() {
|
|
48
|
+
return {};
|
|
49
|
+
}
|
|
38
50
|
}
|
|
39
51
|
|
|
40
52
|
export class ClaudeBackend {
|
|
41
|
-
name() {
|
|
42
|
-
|
|
53
|
+
name() {
|
|
54
|
+
return "claude";
|
|
55
|
+
}
|
|
56
|
+
command() {
|
|
57
|
+
return "claude";
|
|
58
|
+
}
|
|
43
59
|
|
|
44
60
|
buildArgs(prompt, resultFile, opts = {}) {
|
|
45
61
|
return `claude --print ${prompt} --output-format text > '${resultFile}' 2>&1`;
|
|
46
62
|
}
|
|
47
63
|
|
|
48
|
-
env() {
|
|
64
|
+
env() {
|
|
65
|
+
return {};
|
|
66
|
+
}
|
|
49
67
|
}
|
|
50
68
|
|
|
51
69
|
// ── 레지스트리 ─────────────────────────────────────────────────────────────
|
|
52
70
|
|
|
53
71
|
/** @type {Map<string, CodexBackend|GeminiBackend|ClaudeBackend>} */
|
|
54
72
|
const backends = new Map([
|
|
55
|
-
["codex",
|
|
73
|
+
["codex", new CodexBackend()],
|
|
56
74
|
["gemini", new GeminiBackend()],
|
|
57
75
|
["claude", new ClaudeBackend()],
|
|
58
76
|
]);
|
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
import { attachSession } from "../../session.mjs";
|
|
2
2
|
import { DIM, RESET } from "../../shared.mjs";
|
|
3
|
-
import { buildManualAttachCommand, launchAttachInWindowsTerminal, wantsWtAttachFallback } from "../services/attach-fallback.mjs";
|
|
4
|
-
import { isNativeMode, isTeamAlive, isWtMode } from "../services/runtime-mode.mjs";
|
|
5
|
-
import { loadTeamState } from "../services/state-store.mjs";
|
|
6
3
|
import { fail, ok, warn } from "../render.mjs";
|
|
4
|
+
import {
|
|
5
|
+
buildManualAttachCommand,
|
|
6
|
+
launchAttachInWindowsTerminal,
|
|
7
|
+
wantsWtAttachFallback,
|
|
8
|
+
} from "../services/attach-fallback.mjs";
|
|
9
|
+
import {
|
|
10
|
+
isNativeMode,
|
|
11
|
+
isTeamAlive,
|
|
12
|
+
isWtMode,
|
|
13
|
+
} from "../services/runtime-mode.mjs";
|
|
14
|
+
import { loadTeamState } from "../services/state-store.mjs";
|
|
7
15
|
|
|
8
16
|
export async function teamAttach(args = []) {
|
|
9
17
|
const state = loadTeamState();
|
|
@@ -12,11 +20,15 @@ export async function teamAttach(args = []) {
|
|
|
12
20
|
return;
|
|
13
21
|
}
|
|
14
22
|
if (isNativeMode(state)) {
|
|
15
|
-
console.log(
|
|
23
|
+
console.log(
|
|
24
|
+
`\n ${DIM}in-process 모드는 별도 attach가 없습니다.${RESET}\n ${DIM}상태 확인: tfx multi status${RESET}\n`,
|
|
25
|
+
);
|
|
16
26
|
return;
|
|
17
27
|
}
|
|
18
28
|
if (isWtMode(state)) {
|
|
19
|
-
console.log(
|
|
29
|
+
console.log(
|
|
30
|
+
`\n ${DIM}wt 모드는 attach 개념이 없습니다 (Windows Terminal pane가 독립 실행됨).${RESET}\n ${DIM}재실행/정리는: tfx multi stop${RESET}\n`,
|
|
31
|
+
);
|
|
20
32
|
return;
|
|
21
33
|
}
|
|
22
34
|
|
|
@@ -24,14 +36,22 @@ export async function teamAttach(args = []) {
|
|
|
24
36
|
attachSession(state.sessionName);
|
|
25
37
|
} catch (error) {
|
|
26
38
|
const allowWt = wantsWtAttachFallback(args);
|
|
27
|
-
if (allowWt && await launchAttachInWindowsTerminal(state.sessionName)) {
|
|
39
|
+
if (allowWt && (await launchAttachInWindowsTerminal(state.sessionName))) {
|
|
28
40
|
warn(`현재 터미널에서 attach 실패: ${error.message}`);
|
|
29
41
|
ok("Windows Terminal split-pane로 attach 재시도 창을 열었습니다.");
|
|
30
|
-
console.log(
|
|
42
|
+
console.log(
|
|
43
|
+
` ${DIM}수동 attach 명령: ${buildManualAttachCommand(state.sessionName)}${RESET}\n`,
|
|
44
|
+
);
|
|
31
45
|
return;
|
|
32
46
|
}
|
|
33
47
|
fail(`attach 실패: ${error.message}`);
|
|
34
|
-
warn(
|
|
35
|
-
|
|
48
|
+
warn(
|
|
49
|
+
allowWt
|
|
50
|
+
? "WT 분할창 attach 자동 검증 실패 (session_attached 증가 없음)"
|
|
51
|
+
: "자동 WT 분할은 기본 비활성입니다. 필요 시 --wt 옵션으로 실행하세요.",
|
|
52
|
+
);
|
|
53
|
+
console.log(
|
|
54
|
+
` ${DIM}수동 attach 명령: ${buildManualAttachCommand(state.sessionName)}${RESET}\n`,
|
|
55
|
+
);
|
|
36
56
|
}
|
|
37
57
|
}
|