devcouncil 0.2.0 → 0.2.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.
Files changed (205) hide show
  1. package/README.md +191 -253
  2. package/bin/devcouncil.js +130 -32
  3. package/package.json +6 -17
  4. package/pyproject.toml +0 -66
  5. package/src/devcouncil/__init__.py +0 -0
  6. package/src/devcouncil/__main__.py +0 -4
  7. package/src/devcouncil/app/__init__.py +0 -28
  8. package/src/devcouncil/app/config.py +0 -320
  9. package/src/devcouncil/app/errors.py +0 -23
  10. package/src/devcouncil/app/events.py +0 -44
  11. package/src/devcouncil/app/orchestrator.py +0 -92
  12. package/src/devcouncil/app/project_status.py +0 -29
  13. package/src/devcouncil/app/run_context.py +0 -39
  14. package/src/devcouncil/app/state_machine.py +0 -108
  15. package/src/devcouncil/artifacts/__init__.py +0 -1
  16. package/src/devcouncil/artifacts/coverage.py +0 -96
  17. package/src/devcouncil/artifacts/graph.py +0 -163
  18. package/src/devcouncil/artifacts/migrations.py +0 -20
  19. package/src/devcouncil/artifacts/schemas.py +0 -23
  20. package/src/devcouncil/artifacts/serializer.py +0 -21
  21. package/src/devcouncil/artifacts/validators.py +0 -27
  22. package/src/devcouncil/assets/__init__.py +0 -1
  23. package/src/devcouncil/assets/devcouncil-logo.svg +0 -60
  24. package/src/devcouncil/assets/devcouncil_logo_premium.png +0 -0
  25. package/src/devcouncil/cli/__init__.py +0 -0
  26. package/src/devcouncil/cli/commands/__init__.py +0 -0
  27. package/src/devcouncil/cli/commands/agents.py +0 -292
  28. package/src/devcouncil/cli/commands/artifacts.py +0 -54
  29. package/src/devcouncil/cli/commands/ast.py +0 -22
  30. package/src/devcouncil/cli/commands/baseline.py +0 -35
  31. package/src/devcouncil/cli/commands/check.py +0 -209
  32. package/src/devcouncil/cli/commands/config.py +0 -115
  33. package/src/devcouncil/cli/commands/cost.py +0 -57
  34. package/src/devcouncil/cli/commands/dashboard.py +0 -31
  35. package/src/devcouncil/cli/commands/doctor.py +0 -340
  36. package/src/devcouncil/cli/commands/evidence.py +0 -48
  37. package/src/devcouncil/cli/commands/go.py +0 -656
  38. package/src/devcouncil/cli/commands/handoff.py +0 -69
  39. package/src/devcouncil/cli/commands/hook.py +0 -237
  40. package/src/devcouncil/cli/commands/init.py +0 -289
  41. package/src/devcouncil/cli/commands/integrate.py +0 -1515
  42. package/src/devcouncil/cli/commands/lsp.py +0 -20
  43. package/src/devcouncil/cli/commands/map.py +0 -112
  44. package/src/devcouncil/cli/commands/mcp_server.py +0 -18
  45. package/src/devcouncil/cli/commands/plan.py +0 -488
  46. package/src/devcouncil/cli/commands/prompt.py +0 -61
  47. package/src/devcouncil/cli/commands/repair.py +0 -89
  48. package/src/devcouncil/cli/commands/report.py +0 -137
  49. package/src/devcouncil/cli/commands/reset_demo_state.py +0 -33
  50. package/src/devcouncil/cli/commands/rollback.py +0 -59
  51. package/src/devcouncil/cli/commands/run.py +0 -289
  52. package/src/devcouncil/cli/commands/runs.py +0 -223
  53. package/src/devcouncil/cli/commands/scaffold.py +0 -32
  54. package/src/devcouncil/cli/commands/semantic.py +0 -47
  55. package/src/devcouncil/cli/commands/setup.py +0 -362
  56. package/src/devcouncil/cli/commands/shell.py +0 -73
  57. package/src/devcouncil/cli/commands/show.py +0 -76
  58. package/src/devcouncil/cli/commands/skills.py +0 -88
  59. package/src/devcouncil/cli/commands/status.py +0 -141
  60. package/src/devcouncil/cli/commands/tasks.py +0 -55
  61. package/src/devcouncil/cli/commands/trace.py +0 -88
  62. package/src/devcouncil/cli/commands/verify.py +0 -328
  63. package/src/devcouncil/cli/commands/version.py +0 -20
  64. package/src/devcouncil/cli/commands/watch.py +0 -574
  65. package/src/devcouncil/cli/commands/watch_fs.py +0 -40
  66. package/src/devcouncil/cli/main.py +0 -137
  67. package/src/devcouncil/council/__init__.py +0 -0
  68. package/src/devcouncil/council/prompts/__init__.py +0 -0
  69. package/src/devcouncil/council/prompts/arbiter.md +0 -19
  70. package/src/devcouncil/council/prompts/critic_a.md +0 -10
  71. package/src/devcouncil/council/prompts/critic_b.md +0 -10
  72. package/src/devcouncil/council/prompts/implementation_reviewer.md +0 -16
  73. package/src/devcouncil/council/prompts/planner_a.md +0 -16
  74. package/src/devcouncil/council/prompts/planner_b.md +0 -16
  75. package/src/devcouncil/council/prompts/rebuttal.md +0 -10
  76. package/src/devcouncil/council/prompts/spec_writer.md +0 -12
  77. package/src/devcouncil/domain/__init__.py +0 -0
  78. package/src/devcouncil/domain/assumption.py +0 -17
  79. package/src/devcouncil/domain/critique.py +0 -32
  80. package/src/devcouncil/domain/evidence.py +0 -47
  81. package/src/devcouncil/domain/gap.py +0 -52
  82. package/src/devcouncil/domain/requirement.py +0 -22
  83. package/src/devcouncil/domain/task.py +0 -55
  84. package/src/devcouncil/execution/__init__.py +0 -1
  85. package/src/devcouncil/execution/checkpoints.py +0 -246
  86. package/src/devcouncil/execution/context_builder.py +0 -60
  87. package/src/devcouncil/execution/executor.py +0 -15
  88. package/src/devcouncil/execution/fs_watcher.py +0 -180
  89. package/src/devcouncil/execution/handoff.py +0 -102
  90. package/src/devcouncil/execution/hook_policy.py +0 -253
  91. package/src/devcouncil/execution/patch.py +0 -77
  92. package/src/devcouncil/execution/paths.py +0 -14
  93. package/src/devcouncil/execution/permissions.py +0 -85
  94. package/src/devcouncil/execution/policy_engine.py +0 -343
  95. package/src/devcouncil/execution/prompt_builder.py +0 -671
  96. package/src/devcouncil/execution/shell_session.py +0 -225
  97. package/src/devcouncil/execution/task_runner.py +0 -170
  98. package/src/devcouncil/executors/__init__.py +0 -1
  99. package/src/devcouncil/executors/agent_registry.py +0 -575
  100. package/src/devcouncil/executors/coding_cli.py +0 -736
  101. package/src/devcouncil/executors/mini_swe.py +0 -73
  102. package/src/devcouncil/executors/native/__init__.py +0 -0
  103. package/src/devcouncil/executors/native/agent.py +0 -208
  104. package/src/devcouncil/executors/openhands.py +0 -71
  105. package/src/devcouncil/gating/__init__.py +0 -1
  106. package/src/devcouncil/gating/checks/__init__.py +0 -0
  107. package/src/devcouncil/gating/checks/clean_git.py +0 -52
  108. package/src/devcouncil/gating/checks/planned_files_check.py +0 -32
  109. package/src/devcouncil/gating/checks/requirement_coverage.py +0 -26
  110. package/src/devcouncil/gating/checks/secret_scan_check.py +0 -53
  111. package/src/devcouncil/gating/policy.py +0 -338
  112. package/src/devcouncil/hardware.py +0 -184
  113. package/src/devcouncil/indexing/__init__.py +0 -1
  114. package/src/devcouncil/indexing/ast_matcher.py +0 -168
  115. package/src/devcouncil/indexing/graph_index.py +0 -48
  116. package/src/devcouncil/indexing/lsp.py +0 -161
  117. package/src/devcouncil/indexing/repo_mapper.py +0 -1455
  118. package/src/devcouncil/indexing/semantic_index.py +0 -205
  119. package/src/devcouncil/integrations/actions.py +0 -146
  120. package/src/devcouncil/integrations/check.py +0 -423
  121. package/src/devcouncil/integrations/code_review_graph.py +0 -163
  122. package/src/devcouncil/integrations/github.py +0 -39
  123. package/src/devcouncil/integrations/github_intent.py +0 -142
  124. package/src/devcouncil/integrations/gitnexus.py +0 -62
  125. package/src/devcouncil/integrations/graphify.py +0 -34
  126. package/src/devcouncil/integrations/mcp/__init__.py +0 -0
  127. package/src/devcouncil/integrations/mcp/server.py +0 -2122
  128. package/src/devcouncil/integrations/opencode_devcouncil_plugin.mjs +0 -24
  129. package/src/devcouncil/integrations/pr_comments.py +0 -62
  130. package/src/devcouncil/live/__init__.py +0 -2
  131. package/src/devcouncil/live/cards.py +0 -349
  132. package/src/devcouncil/live/models.py +0 -63
  133. package/src/devcouncil/live/repair_prompt.py +0 -83
  134. package/src/devcouncil/live/reviewer.py +0 -70
  135. package/src/devcouncil/live/signals.py +0 -135
  136. package/src/devcouncil/live/summary.py +0 -34
  137. package/src/devcouncil/live/tasks.py +0 -18
  138. package/src/devcouncil/live/transcripts.py +0 -141
  139. package/src/devcouncil/llm/__init__.py +0 -1
  140. package/src/devcouncil/llm/cache.py +0 -42
  141. package/src/devcouncil/llm/model_defaults.yaml +0 -44
  142. package/src/devcouncil/llm/provider.py +0 -627
  143. package/src/devcouncil/llm/router.py +0 -310
  144. package/src/devcouncil/optimization/__init__.py +0 -1
  145. package/src/devcouncil/optimization/gepa_agent.py +0 -318
  146. package/src/devcouncil/planning/__init__.py +0 -1
  147. package/src/devcouncil/planning/arbiter_service.py +0 -57
  148. package/src/devcouncil/planning/correction_manifest.py +0 -303
  149. package/src/devcouncil/planning/critique_service.py +0 -71
  150. package/src/devcouncil/planning/plan_service.py +0 -60
  151. package/src/devcouncil/planning/prompt_enhancer_service.py +0 -167
  152. package/src/devcouncil/planning/repair_service.py +0 -39
  153. package/src/devcouncil/planning/spec_service.py +0 -70
  154. package/src/devcouncil/repo/__init__.py +0 -0
  155. package/src/devcouncil/repo/ci_scaffold.py +0 -157
  156. package/src/devcouncil/repo/gitignore.py +0 -123
  157. package/src/devcouncil/repo/sca.py +0 -374
  158. package/src/devcouncil/reporting/__init__.py +0 -0
  159. package/src/devcouncil/reporting/github_check.py +0 -32
  160. package/src/devcouncil/reporting/json_report.py +0 -30
  161. package/src/devcouncil/reporting/markdown_report.py +0 -83
  162. package/src/devcouncil/reporting/report_builder.py +0 -14
  163. package/src/devcouncil/skills/__init__.py +0 -19
  164. package/src/devcouncil/skills/library/README.md +0 -46
  165. package/src/devcouncil/skills/library/ai-training.md +0 -50
  166. package/src/devcouncil/skills/library/android.md +0 -50
  167. package/src/devcouncil/skills/library/backend.md +0 -52
  168. package/src/devcouncil/skills/library/core-engineering.md +0 -95
  169. package/src/devcouncil/skills/library/data-engineering.md +0 -47
  170. package/src/devcouncil/skills/library/desktop.md +0 -46
  171. package/src/devcouncil/skills/library/devops.md +0 -48
  172. package/src/devcouncil/skills/library/game-dev.md +0 -46
  173. package/src/devcouncil/skills/library/ios.md +0 -48
  174. package/src/devcouncil/skills/library/mobile-cross-platform.md +0 -46
  175. package/src/devcouncil/skills/library/security.md +0 -48
  176. package/src/devcouncil/skills/library/systems.md +0 -48
  177. package/src/devcouncil/skills/library/web.md +0 -47
  178. package/src/devcouncil/skills/library/windows.md +0 -47
  179. package/src/devcouncil/skills/registry.py +0 -330
  180. package/src/devcouncil/storage/__init__.py +0 -0
  181. package/src/devcouncil/storage/db.py +0 -147
  182. package/src/devcouncil/storage/models.py +0 -204
  183. package/src/devcouncil/storage/native.py +0 -557
  184. package/src/devcouncil/storage/repositories.py +0 -485
  185. package/src/devcouncil/telemetry/__init__.py +0 -0
  186. package/src/devcouncil/telemetry/cost.py +0 -140
  187. package/src/devcouncil/telemetry/model_pricing.yaml +0 -48
  188. package/src/devcouncil/telemetry/pricing.py +0 -28
  189. package/src/devcouncil/telemetry/traces.py +0 -146
  190. package/src/devcouncil/telemetry/tracker.py +0 -52
  191. package/src/devcouncil/ui/__init__.py +0 -1
  192. package/src/devcouncil/ui/dashboard.py +0 -423
  193. package/src/devcouncil/utils/__init__.py +0 -1
  194. package/src/devcouncil/utils/redaction.py +0 -147
  195. package/src/devcouncil/utils/subprocess_env.py +0 -69
  196. package/src/devcouncil/verification/__init__.py +0 -1
  197. package/src/devcouncil/verification/acceptance_compiler.py +0 -125
  198. package/src/devcouncil/verification/ad_hoc_check.py +0 -129
  199. package/src/devcouncil/verification/diff_coverage.py +0 -353
  200. package/src/devcouncil/verification/implementation_reviewer.py +0 -55
  201. package/src/devcouncil/verification/next_actions.py +0 -189
  202. package/src/devcouncil/verification/sandbox.py +0 -178
  203. package/src/devcouncil/verification/test_resolver.py +0 -91
  204. package/src/devcouncil/verification/verifier.py +0 -1548
  205. package/uv.lock +0 -1226
@@ -1,142 +0,0 @@
1
- """Resolve a DevCouncil goal from a GitHub issue or pull-request reference.
2
-
3
- A terse goal like ``"#142"`` or a full issue URL carries far more intent than a
4
- one-line argument — the issue body usually *is* the spec. This module detects
5
- such references and expands them into a rich goal string (title + body + a few
6
- comments) by shelling out to the authenticated ``gh`` CLI, so private repos work
7
- without any token plumbing. When ``gh`` is unavailable or the lookup fails, the
8
- caller keeps the original goal text unchanged — expansion is strictly additive.
9
- """
10
-
11
- from __future__ import annotations
12
-
13
- import json
14
- import re
15
- import shutil
16
- import subprocess
17
- from dataclasses import dataclass
18
- from pathlib import Path
19
-
20
- from devcouncil.utils.subprocess_env import clean_subprocess_env
21
-
22
- # Cap each pulled discussion comment so a long thread can't dominate the prompt.
23
- _MAX_COMMENT_CHARS = 600
24
-
25
- # "#142", "GH-142", "owner/repo#142", or a full issues/pull URL.
26
- _SHORT_REF = re.compile(r"^\s*(?:GH-|#)(\d+)\s*$", re.IGNORECASE)
27
- _OWNER_REPO_REF = re.compile(r"^\s*([\w.-]+/[\w.-]+)#(\d+)\s*$")
28
- _URL_REF = re.compile(
29
- r"^\s*https?://github\.com/([\w.-]+/[\w.-]+)/(issues|pull)/(\d+)",
30
- re.IGNORECASE,
31
- )
32
-
33
-
34
- @dataclass(frozen=True)
35
- class IntentRef:
36
- number: int
37
- kind: str # "issue" | "pull" | "auto"
38
- repo: str | None # "owner/repo" when explicit, else None (current repo)
39
-
40
-
41
- def parse_intent_ref(goal: str) -> IntentRef | None:
42
- """Return the GitHub reference a goal points at, or None if it's plain text."""
43
- text = goal.strip()
44
- m = _URL_REF.match(text)
45
- if m:
46
- kind = "pull" if m.group(2).lower() == "pull" else "issue"
47
- return IntentRef(number=int(m.group(3)), kind=kind, repo=m.group(1))
48
- m = _OWNER_REPO_REF.match(text)
49
- if m:
50
- return IntentRef(number=int(m.group(2)), kind="auto", repo=m.group(1))
51
- m = _SHORT_REF.match(text)
52
- if m:
53
- return IntentRef(number=int(m.group(1)), kind="auto", repo=None)
54
- return None
55
-
56
-
57
- def _gh_view(ref: IntentRef, sub: str, root: Path) -> dict | None:
58
- """Run ``gh <issue|pr> view`` and return the parsed JSON, or None on failure."""
59
- gh = shutil.which("gh")
60
- if not gh:
61
- return None
62
- cmd = [gh, sub, "view", str(ref.number), "--json", "title,body,comments,url,state"]
63
- if ref.repo:
64
- cmd += ["--repo", ref.repo]
65
- try:
66
- result = subprocess.run(
67
- cmd, cwd=root, capture_output=True, text=True,
68
- encoding="utf-8", errors="replace", timeout=20, env=clean_subprocess_env(),
69
- )
70
- except Exception:
71
- return None
72
- if result.returncode != 0 or not result.stdout.strip():
73
- return None
74
- try:
75
- data = json.loads(result.stdout)
76
- except json.JSONDecodeError:
77
- return None
78
- return data if isinstance(data, dict) else None
79
-
80
-
81
- def _compose_goal(ref: IntentRef, data: dict, source: str) -> str:
82
- title = str(data.get("title") or "").strip()
83
- body = str(data.get("body") or "").strip()
84
- url = str(data.get("url") or "").strip()
85
- lines = [f"Implement {source} #{ref.number}: {title}".rstrip(": ").rstrip()]
86
- if url:
87
- lines.append(f"Source: {url}")
88
- if body:
89
- lines += ["", body]
90
- # Pull in up to three discussion comments — clarifications often live there.
91
- # Cap each so a long thread can't bloat the planning prompt; the issue body
92
- # above is the primary spec, comments are secondary context.
93
- comments = data.get("comments")
94
- if isinstance(comments, list) and comments:
95
- snippets = []
96
- for comment in comments[:3]:
97
- text = str((comment or {}).get("body") or "").strip()
98
- if text:
99
- if len(text) > _MAX_COMMENT_CHARS:
100
- text = text[:_MAX_COMMENT_CHARS].rstrip() + " […]"
101
- snippets.append(text)
102
- if snippets:
103
- lines += ["", "Discussion notes:"]
104
- lines += [f"- {s}" for s in snippets]
105
- return "\n".join(lines).strip()
106
-
107
-
108
- def resolve_goal_intent(goal: str, root: Path) -> tuple[str, str | None]:
109
- """Expand a GitHub issue/PR reference into a full goal.
110
-
111
- Returns ``(goal, note)``. When ``goal`` is a reference and the lookup
112
- succeeds, the first element is the composed goal and ``note`` describes the
113
- expansion (for display). Otherwise the original goal is returned with a
114
- ``note`` explaining why it could not be expanded (or ``None`` when the goal
115
- was plain text and no expansion was attempted).
116
- """
117
- ref = parse_intent_ref(goal)
118
- if ref is None:
119
- return goal, None
120
-
121
- if not shutil.which("gh"):
122
- return goal, (
123
- f"Goal looks like GitHub reference #{ref.number}, but the `gh` CLI is not on "
124
- "PATH — using the literal text. Install/auth gh to pull the issue/PR body."
125
- )
126
-
127
- order = (
128
- ["pull", "issue"] if ref.kind == "pull"
129
- else ["issue", "pull"] if ref.kind == "issue"
130
- else ["issue", "pull"]
131
- )
132
- for sub in order:
133
- data = _gh_view(ref, "pr" if sub == "pull" else "issue", root)
134
- if data is not None:
135
- source = "pull request" if sub == "pull" else "issue"
136
- composed = _compose_goal(ref, data, source)
137
- return composed, f"Pulled intent from {source} #{ref.number} via gh."
138
-
139
- return goal, (
140
- f"Could not fetch GitHub #{ref.number} via gh (not found, no access, or not a "
141
- "git/GitHub repo) — using the literal text."
142
- )
@@ -1,62 +0,0 @@
1
- from pathlib import Path
2
- from rich.console import Console
3
- from devcouncil.indexing.graph_index import GraphIndex
4
-
5
- console = Console()
6
- AGENT_GUIDE_MARKER = "<!-- Managed by dev map: keep this file in sync with .devcouncil/repo_map.json. -->"
7
-
8
-
9
- def _agent_guide_text() -> str:
10
- return "\n".join(
11
- [
12
- AGENT_GUIDE_MARKER,
13
- "",
14
- "# Agent Workspace Guide",
15
- "",
16
- "Use `.devcouncil/repo_map.json` as the primary file index for this workspace.",
17
- "Repo map: `.devcouncil/repo_map.json`",
18
- "",
19
- "Workflow for agents:",
20
- "1. Open `.devcouncil/repo_map.json` before guessing at file locations.",
21
- "2. Use the `files` list to resolve module ownership and nearby siblings.",
22
- "3. Run `dev map` again after large refactors to refresh the map.",
23
- "",
24
- "Important surfaces:",
25
- "1. `src/devcouncil/cli/main.py` for CLI composition.",
26
- "2. `src/devcouncil/app/orchestrator.py` and `src/devcouncil/app/state_machine.py` for lifecycle control.",
27
- "3. `src/devcouncil/artifacts/graph.py` and `src/devcouncil/storage/repositories.py` for persistence and evidence.",
28
- "4. `src/devcouncil/execution/` and `src/devcouncil/executors/` for task execution.",
29
- "5. `src/devcouncil/verification/` and `src/devcouncil/gating/` for verification and policy gates.",
30
- "",
31
- "If the map and source disagree, trust the source and regenerate the map.",
32
- ]
33
- )
34
-
35
- class GitNexusIntegration:
36
- """
37
- Integration for GitNexus: Codebase knowledge graph and structural awareness.
38
- """
39
- def __init__(self, project_root: Path):
40
- self.project_root = project_root
41
-
42
- def initialize(self):
43
- console.print("[cyan]Initializing GitNexus context...[/cyan]")
44
- nexus_dir = self.project_root / ".devcouncil" / "nexus"
45
- nexus_dir.mkdir(exist_ok=True)
46
- # Mock initialization logic
47
- (nexus_dir / "index_config.json").write_text('{"mode": "structural", "version": "1.0"}')
48
- for filename in ("AGENTS.md", "CLAUDE.md"):
49
- path = self.project_root / filename
50
- if path.exists():
51
- existing = path.read_text(encoding="utf-8")
52
- if AGENT_GUIDE_MARKER not in existing:
53
- continue
54
- path.write_text(_agent_guide_text() + "\n", encoding="utf-8")
55
- console.print(" - GitNexus structural awareness active.")
56
-
57
- def sync_graph(self, graph_index: GraphIndex):
58
- """
59
- Export DevCouncil artifact graph to GitNexus.
60
- """
61
- console.print(" - Syncing DevCouncil artifacts to GitNexus...")
62
- pass
@@ -1,34 +0,0 @@
1
- from pathlib import Path
2
- from rich.console import Console
3
-
4
- console = Console()
5
-
6
- class GraphifyIntegration:
7
- """
8
- Integration for graphify: Always-on graph context and multi-agent integration.
9
- """
10
- def __init__(self, project_root: Path):
11
- self.project_root = project_root
12
-
13
- def initialize(self):
14
- console.print("[magenta]Initializing Graphify engine...[/magenta]")
15
- graphify_config = self.project_root / ".devcouncil" / "graphify.yaml"
16
- # Create a default graphify config
17
- content = """
18
- graph:
19
- engine: internal
20
- persist: true
21
- agents:
22
- shared_context: true
23
- hooks:
24
- enabled: true
25
- """
26
- graphify_config.write_text(content.strip())
27
- console.print(" - Graphify engine configured and ready.")
28
-
29
- def apply_rules(self):
30
- """
31
- Apply graph-based rules to implementation plans.
32
- """
33
- console.print(" - Graphify checking architectural rules...")
34
- pass
File without changes