@triflux/core 10.50.0 → 10.50.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 (55) hide show
  1. package/hub/index.mjs +2 -8
  2. package/hub/lib/cto-env.mjs +0 -23
  3. package/hub/paths.mjs +0 -6
  4. package/hub/pipeline/index.mjs +0 -190
  5. package/hub/pipeline/transitions.mjs +0 -10
  6. package/hub/reflexion.mjs +1 -84
  7. package/hud/cli-policy.mjs +1 -5
  8. package/hud/colors.mjs +0 -13
  9. package/hud/constants.mjs +4 -135
  10. package/hud/context-monitor.mjs +3 -64
  11. package/hud/hud-qos-status.mjs +43 -225
  12. package/hud/providers/claude.mjs +4 -16
  13. package/hud/providers/gemini.mjs +7 -698
  14. package/hud/renderers.mjs +40 -294
  15. package/hud/terminal.mjs +1 -63
  16. package/hud/utils.mjs +0 -24
  17. package/package.json +1 -2
  18. package/scripts/lib/gemini-profiles.mjs +1 -1
  19. package/scripts/lib/legacy-mcp-cleanup.mjs +14 -3
  20. package/scripts/lib/psmux-info.mjs +18 -49
  21. package/scripts/lib/skill-template.mjs +0 -26
  22. package/hub/codex-compat.mjs +0 -12
  23. package/hub/fullcycle.mjs +0 -113
  24. package/hub/gemini-adapter.mjs +0 -174
  25. package/hub/intent.mjs +0 -321
  26. package/hub/lib/mcp-response-cache.mjs +0 -239
  27. package/hub/lib/path-utils.mjs +0 -165
  28. package/hub/lib/timeline-adapter.mjs +0 -190
  29. package/hub/pipeline/gates/confidence.mjs +0 -75
  30. package/hub/pipeline/gates/consensus.mjs +0 -106
  31. package/hub/pipeline/gates/index.mjs +0 -9
  32. package/hub/pipeline/gates/selfcheck.mjs +0 -120
  33. package/hub/quality/deslop.mjs +0 -274
  34. package/hub/research.mjs +0 -155
  35. package/hub/role-control-events.mjs +0 -113
  36. package/hub/routing/complexity.mjs +0 -269
  37. package/hub/routing/index.mjs +0 -122
  38. package/hub/routing/q-learning.mjs +0 -387
  39. package/hub/token-mode.mjs +0 -228
  40. package/hud/mission-board.mjs +0 -56
  41. package/hud/providers/cto.mjs +0 -76
  42. package/scripts/lib/agent-json.mjs +0 -27
  43. package/scripts/lib/async.mjs +0 -174
  44. package/scripts/lib/cli-agy.mjs +0 -85
  45. package/scripts/lib/cli-codex.mjs +0 -62
  46. package/scripts/lib/cli-gemini.mjs +0 -37
  47. package/scripts/lib/env.mjs +0 -14
  48. package/scripts/lib/hub.mjs +0 -48
  49. package/scripts/lib/pid.mjs +0 -63
  50. package/scripts/lib/quota.mjs +0 -47
  51. package/scripts/lib/skill-state.mjs +0 -220
  52. package/scripts/lib/team.mjs +0 -75
  53. package/scripts/lib/timeout.mjs +0 -66
  54. package/scripts/lib/tmp.mjs +0 -26
  55. package/scripts/lib/toml.mjs +0 -132
package/hub/index.mjs CHANGED
@@ -2,12 +2,10 @@
2
2
  // Adapters
3
3
  export { buildExecCommand, sleep, gte, FEATURES, CODEX_MCP_TRANSPORT_EXIT_CODE, normalizePathForShell, shellQuote } from './cli-adapter-base.mjs';
4
4
  export { execute as executeCodex, buildExecArgs as buildCodexArgs, buildLaunchScript, getCircuitState as getCodexCircuit } from './codex-adapter.mjs';
5
- export { execute as executeGemini, buildExecArgs as buildGeminiArgs, getCircuitState as getGeminiCircuit } from './gemini-adapter.mjs';
6
5
  export { getCodexVersion, runPreflight } from './codex-preflight.mjs';
7
6
 
8
- // Routing & Intent
7
+ // Routing
9
8
  export { createRouter } from './router.mjs';
10
- export { classifyIntent, quickClassify, INTENT_CATEGORIES, refineClassification } from './intent.mjs';
11
9
 
12
10
  // State & Paths & Platform
13
11
  export * from './paths.mjs';
@@ -18,12 +16,8 @@ export { createHitlManager } from './hitl.mjs';
18
16
  export { createAssignCallbackServer } from './assign-callbacks.mjs';
19
17
  export { getHubUrl, getHubPipePath, requestJson, post, connectPipe, parseArgs, parseJsonSafe } from './bridge.mjs';
20
18
 
21
- // Fullcycle & Research
22
- export { createFullcycleRunId, getFullcycleRunDir, ensureFullcycleRunDir, saveFullcycleArtifact, readFullcycleArtifact, writeFullcycleState, readFullcycleState, shouldStopQaLoop } from './fullcycle.mjs';
23
- export { generateQueries, normalizeResults, buildReport, saveReport } from './research.mjs';
24
-
25
19
  // Reflexion (adaptive error learning)
26
- export { normalizeError, lookupSolution, learnFromError, reportOutcome, adaptiveRuleFromError, getActiveAdaptiveRules } from './reflexion.mjs';
20
+ export { normalizeError, adaptiveRuleFromError } from './reflexion.mjs';
27
21
 
28
22
  // Neural Memory (Lake 1.5)
29
23
  export { createAdaptiveEngine } from './adaptive.mjs';
@@ -64,30 +64,7 @@ export function isCtoDisabled() {
64
64
  return isExplicitlyOff("TFX_CTO");
65
65
  }
66
66
 
67
- export function isCtoManagerEnabled() {
68
- if (isCtoDisabled()) return false;
69
- return isExplicitlyOn("TFX_CTO_MANAGER");
70
- }
71
-
72
- export function getCtoHygieneApplyMode() {
73
- if (isExplicitlyOff("TFX_CTO")) return "off";
74
- return normalizeEnvValue("TFX_CTO_HYGIENE_APPLY") === "archive"
75
- ? "archive"
76
- : "off";
77
- }
78
-
79
67
  export function isCtoRetentionEnabled() {
80
68
  if (isExplicitlyOff("TFX_CTO")) return false;
81
69
  return isExplicitlyOn("TFX_CTO_RETENTION");
82
70
  }
83
-
84
- export function getCtoMode() {
85
- return normalizeEnvValue("TFX_CTO_MODE") === "bridge" ? "bridge" : "bounded";
86
- }
87
-
88
- export function getCtoMaxTokens() {
89
- const raw = normalizeEnvValue("TFX_CTO_MAX_TOKENS");
90
- if (!raw) return 0;
91
- const value = Number(raw);
92
- return Number.isSafeInteger(value) && value > 0 ? value : 0;
93
- }
package/hub/paths.mjs CHANGED
@@ -6,10 +6,7 @@ import { join } from "node:path";
6
6
  export const TFX_WORK_DIR = ".tfx";
7
7
  export const TFX_PLANS_DIR = join(TFX_WORK_DIR, "plans");
8
8
  export const TFX_REPORTS_DIR = join(TFX_WORK_DIR, "reports");
9
- export const TFX_HANDOFFS_DIR = join(TFX_WORK_DIR, "handoffs");
10
- export const TFX_LOGS_DIR = join(TFX_WORK_DIR, "logs");
11
9
  export const TFX_STATE_DIR = join(TFX_WORK_DIR, "state");
12
- export const TFX_FULLCYCLE_DIR = join(TFX_WORK_DIR, "fullcycle");
13
10
 
14
11
  /**
15
12
  * triflux 워킹 디렉토리 구조를 보장한다.
@@ -20,10 +17,7 @@ export function ensureTfxDirs(baseDir) {
20
17
  TFX_WORK_DIR,
21
18
  TFX_PLANS_DIR,
22
19
  TFX_REPORTS_DIR,
23
- TFX_HANDOFFS_DIR,
24
- TFX_LOGS_DIR,
25
20
  TFX_STATE_DIR,
26
- TFX_FULLCYCLE_DIR,
27
21
  ]) {
28
22
  mkdirSync(join(baseDir, relativeDir), { recursive: true });
29
23
  }
@@ -3,11 +3,7 @@
3
3
  // 상태(state.mjs) + 전이(transitions.mjs) 통합 인터페이스
4
4
 
5
5
  import { mkdirSync, writeFileSync } from "node:fs";
6
- import { homedir } from "node:os";
7
6
  import { join, resolve } from "node:path";
8
- import { classifyIntent as _classifyIntent } from "../intent.mjs";
9
- import { runConfidenceCheck } from "./gates/confidence.mjs";
10
- import { runSelfCheck } from "./gates/selfcheck.mjs";
11
7
  import {
12
8
  ensurePipelineTable,
13
9
  initPipelineState,
@@ -21,7 +17,6 @@ import {
21
17
  TERMINAL,
22
18
  transitionPhase,
23
19
  } from "./transitions.mjs";
24
- // deslop gate: 호출자가 scanDirectory/detectSlop 결과를 전달
25
20
 
26
21
  /**
27
22
  * 파이프라인 매니저 생성
@@ -162,192 +157,7 @@ export function createPipeline(db, teamName, opts = {}) {
162
157
  remove() {
163
158
  return removePipelineState(db, teamName);
164
159
  },
165
-
166
- /**
167
- * Confidence Gate 실행 + 자동 전이
168
- * prd → confidence → exec/failed
169
- * @param {string|object} planArtifact
170
- * @param {object} context - { checks?, codebaseFiles?, existingTests? }
171
- * @returns {{ ok: boolean, gate: object, state?: object, error?: string }}
172
- */
173
- runConfidenceGate(planArtifact, context = {}) {
174
- const current = readPipelineState(db, teamName);
175
- if (!current) return { ok: false, error: `파이프라인 없음: ${teamName}` };
176
-
177
- if (current.phase !== "confidence") {
178
- return {
179
- ok: false,
180
- error: `confidence gate는 confidence 단계에서만 실행 가능 (현재: ${current.phase})`,
181
- };
182
- }
183
-
184
- const gate = runConfidenceCheck(planArtifact, context);
185
- this.setArtifact("confidence_result", gate);
186
-
187
- if (gate.decision === "abort") {
188
- const result = this.advance("failed");
189
- return { ok: true, gate, state: result.state };
190
- }
191
-
192
- // proceed 또는 alternative → exec로 전이
193
- const result = this.advance("exec");
194
- return { ok: result.ok, gate, state: result.state, error: result.error };
195
- },
196
-
197
- /**
198
- * Deslop Gate 실행 + 자동 전이
199
- * exec → deslop → verify
200
- * 호출자가 미리 deslop 결과를 생성하여 전달.
201
- * @param {object} [deslopResult] - scanDirectory() 또는 detectSlop() 결과
202
- * @returns {{ ok: boolean, gate: object, state?: object, error?: string }}
203
- */
204
- runDeslopGate(deslopResult = null) {
205
- const current = readPipelineState(db, teamName);
206
- if (!current) return { ok: false, error: `파이프라인 없음: ${teamName}` };
207
-
208
- if (current.phase !== "deslop") {
209
- return {
210
- ok: false,
211
- error: `deslop gate는 deslop 단계에서만 실행 가능 (현재: ${current.phase})`,
212
- };
213
- }
214
-
215
- const gate = deslopResult || {
216
- files: [],
217
- summary: { total: 0, clean: 0 },
218
- };
219
- this.setArtifact("deslop_result", gate);
220
-
221
- // deslop은 항상 verify로 전이 (정보 제공 게이트, 차단 없음)
222
- const result = this.advance("verify");
223
- return { ok: result.ok, gate, state: result.state, error: result.error };
224
- },
225
-
226
- /**
227
- * Self-Check Gate 실행 + 자동 전이
228
- * verify → selfcheck → complete/fix
229
- * @param {string|object} execResult
230
- * @param {string|object} verifyResult
231
- * @param {object} requirements - { hasDiff?, evidence? }
232
- * @returns {{ ok: boolean, gate: object, state?: object, error?: string }}
233
- */
234
- runSelfCheckGate(execResult, verifyResult, requirements = {}) {
235
- const current = readPipelineState(db, teamName);
236
- if (!current) return { ok: false, error: `파이프라인 없음: ${teamName}` };
237
-
238
- if (current.phase !== "selfcheck") {
239
- return {
240
- ok: false,
241
- error: `selfcheck gate는 selfcheck 단계에서만 실행 가능 (현재: ${current.phase})`,
242
- };
243
- }
244
-
245
- const gate = runSelfCheck(execResult, verifyResult, requirements);
246
- this.setArtifact("selfcheck_result", gate);
247
-
248
- if (gate.passed) {
249
- const result = this.advance("complete");
250
- return {
251
- ok: result.ok,
252
- gate,
253
- state: result.state,
254
- error: result.error,
255
- };
256
- }
257
-
258
- // Red Flag 탐지 또는 필수 질문 실패 → fix
259
- const result = this.advance("fix");
260
- return { ok: result.ok, gate, state: result.state, error: result.error };
261
- },
262
160
  };
263
161
  }
264
-
265
- // ── 토큰 벤치마크 훅 ──
266
-
267
- let _tokenSnapshotMod = null;
268
-
269
- async function loadTokenSnapshot() {
270
- if (_tokenSnapshotMod) return _tokenSnapshotMod;
271
- try {
272
- _tokenSnapshotMod = await import("../../scripts/token-snapshot.mjs");
273
- } catch {
274
- _tokenSnapshotMod = null;
275
- }
276
- return _tokenSnapshotMod;
277
- }
278
-
279
- /**
280
- * 파이프라인 시작 시 토큰 스냅샷 캡처
281
- * @param {string} label - 스냅샷 라벨 (e.g. teamName + timestamp)
282
- * @returns {Promise<{label: string, snapshot: object}|null>}
283
- */
284
- export async function benchmarkStart(label) {
285
- const mod = await loadTokenSnapshot();
286
- if (!mod?.takeSnapshot) return null;
287
- try {
288
- const snapshot = mod.takeSnapshot(label);
289
- return { label, snapshot };
290
- } catch {
291
- return null;
292
- }
293
- }
294
-
295
- /**
296
- * 파이프라인 종료 시 diff 계산 + 결과 저장
297
- * @param {string} preLabel - 시작 스냅샷 라벨
298
- * @param {string} postLabel - 종료 스냅샷 라벨
299
- * @param {object} options - { agent?, cli?, id? }
300
- * @returns {Promise<object|null>} diff 결과
301
- */
302
- export async function benchmarkEnd(preLabel, postLabel, options = {}) {
303
- const mod = await loadTokenSnapshot();
304
- if (!mod?.takeSnapshot || !mod?.computeDiff) return null;
305
- try {
306
- // 종료 스냅샷 캡처
307
- mod.takeSnapshot(postLabel);
308
- // diff 계산 (결과는 DIFFS_DIR에 자동 저장됨)
309
- const diff = mod.computeDiff(preLabel, postLabel, options);
310
-
311
- // 추가로 타임스탬프 기반 사본 저장
312
- const diffsDir = join(
313
- homedir(),
314
- ".omc",
315
- "state",
316
- "cx-auto-tokens",
317
- "diffs",
318
- );
319
- mkdirSync(diffsDir, { recursive: true });
320
- const ts = new Date().toISOString().replace(/[:.]/g, "-");
321
- const outPath = join(diffsDir, `${ts}.json`);
322
- writeFileSync(outPath, JSON.stringify(diff, null, 2));
323
-
324
- return diff;
325
- } catch {
326
- return null;
327
- }
328
- }
329
-
330
- /**
331
- * 트리아지 통합: quickClassify 고신뢰 시 Codex 분류 스킵 판정
332
- * @param {string} prompt
333
- * @param {number} [threshold=0.8]
334
- * @returns {{ skip: boolean, routing: object|null, classification: object }}
335
- */
336
- export function triageWithIntent(prompt, threshold = 0.8) {
337
- const classification = _classifyIntent(prompt);
338
- if (classification.confidence >= threshold) {
339
- return { skip: true, routing: classification.routing, classification };
340
- }
341
- return { skip: false, routing: null, classification };
342
- }
343
-
344
- export {
345
- classifyIntent,
346
- INTENT_CATEGORIES,
347
- quickClassify,
348
- } from "../intent.mjs";
349
- export { autoFixSlop, detectSlop, scanDirectory } from "../quality/deslop.mjs";
350
- export { CRITERIA, runConfidenceCheck } from "./gates/confidence.mjs";
351
- export { QUESTIONS, RED_FLAGS, runSelfCheck } from "./gates/selfcheck.mjs";
352
162
  export { ensurePipelineTable } from "./state.mjs";
353
163
  export { ALLOWED, canTransition, PHASES, TERMINAL } from "./transitions.mjs";
@@ -73,19 +73,9 @@ export function transitionPhase(state, nextPhase) {
73
73
  }
74
74
  }
75
75
 
76
- // fix → exec 재진입 시 (fix 후 재실행)
77
- if (current === "fix" && nextPhase === "exec") {
78
- // fix_attempt 유지 (이미 fix 진입 시 증가됨)
79
- }
80
-
81
76
  // verify → fix → ... → verify 반복 후 fix_max 초과 시 ralph loop
82
77
  if (nextPhase === "failed" && current === "fix") {
83
- // ralph loop 반복 증가
84
78
  next.ralph_iteration = (state.ralph_iteration || 0) + 1;
85
- if (next.ralph_iteration > (state.ralph_max || 10)) {
86
- // 최종 실패 — ralph loop도 초과
87
- next.phase = "failed";
88
- }
89
79
  }
90
80
 
91
81
  // phase_history 기록
package/hub/reflexion.mjs CHANGED
@@ -1,10 +1,7 @@
1
- // hub/reflexion.mjs — Cross-Session Error Learning Engine
2
- // 에러를 구조화 저장 → 다음 세션에서 유사 에러 패턴 매칭 → 자동 솔루션 적용
1
+ // 오류 패턴 정규화 및 adaptive rule 관리
3
2
 
4
- const DEFAULT_REFLEXION_TYPE = "reflexion";
5
3
  export const ADAPTIVE_RULE_TYPE = "adaptive";
6
4
  const DEFAULT_CONFIDENCE = 0.5;
7
- const ACTIVE_RULE_CONFIDENCE = 0.5;
8
5
  const ADAPTIVE_PROMOTION_STEP = 0.1;
9
6
  const ADAPTIVE_DECAY_STEP = 0.1;
10
7
  const ADAPTIVE_DELETE_THRESHOLD = 0.3;
@@ -100,12 +97,6 @@ function buildAdaptiveSolution(errorContext = {}, errorText = "") {
100
97
  return `${toolName} 재시도 전 실패 원인을 검증하세요: ${summary}`;
101
98
  }
102
99
 
103
- function filterEntriesByType(entries, type) {
104
- return entries.filter(
105
- (entry) => (entry.type || DEFAULT_REFLEXION_TYPE) === type,
106
- );
107
- }
108
-
109
100
  function parseAdaptiveRuleId(ruleId, projectSlug = "") {
110
101
  const value = pickString(ruleId);
111
102
  if (!value) return null;
@@ -187,68 +178,6 @@ export function normalizeError(errorMessage) {
187
178
  return p.toLowerCase().replace(/\s+/g, " ").trim();
188
179
  }
189
180
 
190
- /**
191
- * 에러에 대한 기존 솔루션 검색
192
- * @deprecated reflexion_entries 기반. adaptive_rules로 통합 예정. 현재 런타임 호출 없음.
193
- * @param {object} store - createStore() 반환 객체
194
- * @param {string} errorMessage - 원본 에러 메시지
195
- * @param {object} [context={}] - { file, function, cli, agent }
196
- * @returns {{ found: boolean, entries: Array, bestMatch: object|null }}
197
- */
198
- export function lookupSolution(store, errorMessage, context = {}) {
199
- const pattern = normalizeError(errorMessage);
200
- if (!pattern) return { found: false, entries: [], bestMatch: null };
201
- const entries = store.findReflexion(pattern, context);
202
- if (!entries.length) return { found: false, entries: [], bestMatch: null };
203
- return { found: true, entries, bestMatch: entries[0] };
204
- }
205
-
206
- /**
207
- * 에러 해결 후 학습 저장
208
- * @deprecated reflexion_entries 기반. adaptive_rules로 통합 예정. 현재 런타임 호출 없음.
209
- * 동일 패턴이 존재하면 hit 업데이트, 없으면 새로 생성
210
- * @param {object} store
211
- * @param {{ error: string, solution: string, context?: object, success?: boolean }} opts
212
- * @returns {object|null}
213
- */
214
- export function learnFromError(
215
- store,
216
- { error, solution, context = {}, success = false },
217
- ) {
218
- const pattern = normalizeError(error);
219
- if (!pattern || !solution) return null;
220
- const existing = filterEntriesByType(
221
- store.findReflexion(pattern, context),
222
- DEFAULT_REFLEXION_TYPE,
223
- );
224
- if (existing.length && existing[0].error_pattern === pattern) {
225
- return store.updateReflexionHit(existing[0].id, success);
226
- }
227
- const newEntry = store.addReflexion({
228
- type: DEFAULT_REFLEXION_TYPE,
229
- error_pattern: pattern,
230
- error_message: error,
231
- context,
232
- solution,
233
- solution_code: null,
234
- });
235
- return success && newEntry
236
- ? store.updateReflexionHit(newEntry.id, true)
237
- : newEntry;
238
- }
239
-
240
- /**
241
- * 솔루션 적용 결과 피드백
242
- * @deprecated reflexion_entries 기반. adaptive_rules로 통합 예정. 현재 런타임 호출 없음.
243
- * @param {object} store
244
- * @param {string} entryId
245
- * @param {boolean} success
246
- * @returns {object|null}
247
- */
248
- export function reportOutcome(store, entryId, success) {
249
- return store.updateReflexionHit(entryId, success);
250
- }
251
-
252
181
  /**
253
182
  * PostToolUseFailure 컨텍스트에서 adaptive rule payload 생성
254
183
  * @param {object} errorContext
@@ -347,18 +276,6 @@ export function decayRules(store, _sessionCount, projectSlug) {
347
276
  return result;
348
277
  }
349
278
 
350
- /**
351
- * 현재 활성화된 adaptive rules 조회
352
- * @param {object} store — store-adapter 인스턴스 (listAdaptiveRules 필요)
353
- * @param {string} projectSlug
354
- * @returns {Array}
355
- */
356
- export function getActiveAdaptiveRules(store, projectSlug) {
357
- return listAdaptiveRulesFromStore(store, projectSlug).filter(
358
- (rule) => rule.confidence >= ACTIVE_RULE_CONFIDENCE,
359
- );
360
- }
361
-
362
279
  /**
363
280
  * 신뢰도 자동 조정 (success_count / hit_count, 샘플 크기 기반 감쇠)
364
281
  * hit_count가 작으면 0.5(기본값)쪽으로 보수적으로 수렴
@@ -52,8 +52,6 @@ export function resolveHudCliVisibility(env = process.env, opts = {}) {
52
52
  * antigravityAllowed?: boolean,
53
53
  * antigravityReady?: boolean,
54
54
  * geminiEmail?: unknown,
55
- * geminiBucket?: unknown,
56
- * geminiSession?: unknown,
57
55
  * }} [args]
58
56
  * @returns {boolean}
59
57
  */
@@ -61,9 +59,7 @@ export function shouldRenderGeminiFallbackRow({
61
59
  antigravityAllowed = true,
62
60
  antigravityReady = false,
63
61
  geminiEmail = null,
64
- geminiBucket = null,
65
- geminiSession = null,
66
62
  } = {}) {
67
63
  if (antigravityAllowed || antigravityReady) return true;
68
- return Boolean(geminiEmail || geminiBucket || geminiSession);
64
+ return Boolean(geminiEmail);
69
65
  }
package/hud/colors.mjs CHANGED
@@ -47,20 +47,7 @@ export function colorByPercent(value, text) {
47
47
  return green(text);
48
48
  }
49
49
 
50
- export function colorCooldown(seconds, text) {
51
- if (seconds > 120) return red(text);
52
- if (seconds > 0) return yellow(text);
53
- return dim(text);
54
- }
55
-
56
- export function colorParallel(current, cap) {
57
- if (current >= cap) return green(`${current}/${cap}`);
58
- if (current > 1) return yellow(`${current}/${cap}`);
59
- return red(`${current}/${cap}`);
60
- }
61
-
62
50
  export const GAUGE_WIDTH = 5;
63
- export const GAUGE_BLOCKS = ["░", "▒", "▓", "█"]; // 밝기 0~3
64
51
 
65
52
  export function coloredBar(percent, width = GAUGE_WIDTH, baseColor = null) {
66
53
  const safePercent = Math.min(100, Math.max(0, percent));
package/hud/constants.mjs CHANGED
@@ -6,13 +6,6 @@ import { join } from "node:path";
6
6
 
7
7
  export const VERSION = "2.0";
8
8
 
9
- export const QOS_PATH = join(
10
- homedir(),
11
- ".claude",
12
- "cache",
13
- "tfx-hub",
14
- "cli_qos_profile.json",
15
- );
16
9
  export const ACCOUNTS_CONFIG_PATH = join(
17
10
  homedir(),
18
11
  ".claude",
@@ -38,21 +31,9 @@ export const CLAUDE_BAND_MARKER_DIR = join(
38
31
  );
39
32
  export const CLAUDE_BAND_MARKER_TTL_MS = 12 * 60 * 60 * 1000;
40
33
 
41
- // tfx-multi 상태 (v2.2 HUD 통합)
42
- export const TEAM_STATE_PATH = join(
43
- homedir(),
44
- ".claude",
45
- "cache",
46
- "tfx-hub",
47
- "team-state.json",
48
- );
49
- export const CTO_LAKE_CURRENT_RELATIVE_PATH = join(
50
- ".triflux",
51
- "lake",
52
- "current.md",
53
- );
54
- export const CTO_STATUS_STALE_MS = 60 * 60 * 1000; // 1시간
55
- export const CTO_STATUS_LINE_MAX_CHARS = 140;
34
+ // tfx-multi 세션 상태 디렉터리
35
+ export const TEAM_STATE_DIR =
36
+ process.env.TFX_HUB_PID_DIR || join(homedir(), ".claude", "cache", "tfx-hub");
56
37
  export const CONTEXT_MONITOR_CACHE_PATH = join(
57
38
  homedir(),
58
39
  ".claude",
@@ -67,12 +48,6 @@ export const HUB_REQUEST_MONITOR_CACHE_PATH = join(
67
48
  "tfx-hub",
68
49
  "hub-request-context-monitor.json",
69
50
  );
70
- export const CONTEXT_MONITOR_LEGACY_PATH = join(
71
- homedir(),
72
- ".omc",
73
- "state",
74
- "context-monitor.json",
75
- );
76
51
  export const CONTEXT_MONITOR_LOG_DIR = join(
77
52
  homedir(),
78
53
  ".claude",
@@ -81,16 +56,6 @@ export const CONTEXT_MONITOR_LOG_DIR = join(
81
56
  "logs",
82
57
  );
83
58
 
84
- // 원격 프로브 캐시 (tfx-remote)
85
- export const REMOTE_ENV_CACHE_DIR = join(
86
- homedir(),
87
- ".claude",
88
- "cache",
89
- "tfx-hub",
90
- "remote-env",
91
- );
92
- export const REMOTE_ENV_CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24시간
93
-
94
59
  // Claude OAuth Usage API (api.anthropic.com/api/oauth/usage)
95
60
  export const CLAUDE_CREDENTIALS_PATH = join(
96
61
  homedir(),
@@ -182,21 +147,8 @@ export const CODEX_REFRESH_LOCK_PATH = join(
182
147
  "cache",
183
148
  ".codex-refresh-lock",
184
149
  );
185
- export const GEMINI_QUOTA_REFRESH_LOCK_PATH = join(
186
- homedir(),
187
- ".claude",
188
- "cache",
189
- ".gemini-quota-refresh-lock",
190
- );
191
- export const GEMINI_SESSION_REFRESH_LOCK_PATH = join(
192
- homedir(),
193
- ".claude",
194
- "cache",
195
- ".gemini-session-refresh-lock",
196
- );
197
150
  export const SPAWN_LOCK_TTL_MS = 30 * 1000; // 30초 spawn dedup
198
151
 
199
- // Gemini 쿼터 API 관련
200
152
  export const GEMINI_OAUTH_PATH = join(homedir(), ".gemini", "oauth_creds.json");
201
153
  export const ANTIGRAVITY_OAUTH_PATHS = [
202
154
  join(homedir(), ".gemini", "antigravity-cli", "oauth_creds.json"),
@@ -212,10 +164,8 @@ export const ANTIGRAVITY_SETTINGS_PATH = join(
212
164
  "settings.json",
213
165
  );
214
166
  // Antigravity CLI 현재 장착 모델 라벨 → HUD 2자 약어 매핑
215
- // /usage 실측 (2026-05-22): Gemini 4개 모델이 동일 reset window 공유 (family-pool).
216
- // Claude/GPT-OSS family는 Gemini와 별도 quota 윈도우.
217
167
  export const ANTIGRAVITY_MODEL_ABBREV = {
218
- // Gemini family — 통합 quota. 3.6+ Flash 는 세대 숫자 + 등급으로 구분한다.
168
+ // Flash 세대와 등급을 구분한다.
219
169
  "Gemini 3.8 Flash (High)": "8h",
220
170
  "Gemini 3.8 Flash (Medium)": "8m",
221
171
  "Gemini 3.8 Flash (Low)": "8l",
@@ -228,33 +178,7 @@ export const ANTIGRAVITY_MODEL_ABBREV = {
228
178
  "Gemini 3.5 Flash (High)": "Fh",
229
179
  "Gemini 3.5 Flash (Medium)": "Fm",
230
180
  "Gemini 3.5 Flash (Low)": "Fl",
231
- "Gemini 3.1 Pro (High)": "Ph",
232
- "Gemini 3.1 Pro (Low)": "Pl",
233
- "Gemini 3 Flash": "F3",
234
- // Claude family — 각자 별도 quota
235
- "Claude Sonnet 4.6 (Thinking)": "Cs",
236
- "Claude Opus 4.6 (Thinking)": "Co",
237
- // GPT-OSS family — 각자 별도 quota
238
- "GPT-OSS 120B (Medium)": "Go",
239
181
  };
240
- export const GEMINI_QUOTA_CACHE_PATH = join(
241
- homedir(),
242
- ".claude",
243
- "cache",
244
- "gemini-quota-cache.json",
245
- );
246
- export const GEMINI_PROJECT_CACHE_PATH = join(
247
- homedir(),
248
- ".claude",
249
- "cache",
250
- "gemini-project-id.json",
251
- );
252
- export const GEMINI_SESSION_CACHE_PATH = join(
253
- homedir(),
254
- ".claude",
255
- "cache",
256
- "gemini-session-cache.json",
257
- );
258
182
  export const TFX_PREFLIGHT_CACHE_PATH = join(
259
183
  homedir(),
260
184
  ".claude",
@@ -262,42 +186,6 @@ export const TFX_PREFLIGHT_CACHE_PATH = join(
262
186
  "tfx-preflight.json",
263
187
  );
264
188
  export const TFX_PREFLIGHT_CACHE_STALE_MS = 60 * 60 * 1000;
265
- export const GEMINI_RPM_TRACKER_PATH = join(
266
- homedir(),
267
- ".claude",
268
- "cache",
269
- "gemini-rpm-tracker.json",
270
- );
271
- // 이전 .omc/ 경로 fallback (기존 환경 호환)
272
- export const LEGACY_GEMINI_QUOTA_CACHE = join(
273
- homedir(),
274
- ".omc",
275
- "state",
276
- "gemini_quota_cache.json",
277
- );
278
- export const LEGACY_GEMINI_PROJECT_CACHE = join(
279
- homedir(),
280
- ".omc",
281
- "state",
282
- "gemini_project_id.json",
283
- );
284
- export const LEGACY_GEMINI_SESSION_CACHE = join(
285
- homedir(),
286
- ".omc",
287
- "state",
288
- "gemini_session_tokens_cache.json",
289
- );
290
- export const LEGACY_GEMINI_RPM_TRACKER = join(
291
- homedir(),
292
- ".omc",
293
- "state",
294
- "gemini_rpm_tracker.json",
295
- );
296
-
297
- export const GEMINI_RPM_WINDOW_MS = 60 * 1000; // 60초 슬라이딩 윈도우
298
- export const GEMINI_QUOTA_STALE_MS = 5 * 60 * 1000; // 5분
299
- export const GEMINI_SESSION_STALE_MS = 30 * 1000; // 30초
300
- export const GEMINI_API_TIMEOUT_MS = 3000; // 3초
301
189
 
302
190
  export const ACCOUNT_LABEL_WIDTH = 10;
303
191
  export const PROVIDER_PREFIX_WIDTH = 2;
@@ -306,27 +194,8 @@ export const TIME_CELL_INNER_WIDTH = 6;
306
194
 
307
195
  export const CLAUDE_REFRESH_FLAG = "--refresh-claude-usage";
308
196
  export const CODEX_REFRESH_FLAG = "--refresh-codex-rate-limits";
309
- export const GEMINI_REFRESH_FLAG = "--refresh-gemini-quota";
310
- export const GEMINI_SESSION_REFRESH_FLAG = "--refresh-gemini-session";
311
197
 
312
198
  // 모바일/Termux 컴팩트 모드 감지
313
199
  export const HUD_CONFIG_PATH = join(homedir(), ".omc", "config", "hud.json");
314
200
  export const COMPACT_COLS_THRESHOLD = 80;
315
201
  export const MINIMAL_COLS_THRESHOLD = 60;
316
-
317
- // rows 임계값 상수 (selectTier 에서 tier 결정에 사용)
318
- export const ROWS_BUDGET_FULL = 40;
319
- export const ROWS_BUDGET_LARGE = 35;
320
- export const ROWS_BUDGET_MEDIUM = 28;
321
- export const ROWS_BUDGET_SMALL = 22;
322
-
323
- // Gemini Pro 풀 공유 그룹: 같은 remainingFraction을 공유하는 모델 ID들
324
- export const GEMINI_PRO_POOL = new Set([
325
- "gemini-2.5-pro",
326
- "gemini-3-pro-preview",
327
- "gemini-3.1-pro-preview",
328
- ]);
329
- export const GEMINI_FLASH_POOL = new Set([
330
- "gemini-2.5-flash",
331
- "gemini-3-flash-preview",
332
- ]);