@withlo/overview 0.1.0 → 0.1.1
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/README.md +50 -0
- package/dist/checker.js +1 -1
- package/dist/install.js +1 -1
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# @withlo/overview
|
|
2
|
+
|
|
3
|
+
<picture>
|
|
4
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/withlo/lo/81e9d8bf6c3c2ceca0af1064b4c4be3425401718/brand/banner/banner-dark.svg">
|
|
5
|
+
<img alt="Lo" src="https://raw.githubusercontent.com/withlo/lo/81e9d8bf6c3c2ceca0af1064b4c4be3425401718/brand/banner/banner-light.svg" width="100%">
|
|
6
|
+
</picture>
|
|
7
|
+
|
|
8
|
+
[Lo](https://github.com/withlo/lo) is a fast, keyboard-first desktop app for reviewing GitHub pull
|
|
9
|
+
requests, built for people who read far more code than they write.
|
|
10
|
+
|
|
11
|
+
This package is Lo's overview skill for coding agents, such as Claude Code and Codex, and its
|
|
12
|
+
checker. The skill teaches an agent to write an overview of a pull request, the explanation Lo shows
|
|
13
|
+
reviewers beside the diff, then check it and push it to `refs/lo/pr/<n>`. Lo shows the overview to
|
|
14
|
+
everyone who opens the pull request in Lo.
|
|
15
|
+
|
|
16
|
+
## Use
|
|
17
|
+
|
|
18
|
+
Install the skill:
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
npx @withlo/overview install
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
With no options, it installs for each of Claude Code and Codex that's set up on your computer.
|
|
25
|
+
`--claude` or `--codex` installs for one, and `--dir <folder>` installs in a skills folder of your
|
|
26
|
+
own.
|
|
27
|
+
|
|
28
|
+
Then ask your agent to write a Lo overview for a pull request, such as
|
|
29
|
+
`Write a Lo overview of https://github.com/<owner>/<repo>/pull/<n>`.
|
|
30
|
+
|
|
31
|
+
The skill runs the checker's other commands itself, by the exact version it was installed with:
|
|
32
|
+
`check` checks an overview as Lo would, against the code at the commit it describes, and `commit`
|
|
33
|
+
checks it, then writes it as a commit to push to the pull request's ref. `lo-overview --help` lists
|
|
34
|
+
every command and option (`npx @withlo/overview --help` runs it).
|
|
35
|
+
|
|
36
|
+
## Needs
|
|
37
|
+
|
|
38
|
+
- Node 20 or later.
|
|
39
|
+
- `git`, and `gh` signed in to GitHub.
|
|
40
|
+
- Push access to the pull request's repository, or to its fork when it comes from one, to push an
|
|
41
|
+
overview.
|
|
42
|
+
|
|
43
|
+
## Links
|
|
44
|
+
|
|
45
|
+
- [Lo](https://github.com/withlo/lo)
|
|
46
|
+
- [The overview format](https://github.com/withlo/lo/blob/main/skill/references/format.md)
|
|
47
|
+
|
|
48
|
+
## License
|
|
49
|
+
|
|
50
|
+
[MIT](https://github.com/withlo/lo/blob/main/skill/checker/LICENSE)
|
package/dist/checker.js
CHANGED
|
@@ -20598,7 +20598,7 @@ var figures_default = "# Figures in overviews\n\nThe contract for agents that dr
|
|
|
20598
20598
|
var format_default = "# The overview format\n\nAn overview explains a pull request in Lo. Its writer, usually a coding agent, writes `artifact.md`\nand any figures in `figures/`, commits them, and pushes the commit to `refs/lo/pr/<number>` in the\npull request's repository. Lo reads them from there and shows the overview beside the diff.\n\n`artifact.md` is GitHub's Markdown with a header, required sections and a few blocks of its own. Lo\nshows code from the repository itself, so an overview names a file and its lines and never copies\ncode. This is format 1.\n\nAn overview that breaks a rule here is invalid: Lo shows the pull request's diff instead, with a\nreport of what's wrong. A few rules are about what's outside `artifact.md`, and breaking one leaves\nout only what it's about: a block whose code isn't there shows a note in its place, and a file the\ncommit shouldn't hold is never read. The checker reports every rule broken before you push. Warnings\ndon't stop an overview from showing.\n\n## An example\n\n```text\n---\nformat: 1\npr: 4797\ncommit: 3f9c2e1d8b7a6f5e4d3c2b1a0f9e8d7c6b5a4f3e\n---\n\n## tl;dr\n\nRequests over a tenant's quota now wait in a [bucket](term:bucket) instead of failing at once, so\nshort bursts no longer end in errors. The quota itself is unchanged.\n\n## How it works\n\nThe limiter takes a token from the tenant's bucket before it forwards a request:\n\n:::code src/limiter.ts#L46-L58\n:::\n\n:::figure figures/flow.svg\nA request waits for a token in its tenant's bucket, then goes on to the API.\n\n- [bucket](term:bucket)\n- [limiter](code:src/limiter.ts#L12-L40)\n:::\n\n:::walkthrough One request, start to finish\n:::step src/limiter.ts#L12-L20\nThe limiter finds the tenant's bucket, and makes one on the tenant's first request.\n:::\n:::step src/limiter.ts#L46-L58\nWith no token free, the request waits, for up to [the timeout](code:src/config.ts#L8).\n:::\n:::step src/limiter.ts#L60-L64\nA token coming back wakes the request that has waited longest.\n:::\n:::\n\n## Where to look\n\n:::tabs\n:::tab Before\nA burst over the quota failed at once.\n:::\n:::tab After\nA burst over the quota waits, and fails only after the timeout.\n:::\n:::\n\n:::fold Why not a queue per request\nA queue per request would keep a timer for each one. The bucket keeps one timer per tenant.\n:::\n\n## How it was checked\n\nThe new burst tests in [limiter.test.ts](code:src/limiter.test.ts) pass, as do the rest.\n\n## Glossary\n\n- **Bucket**: the tokens a tenant has to spend. Each request takes one, and they come back at the\n tenant's quota rate.\n```\n\n## The files\n\n- **`artifact.md`:** the overview's text, in UTF-8, up to 256 KiB: a file, never a link. A\n byte-order mark at its start is ignored, and lines may end in `\\n` or `\\r\\n`.\n- **`figures/`:** the overview's figures, each a file directly in the folder.\n\nNothing else may be in the commit: no other file, folder, link or submodule. Names match exactly, so\n`Artifact.md` isn't `artifact.md`.\n\n## The header\n\n`artifact.md` starts with its header: a line of `---`, three lines of `key: value` in any order, and\nanother line of `---`.\n\n```text\n---\nformat: 1\npr: 4797\ncommit: 3f9c2e1d8b7a6f5e4d3c2b1a0f9e8d7c6b5a4f3e\n---\n\n## tl;dr\n\nThe smallest overview: a header and a tl;dr.\n```\n\n- **`format`** is the format the overview is written in: `1`.\n- **`pr`** is the pull request's number. An overview found on another pull request's ref is invalid.\n- **`commit`** is the full id of the commit the overview describes, as `git rev-parse` prints it: 40\n lowercase hexadecimal digits, or 64 in a SHA-256 repository. Lo shows code at this commit.\n\nEach key appears once, and nothing else may appear: no blank lines, comments or other keys. It isn't\nYAML, so quotes, anchors and tags aren't read either. Numbers are plain: no sign, no leading zero,\nno decimal point.\n\n## Sections\n\nThe overview is a series of sections, each starting with a `##` heading, in the order you choose.\n\n- **`## tl;dr`** comes first, holding text: what the pull request does and why.\n- **`## Glossary`**, if there is one, holds only a list of terms (see [Terms](#terms)).\n- **Any other section** holds whatever you like. With no other instructions, write \"How it works\",\n \"Where to look\" and \"How it was checked\".\n\nNothing comes before the tl;dr, and the tl;dr and the glossary each appear once. There's no `#`\nheading anywhere, since the pull request's title is the overview's. A `##` heading never sits inside\na block: use `###` there.\n\n## Blocks\n\nA block starts with a line of three or more colons followed by its kind and, for most kinds, an\nargument. A line of three or more colons with nothing after them closes the innermost block still\nopen, so blocks inside blocks need nothing special:\n\n```text\n:::tabs\n:::tab Before\nA burst over the quota failed at once.\n:::\n:::tab After\nA burst over the quota waits.\n:::\n:::\n```\n\n- **An argument** is one line of plain text, at most 1,024 bytes: a title, or a target. A target\n with spaces in its path may go inside `<` and `>`.\n- **A block closes where it opens:** in the same list item or quote, or at the top level.\n- **Blocks nest at most 4 deep.**\n- **Any other kind is invalid,** as is a block left open or a closing line with no block open.\n\n### Code\n\n`:::code` shows lines of the repository's code at the header's commit. Its argument is a target with\nlines, at most 200 of them, and the block is empty: Lo fills it in.\n\n```text\n:::code src/limiter.ts#L46-L58\n:::\n```\n\nLo shows the lines as the pull request changed them, with their review threads. A plain fenced code\nblock is shown as an illustration, never as the repository's code.\n\n### Figures\n\n`:::figure` shows a file from `figures/`. Its argument is the file's path, and the block holds the\nfigure's caption: a sentence or two saying what it shows. A list at the end of the block, each item\none link, makes parts of the figure links:\n\n```text\n:::figure figures/flow.svg\nA request waits for a token in its tenant's bucket, then goes on to the API.\n\n- [bucket](code:src/bucket.ts#L1-L30)\n- [limiter](code:src/limiter.ts#L12-L40)\n:::\n```\n\nThe link's text is the id of an element in the figure, and the link goes to code, a term or a\nsection. An id starts with a letter or `_`, followed by letters, digits, `_`, `.` or `-`, up to 64\nin all, and is linked once. Only an SVG has parts: an image's figure has no such list.\n\n### Walkthroughs\n\n`:::walkthrough` holds 3 to 50 steps, and nothing else. Its argument is its title. Each `:::step`\nnames the lines it's about, at most 200, and holds the text for them, without blocks. Lo shows the\nsteps beside a code view that follows them.\n\n```text\n:::walkthrough One request, start to finish\n:::step src/limiter.ts#L12-L20\nThe limiter finds the tenant's bucket, and makes one on the tenant's first request.\n:::\n:::step src/limiter.ts#L46-L58\nWith no token free, the request waits.\n:::\n:::step src/limiter.ts#L60-L64\nA token coming back wakes the request that has waited longest.\n:::\n:::\n```\n\nWith fewer than 3 steps, write prose instead.\n\n### Tabs\n\n`:::tabs` holds 2 to 12 `:::tab` blocks, and nothing else. It takes no argument, and each tab's\nargument is its title. Use tabs for parallel views of one thing, such as before and after.\n\n### Folds\n\n`:::fold` holds material most readers can skip. Its argument is its title, and it shows closed.\n\n```text\n:::fold Why not a queue per request\nA queue per request would keep a timer for each one.\n:::\n```\n\nNever put the main point of a section in a tab or a fold.\n\n## Targets\n\nWherever an overview points, it uses one form:\n\n| Points at | Written | Example |\n| ---------------- | ---------------------------- | ------------------------ |\n| Lines of code | a path, `#`, then lines | `src/limiter.ts#L46-L58` |\n| One line of code | a path, `#`, then the line | `src/config.ts#L8` |\n| A whole file | a path, from a link only | `src/limiter.test.ts` |\n| A term | its name, from a link only | `bucket` |\n| A heading | `#` and the heading's anchor | `#how-it-works` |\n\nBlocks take targets as their argument. Links take them with a scheme, through Markdown's link\nsyntax: `[the limiter](code:src/limiter.ts#L12-L40)`, `[buckets](term:bucket)`,\n`[as above](#how-it-works)`. A path or a term with spaces goes inside `<` and `>`:\n`[it](<code:docs/read me.md>)`, `[maps](<term:hash map>)`. Otherwise the space ends the address,\nMarkdown makes no link of it, and Lo shows the text as written, with a warning.\n\n- **Paths** are from the repository's root, without a leading `/`, and exactly as the repository\n writes them: the same case, the same Unicode form, no `%` escapes. No part is empty, `.`, `..` or\n `.git`, and none holds `\\`, a control character or an invisible one, such as a zero-width space or\n a right-to-left mark. The last `#` starts the lines, so a file whose path holds a `#` can be named\n only with its lines: a link can't name it whole.\n- **Lines** count from 1: `L12` is one line, `L12-L44` the lines from 12 to 44. A code block and a\n step show at most 200 lines; for more, link the file.\n- **The code** is the repository's at the header's commit, so a target is any file there: changed by\n the pull request or not. It's a file, not a link, folder or submodule, and when the target names\n lines, the file is text and has them. Lo shows a note in place of code that isn't there.\n- **A heading's anchor** is GitHub's: its text in lower case, punctuation removed, spaces as `-`,\n and `-1`, `-2` and on for repeats.\n- **At most 500 targets** in all: code, terms and sections, from blocks, steps, parts and links.\n\nA link to a web page works as on GitHub. A link to anything else, such as a relative path, shows as\nplain text, with a warning. So does a link to a web page or a section once the links before it to\nweb pages and sections have taken 131,072 characters of addresses in all, counting every link, even\none to the same place.\n\n## Terms\n\nA term is a word the overview defines, so a reader can see its definition wherever it's used. Mark\neach use with a `term:` link, and define each term once in the glossary:\n\n```text\n## How it works\n\nEach tenant gets a [bucket](term:bucket), and its [buckets](term:bucket) refill over time.\n\n## Glossary\n\n- **Bucket**: the tokens a tenant has to spend.\n```\n\n- **Matching** ignores case and runs of spaces: `[maps](<term:Hash Map>)` names `**hash map**`. A\n term holds no control or invisible character.\n- **The glossary** is a list whose items each start with the term in bold, then a colon and the\n definition: `- **Term**: definition`. The term is plain text, without links or formatting.\n- **Every term linked is defined,** and two definitions can't differ only in case or spaces. A term\n defined but never linked is a warning.\n\nOnly `term:` links mark a term. Other uses of the word are left alone.\n\n## Figures\n\nA figure is an SVG, PNG, JPEG, GIF or WebP file directly in `figures/`, named with one of the\nendings `.svg`, `.png`, `.jpg`, `.jpeg`, `.gif` or `.webp`, in lower case. Lo reads its type from\nits first bytes, and they must be of the type its name says. A figure that isn't there as a file, of\nanother type, or past a limit, is left out, with a note in its place.\n\n- **SVG figures** follow `figures.md`, in UTF-8, and are drawn at the size their `viewBox` gives,\n or, without one, their `width` and `height` in pixels. One with neither is left out. Lo keeps only\n what a figure may hold: no scripts, styles, outside images or addresses, `<foreignObject>`,\n filters or gradients. A figure Lo had to change, or refused whole, is left out, since a figure\n missing some of what it draws can mislead. A color other than Lo's named colors, `var(--fig-*)`,\n doesn't follow the reader's theme, and is a warning.\n- **Image figures**, such as screenshots, are shown as they are. Lo reads their size from their\n header alone, and never decodes them to check them: a PNG's `IHDR` chunk, a JPEG's frame header, a\n WebP's first chunk, or a GIF's screen, grown to take in its first frame. A figure whose header is\n damaged or cut short is left out. A JPEG or PNG is turned as its Exif orientation says, and an\n animated image shows its first frame, still.\n- **Parts** are an SVG's elements, each named by its id: a shape, a group or a text, but not the\n figure itself, its `<defs>`, a marker or what a marker draws, or a `<tspan>`. An id names an\n element in its own figure only, and an id two elements have names neither. A part that names no\n element Lo can link isn't linked.\n\n## Markdown\n\nEverything else is GitHub's Markdown: paragraphs, lists, tables, quotes, emphasis, inline code, task\nlists, footnotes, alerts and links.\n\n- **Fenced code blocks** are illustrations, such as pseudo-code, and are labeled so.\n- **Raw HTML** shows as its text, with a warning.\n- **Images** from outside GitHub show as links, with a warning: loading them would tell their server\n who's reading. Show the overview's own images with `:::figure`, never `![]()`.\n- **Newlines** inside a paragraph are spaces, as in a README.\n\n## Limits\n\nPast any of these, Lo doesn't show the overview, and says why. It never cuts one short.\n\n| What | At most |\n| -------------------------------------- | ----------------------------- |\n| `artifact.md` | 256 KiB of UTF-8 |\n| The overview's tree | 65,536 pieces, nested 16 deep |\n| Targets | 500 |\n| Blocks inside blocks | 4 deep |\n| A block's argument, or a link's target | 1,024 bytes |\n| A code block's or a step's lines | 200 |\n| Figures | 100 |\n| Steps in a walkthrough | 50, and at least 3 |\n| Tabs in a `:::tabs` block | 12, and at least 2 |\n| The commit, figures included | 50 MiB, 500 files and folders |\n\nThe tree's pieces are what Lo shows: each paragraph, heading, list item, link, run of text and block\ncounts as one, and each level of a list, quote or block inside another is a level of nesting.\n\nPast these, Lo shows the overview without the one block or figure, with a note in its place:\n\n| What | At most |\n| -------------------------------- | ----------------------------------- |\n| A file a target names | 10 MiB of text |\n| The files targets name, together | 64 MiB |\n| An image | 10 MiB, 16,384 pixels a side, 40 MP |\n| An SVG | 512 KiB, 4,096 elements, 32 deep |\n| The SVGs figures show, together | 2 MiB |\n| What SVG figures draw, together | 4 times what one SVG may draw |\n\nA file a target names is text unless one of its first 8 KiB is a NUL byte. The files targets name\ncount in the order the overview first names them, and a file named only whole, by a link, counts for\nnothing. SVGs count in the order the overview first shows them, each once however often it's shown,\nbut what they draw counts each time a block shows one. An SVG also may be no taller than 8 times its\nwidth or wider than 32 times its height, and what it draws is capped.\n\n## Versions\n\nThe header's `format` says which version of this format the overview is written in. A change that an\nearlier version of Lo would read wrongly makes a new format. Each version of Lo reads every format\nup to its own, and says it needs an update for a newer one. Of an overview in a newer format, Lo\nreads only the header: a newer format may allow files, or limits, that this one doesn't, so its\ncommit isn't held to this format's rules either.\n";
|
|
20599
20599
|
// package.json
|
|
20600
20600
|
var name = "@withlo/overview";
|
|
20601
|
-
var version = "0.1.
|
|
20601
|
+
var version = "0.1.1";
|
|
20602
20602
|
// src/skill.ts
|
|
20603
20603
|
/**
|
|
20604
20604
|
* The overview skill, as `install` writes it: its files' text, built into the checker so that what
|
package/dist/install.js
CHANGED
|
@@ -12,7 +12,7 @@ var figures_default = "# Figures in overviews\n\nThe contract for agents that dr
|
|
|
12
12
|
var format_default = "# The overview format\n\nAn overview explains a pull request in Lo. Its writer, usually a coding agent, writes `artifact.md`\nand any figures in `figures/`, commits them, and pushes the commit to `refs/lo/pr/<number>` in the\npull request's repository. Lo reads them from there and shows the overview beside the diff.\n\n`artifact.md` is GitHub's Markdown with a header, required sections and a few blocks of its own. Lo\nshows code from the repository itself, so an overview names a file and its lines and never copies\ncode. This is format 1.\n\nAn overview that breaks a rule here is invalid: Lo shows the pull request's diff instead, with a\nreport of what's wrong. A few rules are about what's outside `artifact.md`, and breaking one leaves\nout only what it's about: a block whose code isn't there shows a note in its place, and a file the\ncommit shouldn't hold is never read. The checker reports every rule broken before you push. Warnings\ndon't stop an overview from showing.\n\n## An example\n\n```text\n---\nformat: 1\npr: 4797\ncommit: 3f9c2e1d8b7a6f5e4d3c2b1a0f9e8d7c6b5a4f3e\n---\n\n## tl;dr\n\nRequests over a tenant's quota now wait in a [bucket](term:bucket) instead of failing at once, so\nshort bursts no longer end in errors. The quota itself is unchanged.\n\n## How it works\n\nThe limiter takes a token from the tenant's bucket before it forwards a request:\n\n:::code src/limiter.ts#L46-L58\n:::\n\n:::figure figures/flow.svg\nA request waits for a token in its tenant's bucket, then goes on to the API.\n\n- [bucket](term:bucket)\n- [limiter](code:src/limiter.ts#L12-L40)\n:::\n\n:::walkthrough One request, start to finish\n:::step src/limiter.ts#L12-L20\nThe limiter finds the tenant's bucket, and makes one on the tenant's first request.\n:::\n:::step src/limiter.ts#L46-L58\nWith no token free, the request waits, for up to [the timeout](code:src/config.ts#L8).\n:::\n:::step src/limiter.ts#L60-L64\nA token coming back wakes the request that has waited longest.\n:::\n:::\n\n## Where to look\n\n:::tabs\n:::tab Before\nA burst over the quota failed at once.\n:::\n:::tab After\nA burst over the quota waits, and fails only after the timeout.\n:::\n:::\n\n:::fold Why not a queue per request\nA queue per request would keep a timer for each one. The bucket keeps one timer per tenant.\n:::\n\n## How it was checked\n\nThe new burst tests in [limiter.test.ts](code:src/limiter.test.ts) pass, as do the rest.\n\n## Glossary\n\n- **Bucket**: the tokens a tenant has to spend. Each request takes one, and they come back at the\n tenant's quota rate.\n```\n\n## The files\n\n- **`artifact.md`:** the overview's text, in UTF-8, up to 256 KiB: a file, never a link. A\n byte-order mark at its start is ignored, and lines may end in `\\n` or `\\r\\n`.\n- **`figures/`:** the overview's figures, each a file directly in the folder.\n\nNothing else may be in the commit: no other file, folder, link or submodule. Names match exactly, so\n`Artifact.md` isn't `artifact.md`.\n\n## The header\n\n`artifact.md` starts with its header: a line of `---`, three lines of `key: value` in any order, and\nanother line of `---`.\n\n```text\n---\nformat: 1\npr: 4797\ncommit: 3f9c2e1d8b7a6f5e4d3c2b1a0f9e8d7c6b5a4f3e\n---\n\n## tl;dr\n\nThe smallest overview: a header and a tl;dr.\n```\n\n- **`format`** is the format the overview is written in: `1`.\n- **`pr`** is the pull request's number. An overview found on another pull request's ref is invalid.\n- **`commit`** is the full id of the commit the overview describes, as `git rev-parse` prints it: 40\n lowercase hexadecimal digits, or 64 in a SHA-256 repository. Lo shows code at this commit.\n\nEach key appears once, and nothing else may appear: no blank lines, comments or other keys. It isn't\nYAML, so quotes, anchors and tags aren't read either. Numbers are plain: no sign, no leading zero,\nno decimal point.\n\n## Sections\n\nThe overview is a series of sections, each starting with a `##` heading, in the order you choose.\n\n- **`## tl;dr`** comes first, holding text: what the pull request does and why.\n- **`## Glossary`**, if there is one, holds only a list of terms (see [Terms](#terms)).\n- **Any other section** holds whatever you like. With no other instructions, write \"How it works\",\n \"Where to look\" and \"How it was checked\".\n\nNothing comes before the tl;dr, and the tl;dr and the glossary each appear once. There's no `#`\nheading anywhere, since the pull request's title is the overview's. A `##` heading never sits inside\na block: use `###` there.\n\n## Blocks\n\nA block starts with a line of three or more colons followed by its kind and, for most kinds, an\nargument. A line of three or more colons with nothing after them closes the innermost block still\nopen, so blocks inside blocks need nothing special:\n\n```text\n:::tabs\n:::tab Before\nA burst over the quota failed at once.\n:::\n:::tab After\nA burst over the quota waits.\n:::\n:::\n```\n\n- **An argument** is one line of plain text, at most 1,024 bytes: a title, or a target. A target\n with spaces in its path may go inside `<` and `>`.\n- **A block closes where it opens:** in the same list item or quote, or at the top level.\n- **Blocks nest at most 4 deep.**\n- **Any other kind is invalid,** as is a block left open or a closing line with no block open.\n\n### Code\n\n`:::code` shows lines of the repository's code at the header's commit. Its argument is a target with\nlines, at most 200 of them, and the block is empty: Lo fills it in.\n\n```text\n:::code src/limiter.ts#L46-L58\n:::\n```\n\nLo shows the lines as the pull request changed them, with their review threads. A plain fenced code\nblock is shown as an illustration, never as the repository's code.\n\n### Figures\n\n`:::figure` shows a file from `figures/`. Its argument is the file's path, and the block holds the\nfigure's caption: a sentence or two saying what it shows. A list at the end of the block, each item\none link, makes parts of the figure links:\n\n```text\n:::figure figures/flow.svg\nA request waits for a token in its tenant's bucket, then goes on to the API.\n\n- [bucket](code:src/bucket.ts#L1-L30)\n- [limiter](code:src/limiter.ts#L12-L40)\n:::\n```\n\nThe link's text is the id of an element in the figure, and the link goes to code, a term or a\nsection. An id starts with a letter or `_`, followed by letters, digits, `_`, `.` or `-`, up to 64\nin all, and is linked once. Only an SVG has parts: an image's figure has no such list.\n\n### Walkthroughs\n\n`:::walkthrough` holds 3 to 50 steps, and nothing else. Its argument is its title. Each `:::step`\nnames the lines it's about, at most 200, and holds the text for them, without blocks. Lo shows the\nsteps beside a code view that follows them.\n\n```text\n:::walkthrough One request, start to finish\n:::step src/limiter.ts#L12-L20\nThe limiter finds the tenant's bucket, and makes one on the tenant's first request.\n:::\n:::step src/limiter.ts#L46-L58\nWith no token free, the request waits.\n:::\n:::step src/limiter.ts#L60-L64\nA token coming back wakes the request that has waited longest.\n:::\n:::\n```\n\nWith fewer than 3 steps, write prose instead.\n\n### Tabs\n\n`:::tabs` holds 2 to 12 `:::tab` blocks, and nothing else. It takes no argument, and each tab's\nargument is its title. Use tabs for parallel views of one thing, such as before and after.\n\n### Folds\n\n`:::fold` holds material most readers can skip. Its argument is its title, and it shows closed.\n\n```text\n:::fold Why not a queue per request\nA queue per request would keep a timer for each one.\n:::\n```\n\nNever put the main point of a section in a tab or a fold.\n\n## Targets\n\nWherever an overview points, it uses one form:\n\n| Points at | Written | Example |\n| ---------------- | ---------------------------- | ------------------------ |\n| Lines of code | a path, `#`, then lines | `src/limiter.ts#L46-L58` |\n| One line of code | a path, `#`, then the line | `src/config.ts#L8` |\n| A whole file | a path, from a link only | `src/limiter.test.ts` |\n| A term | its name, from a link only | `bucket` |\n| A heading | `#` and the heading's anchor | `#how-it-works` |\n\nBlocks take targets as their argument. Links take them with a scheme, through Markdown's link\nsyntax: `[the limiter](code:src/limiter.ts#L12-L40)`, `[buckets](term:bucket)`,\n`[as above](#how-it-works)`. A path or a term with spaces goes inside `<` and `>`:\n`[it](<code:docs/read me.md>)`, `[maps](<term:hash map>)`. Otherwise the space ends the address,\nMarkdown makes no link of it, and Lo shows the text as written, with a warning.\n\n- **Paths** are from the repository's root, without a leading `/`, and exactly as the repository\n writes them: the same case, the same Unicode form, no `%` escapes. No part is empty, `.`, `..` or\n `.git`, and none holds `\\`, a control character or an invisible one, such as a zero-width space or\n a right-to-left mark. The last `#` starts the lines, so a file whose path holds a `#` can be named\n only with its lines: a link can't name it whole.\n- **Lines** count from 1: `L12` is one line, `L12-L44` the lines from 12 to 44. A code block and a\n step show at most 200 lines; for more, link the file.\n- **The code** is the repository's at the header's commit, so a target is any file there: changed by\n the pull request or not. It's a file, not a link, folder or submodule, and when the target names\n lines, the file is text and has them. Lo shows a note in place of code that isn't there.\n- **A heading's anchor** is GitHub's: its text in lower case, punctuation removed, spaces as `-`,\n and `-1`, `-2` and on for repeats.\n- **At most 500 targets** in all: code, terms and sections, from blocks, steps, parts and links.\n\nA link to a web page works as on GitHub. A link to anything else, such as a relative path, shows as\nplain text, with a warning. So does a link to a web page or a section once the links before it to\nweb pages and sections have taken 131,072 characters of addresses in all, counting every link, even\none to the same place.\n\n## Terms\n\nA term is a word the overview defines, so a reader can see its definition wherever it's used. Mark\neach use with a `term:` link, and define each term once in the glossary:\n\n```text\n## How it works\n\nEach tenant gets a [bucket](term:bucket), and its [buckets](term:bucket) refill over time.\n\n## Glossary\n\n- **Bucket**: the tokens a tenant has to spend.\n```\n\n- **Matching** ignores case and runs of spaces: `[maps](<term:Hash Map>)` names `**hash map**`. A\n term holds no control or invisible character.\n- **The glossary** is a list whose items each start with the term in bold, then a colon and the\n definition: `- **Term**: definition`. The term is plain text, without links or formatting.\n- **Every term linked is defined,** and two definitions can't differ only in case or spaces. A term\n defined but never linked is a warning.\n\nOnly `term:` links mark a term. Other uses of the word are left alone.\n\n## Figures\n\nA figure is an SVG, PNG, JPEG, GIF or WebP file directly in `figures/`, named with one of the\nendings `.svg`, `.png`, `.jpg`, `.jpeg`, `.gif` or `.webp`, in lower case. Lo reads its type from\nits first bytes, and they must be of the type its name says. A figure that isn't there as a file, of\nanother type, or past a limit, is left out, with a note in its place.\n\n- **SVG figures** follow `figures.md`, in UTF-8, and are drawn at the size their `viewBox` gives,\n or, without one, their `width` and `height` in pixels. One with neither is left out. Lo keeps only\n what a figure may hold: no scripts, styles, outside images or addresses, `<foreignObject>`,\n filters or gradients. A figure Lo had to change, or refused whole, is left out, since a figure\n missing some of what it draws can mislead. A color other than Lo's named colors, `var(--fig-*)`,\n doesn't follow the reader's theme, and is a warning.\n- **Image figures**, such as screenshots, are shown as they are. Lo reads their size from their\n header alone, and never decodes them to check them: a PNG's `IHDR` chunk, a JPEG's frame header, a\n WebP's first chunk, or a GIF's screen, grown to take in its first frame. A figure whose header is\n damaged or cut short is left out. A JPEG or PNG is turned as its Exif orientation says, and an\n animated image shows its first frame, still.\n- **Parts** are an SVG's elements, each named by its id: a shape, a group or a text, but not the\n figure itself, its `<defs>`, a marker or what a marker draws, or a `<tspan>`. An id names an\n element in its own figure only, and an id two elements have names neither. A part that names no\n element Lo can link isn't linked.\n\n## Markdown\n\nEverything else is GitHub's Markdown: paragraphs, lists, tables, quotes, emphasis, inline code, task\nlists, footnotes, alerts and links.\n\n- **Fenced code blocks** are illustrations, such as pseudo-code, and are labeled so.\n- **Raw HTML** shows as its text, with a warning.\n- **Images** from outside GitHub show as links, with a warning: loading them would tell their server\n who's reading. Show the overview's own images with `:::figure`, never `![]()`.\n- **Newlines** inside a paragraph are spaces, as in a README.\n\n## Limits\n\nPast any of these, Lo doesn't show the overview, and says why. It never cuts one short.\n\n| What | At most |\n| -------------------------------------- | ----------------------------- |\n| `artifact.md` | 256 KiB of UTF-8 |\n| The overview's tree | 65,536 pieces, nested 16 deep |\n| Targets | 500 |\n| Blocks inside blocks | 4 deep |\n| A block's argument, or a link's target | 1,024 bytes |\n| A code block's or a step's lines | 200 |\n| Figures | 100 |\n| Steps in a walkthrough | 50, and at least 3 |\n| Tabs in a `:::tabs` block | 12, and at least 2 |\n| The commit, figures included | 50 MiB, 500 files and folders |\n\nThe tree's pieces are what Lo shows: each paragraph, heading, list item, link, run of text and block\ncounts as one, and each level of a list, quote or block inside another is a level of nesting.\n\nPast these, Lo shows the overview without the one block or figure, with a note in its place:\n\n| What | At most |\n| -------------------------------- | ----------------------------------- |\n| A file a target names | 10 MiB of text |\n| The files targets name, together | 64 MiB |\n| An image | 10 MiB, 16,384 pixels a side, 40 MP |\n| An SVG | 512 KiB, 4,096 elements, 32 deep |\n| The SVGs figures show, together | 2 MiB |\n| What SVG figures draw, together | 4 times what one SVG may draw |\n\nA file a target names is text unless one of its first 8 KiB is a NUL byte. The files targets name\ncount in the order the overview first names them, and a file named only whole, by a link, counts for\nnothing. SVGs count in the order the overview first shows them, each once however often it's shown,\nbut what they draw counts each time a block shows one. An SVG also may be no taller than 8 times its\nwidth or wider than 32 times its height, and what it draws is capped.\n\n## Versions\n\nThe header's `format` says which version of this format the overview is written in. A change that an\nearlier version of Lo would read wrongly makes a new format. Each version of Lo reads every format\nup to its own, and says it needs an update for a newer one. Of an overview in a newer format, Lo\nreads only the header: a newer format may allow files, or limits, that this one doesn't, so its\ncommit isn't held to this format's rules either.\n";
|
|
13
13
|
// package.json
|
|
14
14
|
var name = "@withlo/overview";
|
|
15
|
-
var version = "0.1.
|
|
15
|
+
var version = "0.1.1";
|
|
16
16
|
// src/skill.ts
|
|
17
17
|
/**
|
|
18
18
|
* The overview skill, as `install` writes it: its files' text, built into the checker so that what
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@withlo/overview",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Lo's overview skill for coding agents, and its checker: installs the skill, checks an overview as Lo would, and commits it for its pull request's ref.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"lo",
|