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
|
@@ -22,16 +22,19 @@ from devcouncil.cli.commands.integrate import (
|
|
|
22
22
|
_codex_command,
|
|
23
23
|
_configure_antigravity,
|
|
24
24
|
_configure_cursor,
|
|
25
|
+
_configure_grok,
|
|
25
26
|
_configure_native_hooks,
|
|
26
27
|
_configure_opencode,
|
|
27
28
|
_configure_warp,
|
|
28
29
|
_configure,
|
|
29
|
-
_gemini_command,
|
|
30
30
|
)
|
|
31
31
|
from devcouncil.llm.provider import apply_provider_default_role_models, build_role_model_config, validate_model_provider
|
|
32
|
+
from devcouncil.telemetry.stages import log_stage, log_step
|
|
33
|
+
import logging
|
|
32
34
|
|
|
33
35
|
app = typer.Typer()
|
|
34
36
|
console = Console()
|
|
37
|
+
logger = logging.getLogger(__name__)
|
|
35
38
|
|
|
36
39
|
|
|
37
40
|
def _set_model_provider(project_root: Path, provider: str) -> None:
|
|
@@ -180,7 +183,6 @@ def _configure_coding_cli_integrations(project_root: Path, apply: bool, gemini_s
|
|
|
180
183
|
console.print("[bold]Coding CLI integration[/bold]")
|
|
181
184
|
commands = [
|
|
182
185
|
("Codex CLI", _codex_command(project_root)),
|
|
183
|
-
("Gemini CLI", _gemini_command(project_root, gemini_scope)),
|
|
184
186
|
("Claude Code", _claude_command(project_root, "local")),
|
|
185
187
|
]
|
|
186
188
|
results = []
|
|
@@ -190,6 +192,7 @@ def _configure_coding_cli_integrations(project_root: Path, apply: bool, gemini_s
|
|
|
190
192
|
continue
|
|
191
193
|
results.append(_configure(tool, command, apply))
|
|
192
194
|
results.append(_configure_cursor(project_root, apply))
|
|
195
|
+
results.append(_configure_grok(project_root, apply))
|
|
193
196
|
results.append(_configure_opencode(project_root, apply))
|
|
194
197
|
results.append(_configure_antigravity(project_root, apply))
|
|
195
198
|
results.append(_configure_warp(project_root, apply))
|
|
@@ -261,6 +264,9 @@ def setup(
|
|
|
261
264
|
raise typer.Exit(code=2)
|
|
262
265
|
|
|
263
266
|
root = project_root.expanduser().resolve()
|
|
267
|
+
from devcouncil.telemetry.logging_setup import set_log_dir
|
|
268
|
+
set_log_dir(root)
|
|
269
|
+
logger.info("dev setup: integrate=%s apply=%s", integrate, apply)
|
|
264
270
|
try:
|
|
265
271
|
role_models = parse_role_model_overrides(role_model)
|
|
266
272
|
initial_provider = validate_model_provider(provider) if provider else "openrouter"
|
|
@@ -268,95 +274,99 @@ def setup(
|
|
|
268
274
|
console.print(f"[red]{e}[/red]")
|
|
269
275
|
raise typer.Exit(code=2) from e
|
|
270
276
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
277
|
+
with log_stage("setup", project_root=root, integrate=integrate):
|
|
278
|
+
log_step("setup/1: initializing project", project_root=root, trace=True)
|
|
279
|
+
|
|
280
|
+
# Size the default local model to the host's memory ceiling (unified RAM on Apple
|
|
281
|
+
# Silicon, VRAM on a discrete GPU, system RAM otherwise) instead of the static 7b,
|
|
282
|
+
# so users on any OS get a capable council out of the box. Only when the user chose
|
|
283
|
+
# Ollama and did not pin a model.
|
|
284
|
+
if initial_provider == "ollama" and model is None:
|
|
285
|
+
from devcouncil import hardware
|
|
286
|
+
|
|
287
|
+
host = hardware.describe_host()
|
|
288
|
+
model = host.recommended_ollama_model
|
|
289
|
+
console.print(
|
|
290
|
+
f"[green]Detected {host.chip_label} ({host.memory_label}); "
|
|
291
|
+
f"defaulting Ollama model to {model}.[/green] "
|
|
292
|
+
"Override with --model, and pull it first: "
|
|
293
|
+
f"[bold]ollama pull {model}[/bold]."
|
|
294
|
+
)
|
|
295
|
+
elif initial_provider == "ollama" and model is not None:
|
|
296
|
+
# Model pinned explicitly — still remind the user it must be pulled locally.
|
|
297
|
+
console.print(
|
|
298
|
+
f"[green]Using Ollama model {model}.[/green] "
|
|
299
|
+
f"Pull it first if needed: [bold]ollama pull {model}[/bold]."
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
created = initialize_project(
|
|
303
|
+
root,
|
|
304
|
+
project_name=name,
|
|
305
|
+
model_provider=initial_provider,
|
|
306
|
+
model=model,
|
|
307
|
+
role_models=role_models,
|
|
308
|
+
with_map=not skip_map,
|
|
309
|
+
with_skills=not skip_skills,
|
|
291
310
|
)
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
"
|
|
351
|
-
"
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
"dev run TASK-001 --executor antigravity",
|
|
355
|
-
"dev verify TASK-001",
|
|
356
|
-
"",
|
|
357
|
-
"Use [bold]dev setup --integrate[/bold] to preview coding CLI MCP and native hook setup.",
|
|
358
|
-
"Use [bold]dev setup --integrate --apply[/bold] to configure detected clients.",
|
|
359
|
-
]),
|
|
360
|
-
title="DevCouncil is ready",
|
|
361
|
-
border_style="green",
|
|
362
|
-
))
|
|
311
|
+
if not created:
|
|
312
|
+
console.print(f"[yellow]DevCouncil is already initialized at {root / '.devcouncil'}.[/yellow]")
|
|
313
|
+
|
|
314
|
+
if provider:
|
|
315
|
+
try:
|
|
316
|
+
_set_model_provider(root, provider)
|
|
317
|
+
except ValueError as e:
|
|
318
|
+
console.print(f"[red]{e}[/red]")
|
|
319
|
+
raise typer.Exit(code=2) from e
|
|
320
|
+
|
|
321
|
+
_set_model_roles(root, model=model, role_models=role_models)
|
|
322
|
+
|
|
323
|
+
configured_provider = load_config(root).models.provider
|
|
324
|
+
_configure_vertexai_settings(root, configured_provider, vertex_project, vertex_location)
|
|
325
|
+
_configure_api_key(root, api_key, skip_api_key)
|
|
326
|
+
|
|
327
|
+
console.print()
|
|
328
|
+
render_doctor_check(root)
|
|
329
|
+
|
|
330
|
+
if scaffold_ci:
|
|
331
|
+
from devcouncil.repo.ci_scaffold import WORKFLOW_RELPATH, scaffold_ci as scaffold_ci_workflow
|
|
332
|
+
|
|
333
|
+
written = scaffold_ci_workflow(root)
|
|
334
|
+
if written is None:
|
|
335
|
+
console.print(f"[yellow]{WORKFLOW_RELPATH.as_posix()} already exists; left unchanged.[/yellow]")
|
|
336
|
+
else:
|
|
337
|
+
console.print(f"[green]Wrote starter CI workflow {written.relative_to(root).as_posix()}.[/green]")
|
|
338
|
+
|
|
339
|
+
if integrate:
|
|
340
|
+
_configure_coding_cli_integrations(root, apply=apply, gemini_scope=gemini_scope)
|
|
341
|
+
elif created and not skip_integrations:
|
|
342
|
+
_prompt_for_first_run_integrations(root, apply=True, gemini_scope=gemini_scope)
|
|
343
|
+
|
|
344
|
+
console.print()
|
|
345
|
+
console.print(Panel.fit(
|
|
346
|
+
"\n".join([
|
|
347
|
+
"[bold]Next commands[/bold]",
|
|
348
|
+
f"Keep running DevCouncil commands in this terminal at: {root}",
|
|
349
|
+
"One-command agent path:",
|
|
350
|
+
"dev e2e \"Describe the implementation goal\"",
|
|
351
|
+
"",
|
|
352
|
+
"Manual sidecar path:",
|
|
353
|
+
"dev plan \"Describe the implementation goal\"",
|
|
354
|
+
"dev tasks",
|
|
355
|
+
"dev run TASK-001 --executor manual",
|
|
356
|
+
"dev prompt TASK-001",
|
|
357
|
+
"Paste only the dev prompt output into your coding CLI.",
|
|
358
|
+
"Paste only the dev prompt output into your coding CLI, or run directly:",
|
|
359
|
+
"dev run TASK-001 --executor codex",
|
|
360
|
+
"dev run TASK-001 --executor gemini",
|
|
361
|
+
"dev run TASK-001 --executor claude",
|
|
362
|
+
"dev run TASK-001 --executor opencode",
|
|
363
|
+
"dev run TASK-001 --executor antigravity",
|
|
364
|
+
"dev verify TASK-001",
|
|
365
|
+
"",
|
|
366
|
+
"Use [bold]dev setup --integrate[/bold] to preview coding CLI MCP and native hook setup.",
|
|
367
|
+
"Use [bold]dev setup --integrate --apply[/bold] to configure detected clients.",
|
|
368
|
+
]),
|
|
369
|
+
title="DevCouncil is ready",
|
|
370
|
+
border_style="green",
|
|
371
|
+
))
|
|
372
|
+
log_step("setup/complete", project_root=root, trace=True)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import logging
|
|
1
2
|
import typer
|
|
2
3
|
from pathlib import Path
|
|
3
4
|
from rich.console import Console
|
|
@@ -6,8 +7,10 @@ from devcouncil.cli.commands.init import initialize_project
|
|
|
6
7
|
from devcouncil.execution.shell_session import GuardedShellSession
|
|
7
8
|
from devcouncil.storage.db import get_db
|
|
8
9
|
from devcouncil.storage.repositories import TaskRepository
|
|
10
|
+
from devcouncil.telemetry.stages import log_stage, log_step
|
|
9
11
|
|
|
10
12
|
console = Console()
|
|
13
|
+
logger = logging.getLogger(__name__)
|
|
11
14
|
|
|
12
15
|
|
|
13
16
|
def shell(
|
|
@@ -21,53 +24,59 @@ def shell(
|
|
|
21
24
|
Run guarded shell commands for a task.
|
|
22
25
|
"""
|
|
23
26
|
root = project_root.expanduser().resolve()
|
|
27
|
+
from devcouncil.telemetry.logging_setup import set_log_dir
|
|
28
|
+
set_log_dir(root)
|
|
29
|
+
logger.info("dev shell: task=%s command=%s", task_id, "set" if command else "interactive")
|
|
24
30
|
initialize_project(root, quiet=True)
|
|
25
31
|
db = get_db(root)
|
|
26
32
|
if not db:
|
|
27
33
|
console.print("[red]DevCouncil not initialized.[/red]")
|
|
28
34
|
raise typer.Exit(code=1)
|
|
29
35
|
|
|
30
|
-
with
|
|
31
|
-
task =
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
with log_stage("shell", project_root=root, task_id=task_id):
|
|
37
|
+
log_step("shell/1: loading task and starting session", project_root=root, task_id=task_id, trace=True)
|
|
38
|
+
with db.get_session() as session:
|
|
39
|
+
task = TaskRepository(session).get_by_id(task_id)
|
|
40
|
+
if not task:
|
|
41
|
+
console.print(f"[red]Task {task_id} not found.[/red]")
|
|
42
|
+
raise typer.Exit(code=1)
|
|
35
43
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
44
|
+
try:
|
|
45
|
+
session_runner = GuardedShellSession(root, task, shell=shell_name)
|
|
46
|
+
except ValueError as exc:
|
|
47
|
+
console.print(f"[red]{exc}[/red]")
|
|
48
|
+
raise typer.Exit(code=2)
|
|
49
|
+
try:
|
|
50
|
+
session_runner.start(force=force)
|
|
51
|
+
except ValueError as exc:
|
|
52
|
+
console.print(f"[red]{exc}[/red]")
|
|
53
|
+
console.print(
|
|
54
|
+
"[yellow]Another shell session may be active for this task. If it is "
|
|
55
|
+
"stale (a previous session crashed), re-run with [bold]--force[/bold] to "
|
|
56
|
+
"reclaim it.[/yellow]"
|
|
57
|
+
)
|
|
58
|
+
raise typer.Exit(code=2)
|
|
59
|
+
try:
|
|
60
|
+
if command:
|
|
61
|
+
log_step("shell/2: running guarded command", project_root=root, task_id=task_id)
|
|
62
|
+
code = session_runner.run_one(command)
|
|
63
|
+
log_step("shell/complete", project_root=root, task_id=task_id, trace=True)
|
|
64
|
+
raise typer.Exit(code=code)
|
|
57
65
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
66
|
+
console.print(f"[cyan]Guarded shell for {task_id}. Type exit or quit to end.[/cyan]")
|
|
67
|
+
while True:
|
|
68
|
+
try:
|
|
69
|
+
line = input(f"devcouncil:{task_id}> ")
|
|
70
|
+
except (EOFError, KeyboardInterrupt):
|
|
71
|
+
break
|
|
72
|
+
normalized = line.strip()
|
|
73
|
+
if normalized.lower() in {"exit", "quit"}:
|
|
74
|
+
break
|
|
75
|
+
if not normalized:
|
|
76
|
+
continue
|
|
77
|
+
code = session_runner.run_one(normalized)
|
|
78
|
+
if code != 0:
|
|
79
|
+
console.print(f"[yellow]Command exited with {code}[/yellow]")
|
|
80
|
+
finally:
|
|
81
|
+
session_runner.finish()
|
|
82
|
+
log_step("shell/complete", project_root=root, task_id=task_id, trace=True)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
from devcouncil.utils.json_persist import dump_json
|
|
2
|
+
import logging
|
|
2
3
|
from pathlib import Path
|
|
3
4
|
|
|
4
5
|
import typer
|
|
@@ -7,9 +8,11 @@ from rich.panel import Panel
|
|
|
7
8
|
from devcouncil.cli.commands.init import initialize_project
|
|
8
9
|
from devcouncil.storage.db import get_db
|
|
9
10
|
from devcouncil.storage.repositories import TaskRepository, RequirementRepository
|
|
11
|
+
from devcouncil.telemetry.stages import log_stage, log_step
|
|
10
12
|
|
|
11
13
|
app = typer.Typer()
|
|
12
14
|
console = Console()
|
|
15
|
+
logger = logging.getLogger(__name__)
|
|
13
16
|
|
|
14
17
|
@app.callback(invoke_without_command=True)
|
|
15
18
|
def show(
|
|
@@ -25,52 +28,63 @@ def show(
|
|
|
25
28
|
return
|
|
26
29
|
|
|
27
30
|
root = project_root.expanduser().resolve()
|
|
31
|
+
from devcouncil.telemetry.logging_setup import set_log_dir
|
|
32
|
+
set_log_dir(root)
|
|
33
|
+
logger.info("dev show: task=%s json=%s", task_id, json_format)
|
|
28
34
|
initialize_project(root, quiet=True)
|
|
29
35
|
db = get_db(root)
|
|
30
36
|
if not db:
|
|
31
37
|
raise typer.Exit(code=1)
|
|
32
38
|
|
|
33
|
-
with
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
if not task:
|
|
39
|
-
console.print(f"[red]Task {task_id} not found.[/red]")
|
|
40
|
-
raise typer.Exit(code=1)
|
|
41
|
-
|
|
42
|
-
reqs = req_repo.get_all()
|
|
43
|
-
req_map = {r.id: r for r in reqs}
|
|
39
|
+
with log_stage("show", project_root=root, task_id=task_id):
|
|
40
|
+
log_step("show/1: loading task details", project_root=root, task_id=task_id, trace=True)
|
|
41
|
+
with db.get_session() as session:
|
|
42
|
+
task_repo = TaskRepository(session)
|
|
43
|
+
req_repo = RequirementRepository(session)
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
"linked_requirements": linked_requirements,
|
|
54
|
-
}, indent=2))
|
|
55
|
-
return
|
|
45
|
+
task = task_repo.get_by_id(task_id)
|
|
46
|
+
if not task:
|
|
47
|
+
message = f"Task {task_id} not found."
|
|
48
|
+
if json_format:
|
|
49
|
+
typer.echo(dump_json({"ok": False, "error": message, "task_id": task_id}, indent=2))
|
|
50
|
+
else:
|
|
51
|
+
console.print(f"[red]{message}[/red]")
|
|
52
|
+
raise typer.Exit(code=1)
|
|
56
53
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
output += "[bold]Linked Requirements:[/bold]\n"
|
|
61
|
-
for req_id in task.requirement_ids:
|
|
62
|
-
req = req_map.get(req_id)
|
|
63
|
-
if req:
|
|
64
|
-
output += f" - [cyan]{req.id}[/cyan]: {req.title}\n"
|
|
65
|
-
else:
|
|
66
|
-
output += f" - [cyan]{req_id}[/cyan]: (Requirement not found)\n"
|
|
67
|
-
|
|
68
|
-
output += "\n[bold]Planned Files:[/bold]\n"
|
|
69
|
-
for pf in task.planned_files:
|
|
70
|
-
output += f" - {pf.path} ({pf.allowed_change}): {pf.reason}\n"
|
|
71
|
-
|
|
72
|
-
output += "\n[bold]Expected Tests:[/bold]\n"
|
|
73
|
-
for et in task.expected_tests:
|
|
74
|
-
output += f" - {et}\n"
|
|
54
|
+
reqs = req_repo.get_all()
|
|
55
|
+
req_map = {r.id: r for r in reqs}
|
|
75
56
|
|
|
76
|
-
|
|
57
|
+
if json_format:
|
|
58
|
+
linked_requirements = [
|
|
59
|
+
req_map[req_id].model_dump()
|
|
60
|
+
for req_id in task.requirement_ids
|
|
61
|
+
if req_id in req_map
|
|
62
|
+
]
|
|
63
|
+
typer.echo(dump_json({
|
|
64
|
+
"task": task.model_dump(),
|
|
65
|
+
"linked_requirements": linked_requirements,
|
|
66
|
+
}, indent=2))
|
|
67
|
+
log_step("show/complete", project_root=root, task_id=task_id, trace=True)
|
|
68
|
+
return
|
|
69
|
+
|
|
70
|
+
output = f"[bold]Status:[/bold] {task.status}\n\n"
|
|
71
|
+
output += f"[bold]Description:[/bold]\n{task.description}\n\n"
|
|
72
|
+
|
|
73
|
+
output += "[bold]Linked Requirements:[/bold]\n"
|
|
74
|
+
for req_id in task.requirement_ids:
|
|
75
|
+
req = req_map.get(req_id)
|
|
76
|
+
if req:
|
|
77
|
+
output += f" - [cyan]{req.id}[/cyan]: {req.title}\n"
|
|
78
|
+
else:
|
|
79
|
+
output += f" - [cyan]{req_id}[/cyan]: (Requirement not found)\n"
|
|
80
|
+
|
|
81
|
+
output += "\n[bold]Planned Files:[/bold]\n"
|
|
82
|
+
for pf in task.planned_files:
|
|
83
|
+
output += f" - {pf.path} ({pf.allowed_change}): {pf.reason}\n"
|
|
84
|
+
|
|
85
|
+
output += "\n[bold]Expected Tests:[/bold]\n"
|
|
86
|
+
for et in task.expected_tests:
|
|
87
|
+
output += f" - {et}\n"
|
|
88
|
+
|
|
89
|
+
console.print(Panel(output, title=f"Task {task.id}: {task.title}", expand=False))
|
|
90
|
+
log_step("show/complete", project_root=root, task_id=task_id, trace=True)
|
|
@@ -7,9 +7,12 @@ from rich.table import Table
|
|
|
7
7
|
|
|
8
8
|
from devcouncil.knowledge.frontmatter import build_frontmatter_markdown
|
|
9
9
|
from devcouncil.skills.registry import Skill, get_skill, load_skills, scaffold_skills, select_skills
|
|
10
|
+
from devcouncil.telemetry.stages import log_stage, log_step
|
|
11
|
+
import logging
|
|
10
12
|
|
|
11
13
|
app = typer.Typer(help="Inspect and scaffold DevCouncil engineering skills for coding agents.")
|
|
12
14
|
console = Console()
|
|
15
|
+
logger = logging.getLogger(__name__)
|
|
13
16
|
|
|
14
17
|
|
|
15
18
|
def _is_repo_skill(skill, project_root: Path) -> bool:
|
|
@@ -33,27 +36,33 @@ def skills(
|
|
|
33
36
|
return
|
|
34
37
|
|
|
35
38
|
root = project_root.expanduser().resolve()
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
from devcouncil.telemetry.logging_setup import set_log_dir
|
|
40
|
+
set_log_dir(root)
|
|
41
|
+
logger.info("dev skills list: goal=%r", goal)
|
|
42
|
+
with log_stage("skills", project_root=root):
|
|
43
|
+
log_step("skills/1: loading skill registry", project_root=root, trace=True)
|
|
44
|
+
all_skills = load_skills(project_root=root)
|
|
45
|
+
if not all_skills:
|
|
46
|
+
console.print("[yellow]No skills found in the DevCouncil skills library.[/yellow]")
|
|
47
|
+
raise typer.Exit()
|
|
40
48
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
49
|
+
selected = {skill.name for skill in select_skills(goal, root)}
|
|
50
|
+
table = Table(title="DevCouncil Skills")
|
|
51
|
+
table.add_column("Skill", style="cyan")
|
|
52
|
+
table.add_column("Source", justify="center")
|
|
53
|
+
table.add_column("Applies", justify="center")
|
|
54
|
+
table.add_column("Description")
|
|
55
|
+
for skill in all_skills:
|
|
56
|
+
applies = "always" if skill.always else ("yes" if skill.name in selected else "-")
|
|
57
|
+
style = "green" if skill.name in selected else "dim"
|
|
58
|
+
source = "repo" if _is_repo_skill(skill, root) else "library"
|
|
59
|
+
table.add_row(skill.name, source, f"[{style}]{applies}[/{style}]", skill.description)
|
|
60
|
+
console.print(table)
|
|
61
|
+
console.print(
|
|
62
|
+
"\nScaffold the applicable skills into this repo with: "
|
|
63
|
+
"[bold]dev skills scaffold[/bold] (add a goal to widen selection, or --all)."
|
|
64
|
+
)
|
|
65
|
+
log_step("skills/complete", project_root=root, count=len(all_skills), trace=True)
|
|
57
66
|
|
|
58
67
|
|
|
59
68
|
@app.command("show")
|