@drafthq/draft 3.5.2 → 3.6.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.
Files changed (86) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.cursor-plugin/plugin.json +1 -1
  4. package/cli/src/hosts/cursor.js +3 -0
  5. package/cli/src/installer.js +7 -3
  6. package/cli/src/lib/fsx.js +3 -0
  7. package/cli/src/lib/marker.js +8 -3
  8. package/core/shared/condensation.md +1 -1
  9. package/core/shared/git-report-metadata.md +1 -1
  10. package/core/shared/graph-query.md +24 -24
  11. package/core/shared/tool-resolver.md +20 -15
  12. package/core/templates/okf/index.md +6 -10
  13. package/core/templates/okf/section-index.md +2 -11
  14. package/core/templates/plan.md +1 -1
  15. package/integrations/agents/AGENTS.md +142 -492
  16. package/integrations/copilot/.github/copilot-instructions.md +142 -492
  17. package/package.json +1 -1
  18. package/scripts/fetch-memory-engine.sh +1 -1
  19. package/scripts/lib.sh +79 -2
  20. package/scripts/tools/_graph_queries.sh +12 -5
  21. package/scripts/tools/_lib.sh +56 -8
  22. package/scripts/tools/adr-index.sh +1 -1
  23. package/scripts/tools/check-skill-line-caps.sh +2 -2
  24. package/scripts/tools/check-track-hygiene.sh +41 -21
  25. package/scripts/tools/classify-files.sh +1 -1
  26. package/scripts/tools/cycle-detect.sh +2 -9
  27. package/scripts/tools/detect-test-framework.sh +1 -1
  28. package/scripts/tools/emit-skill-metrics.sh +7 -2
  29. package/scripts/tools/freshness-check.sh +2 -2
  30. package/scripts/tools/git-metadata.sh +6 -6
  31. package/scripts/tools/graph-arch.sh +4 -10
  32. package/scripts/tools/graph-callers.sh +4 -12
  33. package/scripts/tools/graph-deps.sh +3 -10
  34. package/scripts/tools/graph-errors.sh +4 -11
  35. package/scripts/tools/graph-hierarchy.sh +4 -11
  36. package/scripts/tools/graph-impact.sh +17 -17
  37. package/scripts/tools/graph-init.sh +1 -1
  38. package/scripts/tools/graph-preflight.sh +1 -1
  39. package/scripts/tools/graph-query.sh +5 -12
  40. package/scripts/tools/graph-risk.sh +3 -10
  41. package/scripts/tools/graph-search.sh +4 -11
  42. package/scripts/tools/graph-snapshot.sh +9 -4
  43. package/scripts/tools/graph-snippet.sh +3 -10
  44. package/scripts/tools/graph-tests.sh +3 -10
  45. package/scripts/tools/graph-traces.sh +3 -10
  46. package/scripts/tools/hotspot-rank.sh +4 -11
  47. package/scripts/tools/mermaid-from-graph.sh +3 -10
  48. package/scripts/tools/migrate-track-frontmatter.sh +3 -1
  49. package/scripts/tools/okf-coverage-check.sh +24 -6
  50. package/scripts/tools/okf-emit-catalog.sh +256 -0
  51. package/scripts/tools/okf-fix-links.sh +326 -0
  52. package/scripts/tools/okf-plan-concepts.sh +245 -14
  53. package/scripts/tools/okf-render-views.sh +65 -13
  54. package/scripts/tools/okf-validate-all.sh +20 -9
  55. package/scripts/tools/okf-validate-quality.sh +2 -8
  56. package/scripts/tools/okf-validate.sh +20 -10
  57. package/scripts/tools/parse-git-log.sh +4 -4
  58. package/scripts/tools/parse-reports.sh +1 -1
  59. package/scripts/tools/render-track.sh +1 -1
  60. package/scripts/tools/run-coverage.sh +1 -1
  61. package/scripts/tools/scan-markers.sh +4 -4
  62. package/scripts/tools/validate-frontmatter.sh +2 -2
  63. package/scripts/tools/verify-citations.sh +2 -2
  64. package/scripts/tools/verify-doc-anchors.sh +1 -1
  65. package/scripts/tools/verify-graph-binary.sh +2 -2
  66. package/skills/adr/SKILL.md +1 -1
  67. package/skills/bughunt/SKILL.md +1 -1
  68. package/skills/coverage/SKILL.md +2 -2
  69. package/skills/debug/SKILL.md +1 -1
  70. package/skills/decompose/SKILL.md +3 -3
  71. package/skills/deep-review/SKILL.md +2 -2
  72. package/skills/deploy-checklist/SKILL.md +1 -1
  73. package/skills/graph/SKILL.md +1 -1
  74. package/skills/impact/SKILL.md +1 -1
  75. package/skills/implement/SKILL.md +2 -2
  76. package/skills/init/SKILL.md +10 -7
  77. package/skills/init/references/architecture-spec.md +1 -1
  78. package/skills/init/references/okf-emitter.md +51 -76
  79. package/skills/learn/SKILL.md +1 -1
  80. package/skills/quick-review/SKILL.md +1 -1
  81. package/skills/review/SKILL.md +3 -3
  82. package/skills/standup/SKILL.md +1 -1
  83. package/skills/status/SKILL.md +1 -1
  84. package/skills/tech-debt/SKILL.md +2 -2
  85. package/skills/upload/SKILL.md +1 -1
  86. package/core/templates/track-architecture.md +0 -311
@@ -48,7 +48,7 @@ TO_STDOUT=0
48
48
  while (($#)); do
49
49
  case "$1" in
50
50
  -h|--help) USAGE_HELP_MODE=1 usage ;;
51
- --out) OUT_PATH="$2"; shift 2 ;;
51
+ --out) OUT_PATH="${2:?--out requires a value}"; shift 2 ;;
52
52
  --stdout) TO_STDOUT=1; shift ;;
53
53
  -*) printf 'Unknown flag: %s\n' "$1" >&2; usage ;;
54
54
  *) TRACK_DIR="$1"; shift ;;
@@ -51,7 +51,7 @@ EOF
51
51
 
52
52
  while [[ $# -gt 0 ]]; do
53
53
  case "$1" in
54
- --path) COVERAGE_PATH="$2"; shift 2;;
54
+ --path) COVERAGE_PATH="${2:?--path requires a value}"; shift 2;;
55
55
  --schema-check) SCHEMA_CHECK="true"; shift;;
56
56
  --help|-h) usage; exit 0;;
57
57
  -*) echo "Unknown flag: $1" >&2; usage >&2; exit 1;;
@@ -6,7 +6,7 @@
6
6
  #
7
7
  # Usage:
8
8
  # scripts/tools/scan-markers.sh [--root DIR] [--markers LIST]
9
- # [--min-age-days N] [--include-untracked]
9
+ # [--min-age-days N]
10
10
  #
11
11
  # Exit codes: 0 OK (even with zero hits), 1 invocation error, 2 not a git repo
12
12
  # (emits [] on stdout so consumers can still parse).
@@ -38,9 +38,9 @@ EOF
38
38
 
39
39
  while [[ $# -gt 0 ]]; do
40
40
  case "$1" in
41
- --root) ROOT="$2"; shift 2;;
42
- --markers) MARKERS="$2"; shift 2;;
43
- --min-age-days) MIN_AGE="$2"; shift 2;;
41
+ --root) ROOT="${2:?--root requires a value}"; shift 2;;
42
+ --markers) MARKERS="${2:?--markers requires a value}"; shift 2;;
43
+ --min-age-days) MIN_AGE="${2:?--min-age-days requires a value}"; shift 2;;
44
44
  --help|-h) usage; exit 0;;
45
45
  *) echo "Unknown flag: $1" >&2; usage >&2; exit 1;;
46
46
  esac
@@ -43,8 +43,8 @@ REQUIRED="name,description"
43
43
 
44
44
  while [[ $# -gt 0 ]]; do
45
45
  case "$1" in
46
- --require) REQUIRED="$2"; shift 2;;
47
- --mode) MODE="$2"; shift 2;;
46
+ --require) REQUIRED="${2:?--require requires a value}"; shift 2;;
47
+ --mode) MODE="${2:?--mode requires a value}"; shift 2;;
48
48
  --help|-h) usage; exit 0;;
49
49
  -*) echo "Unknown flag: $1" >&2; usage >&2; exit 1;;
50
50
  *)
@@ -48,7 +48,7 @@ while (($#)); do
48
48
  case "$1" in
49
49
  -h|--help) USAGE_HELP_MODE=1 usage ;;
50
50
  --json) EMIT_JSON=1; shift ;;
51
- --tolerance) TOLERANCE="$2"; shift 2 ;;
51
+ --tolerance) TOLERANCE="${2:?--tolerance requires a value}"; shift 2 ;;
52
52
  -*) printf 'Unknown flag: %s\n' "$1" >&2; usage ;;
53
53
  *) TRACK_PATHS+=("$1"); shift ;;
54
54
  esac
@@ -83,7 +83,7 @@ extract_citations() {
83
83
  # bracket expression prematurely terminates a regex literal in
84
84
  # POSIX/BSD awk ("nonterminated character class"), though gawk is
85
85
  # lenient. The string form is portable across awk implementations.
86
- while (match(s, "[A-Za-z0-9_][A-Za-z0-9_./-]*\\.[A-Za-z0-9]+:[0-9]+")) {
86
+ while (match(s, "[A-Za-z0-9_][A-Za-z0-9_./-]*\\.[A-Za-z0-9]+:[0-9]+(-[0-9]+)?")) {
87
87
  cite = substr(s, RSTART, RLENGTH)
88
88
  printf("%s\t%d\t%s\n", FILENAME, NR, cite)
89
89
  s = substr(s, RSTART + RLENGTH)
@@ -150,7 +150,7 @@ scan_md() {
150
150
  # token the `(planned)` annotation owns.
151
151
  if echo "$line" | grep -qE '\(planned\)|\[New file'; then
152
152
  local paths
153
- paths="$(echo "$line" | grep -oE '[A-Za-z][A-Za-z0-9_./-]*\.[A-Za-z]+' | sort -u)"
153
+ paths="$(echo "$line" | grep -oE '[A-Za-z][A-Za-z0-9_./-]*\.[A-Za-z]+' | sort -u || true)"
154
154
  local path_count
155
155
  path_count="$(printf '%s\n' "$paths" | grep -c . || true)"
156
156
  if (( path_count == 1 )); then
@@ -51,8 +51,8 @@ EOF
51
51
 
52
52
  while [[ $# -gt 0 ]]; do
53
53
  case "$1" in
54
- --repo) REPO="$2"; shift 2 ;;
55
- --plugin-root) PLUGIN_ROOT="$2"; shift 2 ;;
54
+ --repo) REPO="${2:?--repo requires a value}"; shift 2 ;;
55
+ --plugin-root) PLUGIN_ROOT="${2:?--plugin-root requires a value}"; shift 2 ;;
56
56
  --json) EMIT_JSON=1; shift ;;
57
57
  --verbose) VERBOSE=1; shift ;;
58
58
  --strict) STRICT=1; shift ;;
@@ -54,7 +54,7 @@ Check for arguments:
54
54
  If argument is `list`:
55
55
  1. Prefer the deterministic `adr-index.sh` wrapper for the listing — it returns a structured JSON `{adrs:[{id,title,date,status,path,related_tracks}]}` derived from each ADR's frontmatter. Resolve via the canonical tool resolver (see [core/shared/tool-resolver.md](../../core/shared/tool-resolver.md)):
56
56
  ```bash
57
- DRAFT_TOOLS="$(cat ~/.cache/draft/plugin-root 2>/dev/null)/scripts/tools"
57
+ DRAFT_TOOLS="${DRAFT_PLUGIN_ROOT:-$(cat ~/.cache/draft/plugin-root 2>/dev/null)}/scripts/tools"
58
58
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/cache/*/draft/*/scripts/tools 2>/dev/null | sort -V | tail -1)"
59
59
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/marketplaces/*draft*/scripts/tools 2>/dev/null | tail -1)"
60
60
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$PWD/scripts/tools"
@@ -72,7 +72,7 @@ Read and follow the base procedure in `core/shared/draft-context-loading.md`.
72
72
  ```bash
73
73
  # Locate Draft's bundled helpers (cwd is the user's project; ${CLAUDE_PLUGIN_ROOT}
74
74
  # is not exported into skill Bash). See core/shared/tool-resolver.md.
75
- DRAFT_TOOLS="$(cat ~/.cache/draft/plugin-root 2>/dev/null)/scripts/tools"
75
+ DRAFT_TOOLS="${DRAFT_PLUGIN_ROOT:-$(cat ~/.cache/draft/plugin-root 2>/dev/null)}/scripts/tools"
76
76
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/cache/*/draft/*/scripts/tools 2>/dev/null | sort -V | tail -1)"
77
77
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/marketplaces/*draft*/scripts/tools 2>/dev/null | tail -1)"
78
78
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$PWD/scripts/tools"
@@ -33,7 +33,7 @@ If no active track and no argument provided:
33
33
  **Preferred:** use the deterministic `detect-test-framework.sh` wrapper — it emits JSON `{languages:[{language,framework,runner_command,test_globs,config_file}]}`. Resolve via the canonical tool resolver (see [core/shared/tool-resolver.md](../../core/shared/tool-resolver.md)):
34
34
 
35
35
  ```bash
36
- DRAFT_TOOLS="$(cat ~/.cache/draft/plugin-root 2>/dev/null)/scripts/tools"
36
+ DRAFT_TOOLS="${DRAFT_PLUGIN_ROOT:-$(cat ~/.cache/draft/plugin-root 2>/dev/null)}/scripts/tools"
37
37
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/cache/*/draft/*/scripts/tools 2>/dev/null | sort -V | tail -1)"
38
38
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/marketplaces/*draft*/scripts/tools 2>/dev/null | tail -1)"
39
39
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$PWD/scripts/tools"
@@ -75,7 +75,7 @@ Build the coverage command with the appropriate scope/filter flags.
75
75
 
76
76
  ```bash
77
77
  # Re-resolve helpers (this is a separate Bash session from Step 2).
78
- DRAFT_TOOLS="$(cat ~/.cache/draft/plugin-root 2>/dev/null)/scripts/tools"
78
+ DRAFT_TOOLS="${DRAFT_PLUGIN_ROOT:-$(cat ~/.cache/draft/plugin-root 2>/dev/null)}/scripts/tools"
79
79
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/cache/*/draft/*/scripts/tools 2>/dev/null | sort -V | tail -1)"
80
80
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/marketplaces/*draft*/scripts/tools 2>/dev/null | tail -1)"
81
81
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$PWD/scripts/tools"
@@ -14,7 +14,7 @@ First resolve the bundled helpers:
14
14
  ```bash
15
15
  # Locate Draft's bundled helpers (cwd is the user's project; ${CLAUDE_PLUGIN_ROOT}
16
16
  # is not exported into skill Bash). See core/shared/tool-resolver.md.
17
- DRAFT_TOOLS="$(cat ~/.cache/draft/plugin-root 2>/dev/null)/scripts/tools"
17
+ DRAFT_TOOLS="${DRAFT_PLUGIN_ROOT:-$(cat ~/.cache/draft/plugin-root 2>/dev/null)}/scripts/tools"
18
18
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/cache/*/draft/*/scripts/tools 2>/dev/null | sort -V | tail -1)"
19
19
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/marketplaces/*draft*/scripts/tools 2>/dev/null | tail -1)"
20
20
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$PWD/scripts/tools"
@@ -14,7 +14,7 @@ First resolve the bundled helpers:
14
14
  ```bash
15
15
  # Locate Draft's bundled helpers (cwd is the user's project; ${CLAUDE_PLUGIN_ROOT}
16
16
  # is not exported into skill Bash). See core/shared/tool-resolver.md.
17
- DRAFT_TOOLS="$(cat ~/.cache/draft/plugin-root 2>/dev/null)/scripts/tools"
17
+ DRAFT_TOOLS="${DRAFT_PLUGIN_ROOT:-$(cat ~/.cache/draft/plugin-root 2>/dev/null)}/scripts/tools"
18
18
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/cache/*/draft/*/scripts/tools 2>/dev/null | sort -V | tail -1)"
19
19
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/marketplaces/*draft*/scripts/tools 2>/dev/null | tail -1)"
20
20
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$PWD/scripts/tools"
@@ -417,7 +417,7 @@ Resolve the script via the canonical tool resolver (see [core/shared/tool-resolv
417
417
  ```bash
418
418
  # Locate Draft's bundled helpers (cwd is the user's project; ${CLAUDE_PLUGIN_ROOT}
419
419
  # is not exported into skill Bash). See core/shared/tool-resolver.md.
420
- DRAFT_TOOLS="$(cat ~/.cache/draft/plugin-root 2>/dev/null)/scripts/tools"
420
+ DRAFT_TOOLS="${DRAFT_PLUGIN_ROOT:-$(cat ~/.cache/draft/plugin-root 2>/dev/null)}/scripts/tools"
421
421
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/cache/*/draft/*/scripts/tools 2>/dev/null | sort -V | tail -1)"
422
422
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/marketplaces/*draft*/scripts/tools 2>/dev/null | tail -1)"
423
423
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$PWD/scripts/tools"
@@ -664,7 +664,7 @@ As the last step after the completion announcement, emit a metrics record. Best-
664
664
  ```bash
665
665
  # Locate Draft's bundled helpers (cwd is the user's project; ${CLAUDE_PLUGIN_ROOT}
666
666
  # is not exported into skill Bash). See core/shared/tool-resolver.md.
667
- DRAFT_TOOLS="$(cat ~/.cache/draft/plugin-root 2>/dev/null)/scripts/tools"
667
+ DRAFT_TOOLS="${DRAFT_PLUGIN_ROOT:-$(cat ~/.cache/draft/plugin-root 2>/dev/null)}/scripts/tools"
668
668
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/cache/*/draft/*/scripts/tools 2>/dev/null | sort -V | tail -1)"
669
669
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/marketplaces/*draft*/scripts/tools 2>/dev/null | tail -1)"
670
670
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$PWD/scripts/tools"
@@ -15,7 +15,7 @@ First resolve the bundled helpers:
15
15
  ```bash
16
16
  # Locate Draft's bundled helpers (cwd is the user's project; ${CLAUDE_PLUGIN_ROOT}
17
17
  # is not exported into skill Bash). See core/shared/tool-resolver.md.
18
- DRAFT_TOOLS="$(cat ~/.cache/draft/plugin-root 2>/dev/null)/scripts/tools"
18
+ DRAFT_TOOLS="${DRAFT_PLUGIN_ROOT:-$(cat ~/.cache/draft/plugin-root 2>/dev/null)}/scripts/tools"
19
19
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/cache/*/draft/*/scripts/tools 2>/dev/null | sort -V | tail -1)"
20
20
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/marketplaces/*draft*/scripts/tools 2>/dev/null | tail -1)"
21
21
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$PWD/scripts/tools"
@@ -330,7 +330,7 @@ As the last step after saving the deep-review report, emit a metrics record. Bes
330
330
  ```bash
331
331
  # Locate Draft's bundled helpers (cwd is the user's project; ${CLAUDE_PLUGIN_ROOT}
332
332
  # is not exported into skill Bash). See core/shared/tool-resolver.md.
333
- DRAFT_TOOLS="$(cat ~/.cache/draft/plugin-root 2>/dev/null)/scripts/tools"
333
+ DRAFT_TOOLS="${DRAFT_PLUGIN_ROOT:-$(cat ~/.cache/draft/plugin-root 2>/dev/null)}/scripts/tools"
334
334
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/cache/*/draft/*/scripts/tools 2>/dev/null | sort -V | tail -1)"
335
335
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/marketplaces/*draft*/scripts/tools 2>/dev/null | tail -1)"
336
336
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$PWD/scripts/tools"
@@ -67,7 +67,7 @@ by validator.
67
67
  ```bash
68
68
  TRACK_DIR="$1" # absolute path to track-under-deploy, or .
69
69
 
70
- DRAFT_TOOLS="$(cat ~/.cache/draft/plugin-root 2>/dev/null)/scripts/tools"
70
+ DRAFT_TOOLS="${DRAFT_PLUGIN_ROOT:-$(cat ~/.cache/draft/plugin-root 2>/dev/null)}/scripts/tools"
71
71
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/cache/*/draft/*/scripts/tools 2>/dev/null | sort -V | tail -1)"
72
72
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/marketplaces/*draft*/scripts/tools 2>/dev/null | tail -1)"
73
73
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$PWD/scripts/tools"
@@ -37,7 +37,7 @@ echo "Target repo: $REPO_ABS"
37
37
  # Locate Draft's bundled helpers. Skills run with cwd = the user's project and
38
38
  # ${CLAUDE_PLUGIN_ROOT} is not exported into skill Bash, so resolve DRAFT_TOOLS here
39
39
  # and call helpers as "$DRAFT_TOOLS/<tool>.sh". See core/shared/tool-resolver.md.
40
- DRAFT_TOOLS="$(cat ~/.cache/draft/plugin-root 2>/dev/null)/scripts/tools"
40
+ DRAFT_TOOLS="${DRAFT_PLUGIN_ROOT:-$(cat ~/.cache/draft/plugin-root 2>/dev/null)}/scripts/tools"
41
41
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/cache/*/draft/*/scripts/tools 2>/dev/null | sort -V | tail -1)"
42
42
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/marketplaces/*draft*/scripts/tools 2>/dev/null | tail -1)"
43
43
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$PWD/scripts/tools"
@@ -21,7 +21,7 @@ First resolve the bundled helpers:
21
21
  ```bash
22
22
  # Locate Draft's bundled helpers (cwd is the user's project; ${CLAUDE_PLUGIN_ROOT}
23
23
  # is not exported into skill Bash). See core/shared/tool-resolver.md.
24
- DRAFT_TOOLS="$(cat ~/.cache/draft/plugin-root 2>/dev/null)/scripts/tools"
24
+ DRAFT_TOOLS="${DRAFT_PLUGIN_ROOT:-$(cat ~/.cache/draft/plugin-root 2>/dev/null)}/scripts/tools"
25
25
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/cache/*/draft/*/scripts/tools 2>/dev/null | sort -V | tail -1)"
26
26
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/marketplaces/*draft*/scripts/tools 2>/dev/null | tail -1)"
27
27
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$PWD/scripts/tools"
@@ -139,7 +139,7 @@ If one of these applies, route directly to the specialist workflow and stop this
139
139
  ```bash
140
140
  # Locate Draft's bundled helpers (cwd is the user's project; ${CLAUDE_PLUGIN_ROOT}
141
141
  # is not exported into skill Bash). See core/shared/tool-resolver.md.
142
- DRAFT_TOOLS="$(cat ~/.cache/draft/plugin-root 2>/dev/null)/scripts/tools"
142
+ DRAFT_TOOLS="${DRAFT_PLUGIN_ROOT:-$(cat ~/.cache/draft/plugin-root 2>/dev/null)}/scripts/tools"
143
143
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/cache/*/draft/*/scripts/tools 2>/dev/null | sort -V | tail -1)"
144
144
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/marketplaces/*draft*/scripts/tools 2>/dev/null | tail -1)"
145
145
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$PWD/scripts/tools"
@@ -639,7 +639,7 @@ After a phase passes review, refresh `metadata.json.impact` so future tracks can
639
639
 
640
640
  2. **Compute downstream blast radius (graph-aware, optional):** If `draft/graph/schema.yaml` exists, for each file in `files_touched` query (this runs in its own Bash session — re-resolve the helpers):
641
641
  ```bash
642
- DRAFT_TOOLS="$(cat ~/.cache/draft/plugin-root 2>/dev/null)/scripts/tools"
642
+ DRAFT_TOOLS="${DRAFT_PLUGIN_ROOT:-$(cat ~/.cache/draft/plugin-root 2>/dev/null)}/scripts/tools"
643
643
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/cache/*/draft/*/scripts/tools 2>/dev/null | sort -V | tail -1)"
644
644
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/marketplaces/*draft*/scripts/tools 2>/dev/null | tail -1)"
645
645
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$PWD/scripts/tools"
@@ -218,13 +218,16 @@ The tier-gated default rests on **maintainability/readability** (one navigable c
218
218
 
219
219
  **OKF Completeness Verification (blocking — tier 3+ `okf` mode).** Completeness is enforced by tooling, not honor system, so the wiki is generated completely for every module/sub-module/component on every run. Before promoting `draft.tmp/` → `draft/`, ALL must hold (see `references/okf-emitter.md` for the pipeline):
220
220
 
221
- 1. `okf-plan-concepts.sh` ran and the expected/required/deferred counts were logged **before** any page was written (the concept boundary is a tool output, not an in-context guess).
222
- 2. Every `required` entry in `concept-plan.json` has a non-stub page.
223
- 3. `okf-validate-all.sh --plan … --strict` exits 0 (structure + per-type quality + coverage all pass).
224
- 4. `systems/coverage.md` was generated by tooling (verify the `<!-- okf:coverage-generated -->` marker) — **every** package/module the graph found is required by default (the fan-in floor only types Subsystem-vs-Module, it does not exempt), so none may be **MISSING**. Section `index.md` tables are regenerated by `okf-render-views.sh --section-indexes`, never hand-authored, so their links cannot dangle.
225
- 5. On any failure: **do not** atomic-rename; surface `.state/validation-report.json`.
221
+ 1. `okf-plan-concepts.sh` ran and counts were logged **before** any page was written. Plan discovery is language-aware: **Cargo workspace members / npm workspaces / Go modules first**, then graph packages (noise-filtered), then heuristic dirs. Log `discovery[]` (e.g. `cargo+graph`).
222
+ 2. `okf-emit-catalog.sh` ran so every REQUIRED plan entry has at least a minimum non-stub catalog page (LLM deep-dives may enrich top hotspots afterward).
223
+ 3. Every `required` entry in `concept-plan.json` has a non-stub page.
224
+ 4. `okf-render-views.sh` + `okf-fix-links.sh --fix` produced `architecture.md` with resolving `wiki/…` links and GFM TOC anchors.
225
+ 5. `okf-validate-all.sh --plan --strict` exits 0 (**quality coverage → structure**; structure runs last so coverage.md rewrites are checked).
226
+ 6. `okf-fix-links.sh --draft draft.tmp --check` exits 0 (zero dead links in architecture / wiki views).
227
+ 7. `systems/coverage.md` has the `<!-- okf:coverage-generated -->` marker; section indexes were regenerated by `okf-render-views.sh --section-indexes`.
228
+ 8. On any failure: **do not** atomic-rename; surface `.state/validation-report.json`.
226
229
 
227
- > **Red flag:** writing concept pages without first running `okf-plan-concepts.sh`, or finishing generation while any `required` plan entry is unwritten, is a **completeness failure** — not a stylistic one.
230
+ > **Red flag:** writing concept pages without first running `okf-plan-concepts.sh` + `okf-emit-catalog.sh`, or finishing while any `required` plan entry is unwritten, is a **completeness failure** — not a stylistic one.
228
231
 
229
232
  ### Route Explicit Modes Before Initialization
230
233
 
@@ -524,7 +527,7 @@ One command resolves ROOT, ensures the engine, builds the whole-repo spine, and
524
527
  ```bash
525
528
  # Locate Draft's bundled helpers (cwd is the user's project; ${CLAUDE_PLUGIN_ROOT}
526
529
  # is not exported into skill Bash). See core/shared/tool-resolver.md.
527
- DRAFT_TOOLS="$(cat ~/.cache/draft/plugin-root 2>/dev/null)/scripts/tools"
530
+ DRAFT_TOOLS="${DRAFT_PLUGIN_ROOT:-$(cat ~/.cache/draft/plugin-root 2>/dev/null)}/scripts/tools"
528
531
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/cache/*/draft/*/scripts/tools 2>/dev/null | sort -V | tail -1)"
529
532
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/marketplaces/*draft*/scripts/tools 2>/dev/null | tail -1)"
530
533
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$PWD/scripts/tools"
@@ -280,7 +280,7 @@ First resolve the bundled helpers:
280
280
  ```bash
281
281
  # Locate Draft's bundled helpers (cwd is the user's project; ${CLAUDE_PLUGIN_ROOT}
282
282
  # is not exported into skill Bash). See core/shared/tool-resolver.md.
283
- DRAFT_TOOLS="$(cat ~/.cache/draft/plugin-root 2>/dev/null)/scripts/tools"
283
+ DRAFT_TOOLS="${DRAFT_PLUGIN_ROOT:-$(cat ~/.cache/draft/plugin-root 2>/dev/null)}/scripts/tools"
284
284
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/cache/*/draft/*/scripts/tools 2>/dev/null | sort -V | tail -1)"
285
285
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/marketplaces/*draft*/scripts/tools 2>/dev/null | tail -1)"
286
286
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$PWD/scripts/tools"
@@ -77,7 +77,8 @@ Templates for each bundle page live in `core/templates/okf/` (`index.md`,
77
77
  ## Frozen `type` vocabulary
78
78
 
79
79
  Every concept carries a `type` from this frozen set (changing it churns every
80
- file; versioned via `index.md` frontmatter `okf_types_version`):
80
+ file; versioned via the `okf-types-version` comment in the wiki root `index.md`
81
+ body — OKF §6/§11 permit only `okf_version` in an index file's frontmatter):
81
82
 
82
83
  | type | Maps to | Home |
83
84
  |------|---------|------|
@@ -103,6 +104,16 @@ the task at hand?"), never a summary. Draft extensions are namespaced `x-` and
103
104
  ignored by generic OKF consumers: `x-grounded-paths`, `x-hotspot-score`,
104
105
  `x-callers`.
105
106
 
107
+ **Meta pages are not concepts.** Index files (`wiki/index.md` and every
108
+ `<section>/index.md`) carry **no concept frontmatter**: per OKF §6 an index file
109
+ has no frontmatter, and per §11 the root `index.md` may declare **only**
110
+ `okf_version`. The tool-generated `systems/coverage.md` is a non-reserved file, so
111
+ OKF §9.1/§9.2 require it to carry a typed frontmatter block; it uses a descriptive
112
+ `type: Report` and is exempt from the frozen vocabulary via `is_meta_page`
113
+ (basename + the `<!-- okf:coverage-generated -->` marker). `okf-validate.sh`
114
+ short-circuits all meta pages before the concept checks, so they are never
115
+ vocab-checked or counted as concepts.
116
+
106
117
  ## Concept granularity (resolves open decision 1)
107
118
 
108
119
  Derive concepts from the graph, not by hand:
@@ -122,75 +133,40 @@ Derive concepts from the graph, not by hand:
122
133
  ```
123
134
  1. Survey → existing /draft:init 5-phase + graph snapshot (graph-snapshot.sh)
124
135
  2. Plan → DETERMINISTIC. okf-plan-concepts.sh derives the expected-concept
125
- set from the graph. EVERY package the graph knows about is
126
- required (fan_in floor Subsystem; below floor Module — the
127
- floor only types/orders, it never exempts); entrypoints required;
128
- only --allow-defer matches are deferred (with a reason). Writes
129
- draft.tmp/.state/concept-plan.json.
136
+ set. Discovery order (exclusive of --manifest):
137
+ a) Cargo workspace members / npm workspaces / Go modules
138
+ b) graph packages (noise-filtered when a language inventory exists)
139
+ c) heuristic top-level source dirs
140
+ Coarse graph parents (e.g. crates/codegen) become Subsystems;
141
+ crate/package names become Modules. Tokenizer noise (str, int, …)
142
+ is dropped when unmapped. Writes draft.tmp/.state/concept-plan.json.
130
143
  okf-plan-concepts.sh --repo . [--scope PATH] \
131
144
  [--manifest FILE] [--min-fan-in 2] [--allow-defer GLOB]... \
132
145
  --out draft.tmp/.state/concept-plan.json
133
- This replaces the old in-context concept enumeration — the boundary
134
- of the work is now a tool output, not an LLM judgment, so modules
135
- and sub-modules cannot be silently dropped. (Legacy fan-in
136
- exemption is opt-in via --defer-below-floor.) LOG the counts
137
- (expected/required/deferred) BEFORE writing any page.
138
- `generated_order` is topo-ish (required + high-fan-in first) so
139
- forward cross-links resolve.
140
- 3. Generate → iterate concept-plan.generated_order; write ONE page per REQUIRED
141
- entry, grounding each from the graph:
142
- x-callers ← graph-callers.sh --symbol <c>
143
- x-grounded-paths ← graph-impact.sh --symbol <c> (blast radius)
144
- x-hotspot-score ← hotspot-rank.sh
145
- overview diagrams mermaid-from-graph.sh
146
- Record each source path → page in .state/path-to-concept.json.
147
- Loop post-condition: every required concept_id has an output file.
148
- Writing pages via shell heredoc without reading x-grounded-paths
149
- sources, or finishing while any required entry is unwritten, is a
150
- completeness failure not a stylistic one.
151
- 4. Render views → ai-context.md (synopsis + Concept Map), architecture.md
152
- (concatenated view + coverage banner), wiki/log.md (see M4).
153
- 5. Validate → the promotion gate. Run all layers via the orchestrator:
154
- 5a. okf-validate-all.sh draft.tmp/wiki \
155
- --repo . \
156
- --plan draft.tmp/.state/concept-plan.json \
157
- --path-index draft.tmp/.state/path-to-concept.json \
158
- --strict --report draft.tmp/.state/validation-report.json
159
- It runs, in order: okf-validate.sh (structure + reverse index +
160
- empty/untyped-page + leftover-template-token + dangling-link checks),
161
- okf-validate-quality.sh (per-type anti-stub / depth / per-section
162
- content / mermaid lint), okf-coverage-check.sh (every required plan
163
- entry → real page).
164
- ANY layer failing ⇒ exit non-zero ⇒ DO NOT atomic-rename.
165
- coverage.md (systems/coverage.md) is regenerated by the coverage
166
- layer; it is tool-owned (marker <!-- okf:coverage-generated -->) —
167
- never hand-author it except deferral reasons in the manifest.
168
- 6. Emit → mv draft.tmp/ draft/ ONLY IF step 5 exit 0 ; update .state/.
169
- On failure keep draft.tmp/ and surface validation-report.json.
170
- ```
171
-
172
- ### Validation report schema (`.state/validation-report.json`)
173
-
174
- ```json
175
- { "valid": false, "bundle": "draft.tmp/wiki",
176
- "layers": { "structure": "pass", "quality": "pass", "coverage": "fail" } }
146
+ LOG counts (expected/required/deferred + discovery[]) BEFORE pages.
147
+ 3. Catalog floor okf-emit-catalog.sh writes a quality-passing MINIMUM page for
148
+ every REQUIRED plan entry that is still missing (so XL monorepos
149
+ do not depend on the LLM for completeness):
150
+ okf-emit-catalog.sh --plan draft.tmp/.state/concept-plan.json \
151
+ --bundle draft.tmp/wiki --repo .
152
+ 4. Generate/enrich → iterate concept-plan.generated_order; enrich top hotspots
153
+ (LLM) beyond the catalog floor. Record path-to-concept.json.
154
+ Post-condition: every required concept_id has a non-stub page.
155
+ 5. Render views → okf-render-views.sh (architecture.md + Concept Map + section
156
+ indexes). Uses GFM slugs for TOC; rewrites sibling links to
157
+ wiki/<section>/…. Then okf-fix-links.sh --draft draft.tmp --fix.
158
+ 6. Validate → promotion gate (order is intentional):
159
+ okf-validate-all.sh draft.tmp/wiki \
160
+ --plan draft.tmp/.state/concept-plan.json \
161
+ --path-index draft.tmp/.state/path-to-concept.json \
162
+ --strict --report draft.tmp/.state/validation-report.json
163
+ Runs: quality coverage (rewrites coverage.md) → structure LAST
164
+ so coverage relative links are checked. Also run:
165
+ okf-fix-links.sh --draft draft.tmp --check
166
+ ANY failure DO NOT atomic-rename.
167
+ 7. Emit → mv draft.tmp/ draft/ ONLY IF step 6 exit 0 ; update .state/.
177
168
  ```
178
169
 
179
- ### Component manifest (optional — `--manifest FILE`)
180
-
181
- When the graph engine is unavailable (or a repo wants an authoritative list), pass
182
- a plain-text manifest: one component name per line, `#` comments and blanks ignored.
183
- Every listed component becomes a REQUIRED concept; `--allow-defer GLOB` still moves
184
- matches to deferred. Without a manifest the plan comes from the graph, and only if
185
- both are unavailable does it fall back to a heuristic top-level-dir scan (which it
186
- marks `degraded: true`).
187
-
188
- Page bodies are LLM-narrated for readability **but** the graph-derived
189
- frontmatter and the `Blast radius`/`Used by` sections are deterministic. To keep
190
- incremental carry-forward byte-identical (open decision 2), cache the narrated
191
- prose keyed by the source hash of `x-grounded-paths` — unchanged sources reuse
192
- the cached narration verbatim.
193
-
194
170
  ## Render views (M4)
195
171
 
196
172
  Both are produced by the deterministic helper `okf-render-views.sh` (no LLM) —
@@ -244,17 +220,16 @@ section `index.md` tables are the injection slots for the routing tables.
244
220
  `/draft:init refresh` under `okf` mode:
245
221
 
246
222
  ```
247
- 1. Re-derive the plan: okf-plan-concepts.sh (modules added since last run become
248
- REQUIRED — a new package can't slip through a refresh either)
249
- 2. Diff hashes.json vs working tree changed source paths
250
- 3. path-to-concept.json affected concept pages
251
- 4. Regenerate ONLY affected concepts; carry the rest verbatim (cached narration)
252
- 5. Re-render ai-context.md / architecture.md / log.md (cheap; always regenerated)
253
- 6. Re-validate (full gate): okf-validate-all.sh on the bundle with --plan and
254
- --path-index. Refresh re-runs structure + quality + coverage — a changed
255
- concept must still clear the quality bar, and a newly-required module must
256
- still be present.
257
- 7. Append log.md; update hashes.json + path-to-concept.json
223
+ 1. Re-derive the plan: okf-plan-concepts.sh (cargo/npm/go + graph). Modules added
224
+ since last run become REQUIRED — a new crate cannot slip through a refresh.
225
+ 2. Diff plan vs previous concept-plan.json NEW required concept_ids
226
+ 3. Diff hashes.json vs working tree changed source paths
227
+ 4. path-to-concept.json → affected concept pages
228
+ 5. okf-emit-catalog.sh for any NEW missing required pages (completeness floor)
229
+ 6. Regenerate/enrich changed + new concepts; carry the rest verbatim
230
+ 7. Re-render ai-context.md / architecture.md / log.md + okf-fix-links --fix
231
+ 8. Re-validate: okf-validate-all + okf-fix-links --check
232
+ 9. Append log.md; update hashes.json + path-to-concept.json + concept-plan.json
258
233
  ```
259
234
 
260
235
  A 1-file change regenerates only the concept(s) that file grounds. Unchanged
@@ -14,7 +14,7 @@ First resolve the bundled helpers:
14
14
  ```bash
15
15
  # Locate Draft's bundled helpers (cwd is the user's project; ${CLAUDE_PLUGIN_ROOT}
16
16
  # is not exported into skill Bash). See core/shared/tool-resolver.md.
17
- DRAFT_TOOLS="$(cat ~/.cache/draft/plugin-root 2>/dev/null)/scripts/tools"
17
+ DRAFT_TOOLS="${DRAFT_PLUGIN_ROOT:-$(cat ~/.cache/draft/plugin-root 2>/dev/null)}/scripts/tools"
18
18
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/cache/*/draft/*/scripts/tools 2>/dev/null | sort -V | tail -1)"
19
19
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/marketplaces/*draft*/scripts/tools 2>/dev/null | tail -1)"
20
20
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$PWD/scripts/tools"
@@ -15,7 +15,7 @@ First resolve the bundled helpers:
15
15
  ```bash
16
16
  # Locate Draft's bundled helpers (cwd is the user's project; ${CLAUDE_PLUGIN_ROOT}
17
17
  # is not exported into skill Bash). See core/shared/tool-resolver.md.
18
- DRAFT_TOOLS="$(cat ~/.cache/draft/plugin-root 2>/dev/null)/scripts/tools"
18
+ DRAFT_TOOLS="${DRAFT_PLUGIN_ROOT:-$(cat ~/.cache/draft/plugin-root 2>/dev/null)}/scripts/tools"
19
19
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/cache/*/draft/*/scripts/tools 2>/dev/null | sort -V | tail -1)"
20
20
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/marketplaces/*draft*/scripts/tools 2>/dev/null | tail -1)"
21
21
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$PWD/scripts/tools"
@@ -15,7 +15,7 @@ First resolve the bundled helpers:
15
15
  ```bash
16
16
  # Locate Draft's bundled helpers (cwd is the user's project; ${CLAUDE_PLUGIN_ROOT}
17
17
  # is not exported into skill Bash). See core/shared/tool-resolver.md.
18
- DRAFT_TOOLS="$(cat ~/.cache/draft/plugin-root 2>/dev/null)/scripts/tools"
18
+ DRAFT_TOOLS="${DRAFT_PLUGIN_ROOT:-$(cat ~/.cache/draft/plugin-root 2>/dev/null)}/scripts/tools"
19
19
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/cache/*/draft/*/scripts/tools 2>/dev/null | sort -V | tail -1)"
20
20
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/marketplaces/*draft*/scripts/tools 2>/dev/null | tail -1)"
21
21
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$PWD/scripts/tools"
@@ -384,7 +384,7 @@ For the files changed in the diff, perform static checks using `grep` or similar
384
384
  ```bash
385
385
  # Locate Draft's bundled helpers (cwd is the user's project; ${CLAUDE_PLUGIN_ROOT}
386
386
  # is not exported into skill Bash). See core/shared/tool-resolver.md.
387
- DRAFT_TOOLS="$(cat ~/.cache/draft/plugin-root 2>/dev/null)/scripts/tools"
387
+ DRAFT_TOOLS="${DRAFT_PLUGIN_ROOT:-$(cat ~/.cache/draft/plugin-root 2>/dev/null)}/scripts/tools"
388
388
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/cache/*/draft/*/scripts/tools 2>/dev/null | sort -V | tail -1)"
389
389
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/marketplaces/*draft*/scripts/tools 2>/dev/null | tail -1)"
390
390
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$PWD/scripts/tools"
@@ -1129,7 +1129,7 @@ As the last step after saving the review report, emit a metrics record. Best-eff
1129
1129
  ```bash
1130
1130
  # Locate Draft's bundled helpers (cwd is the user's project; ${CLAUDE_PLUGIN_ROOT}
1131
1131
  # is not exported into skill Bash). See core/shared/tool-resolver.md.
1132
- DRAFT_TOOLS="$(cat ~/.cache/draft/plugin-root 2>/dev/null)/scripts/tools"
1132
+ DRAFT_TOOLS="${DRAFT_PLUGIN_ROOT:-$(cat ~/.cache/draft/plugin-root 2>/dev/null)}/scripts/tools"
1133
1133
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/cache/*/draft/*/scripts/tools 2>/dev/null | sort -V | tail -1)"
1134
1134
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/marketplaces/*draft*/scripts/tools 2>/dev/null | tail -1)"
1135
1135
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$PWD/scripts/tools"
@@ -54,7 +54,7 @@ Check for arguments:
54
54
  **Preferred:** invoke `parse-git-log.sh` — it parses conventional commits into structured JSONL `{sha,type,scope,track_id,subject,author,timestamp,files_changed}`, eliminating ambiguity in `type(track-id): subject` parsing. Resolve via the canonical tool resolver (see [core/shared/tool-resolver.md](../../core/shared/tool-resolver.md)):
55
55
 
56
56
  ```bash
57
- DRAFT_TOOLS="$(cat ~/.cache/draft/plugin-root 2>/dev/null)/scripts/tools"
57
+ DRAFT_TOOLS="${DRAFT_PLUGIN_ROOT:-$(cat ~/.cache/draft/plugin-root 2>/dev/null)}/scripts/tools"
58
58
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/cache/*/draft/*/scripts/tools 2>/dev/null | sort -V | tail -1)"
59
59
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/marketplaces/*draft*/scripts/tools 2>/dev/null | tail -1)"
60
60
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$PWD/scripts/tools"
@@ -44,7 +44,7 @@ Display a comprehensive overview of project progress.
44
44
  If `parse-reports.sh` and `freshness-check.sh` are available, gather structured signals to enrich the status output (severity counts per track, stale `draft/` docs). Resolve via the canonical tool resolver (see [core/shared/tool-resolver.md](../../core/shared/tool-resolver.md)):
45
45
 
46
46
  ```bash
47
- DRAFT_TOOLS="$(cat ~/.cache/draft/plugin-root 2>/dev/null)/scripts/tools"
47
+ DRAFT_TOOLS="${DRAFT_PLUGIN_ROOT:-$(cat ~/.cache/draft/plugin-root 2>/dev/null)}/scripts/tools"
48
48
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/cache/*/draft/*/scripts/tools 2>/dev/null | sort -V | tail -1)"
49
49
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/marketplaces/*draft*/scripts/tools 2>/dev/null | tail -1)"
50
50
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$PWD/scripts/tools"
@@ -14,7 +14,7 @@ First resolve the bundled helpers:
14
14
  ```bash
15
15
  # Locate Draft's bundled helpers (cwd is the user's project; ${CLAUDE_PLUGIN_ROOT}
16
16
  # is not exported into skill Bash). See core/shared/tool-resolver.md.
17
- DRAFT_TOOLS="$(cat ~/.cache/draft/plugin-root 2>/dev/null)/scripts/tools"
17
+ DRAFT_TOOLS="${DRAFT_PLUGIN_ROOT:-$(cat ~/.cache/draft/plugin-root 2>/dev/null)}/scripts/tools"
18
18
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/cache/*/draft/*/scripts/tools 2>/dev/null | sort -V | tail -1)"
19
19
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/marketplaces/*draft*/scripts/tools 2>/dev/null | tail -1)"
20
20
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$PWD/scripts/tools"
@@ -95,7 +95,7 @@ For TODO/FIXME/HACK/XXX/DEPRECATED markers, prefer the deterministic `scan-marke
95
95
  ```bash
96
96
  # Locate Draft's bundled helpers (cwd is the user's project; ${CLAUDE_PLUGIN_ROOT}
97
97
  # is not exported into skill Bash). See core/shared/tool-resolver.md.
98
- DRAFT_TOOLS="$(cat ~/.cache/draft/plugin-root 2>/dev/null)/scripts/tools"
98
+ DRAFT_TOOLS="${DRAFT_PLUGIN_ROOT:-$(cat ~/.cache/draft/plugin-root 2>/dev/null)}/scripts/tools"
99
99
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/cache/*/draft/*/scripts/tools 2>/dev/null | sort -V | tail -1)"
100
100
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/marketplaces/*draft*/scripts/tools 2>/dev/null | tail -1)"
101
101
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$PWD/scripts/tools"
@@ -52,7 +52,7 @@ Run the WS-9 chain from [verification-gates.md](../../core/shared/verification-g
52
52
 
53
53
  ```bash
54
54
  TRACK_DIR="draft/tracks/<id>"
55
- DRAFT_TOOLS="$(cat ~/.cache/draft/plugin-root 2>/dev/null)/scripts/tools"
55
+ DRAFT_TOOLS="${DRAFT_PLUGIN_ROOT:-$(cat ~/.cache/draft/plugin-root 2>/dev/null)}/scripts/tools"
56
56
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/cache/*/draft/*/scripts/tools 2>/dev/null | sort -V | tail -1)"
57
57
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/marketplaces/*draft*/scripts/tools 2>/dev/null | tail -1)"
58
58
  [ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$PWD/scripts/tools"