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
|
@@ -1,79 +1,312 @@
|
|
|
1
|
-
export const SEARCH_SERVER_ORDER = Object.freeze([
|
|
1
|
+
export const SEARCH_SERVER_ORDER = Object.freeze([
|
|
2
|
+
"brave-search",
|
|
3
|
+
"tavily",
|
|
4
|
+
"exa",
|
|
5
|
+
]);
|
|
2
6
|
|
|
3
7
|
export const MCP_SERVER_TOOL_CATALOG = Object.freeze({
|
|
4
|
-
context7: Object.freeze([
|
|
5
|
-
|
|
6
|
-
exa: Object.freeze([
|
|
7
|
-
tavily: Object.freeze([
|
|
8
|
+
context7: Object.freeze(["resolve-library-id", "query-docs"]),
|
|
9
|
+
"brave-search": Object.freeze(["brave_web_search", "brave_news_search"]),
|
|
10
|
+
exa: Object.freeze(["web_search_exa", "get_code_context_exa"]),
|
|
11
|
+
tavily: Object.freeze(["tavily_search", "tavily_extract"]),
|
|
8
12
|
playwright: Object.freeze([
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
"browser_navigate",
|
|
14
|
+
"browser_navigate_back",
|
|
15
|
+
"browser_snapshot",
|
|
16
|
+
"browser_take_screenshot",
|
|
17
|
+
"browser_wait_for",
|
|
14
18
|
]),
|
|
15
|
-
|
|
19
|
+
"sequential-thinking": Object.freeze(["sequentialthinking"]),
|
|
16
20
|
});
|
|
17
21
|
|
|
18
22
|
export const MCP_SERVER_DOMAIN_TAGS = Object.freeze({
|
|
19
|
-
context7: Object.freeze([
|
|
20
|
-
|
|
21
|
-
exa: Object.freeze([
|
|
22
|
-
tavily: Object.freeze([
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
context7: Object.freeze(["docs", "reference", "api", "sdk", "library"]),
|
|
24
|
+
"brave-search": Object.freeze(["web", "search", "news", "current"]),
|
|
25
|
+
exa: Object.freeze(["code", "repository", "examples", "search"]),
|
|
26
|
+
tavily: Object.freeze([
|
|
27
|
+
"research",
|
|
28
|
+
"search",
|
|
29
|
+
"news",
|
|
30
|
+
"verification",
|
|
31
|
+
"current",
|
|
32
|
+
]),
|
|
33
|
+
playwright: Object.freeze(["browser", "ui", "visual", "e2e"]),
|
|
34
|
+
"sequential-thinking": Object.freeze([
|
|
35
|
+
"analysis",
|
|
36
|
+
"planning",
|
|
37
|
+
"reasoning",
|
|
38
|
+
"security",
|
|
39
|
+
"review",
|
|
40
|
+
]),
|
|
25
41
|
});
|
|
26
42
|
|
|
27
43
|
export const DOMAIN_TAG_KEYWORDS = Object.freeze({
|
|
28
|
-
docs: Object.freeze([
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
44
|
+
docs: Object.freeze([
|
|
45
|
+
"docs",
|
|
46
|
+
"documentation",
|
|
47
|
+
"manual",
|
|
48
|
+
"guide",
|
|
49
|
+
"문서",
|
|
50
|
+
"가이드",
|
|
51
|
+
"매뉴얼",
|
|
52
|
+
]),
|
|
53
|
+
reference: Object.freeze([
|
|
54
|
+
"reference",
|
|
55
|
+
"spec",
|
|
56
|
+
"schema",
|
|
57
|
+
"official",
|
|
58
|
+
"레퍼런스",
|
|
59
|
+
"공식",
|
|
60
|
+
"스펙",
|
|
61
|
+
"스키마",
|
|
62
|
+
]),
|
|
63
|
+
api: Object.freeze([
|
|
64
|
+
"api",
|
|
65
|
+
"endpoint",
|
|
66
|
+
"interface",
|
|
67
|
+
"sdk",
|
|
68
|
+
"호출",
|
|
69
|
+
"엔드포인트",
|
|
70
|
+
]),
|
|
71
|
+
sdk: Object.freeze([
|
|
72
|
+
"sdk",
|
|
73
|
+
"library",
|
|
74
|
+
"package",
|
|
75
|
+
"framework",
|
|
76
|
+
"라이브러리",
|
|
77
|
+
"패키지",
|
|
78
|
+
"프레임워크",
|
|
79
|
+
]),
|
|
80
|
+
library: Object.freeze([
|
|
81
|
+
"library",
|
|
82
|
+
"package",
|
|
83
|
+
"framework",
|
|
84
|
+
"module",
|
|
85
|
+
"라이브러리",
|
|
86
|
+
"패키지",
|
|
87
|
+
"모듈",
|
|
88
|
+
]),
|
|
89
|
+
web: Object.freeze([
|
|
90
|
+
"web",
|
|
91
|
+
"site",
|
|
92
|
+
"article",
|
|
93
|
+
"forum",
|
|
94
|
+
"blog",
|
|
95
|
+
"reddit",
|
|
96
|
+
"웹",
|
|
97
|
+
"사이트",
|
|
98
|
+
"기사",
|
|
99
|
+
"포럼",
|
|
100
|
+
"블로그",
|
|
101
|
+
]),
|
|
102
|
+
search: Object.freeze([
|
|
103
|
+
"search",
|
|
104
|
+
"browse",
|
|
105
|
+
"lookup",
|
|
106
|
+
"find",
|
|
107
|
+
"검색",
|
|
108
|
+
"조회",
|
|
109
|
+
"탐색",
|
|
110
|
+
"찾아",
|
|
111
|
+
]),
|
|
112
|
+
news: Object.freeze([
|
|
113
|
+
"latest",
|
|
114
|
+
"recent",
|
|
115
|
+
"news",
|
|
116
|
+
"today",
|
|
117
|
+
"release",
|
|
118
|
+
"announcement",
|
|
119
|
+
"최신",
|
|
120
|
+
"최근",
|
|
121
|
+
"뉴스",
|
|
122
|
+
"오늘",
|
|
123
|
+
"릴리즈",
|
|
124
|
+
"공지",
|
|
125
|
+
]),
|
|
126
|
+
current: Object.freeze([
|
|
127
|
+
"current",
|
|
128
|
+
"status",
|
|
129
|
+
"pricing",
|
|
130
|
+
"changelog",
|
|
131
|
+
"up-to-date",
|
|
132
|
+
"현재",
|
|
133
|
+
"상태",
|
|
134
|
+
"가격",
|
|
135
|
+
"변경사항",
|
|
136
|
+
]),
|
|
137
|
+
research: Object.freeze([
|
|
138
|
+
"research",
|
|
139
|
+
"verify",
|
|
140
|
+
"fact-check",
|
|
141
|
+
"investigate",
|
|
142
|
+
"리서치",
|
|
143
|
+
"검증",
|
|
144
|
+
"조사",
|
|
145
|
+
]),
|
|
146
|
+
verification: Object.freeze([
|
|
147
|
+
"verify",
|
|
148
|
+
"validation",
|
|
149
|
+
"fact-check",
|
|
150
|
+
"audit",
|
|
151
|
+
"검증",
|
|
152
|
+
"확인",
|
|
153
|
+
"감사",
|
|
154
|
+
]),
|
|
155
|
+
code: Object.freeze([
|
|
156
|
+
"code",
|
|
157
|
+
"repo",
|
|
158
|
+
"repository",
|
|
159
|
+
"source",
|
|
160
|
+
"implementation",
|
|
161
|
+
"bug",
|
|
162
|
+
"fix",
|
|
163
|
+
"test",
|
|
164
|
+
"snippet",
|
|
165
|
+
"cli",
|
|
166
|
+
"코드",
|
|
167
|
+
"리포",
|
|
168
|
+
"저장소",
|
|
169
|
+
"구현",
|
|
170
|
+
"버그",
|
|
171
|
+
"테스트",
|
|
172
|
+
"예제",
|
|
173
|
+
"스크립트",
|
|
174
|
+
]),
|
|
175
|
+
repository: Object.freeze([
|
|
176
|
+
"repo",
|
|
177
|
+
"repository",
|
|
178
|
+
"source",
|
|
179
|
+
"git",
|
|
180
|
+
"github",
|
|
181
|
+
"리포",
|
|
182
|
+
"저장소",
|
|
183
|
+
"소스",
|
|
184
|
+
]),
|
|
185
|
+
examples: Object.freeze([
|
|
186
|
+
"example",
|
|
187
|
+
"examples",
|
|
188
|
+
"snippet",
|
|
189
|
+
"sample",
|
|
190
|
+
"예제",
|
|
191
|
+
"샘플",
|
|
192
|
+
]),
|
|
193
|
+
browser: Object.freeze([
|
|
194
|
+
"browser",
|
|
195
|
+
"page",
|
|
196
|
+
"dom",
|
|
197
|
+
"screenshot",
|
|
198
|
+
"render",
|
|
199
|
+
"브라우저",
|
|
200
|
+
"페이지",
|
|
201
|
+
"스크린샷",
|
|
202
|
+
"렌더",
|
|
203
|
+
]),
|
|
204
|
+
ui: Object.freeze([
|
|
205
|
+
"ui",
|
|
206
|
+
"ux",
|
|
207
|
+
"layout",
|
|
208
|
+
"responsive",
|
|
209
|
+
"css",
|
|
210
|
+
"html",
|
|
211
|
+
"디자인",
|
|
212
|
+
"레이아웃",
|
|
213
|
+
"반응형",
|
|
214
|
+
]),
|
|
215
|
+
visual: Object.freeze([
|
|
216
|
+
"visual",
|
|
217
|
+
"screenshot",
|
|
218
|
+
"layout",
|
|
219
|
+
"render",
|
|
220
|
+
"screen",
|
|
221
|
+
"화면",
|
|
222
|
+
"시각",
|
|
223
|
+
"스크린샷",
|
|
224
|
+
]),
|
|
225
|
+
e2e: Object.freeze([
|
|
226
|
+
"playwright",
|
|
227
|
+
"e2e",
|
|
228
|
+
"click",
|
|
229
|
+
"navigate",
|
|
230
|
+
"automation",
|
|
231
|
+
"playwright",
|
|
232
|
+
"클릭",
|
|
233
|
+
"이동",
|
|
234
|
+
"자동화",
|
|
235
|
+
]),
|
|
236
|
+
analysis: Object.freeze([
|
|
237
|
+
"analysis",
|
|
238
|
+
"analyze",
|
|
239
|
+
"audit",
|
|
240
|
+
"compare",
|
|
241
|
+
"root cause",
|
|
242
|
+
"분석",
|
|
243
|
+
"검토",
|
|
244
|
+
"비교",
|
|
245
|
+
"원인",
|
|
246
|
+
]),
|
|
247
|
+
planning: Object.freeze([
|
|
248
|
+
"plan",
|
|
249
|
+
"planning",
|
|
250
|
+
"strategy",
|
|
251
|
+
"design",
|
|
252
|
+
"계획",
|
|
253
|
+
"전략",
|
|
254
|
+
"설계",
|
|
255
|
+
]),
|
|
256
|
+
reasoning: Object.freeze([
|
|
257
|
+
"reason",
|
|
258
|
+
"reasoning",
|
|
259
|
+
"think",
|
|
260
|
+
"critique",
|
|
261
|
+
"추론",
|
|
262
|
+
"사고",
|
|
263
|
+
"비평",
|
|
264
|
+
]),
|
|
265
|
+
security: Object.freeze([
|
|
266
|
+
"security",
|
|
267
|
+
"risk",
|
|
268
|
+
"threat",
|
|
269
|
+
"vulnerability",
|
|
270
|
+
"보안",
|
|
271
|
+
"위험",
|
|
272
|
+
"취약점",
|
|
273
|
+
]),
|
|
274
|
+
review: Object.freeze(["review", "reviewer", "inspect", "리뷰", "검수"]),
|
|
51
275
|
});
|
|
52
276
|
|
|
53
277
|
export const SERVER_EXPLICIT_KEYWORDS = Object.freeze({
|
|
54
|
-
context7: Object.freeze([
|
|
55
|
-
|
|
56
|
-
exa: Object.freeze([
|
|
57
|
-
tavily: Object.freeze([
|
|
58
|
-
playwright: Object.freeze([
|
|
59
|
-
|
|
278
|
+
context7: Object.freeze(["context7"]),
|
|
279
|
+
"brave-search": Object.freeze(["brave", "brave-search"]),
|
|
280
|
+
exa: Object.freeze(["exa"]),
|
|
281
|
+
tavily: Object.freeze(["tavily"]),
|
|
282
|
+
playwright: Object.freeze(["playwright"]),
|
|
283
|
+
"sequential-thinking": Object.freeze([
|
|
284
|
+
"sequential-thinking",
|
|
285
|
+
"sequential thinking",
|
|
286
|
+
]),
|
|
60
287
|
});
|
|
61
288
|
|
|
62
289
|
export function uniqueStrings(values = []) {
|
|
63
|
-
return [
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
290
|
+
return [
|
|
291
|
+
...new Set(
|
|
292
|
+
values
|
|
293
|
+
.filter((value) => typeof value === "string" && value.trim())
|
|
294
|
+
.map((value) => value.trim()),
|
|
295
|
+
),
|
|
296
|
+
];
|
|
68
297
|
}
|
|
69
298
|
|
|
70
|
-
export function inferDomainTagsFromText(text =
|
|
71
|
-
if (typeof text !==
|
|
299
|
+
export function inferDomainTagsFromText(text = "") {
|
|
300
|
+
if (typeof text !== "string" || !text.trim()) return [];
|
|
72
301
|
const normalized = text.toLocaleLowerCase();
|
|
73
302
|
const matched = [];
|
|
74
303
|
|
|
75
304
|
for (const [tag, keywords] of Object.entries(DOMAIN_TAG_KEYWORDS)) {
|
|
76
|
-
if (
|
|
305
|
+
if (
|
|
306
|
+
keywords.some((keyword) =>
|
|
307
|
+
normalized.includes(String(keyword).toLocaleLowerCase()),
|
|
308
|
+
)
|
|
309
|
+
) {
|
|
77
310
|
matched.push(tag);
|
|
78
311
|
}
|
|
79
312
|
}
|
|
@@ -81,7 +314,7 @@ export function inferDomainTagsFromText(text = '') {
|
|
|
81
314
|
return uniqueStrings(matched);
|
|
82
315
|
}
|
|
83
316
|
|
|
84
|
-
export function getDefaultServerMetadata(serverName =
|
|
317
|
+
export function getDefaultServerMetadata(serverName = "") {
|
|
85
318
|
const toolCount = MCP_SERVER_TOOL_CATALOG[serverName]?.length || 0;
|
|
86
319
|
const domainTags = uniqueStrings([
|
|
87
320
|
...(MCP_SERVER_DOMAIN_TAGS[serverName] || []),
|
|
@@ -94,7 +327,7 @@ export function getDefaultServerMetadata(serverName = '') {
|
|
|
94
327
|
};
|
|
95
328
|
}
|
|
96
329
|
|
|
97
|
-
export function normalizeServerMetadata(serverName =
|
|
330
|
+
export function normalizeServerMetadata(serverName = "", metadata = {}) {
|
|
98
331
|
const fallback = getDefaultServerMetadata(serverName);
|
|
99
332
|
const toolCount = Number.isFinite(metadata.tool_count)
|
|
100
333
|
? Math.max(0, Math.trunc(metadata.tool_count))
|
|
@@ -102,13 +335,17 @@ export function normalizeServerMetadata(serverName = '', metadata = {}) {
|
|
|
102
335
|
const domainTags = uniqueStrings([
|
|
103
336
|
...fallback.domain_tags,
|
|
104
337
|
...(Array.isArray(metadata.domain_tags) ? metadata.domain_tags : []),
|
|
105
|
-
...inferDomainTagsFromText(
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
338
|
+
...inferDomainTagsFromText(
|
|
339
|
+
[
|
|
340
|
+
serverName,
|
|
341
|
+
typeof metadata.command === "string" ? metadata.command : "",
|
|
342
|
+
typeof metadata.url === "string" ? metadata.url : "",
|
|
343
|
+
...(Array.isArray(metadata.args) ? metadata.args : []),
|
|
344
|
+
...(metadata.env && typeof metadata.env === "object"
|
|
345
|
+
? Object.keys(metadata.env)
|
|
346
|
+
: []),
|
|
347
|
+
].join(" "),
|
|
348
|
+
),
|
|
112
349
|
]);
|
|
113
350
|
|
|
114
351
|
return {
|
|
@@ -8,9 +8,7 @@ export const PSMUX_REQUIRED_COMMANDS = [
|
|
|
8
8
|
"capture-pane",
|
|
9
9
|
];
|
|
10
10
|
|
|
11
|
-
export const PSMUX_OPTIONAL_COMMANDS = [
|
|
12
|
-
"detach-client",
|
|
13
|
-
];
|
|
11
|
+
export const PSMUX_OPTIONAL_COMMANDS = ["detach-client"];
|
|
14
12
|
|
|
15
13
|
export const PSMUX_INSTALL_COMMANDS = [
|
|
16
14
|
"winget install marlocarlo.psmux",
|
|
@@ -26,7 +24,10 @@ export const PSMUX_UPDATE_COMMANDS = [
|
|
|
26
24
|
"cargo install psmux --force",
|
|
27
25
|
];
|
|
28
26
|
|
|
29
|
-
export function formatPsmuxCommandList(
|
|
27
|
+
export function formatPsmuxCommandList(
|
|
28
|
+
commands = PSMUX_INSTALL_COMMANDS,
|
|
29
|
+
indent = "",
|
|
30
|
+
) {
|
|
30
31
|
return commands.map((command) => `${indent}${command}`).join("\n");
|
|
31
32
|
}
|
|
32
33
|
|
|
@@ -44,8 +45,12 @@ export function parsePsmuxVersion(output = "") {
|
|
|
44
45
|
}
|
|
45
46
|
|
|
46
47
|
export function compareSemver(a, b) {
|
|
47
|
-
const left = String(a || "")
|
|
48
|
-
|
|
48
|
+
const left = String(a || "")
|
|
49
|
+
.split(".")
|
|
50
|
+
.map((part) => Number.parseInt(part, 10) || 0);
|
|
51
|
+
const right = String(b || "")
|
|
52
|
+
.split(".")
|
|
53
|
+
.map((part) => Number.parseInt(part, 10) || 0);
|
|
49
54
|
for (let index = 0; index < 3; index += 1) {
|
|
50
55
|
if (left[index] > right[index]) return 1;
|
|
51
56
|
if (left[index] < right[index]) return -1;
|
|
@@ -13,22 +13,37 @@ function normalizeMarkdownTarget(raw) {
|
|
|
13
13
|
function sanitizeToken(raw) {
|
|
14
14
|
let token = String(raw || "").trim();
|
|
15
15
|
if (!token) return "";
|
|
16
|
-
token = token
|
|
16
|
+
token = token
|
|
17
|
+
.replace(/^[<(]+/u, "")
|
|
18
|
+
.replace(/[)>.,;:!?]+$/u, "")
|
|
19
|
+
.trim();
|
|
17
20
|
return token;
|
|
18
21
|
}
|
|
19
22
|
|
|
20
23
|
function isLikelyPathToken(token) {
|
|
21
24
|
if (!token || URL_LIKE_RE.test(token)) return false;
|
|
22
|
-
if (
|
|
25
|
+
if (
|
|
26
|
+
token.startsWith("app://") ||
|
|
27
|
+
token.startsWith("plugin://") ||
|
|
28
|
+
token.startsWith("mention://")
|
|
29
|
+
)
|
|
30
|
+
return false;
|
|
23
31
|
if (token === "~") return false;
|
|
24
32
|
|
|
25
33
|
const hasPathSeparator = token.includes("/") || token.includes("\\");
|
|
26
|
-
const hasDotPrefix =
|
|
34
|
+
const hasDotPrefix =
|
|
35
|
+
token.startsWith("./") || token.startsWith("../") || token.startsWith(".");
|
|
27
36
|
const isHomeRelative = token.startsWith("~/") || token.startsWith("~\\");
|
|
28
37
|
const isWindowsAbs = WINDOWS_ABS_RE.test(token);
|
|
29
38
|
const hasFileLikeSuffix = /\.[a-zA-Z0-9]{1,16}$/u.test(token);
|
|
30
39
|
|
|
31
|
-
return
|
|
40
|
+
return (
|
|
41
|
+
hasPathSeparator ||
|
|
42
|
+
hasDotPrefix ||
|
|
43
|
+
isHomeRelative ||
|
|
44
|
+
isWindowsAbs ||
|
|
45
|
+
hasFileLikeSuffix
|
|
46
|
+
);
|
|
32
47
|
}
|
|
33
48
|
|
|
34
49
|
export function extractExplicitFileTokens(text) {
|
|
@@ -67,7 +82,9 @@ function validateTransferFile(filePath, maxBytes) {
|
|
|
67
82
|
throw new Error(`referenced path is not a file: ${filePath}`);
|
|
68
83
|
}
|
|
69
84
|
if (stats.size > maxBytes) {
|
|
70
|
-
throw new Error(
|
|
85
|
+
throw new Error(
|
|
86
|
+
`referenced file too large: ${stats.size} bytes (max ${maxBytes}) for ${filePath}`,
|
|
87
|
+
);
|
|
71
88
|
}
|
|
72
89
|
return stats.size;
|
|
73
90
|
}
|
|
@@ -132,16 +149,23 @@ export function buildRemoteTransferPlan(options = {}) {
|
|
|
132
149
|
validateTransferFile(absoluteHandoffPath, maxBytes);
|
|
133
150
|
const handoffContent = readFileSync(absoluteHandoffPath, "utf8").trim();
|
|
134
151
|
|
|
135
|
-
const stagedHandoffPath = toRemotePath(
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
152
|
+
const stagedHandoffPath = toRemotePath(
|
|
153
|
+
remoteStageRoot,
|
|
154
|
+
`handoff/${basename(absoluteHandoffPath)}`,
|
|
155
|
+
);
|
|
156
|
+
const transfers = [
|
|
157
|
+
{
|
|
158
|
+
localPath: absoluteHandoffPath,
|
|
159
|
+
remotePath: stagedHandoffPath,
|
|
160
|
+
type: "handoff",
|
|
161
|
+
},
|
|
162
|
+
];
|
|
141
163
|
|
|
142
164
|
const tokens = extractExplicitFileTokens(handoffContent);
|
|
143
165
|
if (tokens.length > maxReferenceFiles) {
|
|
144
|
-
throw new Error(
|
|
166
|
+
throw new Error(
|
|
167
|
+
`too many referenced files: ${tokens.length} (max ${maxReferenceFiles})`,
|
|
168
|
+
);
|
|
145
169
|
}
|
|
146
170
|
|
|
147
171
|
const stagedByLocalPath = new Map();
|
|
@@ -166,7 +190,10 @@ export function buildRemoteTransferPlan(options = {}) {
|
|
|
166
190
|
});
|
|
167
191
|
}
|
|
168
192
|
|
|
169
|
-
replacements.push({
|
|
193
|
+
replacements.push({
|
|
194
|
+
token,
|
|
195
|
+
stagedPath: stagedByLocalPath.get(resolvedPath),
|
|
196
|
+
});
|
|
170
197
|
}
|
|
171
198
|
|
|
172
199
|
const replacementEntries = Array.from(
|
|
@@ -189,7 +216,10 @@ export function buildRemoteTransferPlan(options = {}) {
|
|
|
189
216
|
|
|
190
217
|
return {
|
|
191
218
|
prompt,
|
|
192
|
-
replacements: replacementEntries.map(([token, stagedPath]) => ({
|
|
219
|
+
replacements: replacementEntries.map(([token, stagedPath]) => ({
|
|
220
|
+
stagedPath,
|
|
221
|
+
token,
|
|
222
|
+
})),
|
|
193
223
|
stagedHandoffPath,
|
|
194
224
|
transfers,
|
|
195
225
|
};
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
basename,
|
|
4
|
+
extname,
|
|
5
|
+
isAbsolute,
|
|
6
|
+
join,
|
|
7
|
+
relative,
|
|
8
|
+
resolve,
|
|
9
|
+
} from "node:path";
|
|
3
10
|
|
|
4
11
|
const IF_TAG_RE = /{{\s*(#if\s+([A-Za-z0-9_.-]+)|\/if)\s*}}/g;
|
|
5
12
|
const PARTIAL_RE = /{{>\s*([A-Za-z0-9_./-]+)\s*}}/g;
|
|
@@ -187,7 +194,8 @@ function resolveIncludeContent(includeName, options) {
|
|
|
187
194
|
const fullPath = resolve(baseDir, normalizedName);
|
|
188
195
|
const relativePath = relative(baseDir, fullPath);
|
|
189
196
|
const isInsideBaseDir =
|
|
190
|
-
relativePath === "" ||
|
|
197
|
+
relativePath === "" ||
|
|
198
|
+
(!relativePath.startsWith("..") && !isAbsolute(relativePath));
|
|
191
199
|
|
|
192
200
|
if (!isInsideBaseDir || !existsSync(fullPath)) {
|
|
193
201
|
throw new Error(`Missing include: ${normalizedName}`);
|
|
@@ -223,9 +231,21 @@ function renderVariables(source, context) {
|
|
|
223
231
|
});
|
|
224
232
|
}
|
|
225
233
|
|
|
226
|
-
function renderWithContext(
|
|
234
|
+
function renderWithContext(
|
|
235
|
+
source,
|
|
236
|
+
context,
|
|
237
|
+
partials,
|
|
238
|
+
options,
|
|
239
|
+
includeStack = [],
|
|
240
|
+
) {
|
|
227
241
|
const afterIf = evaluateConditionals(source, context);
|
|
228
|
-
const afterPartials = renderPartials(
|
|
242
|
+
const afterPartials = renderPartials(
|
|
243
|
+
afterIf,
|
|
244
|
+
context,
|
|
245
|
+
partials,
|
|
246
|
+
options,
|
|
247
|
+
includeStack,
|
|
248
|
+
);
|
|
229
249
|
const afterFileIncludes = renderFileIncludes(
|
|
230
250
|
afterPartials,
|
|
231
251
|
context,
|
|
@@ -239,8 +259,8 @@ function renderWithContext(source, context, partials, options, includeStack = []
|
|
|
239
259
|
function readAllTemplateFiles(rootDir, currentDir = rootDir) {
|
|
240
260
|
if (!rootDir || !existsSync(rootDir)) return [];
|
|
241
261
|
|
|
242
|
-
const entries = readdirSync(currentDir, { withFileTypes: true }).sort(
|
|
243
|
-
left.name.localeCompare(right.name),
|
|
262
|
+
const entries = readdirSync(currentDir, { withFileTypes: true }).sort(
|
|
263
|
+
(left, right) => left.name.localeCompare(right.name),
|
|
244
264
|
);
|
|
245
265
|
const files = [];
|
|
246
266
|
|
|
@@ -278,7 +298,10 @@ export function parseFrontmatter(source) {
|
|
|
278
298
|
return { data, body };
|
|
279
299
|
}
|
|
280
300
|
|
|
281
|
-
export function buildSkillTemplateContext({
|
|
301
|
+
export function buildSkillTemplateContext({
|
|
302
|
+
frontmatter = {},
|
|
303
|
+
skillDirName = "",
|
|
304
|
+
} = {}) {
|
|
282
305
|
const context = { ...frontmatter };
|
|
283
306
|
const skillName = String(frontmatter.name || skillDirName || "").trim();
|
|
284
307
|
const skillDescription = String(frontmatter.description || "").trim();
|