@triflux/core 10.51.0 → 10.53.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 (61) hide show
  1. package/hub/bridge.mjs +69 -1197
  2. package/hub/cli-adapter-base.mjs +4 -104
  3. package/hub/codex-adapter.mjs +7 -116
  4. package/hub/index.mjs +3 -20
  5. package/hub/lib/process-utils.mjs +1 -33
  6. package/hub/team/claude-daemon-control.mjs +1 -2
  7. package/hub/team/claude-session-projection.mjs +5 -73
  8. package/hub/team/claude-transcript.mjs +19 -0
  9. package/hub/team/nativeProxy.mjs +759 -0
  10. package/hub/team/session-context.mjs +1 -1
  11. package/hud/constants.mjs +9 -22
  12. package/hud/hud-qos-status.mjs +16 -19
  13. package/hud/providers/codex-probe.mjs +2 -31
  14. package/hud/providers/codex.mjs +16 -58
  15. package/hud/providers/gemini.mjs +20 -0
  16. package/hud/renderers.mjs +101 -77
  17. package/hud/utils.mjs +9 -13
  18. package/package.json +3 -6
  19. package/scripts/lib/agent-route-policy.mjs +0 -67
  20. package/scripts/lib/cli-claude.mjs +0 -12
  21. package/scripts/lib/env-probe.mjs +0 -70
  22. package/scripts/lib/legacy-mcp-cleanup.mjs +283 -0
  23. package/scripts/lib/mcp-guard-engine.mjs +42 -101
  24. package/scripts/lib/session-presence.mjs +1 -99
  25. package/hub/account-broker.mjs +0 -1221
  26. package/hub/adaptive-diagnostic.mjs +0 -350
  27. package/hub/adaptive-inject.mjs +0 -224
  28. package/hub/adaptive-memory.mjs +0 -277
  29. package/hub/adaptive.mjs +0 -172
  30. package/hub/assign-callbacks.mjs +0 -170
  31. package/hub/delegator/contracts.mjs +0 -38
  32. package/hub/delegator/index.mjs +0 -14
  33. package/hub/delegator/schema/delegator-tools.schema.json +0 -250
  34. package/hub/delegator/service.mjs +0 -336
  35. package/hub/delegator/tool-definitions.mjs +0 -35
  36. package/hub/hitl.mjs +0 -202
  37. package/hub/lib/known-errors.json +0 -72
  38. package/hub/lib/memory-store.mjs +0 -1001
  39. package/hub/lib/phase-manager.mjs +0 -493
  40. package/hub/lib/state-snapshot.mjs +0 -293
  41. package/hub/lib/trace-recorder.mjs +0 -153
  42. package/hub/lib/uuidv7.mjs +0 -45
  43. package/hub/memory-doctor.mjs +0 -640
  44. package/hub/middleware/quota-middleware.mjs +0 -70
  45. package/hub/middleware/request-logger.mjs +0 -191
  46. package/hub/paths.mjs +0 -24
  47. package/hub/pipeline/index.mjs +0 -163
  48. package/hub/pipeline/state.mjs +0 -191
  49. package/hub/pipeline/transitions.mjs +0 -131
  50. package/hub/reflexion.mjs +0 -290
  51. package/hub/role-contract.mjs +0 -312
  52. package/hub/router.mjs +0 -2026
  53. package/hub/session-fingerprint.mjs +0 -418
  54. package/hub/state.mjs +0 -300
  55. package/hub/team/synapse-http.mjs +0 -311
  56. package/hub/team-bridge.mjs +0 -27
  57. package/scripts/lib/claudemd-scanner.mjs +0 -26
  58. package/scripts/lib/context.mjs +0 -51
  59. package/scripts/lib/handoff.mjs +0 -187
  60. package/scripts/lib/logger.mjs +0 -122
  61. package/scripts/lib/stealth-fetch.mjs +0 -176
package/hud/renderers.mjs CHANGED
@@ -22,6 +22,7 @@ import {
22
22
  PERCENT_CELL_WIDTH,
23
23
  PROVIDER_PREFIX_WIDTH,
24
24
  SEVEN_DAY_MS,
25
+ TIME_CELL_INNER_WIDTH,
25
26
  } from "./constants.mjs";
26
27
  import { buildContextUsageView } from "./context-monitor.mjs";
27
28
  import { getTerminalColumns, tierBar, tierDimBar } from "./terminal.mjs";
@@ -84,7 +85,11 @@ export function getMicroLine(
84
85
  codexBuckets,
85
86
  options = {},
86
87
  ) {
87
- const { showCodex = true, showAntigravity = true } = options;
88
+ const {
89
+ showCodex = true,
90
+ showAntigravity = true,
91
+ codexLoggedOut = false,
92
+ } = options;
88
93
  const ctxView = contextView || buildContextUsageView({});
89
94
  // Claude 5h/1w
90
95
  const cF =
@@ -97,11 +102,11 @@ export function getMicroLine(
97
102
  : null;
98
103
  const cVal =
99
104
  claudeUsage != null
100
- ? `${cF != null ? colorByProvider(cF, `${cF}`, claudeOrange) : dim("--")}${dim("/")}${cW != null ? colorByProvider(cW, `${cW}`, claudeOrange) : dim("--")}`
101
- : dim("--/--");
105
+ ? `${cF != null ? colorByProvider(cF, `${cF}%`, claudeOrange) : dim("--%")}${dim("/")}${cW != null ? colorByProvider(cW, `${cW}%`, claudeOrange) : dim("--%")}`
106
+ : dim("--%/--%");
102
107
 
103
108
  // Codex 5h/1w
104
- let xVal = dim("--/--");
109
+ let xVal = dim("--%/--%");
105
110
  if (codexBuckets) {
106
111
  const mb = codexBuckets.codex || codexBuckets[Object.keys(codexBuckets)[0]];
107
112
  if (mb) {
@@ -113,7 +118,7 @@ export function getMicroLine(
113
118
  mb.secondary?.used_percent != null
114
119
  ? clampPercent(mb.secondary.used_percent)
115
120
  : null;
116
- xVal = `${xF != null ? colorByProvider(xF, `${xF}`, codexWhite) : dim("--")}${dim("/")}${xW != null ? colorByProvider(xW, `${xW}`, codexWhite) : dim("--")}`;
121
+ xVal = `${xF != null ? colorByProvider(xF, `${xF}%`, codexWhite) : dim("--%")}${dim("/")}${xW != null ? colorByProvider(xW, `${xW}%`, codexWhite) : dim("--%")}`;
117
122
  }
118
123
  }
119
124
 
@@ -121,32 +126,41 @@ export function getMicroLine(
121
126
  // 세그먼트를 모아 join 한다. 차단된 프로바이더를 뺄 때 공백이 겹치지 않는다.
122
127
  const segments = [`${bold(claudeOrange("c"))}${dim(":")}${cVal}`];
123
128
  if (showCodex) {
124
- segments.push(`${bold(codexWhite("x"))}${dim(":")}${xVal}`);
129
+ const xMarker = codexLoggedOut ? dim("x") : bold(codexWhite("x"));
130
+ segments.push(`${xMarker}${dim(":")}${xVal}`);
125
131
  }
126
132
  if (showAntigravity) {
127
- const marker = options.antigravityQuota ? bold(geminiBlue("a")) : dim("a");
128
- segments.push(
129
- `${marker}${dim(":")}${antigravityPercentText(options.antigravityQuota)}${options.antigravityQuota?.stale ? dim("*") : ""}`,
130
- );
133
+ const marker = options.antigravityQuota?.auth
134
+ ? bold(geminiBlue("a"))
135
+ : dim("a");
136
+ // stale 은 값을 dim 으로 보인다. 표식을 덧붙이면 최악 폭이 39칸을 넘는다.
137
+ const agyText = antigravityPercentText(options.antigravityQuota);
138
+ const agyValue = options.antigravityQuota?.stale
139
+ ? dim(stripAnsi(agyText))
140
+ : agyText;
141
+ segments.push(`${marker}${dim(":")}${agyValue}`);
131
142
  }
132
143
  segments.push(`${dim("CTX:")}${contextPercentText(ctxView)}`);
133
144
  return truncateAnsi(segments.join(" "), cols);
134
145
  }
135
146
 
136
147
  function antigravityPercentText(quota) {
148
+ if (quota?.auth === "project") {
149
+ return geminiBlue("GCP".padStart(PERCENT_CELL_WIDTH));
150
+ }
137
151
  return quota?.usedPercent != null
138
152
  ? colorByProvider(
139
153
  quota.usedPercent,
140
154
  formatPercentCell(quota.usedPercent),
141
155
  geminiBlue,
142
156
  )
143
- : dim("--".padStart(PERCENT_CELL_WIDTH));
157
+ : dim(formatPlaceholderPercentCell());
144
158
  }
145
159
 
146
160
  // context 는 토큰 수 대신 사용률만 보여 준다.
147
161
  function contextPercentText(ctxView) {
148
- const text = ctxView.display === "--" ? "--" : `${ctxView.percent}%`;
149
- return colorByPercent(ctxView.percent, text);
162
+ if (ctxView.display === "--") return dim("--%");
163
+ return colorByPercent(ctxView.percent, `${ctxView.percent}%`);
150
164
  }
151
165
 
152
166
  // ============================================================================
@@ -160,10 +174,10 @@ export function getClaudeRows(currentTier, contextView, claudeUsage) {
160
174
  const weeklyPercent = claudeUsage?.weeklyPercent ?? null;
161
175
  const fiveHourReset = claudeUsage?.fiveHourResetsAt
162
176
  ? formatResetRemaining(claudeUsage.fiveHourResetsAt, FIVE_HOUR_MS)
163
- : "n/a";
177
+ : "";
164
178
  const weeklyReset = claudeUsage?.weeklyResetsAt
165
179
  ? formatResetRemainingDayHour(claudeUsage.weeklyResetsAt, SEVEN_DAY_MS)
166
- : "n/a";
180
+ : "";
167
181
 
168
182
  const hasData = claudeUsage != null;
169
183
 
@@ -198,11 +212,11 @@ export function getClaudeRows(currentTier, contextView, claudeUsage) {
198
212
  const fShort =
199
213
  hasData && fiveHourPercent != null
200
214
  ? colorByProvider(fiveHourPercent, `${fiveHourPercent}%`, claudeOrange)
201
- : dim("--");
215
+ : dim("--%");
202
216
  const wShort =
203
217
  hasData && weeklyPercent != null
204
218
  ? colorByProvider(weeklyPercent, `${weeklyPercent}%`, claudeOrange)
205
- : dim("--");
219
+ : dim("--%");
206
220
  const quotaSection = `${fShort}${dim("/")}${wShort}`;
207
221
  return [{ prefix, left: quotaSection, right: "" }];
208
222
  }
@@ -237,24 +251,9 @@ export function getClaudeRows(currentTier, contextView, claudeUsage) {
237
251
  // ============================================================================
238
252
  // 계정 라벨 + 범용 프로바이더 행 렌더러
239
253
  // ============================================================================
240
- export function getAccountLabel(
241
- provider,
242
- accountsConfig,
243
- accountsState,
244
- codexEmail,
245
- ) {
246
- const providerConfig = accountsConfig?.providers?.[provider] || [];
247
- const providerState = accountsState?.providers?.[provider] || {};
248
- const lastId = providerState.last_selected_id;
249
- const picked = providerConfig.find((a) => a.id === lastId) ||
250
- providerConfig[0] || {
251
- id: `${provider}-main`,
252
- label: provider === "antigravity" ? "agy" : provider,
253
- };
254
- let label = picked.label || picked.id;
255
- if (codexEmail) label = codexEmail;
256
- if (label.includes("@")) label = label.split("@")[0];
257
- return label;
254
+ export function getAccountLabel(provider, accountName) {
255
+ const label = accountName || (provider === "antigravity" ? "agy" : provider);
256
+ return label.includes("@") ? label.split("@")[0] : label;
258
257
  }
259
258
 
260
259
  export function getProviderRow(
@@ -262,46 +261,23 @@ export function getProviderRow(
262
261
  provider,
263
262
  marker,
264
263
  markerColor,
265
- accountsConfig,
266
- accountsState,
267
264
  realQuota,
268
- codexEmail,
265
+ accountName,
269
266
  ) {
270
267
  const accountLabel = fitText(
271
- getAccountLabel(provider, accountsConfig, accountsState, codexEmail),
268
+ getAccountLabel(provider, accountName),
272
269
  ACCOUNT_LABEL_WIDTH,
273
270
  );
274
271
 
275
272
  const prefix = `${bold(markerColor(marker))}:`;
276
273
  if (provider === "antigravity") {
277
- const usedPercent = realQuota?.usedPercent;
278
- const active = usedPercent != null;
279
- const quotaPercent = antigravityPercentText(realQuota);
280
- const right = `${active ? markerColor(accountLabel) : dim(accountLabel)}${realQuota?.stale ? dim(" [stale]") : ""}`;
281
- if (currentTier === "nano" || currentTier === "micro") {
282
- return {
283
- prefix: active ? prefix : dim(`${marker}:`),
284
- left: quotaPercent,
285
- right,
286
- };
287
- }
288
- const bar = active
289
- ? tierBar(currentTier, usedPercent, GEMINI_BLUE)
290
- : currentTier === "full"
291
- ? " ".repeat(GAUGE_WIDTH + 1)
292
- : "";
293
- const reset =
294
- (Date.parse(realQuota?.resetTime) - Date.now() >= ONE_DAY_MS
295
- ? formatResetRemainingDayHour(realQuota.resetTime)
296
- : formatResetRemaining(realQuota?.resetTime)) || "n/a";
297
- const showTime = currentTier === "full" || currentTier === "compact";
298
- // /usage의 모델별 값에는 5h/1w 식별자가 없으므로 창을 추측하지 않는다.
299
- const slot = `${dim("--:")}${bar}${quotaPercent}${showTime ? ` ${dim(formatTimeCell(reset))}` : ""}`;
300
- return {
301
- prefix: active ? prefix : dim(`${marker}:`),
302
- left: `${slot} ${" ".repeat(stripAnsi(slot).length)}`,
303
- right,
304
- };
274
+ return getAntigravityRow(
275
+ currentTier,
276
+ marker,
277
+ markerColor,
278
+ accountLabel,
279
+ realQuota,
280
+ );
305
281
  }
306
282
  const provAnsi = CODEX_WHITE;
307
283
  const provFn = codexWhite;
@@ -337,7 +313,7 @@ export function getProviderRow(
337
313
  };
338
314
  }
339
315
  }
340
- return { prefix: minPrefix, left: dim("--/--"), right: "" };
316
+ return { prefix: minPrefix, left: dim("--%/--%"), right: "" };
341
317
  }
342
318
 
343
319
  if (currentTier === "minimal") {
@@ -397,16 +373,16 @@ export function getProviderRow(
397
373
  weekP != null
398
374
  ? colorByProvider(weekP, formatPercentCell(weekP), provFn)
399
375
  : dim(formatPlaceholderPercentCell());
400
- const fiveReset =
401
- formatResetRemaining(main.primary?.resets_at) || "n/a";
402
- const weekReset =
403
- formatResetRemainingDayHour(main.secondary?.resets_at) || "n/a";
376
+ const fiveReset = formatResetRemaining(main.primary?.resets_at);
377
+ const weekReset = formatResetRemainingDayHour(
378
+ main.secondary?.resets_at,
379
+ );
404
380
  quotaSection = `${dim("5h:")}${fCell} ${dim(formatTimeCell(fiveReset))} ${dim("1w:")}${wCell} ${dim(formatTimeCellDH(weekReset))}`;
405
381
  if (main.mixedWindows) quotaSection += dim("*");
406
382
  }
407
383
  }
408
384
  if (!quotaSection) {
409
- quotaSection = `${dim("5h:")}${dim(formatPlaceholderPercentCell())} ${dim(formatTimeCell("n/a"))} ${dim("1w:")}${dim(formatPlaceholderPercentCell())} ${dim(formatTimeCellDH("--d--h"))}`;
385
+ quotaSection = `${dim("5h:")}${dim(formatPlaceholderPercentCell())} ${dim(formatTimeCell(""))} ${dim("1w:")}${dim(formatPlaceholderPercentCell())} ${dim(formatTimeCellDH(""))}`;
410
386
  }
411
387
  const compactRight = [accountLabel ? markerColor(accountLabel) : ""]
412
388
  .filter(Boolean)
@@ -429,9 +405,8 @@ export function getProviderRow(
429
405
  main.secondary?.used_percent != null
430
406
  ? clampPercent(main.secondary.used_percent)
431
407
  : null;
432
- const fiveReset = formatResetRemaining(main.primary?.resets_at) || "n/a";
433
- const weekReset =
434
- formatResetRemainingDayHour(main.secondary?.resets_at) || "n/a";
408
+ const fiveReset = formatResetRemaining(main.primary?.resets_at);
409
+ const weekReset = formatResetRemainingDayHour(main.secondary?.resets_at);
435
410
  const fCell =
436
411
  fiveP != null
437
412
  ? colorByProvider(fiveP, formatPercentCell(fiveP), provFn)
@@ -459,7 +434,7 @@ export function getProviderRow(
459
434
 
460
435
  // 폴백
461
436
  if (!quotaSection) {
462
- quotaSection = `${dim("5h:")}${tierDimBar(currentTier)}${dim(formatPlaceholderPercentCell())} ${dim(formatTimeCell("n/a"))} ${dim("1w:")}${tierDimBar(currentTier)}${dim(formatPlaceholderPercentCell())} ${dim(formatTimeCellDH("--d--h"))}`;
437
+ quotaSection = `${dim("5h:")}${tierDimBar(currentTier)}${dim(formatPlaceholderPercentCell())} ${dim(formatTimeCell(""))} ${dim("1w:")}${tierDimBar(currentTier)}${dim(formatPlaceholderPercentCell())} ${dim(formatTimeCellDH(""))}`;
463
438
  }
464
439
 
465
440
  const accountSection = `${markerColor(accountLabel)}`;
@@ -469,3 +444,52 @@ export function getProviderRow(
469
444
  right: accountSection,
470
445
  };
471
446
  }
447
+
448
+ // 회색은 로그인 안 된 경우에만 쓴다. GCP 프로젝트 과금은 개인 쿼터가 없을 뿐 정상 상태다.
449
+ function getAntigravityRow(
450
+ currentTier,
451
+ marker,
452
+ markerColor,
453
+ accountLabel,
454
+ quota,
455
+ ) {
456
+ const usedPercent = quota?.usedPercent;
457
+ const hasValue = usedPercent != null;
458
+ const loggedIn = quota?.auth != null;
459
+ const project = quota?.auth === "project";
460
+ const tint = loggedIn ? markerColor : dim;
461
+ const prefix = loggedIn ? `${bold(markerColor(marker))}:` : dim(`${marker}:`);
462
+ const stale = quota?.stale ? dim(" [stale]") : "";
463
+ const right = `${tint(accountLabel)}${stale}`;
464
+ const percent = antigravityPercentText(quota);
465
+ if (currentTier === "nano" || currentTier === "micro") {
466
+ return { prefix, left: percent, right };
467
+ }
468
+ const isFull = currentTier === "full";
469
+ const showTime = isFull || currentTier === "compact";
470
+ const reset =
471
+ Date.parse(quota?.resetTime) - Date.now() >= ONE_DAY_MS
472
+ ? formatResetRemainingDayHour(quota.resetTime)
473
+ : formatResetRemaining(quota?.resetTime);
474
+ const timeCell = showTime ? ` ${dim(formatTimeCell(reset))}` : "";
475
+ // /usage의 모델별 값에는 5h/1w 식별자가 없으므로 창을 추측하지 않는다.
476
+ // 두 창(5h, 1w) 폭에 맞춰 c, x 행과 구분자 열을 맞춘다.
477
+ const windowWidth =
478
+ "5h:".length +
479
+ (isFull ? GAUGE_WIDTH + 1 : 0) +
480
+ PERCENT_CELL_WIDTH +
481
+ (showTime ? TIME_CELL_INNER_WIDTH + 3 : 0);
482
+ let slot;
483
+ if (project) {
484
+ // 쿼터 대신 과금 방식을 막대 자리(막대가 없는 표시에서는 퍼센트 자리)에 보인다.
485
+ const mark = isFull ? `${markerColor("GCP".padEnd(GAUGE_WIDTH))} ` : "";
486
+ const cell = isFull ? dim(formatPlaceholderPercentCell()) : percent;
487
+ slot = `${dim("--:")}${mark}${cell}${timeCell}`;
488
+ } else {
489
+ const bar = hasValue
490
+ ? tierBar(currentTier, usedPercent, GEMINI_BLUE)
491
+ : tierDimBar(currentTier);
492
+ slot = `${dim("--:")}${bar}${percent}${timeCell}`;
493
+ }
494
+ return { prefix, left: padAnsiRight(slot, windowWidth * 2 + 1), right };
495
+ }
package/hud/utils.mjs CHANGED
@@ -145,7 +145,7 @@ export function formatPlaceholderPercentCell() {
145
145
  }
146
146
 
147
147
  export function normalizeTimeToken(value) {
148
- const text = String(value || "n/a");
148
+ const text = String(value || "");
149
149
  const hourMinute = text.match(/^(\d+)h(\d+)m$/);
150
150
  if (hourMinute) {
151
151
  return `${Number(hourMinute[1])}h${String(Number(hourMinute[2])).padStart(2, "0")}m`;
@@ -157,16 +157,20 @@ export function normalizeTimeToken(value) {
157
157
  return text;
158
158
  }
159
159
 
160
+ // 값이 없는 시간 칸은 단위 모양을 남겨 정상 값과 같은 폭으로 그린다.
161
+ function emptyTimeCell(unit) {
162
+ return unit === "dh" ? "(--d--h)" : "(--h--m)";
163
+ }
164
+
160
165
  export function formatTimeCell(value) {
161
166
  const text = normalizeTimeToken(value);
162
- // 시간값(숫자 포함)은 0패딩, 비시간값(n/a 등)은 공백패딩
163
- const padChar = /\d/.test(text) ? "0" : " ";
164
- return `(${text.padStart(TIME_CELL_INNER_WIDTH, padChar)})`;
167
+ if (!/\d/.test(text)) return emptyTimeCell("hm");
168
+ return `(${text.padStart(TIME_CELL_INNER_WIDTH, "0")})`;
165
169
  }
166
170
 
167
- // n/a도 정상 주간 시간과 같은 너비를 유지한다.
168
171
  export function formatTimeCellDH(value) {
169
172
  const text = normalizeTimeToken(value);
173
+ if (!/\d/.test(text)) return emptyTimeCell("dh");
170
174
  return `(${text.padStart(TIME_CELL_INNER_WIDTH, " ")})`;
171
175
  }
172
176
 
@@ -250,14 +254,6 @@ export function formatResetRemainingDayHour(isoOrUnix, cycleMs = 0) {
250
254
  return `${String(days).padStart(2, "0")}d${String(hours).padStart(2, "0")}h`;
251
255
  }
252
256
 
253
- export function getProviderAccountId(provider, accountsConfig, accountsState) {
254
- const providerState = accountsState?.providers?.[provider] || {};
255
- const selectedId = providerState.last_selected_id;
256
- if (selectedId) return selectedId;
257
- const providerConfig = accountsConfig?.providers?.[provider] || [];
258
- return providerConfig[0]?.id || `${provider}-main`;
259
- }
260
-
261
257
  // JWT base64 디코딩 공통 헬퍼
262
258
  export function decodeJwtEmail(idToken) {
263
259
  if (!idToken) return null;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@triflux/core",
3
- "version": "10.51.0",
4
- "description": "triflux core — CLI routing, pipeline, adapters. Zero native dependencies.",
3
+ "version": "10.53.0",
4
+ "description": "triflux core — CLI routing, adapters. Zero native dependencies.",
5
5
  "type": "module",
6
6
  "main": "hub/index.mjs",
7
7
  "exports": {
@@ -13,10 +13,7 @@
13
13
  "node": ">=20"
14
14
  },
15
15
  "dependencies": {
16
- "@iarna/toml": "^2.2.5",
17
- "pino": "^10.3.1",
18
- "pino-pretty": "^13.1.3",
19
- "zod": "^4.0.0"
16
+ "@iarna/toml": "^2.2.5"
20
17
  },
21
18
  "files": [
22
19
  "hub",
@@ -12,168 +12,126 @@ const policy = {
12
12
  executor: {
13
13
  profile: "gpt61_sol_high",
14
14
  timeoutSec: 1080,
15
- runMode: "fg",
16
- opusOversight: false,
17
15
  mcpHint: "implement",
18
16
  subcommand: "exec",
19
17
  },
20
18
  codex: {
21
19
  profile: "gpt61_sol_high",
22
20
  timeoutSec: 1080,
23
- runMode: "fg",
24
- opusOversight: false,
25
21
  mcpHint: "implement",
26
22
  subcommand: "exec",
27
23
  },
28
24
  "build-fixer": {
29
25
  profile: "gpt6_luna_high",
30
26
  timeoutSec: 540,
31
- runMode: "fg",
32
- opusOversight: false,
33
27
  mcpHint: "implement",
34
28
  subcommand: "exec",
35
29
  },
36
30
  cleanup: {
37
31
  profile: "gpt61_sol_med",
38
32
  timeoutSec: 540,
39
- runMode: "fg",
40
- opusOversight: false,
41
33
  mcpHint: "implement",
42
34
  subcommand: "exec",
43
35
  },
44
36
  deslop: {
45
37
  profile: "gpt61_sol_med",
46
38
  timeoutSec: 540,
47
- runMode: "fg",
48
- opusOversight: false,
49
39
  mcpHint: "implement",
50
40
  subcommand: "exec",
51
41
  },
52
42
  debugger: {
53
43
  profile: "gpt6_astra_xhigh",
54
44
  timeoutSec: 900,
55
- runMode: "bg",
56
- opusOversight: false,
57
45
  mcpHint: "implement",
58
46
  subcommand: "exec",
59
47
  },
60
48
  "deep-executor": {
61
49
  profile: "gpt6_astra_xhigh",
62
50
  timeoutSec: 3600,
63
- runMode: "bg",
64
- opusOversight: true,
65
51
  mcpHint: "implement",
66
52
  subcommand: "exec",
67
53
  },
68
54
  architect: {
69
55
  profile: "gpt6_astra_xhigh",
70
56
  timeoutSec: 3600,
71
- runMode: "bg",
72
- opusOversight: true,
73
57
  mcpHint: "analyze",
74
58
  subcommand: "exec",
75
59
  },
76
60
  critic: {
77
61
  profile: "gpt6_astra_xhigh",
78
62
  timeoutSec: 3600,
79
- runMode: "bg",
80
- opusOversight: true,
81
63
  mcpHint: "analyze",
82
64
  subcommand: "exec",
83
65
  },
84
66
  planner: {
85
67
  profile: "gpt6_astra_xhigh",
86
68
  timeoutSec: 3600,
87
- runMode: "fg",
88
- opusOversight: true,
89
69
  mcpHint: "analyze",
90
70
  subcommand: "exec",
91
71
  },
92
72
  analyst: {
93
73
  profile: "gpt6_astra_xhigh",
94
74
  timeoutSec: 3600,
95
- runMode: "fg",
96
- opusOversight: true,
97
75
  mcpHint: "analyze",
98
76
  subcommand: "exec",
99
77
  },
100
78
  "code-reviewer": {
101
79
  profile: "gpt61_sol_high",
102
80
  timeoutSec: 1800,
103
- runMode: "bg",
104
- opusOversight: false,
105
81
  mcpHint: "review",
106
82
  subcommand: "review",
107
83
  },
108
84
  "quality-reviewer": {
109
85
  profile: "gpt61_sol_high",
110
86
  timeoutSec: 1800,
111
- runMode: "bg",
112
- opusOversight: false,
113
87
  mcpHint: "review",
114
88
  subcommand: "review",
115
89
  },
116
90
  "security-reviewer": {
117
91
  profile: "gpt6_astra_xhigh",
118
92
  timeoutSec: 1800,
119
- runMode: "bg",
120
- opusOversight: true,
121
93
  mcpHint: "review",
122
94
  subcommand: "review",
123
95
  },
124
96
  scientist: {
125
97
  profile: "gpt61_sol_high",
126
98
  timeoutSec: 1440,
127
- runMode: "bg",
128
- opusOversight: false,
129
99
  mcpHint: "analyze",
130
100
  subcommand: "exec",
131
101
  },
132
102
  "document-specialist": {
133
103
  profile: "gpt61_sol_high",
134
104
  timeoutSec: 1440,
135
- runMode: "bg",
136
- opusOversight: false,
137
105
  mcpHint: "analyze",
138
106
  subcommand: "exec",
139
107
  },
140
108
  "scientist-deep": {
141
109
  profile: "gpt6_astra_xhigh",
142
110
  timeoutSec: 3600,
143
- runMode: "bg",
144
- opusOversight: false,
145
111
  mcpHint: "analyze",
146
112
  subcommand: "exec",
147
113
  },
148
114
  verifier: {
149
115
  profile: "gpt61_sol_high",
150
116
  timeoutSec: 1200,
151
- runMode: "fg",
152
- opusOversight: false,
153
117
  mcpHint: "review",
154
118
  subcommand: "review",
155
119
  },
156
120
  "test-engineer": {
157
121
  profile: "gpt61_sol_high",
158
122
  timeoutSec: 1200,
159
- runMode: "bg",
160
- opusOversight: false,
161
123
  mcpHint: "implement",
162
124
  subcommand: "exec",
163
125
  },
164
126
  "qa-tester": {
165
127
  profile: "gpt61_sol_high",
166
128
  timeoutSec: 1200,
167
- runMode: "bg",
168
- opusOversight: false,
169
129
  mcpHint: "review",
170
130
  subcommand: "review",
171
131
  },
172
132
  spark: {
173
133
  profile: "gpt6_luna_low",
174
134
  timeoutSec: 180,
175
- runMode: "fg",
176
- opusOversight: false,
177
135
  mcpHint: "implement",
178
136
  subcommand: "exec",
179
137
  },
@@ -182,16 +140,12 @@ const policy = {
182
140
  designer: {
183
141
  profile: "gpt6_astra_xhigh",
184
142
  timeoutSec: 900,
185
- runMode: "bg",
186
- opusOversight: false,
187
143
  mcpHint: "implement",
188
144
  subcommand: "exec",
189
145
  },
190
146
  writer: {
191
147
  profile: "gpt6_luna_high",
192
148
  timeoutSec: 900,
193
- runMode: "bg",
194
- opusOversight: false,
195
149
  mcpHint: "implement",
196
150
  subcommand: "exec",
197
151
  },
@@ -319,22 +273,6 @@ export function resolveNestedCodexAgentProfile(
319
273
  return effort.toLowerCase() === "ultra" ? "gpt6_astra_max" : candidate;
320
274
  }
321
275
 
322
- const MIN_TIMEOUT_BY_AGENT = Object.freeze({
323
- "deep-executor": 900,
324
- architect: 900,
325
- planner: 900,
326
- critic: 900,
327
- analyst: 900,
328
- "document-specialist": 900,
329
- scientist: 900,
330
- "scientist-deep": 900,
331
- "code-reviewer": 600,
332
- "security-reviewer": 600,
333
- "quality-reviewer": 600,
334
- executor: 300,
335
- debugger: 300,
336
- });
337
-
338
276
  const EXPECTED_DURATION_BY_AGENT = Object.freeze({
339
277
  writer: 90,
340
278
  verifier: 90,
@@ -409,14 +347,11 @@ export function resolveAgentRoute(
409
347
  provider,
410
348
  policy.profile,
411
349
  policy.timeoutSec,
412
- policy.runMode,
413
- policy.opusOversight,
414
350
  policy.mcpHint,
415
351
  policy.subcommand,
416
352
  normalizedOverride,
417
353
  resolvedOverride,
418
354
  geminiProfileResolver(agent),
419
- MIN_TIMEOUT_BY_AGENT[agent] ?? 120,
420
355
  EXPECTED_DURATION_BY_AGENT[agent] ?? 30,
421
356
  NATIVE_CODEX_AGENTS.has(agent),
422
357
  ];
@@ -495,8 +430,6 @@ async function runCli() {
495
430
  [
496
431
  resolved.profile,
497
432
  resolved.timeoutSec,
498
- resolved.runMode,
499
- resolved.opusOversight,
500
433
  resolved.mcpHint,
501
434
  resolved.subcommand,
502
435
  ].join("\t"),
@@ -12,32 +12,22 @@ export const command = null;
12
12
  const AGENT_PROFILES = {
13
13
  explore: {
14
14
  timeoutSec: 600,
15
- runMode: "fg",
16
- opusOversight: false,
17
15
  model: "haiku",
18
16
  },
19
17
  claude: {
20
18
  timeoutSec: 600,
21
- runMode: "fg",
22
- opusOversight: false,
23
19
  model: "haiku",
24
20
  },
25
21
  "test-engineer": {
26
22
  timeoutSec: 1200,
27
- runMode: "bg",
28
- opusOversight: false,
29
23
  model: "sonnet",
30
24
  },
31
25
  "qa-tester": {
32
26
  timeoutSec: 1200,
33
- runMode: "bg",
34
- opusOversight: false,
35
27
  model: "sonnet",
36
28
  },
37
29
  verifier: {
38
30
  timeoutSec: 1200,
39
- runMode: "fg",
40
- opusOversight: false,
41
31
  model: "sonnet",
42
32
  },
43
33
  };
@@ -62,8 +52,6 @@ export function plan({
62
52
  profile: "claude-native",
63
53
  effort: "n/a",
64
54
  timeoutMs: effectiveTimeoutSec * 1000,
65
- runMode: cfg.runMode,
66
- opusOversight: cfg.opusOversight,
67
55
  model: cfg.model,
68
56
  mcpProfile: mcpProfile === "auto" ? null : mcpProfile,
69
57
  promptLength: prompt.length,