@triflux/remote 10.25.1 → 10.26.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 (45) hide show
  1. package/hub/server.mjs +21 -8
  2. package/hub/team/agent-map.json +3 -3
  3. package/hub/team/backend.mjs +3 -9
  4. package/hub/team/build-worker-prompt.mjs +33 -2
  5. package/hub/team/claude-daemon-control.mjs +911 -0
  6. package/hub/team/claude-native-bridge.mjs +238 -11
  7. package/hub/team/claude-session-projection.mjs +10 -1
  8. package/hub/team/cli/commands/start/index.mjs +3 -6
  9. package/hub/team/cli/commands/start/parse-args.mjs +10 -3
  10. package/hub/team/cli/commands/start/start-headless.mjs +50 -20
  11. package/hub/team/cli/help.mjs +1 -1
  12. package/hub/team/cli/services/runtime-mode.mjs +6 -3
  13. package/hub/team/execution-mode.mjs +27 -12
  14. package/hub/team/headless.mjs +191 -43
  15. package/hub/team/interactive-native-launcher.mjs +106 -0
  16. package/hub/team/interactive-native-worker.mjs +80 -0
  17. package/hub/team/interactive-tui-transport.mjs +465 -0
  18. package/hub/team/launcher-template.mjs +28 -6
  19. package/hub/team/native.mjs +46 -7
  20. package/hub/team/pane.mjs +0 -5
  21. package/hub/team/psmux.mjs +3 -3
  22. package/hub/team/retry-state-machine.mjs +83 -14
  23. package/hub/team/session.mjs +5 -36
  24. package/hub/team/swarm-hypervisor.mjs +28 -6
  25. package/hub/team/swarm-preflight.mjs +3 -1
  26. package/hub/team/terminal-opener.mjs +1 -1
  27. package/hub/team/tui-core.mjs +4 -0
  28. package/hub/team/tui-lite.mjs +3 -2
  29. package/hub/team/tui-viewer.mjs +4 -4
  30. package/hub/team/tui.mjs +4 -2
  31. package/hub/team/worker-sandbox.mjs +4 -0
  32. package/hub/tools.mjs +4 -1
  33. package/hub/workers/antigravity-route-worker.mjs +169 -0
  34. package/hub/workers/delegator-mcp.mjs +58 -314
  35. package/hub/workers/factory.mjs +7 -4
  36. package/hub/workers/gemini-worker.mjs +55 -306
  37. package/hub/workers/interface.mjs +2 -1
  38. package/hub/workers/worker-utils.mjs +1 -1
  39. package/package.json +1 -1
  40. package/scripts/lib/cli-codex.mjs +3 -3
  41. package/scripts/lib/cli-gemini.mjs +20 -50
  42. package/scripts/lib/keyword-rules.mjs +1 -1
  43. package/scripts/lib/mcp-gateway-health-check.mjs +159 -0
  44. package/scripts/lib/mcp-gateway-wrapper-check.mjs +35 -0
  45. package/scripts/lib/psmux-info.mjs +50 -5
package/hub/server.mjs CHANGED
@@ -211,7 +211,9 @@ function isInitializeRequest(body) {
211
211
  function parseTfxClientHeader(value) {
212
212
  const raw = Array.isArray(value) ? value[0] : value;
213
213
  const client = String(raw || "unknown").toLowerCase();
214
- return ["codex", "claude", "gemini"].includes(client) ? client : "unknown";
214
+ return ["codex", "claude", "antigravity", "gemini"].includes(client)
215
+ ? client
216
+ : "unknown";
215
217
  }
216
218
 
217
219
  async function parseBody(req) {
@@ -335,8 +337,13 @@ async function syncHubMcpSettingsIfAvailable({ hubUrl }) {
335
337
  const mod = await import(
336
338
  new URL("../scripts/sync-hub-mcp-settings.mjs", import.meta.url)
337
339
  );
340
+ const protectedMcpSyncEnv = isProtectedImplicitMcpSyncEnv();
338
341
  if (typeof mod?.syncHubMcpSettings === "function") {
339
- await mod.syncHubMcpSettings({ hubUrl });
342
+ if (process.env.TFX_USER_MCP_SYNC === "1" || !protectedMcpSyncEnv) {
343
+ await mod.syncHubMcpSettings({ hubUrl });
344
+ } else {
345
+ hubLog.debug({ hubUrl }, "hub.user_mcp_sync_skipped_protected_env");
346
+ }
340
347
  } else {
341
348
  hubLog.warn({ hubUrl }, "hub.mcp_sync_missing_export");
342
349
  }
@@ -344,12 +351,7 @@ async function syncHubMcpSettingsIfAvailable({ hubUrl }) {
344
351
  await mod.syncCodexHubUrl({ hubUrl });
345
352
  }
346
353
  const allowProjectSync =
347
- process.env.TFX_PROJECT_MCP_SYNC === "1" ||
348
- !(
349
- process.env.NODE_ENV === "test" ||
350
- process.env.CI === "true" ||
351
- process.env.TFX_TEST === "1"
352
- );
354
+ process.env.TFX_PROJECT_MCP_SYNC === "1" || !protectedMcpSyncEnv;
353
355
  if (allowProjectSync && typeof mod?.syncProjectMcpJson === "function") {
354
356
  await mod.syncProjectMcpJson({ hubUrl, projectRoot: PROJECT_ROOT });
355
357
  }
@@ -363,6 +365,17 @@ async function syncHubMcpSettingsIfAvailable({ hubUrl }) {
363
365
  }
364
366
  }
365
367
 
368
+ function isProtectedImplicitMcpSyncEnv(env = process.env) {
369
+ return (
370
+ env.NODE_ENV === "test" ||
371
+ env.CI === "true" ||
372
+ env.TFX_TEST === "1" ||
373
+ Boolean(env.TRIFLUX_TEST_HOME) ||
374
+ Boolean(env.NODE_TEST_CONTEXT) ||
375
+ Boolean(env.NODE_TEST_WORKER_ID)
376
+ );
377
+ }
378
+
366
379
  function findListeningPidByPort(
367
380
  port,
368
381
  { platform = process.platform, execSync = execSyncHub } = {},
@@ -16,14 +16,14 @@
16
16
  "scientist-deep": "codex",
17
17
  "document-specialist": "codex",
18
18
  "spark": "codex",
19
- "designer": "gemini",
20
- "writer": "gemini",
19
+ "designer": "antigravity",
20
+ "writer": "antigravity",
21
21
  "explore": "claude",
22
22
  "verifier": "codex",
23
23
  "test-engineer": "codex",
24
24
  "qa-tester": "codex",
25
25
  "codex": "codex",
26
- "gemini": "gemini",
26
+ "gemini": "antigravity",
27
27
  "antigravity": "antigravity",
28
28
  "agy": "antigravity",
29
29
  "claude": "claude"
@@ -1,5 +1,5 @@
1
1
  // hub/team/backend.mjs — CLI 백엔드 추상화 레이어
2
- // 각 CLI(codex/gemini/claude/antigravity)의 명령 빌드 로직을 클래스로 캡슐화한다.
2
+ // 각 CLI(codex/antigravity/claude)의 명령 빌드 로직을 클래스로 캡슐화한다.
3
3
  // v7.2.2
4
4
  import { writeFileSync } from "node:fs";
5
5
  import { createRequire } from "node:module";
@@ -7,14 +7,8 @@ import { createRequire } from "node:module";
7
7
  import { buildExecArgs } from "@triflux/core/hub/codex-adapter.mjs";
8
8
  import { IS_WINDOWS } from "@triflux/core/hub/platform.mjs";
9
9
 
10
- // --yolo is required: without it gemini waits on stdin for tool-call approval
11
- // even when stdin is redirected, producing a 0-byte 90s+ silent hang.
12
- // execution-mode.mjs:buildSpawnSpecForMode enforces the same flag.
13
10
  export function buildGeminiCommand(prompt, resultFile, { isWindows } = {}) {
14
- if (isWindows) {
15
- return `$null | gemini --yolo --prompt ${prompt} --output-format text > '${resultFile}' 2>'${resultFile}.err'`;
16
- }
17
- return `gemini --yolo --prompt ${prompt} --output-format text > '${resultFile}' 2>'${resultFile}.err' < /dev/null`;
11
+ return buildAntigravityCommand(prompt, resultFile, { isWindows });
18
12
  }
19
13
 
20
14
  export function buildAntigravityCommand(
@@ -65,7 +59,7 @@ export class GeminiBackend {
65
59
  return "gemini";
66
60
  }
67
61
  command() {
68
- return "gemini";
62
+ return "agy";
69
63
  }
70
64
 
71
65
  buildArgs(prompt, resultFile, opts = {}) {
@@ -9,6 +9,32 @@
9
9
 
10
10
  import { SENTINEL_BEGIN, SENTINEL_END } from "./sentinel-capture.mjs";
11
11
 
12
+ function normalizeLeaseFiles(leaseFiles) {
13
+ if (!Array.isArray(leaseFiles)) return [];
14
+ return leaseFiles
15
+ .map((file) => (typeof file === "string" ? file.trim() : ""))
16
+ .filter(Boolean);
17
+ }
18
+
19
+ function formatLeaseFiles(leaseFiles) {
20
+ const normalized = normalizeLeaseFiles(leaseFiles);
21
+ if (normalized.length === 0) return "- (none declared)";
22
+ return normalized.map((file) => `- ${file}`).join("\n");
23
+ }
24
+
25
+ export function buildLeaseScopedAcceptanceAppendix({ leaseFiles = [] } = {}) {
26
+ return `
27
+
28
+ ## Lease-scoped Acceptance / Lint Guard (자동 삽입됨)
29
+ - 이 shard 의 파일 lease:
30
+ ${formatLeaseFiles(leaseFiles)}
31
+ - Acceptance, lint, and format checks are scoped to files changed by this shard; if that set is unclear, use only the lease list above.
32
+ - Do not run repo-wide format/lint fixers such as \`biome check --write .\`, \`biome --write .\`, \`npm run lint:fix\`, or broad \`npm run lint\` to absorb unrelated drift.
33
+ - For Biome, use \`npx biome check <changed-files-or-lease-files>\`; add \`--write\` only when every target is a changed/leased file you intend to commit.
34
+ - Pre-existing lint drift outside the lease is not this shard's acceptance responsibility; report it instead of editing it.
35
+ `;
36
+ }
37
+
12
38
  export const COMPLETION_PROTOCOL_APPENDIX = `
13
39
 
14
40
  ## Completion Protocol (자동 삽입됨)
@@ -34,9 +60,14 @@ ${SENTINEL_END}
34
60
  * Append the Completion Protocol section to a PRD prompt.
35
61
  *
36
62
  * @param {string|null|undefined} prdPrompt — original PRD body
63
+ * @param {{ leaseFiles?: string[] }} [opts] — shard file lease for scoped acceptance
37
64
  * @returns {string} prompt with appendix
38
65
  */
39
- export function buildWorkerPrompt(prdPrompt) {
66
+ export function buildWorkerPrompt(prdPrompt, opts = {}) {
40
67
  const body = typeof prdPrompt === "string" ? prdPrompt : "";
41
- return body + COMPLETION_PROTOCOL_APPENDIX;
68
+ return (
69
+ body +
70
+ buildLeaseScopedAcceptanceAppendix({ leaseFiles: opts.leaseFiles }) +
71
+ COMPLETION_PROTOCOL_APPENDIX
72
+ );
42
73
  }