devcouncil 0.4.1 → 0.4.2
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 +7 -8
- package/examples/build-week-demo/README.md +13 -0
- package/examples/build-week-demo/broken_calc.py +11 -0
- package/examples/build-week-demo/calc.py +11 -0
- package/examples/build-week-demo/test_calc.py +21 -0
- package/package.json +7 -2
- package/pyproject.toml +2 -2
- package/scripts/build-week-demo.sh +200 -0
- package/src/devcouncil/indexing/viz.py +29 -5
- package/uv.lock +30 -30
package/README.md
CHANGED
|
@@ -18,19 +18,18 @@ Coding agents -- including Codex and other prompt-taking CLIs -- often claim suc
|
|
|
18
18
|
2. **Self-contained interactive code graph** -- open the packed `demo.html` artifact and navigate filters, path highlighting, and neighborhoods (no blank canvas).
|
|
19
19
|
3. **Codex / MCP agent-control path** -- status, diffs, and task tools stay correct under real project-sized JSON so an agent can resume from evidence instead of chat memory.
|
|
20
20
|
|
|
21
|
-
### Judge path (
|
|
21
|
+
### Judge path (package: `devcouncil@0.4.2`)
|
|
22
22
|
|
|
23
23
|
DevCouncil supports macOS, Linux, and Windows. Requires Node.js 18+, Python 3.12+, and Git. No model provider key is needed for the deterministic demos below.
|
|
24
24
|
|
|
25
25
|
```bash
|
|
26
|
-
#
|
|
27
|
-
npm install -g devcouncil@0.4.
|
|
26
|
+
# Install the Build Week release:
|
|
27
|
+
npm install -g devcouncil@0.4.2
|
|
28
28
|
devcouncil --help
|
|
29
29
|
|
|
30
30
|
# Core demo: red verdict -> apply fix -> green verdict (no API keys)
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
bash scripts/build-week-demo.sh
|
|
31
|
+
devcouncil-build-week-demo
|
|
32
|
+
# Equivalent: bash "$(npm root -g)/devcouncil/scripts/build-week-demo.sh"
|
|
34
33
|
|
|
35
34
|
# Interactive graph artifact (self-contained HTML)
|
|
36
35
|
mkdir -p /tmp/devcouncil-judge-demo
|
|
@@ -38,7 +37,7 @@ dev graph demo --project-root /tmp/devcouncil-judge-demo --json
|
|
|
38
37
|
# Open /tmp/devcouncil-judge-demo/.devcouncil/graph/demo.html
|
|
39
38
|
```
|
|
40
39
|
|
|
41
|
-
|
|
40
|
+
Checkout fallback: clone the repo and run `bash scripts/build-week-demo.sh` (`uv sync --group dev` if you need a local `dev`).
|
|
42
41
|
|
|
43
42
|
### Eligible Build Week work
|
|
44
43
|
|
|
@@ -46,7 +45,7 @@ DevCouncil existed before OpenAI Build Week. This submission covers only meaning
|
|
|
46
45
|
|
|
47
46
|
- canonical SQLite code-intelligence index, multi-language grammars, incremental watching, graph queries/community detection, and a self-contained interactive code-graph artifact (including a ForceGraph compatibility fix for the packed demo);
|
|
48
47
|
- stronger deterministic verification: stop gates, claim checking, diff-to-evidence coverage, task leases, PDG/corpus checks, bounded repair, machine-readable next actions;
|
|
49
|
-
- deeper CLI, MCP, dashboard, coding-agent, and CI integration, plus the installable npm release path aimed at `0.4.
|
|
48
|
+
- deeper CLI, MCP, dashboard, coding-agent, and CI integration, plus the installable npm release path aimed at `0.4.2` for judges.
|
|
50
49
|
|
|
51
50
|
During Build Week, Codex and GPT-5.6 were used as an engineering partner to map paths, challenge claims, run install/browser checks, implement focused repairs, and verify behavior. The maintainer set requirements, scope, and acceptance evidence. The primary Codex `/feedback` session ID is on the Devpost submission. This does **not** claim that all eligible code was authored exclusively by Codex/GPT-5.6.
|
|
52
51
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Build Week calculator sample
|
|
2
|
+
|
|
3
|
+
Tiny provider-free sample used by `scripts/build-week-demo.sh`.
|
|
4
|
+
|
|
5
|
+
| File | Role |
|
|
6
|
+
|---|---|
|
|
7
|
+
| `calc.py` | Correct calculator (green / repaired state) |
|
|
8
|
+
| `broken_calc.py` | Deliberate `sub` bug used for the red evidence-gate pass |
|
|
9
|
+
| `test_calc.py` | Regression checks proving `add` and `sub` |
|
|
10
|
+
|
|
11
|
+
The demo script copies these into an isolated git repository, runs
|
|
12
|
+
`dev check --verify` (no API keys), applies the repair, and reruns to a
|
|
13
|
+
compiled zero-gap pass. See [docs/build-week-demo.md](../../docs/build-week-demo.md) and the fixture index in [examples/README.md](../README.md).
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""Deliberately buggy calculator used only for the demo's red evidence-gate pass."""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def add(a: int, b: int) -> int:
|
|
5
|
+
"""Return the sum of ``a`` and ``b``."""
|
|
6
|
+
return a + b
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def sub(a: int, b: int) -> int:
|
|
10
|
+
"""Intended to return ``a`` minus ``b`` — intentionally wrong for the demo."""
|
|
11
|
+
return a + b
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""Regression checks for the Build Week calculator demo."""
|
|
2
|
+
|
|
3
|
+
from calc import add, sub
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_add() -> None:
|
|
7
|
+
assert add(2, 3) == 5
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def test_sub() -> None:
|
|
11
|
+
assert sub(5, 3) == 2
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def main() -> None:
|
|
15
|
+
test_add()
|
|
16
|
+
test_sub()
|
|
17
|
+
print("ok")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
if __name__ == "__main__":
|
|
21
|
+
main()
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "devcouncil",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "Gated orchestrator for AI-assisted software development",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://github.com/bharathvbcr/DevCouncil#readme",
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
],
|
|
22
22
|
"bin": {
|
|
23
23
|
"devcouncil": "bin/devcouncil.js",
|
|
24
|
-
"dev": "bin/devcouncil.js"
|
|
24
|
+
"dev": "bin/devcouncil.js",
|
|
25
|
+
"devcouncil-build-week-demo": "scripts/build-week-demo.sh"
|
|
25
26
|
},
|
|
26
27
|
"files": [
|
|
27
28
|
"bin/",
|
|
@@ -35,6 +36,8 @@
|
|
|
35
36
|
"packages/codeintel-grammars/pyproject.toml",
|
|
36
37
|
"packages/codeintel-grammars/hatch_build.py",
|
|
37
38
|
"packages/codeintel-grammars/src/devcouncil_codeintel_grammars/__init__.py",
|
|
39
|
+
"scripts/build-week-demo.sh",
|
|
40
|
+
"examples/build-week-demo/**",
|
|
38
41
|
"pyproject.toml",
|
|
39
42
|
"uv.lock",
|
|
40
43
|
"README.md",
|
|
@@ -47,6 +50,8 @@
|
|
|
47
50
|
"pack:check": "npm pack --dry-run",
|
|
48
51
|
"smoke:wheel": "uv run python scripts/check-wheel-assets.py",
|
|
49
52
|
"smoke:package": "node scripts/npm-runtime-smoke.mjs",
|
|
53
|
+
"smoke:registry": "node scripts/npm-registry-smoke.mjs",
|
|
54
|
+
"demo:build-week": "bash scripts/build-week-demo.sh",
|
|
50
55
|
"test": "uv run pytest",
|
|
51
56
|
"lint": "uv run ruff check .",
|
|
52
57
|
"typecheck": "uv run mypy src",
|
package/pyproject.toml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "devcouncil"
|
|
3
|
-
version = "0.4.
|
|
3
|
+
version = "0.4.2"
|
|
4
4
|
description = "Gated orchestrator for AI-assisted software development"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.12"
|
|
@@ -11,7 +11,7 @@ dependencies = [
|
|
|
11
11
|
"pyyaml>=6.0.1",
|
|
12
12
|
"sqlmodel>=0.0.19",
|
|
13
13
|
"httpx>=0.27.0",
|
|
14
|
-
"gitpython>=3.1.
|
|
14
|
+
"gitpython>=3.1.53",
|
|
15
15
|
"mcp>=1.27.2",
|
|
16
16
|
"gepa>=0.1.1",
|
|
17
17
|
"watchdog>=4.0.0",
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Provider-free red→green evidence-gate demo for OpenAI Build Week judges.
|
|
3
|
+
#
|
|
4
|
+
# Creates an isolated calculator git repo, runs `dev check --verify` against a
|
|
5
|
+
# deliberately buggy change (blocking / red), applies the real repair + regression
|
|
6
|
+
# test, then reruns to a compiled zero-gap (green) pass. No API keys required.
|
|
7
|
+
#
|
|
8
|
+
# Usage (checkout):
|
|
9
|
+
# bash scripts/build-week-demo.sh
|
|
10
|
+
#
|
|
11
|
+
# From npm global install (preferred judge path):
|
|
12
|
+
# npm install -g devcouncil@0.4.2
|
|
13
|
+
# devcouncil-build-week-demo
|
|
14
|
+
#
|
|
15
|
+
# Optional:
|
|
16
|
+
# BUILD_WEEK_DEMO_ROOT=/tmp/my-demo bash scripts/build-week-demo.sh
|
|
17
|
+
|
|
18
|
+
set -euo pipefail
|
|
19
|
+
|
|
20
|
+
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
21
|
+
SAMPLE_DIR="${REPO_ROOT}/examples/build-week-demo"
|
|
22
|
+
GOAL='sub returns a - b'
|
|
23
|
+
TEST_CMD='python test_calc.py'
|
|
24
|
+
|
|
25
|
+
if [[ ! -f "${SAMPLE_DIR}/calc.py" || ! -f "${SAMPLE_DIR}/broken_calc.py" || ! -f "${SAMPLE_DIR}/test_calc.py" ]]; then
|
|
26
|
+
echo "error: missing sample files under ${SAMPLE_DIR}" >&2
|
|
27
|
+
exit 2
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
resolve_dev() {
|
|
31
|
+
if [[ -n "${DEVCOUNCIL_DEV_BIN:-}" && -x "${DEVCOUNCIL_DEV_BIN}" ]]; then
|
|
32
|
+
printf '%s\n' "${DEVCOUNCIL_DEV_BIN}"
|
|
33
|
+
return
|
|
34
|
+
fi
|
|
35
|
+
if [[ -x "${REPO_ROOT}/.venv/bin/dev" ]]; then
|
|
36
|
+
printf '%s\n' "${REPO_ROOT}/.venv/bin/dev"
|
|
37
|
+
return
|
|
38
|
+
fi
|
|
39
|
+
if command -v dev >/dev/null 2>&1; then
|
|
40
|
+
command -v dev
|
|
41
|
+
return
|
|
42
|
+
fi
|
|
43
|
+
if [[ -x "${REPO_ROOT}/.venv/bin/python" ]]; then
|
|
44
|
+
printf '%s\n' "${REPO_ROOT}/.venv/bin/python -m devcouncil"
|
|
45
|
+
return
|
|
46
|
+
fi
|
|
47
|
+
if command -v python3 >/dev/null 2>&1; then
|
|
48
|
+
printf '%s\n' "python3 -m devcouncil"
|
|
49
|
+
return
|
|
50
|
+
fi
|
|
51
|
+
echo "error: could not find a DevCouncil CLI (dev / python -m devcouncil)" >&2
|
|
52
|
+
exit 2
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
DEV_BIN="$(resolve_dev)"
|
|
56
|
+
# shellcheck disable=SC2206
|
|
57
|
+
DEV=( ${DEV_BIN} )
|
|
58
|
+
|
|
59
|
+
PROVIDER_FREE_ENV=(
|
|
60
|
+
-u OPENAI_API_KEY
|
|
61
|
+
-u ANTHROPIC_API_KEY
|
|
62
|
+
-u OPENROUTER_API_KEY
|
|
63
|
+
-u GEMINI_API_KEY
|
|
64
|
+
-u GOOGLE_API_KEY
|
|
65
|
+
-u AZURE_OPENAI_API_KEY
|
|
66
|
+
-u COHERE_API_KEY
|
|
67
|
+
-u MISTRAL_API_KEY
|
|
68
|
+
-u GROQ_API_KEY
|
|
69
|
+
-u DEEPSEEK_API_KEY
|
|
70
|
+
-u TOGETHER_API_KEY
|
|
71
|
+
-u FIREWORKS_API_KEY
|
|
72
|
+
-u XAI_API_KEY
|
|
73
|
+
-u DEVCOUNCIL_API_KEY
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
run_check() {
|
|
77
|
+
local label="$1"
|
|
78
|
+
echo
|
|
79
|
+
echo "────────────────────────────────────────────────────────────"
|
|
80
|
+
echo " ${label}"
|
|
81
|
+
echo "────────────────────────────────────────────────────────────"
|
|
82
|
+
# Keep set +e through return: a non-zero return under set -e aborts the script.
|
|
83
|
+
set +e
|
|
84
|
+
env "${PROVIDER_FREE_ENV[@]}" "${DEV[@]}" check --verify \
|
|
85
|
+
--project-root "${DEMO_ROOT}" \
|
|
86
|
+
--goal "${GOAL}" \
|
|
87
|
+
--test "${TEST_CMD}"
|
|
88
|
+
local rc=$?
|
|
89
|
+
return "${rc}"
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if [[ -n "${BUILD_WEEK_DEMO_ROOT:-}" ]]; then
|
|
93
|
+
DEMO_ROOT="${BUILD_WEEK_DEMO_ROOT}"
|
|
94
|
+
rm -rf "${DEMO_ROOT}"
|
|
95
|
+
mkdir -p "${DEMO_ROOT}"
|
|
96
|
+
else
|
|
97
|
+
_tmp="${TMPDIR:-/tmp}"
|
|
98
|
+
DEMO_ROOT="$(mktemp -d "${_tmp%/}/devcouncil-build-week-demo.XXXXXX")"
|
|
99
|
+
unset _tmp
|
|
100
|
+
fi
|
|
101
|
+
|
|
102
|
+
echo "DevCouncil Build Week demo"
|
|
103
|
+
echo " CLI: ${DEV_BIN}"
|
|
104
|
+
echo " Sample templates: ${SAMPLE_DIR}"
|
|
105
|
+
echo " Generated repo: ${DEMO_ROOT}"
|
|
106
|
+
echo
|
|
107
|
+
echo "Judges: leave this path open to inspect the repaired working tree."
|
|
108
|
+
|
|
109
|
+
cd "${DEMO_ROOT}"
|
|
110
|
+
git init -q
|
|
111
|
+
git config user.email "build-week-demo@devcouncil.local"
|
|
112
|
+
git config user.name "DevCouncil Build Week Demo"
|
|
113
|
+
|
|
114
|
+
cat > calc.py <<'EOF'
|
|
115
|
+
def add(a: int, b: int) -> int:
|
|
116
|
+
return a + b
|
|
117
|
+
EOF
|
|
118
|
+
git add calc.py
|
|
119
|
+
git commit -q -m "baseline: add()"
|
|
120
|
+
|
|
121
|
+
cp "${SAMPLE_DIR}/broken_calc.py" calc.py
|
|
122
|
+
cp "${SAMPLE_DIR}/test_calc.py" test_calc.py
|
|
123
|
+
|
|
124
|
+
echo
|
|
125
|
+
echo ">>> Phase 1: RED — expect a blocking evidence-gate failure"
|
|
126
|
+
START_TS="${SECONDS}"
|
|
127
|
+
set +e
|
|
128
|
+
run_check "RED verdict (blocking gaps expected)"
|
|
129
|
+
RED_RC=$?
|
|
130
|
+
set -e
|
|
131
|
+
|
|
132
|
+
if [[ "${RED_RC}" -eq 0 ]]; then
|
|
133
|
+
echo
|
|
134
|
+
echo "error: expected RED (non-zero) from dev check --verify, got exit 0" >&2
|
|
135
|
+
echo "Generated repo left at: ${DEMO_ROOT}" >&2
|
|
136
|
+
exit 1
|
|
137
|
+
fi
|
|
138
|
+
|
|
139
|
+
echo
|
|
140
|
+
echo "RED confirmed (exit ${RED_RC}): blocking gaps — change is not verified."
|
|
141
|
+
|
|
142
|
+
cp "${SAMPLE_DIR}/calc.py" calc.py
|
|
143
|
+
|
|
144
|
+
echo
|
|
145
|
+
echo ">>> Phase 2: GREEN — apply repair + regression test, expect zero-gap pass"
|
|
146
|
+
set +e
|
|
147
|
+
run_check "GREEN verdict (compiled, zero blocking gaps expected)"
|
|
148
|
+
GREEN_RC=$?
|
|
149
|
+
set -e
|
|
150
|
+
|
|
151
|
+
if [[ "${GREEN_RC}" -ne 0 ]]; then
|
|
152
|
+
echo
|
|
153
|
+
echo "error: expected GREEN (exit 0) after repair, got exit ${GREEN_RC}" >&2
|
|
154
|
+
echo "Generated repo left at: ${DEMO_ROOT}" >&2
|
|
155
|
+
exit 1
|
|
156
|
+
fi
|
|
157
|
+
|
|
158
|
+
GREEN_JSON_FILE="${DEMO_ROOT}/.devcouncil-demo-green.json"
|
|
159
|
+
set +e
|
|
160
|
+
env "${PROVIDER_FREE_ENV[@]}" "${DEV[@]}" check --verify \
|
|
161
|
+
--project-root "${DEMO_ROOT}" \
|
|
162
|
+
--goal "${GOAL}" \
|
|
163
|
+
--test "${TEST_CMD}" \
|
|
164
|
+
--json > "${GREEN_JSON_FILE}"
|
|
165
|
+
JSON_RC=$?
|
|
166
|
+
set -e
|
|
167
|
+
if [[ "${JSON_RC}" -ne 0 ]]; then
|
|
168
|
+
echo "error: green JSON re-check failed with exit ${JSON_RC}" >&2
|
|
169
|
+
exit 1
|
|
170
|
+
fi
|
|
171
|
+
|
|
172
|
+
python3 - "${GREEN_JSON_FILE}" <<'PY'
|
|
173
|
+
import json, sys
|
|
174
|
+
from pathlib import Path
|
|
175
|
+
payload = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8"))
|
|
176
|
+
if not payload.get("verified", False):
|
|
177
|
+
raise SystemExit("green JSON missing verified=true")
|
|
178
|
+
if int(payload.get("blocking_gap_count", 1)) != 0:
|
|
179
|
+
raise SystemExit(f"green JSON still has blocking gaps: {payload.get('blocking_gap_count')}")
|
|
180
|
+
if int(payload.get("gap_count", 1)) != 0:
|
|
181
|
+
raise SystemExit(f"green JSON still has gaps: {payload.get('gap_count')}")
|
|
182
|
+
mode = str(payload.get("verification_mode", ""))
|
|
183
|
+
if mode != "compiled":
|
|
184
|
+
raise SystemExit(f"expected verification_mode=compiled, got {mode!r}")
|
|
185
|
+
print(f"JSON confirmed: verified=true, gaps=0, mode={mode}")
|
|
186
|
+
PY
|
|
187
|
+
|
|
188
|
+
ELAPSED=$((SECONDS - START_TS))
|
|
189
|
+
echo
|
|
190
|
+
echo "════════════════════════════════════════════════════════════"
|
|
191
|
+
echo " Demo complete: RED then GREEN in ${ELAPSED}s"
|
|
192
|
+
echo " Generated repository (inspect me):"
|
|
193
|
+
echo " ${DEMO_ROOT}"
|
|
194
|
+
echo "════════════════════════════════════════════════════════════"
|
|
195
|
+
|
|
196
|
+
if [[ "${ELAPSED}" -gt 60 ]]; then
|
|
197
|
+
echo "warning: demo took ${ELAPSED}s (>60s target after package install)" >&2
|
|
198
|
+
fi
|
|
199
|
+
|
|
200
|
+
exit 0
|
|
@@ -321,6 +321,8 @@ label {{ color:var(--muted); font-size:12px; display:block; }}
|
|
|
321
321
|
label.inline {{ display:flex; align-items:center; gap:6px; margin:4px 0; }}
|
|
322
322
|
label.inline input {{ width:auto; margin:0; }}
|
|
323
323
|
#detail {{ margin-top:8px; font-size:12px; color:var(--muted); white-space:pre-wrap; }}
|
|
324
|
+
.interaction-hint {{ margin:8px 0; padding:8px; border:1px solid #334155; border-radius:4px; background:#0f1419; color:var(--fg); font-size:12px; line-height:1.45; }}
|
|
325
|
+
#counts {{ margin:8px 0 4px; font-size:12px; color:var(--accent); font-weight:600; }}
|
|
324
326
|
.flag-dead {{ color:var(--dead); }}
|
|
325
327
|
.badge-entry {{ color:var(--entry); font-weight:600; }}
|
|
326
328
|
.list {{ list-style:none; padding:0; margin:0; font-size:12px; }}
|
|
@@ -342,6 +344,8 @@ label.inline input {{ width:auto; margin:0; }}
|
|
|
342
344
|
</div>
|
|
343
345
|
<div id="panel-graph" class="panel active">
|
|
344
346
|
<h1>DevCouncil Code Graph</h1>
|
|
347
|
+
<div id="counts" aria-live="polite">Nodes: -- · Edges: -- · Filtered: --</div>
|
|
348
|
+
<div class="interaction-hint" id="interactionHint"><strong>Click</strong> a node for details. <strong>Select two nodes</strong> to highlight the shortest path. <strong>Double-click</strong> a node to expand its neighborhood.</div>
|
|
345
349
|
<label>Mode</label>
|
|
346
350
|
<select id="mode"><option value="file">File-level</option><option value="symbol">Symbol-level</option></select>
|
|
347
351
|
<label>Search</label>
|
|
@@ -360,7 +364,7 @@ label.inline input {{ width:auto; margin:0; }}
|
|
|
360
364
|
<label>Dead confidence</label>
|
|
361
365
|
<select id="deadConf"><option value="">(any)</option><option>extracted</option><option>inferred</option><option>ambiguous</option></select>
|
|
362
366
|
<div class="row"><button class="primary" id="reset">Reset view</button><button class="primary" id="clearPath">Clear path</button></div>
|
|
363
|
-
<div id="detail">
|
|
367
|
+
<div id="detail" class="muted">Select a node to inspect callers, callees, and path state.</div>
|
|
364
368
|
</div>
|
|
365
369
|
<div id="panel-dead" class="panel">
|
|
366
370
|
<h1>Dead code</h1>
|
|
@@ -588,11 +592,29 @@ const g = Graph(elem)
|
|
|
588
592
|
redraw();
|
|
589
593
|
}});
|
|
590
594
|
|
|
595
|
+
function updateCounts(fd) {{
|
|
596
|
+
const totalNodes = (activePayload().nodes || []).length;
|
|
597
|
+
const totalEdges = (activePayload().links || []).length;
|
|
598
|
+
const shownNodes = (fd.nodes || []).length;
|
|
599
|
+
const shownEdges = (fd.links || []).length;
|
|
600
|
+
const el = document.getElementById("counts");
|
|
601
|
+
if (el) el.textContent = "Nodes: " + shownNodes + " / " + totalNodes + " · Edges: " + shownEdges + " / " + totalEdges + " · Filtered: " + Math.max(0, totalNodes - shownNodes) + (expandIds ? " · neighborhood focus" : "");
|
|
602
|
+
}}
|
|
603
|
+
|
|
604
|
+
function fitView() {{
|
|
605
|
+
if (g && typeof g.zoomToFit === 'function') {{
|
|
606
|
+
requestAnimationFrame(() => {{
|
|
607
|
+
try {{ g.zoomToFit(400, 40); }} catch (err) {{ /* vendor stub */ }}
|
|
608
|
+
}});
|
|
609
|
+
}}
|
|
610
|
+
}}
|
|
611
|
+
|
|
591
612
|
function redraw() {{
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
613
|
+
const fd = filtered();
|
|
614
|
+
g.graphData(fd);
|
|
615
|
+
g.nodeAutoColorBy(n => colorKey(n));
|
|
616
|
+
g.width(elem.clientWidth).height(elem.clientHeight);
|
|
617
|
+
updateCounts(fd);
|
|
596
618
|
}}
|
|
597
619
|
|
|
598
620
|
function renderDeadList() {{
|
|
@@ -724,6 +746,7 @@ document.getElementById('reset').addEventListener('click', () => {{
|
|
|
724
746
|
selected = [];
|
|
725
747
|
pathHighlight = new Set();
|
|
726
748
|
redraw();
|
|
749
|
+
fitView();
|
|
727
750
|
}});
|
|
728
751
|
document.getElementById('clearPath').addEventListener('click', () => {{
|
|
729
752
|
selected = [];
|
|
@@ -734,6 +757,7 @@ window.addEventListener('resize', () => g.width(elem.clientWidth).height(elem.cl
|
|
|
734
757
|
if (!g || typeof g.zoomToFit !== 'function') document.getElementById('vendorWarn').style.display = 'block';
|
|
735
758
|
refillArea();
|
|
736
759
|
redraw();
|
|
760
|
+
fitView();
|
|
737
761
|
renderDeadList();
|
|
738
762
|
renderCommunities();
|
|
739
763
|
renderProcesses();
|
package/uv.lock
CHANGED
|
@@ -290,7 +290,7 @@ name = "cuda-bindings"
|
|
|
290
290
|
version = "13.3.1"
|
|
291
291
|
source = { registry = "https://pypi.org/simple" }
|
|
292
292
|
dependencies = [
|
|
293
|
-
{ name = "cuda-pathfinder"
|
|
293
|
+
{ name = "cuda-pathfinder" },
|
|
294
294
|
]
|
|
295
295
|
wheels = [
|
|
296
296
|
{ url = "https://files.pythonhosted.org/packages/ce/67/5e7dba1ba576dd73da5dee894ca076ca5e959450dfff66d6d510a255d1f7/cuda_bindings-13.3.1-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c7855c4868aabc0cfae28abbe83d56734bdfbd08f08fc234ac1912a12858bf49", size = 6025351, upload-time = "2026-05-29T23:11:49.685Z" },
|
|
@@ -321,43 +321,43 @@ wheels = [
|
|
|
321
321
|
|
|
322
322
|
[package.optional-dependencies]
|
|
323
323
|
cublas = [
|
|
324
|
-
{ name = "nvidia-cublas", marker = "
|
|
325
|
-
{ name = "nvidia-cuda-nvrtc", marker = "
|
|
324
|
+
{ name = "nvidia-cublas", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" },
|
|
325
|
+
{ name = "nvidia-cuda-nvrtc", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" },
|
|
326
326
|
]
|
|
327
327
|
cudart = [
|
|
328
|
-
{ name = "nvidia-cuda-runtime", marker = "
|
|
328
|
+
{ name = "nvidia-cuda-runtime", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" },
|
|
329
329
|
]
|
|
330
330
|
cufft = [
|
|
331
|
-
{ name = "nvidia-cufft", marker = "
|
|
332
|
-
{ name = "nvidia-nvjitlink", marker = "
|
|
331
|
+
{ name = "nvidia-cufft", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" },
|
|
332
|
+
{ name = "nvidia-nvjitlink", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" },
|
|
333
333
|
]
|
|
334
334
|
cufile = [
|
|
335
|
-
{ name = "nvidia-cufile", marker = "
|
|
335
|
+
{ name = "nvidia-cufile", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" },
|
|
336
336
|
]
|
|
337
337
|
cupti = [
|
|
338
|
-
{ name = "nvidia-cuda-cupti", marker = "
|
|
338
|
+
{ name = "nvidia-cuda-cupti", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" },
|
|
339
339
|
]
|
|
340
340
|
curand = [
|
|
341
|
-
{ name = "nvidia-curand", marker = "
|
|
341
|
+
{ name = "nvidia-curand", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" },
|
|
342
342
|
]
|
|
343
343
|
cusolver = [
|
|
344
|
-
{ name = "nvidia-cublas", marker = "
|
|
345
|
-
{ name = "nvidia-cusolver", marker = "
|
|
346
|
-
{ name = "nvidia-cusparse", marker = "
|
|
347
|
-
{ name = "nvidia-nvjitlink", marker = "
|
|
344
|
+
{ name = "nvidia-cublas", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" },
|
|
345
|
+
{ name = "nvidia-cusolver", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" },
|
|
346
|
+
{ name = "nvidia-cusparse", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" },
|
|
347
|
+
{ name = "nvidia-nvjitlink", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" },
|
|
348
348
|
]
|
|
349
349
|
cusparse = [
|
|
350
|
-
{ name = "nvidia-cusparse", marker = "
|
|
351
|
-
{ name = "nvidia-nvjitlink", marker = "
|
|
350
|
+
{ name = "nvidia-cusparse", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" },
|
|
351
|
+
{ name = "nvidia-nvjitlink", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" },
|
|
352
352
|
]
|
|
353
353
|
nvjitlink = [
|
|
354
|
-
{ name = "nvidia-nvjitlink", marker = "
|
|
354
|
+
{ name = "nvidia-nvjitlink", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" },
|
|
355
355
|
]
|
|
356
356
|
nvrtc = [
|
|
357
|
-
{ name = "nvidia-cuda-nvrtc", marker = "
|
|
357
|
+
{ name = "nvidia-cuda-nvrtc", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" },
|
|
358
358
|
]
|
|
359
359
|
nvtx = [
|
|
360
|
-
{ name = "nvidia-nvtx", marker = "
|
|
360
|
+
{ name = "nvidia-nvtx", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" },
|
|
361
361
|
]
|
|
362
362
|
|
|
363
363
|
[[package]]
|
|
@@ -383,7 +383,7 @@ wheels = [
|
|
|
383
383
|
|
|
384
384
|
[[package]]
|
|
385
385
|
name = "devcouncil"
|
|
386
|
-
version = "0.4.
|
|
386
|
+
version = "0.4.2"
|
|
387
387
|
source = { editable = "." }
|
|
388
388
|
dependencies = [
|
|
389
389
|
{ name = "gepa" },
|
|
@@ -430,7 +430,7 @@ semantic = [
|
|
|
430
430
|
requires-dist = [
|
|
431
431
|
{ name = "devcouncil-codeintel-grammars", marker = "extra == 'codeintel-full'", editable = "packages/codeintel-grammars" },
|
|
432
432
|
{ name = "gepa", specifier = ">=0.1.1" },
|
|
433
|
-
{ name = "gitpython", specifier = ">=3.1.
|
|
433
|
+
{ name = "gitpython", specifier = ">=3.1.53" },
|
|
434
434
|
{ name = "httpx", specifier = ">=0.27.0" },
|
|
435
435
|
{ name = "mcp", specifier = ">=1.27.2" },
|
|
436
436
|
{ name = "networkx", specifier = ">=3.3" },
|
|
@@ -535,14 +535,14 @@ wheels = [
|
|
|
535
535
|
|
|
536
536
|
[[package]]
|
|
537
537
|
name = "gitpython"
|
|
538
|
-
version = "3.1.
|
|
538
|
+
version = "3.1.53"
|
|
539
539
|
source = { registry = "https://pypi.org/simple" }
|
|
540
540
|
dependencies = [
|
|
541
541
|
{ name = "gitdb" },
|
|
542
542
|
]
|
|
543
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
543
|
+
sdist = { url = "https://files.pythonhosted.org/packages/17/24/0e0c12cb6f7cb864779a9d2fefee9ca91838f6db402c8780c9d28a8d7ebe/gitpython-3.1.53.tar.gz", hash = "sha256:06ae8d9623b0ed0d67b8adeac5c7008d0a5a404b087a9e0d0c7163bdd3a6b497", size = 224597, upload-time = "2026-07-20T13:41:52.839Z" }
|
|
544
544
|
wheels = [
|
|
545
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
545
|
+
{ url = "https://files.pythonhosted.org/packages/cf/a6/bff12b3238885eeef7d28ef908b24e0cba91c476c31cb876a00a0986ce2c/gitpython-3.1.53-py3-none-any.whl", hash = "sha256:187885556b64ab357bd4ea84e2c4cce2861a613a7f4268b3f7f7ba05f2ce4ab0", size = 216237, upload-time = "2026-07-20T13:41:51.473Z" },
|
|
546
546
|
]
|
|
547
547
|
|
|
548
548
|
[[package]]
|
|
@@ -1052,7 +1052,7 @@ name = "nvidia-cublas"
|
|
|
1052
1052
|
version = "13.1.1.3"
|
|
1053
1053
|
source = { registry = "https://pypi.org/simple" }
|
|
1054
1054
|
dependencies = [
|
|
1055
|
-
{ name = "nvidia-cuda-nvrtc"
|
|
1055
|
+
{ name = "nvidia-cuda-nvrtc" },
|
|
1056
1056
|
]
|
|
1057
1057
|
wheels = [
|
|
1058
1058
|
{ url = "https://files.pythonhosted.org/packages/a7/a1/0bd24ee8c8d03adac032fd2909426a00c88f8c57961b1277ded97f91119f/nvidia_cublas-13.1.1.3-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:b7a210458267ac818974c53038fbec2e969d5c99f305ab15c72522fa9f001dd5", size = 542848918, upload-time = "2026-04-08T18:46:22.985Z" },
|
|
@@ -1091,7 +1091,7 @@ name = "nvidia-cudnn-cu13"
|
|
|
1091
1091
|
version = "9.20.0.48"
|
|
1092
1092
|
source = { registry = "https://pypi.org/simple" }
|
|
1093
1093
|
dependencies = [
|
|
1094
|
-
{ name = "nvidia-cublas"
|
|
1094
|
+
{ name = "nvidia-cublas" },
|
|
1095
1095
|
]
|
|
1096
1096
|
wheels = [
|
|
1097
1097
|
{ url = "https://files.pythonhosted.org/packages/56/c5/83384d846b2fd17c44bd499b36c75a45ed4f095fbbb2252294e89cea5c5c/nvidia_cudnn_cu13-9.20.0.48-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:e31454ae00094b0c55319d9d15b6fa2fc50a9e1c0f5c8c80fb75258234e731e1", size = 444574296, upload-time = "2026-03-09T19:28:27.751Z" },
|
|
@@ -1103,7 +1103,7 @@ name = "nvidia-cufft"
|
|
|
1103
1103
|
version = "12.0.0.61"
|
|
1104
1104
|
source = { registry = "https://pypi.org/simple" }
|
|
1105
1105
|
dependencies = [
|
|
1106
|
-
{ name = "nvidia-nvjitlink"
|
|
1106
|
+
{ name = "nvidia-nvjitlink" },
|
|
1107
1107
|
]
|
|
1108
1108
|
wheels = [
|
|
1109
1109
|
{ url = "https://files.pythonhosted.org/packages/8b/ae/f417a75c0259e85c1d2f83ca4e960289a5f814ed0cea74d18c353d3e989d/nvidia_cufft-12.0.0.61-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2708c852ef8cd89d1d2068bdbece0aa188813a0c934db3779b9b1faa8442e5f5", size = 214053554, upload-time = "2025-09-04T08:31:38.196Z" },
|
|
@@ -1133,9 +1133,9 @@ name = "nvidia-cusolver"
|
|
|
1133
1133
|
version = "12.0.4.66"
|
|
1134
1134
|
source = { registry = "https://pypi.org/simple" }
|
|
1135
1135
|
dependencies = [
|
|
1136
|
-
{ name = "nvidia-cublas"
|
|
1137
|
-
{ name = "nvidia-cusparse"
|
|
1138
|
-
{ name = "nvidia-nvjitlink"
|
|
1136
|
+
{ name = "nvidia-cublas" },
|
|
1137
|
+
{ name = "nvidia-cusparse" },
|
|
1138
|
+
{ name = "nvidia-nvjitlink" },
|
|
1139
1139
|
]
|
|
1140
1140
|
wheels = [
|
|
1141
1141
|
{ url = "https://files.pythonhosted.org/packages/c8/c3/b30c9e935fc01e3da443ec0116ed1b2a009bb867f5324d3f2d7e533e776b/nvidia_cusolver-12.0.4.66-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:02c2457eaa9e39de20f880f4bd8820e6a1cfb9f9a34f820eb12a155aa5bc92d2", size = 223467760, upload-time = "2025-09-04T08:33:04.222Z" },
|
|
@@ -1147,7 +1147,7 @@ name = "nvidia-cusparse"
|
|
|
1147
1147
|
version = "12.6.3.3"
|
|
1148
1148
|
source = { registry = "https://pypi.org/simple" }
|
|
1149
1149
|
dependencies = [
|
|
1150
|
-
{ name = "nvidia-nvjitlink"
|
|
1150
|
+
{ name = "nvidia-nvjitlink" },
|
|
1151
1151
|
]
|
|
1152
1152
|
wheels = [
|
|
1153
1153
|
{ url = "https://files.pythonhosted.org/packages/f8/94/5c26f33738ae35276672f12615a64bd008ed5be6d1ebcb23579285d960a9/nvidia_cusparse-12.6.3.3-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:80bcc4662f23f1054ee334a15c72b8940402975e0eab63178fc7e670aa59472c", size = 162155568, upload-time = "2025-09-04T08:33:42.864Z" },
|