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/hud/constants.mjs
CHANGED
|
@@ -6,24 +6,77 @@ import { join } from "node:path";
|
|
|
6
6
|
|
|
7
7
|
export const VERSION = "2.0";
|
|
8
8
|
|
|
9
|
-
export const QOS_PATH = join(
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
export const QOS_PATH = join(
|
|
10
|
+
homedir(),
|
|
11
|
+
".omc",
|
|
12
|
+
"state",
|
|
13
|
+
"cli_qos_profile.json",
|
|
14
|
+
);
|
|
15
|
+
export const ACCOUNTS_CONFIG_PATH = join(
|
|
16
|
+
homedir(),
|
|
17
|
+
".omc",
|
|
18
|
+
"router",
|
|
19
|
+
"accounts.json",
|
|
20
|
+
);
|
|
21
|
+
export const ACCOUNTS_STATE_PATH = join(
|
|
22
|
+
homedir(),
|
|
23
|
+
".omc",
|
|
24
|
+
"state",
|
|
25
|
+
"cli_accounts_state.json",
|
|
26
|
+
);
|
|
12
27
|
|
|
13
28
|
// tfx-multi 상태 (v2.2 HUD 통합)
|
|
14
|
-
export const TEAM_STATE_PATH = join(
|
|
15
|
-
|
|
16
|
-
|
|
29
|
+
export const TEAM_STATE_PATH = join(
|
|
30
|
+
homedir(),
|
|
31
|
+
".claude",
|
|
32
|
+
"cache",
|
|
33
|
+
"tfx-hub",
|
|
34
|
+
"team-state.json",
|
|
35
|
+
);
|
|
36
|
+
export const CONTEXT_MONITOR_CACHE_PATH = join(
|
|
37
|
+
homedir(),
|
|
38
|
+
".claude",
|
|
39
|
+
"cache",
|
|
40
|
+
"tfx-hub",
|
|
41
|
+
"context-monitor.json",
|
|
42
|
+
);
|
|
43
|
+
export const CONTEXT_MONITOR_LEGACY_PATH = join(
|
|
44
|
+
homedir(),
|
|
45
|
+
".omc",
|
|
46
|
+
"state",
|
|
47
|
+
"context-monitor.json",
|
|
48
|
+
);
|
|
17
49
|
export const CONTEXT_MONITOR_LOG_DIR = join(homedir(), ".omc", "logs");
|
|
18
50
|
|
|
19
51
|
// 원격 프로브 캐시 (tfx-remote-spawn)
|
|
20
|
-
export const REMOTE_ENV_CACHE_DIR = join(
|
|
52
|
+
export const REMOTE_ENV_CACHE_DIR = join(
|
|
53
|
+
homedir(),
|
|
54
|
+
".claude",
|
|
55
|
+
"cache",
|
|
56
|
+
"tfx-hub",
|
|
57
|
+
"remote-env",
|
|
58
|
+
);
|
|
21
59
|
export const REMOTE_ENV_CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24시간
|
|
22
60
|
|
|
23
61
|
// Claude OAuth Usage API (api.anthropic.com/api/oauth/usage)
|
|
24
|
-
export const CLAUDE_CREDENTIALS_PATH = join(
|
|
25
|
-
|
|
26
|
-
|
|
62
|
+
export const CLAUDE_CREDENTIALS_PATH = join(
|
|
63
|
+
homedir(),
|
|
64
|
+
".claude",
|
|
65
|
+
".credentials.json",
|
|
66
|
+
);
|
|
67
|
+
export const CLAUDE_USAGE_CACHE_PATH = join(
|
|
68
|
+
homedir(),
|
|
69
|
+
".claude",
|
|
70
|
+
"cache",
|
|
71
|
+
"claude-usage-cache.json",
|
|
72
|
+
);
|
|
73
|
+
export const OMC_PLUGIN_USAGE_CACHE_PATH = join(
|
|
74
|
+
homedir(),
|
|
75
|
+
".claude",
|
|
76
|
+
"plugins",
|
|
77
|
+
"oh-my-claudecode",
|
|
78
|
+
".usage-cache.json",
|
|
79
|
+
);
|
|
27
80
|
export const CLAUDE_USAGE_STALE_MS_SOLO = 5 * 60 * 1000; // OMC 없을 때: 5분 캐시
|
|
28
81
|
export const CLAUDE_USAGE_STALE_MS_WITH_OMC = 15 * 60 * 1000; // OMC 있을 때: 15분 (OMC가 30초마다 갱신)
|
|
29
82
|
export const CLAUDE_USAGE_429_BACKOFF_MS = 10 * 60 * 1000; // 429 에러 시 10분 backoff
|
|
@@ -38,29 +91,105 @@ export const ONE_DAY_MS = 24 * 60 * 60 * 1000;
|
|
|
38
91
|
export const DEFAULT_OAUTH_CLIENT_ID = "9d1c250a-e61b-44d9-88ed-5944d1962f5e";
|
|
39
92
|
|
|
40
93
|
export const CODEX_AUTH_PATH = join(homedir(), ".codex", "auth.json");
|
|
41
|
-
export const CODEX_QUOTA_CACHE_PATH = join(
|
|
94
|
+
export const CODEX_QUOTA_CACHE_PATH = join(
|
|
95
|
+
homedir(),
|
|
96
|
+
".claude",
|
|
97
|
+
"cache",
|
|
98
|
+
"codex-rate-limits-cache.json",
|
|
99
|
+
);
|
|
42
100
|
export const CODEX_QUOTA_STALE_MS = 30 * 1000; // 30초
|
|
43
101
|
export const CODEX_MIN_BUCKETS = 2;
|
|
44
102
|
|
|
45
103
|
// Spawn lock (중복 refresh 방지)
|
|
46
|
-
export const
|
|
47
|
-
|
|
48
|
-
|
|
104
|
+
export const CLAUDE_REFRESH_LOCK_PATH = join(
|
|
105
|
+
homedir(),
|
|
106
|
+
".claude",
|
|
107
|
+
"cache",
|
|
108
|
+
".claude-refresh-lock",
|
|
109
|
+
);
|
|
110
|
+
export const CODEX_REFRESH_LOCK_PATH = join(
|
|
111
|
+
homedir(),
|
|
112
|
+
".claude",
|
|
113
|
+
"cache",
|
|
114
|
+
".codex-refresh-lock",
|
|
115
|
+
);
|
|
116
|
+
export const GEMINI_QUOTA_REFRESH_LOCK_PATH = join(
|
|
117
|
+
homedir(),
|
|
118
|
+
".claude",
|
|
119
|
+
"cache",
|
|
120
|
+
".gemini-quota-refresh-lock",
|
|
121
|
+
);
|
|
122
|
+
export const GEMINI_SESSION_REFRESH_LOCK_PATH = join(
|
|
123
|
+
homedir(),
|
|
124
|
+
".claude",
|
|
125
|
+
"cache",
|
|
126
|
+
".gemini-session-refresh-lock",
|
|
127
|
+
);
|
|
49
128
|
export const SPAWN_LOCK_TTL_MS = 30 * 1000; // 30초 spawn dedup
|
|
50
129
|
|
|
51
130
|
// Gemini 쿼터 API 관련
|
|
52
131
|
export const GEMINI_OAUTH_PATH = join(homedir(), ".gemini", "oauth_creds.json");
|
|
53
|
-
export const GEMINI_QUOTA_CACHE_PATH = join(
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
132
|
+
export const GEMINI_QUOTA_CACHE_PATH = join(
|
|
133
|
+
homedir(),
|
|
134
|
+
".claude",
|
|
135
|
+
"cache",
|
|
136
|
+
"gemini-quota-cache.json",
|
|
137
|
+
);
|
|
138
|
+
export const GEMINI_PROJECT_CACHE_PATH = join(
|
|
139
|
+
homedir(),
|
|
140
|
+
".claude",
|
|
141
|
+
"cache",
|
|
142
|
+
"gemini-project-id.json",
|
|
143
|
+
);
|
|
144
|
+
export const GEMINI_SESSION_CACHE_PATH = join(
|
|
145
|
+
homedir(),
|
|
146
|
+
".claude",
|
|
147
|
+
"cache",
|
|
148
|
+
"gemini-session-cache.json",
|
|
149
|
+
);
|
|
150
|
+
export const GEMINI_RPM_TRACKER_PATH = join(
|
|
151
|
+
homedir(),
|
|
152
|
+
".claude",
|
|
153
|
+
"cache",
|
|
154
|
+
"gemini-rpm-tracker.json",
|
|
155
|
+
);
|
|
156
|
+
export const SV_ACCUMULATOR_PATH = join(
|
|
157
|
+
homedir(),
|
|
158
|
+
".claude",
|
|
159
|
+
"cache",
|
|
160
|
+
"sv-accumulator.json",
|
|
161
|
+
);
|
|
58
162
|
// 이전 .omc/ 경로 fallback (기존 환경 호환)
|
|
59
|
-
export const LEGACY_GEMINI_QUOTA_CACHE = join(
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
163
|
+
export const LEGACY_GEMINI_QUOTA_CACHE = join(
|
|
164
|
+
homedir(),
|
|
165
|
+
".omc",
|
|
166
|
+
"state",
|
|
167
|
+
"gemini_quota_cache.json",
|
|
168
|
+
);
|
|
169
|
+
export const LEGACY_GEMINI_PROJECT_CACHE = join(
|
|
170
|
+
homedir(),
|
|
171
|
+
".omc",
|
|
172
|
+
"state",
|
|
173
|
+
"gemini_project_id.json",
|
|
174
|
+
);
|
|
175
|
+
export const LEGACY_GEMINI_SESSION_CACHE = join(
|
|
176
|
+
homedir(),
|
|
177
|
+
".omc",
|
|
178
|
+
"state",
|
|
179
|
+
"gemini_session_tokens_cache.json",
|
|
180
|
+
);
|
|
181
|
+
export const LEGACY_GEMINI_RPM_TRACKER = join(
|
|
182
|
+
homedir(),
|
|
183
|
+
".omc",
|
|
184
|
+
"state",
|
|
185
|
+
"gemini_rpm_tracker.json",
|
|
186
|
+
);
|
|
187
|
+
export const LEGACY_SV_ACCUMULATOR = join(
|
|
188
|
+
homedir(),
|
|
189
|
+
".omc",
|
|
190
|
+
"state",
|
|
191
|
+
"sv-accumulator.json",
|
|
192
|
+
);
|
|
64
193
|
|
|
65
194
|
export const GEMINI_RPM_WINDOW_MS = 60 * 1000; // 60초 슬라이딩 윈도우
|
|
66
195
|
export const GEMINI_QUOTA_STALE_MS = 5 * 60 * 1000; // 5분
|
|
@@ -90,5 +219,12 @@ export const ROWS_BUDGET_MEDIUM = 28;
|
|
|
90
219
|
export const ROWS_BUDGET_SMALL = 22;
|
|
91
220
|
|
|
92
221
|
// Gemini Pro 풀 공유 그룹: 같은 remainingFraction을 공유하는 모델 ID들
|
|
93
|
-
export const GEMINI_PRO_POOL = new Set([
|
|
94
|
-
|
|
222
|
+
export const GEMINI_PRO_POOL = new Set([
|
|
223
|
+
"gemini-2.5-pro",
|
|
224
|
+
"gemini-3-pro-preview",
|
|
225
|
+
"gemini-3.1-pro-preview",
|
|
226
|
+
]);
|
|
227
|
+
export const GEMINI_FLASH_POOL = new Set([
|
|
228
|
+
"gemini-2.5-flash",
|
|
229
|
+
"gemini-3-flash-preview",
|
|
230
|
+
]);
|
package/hud/context-monitor.mjs
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
1
2
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
2
3
|
import { dirname, join } from "node:path";
|
|
3
|
-
import { randomUUID } from "node:crypto";
|
|
4
|
-
import { homedir } from "node:os";
|
|
5
4
|
|
|
6
5
|
import {
|
|
7
6
|
CONTEXT_MONITOR_CACHE_PATH,
|
|
@@ -72,21 +71,24 @@ function normalizeUsage(usage) {
|
|
|
72
71
|
const input = Number(usage.input_tokens ?? usage.inputTokens ?? 0);
|
|
73
72
|
const output = Number(usage.output_tokens ?? usage.outputTokens ?? 0);
|
|
74
73
|
const cacheCreation = Number(
|
|
75
|
-
usage.cache_creation_input_tokens
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
74
|
+
usage.cache_creation_input_tokens ??
|
|
75
|
+
usage.cacheCreationInputTokens ??
|
|
76
|
+
usage.cache_creation_tokens ??
|
|
77
|
+
0,
|
|
79
78
|
);
|
|
80
79
|
const cacheRead = Number(
|
|
81
|
-
usage.cache_read_input_tokens
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
80
|
+
usage.cache_read_input_tokens ??
|
|
81
|
+
usage.cacheReadInputTokens ??
|
|
82
|
+
usage.cache_read_tokens ??
|
|
83
|
+
0,
|
|
84
|
+
);
|
|
85
|
+
const totalCandidate = Number(
|
|
86
|
+
usage.total_tokens ?? usage.totalTokens ?? Number.NaN,
|
|
85
87
|
);
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
const total =
|
|
89
|
+
Number.isFinite(totalCandidate) && totalCandidate > 0
|
|
90
|
+
? totalCandidate
|
|
91
|
+
: input + output + cacheCreation + cacheRead;
|
|
90
92
|
if (!Number.isFinite(total) || total <= 0) return null;
|
|
91
93
|
return {
|
|
92
94
|
input: Math.max(0, Math.round(input)),
|
|
@@ -159,7 +161,10 @@ function extractFileKeys(args) {
|
|
|
159
161
|
function detectSkillHints(payloadText) {
|
|
160
162
|
if (!payloadText) return [];
|
|
161
163
|
const matches = payloadText.match(/\$[a-z0-9_-]+/gi) || [];
|
|
162
|
-
return Array.from(new Set(matches.map((m) => m.replace(/^\$/, "")))).slice(
|
|
164
|
+
return Array.from(new Set(matches.map((m) => m.replace(/^\$/, "")))).slice(
|
|
165
|
+
0,
|
|
166
|
+
5,
|
|
167
|
+
);
|
|
163
168
|
}
|
|
164
169
|
|
|
165
170
|
export function estimateTokens(input) {
|
|
@@ -172,21 +177,34 @@ export function parseUsageFromPayload(payload) {
|
|
|
172
177
|
|
|
173
178
|
export function classifyContextThreshold(percent) {
|
|
174
179
|
const p = clampThresholdPercent(percent);
|
|
175
|
-
if (p >= WARNING_LEVELS.critical.min)
|
|
176
|
-
|
|
177
|
-
if (p >= WARNING_LEVELS.
|
|
180
|
+
if (p >= WARNING_LEVELS.critical.min)
|
|
181
|
+
return { level: "critical", message: WARNING_LEVELS.critical.message };
|
|
182
|
+
if (p >= WARNING_LEVELS.warn.min)
|
|
183
|
+
return { level: "warn", message: WARNING_LEVELS.warn.message };
|
|
184
|
+
if (p >= WARNING_LEVELS.info.min)
|
|
185
|
+
return { level: "info", message: WARNING_LEVELS.info.message };
|
|
178
186
|
return { level: "ok", message: "" };
|
|
179
187
|
}
|
|
180
188
|
|
|
181
189
|
export function formatContextUsage(usedTokens, limitTokens, percent = null) {
|
|
182
190
|
const used = Math.max(0, Math.round(Number(usedTokens) || 0));
|
|
183
|
-
const limit = Math.max(
|
|
184
|
-
|
|
191
|
+
const limit = Math.max(
|
|
192
|
+
1,
|
|
193
|
+
Math.round(Number(limitTokens) || DEFAULT_CONTEXT_LIMIT),
|
|
194
|
+
);
|
|
195
|
+
const pct =
|
|
196
|
+
percent == null
|
|
197
|
+
? clampPercent((used / limit) * 100)
|
|
198
|
+
: clampPercent(percent);
|
|
185
199
|
return `${formatTokenCount(used)}/${formatTokenCount(limit)} (${pct}%)`;
|
|
186
200
|
}
|
|
187
201
|
|
|
188
202
|
export function readContextMonitorSnapshot() {
|
|
189
|
-
return readJsonMigrate(
|
|
203
|
+
return readJsonMigrate(
|
|
204
|
+
CONTEXT_MONITOR_CACHE_PATH,
|
|
205
|
+
CONTEXT_MONITOR_LEGACY_PATH,
|
|
206
|
+
null,
|
|
207
|
+
);
|
|
190
208
|
}
|
|
191
209
|
|
|
192
210
|
function getStdinContextUsage(stdin) {
|
|
@@ -194,9 +212,10 @@ function getStdinContextUsage(stdin) {
|
|
|
194
212
|
const nativePercent = Number(stdin?.context_window?.used_percentage);
|
|
195
213
|
const usage = stdin?.context_window?.current_usage || {};
|
|
196
214
|
const explicitUsed = Number(usage.total_tokens || 0);
|
|
197
|
-
const calculatedUsed =
|
|
198
|
-
|
|
199
|
-
|
|
215
|
+
const calculatedUsed =
|
|
216
|
+
Number(usage.input_tokens || 0) +
|
|
217
|
+
Number(usage.cache_creation_input_tokens || 0) +
|
|
218
|
+
Number(usage.cache_read_input_tokens || 0);
|
|
200
219
|
const usedTokens = explicitUsed > 0 ? explicitUsed : calculatedUsed;
|
|
201
220
|
|
|
202
221
|
if (limitTokens > 0 && usedTokens > 0) {
|
|
@@ -225,12 +244,11 @@ export function buildContextUsageView(stdin, snapshot = null) {
|
|
|
225
244
|
const monitor = snapshot || readContextMonitorSnapshot();
|
|
226
245
|
const fallbackLimit = Number(monitor?.limitTokens || DEFAULT_CONTEXT_LIMIT);
|
|
227
246
|
|
|
228
|
-
const usedTokens = stdinUsage?.usedTokens
|
|
229
|
-
|
|
230
|
-
const
|
|
231
|
-
??
|
|
232
|
-
|
|
233
|
-
?? (limitTokens > 0 ? clampPercent((usedTokens / limitTokens) * 100) : 0);
|
|
247
|
+
const usedTokens = stdinUsage?.usedTokens ?? Number(monitor?.usedTokens || 0);
|
|
248
|
+
const limitTokens = stdinUsage?.limitTokens ?? Math.max(1, fallbackLimit);
|
|
249
|
+
const percent =
|
|
250
|
+
stdinUsage?.percent ??
|
|
251
|
+
(limitTokens > 0 ? clampPercent((usedTokens / limitTokens) * 100) : 0);
|
|
234
252
|
|
|
235
253
|
const warning = classifyContextThreshold(percent);
|
|
236
254
|
return {
|
|
@@ -240,10 +258,14 @@ export function buildContextUsageView(stdin, snapshot = null) {
|
|
|
240
258
|
display: formatContextUsage(usedTokens, limitTokens, percent),
|
|
241
259
|
warningLevel: warning.level,
|
|
242
260
|
warningMessage: warning.message,
|
|
243
|
-
warningTag:
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
261
|
+
warningTag:
|
|
262
|
+
warning.level === "warn"
|
|
263
|
+
? "⚠ 압축 권장"
|
|
264
|
+
: warning.level === "critical"
|
|
265
|
+
? "‼ 분할 권장"
|
|
266
|
+
: warning.level === "info"
|
|
267
|
+
? "ℹ 절반 이상 사용"
|
|
268
|
+
: "",
|
|
247
269
|
source: stdinUsage?.source || (monitor ? "monitor" : "none"),
|
|
248
270
|
};
|
|
249
271
|
}
|
|
@@ -295,7 +317,10 @@ export function createContextMonitor(options = {}) {
|
|
|
295
317
|
const percent = clampPercent((state.usedTokens / state.limitTokens) * 100);
|
|
296
318
|
const warning = classifyContextThreshold(percent);
|
|
297
319
|
const ts = new Date().toISOString().replace(/[:.]/g, "-");
|
|
298
|
-
const reportPath = join(
|
|
320
|
+
const reportPath = join(
|
|
321
|
+
logsDir,
|
|
322
|
+
`context-usage-${state.sessionId}-${ts}.json`,
|
|
323
|
+
);
|
|
299
324
|
safeWriteJson(reportPath, {
|
|
300
325
|
sessionId: state.sessionId,
|
|
301
326
|
reason,
|
|
@@ -329,17 +354,31 @@ export function createContextMonitor(options = {}) {
|
|
|
329
354
|
toolName = "",
|
|
330
355
|
} = {}) => {
|
|
331
356
|
const started = process.hrtime.bigint();
|
|
332
|
-
const reqObj =
|
|
333
|
-
|
|
357
|
+
const reqObj =
|
|
358
|
+
typeof requestBody === "object"
|
|
359
|
+
? requestBody
|
|
360
|
+
: safeJsonParse(String(requestBody || ""));
|
|
361
|
+
const resObj =
|
|
362
|
+
typeof responseBody === "object"
|
|
363
|
+
? responseBody
|
|
364
|
+
: safeJsonParse(String(responseBody || ""));
|
|
334
365
|
|
|
335
366
|
const usage = parseUsageFromPayload(resObj);
|
|
336
|
-
const requestTokens =
|
|
337
|
-
|
|
367
|
+
const requestTokens =
|
|
368
|
+
requestBytes > 0
|
|
369
|
+
? toTokenEstimate(requestBytes)
|
|
370
|
+
: toTokenEstimate(requestBody);
|
|
371
|
+
const responseTokens =
|
|
372
|
+
usage?.total ??
|
|
373
|
+
(responseBytes > 0
|
|
374
|
+
? toTokenEstimate(responseBytes)
|
|
375
|
+
: toTokenEstimate(responseBody));
|
|
338
376
|
const totalTokens = Math.max(0, requestTokens + responseTokens);
|
|
339
377
|
|
|
340
378
|
const method = reqObj?.method || reqObj?.params?.name || "";
|
|
341
379
|
const name = toolName || reqObj?.params?.name || reqObj?.tool || "";
|
|
342
|
-
const args =
|
|
380
|
+
const args =
|
|
381
|
+
reqObj?.params?.arguments || reqObj?.arguments || reqObj?.params || {};
|
|
343
382
|
const payloadText = normalizeText(requestBody).slice(0, MAX_CAPTURE_BYTES);
|
|
344
383
|
const skills = detectSkillHints(payloadText);
|
|
345
384
|
const files = extractFileKeys(args);
|
|
@@ -383,7 +422,9 @@ export function createContextMonitor(options = {}) {
|
|
|
383
422
|
|
|
384
423
|
if (registerExitHooks) {
|
|
385
424
|
const flushOnExit = () => {
|
|
386
|
-
try {
|
|
425
|
+
try {
|
|
426
|
+
flush("process.exit");
|
|
427
|
+
} catch {}
|
|
387
428
|
};
|
|
388
429
|
process.once("exit", flushOnExit);
|
|
389
430
|
process.once("SIGINT", flushOnExit);
|