@drawbridge/drawbridge-agents 0.1.0 → 0.1.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 +11 -7
- package/bin/graph.js +43 -19
- package/bin/preflight-graphify.js +4 -8
- package/claude/CLAUDE.md +2 -0
- package/conventions/git-branching.md +19 -0
- package/conventions/graphify.md +22 -14
- package/conventions/superpowers-docs.md +19 -0
- package/graph/README.md +10 -9
- package/hooks/drift-check.js +6 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -86,12 +86,15 @@ Beyond the conventions, this package gives agents cross-repo visibility and keep
|
|
|
86
86
|
and the knowledge graph from drifting. Everything below is committed **only in this repo** and
|
|
87
87
|
reaches consumers without committing anything to them (see "Isolation").
|
|
88
88
|
|
|
89
|
-
- **Family knowledge graph (Graphify).** `npx drawbridge-agents-graph`
|
|
90
|
-
`drawbridge-*` repo
|
|
91
|
-
Agents query it
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
89
|
+
- **Family knowledge graph (Graphify).** `npx drawbridge-agents-graph` runs code-only AST
|
|
90
|
+
extraction over every `drawbridge-*` repo and writes the merged graph to the committed, shared
|
|
91
|
+
location `drawbridge-docs/knowledge/graphs/global.json`. Agents query it with the `graphify` CLI
|
|
92
|
+
(e.g. `graphify query "…" --graph ../drawbridge-docs/knowledge/graphs/global.json`) instead of
|
|
93
|
+
grepping; refreshing is rebuild + commit in docs + `git pull` (no npm/publish cycle). The
|
|
94
|
+
runtime is a per-machine Python tool — `npm run sync` installs it
|
|
95
|
+
(`bin/preflight-graphify.js`); set `DRAWBRIDGE_SKIP_GRAPHIFY=1` to skip in CI/headless. We
|
|
96
|
+
deliberately do **not** run `graphify install` (it would rewrite `CLAUDE.md`); the optional
|
|
97
|
+
`graphify-mcp` server is available if you prefer MCP.
|
|
95
98
|
- **Docs linkage + validator.** Feature code carries `@story <domain>/<slug>` / `@doc
|
|
96
99
|
reference/<file>#<anchor>` anchors (see `conventions/docs-linkage.md`).
|
|
97
100
|
`npx drawbridge-agents-check-docs` scans every repo and fails if any anchor no longer resolves
|
|
@@ -107,7 +110,8 @@ reaches consumers without committing anything to them (see "Isolation").
|
|
|
107
110
|
### Isolation (nothing ships to DigitalOcean)
|
|
108
111
|
|
|
109
112
|
- The package is a **devDependency** → not installed in production.
|
|
110
|
-
- The
|
|
113
|
+
- The graph and CLI are per-machine (`~/.graphify/`); nothing graph-related is written into the
|
|
114
|
+
consumer repo, and `graphify install` (which edits `CLAUDE.md`) is never run.
|
|
111
115
|
- The Stop hook is merged into `.claude/settings.local.json` (gitignored).
|
|
112
116
|
- Skills install to `~/.claude/skills/` (per-machine, outside any repo).
|
|
113
117
|
- The only in-repo footprint in consumers is inert `@story`/`@doc` source comments.
|
package/bin/graph.js
CHANGED
|
@@ -1,18 +1,35 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// Builds the family knowledge graph:
|
|
3
|
-
// the shared @drawbridge/* packages) into graphify's
|
|
4
|
-
// graph
|
|
5
|
-
//
|
|
2
|
+
// Builds the family knowledge graph: runs graphify's headless AST extraction over every
|
|
3
|
+
// drawbridge-* repo (plus drawbridge-docs and the shared @drawbridge/* packages) into graphify's
|
|
4
|
+
// global graph, then copies it to drawbridge-docs/knowledge/graphs/global.json — the committed,
|
|
5
|
+
// shared graph agents query. Code-only (local AST, no API key). See conventions/graphify.md.
|
|
6
6
|
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
7
|
+
// A semantic build (adds doc/paper content + INFERRED edges) needs an LLM backend: drop
|
|
8
|
+
// --code-only and set an API key (e.g. ANTHROPIC_API_KEY) — slower and costs LLM calls.
|
|
9
9
|
const fs = require('fs')
|
|
10
|
+
const os = require('os')
|
|
10
11
|
const path = require('path')
|
|
11
12
|
const { execFileSync } = require('child_process')
|
|
12
13
|
|
|
13
14
|
const packageRoot = path.resolve(__dirname, '..')
|
|
14
|
-
const
|
|
15
|
-
const
|
|
15
|
+
const buildDir = path.join(os.homedir(), '.graphify', 'build')
|
|
16
|
+
const globalGraph = path.join(os.homedir(), '.graphify', 'global-graph.json')
|
|
17
|
+
|
|
18
|
+
// The family root is the directory that contains drawbridge-docs. Walk up from cwd so this works
|
|
19
|
+
// whether run from the agents repo or via npx from inside a consumer's node_modules.
|
|
20
|
+
const findFamilyRoot = () => {
|
|
21
|
+
let dir = process.env.INIT_CWD || process.cwd()
|
|
22
|
+
for (let i = 0; i < 8; i++) {
|
|
23
|
+
if (fs.existsSync(path.join(dir, 'drawbridge-docs'))) return dir
|
|
24
|
+
const parent = path.dirname(dir)
|
|
25
|
+
if (parent === dir) break
|
|
26
|
+
dir = parent
|
|
27
|
+
}
|
|
28
|
+
return path.resolve(packageRoot, '..')
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const familyRoot = findFamilyRoot()
|
|
32
|
+
const docsGraph = path.join(familyRoot, 'drawbridge-docs', 'knowledge', 'graphs', 'global.json')
|
|
16
33
|
|
|
17
34
|
// The canonical family list lives in the shared settings template — single source of truth.
|
|
18
35
|
const settings = JSON.parse(fs.readFileSync(path.join(packageRoot, '.claude-template', 'settings.json'), 'utf8'))
|
|
@@ -34,7 +51,7 @@ if (!hasGraphify()) {
|
|
|
34
51
|
process.exit(1)
|
|
35
52
|
}
|
|
36
53
|
|
|
37
|
-
fs.mkdirSync(
|
|
54
|
+
fs.mkdirSync(buildDir, { recursive: true })
|
|
38
55
|
|
|
39
56
|
const built = []
|
|
40
57
|
for (const name of repos) {
|
|
@@ -44,17 +61,24 @@ for (const name of repos) {
|
|
|
44
61
|
continue
|
|
45
62
|
}
|
|
46
63
|
console.log(` extract ${ name }`)
|
|
47
|
-
|
|
64
|
+
// --out redirects the per-repo graphify-out/ away from the repo (keeps it clean);
|
|
65
|
+
// --global merges the result into ~/.graphify/global-graph.json under the --as tag.
|
|
66
|
+
execFileSync(
|
|
67
|
+
'graphify',
|
|
68
|
+
[ 'extract', repoPath, '--out', path.join(buildDir, name), '--global', '--as', name, '--code-only' ],
|
|
69
|
+
{ stdio: 'inherit' }
|
|
70
|
+
)
|
|
71
|
+
// graphify still drops a graphify-out/ in the target repo despite --out; remove it so the
|
|
72
|
+
// build never dirties a source repo (the incremental cache lives under ~/.graphify/build).
|
|
73
|
+
fs.rmSync(path.join(repoPath, 'graphify-out'), { recursive: true, force: true })
|
|
48
74
|
built.push(name)
|
|
49
75
|
}
|
|
50
76
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
77
|
+
// Publish the merged global graph to the committed, shared location in drawbridge-docs.
|
|
78
|
+
fs.mkdirSync(path.dirname(docsGraph), { recursive: true })
|
|
79
|
+
fs.copyFileSync(globalGraph, docsGraph)
|
|
54
80
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
fs.writeFileSync(path.join(graphDir, 'manifest.json'), JSON.stringify(manifest, null, 2) + '\n')
|
|
60
|
-
console.log(`drawbridge-agents-graph: built graph from ${ built.length } repo(s)`)
|
|
81
|
+
console.log(`drawbridge-agents-graph: built cross-repo graph from ${ built.length } repo(s)`)
|
|
82
|
+
console.log(` written to: ${ docsGraph }`)
|
|
83
|
+
console.log(' commit it in drawbridge-docs so the team shares one graph, then: git pull')
|
|
84
|
+
console.log(' query it: graphify query "<question>" --graph ' + docsGraph)
|
|
@@ -48,11 +48,7 @@ if (!has('graphify')) {
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
//
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
console.warn('drawbridge-agents-sync: `graphify install` (MCP registration) failed — run it manually.')
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
console.log('drawbridge-agents-sync: graphify runtime ready')
|
|
51
|
+
// Note: we deliberately do NOT run `graphify install` — it writes a graphify section into the
|
|
52
|
+
// repo's CLAUDE.md and a PreToolUse hook, which would mutate a committed file and clash with the
|
|
53
|
+
// shared CLAUDE.md. Agents use the graphify CLI directly (see conventions/graphify.md).
|
|
54
|
+
console.log('drawbridge-agents-sync: graphify runtime ready (run `npx drawbridge-agents-graph` to build the graph)')
|
package/claude/CLAUDE.md
CHANGED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Branch naming (gitflow)
|
|
2
|
+
|
|
3
|
+
Branches use the **full gitflow prefixes, always spelled out**. Never use abbreviations.
|
|
4
|
+
|
|
5
|
+
| Prefix | Use |
|
|
6
|
+
| --- | --- |
|
|
7
|
+
| `feature/<name>` | New features / changes (branched from `develop`) |
|
|
8
|
+
| `bugfix/<name>` | Non-urgent bug fixes |
|
|
9
|
+
| `hotfix/<name>` | Urgent production fixes (branched from `main`) |
|
|
10
|
+
| `release/<version>` | Release preparation |
|
|
11
|
+
| `chore/<name>` | Maintenance — dependency bumps, config, cleanup |
|
|
12
|
+
| `support/<name>` | Long-lived support branches |
|
|
13
|
+
|
|
14
|
+
- **Never** abbreviate: no `feat/`, `fix/`, `ci/`, `docs/`, `refactor/`, etc. Use the full word
|
|
15
|
+
(`feature/`, `bugfix/`, `chore/`, …).
|
|
16
|
+
- `<name>` is a short kebab-case description (e.g. `feature/ecosystem-knowledge-graphify`,
|
|
17
|
+
`chore/agents-devdep`).
|
|
18
|
+
- Branch from `develop` for normal work (see the integration-branch convention); `main`-only
|
|
19
|
+
repos like `drawbridge-docs` branch from `main`.
|
package/conventions/graphify.md
CHANGED
|
@@ -6,32 +6,40 @@ shared packages — built by [Graphify](https://github.com/Graphify-Labs/graphif
|
|
|
6
6
|
## Query the graph before grepping across repos
|
|
7
7
|
|
|
8
8
|
When you need to trace behaviour that spans repos (api ↔ sync ↔ stripe ↔ app-web, who emits an
|
|
9
|
-
event, what depends on a package), **query the graph instead of grepping 16 directories**.
|
|
10
|
-
|
|
9
|
+
event, what depends on a package), **query the graph instead of grepping 16 directories**. The
|
|
10
|
+
cross-repo graph is committed in drawbridge-docs at
|
|
11
|
+
`drawbridge-docs/knowledge/graphs/global.json` — a sibling of every repo, so point the CLI at it:
|
|
11
12
|
|
|
12
13
|
```sh
|
|
13
|
-
graphify query "what connects sync change streams to the billing meter?"
|
|
14
|
-
graphify path "drawbridge-app-web" "drawbridge-stripe"
|
|
15
|
-
graphify explain "closeDraw"
|
|
14
|
+
graphify query "what connects sync change streams to the billing meter?" --graph ../drawbridge-docs/knowledge/graphs/global.json
|
|
15
|
+
graphify path "drawbridge-app-web" "drawbridge-stripe" --graph ../drawbridge-docs/knowledge/graphs/global.json
|
|
16
|
+
graphify explain "closeDraw" --graph ../drawbridge-docs/knowledge/graphs/global.json
|
|
17
|
+
graphify affected "closeDraw" --graph ../drawbridge-docs/knowledge/graphs/global.json
|
|
16
18
|
```
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
`git pull` in drawbridge-docs gets you the current shared graph. It spans all sibling repos
|
|
21
|
+
(code, via local AST); a semantic build additionally pulls in doc prose and richer INFERRED
|
|
22
|
+
edges — see "Refreshing it".
|
|
20
23
|
|
|
21
24
|
## Refreshing it
|
|
22
25
|
|
|
23
|
-
The graph is as fresh as the last build. After a change that alters cross-repo
|
|
24
|
-
rebuild it:
|
|
26
|
+
The graph is as fresh as the last committed build. After a change that alters cross-repo
|
|
27
|
+
structure, rebuild and commit it:
|
|
25
28
|
|
|
26
29
|
```sh
|
|
27
|
-
npx drawbridge-agents-graph
|
|
30
|
+
npx drawbridge-agents-graph # rebuilds -> drawbridge-docs/knowledge/graphs/global.json
|
|
31
|
+
cd ../drawbridge-docs && git add knowledge/graphs && git commit -m "chore: refresh knowledge graph"
|
|
28
32
|
```
|
|
29
33
|
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
Other developers just `git pull` drawbridge-docs. The drift-check hook nudges when tracked
|
|
35
|
+
source has changed since the committed graph was last built. For a semantic build that also
|
|
36
|
+
indexes docs, run `graphify extract <repo> --global --as <repo>` with an LLM backend / API key
|
|
37
|
+
set (slower, costs LLM calls).
|
|
32
38
|
|
|
33
39
|
## Runtime
|
|
34
40
|
|
|
35
41
|
Graphify is a per-machine Python tool; `npm run sync` installs it automatically (see the sync
|
|
36
|
-
preflight
|
|
37
|
-
|
|
42
|
+
preflight — `uv tool install graphifyy`). Set `DRAWBRIDGE_SKIP_GRAPHIFY=1` to skip in CI/headless
|
|
43
|
+
environments. The MCP server (`graphify-mcp <graph.json>`) is available if you prefer it, but is
|
|
44
|
+
**not** auto-registered — `graphify install` would rewrite CLAUDE.md, which we keep managed by
|
|
45
|
+
this package.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Superpowers working docs live in drawbridge-docs
|
|
2
|
+
|
|
3
|
+
All superpowers **plans** and **specs** — the outputs of the brainstorming / writing-plans /
|
|
4
|
+
spec workflows — live in one canonical place:
|
|
5
|
+
|
|
6
|
+
```
|
|
7
|
+
drawbridge-docs/docs/superpowers/plans/YYYY-MM-DD-<slug>.md
|
|
8
|
+
drawbridge-docs/docs/superpowers/specs/YYYY-MM-DD-<slug>.md
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
This is the **only** allowed home for these working docs. Rules:
|
|
12
|
+
|
|
13
|
+
- Do **not** create or keep `docs/superpowers/`, `docs/plans/`, or any plan/spec working docs
|
|
14
|
+
inside any other repo. When you finalize a plan or spec, write it under
|
|
15
|
+
`../drawbridge-docs/docs/superpowers/{plans,specs}/`, not the repo you're working in.
|
|
16
|
+
- When plan mode or a superpowers skill produces a plan/spec, the finalized document goes into
|
|
17
|
+
drawbridge-docs — regardless of which repo the work targets. Note the target repo in the doc.
|
|
18
|
+
- `.superpowers/` (brainstorm scratch — server state, HTML mockups) is ephemeral. **Never commit
|
|
19
|
+
it**; it belongs in `.gitignore`.
|
package/graph/README.md
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
# Family knowledge graph
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
(
|
|
5
|
-
|
|
6
|
-
knowledge graph.
|
|
3
|
+
The cross-repo knowledge graph is built by `npx drawbridge-agents-graph` (`bin/graph.js`), which
|
|
4
|
+
runs [Graphify](https://github.com/Graphify-Labs/graphify) headless AST extraction over every
|
|
5
|
+
`drawbridge-*` repo and writes the merged graph to the **committed, shared** location:
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
-
|
|
10
|
-
|
|
7
|
+
```
|
|
8
|
+
drawbridge-docs/knowledge/graphs/global.json
|
|
9
|
+
```
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
That committed file is what agents query (`--graph ../drawbridge-docs/knowledge/graphs/global.json`)
|
|
12
|
+
and is shared via `git pull` — see `conventions/graphify.md`. There are no graph artifacts in
|
|
13
|
+
this package directory; per-repo extraction output is redirected to `~/.graphify/build/` so it
|
|
14
|
+
never litters the source repos.
|
package/hooks/drift-check.js
CHANGED
|
@@ -69,14 +69,13 @@ const run = () => {
|
|
|
69
69
|
// 2. Graph freshness (non-blocking nudge) — a full re-extract is expensive, so alert rather
|
|
70
70
|
// than block on every edit turn. Flip to block() if you want it enforced hard.
|
|
71
71
|
if (!skipGraph) {
|
|
72
|
-
|
|
72
|
+
// The shared graph is committed in drawbridge-docs (a sibling of this repo).
|
|
73
|
+
const docsGraph = path.join(path.dirname(cwd), 'drawbridge-docs', 'knowledge', 'graphs', 'global.json')
|
|
73
74
|
let builtAt = 0
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
builtAt = 0
|
|
79
|
-
}
|
|
75
|
+
try {
|
|
76
|
+
builtAt = fs.statSync(docsGraph).mtimeMs
|
|
77
|
+
} catch (error) {
|
|
78
|
+
builtAt = 0
|
|
80
79
|
}
|
|
81
80
|
const stale = changedSource.some((file) => {
|
|
82
81
|
try {
|
package/package.json
CHANGED