austere-axi 0.0.0-stage → 0.1.0
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/LICENSE +21 -0
- package/README.md +165 -2
- package/dist/austere.js +1262 -0
- package/dist/chrome/chrome.css +1 -0
- package/dist/chrome/chrome.js +55 -0
- package/dist/cli.mjs +24458 -0
- package/dist/mermaid.min.js +3636 -0
- package/dist/prompt.md +196 -0
- package/dist/spec.json +1 -0
- package/package.json +54 -4
- package/skills/austere/SKILL.md +26 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Siddhanth Kasat
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,166 @@
|
|
|
1
|
-
#
|
|
1
|
+
# austere-axi
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Review artifacts for coding agents, written in [OpenUI Lang](https://github.com/thesysdev/openui) instead of hand-written HTML.
|
|
4
|
+
|
|
5
|
+
The agent writes a short program: one named statement per line, built from a fixed set of components. The reviewer opens it in the browser, points at anything, and the agent gets the feedback back addressed by statement name. To revise, the agent edits only the statements the feedback names, and the page updates in place.
|
|
6
|
+
|
|
7
|
+
It is the same loop as [lavish-axi](https://github.com/kunchenguid/lavish-axi). The difference is that the agent never writes CSS or layout.
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
root = Stack([intro, flow, options, decide], "column", "l")
|
|
11
|
+
intro = Card([CardHeader("Session storage migration", "Redis → Postgres"), introText])
|
|
12
|
+
introText = MarkDownRenderer("Sessions are lost on failover. **Goal:** durable sessions, no forced logout.")
|
|
13
|
+
flow = Card([CardHeader("Request path"), flowDiagram])
|
|
14
|
+
flowDiagram = Mermaid("flowchart LR
|
|
15
|
+
client --> edge --> api --> pg[(Postgres)]")
|
|
16
|
+
options = Card([CardHeader("Rollout options"), optionTable])
|
|
17
|
+
optionTable = Table([Col("Option", ["Big bang", "Dual-write"]), Col("Risk", [Tag("high", null, "sm", "danger"), Tag("low", null, "sm", "success")])])
|
|
18
|
+
decide = Form("rollout", Buttons([Button("Send decision", @ToAssistant("Decision: rollout"), "primary")]), [strategyField])
|
|
19
|
+
strategyField = FormControl("Rollout", RadioGroup("strategy", [RadioItem("Big bang", "", "bigbang"), RadioItem("Dual-write", "", "dualwrite")]))
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
[`examples/session-migration.html`](examples/session-migration.html) is a full page: a KPI row, a diagram, a table, a chart, a diff, and a decision form. The whole file is about 900 tokens.
|
|
23
|
+
|
|
24
|
+
## Why
|
|
25
|
+
|
|
26
|
+
Lavish makes the agent author an entire HTML page every time, and re-author it after every round of feedback. That is slow, because output tokens are the slow part, and it is expensive.
|
|
27
|
+
|
|
28
|
+
austere-axi changes three things:
|
|
29
|
+
|
|
30
|
+
| | lavish-axi | austere-axi |
|
|
31
|
+
|---|---|---|
|
|
32
|
+
| What the agent writes | Full HTML + CSS + inline SVG | OpenUI Lang statements |
|
|
33
|
+
| Revising after feedback | Regenerate the file | Edit the named statements; the page patches in place and highlights what changed |
|
|
34
|
+
| Feedback target | CSS selector + text | Statement name, its line in the file, plus cell / diff line / diagram node / selected text |
|
|
35
|
+
| Validation | In-browser layout audit | `austere-axi check`: the renderer's own parser, in Node, no browser |
|
|
36
|
+
| Look | Whatever the agent designs | One consistent dark design across agents |
|
|
37
|
+
|
|
38
|
+
## How it works
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
agent writes plan.html ──► austere-axi plan.html ──► local server + browser review
|
|
42
|
+
│ reviewer annotates, picks options,
|
|
43
|
+
│ types, presses Send
|
|
44
|
+
agent edits statements ◄── austere-axi poll plan.html ◄─┘ (long-poll returns the batch)
|
|
45
|
+
│
|
|
46
|
+
└─► page updates in place and flashes the changed statements
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
- **An artifact is a plain `.html` file.** It contains one `<script>` tag for the runtime and one `<script type="text/openui">` block holding the program. Opened directly, it renders from the CDN. Under review, the server points that tag at a local copy.
|
|
50
|
+
- **The runtime** bundles the OpenUI React renderer with a curated component library: 58 of the stock components, plus `Mermaid`, `Diff` and `FileTree`. Every rendered statement is tagged with its name.
|
|
51
|
+
- **Annotations** resolve to the innermost named statement. They also carry precise detail where it exists: table row and column, `file:+line` for diff lines, the label of a diagram node, or the selected text. The popover shows the parent chain, so the reviewer can retarget a note to an enclosing section.
|
|
52
|
+
- **Buttons and forms** are feedback channels. `@ToAssistant("…")` queues a message along with the form's values. A button with no action sends its label.
|
|
53
|
+
- **Remote review.** When Tailscale is running, the server also listens on this machine's tailnet IP, and `open` prints a phone link. The review UI has a mobile layout with a conversation sheet.
|
|
54
|
+
|
|
55
|
+
## Install
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
npx skills add MandalorianBatman/austere-axi --skill austere
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
The skill is a stub that sends the agent to `npx -y austere-axi --help` and `spec`. The CLI is the source of truth, so an installed skill cannot go stale. No setup is needed: any agent can run `npx -y austere-axi` directly.
|
|
62
|
+
|
|
63
|
+
## CLI
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
austere-axi sessions + usage
|
|
67
|
+
austere-axi <file> validate + open a review [--no-open] [--reopen]
|
|
68
|
+
austere-axi poll <file> long-poll for feedback [--agent-reply "..."] [--takeover]
|
|
69
|
+
austere-axi reply <file> post a reply without polling
|
|
70
|
+
austere-axi end <file> end the review as the agent
|
|
71
|
+
austere-axi check <file> validate the program (no browser)
|
|
72
|
+
austere-axi patch <file> merge statements from stdin into the program
|
|
73
|
+
austere-axi spec [group...] component reference (~5.9k tokens; groups narrow it)
|
|
74
|
+
austere-axi export <file> one self-contained HTML file, works offline
|
|
75
|
+
austere-axi stop stop the background server
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Output is compact YAML, written for agents to read. `poll` returns each item with the statement it points at and that statement's line in the file, so the agent can edit it without re-reading the file.
|
|
79
|
+
|
|
80
|
+
Session rules follow lavish:
|
|
81
|
+
|
|
82
|
+
- Only one poll listens on a session at a time.
|
|
83
|
+
- Feedback sent while no agent is listening is queued until the next poll.
|
|
84
|
+
- A review the user ended is not reopened unless `--reopen` is passed.
|
|
85
|
+
- If every review tab stays closed, `poll` returns `browser_disconnected`. The wait is 10 s after a tab is closed, or 5 min after a dropped connection, such as a phone screen locking.
|
|
86
|
+
|
|
87
|
+
### Environment
|
|
88
|
+
|
|
89
|
+
| Variable | Default | |
|
|
90
|
+
|---|---|---|
|
|
91
|
+
| `AUSTERE_AXI_PORT` | `4388` | server port |
|
|
92
|
+
| `AUSTERE_AXI_STATE_DIR` | `~/.austere-axi` | sessions, server log |
|
|
93
|
+
| `AUSTERE_AXI_NO_OPEN` | | `1` = never launch a browser |
|
|
94
|
+
| `AUSTERE_AXI_HOST` | | extra concrete bind address (never `0.0.0.0`) |
|
|
95
|
+
| `AUSTERE_AXI_NO_TAILSCALE` | | `1` = loopback only |
|
|
96
|
+
| `AUSTERE_AXI_LINK_HOST` | | host to print in the remote link |
|
|
97
|
+
| `AUSTERE_AXI_ALLOWED_HOSTS` | | extra `Host` headers to accept (reverse proxy) |
|
|
98
|
+
| `AUSTERE_AXI_DISCONNECT_GRACE_MS` | `300000` | how long a dropped connection may stay away before `poll` returns; `0` disables |
|
|
99
|
+
| `AUSTERE_AXI_IDLE_TIMEOUT_MS` | `1800000` | idle server shutdown; `0` disables |
|
|
100
|
+
|
|
101
|
+
## Security
|
|
102
|
+
|
|
103
|
+
The server binds to loopback, plus the Tailscale IP when Tailscale is up. It never binds to every interface.
|
|
104
|
+
|
|
105
|
+
- **CLI control routes** (`/api/*`) answer only loopback callers.
|
|
106
|
+
- **Host headers** are checked against an allowlist, as a DNS-rebinding defense.
|
|
107
|
+
- **Mutating browser routes** reject foreign `Origin` headers.
|
|
108
|
+
- **The artifact** runs in a sandboxed iframe with no same-origin access.
|
|
109
|
+
- **File access** covers only the artifact's own directory, with no dotfiles.
|
|
110
|
+
|
|
111
|
+
The Node side of OpenUI ships PostHog telemetry. The CLI sets `OPENUI_TELEMETRY_DISABLED=1` so nothing is sent; the browser runtime never sends telemetry.
|
|
112
|
+
|
|
113
|
+
## Not in v1
|
|
114
|
+
|
|
115
|
+
These are left out of v1 on purpose:
|
|
116
|
+
|
|
117
|
+
- **Image attachments** in feedback.
|
|
118
|
+
- **Live data:** `Query` and `Mutation` are disabled, so artifacts are static.
|
|
119
|
+
- **Themes:** there is one dark theme. Per-project accents via OpenUI's `ThemeProvider` are an easy follow-up.
|
|
120
|
+
- **Hosted sharing:** use `export` to produce a single offline file instead.
|
|
121
|
+
|
|
122
|
+
## Development
|
|
123
|
+
|
|
124
|
+
```sh
|
|
125
|
+
npm install
|
|
126
|
+
npm run build # dist/: austere.js (runtime), mermaid.min.js, spec.json, prompt.md, chrome/, cli.mjs
|
|
127
|
+
npm test
|
|
128
|
+
node dist/cli.mjs examples/session-migration.html
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
| Path | Contents |
|
|
132
|
+
|---|---|
|
|
133
|
+
| `src/runtime/components/` | Custom components (`Diff`, `Mermaid`, `FileTree`), one self-describing file each, collected automatically |
|
|
134
|
+
| `src/runtime/stock.js` | Which stock OpenUI components ship, their prompt groups, renderer overrides |
|
|
135
|
+
| `src/runtime/` | Library assembly, annotation layer, review bridge, styles |
|
|
136
|
+
| `src/chrome/` | Review UI around the artifact iframe |
|
|
137
|
+
| `src/cli/` | CLI, server, session store, `check`, `export` |
|
|
138
|
+
| `src/shared/statements.js` | Statement splitter used by both sides |
|
|
139
|
+
|
|
140
|
+
To add or change a component, follow [`.agents/skills/add-component/SKILL.md`](.agents/skills/add-component/SKILL.md). It is a maintainer-only skill and is not published; agents working in this repo pick it up through `AGENTS.md`. Tests enforce the mechanical rules:
|
|
141
|
+
|
|
142
|
+
- every component sits in a prompt group
|
|
143
|
+
- the component reference stays within its token budget
|
|
144
|
+
- released prop orders are append-only (`npm run signatures`)
|
|
145
|
+
- every example passes `check`
|
|
146
|
+
|
|
147
|
+
For visual checks, `npm run gallery` and `npm run shot` render the components headlessly. `npm run test:browser` drives the real review loop in headless Chrome. It needs Chrome, or `CHROME_PATH` set to a browser, and it checks:
|
|
148
|
+
|
|
149
|
+
- every component and example renders at desktop and phone width without errors or sideways scrolling
|
|
150
|
+
- every clickable part reaches `poll` correctly
|
|
151
|
+
|
|
152
|
+
Before committing, [`.agents/skills/review-change`](.agents/skills/review-change/SKILL.md) runs these checks plus three review agents from `.agents/agents/`:
|
|
153
|
+
|
|
154
|
+
- **change-reviewer:** an independent code review
|
|
155
|
+
- **visual-qa:** looks at screenshots, including stress inputs
|
|
156
|
+
- **cold-start-author:** writes a page from `--help` and `spec` alone, to test the agent-facing docs
|
|
157
|
+
|
|
158
|
+
All of this is maintainer-only and is not published.
|
|
159
|
+
|
|
160
|
+
CI (`.github/workflows/ci.yml`) builds and tests on every push to `main` and every pull request: Node 20, 22 and 24 on Linux, Node 24 on Windows, plus the browser suite. To release, bump `version` in `package.json`, push, and publish a GitHub Release. `.github/workflows/publish.yml` then tests again and publishes to npmjs.org through npm trusted publishing, with no token secret.
|
|
161
|
+
|
|
162
|
+
The runtime is about 3 MB minified. It is served locally and cached. `export` inlines it, and inlines Mermaid too when the artifact uses it.
|
|
163
|
+
|
|
164
|
+
## License
|
|
165
|
+
|
|
166
|
+
MIT. Builds on [OpenUI](https://github.com/thesysdev/openui) (MIT) and borrows the review-loop design of [lavish-axi](https://github.com/kunchenguid/lavish-axi) (MIT).
|