Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
7a87112
docs(cw-plugin): add design + research artifacts
victorkzam Sep 16, 2026
8ffe136
feat(plugin): cw manifest, hooks.json, profile check, lean protect hooks
victorkzam Sep 16, 2026
b0e51f3
test: run.sh hook, size, dedupe and scan checks; retire the installer
victorkzam Sep 16, 2026
89b8a90
refactor(rules): one home per rule, lean workflow and orchestration f…
victorkzam Sep 16, 2026
bde46f1
refactor(agents): claude 5 model and effort matrix, lean prompts
victorkzam Sep 16, 2026
aab9b0b
refactor(skills): lean cw skills, single design document, google-work…
victorkzam Sep 16, 2026
ddccf56
docs: plugin install story, project CLAUDE.md and lean example settings
victorkzam Sep 16, 2026
bb85af9
fix(settings): enable typescript, pyright and swift LSP plugins in th…
victorkzam Sep 18, 2026
5e5c4d3
docs(fixups-1-0-0): design
victorkzam Sep 21, 2026
af0e21c
fix(rules): one trailer line per commit, no other attribution
victorkzam Sep 21, 2026
7f2cbb5
fix(readme): migration keeps Explore override, names trailer check
victorkzam Sep 21, 2026
a792436
fix(skills): one trailer line on the design commit and series check
victorkzam Sep 21, 2026
e0ffc52
test: per-commit trailer check in run.sh, wired into all and CI
victorkzam Sep 21, 2026
fafca6f
fix(hooks): disable SC2317 too on the trap-invoked finish function
victorkzam Sep 21, 2026
31b9f30
feat(rules): browser recovery rule for Claude in Chrome
victorkzam Sep 22, 2026
126f8a6
docs(hardening-1-0-0): design
victorkzam Sep 22, 2026
640b919
chore(ci): validate the plugin manifest as well as the marketplace
victorkzam Sep 22, 2026
9438f01
fix(skills): ship body via file, build reads Task blocks, implementer…
victorkzam Sep 22, 2026
01fffdd
docs: real plugin cache path, branch-guard scope, trailers in the tes…
victorkzam Sep 22, 2026
c07fdb8
fix(hooks): harden the branch guard, widen secrets patterns, compact …
victorkzam Sep 22, 2026
65cee1a
docs(cw-plugin): design reflects the hardened guard, compact source, …
victorkzam Sep 22, 2026
e075e56
docs(hardening-1-0-0): drop session residue from the plan
victorkzam Sep 22, 2026
657f2b2
fix(hooks): scope subshell cd and -C checkouts in the branch guard
victorkzam Sep 22, 2026
d3b0376
docs: three rule files, the browser rule in profile setup, model in t…
victorkzam Sep 22, 2026
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
13 changes: 13 additions & 0 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "claude-code-setup",
"owner": {
"name": "Victor Kzam"
},
"plugins": [
{
"name": "cw",
"source": "./",
"description": "Claude Code workflow plugin: design/build/ship skills, orchestration agents, and guardrail hooks."
}
]
}
17 changes: 17 additions & 0 deletions .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "cw",
"version": "1.0.0",
"description": "Claude Code workflow plugin: design/build/ship skills, orchestration agents, and guardrail hooks.",
"author": {
"name": "Victor Kzam"
},
"repository": "https://github.com/victorkzam/claude-code-setup",
"license": "MIT",
"keywords": [
"workflow",
"hooks",
"skills",
"agents",
"orchestration"
]
}
184 changes: 0 additions & 184 deletions .claude/skills/setup/SKILL.md

This file was deleted.

1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
docs/plans/** linguist-generated=true
105 changes: 65 additions & 40 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,58 +8,83 @@ on:
branches: [main]

jobs:
lint-and-test:
name: shellcheck + bats + manifest (ubuntu)
ubuntu:
name: shellcheck + jq + tests/run.sh all + plugin validate (ubuntu)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Install shellcheck
run: sudo apt-get update -y && sudo apt-get install -y shellcheck
- name: Install jq and shellcheck
run: sudo apt-get update -y && sudo apt-get install -y shellcheck jq

# Same pinned git-checkout install as the macos job below. `npm install -g
# bats` broke on the ubuntu-24.04 runner image: npm's global prefix is
# /usr/local, whose man dirs the runner user cannot mkdir (EACCES).
- name: Install bats-core from a git checkout
run: |
git clone --depth 1 --branch v1.11.0 https://github.com/bats-core/bats-core.git "$RUNNER_TEMP/bats-core"
echo "$RUNNER_TEMP/bats-core/bin" >> "$GITHUB_PATH"
- name: shellcheck hooks + tests/run.sh
run: shellcheck -x hooks/*.sh tests/run.sh

- name: validate plugin/marketplace/hooks JSON
run: jq empty .claude-plugin/plugin.json .claude-plugin/marketplace.json hooks/hooks.json

- name: shellcheck scripts + hooks
# -x: scripts/*.sh source scripts/lib.sh; a bare single-file shellcheck
# trips info-level SC1091 (can't follow non-constant/relative source).
# House convention: always lint with -x here.
#
# --severity=error: hooks/*.sh (owned by an earlier task, out of scope
# here) carry pre-existing info/warning-level nits (SC2086, SC2015,
# SC2221/2222) that are stylistic, not bugs. Gating on errors keeps this
# a real correctness gate without failing CI on unrelated existing
# style notes. Judgment call — revisit if those files get cleaned up.
run: shellcheck -x --severity=error scripts/*.sh hooks/*.sh
- name: tests/run.sh all
run: bash tests/run.sh all

- name: bats (full suite, incl. e2e)
run: bats tests/*.bats
- name: categorical prompt-hygiene greps
# Red until T3-T6 rewrite skills/agents/rules; CI only runs at push
# time, which happens after T7 (accepted by the design).
run: |
set -e
if git grep -niE 'opus needs|do not trust|be decisive|read all files fresh|claude-design-active|claude-orchestrator-active' -- skills agents rules; then
echo "gate: banned coordination phrases in prompts"
exit 1
fi
if git grep -nwE 'NEVER|ALWAYS|MUST|CRITICAL' -- skills agents rules; then
echo "gate: emphatic capitals in prompts"
exit 1
fi
if git grep -niE 'under 50 lines' -- skills agents rules; then
echo "gate: 'under 50 lines' phrase in prompts"
exit 1
fi
if git grep -nE '^(disallowedTools|permissionMode|mcpServers|hooks):' -- agents; then
echo "gate: disallowed frontmatter keys in agents"
exit 1
fi
for f in agents/*.md; do
for k in model tools effort maxTurns; do
grep -q "^$k:" "$f" || { echo "$f lacks $k:"; exit 1; }
done
done
if git grep -niE '~/.claude/plans|gitattributes|linguist|git clean' -- skills; then
echo "gate: internal-path/meta references in skills"
exit 1
fi
if ! grep -q haiku skills/design/SKILL.md; then
echo "gate: skills/design/SKILL.md missing haiku reference"
exit 1
fi
N=$(sed -n 's/^Copyright (c) [0-9]* //p' LICENSE | cut -d' ' -f1)
if [ -z "$N" ]; then
echo "gate: could not extract copyright name from LICENSE"
exit 1
fi
if git grep -qi "$N" -- skills agents rules hooks tests WORKFLOW.md CLAUDE.md docs; then
echo "gate: LICENSE-derived name leaked into prompts/docs"
exit 1
fi

- name: manifest.txt == git ls-files agents/ hooks/ rules/ skills/ (C3)
- name: install Claude Code CLI and validate plugin
run: |
diff <(git ls-files agents/ hooks/ rules/ skills/) scripts/manifest.txt
npm install -g @anthropic-ai/claude-code
claude plugin validate .
claude plugin validate .claude-plugin/plugin.json

bats-macos:
name: bats (macos system /bin/bash 3.2 + BSD userland)
macos:
name: hooks under system bash 3.2 (macos)
runs-on: macos-latest
steps:
- uses: actions/checkout@v4

# bats-core from a git checkout, invoked directly out of bin/ — NOT via
# brew. A brewed bats would pull in a modern GNU-flavored PATH/toolchain
# and mask exactly the GNUisms this job exists to catch. shellcheck is
# intentionally skipped here: the ubuntu job already lints every script.
- name: Install bats-core from a git checkout
run: |
git clone --depth 1 --branch v1.11.0 https://github.com/bats-core/bats-core.git "$RUNNER_TEMP/bats-core"
echo "$RUNNER_TEMP/bats-core/bin" >> "$GITHUB_PATH"

- name: bats (full suite, incl. e2e) under system bash
- name: tests/run.sh hooks under system /bin/bash (jq preinstalled)
run: |
echo "bash: $(command -v bash) ($(bash --version | head -n1))"
bats tests/*.bats
echo "bash: $(command -v /bin/bash) ($(/bin/bash --version | head -n1))"
/bin/bash tests/run.sh hooks
33 changes: 14 additions & 19 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,33 +19,28 @@
!skills/**
!hooks/
!hooks/**
!scripts/
!scripts/**
!tests/
!tests/**

# Allow only the project-local design-artifact directories under docs/
# (plans and research), not the whole docs/ tree. Gitignore requires
# un-ignoring each parent directory level before its children, so the
# chain below is intentionally explicit rather than a single !docs/**.
# Track the plugin manifest directory.
!.claude-plugin/
!.claude-plugin/**

# Allow the project-local design-artifact directories under docs/plans/:
# a future single-file design doc (docs/plans/<slug>.md) and this build's
# folder (docs/plans/cw-plugin/) are tracked; any other docs/plans/<other>/
# folder stays ignored. Gitignore requires un-ignoring each parent directory
# level before its children, so the chain below is intentionally explicit
# rather than a single !docs/plans/**.
!docs/
!docs/plans/
!docs/plans/**
!docs/research/
!docs/research/**
!docs/plans/*.md
!docs/plans/cw-plugin/
!docs/plans/cw-plugin/**

!.github/
!.github/**

# Allow the repo-scoped setup skill under .claude/, but nothing else in
# .claude/ (agent-memory, local settings, etc. must stay ignored). Gitignore
# requires un-ignoring each parent directory level before its children, so
# the chain below is intentionally explicit rather than a single !.claude/**.
!.claude/
!.claude/skills/
!.claude/skills/setup/
!.claude/skills/setup/**

# Never track local, personal, or generated Claude Code state, even if a
# future copy step drops it in here by mistake.
settings.json
Expand All @@ -59,5 +54,5 @@ history.jsonl
.DS_Store

# Security rail: this repo must never ship an active repo-local settings
# file, even though .claude/ is partially un-ignored above.
# file, even though other repo-local .claude paths may be tracked above.
.claude/settings.json
Loading
Loading