tribunal-kit 6.0.1 → 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/ARCHITECTURE.md +9 -6
- 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 +1532 -1
- package/.agent/history/memory/MEMORY.md +102 -1
- package/.agent/mcp_config.json +1 -6
- package/.agent/routing_index.json +2033 -263
- package/.agent/rules/GEMINI.md +11 -9
- 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 +22 -3
- 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 +6 -2
- package/.agent/skills/ai-app-hardening/SKILL.md +9 -8
- 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 +5 -4
- 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 +7 -3
- package/.agent/skills/edge-ai-mobile/SKILL.md +5 -1
- 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 +2 -1
- 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 +2 -1
- 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 +1 -0
- package/.agent/skills/playwright-ai-e2e/SKILL.md +3 -2
- 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 +10 -12
- 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 +3 -2
- 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 +11 -6
- 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 +2 -1
- 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 +94 -44
- package/SECURITY.md +10 -10
- package/bin/mcp-server.js +385 -252
- package/bin/tribunal-kit.js +29 -30
- package/bin/wrapper.js +40 -46
- package/dist/cli.js +6 -0
- package/dist/commands/case.js +2 -0
- package/dist/commands/contract.js +440 -0
- package/dist/commands/status.js +6 -0
- package/dist/index.d.ts +8 -1
- package/package.json +13 -12
- 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,100 +85,96 @@ 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
|
|
|
113
114
|
function getAgentDir() {
|
|
114
|
-
const fs = require(
|
|
115
|
-
const local = path.join(process.cwd(),
|
|
115
|
+
const fs = require('fs');
|
|
116
|
+
const local = path.join(process.cwd(), '.agent');
|
|
116
117
|
if (fs.existsSync(local)) return local;
|
|
117
|
-
return path.resolve(__dirname,
|
|
118
|
+
return path.resolve(__dirname, '../.agent');
|
|
118
119
|
}
|
|
119
120
|
|
|
120
121
|
function handleRequest(req) {
|
|
121
|
-
const fs = require(
|
|
122
|
-
if (req.method ===
|
|
122
|
+
const fs = require('fs');
|
|
123
|
+
if (req.method === 'notifications/initialized' || req.method === 'notifications/cancelled') {
|
|
123
124
|
return null;
|
|
124
125
|
}
|
|
125
|
-
if (req.method ===
|
|
126
|
+
if (req.method === 'ping') {
|
|
126
127
|
return {};
|
|
127
128
|
}
|
|
128
129
|
|
|
129
130
|
// MCP spec: method names follow path-style convention
|
|
130
|
-
if (req.method ===
|
|
131
|
+
if (req.method === 'initialize') {
|
|
131
132
|
return {
|
|
132
|
-
protocolVersion:
|
|
133
|
+
protocolVersion: '2025-03-26',
|
|
133
134
|
capabilities: {
|
|
134
135
|
tools: {},
|
|
135
136
|
resources: { subscribe: false, listChanged: false },
|
|
136
137
|
prompts: { listChanged: false },
|
|
137
138
|
},
|
|
138
139
|
serverInfo: {
|
|
139
|
-
name:
|
|
140
|
+
name: 'tribunal-kit-mcp',
|
|
140
141
|
version: PKG.version,
|
|
141
142
|
},
|
|
142
143
|
};
|
|
143
144
|
}
|
|
144
145
|
|
|
145
|
-
if (req.method ===
|
|
146
|
+
if (req.method === 'resources/list') {
|
|
146
147
|
const agentDir = getAgentDir();
|
|
147
148
|
const resources = [];
|
|
148
|
-
|
|
149
|
+
|
|
149
150
|
// Agents
|
|
150
|
-
const agentsDir = path.join(agentDir,
|
|
151
|
+
const agentsDir = path.join(agentDir, 'agents');
|
|
151
152
|
if (fs.existsSync(agentsDir)) {
|
|
152
|
-
const files = fs.readdirSync(agentsDir).filter(
|
|
153
|
+
const files = fs.readdirSync(agentsDir).filter(f => f.endsWith('.md'));
|
|
153
154
|
for (const f of files) {
|
|
154
|
-
const name = path.basename(f,
|
|
155
|
+
const name = path.basename(f, '.md');
|
|
155
156
|
resources.push({
|
|
156
157
|
uri: `tribunal://agent/${name}`,
|
|
157
158
|
name: `Agent: ${name}`,
|
|
158
159
|
description: `Tribunal Specialist Agent rule file for ${name}`,
|
|
159
|
-
mimeType:
|
|
160
|
+
mimeType: 'text/markdown',
|
|
160
161
|
});
|
|
161
162
|
}
|
|
162
163
|
}
|
|
163
164
|
|
|
164
165
|
// Skills
|
|
165
|
-
const skillsDir = path.join(agentDir,
|
|
166
|
+
const skillsDir = path.join(agentDir, 'skills');
|
|
166
167
|
if (fs.existsSync(skillsDir)) {
|
|
167
168
|
const dirs = fs.readdirSync(skillsDir, { withFileTypes: true });
|
|
168
169
|
for (const d of dirs) {
|
|
169
170
|
if (d.isDirectory()) {
|
|
170
|
-
const skillFile = path.join(skillsDir, d.name,
|
|
171
|
+
const skillFile = path.join(skillsDir, d.name, 'SKILL.md');
|
|
171
172
|
if (fs.existsSync(skillFile)) {
|
|
172
173
|
resources.push({
|
|
173
174
|
uri: `tribunal://skill/${d.name}`,
|
|
174
175
|
name: `Skill: ${d.name}`,
|
|
175
176
|
description: `Tribunal Skill instruction file for ${d.name}`,
|
|
176
|
-
mimeType:
|
|
177
|
+
mimeType: 'text/markdown',
|
|
177
178
|
});
|
|
178
179
|
}
|
|
179
180
|
}
|
|
@@ -181,16 +182,16 @@ function handleRequest(req) {
|
|
|
181
182
|
}
|
|
182
183
|
|
|
183
184
|
// Workflows
|
|
184
|
-
const workflowsDir = path.join(agentDir,
|
|
185
|
+
const workflowsDir = path.join(agentDir, 'workflows');
|
|
185
186
|
if (fs.existsSync(workflowsDir)) {
|
|
186
|
-
const files = fs.readdirSync(workflowsDir).filter(
|
|
187
|
+
const files = fs.readdirSync(workflowsDir).filter(f => f.endsWith('.md'));
|
|
187
188
|
for (const f of files) {
|
|
188
|
-
const name = path.basename(f,
|
|
189
|
+
const name = path.basename(f, '.md');
|
|
189
190
|
resources.push({
|
|
190
191
|
uri: `tribunal://workflow/${name}`,
|
|
191
192
|
name: `Workflow: ${name}`,
|
|
192
193
|
description: `Tribunal Workflow guide for ${name}`,
|
|
193
|
-
mimeType:
|
|
194
|
+
mimeType: 'text/markdown',
|
|
194
195
|
});
|
|
195
196
|
}
|
|
196
197
|
}
|
|
@@ -198,55 +199,55 @@ function handleRequest(req) {
|
|
|
198
199
|
return { resources };
|
|
199
200
|
}
|
|
200
201
|
|
|
201
|
-
if (req.method ===
|
|
202
|
+
if (req.method === 'resources/read') {
|
|
202
203
|
const uri = req.params && req.params.uri;
|
|
203
|
-
if (!uri) throw new Error(
|
|
204
|
+
if (!uri) throw new Error('Missing uri parameter');
|
|
204
205
|
const agentDir = getAgentDir();
|
|
205
206
|
let filePath = null;
|
|
206
207
|
|
|
207
|
-
if (uri.startsWith(
|
|
208
|
-
const name = uri.replace(
|
|
209
|
-
filePath = path.join(agentDir,
|
|
210
|
-
} else if (uri.startsWith(
|
|
211
|
-
const name = uri.replace(
|
|
212
|
-
filePath = path.join(agentDir,
|
|
213
|
-
} else if (uri.startsWith(
|
|
214
|
-
const name = uri.replace(
|
|
215
|
-
filePath = path.join(agentDir,
|
|
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`);
|
|
216
217
|
}
|
|
217
218
|
|
|
218
219
|
if (!filePath || !fs.existsSync(filePath)) {
|
|
219
220
|
throw new Error(`Resource not found: ${uri}`);
|
|
220
221
|
}
|
|
221
222
|
|
|
222
|
-
const text = fs.readFileSync(filePath,
|
|
223
|
+
const text = fs.readFileSync(filePath, 'utf8');
|
|
223
224
|
return {
|
|
224
225
|
contents: [
|
|
225
226
|
{
|
|
226
227
|
uri,
|
|
227
|
-
mimeType:
|
|
228
|
+
mimeType: 'text/markdown',
|
|
228
229
|
text,
|
|
229
230
|
},
|
|
230
231
|
],
|
|
231
232
|
};
|
|
232
233
|
}
|
|
233
234
|
|
|
234
|
-
if (req.method ===
|
|
235
|
+
if (req.method === 'prompts/list') {
|
|
235
236
|
const agentDir = getAgentDir();
|
|
236
237
|
const prompts = [];
|
|
237
|
-
const workflowsDir = path.join(agentDir,
|
|
238
|
+
const workflowsDir = path.join(agentDir, 'workflows');
|
|
238
239
|
|
|
239
240
|
if (fs.existsSync(workflowsDir)) {
|
|
240
|
-
const files = fs.readdirSync(workflowsDir).filter(
|
|
241
|
+
const files = fs.readdirSync(workflowsDir).filter(f => f.endsWith('.md'));
|
|
241
242
|
for (const f of files) {
|
|
242
|
-
const name = path.basename(f,
|
|
243
|
+
const name = path.basename(f, '.md');
|
|
243
244
|
prompts.push({
|
|
244
245
|
name,
|
|
245
246
|
description: `Execute tribunal workflow /${name}`,
|
|
246
247
|
arguments: [
|
|
247
248
|
{
|
|
248
|
-
name:
|
|
249
|
-
description:
|
|
249
|
+
name: 'task',
|
|
250
|
+
description: 'The task or target file to execute the workflow against',
|
|
250
251
|
required: false,
|
|
251
252
|
},
|
|
252
253
|
],
|
|
@@ -257,26 +258,26 @@ function handleRequest(req) {
|
|
|
257
258
|
return { prompts };
|
|
258
259
|
}
|
|
259
260
|
|
|
260
|
-
if (req.method ===
|
|
261
|
+
if (req.method === 'prompts/get') {
|
|
261
262
|
const name = req.params && req.params.name;
|
|
262
|
-
const task = (req.params && req.params.arguments && req.params.arguments.task) ||
|
|
263
|
-
if (!name) throw new Error(
|
|
263
|
+
const task = (req.params && req.params.arguments && req.params.arguments.task) || '';
|
|
264
|
+
if (!name) throw new Error('Missing prompt name parameter');
|
|
264
265
|
|
|
265
266
|
const agentDir = getAgentDir();
|
|
266
|
-
const workflowPath = path.join(agentDir,
|
|
267
|
+
const workflowPath = path.join(agentDir, 'workflows', `${name}.md`);
|
|
267
268
|
if (!fs.existsSync(workflowPath)) {
|
|
268
269
|
throw new Error(`Prompt workflow not found: ${name}`);
|
|
269
270
|
}
|
|
270
271
|
|
|
271
|
-
const content = fs.readFileSync(workflowPath,
|
|
272
|
+
const content = fs.readFileSync(workflowPath, 'utf8');
|
|
272
273
|
const promptText = task ? `${content}\n\nTarget Task/File: ${task}` : content;
|
|
273
274
|
|
|
274
275
|
return {
|
|
275
276
|
messages: [
|
|
276
277
|
{
|
|
277
|
-
role:
|
|
278
|
+
role: 'user',
|
|
278
279
|
content: {
|
|
279
|
-
type:
|
|
280
|
+
type: 'text',
|
|
280
281
|
text: promptText,
|
|
281
282
|
},
|
|
282
283
|
},
|
|
@@ -284,168 +285,193 @@ function handleRequest(req) {
|
|
|
284
285
|
};
|
|
285
286
|
}
|
|
286
287
|
|
|
287
|
-
if (req.method ===
|
|
288
|
+
if (req.method === 'tools/list') {
|
|
288
289
|
return {
|
|
289
290
|
tools: [
|
|
290
291
|
{
|
|
291
|
-
name:
|
|
292
|
-
description:
|
|
293
|
-
"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.',
|
|
294
294
|
inputSchema: {
|
|
295
|
-
type:
|
|
295
|
+
type: 'object',
|
|
296
296
|
properties: {},
|
|
297
297
|
additionalProperties: false,
|
|
298
298
|
},
|
|
299
299
|
},
|
|
300
300
|
{
|
|
301
|
-
name:
|
|
302
|
-
description:
|
|
303
|
-
"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.',
|
|
304
303
|
inputSchema: {
|
|
305
|
-
type:
|
|
304
|
+
type: 'object',
|
|
306
305
|
properties: {},
|
|
307
306
|
additionalProperties: false,
|
|
308
307
|
},
|
|
309
308
|
},
|
|
310
309
|
{
|
|
311
|
-
name:
|
|
310
|
+
name: 'search_case_law',
|
|
312
311
|
description:
|
|
313
|
-
|
|
312
|
+
'Search historical code rejections and legal precedent. Use this before writing code to avoid past mistakes.',
|
|
314
313
|
inputSchema: {
|
|
315
|
-
type:
|
|
314
|
+
type: 'object',
|
|
316
315
|
properties: {
|
|
317
316
|
query: {
|
|
318
|
-
type:
|
|
317
|
+
type: 'string',
|
|
319
318
|
description: "Search query (e.g. 'useEffect state')",
|
|
320
319
|
},
|
|
321
320
|
},
|
|
322
|
-
required: [
|
|
321
|
+
required: ['query'],
|
|
323
322
|
additionalProperties: false,
|
|
324
323
|
},
|
|
325
324
|
},
|
|
326
325
|
{
|
|
327
|
-
name:
|
|
328
|
-
description:
|
|
326
|
+
name: 'list_tribunal_agents',
|
|
327
|
+
description: 'List all available Tribunal Kit agents.',
|
|
329
328
|
inputSchema: {
|
|
330
|
-
type:
|
|
329
|
+
type: 'object',
|
|
331
330
|
properties: {},
|
|
332
331
|
additionalProperties: false,
|
|
333
332
|
},
|
|
334
333
|
},
|
|
335
334
|
{
|
|
336
|
-
name:
|
|
337
|
-
description:
|
|
335
|
+
name: 'get_tribunal_agent',
|
|
336
|
+
description: 'Get the full markdown rules for a specific Tribunal agent.',
|
|
338
337
|
inputSchema: {
|
|
339
|
-
type:
|
|
338
|
+
type: 'object',
|
|
340
339
|
properties: {
|
|
341
|
-
name: { type:
|
|
340
|
+
name: { type: 'string', description: "The agent name (e.g. 'frontend-specialist')" },
|
|
342
341
|
},
|
|
343
|
-
required: [
|
|
342
|
+
required: ['name'],
|
|
344
343
|
additionalProperties: false,
|
|
345
344
|
},
|
|
346
345
|
},
|
|
347
346
|
{
|
|
348
|
-
name:
|
|
349
|
-
description:
|
|
347
|
+
name: 'list_tribunal_skills',
|
|
348
|
+
description: 'List all available Tribunal Kit skills.',
|
|
350
349
|
inputSchema: {
|
|
351
|
-
type:
|
|
350
|
+
type: 'object',
|
|
352
351
|
properties: {},
|
|
353
352
|
additionalProperties: false,
|
|
354
353
|
},
|
|
355
354
|
},
|
|
356
355
|
{
|
|
357
|
-
name:
|
|
358
|
-
description:
|
|
356
|
+
name: 'get_tribunal_skill',
|
|
357
|
+
description: 'Get the full markdown instructions for a specific Tribunal skill.',
|
|
359
358
|
inputSchema: {
|
|
360
|
-
type:
|
|
359
|
+
type: 'object',
|
|
361
360
|
properties: {
|
|
362
|
-
name: { type:
|
|
361
|
+
name: { type: 'string', description: "The skill name (e.g. 'react-specialist')" },
|
|
363
362
|
},
|
|
364
|
-
required: [
|
|
363
|
+
required: ['name'],
|
|
365
364
|
additionalProperties: false,
|
|
366
365
|
},
|
|
367
366
|
},
|
|
368
367
|
{
|
|
369
|
-
name:
|
|
370
|
-
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.',
|
|
371
371
|
inputSchema: {
|
|
372
|
-
type:
|
|
372
|
+
type: 'object',
|
|
373
373
|
properties: {
|
|
374
374
|
query: {
|
|
375
|
-
type:
|
|
375
|
+
type: 'string',
|
|
376
376
|
description: "Search query (e.g. 'database', 'auth', 'deploy')",
|
|
377
377
|
},
|
|
378
378
|
budget: {
|
|
379
|
-
type:
|
|
380
|
-
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.',
|
|
381
382
|
},
|
|
382
383
|
},
|
|
383
|
-
required: [
|
|
384
|
+
required: ['query'],
|
|
384
385
|
additionalProperties: false,
|
|
385
386
|
},
|
|
386
387
|
},
|
|
387
388
|
{
|
|
388
|
-
name:
|
|
389
|
-
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).',
|
|
390
392
|
inputSchema: {
|
|
391
|
-
type:
|
|
393
|
+
type: 'object',
|
|
392
394
|
properties: {
|
|
393
395
|
type: {
|
|
394
|
-
type:
|
|
395
|
-
enum: [
|
|
396
|
-
description:
|
|
396
|
+
type: 'string',
|
|
397
|
+
enum: ['semantic', 'procedural', 'episodic', 'working'],
|
|
398
|
+
description:
|
|
399
|
+
'Memory type: semantic (facts), procedural (recipes), episodic (events), working (scratch)',
|
|
397
400
|
},
|
|
398
401
|
content: {
|
|
399
|
-
type:
|
|
400
|
-
description:
|
|
402
|
+
type: 'string',
|
|
403
|
+
description: 'The memory content to store',
|
|
401
404
|
},
|
|
402
405
|
tags: {
|
|
403
|
-
type:
|
|
404
|
-
items: { type:
|
|
405
|
-
description:
|
|
406
|
+
type: 'array',
|
|
407
|
+
items: { type: 'string' },
|
|
408
|
+
description: 'Searchable tags for this memory',
|
|
406
409
|
},
|
|
407
410
|
},
|
|
408
|
-
required: [
|
|
411
|
+
required: ['type', 'content'],
|
|
409
412
|
additionalProperties: false,
|
|
410
413
|
},
|
|
411
414
|
},
|
|
412
415
|
{
|
|
413
|
-
name:
|
|
414
|
-
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.',
|
|
415
419
|
inputSchema: {
|
|
416
|
-
type:
|
|
420
|
+
type: 'object',
|
|
417
421
|
properties: {
|
|
418
422
|
task: {
|
|
419
|
-
type:
|
|
423
|
+
type: 'string',
|
|
420
424
|
description: "The user task description (e.g. 'JWT auth API')",
|
|
421
425
|
},
|
|
422
426
|
files: {
|
|
423
|
-
type:
|
|
424
|
-
items: { type:
|
|
427
|
+
type: 'array',
|
|
428
|
+
items: { type: 'string' },
|
|
425
429
|
description: "List of files being touched (e.g. ['src/auth.js'])",
|
|
426
430
|
},
|
|
427
431
|
model: {
|
|
428
|
-
type:
|
|
429
|
-
enum: [
|
|
430
|
-
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)',
|
|
431
436
|
},
|
|
432
437
|
},
|
|
433
|
-
required: [
|
|
438
|
+
required: ['task'],
|
|
434
439
|
additionalProperties: false,
|
|
435
440
|
},
|
|
436
441
|
},
|
|
437
442
|
{
|
|
438
|
-
name:
|
|
439
|
-
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).',
|
|
440
446
|
inputSchema: {
|
|
441
|
-
type:
|
|
447
|
+
type: 'object',
|
|
442
448
|
properties: {
|
|
443
449
|
text: {
|
|
444
|
-
type:
|
|
445
|
-
description:
|
|
450
|
+
type: 'string',
|
|
451
|
+
description: 'The raw output text generated by the model to be aligned.',
|
|
446
452
|
},
|
|
447
453
|
},
|
|
448
|
-
required: [
|
|
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',
|
|
472
|
+
},
|
|
473
|
+
},
|
|
474
|
+
required: ['file', 'content'],
|
|
449
475
|
additionalProperties: false,
|
|
450
476
|
},
|
|
451
477
|
},
|
|
@@ -453,43 +479,42 @@ function handleRequest(req) {
|
|
|
453
479
|
};
|
|
454
480
|
}
|
|
455
481
|
|
|
456
|
-
if (req.method ===
|
|
482
|
+
if (req.method === 'tools/call') {
|
|
457
483
|
const toolName = req.params && req.params.name;
|
|
458
484
|
if (!toolName) {
|
|
459
|
-
throw
|
|
460
|
-
code: -32602,
|
|
461
|
-
message: "Missing required parameter: params.name",
|
|
462
|
-
};
|
|
485
|
+
throw new RpcError(-32602, 'Missing required parameter: params.name');
|
|
463
486
|
}
|
|
464
487
|
|
|
465
|
-
if (toolName ===
|
|
488
|
+
if (toolName === 'run_tribunal_audit') {
|
|
466
489
|
const text = runTribunalAudit();
|
|
467
|
-
return { content: [{ type:
|
|
490
|
+
return { content: [{ type: 'text', text }] };
|
|
468
491
|
}
|
|
469
492
|
|
|
470
|
-
if (toolName ===
|
|
471
|
-
const fs = require(
|
|
493
|
+
if (toolName === 'sync_ide_bridges') {
|
|
494
|
+
const fs = require('fs');
|
|
472
495
|
const cwd = process.cwd();
|
|
473
|
-
const agentDest = path.join(cwd,
|
|
496
|
+
const agentDest = path.join(cwd, '.agent');
|
|
474
497
|
if (!fs.existsSync(agentDest)) {
|
|
475
498
|
return {
|
|
476
499
|
content: [
|
|
477
500
|
{
|
|
478
|
-
type:
|
|
479
|
-
text:
|
|
501
|
+
type: 'text',
|
|
502
|
+
text: 'Error: .agent/ directory not found. Run `tk init` first.',
|
|
480
503
|
},
|
|
481
504
|
],
|
|
482
505
|
};
|
|
483
506
|
}
|
|
484
507
|
try {
|
|
485
|
-
const { generateIDEBridges } = require(path.resolve(__dirname,
|
|
508
|
+
const { generateIDEBridges } = require(path.resolve(__dirname, '../dist/commands/init.js'));
|
|
486
509
|
// generateIDEBridges is async — execute synchronously in MCP context
|
|
487
|
-
generateIDEBridges(cwd, agentDest, true)
|
|
510
|
+
generateIDEBridges(cwd, agentDest, true)
|
|
511
|
+
.then(() => {})
|
|
512
|
+
.catch(() => {});
|
|
488
513
|
return {
|
|
489
514
|
content: [
|
|
490
515
|
{
|
|
491
|
-
type:
|
|
492
|
-
text:
|
|
516
|
+
type: 'text',
|
|
517
|
+
text: 'Sync complete',
|
|
493
518
|
},
|
|
494
519
|
],
|
|
495
520
|
};
|
|
@@ -497,7 +522,7 @@ function handleRequest(req) {
|
|
|
497
522
|
return {
|
|
498
523
|
content: [
|
|
499
524
|
{
|
|
500
|
-
type:
|
|
525
|
+
type: 'text',
|
|
501
526
|
text: `Sync failed: ${e.message}`,
|
|
502
527
|
},
|
|
503
528
|
],
|
|
@@ -505,167 +530,274 @@ function handleRequest(req) {
|
|
|
505
530
|
}
|
|
506
531
|
}
|
|
507
532
|
|
|
508
|
-
if (toolName ===
|
|
509
|
-
const query =
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
throw {
|
|
513
|
-
code: -32602,
|
|
514
|
-
message: "Missing or invalid required argument: query (string)",
|
|
515
|
-
};
|
|
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)');
|
|
516
537
|
}
|
|
517
538
|
const text = searchCaseLaw(query);
|
|
518
|
-
return { content: [{ type:
|
|
539
|
+
return { content: [{ type: 'text', text }] };
|
|
519
540
|
}
|
|
520
541
|
|
|
521
|
-
if (toolName ===
|
|
522
|
-
const fs = require(
|
|
523
|
-
const agentDir = path.join(getAgentDir(),
|
|
524
|
-
if (!fs.existsSync(agentDir))
|
|
525
|
-
|
|
526
|
-
|
|
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- ') }] };
|
|
527
554
|
}
|
|
528
555
|
|
|
529
|
-
if (toolName ===
|
|
530
|
-
const fs = require(
|
|
556
|
+
if (toolName === 'get_tribunal_agent') {
|
|
557
|
+
const fs = require('fs');
|
|
531
558
|
const name = req.params?.arguments?.name;
|
|
532
|
-
if (!name || typeof name !==
|
|
559
|
+
if (!name || typeof name !== 'string')
|
|
560
|
+
throw new RpcError(-32602, 'Missing or invalid argument: name (string)');
|
|
533
561
|
const sanitizedName = path.basename(name);
|
|
534
|
-
const agentsDir = path.resolve(getAgentDir(),
|
|
562
|
+
const agentsDir = path.resolve(getAgentDir(), 'agents');
|
|
535
563
|
const agentPath = path.resolve(agentsDir, `${sanitizedName}.md`);
|
|
536
564
|
// Path containment: ensure resolved path stays within agents directory
|
|
537
|
-
if (!agentPath.startsWith(agentsDir))
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
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) }] };
|
|
541
571
|
}
|
|
542
572
|
|
|
543
|
-
if (toolName ===
|
|
544
|
-
const fs = require(
|
|
545
|
-
const skillsDir = path.join(getAgentDir(),
|
|
546
|
-
if (!fs.existsSync(skillsDir))
|
|
547
|
-
|
|
548
|
-
|
|
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- ') }] };
|
|
549
585
|
}
|
|
550
586
|
|
|
551
|
-
if (toolName ===
|
|
552
|
-
const fs = require(
|
|
587
|
+
if (toolName === 'get_tribunal_skill') {
|
|
588
|
+
const fs = require('fs');
|
|
553
589
|
const name = req.params?.arguments?.name;
|
|
554
|
-
if (!name || typeof name !==
|
|
590
|
+
if (!name || typeof name !== 'string')
|
|
591
|
+
throw new RpcError(-32602, 'Missing or invalid argument: name (string)');
|
|
555
592
|
const sanitizedName = path.basename(name);
|
|
556
|
-
const skillsDir = path.resolve(getAgentDir(),
|
|
557
|
-
const skillPath = path.resolve(skillsDir, sanitizedName,
|
|
593
|
+
const skillsDir = path.resolve(getAgentDir(), 'skills');
|
|
594
|
+
const skillPath = path.resolve(skillsDir, sanitizedName, 'SKILL.md');
|
|
558
595
|
// Path containment: ensure resolved path stays within skills directory
|
|
559
|
-
if (!skillPath.startsWith(skillsDir))
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
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) }] };
|
|
563
602
|
}
|
|
564
603
|
|
|
565
|
-
if (toolName ===
|
|
604
|
+
if (toolName === 'get_sparse_context') {
|
|
566
605
|
const task = req.params?.arguments?.task;
|
|
567
606
|
const files = req.params?.arguments?.files || [];
|
|
568
|
-
const model = req.params?.arguments?.model ||
|
|
607
|
+
const model = req.params?.arguments?.model || 'large';
|
|
569
608
|
|
|
570
|
-
if (!task) throw
|
|
609
|
+
if (!task) throw new RpcError(-32602, 'Missing required argument: task');
|
|
571
610
|
|
|
572
611
|
const agentDest = getAgentDir();
|
|
573
|
-
const fs = require(
|
|
612
|
+
const fs = require('fs');
|
|
574
613
|
if (!fs.existsSync(agentDest)) {
|
|
575
|
-
return {
|
|
614
|
+
return {
|
|
615
|
+
content: [
|
|
616
|
+
{ type: 'text', text: 'Error: .agent/ directory not found. Run `tk init` first.' },
|
|
617
|
+
],
|
|
618
|
+
};
|
|
576
619
|
}
|
|
577
620
|
|
|
578
621
|
try {
|
|
579
|
-
const brokerScript = path.join(agentDest,
|
|
622
|
+
const brokerScript = path.join(agentDest, 'scripts', 'context_broker.js');
|
|
580
623
|
const { broker } = require(brokerScript);
|
|
581
624
|
const brokerResult = broker(task, files, model, agentDest);
|
|
582
|
-
return { content: [{ type:
|
|
625
|
+
return { content: [{ type: 'text', text: stripBoilerplate(brokerResult.promptText) }] };
|
|
583
626
|
} catch (e) {
|
|
584
|
-
return {
|
|
627
|
+
return {
|
|
628
|
+
content: [{ type: 'text', text: `Failed to retrieve sparse context: ${e.message}` }],
|
|
629
|
+
};
|
|
585
630
|
}
|
|
586
631
|
}
|
|
587
632
|
|
|
588
|
-
if (toolName ===
|
|
633
|
+
if (toolName === 'recall_memory') {
|
|
589
634
|
const query = req.params?.arguments?.query;
|
|
590
|
-
if (!query || typeof query !==
|
|
591
|
-
throw
|
|
635
|
+
if (!query || typeof query !== 'string') {
|
|
636
|
+
throw new RpcError(-32602, 'Missing or invalid required argument: query (string)');
|
|
592
637
|
}
|
|
593
638
|
const budget = req.params?.arguments?.budget || 2000;
|
|
594
639
|
const agentDest = getAgentDir();
|
|
595
|
-
const fs = require(
|
|
640
|
+
const fs = require('fs');
|
|
596
641
|
if (!fs.existsSync(agentDest)) {
|
|
597
|
-
return {
|
|
642
|
+
return {
|
|
643
|
+
content: [
|
|
644
|
+
{ type: 'text', text: 'Error: .agent/ directory not found. Run `tk init` first.' },
|
|
645
|
+
],
|
|
646
|
+
};
|
|
598
647
|
}
|
|
599
648
|
try {
|
|
600
|
-
const { _memoryRecall } = require(
|
|
649
|
+
const { _memoryRecall } = require('../dist/commands/memory.js');
|
|
601
650
|
const { results, tokens_used } = _memoryRecall(agentDest, query, budget);
|
|
602
651
|
if (results.length === 0) {
|
|
603
|
-
return { content: [{ type:
|
|
652
|
+
return { content: [{ type: 'text', text: `No memories match query: "${query}"` }] };
|
|
604
653
|
}
|
|
605
654
|
let text = `## Memory Recall (${results.length} results, ~${tokens_used}/${budget} tokens)\n\n`;
|
|
606
655
|
for (const entry of results) {
|
|
607
656
|
text += `- **[${entry.memory_type.toUpperCase()}]** #${entry.id}: ${entry.content}`;
|
|
608
|
-
if (entry.tags.length > 0) text += ` _(${entry.tags.join(
|
|
657
|
+
if (entry.tags.length > 0) text += ` _(${entry.tags.join(', ')})_`;
|
|
609
658
|
text += `\n`;
|
|
610
659
|
}
|
|
611
|
-
return { content: [{ type:
|
|
660
|
+
return { content: [{ type: 'text', text }] };
|
|
612
661
|
} catch (e) {
|
|
613
|
-
return { content: [{ type:
|
|
662
|
+
return { content: [{ type: 'text', text: `Memory recall failed: ${e.message}` }] };
|
|
614
663
|
}
|
|
615
664
|
}
|
|
616
665
|
|
|
617
|
-
if (toolName ===
|
|
666
|
+
if (toolName === 'store_memory') {
|
|
618
667
|
const memType = req.params?.arguments?.type;
|
|
619
668
|
const content = req.params?.arguments?.content;
|
|
620
669
|
const tags = req.params?.arguments?.tags || [];
|
|
621
670
|
if (!memType || !content) {
|
|
622
|
-
throw
|
|
671
|
+
throw new RpcError(-32602, 'Missing required arguments: type (string), content (string)');
|
|
623
672
|
}
|
|
624
|
-
const validTypes = [
|
|
673
|
+
const validTypes = ['semantic', 'procedural', 'episodic', 'working'];
|
|
625
674
|
if (!validTypes.includes(memType)) {
|
|
626
|
-
throw
|
|
675
|
+
throw new RpcError(
|
|
676
|
+
-32602,
|
|
677
|
+
`Invalid memory type: "${memType}". Must be one of: ${validTypes.join(', ')}`,
|
|
678
|
+
);
|
|
627
679
|
}
|
|
628
680
|
const agentDest = getAgentDir();
|
|
629
|
-
const fs = require(
|
|
681
|
+
const fs = require('fs');
|
|
630
682
|
if (!fs.existsSync(agentDest)) {
|
|
631
|
-
return {
|
|
683
|
+
return {
|
|
684
|
+
content: [
|
|
685
|
+
{ type: 'text', text: 'Error: .agent/ directory not found. Run `tk init` first.' },
|
|
686
|
+
],
|
|
687
|
+
};
|
|
632
688
|
}
|
|
633
689
|
try {
|
|
634
|
-
const { _memoryStore } = require(
|
|
690
|
+
const { _memoryStore } = require('../dist/commands/memory.js');
|
|
635
691
|
const result = _memoryStore(agentDest, memType, content, tags, null);
|
|
636
|
-
return {
|
|
692
|
+
return {
|
|
693
|
+
content: [
|
|
694
|
+
{
|
|
695
|
+
type: 'text',
|
|
696
|
+
text: `Memory stored: #${result.id} (${memType}, ~${result.token_estimate} tokens)`,
|
|
697
|
+
},
|
|
698
|
+
],
|
|
699
|
+
};
|
|
637
700
|
} catch (e) {
|
|
638
|
-
return { content: [{ type:
|
|
701
|
+
return { content: [{ type: 'text', text: `Memory store failed: ${e.message}` }] };
|
|
639
702
|
}
|
|
640
703
|
}
|
|
641
704
|
|
|
642
|
-
if (toolName ===
|
|
705
|
+
if (toolName === 'align_output') {
|
|
643
706
|
const text = req.params?.arguments?.text;
|
|
644
|
-
if (typeof text !==
|
|
645
|
-
throw
|
|
707
|
+
if (typeof text !== 'string') {
|
|
708
|
+
throw new RpcError(-32602, 'Missing or invalid required argument: text (string)');
|
|
646
709
|
}
|
|
647
710
|
try {
|
|
648
|
-
const { alignText, validateCodeContent } = require(
|
|
711
|
+
const { alignText, validateCodeContent } = require('../dist/commands/align.js');
|
|
649
712
|
const aligned = alignText(text);
|
|
650
713
|
const warnings = validateCodeContent(aligned);
|
|
651
|
-
|
|
714
|
+
|
|
652
715
|
let outputText = aligned;
|
|
653
716
|
if (warnings.length > 0) {
|
|
654
|
-
outputText +=
|
|
717
|
+
outputText += '\n\n⚠️ OCAE Alignment Validator Warnings:\n';
|
|
655
718
|
for (const warnMsg of warnings) {
|
|
656
719
|
outputText += `● ${warnMsg}\n`;
|
|
657
720
|
}
|
|
658
721
|
}
|
|
659
|
-
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 }] };
|
|
660
792
|
} catch (e) {
|
|
661
|
-
return { content: [{ type:
|
|
793
|
+
return { content: [{ type: 'text', text: `Contract verification failed: ${e.message}` }] };
|
|
662
794
|
}
|
|
663
795
|
}
|
|
664
796
|
|
|
665
|
-
throw
|
|
797
|
+
throw new RpcError(-32601, `Unknown tool: ${toolName}`);
|
|
666
798
|
}
|
|
667
799
|
|
|
668
|
-
throw
|
|
800
|
+
throw new RpcError(-32601, `Unknown method: ${req.method}`);
|
|
669
801
|
}
|
|
670
802
|
|
|
671
803
|
function processSingleRequest(req) {
|
|
@@ -675,31 +807,32 @@ function processSingleRequest(req) {
|
|
|
675
807
|
if (req.id === undefined || req.id === null) {
|
|
676
808
|
return null;
|
|
677
809
|
}
|
|
678
|
-
return { jsonrpc:
|
|
810
|
+
return { jsonrpc: '2.0', id: req.id, result };
|
|
679
811
|
} catch (e) {
|
|
680
|
-
const code = e && typeof e.code ===
|
|
681
|
-
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';
|
|
682
814
|
if (req.id === undefined || req.id === null) {
|
|
683
815
|
return {
|
|
684
|
-
jsonrpc:
|
|
816
|
+
jsonrpc: '2.0',
|
|
685
817
|
id: null,
|
|
686
818
|
error: { code, message },
|
|
687
819
|
};
|
|
688
820
|
}
|
|
689
821
|
return {
|
|
690
|
-
jsonrpc:
|
|
822
|
+
jsonrpc: '2.0',
|
|
691
823
|
id: req.id,
|
|
692
824
|
error: { code, message },
|
|
693
825
|
};
|
|
694
826
|
}
|
|
695
827
|
}
|
|
696
828
|
|
|
697
|
-
rl.on(
|
|
698
|
-
if (line.length > 1048576) {
|
|
829
|
+
rl.on('line', line => {
|
|
830
|
+
if (line.length > 1048576) {
|
|
831
|
+
// 1MB limit
|
|
699
832
|
const errorRes = {
|
|
700
|
-
jsonrpc:
|
|
833
|
+
jsonrpc: '2.0',
|
|
701
834
|
id: null,
|
|
702
|
-
error: { code: -32700, message:
|
|
835
|
+
error: { code: -32700, message: 'Parse error: input line too long (exceeds 1MB limit)' },
|
|
703
836
|
};
|
|
704
837
|
console.log(JSON.stringify(errorRes));
|
|
705
838
|
return;
|
|
@@ -712,9 +845,9 @@ rl.on("line", (line) => {
|
|
|
712
845
|
} catch (parseErr) {
|
|
713
846
|
// Invalid JSON — send a parse error
|
|
714
847
|
const errorRes = {
|
|
715
|
-
jsonrpc:
|
|
848
|
+
jsonrpc: '2.0',
|
|
716
849
|
id: null,
|
|
717
|
-
error: { code: -32700, message:
|
|
850
|
+
error: { code: -32700, message: 'Parse error: ' + parseErr.message },
|
|
718
851
|
};
|
|
719
852
|
console.log(JSON.stringify(errorRes));
|
|
720
853
|
return;
|
|
@@ -739,7 +872,7 @@ rl.on("line", (line) => {
|
|
|
739
872
|
}
|
|
740
873
|
});
|
|
741
874
|
|
|
742
|
-
if (process.env.NODE_ENV ===
|
|
875
|
+
if (process.env.NODE_ENV === 'test') {
|
|
743
876
|
module.exports = {
|
|
744
877
|
handleRequest,
|
|
745
878
|
stripBoilerplate,
|