@triflux/core 10.50.1 → 10.51.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.
Files changed (90) hide show
  1. package/hooks/agy-session-hook.mjs +11 -56
  2. package/hooks/codex-session-hook.mjs +11 -101
  3. package/hub/bridge.mjs +1 -79
  4. package/hub/cli-adapter-base.mjs +12 -90
  5. package/hub/codex-adapter.mjs +0 -1
  6. package/hub/codex-preflight.mjs +5 -28
  7. package/hub/index.mjs +3 -9
  8. package/hub/lib/cto-env.mjs +0 -23
  9. package/hub/lib/known-errors.json +2 -2
  10. package/hub/lib/process-utils.mjs +0 -123
  11. package/hub/lib/spawn-trace.mjs +3 -2
  12. package/hub/lib/timeout-defaults.mjs +0 -1
  13. package/hub/paths.mjs +0 -6
  14. package/hub/pipeline/index.mjs +0 -190
  15. package/hub/pipeline/transitions.mjs +0 -10
  16. package/hub/reflexion.mjs +1 -84
  17. package/hub/role-contract.mjs +0 -2
  18. package/hud/cli-policy.mjs +0 -26
  19. package/hud/colors.mjs +0 -13
  20. package/hud/constants.mjs +7 -153
  21. package/hud/context-monitor.mjs +3 -64
  22. package/hud/hud-qos-status.mjs +54 -264
  23. package/hud/providers/claude.mjs +4 -16
  24. package/hud/providers/gemini.mjs +83 -689
  25. package/hud/renderers.mjs +59 -367
  26. package/hud/terminal.mjs +1 -63
  27. package/hud/utils.mjs +2 -26
  28. package/package.json +1 -4
  29. package/scripts/lib/agent-route-policy.mjs +162 -14
  30. package/scripts/lib/claudemd-scanner.mjs +2 -199
  31. package/scripts/lib/cli-claude.mjs +0 -2
  32. package/scripts/lib/context.mjs +3 -19
  33. package/scripts/lib/env-probe.mjs +5 -64
  34. package/scripts/lib/gemini-profiles.mjs +2 -69
  35. package/scripts/lib/legacy-mcp-cleanup.mjs +14 -3
  36. package/scripts/lib/machine-profile.mjs +3 -17
  37. package/scripts/lib/mcp-filter.mjs +109 -53
  38. package/scripts/lib/mcp-health.mjs +2 -2
  39. package/scripts/lib/mcp-server-catalog.mjs +2 -2
  40. package/scripts/lib/psmux-info.mjs +25 -104
  41. package/scripts/lib/session-presence.mjs +1 -1
  42. package/scripts/lib/skill-template.mjs +0 -271
  43. package/hub/codex-compat.mjs +0 -12
  44. package/hub/dynamic-routing-engine.mjs +0 -511
  45. package/hub/fullcycle.mjs +0 -113
  46. package/hub/gemini-adapter.mjs +0 -174
  47. package/hub/intent.mjs +0 -321
  48. package/hub/lib/mcp-response-cache.mjs +0 -239
  49. package/hub/lib/path-utils.mjs +0 -165
  50. package/hub/lib/risk-tier.mjs +0 -53
  51. package/hub/lib/ssh-command.mjs +0 -231
  52. package/hub/lib/staged-file-detect.mjs +0 -43
  53. package/hub/lib/tfx-route-args.mjs +0 -353
  54. package/hub/lib/timeline-adapter.mjs +0 -190
  55. package/hub/pipeline/gates/confidence.mjs +0 -75
  56. package/hub/pipeline/gates/consensus.mjs +0 -106
  57. package/hub/pipeline/gates/index.mjs +0 -9
  58. package/hub/pipeline/gates/selfcheck.mjs +0 -120
  59. package/hub/quality/deslop.mjs +0 -274
  60. package/hub/research.mjs +0 -155
  61. package/hub/role-control-events.mjs +0 -113
  62. package/hub/routing/complexity.mjs +0 -269
  63. package/hub/routing/index.mjs +0 -122
  64. package/hub/routing/q-learning.mjs +0 -387
  65. package/hub/routing-snapshot.mjs +0 -261
  66. package/hub/token-mode.mjs +0 -228
  67. package/hud/mission-board.mjs +0 -56
  68. package/hud/providers/cto.mjs +0 -76
  69. package/mesh/index.mjs +0 -69
  70. package/mesh/mesh-budget.mjs +0 -137
  71. package/mesh/mesh-heartbeat.mjs +0 -100
  72. package/mesh/mesh-protocol.mjs +0 -96
  73. package/mesh/mesh-queue.mjs +0 -163
  74. package/mesh/mesh-registry.mjs +0 -78
  75. package/mesh/mesh-router.mjs +0 -77
  76. package/scripts/lib/agent-json.mjs +0 -27
  77. package/scripts/lib/async.mjs +0 -174
  78. package/scripts/lib/cli-agy.mjs +0 -85
  79. package/scripts/lib/cli-codex.mjs +0 -62
  80. package/scripts/lib/cli-gemini.mjs +0 -37
  81. package/scripts/lib/dynamic-route-cli.mjs +0 -107
  82. package/scripts/lib/env.mjs +0 -14
  83. package/scripts/lib/hub.mjs +0 -48
  84. package/scripts/lib/pid.mjs +0 -63
  85. package/scripts/lib/quota.mjs +0 -47
  86. package/scripts/lib/skill-state.mjs +0 -220
  87. package/scripts/lib/team.mjs +0 -75
  88. package/scripts/lib/timeout.mjs +0 -66
  89. package/scripts/lib/tmp.mjs +0 -26
  90. package/scripts/lib/toml.mjs +0 -132
@@ -1,113 +0,0 @@
1
- const EVENT_NAMES = new Set(["capability.degraded", "drift.detected"]);
2
- const CONTROL_ACTIONS = new Set([
3
- "log_only",
4
- "candidate_exclude",
5
- "adapter_disable",
6
- "role_failover",
7
- "dispatch_block",
8
- "manager_disable",
9
- ]);
10
- const OPTIONAL_FIELDS = [
11
- "project_id",
12
- "role_key_wire",
13
- "candidate_agent_id",
14
- "transport_id",
15
- "capability",
16
- "expected_version",
17
- "observed_version",
18
- "trace_id",
19
- "error_code",
20
- ];
21
-
22
- export const ROLE_CONTROL_EVENT_SCHEMA_VERSION = "tfx.role-control-event.v1";
23
- export const ROLE_CONTROL_EVENT_FIELDS = Object.freeze([
24
- "schema_version",
25
- "event",
26
- "event_id",
27
- "module",
28
- "dur_ms",
29
- "control_action",
30
- "reason_code",
31
- ...OPTIONAL_FIELDS,
32
- ]);
33
-
34
- function eventError(code, message = code) {
35
- const error = new Error(message);
36
- error.code = code;
37
- return error;
38
- }
39
-
40
- function defaultEventId() {
41
- return (
42
- globalThis.crypto?.randomUUID?.() ??
43
- `evt_${Math.random().toString(36).slice(2)}`
44
- );
45
- }
46
-
47
- function validateRequired(event) {
48
- if (!EVENT_NAMES.has(event.event))
49
- throw eventError("ROLE_CONTROL_EVENT_INVALID");
50
- if (typeof event.event_id !== "string" || !event.event_id) {
51
- throw eventError("ROLE_CONTROL_EVENT_REQUIRED");
52
- }
53
- if (typeof event.module !== "string" || !event.module) {
54
- throw eventError("ROLE_CONTROL_EVENT_REQUIRED");
55
- }
56
- if (!Number.isFinite(event.dur_ms) || event.dur_ms < 0) {
57
- throw eventError("ROLE_CONTROL_EVENT_REQUIRED");
58
- }
59
- if (!CONTROL_ACTIONS.has(event.control_action)) {
60
- throw eventError("ROLE_CONTROL_EVENT_REQUIRED");
61
- }
62
- if (typeof event.reason_code !== "string" || !event.reason_code) {
63
- throw eventError("ROLE_CONTROL_EVENT_REQUIRED");
64
- }
65
- }
66
-
67
- /**
68
- * Build an allowlisted event object. Unknown domain fields are intentionally
69
- * discarded before the event reaches a logger.
70
- */
71
- export function buildRoleControlEvent(
72
- input = {},
73
- { eventId = defaultEventId } = {},
74
- ) {
75
- const event = {
76
- schema_version: ROLE_CONTROL_EVENT_SCHEMA_VERSION,
77
- event: input.event,
78
- event_id: input.event_id ?? eventId(),
79
- module: input.module,
80
- dur_ms: input.dur_ms,
81
- control_action: input.control_action,
82
- reason_code: input.reason_code,
83
- };
84
- for (const field of OPTIONAL_FIELDS) {
85
- if (input[field] !== undefined) event[field] = input[field];
86
- }
87
- validateRequired(event);
88
- return event;
89
- }
90
-
91
- export function buildCapabilityDegradedEvent(input = {}, options = {}) {
92
- return buildRoleControlEvent(
93
- { ...input, event: "capability.degraded" },
94
- options,
95
- );
96
- }
97
-
98
- export function buildDriftDetectedEvent(input = {}, options = {}) {
99
- return buildRoleControlEvent({ ...input, event: "drift.detected" }, options);
100
- }
101
-
102
- /**
103
- * Pino-style loggers receive event as an object field and as the message.
104
- */
105
- export function emitRoleControlEvent(log, event, level = "warn") {
106
- if (!log || typeof log[level] !== "function") {
107
- throw eventError("ROLE_CONTROL_LOGGER_INVALID");
108
- }
109
- const sanitized = buildRoleControlEvent(event, {
110
- eventId: () => event?.event_id,
111
- });
112
- log[level](sanitized, sanitized.event);
113
- }
@@ -1,269 +0,0 @@
1
- // hub/routing/complexity.mjs — 작업 복잡도 스코어링
2
- // 작업 설명 텍스트에서 복잡도를 0-1 범위로 계산한다.
3
- // 외부 의존성 없음 (순수 텍스트 분석)
4
-
5
- /**
6
- * 복잡도 지표 키워드 사전
7
- * 카테고리별 키워드와 가중치 (0-1)
8
- */
9
- const COMPLEXITY_INDICATORS = {
10
- // 높은 복잡도 (0.7-1.0)
11
- high: {
12
- keywords: [
13
- "refactor",
14
- "architecture",
15
- "security",
16
- "migration",
17
- "distributed",
18
- "concurrent",
19
- "parallel",
20
- "optimization",
21
- "performance",
22
- "scalability",
23
- "cryptograph",
24
- "encryption",
25
- "authentication",
26
- "authorization",
27
- "database schema",
28
- "data model",
29
- "state machine",
30
- "event-driven",
31
- "microservice",
32
- "orchestrat",
33
- "pipeline",
34
- "workflow",
35
- // 한국어
36
- "리팩터링",
37
- "리팩토링",
38
- "아키텍처",
39
- "보안",
40
- "마이그레이션",
41
- "분산",
42
- "동시성",
43
- "병렬",
44
- "최적화",
45
- "성능",
46
- "확장성",
47
- "암호화",
48
- "인증",
49
- "인가",
50
- "데이터베이스 스키마",
51
- "데이터 모델",
52
- "상태 머신",
53
- "이벤트 드리븐",
54
- "마이크로서비스",
55
- "오케스트레이션",
56
- ],
57
- weight: 0.85,
58
- },
59
- // 중간 복잡도 (0.4-0.7)
60
- medium: {
61
- keywords: [
62
- "implement",
63
- "integrate",
64
- "api",
65
- "endpoint",
66
- "middleware",
67
- "validation",
68
- "error handling",
69
- "testing",
70
- "debug",
71
- "fix bug",
72
- "configuration",
73
- "deploy",
74
- "ci/cd",
75
- "docker",
76
- "container",
77
- "cache",
78
- "queue",
79
- "webhook",
80
- "notification",
81
- "logging",
82
- // 한국어
83
- "구현",
84
- "통합",
85
- "엔드포인트",
86
- "미들웨어",
87
- "유효성 검사",
88
- "에러 처리",
89
- "오류 처리",
90
- "테스트",
91
- "디버깅",
92
- "버그 수정",
93
- "설정",
94
- "배포",
95
- "컨테이너",
96
- "캐시",
97
- "알림",
98
- "로깅",
99
- ],
100
- weight: 0.55,
101
- },
102
- // 낮은 복잡도 (0.1-0.4)
103
- low: {
104
- keywords: [
105
- "readme",
106
- "comment",
107
- "typo",
108
- "rename",
109
- "format",
110
- "lint",
111
- "update version",
112
- "bump",
113
- "add dependency",
114
- "install",
115
- "simple",
116
- "trivial",
117
- "minor",
118
- "small change",
119
- "one-liner",
120
- // 한국어
121
- "문서화",
122
- "주석",
123
- "오타",
124
- "이름 변경",
125
- "포맷",
126
- "버전 업데이트",
127
- "의존성 추가",
128
- "설치",
129
- "간단",
130
- "사소한",
131
- "소규모",
132
- "한 줄",
133
- ],
134
- weight: 0.2,
135
- },
136
- };
137
-
138
- /**
139
- * 어휘 복잡도 계산 (20%)
140
- * 고유 단어 비율 + 평균 단어 길이 기반
141
- * @param {string[]} words
142
- * @returns {number} 0-1
143
- */
144
- function lexicalComplexity(words) {
145
- if (words.length === 0) return 0;
146
- const unique = new Set(words);
147
- const typeTokenRatio = unique.size / words.length;
148
- const avgWordLen = words.reduce((sum, w) => sum + w.length, 0) / words.length;
149
- // 긴 단어(기술 용어)가 많을수록 복잡
150
- const lenScore = Math.min(avgWordLen / 10, 1);
151
- return typeTokenRatio * 0.5 + lenScore * 0.5;
152
- }
153
-
154
- /**
155
- * 시맨틱 깊이 계산 (35%)
156
- * 키워드 사전 매칭 기반
157
- * @param {string} text
158
- * @returns {number} 0-1
159
- */
160
- function semanticDepth(text) {
161
- const lower = text.toLowerCase();
162
- let maxWeight = 0;
163
- let matchCount = 0;
164
-
165
- for (const [, category] of Object.entries(COMPLEXITY_INDICATORS)) {
166
- for (const kw of category.keywords) {
167
- if (lower.includes(kw)) {
168
- matchCount++;
169
- if (category.weight > maxWeight) maxWeight = category.weight;
170
- }
171
- }
172
- }
173
- // 매칭 키워드 수와 최고 가중치 조합
174
- const countScore = Math.min(matchCount / 5, 1);
175
- return maxWeight * 0.6 + countScore * 0.4;
176
- }
177
-
178
- /**
179
- * 작업 범위 계산 (25%)
180
- * 문장 수, 줄 수, 파일/경로 참조 기반
181
- * @param {string} text
182
- * @returns {number} 0-1
183
- */
184
- function taskScope(text) {
185
- const lines = text.split("\n").filter((l) => l.trim().length > 0);
186
- const sentences = text.split(/[.!?]+/).filter((s) => s.trim().length > 0);
187
- const fileRefs = (text.match(/[\w\-/]+\.\w{1,5}/g) || []).length;
188
-
189
- const lineScore = Math.min(lines.length / 20, 1);
190
- const sentenceScore = Math.min(sentences.length / 10, 1);
191
- const fileScore = Math.min(fileRefs / 5, 1);
192
-
193
- return lineScore * 0.3 + sentenceScore * 0.3 + fileScore * 0.4;
194
- }
195
-
196
- /**
197
- * 불확실성 계산 (20%)
198
- * 모호한 표현, 질문, 조건문 기반
199
- * @param {string} text
200
- * @returns {number} 0-1
201
- */
202
- function uncertainty(text) {
203
- const lower = text.toLowerCase();
204
- const uncertainWords = [
205
- "maybe",
206
- "perhaps",
207
- "might",
208
- "could",
209
- "possibly",
210
- "unclear",
211
- "not sure",
212
- "investigate",
213
- "explore",
214
- "research",
215
- "try",
216
- "consider",
217
- "evaluate",
218
- "assess",
219
- "determine",
220
- "figure out",
221
- ];
222
- let count = 0;
223
- for (const w of uncertainWords) {
224
- if (lower.includes(w)) count++;
225
- }
226
- const questions = (text.match(/\?/g) || []).length;
227
- const wordScore = Math.min(count / 4, 1);
228
- const questionScore = Math.min(questions / 3, 1);
229
- return wordScore * 0.6 + questionScore * 0.4;
230
- }
231
-
232
- /**
233
- * 작업 복잡도 스코어링
234
- * @param {string} taskDescription — 작업 설명 텍스트
235
- * @returns {{ score: number, breakdown: { lexical: number, semantic: number, scope: number, uncertainty: number } }}
236
- */
237
- export function scoreComplexity(taskDescription) {
238
- if (!taskDescription || typeof taskDescription !== "string") {
239
- return {
240
- score: 0,
241
- breakdown: { lexical: 0, semantic: 0, scope: 0, uncertainty: 0 },
242
- };
243
- }
244
-
245
- const words = taskDescription
246
- .toLowerCase()
247
- .split(/\s+/)
248
- .filter((w) => w.length > 0);
249
- const lexical = lexicalComplexity(words);
250
- const semantic = semanticDepth(taskDescription);
251
- const scope = taskScope(taskDescription);
252
- const uncertain = uncertainty(taskDescription);
253
-
254
- // 가중 합산: 어휘(20%) + 시맨틱(35%) + 범위(25%) + 불확실성(20%)
255
- const score = Math.min(
256
- lexical * 0.2 + semantic * 0.35 + scope * 0.25 + uncertain * 0.2,
257
- 1,
258
- );
259
-
260
- return {
261
- score: Math.round(score * 1000) / 1000,
262
- breakdown: {
263
- lexical: Math.round(lexical * 1000) / 1000,
264
- semantic: Math.round(semantic * 1000) / 1000,
265
- scope: Math.round(scope * 1000) / 1000,
266
- uncertainty: Math.round(uncertain * 1000) / 1000,
267
- },
268
- };
269
- }
@@ -1,122 +0,0 @@
1
- // hub/routing/index.mjs — 통합 라우팅 진입점
2
- // Q-Learning 동적 라우팅 + agent-map.json 정적 폴백
3
- // 환경변수 TRIFLUX_DYNAMIC_ROUTING=true 로 옵트인 (기본 false)
4
-
5
- import { createRequire } from "node:module";
6
- import { scoreComplexity } from "./complexity.mjs";
7
- import { QLearningRouter } from "./q-learning.mjs";
8
-
9
- const _require = createRequire(import.meta.url);
10
-
11
- /** agent-map.json 정적 매핑 */
12
- let AGENT_MAP;
13
- try {
14
- AGENT_MAP = _require("../team/agent-map.json");
15
- } catch {
16
- AGENT_MAP = {};
17
- }
18
-
19
- /** 싱글턴 라우터 인스턴스 (lazy init) */
20
- let _router = null;
21
-
22
- /**
23
- * 라우터 인스턴스 획득 (lazy singleton)
24
- * @returns {QLearningRouter}
25
- */
26
- function getRouter() {
27
- if (!_router) {
28
- _router = new QLearningRouter();
29
- _router.load();
30
- }
31
- return _router;
32
- }
33
-
34
- /**
35
- * 동적 라우팅 활성화 여부
36
- * @returns {boolean}
37
- */
38
- function isDynamicRoutingEnabled() {
39
- const env = process.env.TRIFLUX_DYNAMIC_ROUTING;
40
- return env === "true" || env === "1";
41
- }
42
-
43
- /**
44
- * 통합 라우팅 결정
45
- * 우선순위: Q-Learning 예측 (신뢰도 >= 0.6) -> agent-map.json 기본값
46
- *
47
- * @param {string} agentType — 에이전트 역할명 ("executor", "designer" 등)
48
- * @param {string} [taskDescription=''] — 작업 설명 (동적 라우팅용)
49
- * @returns {{ cliType: string, source: 'dynamic' | 'static', confidence: number, complexity: number }}
50
- */
51
- export function resolveRoute(agentType, taskDescription = "") {
52
- // 정적 기본값
53
- const staticCli = AGENT_MAP[agentType] || agentType;
54
- const { score: complexity } = scoreComplexity(taskDescription);
55
-
56
- // 동적 라우팅 비활성화 시 정적 매핑 반환
57
- if (!isDynamicRoutingEnabled()) {
58
- return { cliType: staticCli, source: "static", confidence: 1, complexity };
59
- }
60
-
61
- // 작업 설명 없으면 정적 폴백
62
- if (!taskDescription || taskDescription.trim().length === 0) {
63
- return { cliType: staticCli, source: "static", confidence: 1, complexity };
64
- }
65
-
66
- const router = getRouter();
67
- const prediction = router.predict(taskDescription);
68
-
69
- // 신뢰도 기준 미달 시 정적 폴백
70
- if (prediction.confidence < 0.6) {
71
- return {
72
- cliType: staticCli,
73
- source: "static",
74
- confidence: prediction.confidence,
75
- complexity,
76
- };
77
- }
78
-
79
- return {
80
- cliType: prediction.action,
81
- source: "dynamic",
82
- confidence: prediction.confidence,
83
- complexity,
84
- };
85
- }
86
-
87
- /**
88
- * 라우팅 피드백 업데이트
89
- * @param {string} taskDescription — 작업 설명
90
- * @param {string} action — 수행한 CLI 타입
91
- * @param {number} reward — 보상 (-1 ~ 1)
92
- * @param {boolean} [persist=true] — 영속화 여부
93
- */
94
- export function updateRoute(taskDescription, action, reward, persist = true) {
95
- if (!isDynamicRoutingEnabled()) return;
96
-
97
- const router = getRouter();
98
- router.update(taskDescription, action, reward);
99
- if (persist) router.save();
100
- }
101
-
102
- /**
103
- * 라우터 상태 조회 (진단용)
104
- * @returns {{ enabled: boolean, epsilon: number, totalUpdates: number, stateCount: number }}
105
- */
106
- export function routerStatus() {
107
- const enabled = isDynamicRoutingEnabled();
108
- if (!enabled) {
109
- return { enabled, epsilon: 0, totalUpdates: 0, stateCount: 0 };
110
- }
111
- const router = getRouter();
112
- return {
113
- enabled,
114
- epsilon: router.epsilon,
115
- totalUpdates: router.totalUpdates,
116
- stateCount: router.stateCount,
117
- };
118
- }
119
-
120
- // re-export for convenience
121
- export { scoreComplexity } from "./complexity.mjs";
122
- export { ACTIONS, QLearningRouter } from "./q-learning.mjs";