sloppatrol 0.1.0 → 0.1.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 (73) hide show
  1. package/README.md +111 -160
  2. package/dist/census/index.js +4 -2
  3. package/dist/census/index.js.map +1 -1
  4. package/dist/census/lib/guardrails.js +38 -9
  5. package/dist/census/lib/guardrails.js.map +1 -1
  6. package/dist/census/lib/stack.d.ts +2 -1
  7. package/dist/census/lib/stack.js +8 -4
  8. package/dist/census/lib/stack.js.map +1 -1
  9. package/dist/cli/index.js +20 -4
  10. package/dist/cli/index.js.map +1 -1
  11. package/dist/cli/lib/browser.d.ts +2 -0
  12. package/dist/cli/lib/browser.js +13 -0
  13. package/dist/cli/lib/browser.js.map +1 -0
  14. package/dist/cli/lib/usage.d.ts +1 -1
  15. package/dist/cli/lib/usage.js +4 -3
  16. package/dist/cli/lib/usage.js.map +1 -1
  17. package/dist/config/lib/schema.d.ts +30 -0
  18. package/dist/config/lib/schema.js +16 -0
  19. package/dist/config/lib/schema.js.map +1 -1
  20. package/dist/dashboard/index.d.ts +4 -0
  21. package/dist/dashboard/index.js +6 -2
  22. package/dist/dashboard/index.js.map +1 -1
  23. package/dist/dashboard/lib/snapshot.d.ts +168 -30
  24. package/dist/dashboard/lib/snapshot.js +104 -37
  25. package/dist/dashboard/lib/snapshot.js.map +1 -1
  26. package/dist/dashboard/lib/summary.d.ts +230 -0
  27. package/dist/dashboard/lib/summary.js +398 -0
  28. package/dist/dashboard/lib/summary.js.map +1 -0
  29. package/dist/domain/index.d.ts +2 -0
  30. package/dist/domain/index.js +1 -0
  31. package/dist/domain/index.js.map +1 -1
  32. package/dist/domain/lib/cycle.d.ts +17 -0
  33. package/dist/domain/lib/cycle.js +2 -0
  34. package/dist/domain/lib/cycle.js.map +1 -0
  35. package/dist/{patrol → domain}/lib/pick.d.ts +2 -1
  36. package/dist/{patrol → domain}/lib/pick.js.map +1 -1
  37. package/dist/domain/lib/refactor.d.ts +2 -0
  38. package/dist/gate/index.d.ts +7 -0
  39. package/dist/gate/index.js +15 -0
  40. package/dist/gate/index.js.map +1 -1
  41. package/dist/patrol/lib/attempt.js +10 -2
  42. package/dist/patrol/lib/attempt.js.map +1 -1
  43. package/dist/patrol/lib/base.d.ts +10 -3
  44. package/dist/patrol/lib/base.js +14 -8
  45. package/dist/patrol/lib/base.js.map +1 -1
  46. package/dist/patrol/lib/cycle.d.ts +1 -1
  47. package/dist/patrol/lib/cycle.js +32 -1
  48. package/dist/patrol/lib/cycle.js.map +1 -1
  49. package/dist/patrol/lib/recover.d.ts +2 -1
  50. package/dist/patrol/lib/recover.js +16 -1
  51. package/dist/patrol/lib/recover.js.map +1 -1
  52. package/dist/patrol/lib/scorecard.js +12 -4
  53. package/dist/patrol/lib/scorecard.js.map +1 -1
  54. package/dist/patrol/lib/steps.d.ts +5 -2
  55. package/dist/patrol/lib/steps.js +9 -6
  56. package/dist/patrol/lib/steps.js.map +1 -1
  57. package/dist/playbook/index.js +3 -3
  58. package/dist/roles/lib/prompts.d.ts +1 -0
  59. package/dist/roles/lib/prompts.js +6 -0
  60. package/dist/roles/lib/prompts.js.map +1 -1
  61. package/dist/roles/lib/refactorer.d.ts +1 -0
  62. package/dist/roles/lib/refactorer.js +24 -6
  63. package/dist/roles/lib/refactorer.js.map +1 -1
  64. package/dist/roles/lib/scorecard-text.js +1 -1
  65. package/dist/roles/lib/scorecard-text.js.map +1 -1
  66. package/dist/store/index.d.ts +4 -1
  67. package/dist/store/index.js +7 -0
  68. package/dist/store/index.js.map +1 -1
  69. package/package.json +1 -1
  70. package/ui/app.js +1236 -324
  71. package/ui/index.html +35 -13
  72. package/ui/style.css +1063 -340
  73. /package/dist/{patrol → domain}/lib/pick.js +0 -0
package/README.md CHANGED
@@ -1,206 +1,157 @@
1
- # Sloppatrol
1
+ <p align="center">
2
+ <img src="assets/banner.png" alt="Sloppatrol: AI agents that clean up your code, and prove nothing broke." width="100%">
3
+ </p>
2
4
 
3
- Sloppatrol is a team of agents that patrols your repo all day and makes the code cleaner, one small pull request at a time. It never changes what the code does.
5
+ <p align="center">
6
+ <a href="https://www.npmjs.com/package/sloppatrol"><img src="https://img.shields.io/npm/v/sloppatrol?color=22d3ee&label=npm" alt="npm version"></a>
7
+ <a href="https://github.com/agent-labs-dev/sloppatrol/actions/workflows/ci.yml"><img src="https://github.com/agent-labs-dev/sloppatrol/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
8
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-blue" alt="License: Apache-2.0"></a>
9
+ </p>
4
10
 
5
- It is the code-quality sibling of [Bugpatrol](https://github.com/agent-labs-dev/bugpatrol) and [Speedpatrol](https://github.com/agent-labs-dev/speedpatrol): one `.sloppatrol/` folder, agent roles on any agent runtime, a patrol loop, a live dashboard, and GitHub pull requests.
11
+ Sloppatrol is a team of agents that patrols your repo and makes the code cleaner, one small pull request at a time. It never changes what the code does, and each pull request carries the proof.
6
12
 
7
- - The **surveyor** reads the code and records **opportunities**: shallow modules, mixed concerns, hidden dependencies, deep imports, duplicated owners, dead code, tests that mock the team's own code.
8
- - The **refactorer** makes one opportunity real, in its own git worktree.
9
- - The **gate** is code, not a model. It decides what is kept: guards on the diff, then every check of your repo.
10
- - The **assessor** scores code against a rubric of seven quality metrics: for the repo's scorecard, and blind, before and after, for every refactor.
11
- - The **reviewer** reads a change that passed the gate. It can only reject.
12
- - Each verified refactor becomes a draft pull request.
13
+ - A **surveyor** agent reads the code and records opportunities: shallow modules, mixed concerns, hidden dependencies, tests that mock your own code.
14
+ - A **refactorer** agent makes one opportunity real, in its own git worktree.
15
+ - The **gate** is code, not a model. It keeps a refactor only when your checks pass and a planted bug turns a test red.
16
+ - Three blind **assessor** agents score the code before and after, on seven quality metrics. The target metrics must go up.
17
+ - A **reviewer** agent reads the change against your repo's rules. It can only reject.
18
+
19
+ It is the code-quality sibling of [Bugpatrol](https://github.com/agent-labs-dev/bugpatrol) and [Speedpatrol](https://github.com/agent-labs-dev/speedpatrol).
13
20
 
14
21
  ```bash
15
- npx sloppatrol init
16
22
  npx sloppatrol
17
23
  ```
18
24
 
19
- ## Why you can trust a refactor
20
-
21
- An agent proposes; code decides. A refactor is kept only when every step below passes, and no agent can overrule one.
22
-
23
- | Step | What it checks |
24
- | --- | --- |
25
- | One side | A **source** refactor changes no test file, so your existing tests prove the behaviour held. A **tests** refactor changes no source file, so the unchanged source proves the new tests right. |
26
- | Frozen files | No manifest, lockfile, tool config, CI file, snapshot or `.env` changes. No path in `ignore`. |
27
- | No suppression | No added `@ts-ignore`, `eslint-disable`, `# type: ignore`, `as any`, coverage exclusion, or skipped or focused test. A suppression that moves with its code is fine. |
28
- | Tests kept | The diff removes no test case, and changes no test file that no check runs (`uncheckedTests`). |
29
- | Size | At most `guards.maxFiles` files and `guards.maxLines` lines. |
30
- | Checks | Every command in `checks` passes, as it passes on `main`. Sloppatrol does no work while `main` is red. |
31
- | Review | A reviewer agent reads the diff against the playbook, and rejects when in doubt. |
25
+ `npx sloppatrol` runs the patrol: survey, refactor, gate, prove, review, and publish, again and again. Verified refactors wait for `sloppatrol publish` until you turn on GitHub.
32
26
 
33
- | Mutation | A **tests** refactor plants one bug in the unchanged source; a test check must turn red. A test that cannot fail proves nothing. |
34
- | Improvement | The assessor scores the changed files before and after, blind. The target metrics must go up; no other metric may drop. |
27
+ ### How the patrol runs
35
28
 
36
- So the stronger your tests, the more Sloppatrol can do. Each check must run the same work on `main` and on every refactor: a command that picks its tests from the diff (`--changed`, `affected`) runs less on `main`, so a failure on a refactor can be old. `sloppatrol doctor` warns about such a check. Where code has no tests, the surveyor proposes **characterization tests** first: tests that pin what the code does today. To move a test from a mocking library to a fake, it makes two refactors: `inject-dependency` (source: add a seam, with today's behaviour as the default), then `replace-mock` (tests: inject a fake through the seam).
37
-
38
- ## The metrics
29
+ ```mermaid
30
+ flowchart TB
31
+ start(["npx sloppatrol"]) --> pull["Pull main, run your checks, score more files"]
32
+ pull -->|green| survey["1 · Survey<br/>LLM · Surveyor records opportunities"]
33
+ survey --> refactor["2 · Refactor<br/>LLM · Refactorer edits a worktree"]
34
+ refactor --> gate["3 · Gate<br/>Code · guards, your checks, a planted bug"]
35
+ gate --> assess["4 · Prove the gain<br/>LLM · 3 blind assessors score before and after"]
36
+ assess --> review["5 · Review<br/>LLM · Reviewer, veto only"]
37
+ review --> publish["6 · Publish<br/>Code · a draft PR with its proof"]
38
+ publish --> wait["Wait for the next cycle"]
39
+ wait -->|"next cycle"| pull
40
+
41
+ subgraph legend ["Legend"]
42
+ direction LR
43
+ l1["LLM agent"] ~~~ l3["Code, no model"] ~~~ l4["Off by default"]
44
+ end
45
+ wait ~~~ legend
39
46
 
40
- An assessor agent scores each file against a fixed rubric, and cites the lines behind each score. For each metric it picks one of five anchored levels, and Sloppatrol shows the result as 0 (worst) to 100 (best): a level of 3 is 75. A scorecard also shows one **overall** score, the mean of all metrics. The rubric anchors every level in things a reader can point at, so scores stay consistent ([ADR 0004](docs/adr/0004-llm-judged-metrics.md)).
47
+ classDef llm fill:#312e81,stroke:#a5b4fc,color:#ffffff
48
+ classDef code fill:#1e293b,stroke:#64748b,color:#e2e8f0
49
+ classDef opt fill:#1e293b,stroke:#64748b,color:#e2e8f0,stroke-width:2px,stroke-dasharray:6 4
50
+ class survey,refactor,assess,review,l1 llm
51
+ class start,pull,gate,wait,l3 code
52
+ class publish,l4 opt
53
+ style legend fill:transparent,stroke:#64748b
54
+ ```
41
55
 
42
- | Metric | The question |
43
- | --- | --- |
44
- | Simplicity | Can a reader follow each function without holding much in their head? |
45
- | Modularity | Does the file own one concept, behind a small interface, apart from other concerns? |
46
- | Injection | Does the code receive what it depends on, or reach out for it? |
47
- | Purity | How much of the logic lives in pure functions (same input, same output, no side effects), with state and effects kept small and at the edge? |
48
- | Test quality | Do the tests prove behaviour through the interface, and would they fail if it broke? |
49
- | Clarity | Does every name, comment and abstraction earn its place? |
50
- | Agent-friendliness | How hard is it for an agent to change this file wrong, and is it a pattern worth copying? |
56
+ [How it works](docs/how-it-works.md) shows each step of the gate, and the proof on each pull request.
51
57
 
52
- The scorecard also checks the repo's own guardrails, from files alone: an agent guide, strict types, a linter, module boundary rules, a pre-commit hook, CI and tests. Each one turns a wrong edit into a failed check. Sloppatrol reports a missing one; it never adds one itself, because tool configs are frozen.
58
+ ## Score your codebase
53
59
 
54
- Each commit gets a **scorecard** of the whole repo. A file keeps its scores while its content does not change, and each cycle scores up to `metrics.panel` more files: the most changed first, then the largest. So coverage grows each cycle until every file is scored, and the scorecard shows how much it covers. Every mean is weighted by lines. The surveyor starts from the worst scores, and each opportunity names the metrics it will raise. `sloppatrol score --files 200` scores more now; the dashboard shows the trend.
60
+ Sloppatrol can score your code without the patrol. It changes no code and runs none of your checks, so it works on any repo.
55
61
 
56
- ## The proof
62
+ <p align="center">
63
+ <img src="assets/scorecard.png" alt="The scorecard of a demo project: an overall score of 81 in a green ring, a bar for each of the seven metrics, the repo guardrails, and the command npx sloppatrol score." width="100%">
64
+ </p>
57
65
 
58
- Every pull request carries its proof, built by code and by a blind assessor, never by the agent that wrote the change:
66
+ 1. Log in to Claude Code, Codex or opencode. Sloppatrol uses the agent that you have.
67
+ 2. Go to the root of your repo, and create the config:
59
68
 
60
- - **It breaks nothing:** the side it changed, the guards it passed, the same checks green on `main` and on the change (with the test counts), and for a tests refactor, the planted bug its tests caught.
61
- - **It makes the code better:** each metric before and after, the target marked, and the measured lines, nesting, comments, mocks and suppressions.
62
- - **It follows the repo's rules:** the rule files read, and the reviewer's account of each rule that applies.
69
+ ```bash
70
+ npx sloppatrol init
71
+ ```
63
72
 
64
- ## Your repo's rules
73
+ 3. Optional: add your generated code to `ignore` in `.sloppatrol/sloppatrol.yml`. A tool writes that code, so it must not change your score.
65
74
 
66
- Every agent reads your repo's own rules before it acts, and they win over the playbook: `.sloppatrol/instructions.md`, every `AGENTS.md` and `CLAUDE.md` from the repo root down to the changed files (with their `@path` imports), `CONTRIBUTING.md`, `CODING_STANDARDS.md`, `GLOSSARY.md`, and the titles of your decision records. `sloppatrol doctor` lists what it found.
75
+ ```yaml
76
+ ignore: [src/generated/**]
77
+ ```
67
78
 
68
- ## The playbook
79
+ 4. Score each file:
69
80
 
70
- The agents follow a [playbook](playbook/) of top-tier engineering practice, written for agents:
81
+ ```bash
82
+ npx sloppatrol score
83
+ ```
71
84
 
72
- - [Principles](playbook/principles.md): deep modules, seams, ports and adapters, one owner per concept, separation of concerns, dependency injection, single responsibility, small files, no sediment. The vocabulary comes from Ousterhout, Feathers, Fowler, and [Matt Pocock's skills](https://github.com/mattpocock/skills).
73
- - [Testing](playbook/testing.md): test through the interface; fakes injected through a seam, never a mocking library for your own code.
74
- - [Smells](playbook/smells.md) and [Safety](playbook/safety.md): what to look for, and the behaviour a refactor must keep.
75
- - One page per stack, picked from what the census detects: [TypeScript](playbook/stacks/typescript.md), [React and React Native](playbook/stacks/react.md), [Node backends](playbook/stacks/node-backend.md), [Python](playbook/stacks/python.md), [Go](playbook/stacks/go.md), [Swift](playbook/stacks/swift.md), [Kotlin](playbook/stacks/kotlin.md), [Rust](playbook/stacks/rust.md).
85
+ An assessor agent scores each file on the [seven metrics](docs/metrics.md), from 0 (worst) to 100 (best). Then Sloppatrol opens the scorecard in your browser. Click **Download PNG** or **Copy image**, and post it.
76
86
 
77
- Your repo's own rules win over the playbook: `.sloppatrol/instructions.md`, `CLAUDE.md`, `AGENTS.md`, `CONTRIBUTING.md`, `GLOSSARY.md`, and the decision records in `docs/adr/`.
87
+ Sloppatrol scores the last commit on `origin/main`, not your local changes. The first run can take some minutes on a large repo. Sloppatrol keeps each score, so the next run scores only the files that changed. `--files <n>` scores at most `n` files in one run.
78
88
 
79
- ## Commands
89
+ ## The dashboard
80
90
 
81
- ```text
82
- Start
83
- sloppatrol init Create .sloppatrol/ with a guess at your checks
84
- sloppatrol doctor Show the config, the agent each role runs on, and what is missing
85
-
86
- Run
87
- sloppatrol Patrol all day: a cycle every patrol.intervalMinutes, with the dashboard
88
- sloppatrol --once One cycle, then stop
89
- sloppatrol dashboard Only the dashboard (http://127.0.0.1:4322)
90
-
91
- One step at a time
92
- sloppatrol check Run your checks on the patrolled commit (the oracle)
93
- sloppatrol survey Let the surveyor record opportunities now
94
- sloppatrol refactor [id] Attempt one opportunity now: the best open one, or <id>
95
- sloppatrol score Score the repo now: the metrics of the panel of files
96
- sloppatrol publish Open pull requests for verified refactors (--dry-run)
97
-
98
- Read
99
- sloppatrol status The opportunities, the refactors and the agents
100
- sloppatrol census What the surveyor sees: stack, large files, mocks, churn
101
- sloppatrol dismiss <id> Never propose this opportunity again (--reason "...")
102
- ```
91
+ `npx sloppatrol` serves a live dashboard on http://127.0.0.1:4322. The **Overview** tells you at a glance if the patrol is healthy: the checks on main, what waits for your decision, the code quality and its change, and the last cycle. Then it lists what needs attention, with the command to run next.
103
92
 
104
- ## A cycle
93
+ <p align="center">
94
+ <img src="assets/dashboard.png" alt="The Overview of the dashboard on a demo project: a status band, the items that need attention with their commands, the agents, the code quality per metric, and the refactor results." width="100%">
95
+ </p>
105
96
 
106
- ```mermaid
107
- flowchart TB
108
- start(["sloppatrol"]) --> pull["Resolve origin/main, check it out"]
109
- pull --> base{{"Checks on main<br/>(code)"}}
110
- base -->|red| wait
111
- base -->|green| survey["Survey, when the backlog is low<br/>LLM · surveyor"]
112
- survey --> pick["Pick the strongest opportunity<br/>no file overlap with open PRs"]
113
- pick --> refactor["Refactor in a worktree<br/>LLM · refactorer"]
114
- refactor --> guards{{"Guards on the diff<br/>(code)"}}
115
- guards -->|pass| checks{{"Your checks<br/>(code)"}}
116
- checks -->|pass| review["Review<br/>LLM · reviewer, veto only"]
117
- review -->|approve| pr["Draft pull request"]
118
- guards -->|fail| reject["Rejected: worktree removed"]
119
- checks -->|fail| reject
120
- review -->|reject| reject
121
- pr --> wait["Wait patrol.intervalMinutes"]
122
- reject --> wait
123
- wait --> pull
97
+ The other pages show each refactor as a pipeline with its proof, the scorecard of each file, every check run, the backlog in the order the refactorer picks it, and every agent session. [The dashboard](docs/dashboard.md) tells more.
124
98
 
125
- classDef llm fill:#312e81,stroke:#a5b4fc,color:#ffffff
126
- classDef code fill:#1e293b,stroke:#64748b,color:#e2e8f0
127
- class survey,refactor,review llm
128
- class start,pull,base,pick,guards,checks,pr,reject,wait code
129
- ```
99
+ ## Set up with your agent
130
100
 
131
- - A merged pull request finishes its opportunity. A closed one dismisses it for good.
132
- - At most `github.maxOpen` pull requests wait at once, and two never touch the same file.
133
- - An opportunity that fails the gate `maxAttempts` times is exhausted.
101
+ 1. Install the Sloppatrol skill in your repo:
134
102
 
135
- ## The dashboard
103
+ ```bash
104
+ npx skills add agent-labs-dev/sloppatrol
105
+ ```
136
106
 
137
- `sloppatrol` serves a dashboard on `http://127.0.0.1:4322` while it patrols (`--no-dashboard` turns it off; `sloppatrol dashboard` serves it alone). It shows, live:
107
+ The [skills CLI](https://github.com/vercel-labs/skills) installs the skill for Claude Code, Codex, Cursor, and many other agents. It also writes `skills-lock.json` at the repo root. Commit both, so your team gets the skill too.
138
108
 
139
- - **Agents**: what the patrol, the surveyor, the refactorer, the gate and the reviewer do now.
140
- - **Refactors**: each attempt as a pipeline (refactorer → guards → checks → mutation → metrics → review → pull request), with its full proof.
141
- - **Scorecard**: each metric's score and trend over commits, and every file of the panel with the evidence behind its scores.
142
- - **Checks**: every check run on `main`, on each refactor, and each run the refactorer starts itself, with the output of each check.
143
- - **Backlog**: the opportunities by status, with the problem, the change and the files.
144
- - **Sessions**: every agent session as a timeline of its tool calls.
109
+ 2. Give this prompt to your agent:
145
110
 
146
- ## Any agent, any model
111
+ ```text
112
+ Set up Sloppatrol for this repo.
113
+ ```
147
114
 
148
- By default every role runs on the agent CLI you have installed: `agent: auto` picks `claude`, then `codex`, then `opencode`, from your `PATH`. The surveyor and the reviewer get read-only access; the refactorer gets edit access in its own worktree. Every role reaches Sloppatrol through its tools over a local MCP server.
115
+ The [skill](skills/sloppatrol/SKILL.md) tells the agent what Sloppatrol does, how to configure the checks of your repo, how to run it, and how to read the results.
149
116
 
150
- ```yaml
151
- agent: auto # or claude | codex | opencode
152
- agents:
153
- reviewer: { use: codex } # a second opinion from another agent
154
- surveyor:
155
- use: { runtime: model, via: openrouter, model: anthropic/claude-opus-5.5 }
156
- ```
117
+ If your agent cannot install skills, give it the skill URL:
157
118
 
158
- `{ runtime: model, via: anthropic | openai | openrouter | custom, model }` runs Sloppatrol's own tool loop on an API key. `{ runtime: cli, command: "..." }` runs any command, with `{prompt}`, `{mcp}`, `{mcpUrl}` and `{workdir}` filled in.
159
-
160
- ## Configuration
161
-
162
- ```yaml
163
- # .sloppatrol/sloppatrol.yml
164
- agent: auto
165
- prepare: [pnpm install --frozen-lockfile] # each fresh checkout and worktree
166
- checks: # the oracle
167
- - { name: typecheck, run: pnpm typecheck }
168
- - { name: lint, run: pnpm lint }
169
- - { name: test, run: pnpm test, tests: true } # tests: true marks the checks a planted bug must turn red
170
- focus: [src/**] # where the surveyor looks (default: everywhere)
171
- ignore: [src/generated/**] # what no agent may change
172
- uncheckedTests: [tests/e2e/**] # tests no check runs: no refactor may change them
173
- guards: { maxFiles: 12, maxLines: 600 }
174
- metrics: { enabled: true, panel: 100, tolerance: 0.5, judges: 3 } # panel: files newly scored per cycle
175
- agents:
176
- surveyor: { minBacklog: 3, maxPerSurvey: 8 }
177
- refactorer: { maxPerCycle: 1, maxAttempts: 2 }
178
- reviewer: { enabled: true }
179
- github: { enabled: true, draft: true, maxOpen: 3, labels: [sloppatrol] }
180
- patrol: { intervalMinutes: 60, pull: origin/main }
119
+ ```text
120
+ Read https://raw.githubusercontent.com/agent-labs-dev/sloppatrol/main/skills/sloppatrol/SKILL.md and set up Sloppatrol for this repo.
181
121
  ```
182
122
 
183
- Every role also takes `maxSteps`, `timeoutMinutes` and `budgetUsd` (model runtime). Pull requests open with your `gh` login.
123
+ To set it up by hand, read [Getting started](docs/getting-started.md).
184
124
 
185
- `.sloppatrol/sloppatrol.yml` and `.sloppatrol/instructions.md` are committed. `.sloppatrol/runs/` holds local data (checkouts, worktrees, opportunities, refactors, check runs, sessions) as plain JSON, and git ignores it.
125
+ ## What is supported
186
126
 
187
- ## Docs
127
+ | Area | Supported |
128
+ | --- | --- |
129
+ | Languages | Any language with checks that you can run from a shell. The playbook has pages for TypeScript, React and React Native, Node backends, Python, Go, Swift, Kotlin and Rust. |
130
+ | Agents | Claude Code, Codex or opencode, with your existing login (`agent: auto` picks the installed one). Or an API key for Anthropic, OpenAI, OpenRouter, or a custom endpoint. |
131
+ | Repo rules | `AGENTS.md`, `CLAUDE.md` and their `@` imports, `CONTRIBUTING.md`, `GLOSSARY.md`, and your decision records |
132
+ | GitHub | Draft pull requests through the `gh` CLI |
133
+ | Output | A local dashboard, GitHub pull requests, and JSON files under `.sloppatrol/runs/` |
188
134
 
189
- - [Glossary](GLOSSARY.md)
190
- - [Decisions](docs/adr/): why it works this way.
135
+ ## Documentation
191
136
 
192
- ## Development
137
+ | Page | What it covers |
138
+ | --- | --- |
139
+ | [Getting started](docs/getting-started.md) | Add Sloppatrol to your repo, step by step |
140
+ | [How it works](docs/how-it-works.md) | The cycle, the gate, the proof, your repo's rules, and the playbook |
141
+ | [The metrics](docs/metrics.md) | The seven metrics, the rubric, and how the scorecard grows |
142
+ | [Commands](docs/commands.md) | All the CLI commands |
143
+ | [Configuration](docs/configuration.md) | All the settings in `.sloppatrol/sloppatrol.yml` |
144
+ | [Agents and models](docs/models.md) | The agent of each role, and the model providers |
145
+ | [The dashboard](docs/dashboard.md) | What each page shows |
146
+ | [Playbook](playbook/principles.md) | The engineering practice that the agents follow |
147
+ | [Glossary](GLOSSARY.md) | The words Sloppatrol uses, with one meaning each |
148
+ | [Decisions](docs/adr/) | Why Sloppatrol works this way |
149
+ | [Contributing](CONTRIBUTING.md) | Build Sloppatrol from source, the shape of the code, and releases |
193
150
 
194
- ```bash
195
- pnpm install
196
- pnpm build
197
- pnpm test
198
- pnpm check # Biome, module boundaries (dependency-cruiser), types
199
- pnpm knip
200
- ```
151
+ ## License
201
152
 
202
- Sloppatrol follows its own playbook: each folder in `src/` is a deep module, other modules reach it only through its root files, the CLI is the only composition root, and the tests use real git repos, real processes, an in-memory GitHub and a scripted agent, with no mocking library.
153
+ [Apache-2.0](LICENSE)
203
154
 
204
- ## License
155
+ ---
205
156
 
206
- Apache-2.0
157
+ <p align="center">Made with ❤️ by the <a href="https://nebula.gg">Nebula</a> team.</p>
@@ -9,10 +9,12 @@ export async function takeCensus(root, scope) {
9
9
  !matchesAny(path, scope.ignore) &&
10
10
  (scope.focus.length === 0 || matchesAny(path, scope.focus));
11
11
  const code = all.filter(inScope);
12
+ // Generated files can outnumber the real code, so they do not decide the main language.
13
+ const kept = all.filter((path) => !matchesAny(path, scope.ignore));
12
14
  const tests = code.filter((path) => matchesAny(path, scope.tests));
13
15
  const sources = code.filter((path) => !matchesAny(path, scope.tests));
14
16
  const [stack, measured, hot] = await Promise.all([
15
- detectStack(root, all),
17
+ detectStack(root, kept),
16
18
  measureFiles(root, sources, tests),
17
19
  churn(root, inScope),
18
20
  ]);
@@ -32,7 +34,7 @@ export function censusMarkdown(census) {
32
34
  const list = (items, line) => (items.length ? items.map(line).join('\n') : '- none');
33
35
  return [
34
36
  '# Census',
35
- `Languages: ${stack.languages.map((l) => `${l.name} (${l.files} files)`).join(', ') || 'none found'}`,
37
+ `Languages: ${stack.languages.map((l) => `${l.name} (${l.files} files, ${l.lines} lines)`).join(', ') || 'none found'}`,
36
38
  `Frameworks: ${stack.frameworks.join(', ') || 'none found'}`,
37
39
  `Project kind: ${stack.kinds.join(', ')}`,
38
40
  `Files: ${census.sourceFiles} source, ${census.testFiles} test`,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/census/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/census/index.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,43 @@ async function read(root, file) {
5
5
  const path = join(root, file);
6
6
  return existsSync(path) ? readFile(path, 'utf8').catch(() => '') : '';
7
7
  }
8
- const STATIC_LANGUAGES = ['go', 'rust', 'swift', 'kotlin', 'java', 'csharp'];
8
+ /** The compiler of each of these rejects a wrong type. JavaScript has no compiler check, so it is not here. */
9
+ const STATIC_LANGUAGES = ['typescript', 'go', 'rust', 'swift', 'kotlin', 'java', 'csharp'];
10
+ /** A language with this share of the code lines or more needs its own type check. */
11
+ const MAIN_SHARE = 0.1;
12
+ /** Evidence that a check rejects a wrong type in each language, keyed by language. */
13
+ async function typeChecks(root, files) {
14
+ let python = files.find((f) => /(^|\/)(mypy\.ini|pyrightconfig\.json)$/.test(f));
15
+ for (const file of files.filter((f) => /(^|\/)(pyproject\.toml|setup\.cfg)$/.test(f))) {
16
+ if (python)
17
+ break;
18
+ if (/\[(tool\.(mypy|pyright|ty)|mypy)\]/.test(await read(root, file)))
19
+ python = `${file}: a type checker is configured`;
20
+ }
21
+ return {
22
+ python,
23
+ ...Object.fromEntries(STATIC_LANGUAGES.map((name) => [name, `${name}: the compiler checks types`])),
24
+ };
25
+ }
26
+ /**
27
+ * Strict types are present when each main language of the repo has a type check.
28
+ * A repo can mix languages, such as a Rust server with a JavaScript UI.
29
+ */
30
+ async function strictTypes(root, files, stack) {
31
+ const total = stack.languages.reduce((sum, l) => sum + l.lines, 0);
32
+ const main = stack.languages.filter((l, i) => i === 0 || l.lines >= total * MAIN_SHARE).map((l) => l.name);
33
+ const checks = await typeChecks(root, files);
34
+ const missing = main.filter((name) => !checks[name]);
35
+ return {
36
+ name: 'Strict types',
37
+ present: main.length > 0 && missing.length === 0,
38
+ evidence: main.length === 0
39
+ ? 'No code found.'
40
+ : missing.length === 0
41
+ ? main.map((name) => checks[name]).join('; ')
42
+ : `No strict type check for ${missing.join(', ')}: a wrong type reaches run time.`,
43
+ };
44
+ }
9
45
  /**
10
46
  * The repo-wide guardrails that keep an agent from changing code wrong,
11
47
  * found from files alone. Each one turns a wrong edit into a failed check.
@@ -14,27 +50,20 @@ export async function detectGuardrails(root, files, stack, testFiles) {
14
50
  const has = (pattern) => files.find((f) => pattern.test(f));
15
51
  const pyproject = await read(root, 'pyproject.toml');
16
52
  const pkg = await read(root, 'package.json');
17
- const tsconfig = await read(root, 'tsconfig.json');
18
- const main = stack.languages[0]?.name;
19
53
  const found = (name, evidence, why) => ({
20
54
  name,
21
55
  present: Boolean(evidence),
22
56
  evidence: evidence ?? why,
23
57
  });
24
- const strict = (/"strict"\s*:\s*true/.test(tsconfig) && 'tsconfig.json: strict') ||
25
- (/\[tool\.(mypy|pyright|ty)\]/.test(pyproject) && 'pyproject.toml: a type checker is configured') ||
26
- has(/(^|\/)(mypy\.ini|pyrightconfig\.json)$/) ||
27
- (main && STATIC_LANGUAGES.includes(main) ? `${main} is statically typed` : undefined);
28
58
  return [
29
59
  found('Agent guide', has(/^(AGENTS|CLAUDE)\.md$/), 'No AGENTS.md or CLAUDE.md at the root: agents learn the rules by trial.'),
30
- found('Strict types', strict || undefined, 'No strict type check: a wrong type reaches run time.'),
60
+ await strictTypes(root, files, stack),
31
61
  found('Linter', has(/(^|\/)(biome\.jsonc?|eslint\.config\.\w+|\.eslintrc(\.\w+)?|ruff\.toml|\.golangci\.\w+|\.swiftlint\.yml|detekt\.yml)$/) || (/\[tool\.ruff/.test(pyproject) ? 'pyproject.toml: ruff' : undefined), 'No linter config.'),
32
62
  found('Module boundaries', has(/(^|\/)\.dependency-cruiser\.\w+$|(^|\/)\.importlinter$/) ||
33
63
  (/\[tool\.importlinter\]/.test(pyproject) ? 'pyproject.toml: import-linter' : undefined) ||
34
64
  (/eslint-plugin-boundaries|@nx\/enforce-module-boundaries/.test(pkg)
35
65
  ? 'package.json: boundary lint'
36
66
  : undefined), 'Nothing stops a deep import across modules.'),
37
- found('Pre-commit hook', has(/^(\.husky\/|\.pre-commit-config\.yaml$|lefthook\.ya?ml$|\.githooks\/)/), 'No hook: a broken change reaches a commit.'),
38
67
  found('CI', has(/^(\.github\/workflows\/|\.gitlab-ci\.yml$|\.circleci\/)/), 'No CI config found.'),
39
68
  found('Tests', testFiles > 0 ? `${testFiles} test files` : undefined, 'No test files: nothing pins behaviour.'),
40
69
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"guardrails.js","sourceRoot":"","sources":["../../../src/census/lib/guardrails.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"guardrails.js","sourceRoot":"","sources":["../../../src/census/lib/guardrails.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,9 @@
1
1
  export type Stack = {
2
- /** Languages by file count, most first. */
2
+ /** Languages by line count, most first. Many small files, such as configs, do not make a main language. */
3
3
  languages: {
4
4
  name: string;
5
5
  files: number;
6
+ lines: number;
6
7
  }[];
7
8
  frameworks: string[];
8
9
  /** What the project is: it decides which playbook pages apply. */
@@ -49,11 +49,15 @@ async function nodeDependencies(root, files) {
49
49
  export async function detectStack(root, files) {
50
50
  const counts = new Map();
51
51
  for (const file of files) {
52
- const language = languageOf(file);
53
- if (language)
54
- counts.set(language, (counts.get(language) ?? 0) + 1);
52
+ const name = languageOf(file);
53
+ if (!name)
54
+ continue;
55
+ const count = counts.get(name) ?? { name, files: 0, lines: 0 };
56
+ count.files += 1;
57
+ count.lines += (await read(root, file).catch(() => '')).split('\n').length;
58
+ counts.set(name, count);
55
59
  }
56
- const languages = [...counts].map(([name, n]) => ({ name, files: n })).sort((a, b) => b.files - a.files);
60
+ const languages = [...counts.values()].sort((a, b) => b.lines - a.lines);
57
61
  const { deps, bin } = await nodeDependencies(root, files);
58
62
  const python = (await Promise.all(['pyproject.toml', 'requirements.txt'].map((f) => read(root, f)))).join('\n');
59
63
  for (const name of ['django', 'fastapi', 'flask'])
@@ -1 +1 @@
1
- {"version":3,"file":"stack.js","sourceRoot":"","sources":["../../../src/census/lib/stack.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAU1C,MAAM,SAAS,GAA2B;IACxC,KAAK,EAAE,YAAY;IACnB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,YAAY;IACpB,KAAK,EAAE,YAAY;IACnB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,YAAY;IACpB,KAAK,EAAE,QAAQ;IACf,KAAK,EAAE,IAAI;IACX,KAAK,EAAE,MAAM;IACb,QAAQ,EAAE,OAAO;IACjB,KAAK,EAAE,QAAQ;IACf,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE,MAAM;IACf,KAAK,EAAE,MAAM;IACb,KAAK,EAAE,QAAQ;CAChB,CAAC;AAEF,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,OAAO,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,MAAM,GAAG,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;AACvH,MAAM,OAAO,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AAEpH,KAAK,UAAU,IAAI,CAAC,IAAY,EAAE,IAAY;IAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC9B,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACxD,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,IAAY,EAAE,KAAe;IAC3D,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,IAAI,GAAG,GAAG,KAAK,CAAC;IAChB,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;QAC/G,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAA4B,CAAC;YAC1E,KAAK,MAAM,GAAG,IAAI,CAAC,cAAc,EAAE,iBAAiB,EAAE,kBAAkB,CAAC;gBACvE,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAE,GAAG,CAAC,GAAG,CAAwC,IAAI,EAAE,CAAC;oBAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACzG,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,oDAAoD;QACtD,CAAC;IACH,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;AACvB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAY,EAAE,KAAe;IAC7D,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,QAAQ;YAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACtE,CAAC;IACD,MAAM,SAAS,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IACzG,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,gBAAgB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC1D,MAAM,MAAM,GAAG,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChH,KAAK,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC;QAAE,IAAI,IAAI,MAAM,CAAC,MAAM,IAAI,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;YAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACrH,MAAM,UAAU,GAAG,CAAC,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5E,MAAM,KAAK,GAAG,IAAI,GAAG,EAA0B,CAAC;IAChD,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAAE,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACpE,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,0DAA0D,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAAE,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC/G,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAAE,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACtE,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QAAE,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACvF,IAAI,GAAG;QAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC1B,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC;QAAE,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC3C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC;AACtD,CAAC"}
1
+ {"version":3,"file":"stack.js","sourceRoot":"","sources":["../../../src/census/lib/stack.ts"],"names":[],"mappings":"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"}
package/dist/cli/index.js CHANGED
@@ -12,6 +12,7 @@ import { stopAll } from '../processes/index.js';
12
12
  import { scorecardMarkdown } from '../roles/index.js';
13
13
  import { Store } from '../store/index.js';
14
14
  import { intFlag, parseArgv, strFlag } from './lib/argv.js';
15
+ import { openInBrowser } from './lib/browser.js';
15
16
  import { doctor } from './lib/doctor.js';
16
17
  import { init } from './lib/init.js';
17
18
  import { status } from './lib/status.js';
@@ -45,10 +46,11 @@ async function dashboard(store, project, port) {
45
46
  return startDashboard({ store, project, port: 0 });
46
47
  }
47
48
  }
49
+ const SIGNALS = ['SIGINT', 'SIGTERM', 'SIGHUP'];
48
50
  /**
49
51
  * Ctrl-C or a SIGTERM stops every check and agent CLI Sloppatrol started,
50
52
  * marks the running agents stopped, and exits. The next patrol cleans up
51
- * the interrupted refactor.
53
+ * the interrupted refactor. Returns a function that removes the handlers.
52
54
  */
53
55
  function stopOnSignal(store) {
54
56
  const stop = async (signal) => {
@@ -59,8 +61,12 @@ function stopOnSignal(store) {
59
61
  await store.setStatus({ role: status.role, state: 'idle', detail: 'Stopped.' });
60
62
  process.exit(130);
61
63
  };
62
- for (const signal of ['SIGINT', 'SIGTERM', 'SIGHUP'])
63
- process.once(signal, () => void stop(signal));
64
+ for (const signal of SIGNALS)
65
+ process.once(signal, stop);
66
+ return () => {
67
+ for (const signal of SIGNALS)
68
+ process.off(signal, stop);
69
+ };
64
70
  }
65
71
  function untilSigint() {
66
72
  return new Promise((done) => process.once('SIGINT', () => done()));
@@ -121,8 +127,18 @@ async function main(args) {
121
127
  return refactor.status === 'verified' ? EXIT.ok : EXIT.failed;
122
128
  }
123
129
  case 'score': {
124
- stopOnSignal(store);
130
+ const unwatch = stopOnSignal(store);
125
131
  out(scorecardMarkdown(await scoreNow(loaded, deps, intFlag(flags, 'files'))));
132
+ unwatch();
133
+ if (flags.dashboard === false)
134
+ return EXIT.ok;
135
+ const server = await dashboard(store, loaded.config.project.name, intFlag(flags, 'port'));
136
+ const page = `${server.url}/#share`;
137
+ out(`\nThe scorecard, ready to share: ${page}\nCtrl-C stops the dashboard.`);
138
+ if (flags.open !== false)
139
+ openInBrowser(page);
140
+ await untilSigint();
141
+ await server.close();
126
142
  return EXIT.ok;
127
143
  }
128
144
  case 'status':
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}