stilura 0.0.0-stage → 0.6.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/CHANGELOG.md +97 -0
- package/LICENSE +21 -0
- package/README.md +215 -2
- package/SPEC.md +532 -0
- package/chat-edits.js +107 -0
- package/desktop.js +87 -0
- package/document-store.js +73 -0
- package/editing.js +140 -0
- package/index.js +776 -0
- package/markdown.js +66 -0
- package/mcp-server.mjs +322 -0
- package/package.json +80 -4
- package/pi.js +325 -0
- package/public/app.js +24109 -0
- package/public/dictionary/LICENSE +347 -0
- package/public/dictionary/en.aff +205 -0
- package/public/dictionary/en.dic +49569 -0
- package/public/fonts/iAWriterDuoS-Bold.woff2 +0 -0
- package/public/fonts/iAWriterDuoS-BoldItalic.woff2 +0 -0
- package/public/fonts/iAWriterDuoS-Italic.woff2 +0 -0
- package/public/fonts/iAWriterDuoS-Regular.woff2 +0 -0
- package/public/icons/LICENSE +26 -0
- package/public/icons/arrow-up.svg +17 -0
- package/public/icons/arrows-clockwise.svg +16 -0
- package/public/icons/clock-counter-clockwise.svg +16 -0
- package/public/icons/download-simple.svg +17 -0
- package/public/icons/file-plus.svg +18 -0
- package/public/icons/file-text.svg +19 -0
- package/public/icons/gear.svg +16 -0
- package/public/icons/magnifying-glass.svg +16 -0
- package/public/icons/sidebar.svg +16 -0
- package/public/icons/upload-simple.svg +17 -0
- package/public/icons/x.svg +16 -0
- package/public/index.html +363 -0
- package/public/logo-mark-white.png +0 -0
- package/public/logo-mark.png +0 -0
- package/public/logo-tile.png +0 -0
- package/public/style.css +2861 -0
- package/review-model.js +45 -0
- package/review-prompt.js +93 -0
- package/review.js +337 -0
- package/skills/stilura/SKILL.md +128 -0
- package/style.md +150 -0
- package/suggestions.js +79 -0
- package/tasks.js +94 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Stilura (renamed from Litura) follows [semantic versioning](https://semver.org). Until 1.0 the minor number carries breaking changes.
|
|
4
|
+
|
|
5
|
+
## Unreleased
|
|
6
|
+
|
|
7
|
+
- Fixed cross-document Undo and saves from concurrent tabs. File writes now keep revision checks and history; workspace APIs reject symbolic links.
|
|
8
|
+
- Desktop state survives server port changes. Closing, changing folders, and installing updates wait for confirmed saves. Partial brief answers survive reloads, and Save as falls back to a download where the system file-picker API is unavailable.
|
|
9
|
+
|
|
10
|
+
- Renamed Litura → Stilura (*stilus*, the pen, + *litura*, the correction): npm package `stilura`, commands `stilura` / `stilura-mcp`, desktop app, skill (`skills/stilura`), and all user-facing strings. `STILURA_*` environment variables replace `LITURA_*` (old spellings still honored). The GitHub repo, release URLs, and the Tauri bundle identifier move with the name — reinstall the desktop app from the new releases page; its saved folder choice does not carry over. Browser drafts, `style.md`, and disk history (`.litura-history`, `litura:` storage keys, `<litura-edits>` tags) are untouched and keep working.
|
|
11
|
+
|
|
12
|
+
## 0.6.0 — 2026-10-09
|
|
13
|
+
|
|
14
|
+
- Litura now works alongside coding agents. `litura-mcp` (also `mcp-server.mjs`) is a stdio MCP server with seven tools — `draft_read`, `draft_write`, `review`, `rewrite`, `suggest`, `chat`, `idea` — that reuse the editor's own prompts; only `draft_write` changes anything, under the same revision guard as `PUT /draft`. A ready-made skill ships in `skills/litura/SKILL.md` with the voice rules, finding codes and the localhost API, for Codex CLI and Claude Code.
|
|
15
|
+
- Continuations use their own suggestion model, chosen in Settings. It defaults to the cheapest authenticated model that writes well, with reasoning off; review, rewrites, chat and `/idea` keep the default model.
|
|
16
|
+
- Settings offers ChatGPT Plus/Pro sign-in as an alternative to an API key, with a note that subscriptions count messages and automatic checks send many small requests.
|
|
17
|
+
- The bubble's `Add to context` is now `Discuss`, matching the button on finding cards. After `Discuss` the paragraph `+` is available again: the passage stays selected, and that no longer hides it.
|
|
18
|
+
- Markdown in the draft stays plain text: markers remain, dimmed, and what they mark is styled in place. Headings set bold, `**bold**`, `*italic*`, `_italic_` and `***both***` follow suit, `` `code` `` gets a quiet background, `[links](url)` an accent underline, `>` lines are muted, list markers dimmed and `---` carries a thin rule. Fenced blocks and inline code are left unparsed.
|
|
19
|
+
- The draft sets larger (17px) on a 68-character measure. Margin notes are written in the draft's own italic, sit on the passage's baseline and open as a single line with no background. The conversation island now morphs its outline between the pill, the composer and a notice, notices are pill-sized and wait eight seconds (longer under the pointer), and `Suggesting…` shows in the folded pill instead of vanishing with the composer.
|
|
20
|
+
- The paragraph `+` stands on the line under the pointer instead of a long paragraph's first line, stays up while a bubble is open, and on a paragraph that already has a note opens that note. The selection and Continue bubbles wait a beat (250 and 450 ms) and never appear if you type or click again first; every bubble fades in and out.
|
|
21
|
+
- A margin note now stands on the line it was made at — its passage, or the line its `+` was pressed beside — instead of at the top of a long paragraph, and the `+` is no longer offered beside a line a note already covers. Retrying a failed draft load no longer duplicates the restored notes.
|
|
22
|
+
- Notes in the margin no longer overlap: the rail cards were positioned relative to their normal place instead of the rail, and now also restack when a note grows. The conversation island sits 16px higher.
|
|
23
|
+
- Experiment, Settings → While you write → Actions in the margin: `Note` and `Discuss` stand in the notes rail beside the selected line, and `Continue` sits right after the caret with its `⌘↵` hint, instead of floating over the text. Falls back to the floating bubble where there is no rail.
|
|
24
|
+
- With a conversation open, the turns and the field now stand inside one opaque panel (near-black in dark mode) instead of floating over the draft, and the fade behind the island is gone. Notes in the margin no longer get cut at the header: the rail reaches the window top like the draft's lines do.
|
|
25
|
+
- The text column now narrows (down to 52 characters) before margin notes give up their rail, so notes stay beside their lines on a 1100px pane instead of dropping into the chat.
|
|
26
|
+
- The delete `×` on a margin note stands right after its last word instead of a box corner, and the paragraph `+` shows on a freshly loaded page without waiting for a resize.
|
|
27
|
+
- A notice now takes over the whole island: the turns, finding cards and `×` above it are put away while it stands and come back when it goes, instead of hanging over an alert.
|
|
28
|
+
- The draft no longer slides left when it grows past the window and a scrollbar appears (for instance when a note is added): the gutter is reserved on both edges.
|
|
29
|
+
- Margin notes, slice 1: select a passage and press `Note` in the bubble to pin your own remark beside the line — plain text on the margin, no card chrome, blur commits and `Escape` drops, no Save/Cancel. Hover the empty margin beside a paragraph for its `+` (a paragraph note, never drifts); select all and press `Note` for the whole draft (pinned at the rail top, no mark). Notes stand in the margin rail on wide windows and stack in the chat stream on narrow ones. Create, edit, delete with Undo; notes persist per file. Notes go to the model with chat and rewrite requests as labeled scope context. No threads yet.
|
|
30
|
+
|
|
31
|
+
## 0.5.0 — 2026-09-27
|
|
32
|
+
|
|
33
|
+
- A file sidebar lists the `.md` and `.txt` files beside the draft, with a filter. Clicking one opens it; the previous text goes to History first. New, Open, Save as and History moved there from the header. The sidebar starts hidden.
|
|
34
|
+
- `Save as new` uses the system save dialog.
|
|
35
|
+
- Icons are now Tabler outline at a thinner stroke, resting dim and full on hover.
|
|
36
|
+
- Provider errors such as an exceeded quota are shown as their message instead of raw JSON.
|
|
37
|
+
- The chosen model survives restarts, even while it is missing from the current catalog.
|
|
38
|
+
- The desktop app opens at once: it no longer fetches the model catalog on startup.
|
|
39
|
+
|
|
40
|
+
## 0.4.2 — 2026-09-13
|
|
41
|
+
|
|
42
|
+
- Clicking at the end of a paragraph now offers a Continue bubble, asking for the same continuation Cmd/Ctrl+Enter would. An explicit ask is allowed to open the next sentence and run longer than a background suggestion, instead of stopping at a finished thought.
|
|
43
|
+
- Fixed the field popovers flashing at their previous position before snapping to the trigger.
|
|
44
|
+
- Removed the unused standalone Rewrite button from the chat chip.
|
|
45
|
+
|
|
46
|
+
## 0.4.0 — 2026-09-13
|
|
47
|
+
|
|
48
|
+
- Added spell checking. Misspelled words are marked in the editor using a vendored en_US Hunspell dictionary, checked client-side alongside the existing style-tell markers.
|
|
49
|
+
|
|
50
|
+
## 0.3.7 — 2026-09-13
|
|
51
|
+
|
|
52
|
+
- Litura is now also a desktop app. A Tauri shell picks the writing folder, starts the same server on a free port, and shows it in its own window; it carries its own Node runtime, so nothing has to be installed first.
|
|
53
|
+
- The review panel is one list again. Wording marks and review findings sat in separate sections repeating the same reason on every row; now they share a single list in document order, each row naming the passage and where the remark came from, with the reason on the card a click away. The header button says how many remarks are waiting instead of a bare number.
|
|
54
|
+
- The desktop app updates itself: it asks GitHub on launch and from `Check for Updates…`, installs only what you accept and what its signing key verifies, and restarts. In that build the npm update switch is gone, since it would name a second, wrong way to update.
|
|
55
|
+
|
|
56
|
+
## 0.3.6 — 2026-09-07
|
|
57
|
+
|
|
58
|
+
- Published the latest editor interface and behavior updates together with the product audit and local draft history.
|
|
59
|
+
|
|
60
|
+
## 0.3.5 — 2026-09-07
|
|
61
|
+
|
|
62
|
+
- Refreshed the README preview with natural generic-writing highlights and meaningful rewrite options in a full-screen review flow.
|
|
63
|
+
|
|
64
|
+
## 0.3.4 — 2026-09-07
|
|
65
|
+
|
|
66
|
+
- Refreshed the README preview with a full-screen Litura review flow and three rewrite options.
|
|
67
|
+
|
|
68
|
+
## 0.3.3 — 2026-09-07
|
|
69
|
+
|
|
70
|
+
- Refreshed the README preview with a full-screen editor screenshot showing review marks and inline continuation.
|
|
71
|
+
|
|
72
|
+
## 0.3.2 — 2026-09-07
|
|
73
|
+
|
|
74
|
+
- Moved the Slop Score next to the settings control in the editor header.
|
|
75
|
+
|
|
76
|
+
## 0.3.1 — 2026-09-07
|
|
77
|
+
|
|
78
|
+
- The update badge now copies `npx litura-app` instead of opening a changelog, so the next update command is ready to paste.
|
|
79
|
+
|
|
80
|
+
## 0.3.0 — 2026-09-07
|
|
81
|
+
|
|
82
|
+
- Review remarks stay beside the passage they describe without shifting the draft when opened or clicked.
|
|
83
|
+
- Added document actions and local history, replace-in-place previews, light/dark appearance settings, and automatic settings saves.
|
|
84
|
+
- Refined the editor header, chat composer, settings controls, and release safety checks.
|
|
85
|
+
|
|
86
|
+
## 0.2.0 — 2026-09-06
|
|
87
|
+
|
|
88
|
+
- Settings can ask npm about new versions once a day, off by default. When a newer version is published the header shows a badge linking to this file; the badge links rather than installs, so updating stays a command you run. Left off, Litura opens no connection of its own.
|
|
89
|
+
- Releases are cut by tag, with GitHub Actions running the checks and publishing over OIDC.
|
|
90
|
+
|
|
91
|
+
## 0.1.0 — 2026-09-06
|
|
92
|
+
|
|
93
|
+
First npm release, published as `litura-app`; the command it installs is `litura`.
|
|
94
|
+
|
|
95
|
+
- Run from any folder with `npx litura-app`. The draft and the style guide are read from the folder Litura starts in, not from its install directory.
|
|
96
|
+
- The browser opens on start, and a taken port falls through to the next free one.
|
|
97
|
+
- `litura --version` and `litura --check-update` report the running and published versions. Litura opens no connection of its own.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Vadim
|
|
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,216 @@
|
|
|
1
|
-
|
|
1
|
+
<img src="public/logo-tile.png" alt="Stilura mark" width="72">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# Stilura
|
|
4
|
+
|
|
5
|
+
Your draft reads like a chatbot wrote it, and you can't say why. Stilura is a local editor that points at the exact phrases — "game-changing", "it's not just an app, it's a movement", the tidy list of three — names the pattern, and offers rewrites. Nothing in your text changes until you pick one.
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx stilura
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+

|
|
12
|
+
|
|
13
|
+
> **Renamed from Litura.** Same project, new name. The npm package moved from `litura-app` to `stilura` and the repository from `vadimchirkov/litura` to `vadimchirkov/stilura`. Your `draft.md` and other files stay where they are.
|
|
14
|
+
|
|
15
|
+
## What it finds
|
|
16
|
+
|
|
17
|
+
Each highlight carries a name and a reason, not a score. The patterns come from `style.md`, which you can edit: 20 of them, among them sales language, vague attribution ("studies show"), "not X but Y", forced triples, filler openers, stacked qualifiers, and generic positive endings. A second pass looks at structure: a buried point, a paragraph that breaks its opening promise, an abrupt topic shift.
|
|
18
|
+
|
|
19
|
+
Click the count in the header for every remark in document order. `F8` and `Shift+F8` step between them. Disagree with one? `Keep as is` dismisses it for good.
|
|
20
|
+
|
|
21
|
+
## You decide every change
|
|
22
|
+
|
|
23
|
+
- `Options` on a finding gives three replace-in-place rewrites. Hover to preview, click to apply, `Try again` for three more.
|
|
24
|
+
- `Discuss` opens a compact chat about the passage or the whole draft.
|
|
25
|
+
- Short continuations appear below the line when you pause; `Tab` takes one, `Escape` drops it.
|
|
26
|
+
|
|
27
|
+
The model suggests. It never edits the document on its own.
|
|
28
|
+
|
|
29
|
+
## Rewrites that know the reader
|
|
30
|
+
|
|
31
|
+
Before polishing, `/brief` asks four questions, one at a time: who reads this, what it should make them do, what they already know, and how much ground it covers. The answers travel with every rewrite, chat reply, and `/idea` expansion. Review never sees them, so it judges the prose unbiased.
|
|
32
|
+
|
|
33
|
+
## Your text stays a file on your machine
|
|
34
|
+
|
|
35
|
+
Run Stilura in the folder that holds your writing. It edits `draft.md` there and reads `style.md` next to it if one exists. The sidebar opens any other Markdown or text file in the folder. Nothing leaves the machine except what a model request sends to the provider you chose.
|
|
36
|
+
|
|
37
|
+
## What it does not do
|
|
38
|
+
|
|
39
|
+
- It does not tell you whether a text was written by AI. It names writing patterns.
|
|
40
|
+
- It does not write the piece for you. Every passage it offers replaces one you already wrote.
|
|
41
|
+
- Review and rewrites need a model provider: an API key, ChatGPT Plus/Pro sign-in, or credentials Pi already stores. The local wording count works without one.
|
|
42
|
+
|
|
43
|
+
## Run
|
|
44
|
+
|
|
45
|
+
### Command line
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npx stilura
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Needs Node.js 20 or newer. The browser opens on [http://127.0.0.1:3000](http://127.0.0.1:3000), or the next free port if that one is taken. Choose a provider and model under the gear button.
|
|
52
|
+
|
|
53
|
+
### Desktop
|
|
54
|
+
|
|
55
|
+
Download the build for your machine from [Releases](https://github.com/vadimchirkov/stilura/releases): `.dmg` on macOS, `.exe` on Windows, `.AppImage` or `.deb` on Linux. On first launch Stilura asks which folder holds your writing; `File → Open Folder…` picks a different one. It carries its own Node runtime and installs updates only when you say so.
|
|
56
|
+
|
|
57
|
+
The macOS builds are not yet signed with an Apple Developer ID, so the first launch is refused: open `System Settings → Privacy & Security`, find Stilura near the bottom, and press `Open Anyway`. Once is enough.
|
|
58
|
+
|
|
59
|
+
### Shortcuts
|
|
60
|
+
|
|
61
|
+
`Cmd/Ctrl+K` attaches the selection or focuses the chat. `Cmd/Ctrl+Enter` asks for a continuation. `Cmd/Ctrl+S` downloads the draft; dropping a text file on the editor opens it. In the composer, `/` lists commands.
|
|
62
|
+
|
|
63
|
+
## Data and storage
|
|
64
|
+
|
|
65
|
+
The draft, findings, conversation, brief, and selected model live in browser local storage and survive a reload. Each file keeps its own copy, chat, findings, and brief. The draft is mirrored to its file on disk, so it survives cleared browser storage and opens in any editor. If the file changes underneath a running Stilura, it says so and offers to load it rather than merging or overwriting silently.
|
|
66
|
+
|
|
67
|
+
The desktop app also saves these entries under its application data directory (`editor-state`), so changing the local server port does not reset them. Closing, changing folders, and installing an update wait for the editor to confirm the save; a save error keeps the app open.
|
|
68
|
+
|
|
69
|
+
Stilura opens one connection of its own, and only to ask about new versions: to the npm registry if you switch that on in settings, or to GitHub when the desktop app starts.
|
|
70
|
+
|
|
71
|
+
To work on Stilura itself:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
git clone https://github.com/vadimchirkov/stilura.git
|
|
75
|
+
cd stilura
|
|
76
|
+
npm install
|
|
77
|
+
npm start
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Updating
|
|
81
|
+
|
|
82
|
+
The desktop app checks GitHub on launch and offers what it finds. Accepting downloads a bundle, verifies it against a signing key baked into the app, and restarts; declining changes nothing and the offer returns next launch. `Stilura → Check for Updates…` asks on demand. Because the app owns this, its settings have no npm update switch.
|
|
83
|
+
|
|
84
|
+
On the command line, running `npx stilura` is the update: for a bare package name npm re-resolves the registry on every run, so each start picks up the latest release. The exceptions are a global install, which shadows that check and needs `npm i -g stilura`, and a clone, which needs `git pull`.
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
npx stilura --check-update
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
prints the published version next to the running one.
|
|
91
|
+
|
|
92
|
+
Settings has an `Ask npm about new versions` switch, off by default. Turn it on and Stilura asks once a day and shows a badge in the header when a newer version is published; the badge links to the changelog rather than installing anything. Left off, Stilura opens no connection of its own.
|
|
93
|
+
|
|
94
|
+
Releases are cut by tag: `npm version <patch|minor|major>`, then `git push` and `git push --tags`. GitHub Actions runs the checks, verifies the tag matches `package.json`, and publishes.
|
|
95
|
+
|
|
96
|
+
An update leaves your draft, your `style.md`, and your model settings alone. Stored findings, chat history, and briefs are dropped only when a release changes their format.
|
|
97
|
+
|
|
98
|
+
## Configuring
|
|
99
|
+
|
|
100
|
+
Use the gear button to choose a provider, model, and reasoning level or to add an API key. Stilura also discovers credentials already stored by Pi and supported provider environment variables.
|
|
101
|
+
|
|
102
|
+
Continuations use a separate suggestion model (same dialog, no reasoning
|
|
103
|
+
control — the server always spends the least reasoning allowed). It defaults
|
|
104
|
+
to the cheapest authenticated model that writes well and switches reasoning
|
|
105
|
+
off; review, rewrites, chat, and `/idea` always use the default model above.
|
|
106
|
+
|
|
107
|
+
The same dialog offers ChatGPT Plus/Pro sign-in as an alternative to an API
|
|
108
|
+
key.
|
|
109
|
+
|
|
110
|
+
Optional environment defaults:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
PI_PROVIDER=anthropic
|
|
114
|
+
PI_MODEL=claude-sonnet-4-6
|
|
115
|
+
PI_THINKING_LEVEL=medium
|
|
116
|
+
PORT=3000
|
|
117
|
+
STYLE_FILE=./style.md
|
|
118
|
+
DRAFT_FILE=./draft.md
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Edit `style.md` to describe the voice, facts, and constraints Stilura should preserve. The file is read again for each model request, so changes apply without restarting the server.
|
|
122
|
+
|
|
123
|
+
## Working alongside Codex / Claude Code
|
|
124
|
+
|
|
125
|
+
Stilura pairs well with terminal agents on the same machine: the draft is a
|
|
126
|
+
plain `draft.md`, and the server exposes the same operations the UI uses as
|
|
127
|
+
local HTTP endpoints. If an external edit lands while Stilura runs, it never
|
|
128
|
+
merges silently — it offers `Load disk` / `Keep mine` instead.
|
|
129
|
+
|
|
130
|
+
A ready-made skill ships in `skills/stilura/SKILL.md` (also in the npm
|
|
131
|
+
package): voice rules distilled from `style.md`, the finding-code taxonomy,
|
|
132
|
+
and `curl` recipes for `GET/PUT /draft` and `POST /review /rewrite /suggest
|
|
133
|
+
/chat` on `http://127.0.0.1:3000` (or the next free port up to 3010).
|
|
134
|
+
Install it with:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
cp -r skills/stilura ~/.codex/skills/ # Codex CLI
|
|
138
|
+
cp -r skills/stilura ~/.claude/skills/ # Claude Code
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
then run the agent in the folder holding your draft while Stilura is running.
|
|
142
|
+
Writes go through revision-checked `PUT /draft` (a stale revision returns
|
|
143
|
+
`409` — re-read and retry once, never overwrite blindly).
|
|
144
|
+
`/draft` always addresses the launch file. To work on another workspace file,
|
|
145
|
+
use `?name=filename.md` on `/draft` and `/draft/history`; opening a file in one
|
|
146
|
+
tab does not change another tab's save target. `GET /file?name=filename.md`
|
|
147
|
+
also returns its revision. `PUT /file` requires that revision to replace a
|
|
148
|
+
file; without one it only creates a missing file.
|
|
149
|
+
|
|
150
|
+
### MCP server
|
|
151
|
+
|
|
152
|
+
For agents that speak MCP (Codex CLI, Claude Code, ChatGPT desktop app),
|
|
153
|
+
Stilura exposes the same operations as seven stdio tools — `draft_read`,
|
|
154
|
+
`draft_write`, `review`, `rewrite`, `suggest`, `chat`, `idea` — in
|
|
155
|
+
`mcp-server.mjs`, reusing the exact prompts the editor uses. Document
|
|
156
|
+
arguments default to the live `draft.md`, so `review` with no arguments audits
|
|
157
|
+
the current draft. Only `draft_write` changes anything, and it carries the
|
|
158
|
+
same revision guard as `PUT /draft`. Start the server in the folder holding
|
|
159
|
+
your draft (or set `DRAFT_FILE`), since the draft resolves against the
|
|
160
|
+
server's working directory:
|
|
161
|
+
|
|
162
|
+
```toml
|
|
163
|
+
# Codex: ~/.codex/config.toml (or .codex/config.toml per project).
|
|
164
|
+
# review/rewrite can run past the 60 s default tool timeout — raise it.
|
|
165
|
+
[mcp_servers.stilura]
|
|
166
|
+
command = "node"
|
|
167
|
+
args = ["/path/to/stilura/mcp-server.mjs"]
|
|
168
|
+
cwd = "/path/to/writing"
|
|
169
|
+
tool_timeout_sec = 180
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
# Claude Code (user scope; --scope project or .mcp.json for project scope)
|
|
174
|
+
claude mcp add --scope user stilura -- node /path/to/stilura/mcp-server.mjs
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Model credentials come from the same places as the editor: Pi's stored
|
|
178
|
+
credentials (`~/.pi/agent/auth.json`) and provider environment variables.
|
|
179
|
+
Per-call `agent` overrides accept `{ provider, model, thinkingLevel }`.
|
|
180
|
+
|
|
181
|
+
## Development
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
npm run build
|
|
185
|
+
npm run check
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
The server uses Node's native HTTP module. The browser UI is vanilla JavaScript with CodeMirror 6 and is bundled with esbuild. Source changes belong in `src/app.js`; `public/app.js` is generated.
|
|
189
|
+
|
|
190
|
+
`npm run check:suggestions` tests insertion, cancellation and scheduling without model calls. `npm run eval:suggestions` makes real calls to the configured model using bilingual examples and records output and latency in `tmp/suggestion-evaluation.json`. See [the evaluation guide](docs/suggestion-evaluation.md) for review criteria and prompt/context experiments.
|
|
191
|
+
|
|
192
|
+
The desktop shell needs a Rust toolchain and [Tauri's system dependencies](https://tauri.app/start/prerequisites/):
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
npm run desktop
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
That bundles the frontend, bundles the server into `dist/server.mjs`, downloads the Node runtime into `src-tauri/binaries/` (checksummed against the release, gitignored, ~120 MB), and opens the window. `npm run desktop:build` produces installers in `src-tauri/target/<triple>/release/bundle/`.
|
|
199
|
+
|
|
200
|
+
Name the target when your Rust toolchain and the Tauri CLI disagree about the machine — an Intel `rustc` on Apple silicon, for instance, ends in a bundler looking for a sidecar nobody fetched:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
npm run desktop:build -- --target aarch64-apple-darwin
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
After a build, `npm run smoke:desktop` starts the bundle against a throwaway folder and checks that it serves that folder's draft and gives the port back when the window dies. The UI needs no desktop build to test: it is the same page a browser gets from `npm run test:browser`, with `?shell=desktop` added to the URL for the desktop layout.
|
|
207
|
+
|
|
208
|
+
Updates are signed with a minisign key that is not in this repository. CI reads it from the `TAURI_SIGNING_PRIVATE_KEY` and `TAURI_SIGNING_PRIVATE_KEY_PASSWORD` secrets; the matching public key sits in `src-tauri/tauri.conf.json`, and an installed app refuses any bundle that key did not sign. Generate a new pair with `npx tauri signer generate` — and remember that replacing the public key strands every copy already installed.
|
|
209
|
+
|
|
210
|
+
The app icon in `src-tauri/icons/` is generated from `public/logo-tile.png` (black mark on the cream tile) with `npx tauri icon public/logo-tile.png`. The mark also ships as `public/logo-mark.png` (transparency, light surfaces) and `public/logo-mark-white.png` (dark surfaces).
|
|
211
|
+
|
|
212
|
+
See [SPEC.md](SPEC.md) for product behavior, API contracts, and implementation boundaries.
|
|
213
|
+
|
|
214
|
+
## License
|
|
215
|
+
|
|
216
|
+
[MIT](LICENSE)
|