tribunal-kit 6.0.0 → 7.0.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/.agent/.manifest.json +78 -0
- package/.agent/ARCHITECTURE.md +19 -241
- package/.agent/agents/accessibility-reviewer.md +23 -16
- package/.agent/agents/ai-code-reviewer.md +25 -21
- package/.agent/agents/anti-pattern-reviewer.md +12 -7
- package/.agent/agents/api-architect.md +1 -0
- package/.agent/agents/backend-specialist.md +23 -22
- package/.agent/agents/cloud-engineer.md +1 -0
- package/.agent/agents/code-archaeologist.md +1 -0
- package/.agent/agents/complexity-reviewer.md +10 -7
- package/.agent/agents/database-architect.md +3 -2
- package/.agent/agents/db-latency-auditor.md +6 -2
- package/.agent/agents/debugger.md +3 -2
- package/.agent/agents/dependency-reviewer.md +1 -0
- package/.agent/agents/devops-engineer.md +9 -8
- package/.agent/agents/documentation-writer.md +6 -5
- package/.agent/agents/explorer-agent.md +1 -0
- package/.agent/agents/frontend-reviewer.md +21 -17
- package/.agent/agents/frontend-specialist.md +23 -20
- package/.agent/agents/game-developer.md +1 -0
- package/.agent/agents/interaction-reviewer.md +10 -5
- package/.agent/agents/logic-reviewer.md +3 -0
- package/.agent/agents/minimalist-reviewer.md +6 -0
- package/.agent/agents/mobile-developer.md +7 -6
- package/.agent/agents/mobile-reviewer.md +14 -13
- package/.agent/agents/orchestrator.md +3 -0
- package/.agent/agents/penetration-tester.md +1 -0
- package/.agent/agents/performance-optimizer.md +6 -5
- package/.agent/agents/performance-reviewer.md +6 -6
- package/.agent/agents/pipeline-reviewer.md +144 -0
- package/.agent/agents/precedence-reviewer.md +1 -0
- package/.agent/agents/product-manager.md +1 -0
- package/.agent/agents/product-owner.md +1 -0
- package/.agent/agents/product-reviewer.md +12 -7
- package/.agent/agents/project-planner.md +3 -0
- package/.agent/agents/qa-automation-engineer.md +50 -43
- package/.agent/agents/resilience-reviewer.md +1 -0
- package/.agent/agents/schema-reviewer.md +1 -0
- package/.agent/agents/security-auditor.md +24 -24
- package/.agent/agents/seo-specialist.md +33 -23
- package/.agent/agents/sql-reviewer.md +5 -4
- package/.agent/agents/supervisor-agent.md +12 -2
- package/.agent/agents/swarm-worker-contracts.md +13 -13
- package/.agent/agents/swarm-worker-registry.md +51 -51
- package/.agent/agents/system-architect.md +1 -0
- package/.agent/agents/test-coverage-reviewer.md +25 -22
- package/.agent/agents/test-engineer.md +12 -11
- package/.agent/agents/throughput-optimizer.md +45 -40
- package/.agent/agents/type-safety-reviewer.md +5 -4
- package/.agent/agents/ui-ux-auditor.md +6 -4
- package/.agent/agents/ui-visual-auditor.md +3 -0
- package/.agent/agents/ux-reviewer.md +11 -6
- package/.agent/agents/visual-reviewer.md +11 -6
- package/.agent/agents/vitals-reviewer.md +5 -4
- package/.agent/history/memory/.memory.idx +3716 -1
- package/.agent/history/memory/MEMORY.md +246 -1
- package/.agent/mcp_config.json +1 -6
- package/.agent/routing_index.json +2034 -263
- package/.agent/rules/GEMINI.md +12 -10
- package/.agent/rules/GEMINI_PLANNER.md +19 -21
- package/.agent/scripts/_colors.js +52 -54
- package/.agent/scripts/_utils.js +52 -53
- package/.agent/scripts/auto_preview.js +39 -43
- package/.agent/scripts/bundle_analyzer.js +47 -60
- package/.agent/scripts/case_law_manager.js +200 -294
- package/.agent/scripts/checklist.js +73 -94
- package/.agent/scripts/cicd_validator.js +305 -0
- package/.agent/scripts/compile_router.py +4 -111
- package/.agent/scripts/context_broker.js +317 -412
- package/.agent/scripts/contract_engine.js +402 -0
- package/.agent/scripts/dependency_analyzer.js +112 -124
- package/.agent/scripts/graph_builder.js +75 -103
- package/.agent/scripts/graph_visualizer.js +10 -12
- package/.agent/scripts/graph_zoom.js +38 -55
- package/.agent/scripts/guardrail_engine.js +195 -145
- package/.agent/scripts/impact_classifier.js +55 -30
- package/.agent/scripts/inner_loop_validator.js +108 -159
- package/.agent/scripts/integrity_manifest.js +59 -67
- package/.agent/scripts/lint_runner.js +65 -75
- package/.agent/scripts/marathon_harness.js +131 -208
- package/.agent/scripts/migrate_skills_frontmatter.py +4 -63
- package/.agent/scripts/minify_context.js +29 -33
- package/.agent/scripts/minimal_change_engine.js +95 -87
- package/.agent/scripts/mutation_runner.js +46 -62
- package/.agent/scripts/pipeline_engine.js +320 -209
- package/.agent/scripts/prompt_compiler.js +118 -93
- package/.agent/scripts/schema_validator.js +73 -121
- package/.agent/scripts/security_scan.js +88 -117
- package/.agent/scripts/session_manager.js +52 -69
- package/.agent/scripts/signal_detector.js +24 -22
- package/.agent/scripts/skill_evolution.js +184 -245
- package/.agent/scripts/skill_integrator.js +35 -48
- package/.agent/scripts/socratic_gate_policy.js +15 -12
- package/.agent/scripts/strengthen_skills.js +29 -33
- package/.agent/scripts/swarm_dispatcher.js +120 -151
- package/.agent/scripts/test_runner.js +54 -56
- package/.agent/scripts/token_budget_broker.js +9 -7
- package/.agent/scripts/trace_engine.js +126 -0
- package/.agent/scripts/verify_all.js +76 -93
- package/.agent/scripts/visual_audit.js +16 -21
- package/.agent/skill_topic_map.json +237 -0
- package/.agent/skills/12-principles-of-animation/SKILL.md +7 -0
- package/.agent/skills/60fps-animation/SKILL.md +7 -0
- package/.agent/skills/accessible-animation/SKILL.md +5 -1
- package/.agent/skills/adapt/SKILL.md +7 -1
- package/.agent/skills/advanced-rag-pipelines/SKILL.md +1 -0
- package/.agent/skills/agent-organizer/SKILL.md +1 -0
- package/.agent/skills/agentic-patterns/SKILL.md +33 -25
- package/.agent/skills/agentic-workflows-2026/SKILL.md +80 -0
- package/.agent/skills/ai-app-hardening/SKILL.md +59 -0
- package/.agent/skills/ai-prompt-injection-defense/SKILL.md +7 -6
- package/.agent/skills/animation-on-scroll/SKILL.md +24 -15
- package/.agent/skills/animation-systems/SKILL.md +11 -10
- package/.agent/skills/antfu-conventions/SKILL.md +7 -2
- package/.agent/skills/api-patterns/SKILL.md +14 -10
- package/.agent/skills/api-security-auditor/SKILL.md +15 -14
- package/.agent/skills/app-builder/SKILL.md +1 -0
- package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +2 -2
- package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +1 -1
- package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +12 -12
- package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +3 -3
- package/.agent/skills/apple-design/SKILL.md +8 -7
- package/.agent/skills/architecture/SKILL.md +3 -2
- package/.agent/skills/audit-and-fix/SKILL.md +8 -5
- package/.agent/skills/authentication-best-practices/SKILL.md +9 -8
- package/.agent/skills/backend-security-expert/SKILL.md +1 -0
- package/.agent/skills/baseline-ui/SKILL.md +8 -7
- package/.agent/skills/bash-linux/SKILL.md +1 -0
- package/.agent/skills/behavioral-modes/SKILL.md +1 -0
- package/.agent/skills/better-colors/SKILL.md +11 -7
- package/.agent/skills/better-typography/SKILL.md +30 -16
- package/.agent/skills/better-ui/SKILL.md +17 -10
- package/.agent/skills/bolder/SKILL.md +6 -0
- package/.agent/skills/brainstorming/SKILL.md +6 -4
- package/.agent/skills/browser-native-ai/SKILL.md +5 -4
- package/.agent/skills/build-primitive/SKILL.md +5 -0
- package/.agent/skills/building-native-ui/SKILL.md +1 -0
- package/.agent/skills/cicd-pro/SKILL.md +2 -1
- package/.agent/skills/clarify/SKILL.md +19 -14
- package/.agent/skills/clean-code/SKILL.md +16 -15
- package/.agent/skills/cloud-architect/SKILL.md +1 -0
- package/.agent/skills/cobejs/SKILL.md +7 -9
- package/.agent/skills/code-review-checklist/SKILL.md +1 -0
- package/.agent/skills/codebase-design/SKILL.md +7 -2
- package/.agent/skills/colorize/SKILL.md +8 -3
- package/.agent/skills/compact-landing/SKILL.md +8 -3
- package/.agent/skills/company-logos/SKILL.md +6 -0
- package/.agent/skills/config-validator/SKILL.md +10 -9
- package/.agent/skills/containerization-pro/SKILL.md +6 -5
- package/.agent/skills/context-engineering-pro/SKILL.md +70 -0
- package/.agent/skills/create-design-md/SKILL.md +13 -5
- package/.agent/skills/critique/SKILL.md +10 -8
- package/.agent/skills/csharp-developer/SKILL.md +1 -0
- package/.agent/skills/data-validation-schemas/SKILL.md +28 -23
- package/.agent/skills/database-design/SKILL.md +2 -1
- package/.agent/skills/delight/SKILL.md +6 -0
- package/.agent/skills/deployment-procedures/SKILL.md +2 -1
- package/.agent/skills/design-lab/SKILL.md +5 -0
- package/.agent/skills/devops-engineer/SKILL.md +3 -2
- package/.agent/skills/devops-incident-responder/SKILL.md +2 -1
- package/.agent/skills/diagnosing-bugs/SKILL.md +12 -2
- package/.agent/skills/distill/SKILL.md +7 -2
- package/.agent/skills/documentation-templates/SKILL.md +3 -2
- package/.agent/skills/domain-modeling/SKILL.md +12 -4
- package/.agent/skills/duckdb-analytical-sql/SKILL.md +59 -0
- package/.agent/skills/edge-ai-mobile/SKILL.md +50 -0
- package/.agent/skills/edge-computing/SKILL.md +9 -8
- package/.agent/skills/emil-design-eng/SKILL.md +43 -27
- package/.agent/skills/error-resilience/SKILL.md +34 -16
- package/.agent/skills/expo-router-v4/SKILL.md +81 -0
- package/.agent/skills/extract-design-system/SKILL.md +12 -11
- package/.agent/skills/fabel-protocol/SKILL.md +24 -17
- package/.agent/skills/fixing-accessibility/SKILL.md +23 -16
- package/.agent/skills/fixing-metadata/SKILL.md +24 -13
- package/.agent/skills/fixing-motion-performance/SKILL.md +7 -5
- package/.agent/skills/framer-motion-expert/SKILL.md +29 -15
- package/.agent/skills/frontend-design/SKILL.md +21 -13
- package/.agent/skills/frontend-security-expert/SKILL.md +1 -0
- package/.agent/skills/game-design-expert/SKILL.md +1 -0
- package/.agent/skills/game-engineering-expert/SKILL.md +1 -0
- package/.agent/skills/generative-ui-expert/SKILL.md +3 -2
- package/.agent/skills/geo-fundamentals/SKILL.md +2 -1
- package/.agent/skills/git-pro/SKILL.md +10 -9
- package/.agent/skills/github-operations/SKILL.md +2 -1
- package/.agent/skills/gpt-taste/SKILL.md +7 -0
- package/.agent/skills/gsap-core/SKILL.md +26 -22
- package/.agent/skills/gsap-frameworks/SKILL.md +6 -5
- package/.agent/skills/gsap-performance/SKILL.md +4 -3
- package/.agent/skills/gsap-plugins/SKILL.md +34 -33
- package/.agent/skills/gsap-react/SKILL.md +9 -8
- package/.agent/skills/gsap-scrolltrigger/SKILL.md +34 -33
- package/.agent/skills/gsap-timeline/SKILL.md +18 -15
- package/.agent/skills/gsap-utils/SKILL.md +25 -24
- package/.agent/skills/harden/SKILL.md +9 -3
- package/.agent/skills/harness-protocol/SKILL.md +1 -0
- package/.agent/skills/i18n-localization/SKILL.md +10 -9
- package/.agent/skills/impeccable/SKILL.md +5 -0
- package/.agent/skills/improve-codebase-architecture/SKILL.md +10 -5
- package/.agent/skills/improve-ui/SKILL.md +12 -5
- package/.agent/skills/intelligent-routing/SKILL.md +7 -6
- package/.agent/skills/knowledge-graph/SKILL.md +1 -0
- package/.agent/skills/landing-page/SKILL.md +1 -0
- package/.agent/skills/lint-and-validate/SKILL.md +9 -4
- package/.agent/skills/llm-engineering/SKILL.md +55 -54
- package/.agent/skills/local-first/SKILL.md +20 -19
- package/.agent/skills/local-first-architecture/SKILL.md +6 -1
- package/.agent/skills/lottie-animation/SKILL.md +7 -3
- package/.agent/skills/marquee-loop/SKILL.md +1 -0
- package/.agent/skills/masked-reveal/SKILL.md +17 -4
- package/.agent/skills/mcp-builder/SKILL.md +13 -10
- package/.agent/skills/micro-interaction/SKILL.md +20 -5
- package/.agent/skills/mobile-design/SKILL.md +26 -15
- package/.agent/skills/monorepo-management/SKILL.md +3 -2
- package/.agent/skills/morphing-icons/SKILL.md +16 -6
- package/.agent/skills/motion-engineering/SKILL.md +19 -15
- package/.agent/skills/nextjs-react-expert/SKILL.md +26 -21
- package/.agent/skills/nodejs-best-practices/SKILL.md +89 -76
- package/.agent/skills/observability/SKILL.md +45 -44
- package/.agent/skills/opentelemetry-observability/SKILL.md +59 -0
- package/.agent/skills/page-transition-animation/SKILL.md +6 -3
- package/.agent/skills/parallel-agents/SKILL.md +7 -2
- package/.agent/skills/performance-profiling/SKILL.md +24 -13
- package/.agent/skills/plan-writing/SKILL.md +1 -0
- package/.agent/skills/platform-engineer/SKILL.md +3 -2
- package/.agent/skills/platform-engineering-opentofu/SKILL.md +68 -0
- package/.agent/skills/playwright-ai-e2e/SKILL.md +60 -0
- package/.agent/skills/playwright-best-practices/SKILL.md +29 -28
- package/.agent/skills/polish/SKILL.md +13 -12
- package/.agent/skills/powershell-windows/SKILL.md +1 -0
- package/.agent/skills/pricing-page/SKILL.md +8 -3
- package/.agent/skills/product-aware-heuristics/SKILL.md +122 -72
- package/.agent/skills/progressive-blur/SKILL.md +9 -4
- package/.agent/skills/project-idioms/SKILL.md +1 -0
- package/.agent/skills/property-based-testing/SKILL.md +58 -0
- package/.agent/skills/python-patterns/SKILL.md +1 -0
- package/.agent/skills/python-pro/SKILL.md +1 -0
- package/.agent/skills/quieter/SKILL.md +6 -0
- package/.agent/skills/react-doctor/SKILL.md +6 -0
- package/.agent/skills/react-specialist/SKILL.md +32 -28
- package/.agent/skills/readme-builder/SKILL.md +1 -0
- package/.agent/skills/realtime-patterns/SKILL.md +34 -33
- package/.agent/skills/red-team-tactics/SKILL.md +1 -0
- package/.agent/skills/redesign-skill/SKILL.md +6 -0
- package/.agent/skills/review-animations/SKILL.md +5 -2
- package/.agent/skills/review-animations/STANDARDS.md +37 -23
- package/.agent/skills/rust-pro/SKILL.md +1 -0
- package/.agent/skills/seo-fundamentals/SKILL.md +4 -3
- package/.agent/skills/server-management/SKILL.md +1 -0
- package/.agent/skills/shadcn-ui-expert/SKILL.md +28 -22
- package/.agent/skills/shape/SKILL.md +9 -2
- package/.agent/skills/skill-creator/SKILL.md +1 -0
- package/.agent/skills/soft-skill/SKILL.md +6 -0
- package/.agent/skills/sounds-on-the-web/SKILL.md +1 -0
- package/.agent/skills/sql-pro/SKILL.md +1 -0
- package/.agent/skills/supabase-postgres-best-practices/SKILL.md +1 -0
- package/.agent/skills/svg-animation/SKILL.md +16 -7
- package/.agent/skills/swiftui-expert/SKILL.md +1 -0
- package/.agent/skills/swiss-design/SKILL.md +5 -0
- package/.agent/skills/system-design-pro/SKILL.md +1 -0
- package/.agent/skills/systematic-debugging/SKILL.md +1 -0
- package/.agent/skills/tailwind-patterns/SKILL.md +25 -11
- package/.agent/skills/taste-skill/SKILL.md +6 -0
- package/.agent/skills/tdd-workflow/SKILL.md +5 -0
- package/.agent/skills/test-result-analyzer/SKILL.md +1 -0
- package/.agent/skills/testing-patterns/SKILL.md +123 -115
- package/.agent/skills/thermo-nuclear-code-quality-review/SKILL.md +5 -0
- package/.agent/skills/thinking-protocol/SKILL.md +3 -0
- package/.agent/skills/to-spring-or-not-to-spring/SKILL.md +9 -8
- package/.agent/skills/transitions-dev/SKILL.md +19 -6
- package/.agent/skills/trend-researcher/SKILL.md +1 -0
- package/.agent/skills/typescript-advanced/SKILL.md +23 -18
- package/.agent/skills/typeset/SKILL.md +10 -1
- package/.agent/skills/ui-reasoning-engine/SKILL.md +67 -48
- package/.agent/skills/ui-skill-packs/SKILL.md +6 -1
- package/.agent/skills/ui-skills-root/SKILL.md +39 -38
- package/.agent/skills/ui-ux-pro-max/SKILL.md +34 -26
- package/.agent/skills/ui-ux-researcher/SKILL.md +1 -0
- package/.agent/skills/vector-search-pgvector/SKILL.md +78 -0
- package/.agent/skills/vue-expert/SKILL.md +22 -19
- package/.agent/skills/vulnerability-scanner/SKILL.md +22 -21
- package/.agent/skills/web-accessibility-auditor/SKILL.md +2 -1
- package/.agent/skills/web-design-guidelines/SKILL.md +16 -10
- package/.agent/skills/web-quality-audit/SKILL.md +5 -0
- package/.agent/skills/webapp-testing/SKILL.md +14 -13
- package/.agent/skills/webgpu-performance/SKILL.md +1 -0
- package/.agent/skills/whimsy-injector/SKILL.md +9 -5
- package/.agent/skills/workflow-optimizer/SKILL.md +1 -0
- package/.agent/skills/zero-trust-passkeys/SKILL.md +90 -0
- package/.agent/templates/DESIGN.md +119 -110
- package/.agent/templates/design-tokens.json +9 -6
- package/.agent/workflows/acf.md +1 -0
- package/.agent/workflows/api-tester.md +1 -0
- package/.agent/workflows/audit.md +1 -0
- package/.agent/workflows/brainstorm.md +1 -0
- package/.agent/workflows/changelog.md +1 -0
- package/.agent/workflows/contract.md +60 -0
- package/.agent/workflows/create.md +1 -0
- package/.agent/workflows/debug.md +1 -0
- package/.agent/workflows/deploy.md +1 -0
- package/.agent/workflows/enhance.md +1 -0
- package/.agent/workflows/fix-ci.md +89 -0
- package/.agent/workflows/fix.md +1 -0
- package/.agent/workflows/generate.md +1 -0
- package/.agent/workflows/marathon.md +1 -0
- package/.agent/workflows/migrate.md +1 -0
- package/.agent/workflows/minimal.md +9 -7
- package/.agent/workflows/orchestrate.md +1 -0
- package/.agent/workflows/performance-benchmarker.md +1 -0
- package/.agent/workflows/pipeline.md +26 -21
- package/.agent/workflows/plan.md +1 -0
- package/.agent/workflows/preview.md +1 -0
- package/.agent/workflows/refactor.md +3 -2
- package/.agent/workflows/review-ai.md +4 -3
- package/.agent/workflows/review.md +1 -0
- package/.agent/workflows/session.md +1 -0
- package/.agent/workflows/status.md +1 -0
- package/.agent/workflows/strengthen-skills.md +1 -0
- package/.agent/workflows/super-prompt.md +1 -0
- package/.agent/workflows/swarm.md +15 -3
- package/.agent/workflows/test.md +8 -7
- package/.agent/workflows/tribunal-backend.md +3 -2
- package/.agent/workflows/tribunal-cicd.md +104 -0
- package/.agent/workflows/tribunal-database.md +1 -0
- package/.agent/workflows/tribunal-frontend.md +8 -6
- package/.agent/workflows/tribunal-full.md +15 -14
- package/.agent/workflows/tribunal-mobile.md +6 -5
- package/.agent/workflows/tribunal-performance.md +1 -0
- package/.agent/workflows/tribunal-speed.md +1 -0
- package/.agent/workflows/tribunal-ui.md +29 -21
- package/.agent/workflows/ui-ux-pro-max.md +19 -15
- package/CONTRIBUTING.md +3 -3
- package/README.md +160 -88
- package/SECURITY.md +11 -11
- package/bin/mcp-server.js +512 -233
- package/bin/tribunal-kit.js +29 -30
- package/bin/wrapper.js +45 -48
- package/dist/cli.js +26 -0
- package/dist/commands/case.js +2 -0
- package/dist/commands/contract.js +440 -0
- package/dist/commands/memory.js +3 -2
- package/dist/commands/native.js +36 -0
- package/dist/commands/status.js +6 -0
- package/dist/esm/index.mjs +32 -0
- package/dist/index.d.ts +58 -3
- package/package.json +20 -16
- package/scripts/benchmark.js +62 -86
- package/scripts/changelog.js +67 -73
- package/scripts/fix-vbc.js +13 -15
- package/scripts/fix-vbc.ps1 +2 -118
- package/scripts/stress_benchmark.js +358 -0
- package/scripts/sync-version.js +71 -41
- package/scripts/validate-payload.js +23 -30
- package/scripts/visual_audit.js +23 -13
package/bin/mcp-server.js
CHANGED
|
@@ -13,16 +13,24 @@
|
|
|
13
13
|
* Protocol: MCP 2024-11-05 over JSON-RPC 2.0 / stdio
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
const path = require(
|
|
17
|
-
const { spawnSync } = require(
|
|
16
|
+
const path = require('path');
|
|
17
|
+
const { spawnSync } = require('child_process');
|
|
18
18
|
|
|
19
|
-
const PKG = require(path.resolve(__dirname,
|
|
19
|
+
const PKG = require(path.resolve(__dirname, '../package.json'));
|
|
20
20
|
|
|
21
21
|
// Timeout for intentionally isolated child processes (30 seconds).
|
|
22
22
|
const SPAWN_TIMEOUT_MS = 30000;
|
|
23
23
|
|
|
24
|
+
class RpcError extends Error {
|
|
25
|
+
constructor(code, message) {
|
|
26
|
+
super(message);
|
|
27
|
+
this.code = code;
|
|
28
|
+
this.name = 'RpcError';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
24
32
|
// Minimal JSON-RPC 2.0 over stdio
|
|
25
|
-
const readline = require(
|
|
33
|
+
const readline = require('readline');
|
|
26
34
|
|
|
27
35
|
const rl = readline.createInterface({
|
|
28
36
|
input: process.stdin,
|
|
@@ -36,17 +44,12 @@ const rl = readline.createInterface({
|
|
|
36
44
|
* explicitly supplied payload and schema.
|
|
37
45
|
*/
|
|
38
46
|
function runTribunalAudit() {
|
|
39
|
-
const fs = require(
|
|
47
|
+
const fs = require('fs');
|
|
40
48
|
const projectRoot = process.cwd();
|
|
41
|
-
const manifestScript = path.join(
|
|
42
|
-
projectRoot,
|
|
43
|
-
".agent",
|
|
44
|
-
"scripts",
|
|
45
|
-
"integrity_manifest.js",
|
|
46
|
-
);
|
|
49
|
+
const manifestScript = path.join(projectRoot, '.agent', 'scripts', 'integrity_manifest.js');
|
|
47
50
|
|
|
48
51
|
if (!fs.existsSync(manifestScript)) {
|
|
49
|
-
return
|
|
52
|
+
return 'Error: .agent/scripts/integrity_manifest.js was not found. Run `tk init` first.';
|
|
50
53
|
}
|
|
51
54
|
|
|
52
55
|
try {
|
|
@@ -56,7 +59,7 @@ function runTribunalAudit() {
|
|
|
56
59
|
|
|
57
60
|
const { integrity } = manifest;
|
|
58
61
|
const lines = [
|
|
59
|
-
|
|
62
|
+
'Tribunal audit complete.',
|
|
60
63
|
`Agents: ${manifest.agents.total} (${manifest.agents.reviewer_count} reviewers)`,
|
|
61
64
|
`Skills: ${manifest.skills.total}`,
|
|
62
65
|
`Scripts: ${manifest.scripts.total}`,
|
|
@@ -66,11 +69,13 @@ function runTribunalAudit() {
|
|
|
66
69
|
];
|
|
67
70
|
|
|
68
71
|
if (integrity.phantom_references > 0 || integrity.invalid_claims > 0) {
|
|
69
|
-
lines.push(
|
|
72
|
+
lines.push(
|
|
73
|
+
'Audit found integrity issues; run `tk guardrail --scan` for remediation details.',
|
|
74
|
+
);
|
|
70
75
|
} else {
|
|
71
|
-
lines.push(
|
|
76
|
+
lines.push('All discovered references and global asset-count claims are valid.');
|
|
72
77
|
}
|
|
73
|
-
return lines.join(
|
|
78
|
+
return lines.join('\n');
|
|
74
79
|
} catch (error) {
|
|
75
80
|
return `Audit failed: ${error.message}`;
|
|
76
81
|
}
|
|
@@ -80,228 +85,393 @@ function runTribunalAudit() {
|
|
|
80
85
|
* Search case law in an isolated process because its CLI owns persistent state.
|
|
81
86
|
*/
|
|
82
87
|
function searchCaseLaw(query) {
|
|
83
|
-
const caseLawScript = path.resolve(
|
|
84
|
-
__dirname,
|
|
85
|
-
"../.agent/scripts/case_law_manager.js",
|
|
86
|
-
);
|
|
88
|
+
const caseLawScript = path.resolve(__dirname, '../.agent/scripts/case_law_manager.js');
|
|
87
89
|
// case_law_manager is a standalone stateful CLI, so retain its process boundary.
|
|
88
|
-
const result = spawnSync(
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
encoding: "utf8",
|
|
93
|
-
timeout: SPAWN_TIMEOUT_MS,
|
|
94
|
-
},
|
|
95
|
-
);
|
|
90
|
+
const result = spawnSync(process.execPath, [caseLawScript, 'search-cases', '--query', query], {
|
|
91
|
+
encoding: 'utf8',
|
|
92
|
+
timeout: SPAWN_TIMEOUT_MS,
|
|
93
|
+
});
|
|
96
94
|
if (result.error) {
|
|
97
|
-
if (result.error.code ===
|
|
95
|
+
if (result.error.code === 'ETIMEDOUT')
|
|
96
|
+
return 'Error: Case law search timed out (exceeded 30s limit)';
|
|
98
97
|
return `Error executing case law search: ${result.error.message}`;
|
|
99
98
|
}
|
|
100
|
-
return result.stdout || result.stderr ||
|
|
99
|
+
return result.stdout || result.stderr || 'No results';
|
|
101
100
|
}
|
|
102
101
|
|
|
103
|
-
|
|
104
102
|
function stripBoilerplate(text) {
|
|
105
103
|
if (!text) return text;
|
|
106
|
-
let minified = text.replace(
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
104
|
+
let minified = text.replace(
|
|
105
|
+
/AI coding assistants often fall into specific bad habits[\s\S]*$/g,
|
|
106
|
+
'',
|
|
107
|
+
);
|
|
108
|
+
minified = minified.replace(/## 🤖 LLM-Specific Traps[\s\S]*$/g, '');
|
|
109
|
+
minified = minified.replace(/## 🏛️ Tribunal Integration[\s\S]*$/g, '');
|
|
110
|
+
minified = minified.replace(/## Pre-Flight Checklist[\s\S]*$/g, '');
|
|
110
111
|
return minified.trim();
|
|
111
112
|
}
|
|
112
113
|
|
|
114
|
+
function getAgentDir() {
|
|
115
|
+
const fs = require('fs');
|
|
116
|
+
const local = path.join(process.cwd(), '.agent');
|
|
117
|
+
if (fs.existsSync(local)) return local;
|
|
118
|
+
return path.resolve(__dirname, '../.agent');
|
|
119
|
+
}
|
|
120
|
+
|
|
113
121
|
function handleRequest(req) {
|
|
114
|
-
|
|
122
|
+
const fs = require('fs');
|
|
123
|
+
if (req.method === 'notifications/initialized' || req.method === 'notifications/cancelled') {
|
|
115
124
|
return null;
|
|
116
125
|
}
|
|
117
|
-
if (req.method ===
|
|
126
|
+
if (req.method === 'ping') {
|
|
118
127
|
return {};
|
|
119
128
|
}
|
|
120
|
-
if (req.method === "resources/list") {
|
|
121
|
-
return { resources: [] };
|
|
122
|
-
}
|
|
123
|
-
if (req.method === "prompts/list") {
|
|
124
|
-
return { prompts: [] };
|
|
125
|
-
}
|
|
126
129
|
|
|
127
130
|
// MCP spec: method names follow path-style convention
|
|
128
|
-
if (req.method ===
|
|
131
|
+
if (req.method === 'initialize') {
|
|
129
132
|
return {
|
|
130
|
-
protocolVersion:
|
|
133
|
+
protocolVersion: '2025-03-26',
|
|
131
134
|
capabilities: {
|
|
132
135
|
tools: {},
|
|
133
136
|
resources: { subscribe: false, listChanged: false },
|
|
134
137
|
prompts: { listChanged: false },
|
|
135
138
|
},
|
|
136
139
|
serverInfo: {
|
|
137
|
-
name:
|
|
140
|
+
name: 'tribunal-kit-mcp',
|
|
138
141
|
version: PKG.version,
|
|
139
142
|
},
|
|
140
143
|
};
|
|
141
144
|
}
|
|
142
145
|
|
|
143
|
-
if (req.method ===
|
|
146
|
+
if (req.method === 'resources/list') {
|
|
147
|
+
const agentDir = getAgentDir();
|
|
148
|
+
const resources = [];
|
|
149
|
+
|
|
150
|
+
// Agents
|
|
151
|
+
const agentsDir = path.join(agentDir, 'agents');
|
|
152
|
+
if (fs.existsSync(agentsDir)) {
|
|
153
|
+
const files = fs.readdirSync(agentsDir).filter(f => f.endsWith('.md'));
|
|
154
|
+
for (const f of files) {
|
|
155
|
+
const name = path.basename(f, '.md');
|
|
156
|
+
resources.push({
|
|
157
|
+
uri: `tribunal://agent/${name}`,
|
|
158
|
+
name: `Agent: ${name}`,
|
|
159
|
+
description: `Tribunal Specialist Agent rule file for ${name}`,
|
|
160
|
+
mimeType: 'text/markdown',
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Skills
|
|
166
|
+
const skillsDir = path.join(agentDir, 'skills');
|
|
167
|
+
if (fs.existsSync(skillsDir)) {
|
|
168
|
+
const dirs = fs.readdirSync(skillsDir, { withFileTypes: true });
|
|
169
|
+
for (const d of dirs) {
|
|
170
|
+
if (d.isDirectory()) {
|
|
171
|
+
const skillFile = path.join(skillsDir, d.name, 'SKILL.md');
|
|
172
|
+
if (fs.existsSync(skillFile)) {
|
|
173
|
+
resources.push({
|
|
174
|
+
uri: `tribunal://skill/${d.name}`,
|
|
175
|
+
name: `Skill: ${d.name}`,
|
|
176
|
+
description: `Tribunal Skill instruction file for ${d.name}`,
|
|
177
|
+
mimeType: 'text/markdown',
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Workflows
|
|
185
|
+
const workflowsDir = path.join(agentDir, 'workflows');
|
|
186
|
+
if (fs.existsSync(workflowsDir)) {
|
|
187
|
+
const files = fs.readdirSync(workflowsDir).filter(f => f.endsWith('.md'));
|
|
188
|
+
for (const f of files) {
|
|
189
|
+
const name = path.basename(f, '.md');
|
|
190
|
+
resources.push({
|
|
191
|
+
uri: `tribunal://workflow/${name}`,
|
|
192
|
+
name: `Workflow: ${name}`,
|
|
193
|
+
description: `Tribunal Workflow guide for ${name}`,
|
|
194
|
+
mimeType: 'text/markdown',
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return { resources };
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (req.method === 'resources/read') {
|
|
203
|
+
const uri = req.params && req.params.uri;
|
|
204
|
+
if (!uri) throw new Error('Missing uri parameter');
|
|
205
|
+
const agentDir = getAgentDir();
|
|
206
|
+
let filePath = null;
|
|
207
|
+
|
|
208
|
+
if (uri.startsWith('tribunal://agent/')) {
|
|
209
|
+
const name = uri.replace('tribunal://agent/', '');
|
|
210
|
+
filePath = path.join(agentDir, 'agents', `${name}.md`);
|
|
211
|
+
} else if (uri.startsWith('tribunal://skill/')) {
|
|
212
|
+
const name = uri.replace('tribunal://skill/', '');
|
|
213
|
+
filePath = path.join(agentDir, 'skills', name, 'SKILL.md');
|
|
214
|
+
} else if (uri.startsWith('tribunal://workflow/')) {
|
|
215
|
+
const name = uri.replace('tribunal://workflow/', '');
|
|
216
|
+
filePath = path.join(agentDir, 'workflows', `${name}.md`);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (!filePath || !fs.existsSync(filePath)) {
|
|
220
|
+
throw new Error(`Resource not found: ${uri}`);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const text = fs.readFileSync(filePath, 'utf8');
|
|
224
|
+
return {
|
|
225
|
+
contents: [
|
|
226
|
+
{
|
|
227
|
+
uri,
|
|
228
|
+
mimeType: 'text/markdown',
|
|
229
|
+
text,
|
|
230
|
+
},
|
|
231
|
+
],
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (req.method === 'prompts/list') {
|
|
236
|
+
const agentDir = getAgentDir();
|
|
237
|
+
const prompts = [];
|
|
238
|
+
const workflowsDir = path.join(agentDir, 'workflows');
|
|
239
|
+
|
|
240
|
+
if (fs.existsSync(workflowsDir)) {
|
|
241
|
+
const files = fs.readdirSync(workflowsDir).filter(f => f.endsWith('.md'));
|
|
242
|
+
for (const f of files) {
|
|
243
|
+
const name = path.basename(f, '.md');
|
|
244
|
+
prompts.push({
|
|
245
|
+
name,
|
|
246
|
+
description: `Execute tribunal workflow /${name}`,
|
|
247
|
+
arguments: [
|
|
248
|
+
{
|
|
249
|
+
name: 'task',
|
|
250
|
+
description: 'The task or target file to execute the workflow against',
|
|
251
|
+
required: false,
|
|
252
|
+
},
|
|
253
|
+
],
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
return { prompts };
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
if (req.method === 'prompts/get') {
|
|
262
|
+
const name = req.params && req.params.name;
|
|
263
|
+
const task = (req.params && req.params.arguments && req.params.arguments.task) || '';
|
|
264
|
+
if (!name) throw new Error('Missing prompt name parameter');
|
|
265
|
+
|
|
266
|
+
const agentDir = getAgentDir();
|
|
267
|
+
const workflowPath = path.join(agentDir, 'workflows', `${name}.md`);
|
|
268
|
+
if (!fs.existsSync(workflowPath)) {
|
|
269
|
+
throw new Error(`Prompt workflow not found: ${name}`);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
const content = fs.readFileSync(workflowPath, 'utf8');
|
|
273
|
+
const promptText = task ? `${content}\n\nTarget Task/File: ${task}` : content;
|
|
274
|
+
|
|
275
|
+
return {
|
|
276
|
+
messages: [
|
|
277
|
+
{
|
|
278
|
+
role: 'user',
|
|
279
|
+
content: {
|
|
280
|
+
type: 'text',
|
|
281
|
+
text: promptText,
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
],
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
if (req.method === 'tools/list') {
|
|
144
289
|
return {
|
|
145
290
|
tools: [
|
|
146
291
|
{
|
|
147
|
-
name:
|
|
148
|
-
description:
|
|
149
|
-
"Runs a full anti-hallucination audit across the workspace.",
|
|
292
|
+
name: 'run_tribunal_audit',
|
|
293
|
+
description: 'Runs a full anti-hallucination audit across the workspace.',
|
|
150
294
|
inputSchema: {
|
|
151
|
-
type:
|
|
295
|
+
type: 'object',
|
|
152
296
|
properties: {},
|
|
153
297
|
additionalProperties: false,
|
|
154
298
|
},
|
|
155
299
|
},
|
|
156
300
|
{
|
|
157
|
-
name:
|
|
158
|
-
description:
|
|
159
|
-
"Synchronize IDE bridge files with the current GEMINI.md rules.",
|
|
301
|
+
name: 'sync_ide_bridges',
|
|
302
|
+
description: 'Synchronize IDE bridge files with the current GEMINI.md rules.',
|
|
160
303
|
inputSchema: {
|
|
161
|
-
type:
|
|
304
|
+
type: 'object',
|
|
162
305
|
properties: {},
|
|
163
306
|
additionalProperties: false,
|
|
164
307
|
},
|
|
165
308
|
},
|
|
166
309
|
{
|
|
167
|
-
name:
|
|
310
|
+
name: 'search_case_law',
|
|
168
311
|
description:
|
|
169
|
-
|
|
312
|
+
'Search historical code rejections and legal precedent. Use this before writing code to avoid past mistakes.',
|
|
170
313
|
inputSchema: {
|
|
171
|
-
type:
|
|
314
|
+
type: 'object',
|
|
172
315
|
properties: {
|
|
173
316
|
query: {
|
|
174
|
-
type:
|
|
317
|
+
type: 'string',
|
|
175
318
|
description: "Search query (e.g. 'useEffect state')",
|
|
176
319
|
},
|
|
177
320
|
},
|
|
178
|
-
required: [
|
|
321
|
+
required: ['query'],
|
|
179
322
|
additionalProperties: false,
|
|
180
323
|
},
|
|
181
324
|
},
|
|
182
325
|
{
|
|
183
|
-
name:
|
|
184
|
-
description:
|
|
326
|
+
name: 'list_tribunal_agents',
|
|
327
|
+
description: 'List all available Tribunal Kit agents.',
|
|
185
328
|
inputSchema: {
|
|
186
|
-
type:
|
|
329
|
+
type: 'object',
|
|
187
330
|
properties: {},
|
|
188
331
|
additionalProperties: false,
|
|
189
332
|
},
|
|
190
333
|
},
|
|
191
334
|
{
|
|
192
|
-
name:
|
|
193
|
-
description:
|
|
335
|
+
name: 'get_tribunal_agent',
|
|
336
|
+
description: 'Get the full markdown rules for a specific Tribunal agent.',
|
|
194
337
|
inputSchema: {
|
|
195
|
-
type:
|
|
338
|
+
type: 'object',
|
|
196
339
|
properties: {
|
|
197
|
-
name: { type:
|
|
340
|
+
name: { type: 'string', description: "The agent name (e.g. 'frontend-specialist')" },
|
|
198
341
|
},
|
|
199
|
-
required: [
|
|
342
|
+
required: ['name'],
|
|
200
343
|
additionalProperties: false,
|
|
201
344
|
},
|
|
202
345
|
},
|
|
203
346
|
{
|
|
204
|
-
name:
|
|
205
|
-
description:
|
|
347
|
+
name: 'list_tribunal_skills',
|
|
348
|
+
description: 'List all available Tribunal Kit skills.',
|
|
206
349
|
inputSchema: {
|
|
207
|
-
type:
|
|
350
|
+
type: 'object',
|
|
208
351
|
properties: {},
|
|
209
352
|
additionalProperties: false,
|
|
210
353
|
},
|
|
211
354
|
},
|
|
212
355
|
{
|
|
213
|
-
name:
|
|
214
|
-
description:
|
|
356
|
+
name: 'get_tribunal_skill',
|
|
357
|
+
description: 'Get the full markdown instructions for a specific Tribunal skill.',
|
|
215
358
|
inputSchema: {
|
|
216
|
-
type:
|
|
359
|
+
type: 'object',
|
|
217
360
|
properties: {
|
|
218
|
-
name: { type:
|
|
361
|
+
name: { type: 'string', description: "The skill name (e.g. 'react-specialist')" },
|
|
219
362
|
},
|
|
220
|
-
required: [
|
|
363
|
+
required: ['name'],
|
|
221
364
|
additionalProperties: false,
|
|
222
365
|
},
|
|
223
366
|
},
|
|
224
367
|
{
|
|
225
|
-
name:
|
|
226
|
-
description:
|
|
368
|
+
name: 'recall_memory',
|
|
369
|
+
description:
|
|
370
|
+
'Budget-constrained memory recall from the 4-Type Taxonomy Persistent Memory Engine. Returns the most relevant memories that fit within the token budget, ranked by relevance × recency × priority. Use this BEFORE writing code to recall project guidelines without bloating context.',
|
|
227
371
|
inputSchema: {
|
|
228
|
-
type:
|
|
372
|
+
type: 'object',
|
|
229
373
|
properties: {
|
|
230
374
|
query: {
|
|
231
|
-
type:
|
|
375
|
+
type: 'string',
|
|
232
376
|
description: "Search query (e.g. 'database', 'auth', 'deploy')",
|
|
233
377
|
},
|
|
234
378
|
budget: {
|
|
235
|
-
type:
|
|
236
|
-
description:
|
|
379
|
+
type: 'number',
|
|
380
|
+
description:
|
|
381
|
+
'Maximum token budget for recall (default: 2000). Only the top-ranked memories that fit within this budget are returned.',
|
|
237
382
|
},
|
|
238
383
|
},
|
|
239
|
-
required: [
|
|
384
|
+
required: ['query'],
|
|
240
385
|
additionalProperties: false,
|
|
241
386
|
},
|
|
242
387
|
},
|
|
243
388
|
{
|
|
244
|
-
name:
|
|
245
|
-
description:
|
|
389
|
+
name: 'store_memory',
|
|
390
|
+
description:
|
|
391
|
+
'Store a new memory entry in the 4-Type Taxonomy Persistent Memory Engine. Memories are schema-validated and persisted across sessions. Types: semantic (permanent facts), procedural (how-to recipes), episodic (30-day TTL events), working (session scratch).',
|
|
246
392
|
inputSchema: {
|
|
247
|
-
type:
|
|
393
|
+
type: 'object',
|
|
248
394
|
properties: {
|
|
249
395
|
type: {
|
|
250
|
-
type:
|
|
251
|
-
enum: [
|
|
252
|
-
description:
|
|
396
|
+
type: 'string',
|
|
397
|
+
enum: ['semantic', 'procedural', 'episodic', 'working'],
|
|
398
|
+
description:
|
|
399
|
+
'Memory type: semantic (facts), procedural (recipes), episodic (events), working (scratch)',
|
|
253
400
|
},
|
|
254
401
|
content: {
|
|
255
|
-
type:
|
|
256
|
-
description:
|
|
402
|
+
type: 'string',
|
|
403
|
+
description: 'The memory content to store',
|
|
257
404
|
},
|
|
258
405
|
tags: {
|
|
259
|
-
type:
|
|
260
|
-
items: { type:
|
|
261
|
-
description:
|
|
406
|
+
type: 'array',
|
|
407
|
+
items: { type: 'string' },
|
|
408
|
+
description: 'Searchable tags for this memory',
|
|
262
409
|
},
|
|
263
410
|
},
|
|
264
|
-
required: [
|
|
411
|
+
required: ['type', 'content'],
|
|
265
412
|
additionalProperties: false,
|
|
266
413
|
},
|
|
267
414
|
},
|
|
268
415
|
{
|
|
269
|
-
name:
|
|
270
|
-
description:
|
|
416
|
+
name: 'get_sparse_context',
|
|
417
|
+
description:
|
|
418
|
+
'Get a JIT, token-optimized context prompt tailored to the active task and files. Uses the Context Density Broker to score and select relevant skills, stripping duplicate boilerplate and saving up to 85% in prompt tokens.',
|
|
271
419
|
inputSchema: {
|
|
272
|
-
type:
|
|
420
|
+
type: 'object',
|
|
273
421
|
properties: {
|
|
274
422
|
task: {
|
|
275
|
-
type:
|
|
423
|
+
type: 'string',
|
|
276
424
|
description: "The user task description (e.g. 'JWT auth API')",
|
|
277
425
|
},
|
|
278
426
|
files: {
|
|
279
|
-
type:
|
|
280
|
-
items: { type:
|
|
427
|
+
type: 'array',
|
|
428
|
+
items: { type: 'string' },
|
|
281
429
|
description: "List of files being touched (e.g. ['src/auth.js'])",
|
|
282
430
|
},
|
|
283
431
|
model: {
|
|
284
|
-
type:
|
|
285
|
-
enum: [
|
|
286
|
-
description:
|
|
432
|
+
type: 'string',
|
|
433
|
+
enum: ['large', 'small'],
|
|
434
|
+
description:
|
|
435
|
+
'Model tier: large (default, includes key rules of supplementary skills) or small (essential skills only)',
|
|
287
436
|
},
|
|
288
437
|
},
|
|
289
|
-
required: [
|
|
438
|
+
required: ['task'],
|
|
290
439
|
additionalProperties: false,
|
|
291
440
|
},
|
|
292
441
|
},
|
|
293
442
|
{
|
|
294
|
-
name:
|
|
295
|
-
description:
|
|
443
|
+
name: 'align_output',
|
|
444
|
+
description:
|
|
445
|
+
'Align model outputs to Fabel-5 constraints: strips conversational introductions and conclusions, collapses single/double bullet items to prose, and checks for code traps (unawaited dynamic functions in Next.js 15, deprecated hooks in React 19, or non-existent models).',
|
|
296
446
|
inputSchema: {
|
|
297
|
-
type:
|
|
447
|
+
type: 'object',
|
|
298
448
|
properties: {
|
|
299
449
|
text: {
|
|
300
|
-
type:
|
|
301
|
-
description:
|
|
450
|
+
type: 'string',
|
|
451
|
+
description: 'The raw output text generated by the model to be aligned.',
|
|
452
|
+
},
|
|
453
|
+
},
|
|
454
|
+
required: ['text'],
|
|
455
|
+
additionalProperties: false,
|
|
456
|
+
},
|
|
457
|
+
},
|
|
458
|
+
{
|
|
459
|
+
name: 'verify_contracts',
|
|
460
|
+
description:
|
|
461
|
+
'Verify proposed code changes against project behavioral contracts. Use BEFORE writing code to ensure compliance with team conventions.',
|
|
462
|
+
inputSchema: {
|
|
463
|
+
type: 'object',
|
|
464
|
+
properties: {
|
|
465
|
+
file: {
|
|
466
|
+
type: 'string',
|
|
467
|
+
description: "Relative or absolute file path to verify (e.g. 'src/api/user.ts')",
|
|
468
|
+
},
|
|
469
|
+
content: {
|
|
470
|
+
type: 'string',
|
|
471
|
+
description: 'Proposed file content to verify against loaded contracts',
|
|
302
472
|
},
|
|
303
473
|
},
|
|
304
|
-
required: [
|
|
474
|
+
required: ['file', 'content'],
|
|
305
475
|
additionalProperties: false,
|
|
306
476
|
},
|
|
307
477
|
},
|
|
@@ -309,217 +479,325 @@ function handleRequest(req) {
|
|
|
309
479
|
};
|
|
310
480
|
}
|
|
311
481
|
|
|
312
|
-
if (req.method ===
|
|
482
|
+
if (req.method === 'tools/call') {
|
|
313
483
|
const toolName = req.params && req.params.name;
|
|
314
484
|
if (!toolName) {
|
|
315
|
-
throw
|
|
316
|
-
code: -32602,
|
|
317
|
-
message: "Missing required parameter: params.name",
|
|
318
|
-
};
|
|
485
|
+
throw new RpcError(-32602, 'Missing required parameter: params.name');
|
|
319
486
|
}
|
|
320
487
|
|
|
321
|
-
if (toolName ===
|
|
488
|
+
if (toolName === 'run_tribunal_audit') {
|
|
322
489
|
const text = runTribunalAudit();
|
|
323
|
-
return { content: [{ type:
|
|
490
|
+
return { content: [{ type: 'text', text }] };
|
|
324
491
|
}
|
|
325
492
|
|
|
326
|
-
if (toolName ===
|
|
327
|
-
const fs = require(
|
|
493
|
+
if (toolName === 'sync_ide_bridges') {
|
|
494
|
+
const fs = require('fs');
|
|
328
495
|
const cwd = process.cwd();
|
|
329
|
-
const agentDest = path.join(cwd,
|
|
496
|
+
const agentDest = path.join(cwd, '.agent');
|
|
330
497
|
if (!fs.existsSync(agentDest)) {
|
|
331
498
|
return {
|
|
332
499
|
content: [
|
|
333
500
|
{
|
|
334
|
-
type:
|
|
335
|
-
text:
|
|
501
|
+
type: 'text',
|
|
502
|
+
text: 'Error: .agent/ directory not found. Run `tk init` first.',
|
|
503
|
+
},
|
|
504
|
+
],
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
try {
|
|
508
|
+
const { generateIDEBridges } = require(path.resolve(__dirname, '../dist/commands/init.js'));
|
|
509
|
+
// generateIDEBridges is async — execute synchronously in MCP context
|
|
510
|
+
generateIDEBridges(cwd, agentDest, true)
|
|
511
|
+
.then(() => {})
|
|
512
|
+
.catch(() => {});
|
|
513
|
+
return {
|
|
514
|
+
content: [
|
|
515
|
+
{
|
|
516
|
+
type: 'text',
|
|
517
|
+
text: 'Sync complete',
|
|
518
|
+
},
|
|
519
|
+
],
|
|
520
|
+
};
|
|
521
|
+
} catch (e) {
|
|
522
|
+
return {
|
|
523
|
+
content: [
|
|
524
|
+
{
|
|
525
|
+
type: 'text',
|
|
526
|
+
text: `Sync failed: ${e.message}`,
|
|
336
527
|
},
|
|
337
528
|
],
|
|
338
529
|
};
|
|
339
530
|
}
|
|
340
|
-
// Run synchronously by spawning a minimal script
|
|
341
|
-
const result = spawnSync(
|
|
342
|
-
process.execPath,
|
|
343
|
-
[
|
|
344
|
-
"-e",
|
|
345
|
-
`
|
|
346
|
-
const { generateIDEBridges } = require('${path.resolve(__dirname, "../dist/commands/init.js").replace(/\\/g, "\\\\")}');
|
|
347
|
-
generateIDEBridges('${cwd.replace(/\\/g, "\\\\")}', '${agentDest.replace(/\\/g, "\\\\")}', false).then(() => console.log('Sync complete'));
|
|
348
|
-
`,
|
|
349
|
-
],
|
|
350
|
-
{ encoding: "utf8", timeout: SPAWN_TIMEOUT_MS },
|
|
351
|
-
);
|
|
352
|
-
return {
|
|
353
|
-
content: [
|
|
354
|
-
{
|
|
355
|
-
type: "text",
|
|
356
|
-
text: result.stdout || result.stderr || "Sync complete",
|
|
357
|
-
},
|
|
358
|
-
],
|
|
359
|
-
};
|
|
360
531
|
}
|
|
361
532
|
|
|
362
|
-
if (toolName ===
|
|
363
|
-
const query =
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
throw {
|
|
367
|
-
code: -32602,
|
|
368
|
-
message: "Missing or invalid required argument: query (string)",
|
|
369
|
-
};
|
|
533
|
+
if (toolName === 'search_case_law') {
|
|
534
|
+
const query = req.params && req.params.arguments && req.params.arguments.query;
|
|
535
|
+
if (!query || typeof query !== 'string') {
|
|
536
|
+
throw new RpcError(-32602, 'Missing or invalid required argument: query (string)');
|
|
370
537
|
}
|
|
371
538
|
const text = searchCaseLaw(query);
|
|
372
|
-
return { content: [{ type:
|
|
539
|
+
return { content: [{ type: 'text', text }] };
|
|
373
540
|
}
|
|
374
541
|
|
|
375
|
-
if (toolName ===
|
|
376
|
-
const fs = require(
|
|
377
|
-
const agentDir = path.join(
|
|
378
|
-
if (!fs.existsSync(agentDir))
|
|
379
|
-
|
|
380
|
-
|
|
542
|
+
if (toolName === 'list_tribunal_agents') {
|
|
543
|
+
const fs = require('fs');
|
|
544
|
+
const agentDir = path.join(getAgentDir(), 'agents');
|
|
545
|
+
if (!fs.existsSync(agentDir))
|
|
546
|
+
return {
|
|
547
|
+
content: [{ type: 'text', text: 'No agents found or .agent directory missing.' }],
|
|
548
|
+
};
|
|
549
|
+
const agents = fs
|
|
550
|
+
.readdirSync(agentDir)
|
|
551
|
+
.filter(f => f.endsWith('.md'))
|
|
552
|
+
.map(f => f.replace('.md', ''));
|
|
553
|
+
return { content: [{ type: 'text', text: 'Available Agents:\n- ' + agents.join('\n- ') }] };
|
|
381
554
|
}
|
|
382
555
|
|
|
383
|
-
if (toolName ===
|
|
384
|
-
const fs = require(
|
|
556
|
+
if (toolName === 'get_tribunal_agent') {
|
|
557
|
+
const fs = require('fs');
|
|
385
558
|
const name = req.params?.arguments?.name;
|
|
386
|
-
if (!name || typeof name !==
|
|
559
|
+
if (!name || typeof name !== 'string')
|
|
560
|
+
throw new RpcError(-32602, 'Missing or invalid argument: name (string)');
|
|
387
561
|
const sanitizedName = path.basename(name);
|
|
388
|
-
const agentsDir = path.resolve(
|
|
562
|
+
const agentsDir = path.resolve(getAgentDir(), 'agents');
|
|
389
563
|
const agentPath = path.resolve(agentsDir, `${sanitizedName}.md`);
|
|
390
564
|
// Path containment: ensure resolved path stays within agents directory
|
|
391
|
-
if (!agentPath.startsWith(agentsDir))
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
565
|
+
if (!agentPath.startsWith(agentsDir))
|
|
566
|
+
throw new RpcError(-32602, 'Invalid agent name: path traversal detected');
|
|
567
|
+
if (!fs.existsSync(agentPath))
|
|
568
|
+
return { content: [{ type: 'text', text: `Agent '${sanitizedName}' not found.` }] };
|
|
569
|
+
const text = fs.readFileSync(agentPath, 'utf8');
|
|
570
|
+
return { content: [{ type: 'text', text: stripBoilerplate(text) }] };
|
|
395
571
|
}
|
|
396
572
|
|
|
397
|
-
if (toolName ===
|
|
398
|
-
const fs = require(
|
|
399
|
-
const skillsDir = path.join(
|
|
400
|
-
if (!fs.existsSync(skillsDir))
|
|
401
|
-
|
|
402
|
-
|
|
573
|
+
if (toolName === 'list_tribunal_skills') {
|
|
574
|
+
const fs = require('fs');
|
|
575
|
+
const skillsDir = path.join(getAgentDir(), 'skills');
|
|
576
|
+
if (!fs.existsSync(skillsDir))
|
|
577
|
+
return {
|
|
578
|
+
content: [{ type: 'text', text: 'No skills found or .agent directory missing.' }],
|
|
579
|
+
};
|
|
580
|
+
const skills = fs
|
|
581
|
+
.readdirSync(skillsDir, { withFileTypes: true })
|
|
582
|
+
.filter(d => d.isDirectory())
|
|
583
|
+
.map(d => d.name);
|
|
584
|
+
return { content: [{ type: 'text', text: 'Available Skills:\n- ' + skills.join('\n- ') }] };
|
|
403
585
|
}
|
|
404
586
|
|
|
405
|
-
if (toolName ===
|
|
406
|
-
const fs = require(
|
|
587
|
+
if (toolName === 'get_tribunal_skill') {
|
|
588
|
+
const fs = require('fs');
|
|
407
589
|
const name = req.params?.arguments?.name;
|
|
408
|
-
if (!name || typeof name !==
|
|
590
|
+
if (!name || typeof name !== 'string')
|
|
591
|
+
throw new RpcError(-32602, 'Missing or invalid argument: name (string)');
|
|
409
592
|
const sanitizedName = path.basename(name);
|
|
410
|
-
const skillsDir = path.resolve(
|
|
411
|
-
const skillPath = path.resolve(skillsDir, sanitizedName,
|
|
593
|
+
const skillsDir = path.resolve(getAgentDir(), 'skills');
|
|
594
|
+
const skillPath = path.resolve(skillsDir, sanitizedName, 'SKILL.md');
|
|
412
595
|
// Path containment: ensure resolved path stays within skills directory
|
|
413
|
-
if (!skillPath.startsWith(skillsDir))
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
596
|
+
if (!skillPath.startsWith(skillsDir))
|
|
597
|
+
throw new RpcError(-32602, 'Invalid skill name: path traversal detected');
|
|
598
|
+
if (!fs.existsSync(skillPath))
|
|
599
|
+
return { content: [{ type: 'text', text: `Skill '${sanitizedName}' not found.` }] };
|
|
600
|
+
const text = fs.readFileSync(skillPath, 'utf8');
|
|
601
|
+
return { content: [{ type: 'text', text: stripBoilerplate(text) }] };
|
|
417
602
|
}
|
|
418
603
|
|
|
419
|
-
if (toolName ===
|
|
604
|
+
if (toolName === 'get_sparse_context') {
|
|
420
605
|
const task = req.params?.arguments?.task;
|
|
421
606
|
const files = req.params?.arguments?.files || [];
|
|
422
|
-
const model = req.params?.arguments?.model ||
|
|
607
|
+
const model = req.params?.arguments?.model || 'large';
|
|
423
608
|
|
|
424
|
-
if (!task) throw
|
|
609
|
+
if (!task) throw new RpcError(-32602, 'Missing required argument: task');
|
|
425
610
|
|
|
426
|
-
const agentDest =
|
|
427
|
-
const fs = require(
|
|
611
|
+
const agentDest = getAgentDir();
|
|
612
|
+
const fs = require('fs');
|
|
428
613
|
if (!fs.existsSync(agentDest)) {
|
|
429
|
-
return {
|
|
614
|
+
return {
|
|
615
|
+
content: [
|
|
616
|
+
{ type: 'text', text: 'Error: .agent/ directory not found. Run `tk init` first.' },
|
|
617
|
+
],
|
|
618
|
+
};
|
|
430
619
|
}
|
|
431
620
|
|
|
432
621
|
try {
|
|
433
|
-
const brokerScript = path.join(agentDest,
|
|
622
|
+
const brokerScript = path.join(agentDest, 'scripts', 'context_broker.js');
|
|
434
623
|
const { broker } = require(brokerScript);
|
|
435
624
|
const brokerResult = broker(task, files, model, agentDest);
|
|
436
|
-
return { content: [{ type:
|
|
625
|
+
return { content: [{ type: 'text', text: stripBoilerplate(brokerResult.promptText) }] };
|
|
437
626
|
} catch (e) {
|
|
438
|
-
return {
|
|
627
|
+
return {
|
|
628
|
+
content: [{ type: 'text', text: `Failed to retrieve sparse context: ${e.message}` }],
|
|
629
|
+
};
|
|
439
630
|
}
|
|
440
631
|
}
|
|
441
632
|
|
|
442
|
-
if (toolName ===
|
|
633
|
+
if (toolName === 'recall_memory') {
|
|
443
634
|
const query = req.params?.arguments?.query;
|
|
444
|
-
if (!query || typeof query !==
|
|
445
|
-
throw
|
|
635
|
+
if (!query || typeof query !== 'string') {
|
|
636
|
+
throw new RpcError(-32602, 'Missing or invalid required argument: query (string)');
|
|
446
637
|
}
|
|
447
638
|
const budget = req.params?.arguments?.budget || 2000;
|
|
448
|
-
const agentDest =
|
|
449
|
-
const fs = require(
|
|
639
|
+
const agentDest = getAgentDir();
|
|
640
|
+
const fs = require('fs');
|
|
450
641
|
if (!fs.existsSync(agentDest)) {
|
|
451
|
-
return {
|
|
642
|
+
return {
|
|
643
|
+
content: [
|
|
644
|
+
{ type: 'text', text: 'Error: .agent/ directory not found. Run `tk init` first.' },
|
|
645
|
+
],
|
|
646
|
+
};
|
|
452
647
|
}
|
|
453
648
|
try {
|
|
454
|
-
const { _memoryRecall } = require(
|
|
649
|
+
const { _memoryRecall } = require('../dist/commands/memory.js');
|
|
455
650
|
const { results, tokens_used } = _memoryRecall(agentDest, query, budget);
|
|
456
651
|
if (results.length === 0) {
|
|
457
|
-
return { content: [{ type:
|
|
652
|
+
return { content: [{ type: 'text', text: `No memories match query: "${query}"` }] };
|
|
458
653
|
}
|
|
459
654
|
let text = `## Memory Recall (${results.length} results, ~${tokens_used}/${budget} tokens)\n\n`;
|
|
460
655
|
for (const entry of results) {
|
|
461
656
|
text += `- **[${entry.memory_type.toUpperCase()}]** #${entry.id}: ${entry.content}`;
|
|
462
|
-
if (entry.tags.length > 0) text += ` _(${entry.tags.join(
|
|
657
|
+
if (entry.tags.length > 0) text += ` _(${entry.tags.join(', ')})_`;
|
|
463
658
|
text += `\n`;
|
|
464
659
|
}
|
|
465
|
-
return { content: [{ type:
|
|
660
|
+
return { content: [{ type: 'text', text }] };
|
|
466
661
|
} catch (e) {
|
|
467
|
-
return { content: [{ type:
|
|
662
|
+
return { content: [{ type: 'text', text: `Memory recall failed: ${e.message}` }] };
|
|
468
663
|
}
|
|
469
664
|
}
|
|
470
665
|
|
|
471
|
-
if (toolName ===
|
|
666
|
+
if (toolName === 'store_memory') {
|
|
472
667
|
const memType = req.params?.arguments?.type;
|
|
473
668
|
const content = req.params?.arguments?.content;
|
|
474
669
|
const tags = req.params?.arguments?.tags || [];
|
|
475
670
|
if (!memType || !content) {
|
|
476
|
-
throw
|
|
671
|
+
throw new RpcError(-32602, 'Missing required arguments: type (string), content (string)');
|
|
477
672
|
}
|
|
478
|
-
const validTypes = [
|
|
673
|
+
const validTypes = ['semantic', 'procedural', 'episodic', 'working'];
|
|
479
674
|
if (!validTypes.includes(memType)) {
|
|
480
|
-
throw
|
|
675
|
+
throw new RpcError(
|
|
676
|
+
-32602,
|
|
677
|
+
`Invalid memory type: "${memType}". Must be one of: ${validTypes.join(', ')}`,
|
|
678
|
+
);
|
|
481
679
|
}
|
|
482
|
-
const agentDest =
|
|
483
|
-
const fs = require(
|
|
680
|
+
const agentDest = getAgentDir();
|
|
681
|
+
const fs = require('fs');
|
|
484
682
|
if (!fs.existsSync(agentDest)) {
|
|
485
|
-
return {
|
|
683
|
+
return {
|
|
684
|
+
content: [
|
|
685
|
+
{ type: 'text', text: 'Error: .agent/ directory not found. Run `tk init` first.' },
|
|
686
|
+
],
|
|
687
|
+
};
|
|
486
688
|
}
|
|
487
689
|
try {
|
|
488
|
-
const { _memoryStore } = require(
|
|
690
|
+
const { _memoryStore } = require('../dist/commands/memory.js');
|
|
489
691
|
const result = _memoryStore(agentDest, memType, content, tags, null);
|
|
490
|
-
return {
|
|
692
|
+
return {
|
|
693
|
+
content: [
|
|
694
|
+
{
|
|
695
|
+
type: 'text',
|
|
696
|
+
text: `Memory stored: #${result.id} (${memType}, ~${result.token_estimate} tokens)`,
|
|
697
|
+
},
|
|
698
|
+
],
|
|
699
|
+
};
|
|
491
700
|
} catch (e) {
|
|
492
|
-
return { content: [{ type:
|
|
701
|
+
return { content: [{ type: 'text', text: `Memory store failed: ${e.message}` }] };
|
|
493
702
|
}
|
|
494
703
|
}
|
|
495
704
|
|
|
496
|
-
if (toolName ===
|
|
705
|
+
if (toolName === 'align_output') {
|
|
497
706
|
const text = req.params?.arguments?.text;
|
|
498
|
-
if (typeof text !==
|
|
499
|
-
throw
|
|
707
|
+
if (typeof text !== 'string') {
|
|
708
|
+
throw new RpcError(-32602, 'Missing or invalid required argument: text (string)');
|
|
500
709
|
}
|
|
501
710
|
try {
|
|
502
|
-
const { alignText, validateCodeContent } = require(
|
|
711
|
+
const { alignText, validateCodeContent } = require('../dist/commands/align.js');
|
|
503
712
|
const aligned = alignText(text);
|
|
504
713
|
const warnings = validateCodeContent(aligned);
|
|
505
|
-
|
|
714
|
+
|
|
506
715
|
let outputText = aligned;
|
|
507
716
|
if (warnings.length > 0) {
|
|
508
|
-
outputText +=
|
|
717
|
+
outputText += '\n\n⚠️ OCAE Alignment Validator Warnings:\n';
|
|
509
718
|
for (const warnMsg of warnings) {
|
|
510
719
|
outputText += `● ${warnMsg}\n`;
|
|
511
720
|
}
|
|
512
721
|
}
|
|
513
|
-
return { content: [{ type:
|
|
722
|
+
return { content: [{ type: 'text', text: outputText }] };
|
|
723
|
+
} catch (e) {
|
|
724
|
+
return { content: [{ type: 'text', text: `Output alignment failed: ${e.message}` }] };
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
if (toolName === 'verify_contracts') {
|
|
729
|
+
const file = req.params?.arguments?.file;
|
|
730
|
+
const content = req.params?.arguments?.content;
|
|
731
|
+
|
|
732
|
+
if (!file || typeof file !== 'string' || typeof content !== 'string') {
|
|
733
|
+
throw new RpcError(
|
|
734
|
+
-32602,
|
|
735
|
+
'Missing or invalid required arguments: file (string), content (string)',
|
|
736
|
+
);
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
try {
|
|
740
|
+
const projectRoot = process.cwd();
|
|
741
|
+
const contractEnginePath = path.join(getAgentDir(), 'scripts', 'contract_engine.js');
|
|
742
|
+
if (!require('fs').existsSync(contractEnginePath)) {
|
|
743
|
+
return {
|
|
744
|
+
content: [
|
|
745
|
+
{ type: 'text', text: 'Error: contract_engine.js not found. Run `tk init` first.' },
|
|
746
|
+
],
|
|
747
|
+
};
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
const contractEngine = require(contractEnginePath);
|
|
751
|
+
const contracts = contractEngine.loadContracts(projectRoot);
|
|
752
|
+
|
|
753
|
+
if (contracts.length === 0) {
|
|
754
|
+
return {
|
|
755
|
+
content: [
|
|
756
|
+
{
|
|
757
|
+
type: 'text',
|
|
758
|
+
text: 'No active behavioral contracts found in .tribunal/contracts/.',
|
|
759
|
+
},
|
|
760
|
+
],
|
|
761
|
+
};
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
const relativePath = path.relative(projectRoot, file).replace(/\\/g, '/');
|
|
765
|
+
const allViolations = [];
|
|
766
|
+
|
|
767
|
+
for (const contract of contracts) {
|
|
768
|
+
const vList = contractEngine.evaluateContract(contract, relativePath, content);
|
|
769
|
+
if (vList.length > 0) {
|
|
770
|
+
allViolations.push(...vList);
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
if (allViolations.length === 0) {
|
|
775
|
+
return {
|
|
776
|
+
content: [
|
|
777
|
+
{
|
|
778
|
+
type: 'text',
|
|
779
|
+
text: '✅ Contract check passed. Zero behavioral violations detected.',
|
|
780
|
+
},
|
|
781
|
+
],
|
|
782
|
+
};
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
let report = `📜 Contract Verification Results (${allViolations.length} violations):\n`;
|
|
786
|
+
for (const v of allViolations) {
|
|
787
|
+
report += `● [${v.severity.toUpperCase()}] ${v.contract}: ${v.message}\n`;
|
|
788
|
+
if (v.line) report += ` Line ${v.line}: ${v.snippet || ''}\n`;
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
return { content: [{ type: 'text', text: report }] };
|
|
514
792
|
} catch (e) {
|
|
515
|
-
return { content: [{ type:
|
|
793
|
+
return { content: [{ type: 'text', text: `Contract verification failed: ${e.message}` }] };
|
|
516
794
|
}
|
|
517
795
|
}
|
|
518
796
|
|
|
519
|
-
throw
|
|
797
|
+
throw new RpcError(-32601, `Unknown tool: ${toolName}`);
|
|
520
798
|
}
|
|
521
799
|
|
|
522
|
-
throw
|
|
800
|
+
throw new RpcError(-32601, `Unknown method: ${req.method}`);
|
|
523
801
|
}
|
|
524
802
|
|
|
525
803
|
function processSingleRequest(req) {
|
|
@@ -529,31 +807,32 @@ function processSingleRequest(req) {
|
|
|
529
807
|
if (req.id === undefined || req.id === null) {
|
|
530
808
|
return null;
|
|
531
809
|
}
|
|
532
|
-
return { jsonrpc:
|
|
810
|
+
return { jsonrpc: '2.0', id: req.id, result };
|
|
533
811
|
} catch (e) {
|
|
534
|
-
const code = e && typeof e.code ===
|
|
535
|
-
const message = e && e.message ? e.message :
|
|
812
|
+
const code = e && typeof e.code === 'number' ? e.code : -32603;
|
|
813
|
+
const message = e && e.message ? e.message : 'Internal server error';
|
|
536
814
|
if (req.id === undefined || req.id === null) {
|
|
537
815
|
return {
|
|
538
|
-
jsonrpc:
|
|
816
|
+
jsonrpc: '2.0',
|
|
539
817
|
id: null,
|
|
540
818
|
error: { code, message },
|
|
541
819
|
};
|
|
542
820
|
}
|
|
543
821
|
return {
|
|
544
|
-
jsonrpc:
|
|
822
|
+
jsonrpc: '2.0',
|
|
545
823
|
id: req.id,
|
|
546
824
|
error: { code, message },
|
|
547
825
|
};
|
|
548
826
|
}
|
|
549
827
|
}
|
|
550
828
|
|
|
551
|
-
rl.on(
|
|
552
|
-
if (line.length > 1048576) {
|
|
829
|
+
rl.on('line', line => {
|
|
830
|
+
if (line.length > 1048576) {
|
|
831
|
+
// 1MB limit
|
|
553
832
|
const errorRes = {
|
|
554
|
-
jsonrpc:
|
|
833
|
+
jsonrpc: '2.0',
|
|
555
834
|
id: null,
|
|
556
|
-
error: { code: -32700, message:
|
|
835
|
+
error: { code: -32700, message: 'Parse error: input line too long (exceeds 1MB limit)' },
|
|
557
836
|
};
|
|
558
837
|
console.log(JSON.stringify(errorRes));
|
|
559
838
|
return;
|
|
@@ -566,9 +845,9 @@ rl.on("line", (line) => {
|
|
|
566
845
|
} catch (parseErr) {
|
|
567
846
|
// Invalid JSON — send a parse error
|
|
568
847
|
const errorRes = {
|
|
569
|
-
jsonrpc:
|
|
848
|
+
jsonrpc: '2.0',
|
|
570
849
|
id: null,
|
|
571
|
-
error: { code: -32700, message:
|
|
850
|
+
error: { code: -32700, message: 'Parse error: ' + parseErr.message },
|
|
572
851
|
};
|
|
573
852
|
console.log(JSON.stringify(errorRes));
|
|
574
853
|
return;
|
|
@@ -593,7 +872,7 @@ rl.on("line", (line) => {
|
|
|
593
872
|
}
|
|
594
873
|
});
|
|
595
874
|
|
|
596
|
-
if (process.env.NODE_ENV ===
|
|
875
|
+
if (process.env.NODE_ENV === 'test') {
|
|
597
876
|
module.exports = {
|
|
598
877
|
handleRequest,
|
|
599
878
|
stripBoilerplate,
|