devcouncil 0.1.1 → 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 (146) hide show
  1. package/README.md +218 -96
  2. package/bin/devcouncil.js +130 -32
  3. package/package.json +7 -11
  4. package/pyproject.toml +0 -34
  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 -158
  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 -143
  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/cli/__init__.py +0 -0
  23. package/src/devcouncil/cli/commands/__init__.py +0 -0
  24. package/src/devcouncil/cli/commands/artifacts.py +0 -51
  25. package/src/devcouncil/cli/commands/ast.py +0 -22
  26. package/src/devcouncil/cli/commands/baseline.py +0 -35
  27. package/src/devcouncil/cli/commands/config.py +0 -76
  28. package/src/devcouncil/cli/commands/dashboard.py +0 -26
  29. package/src/devcouncil/cli/commands/doctor.py +0 -140
  30. package/src/devcouncil/cli/commands/go.py +0 -237
  31. package/src/devcouncil/cli/commands/hook.py +0 -128
  32. package/src/devcouncil/cli/commands/init.py +0 -153
  33. package/src/devcouncil/cli/commands/integrate.py +0 -726
  34. package/src/devcouncil/cli/commands/lsp.py +0 -20
  35. package/src/devcouncil/cli/commands/map.py +0 -42
  36. package/src/devcouncil/cli/commands/mcp_server.py +0 -18
  37. package/src/devcouncil/cli/commands/plan.py +0 -327
  38. package/src/devcouncil/cli/commands/prompt.py +0 -50
  39. package/src/devcouncil/cli/commands/repair.py +0 -72
  40. package/src/devcouncil/cli/commands/report.py +0 -129
  41. package/src/devcouncil/cli/commands/reset_demo_state.py +0 -31
  42. package/src/devcouncil/cli/commands/rollback.py +0 -60
  43. package/src/devcouncil/cli/commands/run.py +0 -269
  44. package/src/devcouncil/cli/commands/setup.py +0 -223
  45. package/src/devcouncil/cli/commands/show.py +0 -76
  46. package/src/devcouncil/cli/commands/status.py +0 -117
  47. package/src/devcouncil/cli/commands/tasks.py +0 -55
  48. package/src/devcouncil/cli/commands/trace.py +0 -44
  49. package/src/devcouncil/cli/commands/verify.py +0 -193
  50. package/src/devcouncil/cli/commands/version.py +0 -20
  51. package/src/devcouncil/cli/commands/watch.py +0 -574
  52. package/src/devcouncil/cli/main.py +0 -88
  53. package/src/devcouncil/council/__init__.py +0 -0
  54. package/src/devcouncil/council/prompts/__init__.py +0 -0
  55. package/src/devcouncil/council/prompts/arbiter.md +0 -19
  56. package/src/devcouncil/council/prompts/critic_a.md +0 -10
  57. package/src/devcouncil/council/prompts/critic_b.md +0 -10
  58. package/src/devcouncil/council/prompts/implementation_reviewer.md +0 -16
  59. package/src/devcouncil/council/prompts/planner_a.md +0 -16
  60. package/src/devcouncil/council/prompts/planner_b.md +0 -16
  61. package/src/devcouncil/council/prompts/rebuttal.md +0 -10
  62. package/src/devcouncil/council/prompts/spec_writer.md +0 -12
  63. package/src/devcouncil/domain/__init__.py +0 -0
  64. package/src/devcouncil/domain/assumption.py +0 -17
  65. package/src/devcouncil/domain/critique.py +0 -32
  66. package/src/devcouncil/domain/evidence.py +0 -27
  67. package/src/devcouncil/domain/gap.py +0 -26
  68. package/src/devcouncil/domain/requirement.py +0 -22
  69. package/src/devcouncil/domain/task.py +0 -26
  70. package/src/devcouncil/execution/__init__.py +0 -1
  71. package/src/devcouncil/execution/context_builder.py +0 -60
  72. package/src/devcouncil/execution/executor.py +0 -15
  73. package/src/devcouncil/execution/hook_policy.py +0 -165
  74. package/src/devcouncil/execution/patch.py +0 -28
  75. package/src/devcouncil/execution/paths.py +0 -14
  76. package/src/devcouncil/execution/permissions.py +0 -92
  77. package/src/devcouncil/execution/prompt_builder.py +0 -59
  78. package/src/devcouncil/execution/task_runner.py +0 -166
  79. package/src/devcouncil/executors/__init__.py +0 -1
  80. package/src/devcouncil/executors/coding_cli.py +0 -112
  81. package/src/devcouncil/executors/mini_swe.py +0 -73
  82. package/src/devcouncil/executors/native/__init__.py +0 -0
  83. package/src/devcouncil/executors/native/agent.py +0 -107
  84. package/src/devcouncil/executors/openhands.py +0 -71
  85. package/src/devcouncil/gating/__init__.py +0 -1
  86. package/src/devcouncil/gating/checks/__init__.py +0 -0
  87. package/src/devcouncil/gating/checks/clean_git.py +0 -50
  88. package/src/devcouncil/gating/checks/planned_files_check.py +0 -32
  89. package/src/devcouncil/gating/checks/requirement_coverage.py +0 -26
  90. package/src/devcouncil/gating/checks/secret_scan_check.py +0 -34
  91. package/src/devcouncil/gating/policy.py +0 -190
  92. package/src/devcouncil/indexing/__init__.py +0 -1
  93. package/src/devcouncil/indexing/ast_matcher.py +0 -168
  94. package/src/devcouncil/indexing/graph_index.py +0 -48
  95. package/src/devcouncil/indexing/lsp.py +0 -120
  96. package/src/devcouncil/indexing/repo_mapper.py +0 -208
  97. package/src/devcouncil/indexing/symbol_index.py +0 -0
  98. package/src/devcouncil/integrations/code_review_graph.py +0 -163
  99. package/src/devcouncil/integrations/github.py +0 -39
  100. package/src/devcouncil/integrations/gitnexus.py +0 -27
  101. package/src/devcouncil/integrations/graphify.py +0 -34
  102. package/src/devcouncil/integrations/mcp/__init__.py +0 -0
  103. package/src/devcouncil/integrations/mcp/server.py +0 -599
  104. package/src/devcouncil/integrations/pr_comments.py +0 -62
  105. package/src/devcouncil/live/__init__.py +0 -2
  106. package/src/devcouncil/live/cards.py +0 -207
  107. package/src/devcouncil/live/models.py +0 -63
  108. package/src/devcouncil/live/repair_prompt.py +0 -83
  109. package/src/devcouncil/live/reviewer.py +0 -70
  110. package/src/devcouncil/live/signals.py +0 -135
  111. package/src/devcouncil/live/summary.py +0 -34
  112. package/src/devcouncil/live/tasks.py +0 -18
  113. package/src/devcouncil/live/transcripts.py +0 -138
  114. package/src/devcouncil/llm/__init__.py +0 -1
  115. package/src/devcouncil/llm/cache.py +0 -38
  116. package/src/devcouncil/llm/provider.py +0 -146
  117. package/src/devcouncil/llm/router.py +0 -125
  118. package/src/devcouncil/planning/__init__.py +0 -1
  119. package/src/devcouncil/planning/arbiter_service.py +0 -57
  120. package/src/devcouncil/planning/critique_service.py +0 -66
  121. package/src/devcouncil/planning/plan_service.py +0 -46
  122. package/src/devcouncil/planning/prompt_enhancer_service.py +0 -86
  123. package/src/devcouncil/planning/repair_service.py +0 -39
  124. package/src/devcouncil/planning/spec_service.py +0 -44
  125. package/src/devcouncil/repo/__init__.py +0 -0
  126. package/src/devcouncil/reporting/__init__.py +0 -0
  127. package/src/devcouncil/reporting/github_check.py +0 -32
  128. package/src/devcouncil/reporting/json_report.py +0 -20
  129. package/src/devcouncil/reporting/markdown_report.py +0 -68
  130. package/src/devcouncil/reporting/report_builder.py +0 -14
  131. package/src/devcouncil/storage/__init__.py +0 -0
  132. package/src/devcouncil/storage/db.py +0 -66
  133. package/src/devcouncil/storage/models.py +0 -83
  134. package/src/devcouncil/storage/repositories.py +0 -423
  135. package/src/devcouncil/telemetry/__init__.py +0 -0
  136. package/src/devcouncil/telemetry/cost.py +0 -34
  137. package/src/devcouncil/telemetry/traces.py +0 -91
  138. package/src/devcouncil/telemetry/tracker.py +0 -49
  139. package/src/devcouncil/ui/__init__.py +0 -1
  140. package/src/devcouncil/ui/dashboard.py +0 -122
  141. package/src/devcouncil/utils/__init__.py +0 -1
  142. package/src/devcouncil/utils/redaction.py +0 -141
  143. package/src/devcouncil/verification/__init__.py +0 -1
  144. package/src/devcouncil/verification/implementation_reviewer.py +0 -55
  145. package/src/devcouncil/verification/verifier.py +0 -530
  146. package/uv.lock +0 -1085
@@ -1,208 +0,0 @@
1
- import json
2
- import logging
3
- import os
4
- import subprocess
5
- from pathlib import Path
6
- from typing import List, Dict
7
-
8
- from pydantic import BaseModel, Field
9
-
10
- from devcouncil.indexing.lsp import LspInspector
11
-
12
- logger = logging.getLogger(__name__)
13
-
14
- class RepoMap(BaseModel):
15
- languages: List[str]
16
- frameworks: List[str]
17
- package_managers: List[str]
18
- test_commands: List[str]
19
- important_files: List[str]
20
- candidate_files: List[Dict[str, str]]
21
- lsp: Dict[str, object] = Field(default_factory=dict)
22
-
23
- class RepoMapper:
24
- def __init__(self, project_root: Path):
25
- self.project_root = project_root
26
-
27
- def _is_runtime_or_generated_file(self, path: str) -> bool:
28
- normalized = path.replace("\\", "/")
29
- parts = set(normalized.split("/"))
30
- if "__pycache__" in parts or normalized.endswith(".pyc"):
31
- return True
32
- if parts.intersection({".git", ".devcouncil", ".pytest_cache", ".ruff_cache", ".mypy_cache", ".venv"}):
33
- return True
34
- if normalized.startswith("dist/") or normalized.startswith("build/"):
35
- return True
36
- return False
37
-
38
- def get_git_files(self) -> List[str]:
39
- try:
40
- output = subprocess.check_output(
41
- ["git", "ls-files", "--cached", "--others", "--exclude-standard"],
42
- cwd=self.project_root,
43
- stderr=subprocess.DEVNULL
44
- ).decode().splitlines()
45
- return [path for path in output if not self._is_runtime_or_generated_file(path)]
46
- except Exception:
47
- # Fallback to os.walk if not a git repo or git missing
48
- files = []
49
- for root, _, filenames in os.walk(self.project_root):
50
- for f in filenames:
51
- rel_path = os.path.relpath(os.path.join(root, f), self.project_root)
52
- if not rel_path.startswith(".") and not self._is_runtime_or_generated_file(rel_path):
53
- files.append(rel_path)
54
- return files
55
-
56
- def detect_languages(self, files: List[str]) -> List[str]:
57
- exts = {os.path.splitext(f)[1] for f in files}
58
- lang_map = {
59
- ".py": "python",
60
- ".ts": "typescript",
61
- ".tsx": "typescript",
62
- ".js": "javascript",
63
- ".jsx": "javascript",
64
- ".go": "go",
65
- ".rs": "rust",
66
- ".java": "java",
67
- ".c": "c",
68
- ".cpp": "cpp",
69
- }
70
- return sorted(list({lang_map[ext] for ext in exts if ext in lang_map}))
71
-
72
- def detect_frameworks(self, files: List[str]) -> List[str]:
73
- frameworks = []
74
- file_set = set(files)
75
- if "package.json" in file_set:
76
- content = (self.project_root / "package.json").read_text()
77
- if "next" in content:
78
- frameworks.append("nextjs")
79
- if "react" in content:
80
- frameworks.append("react")
81
- if "vue" in content:
82
- frameworks.append("vue")
83
- if "express" in content:
84
- frameworks.append("express")
85
-
86
- if "requirements.txt" in file_set or "pyproject.toml" in file_set:
87
- try:
88
- content = ""
89
- if "requirements.txt" in file_set:
90
- content += (self.project_root / "requirements.txt").read_text()
91
- if "pyproject.toml" in file_set:
92
- content += (self.project_root / "pyproject.toml").read_text()
93
-
94
- if "fastapi" in content.lower():
95
- frameworks.append("fastapi")
96
- if "flask" in content.lower():
97
- frameworks.append("flask")
98
- if "django" in content.lower():
99
- frameworks.append("django")
100
- except Exception as e:
101
- logger.debug("Failed to read Python config files: %s", e)
102
- return frameworks
103
-
104
- def detect_package_managers(self, files: List[str]) -> List[str]:
105
- managers = []
106
- file_set = set(files)
107
- if "package-lock.json" in file_set:
108
- managers.append("npm")
109
- elif "package.json" in file_set:
110
- managers.append("npm")
111
- if "yarn.lock" in file_set:
112
- managers.append("yarn")
113
- if "pnpm-lock.yaml" in file_set:
114
- managers.append("pnpm")
115
- if "requirements.txt" in file_set:
116
- managers.append("pip")
117
- if "uv.lock" in file_set:
118
- managers.append("uv")
119
- if "go.sum" in file_set:
120
- managers.append("go mod")
121
- return managers
122
-
123
- def detect_test_commands(self, files: List[str]) -> List[str]:
124
- """Detect test, lint, and typecheck commands from project config."""
125
- commands: List[str] = []
126
- file_set = set(files)
127
-
128
- # Node.js projects: read scripts from package.json
129
- if "package.json" in file_set:
130
- try:
131
- pkg = json.loads((self.project_root / "package.json").read_text())
132
- scripts = pkg.get("scripts", {})
133
- pm = "pnpm" if "pnpm-lock.yaml" in file_set else (
134
- "yarn" if "yarn.lock" in file_set else "npm"
135
- )
136
- for key in ["test", "lint", "typecheck", "check", "type-check"]:
137
- if key in scripts:
138
- if pm == "npm" and key != "test":
139
- commands.append(f"npm run {key}")
140
- else:
141
- commands.append(f"{pm} {key}")
142
- except Exception as e:
143
- logger.debug("Failed to parse package.json scripts: %s", e)
144
-
145
- # Python projects
146
- if "pyproject.toml" in file_set or "setup.py" in file_set:
147
- if any(f.startswith("tests/") or f.startswith("test_") for f in files):
148
- commands.append("pytest")
149
- commands.append("ruff check .")
150
- commands.append("mypy .")
151
-
152
- # Go projects
153
- if "go.mod" in file_set:
154
- commands.append("go test ./...")
155
- commands.append("go vet ./...")
156
-
157
- # Rust projects
158
- if "Cargo.toml" in file_set:
159
- commands.append("cargo test")
160
- commands.append("cargo clippy")
161
-
162
- return commands
163
-
164
- def _ripgrep_search(self, goal: str, files: List[str]) -> List[Dict[str, str]]:
165
- """Use ripgrep for goal-keyword search if available, else fall back to naive matching."""
166
- candidates: List[Dict[str, str]] = []
167
- try:
168
- # Try ripgrep first for better matching
169
- result = subprocess.run(
170
- ["rg", "--files-with-matches", "--ignore-case", "--glob", "!.git", goal],
171
- capture_output=True, text=True, cwd=self.project_root, timeout=10,
172
- )
173
- if result.returncode == 0:
174
- for line in result.stdout.strip().splitlines()[:10]:
175
- candidates.append({"path": line.strip(), "reason": f"ripgrep match for '{goal}'"})
176
- return candidates
177
- except Exception:
178
- pass # Fall back to naive matching
179
-
180
- # Naive keyword matching fallback
181
- goal_words = set(goal.lower().split())
182
- for f in files:
183
- f_lower = f.lower()
184
- score = sum(1 for word in goal_words if word in f_lower)
185
- if score > 0:
186
- candidates.append({"path": f, "reason": f"Matches goal keywords (score: {score})"})
187
- candidates = sorted(candidates, key=lambda x: x.get("reason", ""), reverse=True)[:10]
188
- return candidates
189
-
190
- def map_repo(self, goal: str = "") -> RepoMap:
191
- files = self.get_git_files()
192
-
193
- candidates: List[Dict[str, str]] = []
194
- if goal:
195
- candidates = self._ripgrep_search(goal, files)
196
-
197
- return RepoMap(
198
- languages=self.detect_languages(files),
199
- frameworks=self.detect_frameworks(files),
200
- package_managers=self.detect_package_managers(files),
201
- test_commands=self.detect_test_commands(files),
202
- important_files=[f for f in files if f in [
203
- "package.json", "pyproject.toml", "README.md", "go.mod",
204
- "Cargo.toml", "Makefile", "Dockerfile", ".github/workflows",
205
- ]],
206
- candidate_files=candidates,
207
- lsp=LspInspector(self.project_root).summary(files),
208
- )
File without changes
@@ -1,163 +0,0 @@
1
- import json
2
- import shutil
3
- import subprocess
4
- from pathlib import Path
5
- from typing import Any, Iterable
6
-
7
- from pydantic import BaseModel, Field
8
-
9
- from devcouncil.app.config import load_config
10
-
11
-
12
- class CodeReviewGraphContext(BaseModel):
13
- available: bool
14
- summary: str
15
- command: str = "code-review-graph"
16
- changed_files: list[str] = Field(default_factory=list)
17
- impacted_files: list[str] = Field(default_factory=list)
18
- related_tests: list[str] = Field(default_factory=list)
19
- raw: str = ""
20
-
21
-
22
- class CodeReviewGraphAdapter:
23
- """Optional shell adapter for code-review-graph without a hard dependency."""
24
-
25
- def __init__(self, project_root: Path, command: str | None = None):
26
- self.project_root = project_root
27
- self.command = command or self._configured_command()
28
-
29
- def is_enabled(self) -> bool:
30
- try:
31
- return load_config(self.project_root).integrations.code_review_graph.enabled
32
- except Exception:
33
- return False
34
-
35
- def is_available(self) -> bool:
36
- return shutil.which(self.command) is not None
37
-
38
- def get_context(self, files: Iterable[str] = ()) -> CodeReviewGraphContext:
39
- changed_files = [file for file in files if file]
40
- if not self.is_enabled():
41
- return CodeReviewGraphContext(
42
- available=False,
43
- summary="code-review-graph integration is disabled.",
44
- command=self.command,
45
- changed_files=changed_files,
46
- )
47
- if not self.is_available():
48
- return CodeReviewGraphContext(
49
- available=False,
50
- summary="code-review-graph command was not found on PATH.",
51
- command=self.command,
52
- changed_files=changed_files,
53
- )
54
-
55
- commands = self._candidate_commands(changed_files)
56
- errors: list[str] = []
57
- for command in commands:
58
- result = self._run(command)
59
- if result.returncode == 0 and result.output.strip():
60
- return self._parse_context(result.output, changed_files)
61
- errors.append(result.output.strip() or f"exit {result.returncode}")
62
-
63
- return CodeReviewGraphContext(
64
- available=True,
65
- summary="code-review-graph ran but did not return context.",
66
- command=self.command,
67
- changed_files=changed_files,
68
- raw="\n".join(errors),
69
- )
70
-
71
- def prompt_section(self, files: Iterable[str] = ()) -> str:
72
- context = self.get_context(files)
73
- if not context.available:
74
- return ""
75
-
76
- lines = ["## Structural graph context", context.summary]
77
- if context.impacted_files:
78
- lines.append("\nImpacted files:")
79
- lines.extend(f"- `{path}`" for path in context.impacted_files[:20])
80
- if context.related_tests:
81
- lines.append("\nRelated tests:")
82
- lines.extend(f"- `{path}`" for path in context.related_tests[:20])
83
- return "\n".join(lines).strip() + "\n"
84
-
85
- def _configured_command(self) -> str:
86
- try:
87
- return load_config(self.project_root).integrations.code_review_graph.command
88
- except Exception:
89
- return "code-review-graph"
90
-
91
- def _candidate_commands(self, files: list[str]) -> list[list[str]]:
92
- commands = [[self.command, "detect-changes", "--json"]]
93
- if files:
94
- commands.append([self.command, "get-review-context", "--json", *files])
95
- commands.append([self.command, "status", "--json"])
96
- return commands
97
-
98
- def _parse_context(self, output: str, changed_files: list[str]) -> CodeReviewGraphContext:
99
- data: dict[str, Any] = {}
100
- try:
101
- parsed = json.loads(output)
102
- if isinstance(parsed, dict):
103
- data = parsed
104
- except json.JSONDecodeError:
105
- pass
106
-
107
- impacted = self._string_list(
108
- data.get("impacted_files")
109
- or data.get("impact_radius")
110
- or data.get("files")
111
- or []
112
- )
113
- tests = self._string_list(data.get("related_tests") or data.get("tests") or [])
114
- summary = str(data.get("summary") or "code-review-graph context available.")
115
- return CodeReviewGraphContext(
116
- available=True,
117
- summary=summary,
118
- command=self.command,
119
- changed_files=changed_files,
120
- impacted_files=impacted,
121
- related_tests=tests,
122
- raw=output,
123
- )
124
-
125
- def _string_list(self, value: Any) -> list[str]:
126
- if isinstance(value, list):
127
- results: list[str] = []
128
- for item in value:
129
- if isinstance(item, (str, int)):
130
- results.append(str(item))
131
- elif isinstance(item, dict):
132
- path = item.get("path") or item.get("file") or item.get("name") or item.get("id")
133
- if path:
134
- results.append(str(path))
135
- return results
136
- if isinstance(value, dict):
137
- if "path" in value or "file" in value:
138
- return [str(value.get("path") or value.get("file"))]
139
- return [str(key) for key in value.keys()]
140
- return []
141
-
142
- def _run(self, command: list[str]) -> "_RunResult":
143
- try:
144
- result = subprocess.run(
145
- command,
146
- cwd=self.project_root,
147
- capture_output=True,
148
- text=True,
149
- encoding="utf-8",
150
- errors="replace",
151
- timeout=20,
152
- )
153
- return _RunResult(
154
- returncode=result.returncode,
155
- output=(result.stdout or "") + (result.stderr or ""),
156
- )
157
- except Exception as exc:
158
- return _RunResult(returncode=1, output=str(exc))
159
-
160
-
161
- class _RunResult(BaseModel):
162
- returncode: int
163
- output: str
@@ -1,39 +0,0 @@
1
- import httpx
2
- import logging
3
- from devcouncil.artifacts.graph import ArtifactGraph
4
- from devcouncil.reporting.github_check import GitHubCheckGenerator
5
-
6
- logger = logging.getLogger(__name__)
7
-
8
- class GitHubIntegration:
9
- """Manages interactions with GitHub API, specifically PR Checks."""
10
-
11
- def __init__(self, github_token: str, repository: str, commit_sha: str):
12
- self.github_token = github_token
13
- self.repository = repository
14
- self.commit_sha = commit_sha
15
- self.base_url = f"https://api.github.com/repos/{repository}"
16
-
17
- async def report_verification(self, graph: ArtifactGraph):
18
- """Creates or updates a GitHub Check Run with the current verification status."""
19
- payload = GitHubCheckGenerator.generate(graph)
20
- payload["head_sha"] = self.commit_sha
21
-
22
- headers = {
23
- "Authorization": f"Bearer {self.github_token}",
24
- "Accept": "application/vnd.github.v3+json",
25
- "Content-Type": "application/json"
26
- }
27
-
28
- async with httpx.AsyncClient() as client:
29
- try:
30
- response = await client.post(
31
- f"{self.base_url}/check-runs",
32
- headers=headers,
33
- json=payload
34
- )
35
- response.raise_for_status()
36
- logger.info(f"GitHub PR Check updated for {self.repository} at {self.commit_sha}")
37
- except Exception as e:
38
- logger.error(f"Failed to report to GitHub: {e}")
39
- raise
@@ -1,27 +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
-
7
- class GitNexusIntegration:
8
- """
9
- Integration for GitNexus: Codebase knowledge graph and structural awareness.
10
- """
11
- def __init__(self, project_root: Path):
12
- self.project_root = project_root
13
-
14
- def initialize(self):
15
- console.print("[cyan]Initializing GitNexus context...[/cyan]")
16
- nexus_dir = self.project_root / ".devcouncil" / "nexus"
17
- nexus_dir.mkdir(exist_ok=True)
18
- # Mock initialization logic
19
- (nexus_dir / "index_config.json").write_text('{"mode": "structural", "version": "1.0"}')
20
- console.print(" - GitNexus structural awareness active.")
21
-
22
- def sync_graph(self, graph_index: GraphIndex):
23
- """
24
- Export DevCouncil artifact graph to GitNexus.
25
- """
26
- console.print(" - Syncing DevCouncil artifacts to GitNexus...")
27
- 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