the-grimoire-cli 0.3.2

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.
Files changed (103) hide show
  1. package/.agents/AGENTS.md +112 -0
  2. package/.agents/NAVIGATOR.md +168 -0
  3. package/.agents/VERSION +4 -0
  4. package/.agents/agents/INDEX.md +7 -0
  5. package/.agents/agents/verifier.md +50 -0
  6. package/.agents/commands/INDEX.md +11 -0
  7. package/.agents/commands/checkpoint.md +15 -0
  8. package/.agents/commands/grimoire.md +14 -0
  9. package/.agents/commands/onboard.md +56 -0
  10. package/.agents/commands/present.md +23 -0
  11. package/.agents/commands/verify.md +20 -0
  12. package/.agents/grimoire.manifest +18 -0
  13. package/.agents/rules/00-always.md +42 -0
  14. package/.agents/rules/05-code-quality.md +28 -0
  15. package/.agents/rules/10-working-process.md +31 -0
  16. package/.agents/rules/15-skills.md +27 -0
  17. package/.agents/rules/20-modes.md +41 -0
  18. package/.agents/rules/25-surgical-changes.md +29 -0
  19. package/.agents/rules/30-verification.md +36 -0
  20. package/.agents/rules/35-context-economy.md +41 -0
  21. package/.agents/rules/40-handoff.md +25 -0
  22. package/.agents/rules/45-presentation.md +35 -0
  23. package/.agents/rules/50-security.md +30 -0
  24. package/.agents/rules/60-commit-style.md +14 -0
  25. package/.agents/rules/INDEX.md +18 -0
  26. package/.agents/skills/INDEX.md +8 -0
  27. package/.agents/skills/README.md +6 -0
  28. package/.agents/skills/catalog.md +106 -0
  29. package/.agents/skills/find-skills/SKILL.md +142 -0
  30. package/.agents/stack/INDEX.md +9 -0
  31. package/.agents/stack/README.md +66 -0
  32. package/.agents/stack/desktop.md +36 -0
  33. package/.agents/stack/library.md +16 -0
  34. package/.agents/stack/web-app.md +32 -0
  35. package/.agents/standards/INDEX.md +23 -0
  36. package/.agents/standards/accessibility.md +50 -0
  37. package/.agents/standards/architecture.md +39 -0
  38. package/.agents/standards/attribution.md +39 -0
  39. package/.agents/standards/clean-code.md +121 -0
  40. package/.agents/standards/codex.md +69 -0
  41. package/.agents/standards/error-codes.md +41 -0
  42. package/.agents/standards/general.md +46 -0
  43. package/.agents/standards/guardrail-tests.md +40 -0
  44. package/.agents/standards/knowledge-management.md +35 -0
  45. package/.agents/standards/launch-security-checklist.md +45 -0
  46. package/.agents/standards/observability.md +35 -0
  47. package/.agents/standards/release-versioning.md +53 -0
  48. package/.agents/standards/requirements.md +75 -0
  49. package/.agents/standards/security-scanners.md +42 -0
  50. package/.agents/standards/testing-strategy.md +61 -0
  51. package/.agents/standards/typescript.md +19 -0
  52. package/.agents/standards/writing.md +58 -0
  53. package/.agents/tooling.json +19 -0
  54. package/LICENSE +21 -0
  55. package/README.md +139 -0
  56. package/bin/grimoire.mjs +598 -0
  57. package/package.json +32 -0
  58. package/templates/CLAUDE.md +7 -0
  59. package/templates/ci/ci.yml +49 -0
  60. package/templates/ci/sast.yml +44 -0
  61. package/templates/codex/INDEX.md +18 -0
  62. package/templates/codex/README.md +28 -0
  63. package/templates/codex/decisions/0000-template.md +36 -0
  64. package/templates/codex/decisions/INDEX.md +11 -0
  65. package/templates/codex/decisions/README.md +25 -0
  66. package/templates/codex/domain/INDEX.md +14 -0
  67. package/templates/codex/domain/README.md +10 -0
  68. package/templates/codex/evidence/0000-extraction-template.md +36 -0
  69. package/templates/codex/evidence/INDEX.md +11 -0
  70. package/templates/codex/evidence/README.md +15 -0
  71. package/templates/codex/reference/INDEX.md +11 -0
  72. package/templates/codex/reference/README.md +15 -0
  73. package/templates/codex/reference/confirmed-values.md +18 -0
  74. package/templates/codex/requirements/INDEX.md +11 -0
  75. package/templates/codex/requirements/README.md +22 -0
  76. package/templates/codex/requirements/addons/0000-template.md +35 -0
  77. package/templates/codex/requirements/base.md +36 -0
  78. package/templates/codex/requirements/changes/0000-template.md +39 -0
  79. package/templates/codex/resources/INDEX.md +11 -0
  80. package/templates/codex/resources/README.md +17 -0
  81. package/templates/codex/resources/manifest.md +11 -0
  82. package/templates/codex/runbooks/INDEX.md +9 -0
  83. package/templates/codex/runbooks/README.md +8 -0
  84. package/templates/codex/runbooks/incident-runbook-template.md +58 -0
  85. package/templates/gitignore-snippet.txt +12 -0
  86. package/templates/journal/backlog/README.md +18 -0
  87. package/templates/journal/backlog/done/.gitkeep +0 -0
  88. package/templates/journal/memory/MEMORY.md +15 -0
  89. package/templates/journal/session/.gitkeep +0 -0
  90. package/templates/journal/session/archive/.gitkeep +1 -0
  91. package/templates/journal/session/artifacts/.gitkeep +1 -0
  92. package/templates/journal/session/current.md +12 -0
  93. package/templates/lint/README.md +25 -0
  94. package/templates/lint/eslint.config.mjs +33 -0
  95. package/templates/lint/tsconfig.base.json +11 -0
  96. package/templates/local/AGENTS.local.md +33 -0
  97. package/templates/local/README.md +55 -0
  98. package/templates/local/commands/.gitkeep +0 -0
  99. package/templates/local/rules/.gitkeep +0 -0
  100. package/templates/local/skills/.gitkeep +0 -0
  101. package/templates/local/stack/.gitkeep +0 -0
  102. package/templates/local/standards/.gitkeep +0 -0
  103. package/templates/tests/guardrail.invariants.test.ts +59 -0
@@ -0,0 +1,18 @@
1
+ # QUEUE — backlog
2
+
3
+ One work item per file: `backlog/<id>.md`. Frontmatter:
4
+
5
+ ```
6
+ ---
7
+ id: <kebab-id>
8
+ status: open # open | active | blocked | done
9
+ priority: normal # normal | hotfix
10
+ ---
11
+ ```
12
+
13
+ - **Hotfix is a priority flag, not a separate tree.** A hotfix item carries a cleanup checklist
14
+ (tests to backfill, env flag to remove, ADR if implied).
15
+ - Done → move the file to `backlog/done/` with close-out evidence (ADR link, test reproducer,
16
+ sign-off) inside it.
17
+
18
+ Routing (chat → item) is defined in `rules/40-handoff.md`.
File without changes
@@ -0,0 +1,15 @@
1
+ # KNOWLEDGE index
2
+
3
+ One fact per file in `memory/`. Each file has frontmatter (`name` / `description` /
4
+ `type: lesson | field-report | decision-note | reference`) and links to related cards with
5
+ `[[name]]`. This index holds one line per memory — never the content itself.
6
+
7
+ Architecture-level decisions graduate to `codex/decisions/`.
8
+
9
+ ## Promotion & pruning
10
+
11
+ Promote a fact into `memory/` only if **all three** hold: non-obvious, project-specific, and worth
12
+ keeping past this week. Session scratch stays in `session/` (gitignored). Prune periodically: drop
13
+ cards whose underlying state has shifted or that a written ADR now supersedes.
14
+
15
+ <!-- - [Title](file.md) — one-line hook -->
File without changes
@@ -0,0 +1,12 @@
1
+ # NOW — current session (template)
2
+
3
+ > Rewrite this file **in place** every turn. Do not append. Local/gitignored — about *this run* only.
4
+ > Before a context boundary, copy to `session/archive/<YYYY-MM-DD-HHmm>.md` (or run `/checkpoint`).
5
+
6
+ - **mode:** NORMAL <!-- NORMAL | HOTFIX -->
7
+ - **focus:** <!-- the one thing in flight -->
8
+ - **last-done:**
9
+ - **next-step:**
10
+ - **blockers:**
11
+ - **open-questions:**
12
+ - **files-touched:**
@@ -0,0 +1,25 @@
1
+ # Clean-code lint preset
2
+
3
+ Mechanical enforcement of `standards/clean-code.md`. **Copy into your project** and extend — do not
4
+ edit in place (the project owns its lint config).
5
+
6
+ ## Use
7
+
8
+ ```sh
9
+ npm i -D eslint @eslint/js typescript-eslint
10
+ cp templates/lint/eslint.config.mjs ./eslint.config.mjs
11
+ ```
12
+
13
+ Extend the tsconfig from your `tsconfig.json`:
14
+
15
+ ```json
16
+ { "extends": "./tsconfig.base.json" }
17
+ ```
18
+
19
+ ## Severities
20
+
21
+ `warn` for size/complexity limits (guidance while a codebase stabilizes); `error` for safety rules
22
+ (`any`, floating promises, non-null assertions, console). Tighten `warn`→`error` per project once
23
+ clean. Any rule can be overridden in your own config block — it wins.
24
+
25
+ `tsconfig.base.json` is intentionally comment-free so tooling can parse it as plain JSON.
@@ -0,0 +1,33 @@
1
+ // Grimoire clean-code ESLint preset (flat config). Copy to your project root as eslint.config.mjs
2
+ // (or import + extend it). Install peers: `npm i -D eslint @eslint/js typescript-eslint`.
3
+ // Encodes standards/clean-code.md limits. Override any rule in your own config block — yours wins.
4
+ import js from "@eslint/js";
5
+ import tseslint from "typescript-eslint";
6
+
7
+ export default tseslint.config(
8
+ js.configs.recommended,
9
+ ...tseslint.configs.recommendedTypeChecked,
10
+ {
11
+ languageOptions: {
12
+ parserOptions: { projectService: true },
13
+ },
14
+ rules: {
15
+ // --- complexity / size limits (warn: guide, do not block early) ---
16
+ complexity: ["warn", 10],
17
+ "max-depth": ["warn", 3],
18
+ "max-params": ["warn", 4],
19
+ "max-lines-per-function": ["warn", { max: 50, skipBlankLines: true, skipComments: true }],
20
+ "max-lines": ["warn", { max: 300, skipBlankLines: true, skipComments: true }],
21
+ "no-nested-ternary": "warn",
22
+
23
+ // --- safety (error: never ship) ---
24
+ "no-console": ["error", { allow: ["warn", "error"] }],
25
+ "@typescript-eslint/no-explicit-any": "error",
26
+ "@typescript-eslint/no-non-null-assertion": "error",
27
+ "@typescript-eslint/no-floating-promises": "error",
28
+ "@typescript-eslint/switch-exhaustiveness-check": "error",
29
+ "@typescript-eslint/explicit-module-boundary-types": "error",
30
+ "@typescript-eslint/prefer-readonly": "error",
31
+ },
32
+ },
33
+ );
@@ -0,0 +1,11 @@
1
+ {
2
+ "compilerOptions": {
3
+ "strict": true,
4
+ "noUncheckedIndexedAccess": true,
5
+ "exactOptionalPropertyTypes": true,
6
+ "noImplicitOverride": true,
7
+ "noFallthroughCasesInSwitch": true,
8
+ "forceConsistentCasingInFileNames": true,
9
+ "verbatimModuleSyntax": true
10
+ }
11
+ }
@@ -0,0 +1,33 @@
1
+ # Local overrides — this project (loads LAST, wins)
2
+
3
+ `grimoire sync` never touches anything under `local/`. See `local/README.md` for the full protocol.
4
+ **Do not edit the managed base** (`.agents/rules|standards|stack|agents|skills|commands`,
5
+ `AGENTS.md`, `tooling.json`) — put every change here.
6
+
7
+ ## Project profile
8
+
9
+ - **Active stack profile:** <!-- web-app | desktop | library -->
10
+ - **Testing policy:** <!-- tdd-mandatory | test-ready-deferred | none -->
11
+ - **Verify command (if non-default):**
12
+ - **Presentation mode:** off <!-- off | on — render human-facing deliverables as HTML (rules/45-presentation.md) -->
13
+
14
+ ## Project facts
15
+
16
+ <!-- This section is the new home for everything that used to live in a long CLAUDE.md: the system
17
+ model, doc map, domain glossary pointers, access/auth model, environment/build gotchas, confirmed
18
+ values, error-code catalog location, IPC/channel tables. CLAUDE.md becomes a thin pointer; the
19
+ durable project context moves HERE (it loads last and wins, and `grimoire sync` never touches it).
20
+ Large domain contracts (IPC tables, confirmed-value sheets) belong in `local/reference/`.
21
+ Onboarding an existing repo? See commands/onboard.md and move the old CLAUDE.md body into here. -->
22
+
23
+ ## Override declarations
24
+
25
+ <!-- List any base rule/standard/stack default you are overriding, and where the override lives.
26
+ e.g. "rules/10 plan-before-code relaxed for spikes — see local/rules/local-10-spikes.md"
27
+ e.g. "ADRs live in docs/core/adr/ + docs/adr-index.md, not the seeded docs/adr/" -->
28
+
29
+ ## Added (project-only)
30
+
31
+ <!-- Point to project-only rules/skills/commands you added under local/<area>/.
32
+ Project rules go in local/rules/ with a `local-` prefix (see local/README.md → naming).
33
+ Big domain reference docs go in local/reference/. -->
@@ -0,0 +1,55 @@
1
+ # local/ — your project's customization layer
2
+
3
+ Everything under `local/` (at the repo root) belongs to **this project**. `grimoire sync` **never touches it**.
4
+ This is where ALL per-repo customization lives.
5
+
6
+ ## The one hard rule
7
+
8
+ **Never edit the managed base in a consuming project.** These paths are overwritten on every
9
+ `grimoire sync` (they are the "generals" shipped by the template):
10
+
11
+ ```
12
+ .agents/AGENTS.md rules/ standards/ stack/ agents/ skills/ commands/ tooling.json
13
+ ```
14
+
15
+ If you edit them, your change is lost on the next sync. Put the change in `local/` instead.
16
+
17
+ ## Two ways to customize
18
+
19
+ 1. **Override** a base behavior — restate it in `local/`. Because `local/` loads **last**, it wins.
20
+ - A base rule → add the corrected rule in `local/rules/` (or note it in `AGENTS.local.md`).
21
+ - A base standard/stack default → put the project version in `local/standards/` or `local/stack/`.
22
+ 2. **Add** something the base doesn't have — a project-only rule, skill, command, or standard goes
23
+ straight into the matching `local/<area>/`.
24
+
25
+ ## Layout
26
+
27
+ | Path | Holds |
28
+ |---|---|
29
+ | `AGENTS.local.md` | entry: active stack profile, testing policy, project facts, override declarations |
30
+ | `rules/` | project-only always-on rules (named `local-*.md`) |
31
+ | `standards/` | project-only coding standards / per-language additions |
32
+ | `stack/` | project-only stack notes or profile overrides |
33
+ | `skills/` | project-only skills — each `<name>/SKILL.md` is mirrored to `.claude/skills/` by init/sync |
34
+ | `commands/` | project-only slash commands |
35
+ | `reference/` | project domain reference docs (big runtime contract, IPC tables, confirmed values) — indexed by `grimoire index` |
36
+ | `tooling.json` | project-only plugins / MCP servers (Linear, Sentry, Supabase, Figma, …) — `grimoire bootstrap` merges them additively with the base |
37
+
38
+ ## Naming `local/rules/` — avoid number collisions with the base
39
+
40
+ The base ships numbered rules `00–60` (`rules/00-always.md`, `rules/30-verification.md`, …). A
41
+ project rule named `30-security.md` under `local/rules/` reads as "rule 30" too — ambiguous with the
42
+ base's `30-verification.md`. **Prefix every project rule with `local-`** so the number space never
43
+ clashes and the source is obvious at a glance:
44
+
45
+ ```
46
+ local/rules/local-10-design-system.md ✅ unambiguous, clearly project-owned
47
+ local/rules/30-security.md ❌ collides with base rules/30-verification.md
48
+ ```
49
+
50
+ Keep the original topic number after the prefix if it helps (`local-30-security.md`) — the `local-`
51
+ makes it distinct regardless. Reference them from `AGENTS.local.md` so the load order is explicit.
52
+
53
+ ## Precedence
54
+
55
+ base loads first → `local/` loads last → **`local/` wins**. See the load order in `.agents/AGENTS.md`.
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,59 @@
1
+ // Guardrail test — structural invariants (standards/guardrail-tests.md).
2
+ // Copy into the project's test dir and adapt the scanners. Runs under the existing `verify` gate
3
+ // (Vitest shown; the pattern is runner-agnostic). Fail CLOSED: a scan that returns nothing because
4
+ // it could not read its source is a failure, not a pass.
5
+ import { describe, it, expect } from "vitest";
6
+ import fs from "node:fs";
7
+ import path from "node:path";
8
+
9
+ const SRC = path.resolve(__dirname, "..", "src");
10
+
11
+ function walk(dir: string, ext = ".ts"): string[] {
12
+ const out: string[] = [];
13
+ for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
14
+ const p = path.join(dir, e.name);
15
+ if (e.isDirectory()) out.push(...walk(p, ext));
16
+ else if (e.name.endsWith(ext)) out.push(p);
17
+ }
18
+ return out;
19
+ }
20
+
21
+ function scan(re: RegExp): Set<string> {
22
+ const hits = new Set<string>();
23
+ for (const f of walk(SRC)) {
24
+ const text = fs.readFileSync(f, "utf8");
25
+ for (const m of text.matchAll(re)) hits.add(m[1]);
26
+ }
27
+ return hits;
28
+ }
29
+
30
+ function diff(a: Set<string>, b: Set<string>): string[] {
31
+ return [...a].filter((x) => !b.has(x)).sort();
32
+ }
33
+
34
+ describe("guardrail: IPC channels are allow-listed", () => {
35
+ // EXAMPLE — replace with the project's real registry/allow-list source of truth.
36
+ const ALLOW_LIST: string[] = require("../src/ipc/allow-list").CHANNELS; // declared truth
37
+ const used = scan(/ipcMain\.handle\(\s*["']([^"']+)["']/g); // live call sites
38
+
39
+ it("every registered channel is declared (fail closed on undeclared)", () => {
40
+ expect(used.size).toBeGreaterThan(0); // scanner found something — not a silent empty
41
+ expect(diff(used, new Set(ALLOW_LIST))).toEqual([]); // used but undeclared
42
+ });
43
+
44
+ it("no stale allow-list entries", () => {
45
+ expect(diff(new Set(ALLOW_LIST), used)).toEqual([]); // declared but unused
46
+ });
47
+ });
48
+
49
+ describe("guardrail: thrown error codes exist in the catalog", () => {
50
+ // EXAMPLE — replace catalog source + throw pattern with the project's.
51
+ const catalog = fs.readFileSync(path.resolve(__dirname, "../.agents/standards/error-codes.md"), "utf8");
52
+ const declared = new Set([...catalog.matchAll(/`([A-Z]+_[A-Z0-9_]+)`/g)].map((m) => m[1]));
53
+ const thrown = scan(/AppError\(\s*["']([A-Z]+_[A-Z0-9_]+)["']/g);
54
+
55
+ it("every thrown code is catalogued", () => {
56
+ expect(declared.size).toBeGreaterThan(0); // catalog readable — fail closed, not a silent skip
57
+ expect(diff(thrown, declared)).toEqual([]);
58
+ });
59
+ });