@drafthq/draft 3.1.5 → 3.2.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.
@@ -1,27 +1,33 @@
1
1
  #!/usr/bin/env bash
2
- # hotspot-rank.sh — emit complexity/fan-in-ranked symbols from the knowledge graph.
2
+ # hotspot-rank.sh — complexity-weighted hotspot ranking from the knowledge graph.
3
3
  #
4
- # Backed by the codebase-memory-mcp engine (get_architecture, server-computed
5
- # hotspot ranking by fan-in). Indexes the repo on demand if needed.
4
+ # Backed by the codebase-memory-mcp engine. Fan-in alone is skewed by
5
+ # name-collision generics (e.g. a logger `info` with fan_in 1022 but complexity 0),
6
+ # so graph-tooling-v2 Phase 4 blends the engine's pre-computed complexity and
7
+ # cognitive scores into the rank: score = fanIn + complexity + cognitive. Entry
8
+ # points are annotated. fan_in still comes from the engine's server-computed
9
+ # hotspot ranking; the per-symbol complexity/cognitive/is_entry_point come from a
10
+ # node-property query and are merged in.
6
11
  #
7
12
  # Usage:
8
13
  # scripts/tools/hotspot-rank.sh [--repo DIR] [--top N]
9
14
  #
10
- # Output: JSON {hotspots:[{id, name, fanIn}], source}.
15
+ # Output: JSON {hotspots:[{id, name, fanIn, complexity, cognitive, score,
16
+ # isEntryPoint}], source}.
11
17
  # source = "memory-graph" | "unavailable"
12
18
  #
13
19
  # Exit codes: 0 OK, 1 invocation error, 2 graph engine/data unavailable.
14
20
  set -euo pipefail
15
21
 
16
- # shellcheck source=_lib.sh
17
- source "$(dirname "${BASH_SOURCE[0]}")/_lib.sh"
22
+ # shellcheck source=_graph_queries.sh
23
+ source "$(dirname "${BASH_SOURCE[0]}")/_graph_queries.sh"
18
24
 
19
25
  REPO="."
20
26
  TOP=0
21
27
 
22
28
  usage() {
23
29
  cat <<'EOF'
24
- hotspot-rank.sh — fan-in-ranked symbols from the knowledge graph.
30
+ hotspot-rank.sh — complexity-weighted hotspot ranking from the knowledge graph.
25
31
 
26
32
  Usage:
27
33
  scripts/tools/hotspot-rank.sh [--repo DIR] [--top N]
@@ -31,8 +37,8 @@ Flags:
31
37
  --top N Keep only top N hotspots (default: 0 = all).
32
38
  --help Show this help.
33
39
 
34
- Output: JSON {hotspots:[{id, name, fanIn}], source}.
35
- source = "memory-graph" | "unavailable"
40
+ Output: JSON {hotspots:[{id, name, fanIn, complexity, cognitive, score,
41
+ isEntryPoint}], source}. Ranked by score = fanIn + complexity + cognitive.
36
42
 
37
43
  Exit 0 with results, exit 2 with {"hotspots":[],"source":"unavailable"} when the
38
44
  graph engine is unavailable.
@@ -68,10 +74,31 @@ PROJECT="$(memory_ensure_index "$REPO_ABS" || true)"
68
74
 
69
75
  ARCH_JSON="$(memory_cli get_architecture "{\"project\":\"$PROJECT\",\"aspects\":[\"hotspots\"]}" || true)"
70
76
  [[ -n "$ARCH_JSON" ]] || unavailable
71
-
72
- echo "$ARCH_JSON" | jq --argjson top "$TOP" '
73
- {
74
- hotspots: ([ (.hotspots // [])[] | {id: .qualified_name, name: .name, fanIn: .fan_in} ]
75
- | if $top > 0 then .[0:$top] else . end),
76
- source: "memory-graph"
77
- }'
77
+ echo "$ARCH_JSON" | jq -e . >/dev/null 2>&1 || unavailable
78
+
79
+ # Pre-computed complexity/cognitive/is_entry_point per symbol (merged onto fan-in).
80
+ PROPS_JSON="$(gq_run "$PROJECT" "$(gq_q_node_props)" || echo '{"rows":[]}')"
81
+ echo "$PROPS_JSON" | jq -e . >/dev/null 2>&1 || PROPS_JSON='{"rows":[]}'
82
+
83
+ # Merge via temp files (the props row set can exceed argv limits on large repos).
84
+ TMP_ARCH="$(mktemp)"; TMP_PROPS="$(mktemp)"
85
+ trap 'rm -f "$TMP_ARCH" "$TMP_PROPS"' EXIT
86
+ printf '%s' "$ARCH_JSON" > "$TMP_ARCH"
87
+ printf '%s' "$PROPS_JSON" > "$TMP_PROPS"
88
+
89
+ jq -n --slurpfile arch "$TMP_ARCH" --slurpfile props "$TMP_PROPS" --argjson top "$TOP" '
90
+ (($props[0].rows) // []) as $prows
91
+ | (reduce $prows[] as $r ({};
92
+ .[$r[0]] = {c:((($r[1]) // "0") | tonumber? // 0),
93
+ cog:((($r[2]) // "0") | tonumber? // 0),
94
+ ep:((($r[3]) | tostring) == "true")})) as $pmap
95
+ | [ (($arch[0].hotspots) // [])[]
96
+ | (.qualified_name) as $q
97
+ | ($pmap[$q] // {c:0, cog:0, ep:false}) as $p
98
+ | {id:$q, name:.name, fanIn:(.fan_in // 0),
99
+ complexity:$p.c, cognitive:$p.cog,
100
+ score:((.fan_in // 0) + $p.c + $p.cog),
101
+ isEntryPoint:$p.ep} ]
102
+ | sort_by(-.score)
103
+ | (if $top > 0 then .[0:$top] else . end) as $h
104
+ | {hotspots:$h, source:"memory-graph"}'
@@ -1,21 +1,27 @@
1
1
  #!/usr/bin/env bash
2
2
  # mermaid-from-graph.sh — emit Mermaid diagrams from the knowledge graph.
3
3
  #
4
- # Backed by the codebase-memory-mcp engine. Two diagrams:
5
- # module-deps : file co-change coupling (FILE_CHANGES_WITH edges) as a flowchart.
4
+ # Backed by the codebase-memory-mcp engine. Diagrams:
5
+ # module-deps : real file/module dependency graph (IMPORTS edges) as a flowchart.
6
+ # This is the auto-derived dependency diagram for architecture.md
7
+ # §9 (graph-tooling-v2 Phase 4) — it replaces the prior co-change
8
+ # proxy with actual import edges.
9
+ # co-change : file co-change coupling (FILE_CHANGES_WITH edges) — the hidden,
10
+ # git-history dependency proxy (the prior module-deps behavior,
11
+ # still available explicitly).
6
12
  # proto-map : detected service routes (Route nodes) as a flowchart.
7
13
  #
8
14
  # When the engine is unavailable, emits an empty diagram stub and exits 2 so
9
15
  # consuming skills can degrade gracefully.
10
16
  #
11
17
  # Usage:
12
- # scripts/tools/mermaid-from-graph.sh [--repo DIR] [--diagram module-deps|proto-map]
18
+ # scripts/tools/mermaid-from-graph.sh [--repo DIR] [--diagram module-deps|co-change|proto-map]
13
19
  #
14
20
  # Exit codes: 0 OK, 1 invocation error, 2 graph engine/data unavailable.
15
21
  set -euo pipefail
16
22
 
17
- # shellcheck source=_lib.sh
18
- source "$(dirname "${BASH_SOURCE[0]}")/_lib.sh"
23
+ # shellcheck source=_graph_queries.sh
24
+ source "$(dirname "${BASH_SOURCE[0]}")/_graph_queries.sh"
19
25
 
20
26
  REPO="."
21
27
  DIAGRAM="module-deps"
@@ -25,11 +31,12 @@ usage() {
25
31
  mermaid-from-graph.sh — emit Mermaid diagrams from the knowledge graph.
26
32
 
27
33
  Usage:
28
- scripts/tools/mermaid-from-graph.sh [--repo DIR] [--diagram module-deps|proto-map]
34
+ scripts/tools/mermaid-from-graph.sh [--repo DIR] [--diagram module-deps|co-change|proto-map]
29
35
 
30
36
  Flags:
31
37
  --repo DIR Repository root (default: cwd).
32
- --diagram NAME module-deps (default) or proto-map.
38
+ --diagram NAME module-deps (default, IMPORTS edges), co-change
39
+ (FILE_CHANGES_WITH coupling), or proto-map (routes).
33
40
  --help Show this help.
34
41
 
35
42
  Exit 0 with diagram output, exit 2 with an empty stub when the engine is unavailable.
@@ -70,9 +77,22 @@ command -v jq >/dev/null 2>&1 || stub
70
77
  PROJECT="$(memory_ensure_index "$REPO_ABS" || true)"
71
78
  [[ -n "$PROJECT" ]] || stub
72
79
 
80
+ # module-deps: real IMPORTS edges (the auto-derived dependency graph). Self-imports
81
+ # (src == dst) are dropped so the diagram is a true cross-file graph. Capped at 40
82
+ # edges for readability.
73
83
  render_module_deps() {
74
- local q="MATCH (a:File)-[r:FILE_CHANGES_WITH]->(b:File) RETURN a.name AS src, b.name AS dst, r.coupling_score AS score ORDER BY r.coupling_score DESC LIMIT 40"
75
- local res; res="$(memory_cli query_graph "{\"project\":\"$PROJECT\",\"query\":\"$q\"}" || echo '{}')"
84
+ local res; res="$(gq_run "$PROJECT" "$(gq_q_imports)" || echo '{}')"
85
+ local edges; edges="$(echo "${res:-{\}}" | jq -r '
86
+ [ (.rows // [])[] | {s:(.[0]|tostring), d:(.[1]|tostring)}
87
+ | select(.s != "" and .d != "" and .s != .d) ]
88
+ | unique | .[0:40][] | " \"" + .s + "\" --> \"" + .d + "\""' 2>/dev/null || true)"
89
+ if [[ -z "$edges" ]]; then return 1; fi
90
+ printf '```mermaid\nflowchart LR\n%s\n```\n' "$edges"
91
+ }
92
+
93
+ # co-change: FILE_CHANGES_WITH coupling (the prior module-deps proxy).
94
+ render_co_change() {
95
+ local res; res="$(gq_run "$PROJECT" "$(gq_q_co_change)" || echo '{}')"
76
96
  local edges; edges="$(echo "${res:-{\}}" | jq -r '(.rows // [])[] | " \"" + (.[0]|tostring) + "\" --> \"" + (.[1]|tostring) + "\""' 2>/dev/null || true)"
77
97
  if [[ -z "$edges" ]]; then return 1; fi
78
98
  printf '```mermaid\nflowchart LR\n%s\n```\n' "$edges"
@@ -87,6 +107,7 @@ render_proto_map() {
87
107
 
88
108
  case "$DIAGRAM" in
89
109
  module-deps) render_module_deps || stub ;;
110
+ co-change) render_co_change || stub ;;
90
111
  proto-map) render_proto_map || stub ;;
91
- *) echo "Unknown --diagram '$DIAGRAM' (expected module-deps|proto-map)" >&2; exit 1 ;;
112
+ *) echo "Unknown --diagram '$DIAGRAM' (expected module-deps|co-change|proto-map)" >&2; exit 1 ;;
92
113
  esac