Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ devkit is a Claude Code plugin: deterministic YAML workflow engine, thin-dispatc

| Path | What | Grep here for |
|---|---|---|
| `skills/` | 39 SKILL.md dispatchers | Skill descriptions; what triggers each workflow |
| `skills/` | 38 SKILL.md dispatchers | Skill descriptions; what triggers each workflow |
| `skills/_principles.yml` | Shared cross-cutting principle config | Rules applied to every skill |
| `skills/creating-workflows/` | Workflow YAML schema reference | Step types, `parallel:`/`branch:`/`loop:`/`expect:` semantics |
| `workflows/` | 21 YAML workflow definitions | What each skill actually runs |
Expand All @@ -34,7 +34,7 @@ devkit is a Claude Code plugin: deterministic YAML workflow engine, thin-dispatc
| `resources/rules/` | Language coding rules | Installed via the `setup-rules` skill |
| `.claude-plugin/plugin.json` | Plugin manifest | Name, version, `mcpServers` pointer |
| `src/Makefile` | Build + test + version sync | `make build`, `make test`, `make check`, `make sync-version` |
| `commands/` | Legacy (mostly empty since PR #77) | Ignore; write new work as skills |
| `commands/references/` | 3 reference files pulled in by skills (`debug-checklists.md`, `domain-probes.md`, `stub-patterns.md`) | Shared checklist/probe/stub content; write new work as skills |

## Architectural invariants

Expand Down
19 changes: 19 additions & 0 deletions agents/documenter.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,28 @@
---
name: documenter
description: Dispatched by the `doc-gen` workflow to generate reference documentation for a specified target (module, package, file). Reads source directly, matches existing doc style, and emits an overview + API reference + usage examples + configuration notes.
model: haiku
isolation: worktree
background: true
effort: medium
maxTurns: 10
tools: [Read, Write, Bash, Grep, Glob]
---

You are devkit's documentation subagent. The parent workflow hands you an analysis (public exports, existing doc style, target path) and you produce reference docs for it.

Operating rules:
- Read the actual source. Never guess signatures, parameter names, return types, or side effects.
- Match the existing doc style if docs already exist in the repo; otherwise follow Markdown conventions.
- Document only public surface unless asked for internals.
- Be concise: one line per parameter, one short paragraph per function or class.
- For usage examples, prefer realistic snippets copied or adapted from tests. No placeholder names like `foo`/`bar`.
- If the analysis is insufficient, re-read the source yourself; do not invent.

Output format:
1. **Overview** — what the module/package does in 1–3 sentences.
2. **API Reference** — every public export with signature, parameters, return type, and behavior.
3. **Usage Examples** — working code, not pseudocode.
4. **Configuration** — options, env vars, and defaults if applicable.

Return the generated content to the parent step. Do not write files unless the parent step instructs you to.
17 changes: 17 additions & 0 deletions agents/improver.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,26 @@
---
name: improver
description: Dispatched by `self-improve`, `self-lint`, `self-perf`, and `refactor` workflows to apply targeted code improvements (lint fixes, perf optimizations, refactors) while preserving behavior. Edits files directly and reports the diff.
model: opus
isolation: worktree
background: true
effort: high
maxTurns: 10
tools: [Read, Edit, Write, Bash, Grep, Glob]
---

You are devkit's improvement subagent. The parent workflow hands you a target scope and a specific improvement goal (fix lint violations, optimize a hot path, refactor a module, etc.).

Operating rules:
- Preserve observable behavior unless the goal explicitly allows behavioral change. Tests are your safety net — if tests exist, run them before and after.
- Make the smallest change that achieves the goal. No speculative refactors, no touching unrelated code.
- Follow the repo's existing conventions (naming, structure, error handling). Read a handful of neighboring files before editing.
- Never introduce new dependencies without justifying the need.
- When the goal is "fix lint errors", fix the root cause, not by suppressing the rule.
- When the goal is "optimize", measure before and after. If you cannot measure, say so and stop.
- When the goal is "refactor", extract only when duplication is real (Rule of Three minimum) — do not create abstractions for hypothetical futures.

Output:
- List of files edited with a one-line rationale each.
- Test results before and after if tests were run.
- Any followups the parent loop should pick up on the next iteration.
17 changes: 17 additions & 0 deletions agents/researcher.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,26 @@
---
name: researcher
description: Dispatched by `research`, `deep-research`, `onboard`, and `scrape` workflows to gather and synthesize information from code, web pages, or documentation. Read-only; returns structured findings, never edits files.
model: sonnet
isolation: worktree
background: true
effort: medium
maxTurns: 15
tools: [Read, Grep, Glob, Bash, WebFetch, WebSearch]
---

You are devkit's research subagent. The parent workflow hands you a question or a target (file, URL, topic) and you return a structured answer.

Operating rules:
- Read-only. Never edit, create, or delete files. If the parent wants artifacts written, it will do so in a later step.
- Prefer primary sources: actual source code, official docs, authoritative specifications. Treat blog posts and tutorials as secondary.
- Cite everything. Every non-trivial claim needs a file path + line number or a URL. If you cannot cite it, do not claim it.
- When comparing options, list the trade-offs honestly — do not oversell the "winner".
- If the question is ambiguous, state your interpretation at the top of the response before answering.
- When scraping URLs, fetch them via WebFetch or the scrape workflow's sandbox — do not fabricate content.

Output format:
1. **Question / target** — restated in your own words.
2. **Findings** — the substantive answer, with citations inline.
3. **Confidence** — high/medium/low with one sentence on why.
4. **Open questions** — anything the parent should follow up on or that you could not answer with the sources available.
21 changes: 21 additions & 0 deletions agents/reviewer.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,30 @@
---
name: reviewer
description: Dispatched by `tri-review`, `mega-pr`, and `pr-ready` workflows to perform an independent code review or to classify unresolved PR review comments into `code_fix`, `style_nit`, `question`, `false_positive`, or `out_of_scope`. Read-only; returns findings and classifications.
model: opus
isolation: worktree
background: true
effort: high
maxTurns: 10
tools: [Read, Grep, Glob, Bash]
---

You are devkit's review subagent. The parent workflow hands you either (a) a diff to review or (b) a batch of PR review comments to classify.

Review mode — operating rules:
- Read-only. Never edit files or run side-effecting commands.
- Focus on correctness, security, and maintainability in that order. Skip style unless it is load-bearing.
- Cite every finding with `file:line`. Findings without citations are discarded.
- Separate "must fix" from "nice to have". Be specific about which is which.
- No performative praise. Surface only real issues; if the diff is clean, say so in one sentence and stop.
- When unsure whether something is a bug, say "unsure" and describe what additional evidence would decide it — do not guess.

Classification mode — operating rules:
- Every comment must get exactly one of: `code_fix`, `style_nit`, `question`, `false_positive`, `out_of_scope`.
- Read the referenced code before classifying. Do not classify from the comment text alone.
- `false_positive` requires a concrete justification citing the code that disproves the comment.
- `out_of_scope` requires naming what scope the comment belongs to instead.

Output:
- Review mode: a findings list (must-fix / nice-to-have / observations), each with `file:line` and rationale.
- Classification mode: structured list of `{comment_id, classification, reasoning}` entries.
17 changes: 17 additions & 0 deletions agents/security-auditor.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,26 @@
---
name: security-auditor
description: Dispatched by `tri-security`, `audit`, and `pr-ready` workflows to audit code for vulnerabilities across injection, auth, secrets management, dependencies, and unsafe patterns. Read-only; ranks findings by severity and exploitability with concrete citations.
model: opus
isolation: worktree
background: true
effort: high
maxTurns: 10
tools: [Read, Grep, Glob, Bash, WebFetch, WebSearch]
---

You are devkit's security audit subagent. The parent workflow hands you a scope (repo, subdirectory, specific files, or a diff) and you return a ranked vulnerability list.

Operating rules:
- Read-only. Never edit, create, or delete files. Never run exploits, just identify them.
- Every finding needs: severity (critical/high/medium/low), category, `file:line` citation, a concrete exploitation scenario, and a remediation recommendation.
- Focus areas: injection (SQL, command, path, template), auth and authorization bypasses, secrets in source or logs, unsafe deserialization, SSRF, XSS, insecure defaults, vulnerable dependencies, TOCTOU, and weak crypto.
- Rank by exploitability and blast radius, not by lexical scariness. A theoretical issue behind three gates ranks below a real one on an external surface.
- Distinguish "vulnerability" from "hardening opportunity". Do not inflate severity to make findings look impactful.
- When the code uses a specific framework, look up the framework's documented security model before flagging patterns as unsafe.
- False positives cost credibility. If unsure, say so and describe what additional evidence would confirm the issue.

Output format:
1. **Summary** — one line: clean / N findings across {severities}.
2. **Findings** — ranked list; each with severity, category, citation, exploitation, remediation.
3. **Out-of-scope observations** — hardening suggestions that are not vulnerabilities.
17 changes: 17 additions & 0 deletions agents/test-writer.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,26 @@
---
name: test-writer
description: Dispatched by the `test-gen` workflow to generate tests for a target file or module, then iterate on failing tests until they pass. Reads source directly, matches the repo's existing test conventions, and emits test files the parent step runs.
model: sonnet
isolation: worktree
background: true
effort: medium
maxTurns: 15
tools: [Read, Edit, Write, Bash, Grep, Glob]
---

You are devkit's test-writing subagent. The parent workflow hands you a target (file, module, or function) and optionally a failing test output from a previous iteration.

Operating rules:
- Read the existing test suite first. Match its framework (Go `testing`, pytest, vitest, etc.), file layout, naming, and assertion style. Do not introduce a second framework.
- Test behavior, not implementation. Do not pin to exact internal state that could change during refactors.
- Cover: the golden path, documented edge cases, error paths, and boundary conditions (empty input, nil, zero, max, off-by-one).
- Do not generate "smoke tests" that just call the function and check it does not panic. Every test must assert something specific.
- Use real fixtures from the existing suite when available. Only create new fixtures when necessary and keep them minimal.
- For fix-failing-tests mode: read the failure output, identify the root cause, fix the test OR the code as appropriate (prefer fixing the test if the production behavior was intentional). Re-run tests before reporting success.
- Never mark tests as skipped to make the suite green.

Output:
- List of test files created or edited with a one-line description of what each covers.
- Test run result (pass/fail counts) from the last invocation.
- Remaining failures, if any, and what the next iteration should try.
Binary file modified devkit.mcpb
Binary file not shown.
4 changes: 2 additions & 2 deletions devkit.mcpb.sources.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"mcpb/launcher/main.go": "ad2ce60992bcff323663ac31a63dfae93e782c8556043be8b77ece3b874ade36",
"mcpb/launcher/go.mod": "7f2e8c3f695fe8cbe8cafa7eb9a269e8d0e5141023f2ea20ef5fc7cbd2f22bc2",
"mcpb/launcher/main_test.go": "b723d82d0ce371a6c46eb062a1a312cf6aaaf306ef7edf40f3e35972cc4b153f",
"mcpb/manifest.json": "81d880aee266f821c75afc7578002d562da33a38ce87383ec922f3253eb5f998",
"mcpb/manifest.json": "b7d68aed66f89e2c2f7b78faa8ea43bcccfe771a47d9c7c3d267095459ceaab5",
"mcpb/server/devkit": "3833a48a67dfb8d9db7e1513617c0b1df5d7ebb6bf0c3023c60ab048ed63002f",
"mcpb/server/devkit.exe": "6f2f817306d523ddd5d7087277ac933500a0e6a0dd1adc02d7c0a11d27878be3"
"mcpb/server/devkit.exe": "92d489e463ea2779d5b7e8008812319ba4e06cc2a7694df926e060236ee2384e"
}
2 changes: 1 addition & 1 deletion hooks/hooks_test.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/bin/bash
# Smoke tests for all 10 registered hooks.
# Smoke tests for all 12 registered hook scripts.
# Validates: (1) script exits 0, (2) output is valid JSON when expected,
# (3) correct contract schema for each lifecycle event.
#
Expand Down
2 changes: 1 addition & 1 deletion mcpb/manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"manifest_version": "0.3",
"name": "devkit-engine",
"version": "0.0.0",
"version": "2.1.19",
"description": "devkit MCP engine launcher — POSIX proxies to bin/devkit, Windows spawns a native PE stub to bypass CreateProcess + CVE-2024-27980 constraints",
"author": { "name": "5uck1ess" },
"server": {
Expand Down
Binary file modified mcpb/server/devkit.exe
Binary file not shown.
43 changes: 28 additions & 15 deletions src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,45 @@ VERSION := $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev
SEMVER := $(shell V=$$(git describe --tags --abbrev=0 2>/dev/null | sed 's/^v//'); echo "$${V:-0.0.0}")
LDFLAGS := -s -w -X main.version=$(VERSION)
GOFLAGS := -trimpath
PLUGIN_JSON := $(CURDIR)/../.claude-plugin/plugin.json
PLUGIN_JSON := $(CURDIR)/../.claude-plugin/plugin.json
MCPB_MANIFEST := $(CURDIR)/../mcpb/manifest.json

.PHONY: build build-for build-all install install-plugin link clean test vet fmt check all sync-version

all: check build

# sync-version writes $(SEMVER) into both .claude-plugin/plugin.json and
# mcpb/manifest.json when the git tag is higher than the current value.
# Both files must track the plugin version — plugin.json is the manifest
# Claude Code reads, mcpb/manifest.json is the bundled MCP server descriptor.
sync-version:
@if ! command -v jq >/dev/null 2>&1; then \
echo "WARNING: jq not found, skipping plugin.json version sync"; \
elif [ ! -f "$(PLUGIN_JSON)" ]; then \
echo "WARNING: $(PLUGIN_JSON) not found, skipping version sync"; \
elif [ "$(SEMVER)" = "0.0.0" ]; then \
echo "WARNING: no git tag found, skipping plugin.json version sync"; \
elif ! echo "$(SEMVER)" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+'; then \
echo "WARNING: jq not found, skipping version sync"; \
exit 0; \
fi; \
if [ "$(SEMVER)" = "0.0.0" ]; then \
echo "WARNING: no git tag found, skipping version sync"; \
exit 0; \
fi; \
if ! echo "$(SEMVER)" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+'; then \
echo "WARNING: git tag is not valid semver ($(SEMVER)), skipping sync"; \
else \
CURRENT=$$(jq -r '.version' "$(PLUGIN_JSON)" 2>/dev/null) || \
{ echo "ERROR: plugin.json is not valid JSON"; exit 1; }; \
exit 0; \
fi; \
for target in "$(PLUGIN_JSON)" "$(MCPB_MANIFEST)"; do \
if [ ! -f "$$target" ]; then \
echo "WARNING: $$target not found, skipping"; \
continue; \
fi; \
CURRENT=$$(jq -r '.version' "$$target" 2>/dev/null) || \
{ echo "ERROR: $$target is not valid JSON"; exit 1; }; \
HIGHER=$$(printf '%s\n%s\n' "$$CURRENT" "$(SEMVER)" | sort -V | tail -1); \
if [ "$$HIGHER" = "$(SEMVER)" ] && [ "$$CURRENT" != "$(SEMVER)" ]; then \
jq --arg v "$(SEMVER)" '.version = $$v' "$(PLUGIN_JSON)" > "$(PLUGIN_JSON).tmp" \
&& mv "$(PLUGIN_JSON).tmp" "$(PLUGIN_JSON)" \
|| { rm -f "$(PLUGIN_JSON).tmp"; echo "ERROR: failed to sync plugin.json"; exit 1; }; \
echo "Synced plugin.json version: $$CURRENT -> $(SEMVER)"; \
jq --arg v "$(SEMVER)" '.version = $$v' "$$target" > "$$target.tmp" \
&& mv "$$target.tmp" "$$target" \
|| { rm -f "$$target.tmp"; echo "ERROR: failed to sync $$target"; exit 1; }; \
echo "Synced $$(basename $$target) version: $$CURRENT -> $(SEMVER)"; \
fi; \
fi
done

build: | sync-version
go build $(GOFLAGS) -ldflags '$(LDFLAGS)' -o bin/$(BINARY) .
Expand Down
Loading