mirror of
https://github.com/kochetkov-ma/claude-brewcode.git
synced 2026-09-14 20:16:41 +08:00
v3.3.0
This commit is contained in:
@@ -6,13 +6,13 @@
|
||||
},
|
||||
"metadata": {
|
||||
"description": "Claude Code plugin suite: brewcode for infinite task execution and brewdoc for documentation tools",
|
||||
"version": "3.2.0"
|
||||
"version": "3.3.0"
|
||||
},
|
||||
"plugins": [
|
||||
{
|
||||
"name": "brewcode",
|
||||
"description": "Brewcode - full-featured development platform for Claude Code: infinite focus tasks, prompt optimization, skill/agent creation, quorum reviews, rules management",
|
||||
"version": "3.2.0",
|
||||
"version": "3.3.0",
|
||||
"category": "productivity",
|
||||
"keywords": [
|
||||
"brewcode",
|
||||
@@ -46,7 +46,7 @@
|
||||
{
|
||||
"name": "brewdoc",
|
||||
"description": "Brewdoc - Claude Code documentation tools: auto-sync for skills/agents/rules, my-claude installation docs, memory optimization, md-to-pdf conversion",
|
||||
"version": "3.2.0",
|
||||
"version": "3.3.0",
|
||||
"category": "productivity",
|
||||
"keywords": [
|
||||
"brewdoc",
|
||||
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
- name: Verify tag is on main
|
||||
run: |
|
||||
git fetch origin main
|
||||
if ! git merge-base --is-ancestor "$GITHUB_SHA" origin/main; then
|
||||
if ! git branch --contains "$GITHUB_SHA" | grep -qE '(^|\s)main$'; then
|
||||
echo "::error::Tag $GITHUB_REF_NAME is not on the main branch. Skipping release."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -2,6 +2,18 @@
|
||||
|
||||
---
|
||||
|
||||
## v3.3.0 (2026-03-05)
|
||||
|
||||
### brewdoc
|
||||
#### Changed
|
||||
- **session-start hook removed** -- brewdoc no longer injects `BD_PLUGIN_ROOT` at session start
|
||||
- **pre-task hook retained** -- `BD_PLUGIN_ROOT` still injected into subagent prompts for `bd-auto-sync-processor`
|
||||
- **Skills use relative paths** -- `my-claude` uses plain relative paths; `md-to-pdf` and `auto-sync` bash commands use `${CLAUDE_SKILL_DIR}`
|
||||
- Updated `docs/hooks.md`: rewritten to reflect 1 hook (was 2)
|
||||
- Updated `README.md`, `docs/commands.md`: removed stale `BD_PLUGIN_ROOT` references
|
||||
|
||||
---
|
||||
|
||||
## v3.2.0 (2026-03-02)
|
||||
|
||||
### brewcode
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "brewcode",
|
||||
"version": "3.2.0",
|
||||
"version": "3.3.0",
|
||||
"description": "Brewcode - full-featured development platform for Claude Code: infinite focus tasks, prompt optimization, skill/agent creation, quorum reviews, rules management",
|
||||
"author": {
|
||||
"name": "Maksim Kochetkov",
|
||||
|
||||
@@ -40,7 +40,7 @@ permissionMode: acceptEdits
|
||||
| # | Practice | Context | Source |
|
||||
|---|----------|---------|--------|
|
||||
| 1 | `allSatisfy()` over `forEach` | Collection assertions | AssertJ |
|
||||
| 2 | Constructor injection | Spring DI | CLAUDE.md |
|
||||
| 2 | Constructor injection | Spring DI | convention |
|
||||
```
|
||||
|
||||
### Table Constraints
|
||||
@@ -49,7 +49,8 @@ permissionMode: acceptEdits
|
||||
|------|---------|
|
||||
| Numbered entries | Sequential `1, 2, 3...` in `#` column |
|
||||
| Max rows | 20 per file — split into specialized files if exceeded |
|
||||
| Deduplication | By **semantic similarity** (not exact match), merge related entries |
|
||||
| Deduplication | Semantic similarity + 3-Check Protocol before adding any entry |
|
||||
| CLAUDE.md rule | Never add a rule already in project CLAUDE.md; "CLAUDE.md" forbidden as Source |
|
||||
| Priority | critical > important > nice-to-have |
|
||||
|
||||
## Frontmatter Reference
|
||||
@@ -129,7 +130,19 @@ Group rules by logical scope. Classify each rule as anti-pattern (avoid) or best
|
||||
|
||||
Apply transformations: tables over prose, abbreviations (REQ, impl, cfg, env), remove filler, lazy links `> Details: [file.md](../docs/file.md)`.
|
||||
|
||||
Deduplication: semantic similarity (not exact match). Merge related entries into single row. Max 20 rows per file.
|
||||
Deduplication: apply 3-Check Dedup Protocol (below). Max 20 rows per file.
|
||||
|
||||
### 3-Check Dedup Protocol
|
||||
|
||||
| Check | Scope | Action |
|
||||
|-------|-------|--------|
|
||||
| 1. Within-file | Same target file | >70% skip; 40-70% merge |
|
||||
| 2. Cross-file antonym | Paired file (avoid ↔ best-practice) | Same concept as opposite → keep avoid entry only, delete best-practice |
|
||||
| 3. CLAUDE.md duplicate | Project CLAUDE.md | Already documented → skip entirely |
|
||||
|
||||
**Antonym rule:** "don't do X" in avoid + "do not-X" in best-practice = one rule twice. Keep avoid entry, ensure "Instead" column captures the positive.
|
||||
|
||||
**CLAUDE.md rule:** If concept exists in CLAUDE.md → skip. Source column value "CLAUDE.md" is forbidden.
|
||||
|
||||
### Phase 4: File Creation
|
||||
|
||||
@@ -260,7 +273,7 @@ Two naming conventions — use both as appropriate:
|
||||
|
||||
## Quality Checklist
|
||||
|
||||
**Before extraction:** read source completely, identify rule categories, map to path patterns, check existing rules (avoid duplicates).
|
||||
**Before extraction:** read source completely, identify rule categories, map to path patterns, check existing rules via 3-Check Protocol (within-file + cross-file antonym + CLAUDE.md).
|
||||
|
||||
**During creation:** `paths:` frontmatter on all files, quoted glob patterns, tables for multi-column data, `❌ -> ✅` for anti-patterns, lazy links for detailed docs, text-optimize applied.
|
||||
|
||||
@@ -288,6 +301,7 @@ Two naming conventions — use both as appropriate:
|
||||
| 7 | `| Bad | Good |` tables | `| # | Avoid | Instead | Why |` | Standard format |
|
||||
| 8 | Unnumbered table entries | Sequential `1, 2, 3...` | Referenceability |
|
||||
| 9 | >20 rows per file | Split into `{prefix}-avoid.md` | Readability, token budget |
|
||||
| 10 | "CLAUDE.md" as Source value | Skip — already in CLAUDE.md | Duplication |
|
||||
|
||||
## LLM Text Rules
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "claude-plugin-brewcode",
|
||||
"version": "3.2.0",
|
||||
"version": "3.3.0",
|
||||
"description": "Infinite task execution with automatic handoff for Claude Code",
|
||||
"keywords": [
|
||||
"claude-code",
|
||||
@@ -36,6 +36,6 @@
|
||||
},
|
||||
"claude-plugin": {
|
||||
"name": "brewcode",
|
||||
"version": "3.2.0"
|
||||
"version": "3.3.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
# Convention Skill
|
||||
|
||||
Analyze project codebase to extract etalon classes, patterns, architecture, and organize rules.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
/brewcode:convention # Full analysis (P0-P8)
|
||||
/brewcode:convention conventions # Generate docs only (P0-P7)
|
||||
/brewcode:convention rules # Re-extract rules (requires existing docs)
|
||||
/brewcode:convention paths src/a,src/b # Scoped analysis
|
||||
```
|
||||
|
||||
## Phases
|
||||
|
||||
| Phase | Name | Agents | Output |
|
||||
|-------|------|--------|--------|
|
||||
| P0 | Stack + scan | — | Detect stack, setup `.claude/convention/` |
|
||||
| P1 | Load layers | — | Filter layers by stack |
|
||||
| P2 | Layer analysis | 10 (architect + tester) | Etalon candidates, patterns, anti-patterns |
|
||||
| P3 | Etalon selection | 1 architect | Final etalon summary |
|
||||
| P4 | Doc generation | 3 developer | Convention docs |
|
||||
| P5 | Text optimization | 3 text-optimizer | Token-efficient docs |
|
||||
| P6 | User review | — | Approve / revise / skip |
|
||||
| P7 | Rules organization | bc-rules-organizer | `.claude/rules/` updates |
|
||||
| P7.5 | CLAUDE.md update | — | Etalon summary in CLAUDE.md |
|
||||
| P8 | Summary | — | Final report |
|
||||
|
||||
## Output
|
||||
|
||||
```
|
||||
.claude/convention/
|
||||
reference-patterns.md # Main code layers (L4-L11, L14)
|
||||
testing-conventions.md # Test layers (T1-T6)
|
||||
project-architecture.md # Build layers (L1-L3, L12-L13)
|
||||
|
||||
.claude/rules/
|
||||
{prefix}-avoid.md # Extracted anti-patterns
|
||||
{prefix}-best-practice.md # Extracted best practices
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `references/analysis-layers.md` | Layer definitions (L1-L14, T1-T6) |
|
||||
| `references/conventions-guide.md` | Document templates |
|
||||
| `references/rules-guide.md` | Rules extraction + 3-Check Dedup Protocol |
|
||||
| `scripts/convention.sh` | Stack detection, scan, setup, validation |
|
||||
|
||||
## Deduplication
|
||||
|
||||
Rules extraction uses the 3-Check Dedup Protocol:
|
||||
|
||||
| Check | Action |
|
||||
|-------|--------|
|
||||
| Within-file similarity | >70% skip, 40-70% merge |
|
||||
| Cross-file antonym | avoid↔best-practice — keep avoid only |
|
||||
| CLAUDE.md duplicate | Skip if already in CLAUDE.md |
|
||||
@@ -54,6 +54,10 @@ Targets: avoid.md, best-practice.md, {prefix}-avoid.md, {prefix}-best-practice.m
|
||||
|
||||
MODE: {detected mode}
|
||||
KNOWLEDGE: {prepared from table above}
|
||||
DEDUP: 3-Check Protocol:
|
||||
1. Within-file similarity (>70% skip, 40-70% merge)
|
||||
2. Cross-file antonym (avoid↔best-practice — keep avoid only)
|
||||
3. CLAUDE.md duplicate (skip if in CLAUDE.md; "CLAUDE.md" forbidden as Source)
|
||||
```
|
||||
|
||||
> `BC_PLUGIN_ROOT` injected by pre-task.mjs hook.
|
||||
|
||||
@@ -5,7 +5,5 @@ paths:
|
||||
|
||||
# Avoid
|
||||
|
||||
> Auto-synced from KNOWLEDGE by `/brewcode:rules`
|
||||
|
||||
| # | Avoid | Instead | Why |
|
||||
|---|-------|---------|-----|
|
||||
|
||||
@@ -5,7 +5,5 @@ paths:
|
||||
|
||||
# Best Practices
|
||||
|
||||
> Auto-synced from KNOWLEDGE by `/brewcode:rules`
|
||||
|
||||
| # | Practice | Context | Source |
|
||||
|---|----------|---------|--------|
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "brewdoc",
|
||||
"version": "3.2.0",
|
||||
"version": "3.3.0",
|
||||
"description": "Brewdoc - Claude Code documentation tools: auto-sync for skills/agents/rules, my-claude installation docs, memory optimization",
|
||||
"author": {
|
||||
"name": "Maksim Kochetkov",
|
||||
|
||||
+2
-3
@@ -147,8 +147,7 @@ Memory files location: `~/.claude/projects/.../memory/*.md`
|
||||
|
||||
| Variable | Set by | Available in |
|
||||
|----------|--------|--------------|
|
||||
| `BD_PLUGIN_ROOT` | `session-start.mjs` (SessionStart) | Main conversation, skills |
|
||||
| `BD_PLUGIN_ROOT` | `pre-task.mjs` (PreToolUse:Task) | All subagents (prefix line in prompt) |
|
||||
| `BD_PLUGIN_ROOT` | `pre-task.mjs` (PreToolUse:Task) | Agents (subagents via Task tool) |
|
||||
|
||||
## Output Locations
|
||||
|
||||
@@ -165,7 +164,7 @@ brewdoc/
|
||||
.claude-plugin/plugin.json # Manifest (v3.1.0)
|
||||
hooks/
|
||||
hooks.json # Hook registration
|
||||
session-start.mjs # Sets BD_PLUGIN_ROOT
|
||||
session-start.mjs # (unused, not registered in hooks.json)
|
||||
pre-task.mjs # Injects BD_PLUGIN_ROOT into subagent prompts
|
||||
lib/utils.mjs # Shared hook utilities
|
||||
skills/
|
||||
|
||||
@@ -204,7 +204,7 @@ If an existing entry for the same mode exists, the skill offers to update (versi
|
||||
### Workflow
|
||||
|
||||
**INTERNAL mode:**
|
||||
1. Load reference file from `$BD_PLUGIN_ROOT/skills/my-claude/references/internal-mode.md`
|
||||
1. Load reference file from `references/internal-mode.md`
|
||||
2. Spawn 3 parallel `Explore` agents: (1) global `~/.claude` config, (2) project `.claude` config, (3) memory files
|
||||
3. Aggregate findings into structured document
|
||||
4. Write to `~/.claude/brewdoc/YYYYMMDD_my-claude-internal.md`
|
||||
@@ -213,7 +213,7 @@ If an existing entry for the same mode exists, the skill offers to update (versi
|
||||
7. Add INDEX entry
|
||||
|
||||
**EXTERNAL mode (default):**
|
||||
1. Load reference file from `$BD_PLUGIN_ROOT/skills/my-claude/references/external-mode.md`
|
||||
1. Load reference file from `references/external-mode.md`
|
||||
2. Analyze local hook files for event model patterns
|
||||
3. WebSearch for recent Claude Code releases and CHANGELOG
|
||||
4. Spawn `general-purpose` agents for: official docs, GitHub releases, community forums
|
||||
@@ -417,4 +417,4 @@ The command takes no arguments. All interaction happens through `AskUserQuestion
|
||||
|
||||
| Variable | Injected By | Available In | Value |
|
||||
|----------|-------------|--------------|-------|
|
||||
| `BD_PLUGIN_ROOT` | pre-task.mjs | Skills, Agents | Absolute path to brewdoc plugin root |
|
||||
| `BD_PLUGIN_ROOT` | pre-task.mjs | Agents (subagents via Task tool only) | Absolute path to brewdoc plugin root |
|
||||
|
||||
+24
-119
@@ -9,36 +9,29 @@ description: Detailed description of brewdoc plugin hooks
|
||||
|
||||
## Why Hooks?
|
||||
|
||||
Claude Code plugins can define skills (slash commands) and agents. But skills and agents need to know WHERE the plugin is installed -- the absolute filesystem path changes with each version update and differs across machines. Hooks solve this by automatically injecting `BD_PLUGIN_ROOT` (the plugin's absolute path) into every conversation and every subagent call. Without hooks, skills would need to hard-code paths that break on updates.
|
||||
Claude Code plugins can define skills (slash commands) and agents. But agents spawned via the Task tool need to know WHERE the plugin is installed -- the absolute filesystem path changes with each version update and differs across machines. The pre-task hook solves this by automatically injecting `BD_PLUGIN_ROOT` into every subagent prompt. Without this hook, agents would need to hard-code paths that break on updates.
|
||||
|
||||
brewdoc has exactly **2 hooks** -- the minimum needed for path injection:
|
||||
brewdoc has exactly **1 hook**:
|
||||
|
||||
1. **session-start.mjs** -- injects `BD_PLUGIN_ROOT` into the main conversation at session start
|
||||
2. **pre-task.mjs** -- injects `BD_PLUGIN_ROOT` into subagent prompts when skills spawn agents
|
||||
1. **pre-task.mjs** -- injects `BD_PLUGIN_ROOT` into subagent prompts when skills spawn agents via the Task tool
|
||||
|
||||
Skills running in the main conversation do NOT receive `BD_PLUGIN_ROOT`. They use relative paths or `${CLAUDE_SKILL_DIR}` to reference their own files.
|
||||
|
||||
## Summary Table
|
||||
|
||||
| Hook | Event | Matcher | Timeout | Purpose |
|
||||
|------|-------|---------|---------|---------|
|
||||
| `session-start.mjs` | SessionStart | -- | 2s | Inject `BD_PLUGIN_ROOT` into main conversation context |
|
||||
| `pre-task.mjs` | PreToolUse | `Task` | 3s | Prepend `BD_PLUGIN_ROOT` to subagent prompts |
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
```
|
||||
Claude Code Session
|
||||
|
|
||||
| SessionStart
|
||||
v
|
||||
+----------------------------------------------+
|
||||
| session-start.mjs |
|
||||
| |
|
||||
| BD_PLUGIN_ROOT=/path/to/brewdoc/X.Y.Z |
|
||||
| |
|
||||
| --> additionalContext (main conversation) |
|
||||
+----------------------------------------------+
|
||||
|
|
||||
| User runs /brewdoc:auto-sync or /brewdoc:memory etc.
|
||||
| Skill runs in main conversation
|
||||
| (uses relative paths or ${CLAUDE_SKILL_DIR} for own files)
|
||||
|
|
||||
| Skill spawns agents via Task tool
|
||||
|
|
||||
| PreToolUse:Task
|
||||
@@ -73,20 +66,10 @@ Claude Code Session
|
||||
```
|
||||
CLAUDE_PLUGIN_ROOT (env var set by Claude Code)
|
||||
|
|
||||
| session-start.mjs reads it
|
||||
| pre-task.mjs reads it on every Task tool call
|
||||
v
|
||||
additionalContext in SessionStart output:
|
||||
"BD_PLUGIN_ROOT=/Users/.../.claude/plugins/cache/claude-brewcode/brewdoc/X.Y.Z"
|
||||
|
|
||||
| injected into main conversation context
|
||||
v
|
||||
Skills can use $BD_PLUGIN_ROOT in their instructions
|
||||
|
|
||||
| When skill spawns agents via Task tool:
|
||||
| pre-task.mjs intercepts PreToolUse:Task
|
||||
v
|
||||
Agent prompt gets prepended:
|
||||
"BD_PLUGIN_ROOT=/Users/.../.claude/plugins/cache/.../brewdoc/X.Y.Z
|
||||
updatedInput.prompt in PreToolUse output:
|
||||
"BD_PLUGIN_ROOT=/Users/.../.claude/plugins/cache/claude-brewcode/brewdoc/X.Y.Z
|
||||
|
||||
[original agent prompt]"
|
||||
|
|
||||
@@ -98,7 +81,6 @@ Agent uses $BD_PLUGIN_ROOT to load reference files
|
||||
|
||||
| Event | Hook | Channel | Target |
|
||||
|-------|------|---------|--------|
|
||||
| SessionStart | `session-start.mjs` | `additionalContext` | Main conversation |
|
||||
| PreToolUse:Task | `pre-task.mjs` | `updatedInput.prompt` (prefix) | Subagent prompt |
|
||||
|
||||
### Format
|
||||
@@ -111,8 +93,8 @@ BD_PLUGIN_ROOT=/Users/maximus/.claude/plugins/cache/claude-brewcode/brewdoc/X.Y.
|
||||
|
||||
| Context | How to Use |
|
||||
|---------|------------|
|
||||
| Skills (main conversation) | `$BD_PLUGIN_ROOT` available in additionalContext |
|
||||
| Subagents | `$BD_PLUGIN_ROOT` prepended to prompt |
|
||||
| Subagents (Task tool) | `$BD_PLUGIN_ROOT` prepended to prompt by pre-task.mjs |
|
||||
| Skills (main conversation) | Use relative paths or `${CLAUDE_SKILL_DIR}` -- BD_PLUGIN_ROOT is NOT available |
|
||||
| Hooks | `process.env.CLAUDE_PLUGIN_ROOT` (raw env var) |
|
||||
|
||||
---
|
||||
@@ -142,75 +124,11 @@ All hooks use shared utilities from `hooks/lib/utils.mjs`:
|
||||
- `output(response)` -- serializes and writes JSON to stdout
|
||||
- `log(level, prefix, message, cwd, sessionId)` -- writes to stderr
|
||||
|
||||
**Error handling:** Both hooks catch all exceptions and call `output({})` on failure -- silent pass-through, never blocks the session.
|
||||
**Error handling:** The hook catches all exceptions and calls `output({})` on failure -- silent pass-through, never blocks the session.
|
||||
|
||||
---
|
||||
|
||||
## 1. session-start.mjs
|
||||
|
||||
### Configuration
|
||||
|
||||
| Field | Value |
|
||||
|-------|-------|
|
||||
| Event | `SessionStart` |
|
||||
| Matcher | none (all sessions) |
|
||||
| Timeout | 2000 ms |
|
||||
| Output channel | `additionalContext` |
|
||||
|
||||
### Input
|
||||
|
||||
```json
|
||||
{
|
||||
"session_id": "abc123def456...",
|
||||
"cwd": "/path/to/project",
|
||||
"source": "init"
|
||||
}
|
||||
```
|
||||
|
||||
### Behavior
|
||||
|
||||
| Condition | Result |
|
||||
|-----------|--------|
|
||||
| `CLAUDE_PLUGIN_ROOT` set | Injects `BD_PLUGIN_ROOT=...` + `brewdoc: active \| session: {short_id}` |
|
||||
| `CLAUDE_PLUGIN_ROOT` not set | Injects `brewdoc: active \| session: {short_id}` (no path) |
|
||||
| Any error | Silent pass-through (`output({})`) |
|
||||
|
||||
### Logic
|
||||
|
||||
```
|
||||
input = readStdin()
|
||||
pluginRoot = process.env.CLAUDE_PLUGIN_ROOT || ''
|
||||
sessionShort = session_id[0..8] || 'unknown'
|
||||
|
||||
if pluginRoot:
|
||||
context = "BD_PLUGIN_ROOT={pluginRoot}\nbrewdoc: active | session: {sessionShort}"
|
||||
else:
|
||||
context = "brewdoc: active | session: {sessionShort}"
|
||||
|
||||
output:
|
||||
systemMessage = "brewdoc: {pluginRoot} | session: {sessionShort}"
|
||||
hookSpecificOutput.hookEventName = "SessionStart"
|
||||
hookSpecificOutput.additionalContext = context
|
||||
```
|
||||
|
||||
### Output
|
||||
|
||||
```json
|
||||
{
|
||||
"systemMessage": "brewdoc: /path/to/plugin | session: abc123de",
|
||||
"hookSpecificOutput": {
|
||||
"hookEventName": "SessionStart",
|
||||
"additionalContext": "BD_PLUGIN_ROOT=/path/to/plugin\nbrewdoc: active | session: abc123de"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- `systemMessage` -- shown to user in console
|
||||
- `additionalContext` -- injected into Claude's context (invisible to user)
|
||||
|
||||
---
|
||||
|
||||
## 2. pre-task.mjs
|
||||
## pre-task.mjs
|
||||
|
||||
### Configuration
|
||||
|
||||
@@ -291,13 +209,11 @@ The original `tool_input` is spread into `updatedInput` -- all fields are preser
|
||||
+---------------------------------------------------------------+
|
||||
| Claude Code Session |
|
||||
| |
|
||||
| SessionStart --> session-start.mjs --> BD_PLUGIN_ROOT in ctx |
|
||||
| |
|
||||
| User: /brewdoc:memory |
|
||||
| | |
|
||||
| v |
|
||||
| Skill runs in main conversation |
|
||||
| (has BD_PLUGIN_ROOT from additionalContext) |
|
||||
| (uses relative paths or ${CLAUDE_SKILL_DIR} for own files) |
|
||||
| | |
|
||||
| | Task(subagent_type="brewdoc:reviewer", prompt="...") |
|
||||
| | |
|
||||
@@ -316,15 +232,15 @@ The original `tool_input` is spread into `updatedInput` -- all fields are preser
|
||||
|
||||
Key points:
|
||||
|
||||
- `session-start.mjs` fires once per session -- covers the main conversation
|
||||
- `pre-task.mjs` fires on every `Task` tool call -- covers every subagent
|
||||
- Together they ensure `BD_PLUGIN_ROOT` is available everywhere
|
||||
- Skills in the main conversation do NOT have `BD_PLUGIN_ROOT` -- they use `${CLAUDE_SKILL_DIR}` or relative paths
|
||||
- `BD_PLUGIN_ROOT` is only available inside subagent prompts
|
||||
|
||||
---
|
||||
|
||||
## Library: hooks/lib/utils.mjs
|
||||
|
||||
Shared utilities used by both hooks.
|
||||
Shared utilities used by the hook.
|
||||
|
||||
| Function | Signature | Description |
|
||||
|----------|-----------|-------------|
|
||||
@@ -336,18 +252,19 @@ Shared utilities used by both hooks.
|
||||
|
||||
## Comparison with brewcode Hooks
|
||||
|
||||
brewdoc is intentionally minimal. This table explains why brewdoc needs only 2 of brewcode's 7 hooks:
|
||||
brewdoc is intentionally minimal. This table explains why brewdoc needs only 1 of brewcode's 7 hooks:
|
||||
|
||||
| Feature | brewcode (7 hooks) | brewdoc (2 hooks) |
|
||||
| Feature | brewcode (7 hooks) | brewdoc (1 hook) |
|
||||
|---------|-------------------|-------------------|
|
||||
| Plugin root injection | BC_PLUGIN_ROOT | BD_PLUGIN_ROOT |
|
||||
| Plugin root injection (subagents) | pre-task.mjs (BC_PLUGIN_ROOT) | pre-task.mjs (BD_PLUGIN_ROOT) |
|
||||
| Plugin root injection (main conversation) | session-start.mjs | not needed (skills use relative paths) |
|
||||
| KNOWLEDGE injection | pre-task.mjs injects into subagent prompts | not needed |
|
||||
| Task lifecycle (lock, compact, stop) | pre-compact.mjs, stop.mjs, post-task.mjs | not needed |
|
||||
| grepai integration | grepai-session.mjs, grepai-reminder.mjs | not needed |
|
||||
| Plan symlinks | session-start.mjs (LATEST.md) | not needed |
|
||||
| Session binding | post-task.mjs (lock file) | not needed |
|
||||
|
||||
brewdoc is a documentation tool -- it does not manage long-running multi-phase tasks. It only needs to know where it is installed so skills and agents can locate their instruction and reference files.
|
||||
brewdoc is a documentation tool -- it does not manage long-running multi-phase tasks. It only needs to know where it is installed so agents can locate their instruction and reference files.
|
||||
|
||||
---
|
||||
|
||||
@@ -358,17 +275,6 @@ The complete hook registration file:
|
||||
```json
|
||||
{
|
||||
"hooks": {
|
||||
"SessionStart": [
|
||||
{
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/session-start.mjs\"",
|
||||
"timeout": 2000
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"PreToolUse": [
|
||||
{
|
||||
"matcher": "Task",
|
||||
@@ -387,4 +293,3 @@ The complete hook registration file:
|
||||
|
||||
- `${CLAUDE_PLUGIN_ROOT}` is expanded by Claude Code at runtime to the plugin's installed path
|
||||
- `matcher: "Task"` restricts `pre-task.mjs` to fire only on Task tool calls (subagent spawns)
|
||||
- SessionStart has no matcher -- fires on every session start (init, resume, clear)
|
||||
|
||||
@@ -1,16 +1,5 @@
|
||||
{
|
||||
"hooks": {
|
||||
"SessionStart": [
|
||||
{
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/session-start.mjs\"",
|
||||
"timeout": 2000
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"PreToolUse": [
|
||||
{
|
||||
"matcher": "Task",
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
import { readStdin, output, log } from './lib/utils.mjs';
|
||||
|
||||
async function main() {
|
||||
let cwd = null;
|
||||
let session_id = null;
|
||||
try {
|
||||
cwd = process.cwd();
|
||||
const input = await readStdin();
|
||||
session_id = input.session_id;
|
||||
cwd = input.cwd || cwd;
|
||||
|
||||
const pluginRoot = process.env.CLAUDE_PLUGIN_ROOT || '';
|
||||
const sessionShort = session_id?.slice(0, 8) || 'unknown';
|
||||
|
||||
const context = pluginRoot
|
||||
? `BD_PLUGIN_ROOT=${pluginRoot}\nbrewdoc: active | session: ${sessionShort}`
|
||||
: `brewdoc: active | session: ${sessionShort}`;
|
||||
|
||||
output({
|
||||
systemMessage: `brewdoc: ${pluginRoot} | session: ${sessionShort}`,
|
||||
hookSpecificOutput: {
|
||||
hookEventName: 'SessionStart',
|
||||
additionalContext: context
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
log('error', '[session-start]', `Error: ${error.message}`, cwd, session_id);
|
||||
output({});
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -19,9 +19,8 @@ auto-sync-type: skill
|
||||
|
||||
**EXECUTE** using Bash tool (args: `$ARGUMENTS`):
|
||||
```bash
|
||||
bash "scripts/detect-mode.sh" $ARGUMENTS
|
||||
bash "${CLAUDE_SKILL_DIR}/scripts/detect-mode.sh" $ARGUMENTS
|
||||
```
|
||||
> Script path is relative to skill directory.
|
||||
|
||||
Parse output: `MODE|ARG|FLAGS`. If exit code non-zero → report error, EXIT.
|
||||
|
||||
@@ -124,9 +123,8 @@ echo "INDEX=$INDEX_FILE"
|
||||
|
||||
1. Find tagged files — **EXECUTE** using Bash tool:
|
||||
```bash
|
||||
bash "scripts/discover.sh" "$SCOPE_PATH" typed
|
||||
bash "${CLAUDE_SKILL_DIR}/scripts/discover.sh" "$SCOPE_PATH" typed
|
||||
```
|
||||
> Script path is relative to skill directory.
|
||||
Output: `TYPE|PATH` per line (types: `skill`, `agent`, `rule`, `config`, `doc`). Capped at `MAX_FILES` (default 50).
|
||||
|
||||
2. For each file not in INDEX → auto-add:
|
||||
@@ -137,9 +135,8 @@ Output: `TYPE|PATH` per line (types: `skill`, `agent`, `rule`, `config`, `doc`).
|
||||
|
||||
3. Find stale entries — **EXECUTE** using Bash tool:
|
||||
```bash
|
||||
bash "scripts/index-ops.sh" stale "$INDEX_FILE" "$INTERVAL_DAYS"
|
||||
bash "${CLAUDE_SKILL_DIR}/scripts/index-ops.sh" stale "$INDEX_FILE" "$INTERVAL_DAYS"
|
||||
```
|
||||
> Script path is relative to skill directory.
|
||||
|
||||
4. Queue: new + stale files
|
||||
|
||||
@@ -150,7 +147,7 @@ bash "scripts/index-ops.sh" stale "$INDEX_FILE" "$INTERVAL_DAYS"
|
||||
Task(subagent_type="brewdoc:bd-auto-sync-processor",
|
||||
prompt="PATH: {path} | TYPE: {type} | FLAGS: {flags}")
|
||||
```
|
||||
> **Context:** BD_PLUGIN_ROOT is available in your context (injected by pre-task.mjs hook).
|
||||
> **Context:** BD_PLUGIN_ROOT is injected into agent prompt by pre-task.mjs hook.
|
||||
|
||||
2. For each result:
|
||||
- If status = `updated` or `unchanged` → update INDEX `u` to today (`index-ops.sh update`)
|
||||
|
||||
@@ -35,15 +35,11 @@ Extract `--engine <name>` from anywhere in arguments if present. Remove it befor
|
||||
|
||||
## Step 1: Dependency Check
|
||||
|
||||
Resolve script paths using `$BD_PLUGIN_ROOT`:
|
||||
- `$BD_PLUGIN_ROOT/skills/md-to-pdf/scripts/check_deps.sh`
|
||||
- `$BD_PLUGIN_ROOT/skills/md-to-pdf/scripts/md_to_pdf.py`
|
||||
|
||||
Determine the target engine (from `--engine` flag, saved config, or default `reportlab`).
|
||||
|
||||
**EXECUTE** using Bash tool:
|
||||
```bash
|
||||
bash "$BD_PLUGIN_ROOT/skills/md-to-pdf/scripts/check_deps.sh" check ENGINE_NAME 2>&1; echo "EXIT_CODE=$?"
|
||||
bash "${CLAUDE_SKILL_DIR}/scripts/check_deps.sh" check ENGINE_NAME 2>&1; echo "EXIT_CODE=$?"
|
||||
```
|
||||
Replace `ENGINE_NAME` with the target engine.
|
||||
|
||||
@@ -67,7 +63,7 @@ Options:
|
||||
|
||||
If user chooses install, **EXECUTE** using Bash tool:
|
||||
```bash
|
||||
bash "$BD_PLUGIN_ROOT/skills/md-to-pdf/scripts/check_deps.sh" install ENGINE_NAME 2>&1 && echo "---INSTALL_OK---" || echo "---INSTALL_FAILED---"
|
||||
bash "${CLAUDE_SKILL_DIR}/scripts/check_deps.sh" install ENGINE_NAME 2>&1 && echo "---INSTALL_OK---" || echo "---INSTALL_FAILED---"
|
||||
```
|
||||
|
||||
> **STOP if INSTALL_FAILED** -- report error and exit.
|
||||
@@ -125,7 +121,7 @@ EXIT after printing.
|
||||
|
||||
**EXECUTE** using Bash tool:
|
||||
```bash
|
||||
python3 "$BD_PLUGIN_ROOT/skills/md-to-pdf/scripts/md_to_pdf.py" "INPUT_PATH" "OUTPUT_PATH" --engine ENGINE --quiet 2>&1 && echo "---CONVERT_OK---" || echo "---CONVERT_FAILED---"
|
||||
python3 "${CLAUDE_SKILL_DIR}/scripts/md_to_pdf.py" "INPUT_PATH" "OUTPUT_PATH" --engine ENGINE --quiet 2>&1 && echo "---CONVERT_OK---" || echo "---CONVERT_FAILED---"
|
||||
```
|
||||
Replace `INPUT_PATH`, `OUTPUT_PATH`, `ENGINE` with actual values. Add `--config CONFIG_PATH` if a style config JSON exists. Add `--pygments-theme THEME` for weasyprint if configured.
|
||||
|
||||
@@ -170,7 +166,7 @@ Report saved settings table and EXIT.
|
||||
|
||||
### TEST Mode
|
||||
|
||||
1. Use bundled test file: `$BD_PLUGIN_ROOT/skills/md-to-pdf/test/test-all-elements.md`
|
||||
1. Use bundled test file at `${CLAUDE_SKILL_DIR}/test/test-all-elements.md` as INPUT_PATH.
|
||||
2. Determine output path: `/tmp/md-to-pdf-test-ENGINE.pdf`
|
||||
3. Run converter (same command as CONVERT mode, using test file as input, `/tmp/` output).
|
||||
4. Proceed to Step 4.
|
||||
|
||||
@@ -23,11 +23,9 @@ Detect mode from `$ARGUMENTS`:
|
||||
| starts with `r ` or `research ` | RESEARCH | query = rest of args |
|
||||
|
||||
After detection, load the appropriate reference file:
|
||||
- INTERNAL: `$BD_PLUGIN_ROOT/skills/my-claude/references/internal-mode.md`
|
||||
- EXTERNAL: `$BD_PLUGIN_ROOT/skills/my-claude/references/external-mode.md`
|
||||
- RESEARCH: `$BD_PLUGIN_ROOT/skills/my-claude/references/research-mode.md`
|
||||
|
||||
> **BD_PLUGIN_ROOT** is injected by brewdoc's pre-task.mjs hook and available in your context.
|
||||
- INTERNAL: `references/internal-mode.md`
|
||||
- EXTERNAL: `references/external-mode.md`
|
||||
- RESEARCH: `references/research-mode.md`
|
||||
|
||||
## Output Directory
|
||||
|
||||
|
||||
Reference in New Issue
Block a user