aios-core 4.2.15 → 4.4.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/.aios-core/cli/commands/validate/index.js +1 -1
- package/.aios-core/core/code-intel/code-intel-client.js +19 -5
- package/.aios-core/core/code-intel/helpers/creation-helper.js +183 -0
- package/.aios-core/core/code-intel/helpers/devops-helper.js +166 -0
- package/.aios-core/core/code-intel/helpers/planning-helper.js +248 -0
- package/.aios-core/core/code-intel/helpers/qa-helper.js +187 -0
- package/.aios-core/core/code-intel/helpers/story-helper.js +146 -0
- package/.aios-core/core/code-intel/hook-runtime.js +186 -0
- package/.aios-core/core/code-intel/index.js +2 -0
- package/.aios-core/core/code-intel/providers/code-graph-provider.js +8 -0
- package/.aios-core/core/code-intel/providers/provider-interface.js +9 -0
- package/.aios-core/core/code-intel/providers/registry-provider.js +515 -0
- package/.aios-core/core/config/schemas/framework-config.schema.json +155 -7
- package/.aios-core/core/config/schemas/project-config.schema.json +329 -15
- package/.aios-core/core/config/template-overrides.js +84 -0
- package/.aios-core/core/docs/troubleshooting-guide.md +1 -1
- package/.aios-core/core/doctor/checks/agent-memory.js +63 -0
- package/.aios-core/core/doctor/checks/claude-md.js +56 -0
- package/.aios-core/core/doctor/checks/code-intel.js +131 -0
- package/.aios-core/core/doctor/checks/commands-count.js +81 -0
- package/.aios-core/core/doctor/checks/core-config.js +53 -0
- package/.aios-core/core/doctor/checks/entity-registry.js +53 -0
- package/.aios-core/core/doctor/checks/git-hooks.js +50 -0
- package/.aios-core/core/doctor/checks/graph-dashboard.js +48 -0
- package/.aios-core/core/doctor/checks/hooks-claude-count.js +118 -0
- package/.aios-core/core/doctor/checks/ide-sync.js +85 -0
- package/.aios-core/core/doctor/checks/index.js +46 -0
- package/.aios-core/core/doctor/checks/node-version.js +33 -0
- package/.aios-core/core/doctor/checks/npm-packages.js +35 -0
- package/.aios-core/core/doctor/checks/rules-files.js +61 -0
- package/.aios-core/core/doctor/checks/settings-json.js +121 -0
- package/.aios-core/core/doctor/checks/skills-count.js +72 -0
- package/.aios-core/core/doctor/fix-handler.js +165 -0
- package/.aios-core/core/doctor/formatters/json.js +14 -0
- package/.aios-core/core/doctor/formatters/text.js +59 -0
- package/.aios-core/core/doctor/index.js +94 -0
- package/.aios-core/core/graph-dashboard/cli.js +361 -0
- package/.aios-core/core/graph-dashboard/data-sources/code-intel-source.js +234 -0
- package/.aios-core/core/graph-dashboard/data-sources/metrics-source.js +95 -0
- package/.aios-core/core/graph-dashboard/data-sources/registry-source.js +106 -0
- package/.aios-core/core/graph-dashboard/formatters/dot-formatter.js +45 -0
- package/.aios-core/core/graph-dashboard/formatters/html-formatter.js +1437 -0
- package/.aios-core/core/graph-dashboard/formatters/json-formatter.js +13 -0
- package/.aios-core/core/graph-dashboard/formatters/mermaid-formatter.js +59 -0
- package/.aios-core/core/graph-dashboard/index.js +21 -0
- package/.aios-core/core/graph-dashboard/renderers/stats-renderer.js +217 -0
- package/.aios-core/core/graph-dashboard/renderers/status-renderer.js +125 -0
- package/.aios-core/core/graph-dashboard/renderers/tree-renderer.js +119 -0
- package/.aios-core/core/health-check/base-check.js +1 -1
- package/.aios-core/core/health-check/check-registry.js +1 -1
- package/.aios-core/core/health-check/checks/deployment/build-config.js +1 -1
- package/.aios-core/core/health-check/checks/deployment/ci-config.js +1 -1
- package/.aios-core/core/health-check/checks/deployment/deployment-readiness.js +1 -1
- package/.aios-core/core/health-check/checks/deployment/docker-config.js +1 -1
- package/.aios-core/core/health-check/checks/deployment/env-file.js +1 -1
- package/.aios-core/core/health-check/checks/deployment/index.js +1 -1
- package/.aios-core/core/health-check/checks/index.js +1 -1
- package/.aios-core/core/health-check/checks/local/disk-space.js +1 -1
- package/.aios-core/core/health-check/checks/local/environment-vars.js +1 -1
- package/.aios-core/core/health-check/checks/local/git-install.js +1 -1
- package/.aios-core/core/health-check/checks/local/ide-detection.js +1 -1
- package/.aios-core/core/health-check/checks/local/index.js +1 -1
- package/.aios-core/core/health-check/checks/local/memory.js +1 -1
- package/.aios-core/core/health-check/checks/local/network.js +1 -1
- package/.aios-core/core/health-check/checks/local/npm-install.js +1 -1
- package/.aios-core/core/health-check/checks/local/shell-environment.js +1 -1
- package/.aios-core/core/health-check/checks/project/agent-config.js +1 -1
- package/.aios-core/core/health-check/checks/project/aios-directory.js +1 -1
- package/.aios-core/core/health-check/checks/project/dependencies.js +1 -1
- package/.aios-core/core/health-check/checks/project/framework-config.js +1 -1
- package/.aios-core/core/health-check/checks/project/index.js +1 -1
- package/.aios-core/core/health-check/checks/project/node-version.js +1 -1
- package/.aios-core/core/health-check/checks/project/package-json.js +1 -1
- package/.aios-core/core/health-check/checks/project/task-definitions.js +1 -1
- package/.aios-core/core/health-check/checks/project/workflow-dependencies.js +1 -1
- package/.aios-core/core/health-check/checks/repository/branch-protection.js +1 -1
- package/.aios-core/core/health-check/checks/repository/commit-history.js +1 -1
- package/.aios-core/core/health-check/checks/repository/conflicts.js +1 -1
- package/.aios-core/core/health-check/checks/repository/git-repo.js +1 -1
- package/.aios-core/core/health-check/checks/repository/git-status.js +1 -1
- package/.aios-core/core/health-check/checks/repository/gitignore.js +1 -1
- package/.aios-core/core/health-check/checks/repository/index.js +1 -1
- package/.aios-core/core/health-check/checks/repository/large-files.js +1 -1
- package/.aios-core/core/health-check/checks/repository/lockfile-integrity.js +1 -1
- package/.aios-core/core/health-check/checks/services/api-endpoints.js +1 -1
- package/.aios-core/core/health-check/checks/services/claude-code.js +1 -1
- package/.aios-core/core/health-check/checks/services/gemini-cli.js +1 -1
- package/.aios-core/core/health-check/checks/services/github-cli.js +1 -1
- package/.aios-core/core/health-check/checks/services/index.js +1 -1
- package/.aios-core/core/health-check/checks/services/mcp-integration.js +1 -1
- package/.aios-core/core/health-check/engine.js +1 -1
- package/.aios-core/core/health-check/healers/backup-manager.js +1 -1
- package/.aios-core/core/health-check/healers/index.js +1 -1
- package/.aios-core/core/health-check/index.js +9 -2
- package/.aios-core/core/health-check/reporters/console.js +1 -1
- package/.aios-core/core/health-check/reporters/index.js +1 -1
- package/.aios-core/core/health-check/reporters/json.js +1 -1
- package/.aios-core/core/health-check/reporters/markdown.js +1 -1
- package/.aios-core/core/ids/layer-classifier.js +65 -0
- package/.aios-core/core/ids/registry-updater.js +49 -0
- package/.aios-core/core/index.esm.js +1 -1
- package/.aios-core/core/index.js +1 -1
- package/.aios-core/core/session/context-detector.js +2 -7
- package/.aios-core/core/synapse/context/context-tracker.js +9 -1
- package/.aios-core/core/synapse/engine.js +33 -13
- package/.aios-core/core/synapse/memory/memory-bridge.js +17 -43
- package/.aios-core/core/synapse/memory/synapse-memory-provider.js +201 -0
- package/.aios-core/core/synapse/runtime/hook-runtime.js +40 -2
- package/.aios-core/core/synapse/session/session-manager.js +3 -2
- package/.aios-core/core/synapse/utils/atomic-write.js +79 -0
- package/.aios-core/core-config.yaml +34 -1
- package/.aios-core/data/aios-kb.md +2 -2
- package/.aios-core/data/capability-detection.js +290 -0
- package/.aios-core/data/entity-registry.yaml +10450 -2129
- package/.aios-core/data/mcp-discipline.js +166 -0
- package/.aios-core/data/mcp-tool-examples.yaml +215 -0
- package/.aios-core/data/tok2-validation.js +168 -0
- package/.aios-core/data/tok3-token-comparison.js +123 -0
- package/.aios-core/data/tool-registry.yaml +648 -0
- package/.aios-core/data/tool-search-validation.js +174 -0
- package/.aios-core/data/workflow-chains.yaml +156 -0
- package/.aios-core/development/agents/aios-master.md +17 -10
- package/.aios-core/development/agents/analyst/MEMORY.md +33 -0
- package/.aios-core/development/agents/analyst.md +17 -10
- package/.aios-core/development/agents/architect/MEMORY.md +39 -0
- package/.aios-core/development/agents/architect.md +17 -10
- package/.aios-core/development/agents/data-engineer/MEMORY.md +32 -0
- package/.aios-core/development/agents/data-engineer.md +17 -10
- package/.aios-core/development/agents/dev/MEMORY.md +46 -0
- package/.aios-core/development/agents/dev.md +18 -11
- package/.aios-core/development/agents/devops/MEMORY.md +39 -0
- package/.aios-core/development/agents/devops.md +44 -10
- package/.aios-core/development/agents/pm/MEMORY.md +38 -0
- package/.aios-core/development/agents/pm.md +17 -10
- package/.aios-core/development/agents/po/MEMORY.md +45 -0
- package/.aios-core/development/agents/po.md +17 -10
- package/.aios-core/development/agents/qa/MEMORY.md +42 -0
- package/.aios-core/development/agents/qa.md +18 -11
- package/.aios-core/development/agents/sm/MEMORY.md +31 -0
- package/.aios-core/development/agents/sm.md +17 -10
- package/.aios-core/development/agents/squad-creator.md +18 -9
- package/.aios-core/development/agents/ux/MEMORY.md +31 -0
- package/.aios-core/development/agents/ux-design-expert.md +16 -9
- package/.aios-core/development/checklists/issue-triage-checklist.md +35 -0
- package/.aios-core/development/checklists/memory-audit-checklist.md +53 -0
- package/.aios-core/development/scripts/issue-triage.js +171 -0
- package/.aios-core/development/scripts/populate-entity-registry.js +412 -19
- package/.aios-core/development/scripts/unified-activation-pipeline.js +31 -10
- package/.aios-core/development/tasks/analyze-project-structure.md +48 -0
- package/.aios-core/development/tasks/apply-qa-fixes.md +7 -0
- package/.aios-core/development/tasks/architect-analyze-impact.md +8 -1
- package/.aios-core/development/tasks/brownfield-create-epic.md +41 -0
- package/.aios-core/development/tasks/brownfield-create-story.md +7 -0
- package/.aios-core/development/tasks/build-autonomous.md +7 -0
- package/.aios-core/development/tasks/create-deep-research-prompt.md +7 -0
- package/.aios-core/development/tasks/create-doc.md +44 -0
- package/.aios-core/development/tasks/create-next-story.md +17 -0
- package/.aios-core/development/tasks/create-suite.md +7 -0
- package/.aios-core/development/tasks/dev-develop-story.md +9 -1
- package/.aios-core/development/tasks/execute-checklist.md +7 -0
- package/.aios-core/development/tasks/github-devops-github-pr-automation.md +56 -0
- package/.aios-core/development/tasks/github-devops-pre-push-quality-gate.md +70 -0
- package/.aios-core/development/tasks/github-issue-triage.md +118 -0
- package/.aios-core/development/tasks/health-check.yaml +206 -171
- package/.aios-core/development/tasks/kb-mode-interaction.md +3 -3
- package/.aios-core/development/tasks/plan-create-context.md +47 -1
- package/.aios-core/development/tasks/plan-create-implementation.md +55 -0
- package/.aios-core/development/tasks/po-close-story.md +7 -0
- package/.aios-core/development/tasks/pr-automation.md +5 -5
- package/.aios-core/development/tasks/qa-create-fix-request.md +7 -0
- package/.aios-core/development/tasks/qa-fix-issues.md +7 -0
- package/.aios-core/development/tasks/qa-gate.md +56 -0
- package/.aios-core/development/tasks/qa-review-story.md +32 -1
- package/.aios-core/development/tasks/release-management.md +7 -0
- package/.aios-core/development/tasks/resolve-github-issue.md +608 -0
- package/.aios-core/development/tasks/review-contributor-pr.md +152 -0
- package/.aios-core/development/tasks/setup-llm-routing.md +1 -1
- package/.aios-core/development/tasks/spec-critique.md +8 -0
- package/.aios-core/development/tasks/spec-gather-requirements.md +7 -0
- package/.aios-core/development/tasks/spec-research-dependencies.md +4 -0
- package/.aios-core/development/tasks/spec-write-spec.md +5 -0
- package/.aios-core/development/tasks/triage-github-issues.md +356 -0
- package/.aios-core/development/tasks/validate-agents.md +4 -0
- package/.aios-core/development/tasks/validate-next-story.md +17 -0
- package/.aios-core/development/templates/agent-handoff-tmpl.yaml +48 -0
- package/.aios-core/development/templates/code-intel-integration-pattern.md +199 -0
- package/.aios-core/development/templates/ptc-entity-validation.md +113 -0
- package/.aios-core/development/templates/ptc-qa-gate.md +100 -0
- package/.aios-core/development/templates/ptc-research-aggregation.md +94 -0
- package/.aios-core/development/templates/service-template/README.md.hbs +158 -158
- package/.aios-core/development/templates/service-template/__tests__/index.test.ts.hbs +237 -237
- package/.aios-core/development/templates/service-template/client.ts.hbs +403 -403
- package/.aios-core/development/templates/service-template/errors.ts.hbs +182 -182
- package/.aios-core/development/templates/service-template/index.ts.hbs +120 -120
- package/.aios-core/development/templates/service-template/package.json.hbs +87 -87
- package/.aios-core/development/templates/service-template/types.ts.hbs +145 -145
- package/.aios-core/development/templates/squad/agent-template.md +11 -0
- package/.aios-core/development/templates/squad/task-template.md +21 -0
- package/.aios-core/development/templates/squad-template/LICENSE +21 -21
- package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO-V2.1-COMPLETE.md +1 -1
- package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO-V2.2-SUMMARY.md +1 -1
- package/.aios-core/framework-config.yaml +8 -0
- package/.aios-core/index.esm.js +1 -1
- package/.aios-core/index.js +1 -1
- package/.aios-core/infrastructure/integrations/ai-providers/index.js +1 -1
- package/.aios-core/infrastructure/schemas/task-v3-schema.json +6 -0
- package/.aios-core/infrastructure/scripts/collect-tool-usage.js +311 -0
- package/.aios-core/infrastructure/scripts/generate-optimization-report.js +497 -0
- package/.aios-core/infrastructure/scripts/generate-settings-json.js +300 -0
- package/.aios-core/infrastructure/scripts/git-config-detector.js +65 -9
- package/.aios-core/infrastructure/scripts/ide-sync/index.js +3 -1
- package/.aios-core/infrastructure/scripts/ide-sync/transformers/github-copilot.js +184 -0
- package/.aios-core/infrastructure/scripts/repository-detector.js +3 -3
- package/.aios-core/infrastructure/templates/aios-sync.yaml.template +182 -182
- package/.aios-core/infrastructure/templates/coderabbit.yaml.template +279 -279
- package/.aios-core/infrastructure/templates/github-workflows/ci.yml.template +169 -169
- package/.aios-core/infrastructure/templates/github-workflows/pr-automation.yml.template +330 -330
- package/.aios-core/infrastructure/templates/github-workflows/release.yml.template +196 -196
- package/.aios-core/infrastructure/templates/gitignore/gitignore-aios-base.tmpl +63 -63
- package/.aios-core/infrastructure/templates/gitignore/gitignore-brownfield-merge.tmpl +18 -18
- package/.aios-core/infrastructure/templates/gitignore/gitignore-node.tmpl +85 -85
- package/.aios-core/infrastructure/templates/gitignore/gitignore-python.tmpl +145 -145
- package/.aios-core/install-manifest.yaml +613 -305
- package/.aios-core/lib/build.json +1 -0
- package/.aios-core/local-config.yaml.template +71 -71
- package/.aios-core/monitor/hooks/lib/__init__.py +1 -1
- package/.aios-core/monitor/hooks/lib/enrich.py +58 -58
- package/.aios-core/monitor/hooks/lib/send_event.py +47 -47
- package/.aios-core/monitor/hooks/notification.py +29 -29
- package/.aios-core/monitor/hooks/post_tool_use.py +45 -45
- package/.aios-core/monitor/hooks/pre_compact.py +29 -29
- package/.aios-core/monitor/hooks/pre_tool_use.py +40 -40
- package/.aios-core/monitor/hooks/stop.py +29 -29
- package/.aios-core/monitor/hooks/subagent_stop.py +29 -29
- package/.aios-core/monitor/hooks/user_prompt_submit.py +38 -38
- package/.aios-core/product/templates/adr.hbs +125 -125
- package/.aios-core/product/templates/dbdr.hbs +241 -241
- package/.aios-core/product/templates/epic.hbs +212 -212
- package/.aios-core/product/templates/ide-rules/claude-rules.md +125 -0
- package/.aios-core/product/templates/pmdr.hbs +186 -186
- package/.aios-core/product/templates/prd-v2.0.hbs +216 -216
- package/.aios-core/product/templates/prd.hbs +201 -201
- package/.aios-core/product/templates/story.hbs +263 -263
- package/.aios-core/product/templates/task.hbs +170 -170
- package/.aios-core/product/templates/tmpl-comment-on-examples.sql +158 -158
- package/.aios-core/product/templates/tmpl-migration-script.sql +91 -91
- package/.aios-core/product/templates/tmpl-rls-granular-policies.sql +104 -104
- package/.aios-core/product/templates/tmpl-rls-kiss-policy.sql +10 -10
- package/.aios-core/product/templates/tmpl-rls-roles.sql +135 -135
- package/.aios-core/product/templates/tmpl-rls-simple.sql +77 -77
- package/.aios-core/product/templates/tmpl-rls-tenant.sql +152 -152
- package/.aios-core/product/templates/tmpl-rollback-script.sql +77 -77
- package/.aios-core/product/templates/tmpl-seed-data.sql +140 -140
- package/.aios-core/product/templates/tmpl-smoke-test.sql +16 -16
- package/.aios-core/product/templates/tmpl-staging-copy-merge.sql +139 -139
- package/.aios-core/product/templates/tmpl-stored-proc.sql +140 -140
- package/.aios-core/product/templates/tmpl-trigger.sql +152 -152
- package/.aios-core/product/templates/tmpl-view-materialized.sql +133 -133
- package/.aios-core/product/templates/tmpl-view.sql +177 -177
- package/.aios-core/scripts/pm.sh +0 -0
- package/.aios-core/user-guide.md +15 -15
- package/.aios-core/utils/filters/constants.js +10 -0
- package/.aios-core/utils/filters/content-filter.js +223 -0
- package/.aios-core/utils/filters/field-filter.js +126 -0
- package/.aios-core/utils/filters/index.js +180 -0
- package/.aios-core/utils/filters/schema-filter.js +157 -0
- package/.claude/CLAUDE.md +62 -0
- package/.claude/hooks/enforce-architecture-first.py +196 -196
- package/.claude/hooks/enforce-git-push-authority.sh +33 -0
- package/.claude/hooks/mind-clone-governance.py +192 -192
- package/.claude/hooks/read-protection.py +151 -151
- package/.claude/hooks/slug-validation.py +176 -176
- package/.claude/hooks/sql-governance.py +182 -182
- package/.claude/hooks/synapse-engine.cjs +28 -5
- package/.claude/hooks/write-path-validation.py +194 -194
- package/.claude/rules/agent-authority.md +105 -0
- package/.claude/rules/agent-handoff.md +97 -0
- package/.claude/rules/agent-memory-imports.md +15 -0
- package/.claude/rules/coderabbit-integration.md +101 -0
- package/.claude/rules/ids-principles.md +119 -0
- package/.claude/rules/story-lifecycle.md +145 -0
- package/.claude/rules/tool-examples.md +64 -0
- package/.claude/rules/tool-response-filtering.md +57 -0
- package/.claude/rules/workflow-execution.md +150 -0
- package/LICENSE +33 -33
- package/bin/aios-graph.js +9 -0
- package/bin/aios-init.js +2 -2
- package/bin/aios-minimal.js +0 -0
- package/bin/aios.js +17 -221
- package/bin/utils/detect-fsmonitor.js +70 -0
- package/bin/utils/framework-guard.js +238 -0
- package/bin/utils/validate-publish.js +108 -0
- package/package.json +6 -3
- package/packages/aios-install/bin/aios-install.js +0 -0
- package/packages/aios-install/bin/edmcp.js +0 -0
- package/packages/aios-pro-cli/bin/aios-pro.js +2 -0
- package/packages/installer/src/config/templates/core-config-template.js +25 -0
- package/packages/installer/src/installer/brownfield-upgrader.js +68 -5
- package/packages/installer/src/merger/index.js +3 -0
- package/packages/installer/src/merger/strategies/index.js +6 -0
- package/packages/installer/src/merger/strategies/yaml-merger.js +181 -0
- package/packages/installer/src/updater/index.js +4 -4
- package/packages/installer/src/wizard/i18n.js +321 -3
- package/packages/installer/src/wizard/ide-config-generator.js +173 -25
- package/packages/installer/src/wizard/index.js +119 -1
- package/packages/installer/src/wizard/pro-setup.js +137 -121
- package/packages/installer/tests/unit/artifact-copy-pipeline/artifact-copy-pipeline.test.js +271 -0
- package/packages/installer/tests/unit/claude-md-template-v5/claude-md-template-v5.test.js +192 -0
- package/packages/installer/tests/unit/doctor/doctor-checks.test.js +610 -0
- package/packages/installer/tests/unit/doctor/doctor-orchestrator.test.js +134 -0
- package/packages/installer/tests/unit/entity-registry-bootstrap.test.js +186 -0
- package/packages/installer/tests/unit/generate-settings-json/generate-settings-json.test.js +309 -0
- package/packages/installer/tests/unit/ide-sync-integration/ide-sync-integration.test.js +230 -0
- package/packages/installer/tests/unit/merger/strategies.test.js +2 -2
- package/packages/installer/tests/unit/merger/yaml-merger.test.js +327 -0
- package/scripts/check-markdown-links.py +352 -352
- package/scripts/dashboard-parallel-dev.sh +0 -0
- package/scripts/dashboard-parallel-phase3.sh +0 -0
- package/scripts/dashboard-parallel-phase4.sh +0 -0
- package/scripts/install-monitor-hooks.sh +0 -0
- package/scripts/package-synapse.js +2 -1
- package/pro/README.md +0 -66
- package/pro/license/degradation.js +0 -220
- package/pro/license/errors.js +0 -450
- package/pro/license/feature-gate.js +0 -354
- package/pro/license/index.js +0 -181
- package/pro/license/license-api.js +0 -651
- package/pro/license/license-cache.js +0 -523
- package/pro/license/license-crypto.js +0 -303
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Format graph data as JSON string.
|
|
5
|
+
* Output is pipe-friendly and parseable by jq.
|
|
6
|
+
* @param {Object} graphData - Normalized graph data { nodes, edges, source, isFallback }
|
|
7
|
+
* @returns {string} JSON string (indented, no trailing newline)
|
|
8
|
+
*/
|
|
9
|
+
function formatAsJson(graphData) {
|
|
10
|
+
return JSON.stringify(graphData, null, 2);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
module.exports = { formatAsJson };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Format graph data as Mermaid diagram string.
|
|
5
|
+
* Output is valid Mermaid syntax for documentation.
|
|
6
|
+
* @param {Object} graphData - Normalized graph data { nodes, edges, source, isFallback }
|
|
7
|
+
* @returns {string} Mermaid format string
|
|
8
|
+
*/
|
|
9
|
+
function formatAsMermaid(graphData) {
|
|
10
|
+
const nodes = graphData.nodes || [];
|
|
11
|
+
const edges = graphData.edges || [];
|
|
12
|
+
const lines = [];
|
|
13
|
+
|
|
14
|
+
lines.push('graph TD');
|
|
15
|
+
|
|
16
|
+
const connectedNodes = new Set();
|
|
17
|
+
|
|
18
|
+
for (const edge of edges) {
|
|
19
|
+
const fromLabel = _escapeMermaid(edge.from);
|
|
20
|
+
const toLabel = _escapeMermaid(edge.to);
|
|
21
|
+
lines.push(` ${_safeId(edge.from)}["${fromLabel}"] --> ${_safeId(edge.to)}["${toLabel}"]`);
|
|
22
|
+
connectedNodes.add(edge.from);
|
|
23
|
+
connectedNodes.add(edge.to);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
for (const node of nodes) {
|
|
27
|
+
if (!connectedNodes.has(node.id)) {
|
|
28
|
+
const label = _escapeMermaid(node.label || node.id);
|
|
29
|
+
lines.push(` ${_safeId(node.id)}["${label}"]`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return lines.join('\n');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Create a safe Mermaid node ID (alphanumeric + hyphens + underscores).
|
|
38
|
+
* @param {string} id - Raw node ID
|
|
39
|
+
* @returns {string} Safe ID
|
|
40
|
+
* @private
|
|
41
|
+
*/
|
|
42
|
+
function _safeId(id) {
|
|
43
|
+
return String(id).replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Escape special characters for Mermaid label strings.
|
|
48
|
+
* @param {string} str - Raw string
|
|
49
|
+
* @returns {string} Escaped string
|
|
50
|
+
* @private
|
|
51
|
+
*/
|
|
52
|
+
function _escapeMermaid(str) {
|
|
53
|
+
return String(str)
|
|
54
|
+
.replace(/"/g, '"')
|
|
55
|
+
.replace(/\[/g, '[')
|
|
56
|
+
.replace(/\]/g, ']');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
module.exports = { formatAsMermaid, _safeId, _escapeMermaid };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { CodeIntelSource } = require('./data-sources/code-intel-source');
|
|
4
|
+
const { renderTree } = require('./renderers/tree-renderer');
|
|
5
|
+
const { run } = require('./cli');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Get graph data from code-intel or registry fallback.
|
|
9
|
+
* @returns {Promise<Object>} Normalized graph data { nodes, edges, source, isFallback, timestamp }
|
|
10
|
+
*/
|
|
11
|
+
async function getGraphData() {
|
|
12
|
+
const source = new CodeIntelSource();
|
|
13
|
+
return source.getData();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
module.exports = {
|
|
17
|
+
getGraphData,
|
|
18
|
+
renderTree,
|
|
19
|
+
run,
|
|
20
|
+
CodeIntelSource,
|
|
21
|
+
};
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const asciichart = require('asciichart');
|
|
4
|
+
|
|
5
|
+
const SPARKLINE_CHARS = ['\u2581', '\u2582', '\u2583', '\u2584', '\u2585', '\u2586', '\u2587'];
|
|
6
|
+
const MAX_LATENCY_POINTS = 10;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Render entity statistics and cache metrics as formatted ASCII text.
|
|
10
|
+
* @param {Object} registryData - From RegistrySource.getData()
|
|
11
|
+
* @param {Object} metricsData - From MetricsSource.getData()
|
|
12
|
+
* @param {Object} [options]
|
|
13
|
+
* @param {boolean} [options.isTTY=true] - Whether output is to a TTY
|
|
14
|
+
* @returns {string} Formatted multiline string
|
|
15
|
+
*/
|
|
16
|
+
function renderStats(registryData, metricsData, options = {}) {
|
|
17
|
+
const isTTY = options.isTTY !== false;
|
|
18
|
+
const lines = [];
|
|
19
|
+
|
|
20
|
+
lines.push(..._renderEntityTable(registryData, isTTY));
|
|
21
|
+
lines.push('');
|
|
22
|
+
lines.push(..._renderCachePerformance(metricsData, isTTY));
|
|
23
|
+
lines.push('');
|
|
24
|
+
lines.push(..._renderLatencyChart(metricsData, isTTY));
|
|
25
|
+
|
|
26
|
+
if (registryData.lastUpdated) {
|
|
27
|
+
lines.push('');
|
|
28
|
+
lines.push(`Last updated: ${_timeAgo(registryData.lastUpdated)}`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return lines.join('\n');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Render entity statistics table.
|
|
36
|
+
* @param {Object} data - Registry stats
|
|
37
|
+
* @param {boolean} isTTY
|
|
38
|
+
* @returns {string[]}
|
|
39
|
+
* @private
|
|
40
|
+
*/
|
|
41
|
+
function _renderEntityTable(data, isTTY) {
|
|
42
|
+
const lines = [];
|
|
43
|
+
const categories = data.categories || {};
|
|
44
|
+
const sortedCategories = Object.entries(categories)
|
|
45
|
+
.sort((a, b) => b[1].count - a[1].count);
|
|
46
|
+
|
|
47
|
+
if (isTTY) {
|
|
48
|
+
lines.push('Entity Statistics');
|
|
49
|
+
lines.push('\u2500'.repeat(37));
|
|
50
|
+
lines.push(` ${'Category'.padEnd(13)}\u2502 ${'Count'.padStart(5)} \u2502 ${'%'.padStart(6)}`);
|
|
51
|
+
lines.push(`${'\u2500'.repeat(14)}\u253C${'\u2500'.repeat(7)}\u253C${'\u2500'.repeat(8)}`);
|
|
52
|
+
|
|
53
|
+
for (const [name, stats] of sortedCategories) {
|
|
54
|
+
const pctStr = `${stats.pct.toFixed(1)}%`;
|
|
55
|
+
lines.push(` ${name.padEnd(13)}\u2502 ${String(stats.count).padStart(5)} \u2502 ${pctStr.padStart(6)}`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
lines.push(`${'\u2500'.repeat(14)}\u253C${'\u2500'.repeat(7)}\u253C${'\u2500'.repeat(8)}`);
|
|
59
|
+
lines.push(` ${'TOTAL'.padEnd(13)}\u2502 ${String(data.totalEntities).padStart(5)} \u2502 ${'100%'.padStart(6)}`);
|
|
60
|
+
} else {
|
|
61
|
+
lines.push('Entity Statistics');
|
|
62
|
+
lines.push('-'.repeat(37));
|
|
63
|
+
lines.push(` ${'Category'.padEnd(13)}| ${'Count'.padStart(5)} | ${'%'.padStart(6)}`);
|
|
64
|
+
lines.push(`${'-'.repeat(14)}+${'-'.repeat(7)}+${'-'.repeat(8)}`);
|
|
65
|
+
|
|
66
|
+
for (const [name, stats] of sortedCategories) {
|
|
67
|
+
const pctStr = `${stats.pct.toFixed(1)}%`;
|
|
68
|
+
lines.push(` ${name.padEnd(13)}| ${String(stats.count).padStart(5)} | ${pctStr.padStart(6)}`);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
lines.push(`${'-'.repeat(14)}+${'-'.repeat(7)}+${'-'.repeat(8)}`);
|
|
72
|
+
lines.push(` ${'TOTAL'.padEnd(13)}| ${String(data.totalEntities).padStart(5)} | ${'100%'.padStart(6)}`);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return lines;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Render cache performance with sparkline.
|
|
80
|
+
* @param {Object} data - Metrics data
|
|
81
|
+
* @param {boolean} isTTY
|
|
82
|
+
* @returns {string[]}
|
|
83
|
+
* @private
|
|
84
|
+
*/
|
|
85
|
+
function _renderCachePerformance(data, isTTY) {
|
|
86
|
+
const lines = [];
|
|
87
|
+
|
|
88
|
+
lines.push('Cache Performance');
|
|
89
|
+
|
|
90
|
+
if (!data.providerAvailable) {
|
|
91
|
+
lines.push(' [OFFLINE] No metrics available');
|
|
92
|
+
return lines;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const hitPct = (data.cacheHitRate * 100).toFixed(1);
|
|
96
|
+
const missPct = (100 - data.cacheHitRate * 100).toFixed(1);
|
|
97
|
+
|
|
98
|
+
if (isTTY) {
|
|
99
|
+
const hitSparkline = _generateSparkline(data.latencyLog, true);
|
|
100
|
+
const missSparkline = _generateSparkline(data.latencyLog, false);
|
|
101
|
+
lines.push(` Hit Rate: ${hitPct.padStart(5)}% ${hitSparkline}`);
|
|
102
|
+
lines.push(` Misses: ${missPct.padStart(5)}% ${missSparkline}`);
|
|
103
|
+
} else {
|
|
104
|
+
lines.push(` Hit Rate: ${hitPct}%`);
|
|
105
|
+
lines.push(` Misses: ${missPct}%`);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return lines;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Generate sparkline string from latency log entries.
|
|
113
|
+
* @param {Array} latencyLog - Array of { isCacheHit, durationMs }
|
|
114
|
+
* @param {boolean} forHits - true = sparkline for hits, false = for misses
|
|
115
|
+
* @returns {string}
|
|
116
|
+
* @private
|
|
117
|
+
*/
|
|
118
|
+
function _generateSparkline(latencyLog, forHits) {
|
|
119
|
+
if (!latencyLog || latencyLog.length === 0) {
|
|
120
|
+
return '';
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const recent = latencyLog.slice(-MAX_LATENCY_POINTS);
|
|
124
|
+
const values = recent.map((entry) => {
|
|
125
|
+
if (forHits) {
|
|
126
|
+
return entry.isCacheHit ? entry.durationMs || 1 : 0;
|
|
127
|
+
}
|
|
128
|
+
return entry.isCacheHit ? 0 : entry.durationMs || 1;
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
const max = Math.max(...values, 1);
|
|
132
|
+
|
|
133
|
+
return values
|
|
134
|
+
.map((v) => {
|
|
135
|
+
const idx = Math.round((v / max) * (SPARKLINE_CHARS.length - 1));
|
|
136
|
+
return SPARKLINE_CHARS[Math.min(idx, SPARKLINE_CHARS.length - 1)];
|
|
137
|
+
})
|
|
138
|
+
.join('');
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Render latency chart using asciichart.
|
|
143
|
+
* @param {Object} data - Metrics data
|
|
144
|
+
* @param {boolean} isTTY
|
|
145
|
+
* @returns {string[]}
|
|
146
|
+
* @private
|
|
147
|
+
*/
|
|
148
|
+
function _renderLatencyChart(data, _isTTY) {
|
|
149
|
+
const lines = [];
|
|
150
|
+
const latencyLog = data.latencyLog || [];
|
|
151
|
+
|
|
152
|
+
if (!data.providerAvailable) {
|
|
153
|
+
lines.push('Latency');
|
|
154
|
+
lines.push(' [OFFLINE] No latency data');
|
|
155
|
+
return lines;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (latencyLog.length === 0) {
|
|
159
|
+
lines.push('Latency');
|
|
160
|
+
lines.push(' No operations recorded');
|
|
161
|
+
return lines;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const recent = latencyLog.slice(-MAX_LATENCY_POINTS);
|
|
165
|
+
const durations = recent.map((entry) => entry.durationMs || 0);
|
|
166
|
+
|
|
167
|
+
lines.push(`Latency (last ${recent.length} operations)`);
|
|
168
|
+
|
|
169
|
+
const chart = asciichart.plot(durations, { height: 4, padding: ' ' });
|
|
170
|
+
lines.push(chart);
|
|
171
|
+
|
|
172
|
+
return lines;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Calculate relative time string from ISO date.
|
|
177
|
+
* @param {string} isoDate - ISO date string
|
|
178
|
+
* @returns {string} Relative time (e.g., "5 minutes ago")
|
|
179
|
+
* @private
|
|
180
|
+
*/
|
|
181
|
+
function _timeAgo(isoDate) {
|
|
182
|
+
const now = Date.now();
|
|
183
|
+
const then = new Date(isoDate).getTime();
|
|
184
|
+
const diffMs = now - then;
|
|
185
|
+
|
|
186
|
+
if (isNaN(diffMs) || diffMs < 0) {
|
|
187
|
+
return 'unknown';
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const seconds = Math.floor(diffMs / 1000);
|
|
191
|
+
|
|
192
|
+
if (seconds < 60) {
|
|
193
|
+
return `${seconds}s ago`;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const minutes = Math.floor(seconds / 60);
|
|
197
|
+
if (minutes < 60) {
|
|
198
|
+
return `${minutes}m ago`;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const hours = Math.floor(minutes / 60);
|
|
202
|
+
if (hours < 24) {
|
|
203
|
+
return `${hours}h ago`;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const days = Math.floor(hours / 24);
|
|
207
|
+
return `${days}d ago`;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
module.exports = {
|
|
211
|
+
renderStats,
|
|
212
|
+
_renderEntityTable,
|
|
213
|
+
_renderCachePerformance,
|
|
214
|
+
_renderLatencyChart,
|
|
215
|
+
_generateSparkline,
|
|
216
|
+
_timeAgo,
|
|
217
|
+
};
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const COLORS = {
|
|
4
|
+
green: '\x1b[32m',
|
|
5
|
+
red: '\x1b[31m',
|
|
6
|
+
yellow: '\x1b[33m',
|
|
7
|
+
reset: '\x1b[0m',
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const CB_FAILURE_THRESHOLD = 5;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Render provider status as formatted multiline string.
|
|
14
|
+
* @param {Object} metricsData - From MetricsSource.getData()
|
|
15
|
+
* @param {Object} [options]
|
|
16
|
+
* @param {boolean} [options.isTTY=true] - Whether output is to a TTY
|
|
17
|
+
* @returns {string} Formatted multiline string
|
|
18
|
+
*/
|
|
19
|
+
function renderStatus(metricsData, options = {}) {
|
|
20
|
+
const isTTY = options.isTTY !== false;
|
|
21
|
+
const lines = [];
|
|
22
|
+
|
|
23
|
+
lines.push(_renderHeader(isTTY));
|
|
24
|
+
lines.push(_renderProviderLine(metricsData, isTTY));
|
|
25
|
+
lines.push(_renderCircuitBreaker(metricsData, isTTY));
|
|
26
|
+
lines.push(_renderFailures(metricsData));
|
|
27
|
+
lines.push(_renderCacheEntries(metricsData));
|
|
28
|
+
lines.push(_renderUptime());
|
|
29
|
+
|
|
30
|
+
return lines.join('\n');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Render status section header.
|
|
35
|
+
* @param {boolean} isTTY
|
|
36
|
+
* @returns {string}
|
|
37
|
+
* @private
|
|
38
|
+
*/
|
|
39
|
+
function _renderHeader(isTTY) {
|
|
40
|
+
const separator = isTTY ? '\u2500'.repeat(27) : '-'.repeat(27);
|
|
41
|
+
return `Provider Status\n${separator}`;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Render provider availability line.
|
|
46
|
+
* @param {Object} data - Metrics data
|
|
47
|
+
* @param {boolean} isTTY
|
|
48
|
+
* @returns {string}
|
|
49
|
+
* @private
|
|
50
|
+
*/
|
|
51
|
+
function _renderProviderLine(data, isTTY) {
|
|
52
|
+
const isActive = !!data.providerAvailable;
|
|
53
|
+
|
|
54
|
+
if (isTTY) {
|
|
55
|
+
if (isActive) {
|
|
56
|
+
return ` Code Graph MCP: ${COLORS.green}\u25CF ACTIVE${COLORS.reset}`;
|
|
57
|
+
}
|
|
58
|
+
return ` Code Graph MCP: ${COLORS.red}\u25CB OFFLINE${COLORS.reset}`;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (isActive) {
|
|
62
|
+
return ' Code Graph MCP: [ACTIVE]';
|
|
63
|
+
}
|
|
64
|
+
return ' Code Graph MCP: [OFFLINE]';
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Render circuit breaker state line.
|
|
69
|
+
* @param {Object} data - Metrics data
|
|
70
|
+
* @param {boolean} isTTY
|
|
71
|
+
* @returns {string}
|
|
72
|
+
* @private
|
|
73
|
+
*/
|
|
74
|
+
function _renderCircuitBreaker(data, isTTY) {
|
|
75
|
+
const state = data.circuitBreakerState || 'CLOSED';
|
|
76
|
+
|
|
77
|
+
if (isTTY && state === 'HALF-OPEN') {
|
|
78
|
+
return ` Circuit Breaker: ${COLORS.yellow}${state}${COLORS.reset}`;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return ` Circuit Breaker: ${state}`;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Render failure count line.
|
|
86
|
+
* @param {Object} data - Metrics data
|
|
87
|
+
* @returns {string}
|
|
88
|
+
* @private
|
|
89
|
+
*/
|
|
90
|
+
function _renderFailures(data) {
|
|
91
|
+
const failures = data.circuitBreakerFailures || 0;
|
|
92
|
+
return ` Failures: ${failures}/${CB_FAILURE_THRESHOLD}`;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Render cache entries count line.
|
|
97
|
+
* Uses cacheHits + cacheMisses as proxy for total cache operations.
|
|
98
|
+
* @param {Object} data - Metrics data
|
|
99
|
+
* @returns {string}
|
|
100
|
+
* @private
|
|
101
|
+
*/
|
|
102
|
+
function _renderCacheEntries(data) {
|
|
103
|
+
const entries = (data.cacheHits || 0) + (data.cacheMisses || 0);
|
|
104
|
+
return ` Cache Entries: ${entries}`;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Render uptime line (static string, no real tracking).
|
|
109
|
+
* @returns {string}
|
|
110
|
+
* @private
|
|
111
|
+
*/
|
|
112
|
+
function _renderUptime() {
|
|
113
|
+
return ' Uptime: session';
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
module.exports = {
|
|
117
|
+
renderStatus,
|
|
118
|
+
CB_FAILURE_THRESHOLD,
|
|
119
|
+
_renderHeader,
|
|
120
|
+
_renderProviderLine,
|
|
121
|
+
_renderCircuitBreaker,
|
|
122
|
+
_renderFailures,
|
|
123
|
+
_renderCacheEntries,
|
|
124
|
+
_renderUptime,
|
|
125
|
+
};
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const MAX_ITEMS_PER_BRANCH = 20;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Box-drawing characters for tree rendering.
|
|
7
|
+
*/
|
|
8
|
+
const UNICODE_CHARS = { branch: '\u251C\u2500', last: '\u2514\u2500', pipe: '\u2502', space: ' ' };
|
|
9
|
+
const ASCII_CHARS = { branch: '+-', last: '\\-', pipe: '|', space: ' ' };
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Render graph data as ASCII dependency tree.
|
|
13
|
+
* @param {Object} graphData - Normalized graph data { nodes, edges, source, isFallback }
|
|
14
|
+
* @param {Object} [options]
|
|
15
|
+
* @param {boolean} [options.color=true] - Enable ANSI colors (ignored if not TTY)
|
|
16
|
+
* @param {boolean} [options.unicode=true] - Use Unicode box-drawing characters
|
|
17
|
+
* @returns {string} Multiline ASCII tree string
|
|
18
|
+
*/
|
|
19
|
+
function renderTree(graphData, options = {}) {
|
|
20
|
+
const useUnicode = options.unicode !== false;
|
|
21
|
+
const chars = useUnicode ? UNICODE_CHARS : ASCII_CHARS;
|
|
22
|
+
|
|
23
|
+
const nodes = graphData.nodes || [];
|
|
24
|
+
const edges = graphData.edges || [];
|
|
25
|
+
|
|
26
|
+
if (nodes.length === 0) {
|
|
27
|
+
const badge = graphData.isFallback ? ' [OFFLINE]' : '';
|
|
28
|
+
return `Dependency Graph (0 entities)${badge}\n(empty)`;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Build dependency lookup: entityId → [dep1, dep2, ...]
|
|
32
|
+
const depsMap = _buildDepsMap(edges);
|
|
33
|
+
|
|
34
|
+
// Group nodes by category
|
|
35
|
+
const categories = _groupByCategory(nodes);
|
|
36
|
+
const categoryNames = Object.keys(categories).sort();
|
|
37
|
+
|
|
38
|
+
const lines = [];
|
|
39
|
+
const badge = graphData.isFallback ? ' [OFFLINE]' : '';
|
|
40
|
+
lines.push(`Dependency Graph (${nodes.length} entities)${badge}`);
|
|
41
|
+
|
|
42
|
+
for (let ci = 0; ci < categoryNames.length; ci++) {
|
|
43
|
+
const catName = categoryNames[ci];
|
|
44
|
+
const catNodes = categories[catName];
|
|
45
|
+
const isLastCategory = ci === categoryNames.length - 1;
|
|
46
|
+
const catPrefix = isLastCategory ? chars.last : chars.branch;
|
|
47
|
+
const catContinue = isLastCategory ? chars.space : chars.pipe;
|
|
48
|
+
|
|
49
|
+
lines.push(`${catPrefix} ${catName}/ (${catNodes.length})`);
|
|
50
|
+
|
|
51
|
+
const sortedNodes = catNodes.sort((a, b) => a.id.localeCompare(b.id));
|
|
52
|
+
const displayCount = Math.min(sortedNodes.length, MAX_ITEMS_PER_BRANCH);
|
|
53
|
+
const hasMore = sortedNodes.length > MAX_ITEMS_PER_BRANCH;
|
|
54
|
+
|
|
55
|
+
for (let ni = 0; ni < displayCount; ni++) {
|
|
56
|
+
const node = sortedNodes[ni];
|
|
57
|
+
const isLastNode = ni === displayCount - 1 && !hasMore;
|
|
58
|
+
const nodePrefix = isLastNode ? chars.last : chars.branch;
|
|
59
|
+
|
|
60
|
+
const deps = depsMap.get(node.id) || [];
|
|
61
|
+
const depSuffix = deps.length > 0 ? ` ${chars.last} depends: ${deps.join(', ')}` : '';
|
|
62
|
+
|
|
63
|
+
lines.push(`${catContinue} ${nodePrefix} ${node.id}${depSuffix}`);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (hasMore) {
|
|
67
|
+
const remaining = sortedNodes.length - MAX_ITEMS_PER_BRANCH;
|
|
68
|
+
lines.push(`${catContinue} ${chars.last} ... (${remaining} more)`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return lines.join('\n');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Build map of entityId → array of dependency IDs from edges.
|
|
77
|
+
* @param {Array} edges - Array of { from, to, type }
|
|
78
|
+
* @returns {Map<string, string[]>}
|
|
79
|
+
*/
|
|
80
|
+
function _buildDepsMap(edges) {
|
|
81
|
+
const map = new Map();
|
|
82
|
+
|
|
83
|
+
for (const edge of edges) {
|
|
84
|
+
if (edge.type !== 'depends') continue;
|
|
85
|
+
|
|
86
|
+
if (!map.has(edge.from)) {
|
|
87
|
+
map.set(edge.from, []);
|
|
88
|
+
}
|
|
89
|
+
map.get(edge.from).push(edge.to);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return map;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Group nodes by their category field.
|
|
97
|
+
* @param {Array} nodes - Array of { id, label, type, path, category }
|
|
98
|
+
* @returns {Object} { categoryName: [nodes...] }
|
|
99
|
+
*/
|
|
100
|
+
function _groupByCategory(nodes) {
|
|
101
|
+
const groups = {};
|
|
102
|
+
|
|
103
|
+
for (const node of nodes) {
|
|
104
|
+
const cat = node.category || 'other';
|
|
105
|
+
if (!groups[cat]) {
|
|
106
|
+
groups[cat] = [];
|
|
107
|
+
}
|
|
108
|
+
groups[cat].push(node);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return groups;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
module.exports = {
|
|
115
|
+
renderTree,
|
|
116
|
+
MAX_ITEMS_PER_BRANCH,
|
|
117
|
+
UNICODE_CHARS,
|
|
118
|
+
ASCII_CHARS,
|
|
119
|
+
};
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Abstract base class for all health checks. Provides common
|
|
5
5
|
* functionality and enforces the check interface.
|
|
6
6
|
*
|
|
7
|
-
* @module
|
|
7
|
+
* @module aios-core/health-check/base-check
|
|
8
8
|
* @version 1.0.0
|
|
9
9
|
* @story HCS-2 - Health Check System Implementation
|
|
10
10
|
*/
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Central registry for all health checks. Manages check registration,
|
|
5
5
|
* lookup, and categorization by domain and severity.
|
|
6
6
|
*
|
|
7
|
-
* @module
|
|
7
|
+
* @module aios-core/health-check/check-registry
|
|
8
8
|
* @version 1.0.0
|
|
9
9
|
* @story HCS-2 - Health Check System Implementation
|
|
10
10
|
*/
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Verifies build configuration is valid.
|
|
5
5
|
*
|
|
6
|
-
* @module
|
|
6
|
+
* @module aios-core/health-check/checks/deployment/build-config
|
|
7
7
|
* @version 1.0.0
|
|
8
8
|
* @story HCS-2 - Health Check System Implementation
|
|
9
9
|
*/
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Verifies project is ready for deployment.
|
|
5
5
|
*
|
|
6
|
-
* @module
|
|
6
|
+
* @module aios-core/health-check/checks/deployment/deployment-readiness
|
|
7
7
|
* @version 1.0.0
|
|
8
8
|
* @story HCS-2 - Health Check System Implementation
|
|
9
9
|
*/
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Verifies Docker configuration if present.
|
|
5
5
|
*
|
|
6
|
-
* @module
|
|
6
|
+
* @module aios-core/health-check/checks/deployment/docker-config
|
|
7
7
|
* @version 1.0.0
|
|
8
8
|
* @story HCS-2 - Health Check System Implementation
|
|
9
9
|
*/
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Checks for deployment configuration and environment.
|
|
5
5
|
* Domain: deployment
|
|
6
6
|
*
|
|
7
|
-
* @module
|
|
7
|
+
* @module aios-core/health-check/checks/deployment
|
|
8
8
|
* @version 1.0.0
|
|
9
9
|
* @story HCS-2 - Health Check System Implementation
|
|
10
10
|
*/
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Verifies required environment variables are set.
|
|
5
5
|
*
|
|
6
|
-
* @module
|
|
6
|
+
* @module aios-core/health-check/checks/local/environment-vars
|
|
7
7
|
* @version 1.0.0
|
|
8
8
|
* @story HCS-2 - Health Check System Implementation
|
|
9
9
|
*/
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Detects and validates IDE/editor configuration.
|
|
5
5
|
*
|
|
6
|
-
* @module
|
|
6
|
+
* @module aios-core/health-check/checks/local/ide-detection
|
|
7
7
|
* @version 1.0.0
|
|
8
8
|
* @story HCS-2 - Health Check System Implementation
|
|
9
9
|
*/
|