@drafthq/draft 2.8.1 → 3.0.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.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +9 -3
- package/bin/README.md +13 -0
- package/cli/src/installer.js +11 -2
- package/core/methodology.md +17 -18
- package/core/shared/condensation.md +1 -1
- package/core/shared/draft-context-loading.md +4 -2
- package/core/shared/graph-query.md +4 -3
- package/core/templates/ai-context.md +1 -0
- package/core/templates/ai-profile.md +1 -0
- package/core/templates/architecture.md +1 -0
- package/core/templates/dependency-graph.md +2 -2
- package/core/templates/discovery.md +1 -0
- package/core/templates/guardrails.md +1 -0
- package/core/templates/hld.md +1 -0
- package/core/templates/lld.md +1 -0
- package/core/templates/plan.md +1 -0
- package/core/templates/product.md +1 -0
- package/core/templates/rca.md +1 -0
- package/core/templates/root-architecture.md +3 -3
- package/core/templates/root-product.md +2 -2
- package/core/templates/root-tech-stack.md +2 -2
- package/core/templates/service-index.md +3 -3
- package/core/templates/spec.md +1 -0
- package/core/templates/tech-matrix.md +2 -2
- package/core/templates/tech-stack.md +1 -0
- package/core/templates/workflow.md +1 -0
- package/integrations/agents/AGENTS.md +134 -918
- package/integrations/copilot/.github/copilot-instructions.md +134 -918
- package/integrations/copilot/.github/copilot-instructions.md.7iDz8X +91 -0
- package/integrations/copilot/.github/copilot-instructions.md.DoBdtd +91 -0
- package/integrations/copilot/.github/copilot-instructions.md.McGoBW +122 -0
- package/integrations/copilot/.github/copilot-instructions.md.VsPyLB +91 -0
- package/integrations/copilot/.github/copilot-instructions.md.XAVr7D +91 -0
- package/integrations/copilot/.github/copilot-instructions.md.YoFVFa +91 -0
- package/integrations/copilot/.github/copilot-instructions.md.a9DeW0 +91 -0
- package/integrations/copilot/.github/copilot-instructions.md.oxQs3B +91 -0
- package/integrations/copilot/.github/copilot-instructions.md.ww33Ly +91 -0
- package/package.json +1 -1
- package/scripts/lib.sh +4 -1
- package/scripts/tools/graph-init.sh +187 -0
- package/scripts/tools/graph-snapshot.sh +6 -1
- package/scripts/tools/okf-bundle.sh +141 -0
- package/scripts/tools/okf-check.sh +137 -0
- package/scripts/tools/okf-emit.sh +161 -0
- package/scripts/tools/skill-caps.conf +0 -1
- package/skills/GRAPH.md +7 -10
- package/skills/bughunt/SKILL.md +13 -0
- package/skills/discover/SKILL.md +2 -4
- package/skills/draft/SKILL.md +2 -2
- package/skills/draft/intent-mapping.md +3 -2
- package/skills/graph/SKILL.md +3 -3
- package/skills/init/SKILL.md +58 -19
- package/skills/init/references/architecture-spec.md +5 -5
- package/skills/index/SKILL.md +0 -848
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Draft - Context-Driven Development
|
|
2
|
+
|
|
3
|
+
You are operating with the Draft methodology for Context-Driven Development.
|
|
4
|
+
|
|
5
|
+
**Measure twice, code once.**
|
|
6
|
+
|
|
7
|
+
## Core Workflow
|
|
8
|
+
|
|
9
|
+
**Context -> Spec & Plan -> Implement**
|
|
10
|
+
|
|
11
|
+
Every feature follows this lifecycle:
|
|
12
|
+
1. **Setup** - Initialize project context (once per project)
|
|
13
|
+
2. **New Track** - Create specification and plan
|
|
14
|
+
3. **Implement** - Execute tasks with TDD workflow
|
|
15
|
+
4. **Verify** - Confirm acceptance criteria met
|
|
16
|
+
|
|
17
|
+
## Project Context Files
|
|
18
|
+
|
|
19
|
+
When `draft/` exists in the project, always consider:
|
|
20
|
+
- `draft/.ai-context.md` - Source of truth for AI agents (dense codebase understanding)
|
|
21
|
+
- `draft/architecture.md` - Human-readable engineering guide (derived from .ai-context.md)
|
|
22
|
+
- `draft/product.md` - Product vision and goals
|
|
23
|
+
- `draft/tech-stack.md` - Technical constraints
|
|
24
|
+
- `draft/workflow.md` - TDD and commit preferences
|
|
25
|
+
- `draft/tracks.md` - Active work items
|
|
26
|
+
|
|
27
|
+
## Available Commands
|
|
28
|
+
|
|
29
|
+
| Command | Purpose |
|
|
30
|
+
|---------|---------|
|
|
31
|
+
| `draft` | Show overview and available commands |
|
|
32
|
+
| `draft init` | Initialize project (run once) |
|
|
33
|
+
| `draft index [--init-missing]` | Aggregate monorepo service contexts |
|
|
34
|
+
| `draft new-track <description>` | Create feature/bug track |
|
|
35
|
+
| `draft decompose` | Module decomposition with dependency mapping |
|
|
36
|
+
| `draft implement` | Execute tasks from plan |
|
|
37
|
+
| `draft coverage` | Code coverage report (target 95%+) |
|
|
38
|
+
| `draft bughunt [--track <id>]` | Systematic bug discovery |
|
|
39
|
+
| `draft review [--track <id>]` | Three-stage code review |
|
|
40
|
+
| `draft deep-review [module]` | Exhaustive production-grade module audit |
|
|
41
|
+
| `draft learn [promote\|migrate]` | Discover coding patterns, update guardrails |
|
|
42
|
+
| `draft adr [title]` | Architecture Decision Records |
|
|
43
|
+
| `draft status` | Show progress overview |
|
|
44
|
+
| `draft revert` | Git-aware rollback |
|
|
45
|
+
| `draft change <description>` | Handle mid-track requirement changes |
|
|
46
|
+
| `draft jira-preview [track-id]` | Generate jira-export.md for review |
|
|
47
|
+
| `draft jira-create [track-id]` | Create Jira issues from export via MCP |
|
|
48
|
+
|
|
49
|
+
## Intent Mapping
|
|
50
|
+
|
|
51
|
+
Recognize these natural language patterns:
|
|
52
|
+
|
|
53
|
+
| User Says | Action |
|
|
54
|
+
|-----------|--------|
|
|
55
|
+
| "set up the project" | Run init |
|
|
56
|
+
| "index services", "aggregate context" | Run index |
|
|
57
|
+
| "new feature", "add X" | Create new track |
|
|
58
|
+
| "break into modules", "decompose" | Run decompose |
|
|
59
|
+
| "start implementing" | Execute implement |
|
|
60
|
+
| "check coverage", "test coverage" | Run coverage |
|
|
61
|
+
| "hunt bugs", "find bugs" | Run bug hunt |
|
|
62
|
+
| "review code", "review track", "check quality" | Run review |
|
|
63
|
+
| "deep review", "production audit", "module audit" | Run deep-review |
|
|
64
|
+
| "learn patterns", "update guardrails", "discover conventions" | Run learn |
|
|
65
|
+
| "what's the status" | Show status |
|
|
66
|
+
| "undo", "revert" | Run revert |
|
|
67
|
+
| "requirements changed", "scope changed", "update the spec" | Run change |
|
|
68
|
+
| "preview jira", "export to jira" | Run jira-preview |
|
|
69
|
+
| "create jira", "push to jira" | Run jira-create |
|
|
70
|
+
| "document decision", "create ADR" | Create architecture decision record |
|
|
71
|
+
| "help", "what commands" | Show draft overview |
|
|
72
|
+
| "the plan" | Read active track's plan.md |
|
|
73
|
+
| "the spec" | Read active track's spec.md |
|
|
74
|
+
|
|
75
|
+
## Tracks
|
|
76
|
+
|
|
77
|
+
A **track** is a high-level unit of work (feature, bug fix, refactor). Each track contains:
|
|
78
|
+
- `spec.md` - Requirements and acceptance criteria
|
|
79
|
+
- `plan.md` - Phased task breakdown
|
|
80
|
+
- `metadata.json` - Status and timestamps
|
|
81
|
+
|
|
82
|
+
Located at: `draft/tracks/<track-id>/`
|
|
83
|
+
|
|
84
|
+
## Status Markers
|
|
85
|
+
|
|
86
|
+
Recognize and use these throughout plan.md:
|
|
87
|
+
- `[ ]` - Pending
|
|
88
|
+
- `[~]` - In Progress
|
|
89
|
+
- `[x]` - Completed
|
|
90
|
+
- `[!]` - Blocked
|
|
91
|
+
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Draft - Context-Driven Development
|
|
2
|
+
|
|
3
|
+
You are operating with the Draft methodology for Context-Driven Development.
|
|
4
|
+
|
|
5
|
+
**Measure twice, code once.**
|
|
6
|
+
|
|
7
|
+
## Core Workflow
|
|
8
|
+
|
|
9
|
+
**Context -> Spec & Plan -> Implement**
|
|
10
|
+
|
|
11
|
+
Every feature follows this lifecycle:
|
|
12
|
+
1. **Setup** - Initialize project context (once per project)
|
|
13
|
+
2. **New Track** - Create specification and plan
|
|
14
|
+
3. **Implement** - Execute tasks with TDD workflow
|
|
15
|
+
4. **Verify** - Confirm acceptance criteria met
|
|
16
|
+
|
|
17
|
+
## Project Context Files
|
|
18
|
+
|
|
19
|
+
When `draft/` exists in the project, always consider:
|
|
20
|
+
- `draft/.ai-context.md` - Source of truth for AI agents (dense codebase understanding)
|
|
21
|
+
- `draft/architecture.md` - Human-readable engineering guide (derived from .ai-context.md)
|
|
22
|
+
- `draft/product.md` - Product vision and goals
|
|
23
|
+
- `draft/tech-stack.md` - Technical constraints
|
|
24
|
+
- `draft/workflow.md` - TDD and commit preferences
|
|
25
|
+
- `draft/tracks.md` - Active work items
|
|
26
|
+
|
|
27
|
+
## Available Commands
|
|
28
|
+
|
|
29
|
+
| Command | Purpose |
|
|
30
|
+
|---------|---------|
|
|
31
|
+
| `draft` | Show overview and available commands |
|
|
32
|
+
| `draft init` | Initialize project (run once) |
|
|
33
|
+
| `draft index [--init-missing]` | Aggregate monorepo service contexts |
|
|
34
|
+
| `draft new-track <description>` | Create feature/bug track |
|
|
35
|
+
| `draft decompose` | Module decomposition with dependency mapping |
|
|
36
|
+
| `draft implement` | Execute tasks from plan |
|
|
37
|
+
| `draft coverage` | Code coverage report (target 95%+) |
|
|
38
|
+
| `draft bughunt [--track <id>]` | Systematic bug discovery |
|
|
39
|
+
| `draft review [--track <id>]` | Three-stage code review |
|
|
40
|
+
| `draft deep-review [module]` | Exhaustive production-grade module audit |
|
|
41
|
+
| `draft learn [promote\|migrate]` | Discover coding patterns, update guardrails |
|
|
42
|
+
| `draft adr [title]` | Architecture Decision Records |
|
|
43
|
+
| `draft status` | Show progress overview |
|
|
44
|
+
| `draft revert` | Git-aware rollback |
|
|
45
|
+
| `draft change <description>` | Handle mid-track requirement changes |
|
|
46
|
+
| `draft jira-preview [track-id]` | Generate jira-export.md for review |
|
|
47
|
+
| `draft jira-create [track-id]` | Create Jira issues from export via MCP |
|
|
48
|
+
|
|
49
|
+
## Intent Mapping
|
|
50
|
+
|
|
51
|
+
Recognize these natural language patterns:
|
|
52
|
+
|
|
53
|
+
| User Says | Action |
|
|
54
|
+
|-----------|--------|
|
|
55
|
+
| "set up the project" | Run init |
|
|
56
|
+
| "index services", "aggregate context" | Run index |
|
|
57
|
+
| "new feature", "add X" | Create new track |
|
|
58
|
+
| "break into modules", "decompose" | Run decompose |
|
|
59
|
+
| "start implementing" | Execute implement |
|
|
60
|
+
| "check coverage", "test coverage" | Run coverage |
|
|
61
|
+
| "hunt bugs", "find bugs" | Run bug hunt |
|
|
62
|
+
| "review code", "review track", "check quality" | Run review |
|
|
63
|
+
| "deep review", "production audit", "module audit" | Run deep-review |
|
|
64
|
+
| "learn patterns", "update guardrails", "discover conventions" | Run learn |
|
|
65
|
+
| "what's the status" | Show status |
|
|
66
|
+
| "undo", "revert" | Run revert |
|
|
67
|
+
| "requirements changed", "scope changed", "update the spec" | Run change |
|
|
68
|
+
| "preview jira", "export to jira" | Run jira-preview |
|
|
69
|
+
| "create jira", "push to jira" | Run jira-create |
|
|
70
|
+
| "document decision", "create ADR" | Create architecture decision record |
|
|
71
|
+
| "help", "what commands" | Show draft overview |
|
|
72
|
+
| "the plan" | Read active track's plan.md |
|
|
73
|
+
| "the spec" | Read active track's spec.md |
|
|
74
|
+
|
|
75
|
+
## Tracks
|
|
76
|
+
|
|
77
|
+
A **track** is a high-level unit of work (feature, bug fix, refactor). Each track contains:
|
|
78
|
+
- `spec.md` - Requirements and acceptance criteria
|
|
79
|
+
- `plan.md` - Phased task breakdown
|
|
80
|
+
- `metadata.json` - Status and timestamps
|
|
81
|
+
|
|
82
|
+
Located at: `draft/tracks/<track-id>/`
|
|
83
|
+
|
|
84
|
+
## Status Markers
|
|
85
|
+
|
|
86
|
+
Recognize and use these throughout plan.md:
|
|
87
|
+
- `[ ]` - Pending
|
|
88
|
+
- `[~]` - In Progress
|
|
89
|
+
- `[x]` - Completed
|
|
90
|
+
- `[!]` - Blocked
|
|
91
|
+
|
package/package.json
CHANGED
package/scripts/lib.sh
CHANGED
|
@@ -24,7 +24,6 @@ TOOLS_DIR="$ROOT_DIR/scripts/tools"
|
|
|
24
24
|
SKILL_ORDER=(
|
|
25
25
|
draft
|
|
26
26
|
init
|
|
27
|
-
index
|
|
28
27
|
graph
|
|
29
28
|
new-track
|
|
30
29
|
decompose
|
|
@@ -158,6 +157,10 @@ TOOLS=(
|
|
|
158
157
|
"manage-symlinks.sh"
|
|
159
158
|
"mermaid-from-graph.sh"
|
|
160
159
|
"graph-snapshot.sh"
|
|
160
|
+
"graph-init.sh"
|
|
161
|
+
"okf-emit.sh"
|
|
162
|
+
"okf-bundle.sh"
|
|
163
|
+
"okf-check.sh"
|
|
161
164
|
"graph-impact.sh"
|
|
162
165
|
"graph-callers.sh"
|
|
163
166
|
"validate-frontmatter.sh"
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# graph-init.sh — scope-aware, root-first knowledge-graph builder for /draft:init.
|
|
3
|
+
#
|
|
4
|
+
# Ensures the whole-repo "code graph knowledge memory" exists at the repository
|
|
5
|
+
# ROOT (the spine — the single structural source of truth), then builds a
|
|
6
|
+
# scope-local snapshot and links a sub-module's graph up to the root.
|
|
7
|
+
#
|
|
8
|
+
# Model:
|
|
9
|
+
# - ROOT resolution: nearest ancestor ABOVE scope containing draft/ (bounded by
|
|
10
|
+
# the git toplevel) → git toplevel → scope itself (no git / module-local).
|
|
11
|
+
# - The engine is the default capability tier. If the codebase-memory-mcp binary
|
|
12
|
+
# is missing it is fetched (blocking) unless --no-fetch or DRAFT_MEMORY_DISABLE.
|
|
13
|
+
# - Root init (scope == root): build the whole-repo snapshot at <root>/draft/graph/.
|
|
14
|
+
# - Module init (scope != root): unless --module-only, (re)build the root snapshot
|
|
15
|
+
# first (the spine — index time is accepted, incremental once warm), then build
|
|
16
|
+
# <scope>/draft/graph/ and write root-link.json pointing up to the root snapshot.
|
|
17
|
+
#
|
|
18
|
+
# The committed snapshot (draft/graph/) is the git-tracked memory; the engine's
|
|
19
|
+
# ~/.cache index is a disposable accelerator and is never committed.
|
|
20
|
+
#
|
|
21
|
+
# Usage: scripts/tools/graph-init.sh [--scope DIR] [--module-only] [--no-fetch] [--json]
|
|
22
|
+
# Exit codes: 0 OK, 1 invocation error, 2 graph engine unavailable.
|
|
23
|
+
set -euo pipefail
|
|
24
|
+
|
|
25
|
+
TOOLS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
26
|
+
# shellcheck source=_lib.sh
|
|
27
|
+
source "$TOOLS_DIR/_lib.sh"
|
|
28
|
+
|
|
29
|
+
SCOPE="."
|
|
30
|
+
MODULE_ONLY=0
|
|
31
|
+
NO_FETCH=0
|
|
32
|
+
EMIT_JSON=0
|
|
33
|
+
|
|
34
|
+
usage() {
|
|
35
|
+
cat <<'EOF'
|
|
36
|
+
graph-init.sh — scope-aware, root-first knowledge-graph builder.
|
|
37
|
+
|
|
38
|
+
Usage:
|
|
39
|
+
scripts/tools/graph-init.sh [--scope DIR] [--module-only] [--no-fetch] [--json]
|
|
40
|
+
|
|
41
|
+
Flags:
|
|
42
|
+
--scope DIR Directory init was invoked in (default: cwd).
|
|
43
|
+
--module-only Do not touch the root; build only the module snapshot and mark
|
|
44
|
+
its root link "pending".
|
|
45
|
+
--no-fetch Never download the engine; degrade if it is absent (CI/tests).
|
|
46
|
+
--json Emit a machine-readable summary instead of a human report.
|
|
47
|
+
--help Show this help.
|
|
48
|
+
|
|
49
|
+
Exit 0 on success, 2 when the graph engine is unavailable (no snapshot built).
|
|
50
|
+
EOF
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
while [[ $# -gt 0 ]]; do
|
|
54
|
+
case "$1" in
|
|
55
|
+
--scope) SCOPE="$2"; shift 2;;
|
|
56
|
+
--module-only) MODULE_ONLY=1; shift;;
|
|
57
|
+
--no-fetch) NO_FETCH=1; shift;;
|
|
58
|
+
--json) EMIT_JSON=1; shift;;
|
|
59
|
+
--help|-h) usage; exit 0;;
|
|
60
|
+
*) echo "Unknown flag: $1" >&2; usage >&2; exit 1;;
|
|
61
|
+
esac
|
|
62
|
+
done
|
|
63
|
+
|
|
64
|
+
[[ -d "$SCOPE" ]] || { echo "ERROR: --scope '$SCOPE' is not a directory" >&2; exit 1; }
|
|
65
|
+
SCOPE_ABS="$(cd "$SCOPE" && pwd)"
|
|
66
|
+
SELF_REPO="$(cd "$TOOLS_DIR/../.." && pwd)"
|
|
67
|
+
|
|
68
|
+
# --- Resolve ROOT (bounded by the git toplevel; never escapes the repo) ---
|
|
69
|
+
GIT_TOP="$(git -C "$SCOPE_ABS" rev-parse --show-toplevel 2>/dev/null || true)"
|
|
70
|
+
resolve_root() {
|
|
71
|
+
if [[ -z "$GIT_TOP" ]]; then printf '%s' "$SCOPE_ABS"; return; fi # no git → module-local
|
|
72
|
+
local d="$SCOPE_ABS"
|
|
73
|
+
while [[ "$d" != "$GIT_TOP" && "$d" != "/" ]]; do
|
|
74
|
+
d="$(dirname "$d")"
|
|
75
|
+
if [[ "$d" != "$SCOPE_ABS" && -d "$d/draft" ]]; then printf '%s' "$d"; return; fi
|
|
76
|
+
done
|
|
77
|
+
printf '%s' "$GIT_TOP"
|
|
78
|
+
}
|
|
79
|
+
ROOT_ABS="$(resolve_root)"
|
|
80
|
+
IS_ROOT=0
|
|
81
|
+
[[ "$SCOPE_ABS" == "$ROOT_ABS" ]] && IS_ROOT=1
|
|
82
|
+
|
|
83
|
+
# --- Ensure the engine (the default tier); fetch when missing unless told not to ---
|
|
84
|
+
ensure_engine() {
|
|
85
|
+
[[ -z "${DRAFT_MEMORY_DISABLE:-}" ]] || return 1
|
|
86
|
+
find_memory_bin "$SCOPE_ABS" "$SELF_REPO" && return 0
|
|
87
|
+
[[ "$NO_FETCH" -eq 0 ]] || return 1
|
|
88
|
+
echo "Graph engine not found — fetching it (one-time download; this may take a while)..." >&2
|
|
89
|
+
"$SELF_REPO/scripts/fetch-memory-engine.sh" >&2 2>&1 || true
|
|
90
|
+
find_memory_bin "$SCOPE_ABS" "$SELF_REPO"
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
engine_unavailable() {
|
|
94
|
+
if [[ "$EMIT_JSON" -eq 1 ]]; then
|
|
95
|
+
printf '{"status":"unavailable","root":"%s","scope":"%s","is_root":%s}\n' \
|
|
96
|
+
"$ROOT_ABS" "$SCOPE_ABS" "$IS_ROOT"
|
|
97
|
+
else
|
|
98
|
+
echo "WARNING: knowledge-graph engine (codebase-memory-mcp) is unavailable — no graph built." >&2
|
|
99
|
+
echo " The engine is Draft's default capability tier. Install it with:" >&2
|
|
100
|
+
echo " scripts/fetch-memory-engine.sh" >&2
|
|
101
|
+
echo " or put codebase-memory-mcp on PATH. Set DRAFT_MEMORY_DISABLE=1 to silence this." >&2
|
|
102
|
+
echo " Committed draft/graph/ snapshots (if present) still provide structural context." >&2
|
|
103
|
+
fi
|
|
104
|
+
exit 2
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
# Build a committed snapshot for a repo dir; returns graph-snapshot's exit code.
|
|
108
|
+
# Snapshot progress goes to stderr so stdout stays clean for --json consumers.
|
|
109
|
+
build_snapshot() {
|
|
110
|
+
local rc=0
|
|
111
|
+
"$TOOLS_DIR/graph-snapshot.sh" --repo "$1" 1>&2 || rc=$?
|
|
112
|
+
return "$rc"
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
# Path from <module>/draft/graph back to <root>/draft/graph (module is under root).
|
|
116
|
+
root_link_relpath() {
|
|
117
|
+
local sub="${SCOPE_ABS#"$ROOT_ABS"/}"
|
|
118
|
+
local ups=2 seg
|
|
119
|
+
IFS='/' read -ra seg <<< "$sub"
|
|
120
|
+
ups=$(( ${#seg[@]} + 2 ))
|
|
121
|
+
local i out=""
|
|
122
|
+
for ((i = 0; i < ups; i++)); do out+="../"; done
|
|
123
|
+
printf '%sdraft/graph' "$out"
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
write_root_link() {
|
|
127
|
+
local status="$1"
|
|
128
|
+
local mod_graph="$SCOPE_ABS/draft/graph"
|
|
129
|
+
mkdir -p "$mod_graph"
|
|
130
|
+
local rel root_project="unknown" root_commit ts schema="$ROOT_ABS/draft/graph/schema.yaml"
|
|
131
|
+
rel="$(root_link_relpath)"
|
|
132
|
+
if [[ -f "$schema" ]]; then
|
|
133
|
+
root_project="$(grep -m1 '^project:' "$schema" 2>/dev/null | sed 's/^project:[[:space:]]*//; s/^"//; s/"$//' || true)"
|
|
134
|
+
[[ -n "$root_project" ]] || root_project="unknown"
|
|
135
|
+
fi
|
|
136
|
+
root_commit="$(git -C "$ROOT_ABS" rev-parse --verify --quiet HEAD 2>/dev/null || echo none)"
|
|
137
|
+
ts="$(date -Iseconds 2>/dev/null || date)"
|
|
138
|
+
cat > "$mod_graph/root-link.json" <<EOF
|
|
139
|
+
{
|
|
140
|
+
"root_graph": "$rel",
|
|
141
|
+
"root_abs": "$ROOT_ABS/draft/graph",
|
|
142
|
+
"root_project": "${root_project:-unknown}",
|
|
143
|
+
"root_commit": "$root_commit",
|
|
144
|
+
"status": "$status",
|
|
145
|
+
"linked_at": "$ts",
|
|
146
|
+
"linked_by": "graph-init.sh",
|
|
147
|
+
"note": "Root is the authoritative whole-repo graph. Follow root_graph for cross-module understanding."
|
|
148
|
+
}
|
|
149
|
+
EOF
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
ensure_engine || engine_unavailable
|
|
153
|
+
|
|
154
|
+
ROOT_BUILT=0
|
|
155
|
+
MODULE_BUILT=0
|
|
156
|
+
LINK_STATUS="none"
|
|
157
|
+
|
|
158
|
+
if [[ "$IS_ROOT" -eq 1 ]]; then
|
|
159
|
+
build_snapshot "$ROOT_ABS" && ROOT_BUILT=1
|
|
160
|
+
else
|
|
161
|
+
if [[ "$MODULE_ONLY" -eq 0 ]]; then
|
|
162
|
+
echo "Sub-module of $ROOT_ABS — ensuring the root code-graph spine first..." >&2
|
|
163
|
+
build_snapshot "$ROOT_ABS" && ROOT_BUILT=1
|
|
164
|
+
fi
|
|
165
|
+
build_snapshot "$SCOPE_ABS" && MODULE_BUILT=1
|
|
166
|
+
if [[ -f "$ROOT_ABS/draft/graph/schema.yaml" ]]; then
|
|
167
|
+
LINK_STATUS="linked"
|
|
168
|
+
else
|
|
169
|
+
LINK_STATUS="pending"
|
|
170
|
+
fi
|
|
171
|
+
write_root_link "$LINK_STATUS"
|
|
172
|
+
fi
|
|
173
|
+
|
|
174
|
+
if [[ "$EMIT_JSON" -eq 1 ]]; then
|
|
175
|
+
printf '{"status":"ok","root":"%s","scope":"%s","is_root":%s,"root_built":%s,"module_built":%s,"link_status":"%s"}\n' \
|
|
176
|
+
"$ROOT_ABS" "$SCOPE_ABS" "$IS_ROOT" "$ROOT_BUILT" "$MODULE_BUILT" "$LINK_STATUS"
|
|
177
|
+
else
|
|
178
|
+
echo "--- graph-init ---"
|
|
179
|
+
echo "Root: $ROOT_ABS$([[ $IS_ROOT -eq 1 ]] && echo ' (this scope is the root)')"
|
|
180
|
+
[[ "$IS_ROOT" -eq 1 ]] && echo "Built whole-repo spine: $ROOT_ABS/draft/graph/"
|
|
181
|
+
if [[ "$IS_ROOT" -eq 0 ]]; then
|
|
182
|
+
[[ "$ROOT_BUILT" -eq 1 ]] && echo "Root spine: refreshed $ROOT_ABS/draft/graph/"
|
|
183
|
+
echo "Module: $SCOPE_ABS/draft/graph/"
|
|
184
|
+
echo "Root link: $LINK_STATUS ($SCOPE_ABS/draft/graph/root-link.json)"
|
|
185
|
+
fi
|
|
186
|
+
fi
|
|
187
|
+
exit 0
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
# hotspots.jsonl fan-in-ranked symbols, one JSON object per line
|
|
14
14
|
# module-deps.mermaid co-change coupling diagram
|
|
15
15
|
# proto-map.mermaid detected-route diagram
|
|
16
|
+
# okf/ Open Knowledge Format bundle (portable markdown mirror)
|
|
16
17
|
#
|
|
17
18
|
# Usage: scripts/tools/graph-snapshot.sh [--repo DIR] [--out DIR]
|
|
18
19
|
# Exit codes: 0 OK, 1 invocation error, 2 graph engine unavailable.
|
|
@@ -76,7 +77,10 @@ echo "$ARCH" | jq '.' > "$OUT/architecture.json"
|
|
|
76
77
|
"$TOOLS_DIR/mermaid-from-graph.sh" --repo "$REPO_ABS" --diagram module-deps > "$OUT/module-deps.mermaid" 2>/dev/null || true
|
|
77
78
|
"$TOOLS_DIR/mermaid-from-graph.sh" --repo "$REPO_ABS" --diagram proto-map > "$OUT/proto-map.mermaid" 2>/dev/null || true
|
|
78
79
|
|
|
79
|
-
# 4.
|
|
80
|
+
# 4. OKF bundle (best-effort) — portable Open Knowledge Format mirror of the graph.
|
|
81
|
+
"$TOOLS_DIR/okf-emit.sh" --repo "$REPO_ABS" --snapshot "$OUT" --out "$OUT/okf" >/dev/null 2>&1 || true
|
|
82
|
+
|
|
83
|
+
# 5. schema.yaml — metadata + gate for skill graph use
|
|
80
84
|
NODES="$(echo "$ARCH" | jq -r '.total_nodes // 0')"
|
|
81
85
|
EDGES="$(echo "$ARCH" | jq -r '.total_edges // 0')"
|
|
82
86
|
HOTN="$(wc -l < "$OUT/hotspots.jsonl" | tr -d ' ')"
|
|
@@ -96,6 +100,7 @@ artifacts:
|
|
|
96
100
|
- hotspots.jsonl
|
|
97
101
|
- module-deps.mermaid
|
|
98
102
|
- proto-map.mermaid
|
|
103
|
+
- okf/
|
|
99
104
|
EOF
|
|
100
105
|
|
|
101
106
|
echo "Snapshot written to $OUT (nodes=$NODES edges=$EDGES hotspots=$HOTN)"
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# okf-bundle.sh — make a draft/ context directory an Open Knowledge Format bundle.
|
|
3
|
+
#
|
|
4
|
+
# OKF (Google Cloud, open spec) treats a directory of markdown files with YAML
|
|
5
|
+
# frontmatter as a knowledge bundle: one file per concept, the file path is the
|
|
6
|
+
# concept's identity, concepts cross-link with markdown links, and index.md is
|
|
7
|
+
# the navigable root. Draft's project-doc files already carry the required
|
|
8
|
+
# `type` frontmatter (architecture.md, .ai-context.md, product.md, ...); this
|
|
9
|
+
# tool writes the bundle's root index.md so the whole draft/ tree is a portable,
|
|
10
|
+
# vendor-neutral OKF bundle.
|
|
11
|
+
# https://cloud.google.com/blog/products/data-analytics/how-the-open-knowledge-format-can-improve-data-sharing
|
|
12
|
+
#
|
|
13
|
+
# Writes <dir>/index.md (the OKF bundle-root index, §6/§11) linking every concept
|
|
14
|
+
# file present, the tracks, and the graph sub-bundle (graph/okf/). Validate the
|
|
15
|
+
# result with okf-check.sh (the OKF v0.1 conformance checker).
|
|
16
|
+
#
|
|
17
|
+
# Usage: scripts/tools/okf-bundle.sh [--dir DIR]
|
|
18
|
+
# Exit codes: 0 OK, 1 invocation error, 2 dir missing.
|
|
19
|
+
set -euo pipefail
|
|
20
|
+
|
|
21
|
+
DIR="draft"
|
|
22
|
+
|
|
23
|
+
usage() {
|
|
24
|
+
cat <<'EOF'
|
|
25
|
+
okf-bundle.sh — write the OKF bundle-root index.md for a draft/ context bundle.
|
|
26
|
+
|
|
27
|
+
Usage:
|
|
28
|
+
scripts/tools/okf-bundle.sh [--dir DIR]
|
|
29
|
+
|
|
30
|
+
Flags:
|
|
31
|
+
--dir DIR Bundle root (default: draft).
|
|
32
|
+
--help Show this help.
|
|
33
|
+
|
|
34
|
+
Writes <dir>/index.md cross-linking every concept present, the tracks, and the
|
|
35
|
+
graph sub-bundle. Validate conformance with `okf-check.sh --dir <dir>`.
|
|
36
|
+
Exit 0 OK, 1 invocation error, 2 when <dir> is absent.
|
|
37
|
+
EOF
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
while [[ $# -gt 0 ]]; do
|
|
41
|
+
case "$1" in
|
|
42
|
+
--dir) DIR="$2"; shift 2;;
|
|
43
|
+
--help|-h) usage; exit 0;;
|
|
44
|
+
-*) echo "Unknown flag: $1" >&2; usage >&2; exit 1;;
|
|
45
|
+
*) echo "Unexpected arg: $1" >&2; usage >&2; exit 1;;
|
|
46
|
+
esac
|
|
47
|
+
done
|
|
48
|
+
|
|
49
|
+
[[ -d "$DIR" ]] || { echo "ERROR: --dir '$DIR' is not a directory" >&2; exit 2; }
|
|
50
|
+
|
|
51
|
+
# Canonical Draft concepts, ordered: "filename|label|expected-type".
|
|
52
|
+
# Each present file is linked from index.md and checked for `type:` under --check.
|
|
53
|
+
CONCEPTS=(
|
|
54
|
+
".ai-profile.md|AI Profile|Profile"
|
|
55
|
+
".ai-context.md|AI Context Map|ContextMap"
|
|
56
|
+
"architecture.md|Architecture|Architecture"
|
|
57
|
+
"product.md|Product|Product"
|
|
58
|
+
"tech-stack.md|Tech Stack|TechStack"
|
|
59
|
+
"workflow.md|Workflow|Workflow"
|
|
60
|
+
"guardrails.md|Guardrails|Guardrails"
|
|
61
|
+
"service-index.md|Service Index|ServiceIndex"
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
# read_fm_field FILE FIELD — print a top-level frontmatter scalar (quotes stripped).
|
|
65
|
+
read_fm_field() {
|
|
66
|
+
awk -v field="$2" '
|
|
67
|
+
NR==1 { if ($0 != "---") exit; next }
|
|
68
|
+
/^---[[:space:]]*$/ { exit }
|
|
69
|
+
{
|
|
70
|
+
if (index($0, field ":") == 1) {
|
|
71
|
+
sub("^" field ":[[:space:]]*", "")
|
|
72
|
+
gsub(/^"|"$/, "")
|
|
73
|
+
print
|
|
74
|
+
exit
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
' "$1"
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
# --- write the bundle root index.md ---
|
|
81
|
+
PROJECT=""
|
|
82
|
+
for probe in architecture.md .ai-context.md product.md .ai-profile.md; do
|
|
83
|
+
if [[ -f "$DIR/$probe" ]]; then
|
|
84
|
+
PROJECT="$(read_fm_field "$DIR/$probe" project)"
|
|
85
|
+
[[ -n "$PROJECT" ]] && break
|
|
86
|
+
fi
|
|
87
|
+
done
|
|
88
|
+
[[ -n "$PROJECT" && "$PROJECT" != "{PROJECT_NAME}" ]] || PROJECT="$(basename "$(cd "$DIR/.." && pwd)")"
|
|
89
|
+
|
|
90
|
+
INDEX="$DIR/index.md"
|
|
91
|
+
{
|
|
92
|
+
# Bundle-root index.md: frontmatter is permitted only to declare okf_version (§11).
|
|
93
|
+
printf -- '---\n'
|
|
94
|
+
printf 'okf_version: "0.1"\n'
|
|
95
|
+
printf -- '---\n\n'
|
|
96
|
+
printf '# %s — Draft Context Bundle\n\n' "$PROJECT"
|
|
97
|
+
printf 'Open Knowledge Format (OKF) bundle root. Each concept below is a markdown file with a `type` frontmatter field; the links form the navigable knowledge graph.\n'
|
|
98
|
+
|
|
99
|
+
# Context concepts (only if at least one is present)
|
|
100
|
+
context=""
|
|
101
|
+
for entry in "${CONCEPTS[@]}"; do
|
|
102
|
+
IFS='|' read -r fname label expected <<< "$entry"
|
|
103
|
+
[[ -f "$DIR/$fname" ]] || continue
|
|
104
|
+
t="$(read_fm_field "$DIR/$fname" type)"
|
|
105
|
+
[[ -n "$t" ]] || t="$expected"
|
|
106
|
+
d="$(read_fm_field "$DIR/$fname" description)"
|
|
107
|
+
desc="${d:-$t concept}"
|
|
108
|
+
context+="$(printf -- '* [%s](%s) - %s' "$label" "$fname" "$desc")"$'\n'
|
|
109
|
+
done
|
|
110
|
+
if [[ -n "$context" ]]; then
|
|
111
|
+
printf '\n# Context\n\n%s' "$context"
|
|
112
|
+
fi
|
|
113
|
+
|
|
114
|
+
# Tracks
|
|
115
|
+
if [[ -f "$DIR/tracks.md" || -d "$DIR/tracks" ]]; then
|
|
116
|
+
printf '\n# Tracks\n\n'
|
|
117
|
+
[[ -f "$DIR/tracks.md" ]] && printf -- '* [Track Index](tracks.md) - active, completed, and archived tracks\n'
|
|
118
|
+
if [[ -d "$DIR/tracks" ]]; then
|
|
119
|
+
for td in "$DIR"/tracks/*/; do
|
|
120
|
+
[[ -d "$td" ]] || continue
|
|
121
|
+
id="$(basename "$td")"
|
|
122
|
+
[[ -f "$td/spec.md" ]] || continue
|
|
123
|
+
title="$id"
|
|
124
|
+
if command -v jq >/dev/null 2>&1 && [[ -f "$td/metadata.json" ]]; then
|
|
125
|
+
mt="$(jq -r '.title // empty' "$td/metadata.json" 2>/dev/null || true)"
|
|
126
|
+
[[ -n "$mt" ]] && title="$mt"
|
|
127
|
+
fi
|
|
128
|
+
printf -- '* [%s](tracks/%s/spec.md) - track %s\n' "$title" "$id" "$id"
|
|
129
|
+
done
|
|
130
|
+
fi
|
|
131
|
+
fi
|
|
132
|
+
|
|
133
|
+
# Knowledge graph sub-bundle
|
|
134
|
+
if [[ -f "$DIR/graph/okf/index.md" ]]; then
|
|
135
|
+
printf '\n# Knowledge graph\n\n'
|
|
136
|
+
printf -- '* [Graph bundle](graph/okf/index.md) - structural knowledge graph (modules, dependencies, hotspots)\n'
|
|
137
|
+
fi
|
|
138
|
+
} > "$INDEX"
|
|
139
|
+
|
|
140
|
+
echo "OKF bundle root written to $INDEX"
|
|
141
|
+
exit 0
|