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/hub/codex-preflight.mjs
CHANGED
|
@@ -1,28 +1,30 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { homedir } from
|
|
4
|
-
import {
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
5
|
|
|
6
|
-
import { whichCommandAsync } from
|
|
6
|
+
import { whichCommandAsync } from "./platform.mjs";
|
|
7
7
|
|
|
8
8
|
const MIN_RECOMMENDED_MINOR = 118;
|
|
9
9
|
let _cachedVersion = null;
|
|
10
10
|
|
|
11
11
|
function escapeRegExp(value) {
|
|
12
|
-
return String(value).replace(/[.*+?^${}()|[\]\\]/g,
|
|
12
|
+
return String(value).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
function readConfigText(configPath = join(homedir(),
|
|
16
|
-
if (!existsSync(configPath)) return
|
|
15
|
+
function readConfigText(configPath = join(homedir(), ".codex", "config.toml")) {
|
|
16
|
+
if (!existsSync(configPath)) return "";
|
|
17
17
|
try {
|
|
18
|
-
return readFileSync(configPath,
|
|
18
|
+
return readFileSync(configPath, "utf8");
|
|
19
19
|
} catch {
|
|
20
|
-
return
|
|
20
|
+
return "";
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
function readTomlString(text, key) {
|
|
25
|
-
const match = String(text).match(
|
|
25
|
+
const match = String(text).match(
|
|
26
|
+
new RegExp(`^\\s*${escapeRegExp(key)}\\s*=\\s*"([^"]*)"\\s*$`, "mu"),
|
|
27
|
+
);
|
|
26
28
|
return match?.[1] ?? null;
|
|
27
29
|
}
|
|
28
30
|
|
|
@@ -30,13 +32,13 @@ function readSection(text, name) {
|
|
|
30
32
|
const lines = String(text).split(/\r?\n/u);
|
|
31
33
|
const header = `[${name}]`;
|
|
32
34
|
const start = lines.findIndex((line) => line.trim() === header);
|
|
33
|
-
if (start < 0) return
|
|
35
|
+
if (start < 0) return "";
|
|
34
36
|
const body = [];
|
|
35
37
|
for (const line of lines.slice(start + 1)) {
|
|
36
38
|
if (/^\s*\[[^\]]+\]\s*$/u.test(line)) break;
|
|
37
39
|
body.push(line);
|
|
38
40
|
}
|
|
39
|
-
return body.join(
|
|
41
|
+
return body.join("\n");
|
|
40
42
|
}
|
|
41
43
|
|
|
42
44
|
/**
|
|
@@ -47,7 +49,10 @@ function readSection(text, name) {
|
|
|
47
49
|
export function getCodexVersion() {
|
|
48
50
|
if (_cachedVersion !== null) return _cachedVersion;
|
|
49
51
|
try {
|
|
50
|
-
const out = execSync(
|
|
52
|
+
const out = execSync("codex --version", {
|
|
53
|
+
encoding: "utf8",
|
|
54
|
+
timeout: 5000,
|
|
55
|
+
}).trim();
|
|
51
56
|
// "codex 0.117.0" 또는 "0.117.0" 형식 대응
|
|
52
57
|
const match = out.match(/(\d+)\.(\d+)\.(\d+)/);
|
|
53
58
|
_cachedVersion = match ? parseInt(match[2], 10) : 0;
|
|
@@ -58,29 +63,34 @@ export function getCodexVersion() {
|
|
|
58
63
|
}
|
|
59
64
|
|
|
60
65
|
async function checkCodexInstalled() {
|
|
61
|
-
const codexPath = await whichCommandAsync(
|
|
66
|
+
const codexPath = await whichCommandAsync("codex");
|
|
62
67
|
if (codexPath) return { codexPath, ok: true, warnings: [] };
|
|
63
68
|
return {
|
|
64
69
|
codexPath: null,
|
|
65
70
|
ok: false,
|
|
66
|
-
warnings: [
|
|
71
|
+
warnings: [
|
|
72
|
+
"Codex CLI not found. Install Codex and ensure `codex` is available on PATH.",
|
|
73
|
+
],
|
|
67
74
|
};
|
|
68
75
|
}
|
|
69
76
|
|
|
70
77
|
function checkCodexVersion() {
|
|
71
78
|
const version = getCodexVersion();
|
|
72
|
-
const warnings =
|
|
73
|
-
|
|
74
|
-
|
|
79
|
+
const warnings =
|
|
80
|
+
version >= MIN_RECOMMENDED_MINOR
|
|
81
|
+
? []
|
|
82
|
+
: [
|
|
83
|
+
`Codex CLI 0.${version}.x detected; 0.${MIN_RECOMMENDED_MINOR}.x or newer is recommended.`,
|
|
84
|
+
];
|
|
75
85
|
return { version, warnings };
|
|
76
86
|
}
|
|
77
87
|
|
|
78
88
|
function checkApprovalMode(configText, opts = {}) {
|
|
79
|
-
const approvalMode = readTomlString(configText,
|
|
80
|
-
const sandbox = readTomlString(configText,
|
|
81
|
-
const subcommand = opts.subcommand ||
|
|
89
|
+
const approvalMode = readTomlString(configText, "approval_mode");
|
|
90
|
+
const sandbox = readTomlString(configText, "sandbox");
|
|
91
|
+
const subcommand = opts.subcommand || "exec";
|
|
82
92
|
return {
|
|
83
|
-
needsBypass: subcommand ===
|
|
93
|
+
needsBypass: subcommand === "exec" || approvalMode !== "full-auto",
|
|
84
94
|
approvalMode,
|
|
85
95
|
sandbox,
|
|
86
96
|
};
|
|
@@ -88,28 +98,41 @@ function checkApprovalMode(configText, opts = {}) {
|
|
|
88
98
|
|
|
89
99
|
async function verifyServerHealth(name, configText) {
|
|
90
100
|
const section = readSection(configText, `mcp_servers.${name}`);
|
|
91
|
-
if (!section)
|
|
101
|
+
if (!section)
|
|
102
|
+
return { ok: false, warning: `MCP server '${name}' is not configured.` };
|
|
92
103
|
if (/^\s*enabled\s*=\s*false\s*$/mu.test(section)) {
|
|
93
|
-
return {
|
|
104
|
+
return {
|
|
105
|
+
ok: false,
|
|
106
|
+
warning: `MCP server '${name}' is disabled in config.toml.`,
|
|
107
|
+
};
|
|
94
108
|
}
|
|
95
109
|
|
|
96
|
-
const command = readTomlString(section,
|
|
110
|
+
const command = readTomlString(section, "command");
|
|
97
111
|
if (command) {
|
|
98
112
|
const resolved = await whichCommandAsync(command);
|
|
99
113
|
return resolved
|
|
100
|
-
? { ok: true, warning:
|
|
101
|
-
: {
|
|
114
|
+
? { ok: true, warning: "" }
|
|
115
|
+
: {
|
|
116
|
+
ok: false,
|
|
117
|
+
warning: `MCP server '${name}' command not found: ${command}`,
|
|
118
|
+
};
|
|
102
119
|
}
|
|
103
120
|
|
|
104
|
-
const url = readTomlString(section,
|
|
105
|
-
if (!url || !/^https?:\/\//u.test(url)) return { ok: true, warning:
|
|
121
|
+
const url = readTomlString(section, "url");
|
|
122
|
+
if (!url || !/^https?:\/\//u.test(url)) return { ok: true, warning: "" };
|
|
106
123
|
try {
|
|
107
124
|
const response = await fetch(url, { signal: AbortSignal.timeout(2000) });
|
|
108
125
|
return response.status < 500
|
|
109
|
-
? { ok: true, warning:
|
|
110
|
-
: {
|
|
126
|
+
? { ok: true, warning: "" }
|
|
127
|
+
: {
|
|
128
|
+
ok: false,
|
|
129
|
+
warning: `MCP server '${name}' returned HTTP ${response.status}.`,
|
|
130
|
+
};
|
|
111
131
|
} catch {
|
|
112
|
-
return {
|
|
132
|
+
return {
|
|
133
|
+
ok: false,
|
|
134
|
+
warning: `MCP server '${name}' is unreachable at ${url}.`,
|
|
135
|
+
};
|
|
113
136
|
}
|
|
114
137
|
}
|
|
115
138
|
|
|
@@ -118,7 +141,7 @@ async function checkMcpHealth(mcpServers, configText) {
|
|
|
118
141
|
const warnings = [];
|
|
119
142
|
|
|
120
143
|
for (const name of Array.isArray(mcpServers) ? mcpServers : []) {
|
|
121
|
-
const server = String(name ??
|
|
144
|
+
const server = String(name ?? "").trim();
|
|
122
145
|
if (!server) continue;
|
|
123
146
|
const result = await verifyServerHealth(server, configText);
|
|
124
147
|
if (!result.ok) excludeMcpServers.push(server);
|
|
@@ -147,10 +170,13 @@ export async function runPreflight(opts = {}) {
|
|
|
147
170
|
|
|
148
171
|
const configText = readConfigText(opts.configPath);
|
|
149
172
|
const approval = checkApprovalMode(configText, opts);
|
|
150
|
-
if (approval.approvalMode !==
|
|
151
|
-
warnings.push(
|
|
173
|
+
if (approval.approvalMode !== "full-auto") {
|
|
174
|
+
warnings.push(
|
|
175
|
+
`approval_mode is '${approval.approvalMode || "unset"}'; bypass flag will be used.`,
|
|
176
|
+
);
|
|
152
177
|
}
|
|
153
|
-
if (approval.sandbox)
|
|
178
|
+
if (approval.sandbox)
|
|
179
|
+
warnings.push(`sandbox mode from config.toml: ${approval.sandbox}`);
|
|
154
180
|
|
|
155
181
|
const mcp = await checkMcpHealth(opts.mcpServers, configText);
|
|
156
182
|
warnings.push(...mcp.warnings);
|
|
@@ -1,37 +1,33 @@
|
|
|
1
1
|
export const DELEGATOR_MCP_SERVER_INFO = Object.freeze({
|
|
2
|
-
name:
|
|
3
|
-
version:
|
|
2
|
+
name: "triflux-delegator",
|
|
3
|
+
version: "0.1.0",
|
|
4
4
|
});
|
|
5
5
|
|
|
6
6
|
export const DELEGATOR_TOOL_NAMES = Object.freeze({
|
|
7
|
-
delegate:
|
|
8
|
-
delegateReply:
|
|
9
|
-
status:
|
|
7
|
+
delegate: "delegate",
|
|
8
|
+
delegateReply: "delegate-reply",
|
|
9
|
+
status: "status",
|
|
10
10
|
});
|
|
11
11
|
|
|
12
12
|
export const DELEGATOR_PIPE_ACTIONS = Object.freeze({
|
|
13
|
-
delegate:
|
|
14
|
-
delegateReply:
|
|
15
|
-
status:
|
|
13
|
+
delegate: "delegator_delegate",
|
|
14
|
+
delegateReply: "delegator_reply",
|
|
15
|
+
status: "delegator_status",
|
|
16
16
|
});
|
|
17
17
|
|
|
18
18
|
export const DELEGATOR_JOB_STATUSES = Object.freeze([
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
"queued",
|
|
20
|
+
"running",
|
|
21
|
+
"waiting_reply",
|
|
22
|
+
"completed",
|
|
23
|
+
"failed",
|
|
24
24
|
]);
|
|
25
25
|
|
|
26
|
-
export const DELEGATOR_MODES = Object.freeze([
|
|
27
|
-
'sync',
|
|
28
|
-
'async',
|
|
29
|
-
]);
|
|
26
|
+
export const DELEGATOR_MODES = Object.freeze(["sync", "async"]);
|
|
30
27
|
|
|
31
|
-
export const DELEGATOR_PROVIDERS = Object.freeze([
|
|
32
|
-
'auto',
|
|
33
|
-
'codex',
|
|
34
|
-
'gemini',
|
|
35
|
-
]);
|
|
28
|
+
export const DELEGATOR_PROVIDERS = Object.freeze(["auto", "codex", "gemini"]);
|
|
36
29
|
|
|
37
|
-
export const DELEGATOR_SCHEMA_URL = new URL(
|
|
30
|
+
export const DELEGATOR_SCHEMA_URL = new URL(
|
|
31
|
+
"./schema/delegator-tools.schema.json",
|
|
32
|
+
import.meta.url,
|
|
33
|
+
);
|
package/hub/delegator/index.mjs
CHANGED
|
@@ -6,9 +6,9 @@ export {
|
|
|
6
6
|
DELEGATOR_PROVIDERS,
|
|
7
7
|
DELEGATOR_SCHEMA_URL,
|
|
8
8
|
DELEGATOR_TOOL_NAMES,
|
|
9
|
-
} from
|
|
10
|
-
export { DelegatorService } from
|
|
9
|
+
} from "./contracts.mjs";
|
|
10
|
+
export { DelegatorService } from "./service.mjs";
|
|
11
11
|
export {
|
|
12
12
|
getDelegatorMcpToolDefinitions,
|
|
13
13
|
loadDelegatorSchemaBundle,
|
|
14
|
-
} from
|
|
14
|
+
} from "./tool-definitions.mjs";
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { randomUUID } from
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
DELEGATOR_JOB_STATUSES,
|
|
5
5
|
DELEGATOR_MODES,
|
|
6
6
|
DELEGATOR_PROVIDERS,
|
|
7
|
-
} from
|
|
8
|
-
import { getDelegatorMcpToolDefinitions } from
|
|
7
|
+
} from "./contracts.mjs";
|
|
8
|
+
import { getDelegatorMcpToolDefinitions } from "./tool-definitions.mjs";
|
|
9
9
|
|
|
10
10
|
function deepClone(value) {
|
|
11
11
|
if (value == null) return value;
|
|
@@ -39,28 +39,28 @@ export class DelegatorService {
|
|
|
39
39
|
createJobSnapshot(input = {}) {
|
|
40
40
|
const timestamp = this.now().toISOString();
|
|
41
41
|
const jobId = input.job_id || this.idFactory();
|
|
42
|
-
const mode = input.mode ||
|
|
43
|
-
const providerRequested = input.provider ||
|
|
42
|
+
const mode = input.mode || "sync";
|
|
43
|
+
const providerRequested = input.provider || "auto";
|
|
44
44
|
|
|
45
|
-
assertKnown(DELEGATOR_MODES, mode,
|
|
46
|
-
assertKnown(DELEGATOR_PROVIDERS, providerRequested,
|
|
45
|
+
assertKnown(DELEGATOR_MODES, mode, "mode");
|
|
46
|
+
assertKnown(DELEGATOR_PROVIDERS, providerRequested, "provider");
|
|
47
47
|
|
|
48
48
|
return {
|
|
49
49
|
ok: true,
|
|
50
50
|
job_id: jobId,
|
|
51
|
-
status:
|
|
51
|
+
status: "queued",
|
|
52
52
|
mode,
|
|
53
53
|
provider_requested: providerRequested,
|
|
54
54
|
provider_resolved: null,
|
|
55
|
-
agent_type: input.agent_type ||
|
|
56
|
-
transport:
|
|
55
|
+
agent_type: input.agent_type || "executor",
|
|
56
|
+
transport: "resident-pending",
|
|
57
57
|
created_at: timestamp,
|
|
58
58
|
started_at: null,
|
|
59
59
|
updated_at: timestamp,
|
|
60
60
|
completed_at: null,
|
|
61
|
-
output:
|
|
62
|
-
stderr:
|
|
63
|
-
error:
|
|
61
|
+
output: "",
|
|
62
|
+
stderr: "",
|
|
63
|
+
error: "",
|
|
64
64
|
thread_id: input.thread_id || null,
|
|
65
65
|
session_key: input.session_key || null,
|
|
66
66
|
conversation_open: false,
|
|
@@ -69,9 +69,9 @@ export class DelegatorService {
|
|
|
69
69
|
|
|
70
70
|
recordJob(snapshot) {
|
|
71
71
|
if (!snapshot?.job_id) {
|
|
72
|
-
throw new Error(
|
|
72
|
+
throw new Error("job_id is required");
|
|
73
73
|
}
|
|
74
|
-
assertKnown(DELEGATOR_JOB_STATUSES, snapshot.status,
|
|
74
|
+
assertKnown(DELEGATOR_JOB_STATUSES, snapshot.status, "status");
|
|
75
75
|
this.jobs.set(snapshot.job_id, deepClone(snapshot));
|
|
76
76
|
return this.getStatusSnapshot(snapshot.job_id);
|
|
77
77
|
}
|
|
@@ -86,19 +86,20 @@ export class DelegatorService {
|
|
|
86
86
|
_normalizeInput(input = {}) {
|
|
87
87
|
return {
|
|
88
88
|
prompt: input.prompt,
|
|
89
|
-
provider: input.provider ||
|
|
90
|
-
mode: input.mode ||
|
|
91
|
-
agent_type: input.agent_type || input.agentType ||
|
|
89
|
+
provider: input.provider || "auto",
|
|
90
|
+
mode: input.mode || "sync",
|
|
91
|
+
agent_type: input.agent_type || input.agentType || "executor",
|
|
92
92
|
cwd: input.cwd || null,
|
|
93
93
|
timeout_ms: input.timeout_ms || input.timeoutMs || null,
|
|
94
94
|
session_key: input.session_key || input.sessionKey || null,
|
|
95
95
|
thread_id: input.thread_id || input.threadId || null,
|
|
96
96
|
reset_session: input.reset_session ?? input.resetSession ?? false,
|
|
97
|
-
mcp_profile: input.mcp_profile || input.mcpProfile ||
|
|
97
|
+
mcp_profile: input.mcp_profile || input.mcpProfile || "auto",
|
|
98
98
|
search_tool: input.search_tool || input.searchTool || null,
|
|
99
99
|
context_file: input.context_file || input.contextFile || null,
|
|
100
100
|
model: input.model || null,
|
|
101
|
-
developer_instructions:
|
|
101
|
+
developer_instructions:
|
|
102
|
+
input.developer_instructions || input.developerInstructions || null,
|
|
102
103
|
compact_prompt: input.compact_prompt || input.compactPrompt || null,
|
|
103
104
|
};
|
|
104
105
|
}
|
|
@@ -131,18 +132,22 @@ export class DelegatorService {
|
|
|
131
132
|
const ok = workerResult.ok !== false;
|
|
132
133
|
|
|
133
134
|
snapshot.ok = ok;
|
|
134
|
-
snapshot.status = workerResult.status || (ok ?
|
|
135
|
-
snapshot.provider_resolved =
|
|
135
|
+
snapshot.status = workerResult.status || (ok ? "completed" : "failed");
|
|
136
|
+
snapshot.provider_resolved =
|
|
137
|
+
workerResult.providerResolved || workerResult.provider_resolved || null;
|
|
136
138
|
snapshot.transport = workerResult.transport || snapshot.transport;
|
|
137
|
-
snapshot.output = workerResult.output ||
|
|
138
|
-
snapshot.stderr = workerResult.stderr ||
|
|
139
|
-
snapshot.error = workerResult.error ||
|
|
140
|
-
snapshot.thread_id =
|
|
141
|
-
|
|
142
|
-
snapshot.
|
|
139
|
+
snapshot.output = workerResult.output || "";
|
|
140
|
+
snapshot.stderr = workerResult.stderr || "";
|
|
141
|
+
snapshot.error = workerResult.error || "";
|
|
142
|
+
snapshot.thread_id =
|
|
143
|
+
workerResult.threadId || workerResult.thread_id || null;
|
|
144
|
+
snapshot.session_key =
|
|
145
|
+
workerResult.sessionKey || workerResult.session_key || null;
|
|
146
|
+
snapshot.conversation_open =
|
|
147
|
+
workerResult.conversationOpen ?? workerResult.conversation_open ?? false;
|
|
143
148
|
snapshot.started_at = snapshot.started_at || timestamp;
|
|
144
149
|
snapshot.updated_at = timestamp;
|
|
145
|
-
if (snapshot.status ===
|
|
150
|
+
if (snapshot.status === "completed" || snapshot.status === "failed") {
|
|
146
151
|
snapshot.completed_at = timestamp;
|
|
147
152
|
}
|
|
148
153
|
|
|
@@ -155,7 +160,7 @@ export class DelegatorService {
|
|
|
155
160
|
if (snapshot) {
|
|
156
161
|
const timestamp = this.now().toISOString();
|
|
157
162
|
snapshot.ok = false;
|
|
158
|
-
snapshot.status =
|
|
163
|
+
snapshot.status = "failed";
|
|
159
164
|
snapshot.error = error;
|
|
160
165
|
snapshot.updated_at = timestamp;
|
|
161
166
|
snapshot.completed_at = timestamp;
|
|
@@ -169,19 +174,19 @@ export class DelegatorService {
|
|
|
169
174
|
const timestamp = this.now().toISOString();
|
|
170
175
|
return {
|
|
171
176
|
ok: false,
|
|
172
|
-
job_id: jobId ||
|
|
173
|
-
status:
|
|
174
|
-
mode:
|
|
175
|
-
provider_requested:
|
|
177
|
+
job_id: jobId || "unknown",
|
|
178
|
+
status: "failed",
|
|
179
|
+
mode: "sync",
|
|
180
|
+
provider_requested: "auto",
|
|
176
181
|
provider_resolved: null,
|
|
177
|
-
agent_type:
|
|
178
|
-
transport:
|
|
182
|
+
agent_type: "executor",
|
|
183
|
+
transport: "resident-pending",
|
|
179
184
|
created_at: timestamp,
|
|
180
185
|
started_at: null,
|
|
181
186
|
updated_at: timestamp,
|
|
182
187
|
completed_at: timestamp,
|
|
183
|
-
output:
|
|
184
|
-
stderr:
|
|
188
|
+
output: "",
|
|
189
|
+
stderr: "",
|
|
185
190
|
error,
|
|
186
191
|
thread_id: null,
|
|
187
192
|
session_key: null,
|
|
@@ -194,15 +199,19 @@ export class DelegatorService {
|
|
|
194
199
|
async delegate(input = {}) {
|
|
195
200
|
const normalized = this._normalizeInput(input);
|
|
196
201
|
|
|
197
|
-
if (
|
|
198
|
-
|
|
202
|
+
if (
|
|
203
|
+
!normalized.prompt ||
|
|
204
|
+
typeof normalized.prompt !== "string" ||
|
|
205
|
+
!normalized.prompt.trim()
|
|
206
|
+
) {
|
|
207
|
+
return this._errorSnapshot(null, "prompt is required");
|
|
199
208
|
}
|
|
200
209
|
|
|
201
210
|
const snapshot = this.createJobSnapshot(normalized);
|
|
202
211
|
this.recordJob(snapshot);
|
|
203
212
|
|
|
204
213
|
if (!this.worker) {
|
|
205
|
-
return this._failJob(snapshot.job_id,
|
|
214
|
+
return this._failJob(snapshot.job_id, "worker가 설정되지 않았습니다");
|
|
206
215
|
}
|
|
207
216
|
|
|
208
217
|
const workerArgs = this._toWorkerArgs(normalized);
|
|
@@ -218,44 +227,53 @@ export class DelegatorService {
|
|
|
218
227
|
|
|
219
228
|
return this._applyWorkerResult(snapshot.job_id, workerResult);
|
|
220
229
|
} catch (err) {
|
|
221
|
-
return this._failJob(
|
|
230
|
+
return this._failJob(
|
|
231
|
+
snapshot.job_id,
|
|
232
|
+
err instanceof Error ? err.message : String(err),
|
|
233
|
+
);
|
|
222
234
|
}
|
|
223
235
|
}
|
|
224
236
|
|
|
225
237
|
async reply(input = {}) {
|
|
226
238
|
const jobId = input.job_id || input.jobId;
|
|
227
239
|
if (!jobId) {
|
|
228
|
-
return this._errorSnapshot(
|
|
240
|
+
return this._errorSnapshot("unknown", "job_id is required");
|
|
229
241
|
}
|
|
230
242
|
|
|
231
243
|
const snapshot = this.jobs.get(jobId);
|
|
232
244
|
if (!snapshot) {
|
|
233
|
-
return this._errorSnapshot(jobId,
|
|
245
|
+
return this._errorSnapshot(jobId, "job not found");
|
|
234
246
|
}
|
|
235
247
|
|
|
236
248
|
if (!snapshot.conversation_open) {
|
|
237
|
-
return this._failJob(jobId,
|
|
249
|
+
return this._failJob(jobId, "conversation is not open");
|
|
238
250
|
}
|
|
239
251
|
|
|
240
252
|
if (!this.worker) {
|
|
241
|
-
return this._failJob(jobId,
|
|
253
|
+
return this._failJob(jobId, "worker가 설정되지 않았습니다");
|
|
242
254
|
}
|
|
243
255
|
|
|
244
256
|
const workerJobId = this._workerJobMap.get(jobId);
|
|
245
257
|
if (!workerJobId) {
|
|
246
|
-
return this._failJob(jobId,
|
|
258
|
+
return this._failJob(jobId, "worker job 매핑을 찾을 수 없습니다");
|
|
247
259
|
}
|
|
248
260
|
|
|
249
261
|
try {
|
|
250
|
-
const workerResult = await this.worker.reply(
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
262
|
+
const workerResult = await this.worker.reply(
|
|
263
|
+
{
|
|
264
|
+
job_id: workerJobId,
|
|
265
|
+
reply: input.reply,
|
|
266
|
+
done: input.done ?? false,
|
|
267
|
+
},
|
|
268
|
+
null,
|
|
269
|
+
);
|
|
255
270
|
|
|
256
271
|
return this._applyWorkerResult(jobId, workerResult);
|
|
257
272
|
} catch (err) {
|
|
258
|
-
return this._failJob(
|
|
273
|
+
return this._failJob(
|
|
274
|
+
jobId,
|
|
275
|
+
err instanceof Error ? err.message : String(err),
|
|
276
|
+
);
|
|
259
277
|
}
|
|
260
278
|
}
|
|
261
279
|
|
|
@@ -267,20 +285,20 @@ export class DelegatorService {
|
|
|
267
285
|
const timestamp = this.now().toISOString();
|
|
268
286
|
return {
|
|
269
287
|
ok: false,
|
|
270
|
-
job_id: resolvedId ||
|
|
271
|
-
status:
|
|
272
|
-
mode:
|
|
273
|
-
provider_requested:
|
|
288
|
+
job_id: resolvedId || "unknown-job",
|
|
289
|
+
status: "failed",
|
|
290
|
+
mode: "async",
|
|
291
|
+
provider_requested: "auto",
|
|
274
292
|
provider_resolved: null,
|
|
275
|
-
agent_type:
|
|
276
|
-
transport:
|
|
293
|
+
agent_type: "executor",
|
|
294
|
+
transport: "resident-pending",
|
|
277
295
|
created_at: timestamp,
|
|
278
296
|
started_at: null,
|
|
279
297
|
updated_at: timestamp,
|
|
280
298
|
completed_at: null,
|
|
281
|
-
output:
|
|
282
|
-
stderr:
|
|
283
|
-
error:
|
|
299
|
+
output: "",
|
|
300
|
+
stderr: "",
|
|
301
|
+
error: "job not found",
|
|
284
302
|
thread_id: null,
|
|
285
303
|
session_key: null,
|
|
286
304
|
conversation_open: false,
|
|
@@ -288,11 +306,17 @@ export class DelegatorService {
|
|
|
288
306
|
}
|
|
289
307
|
|
|
290
308
|
// running/queued 상태이면 worker에서 최신 상태 갱신
|
|
291
|
-
if (
|
|
309
|
+
if (
|
|
310
|
+
this.worker &&
|
|
311
|
+
(snapshot.status === "running" || snapshot.status === "queued")
|
|
312
|
+
) {
|
|
292
313
|
const workerJobId = this._workerJobMap.get(resolvedId);
|
|
293
314
|
if (workerJobId) {
|
|
294
315
|
try {
|
|
295
|
-
const workerResult = await this.worker.getJobStatus(
|
|
316
|
+
const workerResult = await this.worker.getJobStatus(
|
|
317
|
+
workerJobId,
|
|
318
|
+
null,
|
|
319
|
+
);
|
|
296
320
|
if (workerResult && workerResult.ok !== undefined) {
|
|
297
321
|
return this._applyWorkerResult(resolvedId, workerResult);
|
|
298
322
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { readFileSync } from
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
2
|
|
|
3
|
-
import { DELEGATOR_SCHEMA_URL } from
|
|
3
|
+
import { DELEGATOR_SCHEMA_URL } from "./contracts.mjs";
|
|
4
4
|
|
|
5
5
|
let schemaBundleCache = null;
|
|
6
6
|
|
|
@@ -14,15 +14,15 @@ export function loadDelegatorSchemaBundle() {
|
|
|
14
14
|
return schemaBundleCache;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
schemaBundleCache = JSON.parse(readFileSync(DELEGATOR_SCHEMA_URL,
|
|
17
|
+
schemaBundleCache = JSON.parse(readFileSync(DELEGATOR_SCHEMA_URL, "utf8"));
|
|
18
18
|
return schemaBundleCache;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export function getDelegatorMcpToolDefinitions() {
|
|
22
22
|
const bundle = loadDelegatorSchemaBundle();
|
|
23
23
|
const defs = bundle.$defs || {};
|
|
24
|
-
const tools = Array.isArray(bundle[
|
|
25
|
-
? bundle[
|
|
24
|
+
const tools = Array.isArray(bundle["x-triflux-mcp-tools"])
|
|
25
|
+
? bundle["x-triflux-mcp-tools"]
|
|
26
26
|
: [];
|
|
27
27
|
|
|
28
28
|
return tools.map((tool) => ({
|