From 0ab83f2429a7172675ae00ff23458ce0c94af3d8 Mon Sep 17 00:00:00 2001
From: Kodaxa
Date: Sat, 16 May 2026 10:10:33 -0700
Subject: [PATCH] fix: handle EPERM on restricted directories, add quickstart
to README
- collectFiles now skips unreadable directories/files instead of crashing
- Add Quickstart section and npm badge to root README
- Add contributor npx note to inner README
- Bump to 3.3.1
Co-Authored-By: Claude Opus 4.6
---
CHANGELOG.md | 11 +++++++++++
README.md | 22 ++++++++++++++++++++++
code-warden/README.md | 6 ++++++
code-warden/package.json | 2 +-
code-warden/tools/lib/file-collection.js | 7 +++++--
5 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3bf10c2..099bc0b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,17 @@ Versions follow [Semantic Versioning](https://semver.org/).
---
+## v3.3.1 — 2026-05-16
+
+**Hardening + quickstart polish.**
+
+- Fixed `EPERM` crash when scanning directories with restricted permissions (Windows `WinSAT`, etc.) — `collectFiles` now skips unreadable directories and files instead of throwing
+- Added npm badge to root README
+- Added Quickstart section at top of root README: `npx code-warden init`, `report`, `hooks`
+- Added contributor note about `npx` local-package conflict in source checkouts
+
+---
+
## v3.3.0 — 2026-05-16
**npm package + CLI quickstart.**
diff --git a/README.md b/README.md
index f90aa0c..e51edb7 100644
--- a/README.md
+++ b/README.md
@@ -8,12 +8,34 @@
+
+
+
+## Quickstart
+
+```bash
+npx code-warden init
+```
+
+Generate a governance report:
+
+```bash
+npx code-warden report
+```
+
+Enable hard hooks where supported:
+
+```bash
+npx code-warden hooks claude
+npx code-warden hooks codex
+```
+
## Who This Is For
**Code-Warden is for when AI coding stops being autocomplete and starts being delegated work.**
diff --git a/code-warden/README.md b/code-warden/README.md
index 19f74e2..65dcca7 100644
--- a/code-warden/README.md
+++ b/code-warden/README.md
@@ -194,6 +194,12 @@ See [`CONFIGURE.md`](CONFIGURE.md) for team-size profiles and tuning rationale.
| `references/operations.md` | Verification, source-control hygiene, dependency control |
| `references/research-and-fit.md` | Live research gate, stack fit, product-shape guardrails |
+## Note for contributors
+
+> If testing `npx code-warden` from inside the Code-Warden source checkout,
+> npm may prefer the local package context. Test from a separate directory for
+> the same behavior users will see.
+
## Author
Justin Davis — MIT License
diff --git a/code-warden/package.json b/code-warden/package.json
index 5042d64..1398456 100644
--- a/code-warden/package.json
+++ b/code-warden/package.json
@@ -1,6 +1,6 @@
{
"name": "code-warden",
- "version": "3.3.0",
+ "version": "3.3.1",
"description": "Verifiable governance for AI-assisted development — checks, hooks, and evidence.",
"main": "SKILL.md",
"bin": {
diff --git a/code-warden/tools/lib/file-collection.js b/code-warden/tools/lib/file-collection.js
index c5d4e6b..1531ef7 100644
--- a/code-warden/tools/lib/file-collection.js
+++ b/code-warden/tools/lib/file-collection.js
@@ -30,10 +30,13 @@ const SKIP_EXTS = new Set([
* @param {string[]} results - accumulator (mutated)
*/
function collectFiles(dir, results) {
- for (const entry of fs.readdirSync(dir)) {
+ let entries;
+ try { entries = fs.readdirSync(dir); } catch { return; }
+ for (const entry of entries) {
if (SKIP_DIRS.has(entry)) continue;
const full = path.join(dir, entry);
- const stat = fs.statSync(full);
+ let stat;
+ try { stat = fs.statSync(full); } catch { continue; }
if (stat.isDirectory()) {
collectFiles(full, results);
} else if (!SKIP_EXTS.has(path.extname(entry).toLowerCase())) {