devcouncil 0.3.1 → 0.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/README.md +46 -30
- package/package.json +6 -2
- package/packages/codeintel-grammars/hatch_build.py +43 -0
- package/packages/codeintel-grammars/pyproject.toml +16 -0
- package/packages/codeintel-grammars/src/devcouncil_codeintel_grammars/__init__.py +93 -0
- package/pyproject.toml +99 -4
- package/src/devcouncil/app/config.py +512 -20
- package/src/devcouncil/app/events.py +4 -23
- package/src/devcouncil/app/orchestrator.py +5 -0
- package/src/devcouncil/app/run_context.py +3 -3
- package/src/devcouncil/assets/__init__.py +4 -1
- package/src/devcouncil/assets/vendor/force-graph.min.js +5 -0
- package/src/devcouncil/campaign/__init__.py +71 -0
- package/src/devcouncil/campaign/bloom.py +137 -0
- package/src/devcouncil/campaign/dashboard.py +123 -0
- package/src/devcouncil/campaign/mailbox.py +305 -0
- package/src/devcouncil/campaign/notify.py +91 -0
- package/src/devcouncil/campaign/orchestrator.py +592 -0
- package/src/devcouncil/campaign/prompts/coordinator.md +29 -0
- package/src/devcouncil/campaign/prompts/director.md +21 -0
- package/src/devcouncil/campaign/prompts/protocol.md +46 -0
- package/src/devcouncil/campaign/prompts/reviewer.md +24 -0
- package/src/devcouncil/campaign/prompts/worker.md +24 -0
- package/src/devcouncil/campaign/roles.py +202 -0
- package/src/devcouncil/campaign/watcher.py +153 -0
- package/src/devcouncil/cli/commands/agents.py +24 -17
- package/src/devcouncil/cli/commands/artifacts.py +36 -27
- package/src/devcouncil/cli/commands/ast.py +12 -3
- package/src/devcouncil/cli/commands/baseline.py +21 -12
- package/src/devcouncil/cli/commands/boot.py +218 -0
- package/src/devcouncil/cli/commands/campaign.py +302 -0
- package/src/devcouncil/cli/commands/check.py +225 -12
- package/src/devcouncil/cli/commands/config.py +221 -74
- package/src/devcouncil/cli/commands/cost.py +137 -28
- package/src/devcouncil/cli/commands/dashboard.py +12 -4
- package/src/devcouncil/cli/commands/debug_cmd.py +249 -0
- package/src/devcouncil/cli/commands/design.py +27 -17
- package/src/devcouncil/cli/commands/doctor.py +790 -8
- package/src/devcouncil/cli/commands/evidence.py +41 -20
- package/src/devcouncil/cli/commands/export.py +73 -0
- package/src/devcouncil/cli/commands/gaps.py +175 -0
- package/src/devcouncil/cli/commands/gated_write.py +76 -0
- package/src/devcouncil/cli/commands/go.py +220 -68
- package/src/devcouncil/cli/commands/graph_cmd.py +1192 -0
- package/src/devcouncil/cli/commands/handoff.py +45 -34
- package/src/devcouncil/cli/commands/hook.py +630 -85
- package/src/devcouncil/cli/commands/init.py +89 -30
- package/src/devcouncil/cli/commands/integrate.py +296 -1385
- package/src/devcouncil/cli/commands/lease.py +120 -0
- package/src/devcouncil/cli/commands/logs.py +12 -5
- package/src/devcouncil/cli/commands/lsp.py +40 -5
- package/src/devcouncil/cli/commands/map.py +317 -74
- package/src/devcouncil/cli/commands/mcp_server.py +12 -2
- package/src/devcouncil/cli/commands/okf.py +44 -6
- package/src/devcouncil/cli/commands/plan.py +184 -69
- package/src/devcouncil/cli/commands/prompt.py +26 -17
- package/src/devcouncil/cli/commands/provenance.py +79 -0
- package/src/devcouncil/cli/commands/repair.py +60 -49
- package/src/devcouncil/cli/commands/report.py +148 -40
- package/src/devcouncil/cli/commands/requirements.py +104 -0
- package/src/devcouncil/cli/commands/reset_demo_state.py +13 -4
- package/src/devcouncil/cli/commands/rollback.py +46 -35
- package/src/devcouncil/cli/commands/run.py +173 -8
- package/src/devcouncil/cli/commands/runs.py +298 -68
- package/src/devcouncil/cli/commands/scaffold.py +33 -12
- package/src/devcouncil/cli/commands/semantic.py +29 -14
- package/src/devcouncil/cli/commands/setup.py +103 -93
- package/src/devcouncil/cli/commands/shell.py +51 -42
- package/src/devcouncil/cli/commands/show.py +56 -42
- package/src/devcouncil/cli/commands/skills.py +29 -20
- package/src/devcouncil/cli/commands/status.py +80 -67
- package/src/devcouncil/cli/commands/task_gate.py +295 -0
- package/src/devcouncil/cli/commands/tasks.py +248 -19
- package/src/devcouncil/cli/commands/trace.py +14 -8
- package/src/devcouncil/cli/commands/verify.py +33 -8
- package/src/devcouncil/cli/commands/version.py +14 -6
- package/src/devcouncil/cli/commands/watch.py +49 -30
- package/src/devcouncil/cli/commands/watch_fs.py +30 -19
- package/src/devcouncil/cli/commands/wiki.py +278 -0
- package/src/devcouncil/cli/main.py +58 -1
- package/src/devcouncil/codeintel/__init__.py +16 -0
- package/src/devcouncil/codeintel/build_control.py +429 -0
- package/src/devcouncil/codeintel/build_worker.py +78 -0
- package/src/devcouncil/codeintel/debug/__init__.py +17 -0
- package/src/devcouncil/codeintel/debug/broker.py +114 -0
- package/src/devcouncil/codeintel/debug/broker_client.py +61 -0
- package/src/devcouncil/codeintel/debug/consent.py +36 -0
- package/src/devcouncil/codeintel/debug/discovery.py +132 -0
- package/src/devcouncil/codeintel/debug/fingerprint.py +85 -0
- package/src/devcouncil/codeintel/debug/protocol.py +259 -0
- package/src/devcouncil/codeintel/debug/python_trace_runner.py +81 -0
- package/src/devcouncil/codeintel/debug/session.py +238 -0
- package/src/devcouncil/codeintel/debug/tracing.py +201 -0
- package/src/devcouncil/codeintel/languages/__init__.py +17 -0
- package/src/devcouncil/codeintel/languages/generic_extractor.py +236 -0
- package/src/devcouncil/codeintel/languages/registry.py +149 -0
- package/src/devcouncil/codeintel/languages/workers.py +245 -0
- package/src/devcouncil/codeintel/query/__init__.py +5 -0
- package/src/devcouncil/codeintel/query/engine.py +289 -0
- package/src/devcouncil/codeintel/resolution/__init__.py +6 -0
- package/src/devcouncil/codeintel/resolution/abstract_state.py +301 -0
- package/src/devcouncil/codeintel/resolution/frameworks/__init__.py +33 -0
- package/src/devcouncil/codeintel/resolution/frameworks/base.py +46 -0
- package/src/devcouncil/codeintel/resolution/frameworks/di.py +56 -0
- package/src/devcouncil/codeintel/resolution/frameworks/events.py +45 -0
- package/src/devcouncil/codeintel/resolution/frameworks/routes.py +88 -0
- package/src/devcouncil/codeintel/resolution/semantic.py +887 -0
- package/src/devcouncil/codeintel/service.py +104 -0
- package/src/devcouncil/codeintel/store/__init__.py +15 -0
- package/src/devcouncil/codeintel/store/sqlite.py +1565 -0
- package/src/devcouncil/codeintel/sync/__init__.py +19 -0
- package/src/devcouncil/codeintel/sync/coordinator.py +430 -0
- package/src/devcouncil/codeintel/sync/incremental.py +484 -0
- package/src/devcouncil/codeintel/sync/lease.py +96 -0
- package/src/devcouncil/codeintel/sync/scope.py +98 -0
- package/src/devcouncil/council/__init__.py +4 -0
- package/src/devcouncil/council/prompts/__init__.py +4 -0
- package/src/devcouncil/domain/checkpoint_refs.py +17 -0
- package/src/devcouncil/domain/evidence.py +1 -0
- package/src/devcouncil/domain/gap.py +10 -0
- package/src/devcouncil/domain/requirement.py +5 -1
- package/src/devcouncil/domain/task.py +43 -2
- package/src/devcouncil/execution/checkpoints.py +25 -31
- package/src/devcouncil/execution/context_builder.py +15 -44
- package/src/devcouncil/execution/fs_watcher.py +64 -0
- package/src/devcouncil/execution/gated_write.py +203 -0
- package/src/devcouncil/execution/handoff.py +2 -1
- package/src/devcouncil/execution/hook_policy.py +19 -5
- package/src/devcouncil/execution/lease_ops.py +177 -0
- package/src/devcouncil/execution/lease_validation.py +71 -0
- package/src/devcouncil/execution/patch.py +3 -0
- package/src/devcouncil/execution/permissions.py +1 -0
- package/src/devcouncil/execution/policy_engine.py +205 -10
- package/src/devcouncil/execution/prompt_builder.py +278 -33
- package/src/devcouncil/execution/run_trace.py +356 -0
- package/src/devcouncil/execution/shell_session.py +46 -5
- package/src/devcouncil/execution/stop_gate.py +746 -0
- package/src/devcouncil/execution/stop_gate_history.py +113 -0
- package/src/devcouncil/execution/stop_gate_state.py +54 -0
- package/src/devcouncil/execution/stop_gate_verify_cache.py +69 -0
- package/src/devcouncil/execution/task_gate_ops.py +590 -0
- package/src/devcouncil/execution/task_runner.py +19 -0
- package/src/devcouncil/executors/advisor_tool.py +315 -0
- package/src/devcouncil/executors/agent_registry.py +125 -17
- package/src/devcouncil/executors/claude_sdk.py +376 -0
- package/src/devcouncil/executors/coding_cli.py +724 -25
- package/src/devcouncil/executors/mini_swe.py +50 -8
- package/src/devcouncil/executors/native/agent.py +224 -19
- package/src/devcouncil/executors/openhands.py +50 -8
- package/src/devcouncil/executors/transient_retry.py +99 -0
- package/src/devcouncil/gating/checks/clean_git.py +5 -2
- package/src/devcouncil/gating/checks/planned_files_check.py +38 -11
- package/src/devcouncil/gating/checks/secret_scan_check.py +2 -2
- package/src/devcouncil/gating/policy.py +46 -2
- package/src/devcouncil/indexing/ast_matcher.py +41 -4
- package/src/devcouncil/indexing/graph/__init__.py +78 -0
- package/src/devcouncil/indexing/graph/api_routes.py +522 -0
- package/src/devcouncil/indexing/graph/build.py +862 -0
- package/src/devcouncil/indexing/graph/cache.py +329 -0
- package/src/devcouncil/indexing/graph/communities.py +28 -0
- package/src/devcouncil/indexing/graph/cypher.py +107 -0
- package/src/devcouncil/indexing/graph/embeddings.py +194 -0
- package/src/devcouncil/indexing/graph/export.py +381 -0
- package/src/devcouncil/indexing/graph/export_links.py +81 -0
- package/src/devcouncil/indexing/graph/extract_python.py +307 -0
- package/src/devcouncil/indexing/graph/extract_ts.py +1205 -0
- package/src/devcouncil/indexing/graph/intel.py +668 -0
- package/src/devcouncil/indexing/graph/liveness.py +992 -0
- package/src/devcouncil/indexing/graph/okf_export.py +65 -0
- package/src/devcouncil/indexing/graph/pdg/__init__.py +67 -0
- package/src/devcouncil/indexing/graph/pdg/build.py +11 -0
- package/src/devcouncil/indexing/graph/pdg/cdg.py +41 -0
- package/src/devcouncil/indexing/graph/pdg/cfg.py +199 -0
- package/src/devcouncil/indexing/graph/pdg/query.py +21 -0
- package/src/devcouncil/indexing/graph/pdg/reaching_def.py +126 -0
- package/src/devcouncil/indexing/graph/pdg/schema.py +253 -0
- package/src/devcouncil/indexing/graph/pdg/taint.py +154 -0
- package/src/devcouncil/indexing/graph/query.py +302 -0
- package/src/devcouncil/indexing/graph/resolve.py +1020 -0
- package/src/devcouncil/indexing/graph/schema.py +103 -0
- package/src/devcouncil/indexing/graph_index.py +20 -29
- package/src/devcouncil/indexing/lsp.py +57 -25
- package/src/devcouncil/indexing/lsp_client.py +577 -0
- package/src/devcouncil/indexing/map_artifacts.py +355 -0
- package/src/devcouncil/indexing/map_refresh.py +141 -0
- package/src/devcouncil/indexing/repo_mapper.py +1509 -138
- package/src/devcouncil/indexing/semantic_index.py +12 -6
- package/src/devcouncil/indexing/subsystem_map.py +163 -0
- package/src/devcouncil/indexing/ts_imports.py +343 -0
- package/src/devcouncil/indexing/viz.py +960 -0
- package/src/devcouncil/indexing/walk.py +52 -0
- package/src/devcouncil/indexing/wiring.py +1776 -0
- package/src/devcouncil/integrations/actions.py +27 -4
- package/src/devcouncil/integrations/check.py +211 -16
- package/src/devcouncil/integrations/claude_assets.py +209 -12
- package/src/devcouncil/integrations/clients/__init__.py +1 -0
- package/src/devcouncil/integrations/clients/aider.py +52 -0
- package/src/devcouncil/integrations/clients/antigravity.py +87 -0
- package/src/devcouncil/integrations/clients/claude.py +339 -0
- package/src/devcouncil/integrations/clients/codex.py +39 -0
- package/src/devcouncil/integrations/clients/common.py +332 -0
- package/src/devcouncil/integrations/clients/cursor.py +164 -0
- package/src/devcouncil/integrations/clients/gemini.py +49 -0
- package/src/devcouncil/integrations/clients/grok.py +105 -0
- package/src/devcouncil/integrations/clients/hooks.py +500 -0
- package/src/devcouncil/integrations/clients/opencode.py +96 -0
- package/src/devcouncil/integrations/clients/warp.py +75 -0
- package/src/devcouncil/integrations/code_review_graph.py +2 -2
- package/src/devcouncil/integrations/github.py +73 -7
- package/src/devcouncil/integrations/integration_cli.py +197 -0
- package/src/devcouncil/integrations/mcp/handlers/__init__.py +1 -0
- package/src/devcouncil/integrations/mcp/handlers/ast_lsp.py +77 -0
- package/src/devcouncil/integrations/mcp/handlers/checkout.py +50 -0
- package/src/devcouncil/integrations/mcp/handlers/cli_gate.py +43 -0
- package/src/devcouncil/integrations/mcp/handlers/codeintel.py +182 -0
- package/src/devcouncil/integrations/mcp/handlers/debug.py +236 -0
- package/src/devcouncil/integrations/mcp/handlers/evidence.py +70 -0
- package/src/devcouncil/integrations/mcp/handlers/git.py +99 -0
- package/src/devcouncil/integrations/mcp/handlers/graph.py +36 -0
- package/src/devcouncil/integrations/mcp/handlers/handoff.py +53 -0
- package/src/devcouncil/integrations/mcp/handlers/knowledge.py +30 -0
- package/src/devcouncil/integrations/mcp/handlers/lease.py +70 -0
- package/src/devcouncil/integrations/mcp/handlers/live.py +108 -0
- package/src/devcouncil/integrations/mcp/handlers/map.py +676 -0
- package/src/devcouncil/integrations/mcp/handlers/next_task.py +35 -0
- package/src/devcouncil/integrations/mcp/handlers/policy.py +80 -0
- package/src/devcouncil/integrations/mcp/handlers/prompts.py +168 -0
- package/src/devcouncil/integrations/mcp/handlers/provenance.py +101 -0
- package/src/devcouncil/integrations/mcp/handlers/read.py +74 -0
- package/src/devcouncil/integrations/mcp/handlers/router_cache.py +53 -0
- package/src/devcouncil/integrations/mcp/handlers/run.py +53 -0
- package/src/devcouncil/integrations/mcp/handlers/runs.py +84 -0
- package/src/devcouncil/integrations/mcp/handlers/scope.py +56 -0
- package/src/devcouncil/integrations/mcp/handlers/status.py +114 -0
- package/src/devcouncil/integrations/mcp/handlers/task.py +100 -0
- package/src/devcouncil/integrations/mcp/handlers/tool_specs.py +904 -0
- package/src/devcouncil/integrations/mcp/handlers/trace.py +65 -0
- package/src/devcouncil/integrations/mcp/handlers/verify.py +45 -0
- package/src/devcouncil/integrations/mcp/handlers/wiki.py +60 -0
- package/src/devcouncil/integrations/mcp/handlers/write.py +69 -0
- package/src/devcouncil/integrations/mcp/server.py +265 -2391
- package/src/devcouncil/integrations/mcp/util.py +303 -0
- package/src/devcouncil/integrations/setup.py +152 -0
- package/src/devcouncil/knowledge/fetch.py +4 -0
- package/src/devcouncil/knowledge/knowledge_select.py +38 -0
- package/src/devcouncil/knowledge/okf.py +2 -1
- package/src/devcouncil/knowledge/resource_discovery.py +40 -0
- package/src/devcouncil/knowledge/wiki.py +643 -0
- package/src/devcouncil/knowledge/wiki_read.py +87 -0
- package/src/devcouncil/live/cards.py +7 -7
- package/src/devcouncil/live/models.py +4 -1
- package/src/devcouncil/live/reviewer.py +90 -11
- package/src/devcouncil/live/signals.py +4 -2
- package/src/devcouncil/live/tasks.py +12 -3
- package/src/devcouncil/live/transcripts.py +69 -2
- package/src/devcouncil/llm/cache.py +5 -6
- package/src/devcouncil/llm/model_defaults.yaml +10 -10
- package/src/devcouncil/llm/provider.py +647 -73
- package/src/devcouncil/llm/router.py +271 -46
- package/src/devcouncil/llm/semantic_bridge.py +614 -0
- package/src/devcouncil/optimization/gepa_agent.py +6 -4
- package/src/devcouncil/optimization/skillopt.py +9 -5
- package/src/devcouncil/planning/arbiter_service.py +12 -3
- package/src/devcouncil/planning/correction_manifest.py +107 -10
- package/src/devcouncil/planning/plan_difficulty.py +69 -0
- package/src/devcouncil/planning/plan_service.py +5 -2
- package/src/devcouncil/planning/planned_files_reconcile.py +191 -0
- package/src/devcouncil/planning/prompt_enhancer_service.py +6 -5
- package/src/devcouncil/planning/question_conversion.py +56 -0
- package/src/devcouncil/planning/spec_service.py +9 -3
- package/src/devcouncil/repo/ci_scaffold.py +197 -1
- package/src/devcouncil/repo/gitignore.py +1 -2
- package/src/devcouncil/reporting/evidence_export.py +124 -0
- package/src/devcouncil/reporting/evidence_html.py +210 -0
- package/src/devcouncil/reporting/json_report.py +16 -12
- package/src/devcouncil/reporting/markdown_report.py +38 -9
- package/src/devcouncil/reporting/mcp_resources.py +142 -0
- package/src/devcouncil/reporting/report_builder.py +40 -4
- package/src/devcouncil/reporting/task_provenance.py +42 -0
- package/src/devcouncil/reporting/verdict.py +75 -0
- package/src/devcouncil/skills/library/README.md +1 -0
- package/src/devcouncil/skills/library/devcouncil-hero-loop.md +109 -0
- package/src/devcouncil/skills/library/devcouncil-verification.md +109 -0
- package/src/devcouncil/skills/library/devcouncil.md +93 -0
- package/src/devcouncil/skills/registry.py +43 -12
- package/src/devcouncil/storage/db.py +57 -11
- package/src/devcouncil/storage/models.py +6 -0
- package/src/devcouncil/storage/native.py +5 -3
- package/src/devcouncil/storage/repositories.py +50 -18
- package/src/devcouncil/telemetry/context.py +28 -0
- package/src/devcouncil/telemetry/cost.py +4 -5
- package/src/devcouncil/telemetry/logging_setup.py +78 -11
- package/src/devcouncil/telemetry/model_pricing.yaml +7 -0
- package/src/devcouncil/telemetry/stages.py +27 -2
- package/src/devcouncil/telemetry/tracker.py +50 -13
- package/src/devcouncil/ui/dashboard.py +120 -8
- package/src/devcouncil/utils/fsio.py +58 -0
- package/src/devcouncil/utils/git_snapshot.py +112 -0
- package/src/devcouncil/utils/json_persist.py +53 -0
- package/src/devcouncil/utils/proc.py +89 -0
- package/src/devcouncil/verification/acceptance_compiler.py +36 -13
- package/src/devcouncil/verification/ad_hoc_check.py +95 -3
- package/src/devcouncil/verification/checks/__init__.py +41 -0
- package/src/devcouncil/verification/checks/acceptance.py +39 -0
- package/src/devcouncil/verification/checks/acceptance_corpus.py +194 -0
- package/src/devcouncil/verification/checks/acceptance_evidence.py +239 -0
- package/src/devcouncil/verification/checks/command_evidence.py +148 -0
- package/src/devcouncil/verification/checks/compiled_acceptance.py +179 -0
- package/src/devcouncil/verification/checks/corpus_stale.py +124 -0
- package/src/devcouncil/verification/checks/corpus_verification.py +9 -0
- package/src/devcouncil/verification/checks/dead_symbols.py +360 -0
- package/src/devcouncil/verification/checks/diff_coverage_gate.py +101 -0
- package/src/devcouncil/verification/checks/doc_code_ref.py +79 -0
- package/src/devcouncil/verification/checks/liveness_ratchet.py +336 -0
- package/src/devcouncil/verification/checks/orphan_diff.py +104 -0
- package/src/devcouncil/verification/checks/planned_files.py +98 -0
- package/src/devcouncil/verification/checks/semantic_diff.py +241 -0
- package/src/devcouncil/verification/checks/stale_map.py +80 -0
- package/src/devcouncil/verification/checks/stub_scan.py +71 -0
- package/src/devcouncil/verification/checks/subsystem_boundary.py +103 -0
- package/src/devcouncil/verification/checks/wiring.py +216 -0
- package/src/devcouncil/verification/claims/__init__.py +23 -0
- package/src/devcouncil/verification/claims/checks.py +395 -0
- package/src/devcouncil/verification/claims/mapper.py +168 -0
- package/src/devcouncil/verification/claims/models.py +39 -0
- package/src/devcouncil/verification/claims/transcript.py +92 -0
- package/src/devcouncil/verification/claims/verdict.py +88 -0
- package/src/devcouncil/verification/command_evidence.py +170 -0
- package/src/devcouncil/verification/command_malformation.py +147 -0
- package/src/devcouncil/verification/command_runner.py +164 -0
- package/src/devcouncil/verification/coverage_measurement.py +292 -0
- package/src/devcouncil/verification/diff_coverage.py +151 -0
- package/src/devcouncil/verification/difficulty.py +296 -0
- package/src/devcouncil/verification/effort_heuristics.py +178 -0
- package/src/devcouncil/verification/gap_ids.py +63 -0
- package/src/devcouncil/verification/gate_cache.py +194 -0
- package/src/devcouncil/verification/gate_selector.py +344 -0
- package/src/devcouncil/verification/git_diff_fallback.py +272 -0
- package/src/devcouncil/verification/implementation_reviewer.py +13 -0
- package/src/devcouncil/verification/incremental_check.py +241 -0
- package/src/devcouncil/verification/next_actions.py +60 -1
- package/src/devcouncil/verification/rigor_analytics.py +130 -0
- package/src/devcouncil/verification/sandbox.py +38 -11
- package/src/devcouncil/verification/stub_detector.py +369 -0
- package/src/devcouncil/verification/test_resolver.py +67 -1
- package/src/devcouncil/verification/verifier.py +137 -1666
- package/src/devcouncil/verification/verify_orchestration.py +610 -0
- package/src/devcouncil/verification/verify_setup.py +176 -0
- package/src/devcouncil/verification/wiki_refresh.py +208 -0
- package/src/semantic_layer/__init__.py +58 -0
- package/src/semantic_layer/benchmark.py +75 -0
- package/src/semantic_layer/cache.py +290 -0
- package/src/semantic_layer/compressor.py +137 -0
- package/src/semantic_layer/config.py +75 -0
- package/src/semantic_layer/embeddings.py +69 -0
- package/src/semantic_layer/llm_backends.py +99 -0
- package/src/semantic_layer/pipeline.py +111 -0
- package/src/semantic_layer/router.py +128 -0
- package/src/semantic_layer/tuner.py +72 -0
- package/uv.lock +973 -9
- package/src/devcouncil/artifacts/migrations.py +0 -20
- package/src/devcouncil/artifacts/schemas.py +0 -23
- package/src/devcouncil/artifacts/serializer.py +0 -21
- package/src/devcouncil/integrations/gitnexus.py +0 -70
- package/src/devcouncil/integrations/graphify.py +0 -34
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"""Pydantic schema for the symbol-level code knowledge graph.
|
|
2
|
+
|
|
3
|
+
devcouncil: allow-unwired — package-private types; imported by sibling graph modules.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
from enum import Enum
|
|
9
|
+
from typing import Any, Dict, List
|
|
10
|
+
|
|
11
|
+
from pydantic import BaseModel, Field
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
SCHEMA_VERSION = 2
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class NodeKind(str, Enum):
|
|
18
|
+
FILE = "file"
|
|
19
|
+
MODULE = "module"
|
|
20
|
+
NAMESPACE = "namespace"
|
|
21
|
+
PACKAGE = "package"
|
|
22
|
+
FUNCTION = "function"
|
|
23
|
+
CLASS = "class"
|
|
24
|
+
METHOD = "method"
|
|
25
|
+
INTERFACE = "interface"
|
|
26
|
+
TYPE = "type"
|
|
27
|
+
STRUCT = "struct"
|
|
28
|
+
ENUM = "enum"
|
|
29
|
+
TRAIT = "trait"
|
|
30
|
+
PROPERTY = "property"
|
|
31
|
+
VARIABLE = "variable"
|
|
32
|
+
ROUTE = "route"
|
|
33
|
+
EVENT = "event"
|
|
34
|
+
STATE = "state"
|
|
35
|
+
PROVIDER = "provider"
|
|
36
|
+
COMPONENT = "component"
|
|
37
|
+
DYNAMIC = "dynamic"
|
|
38
|
+
RATIONALE = "rationale"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class Confidence(str, Enum):
|
|
42
|
+
EXTRACTED = "extracted"
|
|
43
|
+
INFERRED = "inferred"
|
|
44
|
+
AMBIGUOUS = "ambiguous"
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class GraphNode(BaseModel):
|
|
48
|
+
id: str
|
|
49
|
+
kind: NodeKind
|
|
50
|
+
path: str = ""
|
|
51
|
+
name: str = ""
|
|
52
|
+
line: int = 0
|
|
53
|
+
end_line: int = 0
|
|
54
|
+
area: str = ""
|
|
55
|
+
language: str = ""
|
|
56
|
+
exported: bool = False
|
|
57
|
+
community: str = ""
|
|
58
|
+
extras: Dict[str, Any] = Field(default_factory=dict)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class GraphEdge(BaseModel):
|
|
62
|
+
source: str
|
|
63
|
+
target: str
|
|
64
|
+
kind: str # contains | imports | calls | inherits | implements | overrides | decorates | documents
|
|
65
|
+
confidence: Confidence = Confidence.EXTRACTED
|
|
66
|
+
reason: str = ""
|
|
67
|
+
extras: Dict[str, Any] = Field(default_factory=dict)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class DeadCodeEntry(BaseModel):
|
|
71
|
+
id: str
|
|
72
|
+
path: str
|
|
73
|
+
line: int = 0
|
|
74
|
+
kind: str = ""
|
|
75
|
+
confidence: Confidence = Confidence.INFERRED
|
|
76
|
+
reason: str = ""
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class CodeGraph(BaseModel):
|
|
80
|
+
schema_version: int = SCHEMA_VERSION
|
|
81
|
+
nodes: List[GraphNode] = Field(default_factory=list)
|
|
82
|
+
edges: List[GraphEdge] = Field(default_factory=list)
|
|
83
|
+
dead_code: List[DeadCodeEntry] = Field(default_factory=list)
|
|
84
|
+
entry_roots: List[str] = Field(default_factory=list)
|
|
85
|
+
unwired_candidates: List[str] = Field(default_factory=list)
|
|
86
|
+
unreachable_files: List[str] = Field(default_factory=list)
|
|
87
|
+
generated_head: str = ""
|
|
88
|
+
indexed_hash: str = ""
|
|
89
|
+
content_fingerprint: str = ""
|
|
90
|
+
meta: Dict[str, Any] = Field(default_factory=dict)
|
|
91
|
+
|
|
92
|
+
def node_by_id(self) -> Dict[str, GraphNode]:
|
|
93
|
+
return {n.id: n for n in self.nodes}
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def file_node_id(path: str) -> str:
|
|
97
|
+
return path.replace("\\", "/")
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def symbol_node_id(path: str, qualname: str) -> str:
|
|
101
|
+
"""Deterministic id: ``src/x.py::Class.method``."""
|
|
102
|
+
norm = path.replace("\\", "/")
|
|
103
|
+
return f"{norm}::{qualname}"
|
|
@@ -1,48 +1,39 @@
|
|
|
1
|
-
|
|
1
|
+
"""Legacy artifact knowledge graph — deprecated compat shim.
|
|
2
|
+
|
|
3
|
+
devcouncil: allow-unwired — deprecated compat shim; real graph is indexing/graph/.
|
|
4
|
+
|
|
5
|
+
This module holds a minimal Pydantic model for requirements/tasks/files used by
|
|
6
|
+
older integration experiments. It is **not** the symbol-level code graph in
|
|
7
|
+
``indexing/graph/`` (built by ``dev map``).
|
|
8
|
+
|
|
9
|
+
Do not extend this module for dead-code analysis, call-graph queries, or new
|
|
10
|
+
features — use ``indexing/graph/`` instead. Kept only so imports remain stable.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from typing import Any, Dict, List
|
|
14
|
+
|
|
2
15
|
from pydantic import BaseModel, Field
|
|
3
16
|
from pathlib import Path
|
|
4
17
|
|
|
18
|
+
|
|
5
19
|
class GraphNode(BaseModel):
|
|
6
20
|
id: str
|
|
7
|
-
type: str
|
|
21
|
+
type: str # "file", "symbol", "requirement", "task"
|
|
8
22
|
metadata: Dict[str, Any] = Field(default_factory=dict)
|
|
9
23
|
|
|
24
|
+
|
|
10
25
|
class GraphEdge(BaseModel):
|
|
11
26
|
source: str
|
|
12
27
|
target: str
|
|
13
|
-
relation: str
|
|
28
|
+
relation: str # "imports", "implements", "validates", "contains"
|
|
29
|
+
|
|
14
30
|
|
|
15
31
|
class KnowledgeGraph(BaseModel):
|
|
16
32
|
nodes: List[GraphNode] = []
|
|
17
33
|
edges: List[GraphEdge] = []
|
|
18
34
|
|
|
35
|
+
|
|
19
36
|
class GraphIndex:
|
|
20
37
|
def __init__(self, project_root: Path):
|
|
21
38
|
self.project_root = project_root
|
|
22
39
|
self.graph = KnowledgeGraph()
|
|
23
|
-
|
|
24
|
-
def build_initial_graph(self, files: List[str]):
|
|
25
|
-
"""
|
|
26
|
-
Bootstrap the graph from file list.
|
|
27
|
-
"""
|
|
28
|
-
for f in files:
|
|
29
|
-
self.graph.nodes.append(GraphNode(
|
|
30
|
-
id=f,
|
|
31
|
-
type="file",
|
|
32
|
-
metadata={"extension": Path(f).suffix}
|
|
33
|
-
))
|
|
34
|
-
|
|
35
|
-
def add_relation(self, source: str, target: str, relation: str):
|
|
36
|
-
self.graph.edges.append(GraphEdge(source=source, target=target, relation=relation))
|
|
37
|
-
|
|
38
|
-
def get_context_for_file(self, file_path: str) -> Set[str]:
|
|
39
|
-
"""
|
|
40
|
-
Retrieve related paths for a given file.
|
|
41
|
-
"""
|
|
42
|
-
related = {file_path}
|
|
43
|
-
for edge in self.graph.edges:
|
|
44
|
-
if edge.source == file_path:
|
|
45
|
-
related.add(edge.target)
|
|
46
|
-
if edge.target == file_path:
|
|
47
|
-
related.add(edge.source)
|
|
48
|
-
return related
|
|
@@ -16,15 +16,17 @@ class LspServerCandidate:
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
class LspInspector:
|
|
19
|
-
"""Language-server
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
19
|
+
"""Language-server detection, with optional live client mode.
|
|
20
|
+
|
|
21
|
+
By default this inspector only answers: which language servers for the repo's
|
|
22
|
+
languages are installed on PATH? It does NOT spawn a server or speak the wire
|
|
23
|
+
protocol. When ``client_enabled=True`` (config ``indexing.lsp_refs`` / ``dev map
|
|
24
|
+
--lsp-refs``), summaries report ``mode: "client"`` — the optional
|
|
25
|
+
:mod:`devcouncil.indexing.lsp_client` can then run ``initialize``,
|
|
26
|
+
``textDocument/references``, and ``textDocument/definition``.
|
|
27
|
+
|
|
28
|
+
``starter_initialize_payload`` remains a never-sent reference payload for
|
|
29
|
+
detection-only mode.
|
|
28
30
|
"""
|
|
29
31
|
|
|
30
32
|
_LANGUAGE_SERVERS: dict[str, list[list[str]]] = {
|
|
@@ -86,12 +88,11 @@ class LspInspector:
|
|
|
86
88
|
return candidates
|
|
87
89
|
|
|
88
90
|
def starter_initialize_payload(self, language: str) -> dict[str, Any]:
|
|
89
|
-
"""Build the JSON-RPC ``initialize`` request a
|
|
91
|
+
"""Build the JSON-RPC ``initialize`` request a client would send.
|
|
90
92
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
non-sent payloads under an explicit ``"_note"`` disclaimer.
|
|
93
|
+
In detection-only mode this payload is NEVER sent — it is a reference for
|
|
94
|
+
wiring. When ``mode: "client"``, :mod:`devcouncil.indexing.lsp_client`
|
|
95
|
+
sends an equivalent initialize over stdio.
|
|
95
96
|
"""
|
|
96
97
|
return {
|
|
97
98
|
"jsonrpc": "2.0",
|
|
@@ -113,23 +114,40 @@ class LspInspector:
|
|
|
113
114
|
},
|
|
114
115
|
}
|
|
115
116
|
|
|
116
|
-
# Made explicit in every summary so no consumer reads this as a live LSP feature.
|
|
117
117
|
_DETECTION_ONLY_NOTE = (
|
|
118
118
|
"Detection only: DevCouncil checks which language servers are installed on "
|
|
119
|
-
"PATH; it does not run an LSP client or send any requests."
|
|
119
|
+
"PATH; it does not run an LSP client or send any requests. Enable live "
|
|
120
|
+
"references via indexing.lsp_refs or `dev map --lsp-refs`."
|
|
121
|
+
)
|
|
122
|
+
_CLIENT_MODE_NOTE = (
|
|
123
|
+
"Client mode: DevCouncil may spawn detected language servers for "
|
|
124
|
+
"textDocument/references and textDocument/definition (dead-symbol "
|
|
125
|
+
"confirmation and precise MCP impact). Still opt-in per run/config."
|
|
120
126
|
)
|
|
121
127
|
_STARTER_PAYLOAD_NOTE = (
|
|
122
|
-
"Starter payloads only — these initialize requests are NEVER sent
|
|
123
|
-
"
|
|
128
|
+
"Starter payloads only — these initialize requests are NEVER sent in "
|
|
129
|
+
"detection-only mode. In client mode, lsp_client sends initialize live."
|
|
130
|
+
)
|
|
131
|
+
_CLIENT_PAYLOAD_NOTE = (
|
|
132
|
+
"Reference initialize shapes; the live client sends equivalent requests "
|
|
133
|
+
"when indexing.lsp_refs / --lsp-refs is enabled."
|
|
124
134
|
)
|
|
125
135
|
|
|
126
|
-
def summary(
|
|
136
|
+
def summary(
|
|
137
|
+
self,
|
|
138
|
+
files: list[str] | None = None,
|
|
139
|
+
*,
|
|
140
|
+
client_enabled: bool = False,
|
|
141
|
+
) -> dict[str, Any]:
|
|
127
142
|
candidates = self.server_candidates(files)
|
|
143
|
+
mode = "client" if client_enabled else "detection-only"
|
|
144
|
+
note = self._CLIENT_MODE_NOTE if client_enabled else self._DETECTION_ONLY_NOTE
|
|
145
|
+
init_note = self._CLIENT_PAYLOAD_NOTE if client_enabled else self._STARTER_PAYLOAD_NOTE
|
|
128
146
|
return {
|
|
129
|
-
"mode":
|
|
130
|
-
"note":
|
|
147
|
+
"mode": mode,
|
|
148
|
+
"note": note,
|
|
131
149
|
"languages": self.detect_languages(files),
|
|
132
|
-
"
|
|
150
|
+
"servers_detected": [
|
|
133
151
|
{
|
|
134
152
|
"language": candidate.language,
|
|
135
153
|
"command": candidate.command,
|
|
@@ -139,6 +157,15 @@ class LspInspector:
|
|
|
139
157
|
for candidate in candidates
|
|
140
158
|
],
|
|
141
159
|
# Back-compat alias for "detected_servers" (older consumers/tests).
|
|
160
|
+
"detected_servers": [
|
|
161
|
+
{
|
|
162
|
+
"language": candidate.language,
|
|
163
|
+
"command": candidate.command,
|
|
164
|
+
"available": candidate.available,
|
|
165
|
+
"reason": candidate.reason,
|
|
166
|
+
}
|
|
167
|
+
for candidate in candidates
|
|
168
|
+
],
|
|
142
169
|
"servers": [
|
|
143
170
|
{
|
|
144
171
|
"language": candidate.language,
|
|
@@ -149,7 +176,7 @@ class LspInspector:
|
|
|
149
176
|
for candidate in candidates
|
|
150
177
|
],
|
|
151
178
|
"initialize_requests": {
|
|
152
|
-
"_note":
|
|
179
|
+
"_note": init_note,
|
|
153
180
|
**{
|
|
154
181
|
language: self.starter_initialize_payload(language)
|
|
155
182
|
for language in sorted({candidate.language for candidate in candidates})
|
|
@@ -157,5 +184,10 @@ class LspInspector:
|
|
|
157
184
|
},
|
|
158
185
|
}
|
|
159
186
|
|
|
160
|
-
def summary_json(
|
|
161
|
-
|
|
187
|
+
def summary_json(
|
|
188
|
+
self,
|
|
189
|
+
files: list[str] | None = None,
|
|
190
|
+
*,
|
|
191
|
+
client_enabled: bool = False,
|
|
192
|
+
) -> str:
|
|
193
|
+
return json.dumps(self.summary(files, client_enabled=client_enabled), indent=2)
|