@jesdi/skills 0.0.10 → 0.0.12

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jesdi/skills",
3
- "version": "0.0.10",
3
+ "version": "0.0.12",
4
4
  "description": "jesdi's agent skills (content package consumed by @jesdi/skills-cli)",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -20,7 +20,7 @@ from pathlib import Path
20
20
  import crap_git
21
21
  import crap_python
22
22
  import crap_typescript
23
- from crap_config import CODE_SUFFIXES, Config, Target, find_config, load, matches
23
+ from crap_config import CODE_SUFFIXES, CONFIG_NAME, Config, Target, find_config, load, matches
24
24
  from crap_coverage import Report, load_report
25
25
  from crap_model import Func, ToolError
26
26
  from crap_report import Result, TargetRun, render_json, render_text
@@ -192,6 +192,12 @@ def main(argv: list[str] | None = None) -> int:
192
192
  config_path,
193
193
  {"base": args.base, "threshold_existing": args.threshold_existing, "threshold_new": args.threshold_new},
194
194
  )
195
+ toplevel = crap_git.toplevel(cfg.root).resolve()
196
+ if toplevel != cfg.root:
197
+ raise ToolError(
198
+ f"{CONFIG_NAME} must live at the git repository root; it is in "
199
+ f"{cfg.root}, but the root is {toplevel}"
200
+ )
195
201
  result = run(cfg, run_mode=args.run_mode, all_functions=args.all)
196
202
  except ToolError as exc:
197
203
  print(f"crap: {exc}", file=sys.stderr)
@@ -138,3 +138,15 @@ def test_failing_coverage_command_that_still_writes_a_report_warns(repo, capsys)
138
138
  def test_unknown_base_is_a_tool_error(repo, capsys):
139
139
  assert crap.main(["--base", "nope"]) == 2
140
140
  assert "nope" in capsys.readouterr().err
141
+
142
+
143
+ def test_config_not_at_git_toplevel_is_a_tool_error(tmp_path, monkeypatch, capsys):
144
+ git(tmp_path, "init", "-q", "-b", "main")
145
+ sub = tmp_path / "sub"
146
+ sub.mkdir()
147
+ (sub / ".crap-gate.json").write_text(json.dumps(CONFIG))
148
+ git(tmp_path, "add", ".")
149
+ git(tmp_path, "commit", "-q", "-m", "base")
150
+ monkeypatch.chdir(sub)
151
+ assert crap.main([]) == 2
152
+ assert "git repository root" in capsys.readouterr().err
@@ -0,0 +1,98 @@
1
+ ---
2
+ name: deep-quality-review
3
+ description: >-
4
+ Extremely strict maintainability review of a branch's changes: duplicated
5
+ concepts, complexity that got rearranged instead of deleted, spaghetti
6
+ branching, boundary leaks, weak type contracts, file sprawl, and "temporary"
7
+ fixes that will outlive their reason. Use when the user asks for a "deep code
8
+ quality review", "thermonuclear review", "harsh maintainability review",
9
+ "code judo", "is this making the codebase messier", or before merging a
10
+ change that touches shared code. Not a correctness, security, or test-coverage
11
+ review.
12
+ ---
13
+
14
+ # Deep Quality Review
15
+
16
+ ## Overview
17
+
18
+ One principle: **a change should leave the codebase with fewer concepts, not
19
+ more.** Behavior stays the same; structure gets simpler. Judge the diff by the
20
+ shape the code will have in a year, when the deadline, migration, or incident
21
+ that motivated it is forgotten.
22
+
23
+ Be ambitious. Do not stop at "this could be a bit cleaner" — look for the
24
+ "code judo" move: a reframing that uses the existing architecture so whole
25
+ branches, helpers, flags, or layers disappear. If complexity can be deleted
26
+ rather than rearranged, push for deletion.
27
+
28
+ ## Scope
29
+
30
+ **In:** structure, abstractions, duplication, layering, type contracts, file
31
+ size, orchestration.
32
+
33
+ **Out:** correctness bugs, security, tests. Raise one only when structure
34
+ causes it (an invariant enforced by an optional parameter is a structure
35
+ finding). Everything else belongs in a different review.
36
+
37
+ ## The smells
38
+
39
+ Run every meaningful change through this table, top row first. Each row is one
40
+ concept; the *Ask* is the question that exposes it, the *Remedy* is what to
41
+ push for.
42
+
43
+ | # | Smell | Ask | Remedy |
44
+ |---|-------|-----|--------|
45
+ | 1 | **Duplicated concept** — one idea expressed twice: near-duplicate helper, parallel model, copy-pasted branch, a flag *and* an optional both meaning "off", the same predicate reimplemented instead of reused | What single concept are these copies of? Where is its canonical home? | Name the concept once; make the variants its data or parameters; delete the copies. Never accept a second copy because the first one exists. |
46
+ | 2 | **Complexity rearranged, not deleted** — the diff moves code around but the reader still holds the same number of branches, modes, and helpers | Which reframing of the model or ownership makes these branches disappear? | Change the model so the special case becomes the default flow. Prefer the version that feels inevitable in hindsight. |
47
+ | 3 | **Special case in a shared flow** — new `if`, one-off boolean, nullable mode, or feature check bolted into an unrelated path | Whose decision is this, and why is it made here? | Move it behind its own abstraction (policy, resolver, dispatcher, module); keep the shared path linear. |
48
+ | 4 | **Wrong layer / boundary leak** — feature logic in a shared module, implementation details through an API, callers re-deriving what the owner already knows | Which module owns this concept? | Move the logic to the owner; callers receive results, not raw inputs to recompute. |
49
+ | 5 | **Indirection without clarity** — thin wrapper, pass-through helper, "generic" mechanism hiding a simple data shape | What does the reader learn from this layer? | Delete it and keep the direct call. Boring and direct beats clever. |
50
+ | 6 | **Weak contract** — `any`, `unknown`, casts, optional params, silent fallbacks that paper over an unclear invariant | What invariant is this hiding? | Make the boundary explicit in the type so the control flow simplifies. |
51
+ | 7 | **File sprawl** — the diff pushes a file past a healthy size boundary (~1k lines) | Should this be decomposed *before* adding to it? | Split by concept first; waive only with a compelling structural reason. |
52
+ | 8 | **Needless sequencing / non-atomic update** — independent work serialized, related updates that can leave state half-applied | Is this actually dependent? Can it be observed half-done? | Parallelize independent work; group related updates. Not micro-optimization — brittleness. |
53
+ | 9 | **Short-horizon change** — "temporary", TODO-later, quick patch, deferred cleanup, a shape chosen because it is the smallest diff | What does this look like when its reason is gone? What does removing it cost? | Do the durable fix now, or structure the stopgap so removal is a pure deletion (one branch, one file), never a refactor of live callers. |
54
+
55
+ Row 9 is the long-term rule and it applies to every other row: prefer
56
+ consolidating now over a third copy later; prefer the simplification that
57
+ still makes sense after the migration; never trade a durable simplification
58
+ for a smaller diff.
59
+
60
+ ## Process
61
+
62
+ 1. Read the full diff, then the files it touches and the canonical helpers it
63
+ should have reused. Structural problems are only visible in context.
64
+ 2. For each meaningful change, ask the table's questions in order. Rows 1 and
65
+ 2 are where the big wins hide; spend most of the effort there.
66
+ 3. For every finding, write the *restructuring*, not the patch. "Extract a
67
+ shared helper" is a patch; "one `Message` model with a renderer per channel,
68
+ so channels become data" is a restructuring.
69
+
70
+ ## Output
71
+
72
+ Write the review in this shape:
73
+
74
+ 1. **Findings**, ordered by table row (row 1 first), each with: the row,
75
+ where, and the concrete restructuring. Keep to the few high-conviction
76
+ findings — structural findings displace cosmetic ones, and a cosmetic
77
+ finding never appears while a structural one exists.
78
+ 2. **Verdict**: `APPROVE` or `REQUEST CHANGES`, one line of justification.
79
+
80
+ ## Approval bar
81
+
82
+ Working code is not the bar. `REQUEST CHANGES` when any row 1–6 or row 9
83
+ smell is present and unjustified, or when a visible code-judo move was
84
+ skipped. Rows 7–8 block when the cleaner structure is obvious.
85
+
86
+ ## Author pushback
87
+
88
+ | Pushback | Answer |
89
+ |----------|--------|
90
+ | "It works, tests pass" | The bar is structure. Working code that makes the codebase messier is a regression. |
91
+ | "We'll clean it up after the migration / next quarter" | Cleanup later is a refactor of live callers; the durable version is cheaper now. |
92
+ | "It's just one flag / one `if`" | Every flag is a mode every future reader must hold in their head. |
93
+ | "The existing code already does it this way" | Existing mess licenses fixing the concept, not adding a copy of it. |
94
+ | "A restructure is out of scope" | If the restructure deletes the complexity this change adds, it is the scope. |
95
+
96
+ ## Review Tone
97
+
98
+ Be direct, serious, and demanding about quality.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "generatedAt": "2026-08-30T14:16:24.650Z",
3
+ "generatedAt": "2026-09-03T08:16:37.503Z",
4
4
  "skills": [
5
5
  {
6
6
  "name": "backlog",
@@ -22,10 +22,16 @@
22
22
  },
23
23
  {
24
24
  "name": "crap-gate",
25
- "version": "0.1.0",
26
- "hash": "sha256-15a410b845b5346ed6ad1a0fa15c33add9e82acb7f1b7bbf8fdf83ab485bc741",
25
+ "version": "0.1.1",
26
+ "hash": "sha256-c4d66903f2d8b3d17b65e193f75ee0eea6dff9b8f47bd04a520a4f10778d895c",
27
27
  "description": "Score every function a branch changed with CRAP (cyclomatic complexity × untested fraction), fail on existing functions > 15 and new functions > 9, and drive a fixer + independent reviewer loop until the gate passes. Use when implementation is done and before pushing, when the user says \"run the crap gate\", \"check CRAP\", \"is this change tested enough\", or when a push gate reports CRAP violations."
28
28
  },
29
+ {
30
+ "name": "deep-quality-review",
31
+ "version": "0.1.0",
32
+ "hash": "sha256-b3b3c00fd82175f1708d6042c583fedc7c393d663699e7dbee9579d19ecc9ce4",
33
+ "description": "Extremely strict maintainability review of a branch's changes: duplicated concepts, complexity that got rearranged instead of deleted, spaghetti branching, boundary leaks, weak type contracts, file sprawl, and \"temporary\" fixes that will outlive their reason. Use when the user asks for a \"deep code quality review\", \"thermonuclear review\", \"harsh maintainability review\", \"code judo\", \"is this making the codebase messier\", or before merging a change that touches shared code. Not a correctness, security, or test-coverage review."
34
+ },
29
35
  {
30
36
  "name": "file-bug-issue",
31
37
  "version": "0.1.0",