code-warden 3.1.1 → 3.3.0
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/CONFIGURE.md +39 -39
- package/DECISIONS.md +107 -107
- package/README.md +199 -137
- package/SKILL.md +169 -169
- package/bin/code-warden.js +82 -0
- package/codewarden.json +14 -14
- package/examples/governed-session.md +132 -132
- package/install.js +399 -399
- package/install.ps1 +32 -32
- package/install.sh +33 -33
- package/package.json +45 -2
- package/references/anti-drift.md +55 -55
- package/references/architecture.md +26 -26
- package/references/cleanup.md +30 -30
- package/references/cognition.md +36 -36
- package/references/operations.md +45 -45
- package/references/planning-gates.md +83 -83
- package/references/research-and-fit.md +51 -51
- package/references/safety.md +31 -31
- package/templates/ci/github-actions.yml +83 -66
- package/tools/auto-detect.js +91 -91
- package/tools/auto-targets.js +104 -104
- package/tools/auto-windsurf-adapter.js +75 -75
- package/tools/get-context.js +50 -50
- package/tools/governance-report.js +302 -0
- package/tools/hooks/claude/install-hooks.js +112 -112
- package/tools/hooks/claude/uninstall-hooks.js +75 -75
- package/tools/hooks/claude/warden-lint-hook.js +106 -106
- package/tools/hooks/claude/warden-secrets-hook.js +73 -73
- package/tools/hooks/codex/install-hooks.js +100 -100
- package/tools/hooks/codex/uninstall-hooks.js +53 -53
- package/tools/hooks/codex/warden-apply-patch-hook.js +113 -113
- package/tools/hooks/codex/warden-bash-hook.js +51 -51
- package/tools/lib/config.js +49 -49
- package/tools/lib/file-collection.js +72 -72
- package/tools/lib/line-count.js +28 -28
- package/tools/lib/secret-patterns.js +57 -57
- package/tools/tests/fixtures/clean.js +9 -9
- package/tools/tests/run-tests.js +210 -210
- package/tools/verify-secrets.js +26 -26
- package/tools/warden-lint.js +27 -27
|
@@ -1,83 +1,83 @@
|
|
|
1
|
-
# Planning Gates
|
|
2
|
-
|
|
3
|
-
Two mandatory declaration blocks that fire before implementation begins.
|
|
4
|
-
Neither is a checklist — they are structured outputs the AI produces and
|
|
5
|
-
the user confirms before any code is written.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## Scope Gate
|
|
10
|
-
|
|
11
|
-
Fires when: a new session begins, scope is ambiguous, or a request would
|
|
12
|
-
touch files outside the current declared scope.
|
|
13
|
-
|
|
14
|
-
**AI produces this block. User confirms before proceeding.**
|
|
15
|
-
|
|
16
|
-
```
|
|
17
|
-
SCOPE GATE
|
|
18
|
-
|
|
19
|
-
Goal: [One sentence — what this session will accomplish]
|
|
20
|
-
Non-goals: [What is explicitly out of scope for this session]
|
|
21
|
-
Files in: [Complete list of files the AI expects to read or modify]
|
|
22
|
-
Files out: [Files that must not be touched, with reason]
|
|
23
|
-
Verify after: [The exact commands that will confirm success]
|
|
24
|
-
Rollback: [One-step revert — e.g. git checkout HEAD -- <files>]
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
Rules:
|
|
28
|
-
- Goal must be one sentence. If it cannot be, split into multiple sessions.
|
|
29
|
-
- Files-in list is a contract. Any unlisted file requires a new Scope Gate
|
|
30
|
-
or explicit user approval before it is touched.
|
|
31
|
-
- Rollback must be a concrete command, not "undo manually."
|
|
32
|
-
- If any field is unknown, write `[UNKNOWN — user must provide]` and halt.
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
## Plan Gate
|
|
37
|
-
|
|
38
|
-
Fires when: the session will touch more than one file, or any single change
|
|
39
|
-
exceeds 30 lines.
|
|
40
|
-
|
|
41
|
-
**AI produces this block after Scope Gate is confirmed. User confirms before any edits.**
|
|
42
|
-
|
|
43
|
-
```
|
|
44
|
-
PLAN GATE
|
|
45
|
-
|
|
46
|
-
Patch order:
|
|
47
|
-
1. <file> — <one-line description of change>
|
|
48
|
-
2. <file> — <one-line description of change>
|
|
49
|
-
...
|
|
50
|
-
|
|
51
|
-
Blast radius class: [CONTAINED | MODERATE | HIGH]
|
|
52
|
-
CONTAINED — changes isolated to declared files, no interface changes
|
|
53
|
-
MODERATE — shared interfaces or types modified, downstream callers may need updates
|
|
54
|
-
HIGH — data-flow changes, schema changes, or deletions of public APIs
|
|
55
|
-
|
|
56
|
-
Human checkpoint: [YES | NO]
|
|
57
|
-
YES if: blast radius is MODERATE or HIGH, or more than 2 files are touched.
|
|
58
|
-
|
|
59
|
-
Post-patch checks:
|
|
60
|
-
After step 1: [command or verification]
|
|
61
|
-
After step 2: [command or verification]
|
|
62
|
-
After all: [final verification suite]
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
Rules:
|
|
66
|
-
- Patch order is sequential. Do not parallelise edits across files unless
|
|
67
|
-
confirmed safe and explicitly approved.
|
|
68
|
-
- Blast radius class must be declared before the first edit, not assessed after.
|
|
69
|
-
- If Human Checkpoint is YES, pause after the last patch and output
|
|
70
|
-
`[AWAITING CONFIRMATION]` before marking the task complete.
|
|
71
|
-
- Post-patch checks must be concrete commands, not "verify it works."
|
|
72
|
-
|
|
73
|
-
---
|
|
74
|
-
|
|
75
|
-
## Gate Failure Response
|
|
76
|
-
|
|
77
|
-
If either gate cannot be completed:
|
|
78
|
-
|
|
79
|
-
1. State which field is blocking and why.
|
|
80
|
-
2. Ask for the minimum information needed to fill it.
|
|
81
|
-
3. Do not produce partial gates. Do not proceed without both gates confirmed.
|
|
82
|
-
|
|
83
|
-
A partial plan is not a plan. Implement nothing until both gates are signed off.
|
|
1
|
+
# Planning Gates
|
|
2
|
+
|
|
3
|
+
Two mandatory declaration blocks that fire before implementation begins.
|
|
4
|
+
Neither is a checklist — they are structured outputs the AI produces and
|
|
5
|
+
the user confirms before any code is written.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Scope Gate
|
|
10
|
+
|
|
11
|
+
Fires when: a new session begins, scope is ambiguous, or a request would
|
|
12
|
+
touch files outside the current declared scope.
|
|
13
|
+
|
|
14
|
+
**AI produces this block. User confirms before proceeding.**
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
SCOPE GATE
|
|
18
|
+
|
|
19
|
+
Goal: [One sentence — what this session will accomplish]
|
|
20
|
+
Non-goals: [What is explicitly out of scope for this session]
|
|
21
|
+
Files in: [Complete list of files the AI expects to read or modify]
|
|
22
|
+
Files out: [Files that must not be touched, with reason]
|
|
23
|
+
Verify after: [The exact commands that will confirm success]
|
|
24
|
+
Rollback: [One-step revert — e.g. git checkout HEAD -- <files>]
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Rules:
|
|
28
|
+
- Goal must be one sentence. If it cannot be, split into multiple sessions.
|
|
29
|
+
- Files-in list is a contract. Any unlisted file requires a new Scope Gate
|
|
30
|
+
or explicit user approval before it is touched.
|
|
31
|
+
- Rollback must be a concrete command, not "undo manually."
|
|
32
|
+
- If any field is unknown, write `[UNKNOWN — user must provide]` and halt.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Plan Gate
|
|
37
|
+
|
|
38
|
+
Fires when: the session will touch more than one file, or any single change
|
|
39
|
+
exceeds 30 lines.
|
|
40
|
+
|
|
41
|
+
**AI produces this block after Scope Gate is confirmed. User confirms before any edits.**
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
PLAN GATE
|
|
45
|
+
|
|
46
|
+
Patch order:
|
|
47
|
+
1. <file> — <one-line description of change>
|
|
48
|
+
2. <file> — <one-line description of change>
|
|
49
|
+
...
|
|
50
|
+
|
|
51
|
+
Blast radius class: [CONTAINED | MODERATE | HIGH]
|
|
52
|
+
CONTAINED — changes isolated to declared files, no interface changes
|
|
53
|
+
MODERATE — shared interfaces or types modified, downstream callers may need updates
|
|
54
|
+
HIGH — data-flow changes, schema changes, or deletions of public APIs
|
|
55
|
+
|
|
56
|
+
Human checkpoint: [YES | NO]
|
|
57
|
+
YES if: blast radius is MODERATE or HIGH, or more than 2 files are touched.
|
|
58
|
+
|
|
59
|
+
Post-patch checks:
|
|
60
|
+
After step 1: [command or verification]
|
|
61
|
+
After step 2: [command or verification]
|
|
62
|
+
After all: [final verification suite]
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Rules:
|
|
66
|
+
- Patch order is sequential. Do not parallelise edits across files unless
|
|
67
|
+
confirmed safe and explicitly approved.
|
|
68
|
+
- Blast radius class must be declared before the first edit, not assessed after.
|
|
69
|
+
- If Human Checkpoint is YES, pause after the last patch and output
|
|
70
|
+
`[AWAITING CONFIRMATION]` before marking the task complete.
|
|
71
|
+
- Post-patch checks must be concrete commands, not "verify it works."
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Gate Failure Response
|
|
76
|
+
|
|
77
|
+
If either gate cannot be completed:
|
|
78
|
+
|
|
79
|
+
1. State which field is blocking and why.
|
|
80
|
+
2. Ask for the minimum information needed to fill it.
|
|
81
|
+
3. Do not produce partial gates. Do not proceed without both gates confirmed.
|
|
82
|
+
|
|
83
|
+
A partial plan is not a plan. Implement nothing until both gates are signed off.
|
|
@@ -1,51 +1,51 @@
|
|
|
1
|
-
# Research and Fit
|
|
2
|
-
|
|
3
|
-
## Live Research Gate
|
|
4
|
-
|
|
5
|
-
Do not rely on model training data when a decision depends on current facts.
|
|
6
|
-
Run live research first when the task involves:
|
|
7
|
-
- Current package versions, APIs, pricing, licenses, limits, or deprecations.
|
|
8
|
-
- Framework, runtime, cloud, database, or platform recommendations.
|
|
9
|
-
- Security, legal, policy, compliance, or financial claims.
|
|
10
|
-
- Recently released tools, libraries, models, protocols, or standards.
|
|
11
|
-
- Anything the user describes as latest, current, modern, today, new, or changed.
|
|
12
|
-
|
|
13
|
-
Research standard:
|
|
14
|
-
- Prefer official docs, release notes, standards, or source repositories.
|
|
15
|
-
- Use registry metadata for package versions and license facts.
|
|
16
|
-
- Capture the date-sensitive fact, source, and date accessed in the response or decision log.
|
|
17
|
-
- If live research is unavailable, say so and treat the claim as unverified.
|
|
18
|
-
|
|
19
|
-
## Default-Pattern Challenge
|
|
20
|
-
|
|
21
|
-
Before choosing a stack, architecture, or product shape, challenge familiar defaults.
|
|
22
|
-
Do not pick Node, Next.js, React, a SaaS dashboard, CRUD admin, or auth-first app
|
|
23
|
-
unless the project context makes that choice fit.
|
|
24
|
-
|
|
25
|
-
Required fit check:
|
|
26
|
-
- User goal: what is the thing being built?
|
|
27
|
-
- Primary user: who uses it and under what constraints?
|
|
28
|
-
- Runtime/environment: browser, desktop, mobile, server, embedded, game engine, CLI, or hybrid.
|
|
29
|
-
- Data shape: static, local-first, collaborative, realtime, batch, transactional, analytical, or media-heavy.
|
|
30
|
-
- Interaction shape: workflow tool, creative tool, game, simulation, content site, dashboard, automation, API, or library.
|
|
31
|
-
- Operational constraints: deployment target, offline needs, privacy, performance, budget, and maintenance burden.
|
|
32
|
-
|
|
33
|
-
## Recommendation Discipline
|
|
34
|
-
|
|
35
|
-
When recommending an approach over alternatives:
|
|
36
|
-
- Name at least two viable alternatives unless the user already chose the stack.
|
|
37
|
-
- Explain why the chosen approach fits the project's constraints better.
|
|
38
|
-
- Identify the main tradeoff or downside.
|
|
39
|
-
- Do not optimize for what is easiest for the model to generate.
|
|
40
|
-
|
|
41
|
-
## Product-Shape Guardrail
|
|
42
|
-
|
|
43
|
-
Do not assume every app is a SaaS dashboard.
|
|
44
|
-
Match the first screen and navigation to the domain:
|
|
45
|
-
- Operational tools can be dense and workflow-first.
|
|
46
|
-
- Creative tools should put the canvas or creation surface first.
|
|
47
|
-
- Games should open on the playable loop, not a marketing page.
|
|
48
|
-
- Content sites should prioritize the content object or story.
|
|
49
|
-
- Developer tools should expose the core command, API, or artifact early.
|
|
50
|
-
|
|
51
|
-
If the shape is unclear, make a small fit assessment before designing or coding.
|
|
1
|
+
# Research and Fit
|
|
2
|
+
|
|
3
|
+
## Live Research Gate
|
|
4
|
+
|
|
5
|
+
Do not rely on model training data when a decision depends on current facts.
|
|
6
|
+
Run live research first when the task involves:
|
|
7
|
+
- Current package versions, APIs, pricing, licenses, limits, or deprecations.
|
|
8
|
+
- Framework, runtime, cloud, database, or platform recommendations.
|
|
9
|
+
- Security, legal, policy, compliance, or financial claims.
|
|
10
|
+
- Recently released tools, libraries, models, protocols, or standards.
|
|
11
|
+
- Anything the user describes as latest, current, modern, today, new, or changed.
|
|
12
|
+
|
|
13
|
+
Research standard:
|
|
14
|
+
- Prefer official docs, release notes, standards, or source repositories.
|
|
15
|
+
- Use registry metadata for package versions and license facts.
|
|
16
|
+
- Capture the date-sensitive fact, source, and date accessed in the response or decision log.
|
|
17
|
+
- If live research is unavailable, say so and treat the claim as unverified.
|
|
18
|
+
|
|
19
|
+
## Default-Pattern Challenge
|
|
20
|
+
|
|
21
|
+
Before choosing a stack, architecture, or product shape, challenge familiar defaults.
|
|
22
|
+
Do not pick Node, Next.js, React, a SaaS dashboard, CRUD admin, or auth-first app
|
|
23
|
+
unless the project context makes that choice fit.
|
|
24
|
+
|
|
25
|
+
Required fit check:
|
|
26
|
+
- User goal: what is the thing being built?
|
|
27
|
+
- Primary user: who uses it and under what constraints?
|
|
28
|
+
- Runtime/environment: browser, desktop, mobile, server, embedded, game engine, CLI, or hybrid.
|
|
29
|
+
- Data shape: static, local-first, collaborative, realtime, batch, transactional, analytical, or media-heavy.
|
|
30
|
+
- Interaction shape: workflow tool, creative tool, game, simulation, content site, dashboard, automation, API, or library.
|
|
31
|
+
- Operational constraints: deployment target, offline needs, privacy, performance, budget, and maintenance burden.
|
|
32
|
+
|
|
33
|
+
## Recommendation Discipline
|
|
34
|
+
|
|
35
|
+
When recommending an approach over alternatives:
|
|
36
|
+
- Name at least two viable alternatives unless the user already chose the stack.
|
|
37
|
+
- Explain why the chosen approach fits the project's constraints better.
|
|
38
|
+
- Identify the main tradeoff or downside.
|
|
39
|
+
- Do not optimize for what is easiest for the model to generate.
|
|
40
|
+
|
|
41
|
+
## Product-Shape Guardrail
|
|
42
|
+
|
|
43
|
+
Do not assume every app is a SaaS dashboard.
|
|
44
|
+
Match the first screen and navigation to the domain:
|
|
45
|
+
- Operational tools can be dense and workflow-first.
|
|
46
|
+
- Creative tools should put the canvas or creation surface first.
|
|
47
|
+
- Games should open on the playable loop, not a marketing page.
|
|
48
|
+
- Content sites should prioritize the content object or story.
|
|
49
|
+
- Developer tools should expose the core command, API, or artifact early.
|
|
50
|
+
|
|
51
|
+
If the shape is unclear, make a small fit assessment before designing or coding.
|
package/references/safety.md
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
# Execution and Safety
|
|
2
|
-
|
|
3
|
-
## Blast Radius Check
|
|
4
|
-
|
|
5
|
-
Before deleting or rewriting any working code, define:
|
|
6
|
-
1. **What might break** - list affected modules and interfaces.
|
|
7
|
-
2. **How it will be tested** - specific test strategy or smoke test.
|
|
8
|
-
3. **Rollback procedure** - one-step command or revert method.
|
|
9
|
-
|
|
10
|
-
Example: `git checkout HEAD -- path/to/file`
|
|
11
|
-
|
|
12
|
-
Never skip for any rewrite touching core logic.
|
|
13
|
-
|
|
14
|
-
## Patch-First Editing
|
|
15
|
-
|
|
16
|
-
- Prefer diff/patch edits over full file rewrites.
|
|
17
|
-
- Only rewrite an entire file when structural changes affect >50% of its content.
|
|
18
|
-
- All full rewrites require a Blast Radius Check first.
|
|
19
|
-
- Surgical edits reduce accidental deletions, regression bugs, and context loss.
|
|
20
|
-
|
|
21
|
-
## Zero-Trust Secrets
|
|
22
|
-
|
|
23
|
-
- Never generate code with hardcoded API keys, passwords, tokens, or placeholder secrets.
|
|
24
|
-
- Always default to environment variables such as `.env` or secure vault implementations.
|
|
25
|
-
- No "TODO: replace later" escape hatches. Ever.
|
|
26
|
-
|
|
27
|
-
## Dependency Freeze
|
|
28
|
-
|
|
29
|
-
- Before any structural changes, list all current dependency versions.
|
|
30
|
-
- Do not silently upgrade packages during a refactor.
|
|
31
|
-
- Flag outdated dependencies separately. Do not fix without explicit confirmation.
|
|
1
|
+
# Execution and Safety
|
|
2
|
+
|
|
3
|
+
## Blast Radius Check
|
|
4
|
+
|
|
5
|
+
Before deleting or rewriting any working code, define:
|
|
6
|
+
1. **What might break** - list affected modules and interfaces.
|
|
7
|
+
2. **How it will be tested** - specific test strategy or smoke test.
|
|
8
|
+
3. **Rollback procedure** - one-step command or revert method.
|
|
9
|
+
|
|
10
|
+
Example: `git checkout HEAD -- path/to/file`
|
|
11
|
+
|
|
12
|
+
Never skip for any rewrite touching core logic.
|
|
13
|
+
|
|
14
|
+
## Patch-First Editing
|
|
15
|
+
|
|
16
|
+
- Prefer diff/patch edits over full file rewrites.
|
|
17
|
+
- Only rewrite an entire file when structural changes affect >50% of its content.
|
|
18
|
+
- All full rewrites require a Blast Radius Check first.
|
|
19
|
+
- Surgical edits reduce accidental deletions, regression bugs, and context loss.
|
|
20
|
+
|
|
21
|
+
## Zero-Trust Secrets
|
|
22
|
+
|
|
23
|
+
- Never generate code with hardcoded API keys, passwords, tokens, or placeholder secrets.
|
|
24
|
+
- Always default to environment variables such as `.env` or secure vault implementations.
|
|
25
|
+
- No "TODO: replace later" escape hatches. Ever.
|
|
26
|
+
|
|
27
|
+
## Dependency Freeze
|
|
28
|
+
|
|
29
|
+
- Before any structural changes, list all current dependency versions.
|
|
30
|
+
- Do not silently upgrade packages during a refactor.
|
|
31
|
+
- Flag outdated dependencies separately. Do not fix without explicit confirmation.
|
|
@@ -1,66 +1,83 @@
|
|
|
1
|
-
# Code-Warden Quality Gate — Project Template
|
|
2
|
-
# https://github.com/Kodaxadev/Code-Warden
|
|
3
|
-
#
|
|
4
|
-
# Copy this file to .github/workflows/code-warden.yml in your project.
|
|
5
|
-
#
|
|
6
|
-
# What it enforces:
|
|
7
|
-
# - File length limits (
|
|
8
|
-
# - Zero-trust secrets (
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
- name:
|
|
63
|
-
run:
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
1
|
+
# Code-Warden Quality Gate — Project Template
|
|
2
|
+
# https://github.com/Kodaxadev/Code-Warden
|
|
3
|
+
#
|
|
4
|
+
# Copy this file to .github/workflows/code-warden.yml in your project.
|
|
5
|
+
#
|
|
6
|
+
# What it enforces:
|
|
7
|
+
# - File length limits (default 400 lines per codewarden.json)
|
|
8
|
+
# - Zero-trust secrets (hardcoded-credential patterns)
|
|
9
|
+
# - Behavioral tests (scanner and hook pass/fail verification)
|
|
10
|
+
# - Source integrity (required files present)
|
|
11
|
+
#
|
|
12
|
+
# What it produces:
|
|
13
|
+
# - .code-warden-report.json — machine-readable governance artifact
|
|
14
|
+
# - Markdown summary on the workflow run / PR (via GITHUB_STEP_SUMMARY)
|
|
15
|
+
# - Uploaded artifact for audit trail (90-day retention)
|
|
16
|
+
#
|
|
17
|
+
# How code-warden is made available in CI (choose one):
|
|
18
|
+
#
|
|
19
|
+
# Option A — Download from release (recommended, no files to commit)
|
|
20
|
+
# Set CODE_WARDEN_VERSION below to pin a specific release.
|
|
21
|
+
# The "Install Code-Warden" step downloads and extracts automatically.
|
|
22
|
+
#
|
|
23
|
+
# Option B — Commit to your repo
|
|
24
|
+
# Run: node /path/to/code-warden/install.js --target=claude
|
|
25
|
+
# Add .claude/skills/code-warden/ to git tracking.
|
|
26
|
+
# Set CODE_WARDEN_PATH: .claude/skills/code-warden
|
|
27
|
+
# Remove the "Install Code-Warden" step.
|
|
28
|
+
#
|
|
29
|
+
# Customise thresholds in codewarden.json after install:
|
|
30
|
+
# max_file_length (default 400 lines)
|
|
31
|
+
# pre_flight_trigger_lines (default 150 lines)
|
|
32
|
+
# human_checkpoint_files (default 2 files)
|
|
33
|
+
|
|
34
|
+
name: Code-Warden Quality Gate
|
|
35
|
+
|
|
36
|
+
on:
|
|
37
|
+
push:
|
|
38
|
+
branches: [main, master]
|
|
39
|
+
pull_request:
|
|
40
|
+
branches: [main, master]
|
|
41
|
+
|
|
42
|
+
env:
|
|
43
|
+
CODE_WARDEN_VERSION: v3.2.0
|
|
44
|
+
CODE_WARDEN_PATH: .code-warden-ci
|
|
45
|
+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
|
46
|
+
|
|
47
|
+
jobs:
|
|
48
|
+
code-warden:
|
|
49
|
+
name: Code-Warden Quality Gate
|
|
50
|
+
runs-on: ubuntu-latest
|
|
51
|
+
|
|
52
|
+
steps:
|
|
53
|
+
- name: Checkout
|
|
54
|
+
uses: actions/checkout@v4
|
|
55
|
+
|
|
56
|
+
- name: Setup Node.js
|
|
57
|
+
uses: actions/setup-node@v4
|
|
58
|
+
with:
|
|
59
|
+
node-version: '24'
|
|
60
|
+
|
|
61
|
+
# Option A: download from GitHub release (remove if using Option B)
|
|
62
|
+
- name: Install Code-Warden
|
|
63
|
+
run: |
|
|
64
|
+
curl -fsSL -o cw.zip \
|
|
65
|
+
"https://github.com/Kodaxadev/Code-Warden/releases/download/${{ env.CODE_WARDEN_VERSION }}/code-warden-${{ env.CODE_WARDEN_VERSION }}.zip"
|
|
66
|
+
mkdir -p ${{ env.CODE_WARDEN_PATH }}
|
|
67
|
+
unzip -q cw.zip -d ${{ env.CODE_WARDEN_PATH }}
|
|
68
|
+
|
|
69
|
+
- name: Governance report
|
|
70
|
+
run: node ${{ env.CODE_WARDEN_PATH }}/tools/governance-report.js .
|
|
71
|
+
|
|
72
|
+
- name: Publish governance summary
|
|
73
|
+
if: always()
|
|
74
|
+
run: node ${{ env.CODE_WARDEN_PATH }}/tools/governance-report.js . --format=md >> $GITHUB_STEP_SUMMARY
|
|
75
|
+
|
|
76
|
+
- name: Upload governance artifact
|
|
77
|
+
if: always()
|
|
78
|
+
uses: actions/upload-artifact@v4
|
|
79
|
+
with:
|
|
80
|
+
name: code-warden-report
|
|
81
|
+
path: .code-warden-report.json
|
|
82
|
+
if-no-files-found: ignore
|
|
83
|
+
retention-days: 90
|
package/tools/auto-detect.js
CHANGED
|
@@ -1,91 +1,91 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* auto-detect.js
|
|
4
|
-
* Detection logic for the code-warden auto-installer.
|
|
5
|
-
* Exports scanTargets(targets) -> targets annotated with detected/method fields.
|
|
6
|
-
*
|
|
7
|
-
* Detection order per target:
|
|
8
|
-
* 1. Binary found in PATH (where / which)
|
|
9
|
-
* 2. Config directory exists in HOME
|
|
10
|
-
* 3. App install path exists (platform-specific)
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
const fs = require('fs');
|
|
14
|
-
const { execSync } = require('child_process');
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Returns true if a CLI binary is resolvable via PATH.
|
|
18
|
-
* Uses 'where' on Windows, 'which' on Unix.
|
|
19
|
-
*/
|
|
20
|
-
function commandExists(bin) {
|
|
21
|
-
try {
|
|
22
|
-
const cmd = process.platform === 'win32' ? `where ${bin}` : `which ${bin}`;
|
|
23
|
-
execSync(cmd, { stdio: 'ignore' });
|
|
24
|
-
return true;
|
|
25
|
-
} catch {
|
|
26
|
-
return false;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Returns true if a path exists and is a directory.
|
|
32
|
-
*/
|
|
33
|
-
function dirExists(p) {
|
|
34
|
-
try {
|
|
35
|
-
return fs.existsSync(p) && fs.statSync(p).isDirectory();
|
|
36
|
-
} catch {
|
|
37
|
-
return false;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Returns true if a path exists (file or directory).
|
|
43
|
-
*/
|
|
44
|
-
function pathExists(p) {
|
|
45
|
-
try {
|
|
46
|
-
return fs.existsSync(p);
|
|
47
|
-
} catch {
|
|
48
|
-
return false;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Checks all detection signals for a single target.
|
|
54
|
-
* Returns { detected: boolean, method: string|null }
|
|
55
|
-
*/
|
|
56
|
-
function isInstalled(target) {
|
|
57
|
-
for (const bin of (target.detect.binaries || [])) {
|
|
58
|
-
if (commandExists(bin)) {
|
|
59
|
-
return { detected: true, method: `binary:${bin}` };
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
for (const dir of (target.detect.dirs || [])) {
|
|
64
|
-
if (dirExists(dir)) {
|
|
65
|
-
return { detected: true, method: `dir:${dir}` };
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const platformApps = (target.detect.apps || {})[process.platform] || [];
|
|
70
|
-
for (const appPath of platformApps) {
|
|
71
|
-
if (pathExists(appPath)) {
|
|
72
|
-
return { detected: true, method: `app:${appPath}` };
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return { detected: false, method: null };
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Scans all targets and annotates each with detection results.
|
|
81
|
-
* @param {Array} targets - TARGETS array from auto-targets.js
|
|
82
|
-
* @returns {Array} - same array with detected and method fields added
|
|
83
|
-
*/
|
|
84
|
-
function scanTargets(targets) {
|
|
85
|
-
return targets.map(target => {
|
|
86
|
-
const result = isInstalled(target);
|
|
87
|
-
return { ...target, ...result };
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
module.exports = { scanTargets, isInstalled, commandExists };
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* auto-detect.js
|
|
4
|
+
* Detection logic for the code-warden auto-installer.
|
|
5
|
+
* Exports scanTargets(targets) -> targets annotated with detected/method fields.
|
|
6
|
+
*
|
|
7
|
+
* Detection order per target:
|
|
8
|
+
* 1. Binary found in PATH (where / which)
|
|
9
|
+
* 2. Config directory exists in HOME
|
|
10
|
+
* 3. App install path exists (platform-specific)
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
const { execSync } = require('child_process');
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Returns true if a CLI binary is resolvable via PATH.
|
|
18
|
+
* Uses 'where' on Windows, 'which' on Unix.
|
|
19
|
+
*/
|
|
20
|
+
function commandExists(bin) {
|
|
21
|
+
try {
|
|
22
|
+
const cmd = process.platform === 'win32' ? `where ${bin}` : `which ${bin}`;
|
|
23
|
+
execSync(cmd, { stdio: 'ignore' });
|
|
24
|
+
return true;
|
|
25
|
+
} catch {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Returns true if a path exists and is a directory.
|
|
32
|
+
*/
|
|
33
|
+
function dirExists(p) {
|
|
34
|
+
try {
|
|
35
|
+
return fs.existsSync(p) && fs.statSync(p).isDirectory();
|
|
36
|
+
} catch {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Returns true if a path exists (file or directory).
|
|
43
|
+
*/
|
|
44
|
+
function pathExists(p) {
|
|
45
|
+
try {
|
|
46
|
+
return fs.existsSync(p);
|
|
47
|
+
} catch {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Checks all detection signals for a single target.
|
|
54
|
+
* Returns { detected: boolean, method: string|null }
|
|
55
|
+
*/
|
|
56
|
+
function isInstalled(target) {
|
|
57
|
+
for (const bin of (target.detect.binaries || [])) {
|
|
58
|
+
if (commandExists(bin)) {
|
|
59
|
+
return { detected: true, method: `binary:${bin}` };
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
for (const dir of (target.detect.dirs || [])) {
|
|
64
|
+
if (dirExists(dir)) {
|
|
65
|
+
return { detected: true, method: `dir:${dir}` };
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const platformApps = (target.detect.apps || {})[process.platform] || [];
|
|
70
|
+
for (const appPath of platformApps) {
|
|
71
|
+
if (pathExists(appPath)) {
|
|
72
|
+
return { detected: true, method: `app:${appPath}` };
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return { detected: false, method: null };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Scans all targets and annotates each with detection results.
|
|
81
|
+
* @param {Array} targets - TARGETS array from auto-targets.js
|
|
82
|
+
* @returns {Array} - same array with detected and method fields added
|
|
83
|
+
*/
|
|
84
|
+
function scanTargets(targets) {
|
|
85
|
+
return targets.map(target => {
|
|
86
|
+
const result = isInstalled(target);
|
|
87
|
+
return { ...target, ...result };
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
module.exports = { scanTargets, isInstalled, commandExists };
|