altalandi 0.6.0 → 0.6.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 +260 -260
- package/altalandi.mjs +330 -325
- package/auth.mjs +223 -223
- package/batch.mjs +620 -620
- package/package.json +1 -1
- package/report.mjs +5 -3
- package/skill/SKILL.md +180 -112
- package/update.mjs +313 -273
package/README.md
CHANGED
|
@@ -1,260 +1,260 @@
|
|
|
1
|
-
# altalandi
|
|
2
|
-
|
|
3
|
-
Turn English or stiff/AI-translated Icelandic into Icelandic that reads as if a
|
|
4
|
-
native wrote it—from your terminal or application. This package provides the
|
|
5
|
-
`altalandi` CLI and a typed, zero-dependency JavaScript client for the hosted
|
|
6
|
-
[Altalandi API](https://altalandi.is) (Node ≥ 18).
|
|
7
|
-
|
|
8
|
-
```bash
|
|
9
|
-
npx altalandi login # once: opens altalandi.is, you sign in or sign up and click "Tengja"
|
|
10
|
-
npx altalandi "Make sure to reach out to us today."
|
|
11
|
-
# → Hafðu samband við okkur í dag.
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
`login` stores the key in your config directory (`%APPDATA%ltalandi` on
|
|
15
|
-
Windows, `~/.config/altalandi` elsewhere) and installs the Claude Code skill, so
|
|
16
|
-
afterwards you can just tell Claude *"write this in proper Icelandic with
|
|
17
|
-
Altalandi"*. `altalandi whoami` shows the account and credit; `altalandi logout`
|
|
18
|
-
forgets the key. On servers and in CI, set `ALTALANDI_API_KEY` instead; it takes
|
|
19
|
-
precedence over the stored login. For agents, `--file draft.txt` avoids shell
|
|
20
|
-
quoting entirely.
|
|
21
|
-
|
|
22
|
-
`stdout` is the refined text (pipe it anywhere); `stderr` carries the 0–100
|
|
23
|
-
nativeness score, the meaning verdict, every API warning, and the diff.
|
|
24
|
-
|
|
25
|
-
## Install
|
|
26
|
-
|
|
27
|
-
```bash
|
|
28
|
-
npm i -g altalandi # then use `altalandi ...`
|
|
29
|
-
# or run without installing: npx altalandi "..."
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
For an application dependency, install locally and import the package root:
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
npm i altalandi
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## Updating
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
altalandi update # check, then ask before updating
|
|
42
|
-
altalandi update --check # only report; change nothing
|
|
43
|
-
altalandi --version
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
`altalandi update` checks npm for a newer version and asks before installing
|
|
47
|
-
it. It works out how you installed the CLI (global, project dependency or `npx`)
|
|
48
|
-
and runs the matching command. If you use Claude Code, it then offers to install
|
|
49
|
-
or refresh the `/altalandi` skill that ships with each version. A skill you have
|
|
50
|
-
edited is backed up before it is replaced.
|
|
51
|
-
|
|
52
|
-
Nothing changes without your answer. Without a terminal to ask in (agents, CI,
|
|
53
|
-
pipes) it only reports what is available; pass `--yes` when a script already has
|
|
54
|
-
your consent.
|
|
55
|
-
|
|
56
|
-
Exit codes: `0` up to date or updated · `10` an update is available but was not
|
|
57
|
-
applied · `1` the check or the update failed.
|
|
58
|
-
|
|
59
|
-
## JavaScript / TypeScript client
|
|
60
|
-
|
|
61
|
-
`refineVerified` requests the meaning gate and throws unless the API returns
|
|
62
|
-
strict `meaningPreserved: true`. It reads `ALTALANDI_API_KEY` automatically:
|
|
63
|
-
|
|
64
|
-
```js
|
|
65
|
-
import { refineVerified } from "altalandi";
|
|
66
|
-
|
|
67
|
-
const result = await refineVerified("Make sure to reach out to us today.", {
|
|
68
|
-
domain: "marketing",
|
|
69
|
-
});
|
|
70
|
-
console.log(result.output);
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
Use `refine` when you need to inspect an unverified result yourself, then apply
|
|
74
|
-
the same strict assertion before shipping it:
|
|
75
|
-
|
|
76
|
-
```js
|
|
77
|
-
import { assertMeaningVerified, refine } from "altalandi";
|
|
78
|
-
|
|
79
|
-
const result = await refine("Some text", { register: "warm" });
|
|
80
|
-
assertMeaningVerified(result); // throws on both false and null
|
|
81
|
-
console.log(result.output);
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
Both functions accept `apiKey` (for a secret-manager value), `baseUrl`, and
|
|
85
|
-
`timeoutMs` alongside the request options. The defaults are
|
|
86
|
-
`ALTALANDI_API_KEY`, `https://altalandi.is/api`, and 300,000 ms. API, network,
|
|
87
|
-
timeout, and verification failures throw `AltalandiError` subclasses with a
|
|
88
|
-
stable `code`; errors never include the request text or API key. TypeScript
|
|
89
|
-
declarations ship with the package. The CLI uses the same 300-second request
|
|
90
|
-
deadline, including response-body download.
|
|
91
|
-
|
|
92
|
-
## Usage
|
|
93
|
-
|
|
94
|
-
```bash
|
|
95
|
-
altalandi "Some English or Icelandic text."
|
|
96
|
-
echo "some text" | altalandi --domain marketing
|
|
97
|
-
altalandi --json "..." # full JSON response
|
|
98
|
-
altalandi --fast "..." # skip the meaning + nativeness gates
|
|
99
|
-
altalandi --diff --file draft.txt # show before, after and every change with its reason
|
|
100
|
-
altalandi --review --file in.txt --out out.txt # for agents: one block to show as it is
|
|
101
|
-
altalandi --report --file draft.txt # also write a Markdown report to ./altalandi-reports/
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
| flag | default | meaning |
|
|
105
|
-
|------|---------|---------|
|
|
106
|
-
| `--domain` | `general` | `general` \| `marketing` \| `data-analysis` \| `childrens-fiction` |
|
|
107
|
-
| `--register` | `neutral` | `formal` \| `neutral` \| `warm` |
|
|
108
|
-
| `--json` | off | print the full API response |
|
|
109
|
-
| `--diff` | off | print the text before and after, then each change with its reason, on `stderr` (coloured in a terminal; `NO_COLOR` turns colour off) |
|
|
110
|
-
| `--review` | off | print one Markdown block on `stdout`, made to be shown as it is: the verdict, the text before and after, each change with its reason, what the call cost and the balance and free units left. Exits on the outcome: `0` rewritten and verified or no change needed, `3` refused or unverified, `4` out of credit |
|
|
111
|
-
| `--no-store` | off | send `contribute: false`: this text is never kept. Without it, free use (calls covered by the free daily units) is kept with personal data scrubbed, to improve the service; paid use is kept only with consent ([privacy](https://altalandi.is/personuvernd#textabanki)) |
|
|
112
|
-
| `--out <file>` | | write the refined text to `<file>` (UTF-8); with `--review` the block names it when the text is shortened |
|
|
113
|
-
| `--report` | off | also write `./altalandi-reports/altalandi-<time>-<id>.md`: input, output, a table of every change (before, after, reason, layer), warnings and the verdict |
|
|
114
|
-
| `--report-dir <dir>` | | write the report to `<dir>` instead (implies `--report`) |
|
|
115
|
-
| `--fast` | off | `preserveMeaning:false`, `scoreNativeness:false`, `onlyImprove:false`, `polishPass:false`, `scoring:"none"` — normally one model call (structured input can still add a structure-preserving retry) |
|
|
116
|
-
|
|
117
|
-
## Folders, i18n catalogs and websites
|
|
118
|
-
|
|
119
|
-
One command for a whole folder, one web page, or a site. The input is never
|
|
120
|
-
written to.
|
|
121
|
-
|
|
122
|
-
```bash
|
|
123
|
-
altalandi ./docs # every .md .txt .html .json under ./docs → ./docs-is
|
|
124
|
-
altalandi ./locales --out ./locales-is # i18n catalogs: values only, placeholders kept
|
|
125
|
-
altalandi ./docs --dry-run # every passage and the estimate; sends nothing
|
|
126
|
-
altalandi https://example.com/pricing --out pricing-is.md # one page → Markdown
|
|
127
|
-
altalandi https://example.com/docs/ --site --max-pages 50 # a site → ./example.com-is/
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
Each passage (a paragraph, list item, table cell, heading or string) is its own
|
|
131
|
-
call. Everything outside the passages is written back byte for byte:
|
|
132
|
-
|
|
133
|
-
| format | refined | never touched |
|
|
134
|
-
|--------|---------|---------------|
|
|
135
|
-
| Markdown | paragraphs, list items, table cells, heading text, front-matter `title`/`description`-style values | code blocks, inline code, URLs, link targets, HTML tags, front-matter keys, heading markup |
|
|
136
|
-
| HTML | text in elements (inline tags travel as numbered markers and come back exactly) | tags, attributes, entities, `script`, `style`, `pre`, `code`, `translate="no"` |
|
|
137
|
-
| JSON | string values of i18n catalogs | keys, `@`/`$` metadata, `{name}` `{{name}}` `%s` `%(name)s`, ICU plural/select structure, HTML in strings |
|
|
138
|
-
| Text | paragraphs (re-wrapped to their width) and lines | |
|
|
139
|
-
|
|
140
|
-
Passages with nothing to refine (code, numbers, URLs or placeholders alone) are
|
|
141
|
-
skipped, and a passage that appears twice is sent once. `node_modules`, `.git`,
|
|
142
|
-
`dist`, `build`, `altalandi-reports`, hidden files and folders and symlinks are
|
|
143
|
-
skipped. JSON config (`package.json`, `tsconfig.json`, …) and JSON with numbers
|
|
144
|
-
or booleans is copied unchanged; other file types are not copied.
|
|
145
|
-
|
|
146
|
-
Pages are fetched one at a time with a User-Agent naming altalandi, only where
|
|
147
|
-
robots.txt allows it for `altalandi` and for `*` (`Crawl-delay` is honoured).
|
|
148
|
-
The readable part (`<main>` or `<article>`, else `<body>` without navigation,
|
|
149
|
-
header, footer, sidebars, forms, scripts and hidden elements) becomes Markdown.
|
|
150
|
-
`--site` reads `/sitemap.xml`, or follows links when there is none, staying on
|
|
151
|
-
the same origin and under the URL's folder.
|
|
152
|
-
|
|
153
|
-
**Cost and safety.** Before anything is sent, the CLI prints an estimate, priced
|
|
154
|
-
from the public tariff:
|
|
155
|
-
|
|
156
|
-
```text
|
|
157
|
-
5 files, 24 passages, about 851 characters (23 calls: repeated passages are sent once).
|
|
158
|
-
1 more file has nothing to refine and is copied unchanged.
|
|
159
|
-
Billing: about 920 units (at least 40 a call), about 74 kr if paid from credit. The free allowance is 2,000 units a day.
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
Every call costs at least the per-call minimum, so many short strings cost more
|
|
163
|
-
than their word count. In a terminal it asks before sending; without one (CI,
|
|
164
|
-
agents) it sends nothing unless you pass `--yes`.
|
|
165
|
-
|
|
166
|
-
| flag | default | meaning |
|
|
167
|
-
|------|---------|---------|
|
|
168
|
-
| `--out <path>` | `<folder>-is` | output folder, refused if it is the input, inside it or around it; for one page, the `.md` file |
|
|
169
|
-
| `--dry-run` | off | list every passage and the estimate; send nothing, write nothing |
|
|
170
|
-
| `--yes`, `-y` | off | send without asking |
|
|
171
|
-
| `--max-chars <n>` | | files are sent in order until the next would go over n characters; the rest are neither sent nor written |
|
|
172
|
-
| `--concurrency <n>` | `2` | calls at once, 1–4 |
|
|
173
|
-
| `--site` / `--max-pages <n>` | off / `20` | read a site from the URL, up to n pages |
|
|
174
|
-
| `--no-store` | off | keep none of the passages (free use is otherwise kept, scrubbed of personal data) |
|
|
175
|
-
| `--json` | off | a machine-readable summary of every file and passage on stdout |
|
|
176
|
-
|
|
177
|
-
A `429` waits as long as `Retry-After` asks (up to 5 minutes) and retries. A
|
|
178
|
-
`402` stops the run cleanly: finished files are written, the rest are listed and
|
|
179
|
-
not written; run the same command again after topping up.
|
|
180
|
-
|
|
181
|
-
**Results.** Only verified changes are written. A passage keeps its original
|
|
182
|
-
text when its meaning check did not pass (`meaningCheck` other than `passed`, or
|
|
183
|
-
`meaningPreserved` not `true`), or when the refined text lost or changed code, a
|
|
184
|
-
URL, a placeholder or a tag. One report next to the output
|
|
185
|
-
(`altalandi-reports/altalandi-<time>-<input>.md`) lists every file and every
|
|
186
|
-
changed passage with its meaning verdict, and the kept passages under their own
|
|
187
|
-
heading with the unused suggestion and the reason.
|
|
188
|
-
|
|
189
|
-
| exit | meaning |
|
|
190
|
-
|------|---------|
|
|
191
|
-
| `0` | done |
|
|
192
|
-
| `2` | done, but some passages kept their original text (see the report) |
|
|
193
|
-
| `4` | stopped: out of credit or allowance |
|
|
194
|
-
| `1` | error, or not everything was done (a failed call, `--max-chars`, no `--yes`) |
|
|
195
|
-
|
|
196
|
-
## Before and after
|
|
197
|
-
|
|
198
|
-
`--diff` prints what the website shows inline, in the terminal:
|
|
199
|
-
|
|
200
|
-
```text
|
|
201
|
-
── Fyrir ───────────────────────────────────
|
|
202
|
-
Vertu viss um að ná út til okkar ef þú hefur einhverjar spurningar.
|
|
203
|
-
|
|
204
|
-
── Eftir ───────────────────────────────────
|
|
205
|
-
Ekki hika við að hafa samband ef einhverjar spurningar vakna.
|
|
206
|
-
|
|
207
|
-
── Breytingar (1) ──────────────────────────
|
|
208
|
-
1. − Vertu viss um að ná út til okkar ef þú hefur einhverjar spurningar.
|
|
209
|
-
+ Ekki hika við að hafa samband ef einhverjar spurningar vakna.
|
|
210
|
-
↳ <the reason the engine gives>
|
|
211
|
-
|
|
212
|
-
Endurskrifað og merking staðfest · innfæddni 91/100
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
`--report` (or `ALTALANDI_REPORT=1`) writes the same content as a Markdown file
|
|
216
|
-
you can keep or share. Reports are off by default because they contain your text.
|
|
217
|
-
`stdout` stays the refined text alone either way, so piping is unaffected.
|
|
218
|
-
|
|
219
|
-
## The meaning guarantee
|
|
220
|
-
|
|
221
|
-
Altalandi never silently changes meaning. For Icelandic input where the rewrite
|
|
222
|
-
can't be verified to preserve meaning, it returns the **original unchanged** and
|
|
223
|
-
says so on `stderr` (or `meaningPreserved:false` with `--json`). Check it before
|
|
224
|
-
trusting the output in an automated pipeline. Only `meaningPreserved:true` is a
|
|
225
|
-
verified pass; `null` means the gate was skipped or did not complete. `--fast`
|
|
226
|
-
deliberately skips the gate, so its result is unverified by design.
|
|
227
|
-
|
|
228
|
-
Without `--fast`, a `null` meaning verdict is printed as **MEANING UNVERIFIED**:
|
|
229
|
-
the check did not run or could not complete, so review the output before use.
|
|
230
|
-
With `--fast`, `null` is expected and is printed as **meaning check skipped**.
|
|
231
|
-
API warnings are always printed on `stderr`; under `--json` they remain in the
|
|
232
|
-
unchanged `warnings` array.
|
|
233
|
-
|
|
234
|
-
For automation, a successful HTTP response is not enough: without `--fast`, the
|
|
235
|
-
CLI prints the text or JSON response and then exits with status **3** when
|
|
236
|
-
`meaningPreserved` is `false` or `null`. Only strict `true` exits 0. `--fast` is
|
|
237
|
-
the explicit verification opt-out and exits 0 after a successful API response.
|
|
238
|
-
|
|
239
|
-
| exit | meaning |
|
|
240
|
-
|------|---------|
|
|
241
|
-
| `0` | verified success, or successful `--fast` request |
|
|
242
|
-
| `1` | API or network failure |
|
|
243
|
-
| `2` | missing input/key or invalid CLI usage |
|
|
244
|
-
| `3` | response printed, but meaning was false or unverified |
|
|
245
|
-
|
|
246
|
-
## Config
|
|
247
|
-
|
|
248
|
-
| env | default | purpose |
|
|
249
|
-
|-----|---------|---------|
|
|
250
|
-
| `ALTALANDI_API_KEY` | — | your key (Bearer). Mint at https://altalandi.is/
|
|
251
|
-
| `ALTALANDI_BASE_URL` | `https://altalandi.is/api` | API base (override for self-hosting) |
|
|
252
|
-
| `ALTALANDI_DIFF` | — | `1` = always print the before/after (as `--diff`) |
|
|
253
|
-
| `ALTALANDI_REPORT` | — | `1` = always write a report (as `--report`) |
|
|
254
|
-
| `ALTALANDI_REPORT_DIR` | `./altalandi-reports` | where reports go |
|
|
255
|
-
|
|
256
|
-
MIT licensed. Calls are paid from the account's prepaid credit (a 500 kr trial,
|
|
257
|
-
then credit bought in the portal); a call the credit cannot cover exits with the
|
|
258
|
-
server's `402 insufficient_balance` message. The request's text and glossary fields are charged at the effective billing-tier
|
|
259
|
-
weight. Each whitespace-delimited token is at least one unit; an unbroken token
|
|
260
|
-
uses one unit per 20 characters, rounded up.
|
|
1
|
+
# altalandi
|
|
2
|
+
|
|
3
|
+
Turn English or stiff/AI-translated Icelandic into Icelandic that reads as if a
|
|
4
|
+
native wrote it—from your terminal or application. This package provides the
|
|
5
|
+
`altalandi` CLI and a typed, zero-dependency JavaScript client for the hosted
|
|
6
|
+
[Altalandi API](https://altalandi.is) (Node ≥ 18).
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
npx altalandi login # once: opens altalandi.is, you sign in or sign up and click "Tengja"
|
|
10
|
+
npx altalandi "Make sure to reach out to us today."
|
|
11
|
+
# → Hafðu samband við okkur í dag.
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
`login` stores the key in your config directory (`%APPDATA%ltalandi` on
|
|
15
|
+
Windows, `~/.config/altalandi` elsewhere) and installs the Claude Code skill, so
|
|
16
|
+
afterwards you can just tell Claude *"write this in proper Icelandic with
|
|
17
|
+
Altalandi"*. `altalandi whoami` shows the account and credit; `altalandi logout`
|
|
18
|
+
forgets the key. On servers and in CI, set `ALTALANDI_API_KEY` instead; it takes
|
|
19
|
+
precedence over the stored login. For agents, `--file draft.txt` avoids shell
|
|
20
|
+
quoting entirely.
|
|
21
|
+
|
|
22
|
+
`stdout` is the refined text (pipe it anywhere); `stderr` carries the 0–100
|
|
23
|
+
nativeness score, the meaning verdict, every API warning, and the diff.
|
|
24
|
+
|
|
25
|
+
## Install
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm i -g altalandi # then use `altalandi ...`
|
|
29
|
+
# or run without installing: npx altalandi "..."
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
For an application dependency, install locally and import the package root:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm i altalandi
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Updating
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
altalandi update # check, then ask before updating
|
|
42
|
+
altalandi update --check # only report; change nothing
|
|
43
|
+
altalandi --version
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
`altalandi update` checks npm for a newer version and asks before installing
|
|
47
|
+
it. It works out how you installed the CLI (global, project dependency or `npx`)
|
|
48
|
+
and runs the matching command. If you use Claude Code, it then offers to install
|
|
49
|
+
or refresh the `/altalandi` skill that ships with each version. A skill you have
|
|
50
|
+
edited is backed up before it is replaced.
|
|
51
|
+
|
|
52
|
+
Nothing changes without your answer. Without a terminal to ask in (agents, CI,
|
|
53
|
+
pipes) it only reports what is available; pass `--yes` when a script already has
|
|
54
|
+
your consent.
|
|
55
|
+
|
|
56
|
+
Exit codes: `0` up to date or updated · `10` an update is available but was not
|
|
57
|
+
applied · `1` the check or the update failed.
|
|
58
|
+
|
|
59
|
+
## JavaScript / TypeScript client
|
|
60
|
+
|
|
61
|
+
`refineVerified` requests the meaning gate and throws unless the API returns
|
|
62
|
+
strict `meaningPreserved: true`. It reads `ALTALANDI_API_KEY` automatically:
|
|
63
|
+
|
|
64
|
+
```js
|
|
65
|
+
import { refineVerified } from "altalandi";
|
|
66
|
+
|
|
67
|
+
const result = await refineVerified("Make sure to reach out to us today.", {
|
|
68
|
+
domain: "marketing",
|
|
69
|
+
});
|
|
70
|
+
console.log(result.output);
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Use `refine` when you need to inspect an unverified result yourself, then apply
|
|
74
|
+
the same strict assertion before shipping it:
|
|
75
|
+
|
|
76
|
+
```js
|
|
77
|
+
import { assertMeaningVerified, refine } from "altalandi";
|
|
78
|
+
|
|
79
|
+
const result = await refine("Some text", { register: "warm" });
|
|
80
|
+
assertMeaningVerified(result); // throws on both false and null
|
|
81
|
+
console.log(result.output);
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Both functions accept `apiKey` (for a secret-manager value), `baseUrl`, and
|
|
85
|
+
`timeoutMs` alongside the request options. The defaults are
|
|
86
|
+
`ALTALANDI_API_KEY`, `https://altalandi.is/api`, and 300,000 ms. API, network,
|
|
87
|
+
timeout, and verification failures throw `AltalandiError` subclasses with a
|
|
88
|
+
stable `code`; errors never include the request text or API key. TypeScript
|
|
89
|
+
declarations ship with the package. The CLI uses the same 300-second request
|
|
90
|
+
deadline, including response-body download.
|
|
91
|
+
|
|
92
|
+
## Usage
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
altalandi "Some English or Icelandic text."
|
|
96
|
+
echo "some text" | altalandi --domain marketing
|
|
97
|
+
altalandi --json "..." # full JSON response
|
|
98
|
+
altalandi --fast "..." # skip the meaning + nativeness gates
|
|
99
|
+
altalandi --diff --file draft.txt # show before, after and every change with its reason
|
|
100
|
+
altalandi --review --file in.txt --out out.txt # for agents: one block to show as it is
|
|
101
|
+
altalandi --report --file draft.txt # also write a Markdown report to ./altalandi-reports/
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
| flag | default | meaning |
|
|
105
|
+
|------|---------|---------|
|
|
106
|
+
| `--domain` | `general` | `general` \| `marketing` \| `data-analysis` \| `childrens-fiction` |
|
|
107
|
+
| `--register` | `neutral` | `formal` \| `neutral` \| `warm` |
|
|
108
|
+
| `--json` | off | print the full API response |
|
|
109
|
+
| `--diff` | off | print the text before and after, then each change with its reason, on `stderr` (coloured in a terminal; `NO_COLOR` turns colour off) |
|
|
110
|
+
| `--review` | off | print one Markdown block on `stdout`, made to be shown as it is: the verdict, the text before and after, each change with its reason, what the call cost and the balance and free units left. Exits on the outcome: `0` rewritten and verified or no change needed, `3` refused or unverified, `4` out of credit |
|
|
111
|
+
| `--no-store` | off | send `contribute: false`: this text is never kept. Without it, free use (calls covered by the free daily units) is kept with personal data scrubbed, to improve the service; paid use is kept only with consent ([privacy](https://altalandi.is/personuvernd#textabanki)) |
|
|
112
|
+
| `--out <file>` | | write the refined text to `<file>` (UTF-8); with `--review` the block names it when the text is shortened |
|
|
113
|
+
| `--report` | off | also write `./altalandi-reports/altalandi-<time>-<id>.md`: input, output, a table of every change (before, after, reason, layer), warnings and the verdict |
|
|
114
|
+
| `--report-dir <dir>` | | write the report to `<dir>` instead (implies `--report`) |
|
|
115
|
+
| `--fast` | off | `preserveMeaning:false`, `scoreNativeness:false`, `onlyImprove:false`, `polishPass:false`, `scoring:"none"` — normally one model call (structured input can still add a structure-preserving retry) |
|
|
116
|
+
|
|
117
|
+
## Folders, i18n catalogs and websites
|
|
118
|
+
|
|
119
|
+
One command for a whole folder, one web page, or a site. The input is never
|
|
120
|
+
written to.
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
altalandi ./docs # every .md .txt .html .json under ./docs → ./docs-is
|
|
124
|
+
altalandi ./locales --out ./locales-is # i18n catalogs: values only, placeholders kept
|
|
125
|
+
altalandi ./docs --dry-run # every passage and the estimate; sends nothing
|
|
126
|
+
altalandi https://example.com/pricing --out pricing-is.md # one page → Markdown
|
|
127
|
+
altalandi https://example.com/docs/ --site --max-pages 50 # a site → ./example.com-is/
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Each passage (a paragraph, list item, table cell, heading or string) is its own
|
|
131
|
+
call. Everything outside the passages is written back byte for byte:
|
|
132
|
+
|
|
133
|
+
| format | refined | never touched |
|
|
134
|
+
|--------|---------|---------------|
|
|
135
|
+
| Markdown | paragraphs, list items, table cells, heading text, front-matter `title`/`description`-style values | code blocks, inline code, URLs, link targets, HTML tags, front-matter keys, heading markup |
|
|
136
|
+
| HTML | text in elements (inline tags travel as numbered markers and come back exactly) | tags, attributes, entities, `script`, `style`, `pre`, `code`, `translate="no"` |
|
|
137
|
+
| JSON | string values of i18n catalogs | keys, `@`/`$` metadata, `{name}` `{{name}}` `%s` `%(name)s`, ICU plural/select structure, HTML in strings |
|
|
138
|
+
| Text | paragraphs (re-wrapped to their width) and lines | |
|
|
139
|
+
|
|
140
|
+
Passages with nothing to refine (code, numbers, URLs or placeholders alone) are
|
|
141
|
+
skipped, and a passage that appears twice is sent once. `node_modules`, `.git`,
|
|
142
|
+
`dist`, `build`, `altalandi-reports`, hidden files and folders and symlinks are
|
|
143
|
+
skipped. JSON config (`package.json`, `tsconfig.json`, …) and JSON with numbers
|
|
144
|
+
or booleans is copied unchanged; other file types are not copied.
|
|
145
|
+
|
|
146
|
+
Pages are fetched one at a time with a User-Agent naming altalandi, only where
|
|
147
|
+
robots.txt allows it for `altalandi` and for `*` (`Crawl-delay` is honoured).
|
|
148
|
+
The readable part (`<main>` or `<article>`, else `<body>` without navigation,
|
|
149
|
+
header, footer, sidebars, forms, scripts and hidden elements) becomes Markdown.
|
|
150
|
+
`--site` reads `/sitemap.xml`, or follows links when there is none, staying on
|
|
151
|
+
the same origin and under the URL's folder.
|
|
152
|
+
|
|
153
|
+
**Cost and safety.** Before anything is sent, the CLI prints an estimate, priced
|
|
154
|
+
from the public tariff:
|
|
155
|
+
|
|
156
|
+
```text
|
|
157
|
+
5 files, 24 passages, about 851 characters (23 calls: repeated passages are sent once).
|
|
158
|
+
1 more file has nothing to refine and is copied unchanged.
|
|
159
|
+
Billing: about 920 units (at least 40 a call), about 74 kr if paid from credit. The free allowance is 2,000 units a day.
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Every call costs at least the per-call minimum, so many short strings cost more
|
|
163
|
+
than their word count. In a terminal it asks before sending; without one (CI,
|
|
164
|
+
agents) it sends nothing unless you pass `--yes`.
|
|
165
|
+
|
|
166
|
+
| flag | default | meaning |
|
|
167
|
+
|------|---------|---------|
|
|
168
|
+
| `--out <path>` | `<folder>-is` | output folder, refused if it is the input, inside it or around it; for one page, the `.md` file |
|
|
169
|
+
| `--dry-run` | off | list every passage and the estimate; send nothing, write nothing |
|
|
170
|
+
| `--yes`, `-y` | off | send without asking |
|
|
171
|
+
| `--max-chars <n>` | | files are sent in order until the next would go over n characters; the rest are neither sent nor written |
|
|
172
|
+
| `--concurrency <n>` | `2` | calls at once, 1–4 |
|
|
173
|
+
| `--site` / `--max-pages <n>` | off / `20` | read a site from the URL, up to n pages |
|
|
174
|
+
| `--no-store` | off | keep none of the passages (free use is otherwise kept, scrubbed of personal data) |
|
|
175
|
+
| `--json` | off | a machine-readable summary of every file and passage on stdout |
|
|
176
|
+
|
|
177
|
+
A `429` waits as long as `Retry-After` asks (up to 5 minutes) and retries. A
|
|
178
|
+
`402` stops the run cleanly: finished files are written, the rest are listed and
|
|
179
|
+
not written; run the same command again after topping up.
|
|
180
|
+
|
|
181
|
+
**Results.** Only verified changes are written. A passage keeps its original
|
|
182
|
+
text when its meaning check did not pass (`meaningCheck` other than `passed`, or
|
|
183
|
+
`meaningPreserved` not `true`), or when the refined text lost or changed code, a
|
|
184
|
+
URL, a placeholder or a tag. One report next to the output
|
|
185
|
+
(`altalandi-reports/altalandi-<time>-<input>.md`) lists every file and every
|
|
186
|
+
changed passage with its meaning verdict, and the kept passages under their own
|
|
187
|
+
heading with the unused suggestion and the reason.
|
|
188
|
+
|
|
189
|
+
| exit | meaning |
|
|
190
|
+
|------|---------|
|
|
191
|
+
| `0` | done |
|
|
192
|
+
| `2` | done, but some passages kept their original text (see the report) |
|
|
193
|
+
| `4` | stopped: out of credit or allowance |
|
|
194
|
+
| `1` | error, or not everything was done (a failed call, `--max-chars`, no `--yes`) |
|
|
195
|
+
|
|
196
|
+
## Before and after
|
|
197
|
+
|
|
198
|
+
`--diff` prints what the website shows inline, in the terminal:
|
|
199
|
+
|
|
200
|
+
```text
|
|
201
|
+
── Fyrir ───────────────────────────────────
|
|
202
|
+
Vertu viss um að ná út til okkar ef þú hefur einhverjar spurningar.
|
|
203
|
+
|
|
204
|
+
── Eftir ───────────────────────────────────
|
|
205
|
+
Ekki hika við að hafa samband ef einhverjar spurningar vakna.
|
|
206
|
+
|
|
207
|
+
── Breytingar (1) ──────────────────────────
|
|
208
|
+
1. − Vertu viss um að ná út til okkar ef þú hefur einhverjar spurningar.
|
|
209
|
+
+ Ekki hika við að hafa samband ef einhverjar spurningar vakna.
|
|
210
|
+
↳ <the reason the engine gives>
|
|
211
|
+
|
|
212
|
+
Endurskrifað og merking staðfest · innfæddni 91/100
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
`--report` (or `ALTALANDI_REPORT=1`) writes the same content as a Markdown file
|
|
216
|
+
you can keep or share. Reports are off by default because they contain your text.
|
|
217
|
+
`stdout` stays the refined text alone either way, so piping is unaffected.
|
|
218
|
+
|
|
219
|
+
## The meaning guarantee
|
|
220
|
+
|
|
221
|
+
Altalandi never silently changes meaning. For Icelandic input where the rewrite
|
|
222
|
+
can't be verified to preserve meaning, it returns the **original unchanged** and
|
|
223
|
+
says so on `stderr` (or `meaningPreserved:false` with `--json`). Check it before
|
|
224
|
+
trusting the output in an automated pipeline. Only `meaningPreserved:true` is a
|
|
225
|
+
verified pass; `null` means the gate was skipped or did not complete. `--fast`
|
|
226
|
+
deliberately skips the gate, so its result is unverified by design.
|
|
227
|
+
|
|
228
|
+
Without `--fast`, a `null` meaning verdict is printed as **MEANING UNVERIFIED**:
|
|
229
|
+
the check did not run or could not complete, so review the output before use.
|
|
230
|
+
With `--fast`, `null` is expected and is printed as **meaning check skipped**.
|
|
231
|
+
API warnings are always printed on `stderr`; under `--json` they remain in the
|
|
232
|
+
unchanged `warnings` array.
|
|
233
|
+
|
|
234
|
+
For automation, a successful HTTP response is not enough: without `--fast`, the
|
|
235
|
+
CLI prints the text or JSON response and then exits with status **3** when
|
|
236
|
+
`meaningPreserved` is `false` or `null`. Only strict `true` exits 0. `--fast` is
|
|
237
|
+
the explicit verification opt-out and exits 0 after a successful API response.
|
|
238
|
+
|
|
239
|
+
| exit | meaning |
|
|
240
|
+
|------|---------|
|
|
241
|
+
| `0` | verified success, or successful `--fast` request |
|
|
242
|
+
| `1` | API or network failure |
|
|
243
|
+
| `2` | missing input/key or invalid CLI usage |
|
|
244
|
+
| `3` | response printed, but meaning was false or unverified |
|
|
245
|
+
|
|
246
|
+
## Config
|
|
247
|
+
|
|
248
|
+
| env | default | purpose |
|
|
249
|
+
|-----|---------|---------|
|
|
250
|
+
| `ALTALANDI_API_KEY` | — | your key (Bearer). Mint at https://altalandi.is/stjornbord/forritarar |
|
|
251
|
+
| `ALTALANDI_BASE_URL` | `https://altalandi.is/api` | API base (override for self-hosting) |
|
|
252
|
+
| `ALTALANDI_DIFF` | — | `1` = always print the before/after (as `--diff`) |
|
|
253
|
+
| `ALTALANDI_REPORT` | — | `1` = always write a report (as `--report`) |
|
|
254
|
+
| `ALTALANDI_REPORT_DIR` | `./altalandi-reports` | where reports go |
|
|
255
|
+
|
|
256
|
+
MIT licensed. Calls are paid from the account's prepaid credit (a 500 kr trial,
|
|
257
|
+
then credit bought in the portal); a call the credit cannot cover exits with the
|
|
258
|
+
server's `402 insufficient_balance` message. The request's text and glossary fields are charged at the effective billing-tier
|
|
259
|
+
weight. Each whitespace-delimited token is at least one unit; an unbroken token
|
|
260
|
+
uses one unit per 20 characters, rounded up.
|