@triflux/core 10.43.0 → 10.45.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 (41) hide show
  1. package/hooks/codex-session-hook.mjs +67 -1
  2. package/hooks/cto-north-star-brief.mjs +3 -16
  3. package/hooks/error-context.mjs +3 -6
  4. package/hooks/hook-manager.mjs +1 -1
  5. package/hooks/hook-registry.json +0 -11
  6. package/hooks/keyword-rules.json +147 -23
  7. package/hooks/permission-safe-allow.mjs +36 -2
  8. package/hooks/session-start-fast.mjs +50 -1
  9. package/hooks/session-start-lake.mjs +3 -16
  10. package/hub/bridge.mjs +111 -5
  11. package/hub/cli-adapter-base.mjs +11 -2
  12. package/hub/codex-adapter.mjs +3 -0
  13. package/hub/gemini-adapter.mjs +29 -11
  14. package/hub/intent.mjs +24 -32
  15. package/hub/lib/memory-store.mjs +66 -30
  16. package/hub/lib/tfx-route-args.mjs +41 -4
  17. package/hub/reflexion.mjs +0 -57
  18. package/hub/router.mjs +474 -24
  19. package/hub/team/claude-daemon-control.mjs +2 -0
  20. package/hub/team/intervention.mjs +1 -1
  21. package/hub/team/retry-state-machine.mjs +41 -13
  22. package/hub/team/synapse-http.mjs +149 -4
  23. package/hud/cli-policy.mjs +69 -0
  24. package/hud/constants.mjs +20 -17
  25. package/hud/context-monitor.mjs +31 -21
  26. package/hud/hud-qos-status.mjs +81 -91
  27. package/hud/providers/claude.mjs +150 -84
  28. package/hud/providers/codex.mjs +10 -1
  29. package/hud/renderers.mjs +21 -59
  30. package/hud/utils.mjs +1 -15
  31. package/package.json +1 -1
  32. package/scripts/lib/agent-route-policy.mjs +367 -0
  33. package/scripts/lib/cli-agy.mjs +24 -4
  34. package/scripts/lib/cli-codex.mjs +22 -160
  35. package/scripts/lib/codex-profile-config.mjs +48 -4
  36. package/scripts/lib/gemini-profiles.mjs +113 -29
  37. package/scripts/lib/keyword-rules.mjs +24 -0
  38. package/scripts/lib/logger.mjs +60 -43
  39. package/scripts/lib/machine-profile.mjs +293 -0
  40. package/scripts/lib/mcp-health.mjs +44 -18
  41. package/hub/log-retention.mjs +0 -726
@@ -8,11 +8,12 @@
8
8
  //
9
9
  // 기존 플래그 (Phase 2 v10.9.33+):
10
10
  // --cli {auto|codex|antigravity|claude}
11
- // --mode {quick|deep|consensus}
11
+ // --mode {quick|deep|consensus|live}
12
12
  // --parallel {1|N|swarm}
13
13
  // --retry {0|1|ralph|auto-escalate} (Phase 3 에서 ralph/auto-escalate 신규)
14
14
  // --isolation {none|worktree}
15
15
  // --remote {none|<host>}
16
+ // --rounds <N> (--mode live 전용, 기본 4)
16
17
  //
17
18
  // Phase 3 신규:
18
19
  // --lead {claude|codex} (tfx-auto-codex 의미 흡수)
@@ -31,11 +32,12 @@ export const DEFAULT_OPTIONS = Object.freeze({
31
32
  lead: "claude",
32
33
  noClaudeNative: false,
33
34
  maxIterations: 0,
35
+ rounds: 4,
34
36
  });
35
37
 
36
38
  const VALID_VALUES = Object.freeze({
37
39
  cli: ["auto", "codex", "antigravity", "claude"],
38
- mode: ["quick", "deep", "consensus"],
40
+ mode: ["quick", "deep", "consensus", "live"],
39
41
  retry: ["0", "1", "ralph", "auto-escalate"],
40
42
  isolation: ["none", "worktree"],
41
43
  lead: ["claude", "codex"],
@@ -50,6 +52,7 @@ const VALUE_FLAGS = new Set([
50
52
  "--remote",
51
53
  "--lead",
52
54
  "--max-iterations",
55
+ "--rounds",
53
56
  ]);
54
57
 
55
58
  const BOOL_FLAGS = new Set(["--no-claude-native"]);
@@ -61,12 +64,14 @@ export function parseArgs(input) {
61
64
  const opts = { ...DEFAULT_OPTIONS };
62
65
  const warnings = [];
63
66
  const taskTokens = [];
67
+ const providedFlags = new Set();
64
68
 
65
69
  let i = 0;
66
70
  while (i < tokens.length) {
67
71
  const raw = tokens[i];
68
72
 
69
73
  if (BOOL_FLAGS.has(raw)) {
74
+ providedFlags.add(raw);
70
75
  applyBool(opts, raw);
71
76
  i += 1;
72
77
  continue;
@@ -82,6 +87,7 @@ export function parseArgs(input) {
82
87
  }
83
88
 
84
89
  if (VALUE_FLAGS.has(flag)) {
90
+ providedFlags.add(flag);
85
91
  if (value === null) {
86
92
  const next = tokens[i + 1];
87
93
  if (next === undefined || next.startsWith("--")) {
@@ -108,7 +114,7 @@ export function parseArgs(input) {
108
114
  i += 1;
109
115
  }
110
116
 
111
- validate(opts, warnings);
117
+ validate(opts, warnings, providedFlags);
112
118
 
113
119
  return {
114
120
  ...opts,
@@ -196,10 +202,19 @@ function applyValue(opts, flag, value, warnings) {
196
202
  }
197
203
  break;
198
204
  }
205
+ case "--rounds": {
206
+ const n = Number(value);
207
+ if (!Number.isInteger(n) || n <= 0) {
208
+ warnings.push(`invalid --rounds=${value}, expected positive integer`);
209
+ } else {
210
+ opts.rounds = n;
211
+ }
212
+ break;
213
+ }
199
214
  }
200
215
  }
201
216
 
202
- function validate(opts, warnings) {
217
+ function validate(opts, warnings, providedFlags = new Set()) {
203
218
  for (const key of Object.keys(VALID_VALUES)) {
204
219
  if (!VALID_VALUES[key].includes(opts[key])) {
205
220
  warnings.push(
@@ -214,6 +229,28 @@ function validate(opts, warnings) {
214
229
  ) {
215
230
  warnings.push(`invalid --parallel=${opts.parallel}, expected 1|N|swarm`);
216
231
  }
232
+
233
+ if (opts.mode === "live") {
234
+ const ignored = [
235
+ ["--parallel", "parallel", DEFAULT_OPTIONS.parallel],
236
+ ["--isolation", "isolation", DEFAULT_OPTIONS.isolation],
237
+ ["--remote", "remote", DEFAULT_OPTIONS.remote],
238
+ ];
239
+ for (const [flag, key, fallback] of ignored) {
240
+ if (providedFlags.has(flag)) {
241
+ warnings.push(`${flag} ignored with --mode live`);
242
+ opts[key] = fallback;
243
+ }
244
+ }
245
+ if (providedFlags.has("--retry") && opts.retry === "ralph") {
246
+ warnings.push("--retry ralph ignored with --mode live");
247
+ opts.retry = DEFAULT_OPTIONS.retry;
248
+ }
249
+ } else if (providedFlags.has("--rounds")) {
250
+ warnings.push("--rounds ignored unless --mode live");
251
+ opts.rounds = DEFAULT_OPTIONS.rounds;
252
+ }
253
+
217
254
  const parallelOne = opts.parallel === "1" || opts.parallel === 1;
218
255
  if (parallelOne && opts.isolation === "worktree") {
219
256
  warnings.push(
package/hub/reflexion.mjs CHANGED
@@ -7,8 +7,6 @@ const DEFAULT_CONFIDENCE = 0.5;
7
7
  const ACTIVE_RULE_CONFIDENCE = 0.5;
8
8
  const ADAPTIVE_PROMOTION_STEP = 0.1;
9
9
  const ADAPTIVE_DECAY_STEP = 0.1;
10
- /** @deprecated 세션 기반 decay에서 시간 기반으로 변경됨. 미사용. */
11
- const _ADAPTIVE_DECAY_WINDOW = 5;
12
10
  const ADAPTIVE_DELETE_THRESHOLD = 0.3;
13
11
 
14
12
  function clampConfidence(value) {
@@ -102,61 +100,6 @@ function buildAdaptiveSolution(errorContext = {}, errorText = "") {
102
100
  return `${toolName} 재시도 전 실패 원인을 검증하세요: ${summary}`;
103
101
  }
104
102
 
105
- function normalizeSessionIds(sessionIds) {
106
- if (!Array.isArray(sessionIds)) return [];
107
- return [
108
- ...new Set(
109
- sessionIds.filter((value) => typeof value === "string" && value.trim()),
110
- ),
111
- ];
112
- }
113
-
114
- /** @deprecated reflexion_entries 기반. adaptive_rules에서는 미사용. 세션 인식 복원 시 재활용 예정. */
115
- function getAdaptiveState(rule = {}) {
116
- const state = rule.adaptive_state || {};
117
- const session_ids = normalizeSessionIds(state.session_ids);
118
- return {
119
- ...state,
120
- project_slug: pickString(state.project_slug, rule.context?.project_slug),
121
- session_ids,
122
- session_occurrences: Math.max(
123
- state.session_occurrences || 0,
124
- session_ids.length,
125
- ),
126
- last_seen_session: pickSessionCount(state.last_seen_session),
127
- last_decay_session: pickSessionCount(state.last_decay_session),
128
- };
129
- }
130
-
131
- /** @deprecated reflexion_entries 기반. adaptive_rules에서는 미사용. 세션 인식 복원 시 재활용 예정. */
132
- function _mergeAdaptiveState(rule, errorContext = {}) {
133
- const current = getAdaptiveState(rule);
134
- const sessionId = pickSessionId(errorContext);
135
- const sessionCount = pickSessionCount(
136
- errorContext.sessionCount,
137
- errorContext.session_count,
138
- errorContext.context?.sessionCount,
139
- errorContext.context?.session_count,
140
- );
141
- const session_ids = normalizeSessionIds(
142
- sessionId ? [...current.session_ids, sessionId] : current.session_ids,
143
- );
144
- return {
145
- ...current,
146
- project_slug: pickString(
147
- pickProjectSlug(errorContext),
148
- current.project_slug,
149
- ),
150
- session_ids,
151
- session_occurrences: Math.max(
152
- current.session_occurrences,
153
- session_ids.length,
154
- ),
155
- last_seen_session: Math.max(current.last_seen_session, sessionCount),
156
- last_decay_session: current.last_decay_session || sessionCount,
157
- };
158
- }
159
-
160
103
  function filterEntriesByType(entries, type) {
161
104
  return entries.filter(
162
105
  (entry) => (entry.type || DEFAULT_REFLEXION_TYPE) === type,