contextpro-mcp 0.0.0-stage → 1.5.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/CHANGELOG.md +425 -0
- package/INSTALL.md +218 -0
- package/INSTRUCTIONS.md +33 -0
- package/LICENSE +21 -0
- package/NOTICE +12 -0
- package/README.md +89 -2
- package/SECURITY.md +29 -0
- package/agent-guide.md +354 -0
- package/agent-instructions.md +1 -0
- package/build/core/agent-setup.d.ts +5 -0
- package/build/core/agent-setup.d.ts.map +1 -0
- package/build/core/agent-setup.js +95 -0
- package/build/core/agent-setup.js.map +1 -0
- package/build/core/artifacts.d.ts +64 -0
- package/build/core/artifacts.d.ts.map +1 -0
- package/build/core/artifacts.js +370 -0
- package/build/core/artifacts.js.map +1 -0
- package/build/core/bounded-source.d.ts +15 -0
- package/build/core/bounded-source.d.ts.map +1 -0
- package/build/core/bounded-source.js +78 -0
- package/build/core/bounded-source.js.map +1 -0
- package/build/core/changed-since.d.ts +20 -0
- package/build/core/changed-since.d.ts.map +1 -0
- package/build/core/changed-since.js +43 -0
- package/build/core/changed-since.js.map +1 -0
- package/build/core/chat-model.d.ts +8 -0
- package/build/core/chat-model.d.ts.map +1 -0
- package/build/core/chat-model.js +135 -0
- package/build/core/chat-model.js.map +1 -0
- package/build/core/clustering.d.ts +6 -0
- package/build/core/clustering.d.ts.map +1 -0
- package/build/core/clustering.js +201 -0
- package/build/core/clustering.js.map +1 -0
- package/build/core/context-metadata.d.ts +50 -0
- package/build/core/context-metadata.d.ts.map +1 -0
- package/build/core/context-metadata.js +118 -0
- package/build/core/context-metadata.js.map +1 -0
- package/build/core/data-dir.d.ts +5 -0
- package/build/core/data-dir.d.ts.map +1 -0
- package/build/core/data-dir.js +61 -0
- package/build/core/data-dir.js.map +1 -0
- package/build/core/db-native.d.ts +28 -0
- package/build/core/db-native.d.ts.map +1 -0
- package/build/core/db-native.js +120 -0
- package/build/core/db-native.js.map +1 -0
- package/build/core/db.d.ts +294 -0
- package/build/core/db.d.ts.map +1 -0
- package/build/core/db.js +1047 -0
- package/build/core/db.js.map +1 -0
- package/build/core/doctor.d.ts +13 -0
- package/build/core/doctor.d.ts.map +1 -0
- package/build/core/doctor.js +55 -0
- package/build/core/doctor.js.map +1 -0
- package/build/core/efficiency.d.ts +16 -0
- package/build/core/efficiency.d.ts.map +1 -0
- package/build/core/efficiency.js +170 -0
- package/build/core/efficiency.js.map +1 -0
- package/build/core/embedding-tracker.d.ts +25 -0
- package/build/core/embedding-tracker.d.ts.map +1 -0
- package/build/core/embedding-tracker.js +228 -0
- package/build/core/embedding-tracker.js.map +1 -0
- package/build/core/embeddings.d.ts +90 -0
- package/build/core/embeddings.d.ts.map +1 -0
- package/build/core/embeddings.js +693 -0
- package/build/core/embeddings.js.map +1 -0
- package/build/core/evidence-state.d.ts +42 -0
- package/build/core/evidence-state.d.ts.map +1 -0
- package/build/core/evidence-state.js +153 -0
- package/build/core/evidence-state.js.map +1 -0
- package/build/core/extractor-stamp.d.ts +10 -0
- package/build/core/extractor-stamp.d.ts.map +1 -0
- package/build/core/extractor-stamp.js +51 -0
- package/build/core/extractor-stamp.js.map +1 -0
- package/build/core/feature-brief-cache.d.ts +37 -0
- package/build/core/feature-brief-cache.d.ts.map +1 -0
- package/build/core/feature-brief-cache.js +100 -0
- package/build/core/feature-brief-cache.js.map +1 -0
- package/build/core/file-fingerprint.d.ts +15 -0
- package/build/core/file-fingerprint.d.ts.map +1 -0
- package/build/core/file-fingerprint.js +24 -0
- package/build/core/file-fingerprint.js.map +1 -0
- package/build/core/graph-analytics.d.ts +46 -0
- package/build/core/graph-analytics.d.ts.map +1 -0
- package/build/core/graph-analytics.js +371 -0
- package/build/core/graph-analytics.js.map +1 -0
- package/build/core/hub.d.ts +23 -0
- package/build/core/hub.d.ts.map +1 -0
- package/build/core/hub.js +123 -0
- package/build/core/hub.js.map +1 -0
- package/build/core/ignore-dirs.d.ts +7 -0
- package/build/core/ignore-dirs.d.ts.map +1 -0
- package/build/core/ignore-dirs.js +84 -0
- package/build/core/ignore-dirs.js.map +1 -0
- package/build/core/index-freshness.d.ts +15 -0
- package/build/core/index-freshness.d.ts.map +1 -0
- package/build/core/index-freshness.js +96 -0
- package/build/core/index-freshness.js.map +1 -0
- package/build/core/index-reconcile.d.ts +28 -0
- package/build/core/index-reconcile.d.ts.map +1 -0
- package/build/core/index-reconcile.js +129 -0
- package/build/core/index-reconcile.js.map +1 -0
- package/build/core/local-daemon.d.ts +5 -0
- package/build/core/local-daemon.d.ts.map +1 -0
- package/build/core/local-daemon.js +282 -0
- package/build/core/local-daemon.js.map +1 -0
- package/build/core/memory-graph.d.ts +68 -0
- package/build/core/memory-graph.d.ts.map +1 -0
- package/build/core/memory-graph.js +152 -0
- package/build/core/memory-graph.js.map +1 -0
- package/build/core/native-repair.d.ts +12 -0
- package/build/core/native-repair.d.ts.map +1 -0
- package/build/core/native-repair.js +167 -0
- package/build/core/native-repair.js.map +1 -0
- package/build/core/native-runtime.d.ts +12 -0
- package/build/core/native-runtime.d.ts.map +1 -0
- package/build/core/native-runtime.js +38 -0
- package/build/core/native-runtime.js.map +1 -0
- package/build/core/pagerank.d.ts +29 -0
- package/build/core/pagerank.d.ts.map +1 -0
- package/build/core/pagerank.js +90 -0
- package/build/core/pagerank.js.map +1 -0
- package/build/core/parser-process.d.ts +21 -0
- package/build/core/parser-process.d.ts.map +1 -0
- package/build/core/parser-process.js +103 -0
- package/build/core/parser-process.js.map +1 -0
- package/build/core/parser-worker.d.ts +2 -0
- package/build/core/parser-worker.d.ts.map +1 -0
- package/build/core/parser-worker.js +17 -0
- package/build/core/parser-worker.js.map +1 -0
- package/build/core/parser.d.ts +66 -0
- package/build/core/parser.d.ts.map +1 -0
- package/build/core/parser.js +750 -0
- package/build/core/parser.js.map +1 -0
- package/build/core/path-guard.d.ts +6 -0
- package/build/core/path-guard.d.ts.map +1 -0
- package/build/core/path-guard.js +55 -0
- package/build/core/path-guard.js.map +1 -0
- package/build/core/process-lifecycle.d.ts +30 -0
- package/build/core/process-lifecycle.d.ts.map +1 -0
- package/build/core/process-lifecycle.js +129 -0
- package/build/core/process-lifecycle.js.map +1 -0
- package/build/core/project-config.d.ts +83 -0
- package/build/core/project-config.d.ts.map +1 -0
- package/build/core/project-config.js +302 -0
- package/build/core/project-config.js.map +1 -0
- package/build/core/project-graph.d.ts +69 -0
- package/build/core/project-graph.d.ts.map +1 -0
- package/build/core/project-graph.js +874 -0
- package/build/core/project-graph.js.map +1 -0
- package/build/core/provider-config.d.ts +15 -0
- package/build/core/provider-config.d.ts.map +1 -0
- package/build/core/provider-config.js +67 -0
- package/build/core/provider-config.js.map +1 -0
- package/build/core/provider-usage.d.ts +21 -0
- package/build/core/provider-usage.d.ts.map +1 -0
- package/build/core/provider-usage.js +52 -0
- package/build/core/provider-usage.js.map +1 -0
- package/build/core/python-language-server.d.ts +23 -0
- package/build/core/python-language-server.d.ts.map +1 -0
- package/build/core/python-language-server.js +217 -0
- package/build/core/python-language-server.js.map +1 -0
- package/build/core/python-runtime-identity.d.ts +3 -0
- package/build/core/python-runtime-identity.d.ts.map +1 -0
- package/build/core/python-runtime-identity.js +53 -0
- package/build/core/python-runtime-identity.js.map +1 -0
- package/build/core/reconcile-scheduler.d.ts +20 -0
- package/build/core/reconcile-scheduler.d.ts.map +1 -0
- package/build/core/reconcile-scheduler.js +58 -0
- package/build/core/reconcile-scheduler.js.map +1 -0
- package/build/core/request-context.d.ts +7 -0
- package/build/core/request-context.d.ts.map +1 -0
- package/build/core/request-context.js +17 -0
- package/build/core/request-context.js.map +1 -0
- package/build/core/request-root.d.ts +19 -0
- package/build/core/request-root.d.ts.map +1 -0
- package/build/core/request-root.js +26 -0
- package/build/core/request-root.js.map +1 -0
- package/build/core/root-guard.d.ts +9 -0
- package/build/core/root-guard.d.ts.map +1 -0
- package/build/core/root-guard.js +64 -0
- package/build/core/root-guard.js.map +1 -0
- package/build/core/roots-detect.d.ts +17 -0
- package/build/core/roots-detect.d.ts.map +1 -0
- package/build/core/roots-detect.js +63 -0
- package/build/core/roots-detect.js.map +1 -0
- package/build/core/runtime-session.d.ts +5 -0
- package/build/core/runtime-session.d.ts.map +1 -0
- package/build/core/runtime-session.js +10 -0
- package/build/core/runtime-session.js.map +1 -0
- package/build/core/scip-index.d.ts +71 -0
- package/build/core/scip-index.d.ts.map +1 -0
- package/build/core/scip-index.js +343 -0
- package/build/core/scip-index.js.map +1 -0
- package/build/core/semantic-diff.d.ts +32 -0
- package/build/core/semantic-diff.d.ts.map +1 -0
- package/build/core/semantic-diff.js +259 -0
- package/build/core/semantic-diff.js.map +1 -0
- package/build/core/source-context.d.ts +3 -0
- package/build/core/source-context.d.ts.map +1 -0
- package/build/core/source-context.js +86 -0
- package/build/core/source-context.js.map +1 -0
- package/build/core/source-mask.d.ts +8 -0
- package/build/core/source-mask.d.ts.map +1 -0
- package/build/core/source-mask.js +156 -0
- package/build/core/source-mask.js.map +1 -0
- package/build/core/source-mutation.d.ts +16 -0
- package/build/core/source-mutation.d.ts.map +1 -0
- package/build/core/source-mutation.js +193 -0
- package/build/core/source-mutation.js.map +1 -0
- package/build/core/sql-schema.d.ts +59 -0
- package/build/core/sql-schema.d.ts.map +1 -0
- package/build/core/sql-schema.js +218 -0
- package/build/core/sql-schema.js.map +1 -0
- package/build/core/startup-health.d.ts +40 -0
- package/build/core/startup-health.d.ts.map +1 -0
- package/build/core/startup-health.js +132 -0
- package/build/core/startup-health.js.map +1 -0
- package/build/core/team-ledger.d.ts +60 -0
- package/build/core/team-ledger.d.ts.map +1 -0
- package/build/core/team-ledger.js +171 -0
- package/build/core/team-ledger.js.map +1 -0
- package/build/core/test-impact.d.ts +23 -0
- package/build/core/test-impact.d.ts.map +1 -0
- package/build/core/test-impact.js +131 -0
- package/build/core/test-impact.js.map +1 -0
- package/build/core/tool-metrics.d.ts +29 -0
- package/build/core/tool-metrics.d.ts.map +1 -0
- package/build/core/tool-metrics.js +74 -0
- package/build/core/tool-metrics.js.map +1 -0
- package/build/core/tool-profile.d.ts +12 -0
- package/build/core/tool-profile.d.ts.map +1 -0
- package/build/core/tool-profile.js +102 -0
- package/build/core/tool-profile.js.map +1 -0
- package/build/core/tool-trace.d.ts +8 -0
- package/build/core/tool-trace.d.ts.map +1 -0
- package/build/core/tool-trace.js +70 -0
- package/build/core/tool-trace.js.map +1 -0
- package/build/core/tree-sitter-runtime.d.ts +20 -0
- package/build/core/tree-sitter-runtime.d.ts.map +1 -0
- package/build/core/tree-sitter-runtime.js +324 -0
- package/build/core/tree-sitter-runtime.js.map +1 -0
- package/build/core/tree-sitter.d.ts +6 -0
- package/build/core/tree-sitter.d.ts.map +1 -0
- package/build/core/tree-sitter.js +24 -0
- package/build/core/tree-sitter.js.map +1 -0
- package/build/core/typescript-reference-process.d.ts +30 -0
- package/build/core/typescript-reference-process.d.ts.map +1 -0
- package/build/core/typescript-reference-process.js +124 -0
- package/build/core/typescript-reference-process.js.map +1 -0
- package/build/core/typescript-reference-worker.d.ts +2 -0
- package/build/core/typescript-reference-worker.d.ts.map +1 -0
- package/build/core/typescript-reference-worker.js +14 -0
- package/build/core/typescript-reference-worker.js.map +1 -0
- package/build/core/typescript-references.d.ts +71 -0
- package/build/core/typescript-references.d.ts.map +1 -0
- package/build/core/typescript-references.js +392 -0
- package/build/core/typescript-references.js.map +1 -0
- package/build/core/typescript-skeleton.d.ts +5 -0
- package/build/core/typescript-skeleton.d.ts.map +1 -0
- package/build/core/typescript-skeleton.js +49 -0
- package/build/core/typescript-skeleton.js.map +1 -0
- package/build/core/walker.d.ts +16 -0
- package/build/core/walker.d.ts.map +1 -0
- package/build/core/walker.js +152 -0
- package/build/core/walker.js.map +1 -0
- package/build/core/workspace-router.d.ts +28 -0
- package/build/core/workspace-router.d.ts.map +1 -0
- package/build/core/workspace-router.js +93 -0
- package/build/core/workspace-router.js.map +1 -0
- package/build/core/worktree-gc.d.ts +16 -0
- package/build/core/worktree-gc.d.ts.map +1 -0
- package/build/core/worktree-gc.js +69 -0
- package/build/core/worktree-gc.js.map +1 -0
- package/build/core/worktree-overlay.d.ts +22 -0
- package/build/core/worktree-overlay.d.ts.map +1 -0
- package/build/core/worktree-overlay.js +84 -0
- package/build/core/worktree-overlay.js.map +1 -0
- package/build/core/worktree-root-guard.d.ts +8 -0
- package/build/core/worktree-root-guard.d.ts.map +1 -0
- package/build/core/worktree-root-guard.js +82 -0
- package/build/core/worktree-root-guard.js.map +1 -0
- package/build/core/worktree-seed.d.ts +14 -0
- package/build/core/worktree-seed.d.ts.map +1 -0
- package/build/core/worktree-seed.js +98 -0
- package/build/core/worktree-seed.js.map +1 -0
- package/build/git/shadow.d.ts +40 -0
- package/build/git/shadow.d.ts.map +1 -0
- package/build/git/shadow.js +298 -0
- package/build/git/shadow.js.map +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +634 -0
- package/build/index.js.map +1 -0
- package/build/tools/agentic-context.d.ts +86 -0
- package/build/tools/agentic-context.d.ts.map +1 -0
- package/build/tools/agentic-context.js +1546 -0
- package/build/tools/agentic-context.js.map +1 -0
- package/build/tools/blast-radius.d.ts +24 -0
- package/build/tools/blast-radius.d.ts.map +1 -0
- package/build/tools/blast-radius.js +231 -0
- package/build/tools/blast-radius.js.map +1 -0
- package/build/tools/changed-since.d.ts +7 -0
- package/build/tools/changed-since.d.ts.map +1 -0
- package/build/tools/changed-since.js +68 -0
- package/build/tools/changed-since.js.map +1 -0
- package/build/tools/compiler-actions.d.ts +26 -0
- package/build/tools/compiler-actions.d.ts.map +1 -0
- package/build/tools/compiler-actions.js +121 -0
- package/build/tools/compiler-actions.js.map +1 -0
- package/build/tools/context-tree.d.ts +9 -0
- package/build/tools/context-tree.d.ts.map +1 -0
- package/build/tools/context-tree.js +131 -0
- package/build/tools/context-tree.js.map +1 -0
- package/build/tools/context.d.ts +37 -0
- package/build/tools/context.d.ts.map +1 -0
- package/build/tools/context.js +800 -0
- package/build/tools/context.js.map +1 -0
- package/build/tools/diff.d.ts +9 -0
- package/build/tools/diff.d.ts.map +1 -0
- package/build/tools/diff.js +176 -0
- package/build/tools/diff.js.map +1 -0
- package/build/tools/directory-prior.d.ts +16 -0
- package/build/tools/directory-prior.d.ts.map +1 -0
- package/build/tools/directory-prior.js +121 -0
- package/build/tools/directory-prior.js.map +1 -0
- package/build/tools/discovery-documents.d.ts +11 -0
- package/build/tools/discovery-documents.d.ts.map +1 -0
- package/build/tools/discovery-documents.js +71 -0
- package/build/tools/discovery-documents.js.map +1 -0
- package/build/tools/discovery-hints.d.ts +25 -0
- package/build/tools/discovery-hints.d.ts.map +1 -0
- package/build/tools/discovery-hints.js +329 -0
- package/build/tools/discovery-hints.js.map +1 -0
- package/build/tools/efficiency-report.d.ts +13 -0
- package/build/tools/efficiency-report.d.ts.map +1 -0
- package/build/tools/efficiency-report.js +78 -0
- package/build/tools/efficiency-report.js.map +1 -0
- package/build/tools/evidence-retrieval.d.ts +33 -0
- package/build/tools/evidence-retrieval.d.ts.map +1 -0
- package/build/tools/evidence-retrieval.js +200 -0
- package/build/tools/evidence-retrieval.js.map +1 -0
- package/build/tools/exact-references.d.ts +10 -0
- package/build/tools/exact-references.d.ts.map +1 -0
- package/build/tools/exact-references.js +351 -0
- package/build/tools/exact-references.js.map +1 -0
- package/build/tools/explain.d.ts +14 -0
- package/build/tools/explain.d.ts.map +1 -0
- package/build/tools/explain.js +370 -0
- package/build/tools/explain.js.map +1 -0
- package/build/tools/feature-brief.d.ts +7 -0
- package/build/tools/feature-brief.d.ts.map +1 -0
- package/build/tools/feature-brief.js +89 -0
- package/build/tools/feature-brief.js.map +1 -0
- package/build/tools/feature-hub.d.ts +15 -0
- package/build/tools/feature-hub.d.ts.map +1 -0
- package/build/tools/feature-hub.js +404 -0
- package/build/tools/feature-hub.js.map +1 -0
- package/build/tools/file-skeleton.d.ts +7 -0
- package/build/tools/file-skeleton.d.ts.map +1 -0
- package/build/tools/file-skeleton.js +190 -0
- package/build/tools/file-skeleton.js.map +1 -0
- package/build/tools/grep.d.ts +25 -0
- package/build/tools/grep.d.ts.map +1 -0
- package/build/tools/grep.js +341 -0
- package/build/tools/grep.js.map +1 -0
- package/build/tools/impact-delta.d.ts +7 -0
- package/build/tools/impact-delta.d.ts.map +1 -0
- package/build/tools/impact-delta.js +102 -0
- package/build/tools/impact-delta.js.map +1 -0
- package/build/tools/memory-tools.d.ts +69 -0
- package/build/tools/memory-tools.d.ts.map +1 -0
- package/build/tools/memory-tools.js +366 -0
- package/build/tools/memory-tools.js.map +1 -0
- package/build/tools/planning-helpers.d.ts +26 -0
- package/build/tools/planning-helpers.d.ts.map +1 -0
- package/build/tools/planning-helpers.js +269 -0
- package/build/tools/planning-helpers.js.map +1 -0
- package/build/tools/project-graph.d.ts +19 -0
- package/build/tools/project-graph.d.ts.map +1 -0
- package/build/tools/project-graph.js +259 -0
- package/build/tools/project-graph.js.map +1 -0
- package/build/tools/propose-commit.d.ts +9 -0
- package/build/tools/propose-commit.d.ts.map +1 -0
- package/build/tools/propose-commit.js +156 -0
- package/build/tools/propose-commit.js.map +1 -0
- package/build/tools/register-tools.d.ts +18 -0
- package/build/tools/register-tools.d.ts.map +1 -0
- package/build/tools/register-tools.js +1131 -0
- package/build/tools/register-tools.js.map +1 -0
- package/build/tools/reindex.d.ts +76 -0
- package/build/tools/reindex.d.ts.map +1 -0
- package/build/tools/reindex.js +871 -0
- package/build/tools/reindex.js.map +1 -0
- package/build/tools/related.d.ts +6 -0
- package/build/tools/related.d.ts.map +1 -0
- package/build/tools/related.js +143 -0
- package/build/tools/related.js.map +1 -0
- package/build/tools/repo-map.d.ts +59 -0
- package/build/tools/repo-map.d.ts.map +1 -0
- package/build/tools/repo-map.js +270 -0
- package/build/tools/repo-map.js.map +1 -0
- package/build/tools/resolve-symbol.d.ts +41 -0
- package/build/tools/resolve-symbol.d.ts.map +1 -0
- package/build/tools/resolve-symbol.js +250 -0
- package/build/tools/resolve-symbol.js.map +1 -0
- package/build/tools/retrieval-helpers.d.ts +35 -0
- package/build/tools/retrieval-helpers.d.ts.map +1 -0
- package/build/tools/retrieval-helpers.js +302 -0
- package/build/tools/retrieval-helpers.js.map +1 -0
- package/build/tools/scip-index.d.ts +12 -0
- package/build/tools/scip-index.d.ts.map +1 -0
- package/build/tools/scip-index.js +66 -0
- package/build/tools/scip-index.js.map +1 -0
- package/build/tools/scoped-discovery.d.ts +7 -0
- package/build/tools/scoped-discovery.d.ts.map +1 -0
- package/build/tools/scoped-discovery.js +89 -0
- package/build/tools/scoped-discovery.js.map +1 -0
- package/build/tools/search.d.ts +62 -0
- package/build/tools/search.d.ts.map +1 -0
- package/build/tools/search.js +419 -0
- package/build/tools/search.js.map +1 -0
- package/build/tools/semantic-diff.d.ts +7 -0
- package/build/tools/semantic-diff.d.ts.map +1 -0
- package/build/tools/semantic-diff.js +45 -0
- package/build/tools/semantic-diff.js.map +1 -0
- package/build/tools/semantic-identifiers.d.ts +51 -0
- package/build/tools/semantic-identifiers.d.ts.map +1 -0
- package/build/tools/semantic-identifiers.js +522 -0
- package/build/tools/semantic-identifiers.js.map +1 -0
- package/build/tools/semantic-navigate.d.ts +18 -0
- package/build/tools/semantic-navigate.d.ts.map +1 -0
- package/build/tools/semantic-navigate.js +413 -0
- package/build/tools/semantic-navigate.js.map +1 -0
- package/build/tools/semantic-search.d.ts +30 -0
- package/build/tools/semantic-search.d.ts.map +1 -0
- package/build/tools/semantic-search.js +466 -0
- package/build/tools/semantic-search.js.map +1 -0
- package/build/tools/sql-schema.d.ts +23 -0
- package/build/tools/sql-schema.d.ts.map +1 -0
- package/build/tools/sql-schema.js +155 -0
- package/build/tools/sql-schema.js.map +1 -0
- package/build/tools/static-analysis.d.ts +7 -0
- package/build/tools/static-analysis.d.ts.map +1 -0
- package/build/tools/static-analysis.js +331 -0
- package/build/tools/static-analysis.js.map +1 -0
- package/build/tools/status.d.ts +74 -0
- package/build/tools/status.d.ts.map +1 -0
- package/build/tools/status.js +227 -0
- package/build/tools/status.js.map +1 -0
- package/build/tools/symbolic-edit.d.ts +57 -0
- package/build/tools/symbolic-edit.d.ts.map +1 -0
- package/build/tools/symbolic-edit.js +500 -0
- package/build/tools/symbolic-edit.js.map +1 -0
- package/build/tools/test-impact.d.ts +7 -0
- package/build/tools/test-impact.d.ts.map +1 -0
- package/build/tools/test-impact.js +34 -0
- package/build/tools/test-impact.js.map +1 -0
- package/build/tools/test-map.d.ts +8 -0
- package/build/tools/test-map.d.ts.map +1 -0
- package/build/tools/test-map.js +75 -0
- package/build/tools/test-map.js.map +1 -0
- package/docs/README.md +35 -0
- package/docs/architecture.md +35 -0
- package/docs/configuration.md +207 -0
- package/docs/maintenance.md +77 -0
- package/package.json +80 -4
package/build/index.js
ADDED
|
@@ -0,0 +1,634 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// ContextPro MCP - Semantic codebase navigator for AI agents
|
|
3
|
+
// Structural AST tree, blast radius, semantic search, commit gatekeeper
|
|
4
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
5
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
6
|
+
import { existsSync, readFileSync, statSync } from "fs";
|
|
7
|
+
import { readFile, stat, writeFile } from "fs/promises";
|
|
8
|
+
import { dirname, join, resolve } from "path";
|
|
9
|
+
import { fileURLToPath } from "url";
|
|
10
|
+
import { cancelAllEmbeddings } from "./core/embeddings.js";
|
|
11
|
+
import { createEmbeddingTrackerController } from "./core/embedding-tracker.js";
|
|
12
|
+
import { createIdleMonitor, getIdleShutdownMs, getParentPollMs, isBrokenPipeError, runCleanup, startParentMonitor } from "./core/process-lifecycle.js";
|
|
13
|
+
import { getContextTree } from "./tools/context-tree.js";
|
|
14
|
+
import { waitForIndexingCompletion } from "./tools/reindex.js";
|
|
15
|
+
import { ensureProjectConfig, registerWorkspace, verifyProjectContext } from "./core/project-config.js";
|
|
16
|
+
import { formatStartupHealthReport, runStartupHealthCheck } from "./core/startup-health.js";
|
|
17
|
+
import { formatDoctorReport, runDoctor } from "./core/doctor.js";
|
|
18
|
+
import { recordToolTiming, setToolCallSink } from "./core/tool-metrics.js";
|
|
19
|
+
import { withToolTrace } from "./core/tool-trace.js";
|
|
20
|
+
import { runtimeSessionId } from "./core/runtime-session.js";
|
|
21
|
+
import { installAgentInstructions, mergeMcpConfig } from "./core/agent-setup.js";
|
|
22
|
+
import { registerTools } from "./tools/register-tools.js";
|
|
23
|
+
import { isUnexpandedVariable, selectRootDir, validateSelectedRoot } from "./core/root-guard.js";
|
|
24
|
+
import { resolveRequestRoot } from "./core/request-root.js";
|
|
25
|
+
import { runWithRequestRoot } from "./core/request-context.js";
|
|
26
|
+
import { resolveProjectPath } from "./core/path-guard.js";
|
|
27
|
+
import { captureSource, publishSource, withSourceMutation } from "./core/source-mutation.js";
|
|
28
|
+
import { CONTEXTPRO_DIR, ensureContextProDir } from "./core/data-dir.js";
|
|
29
|
+
import { closeDB, getDB } from "./core/db.js";
|
|
30
|
+
import { ensureFreshIndex } from "./core/index-freshness.js";
|
|
31
|
+
import { addToSessionSavings, appendEfficiencyFooter, estimateResponseTokens, estimateToolEfficiency } from "./core/efficiency.js";
|
|
32
|
+
const AGENT_CONFIG_PATH = {
|
|
33
|
+
claude: ".mcp.json",
|
|
34
|
+
cursor: ".cursor/mcp.json",
|
|
35
|
+
vscode: ".vscode/mcp.json",
|
|
36
|
+
windsurf: ".windsurf/mcp.json",
|
|
37
|
+
opencode: "opencode.json",
|
|
38
|
+
};
|
|
39
|
+
const SUB_COMMANDS = ["init", "skeleton", "tree", "doctor"];
|
|
40
|
+
const INSTRUCTIONS_RESOURCE_URI = "contextpro://instructions";
|
|
41
|
+
const INSTRUCTIONS_REMOTE_URL = process.env.CONTEXTPRO_INSTRUCTIONS_REMOTE_URL ?? "https://contextpro.dev/api/instructions";
|
|
42
|
+
const PACKAGE_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
43
|
+
function readPackageVersion() {
|
|
44
|
+
try {
|
|
45
|
+
const pkg = JSON.parse(readFileSync(resolve(PACKAGE_ROOT, "package.json"), "utf8"));
|
|
46
|
+
return typeof pkg.version === "string" ? pkg.version : "0.0.0";
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return "0.0.0";
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const PACKAGE_VERSION = readPackageVersion();
|
|
53
|
+
let agentInstructions;
|
|
54
|
+
try {
|
|
55
|
+
agentInstructions = readFileSync(resolve(PACKAGE_ROOT, "agent-instructions.md"), "utf8");
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
process.stderr.write("[contextpro/startup] agent-instructions.md not found; manifest instructions disabled\n");
|
|
59
|
+
}
|
|
60
|
+
let agentGuide;
|
|
61
|
+
try {
|
|
62
|
+
agentGuide = readFileSync(resolve(PACKAGE_ROOT, "agent-guide.md"), "utf8");
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
process.stderr.write("[contextpro/startup] agent-guide.md not found; instructions resource will use the manifest summary\n");
|
|
66
|
+
}
|
|
67
|
+
function isInstructionsRemoteEnabled() {
|
|
68
|
+
const raw = (process.env.CONTEXTPRO_INSTRUCTIONS_REMOTE ?? "").trim().toLowerCase();
|
|
69
|
+
return raw === "1" || raw === "true" || raw === "yes";
|
|
70
|
+
}
|
|
71
|
+
let noteServerActivity = () => { };
|
|
72
|
+
let ensureTrackerRunning = () => { };
|
|
73
|
+
function appendFreshnessNotice(result, freshness) {
|
|
74
|
+
if (!freshness?.refreshed || !result || typeof result !== "object")
|
|
75
|
+
return;
|
|
76
|
+
const content = result.content;
|
|
77
|
+
if (!Array.isArray(content))
|
|
78
|
+
return;
|
|
79
|
+
const item = content.find((candidate) => candidate && typeof candidate === "object" && typeof candidate.text === "string");
|
|
80
|
+
if (!item)
|
|
81
|
+
return;
|
|
82
|
+
try {
|
|
83
|
+
JSON.parse(item.text);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
// Text response; add a concise provenance notice.
|
|
88
|
+
}
|
|
89
|
+
const mode = freshness.fullReindex ? "structural reindex" : "incremental refresh";
|
|
90
|
+
const subject = freshness.fullReindex ? "indexed file" : "changed file";
|
|
91
|
+
item.text = `[ContextPro ${mode}: ${freshness.staleCount} ${subject}${freshness.staleCount === 1 ? "" : "s"} in ${freshness.durationMs}ms]\n\n${item.text}`;
|
|
92
|
+
}
|
|
93
|
+
function parseCliArgs(args) {
|
|
94
|
+
const parsed = {
|
|
95
|
+
rootDir: process.cwd(),
|
|
96
|
+
rootSource: "cwd",
|
|
97
|
+
positional: [],
|
|
98
|
+
};
|
|
99
|
+
let index = 0;
|
|
100
|
+
while (index < args.length) {
|
|
101
|
+
const arg = args[index];
|
|
102
|
+
if (index === 0 && SUB_COMMANDS.includes(arg)) {
|
|
103
|
+
parsed.command = arg;
|
|
104
|
+
index += 1;
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
if (arg.startsWith("--runner=")) {
|
|
108
|
+
parsed.runner = arg.split("=")[1];
|
|
109
|
+
index += 1;
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
if (arg === "--runner") {
|
|
113
|
+
parsed.runner = args[index + 1];
|
|
114
|
+
index += 2;
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
if (arg.startsWith("--root=")) {
|
|
118
|
+
parsed.flagRoot = arg.split("=")[1];
|
|
119
|
+
index += 1;
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
if (arg === "--root") {
|
|
123
|
+
parsed.flagRoot = args[index + 1];
|
|
124
|
+
index += 2;
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if (arg.startsWith("--project-id=")) {
|
|
128
|
+
parsed.projectId = arg.split("=")[1];
|
|
129
|
+
index += 1;
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
if (arg === "--project-id") {
|
|
133
|
+
parsed.projectId = args[index + 1];
|
|
134
|
+
index += 2;
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
if (arg.startsWith("--client-id=")) {
|
|
138
|
+
parsed.clientId = arg.split("=")[1];
|
|
139
|
+
index += 1;
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
if (arg === "--client-id") {
|
|
143
|
+
parsed.clientId = args[index + 1];
|
|
144
|
+
index += 2;
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
if (arg.startsWith("--session-source=")) {
|
|
148
|
+
parsed.sessionSource = arg.split("=")[1];
|
|
149
|
+
index += 1;
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
if (arg === "--session-source") {
|
|
153
|
+
parsed.sessionSource = args[index + 1];
|
|
154
|
+
index += 2;
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
if (arg === "--fix") {
|
|
158
|
+
parsed.fix = true;
|
|
159
|
+
index += 1;
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
if (arg === "--no-agent-instructions") {
|
|
163
|
+
index += 1;
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
// Without this, a mistyped flag became the project root and got a .contextpro/ directory.
|
|
167
|
+
if (arg.startsWith("-"))
|
|
168
|
+
throw new Error(`Unknown option "${arg}". Run contextpro-mcp --help for usage.`);
|
|
169
|
+
parsed.positional.push(arg);
|
|
170
|
+
index += 1;
|
|
171
|
+
}
|
|
172
|
+
if (parsed.command === "init" && parsed.positional.length > 0)
|
|
173
|
+
parsed.positional = parsed.positional.slice(0, 1);
|
|
174
|
+
const rootArgs = parsed.command === "init" ? [] : parsed.positional;
|
|
175
|
+
const selectedRoot = selectRootDir(process.cwd(), rootArgs, parsed.flagRoot);
|
|
176
|
+
parsed.rootDir = selectedRoot.rootDir;
|
|
177
|
+
parsed.rootSource = selectedRoot.source;
|
|
178
|
+
return parsed;
|
|
179
|
+
}
|
|
180
|
+
const USAGE = `ContextPro ${PACKAGE_VERSION}: local MCP server for coding agents.
|
|
181
|
+
|
|
182
|
+
Usage:
|
|
183
|
+
contextpro-mcp [--root <dir>] Start the MCP server on stdio (root defaults to the current directory)
|
|
184
|
+
contextpro-mcp init [claude|cursor|vscode|windsurf|opencode] [--root <dir>] [--runner npx|bunx] [--no-agent-instructions]
|
|
185
|
+
Write the client's project MCP config and agent instructions
|
|
186
|
+
contextpro-mcp doctor [--root <dir>] [--fix]
|
|
187
|
+
Check storage and the native SQLite module
|
|
188
|
+
contextpro-mcp tree [--root <dir>] Print the project's structure (alias: skeleton)
|
|
189
|
+
contextpro-mcp daemon start|status|stop
|
|
190
|
+
contextpro-mcp --version | --help
|
|
191
|
+
|
|
192
|
+
Docs: https://github.com/AlaeddineMessadi/contextpro-mcp#readme`;
|
|
193
|
+
const cliArgs = process.argv.slice(2);
|
|
194
|
+
if (cliArgs.includes("--version") || cliArgs.includes("-v")) {
|
|
195
|
+
console.log(PACKAGE_VERSION);
|
|
196
|
+
process.exit(0);
|
|
197
|
+
}
|
|
198
|
+
if (cliArgs.includes("--help") || cliArgs.includes("-h") || cliArgs[0] === "help") {
|
|
199
|
+
console.log(USAGE);
|
|
200
|
+
process.exit(0);
|
|
201
|
+
}
|
|
202
|
+
if (process.argv[2] === "daemon") {
|
|
203
|
+
try {
|
|
204
|
+
console.log(JSON.stringify(await (await import("./core/local-daemon.js")).daemonCommand(process.argv[3] ?? "status"), null, 2));
|
|
205
|
+
}
|
|
206
|
+
catch (error) {
|
|
207
|
+
console.error(error.message);
|
|
208
|
+
process.exit(1);
|
|
209
|
+
}
|
|
210
|
+
process.exit(0);
|
|
211
|
+
}
|
|
212
|
+
function parseStartupOrExit() {
|
|
213
|
+
try {
|
|
214
|
+
const parsed = parseCliArgs(cliArgs);
|
|
215
|
+
if (parsed.flagRoot && isUnexpandedVariable(parsed.flagRoot))
|
|
216
|
+
console.error(`[contextpro/startup] ignoring unexpanded --root "${parsed.flagRoot}"; using ${parsed.rootDir}`);
|
|
217
|
+
const root = validateSelectedRoot({ rootDir: parsed.rootDir, source: parsed.rootSource }).rootDir;
|
|
218
|
+
if (!existsSync(root) || !statSync(root).isDirectory()) {
|
|
219
|
+
throw new Error(`Project root "${root}" does not exist or is not a directory. Pass --root <existing project directory>.`);
|
|
220
|
+
}
|
|
221
|
+
return { parsedCliArgs: parsed, ROOT_DIR: root };
|
|
222
|
+
}
|
|
223
|
+
catch (error) {
|
|
224
|
+
console.error(error.message);
|
|
225
|
+
process.exit(1);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
const { parsedCliArgs, ROOT_DIR } = parseStartupOrExit();
|
|
229
|
+
// Cache the client's advertised roots briefly so auto-detection doesn't round-trip
|
|
230
|
+
// to the client on every single tool call. The TTL is short because a client can
|
|
231
|
+
// add/remove workspace roots mid-session.
|
|
232
|
+
const ROOTS_CACHE_TTL_MS = 5000;
|
|
233
|
+
let rootsCache = null;
|
|
234
|
+
async function getClientRoots() {
|
|
235
|
+
const now = Date.now();
|
|
236
|
+
if (rootsCache && now - rootsCache.at < ROOTS_CACHE_TTL_MS)
|
|
237
|
+
return rootsCache.uris;
|
|
238
|
+
// Only the client advertising the roots capability can answer; otherwise this
|
|
239
|
+
// throws and resolveAutoRoot falls back to the boot root.
|
|
240
|
+
const caps = server.server.getClientCapabilities?.();
|
|
241
|
+
if (!caps?.roots)
|
|
242
|
+
throw new Error("client does not support roots capability");
|
|
243
|
+
const result = await server.server.listRoots();
|
|
244
|
+
const uris = (result.roots ?? []).map((r) => r.uri).filter((u) => typeof u === "string");
|
|
245
|
+
rootsCache = { uris, at: now };
|
|
246
|
+
return uris;
|
|
247
|
+
}
|
|
248
|
+
function withRequestActivity(handler, options) {
|
|
249
|
+
return async (args) => withToolTrace(options?.toolName ?? "unknown", args, async (trace) => {
|
|
250
|
+
const started = Date.now();
|
|
251
|
+
noteServerActivity();
|
|
252
|
+
const lexicalOnly = args && typeof args === "object" && "preset" in args && args.preset === "keyword_only";
|
|
253
|
+
// Resolve the workspace this request targets. Precedence: an explicit `root`
|
|
254
|
+
// arg → the MCP client's advertised roots (auto-detected) → the server's boot
|
|
255
|
+
// ROOT_DIR. The resolved root is made active for the handler via
|
|
256
|
+
// AsyncLocalStorage, and `root` is stripped so handlers see their normal args.
|
|
257
|
+
const resolution = await resolveRequestRoot(args, ROOT_DIR, {
|
|
258
|
+
rootsProvider: getClientRoots,
|
|
259
|
+
requestCwd: process.cwd(),
|
|
260
|
+
});
|
|
261
|
+
const effectiveRoot = resolution.rootDir;
|
|
262
|
+
trace.rootResolved(effectiveRoot, typeof args?.root === "string"
|
|
263
|
+
&& String(args.root).trim().length > 0);
|
|
264
|
+
// Reject ambiguous routing before starting project work. This controller is
|
|
265
|
+
// bound to the boot checkout; another worktree must not start its tracker.
|
|
266
|
+
if (options?.useEmbeddingTracker && !lexicalOnly && effectiveRoot === ROOT_DIR)
|
|
267
|
+
ensureTrackerRunning();
|
|
268
|
+
const handlerArgs = resolution.handlerArgs;
|
|
269
|
+
return runWithRequestRoot(effectiveRoot, async () => {
|
|
270
|
+
try {
|
|
271
|
+
if (!options?.skipProjectVerification)
|
|
272
|
+
await verifyProjectContext(effectiveRoot);
|
|
273
|
+
let freshness;
|
|
274
|
+
if (options?.ensureFreshIndex) {
|
|
275
|
+
freshness = await ensureFreshIndex(effectiveRoot);
|
|
276
|
+
if (freshness.warning)
|
|
277
|
+
process.stderr.write(`[contextpro/freshness] ${freshness.warning}\n`);
|
|
278
|
+
}
|
|
279
|
+
else if (options?.waitForIndexing !== false) {
|
|
280
|
+
const waitState = await waitForIndexingCompletion(effectiveRoot);
|
|
281
|
+
if (waitState.timedOut) {
|
|
282
|
+
throw new Error("Indexing is still in progress and did not settle before timeout.");
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
trace.handlerStarted();
|
|
286
|
+
let result;
|
|
287
|
+
try {
|
|
288
|
+
result = await handler(handlerArgs);
|
|
289
|
+
}
|
|
290
|
+
finally {
|
|
291
|
+
trace.handlerFinished();
|
|
292
|
+
}
|
|
293
|
+
const toolName = options?.toolName ?? "unknown";
|
|
294
|
+
// Budgeted tools include their own freshness; do not add unbudgeted prose.
|
|
295
|
+
const bounded = toolName === "task_pack" || toolName === "context" || (handlerArgs && typeof handlerArgs === "object" && "max_tokens" in handlerArgs);
|
|
296
|
+
if (!bounded)
|
|
297
|
+
appendFreshnessNotice(result, freshness);
|
|
298
|
+
const failed = !!(result && typeof result === "object" && "isError" in result && result.isError);
|
|
299
|
+
let efficiency;
|
|
300
|
+
try {
|
|
301
|
+
efficiency = await estimateToolEfficiency(effectiveRoot, handlerArgs, result, !failed);
|
|
302
|
+
if (failed)
|
|
303
|
+
efficiency = { ...efficiency, sourceTokens: 0, savedTokens: 0 };
|
|
304
|
+
const sessionSavedTokens = addToSessionSavings(effectiveRoot, efficiency);
|
|
305
|
+
if (!bounded && toolName !== "efficiency_report") {
|
|
306
|
+
appendEfficiencyFooter(result, efficiency, sessionSavedTokens);
|
|
307
|
+
// Include optional footer bytes in persisted traffic, without crediting source twice.
|
|
308
|
+
const outputTokens = estimateResponseTokens(result);
|
|
309
|
+
efficiency = { ...efficiency, outputTokens,
|
|
310
|
+
savedTokens: Math.max(0, efficiency.sourceTokens - efficiency.inputTokens - outputTokens) };
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
catch {
|
|
314
|
+
// Efficiency telemetry is optional and must never affect the tool result.
|
|
315
|
+
}
|
|
316
|
+
recordToolTiming(effectiveRoot, toolName, Date.now() - started, failed ? "error" : "ok", efficiency);
|
|
317
|
+
return result;
|
|
318
|
+
}
|
|
319
|
+
catch (error) {
|
|
320
|
+
let traffic;
|
|
321
|
+
try {
|
|
322
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
323
|
+
const estimate = await estimateToolEfficiency(effectiveRoot, handlerArgs, { content: [{ type: "text", text: message }] });
|
|
324
|
+
traffic = { ...estimate, sourceTokens: 0, savedTokens: 0, representedFiles: 0 };
|
|
325
|
+
}
|
|
326
|
+
catch { /* A broken store must not hide the original error. */ }
|
|
327
|
+
recordToolTiming(effectiveRoot, options?.toolName ?? "unknown", Date.now() - started, "error", traffic);
|
|
328
|
+
throw error;
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
function parseAgentTarget(input) {
|
|
334
|
+
const normalized = (input ?? "claude").toLowerCase();
|
|
335
|
+
if (normalized === "claude" || normalized === "claude-code")
|
|
336
|
+
return "claude";
|
|
337
|
+
if (normalized === "cursor")
|
|
338
|
+
return "cursor";
|
|
339
|
+
if (normalized === "vscode" || normalized === "vs-code" || normalized === "vs")
|
|
340
|
+
return "vscode";
|
|
341
|
+
if (normalized === "windsurf")
|
|
342
|
+
return "windsurf";
|
|
343
|
+
if (normalized === "opencode" || normalized === "open-code")
|
|
344
|
+
return "opencode";
|
|
345
|
+
throw new Error(`Unsupported coding agent \"${input}\". Use one of: claude, cursor, vscode, windsurf, opencode.`);
|
|
346
|
+
}
|
|
347
|
+
function parseRunner(args) {
|
|
348
|
+
const parsed = parseCliArgs(args);
|
|
349
|
+
if (parsed.runner) {
|
|
350
|
+
if (parsed.runner === "npx" || parsed.runner === "bunx")
|
|
351
|
+
return parsed.runner;
|
|
352
|
+
throw new Error(`Unsupported runner \"${parsed.runner}\". Use --runner=npx or --runner=bunx.`);
|
|
353
|
+
}
|
|
354
|
+
const userAgent = (process.env.npm_config_user_agent ?? "").toLowerCase();
|
|
355
|
+
const execPath = (process.env.npm_execpath ?? "").toLowerCase();
|
|
356
|
+
if (userAgent.includes("bun/") || execPath.includes("bun"))
|
|
357
|
+
return "bunx";
|
|
358
|
+
return "npx";
|
|
359
|
+
}
|
|
360
|
+
function buildMcpConfig(runner, target) {
|
|
361
|
+
const commandArgs = runner === "npx" ? ["-y", "contextpro-mcp"] : ["contextpro-mcp"];
|
|
362
|
+
const env = { CONTEXTPRO_TOOL_PROFILE: "lean" };
|
|
363
|
+
// VS Code and Cursor expand ${workspaceFolder}, so GUI launches outside the project still get the right root.
|
|
364
|
+
// VS Code reads `servers`; the other clients read `mcpServers`.
|
|
365
|
+
const workspaceRoot = ["--root", "${workspaceFolder}"];
|
|
366
|
+
const config = target === "vscode"
|
|
367
|
+
? { servers: { contextpro: { type: "stdio", command: runner, args: [...commandArgs, ...workspaceRoot], env } } }
|
|
368
|
+
: { mcpServers: { contextpro: { command: runner, args: target === "cursor" ? [...commandArgs, ...workspaceRoot] : commandArgs, env } } };
|
|
369
|
+
return JSON.stringify(config, null, 2);
|
|
370
|
+
}
|
|
371
|
+
async function runDoctorCommand(args) {
|
|
372
|
+
const parsed = parseCliArgs(["doctor", ...args]);
|
|
373
|
+
const report = await runDoctor(parsed.rootDir, parsed.fix === true);
|
|
374
|
+
process.stdout.write(formatDoctorReport(report) + "\n");
|
|
375
|
+
}
|
|
376
|
+
function buildOpenCodeConfig(runner) {
|
|
377
|
+
const command = runner === "npx" ? ["npx", "-y", "contextpro-mcp"] : ["bunx", "contextpro-mcp"];
|
|
378
|
+
return JSON.stringify({
|
|
379
|
+
$schema: "https://opencode.ai/config.json",
|
|
380
|
+
mcp: {
|
|
381
|
+
contextpro: {
|
|
382
|
+
type: "local",
|
|
383
|
+
command,
|
|
384
|
+
enabled: true,
|
|
385
|
+
environment: { CONTEXTPRO_TOOL_PROFILE: "lean" },
|
|
386
|
+
},
|
|
387
|
+
},
|
|
388
|
+
}, null, 2);
|
|
389
|
+
}
|
|
390
|
+
async function runInitCommand(args) {
|
|
391
|
+
const parsed = parseCliArgs(["init", ...args]);
|
|
392
|
+
const target = parseAgentTarget(parsed.positional[0]);
|
|
393
|
+
const runner = parseRunner(args);
|
|
394
|
+
const root = parsed.rootDir;
|
|
395
|
+
const migratedFrom = await ensureContextProDir(root);
|
|
396
|
+
const outputPath = resolveProjectPath(root, AGENT_CONFIG_PATH[target], "MCP config");
|
|
397
|
+
await withSourceMutation(root, async () => {
|
|
398
|
+
const snapshot = captureSource(root, outputPath);
|
|
399
|
+
let content = target === "opencode" ? buildOpenCodeConfig(runner) : buildMcpConfig(runner, target);
|
|
400
|
+
try {
|
|
401
|
+
const prior = await readFile(outputPath, "utf8");
|
|
402
|
+
content = JSON.stringify(mergeMcpConfig(JSON.parse(prior), JSON.parse(content), target), null, 2);
|
|
403
|
+
}
|
|
404
|
+
catch (error) {
|
|
405
|
+
if (error.code !== "ENOENT")
|
|
406
|
+
throw error;
|
|
407
|
+
}
|
|
408
|
+
await publishSource(root, snapshot, `${content}\n`);
|
|
409
|
+
});
|
|
410
|
+
if (!args.includes("--no-agent-instructions")) {
|
|
411
|
+
const files = await installAgentInstructions(root, target);
|
|
412
|
+
console.error(`Installed ContextPro workflow in ${files.join(", ")} (existing instructions preserved).`);
|
|
413
|
+
}
|
|
414
|
+
const contextProDir = join(root, CONTEXTPRO_DIR);
|
|
415
|
+
const configPath = join(contextProDir, "config.json");
|
|
416
|
+
try {
|
|
417
|
+
await stat(configPath);
|
|
418
|
+
}
|
|
419
|
+
catch {
|
|
420
|
+
await writeFile(configPath, JSON.stringify({ provider: "ollama", embedModel: "nomic-embed-text:latest" }, null, 2) + "\n");
|
|
421
|
+
}
|
|
422
|
+
await ensureProjectConfig({
|
|
423
|
+
rootDir: root,
|
|
424
|
+
projectId: parsed.projectId,
|
|
425
|
+
clientId: parsed.clientId,
|
|
426
|
+
sessionSource: parsed.sessionSource ?? "mcp",
|
|
427
|
+
});
|
|
428
|
+
console.error(`ContextPro initialized for ${target} using ${runner}.`);
|
|
429
|
+
console.error(`Wrote MCP config: ${outputPath}`);
|
|
430
|
+
if (migratedFrom)
|
|
431
|
+
console.error(`Migrated ${migratedFrom}/ to ${CONTEXTPRO_DIR}/.`);
|
|
432
|
+
console.error(`Created .contextpro/ directory with config.json`);
|
|
433
|
+
}
|
|
434
|
+
const server = new McpServer({
|
|
435
|
+
name: "contextpro",
|
|
436
|
+
version: PACKAGE_VERSION,
|
|
437
|
+
}, {
|
|
438
|
+
capabilities: { logging: {} },
|
|
439
|
+
...(agentInstructions && { instructions: agentInstructions }),
|
|
440
|
+
});
|
|
441
|
+
server.resource("contextpro_instructions", INSTRUCTIONS_RESOURCE_URI, async (uri) => {
|
|
442
|
+
// This bundled guide is independent of the repository. Resource reads have
|
|
443
|
+
// no tool root argument, so they must remain available during routing errors.
|
|
444
|
+
noteServerActivity();
|
|
445
|
+
if (isInstructionsRemoteEnabled()) {
|
|
446
|
+
try {
|
|
447
|
+
const response = await fetch(INSTRUCTIONS_REMOTE_URL);
|
|
448
|
+
if (response.ok) {
|
|
449
|
+
return {
|
|
450
|
+
contents: [{
|
|
451
|
+
uri: uri.href,
|
|
452
|
+
mimeType: "text/markdown",
|
|
453
|
+
text: await response.text(),
|
|
454
|
+
}],
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
process.stderr.write(`[contextpro/instructions] remote fetch failed (${response.status}); falling back to bundled\n`);
|
|
458
|
+
}
|
|
459
|
+
catch (error) {
|
|
460
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
461
|
+
process.stderr.write(`[contextpro/instructions] remote fetch error: ${message}; falling back to bundled\n`);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
return {
|
|
465
|
+
contents: [{
|
|
466
|
+
uri: uri.href,
|
|
467
|
+
mimeType: "text/markdown",
|
|
468
|
+
text: agentGuide ?? agentInstructions ?? "ContextPro instructions are not bundled with this build.",
|
|
469
|
+
}],
|
|
470
|
+
};
|
|
471
|
+
});
|
|
472
|
+
registerTools(server, ROOT_DIR, withRequestActivity);
|
|
473
|
+
// Persist every tool call to the per-root DB so external readers can
|
|
474
|
+
// show real tool-call history across restarts. Best-effort and fire-and-forget:
|
|
475
|
+
// getDB is async + cached, and a failure here must never disturb the tool itself.
|
|
476
|
+
// Prune occasionally to keep the table bounded.
|
|
477
|
+
let toolCallWrites = 0;
|
|
478
|
+
setToolCallSink((event) => {
|
|
479
|
+
void (async () => {
|
|
480
|
+
try {
|
|
481
|
+
const db = await getDB(event.rootDir);
|
|
482
|
+
db.recordToolCall(event.tool, event.status, event.durationMs, event.calledAt, event.efficiency, runtimeSessionId);
|
|
483
|
+
if (++toolCallWrites % 200 === 0)
|
|
484
|
+
db.pruneToolCalls(5000);
|
|
485
|
+
}
|
|
486
|
+
catch {
|
|
487
|
+
// telemetry is non-critical
|
|
488
|
+
}
|
|
489
|
+
})();
|
|
490
|
+
});
|
|
491
|
+
async function main() {
|
|
492
|
+
const args = process.argv.slice(2);
|
|
493
|
+
if (parsedCliArgs.command === "init" || parsedCliArgs.command === "doctor") {
|
|
494
|
+
try {
|
|
495
|
+
await (parsedCliArgs.command === "init" ? runInitCommand : runDoctorCommand)(args.slice(1));
|
|
496
|
+
}
|
|
497
|
+
catch (error) {
|
|
498
|
+
console.error(error.message);
|
|
499
|
+
process.exit(1);
|
|
500
|
+
}
|
|
501
|
+
process.exit(0);
|
|
502
|
+
}
|
|
503
|
+
if (parsedCliArgs.command === "skeleton" || parsedCliArgs.command === "tree") {
|
|
504
|
+
const targetRoot = parsedCliArgs.rootDir;
|
|
505
|
+
const tree = await getContextTree({
|
|
506
|
+
rootDir: targetRoot,
|
|
507
|
+
includeSymbols: true,
|
|
508
|
+
maxTokens: 50000,
|
|
509
|
+
});
|
|
510
|
+
process.stdout.write(tree + "\n");
|
|
511
|
+
closeDB(targetRoot);
|
|
512
|
+
process.exit(0);
|
|
513
|
+
}
|
|
514
|
+
const migratedFrom = await ensureContextProDir(ROOT_DIR);
|
|
515
|
+
if (migratedFrom)
|
|
516
|
+
console.error(`[contextpro/startup] migrated ${migratedFrom}/ to ${CONTEXTPRO_DIR}/`);
|
|
517
|
+
const projectConfig = await ensureProjectConfig({
|
|
518
|
+
rootDir: ROOT_DIR,
|
|
519
|
+
projectId: parsedCliArgs.projectId ?? process.env.CONTEXTPRO_PROJECT_ID ?? process.env.CONTEXTPLUS_PROJECT_ID,
|
|
520
|
+
clientId: parsedCliArgs.clientId ?? process.env.CONTEXTPRO_CLIENT_ID ?? process.env.CONTEXTPLUS_CLIENT_ID,
|
|
521
|
+
sessionSource: parsedCliArgs.sessionSource ?? process.env.CONTEXTPRO_SESSION_SOURCE ?? process.env.CONTEXTPLUS_SESSION_SOURCE ?? "mcp",
|
|
522
|
+
});
|
|
523
|
+
await registerWorkspace(projectConfig);
|
|
524
|
+
const startupHealth = await runStartupHealthCheck(ROOT_DIR);
|
|
525
|
+
console.error(formatStartupHealthReport(startupHealth));
|
|
526
|
+
const trackerController = createEmbeddingTrackerController({
|
|
527
|
+
rootDir: ROOT_DIR,
|
|
528
|
+
mode: process.env.CONTEXTPRO_EMBED_TRACKER ?? process.env.CONTEXTPLUS_EMBED_TRACKER,
|
|
529
|
+
debounceMs: Number.parseInt(process.env.CONTEXTPRO_EMBED_TRACKER_DEBOUNCE_MS ?? process.env.CONTEXTPLUS_EMBED_TRACKER_DEBOUNCE_MS ?? "700", 10),
|
|
530
|
+
maxFilesPerTick: Number.parseInt(process.env.CONTEXTPRO_EMBED_TRACKER_MAX_FILES ?? process.env.CONTEXTPLUS_EMBED_TRACKER_MAX_FILES ?? "8", 10),
|
|
531
|
+
reconcileIntervalMs: Number.parseInt(process.env.CONTEXTPRO_RECONCILE_INTERVAL_MS ?? process.env.CONTEXTPLUS_RECONCILE_INTERVAL_MS ?? "30000", 10),
|
|
532
|
+
reconcileMaxFiles: Number.parseInt(process.env.CONTEXTPRO_RECONCILE_MAX_FILES ?? process.env.CONTEXTPLUS_RECONCILE_MAX_FILES ?? "40", 10),
|
|
533
|
+
});
|
|
534
|
+
const transport = new StdioServerTransport();
|
|
535
|
+
await server.connect(transport);
|
|
536
|
+
let shuttingDown = false;
|
|
537
|
+
let stopParentMonitor = () => { };
|
|
538
|
+
const idleMonitor = createIdleMonitor({
|
|
539
|
+
timeoutMs: getIdleShutdownMs(process.env.CONTEXTPRO_IDLE_TIMEOUT_MS ?? process.env.CONTEXTPLUS_IDLE_TIMEOUT_MS),
|
|
540
|
+
onIdle: () => requestShutdown("idle-timeout", 0),
|
|
541
|
+
isTransportAlive: () => process.stdin.readable && !process.stdin.destroyed,
|
|
542
|
+
});
|
|
543
|
+
noteServerActivity = idleMonitor.touch;
|
|
544
|
+
ensureTrackerRunning = trackerController.ensureStarted;
|
|
545
|
+
const closeServer = async () => {
|
|
546
|
+
const closable = server;
|
|
547
|
+
if (typeof closable.close === "function") {
|
|
548
|
+
await closable.close();
|
|
549
|
+
}
|
|
550
|
+
};
|
|
551
|
+
const closeTransport = async () => {
|
|
552
|
+
const closable = transport;
|
|
553
|
+
if (typeof closable.close === "function") {
|
|
554
|
+
await closable.close();
|
|
555
|
+
}
|
|
556
|
+
};
|
|
557
|
+
const shutdown = async (reason, exitCode = 0) => {
|
|
558
|
+
if (shuttingDown)
|
|
559
|
+
return;
|
|
560
|
+
shuttingDown = true;
|
|
561
|
+
console.error(`ContextPro MCP shutdown requested: ${reason}`);
|
|
562
|
+
await runCleanup({
|
|
563
|
+
cancelEmbeddings: cancelAllEmbeddings,
|
|
564
|
+
stopTracker: trackerController.stop,
|
|
565
|
+
closeServer,
|
|
566
|
+
closeTransport,
|
|
567
|
+
stopMonitors: () => {
|
|
568
|
+
idleMonitor.stop();
|
|
569
|
+
stopParentMonitor();
|
|
570
|
+
},
|
|
571
|
+
});
|
|
572
|
+
process.exit(exitCode);
|
|
573
|
+
};
|
|
574
|
+
const requestShutdown = (reason, exitCode = 0) => {
|
|
575
|
+
void shutdown(reason, exitCode);
|
|
576
|
+
};
|
|
577
|
+
stopParentMonitor = startParentMonitor({
|
|
578
|
+
parentPid: process.ppid,
|
|
579
|
+
pollIntervalMs: getParentPollMs(process.env.CONTEXTPRO_PARENT_POLL_MS ?? process.env.CONTEXTPLUS_PARENT_POLL_MS),
|
|
580
|
+
onParentExit: () => requestShutdown("parent-exit", 0),
|
|
581
|
+
});
|
|
582
|
+
process.once("SIGINT", () => requestShutdown("SIGINT", 0));
|
|
583
|
+
process.once("SIGTERM", () => requestShutdown("SIGTERM", 0));
|
|
584
|
+
process.once("SIGHUP", () => requestShutdown("SIGHUP", 0));
|
|
585
|
+
process.once("disconnect", () => requestShutdown("disconnect", 0));
|
|
586
|
+
process.once("exit", () => {
|
|
587
|
+
idleMonitor.stop();
|
|
588
|
+
stopParentMonitor();
|
|
589
|
+
trackerController.stop();
|
|
590
|
+
});
|
|
591
|
+
process.stdin.once("end", () => requestShutdown("stdin-end", 0));
|
|
592
|
+
process.stdin.once("close", () => requestShutdown("stdin-close", 0));
|
|
593
|
+
process.stdin.once("error", (error) => {
|
|
594
|
+
if (isBrokenPipeError(error))
|
|
595
|
+
requestShutdown("stdin-error", 0);
|
|
596
|
+
});
|
|
597
|
+
process.stdout.once("error", (error) => {
|
|
598
|
+
if (isBrokenPipeError(error))
|
|
599
|
+
requestShutdown("stdout-error", 0);
|
|
600
|
+
});
|
|
601
|
+
process.stderr.once("error", (error) => {
|
|
602
|
+
if (isBrokenPipeError(error))
|
|
603
|
+
requestShutdown("stderr-error", 0);
|
|
604
|
+
});
|
|
605
|
+
noteServerActivity();
|
|
606
|
+
console.error(`ContextPro MCP server running on stdio | root: ${ROOT_DIR}`);
|
|
607
|
+
}
|
|
608
|
+
main().catch((error) => {
|
|
609
|
+
console.error("Fatal error:", error);
|
|
610
|
+
process.exit(1);
|
|
611
|
+
});
|
|
612
|
+
process.on("uncaughtException", (error) => {
|
|
613
|
+
if (isBrokenPipeError(error)) {
|
|
614
|
+
process.exit(0);
|
|
615
|
+
}
|
|
616
|
+
console.error("Uncaught exception:", error);
|
|
617
|
+
// Last-resort guard ONLY. Reaching here means an error escaped every local
|
|
618
|
+
// try/catch, and Node considers the process state undefined — so a clean exit
|
|
619
|
+
// (which the MCP client recovers from by respawning) is safer than resuming
|
|
620
|
+
// into possible corruption. Do NOT "fix" disconnects by swallowing here:
|
|
621
|
+
// instead ensure the source can't throw uncaught. Known background timers
|
|
622
|
+
// (reconcile sweep, idle monitor, parent monitor) are individually guarded so
|
|
623
|
+
// a routine background failure never reaches this hard-exit path.
|
|
624
|
+
// The `process.once("exit")` handler in main() synchronously stops the idle monitor, parent
|
|
625
|
+
// monitor, and embedding tracker — those run even on this hard exit. Async cleanup (server /
|
|
626
|
+
// transport close) cannot run during a synchronous exit and is reclaimed by the OS.
|
|
627
|
+
process.exit(1);
|
|
628
|
+
});
|
|
629
|
+
process.on("unhandledRejection", (reason) => {
|
|
630
|
+
// Surface unhandled rejections instead of letting Node terminate silently in some versions.
|
|
631
|
+
// Most paths use try/catch; this is a safety net so a stray rejection produces a clear log.
|
|
632
|
+
console.error("Unhandled promise rejection:", reason);
|
|
633
|
+
});
|
|
634
|
+
//# sourceMappingURL=index.js.map
|