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
|
@@ -6,61 +6,50 @@
|
|
|
6
6
|
* Now includes Blast Radius calculation and robust token stripping.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const fs = require(
|
|
12
|
-
const path = require(
|
|
13
|
-
const crypto = require(
|
|
14
|
-
|
|
15
|
-
const {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
RESET,
|
|
22
|
-
timer,
|
|
23
|
-
formatMs,
|
|
24
|
-
} = require("./_colors");
|
|
25
|
-
|
|
26
|
-
const AGENT_DIR = path.join(process.cwd(), ".agent");
|
|
27
|
-
const HISTORY_DIR = path.join(AGENT_DIR, "history");
|
|
28
|
-
const CACHE_FILE = path.join(HISTORY_DIR, "graph-cache.json");
|
|
29
|
-
const GRAPH_FILE = path.join(HISTORY_DIR, "architecture-graph.yaml");
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const fs = require('fs');
|
|
12
|
+
const path = require('path');
|
|
13
|
+
const crypto = require('crypto');
|
|
14
|
+
|
|
15
|
+
const { RED, GREEN, BOLD, DIM, CYAN, RESET, timer, formatMs } = require('./_colors');
|
|
16
|
+
|
|
17
|
+
const AGENT_DIR = path.join(process.cwd(), '.agent');
|
|
18
|
+
const HISTORY_DIR = path.join(AGENT_DIR, 'history');
|
|
19
|
+
const CACHE_FILE = path.join(HISTORY_DIR, 'graph-cache.json');
|
|
20
|
+
const GRAPH_FILE = path.join(HISTORY_DIR, 'architecture-graph.yaml');
|
|
30
21
|
|
|
31
22
|
// ── Exclusions & Safety ───────────────────────────────────────────────────────
|
|
32
23
|
const DEFAULT_EXCLUSIONS = new Set([
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
24
|
+
'node_modules',
|
|
25
|
+
'.git',
|
|
26
|
+
'.next',
|
|
27
|
+
'dist',
|
|
28
|
+
'build',
|
|
29
|
+
'coverage',
|
|
30
|
+
'.agent',
|
|
31
|
+
'artifacts',
|
|
41
32
|
]);
|
|
42
33
|
|
|
43
34
|
function loadGitIgnore() {
|
|
44
|
-
const gitignorePath = path.join(process.cwd(),
|
|
35
|
+
const gitignorePath = path.join(process.cwd(), '.gitignore');
|
|
45
36
|
if (!fs.existsSync(gitignorePath)) return [];
|
|
46
37
|
|
|
47
38
|
return fs
|
|
48
|
-
.readFileSync(gitignorePath,
|
|
49
|
-
.split(
|
|
50
|
-
.map(
|
|
51
|
-
.filter(
|
|
52
|
-
.map(
|
|
39
|
+
.readFileSync(gitignorePath, 'utf8')
|
|
40
|
+
.split('\n')
|
|
41
|
+
.map(line => line.trim())
|
|
42
|
+
.filter(line => line && !line.startsWith('#'))
|
|
43
|
+
.map(line => line.replace(/\/$/, '').replace(/^\//, ''));
|
|
53
44
|
}
|
|
54
45
|
|
|
55
46
|
const customExclusions = loadGitIgnore();
|
|
56
47
|
|
|
57
48
|
function isExcluded(filePath) {
|
|
58
49
|
const parts = filePath.split(path.sep);
|
|
59
|
-
if (parts.some(
|
|
50
|
+
if (parts.some(p => DEFAULT_EXCLUSIONS.has(p))) return true;
|
|
60
51
|
|
|
61
|
-
const relativePath = path
|
|
62
|
-
.relative(process.cwd(), filePath)
|
|
63
|
-
.replace(/\\/g, "/");
|
|
52
|
+
const relativePath = path.relative(process.cwd(), filePath).replace(/\\/g, '/');
|
|
64
53
|
for (const pattern of customExclusions) {
|
|
65
54
|
if (relativePath.includes(pattern)) return true;
|
|
66
55
|
}
|
|
@@ -70,7 +59,7 @@ function isExcluded(filePath) {
|
|
|
70
59
|
// ── Content Hashing ───────────────────────────────────────────────────────────
|
|
71
60
|
function getFileHash(filePath) {
|
|
72
61
|
const content = fs.readFileSync(filePath);
|
|
73
|
-
return crypto.createHash(
|
|
62
|
+
return crypto.createHash('sha1').update(content).digest('hex');
|
|
74
63
|
}
|
|
75
64
|
|
|
76
65
|
// ── Traversal ─────────────────────────────────────────────────────────────────
|
|
@@ -119,38 +108,27 @@ function parseFile(content) {
|
|
|
119
108
|
|
|
120
109
|
// I'll define an inner function to just strip comments to be safe for imports.
|
|
121
110
|
// Let's stick to the simple `.replace` for comments for now, and rely on regex boundaries.
|
|
122
|
-
const semiCleanContent = content
|
|
123
|
-
.replace(/\/\*[\s\S]*?\*\//g, "")
|
|
124
|
-
.replace(/\/\/.*$/gm, "");
|
|
111
|
+
const semiCleanContent = content.replace(/\/\*[\s\S]*?\*\//g, '').replace(/\/\/.*$/gm, '');
|
|
125
112
|
|
|
126
|
-
const importRegex2 =
|
|
127
|
-
/^[\s]*import(?:(?:[\w*\s{},]*)\sfrom\s+)?['"]([^'"]+)['"]/gm;
|
|
113
|
+
const importRegex2 = /^[\s]*import(?:(?:[\w*\s{},]*)\sfrom\s+)?['"]([^'"]+)['"]/gm;
|
|
128
114
|
const requireRegex = /require\(['"]([^'"]+)['"]\)/g;
|
|
129
115
|
const dynamicImportRegex = /import\(['"]([^'"]+)['"]\)/g;
|
|
130
116
|
|
|
131
|
-
const exportRegex =
|
|
132
|
-
/^[\s]*export\s+(?:const|let|var|function|class)\s+([a-zA-Z0-9_]+)/gm;
|
|
117
|
+
const exportRegex = /^[\s]*export\s+(?:const|let|var|function|class)\s+([a-zA-Z0-9_]+)/gm;
|
|
133
118
|
const moduleExportRegex = /module\.exports\s*=\s*\{([^}]+)\}/g;
|
|
134
119
|
const defaultExportRegex = /^[\s]*export\s+default\s+([a-zA-Z0-9_]+)/gm;
|
|
135
120
|
|
|
136
121
|
let match;
|
|
137
|
-
while ((match = importRegex2.exec(semiCleanContent)) !== null)
|
|
138
|
-
|
|
139
|
-
while ((match =
|
|
140
|
-
|
|
141
|
-
while ((match =
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
while ((match = exportRegex.exec(semiCleanContent)) !== null)
|
|
145
|
-
exports.add(match[1]);
|
|
146
|
-
while ((match = defaultExportRegex.exec(semiCleanContent)) !== null)
|
|
147
|
-
exports.add(match[1]);
|
|
122
|
+
while ((match = importRegex2.exec(semiCleanContent)) !== null) imports.add(match[1]);
|
|
123
|
+
while ((match = requireRegex.exec(semiCleanContent)) !== null) imports.add(match[1]);
|
|
124
|
+
while ((match = dynamicImportRegex.exec(semiCleanContent)) !== null) imports.add(match[1]);
|
|
125
|
+
|
|
126
|
+
while ((match = exportRegex.exec(semiCleanContent)) !== null) exports.add(match[1]);
|
|
127
|
+
while ((match = defaultExportRegex.exec(semiCleanContent)) !== null) exports.add(match[1]);
|
|
148
128
|
|
|
149
129
|
while ((match = moduleExportRegex.exec(semiCleanContent)) !== null) {
|
|
150
|
-
const tokens = match[1]
|
|
151
|
-
|
|
152
|
-
.map((s) => s.trim().split(":")[0].trim());
|
|
153
|
-
tokens.forEach((t) => t && exports.add(t));
|
|
130
|
+
const tokens = match[1].split(',').map(s => s.trim().split(':')[0].trim());
|
|
131
|
+
tokens.forEach(t => t && exports.add(t));
|
|
154
132
|
}
|
|
155
133
|
|
|
156
134
|
return {
|
|
@@ -161,8 +139,8 @@ function parseFile(content) {
|
|
|
161
139
|
|
|
162
140
|
// ── YAML Generation ───────────────────────────────────────────────────────────
|
|
163
141
|
function generateYAML(data) {
|
|
164
|
-
let yaml =
|
|
165
|
-
yaml +=
|
|
142
|
+
let yaml = '# Auto-generated Architecture Graph by Tribunal Kit\n';
|
|
143
|
+
yaml += '# DO NOT EDIT MANUALLY - Auto-updates via incremental cache\n\n';
|
|
166
144
|
|
|
167
145
|
for (const [file, info] of Object.entries(data)) {
|
|
168
146
|
if (
|
|
@@ -173,20 +151,20 @@ function generateYAML(data) {
|
|
|
173
151
|
continue;
|
|
174
152
|
|
|
175
153
|
yaml += `"${file}":\n`;
|
|
176
|
-
yaml += ` riskScore: "${info.riskScore ||
|
|
154
|
+
yaml += ` riskScore: "${info.riskScore || 'Low'}"\n`;
|
|
177
155
|
yaml += ` blastRadius: ${info.blastRadius || 0}\n`;
|
|
178
156
|
|
|
179
157
|
if (info.imports && info.imports.length > 0) {
|
|
180
158
|
yaml += ` imports:\n`;
|
|
181
|
-
info.imports.forEach(
|
|
159
|
+
info.imports.forEach(i => (yaml += ` - "${i}"\n`));
|
|
182
160
|
}
|
|
183
161
|
if (info.exports && info.exports.length > 0) {
|
|
184
162
|
yaml += ` exports:\n`;
|
|
185
|
-
info.exports.forEach(
|
|
163
|
+
info.exports.forEach(e => (yaml += ` - "${e}"\n`));
|
|
186
164
|
}
|
|
187
165
|
if (info.dependents && info.dependents.length > 0) {
|
|
188
166
|
yaml += ` dependents:\n`;
|
|
189
|
-
info.dependents.forEach(
|
|
167
|
+
info.dependents.forEach(d => (yaml += ` - "${d}"\n`));
|
|
190
168
|
}
|
|
191
169
|
}
|
|
192
170
|
return yaml;
|
|
@@ -199,13 +177,12 @@ function main() {
|
|
|
199
177
|
process.exit(1);
|
|
200
178
|
}
|
|
201
179
|
|
|
202
|
-
if (!fs.existsSync(HISTORY_DIR))
|
|
203
|
-
fs.mkdirSync(HISTORY_DIR, { recursive: true });
|
|
180
|
+
if (!fs.existsSync(HISTORY_DIR)) fs.mkdirSync(HISTORY_DIR, { recursive: true });
|
|
204
181
|
|
|
205
182
|
let cache = {};
|
|
206
183
|
if (fs.existsSync(CACHE_FILE)) {
|
|
207
184
|
try {
|
|
208
|
-
cache = JSON.parse(fs.readFileSync(CACHE_FILE,
|
|
185
|
+
cache = JSON.parse(fs.readFileSync(CACHE_FILE, 'utf8'));
|
|
209
186
|
} catch {
|
|
210
187
|
/* ignore */
|
|
211
188
|
}
|
|
@@ -221,7 +198,7 @@ function main() {
|
|
|
221
198
|
const changedFiles = new Set();
|
|
222
199
|
|
|
223
200
|
for (const file of files) {
|
|
224
|
-
const relativePath = path.relative(process.cwd(), file).replace(/\\/g,
|
|
201
|
+
const relativePath = path.relative(process.cwd(), file).replace(/\\/g, '/');
|
|
225
202
|
let fileHash;
|
|
226
203
|
try {
|
|
227
204
|
fileHash = getFileHash(file);
|
|
@@ -237,7 +214,7 @@ function main() {
|
|
|
237
214
|
cachedCount++;
|
|
238
215
|
} else {
|
|
239
216
|
try {
|
|
240
|
-
const content = fs.readFileSync(file,
|
|
217
|
+
const content = fs.readFileSync(file, 'utf8');
|
|
241
218
|
const parsed = parseFile(content);
|
|
242
219
|
graphData[relativePath] = parsed;
|
|
243
220
|
|
|
@@ -260,15 +237,15 @@ function main() {
|
|
|
260
237
|
const fileKeys = Object.keys(graphData);
|
|
261
238
|
for (const [file, info] of Object.entries(graphData)) {
|
|
262
239
|
for (const imp of info.imports) {
|
|
263
|
-
if (imp.startsWith(
|
|
264
|
-
|
|
240
|
+
if (imp.startsWith('.')) {
|
|
241
|
+
const resolved = path.posix.join(path.dirname(file), imp);
|
|
265
242
|
// Look for direct match or .js / index.js
|
|
266
|
-
|
|
267
|
-
|
|
243
|
+
const matchingKey = fileKeys.find(
|
|
244
|
+
k =>
|
|
268
245
|
k === resolved ||
|
|
269
|
-
k === resolved +
|
|
270
|
-
k === resolved +
|
|
271
|
-
k === resolved +
|
|
246
|
+
k === resolved + '.js' ||
|
|
247
|
+
k === resolved + '.ts' ||
|
|
248
|
+
k === resolved + '/index.js',
|
|
272
249
|
);
|
|
273
250
|
if (matchingKey) {
|
|
274
251
|
if (!graphData[matchingKey].dependents.includes(file)) {
|
|
@@ -290,10 +267,10 @@ function main() {
|
|
|
290
267
|
}
|
|
291
268
|
visit(file);
|
|
292
269
|
const radius = visited.size - 1;
|
|
293
|
-
let score =
|
|
294
|
-
if (radius > 10) score =
|
|
295
|
-
else if (radius >= 5) score =
|
|
296
|
-
else if (radius >= 2) score =
|
|
270
|
+
let score = 'Low';
|
|
271
|
+
if (radius > 10) score = 'Critical';
|
|
272
|
+
else if (radius >= 5) score = 'High';
|
|
273
|
+
else if (radius >= 2) score = 'Medium';
|
|
297
274
|
return { score, count: Math.max(0, radius) };
|
|
298
275
|
}
|
|
299
276
|
|
|
@@ -314,7 +291,7 @@ function main() {
|
|
|
314
291
|
fs.writeFileSync(GRAPH_FILE, generateYAML(graphData));
|
|
315
292
|
|
|
316
293
|
// ── Pre-Computed Context Snapshots (Incremental) ─────────────────────────
|
|
317
|
-
const SNAPSHOTS_DIR = path.join(HISTORY_DIR,
|
|
294
|
+
const SNAPSHOTS_DIR = path.join(HISTORY_DIR, 'snapshots');
|
|
318
295
|
if (!fs.existsSync(SNAPSHOTS_DIR)) {
|
|
319
296
|
fs.mkdirSync(SNAPSHOTS_DIR, { recursive: true });
|
|
320
297
|
}
|
|
@@ -322,12 +299,9 @@ function main() {
|
|
|
322
299
|
// Clean up snapshots for files that no longer exist
|
|
323
300
|
try {
|
|
324
301
|
const existingSnapshots = fs.readdirSync(SNAPSHOTS_DIR);
|
|
325
|
-
const currentFileSet = new Set(
|
|
326
|
-
fileKeys.map((f) => f.replace(/[\\/]/g, "__") + ".json"),
|
|
327
|
-
);
|
|
302
|
+
const currentFileSet = new Set(fileKeys.map(f => f.replace(/[\\/]/g, '__') + '.json'));
|
|
328
303
|
for (const snap of existingSnapshots) {
|
|
329
|
-
if (!currentFileSet.has(snap))
|
|
330
|
-
fs.unlinkSync(path.join(SNAPSHOTS_DIR, snap));
|
|
304
|
+
if (!currentFileSet.has(snap)) fs.unlinkSync(path.join(SNAPSHOTS_DIR, snap));
|
|
331
305
|
}
|
|
332
306
|
} catch {
|
|
333
307
|
/* ignore */
|
|
@@ -338,7 +312,7 @@ function main() {
|
|
|
338
312
|
let snapshotSkipped = 0;
|
|
339
313
|
for (const file of fileKeys) {
|
|
340
314
|
const info = graphData[file];
|
|
341
|
-
const snapshotFile = file.replace(/[\\/]/g,
|
|
315
|
+
const snapshotFile = file.replace(/[\\/]/g, '__') + '.json';
|
|
342
316
|
const snapshotPath = path.join(SNAPSHOTS_DIR, snapshotFile);
|
|
343
317
|
|
|
344
318
|
// Skip unchanged files that already have a snapshot
|
|
@@ -347,9 +321,9 @@ function main() {
|
|
|
347
321
|
continue;
|
|
348
322
|
}
|
|
349
323
|
|
|
350
|
-
let content =
|
|
324
|
+
let content = '';
|
|
351
325
|
try {
|
|
352
|
-
content = fs.readFileSync(path.join(process.cwd(), file),
|
|
326
|
+
content = fs.readFileSync(path.join(process.cwd(), file), 'utf8');
|
|
353
327
|
} catch {
|
|
354
328
|
continue;
|
|
355
329
|
}
|
|
@@ -364,14 +338,14 @@ function main() {
|
|
|
364
338
|
};
|
|
365
339
|
|
|
366
340
|
for (const imp of info.imports) {
|
|
367
|
-
if (imp.startsWith(
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
341
|
+
if (imp.startsWith('.')) {
|
|
342
|
+
const resolved = path.posix.join(path.dirname(file), imp);
|
|
343
|
+
const matchingKey = fileKeys.find(
|
|
344
|
+
k =>
|
|
371
345
|
k === resolved ||
|
|
372
|
-
k === resolved +
|
|
373
|
-
k === resolved +
|
|
374
|
-
k === resolved +
|
|
346
|
+
k === resolved + '.js' ||
|
|
347
|
+
k === resolved + '.ts' ||
|
|
348
|
+
k === resolved + '/index.js',
|
|
375
349
|
);
|
|
376
350
|
if (matchingKey && graphData[matchingKey]) {
|
|
377
351
|
snapshot.imports[imp] = graphData[matchingKey].exports;
|
|
@@ -386,9 +360,7 @@ function main() {
|
|
|
386
360
|
fs.writeFileSync(snapshotPath, JSON.stringify(snapshot, null, 2));
|
|
387
361
|
snapshotWritten++;
|
|
388
362
|
}
|
|
389
|
-
console.log(
|
|
390
|
-
` ${DIM}Snapshots: ${snapshotWritten} written | ${snapshotSkipped} cached${RESET}`,
|
|
391
|
-
);
|
|
363
|
+
console.log(` ${DIM}Snapshots: ${snapshotWritten} written | ${snapshotSkipped} cached${RESET}`);
|
|
392
364
|
|
|
393
365
|
const totalMs = totalTimer();
|
|
394
366
|
console.log(`\n${GREEN}${BOLD}✔ Graph successfully built.${RESET}`);
|
|
@@ -5,27 +5,25 @@
|
|
|
5
5
|
* Uses a native zero-dependency Canvas force-directed graph.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
'use strict';
|
|
9
9
|
|
|
10
|
-
const fs = require(
|
|
11
|
-
const path = require(
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
const path = require('path');
|
|
12
12
|
|
|
13
|
-
const { RED, GREEN, DIM, RESET } = require(
|
|
13
|
+
const { RED, GREEN, DIM, RESET } = require('./_colors');
|
|
14
14
|
|
|
15
|
-
const AGENT_DIR = path.join(process.cwd(),
|
|
16
|
-
const HISTORY_DIR = path.join(AGENT_DIR,
|
|
17
|
-
const CACHE_FILE = path.join(HISTORY_DIR,
|
|
18
|
-
const HTML_FILE = path.join(HISTORY_DIR,
|
|
15
|
+
const AGENT_DIR = path.join(process.cwd(), '.agent');
|
|
16
|
+
const HISTORY_DIR = path.join(AGENT_DIR, 'history');
|
|
17
|
+
const CACHE_FILE = path.join(HISTORY_DIR, 'graph-cache.json');
|
|
18
|
+
const HTML_FILE = path.join(HISTORY_DIR, 'architecture-explorer.html');
|
|
19
19
|
|
|
20
20
|
function main() {
|
|
21
21
|
if (!fs.existsSync(CACHE_FILE)) {
|
|
22
|
-
console.error(
|
|
23
|
-
`${RED}✖ Error: graph-cache.json not found. Run graph_builder.js first.${RESET}`,
|
|
24
|
-
);
|
|
22
|
+
console.error(`${RED}✖ Error: graph-cache.json not found. Run graph_builder.js first.${RESET}`);
|
|
25
23
|
process.exit(1);
|
|
26
24
|
}
|
|
27
25
|
|
|
28
|
-
const cacheData = fs.readFileSync(CACHE_FILE,
|
|
26
|
+
const cacheData = fs.readFileSync(CACHE_FILE, 'utf8');
|
|
29
27
|
|
|
30
28
|
const htmlContent = `<!DOCTYPE html>
|
|
31
29
|
<html lang="en">
|
|
@@ -5,19 +5,19 @@
|
|
|
5
5
|
* stripping out internal logic to save tokens and prevent context bloat.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
'use strict';
|
|
9
9
|
|
|
10
|
-
const fs = require(
|
|
11
|
-
const path = require(
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
const path = require('path');
|
|
12
12
|
|
|
13
|
-
const { RED, CYAN, RESET } = require(
|
|
13
|
+
const { RED, CYAN, RESET } = require('./_colors');
|
|
14
14
|
|
|
15
15
|
function getFlag(name) {
|
|
16
16
|
const idx = process.argv.indexOf(name);
|
|
17
17
|
return idx !== -1 && process.argv[idx + 1] ? process.argv[idx + 1] : null;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
const targetFile = getFlag(
|
|
20
|
+
const targetFile = getFlag('--focus');
|
|
21
21
|
|
|
22
22
|
if (!targetFile) {
|
|
23
23
|
console.error(
|
|
@@ -34,7 +34,7 @@ if (!fs.existsSync(absolutePath)) {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
function extractSkeleton(content) {
|
|
37
|
-
const lines = content.split(
|
|
37
|
+
const lines = content.split('\n');
|
|
38
38
|
const skeleton = [];
|
|
39
39
|
|
|
40
40
|
// State machine flags
|
|
@@ -44,15 +44,12 @@ function extractSkeleton(content) {
|
|
|
44
44
|
// ── Regex Matchers ──
|
|
45
45
|
const importRegex = /^import\s+.*$/;
|
|
46
46
|
const requireRegex = /^(?:const|let|var)\s+.*require\(.*$/;
|
|
47
|
-
const classRegex =
|
|
48
|
-
|
|
49
|
-
const functionRegex =
|
|
50
|
-
/^(?:export\s+)?(?:default\s+)?(?:async\s+)?function\s+(\w*)\s*\(([^)]*)\)/;
|
|
47
|
+
const classRegex = /^(?:export\s+)?(?:default\s+)?class\s+(\w+)(?:\s+extends\s+[\w.]+)?/;
|
|
48
|
+
const functionRegex = /^(?:export\s+)?(?:default\s+)?(?:async\s+)?function\s+(\w*)\s*\(([^)]*)\)/;
|
|
51
49
|
const arrowFuncRegex =
|
|
52
50
|
/^(?:export\s+)?(?:const|let|var)\s+(\w+)\s*=\s*(?:async\s+)?\(([^)]*)\)\s*=>/;
|
|
53
51
|
// Heuristic for React Components (starts with Capital letter)
|
|
54
|
-
const reactComponentRegex =
|
|
55
|
-
/^(?:export\s+)?(?:const|let|var)\s+([A-Z]\w+)\s*=\s*(?:[^=;]+)?=>/;
|
|
52
|
+
const reactComponentRegex = /^(?:export\s+)?(?:const|let|var)\s+([A-Z]\w+)\s*=\s*(?:[^=;]+)?=>/;
|
|
56
53
|
const typeInterfaceRegex = /^(?:export\s+)?(?:type|interface)\s+(\w+)/;
|
|
57
54
|
|
|
58
55
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -69,18 +66,16 @@ function extractSkeleton(content) {
|
|
|
69
66
|
|
|
70
67
|
// Keep types and interfaces
|
|
71
68
|
if (typeInterfaceRegex.test(trimmed)) {
|
|
72
|
-
skeleton.push(line + (trimmed.endsWith(
|
|
69
|
+
skeleton.push(line + (trimmed.endsWith('{') ? ' /* ... */ }' : ''));
|
|
73
70
|
continue;
|
|
74
71
|
}
|
|
75
72
|
|
|
76
73
|
// Keep classes
|
|
77
74
|
const classMatch = classRegex.exec(trimmed);
|
|
78
75
|
if (classMatch) {
|
|
79
|
-
skeleton.push(
|
|
76
|
+
skeleton.push('\n' + line + (trimmed.endsWith('{') ? '' : ' {'));
|
|
80
77
|
inClass = true;
|
|
81
|
-
braceDepth =
|
|
82
|
-
(trimmed.match(/\{/g) || []).length -
|
|
83
|
-
(trimmed.match(/\}/g) || []).length;
|
|
78
|
+
braceDepth = (trimmed.match(/\{/g) || []).length - (trimmed.match(/\}/g) || []).length;
|
|
84
79
|
continue;
|
|
85
80
|
}
|
|
86
81
|
|
|
@@ -88,11 +83,9 @@ function extractSkeleton(content) {
|
|
|
88
83
|
const funcMatch = functionRegex.exec(trimmed);
|
|
89
84
|
if (funcMatch) {
|
|
90
85
|
skeleton.push(
|
|
91
|
-
|
|
86
|
+
'\n' +
|
|
92
87
|
line +
|
|
93
|
-
(trimmed.endsWith(
|
|
94
|
-
? " /* logic stripped */ }"
|
|
95
|
-
: " { /* logic stripped */ }"),
|
|
88
|
+
(trimmed.endsWith('{') ? ' /* logic stripped */ }' : ' { /* logic stripped */ }'),
|
|
96
89
|
);
|
|
97
90
|
continue;
|
|
98
91
|
}
|
|
@@ -101,11 +94,9 @@ function extractSkeleton(content) {
|
|
|
101
94
|
const arrowMatch = arrowFuncRegex.exec(trimmed);
|
|
102
95
|
if (arrowMatch) {
|
|
103
96
|
skeleton.push(
|
|
104
|
-
|
|
97
|
+
'\n' +
|
|
105
98
|
line +
|
|
106
|
-
(trimmed.endsWith(
|
|
107
|
-
? " /* logic stripped */ }"
|
|
108
|
-
: " { /* logic stripped */ }"),
|
|
99
|
+
(trimmed.endsWith('{') ? ' /* logic stripped */ }' : ' { /* logic stripped */ }'),
|
|
109
100
|
);
|
|
110
101
|
continue;
|
|
111
102
|
}
|
|
@@ -114,11 +105,9 @@ function extractSkeleton(content) {
|
|
|
114
105
|
const reactMatch = reactComponentRegex.exec(trimmed);
|
|
115
106
|
if (reactMatch && !arrowMatch) {
|
|
116
107
|
skeleton.push(
|
|
117
|
-
|
|
108
|
+
'\n' +
|
|
118
109
|
line +
|
|
119
|
-
(trimmed.endsWith(
|
|
120
|
-
? " /* logic stripped */ }"
|
|
121
|
-
: " { /* logic stripped */ }"),
|
|
110
|
+
(trimmed.endsWith('{') ? ' /* logic stripped */ }' : ' { /* logic stripped */ }'),
|
|
122
111
|
);
|
|
123
112
|
continue;
|
|
124
113
|
}
|
|
@@ -126,18 +115,18 @@ function extractSkeleton(content) {
|
|
|
126
115
|
// Very basic tracking of class methods (indentation heuristic)
|
|
127
116
|
if (
|
|
128
117
|
inClass &&
|
|
129
|
-
(line.startsWith(
|
|
130
|
-
trimmed.includes(
|
|
131
|
-
trimmed.includes(
|
|
132
|
-
!trimmed.startsWith(
|
|
118
|
+
(line.startsWith(' ') || line.startsWith('\t')) &&
|
|
119
|
+
trimmed.includes('(') &&
|
|
120
|
+
trimmed.includes(')') &&
|
|
121
|
+
!trimmed.startsWith('//')
|
|
133
122
|
) {
|
|
134
123
|
// Avoid pushing if it's just a deeply nested logic block
|
|
135
124
|
if (
|
|
136
|
-
!trimmed.startsWith(
|
|
137
|
-
!trimmed.startsWith(
|
|
138
|
-
!trimmed.startsWith(
|
|
125
|
+
!trimmed.startsWith('if') &&
|
|
126
|
+
!trimmed.startsWith('for') &&
|
|
127
|
+
!trimmed.startsWith('switch')
|
|
139
128
|
) {
|
|
140
|
-
skeleton.push(
|
|
129
|
+
skeleton.push(' ' + trimmed + ' { /* ... */ }');
|
|
141
130
|
}
|
|
142
131
|
}
|
|
143
132
|
|
|
@@ -146,52 +135,46 @@ function extractSkeleton(content) {
|
|
|
146
135
|
braceDepth += (line.match(/\{/g) || []).length;
|
|
147
136
|
braceDepth -= (line.match(/\}/g) || []).length;
|
|
148
137
|
if (braceDepth <= 0) {
|
|
149
|
-
skeleton.push(
|
|
138
|
+
skeleton.push('}\n');
|
|
150
139
|
inClass = false;
|
|
151
140
|
braceDepth = 0;
|
|
152
141
|
}
|
|
153
142
|
}
|
|
154
143
|
}
|
|
155
144
|
|
|
156
|
-
return skeleton.join(
|
|
145
|
+
return skeleton.join('\n');
|
|
157
146
|
}
|
|
158
147
|
|
|
159
148
|
function main() {
|
|
160
149
|
console.log(`${CYAN}✦ Zooming into: ${targetFile}${RESET}`);
|
|
161
150
|
|
|
162
151
|
try {
|
|
163
|
-
const content = fs.readFileSync(absolutePath,
|
|
152
|
+
const content = fs.readFileSync(absolutePath, 'utf8');
|
|
164
153
|
|
|
165
154
|
// Strip comments to make regex parsing easier
|
|
166
|
-
const noComments = content
|
|
167
|
-
.replace(/\/\*[\s\S]*?\*\//g, "")
|
|
168
|
-
.replace(/\/\/.*$/gm, "");
|
|
155
|
+
const noComments = content.replace(/\/\*[\s\S]*?\*\//g, '').replace(/\/\/.*$/gm, '');
|
|
169
156
|
|
|
170
157
|
let skeleton = extractSkeleton(noComments);
|
|
171
158
|
|
|
172
159
|
// Fallback Logic: If the file produced practically no useful skeleton (e.g. pure data object or failed parsing)
|
|
173
160
|
if (skeleton.trim().length < 20) {
|
|
174
|
-
const lines = content.split(
|
|
161
|
+
const lines = content.split('\n');
|
|
175
162
|
skeleton =
|
|
176
163
|
`// [WARNING: Parser yielded little structure. Falling back to truncated raw file]\n` +
|
|
177
|
-
lines.slice(0, 100).join(
|
|
178
|
-
(lines.length > 100 ?
|
|
164
|
+
lines.slice(0, 100).join('\n') +
|
|
165
|
+
(lines.length > 100 ? '\n\n... (truncated)' : '');
|
|
179
166
|
}
|
|
180
167
|
|
|
181
|
-
console.log(
|
|
168
|
+
console.log('\n--- SKELETON START ---');
|
|
182
169
|
console.log(skeleton);
|
|
183
|
-
console.log(
|
|
170
|
+
console.log('--- SKELETON END ---\n');
|
|
184
171
|
} catch (e) {
|
|
185
172
|
console.error(`${RED}✖ Error parsing file: ${e.message}${RESET}`);
|
|
186
173
|
// Fallback Logic: Return truncated raw on hard failure
|
|
187
|
-
const rawContent = fs
|
|
188
|
-
|
|
189
|
-
.split("\n")
|
|
190
|
-
.slice(0, 100)
|
|
191
|
-
.join("\n");
|
|
192
|
-
console.log("\n--- RAW FILE FALLBACK (100 lines) ---");
|
|
174
|
+
const rawContent = fs.readFileSync(absolutePath, 'utf8').split('\n').slice(0, 100).join('\n');
|
|
175
|
+
console.log('\n--- RAW FILE FALLBACK (100 lines) ---');
|
|
193
176
|
console.log(rawContent);
|
|
194
|
-
console.log(
|
|
177
|
+
console.log('-------------------------------------\n');
|
|
195
178
|
}
|
|
196
179
|
}
|
|
197
180
|
|