triflux 10.9.14 → 10.9.15
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/.claude-plugin/marketplace.json +34 -0
- package/.claude-plugin/plugin.json +22 -0
- package/config/mcp-registry.json +29 -0
- package/hub/server.mjs +41 -0
- package/hub/team/conductor.mjs +69 -26
- package/hub/team/synapse-registry.mjs +4 -2
- package/package.json +56 -21
- package/scripts/tfx-route.sh +8 -11
- package/tui/codex-profile.mjs +457 -0
- package/tui/core.mjs +266 -0
- package/tui/doctor.mjs +375 -0
- package/tui/gemini-profile.mjs +299 -0
- package/tui/monitor-data.mjs +152 -0
- package/tui/monitor.mjs +339 -0
- package/tui/setup.mjs +598 -0
- package/CLAUDE.md +0 -212
- package/references/hosts.json +0 -46
- package/skills/tfx-workspace/async-tests/run-tests.sh +0 -203
- package/skills/tfx-workspace/evals/evals.json +0 -79
- package/skills/tfx-workspace/iteration-1/benchmark.json +0 -524
- package/skills/tfx-workspace/iteration-1/codex-gemini-remap/eval_metadata.json +0 -11
- package/skills/tfx-workspace/iteration-1/codex-gemini-remap/old_skill/grading.json +0 -25
- package/skills/tfx-workspace/iteration-1/codex-gemini-remap/old_skill/outputs/analysis.md +0 -154
- package/skills/tfx-workspace/iteration-1/codex-gemini-remap/old_skill/timing.json +0 -5
- package/skills/tfx-workspace/iteration-1/codex-gemini-remap/with_skill/grading.json +0 -25
- package/skills/tfx-workspace/iteration-1/codex-gemini-remap/with_skill/outputs/analysis.md +0 -126
- package/skills/tfx-workspace/iteration-1/codex-gemini-remap/with_skill/timing.json +0 -5
- package/skills/tfx-workspace/iteration-1/doctor-diagnosis/eval_metadata.json +0 -11
- package/skills/tfx-workspace/iteration-1/doctor-diagnosis/old_skill/grading.json +0 -25
- package/skills/tfx-workspace/iteration-1/doctor-diagnosis/old_skill/outputs/analysis.md +0 -119
- package/skills/tfx-workspace/iteration-1/doctor-diagnosis/old_skill/timing.json +0 -5
- package/skills/tfx-workspace/iteration-1/doctor-diagnosis/with_skill/grading.json +0 -25
- package/skills/tfx-workspace/iteration-1/doctor-diagnosis/with_skill/outputs/analysis.md +0 -115
- package/skills/tfx-workspace/iteration-1/doctor-diagnosis/with_skill/timing.json +0 -5
- package/skills/tfx-workspace/iteration-1/hub-start-sequence/eval_metadata.json +0 -10
- package/skills/tfx-workspace/iteration-1/hub-start-sequence/old_skill/grading.json +0 -20
- package/skills/tfx-workspace/iteration-1/hub-start-sequence/old_skill/outputs/analysis.md +0 -86
- package/skills/tfx-workspace/iteration-1/hub-start-sequence/old_skill/timing.json +0 -5
- package/skills/tfx-workspace/iteration-1/hub-start-sequence/with_skill/grading.json +0 -20
- package/skills/tfx-workspace/iteration-1/hub-start-sequence/with_skill/outputs/analysis.md +0 -81
- package/skills/tfx-workspace/iteration-1/hub-start-sequence/with_skill/timing.json +0 -5
- package/skills/tfx-workspace/iteration-1/multi-team-creation/eval_metadata.json +0 -12
- package/skills/tfx-workspace/iteration-1/multi-team-creation/old_skill/grading.json +0 -30
- package/skills/tfx-workspace/iteration-1/multi-team-creation/old_skill/outputs/analysis.md +0 -316
- package/skills/tfx-workspace/iteration-1/multi-team-creation/old_skill/timing.json +0 -5
- package/skills/tfx-workspace/iteration-1/multi-team-creation/with_skill/grading.json +0 -30
- package/skills/tfx-workspace/iteration-1/multi-team-creation/with_skill/outputs/analysis.md +0 -352
- package/skills/tfx-workspace/iteration-1/multi-team-creation/with_skill/timing.json +0 -5
- package/skills/tfx-workspace/iteration-1/review.html +0 -1325
- package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/eval_metadata.json +0 -12
- package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/old_skill/grading.json +0 -30
- package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/old_skill/outputs/analysis.md +0 -97
- package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/old_skill/timing.json +0 -5
- package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/with_skill/grading.json +0 -30
- package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/with_skill/outputs/analysis.md +0 -94
- package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/with_skill/timing.json +0 -5
- package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/eval_metadata.json +0 -12
- package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/old_skill/grading.json +0 -30
- package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/old_skill/outputs/analysis.md +0 -209
- package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/old_skill/timing.json +0 -5
- package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/with_skill/grading.json +0 -30
- package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/with_skill/outputs/analysis.md +0 -193
- package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/with_skill/timing.json +0 -5
- package/skills/tfx-workspace/iteration-2/benchmark.json +0 -144
- package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/eval_metadata.json +0 -13
- package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/old_skill/grading.json +0 -35
- package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/old_skill/outputs/analysis.md +0 -382
- package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/old_skill/timing.json +0 -5
- package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/with_skill/grading.json +0 -35
- package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/with_skill/outputs/analysis.md +0 -333
- package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/with_skill/timing.json +0 -5
- package/skills/tfx-workspace/iteration-2/review.html +0 -1325
- package/skills/tfx-workspace/skill-snapshot/tfx-auto/SKILL.md +0 -217
- package/skills/tfx-workspace/skill-snapshot/tfx-auto-codex/SKILL.md +0 -77
- package/skills/tfx-workspace/skill-snapshot/tfx-codex/SKILL.md +0 -65
- package/skills/tfx-workspace/skill-snapshot/tfx-doctor/SKILL.md +0 -94
- package/skills/tfx-workspace/skill-snapshot/tfx-gemini/SKILL.md +0 -82
- package/skills/tfx-workspace/skill-snapshot/tfx-hub/SKILL.md +0 -133
- package/skills/tfx-workspace/skill-snapshot/tfx-multi/SKILL.md +0 -426
- package/skills/tfx-workspace/skill-snapshot/tfx-setup/SKILL.md +0 -101
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
|
|
3
|
+
"name": "triflux",
|
|
4
|
+
"description": "CLI-first multi-model orchestrator — Codex/Gemini/Claude routing with DAG execution, auto-triage, and cost optimization",
|
|
5
|
+
"owner": {
|
|
6
|
+
"name": "tellang"
|
|
7
|
+
},
|
|
8
|
+
"plugins": [
|
|
9
|
+
{
|
|
10
|
+
"name": "triflux",
|
|
11
|
+
"description": "Tri-CLI orchestrator for Claude Code. Routes tasks across Claude + Codex + Gemini with consensus intelligence, natural language routing, 42 skills, and cross-model review.",
|
|
12
|
+
"version": "10.9.6",
|
|
13
|
+
"author": {
|
|
14
|
+
"name": "tellang"
|
|
15
|
+
},
|
|
16
|
+
"source": {
|
|
17
|
+
"source": "npm",
|
|
18
|
+
"package": "triflux"
|
|
19
|
+
},
|
|
20
|
+
"category": "productivity",
|
|
21
|
+
"homepage": "https://github.com/tellang/triflux",
|
|
22
|
+
"tags": [
|
|
23
|
+
"multi-model",
|
|
24
|
+
"codex",
|
|
25
|
+
"gemini",
|
|
26
|
+
"cli-routing",
|
|
27
|
+
"orchestration",
|
|
28
|
+
"cost-optimization",
|
|
29
|
+
"dag-execution"
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
],
|
|
33
|
+
"version": "10.9.14"
|
|
34
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "triflux",
|
|
3
|
+
"version": "10.3.4",
|
|
4
|
+
"description": "CLI-first multi-model orchestrator for Claude Code — route tasks to Codex, Gemini, and Claude",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "tellang"
|
|
7
|
+
},
|
|
8
|
+
"repository": "https://github.com/tellang/triflux",
|
|
9
|
+
"homepage": "https://github.com/tellang/triflux",
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"keywords": [
|
|
12
|
+
"claude-code",
|
|
13
|
+
"plugin",
|
|
14
|
+
"codex",
|
|
15
|
+
"gemini",
|
|
16
|
+
"cli-routing",
|
|
17
|
+
"orchestration",
|
|
18
|
+
"multi-model"
|
|
19
|
+
],
|
|
20
|
+
"skills": "./skills/",
|
|
21
|
+
"hooks": "./hooks/hooks.json"
|
|
22
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "mcp-registry-schema",
|
|
3
|
+
"version": 1,
|
|
4
|
+
"description": "MCP 서버 중앙 레지스트리 — 진실의 원천",
|
|
5
|
+
"defaults": {
|
|
6
|
+
"transport": "hub-url",
|
|
7
|
+
"hub_base": "http://127.0.0.1:27888"
|
|
8
|
+
},
|
|
9
|
+
"servers": {
|
|
10
|
+
"tfx-hub": {
|
|
11
|
+
"transport": "hub-url",
|
|
12
|
+
"url": "http://127.0.0.1:27888/mcp",
|
|
13
|
+
"safe": true,
|
|
14
|
+
"targets": ["claude", "gemini", "codex"],
|
|
15
|
+
"description": "triflux Hub MCP 서버"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"policies": {
|
|
19
|
+
"stdio_action": "replace-with-hub",
|
|
20
|
+
"unknown_server_action": "warn",
|
|
21
|
+
"watched_paths": [
|
|
22
|
+
"~/.gemini/settings.json",
|
|
23
|
+
"~/.codex/config.toml",
|
|
24
|
+
"~/.claude/settings.json",
|
|
25
|
+
"~/.claude/settings.local.json",
|
|
26
|
+
".mcp.json"
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
}
|
package/hub/server.mjs
CHANGED
|
@@ -593,6 +593,20 @@ export async function startHub({
|
|
|
593
593
|
locks: swarmLocks,
|
|
594
594
|
});
|
|
595
595
|
|
|
596
|
+
// Synapse Layer 5: emitter subscribers — bridge events to hub logging
|
|
597
|
+
synapseEmitter.on("synapse.session.started", ({ sessionId }) => {
|
|
598
|
+
hubLog.info({ sessionId }, "synapse.session.started");
|
|
599
|
+
});
|
|
600
|
+
synapseEmitter.on("synapse.session.heartbeat", ({ sessionId }) => {
|
|
601
|
+
hubLog.debug({ sessionId }, "synapse.session.heartbeat");
|
|
602
|
+
});
|
|
603
|
+
synapseEmitter.on("synapse.session.stale", ({ sessionId }) => {
|
|
604
|
+
hubLog.warn({ sessionId }, "synapse.session.stale");
|
|
605
|
+
});
|
|
606
|
+
synapseEmitter.on("synapse.session.removed", ({ sessionId }) => {
|
|
607
|
+
hubLog.info({ sessionId }, "synapse.session.removed");
|
|
608
|
+
});
|
|
609
|
+
|
|
596
610
|
const hitl = createHitlManager(store, router);
|
|
597
611
|
const pipe = createPipeServer({
|
|
598
612
|
router,
|
|
@@ -760,6 +774,33 @@ export async function startHub({
|
|
|
760
774
|
return writeJson(res, 200, { ok: true, accounts });
|
|
761
775
|
}
|
|
762
776
|
|
|
777
|
+
// ── Synapse Layer 5: session registry + locks + preflight routes ──
|
|
778
|
+
if (path === "/synapse/sessions" && req.method === "GET") {
|
|
779
|
+
return writeJson(res, 200, { ok: true, ...synapseRegistry.snapshot(), ts: Date.now() });
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
if (path === "/synapse/locks" && req.method === "GET") {
|
|
783
|
+
return writeJson(res, 200, { ok: true, locks: swarmLocks.snapshot(), ts: Date.now() });
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
if (path === "/synapse/preflight" && req.method === "POST") {
|
|
787
|
+
const VALID_OPS = new Set(["checkout", "rebase", "cherry-pick", "reset", "stash-pop", "worktree-remove"]);
|
|
788
|
+
try {
|
|
789
|
+
const body = await parseBody(req);
|
|
790
|
+
const { op, args = {}, sessionContext = {} } = body;
|
|
791
|
+
if (!op || typeof op !== "string") {
|
|
792
|
+
return writeJson(res, 400, { ok: false, error: "op 필수" });
|
|
793
|
+
}
|
|
794
|
+
if (!VALID_OPS.has(op)) {
|
|
795
|
+
return writeJson(res, 400, { ok: false, error: `invalid op: ${op}` });
|
|
796
|
+
}
|
|
797
|
+
const result = gitPreflight.check(op, args, sessionContext);
|
|
798
|
+
return writeJson(res, 200, { ok: true, ...result });
|
|
799
|
+
} catch (err) {
|
|
800
|
+
return writeJson(res, 400, { ok: false, error: String(err?.message || err) });
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
|
|
763
804
|
if (path.startsWith("/bridge")) {
|
|
764
805
|
const isBridgeStatusGet =
|
|
765
806
|
path === "/bridge/status" && req.method === "GET";
|
package/hub/team/conductor.mjs
CHANGED
|
@@ -66,6 +66,40 @@ const TERMINAL_STATES = new Set([STATES.DEAD, STATES.COMPLETED]);
|
|
|
66
66
|
const DEFAULT_MAX_RESTARTS = 3;
|
|
67
67
|
const DEFAULT_GRACE_MS = 10_000;
|
|
68
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Auth 파일을 lease 소스에서 CLI 대상 경로로 복사.
|
|
71
|
+
* @param {object} lease — broker lease 객체 (mode, authFile 필수)
|
|
72
|
+
* @param {'codex'|'gemini'} agent
|
|
73
|
+
* @param {string} sessionId — 로깅용
|
|
74
|
+
* @param {object} eventLog — createEventLog 인스턴스
|
|
75
|
+
*/
|
|
76
|
+
function swapAuthFile(lease, agent, sessionId, eventLog) {
|
|
77
|
+
if (lease?.mode !== "auth" || !lease.authFile) return true;
|
|
78
|
+
const dests =
|
|
79
|
+
agent === "codex"
|
|
80
|
+
? [join(homedir(), ".codex", "auth.json")]
|
|
81
|
+
: [
|
|
82
|
+
join(homedir(), ".gemini", "oauth_creds.json"),
|
|
83
|
+
join(homedir(), ".gemini", "gemini-credentials.json"),
|
|
84
|
+
];
|
|
85
|
+
let allOk = true;
|
|
86
|
+
for (const dest of dests) {
|
|
87
|
+
try {
|
|
88
|
+
mkdirSync(dirname(dest), { recursive: true });
|
|
89
|
+
copyFileSync(lease.authFile, dest);
|
|
90
|
+
eventLog.append("auth_copy", { session: sessionId, agent, dest });
|
|
91
|
+
} catch (err) {
|
|
92
|
+
allOk = false;
|
|
93
|
+
eventLog.append("auth_copy_error", {
|
|
94
|
+
session: sessionId,
|
|
95
|
+
dest,
|
|
96
|
+
error: err.message,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return allOk;
|
|
101
|
+
}
|
|
102
|
+
|
|
69
103
|
/**
|
|
70
104
|
* Conductor 팩토리.
|
|
71
105
|
* @param {object} opts
|
|
@@ -73,6 +107,7 @@ const DEFAULT_GRACE_MS = 10_000;
|
|
|
73
107
|
* @param {number} [opts.maxRestarts=3]
|
|
74
108
|
* @param {number} [opts.graceMs=10000] — shutdown grace period
|
|
75
109
|
* @param {object} [opts.probeOpts] — health-probe 옵션 오버라이드
|
|
110
|
+
* @param {object} [opts.broker] — AccountBroker 인스턴스 (tierFallback 구독용)
|
|
76
111
|
* @returns {Conductor}
|
|
77
112
|
*/
|
|
78
113
|
export function createConductor(opts = {}) {
|
|
@@ -81,6 +116,7 @@ export function createConductor(opts = {}) {
|
|
|
81
116
|
maxRestarts = DEFAULT_MAX_RESTARTS,
|
|
82
117
|
graceMs = DEFAULT_GRACE_MS,
|
|
83
118
|
probeOpts = {},
|
|
119
|
+
broker: optsBroker,
|
|
84
120
|
} = opts;
|
|
85
121
|
|
|
86
122
|
if (!logsDir) throw new Error("logsDir is required");
|
|
@@ -739,32 +775,7 @@ export function createConductor(opts = {}) {
|
|
|
739
775
|
: config;
|
|
740
776
|
|
|
741
777
|
// auth file copy — broker resolved absolute path, conductor does the actual copy
|
|
742
|
-
|
|
743
|
-
const dests =
|
|
744
|
-
config.agent === "codex"
|
|
745
|
-
? [join(homedir(), ".codex", "auth.json")]
|
|
746
|
-
: [
|
|
747
|
-
join(homedir(), ".gemini", "oauth_creds.json"),
|
|
748
|
-
join(homedir(), ".gemini", "gemini-credentials.json"),
|
|
749
|
-
];
|
|
750
|
-
for (const dest of dests) {
|
|
751
|
-
try {
|
|
752
|
-
mkdirSync(dirname(dest), { recursive: true });
|
|
753
|
-
copyFileSync(lease.authFile, dest);
|
|
754
|
-
eventLog.append("auth_copy", {
|
|
755
|
-
session: config.id,
|
|
756
|
-
agent: config.agent,
|
|
757
|
-
dest,
|
|
758
|
-
});
|
|
759
|
-
} catch (err) {
|
|
760
|
-
eventLog.append("auth_copy_error", {
|
|
761
|
-
session: config.id,
|
|
762
|
-
dest,
|
|
763
|
-
error: err.message,
|
|
764
|
-
});
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
}
|
|
778
|
+
swapAuthFile(lease, config.agent, config.id, eventLog);
|
|
768
779
|
|
|
769
780
|
// 원격 세션은 launcher 불필요 (이미 원격에서 실행 중)
|
|
770
781
|
const launcher = resolvedConfig.remote
|
|
@@ -892,12 +903,44 @@ export function createConductor(opts = {}) {
|
|
|
892
903
|
});
|
|
893
904
|
|
|
894
905
|
await Promise.allSettled(cleanups);
|
|
906
|
+
process.removeListener("SIGINT", onSignal);
|
|
907
|
+
process.removeListener("SIGTERM", onSignal);
|
|
908
|
+
if (brokerInstance && onTierFallback) {
|
|
909
|
+
brokerInstance.removeListener("tierFallback", onTierFallback);
|
|
910
|
+
}
|
|
895
911
|
if (conductor._meshBridge) conductor._meshBridge.detach();
|
|
896
912
|
await eventLog.flush();
|
|
897
913
|
await eventLog.close();
|
|
898
914
|
emitter.emit("shutdown");
|
|
899
915
|
}
|
|
900
916
|
|
|
917
|
+
// ── broker tierFallback 구독 ──────────────────────────────────
|
|
918
|
+
// 토큰 만료 등으로 상위 tier 계정이 불가능해지면, 활성 세션의 auth를 새 lease로 교체.
|
|
919
|
+
const brokerInstance = optsBroker ?? null;
|
|
920
|
+
const onTierFallback = brokerInstance
|
|
921
|
+
? ({ provider }) => {
|
|
922
|
+
for (const session of sessions.values()) {
|
|
923
|
+
if (TERMINAL_STATES.has(session.state)) continue;
|
|
924
|
+
if (session.config.agent !== provider) continue;
|
|
925
|
+
if (session.config.remote) continue;
|
|
926
|
+
|
|
927
|
+
const newLease = brokerInstance.lease({ provider });
|
|
928
|
+
if (!newLease) continue;
|
|
929
|
+
|
|
930
|
+
swapAuthFile(newLease, provider, session.id, eventLog);
|
|
931
|
+
eventLog.append("tier_fallback_swap", {
|
|
932
|
+
session: session.id,
|
|
933
|
+
agent: provider,
|
|
934
|
+
newAccount: newLease.id,
|
|
935
|
+
});
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
: null;
|
|
939
|
+
|
|
940
|
+
if (brokerInstance && onTierFallback) {
|
|
941
|
+
brokerInstance.on("tierFallback", onTierFallback);
|
|
942
|
+
}
|
|
943
|
+
|
|
901
944
|
// Shutdown traps
|
|
902
945
|
const onSignal = () => {
|
|
903
946
|
void shutdown("signal");
|
|
@@ -69,6 +69,7 @@ export function createSynapseRegistry(opts = {}) {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
let persistTimer = null;
|
|
72
|
+
let destroyed = false;
|
|
72
73
|
|
|
73
74
|
function persist() {
|
|
74
75
|
if (!persistPath) return;
|
|
@@ -84,10 +85,10 @@ export function createSynapseRegistry(opts = {}) {
|
|
|
84
85
|
}
|
|
85
86
|
|
|
86
87
|
function schedulePersist() {
|
|
87
|
-
if (persistTimer) return;
|
|
88
|
+
if (destroyed || persistTimer) return;
|
|
88
89
|
persistTimer = setTimeout(() => {
|
|
89
90
|
persistTimer = null;
|
|
90
|
-
persist();
|
|
91
|
+
if (!destroyed) persist();
|
|
91
92
|
}, 200);
|
|
92
93
|
if (typeof persistTimer.unref === "function") persistTimer.unref();
|
|
93
94
|
}
|
|
@@ -277,6 +278,7 @@ export function createSynapseRegistry(opts = {}) {
|
|
|
277
278
|
}
|
|
278
279
|
|
|
279
280
|
function destroy() {
|
|
281
|
+
destroyed = true;
|
|
280
282
|
for (const sessionId of monitors.keys()) {
|
|
281
283
|
stopMonitor(sessionId);
|
|
282
284
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "triflux",
|
|
3
|
-
"version": "10.9.
|
|
3
|
+
"version": "10.9.15",
|
|
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": {
|
|
@@ -13,26 +13,69 @@
|
|
|
13
13
|
"tfx-doctor-tui": "bin/tfx-doctor-tui.mjs",
|
|
14
14
|
"tfx-setup-tui": "bin/tfx-setup-tui.mjs"
|
|
15
15
|
},
|
|
16
|
-
"engines": {
|
|
17
|
-
"node": ">=18.0.0"
|
|
18
|
-
},
|
|
19
|
-
"dependencies": {
|
|
20
|
-
"@triflux/core": "10.0.1",
|
|
21
|
-
"@triflux/remote": "^10.0.0-alpha.1"
|
|
22
|
-
},
|
|
23
16
|
"files": [
|
|
24
17
|
"bin",
|
|
18
|
+
"tui",
|
|
19
|
+
"hub",
|
|
20
|
+
"config",
|
|
25
21
|
"skills",
|
|
22
|
+
"!skills/tfx-workspace",
|
|
23
|
+
"!**/failure-reports",
|
|
24
|
+
"scripts",
|
|
26
25
|
"hooks",
|
|
27
26
|
"hud",
|
|
28
|
-
"scripts",
|
|
29
|
-
"hub",
|
|
30
27
|
"mesh",
|
|
31
|
-
"
|
|
32
|
-
"CLAUDE.md",
|
|
28
|
+
".claude-plugin",
|
|
33
29
|
"README.md",
|
|
30
|
+
"README.ko.md",
|
|
34
31
|
"LICENSE"
|
|
35
32
|
],
|
|
33
|
+
"workspaces": [
|
|
34
|
+
"packages/core",
|
|
35
|
+
"packages/remote",
|
|
36
|
+
"packages/triflux"
|
|
37
|
+
],
|
|
38
|
+
"scripts": {
|
|
39
|
+
"pack": "node scripts/pack.mjs all",
|
|
40
|
+
"pack:core": "node scripts/pack.mjs core",
|
|
41
|
+
"pack:remote": "node scripts/pack.mjs remote",
|
|
42
|
+
"setup": "node scripts/setup.mjs",
|
|
43
|
+
"preinstall": "node scripts/preinstall.mjs",
|
|
44
|
+
"postinstall": "node scripts/setup.mjs",
|
|
45
|
+
"lint": "biome check .",
|
|
46
|
+
"lint:fix": "biome check --fix .",
|
|
47
|
+
"health": "npm test && npm run lint",
|
|
48
|
+
"test": "node scripts/test-lock.mjs --test --test-force-exit --test-concurrency=8 \"tests/**/*.test.mjs\" \"scripts/__tests__/**/*.test.mjs\"",
|
|
49
|
+
"test:unit": "node scripts/test-lock.mjs --test --test-force-exit --test-concurrency=8 tests/unit/**/*.test.mjs",
|
|
50
|
+
"test:integration": "node scripts/test-lock.mjs --test --test-force-exit --test-concurrency=8 tests/integration/**/*.test.mjs",
|
|
51
|
+
"test:route-smoke": "node scripts/test-lock.mjs --test scripts/test-tfx-route-no-claude-native.mjs",
|
|
52
|
+
"test:contract": "node scripts/test-lock.mjs --test --test-force-exit --test-concurrency=8 tests/contract/**/*.test.mjs",
|
|
53
|
+
"test:coverage": "node --experimental-test-coverage --test-coverage-lines=60 --test-coverage-functions=60 --test --test-force-exit --test-concurrency=8 \"tests/**/*.test.mjs\"",
|
|
54
|
+
"gen:skill-docs": "node scripts/gen-skill-docs.mjs",
|
|
55
|
+
"gen:skill-manifest": "node scripts/gen-skill-manifest.mjs"
|
|
56
|
+
},
|
|
57
|
+
"engines": {
|
|
58
|
+
"node": ">=18.0.0"
|
|
59
|
+
},
|
|
60
|
+
"repository": {
|
|
61
|
+
"type": "git",
|
|
62
|
+
"url": "git+https://github.com/tellang/triflux.git"
|
|
63
|
+
},
|
|
64
|
+
"homepage": "https://github.com/tellang/triflux#readme",
|
|
65
|
+
"author": "tellang",
|
|
66
|
+
"license": "MIT",
|
|
67
|
+
"dependencies": {
|
|
68
|
+
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
69
|
+
"better-sqlite3": "^12.6.2",
|
|
70
|
+
"pino": "^10.3.1",
|
|
71
|
+
"pino-pretty": "^13.1.3",
|
|
72
|
+
"systray2": "^2.1.4",
|
|
73
|
+
"zod": "^4.0.0"
|
|
74
|
+
},
|
|
75
|
+
"devDependencies": {
|
|
76
|
+
"@biomejs/biome": "^2.0.0",
|
|
77
|
+
"knip": "^6.3.0"
|
|
78
|
+
},
|
|
36
79
|
"keywords": [
|
|
37
80
|
"claude-code",
|
|
38
81
|
"plugin",
|
|
@@ -43,13 +86,5 @@
|
|
|
43
86
|
"multi-model",
|
|
44
87
|
"triflux",
|
|
45
88
|
"tfx"
|
|
46
|
-
]
|
|
47
|
-
"author": "tellang",
|
|
48
|
-
"license": "MIT",
|
|
49
|
-
"homepage": "https://github.com/tellang/triflux#readme",
|
|
50
|
-
"repository": {
|
|
51
|
-
"type": "git",
|
|
52
|
-
"url": "git+https://github.com/tellang/triflux.git",
|
|
53
|
-
"directory": "packages/triflux"
|
|
54
|
-
}
|
|
89
|
+
]
|
|
55
90
|
}
|
package/scripts/tfx-route.sh
CHANGED
|
@@ -105,17 +105,14 @@ if [[ -f "$_CODEX_CONFIG" ]] && awk '
|
|
|
105
105
|
fi
|
|
106
106
|
|
|
107
107
|
build_codex_base() {
|
|
108
|
-
#
|
|
109
|
-
#
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
else
|
|
117
|
-
echo "--dangerously-bypass-approvals-and-sandbox --skip-git-repo-check"
|
|
118
|
-
fi
|
|
108
|
+
# codex exec는 항상 non-TTY subprocess에서 실행되므로 --dangerously-bypass 필수.
|
|
109
|
+
# --dangerously-bypass는 config.toml의 approval_mode/sandbox와 충돌하지 않음
|
|
110
|
+
# (--full-auto와 달리 bypass는 config 값을 override할 뿐 에러를 던지지 않음).
|
|
111
|
+
# 검증: approval_mode="auto" config에서 --dangerously-bypass 동시 사용 → exit 0 확인.
|
|
112
|
+
#
|
|
113
|
+
# Note: 위의 _CODEX_HAS_SANDBOX awk 감지는 현재 미사용이지만, 향후 codex가
|
|
114
|
+
# bypass와 config.toml 충돌을 감지하면 분기 로직을 재활성화할 수 있으므로 유지.
|
|
115
|
+
echo "--dangerously-bypass-approvals-and-sandbox --skip-git-repo-check"
|
|
119
116
|
}
|
|
120
117
|
|
|
121
118
|
# ── Async Job 디렉토리 ──
|