@drafthq/draft 3.7.1 → 3.7.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.
@@ -12,7 +12,7 @@
12
12
  "name": "draft",
13
13
  "source": "./",
14
14
  "description": "Context-Driven Development: draft specs and plans before implementation. Structured workflows for features and fixes.",
15
- "version": "3.7.1",
15
+ "version": "3.7.2",
16
16
  "author": {
17
17
  "name": "mayurpise"
18
18
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "draft",
3
3
  "description": "Context-Driven Development: draft specs and plans before implementation. Structured workflows for features and fixes.",
4
- "version": "3.7.1",
4
+ "version": "3.7.2",
5
5
  "author": {
6
6
  "name": "mayurpise"
7
7
  },
@@ -2,7 +2,7 @@
2
2
  "name": "draft",
3
3
  "displayName": "Draft",
4
4
  "description": "Context-Driven Development: draft specs and plans before implementation. Structured workflows for features and fixes.",
5
- "version": "3.7.1",
5
+ "version": "3.7.2",
6
6
  "skills": "./skills/",
7
7
  "agents": "./core/agents/",
8
8
  "author": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drafthq/draft",
3
- "version": "3.7.1",
3
+ "version": "3.7.2",
4
4
  "description": "Context-Driven Development for AI coding agents — install Draft into Claude Code, Cursor, Codex, or opencode.",
5
5
  "bin": {
6
6
  "draft": "cli/bin/draft.js"
@@ -71,8 +71,20 @@ ARCH_JSON="$(memory_cli get_architecture \
71
71
  echo "$ARCH_JSON" | jq -e . >/dev/null 2>&1 || unavailable
72
72
 
73
73
  # Pre-computed complexity/cognitive/is_entry_point per symbol (merged onto fan-in).
74
- PROPS_JSON="$(gq_run "$PROJECT" "$(gq_q_node_props)" || echo '{"rows":[]}')"
75
- echo "$PROPS_JSON" | jq -e . >/dev/null 2>&1 || PROPS_JSON='{"rows":[]}'
74
+ #
75
+ # The hotspots themselves come from get_architecture above, which is fail-loud,
76
+ # so a failure here costs enrichment rather than the whole result — worth keeping
77
+ # the ranking for. But it must not pass silently: substituting an empty row set
78
+ # gave every symbol complexity 0 and cognitive 0, folded those zeros into `score`,
79
+ # and still reported source:"memory-graph", so a fan-in-only ranking was
80
+ # indistinguishable from a fully measured one. Record the outcome instead, and
81
+ # omit the fields rather than emitting measurements that were never taken.
82
+ if PROPS_JSON="$(gq_run "$PROJECT" "$(gq_q_node_props)")"; then
83
+ ENRICHMENT="ok"
84
+ else
85
+ PROPS_JSON='{"rows":[]}'
86
+ ENRICHMENT="unavailable"
87
+ fi
76
88
 
77
89
  # Merge via temp files (the props row set can exceed argv limits on large repos).
78
90
  TMP_ARCH="$(mktemp)"; TMP_PROPS="$(mktemp)"
@@ -80,7 +92,8 @@ trap 'rm -f "$TMP_ARCH" "$TMP_PROPS"' EXIT
80
92
  printf '%s' "$ARCH_JSON" > "$TMP_ARCH"
81
93
  printf '%s' "$PROPS_JSON" > "$TMP_PROPS"
82
94
 
83
- jq -n --slurpfile arch "$TMP_ARCH" --slurpfile props "$TMP_PROPS" --argjson top "$TOP" '
95
+ jq -n --slurpfile arch "$TMP_ARCH" --slurpfile props "$TMP_PROPS" --argjson top "$TOP" \
96
+ --arg enrichment "$ENRICHMENT" '
84
97
  ((($props[0].rows) // []) | map(select(.[0] != null))) as $prows
85
98
  | (reduce $prows[] as $r ({};
86
99
  .[$r[0]] = {c:((($r[1]) // "0") | tonumber? // 0),
@@ -89,10 +102,11 @@ jq -n --slurpfile arch "$TMP_ARCH" --slurpfile props "$TMP_PROPS" --argjson top
89
102
  | [ (($arch[0].hotspots) // [])[]
90
103
  | (.qualified_name) as $q
91
104
  | ($pmap[$q] // {c:0, cog:0, ep:false}) as $p
92
- | {id:$q, name:.name, fanIn:(.fan_in // 0),
93
- complexity:$p.c, cognitive:$p.cog,
94
- score:((.fan_in // 0) + $p.c + $p.cog),
95
- isEntryPoint:$p.ep} ]
105
+ | ({id:$q, name:.name, fanIn:(.fan_in // 0),
106
+ score:((.fan_in // 0) + $p.c + $p.cog)}
107
+ + (if $enrichment == "ok"
108
+ then {complexity:$p.c, cognitive:$p.cog, isEntryPoint:$p.ep}
109
+ else {} end)) ]
96
110
  | sort_by(-.score)
97
111
  | (if $top > 0 then .[0:$top] else . end) as $h
98
- | {hotspots:$h, source:"memory-graph"}'
112
+ | {hotspots:$h, enrichment:$enrichment, source:"memory-graph"}'
@@ -57,25 +57,39 @@ if [[ ! -d "$REPO" ]]; then
57
57
  exit 1
58
58
  fi
59
59
 
60
+ # $1: "unavailable" (engine/query failed) or "empty" (query ran, no such edges).
61
+ # Swallowing a failed query with `{}` used to make both look identical, so an
62
+ # engine failure and a repo with genuinely no cross-file imports produced the
63
+ # same "graph not built" diagram — the reader could not tell which they had.
60
64
  stub() {
61
- cat <<'EOF'
65
+ if [[ "${1:-unavailable}" == "empty" ]]; then
66
+ cat <<'EOF'
67
+ ```mermaid
68
+ %% graph is built, but holds no edges of this kind — nothing to draw
69
+ flowchart LR
70
+ empty["no edges"]
71
+ ```
72
+ EOF
73
+ else
74
+ cat <<'EOF'
62
75
  ```mermaid
63
76
  %% graph data unavailable — index the repo with the graph engine first
64
77
  flowchart LR
65
78
  empty["graph not built"]
66
79
  ```
67
80
  EOF
81
+ fi
68
82
  exit 2
69
83
  }
70
84
 
71
- graph_bootstrap "$REPO" || stub
85
+ graph_bootstrap "$REPO" || stub unavailable
72
86
 
73
87
  # module-deps: real IMPORTS edges (the auto-derived dependency graph). Self-imports
74
88
  # (src == dst) are dropped so the diagram is a true cross-file graph. Capped at 40
75
89
  # edges for readability.
76
90
  render_module_deps() {
77
- local res; res="$(gq_run "$PROJECT" "$(gq_q_imports)" || echo '{}')"
78
- local edges; edges="$(echo "${res:-{\}}" | jq -r '
91
+ local res; res="$(gq_run "$PROJECT" "$(gq_q_imports)")" || return 2
92
+ local edges; edges="$(echo "$res" | jq -r '
79
93
  [ (.rows // [])[] | {s:(.[0]|tostring), d:(.[1]|tostring)}
80
94
  | select(.s != "" and .d != "" and .s != .d) ]
81
95
  | unique | .[0:40][] | " \"" + .s + "\" --> \"" + .d + "\""' 2>/dev/null || true)"
@@ -85,23 +99,25 @@ render_module_deps() {
85
99
 
86
100
  # co-change: FILE_CHANGES_WITH coupling (the prior module-deps proxy).
87
101
  render_co_change() {
88
- local res; res="$(gq_run "$PROJECT" "$(gq_q_co_change)" || echo '{}')"
89
- local edges; edges="$(echo "${res:-{\}}" | jq -r '(.rows // [])[] | " \"" + (.[0]|tostring) + "\" --> \"" + (.[1]|tostring) + "\""' 2>/dev/null || true)"
102
+ local res; res="$(gq_run "$PROJECT" "$(gq_q_co_change)")" || return 2
103
+ local edges; edges="$(echo "$res" | jq -r '(.rows // [])[] | " \"" + (.[0]|tostring) + "\" --> \"" + (.[1]|tostring) + "\""' 2>/dev/null || true)"
90
104
  if [[ -z "$edges" ]]; then return 1; fi
91
105
  printf '```mermaid\nflowchart LR\n%s\n```\n' "$edges"
92
106
  }
93
107
 
94
108
  render_proto_map() {
95
109
  local res; res="$(memory_cli get_architecture \
96
- "$(jq -n --arg p "$PROJECT" '{project:$p, aspects:["routes"]}')" || echo '{}')"
97
- local edges; edges="$(echo "${res:-{\}}" | jq -r '(.routes // [])[] | " \"" + ((.method // "")|tostring) + " " + ((.path // "")|tostring) + "\" --> \"" + ((.handler // "?")|tostring) + "\""' 2>/dev/null || true)"
110
+ "$(jq -n --arg p "$PROJECT" '{project:$p, aspects:["routes"]}')" || true)"
111
+ [[ -n "$res" ]] && echo "$res" | jq -e . >/dev/null 2>&1 || return 2
112
+ local edges; edges="$(echo "$res" | jq -r '(.routes // [])[] | " \"" + ((.method // "")|tostring) + " " + ((.path // "")|tostring) + "\" --> \"" + ((.handler // "?")|tostring) + "\""' 2>/dev/null || true)"
98
113
  if [[ -z "$edges" ]]; then return 1; fi
99
114
  printf '```mermaid\nflowchart LR\n%s\n```\n' "$edges"
100
115
  }
101
116
 
117
+ # rc 2 = the query failed; rc 1 = it ran and returned nothing. Different stubs.
102
118
  case "$DIAGRAM" in
103
- module-deps) render_module_deps || stub ;;
104
- co-change) render_co_change || stub ;;
105
- proto-map) render_proto_map || stub ;;
119
+ module-deps) render_module_deps || { rc=$?; [[ $rc -eq 1 ]] && stub empty || stub unavailable; } ;;
120
+ co-change) render_co_change || { rc=$?; [[ $rc -eq 1 ]] && stub empty || stub unavailable; } ;;
121
+ proto-map) render_proto_map || { rc=$?; [[ $rc -eq 1 ]] && stub empty || stub unavailable; } ;;
106
122
  *) echo "Unknown --diagram '$DIAGRAM' (expected module-deps|co-change|proto-map)" >&2; exit 1 ;;
107
123
  esac