@coldtea/pr-lens-agent-skill 0.1.2 → 0.1.4

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/SKILL.md CHANGED
@@ -1,41 +1,81 @@
1
1
  ---
2
2
  name: pr-lens
3
- description: Draw a code change as an architecture or data-flow diagram with PR Lens. Author a graph document from a diff, validate it, render it to SVG, and attach it to a pull request; or correct a repository's map in .github/pr-lens.yml. Use when asked to diagram, visualise or explain the shape of a change, when attaching a diagram to a pull request you opened, or when an existing PR Lens diagram names things wrongly.
3
+ description: "WHAT: Draws a code change or part of a codebase as an animated architecture or data-flow diagram, on its own or in a pull request. WHEN: asked to diagram, visualise or explain a change or a system, or when a pull request should carry a diagram. KEYWORDS: PR Lens, diagram, architecture, data flow, visualise, visualize, pull request"
4
4
  ---
5
5
 
6
6
  # PR Lens
7
7
 
8
- PR Lens turns a diff into one JSON document (lanes, nodes, edges, ordered flows) and renders it as an animated SVG that reads inside a GitHub pull request comment. The document is the whole contract: if it validates, it renders.
8
+ PR Lens draws code as visually rich animated diagrams. It can represent diffs, architecture, data flows, and more.
9
9
 
10
- You are usually the model. Rather than calling out to a provider, read the diff and write the document yourself, then let the tooling check it. Nothing on this path needs a model key or names a model: whichever one you are running is the one doing the reasoning.
10
+ The diff or code is represented as one JSON document (lanes, nodes, edges, ordered flows) and it renders the JSON as an animated SVG
11
11
 
12
- ## The loop
12
+ ## Operating manual
13
+
14
+ 1. **Read the diff.** When asked to represent a code change: `git diff --find-renames <base>...<head>`. The base is the merge base, not the tip of the base branch.
15
+
16
+ If not expressing a code diff, read the code to be visually represented
17
+
18
+ 2. **Write the document** to `.pr-lens/graph.json`, following `references/graph-document.md`. `references/example.graph.json` is valid reference with three lanes, all four delta states, a hero edge, a seven-step flow, a nested drill-down tree. Read it before you write your first one. It is quicker than reading the reference.
19
+
20
+ 3. **Validate, and fix**
13
21
 
14
- 1. **Read the diff.** `git diff --find-renames <base>...<head>`. The base is the merge base, not the tip of the base branch.
15
- 2. **Write the document** to `.pr-lens/graph.json`, following `references/graph-document.md`. That page is the whole shape: every field, every enum, every limit, and the four rules a JSON Schema cannot express. `references/example.graph.json` is a document that validates — three lanes, all four delta states, a hero edge, a seven-step flow, a nested drill-down tree. Read it before you write your first one. It is quicker than reading the reference.
16
- 3. **Validate, and fix what it names.**
17
22
  ```bash
18
23
  npx @coldtea/pr-lens-cli validate .pr-lens/graph.json
19
24
  ```
20
- Each failure is a path into your document, a reason and a code. Fix every one and run it again. Do not render an invalid document; do not "work around" a failure by deleting the element it names.
25
+
26
+ Fix every failure and run it again. Do not render an invalid document; do not "work around" a failure by deleting the element it names.
27
+
21
28
  4. **Render.**
29
+
30
+ ```bash
31
+ npx @coldtea/pr-lens-cli render .pr-lens/graph.json --theme dark
32
+ ```
33
+
34
+ Render dark as the default theme unless explicitly requested. The SVGs, the manifest and `drawn.graph.json` land in `.pr-lens/`, which the CLI adds to the repository's .gitignore. Do not commit any of it. These files are rebuilt from the diff whenever anyone wants them again. Each SVG is named after its view, the theme and a content hash; `manifest.json` lists them by lens and view, so read the names from there or from the directory.
35
+
36
+ If the user asked for a diagram and nothing more, this is the end of the loop. If working in an environment that supports a visual way to display the image e.g., an in-app browser, an artifact, do so. Otherwise, tell them where the SVGs are and which one is the top view.
37
+
38
+ 5. **Attach, when there is a pull request to attach to.** That means the user asked you to open a PR, asked for a diagram on one that exists, or you are opening a PR as part of changes made. Otherwise skip this step.
39
+
40
+ GitHub CLI uploads the diagram with the pull request. Write the body with a Markdown image pointing at the local file, then pass the same path to `--attach`. `gh` rewrites the reference to the uploaded asset and keeps the alt text you wrote:
41
+
42
+ ```markdown
43
+ Moves bulk sending off the per-recipient trigger and onto a batch endpoint.
44
+
45
+ ![Architecture after this change: the queue route, the new bulk sender and the retired per-recipient path](.pr-lens/overview-dark-4f9bd6c1.svg)
46
+ ```
47
+
22
48
  ```bash
23
- npx @coldtea/pr-lens-cli render .pr-lens/graph.json
49
+ gh pr create --title "Batch broadcast sends" --body-file .pr-lens/body.md \
50
+ --attach .pr-lens/overview-dark-4f9bd6c1.svg
24
51
  ```
25
- The SVGs, the manifest and `drawn.graph.json` land in `.pr-lens/`, which the CLI adds to the repository's .gitignore. Do not commit any of it. These files are a preview, rebuilt from the diff whenever anyone wants them again; the comment on the pull request is the thing you are making.
26
- 5. **Attach.** Put the SVGs somewhere durable an orphan branch, a release asset then compose the comment from the document that was drawn:
52
+
53
+ On a pull request that already exists, `gh pr edit <number>` with the same two flags puts the diagram in the description, and `gh pr comment <number>` puts it in a comment. Repeat `--attach` for each diagram the body references.
54
+
55
+ gh has three rules:
56
+ - The reference has to be a Markdown image, `![alt](path)`. An HTML `<img>` or `<picture>` is left as written, and the file is appended at the bottom of the body instead.
57
+ - The alt text is the caption a reader without images gets. Say what the diagram shows, in one line.
58
+ - `--attach` arrived in GitHub CLI 2.99. Check with `gh --version` before you write a body around it.
59
+
60
+ Attach the views a reviewer needs and leave the rest in `.pr-lens/`: the top architecture view first, then a data flow if the change has a sequence worth following. A body with four diagrams reads worse than one with two, except the four are really needed to understand the change e.g., in the case of a complex feature or refactor.
61
+
62
+ When `--attach` is not an option, publish the SVGs somewhere durable and let the CLI compose the comment instead:
63
+
27
64
  ```bash
28
65
  npx @coldtea/pr-lens-cli comment \
29
66
  --graph .pr-lens/drawn.graph.json \
30
67
  --manifest .pr-lens/manifest.json \
31
68
  --asset-base-url https://raw.githubusercontent.com/<owner>/<repo>/<branch>/<dir>
32
69
  ```
33
- The markdown goes to stdout, with each diagram as a `<picture>` pair so it reads in both GitHub themes. Posting it is your business.
34
70
 
35
- Both flags matter. `--graph` takes `drawn.graph.json`, not the document you wrote: corrections change what the diagrams show, and the CLI refuses a document its manifest does not describe. `--asset-base-url` is where you published the SVGs; leave it out and the markdown points at local paths no reader can fetch.
71
+ `--graph` takes `drawn.graph.json`, not the document you wrote, because corrections change what the diagrams show and the CLI refuses a document its manifest does not describe. `--asset-base-url` is where you published the SVGs; leave it out and the markdown points at local paths no reader can fetch. The markdown goes to stdout, with each diagram as a `<picture>` pair; posting it is your business.
36
72
 
37
73
  If you would rather not author the document yourself, `npx @coldtea/pr-lens-cli analyze --base <ref>` does steps 1 and 2 by asking a provider — Gemini, OpenAI, or any endpoint speaking `/chat/completions` — with a key of your own. That is the only path here that needs one.
38
74
 
75
+ ## The pull request body, when there is one
76
+
77
+ A reviewer should understand the change before reading the diff, so the diagram goes where they look first: the description, not a trailing comment. Open with one sentence on why the change exists, then the architecture diagram, then whatever proves the change works, such as a screenshot of the result or a recording of the interaction. Use one visual per idea. A diagram that needs a paragraph of explanation has a document problem; go back to step 2.
78
+
39
79
  ## What makes a document worth reading
40
80
 
41
81
  - **Include what did not change.** A diagram of only the changed nodes says nothing about blast radius. The unchanged neighbours a change touches are the context; mark them `delta: "unchanged"`.
@@ -45,16 +85,24 @@ If you would rather not author the document yourself, `npx @coldtea/pr-lens-cli
45
85
  - **Attach file refs**: they become the permalinks a reviewer clicks.
46
86
  - **There is no findings lens.** PR Lens is the comprehension layer, not another review bot. There is no field for a bug, a risk or a security note, and a document that invents one is rejected rather than trimmed.
47
87
 
88
+ ## Choosing architecture views
89
+
90
+ Treat architecture views as a C4-inspired decision tree, not a checklist. One useful view is enough for a small change. Start with system context when the change affects a user, an external system or a system boundary. Use a container view for the affected applications, services, jobs, data stores and runtimes. Add a component child only when an affected container's internals matter. Do not add code-level views by default.
91
+
92
+ Every child moves down one level and covers a materially narrower scope. Skip empty, repetitive or speculative levels, and do not infer architecture from folder names alone. Two views should not carry substantially the same nodes and edges. Keep the unchanged direct neighbours that explain blast radius.
93
+
94
+ Keep data-flow views as separate roots rather than nesting them in the architecture tree. Set `defaultOpen: true` on the highest useful architecture view. Lower levels should normally keep the default, `false`.
95
+
48
96
  ## What the validator will catch
49
97
 
50
98
  Read `references/graph-document.md` before writing. The four failures that account for nearly everything:
51
99
 
52
- | Code | What you did |
53
- | --- | --- |
54
- | `BROKEN_REFERENCE` | an edge, a flow step or a view names an id you never declared |
55
- | `INVALID_DOCUMENT` | an invented field; the schemas are strict, unknown keys are rejected |
56
- | `DUPLICATE_ID` | two nodes, edges or views sharing an id |
57
- | `UNSUPPORTED_SCHEMA_VERSION` | `schemaVersion` is not the contract version installed |
100
+ | Code | What you did |
101
+ | ---------------------------- | -------------------------------------------------------------------- |
102
+ | `BROKEN_REFERENCE` | an edge, a flow step or a view names an id you never declared |
103
+ | `INVALID_DOCUMENT` | an invented field; the schemas are strict, unknown keys are rejected |
104
+ | `DUPLICATE_ID` | two nodes, edges or views sharing an id |
105
+ | `UNSUPPORTED_SCHEMA_VERSION` | `schemaVersion` is not the contract version installed |
58
106
 
59
107
  Four rules cannot be expressed in JSON Schema and are checked only by the parser, so structured output alone does not make a document valid: referential integrity, a line range that ends before it starts, a `self` message whose endpoints disagree, and a patch whose two commits are the same. Always validate.
60
108
 
@@ -85,10 +133,10 @@ A `match` beginning with `id:` addresses one node exactly; anything else is a pa
85
133
 
86
134
  Everything you need is beside this page. Nothing here asks you to install a package first.
87
135
 
88
- | | |
89
- | --- | --- |
90
- | `references/graph-document.md` | the document, field by field: enums, limits, and where documents actually go wrong |
91
- | `references/config.md` | `.github/pr-lens.yml`, the correction overlay, in full |
92
- | `references/example.graph.json` | one complete document that validates, to read and to copy the shape of |
136
+ | | |
137
+ | ------------------------------- | ---------------------------------------------------------------------------------- |
138
+ | `references/graph-document.md` | the document, field by field: enums, limits, and where documents actually go wrong |
139
+ | `references/config.md` | `.github/pr-lens.yml`, the correction overlay, in full |
140
+ | `references/example.graph.json` | one complete document that validates, to read and to copy the shape of |
93
141
 
94
142
  The same document ships as `postmark-refactor.graph.json` in `@coldtea/pr-lens-schema`, and the JSON Schema the validator enforces is published at `https://unpkg.com/@coldtea/pr-lens-schema/json-schema/graph-doc.schema.json`. Neither is something you need to fetch to write a document.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coldtea/pr-lens-agent-skill",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "The PR Lens skill for coding agents: author a graph document from a diff, validate it, render it, and correct a repository's map.",
5
5
  "license": "MIT",
6
6
  "author": "Coldtea AI",
@@ -34,8 +34,8 @@
34
34
  "typescript": "7.0.2",
35
35
  "vitest": "4.1.11",
36
36
  "yaml": "^2.8.1",
37
- "@coldtea/pr-lens-renderer": "^0.1.2",
38
- "@coldtea/pr-lens-schema": "^0.1.2"
37
+ "@coldtea/pr-lens-schema": "^0.1.2",
38
+ "@coldtea/pr-lens-renderer": "^0.1.2"
39
39
  },
40
40
  "scripts": {
41
41
  "skill:sync": "tsx scripts/sync.ts",
@@ -141,6 +141,69 @@ The drill-down tree in the comment: up to 32 at the root, nesting up to 32 child
141
141
 
142
142
  `scope` is either `{ "kind": "all" }` (the default) or a selection naming at least one lane, node, edge or flow. The two are distinct states on purpose: removing the last element a view pointed at can never quietly turn it into a view of everything. A view's `lens` must be one the document declares.
143
143
 
144
+ ### Choosing architecture views
145
+
146
+ Treat the architecture tree as a set of decisions, not a quota:
147
+
148
+ 1. Ask whether the change affects a user, an external system or a system boundary. If it does, start with a system-context view. If it does not, leave that level out.
149
+ 2. Show affected applications, services, jobs, data stores and runtimes in a container view. Make it the root when there is no useful context view; otherwise make it a child of that context.
150
+ 3. Add a component child only when the internals of an affected container matter to the change. Components may be modules, routes or functions, but the view should explain their responsibilities and relationships rather than mirror folders.
151
+ 4. Stop at components unless someone explicitly asks for code-level detail.
152
+
153
+ One architecture view may be the right answer for a small change. Each child must move down exactly one level and cover a materially narrower scope. Skip a level when it would be empty, speculative or a repeat of its parent. Do not create two views with substantially the same nodes and edges, and do not infer a boundary from a folder name alone. Keep unchanged direct neighbours when they make the blast radius clear.
154
+
155
+ Set `defaultOpen: true` on the highest useful architecture view. Lower levels should normally stay collapsed. A data-flow view describes an ordered sequence, so keep it as a separate root instead of placing it inside the architecture hierarchy.
156
+
157
+ This compact fragment shows the shape. The selected ids refer to elements declared elsewhere in the document:
158
+
159
+ ```json
160
+ {
161
+ "views": [
162
+ {
163
+ "id": "checkout-context",
164
+ "title": "Checkout in its environment",
165
+ "lens": "architecture",
166
+ "defaultOpen": true,
167
+ "scope": {
168
+ "kind": "selection",
169
+ "nodes": ["shopper", "commerce-platform", "payment-provider", "fulfilment-system"],
170
+ "edges": ["shopper-to-commerce", "commerce-to-payment", "commerce-to-fulfilment"]
171
+ },
172
+ "children": [
173
+ {
174
+ "id": "checkout-containers",
175
+ "title": "Checkout containers",
176
+ "lens": "architecture",
177
+ "scope": {
178
+ "kind": "selection",
179
+ "nodes": ["storefront", "checkout-api", "orders-db", "payment-provider"],
180
+ "edges": ["storefront-to-checkout", "checkout-to-orders", "checkout-to-payment"]
181
+ },
182
+ "children": [
183
+ {
184
+ "id": "checkout-components",
185
+ "title": "Checkout API components",
186
+ "lens": "architecture",
187
+ "scope": {
188
+ "kind": "selection",
189
+ "nodes": ["checkout-route", "order-service", "payment-client"],
190
+ "edges": ["route-to-orders", "orders-to-payment-client"]
191
+ }
192
+ }
193
+ ]
194
+ }
195
+ ]
196
+ },
197
+ {
198
+ "id": "place-order-flow",
199
+ "title": "Placing an order",
200
+ "lens": "data-flow",
201
+ "scope": { "kind": "selection", "flows": ["place-order"] }
202
+ }
203
+ ]
204
+ }
205
+ ```
206
+
144
207
  ## Layout
145
208
 
146
209
  ```json