devcouncil 0.3.1 → 0.4.1
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 +92 -33
- 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 +56 -40
- 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 +964 -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 +281 -0
- package/src/devcouncil/integrations/mcp/handlers/graph.py +34 -0
- package/src/devcouncil/integrations/mcp/handlers/handoff.py +53 -0
- package/src/devcouncil/integrations/mcp/handlers/knowledge.py +28 -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 +87 -0
- package/src/devcouncil/integrations/mcp/handlers/read.py +103 -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 +69 -0
- package/src/devcouncil/integrations/mcp/handlers/scope.py +56 -0
- package/src/devcouncil/integrations/mcp/handlers/status.py +199 -0
- package/src/devcouncil/integrations/mcp/handlers/task.py +88 -0
- package/src/devcouncil/integrations/mcp/handlers/tool_specs.py +922 -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 +53 -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 +325 -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/summary.py +21 -3
- 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
|
@@ -26,7 +26,9 @@ import json
|
|
|
26
26
|
from dataclasses import dataclass
|
|
27
27
|
from pathlib import Path
|
|
28
28
|
|
|
29
|
+
from devcouncil.executors.advisor_tool import ADVISOR_STEERING_NUDGE
|
|
29
30
|
from devcouncil.knowledge.frontmatter import build_frontmatter_markdown
|
|
31
|
+
from devcouncil.integrations.clients.hooks import SESSION_START_MATCHER
|
|
30
32
|
|
|
31
33
|
# Tools a DevCouncil subagent should be allowed to use: the standard read/edit/run set
|
|
32
34
|
# plus the DevCouncil MCP tools it drives the task loop with. Listing the MCP tools keeps
|
|
@@ -90,7 +92,8 @@ def _slash_commands() -> list[_SlashCommand]:
|
|
|
90
92
|
"MCP tools to implement it: call `mcp__devcouncil__devcouncil_next_task`, then "
|
|
91
93
|
"`mcp__devcouncil__devcouncil_checkout_task` to acquire a lease, make changes only "
|
|
92
94
|
"through the policy-gated write tools, run tests, then "
|
|
93
|
-
"`mcp__devcouncil__devcouncil_verify_task` and release the lease when verified."
|
|
95
|
+
"`mcp__devcouncil__devcouncil_verify_task` and release the lease when verified. "
|
|
96
|
+
f"{ADVISOR_STEERING_NUDGE}"
|
|
94
97
|
),
|
|
95
98
|
allowed_tools="Bash(dev tasks:*)",
|
|
96
99
|
),
|
|
@@ -113,7 +116,7 @@ def _slash_commands() -> list[_SlashCommand]:
|
|
|
113
116
|
body=(
|
|
114
117
|
"Work through the repair guidance above. Apply the smallest changes that close the "
|
|
115
118
|
"blocking gaps via the policy-gated DevCouncil write tools, then re-run "
|
|
116
|
-
"`/devcouncil:verify` until the task is clean."
|
|
119
|
+
f"`/devcouncil:verify` until the task is clean. {ADVISOR_STEERING_NUDGE}"
|
|
117
120
|
),
|
|
118
121
|
allowed_tools="Bash(dev repair:*)",
|
|
119
122
|
),
|
|
@@ -152,6 +155,46 @@ def _slash_commands() -> list[_SlashCommand]:
|
|
|
152
155
|
),
|
|
153
156
|
allowed_tools="Bash(dev report:*)",
|
|
154
157
|
),
|
|
158
|
+
_SlashCommand(
|
|
159
|
+
name="map",
|
|
160
|
+
description="Build or refresh the deterministic repository map (no LLM).",
|
|
161
|
+
argument_hint="[goal]",
|
|
162
|
+
bash="dev map $ARGUMENTS",
|
|
163
|
+
body=(
|
|
164
|
+
"Summarize the repository map above: languages, frameworks, test commands, and "
|
|
165
|
+
"the most relevant entry points for the stated goal (if any). Point the user at "
|
|
166
|
+
"`.devcouncil/repo_map.json` for the full index and recommend `/devcouncil:next` "
|
|
167
|
+
"or `/devcouncil:plan` as the next step."
|
|
168
|
+
),
|
|
169
|
+
allowed_tools="Bash(dev map:*)",
|
|
170
|
+
),
|
|
171
|
+
_SlashCommand(
|
|
172
|
+
name="wiki",
|
|
173
|
+
description="Consult the generated codebase wiki for a topic or subsystem.",
|
|
174
|
+
argument_hint="[topic]",
|
|
175
|
+
bash="dev wiki status",
|
|
176
|
+
body=(
|
|
177
|
+
"The codebase wiki status is shown above. Use "
|
|
178
|
+
"`mcp__devcouncil__devcouncil_wiki_page` with query \"$ARGUMENTS\" (or no "
|
|
179
|
+
"arguments for the index) to read the relevant subsystem page(s), and "
|
|
180
|
+
"summarize what they say about the topic before making changes. If pages "
|
|
181
|
+
"are stale, suggest running `dev wiki update`."
|
|
182
|
+
),
|
|
183
|
+
allowed_tools="Bash(dev wiki:*)",
|
|
184
|
+
),
|
|
185
|
+
_SlashCommand(
|
|
186
|
+
name="supervise",
|
|
187
|
+
description="Review a recorded agent run and decide keep/revert/repair.",
|
|
188
|
+
argument_hint="[RUN-ID or TASK-ID]",
|
|
189
|
+
bash="dev runs list",
|
|
190
|
+
body=(
|
|
191
|
+
"The recorded runs are listed above. For the run the user named (or the "
|
|
192
|
+
"newest relevant one), run `dev runs supervise $ARGUMENTS` and present the "
|
|
193
|
+
"verdict with its findings. If the verdict is revert, show `dev runs diff "
|
|
194
|
+
"$ARGUMENTS` and ask before running `dev runs revert $ARGUMENTS`."
|
|
195
|
+
),
|
|
196
|
+
allowed_tools="Bash(dev runs:*)",
|
|
197
|
+
),
|
|
155
198
|
]
|
|
156
199
|
|
|
157
200
|
|
|
@@ -169,6 +212,34 @@ def _slash_command_markdown(cmd: _SlashCommand) -> str:
|
|
|
169
212
|
return build_frontmatter_markdown(meta, "\n".join(lines))
|
|
170
213
|
|
|
171
214
|
|
|
215
|
+
# Bash permission rules merged into .claude/settings.local.json so slash commands and
|
|
216
|
+
# common hero-loop CLIs run without interactive approval. Kept here (with the slash
|
|
217
|
+
# commands) so the allow-list stays in sync with generated command allowed-tools.
|
|
218
|
+
_EXTRA_BASH_PERMISSIONS = (
|
|
219
|
+
"Bash(dev go:*)",
|
|
220
|
+
"Bash(dev check:*)",
|
|
221
|
+
"Bash(dev gaps:*)",
|
|
222
|
+
"Bash(dev export:*)",
|
|
223
|
+
"Bash(dev doctor:*)",
|
|
224
|
+
"Bash(devcouncil mcp-server)",
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def claude_bash_permission_allow() -> list[str]:
|
|
229
|
+
"""Ordered, de-duplicated Bash allow-rules for Claude Code settings merge."""
|
|
230
|
+
seen: set[str] = set()
|
|
231
|
+
rules: list[str] = []
|
|
232
|
+
for cmd in _slash_commands():
|
|
233
|
+
if cmd.allowed_tools and cmd.allowed_tools not in seen:
|
|
234
|
+
seen.add(cmd.allowed_tools)
|
|
235
|
+
rules.append(cmd.allowed_tools)
|
|
236
|
+
for rule in _EXTRA_BASH_PERMISSIONS:
|
|
237
|
+
if rule not in seen:
|
|
238
|
+
seen.add(rule)
|
|
239
|
+
rules.append(rule)
|
|
240
|
+
return rules
|
|
241
|
+
|
|
242
|
+
|
|
172
243
|
def build_slash_commands(root: Path) -> list[GeneratedAsset]:
|
|
173
244
|
base = root / ".claude" / "commands" / "devcouncil"
|
|
174
245
|
return [
|
|
@@ -237,8 +308,9 @@ def _subagents() -> list[_Subagent]:
|
|
|
237
308
|
"and `devcouncil_get_diff` to inspect.\n"
|
|
238
309
|
"3. Change files only via `devcouncil_write_file` / `devcouncil_apply_patch` (the gate "
|
|
239
310
|
"rejects out-of-scope or protected paths) and run tests via `devcouncil_run_command`.\n"
|
|
240
|
-
"4.
|
|
241
|
-
"5. `
|
|
311
|
+
f"4. {ADVISOR_STEERING_NUDGE}\n"
|
|
312
|
+
"5. `devcouncil_verify_task`; fix any blocking gaps and re-verify.\n"
|
|
313
|
+
"6. `devcouncil_release_task` when verified.\n\n"
|
|
242
314
|
"Never touch files outside the task scope. Report the final status and remaining gaps."
|
|
243
315
|
),
|
|
244
316
|
),
|
|
@@ -314,6 +386,7 @@ def build_output_style(root: Path) -> list[GeneratedAsset]:
|
|
|
314
386
|
"`file:line`. Do not call work done while blocking gaps remain.\n"
|
|
315
387
|
"- When unsure of project conventions, consult `.devcouncil/repo_map.json` and the "
|
|
316
388
|
"applicable skills before writing code.\n"
|
|
389
|
+
f"- {ADVISOR_STEERING_NUDGE}\n"
|
|
317
390
|
"- Be concise: report what changed, what was verified, and what is still blocking."
|
|
318
391
|
)
|
|
319
392
|
return [GeneratedAsset(root / ".claude" / "output-styles" / "devcouncil.md", build_frontmatter_markdown(meta, body))]
|
|
@@ -364,23 +437,26 @@ def _marketplace_json(version: str) -> str:
|
|
|
364
437
|
def _plugin_hooks_json(*, write_gate: bool = False) -> str:
|
|
365
438
|
"""hooks.json for the plugin, resolving the project root via ${CLAUDE_PROJECT_DIR}.
|
|
366
439
|
|
|
367
|
-
Assist-mode by default
|
|
368
|
-
|
|
369
|
-
|
|
440
|
+
Assist-mode by default installs refresh-only PostToolUse (never gates writes) plus
|
|
441
|
+
lifecycle hooks. The blocking PreToolUse write-gate is included only when
|
|
442
|
+
``write_gate`` is True."""
|
|
370
443
|
def cmd(event: str) -> str:
|
|
371
444
|
return f'devcouncil hook {event} --client claude --project-root "${{CLAUDE_PROJECT_DIR}}"'
|
|
372
445
|
|
|
446
|
+
tool_matcher = "Bash|Write|Edit|MultiEdit"
|
|
373
447
|
hooks: dict[str, list] = {
|
|
374
|
-
"
|
|
375
|
-
"
|
|
448
|
+
"PostToolUse": [{"matcher": tool_matcher, "hooks": [{"type": "command", "command": cmd("post-tool-use"), "timeout": 10000}]}],
|
|
449
|
+
"Stop": [{"hooks": [{"type": "command", "command": cmd("agent-response"), "timeout": 150000}]}],
|
|
450
|
+
"SessionStart": [{"matcher": SESSION_START_MATCHER, "hooks": [{"type": "command", "command": cmd("session-start"), "timeout": 10000}]}],
|
|
376
451
|
"UserPromptSubmit": [{"hooks": [{"type": "command", "command": cmd("user-prompt-submit"), "timeout": 10000}]}],
|
|
377
|
-
"
|
|
452
|
+
"SessionEnd": [{"hooks": [{"type": "command", "command": cmd("session-end"), "timeout": 10000}]}],
|
|
453
|
+
"PreCompact": [{"hooks": [{"type": "command", "command": cmd("pre-compact"), "timeout": 10000}]}],
|
|
454
|
+
"PostCompact": [{"hooks": [{"type": "command", "command": cmd("post-compact"), "timeout": 10000}]}],
|
|
455
|
+
"SubagentStop": [{"hooks": [{"type": "command", "command": cmd("subagent-stop"), "timeout": 150000}]}],
|
|
378
456
|
"Notification": [{"hooks": [{"type": "command", "command": cmd("notification"), "timeout": 10000}]}],
|
|
379
457
|
}
|
|
380
458
|
if write_gate:
|
|
381
|
-
tool_matcher = "Bash|Write|Edit|MultiEdit"
|
|
382
459
|
hooks["PreToolUse"] = [{"matcher": tool_matcher, "hooks": [{"type": "command", "command": cmd("pre-tool-use"), "timeout": 10000}]}]
|
|
383
|
-
hooks["PostToolUse"] = [{"matcher": tool_matcher, "hooks": [{"type": "command", "command": cmd("post-tool-use"), "timeout": 10000}]}]
|
|
384
460
|
return json.dumps({"hooks": hooks}, indent=2) + "\n"
|
|
385
461
|
|
|
386
462
|
|
|
@@ -398,6 +474,122 @@ def _plugin_mcp_json(root: Path) -> str:
|
|
|
398
474
|
return json.dumps(config, indent=2) + "\n"
|
|
399
475
|
|
|
400
476
|
|
|
477
|
+
def _plugin_lsp_json(root: Path) -> str | None:
|
|
478
|
+
"""Build the plugin's ``.lsp.json`` from DevCouncil's language-server detection.
|
|
479
|
+
|
|
480
|
+
DevCouncil already knows which LSP servers match the repo's languages (it detects
|
|
481
|
+
them for the repo map); this ships that knowledge to Claude Code so the plugin grants
|
|
482
|
+
real code intelligence (go-to-definition, references, diagnostics) instead of only
|
|
483
|
+
detecting servers. One server per detected language (the preferred candidate), keyed by
|
|
484
|
+
language name, in Claude Code's documented schema: ``command`` + ``args`` +
|
|
485
|
+
``extensionToLanguage``. The consumer still installs the binary (Claude Code flags a
|
|
486
|
+
missing one in ``/plugin`` Errors). Returns None when the repo has no supported
|
|
487
|
+
languages, so the bundle simply omits the file."""
|
|
488
|
+
from devcouncil.indexing.lsp import LspInspector
|
|
489
|
+
|
|
490
|
+
inspector = LspInspector(root)
|
|
491
|
+
ext_by_language: dict[str, dict[str, str]] = {}
|
|
492
|
+
for ext, language in LspInspector._EXTENSIONS.items():
|
|
493
|
+
ext_by_language.setdefault(language, {})[ext] = language
|
|
494
|
+
|
|
495
|
+
servers: dict[str, dict] = {}
|
|
496
|
+
for candidate in inspector.server_candidates():
|
|
497
|
+
if candidate.language in servers:
|
|
498
|
+
continue # first (preferred) candidate per language wins
|
|
499
|
+
command = list(candidate.command)
|
|
500
|
+
entry: dict = {"command": command[0]}
|
|
501
|
+
if command[1:]:
|
|
502
|
+
entry["args"] = command[1:]
|
|
503
|
+
entry["extensionToLanguage"] = ext_by_language.get(candidate.language, {})
|
|
504
|
+
servers[candidate.language] = entry
|
|
505
|
+
|
|
506
|
+
if not servers:
|
|
507
|
+
return None
|
|
508
|
+
return json.dumps(servers, indent=2) + "\n"
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
_GITHUB_WORKFLOW = """\
|
|
512
|
+
# DevCouncil + Claude Code — event-driven task runner.
|
|
513
|
+
#
|
|
514
|
+
# Generated by `dev integrate claude-github`. This is the stable-primitive alternative to
|
|
515
|
+
# Claude Code's (experimental) cloud Routines: it runs DevCouncil's verify loop on pull
|
|
516
|
+
# requests and, on demand or on a schedule, hands the next task to headless Claude Code —
|
|
517
|
+
# staying inside DevCouncil's evidence/verify gate the whole way.
|
|
518
|
+
#
|
|
519
|
+
# Setup: add an ANTHROPIC_API_KEY repository secret for the autonomous (dispatch/schedule)
|
|
520
|
+
# runs. The pull_request job needs no secret; it only runs read-only verification.
|
|
521
|
+
name: DevCouncil
|
|
522
|
+
|
|
523
|
+
on:
|
|
524
|
+
pull_request:
|
|
525
|
+
workflow_dispatch:
|
|
526
|
+
schedule:
|
|
527
|
+
- cron: "0 6 * * *" # nightly task pickup (UTC); adjust or remove as needed
|
|
528
|
+
|
|
529
|
+
permissions:
|
|
530
|
+
contents: read
|
|
531
|
+
pull-requests: write
|
|
532
|
+
|
|
533
|
+
jobs:
|
|
534
|
+
verify:
|
|
535
|
+
# Read-only DevCouncil verification on every PR — no model calls, no secrets.
|
|
536
|
+
if: github.event_name == 'pull_request'
|
|
537
|
+
runs-on: ubuntu-latest
|
|
538
|
+
steps:
|
|
539
|
+
- uses: actions/checkout@v4
|
|
540
|
+
- uses: astral-sh/setup-uv@v7
|
|
541
|
+
- name: Install DevCouncil
|
|
542
|
+
run: |
|
|
543
|
+
uv tool install devcouncil
|
|
544
|
+
echo "$HOME/.local/bin" >> "$GITHUB_PATH" # put the dev/devcouncil CLIs on PATH
|
|
545
|
+
- name: Verify project state
|
|
546
|
+
run: |
|
|
547
|
+
dev status
|
|
548
|
+
dev report
|
|
549
|
+
|
|
550
|
+
autonomous:
|
|
551
|
+
# On demand or on schedule: let headless Claude Code pick up and implement the next task
|
|
552
|
+
# through the DevCouncil MCP loop, then verify.
|
|
553
|
+
if: github.event_name != 'pull_request'
|
|
554
|
+
runs-on: ubuntu-latest
|
|
555
|
+
steps:
|
|
556
|
+
- uses: actions/checkout@v4
|
|
557
|
+
- uses: astral-sh/setup-uv@v7
|
|
558
|
+
- uses: actions/setup-node@v5
|
|
559
|
+
with:
|
|
560
|
+
node-version: "24"
|
|
561
|
+
- name: Install DevCouncil and Claude Code
|
|
562
|
+
run: |
|
|
563
|
+
uv tool install devcouncil
|
|
564
|
+
echo "$HOME/.local/bin" >> "$GITHUB_PATH" # put the dev/devcouncil CLIs on PATH
|
|
565
|
+
npm install -g @anthropic-ai/claude-code
|
|
566
|
+
- name: Wire DevCouncil into Claude Code
|
|
567
|
+
run: dev integrate claude --apply
|
|
568
|
+
- name: Implement next task (headless, gated)
|
|
569
|
+
env:
|
|
570
|
+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
571
|
+
# --dangerously-skip-permissions is appropriate here: the runner is an ephemeral
|
|
572
|
+
# sandbox, and DevCouncil's own scope gate + the verify step below still constrain
|
|
573
|
+
# the result. Without it, headless Claude blocks on MCP-tool permission prompts.
|
|
574
|
+
run: |
|
|
575
|
+
claude -p --dangerously-skip-permissions --output-format json \\
|
|
576
|
+
"Use the DevCouncil MCP tools to implement the next task: call \\
|
|
577
|
+
mcp__devcouncil__devcouncil_next_task, checkout a lease, make only the \\
|
|
578
|
+
authorized changes, then verify and release the lease."
|
|
579
|
+
- name: Verify result
|
|
580
|
+
run: dev verify || true
|
|
581
|
+
"""
|
|
582
|
+
|
|
583
|
+
|
|
584
|
+
def build_github_workflow(root: Path) -> GeneratedAsset:
|
|
585
|
+
"""Generate ``.github/workflows/devcouncil.yml``.
|
|
586
|
+
|
|
587
|
+
Delivers the event-driven-run value of Claude Code Routines using stable primitives
|
|
588
|
+
(GitHub Actions + headless Claude Code) instead of the experimental cloud API: read-only
|
|
589
|
+
DevCouncil verification on PRs, and gated autonomous task pickup on dispatch/schedule."""
|
|
590
|
+
return GeneratedAsset(root / ".github" / "workflows" / "devcouncil.yml", _GITHUB_WORKFLOW)
|
|
591
|
+
|
|
592
|
+
|
|
401
593
|
def _plugin_readme() -> str:
|
|
402
594
|
return (
|
|
403
595
|
"# DevCouncil Claude Code plugin\n\n"
|
|
@@ -426,6 +618,11 @@ def build_plugin_bundle(
|
|
|
426
618
|
GeneratedAsset(plugin / ".mcp.json", _plugin_mcp_json(root)),
|
|
427
619
|
GeneratedAsset(plugin / "README.md", _plugin_readme()),
|
|
428
620
|
]
|
|
621
|
+
# Ship an .lsp.json (auto-discovered at plugin root) for the repo's languages, so the
|
|
622
|
+
# plugin delivers live code intelligence — omitted entirely when nothing is detected.
|
|
623
|
+
lsp_config = _plugin_lsp_json(root)
|
|
624
|
+
if lsp_config:
|
|
625
|
+
assets.append(GeneratedAsset(plugin / ".lsp.json", lsp_config))
|
|
429
626
|
# Bundle command + agent copies into the plugin tree (plugin layout puts them at the
|
|
430
627
|
# plugin root, not under .claude/).
|
|
431
628
|
for cmd in _slash_commands():
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Per-client integration adapters for coding CLIs."""
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"""Aider integration adapter."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import shutil
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
from devcouncil.integrations.clients import common as _common
|
|
10
|
+
_project_root = _common._project_root
|
|
11
|
+
_warn_if_verify_only = _common._warn_if_verify_only
|
|
12
|
+
_server_args = _common._server_args
|
|
13
|
+
_format_command = _common._format_command
|
|
14
|
+
_quote_powershell_arg = _common._quote_powershell_arg
|
|
15
|
+
_run = _common._run
|
|
16
|
+
_run_capture = _common._run_capture
|
|
17
|
+
_config_path = _common._config_path
|
|
18
|
+
_load_raw_config = _common._load_raw_config
|
|
19
|
+
_save_raw_config = _common._save_raw_config
|
|
20
|
+
_load_json = _common._load_json
|
|
21
|
+
_save_json = _common._save_json
|
|
22
|
+
_load_json_strict = _common._load_json_strict
|
|
23
|
+
_mutate_raw_config = _common._mutate_raw_config
|
|
24
|
+
_batched_raw_config = _common._batched_raw_config
|
|
25
|
+
_probe_mcp_tools = _common._probe_mcp_tools
|
|
26
|
+
_print_command = _common._print_command
|
|
27
|
+
_configure = _common._configure
|
|
28
|
+
|
|
29
|
+
console = _common.console
|
|
30
|
+
def _record_aider_config(project_root: Path) -> None:
|
|
31
|
+
def mutate(config: dict) -> None:
|
|
32
|
+
config.setdefault("integrations", {}).setdefault("aider", {}).update({"enabled": True})
|
|
33
|
+
|
|
34
|
+
_mutate_raw_config(project_root, mutate)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _configure_aider(project_root: Path, apply: bool) -> bool:
|
|
38
|
+
command = ["aider", "--yes", "--no-show-model-warnings", "--message", "<task prompt>"]
|
|
39
|
+
if not apply:
|
|
40
|
+
console.print("[bold]Aider[/bold]")
|
|
41
|
+
console.print("Built-in executor: [dim]dev run TASK-001 --executor aider[/dim]")
|
|
42
|
+
console.print("Launch command: [dim]" + _format_command(command) + "[/dim]")
|
|
43
|
+
console.print("Aider does not expose a first-party DevCouncil MCP server.")
|
|
44
|
+
return True
|
|
45
|
+
|
|
46
|
+
if not shutil.which("aider"):
|
|
47
|
+
console.print("[yellow]Aider CLI not found on PATH. Install it before using `dev run --executor aider`.[/yellow]")
|
|
48
|
+
_record_aider_config(project_root)
|
|
49
|
+
console.print("[green]Aider executor enabled in .devcouncil/config.yaml.[/green]")
|
|
50
|
+
return True
|
|
51
|
+
|
|
52
|
+
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""Antigravity integration adapter."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import json
|
|
5
|
+
import shutil
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
from devcouncil.integrations.clients import common as _common
|
|
11
|
+
_project_root = _common._project_root
|
|
12
|
+
_warn_if_verify_only = _common._warn_if_verify_only
|
|
13
|
+
_server_args = _common._server_args
|
|
14
|
+
_format_command = _common._format_command
|
|
15
|
+
_quote_powershell_arg = _common._quote_powershell_arg
|
|
16
|
+
_run = _common._run
|
|
17
|
+
_run_capture = _common._run_capture
|
|
18
|
+
_config_path = _common._config_path
|
|
19
|
+
_load_raw_config = _common._load_raw_config
|
|
20
|
+
_save_raw_config = _common._save_raw_config
|
|
21
|
+
_load_json = _common._load_json
|
|
22
|
+
_save_json = _common._save_json
|
|
23
|
+
_load_json_strict = _common._load_json_strict
|
|
24
|
+
_mutate_raw_config = _common._mutate_raw_config
|
|
25
|
+
_batched_raw_config = _common._batched_raw_config
|
|
26
|
+
_probe_mcp_tools = _common._probe_mcp_tools
|
|
27
|
+
_print_command = _common._print_command
|
|
28
|
+
_configure = _common._configure
|
|
29
|
+
|
|
30
|
+
console = _common.console
|
|
31
|
+
def _antigravity_mcp_path(project_root: Path) -> Path:
|
|
32
|
+
return project_root / ".agents" / "mcp_config.json"
|
|
33
|
+
|
|
34
|
+
def _antigravity_mcp_config(project_root: Path) -> dict:
|
|
35
|
+
return {
|
|
36
|
+
"mcpServers": {
|
|
37
|
+
"devcouncil": {
|
|
38
|
+
"command": "devcouncil",
|
|
39
|
+
"args": ["mcp-server"],
|
|
40
|
+
"env": {"DEVCOUNCIL_PROJECT_ROOT": str(project_root)},
|
|
41
|
+
"cwd": str(project_root),
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
def _record_antigravity_config(project_root: Path) -> None:
|
|
47
|
+
def mutate(config: dict) -> None:
|
|
48
|
+
antigravity = config.setdefault("integrations", {}).setdefault("antigravity", {})
|
|
49
|
+
antigravity.update({
|
|
50
|
+
"enabled": True,
|
|
51
|
+
"mcp_config_path": str(_antigravity_mcp_path(project_root).relative_to(project_root)),
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
_mutate_raw_config(project_root, mutate)
|
|
55
|
+
|
|
56
|
+
def _write_antigravity_mcp_config(project_root: Path) -> Path:
|
|
57
|
+
path = _antigravity_mcp_path(project_root)
|
|
58
|
+
data = _load_json_strict(path, "Antigravity")
|
|
59
|
+
mcp_servers = data.setdefault("mcpServers", {})
|
|
60
|
+
mcp_servers["devcouncil"] = _antigravity_mcp_config(project_root)["mcpServers"]["devcouncil"]
|
|
61
|
+
_save_json(path, data)
|
|
62
|
+
return path
|
|
63
|
+
|
|
64
|
+
def _configure_antigravity(project_root: Path, apply: bool) -> bool:
|
|
65
|
+
path = _antigravity_mcp_path(project_root)
|
|
66
|
+
config = _antigravity_mcp_config(project_root)
|
|
67
|
+
if not apply:
|
|
68
|
+
console.print("[bold]Google Antigravity CLI[/bold]")
|
|
69
|
+
console.print(f"Project MCP config file: [dim]{path}[/dim]")
|
|
70
|
+
console.print(json.dumps(config, separators=(",", ":")), soft_wrap=True)
|
|
71
|
+
console.print(
|
|
72
|
+
"Direct executor command: "
|
|
73
|
+
"[dim]agy --print --print-timeout 30m "
|
|
74
|
+
'"Read and execute the DevCouncil task prompt at .devcouncil/TASK-001-antigravity-task.md."[/dim]'
|
|
75
|
+
)
|
|
76
|
+
return True
|
|
77
|
+
|
|
78
|
+
if not shutil.which("agy"):
|
|
79
|
+
console.print("[yellow]Antigravity CLI (`agy`) not found on PATH. Install it before using `dev run --executor antigravity`.[/yellow]")
|
|
80
|
+
try:
|
|
81
|
+
written = _write_antigravity_mcp_config(project_root)
|
|
82
|
+
except ValueError as exc:
|
|
83
|
+
console.print(f"[red]{exc}[/red]")
|
|
84
|
+
return False
|
|
85
|
+
_record_antigravity_config(project_root)
|
|
86
|
+
console.print(f"[green]Antigravity MCP config written:[/green] {written}")
|
|
87
|
+
return True
|