vigiles 3.0.0 → 4.0.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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +2 -2
- package/README.md +14 -12
- package/action.yml +3 -3
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +384 -159
- package/dist/setup-plan.d.ts +47 -7
- package/dist/setup-plan.js +104 -29
- package/package.json +1 -1
- package/skills/audit-feedback-loop/SKILL.md +0 -76
- package/skills/enforce-rules-format/SKILL.md +0 -71
- package/skills/generate-logo/SKILL.md +0 -103
- package/skills/pr-to-lint-rule/SKILL.md +0 -97
package/dist/setup-plan.d.ts
CHANGED
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
*/
|
|
11
11
|
/** What `vigiles init` will set up. */
|
|
12
12
|
export interface SetupPlan {
|
|
13
|
-
/**
|
|
14
|
-
|
|
15
|
-
/**
|
|
13
|
+
/** Lint pillar — verify instruction-file references (specs, types, compile, lint/audit, hooks). */
|
|
14
|
+
lint: boolean;
|
|
15
|
+
/** Test pillar — test the harness (scaffold a starter harness test + CI job). */
|
|
16
16
|
test: boolean;
|
|
17
17
|
/** Wire CI (the `zernie/vigiles@v1` Action; creates a workflow if none). */
|
|
18
18
|
gha: boolean;
|
|
@@ -26,11 +26,17 @@ export interface ParsedSetupArgs {
|
|
|
26
26
|
target?: string;
|
|
27
27
|
strict: boolean;
|
|
28
28
|
yes: boolean;
|
|
29
|
-
|
|
29
|
+
/** Lint pillar — `--lint` → true, `--no-lint` → false, absent → undefined. */
|
|
30
|
+
lint?: boolean;
|
|
31
|
+
/** Test pillar — `--test` → true, `--no-test` → false, absent → undefined. */
|
|
32
|
+
test?: boolean;
|
|
33
|
+
/** `--harness=claude,codex` override (empty = auto-detect). */
|
|
34
|
+
harness?: string;
|
|
30
35
|
gha?: boolean;
|
|
31
36
|
plugin?: boolean;
|
|
32
37
|
}
|
|
33
|
-
/** Parse `init` args into the choices the user pinned.
|
|
38
|
+
/** Parse `init` args into the choices the user pinned. The two pillars are
|
|
39
|
+
* selected with `--lint` / `--test`. */
|
|
34
40
|
export declare function parseSetupArgs(args: readonly string[]): ParsedSetupArgs;
|
|
35
41
|
/** The non-interactive defaults: both pillars, CI, and the plugin. */
|
|
36
42
|
export declare function defaultPlan(strict?: boolean): SetupPlan;
|
|
@@ -41,11 +47,45 @@ export declare function defaultPlan(strict?: boolean): SetupPlan;
|
|
|
41
47
|
*/
|
|
42
48
|
export declare function shouldPrompt(parsed: ParsedSetupArgs, isTTY: boolean): boolean;
|
|
43
49
|
/** Interactive answers (only the fields the prompts cover). */
|
|
44
|
-
export type SetupAnswers = Partial<Pick<SetupPlan, "
|
|
50
|
+
export type SetupAnswers = Partial<Pick<SetupPlan, "lint" | "test" | "gha" | "plugin">>;
|
|
51
|
+
/**
|
|
52
|
+
* How to install vigiles's skills/hooks for ONE harness — the deterministic
|
|
53
|
+
* decision behind the IO in cli.ts, so a CI test asserts WHICH commands an
|
|
54
|
+
* install runs without a network call or a real `claude`/`codex` binary.
|
|
55
|
+
*
|
|
56
|
+
* The method is genuinely harness-specific: Claude Code has a GLOBAL plugin
|
|
57
|
+
* marketplace (installs to ~/.claude/plugins/, nothing in the repo); Codex has
|
|
58
|
+
* no global store — its config is repo-committed (`.codex/`, AGENTS.md), so its
|
|
59
|
+
* instructions are read directly and skills are an opt-in, repo-local concern.
|
|
60
|
+
*/
|
|
61
|
+
export interface InstallPlan {
|
|
62
|
+
harness: string;
|
|
63
|
+
/** Shell commands to auto-run (empty = nothing runnable here). */
|
|
64
|
+
commands: string[];
|
|
65
|
+
/** One-line success message printed after the commands run. */
|
|
66
|
+
successMessage: string;
|
|
67
|
+
/** The equivalent commands a user runs by hand (printed on failure / no-CLI). */
|
|
68
|
+
manualSteps: string[];
|
|
69
|
+
/** Always-printed informational lines (where it installs, caveats). */
|
|
70
|
+
notes: string[];
|
|
71
|
+
/** Whether this method writes files into the consumer's repo (vendoring). */
|
|
72
|
+
vendors: boolean;
|
|
73
|
+
}
|
|
74
|
+
/** Per-harness install plan. `hasClaude` gates the auto-run `claude plugin` CLI
|
|
75
|
+
* (else the same two steps are printed as `/plugin` slash commands).
|
|
76
|
+
*
|
|
77
|
+
* Both methods install GLOBALLY, never into the repo: Claude through its plugin
|
|
78
|
+
* marketplace (~/.claude/plugins/), Codex through the cross-agent `skills` CLI
|
|
79
|
+
* with `-g -y` (the global store ~/.agents/skills/, which Codex reads). Codex
|
|
80
|
+
* gets the skills but NOT hooks — Codex hook wiring (.codex/config.toml [hooks])
|
|
81
|
+
* is not automated yet. */
|
|
82
|
+
export declare function planPluginInstall(harnesses: readonly string[], opts: {
|
|
83
|
+
hasClaude: boolean;
|
|
84
|
+
}): InstallPlan[];
|
|
45
85
|
/**
|
|
46
86
|
* Resolve the final plan: defaults, then flags, then interactive answers (each
|
|
47
87
|
* layer overrides the previous only where it has an opinion). `--target` pins a
|
|
48
|
-
* bare
|
|
88
|
+
* bare lint-pillar spec (no harness scaffold).
|
|
49
89
|
*/
|
|
50
90
|
export declare function resolvePlan(parsed: ParsedSetupArgs, answers?: SetupAnswers): SetupPlan;
|
|
51
91
|
//# sourceMappingURL=setup-plan.d.ts.map
|
package/dist/setup-plan.js
CHANGED
|
@@ -13,28 +13,36 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
13
13
|
exports.parseSetupArgs = parseSetupArgs;
|
|
14
14
|
exports.defaultPlan = defaultPlan;
|
|
15
15
|
exports.shouldPrompt = shouldPrompt;
|
|
16
|
+
exports.planPluginInstall = planPluginInstall;
|
|
16
17
|
exports.resolvePlan = resolvePlan;
|
|
17
18
|
function flagValue(args, prefix) {
|
|
18
19
|
return args.find((a) => a.startsWith(prefix))?.slice(prefix.length);
|
|
19
20
|
}
|
|
20
|
-
/**
|
|
21
|
+
/** `--name` → true, `--no-name` → false, neither present → undefined. */
|
|
22
|
+
function boolFlag(args, name) {
|
|
23
|
+
if (args.includes(`--${name}`))
|
|
24
|
+
return true;
|
|
25
|
+
if (args.includes(`--no-${name}`))
|
|
26
|
+
return false;
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
/** Parse `init` args into the choices the user pinned. The two pillars are
|
|
30
|
+
* selected with `--lint` / `--test`. */
|
|
21
31
|
function parseSetupArgs(args) {
|
|
22
|
-
const pillarsRaw = flagValue(args, "--pillars=");
|
|
23
|
-
const pillars = pillarsRaw === "verify" || pillarsRaw === "test" || pillarsRaw === "both"
|
|
24
|
-
? pillarsRaw
|
|
25
|
-
: undefined;
|
|
26
32
|
return {
|
|
27
33
|
target: flagValue(args, "--target="),
|
|
28
34
|
strict: args.includes("--strict"),
|
|
29
35
|
yes: args.includes("--yes") || args.includes("-y"),
|
|
30
|
-
|
|
36
|
+
lint: boolFlag(args, "lint"),
|
|
37
|
+
test: boolFlag(args, "test"),
|
|
38
|
+
harness: flagValue(args, "--harness="),
|
|
31
39
|
gha: args.includes("--no-gha") ? false : undefined,
|
|
32
40
|
plugin: args.includes("--no-plugin") ? false : undefined,
|
|
33
41
|
};
|
|
34
42
|
}
|
|
35
43
|
/** The non-interactive defaults: both pillars, CI, and the plugin. */
|
|
36
44
|
function defaultPlan(strict = false) {
|
|
37
|
-
return {
|
|
45
|
+
return { lint: true, test: true, gha: true, plugin: true, strict };
|
|
38
46
|
}
|
|
39
47
|
/**
|
|
40
48
|
* Whether to drop into interactive prompts: a human at a TTY who passed neither
|
|
@@ -44,42 +52,109 @@ function defaultPlan(strict = false) {
|
|
|
44
52
|
function shouldPrompt(parsed, isTTY) {
|
|
45
53
|
if (!isTTY || parsed.yes || parsed.target)
|
|
46
54
|
return false;
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
parsed.plugin !== undefined;
|
|
55
|
+
const pillarsPinned = parsed.lint !== undefined || parsed.test !== undefined;
|
|
56
|
+
const allPinned = pillarsPinned && parsed.gha !== undefined && parsed.plugin !== undefined;
|
|
50
57
|
return !allPinned;
|
|
51
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Apply the pillar flags. A positive flag (`--lint` and/or `--test`) is an
|
|
61
|
+
* explicit SELECTION — enable exactly the named pillars. Otherwise default to
|
|
62
|
+
* both and let a `--no-*` flag drop one.
|
|
63
|
+
*/
|
|
64
|
+
function applyPillarFlags(plan, parsed) {
|
|
65
|
+
if (parsed.lint === true || parsed.test === true) {
|
|
66
|
+
plan.lint = parsed.lint === true;
|
|
67
|
+
plan.test = parsed.test === true;
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (parsed.lint === false)
|
|
71
|
+
plan.lint = false;
|
|
72
|
+
if (parsed.test === false)
|
|
73
|
+
plan.test = false;
|
|
74
|
+
}
|
|
75
|
+
function applyAnswers(plan, answers) {
|
|
76
|
+
if (answers.lint !== undefined)
|
|
77
|
+
plan.lint = answers.lint;
|
|
78
|
+
if (answers.test !== undefined)
|
|
79
|
+
plan.test = answers.test;
|
|
80
|
+
if (answers.gha !== undefined)
|
|
81
|
+
plan.gha = answers.gha;
|
|
82
|
+
if (answers.plugin !== undefined)
|
|
83
|
+
plan.plugin = answers.plugin;
|
|
84
|
+
}
|
|
85
|
+
/** Per-harness install plan. `hasClaude` gates the auto-run `claude plugin` CLI
|
|
86
|
+
* (else the same two steps are printed as `/plugin` slash commands).
|
|
87
|
+
*
|
|
88
|
+
* Both methods install GLOBALLY, never into the repo: Claude through its plugin
|
|
89
|
+
* marketplace (~/.claude/plugins/), Codex through the cross-agent `skills` CLI
|
|
90
|
+
* with `-g -y` (the global store ~/.agents/skills/, which Codex reads). Codex
|
|
91
|
+
* gets the skills but NOT hooks — Codex hook wiring (.codex/config.toml [hooks])
|
|
92
|
+
* is not automated yet. */
|
|
93
|
+
function planPluginInstall(harnesses, opts) {
|
|
94
|
+
return harnesses.map((harness) => {
|
|
95
|
+
if (harness === "claude") {
|
|
96
|
+
return {
|
|
97
|
+
harness,
|
|
98
|
+
commands: opts.hasClaude
|
|
99
|
+
? [
|
|
100
|
+
"claude plugin marketplace add zernie/vigiles",
|
|
101
|
+
"claude plugin install vigiles@vigiles",
|
|
102
|
+
]
|
|
103
|
+
: [],
|
|
104
|
+
successMessage: "✓ Installed the vigiles plugin (hooks + skills) into ~/.claude/plugins/",
|
|
105
|
+
manualSteps: [
|
|
106
|
+
"/plugin marketplace add zernie/vigiles",
|
|
107
|
+
"/plugin install vigiles@vigiles",
|
|
108
|
+
],
|
|
109
|
+
notes: [
|
|
110
|
+
"Installs globally to ~/.claude/plugins/ — nothing is added to your repo.",
|
|
111
|
+
],
|
|
112
|
+
vendors: false,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
if (harness === "codex") {
|
|
116
|
+
// The cross-agent `skills` CLI with `-g -y` installs to the global store
|
|
117
|
+
// ~/.agents/skills/ (NOT the repo, and NOT ~/.codex/ — verified against
|
|
118
|
+
// the real CLI). Skills only; Codex hooks (.codex/config.toml [hooks])
|
|
119
|
+
// are not wired automatically.
|
|
120
|
+
return {
|
|
121
|
+
harness,
|
|
122
|
+
commands: ["npx --yes skills add zernie/vigiles -a codex -g -y"],
|
|
123
|
+
successMessage: "✓ Installed the vigiles skills into ~/.agents/skills/ (global, not vendored)",
|
|
124
|
+
manualSteps: ["npx skills add zernie/vigiles -a codex -g -y"],
|
|
125
|
+
notes: [
|
|
126
|
+
"Codex reads AGENTS.md directly; the skills install globally to ~/.agents/skills/ (not the repo).",
|
|
127
|
+
"Codex hooks (.codex/config.toml [hooks]) are not auto-wired yet — add them manually for compile-on-edit.",
|
|
128
|
+
],
|
|
129
|
+
vendors: false,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
harness,
|
|
134
|
+
commands: [],
|
|
135
|
+
successMessage: "",
|
|
136
|
+
manualSteps: [],
|
|
137
|
+
notes: [`No plugin install path for harness '${harness}'.`],
|
|
138
|
+
vendors: false,
|
|
139
|
+
};
|
|
140
|
+
});
|
|
141
|
+
}
|
|
52
142
|
/**
|
|
53
143
|
* Resolve the final plan: defaults, then flags, then interactive answers (each
|
|
54
144
|
* layer overrides the previous only where it has an opinion). `--target` pins a
|
|
55
|
-
* bare
|
|
145
|
+
* bare lint-pillar spec (no harness scaffold).
|
|
56
146
|
*/
|
|
57
147
|
function resolvePlan(parsed, answers) {
|
|
58
148
|
const plan = defaultPlan(parsed.strict);
|
|
59
|
-
|
|
60
|
-
plan.verify = true;
|
|
61
|
-
plan.test = false;
|
|
62
|
-
}
|
|
63
|
-
else if (parsed.pillars === "test") {
|
|
64
|
-
plan.verify = false;
|
|
65
|
-
plan.test = true;
|
|
66
|
-
}
|
|
149
|
+
applyPillarFlags(plan, parsed);
|
|
67
150
|
if (parsed.gha === false)
|
|
68
151
|
plan.gha = false;
|
|
69
152
|
if (parsed.plugin === false)
|
|
70
153
|
plan.plugin = false;
|
|
71
154
|
if (parsed.target)
|
|
72
155
|
plan.test = false;
|
|
73
|
-
if (answers)
|
|
74
|
-
|
|
75
|
-
plan.verify = answers.verify;
|
|
76
|
-
if (answers.test !== undefined)
|
|
77
|
-
plan.test = answers.test;
|
|
78
|
-
if (answers.gha !== undefined)
|
|
79
|
-
plan.gha = answers.gha;
|
|
80
|
-
if (answers.plugin !== undefined)
|
|
81
|
-
plan.plugin = answers.plugin;
|
|
82
|
-
}
|
|
156
|
+
if (answers)
|
|
157
|
+
applyAnswers(plan, answers);
|
|
83
158
|
return plan;
|
|
84
159
|
}
|
|
85
160
|
//# sourceMappingURL=setup-plan.js.map
|
package/package.json
CHANGED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: audit-feedback-loop
|
|
3
|
-
description: Scan the current repo and score its feedback loop maturity for AI-assisted development
|
|
4
|
-
disable-model-invocation: true
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
Scan the current repository and score its feedback loop maturity for AI-assisted development.
|
|
8
|
-
|
|
9
|
-
## Instructions
|
|
10
|
-
|
|
11
|
-
Analyze this repository and score its **feedback loop maturity** using the levels below. Check for each signal, then output a summary report.
|
|
12
|
-
|
|
13
|
-
### Maturity Levels
|
|
14
|
-
|
|
15
|
-
**Level 0 — Vibes**
|
|
16
|
-
No CI config, no linter rules, no CLAUDE.md. The AI agent is flying blind.
|
|
17
|
-
|
|
18
|
-
**Level 1 — Guardrails**
|
|
19
|
-
Has CI + standard linters, but no custom rules. The agent gets basic feedback but can't learn project-specific conventions.
|
|
20
|
-
|
|
21
|
-
**Level 2 — Architecture as Code**
|
|
22
|
-
Has custom lint rules, CLAUDE.md rules have enforcement annotations. The agent gets rich, project-specific feedback.
|
|
23
|
-
|
|
24
|
-
**Level 3 — The Organism**
|
|
25
|
-
Has CI + custom rules + screenshot/visual tests + observability + scheduled agent tasks. The entire development loop is instrumented.
|
|
26
|
-
|
|
27
|
-
### Signals to Check
|
|
28
|
-
|
|
29
|
-
Scan the repository for the following and note which exist:
|
|
30
|
-
|
|
31
|
-
1. **CI Configuration**: Look for `.github/workflows/`, `.circleci/`, `Jenkinsfile`, `.gitlab-ci.yml`, `bitbucket-pipelines.yml`, `.travis.yml`, etc.
|
|
32
|
-
2. **Linter Config** (language-aware):
|
|
33
|
-
- **JS/TS**: `eslint.config.*`, `.eslintrc*`, `biome.json`, `.prettierrc*`, `deno.json`
|
|
34
|
-
- **Python**: `pyproject.toml` (look for `[tool.ruff]`, `[tool.pylint]`, `[tool.flake8]`), `setup.cfg`, `.flake8`, `ruff.toml`
|
|
35
|
-
- **Rust**: `clippy.toml`, `.clippy.toml`, `rustfmt.toml`
|
|
36
|
-
- **Go**: `.golangci.yml`, `.golangci.yaml`
|
|
37
|
-
- **Ruby**: `.rubocop.yml`
|
|
38
|
-
- **Java/Kotlin**: `checkstyle.xml`, `pmd.xml`, `detekt.yml`
|
|
39
|
-
3. **Custom Lint Rules**: Look for custom plugins, rule directories, or inline rule definitions in linter configs
|
|
40
|
-
- JS/TS: `eslint-plugin-*`, `eslint-rules/` directories
|
|
41
|
-
- Python: custom Ruff/Pylint plugins, AST-based checks
|
|
42
|
-
- Rust: custom Clippy lints
|
|
43
|
-
- Go: custom analyzers
|
|
44
|
-
4. **CLAUDE.md**: Check if `CLAUDE.md` exists at the repo root
|
|
45
|
-
5. **CLAUDE.md Enforcement**: Check if using vigiles v2 specs (`CLAUDE.md.spec.ts` exists) or v1 annotations (`**Enforced by:**` in CLAUDE.md). v2 specs = higher maturity.
|
|
46
|
-
6. **Type-Safe Specs**: Check for `CLAUDE.md.spec.ts` or `*.spec.ts` files — indicates typed spec compilation via vigiles v2
|
|
47
|
-
7. **Generated Types**: Check for `.vigiles/generated.d.ts` — indicates linter rules are type-checked at authoring time
|
|
48
|
-
8. **Screenshot/Visual Tests**: Look for Playwright (`playwright.config.*`), Cypress (`cypress.config.*`), Chromatic, Percy, BackstopJS configs
|
|
49
|
-
9. **Observability**: Search for imports/usage of `@sentry/`, `dd-trace`, `@datadog/`, `newrelic`, `@opentelemetry/`, `sentry_sdk`, `structlog`, `tracing` (Rust), `opentelemetry` in source files
|
|
50
|
-
10. **Scheduled Agent Tasks**: Look for cron patterns in CI configs, `.github/workflows/` with `schedule:` triggers, or references to scheduled Claude Code tasks
|
|
51
|
-
|
|
52
|
-
### Output Format
|
|
53
|
-
|
|
54
|
-
```
|
|
55
|
-
## Feedback Loop Audit
|
|
56
|
-
|
|
57
|
-
**Repository:** <repo name>
|
|
58
|
-
**Primary language(s):** <detected languages>
|
|
59
|
-
**Score: Level X — <Name>**
|
|
60
|
-
|
|
61
|
-
### Signals Found
|
|
62
|
-
- [x] CI Configuration: <details>
|
|
63
|
-
- [ ] Custom Lint Rules: not found
|
|
64
|
-
- [x] CLAUDE.md: found, 5 enforced / 2 guidance / 1 missing
|
|
65
|
-
...
|
|
66
|
-
|
|
67
|
-
### Recommendations
|
|
68
|
-
1. <Most impactful next step to level up>
|
|
69
|
-
2. <Second recommendation>
|
|
70
|
-
3. <Third recommendation>
|
|
71
|
-
|
|
72
|
-
### How to Level Up
|
|
73
|
-
<Specific, actionable advice for reaching the next maturity level>
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
Be specific about file paths and what you found. Give actionable recommendations tailored to the project's language and toolchain.
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: enforce-rules-format
|
|
3
|
-
description: Validate that all rules have proper enforcement classification (enforce/check/guidance)
|
|
4
|
-
disable-model-invocation: true
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
Validate that every rule in the project's instruction files has a proper enforcement classification, and fix any that are missing.
|
|
8
|
-
|
|
9
|
-
## Instructions
|
|
10
|
-
|
|
11
|
-
### Step 1: Detect Format
|
|
12
|
-
|
|
13
|
-
Check which format the project uses:
|
|
14
|
-
|
|
15
|
-
**v2 (spec-based):** Look for `CLAUDE.md.spec.ts` or any `*.spec.ts` files. If found, this is a v2 project — rules must use `enforce()`, `check()`, or `guidance()`.
|
|
16
|
-
|
|
17
|
-
**v1 (hand-written):** Look for `CLAUDE.md`, `AGENTS.md`, `.cursorrules`. If found without a spec file, this is a v1 project — rules need `**Enforced by:**` or `**Guidance only**` annotations.
|
|
18
|
-
|
|
19
|
-
### Step 2: Validate
|
|
20
|
-
|
|
21
|
-
**For v2 specs:**
|
|
22
|
-
|
|
23
|
-
The TypeScript type system already prevents unannotated rules — you can't create a rule without calling `enforce()`, `check()`, or `guidance()`. So focus on:
|
|
24
|
-
|
|
25
|
-
1. Do `enforce()` rules reference real linter rules? Run `npx vigiles compile` to check.
|
|
26
|
-
2. Are there guidance rules that COULD be `enforce()`? Check linter configs for matching rules.
|
|
27
|
-
3. Are there `check()` assertions that could be delegated to a linter? Suggest `enforce()` instead.
|
|
28
|
-
|
|
29
|
-
```bash
|
|
30
|
-
npx vigiles compile
|
|
31
|
-
npx vigiles discover
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
**For v1 hand-written files:**
|
|
35
|
-
|
|
36
|
-
Scan for `###` headings. Each must have one of:
|
|
37
|
-
|
|
38
|
-
- `**Enforced by:** \`linter/rule-name\``
|
|
39
|
-
- `**Guidance only** — reason`
|
|
40
|
-
- `<!-- vigiles-disable -->`
|
|
41
|
-
|
|
42
|
-
Report missing annotations with a summary table.
|
|
43
|
-
|
|
44
|
-
### Step 3: Fix Issues
|
|
45
|
-
|
|
46
|
-
For each issue found:
|
|
47
|
-
|
|
48
|
-
1. Check the project's linter configuration for matching rules
|
|
49
|
-
2. Suggest `enforce("linter/rule")` (v2) or `**Enforced by:** \`linter/rule\`` (v1)
|
|
50
|
-
3. If no linter rule exists, suggest `guidance()` (v2) or `**Guidance only**` (v1)
|
|
51
|
-
4. **Ask the user** before making changes
|
|
52
|
-
|
|
53
|
-
### Step 4: Suggest Migration
|
|
54
|
-
|
|
55
|
-
If the project uses v1 format, suggest migrating to v2 specs for type safety:
|
|
56
|
-
|
|
57
|
-
> Your rules could benefit from type-safe specs. Run the `migrate-to-spec` skill to convert your CLAUDE.md to a typed .spec.ts file.
|
|
58
|
-
|
|
59
|
-
### Step 5: Verify
|
|
60
|
-
|
|
61
|
-
Run the appropriate command:
|
|
62
|
-
|
|
63
|
-
```bash
|
|
64
|
-
# v2
|
|
65
|
-
npx vigiles compile && npx vigiles check
|
|
66
|
-
|
|
67
|
-
# validate
|
|
68
|
-
npx vigiles check
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
Report the validation result.
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: generate-logo
|
|
3
|
-
description: Generate or iterate on the vigiles logo using ImageRouter API
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Generate Logo
|
|
7
|
-
|
|
8
|
-
Generate logo variations for vigiles using the ImageRouter API (imagerouter.io).
|
|
9
|
-
|
|
10
|
-
## Setup
|
|
11
|
-
|
|
12
|
-
Get an API key from https://imagerouter.io/api-keys. Pass it as an argument or set `IMAGEROUTER_API_KEY` env var. Do NOT commit the key.
|
|
13
|
-
|
|
14
|
-
## API
|
|
15
|
-
|
|
16
|
-
```
|
|
17
|
-
Endpoint: https://api.imagerouter.io/v1/openai/images/generations
|
|
18
|
-
Auth: Bearer token in Authorization header
|
|
19
|
-
Method: POST, Content-Type: application/json
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
### Request body
|
|
23
|
-
|
|
24
|
-
```json
|
|
25
|
-
{
|
|
26
|
-
"prompt": "...",
|
|
27
|
-
"model": "google/nano-banana-2",
|
|
28
|
-
"quality": "high",
|
|
29
|
-
"size": "1024x1024",
|
|
30
|
-
"response_format": "url",
|
|
31
|
-
"output_format": "png"
|
|
32
|
-
}
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
### Available models (image generation)
|
|
36
|
-
|
|
37
|
-
List models: `GET https://api.imagerouter.io/v1/models`
|
|
38
|
-
|
|
39
|
-
Known good models:
|
|
40
|
-
|
|
41
|
-
- `google/nano-banana-2` — best quality, $0.07/image
|
|
42
|
-
- `google/nano-banana-2:free` — free tier
|
|
43
|
-
- `openai/gpt-image-1` — OpenAI's image model
|
|
44
|
-
- `black-forest-labs/FLUX-1.1-pro` — FLUX pro
|
|
45
|
-
|
|
46
|
-
### Response
|
|
47
|
-
|
|
48
|
-
```json
|
|
49
|
-
{
|
|
50
|
-
"created": 1775430873,
|
|
51
|
-
"data": [{ "url": "https://storage.imagerouter.io/..." }],
|
|
52
|
-
"cost": 0.069,
|
|
53
|
-
"latency": 27627
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
Download the image from the URL in `data[0].url`.
|
|
58
|
-
|
|
59
|
-
## Current logo
|
|
60
|
-
|
|
61
|
-
The current logo (`logo.png`) is v6: overlapping translucent flame petals on dark background, amber-orange palette. Generated with `google/nano-banana-2`.
|
|
62
|
-
|
|
63
|
-
### Prompt that produced it
|
|
64
|
-
|
|
65
|
-
```
|
|
66
|
-
A premium, refined logo icon for a developer tool called vigiles that compiles
|
|
67
|
-
typed TypeScript specs to AI instruction files. Inspired by OpenAI geometric aesthetic and Apple
|
|
68
|
-
minimalism. A single abstract geometric shape: an upward-pointing flame composed
|
|
69
|
-
of 3 overlapping translucent rounded shapes, creating depth through overlap —
|
|
70
|
-
similar to how the OpenAI logo uses overlapping curves. Warm amber to deep orange
|
|
71
|
-
color palette. Black background. No text. No letters. Pure abstract mark. Clean
|
|
72
|
-
enough to be an app icon. Luxurious, premium, modern tech company feel.
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
## Design principles
|
|
76
|
-
|
|
77
|
-
- **Flame/torch motif** — vigiles were Rome's night watchmen who carried torches
|
|
78
|
-
- **Amber/orange palette** — matches GitHub Action branding color
|
|
79
|
-
- **No text in the icon** — must work at 16px favicon size
|
|
80
|
-
- **Dark background variant** for README, light/transparent variant for npm
|
|
81
|
-
|
|
82
|
-
## Example curl
|
|
83
|
-
|
|
84
|
-
```bash
|
|
85
|
-
curl 'https://api.imagerouter.io/v1/openai/images/generations' \
|
|
86
|
-
-H "Authorization: Bearer $IMAGEROUTER_API_KEY" \
|
|
87
|
-
-H 'Content-Type: application/json' \
|
|
88
|
-
-d '{
|
|
89
|
-
"prompt": "YOUR PROMPT HERE",
|
|
90
|
-
"model": "google/nano-banana-2",
|
|
91
|
-
"quality": "high",
|
|
92
|
-
"size": "1024x1024",
|
|
93
|
-
"response_format": "url",
|
|
94
|
-
"output_format": "png"
|
|
95
|
-
}'
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
## Workflow
|
|
99
|
-
|
|
100
|
-
1. Generate variations with different prompts
|
|
101
|
-
2. Save as `logo-v*.png` (gitignored)
|
|
102
|
-
3. Pick the best, copy to `logo.png`
|
|
103
|
-
4. Commit `logo.png` only
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: pr-to-lint-rule
|
|
3
|
-
description: Convert a recurring PR review comment into an automated lint rule with tests and spec entry
|
|
4
|
-
disable-model-invocation: true
|
|
5
|
-
argument-hint: <description of recurring PR feedback>
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
Convert a recurring PR review comment into an automated lint rule.
|
|
9
|
-
|
|
10
|
-
## Arguments
|
|
11
|
-
|
|
12
|
-
$ARGUMENTS — A natural language description of the pattern to enforce. Examples:
|
|
13
|
-
|
|
14
|
-
- "we keep telling people not to import directly from antd, use our design system barrel file instead"
|
|
15
|
-
- "people forget to use our custom logger instead of console.log"
|
|
16
|
-
- "don't use unwrap() in production code, use expect() or proper error handling"
|
|
17
|
-
- "API route handlers must use the withAuth wrapper"
|
|
18
|
-
|
|
19
|
-
## Instructions
|
|
20
|
-
|
|
21
|
-
You are generating an automated lint rule from a recurring code review pattern. Follow these steps:
|
|
22
|
-
|
|
23
|
-
### Step 1: Detect the Project Language and Toolchain
|
|
24
|
-
|
|
25
|
-
Look at the repository to determine:
|
|
26
|
-
|
|
27
|
-
- **Primary language** (JS/TS, Python, Rust, Go, Ruby, etc.)
|
|
28
|
-
- **Linter in use** (ESLint, Ruff, Clippy, golangci-lint, RuboCop, etc.)
|
|
29
|
-
- **Testing framework** (Vitest, Jest, pytest, cargo test, etc.)
|
|
30
|
-
- **Existing custom rules** (to match conventions)
|
|
31
|
-
|
|
32
|
-
**If the language or linter cannot be confidently detected** (e.g. polyglot repo, no linter config, or multiple candidates), **ask the user** which language and linter to target before generating anything.
|
|
33
|
-
|
|
34
|
-
### Step 2: Generate the Lint Rule
|
|
35
|
-
|
|
36
|
-
Based on the detected (or user-specified) language, generate the appropriate rule type:
|
|
37
|
-
|
|
38
|
-
**Read the linter-specific reference doc before generating.** Each doc covers existing plugins to check first, rule/lint anatomy, AST patterns, auto-fix safety, testing, and edge cases.
|
|
39
|
-
|
|
40
|
-
| Language | Linter | Reference doc |
|
|
41
|
-
| --------------------- | --------- | ----------------------------- |
|
|
42
|
-
| JavaScript/TypeScript | ESLint | `../linter-docs/eslint.md` |
|
|
43
|
-
| Python | Ruff | `../linter-docs/ruff.md` |
|
|
44
|
-
| Python | Pylint | `../linter-docs/pylint.md` |
|
|
45
|
-
| Ruby | RuboCop | `../linter-docs/rubocop.md` |
|
|
46
|
-
| Rust | Clippy | `../linter-docs/clippy.md` |
|
|
47
|
-
| CSS | Stylelint | `../linter-docs/stylelint.md` |
|
|
48
|
-
|
|
49
|
-
For all linters, follow this order:
|
|
50
|
-
|
|
51
|
-
1. **Check existing plugins/rules first** — see the plugin table in the linter doc
|
|
52
|
-
2. **Try built-in config options** — most linters have `no-restricted-*` or equivalent rules that handle one-off patterns without custom code
|
|
53
|
-
3. **Only write a custom rule** when you need AST analysis, auto-fix, or configurable options beyond what exists
|
|
54
|
-
|
|
55
|
-
If a custom rule is needed, the reference doc provides: rule anatomy, AST node cheat sheet, auto-fix/suggest patterns, testing examples, and registration instructions.
|
|
56
|
-
|
|
57
|
-
#### For Go (go/analysis)
|
|
58
|
-
|
|
59
|
-
No linter doc yet. Generate an analyzer using `golang.org/x/tools/go/analysis` with `analysistest` tests.
|
|
60
|
-
|
|
61
|
-
#### For other languages
|
|
62
|
-
|
|
63
|
-
Generate the most idiomatic linting approach with test cases and integration instructions.
|
|
64
|
-
|
|
65
|
-
### Step 3: Add to Instruction File
|
|
66
|
-
|
|
67
|
-
**If the project uses v2 specs** (has `CLAUDE.md.spec.ts`):
|
|
68
|
-
|
|
69
|
-
Add an `enforce()` rule to the spec file:
|
|
70
|
-
|
|
71
|
-
```typescript
|
|
72
|
-
"<rule-id>": enforce("<linter>/<rule-name>", "<why>"),
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
Then run `npx vigiles compile` to regenerate CLAUDE.md.
|
|
76
|
-
|
|
77
|
-
**If the project uses v1** (hand-written CLAUDE.md):
|
|
78
|
-
|
|
79
|
-
Append an annotation block:
|
|
80
|
-
|
|
81
|
-
```markdown
|
|
82
|
-
### <Rule title — imperative, concise>
|
|
83
|
-
|
|
84
|
-
**Enforced by:** `<linter>/<rule-name>`
|
|
85
|
-
**Why:** <One sentence explaining the architectural reason>
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### Step 4: Present the Output
|
|
89
|
-
|
|
90
|
-
Show the user:
|
|
91
|
-
|
|
92
|
-
1. All generated files with full contents
|
|
93
|
-
2. Step-by-step integration instructions
|
|
94
|
-
3. The spec rule or CLAUDE.md block to add
|
|
95
|
-
4. How to verify it works (run the linter, expect it to catch a violation)
|
|
96
|
-
|
|
97
|
-
Ask the user if they want you to write the files and update the spec/CLAUDE.md.
|