lakonai 0.6.1 → 0.7.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/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  <p align="center">
2
- <img src="./assets/logo.svg" width="140" alt="lakon" />
2
+ <img src="./assets/logo.svg" width="140" alt="lakonai" />
3
3
  </p>
4
4
 
5
- <h1 align="center">lakon</h1>
5
+ <h1 align="center">lakonai</h1>
6
6
 
7
7
  <p align="center">
8
8
  <strong>Cut LLM tokens by up to 94% — without losing a single identifier.</strong>
@@ -13,7 +13,7 @@
13
13
  </p>
14
14
 
15
15
  <p align="center">
16
- <a href="https://www.npmjs.com/package/lakon"><img src="https://img.shields.io/npm/v/lakon?color=0F0F0F&label=npm" alt="npm" /></a>
16
+ <a href="https://www.npmjs.com/package/lakonai"><img src="https://img.shields.io/npm/v/lakonai?color=0F0F0F&label=npm" alt="npm" /></a>
17
17
  <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-0F0F0F" alt="MIT" /></a>
18
18
  <img src="https://img.shields.io/badge/node-%E2%89%A518-0F0F0F" alt="node ≥18" />
19
19
  <img src="https://img.shields.io/badge/deps-0-0F0F0F" alt="zero dependencies" />
@@ -40,7 +40,7 @@
40
40
  | `Read pnpm-lock.yaml` | ~56,000 | **blocked** | **-95%** |
41
41
  | `Grep` (auto `head_limit`) | unbounded | 30 matches | **capped** |
42
42
 
43
- Conservative numbers — peaks go higher in practice. Run `lakon inspect <cmd>` on your own commands to measure.
43
+ Conservative numbers — peaks go higher in practice. Run `lakonai inspect <cmd>` on your own commands to measure.
44
44
 
45
45
  ---
46
46
 
@@ -58,13 +58,13 @@ That region was **Lakonía**. Its people gave the English language the word **la
58
58
 
59
59
  Your AI coding agent does. It opens with *"Sure! I'd be happy to help…"*, repeats your question back, and explains what the diff already shows. It reads `git log` in full when one line per commit would do. Every wasted token is a soldier you didn't need to send.
60
60
 
61
- **lakon trims both sides.**
61
+ **lakonai trims both sides.**
62
62
 
63
63
  ---
64
64
 
65
65
  ## Three fronts. One install.
66
66
 
67
- | Front | Wasted tokens look like… | lakon fixes it by… |
67
+ | Front | Wasted tokens look like… | lakonai fixes it by… |
68
68
  |--------------------------------|-------------------------------------------------------|-------------------------------------------------------------------------------------|
69
69
  | **Output** (the model) | *"Great question! Let me explain…"* | Installing a terse-response rule. No preamble, no recap, no restating. |
70
70
  | **Input** (your shell tools) | `git log` dumping 1.8 k tokens of author metadata | Wrapping `git`/`ls`/`grep`/`cat`/`tree`/`head`/`tail` and compressing before context. |
@@ -72,54 +72,56 @@ Your AI coding agent does. It opens with *"Sure! I'd be happy to help…"*, repe
72
72
  | **Search** (Grep tool) | `Grep` returns 800 matches and you re-read every one | A `PreToolUse` hook on `Grep` auto-caps `head_limit` at 30 with a one-shot hint. |
73
73
  | **Analysis** (the rule) | `Read` 5k of logs to count errors in your head | "Think in code" — write `node -e '…filter…count'`, consume only the answer. |
74
74
 
75
- Other tools stop at one front. lakon does all three transparently — your agent doesn't have to remember anything.
75
+ Other tools stop at one front. lakonai does all three transparently — your agent doesn't have to remember anything.
76
76
 
77
77
  ---
78
78
 
79
79
  ## Quick start
80
80
 
81
81
  ```bash
82
- npm install -g lakon
83
- lakon install
82
+ npm install -g lakonai
83
+ lakonai install
84
84
  ```
85
85
 
86
- That's it. `lakon install` configures your **global** agents — Claude Code, Codex, Gemini CLI — by writing rule blocks under `~/` only. It never touches your current directory by default.
86
+ That's it. `lakonai install` configures your **global** agents — Claude Code, Codex, Gemini CLI — by writing rule blocks under `~/` only. It never touches your current directory by default.
87
87
 
88
88
  Working inside a repo and want **per-project** rules (Cursor, Windsurf, Cline)? Add `--here`:
89
89
 
90
90
  ```bash
91
91
  cd path/to/your/repo
92
- lakon install --here # globals + per-project rules in this dir
92
+ lakonai install --here # globals + per-project rules in this dir
93
93
  ```
94
94
 
95
95
  From the next session forward your agent:
96
96
 
97
97
  1. **Responds tersely** — no preamble, no restating, no recap. (rule in `CLAUDE.md` / equivalent)
98
- 2. **Has its `Bash` calls auto-rewritten** — `PreToolUse` hook intercepts `git`/`ls`/`cat`/`grep`/etc and prefixes them with `lakon` transparently.
98
+ 2. **Has its `Bash` calls auto-rewritten** — `PreToolUse` hook intercepts `git`/`ls`/`cat`/`grep`/etc and prefixes them with `lakonai` transparently.
99
99
  3. **Has its `Read` calls guarded** — a second hook denies `node_modules/`, lockfiles, and build artifacts (with a hint to `grep` instead), and auto-caps reads over 800 lines.
100
100
  4. **Has its `Grep` calls capped** — a third hook auto-sets `head_limit` to 30 if you didn't, with a once-per-session hint to use `output_mode:"count"` for tallies.
101
101
  5. **Is told to "think in code"** — for any count/filter/parse task, the rule pushes the agent toward a one-shot `node -e` (or `awk`) script that consumes the data so the agent consumes only the answer.
102
- 6. **Logs per-turn LLM token usage** — a `Stop` hook records `input_tokens` / `output_tokens` / `cache_read` after each model turn so `lakon gain` shows model-side savings alongside shell-side savings.
103
- 7. **Tells you about new versions** — a `SessionStart` hook checks npm once per day and surfaces a `lakon X.Y.Z available` notice inside the session (opt-out: `LAKON_NO_UPDATE_CHECK=1`).
102
+ 6. **Logs per-turn LLM token usage** — a `Stop` hook records `input_tokens` / `output_tokens` / `cache_read` after each model turn so `lakonai gain` shows model-side savings alongside shell-side savings.
103
+ 7. **Tells you about new versions** — a `SessionStart` hook checks npm once per day and surfaces a `lakonai X.Y.Z available` notice inside the session (opt-out: `LAKON_NO_UPDATE_CHECK=1`).
104
104
 
105
- You'll see savings stack up immediately in `lakon gain`.
105
+ You'll see savings stack up immediately in `lakonai gain`.
106
106
 
107
- > Hooks are currently Claude Code-only (the only platform with documented hook APIs). For Codex/Cursor/Windsurf/Cline/Gemini, the rule asks the model to grep-before-Read and use the `lakon` prefix itself.
107
+ > Hooks are currently Claude Code-only (the only platform with documented hook APIs). For Codex/Cursor/Windsurf/Cline/Gemini, the rule asks the model to grep-before-Read and use the `lakonai` prefix itself.
108
108
 
109
- > **Worried?** Every install backs up the target file first. `lakon revert` puts it back byte-for-byte.
109
+ > **Worried?** Every install backs up the target file first. `lakonai revert` puts it back byte-for-byte.
110
+
111
+ > **Upgrading from `lakon`?** The package was renamed to **lakonai** in 0.7.0. The `lakon` and `lak` commands still work as aliases, your `~/.lakon/` log + backups carry over untouched, and `lakonai install` rewrites your existing config block to the new brand. No migration needed.
110
112
 
111
113
  ---
112
114
 
113
115
  ## Use the filter directly
114
116
 
115
- The CLI works as a standalone tool too. Run any shell command through `lakon` (or the short alias `lak`) to filter its output:
117
+ The CLI works as a standalone tool too. Run any shell command through `lakonai` (or the short alias `lak`) to filter its output:
116
118
 
117
119
  ```bash
118
- lakon git status # compressed git status
119
- lakon git log -50 # one line per commit (hash + subject)
120
- lakon git diff # only +/- lines, no noise
121
- lakon ls -la # size + name only
122
- lakon grep -r foo src/ # truncates at 40 matches
120
+ lakonai git status # compressed git status
121
+ lakonai git log -50 # one line per commit (hash + subject)
122
+ lakonai git diff # only +/- lines, no noise
123
+ lakonai ls -la # size + name only
124
+ lakonai grep -r foo src/ # truncates at 40 matches
123
125
  ```
124
126
 
125
127
  Unsupported commands run unchanged.
@@ -129,11 +131,11 @@ Unsupported commands run unchanged.
129
131
  ## See your savings
130
132
 
131
133
  ```bash
132
- lakon gain
134
+ lakonai gain
133
135
  ```
134
136
 
135
137
  ```
136
- lakon — savings this week: 36.4k tok saved across 512 shell calls (67%)
138
+ lakonai — savings this week: 36.4k tok saved across 512 shell calls (67%)
137
139
 
138
140
  shell + read/grep guards (tokens filtered before context)
139
141
  win calls before after saved %
@@ -160,7 +162,7 @@ The top block measures **input savings** (what filtered shell + guards prevented
160
162
  ### Inspect a single command
161
163
 
162
164
  ```bash
163
- lakon inspect git log
165
+ lakonai inspect git log
164
166
  ```
165
167
 
166
168
  ```
@@ -174,22 +176,22 @@ saved: 85%
174
176
 
175
177
  ## Commands
176
178
 
177
- | Command | What it does |
178
- |----------------------------------|-----------------------------------------------------------------------|
179
- | `lakon install` | Install rule for detected GLOBAL agents only (no CWD writes) |
180
- | `lakon install --here` | Globals + per-project rules (Cursor/Windsurf/Cline) in current dir |
181
- | `lakon install --only <p>` | Install just one platform by id (any scope) |
182
- | `lakon uninstall` | Strip the lakon block from each config (keeps your other content) |
183
- | `lakon revert [--only <p>]` | Restore each config to its pre-install state from backup |
184
- | `lakon backups` | Show backup history per platform |
185
- | `lakon list` | Show supported platforms and which are detected |
186
- | `lakon <cmd> [args]` | Run a command, filter its output, track savings |
187
- | `lakon gain` | Show savings by hour / day / week / month / all-time + session totals |
188
- | `lakon inspect <cmd>` | Run once and show raw-vs-filtered (no tracking) |
189
- | `lakon reset` | Wipe the savings log |
190
- | `lakon version` / `--version` / `-v` | Print the installed lakon version |
191
-
192
- `lak` is the short alias for `lakon` same behavior.
179
+ | Command | What it does |
180
+ |--------------------------------------|-----------------------------------------------------------------------|
181
+ | `lakonai install` | Install rule for detected GLOBAL agents only (no CWD writes) |
182
+ | `lakonai install --here` | Globals + per-project rules (Cursor/Windsurf/Cline) in current dir |
183
+ | `lakonai install --only <p>` | Install just one platform by id (any scope) |
184
+ | `lakonai uninstall` | Strip the lakonai block from each config (keeps your other content) |
185
+ | `lakonai revert [--only <p>]` | Restore each config to its pre-install state from backup |
186
+ | `lakonai backups` | Show backup history per platform |
187
+ | `lakonai list` | Show supported platforms and which are detected |
188
+ | `lakonai <cmd> [args]` | Run a command, filter its output, track savings |
189
+ | `lakonai gain` | Show savings by hour / day / week / month / all-time + session totals |
190
+ | `lakonai inspect <cmd>` | Run once and show raw-vs-filtered (no tracking) |
191
+ | `lakonai reset` | Wipe the savings log |
192
+ | `lakonai version` / `--version` / `-v` | Print the installed lakonai version |
193
+
194
+ `lak` is the short alias for `lakonai`. `lakon` is kept as a legacy alias so existing setups keep working.
193
195
 
194
196
  ---
195
197
 
@@ -226,48 +228,48 @@ The `Grep` hook auto-sets `head_limit` to **30** when the agent didn't pass one.
226
228
 
227
229
  A `Stop` hook fires at the end of every model turn, reads the latest `usage` block from the transcript, and appends a `cmd: "session"` entry to the log with `input_tokens`, `output_tokens`, `cache_read_input_tokens`, and `cache_creation_input_tokens`.
228
230
 
229
- `lakon gain` renders these in a separate **session output** block (see example above) — so you can watch model-side verbosity drop and cache-hit ratios climb over time. Top commands list excludes session entries; they're not shell calls.
231
+ `lakonai gain` renders these in a separate **session output** block (see example above) — so you can watch model-side verbosity drop and cache-hit ratios climb over time. Top commands list excludes session entries; they're not shell calls.
230
232
 
231
233
  ### Update notifications (Claude Code)
232
234
 
233
- A `SessionStart` hook checks `registry.npmjs.org/lakon/latest` at most once per 24 hours (cached at `~/.lakon/version.json`) and, if a newer version exists, emits a `hookSpecificOutput.additionalContext` that surfaces inside the Claude session:
235
+ A `SessionStart` hook checks `registry.npmjs.org/lakonai/latest` at most once per 24 hours (cached at `~/.lakon/version.json`) and, if a newer version exists, emits a `hookSpecificOutput.additionalContext` that surfaces inside the Claude session:
234
236
 
235
237
  ```
236
- lakon 0.7.0 available (you have 0.6.0). Update: npm i -g lakon@latest
238
+ lakonai 0.8.0 available (you have 0.7.0). Update: npm i -g lakonai@latest
237
239
  ```
238
240
 
239
- Outside Claude, `lakon gain` and `lakon version` print the same notice on stderr (yellow when TTY).
241
+ Outside Claude, `lakonai gain` and `lakonai version` print the same notice on stderr (yellow when TTY).
240
242
 
241
243
  **Opt out:** `LAKON_NO_UPDATE_CHECK=1`.
242
244
  **Test endpoint:** `LAKON_REGISTRY_URL=http://localhost:8080/` (overrides the npm URL for local testing).
243
245
 
244
246
  ### Multi-profile Claude Code
245
247
 
246
- If you use wrapper aliases like `claude-my=CLAUDE_CONFIG_DIR=$HOME/.claude-my claude` (e.g. one profile per Anthropic account or org), set the same env var when running `lakon install` so hooks and the rule file land in the right config dir:
248
+ If you use wrapper aliases like `claude-my=CLAUDE_CONFIG_DIR=$HOME/.claude-my claude` (e.g. one profile per Anthropic account or org), set the same env var when running `lakonai install` so hooks and the rule file land in the right config dir:
247
249
 
248
250
  ```bash
249
- CLAUDE_CONFIG_DIR=$HOME/.claude-my lakon install
250
- CLAUDE_CONFIG_DIR=$HOME/.claude-arco lakon install
251
+ CLAUDE_CONFIG_DIR=$HOME/.claude-my lakonai install
252
+ CLAUDE_CONFIG_DIR=$HOME/.claude-arco lakonai install
251
253
  ```
252
254
 
253
- Each profile gets its own independent install. `lakon uninstall` / `lakon revert` respect the same env var.
255
+ Each profile gets its own independent install. `lakonai uninstall` / `lakonai revert` respect the same env var.
254
256
 
255
257
  ---
256
258
 
257
259
  ## Supported AI agents
258
260
 
259
- | Agent | Scope | What `lakon install` writes |
260
- |-----------------|----------|------------------------------------------------------------------------------------------------------|
261
- | Claude Code¹ | global | Rule block in `~/.claude/CLAUDE.md` + **five** hooks in `~/.claude/settings.json` (`PreToolUse`: Bash rewrite + Read guard + Grep guard; `Stop`: session-usage log; `SessionStart`: update notify) + `/lakon:gain` `/lakon:reset` `/lakon:inspect` slash commands |
262
- | Codex CLI | global | Rule block in `~/.codex/AGENTS.md` |
263
- | Gemini CLI | global | Rule block in `~/.gemini/GEMINI.md` |
264
- | Cursor | project² | `.cursor/rules/lakon.mdc` in the current dir |
265
- | Windsurf | project² | `.windsurf/rules/lakon.md` in the current dir |
266
- | Cline | project² | `.clinerules/lakon.md` in the current dir |
261
+ | Agent | Scope | What `lakonai install` writes |
262
+ |-----------------|----------|--------------------------------------------------------------------------------------------------------|
263
+ | Claude Code¹ | global | Rule block in `~/.claude/CLAUDE.md` + **five** hooks in `~/.claude/settings.json` (`PreToolUse`: Bash rewrite + Read guard + Grep guard; `Stop`: session-usage log; `SessionStart`: update notify) + `/lakonai:gain` `/lakonai:reset` `/lakonai:inspect` slash commands |
264
+ | Codex CLI | global | Rule block in `~/.codex/AGENTS.md` |
265
+ | Gemini CLI | global | Rule block in `~/.gemini/GEMINI.md` |
266
+ | Cursor | project² | `.cursor/rules/lakonai.mdc` in the current dir |
267
+ | Windsurf | project² | `.windsurf/rules/lakonai.md` in the current dir |
268
+ | Cline | project² | `.clinerules/lakonai.md` in the current dir |
267
269
 
268
270
  ¹ "Claude Code" covers **every** Claude Code frontend — terminal CLI, VS Code extension, JetBrains plugin, desktop app. All read the same `~/.claude/CLAUDE.md` + `~/.claude/settings.json`, so one install lights up all of them.
269
271
 
270
- ² Project-scoped tools only read rules from the current directory, so `lakon install` skips them by default to avoid scattering files across your repos. Add `--here` (or use `--project`) when you actually want them in the current dir.
272
+ ² Project-scoped tools only read rules from the current directory, so `lakonai install` skips them by default to avoid scattering files across your repos. Add `--here` (or use `--project`) when you actually want them in the current dir.
271
273
 
272
274
  Each install is **idempotent** (rerunning replaces the existing block) and **reversible** (`uninstall` strips it, `revert` restores from backup).
273
275
 
@@ -275,39 +277,41 @@ Each install is **idempotent** (rerunning replaces the existing block) and **rev
275
277
 
276
278
  ## Backup & revert
277
279
 
278
- Before writing to your config file for the first time, `lakon` copies it into `~/.lakon/backups/<platform>/<filename>.<timestamp>.bak`. Every install thereafter appends another snapshot to that file's manifest.
280
+ Before writing to your config file for the first time, `lakonai` copies it into `~/.lakon/backups/<platform>/<filename>.<timestamp>.bak`. Every install thereafter appends another snapshot to that file's manifest.
279
281
 
280
282
  ```bash
281
- lakon uninstall # strips just the lakon block; keeps your other CLAUDE.md content
282
- lakon revert # restores the file to its pre-install state, byte for byte
283
- lakon backups # shows every snapshot, per platform, with timestamps
283
+ lakonai uninstall # strips just the lakonai block; keeps your other CLAUDE.md content
284
+ lakonai revert # restores the file to its pre-install state, byte for byte
285
+ lakonai backups # shows every snapshot, per platform, with timestamps
284
286
  ```
285
287
 
286
- Use `uninstall` to remove lakon while keeping your other edits. Use `revert` when you want a clean rollback to exactly the file you had before.
288
+ Use `uninstall` to remove lakonai while keeping your other edits. Use `revert` when you want a clean rollback to exactly the file you had before.
287
289
 
288
290
  ---
289
291
 
290
292
  ## How tracking works
291
293
 
292
- Every filtered command appends a JSON line to `~/.lakon/log.jsonl`. The `Stop` hook appends one line per model turn with token counts (`cmd: "session"`). `lakon gain` reads that log and renders both sides separately.
294
+ Every filtered command appends a JSON line to `~/.lakon/log.jsonl`. The `Stop` hook appends one line per model turn with token counts (`cmd: "session"`). `lakonai gain` reads that log and renders both sides separately.
293
295
 
294
296
  The log stores: timestamp, command name, first few args, raw/filtered token counts (shell entries); timestamp, session id, `input_tokens` / `output_tokens` / `cache_read` / `cache_create` (session entries). **No file contents. No full arguments. No transcript content. No data ever leaves your machine** — except the one daily HEAD request to `registry.npmjs.org` for the update check (opt-out: `LAKON_NO_UPDATE_CHECK=1`).
295
297
 
296
298
  Override the location with `LAKON_HOME=/path`. Disable per-command logging with `LAKON_NO_TRACK=1`.
297
299
 
300
+ > Note: env vars and the data dir keep the historical `LAKON_*` / `~/.lakon/` names so existing installs keep their logs and backups intact. New installs land there too.
301
+
298
302
  ---
299
303
 
300
304
  ## Configuration
301
305
 
302
- | Env var | Effect |
303
- |-------------------------|-----------------------------------------------------------------------------|
306
+ | Env var | Effect |
307
+ |-------------------------|------------------------------------------------------------------------------|
304
308
  | `LAKON_HOME` | Where to keep the log + backups + version cache (default `~/.lakon`) |
305
309
  | `LAKON_NO_TRACK` | Set to `1` to disable per-command logging |
306
310
  | `LAKON_NO_UPDATE_CHECK` | Set to `1` to disable the `SessionStart` npm check + terminal hint |
307
311
  | `LAKON_REGISTRY_URL` | Override the npm registry URL used by the update check (testing) |
308
- | `LAKON_COLOR` | `1` forces ANSI colors in `lakon gain`; `0` disables; unset = TTY auto-detect |
312
+ | `LAKON_COLOR` | `1` forces ANSI colors in `lakonai gain`; `0` disables; unset = TTY auto-detect |
309
313
  | `NO_COLOR` | Standard. Disables ANSI colors when set to any non-empty value. |
310
- | `CLAUDE_CONFIG_DIR` | When set during `lakon install` / `uninstall`, hooks + rule land in that dir instead of `~/.claude/`. Used for multi-profile setups. |
314
+ | `CLAUDE_CONFIG_DIR` | When set during `lakonai install` / `uninstall`, hooks + rule land in that dir instead of `~/.claude/`. Used for multi-profile setups. |
311
315
 
312
316
  ---
313
317
 
@@ -317,7 +321,7 @@ Override the location with `LAKON_HOME=/path`. Disable per-command logging with
317
321
  > *"Vēnī, vīdī, vīcī."* — Julius Caesar, three words to describe winning a war.
318
322
  > *"If."* — Spartans, refusing to be intimidated by a single conditional.
319
323
 
320
- Every token your agent emits or reads is paid for — in latency, in money, in context budget. The fastest way to think clearly is to speak briefly. lakon doesn't make your agent dumber; it makes it Spartan.
324
+ Every token your agent emits or reads is paid for — in latency, in money, in context budget. The fastest way to think clearly is to speak briefly. lakonai doesn't make your agent dumber; it makes it Spartan.
321
325
 
322
326
  ---
323
327
 
@@ -330,7 +334,7 @@ npm install # only devDeps (c8 for coverage); zero runtime
330
334
  node --test tests/ # run the suite
331
335
  npm run test:coverage # text + HTML coverage report (coverage/index.html)
332
336
  npm run test:coverage:check # fail if any metric drops below 100%
333
- node bin/lakon.js --help
337
+ node bin/lakonai.js --help
334
338
  ```
335
339
 
336
340
  Suite: **187 tests**. Coverage gate: **100% lines / 100% branches / 100% functions / 100% statements**. Zero runtime dependencies. Node ≥ 18.
@@ -344,7 +348,7 @@ Built on ideas from two excellent projects:
344
348
  - [**caveman**](https://github.com/juliusbrussee/caveman) — terse-prose rule + auto-clarity carve-outs.
345
349
  - [**rtk**](https://github.com/rtk-ai/rtk) — CLI output filtering as a force multiplier for LLM agents.
346
350
 
347
- lakon condenses both into one zero-dependency npm package with a single install command, automatic backups, and time-windowed savings tracking.
351
+ lakonai condenses both into one zero-dependency npm package with a single install command, automatic backups, and time-windowed savings tracking.
348
352
 
349
353
  ---
350
354
 
package/assets/logo.svg CHANGED
@@ -1,5 +1,5 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 240" width="240" height="240" role="img" aria-label="lakon">
2
- <title>lakon</title>
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 240" width="240" height="240" role="img" aria-label="lakonai">
2
+ <title>lakonai</title>
3
3
  <desc>Spartan lambda inside a circular shield — symbol of Lakonía, ancient Sparta.</desc>
4
4
  <style>
5
5
  .mark { stroke: #0F0F0F; fill: none; }
@@ -7,45 +7,46 @@ const { install, uninstall, revert, listPlatforms, backupsReport } = require('..
7
7
  const tracking = require('../src/tracking');
8
8
  const versionCheck = require('../src/hooks/version-check');
9
9
 
10
- const HELP = `lakon — spartan replies for AI agents
10
+ const HELP = `lakonai — spartan replies for AI agents
11
11
 
12
12
  Usage:
13
- lakon <cmd> [args...] Run <cmd> and filter its output (tracks savings)
13
+ lakonai <cmd> [args...] Run <cmd> and filter its output (tracks savings)
14
14
  lak <cmd> [args...] (short alias)
15
+ lakon <cmd> [args...] (legacy alias, kept for back-compat)
15
16
 
16
- lakon install Install rule + hooks for detected GLOBAL platforms
17
+ lakonai install Install rule + hooks for detected GLOBAL platforms
17
18
  (Claude Code / Codex / Gemini — touches ~/ only)
18
- lakon install --here Same as above + per-project rules (Cursor /
19
+ lakonai install --here Same as above + per-project rules (Cursor /
19
20
  Windsurf / Cline) written into the current dir
20
- lakon install --only <p> Install just one platform by id (any scope)
21
+ lakonai install --only <p> Install just one platform by id (any scope)
21
22
  (every install backs up the target file first)
22
- lakon uninstall Strip the lakon block (keeps rest of file)
23
- lakon revert [--only <p>] Restore files to pre-install state from backup
24
- lakon backups Show backup history per platform
25
- lakon list Show supported platforms
23
+ lakonai uninstall Strip the lakonai block (keeps rest of file)
24
+ lakonai revert [--only <p>] Restore files to pre-install state from backup
25
+ lakonai backups Show backup history per platform
26
+ lakonai list Show supported platforms
26
27
 
27
- lakon gain Show token savings (hour / day / week / month / all)
28
- lakon inspect <cmd> ... Run <cmd> once and show raw vs filtered (no tracking)
29
- lakon reset Wipe the savings log
30
- lakon version Print the installed lakon version
31
- lakon --help This help
28
+ lakonai gain Show token savings (hour / day / week / month / all)
29
+ lakonai inspect <cmd> ... Run <cmd> once and show raw vs filtered (no tracking)
30
+ lakonai reset Wipe the savings log
31
+ lakonai version Print the installed lakonai version
32
+ lakonai --help This help
32
33
 
33
34
  Supported filters: git (log/status/diff/show), ls, tree, cat, head, tail, grep, rg, ag.
34
35
  Unsupported commands run unchanged (passthrough, still tracked as 0% savings).
35
36
 
36
37
  Multi-profile Claude Code (e.g. claude-my / claude-arco wrappers):
37
- CLAUDE_CONFIG_DIR=$HOME/.claude-my lakon install
38
- CLAUDE_CONFIG_DIR=$HOME/.claude-arco lakon install
38
+ CLAUDE_CONFIG_DIR=$HOME/.claude-my lakonai install
39
+ CLAUDE_CONFIG_DIR=$HOME/.claude-arco lakonai install
39
40
 
40
41
  Update notifications:
41
- SessionStart hook + \`lakon gain\` / \`lakon version\` check npm once per day.
42
+ SessionStart hook + \`lakonai gain\` / \`lakonai version\` check npm once per day.
42
43
  Disable with LAKON_NO_UPDATE_CHECK=1.
43
44
  `;
44
45
 
45
46
  function runAndFilter(cmd, args) {
46
47
  const child = spawnSync(cmd, args, { encoding: 'utf8', stdio: ['inherit', 'pipe', 'inherit'] });
47
48
  if (child.error) {
48
- process.stderr.write(`lakon: ${child.error.message}\n`);
49
+ process.stderr.write(`lakonai: ${child.error.message}\n`);
49
50
  process.exit(127);
50
51
  }
51
52
  /* c8 ignore next */
@@ -68,7 +69,7 @@ function runAndFilter(cmd, args) {
68
69
 
69
70
  function inspectCmd(rest) {
70
71
  if (!rest.length) {
71
- process.stderr.write('lakon inspect: missing command\n');
72
+ process.stderr.write('lakonai inspect: missing command\n');
72
73
  process.exit(2);
73
74
  }
74
75
  const [cmd, ...args] = rest;
@@ -163,7 +164,7 @@ async function main() {
163
164
  }
164
165
  if (first === 'reset') {
165
166
  const ok = tracking.reset();
166
- process.stdout.write(ok ? 'lakon: log cleared\n' : 'lakon: nothing to clear\n');
167
+ process.stdout.write(ok ? 'lakonai: log cleared\n' : 'lakonai: nothing to clear\n');
167
168
  return;
168
169
  }
169
170
 
@@ -172,6 +173,6 @@ async function main() {
172
173
 
173
174
  /* c8 ignore next 4 */
174
175
  main().catch((err) => {
175
- process.stderr.write(`lakon: ${err.message}\n`);
176
+ process.stderr.write(`lakonai: ${err.message}\n`);
176
177
  process.exit(1);
177
178
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "lakonai",
3
- "version": "0.6.1",
4
- "description": "Spartan replies for AI agents terse model output + filtered CLI output for Claude Code, Codex, Cursor, Windsurf, Cline, and Gemini.",
3
+ "version": "0.7.0",
4
+ "description": "lakonai — Spartan replies for AI agents. Terse model output + filtered CLI output for Claude Code, Codex, Cursor, Windsurf, Cline, and Gemini.",
5
5
  "keywords": [
6
6
  "claude",
7
7
  "claude-code",
@@ -29,8 +29,9 @@
29
29
  "type": "commonjs",
30
30
  "main": "src/filters/index.js",
31
31
  "bin": {
32
- "lakon": "bin/lakon.js",
33
- "lak": "bin/lakon.js"
32
+ "lakonai": "bin/lakonai.js",
33
+ "lakon": "bin/lakonai.js",
34
+ "lak": "bin/lakonai.js"
34
35
  },
35
36
  "files": [
36
37
  "bin/",
@@ -9,10 +9,10 @@ function rewriteIfNeeded(command) {
9
9
  if (typeof command !== 'string') return null;
10
10
  const trimmed = command.trim();
11
11
  if (!trimmed) return null;
12
- if (/^(lakon|lak)(\s|$)/.test(trimmed)) return null;
12
+ if (/^(lakonai|lakon|lak)(\s|$)/.test(trimmed)) return null;
13
13
  const firstWord = trimmed.split(/\s+/)[0];
14
14
  if (!FILTERED_CMDS.has(firstWord)) return null;
15
- return `lakon ${trimmed}`;
15
+ return `lakonai ${trimmed}`;
16
16
  }
17
17
 
18
18
  async function readStdin() {
@@ -54,7 +54,7 @@ async function main() {
54
54
 
55
55
  const updatedInput = { ...input, head_limit: DEFAULT_HEAD_LIMIT };
56
56
  const reason = shouldEmit('grep-head-cap')
57
- ? `lakon: head_limit auto-set to ${DEFAULT_HEAD_LIMIT}. Pass head_limit explicitly to override; pass output_mode:"count" for a tally instead of matches.`
57
+ ? `lakonai: head_limit auto-set to ${DEFAULT_HEAD_LIMIT}. Pass head_limit explicitly to override; pass output_mode:"count" for a tally instead of matches.`
58
58
  : undefined;
59
59
 
60
60
  trackRecord({
@@ -137,7 +137,7 @@ async function main() {
137
137
  hookSpecificOutput: {
138
138
  hookEventName: 'PreToolUse',
139
139
  permissionDecision: 'deny',
140
- permissionDecisionReason: `lakon: ${denyReason}`,
140
+ permissionDecisionReason: `lakonai: ${denyReason}`,
141
141
  },
142
142
  };
143
143
  process.stdout.write(JSON.stringify(response));
@@ -165,7 +165,7 @@ async function main() {
165
165
  offset: 1,
166
166
  limit: AUTO_CAP_LINES,
167
167
  },
168
- permissionDecisionReason: `lakon: file has ${n} lines, capped at ${AUTO_CAP_LINES}. Read again with offset=${AUTO_CAP_LINES + 1} for more, or grep -n the symbol you need.`,
168
+ permissionDecisionReason: `lakonai: file has ${n} lines, capped at ${AUTO_CAP_LINES}. Read again with offset=${AUTO_CAP_LINES + 1} for more, or grep -n the symbol you need.`,
169
169
  },
170
170
  };
171
171
  process.stdout.write(JSON.stringify(response));
@@ -8,7 +8,7 @@ const http = require('http');
8
8
 
9
9
  const CHECK_TTL_MS = 24 * 60 * 60 * 1000;
10
10
  const FETCH_TIMEOUT_MS = 1500;
11
- const REGISTRY_URL = 'https://registry.npmjs.org/lakon/latest';
11
+ const REGISTRY_URL = 'https://registry.npmjs.org/lakonai/latest';
12
12
 
13
13
  function lakonHome() {
14
14
  /* c8 ignore next */
@@ -161,7 +161,7 @@ function getCachedUpdate() {
161
161
  }
162
162
 
163
163
  function formatNotice(info) {
164
- return `lakon ${info.latest} available (you have ${info.current}). Update: npm i -g lakon@latest`;
164
+ return `lakonai ${info.latest} available (you have ${info.current}). Update: npm i -g lakonai@latest`;
165
165
  }
166
166
 
167
167
  module.exports = {
@@ -8,37 +8,41 @@ const COMMANDS = [
8
8
  {
9
9
  name: 'gain',
10
10
  body: `---
11
- description: Show lakon token savings (raw vs filtered, per window and top commands).
12
- allowed-tools: Bash(lakon gain:*), Bash(lak gain:*)
11
+ description: Show lakonai token savings (raw vs filtered, per window and top commands).
12
+ allowed-tools: Bash(lakonai gain:*), Bash(lakon gain:*), Bash(lak gain:*)
13
13
  ---
14
14
 
15
- Run \`lakon gain\` and show the output verbatim. Do not summarize — the table is the answer.
15
+ Run \`lakonai gain\` and show the output verbatim. Do not summarize — the table is the answer.
16
16
  `,
17
17
  },
18
18
  {
19
19
  name: 'reset',
20
20
  body: `---
21
- description: Wipe the lakon savings log.
22
- allowed-tools: Bash(lakon reset:*)
21
+ description: Wipe the lakonai savings log.
22
+ allowed-tools: Bash(lakonai reset:*), Bash(lakon reset:*)
23
23
  ---
24
24
 
25
- Run \`lakon reset\` and show the output. Confirm with the user before running if they didn't explicitly ask to clear.
25
+ Run \`lakonai reset\` and show the output. Confirm with the user before running if they didn't explicitly ask to clear.
26
26
  `,
27
27
  },
28
28
  {
29
29
  name: 'inspect',
30
30
  body: `---
31
- description: Run a command once through lakon and compare raw vs filtered token counts.
31
+ description: Run a command once through lakonai and compare raw vs filtered token counts.
32
32
  argument-hint: <command> [args...]
33
- allowed-tools: Bash(lakon inspect:*)
33
+ allowed-tools: Bash(lakonai inspect:*), Bash(lakon inspect:*)
34
34
  ---
35
35
 
36
- Run \`lakon inspect $ARGUMENTS\` and show the output verbatim.
36
+ Run \`lakonai inspect $ARGUMENTS\` and show the output verbatim.
37
37
  `,
38
38
  },
39
39
  ];
40
40
 
41
41
  function commandsDir(home) {
42
+ return path.join(claudeConfigDir(home), 'commands', 'lakonai');
43
+ }
44
+
45
+ function legacyCommandsDir(home) {
42
46
  return path.join(claudeConfigDir(home), 'commands', 'lakon');
43
47
  }
44
48
 
@@ -49,13 +53,12 @@ function installCommands(home) {
49
53
  for (const c of COMMANDS) {
50
54
  const p = path.join(dir, `${c.name}.md`);
51
55
  fs.writeFileSync(p, c.body, 'utf8');
52
- written.push(`/lakon:${c.name}`);
56
+ written.push(`/lakonai:${c.name}`);
53
57
  }
54
58
  return written;
55
59
  }
56
60
 
57
- function uninstallCommands(home) {
58
- const dir = commandsDir(home);
61
+ function removeCommandsFromDir(dir) {
59
62
  const removed = [];
60
63
  for (const c of COMMANDS) {
61
64
  const p = path.join(dir, `${c.name}.md`);
@@ -68,4 +71,12 @@ function uninstallCommands(home) {
68
71
  return removed;
69
72
  }
70
73
 
74
+ function uninstallCommands(home) {
75
+ const removed = [
76
+ ...removeCommandsFromDir(commandsDir(home)),
77
+ ...removeCommandsFromDir(legacyCommandsDir(home)),
78
+ ];
79
+ return removed;
80
+ }
81
+
71
82
  module.exports = { installCommands, uninstallCommands, commandsDir };
@@ -6,7 +6,7 @@ const os = require('os');
6
6
  const platforms = require('./platforms');
7
7
  const { listBackups } = require('./backup');
8
8
 
9
- const RULE_PATH = path.join(__dirname, '..', 'rules', 'caveman.md');
9
+ const RULE_PATH = path.join(__dirname, '..', 'rules', 'lakonai.md');
10
10
 
11
11
  const OK = '✅';
12
12
  const FAIL = '❌';
@@ -52,16 +52,16 @@ async function install({ only, here = false } = {}) {
52
52
 
53
53
  if (!targets.length) {
54
54
  if (only) {
55
- process.stdout.write(`${FAIL} unknown platform "${only}". Run \`lakon list\` to see options.\n`);
55
+ process.stdout.write(`${FAIL} unknown platform "${only}". Run \`lakonai list\` to see options.\n`);
56
56
  } else {
57
- process.stdout.write(`${FAIL} no supported global platforms detected. Install Claude Code, Codex, or Gemini CLI first — or run \`lakon install --here\` to write per-project rules (Cursor/Windsurf/Cline) in the current directory.\n`);
57
+ process.stdout.write(`${FAIL} no supported global platforms detected. Install Claude Code, Codex, or Gemini CLI first — or run \`lakonai install --here\` to write per-project rules (Cursor/Windsurf/Cline) in the current directory.\n`);
58
58
  }
59
59
  process.exitCode = 1;
60
60
  return;
61
61
  }
62
62
 
63
- process.stdout.write('\nlakon install\n');
64
- process.stdout.write('─────────────\n');
63
+ process.stdout.write('\nlakonai install\n');
64
+ process.stdout.write('───────────────\n');
65
65
 
66
66
  for (const p of targets) {
67
67
  try {
@@ -76,18 +76,18 @@ async function install({ only, here = false } = {}) {
76
76
  process.stdout.write('\n');
77
77
  if (!only && !here) {
78
78
  process.stdout.write(` ${BULLET} Per-project rules (Cursor/Windsurf/Cline) were skipped.\n`);
79
- process.stdout.write(` Inside a repo? Run \`lakon install --here\` to add them in the current directory.\n`);
79
+ process.stdout.write(` Inside a repo? Run \`lakonai install --here\` to add them in the current directory.\n`);
80
80
  }
81
- process.stdout.write(` ${BULLET} \`lakon uninstall\` removes only the lakon block (keeps your other content).\n`);
82
- process.stdout.write(` ${BULLET} \`lakon revert\` restores files to pre-install state from backup.\n`);
83
- process.stdout.write(` ${BULLET} \`lakon gain\` shows how many tokens you've saved.\n`);
81
+ process.stdout.write(` ${BULLET} \`lakonai uninstall\` removes only the lakonai block (keeps your other content).\n`);
82
+ process.stdout.write(` ${BULLET} \`lakonai revert\` restores files to pre-install state from backup.\n`);
83
+ process.stdout.write(` ${BULLET} \`lakonai gain\` shows how many tokens you've saved.\n`);
84
84
  process.stdout.write('\nRestart your AI agent (or open a new session) for the rule to take effect.\n');
85
85
  }
86
86
 
87
87
  async function uninstall() {
88
88
  const home = os.homedir();
89
- process.stdout.write('\nlakon uninstall\n');
90
- process.stdout.write('───────────────\n');
89
+ process.stdout.write('\nlakonai uninstall\n');
90
+ process.stdout.write('─────────────────\n');
91
91
  let any = false;
92
92
  for (const p of platforms.list()) {
93
93
  try {
@@ -108,8 +108,8 @@ async function revert({ only } = {}) {
108
108
  ? platforms.list().filter((p) => p.id === only)
109
109
  : platforms.list();
110
110
 
111
- process.stdout.write('\nlakon revert\n');
112
- process.stdout.write('────────────\n');
111
+ process.stdout.write('\nlakonai revert\n');
112
+ process.stdout.write('──────────────\n');
113
113
 
114
114
  let any = false;
115
115
  for (const p of targets) {
@@ -129,7 +129,7 @@ async function revert({ only } = {}) {
129
129
  }
130
130
 
131
131
  function backupsReport() {
132
- const lines = ['', 'lakon — backup history', '──────────────────────'];
132
+ const lines = ['', 'lakonai — backup history', '────────────────────────'];
133
133
  let any = false;
134
134
  for (const p of platforms.list()) {
135
135
  const entries = listBackups(p.id);
@@ -7,8 +7,10 @@ const { installHook, uninstallHook } = require('./claude-hook');
7
7
  const { installCommands, uninstallCommands } = require('./claude-commands');
8
8
  const { claudeConfigDir } = require('./paths');
9
9
 
10
- const MARK_BEGIN = '<!-- lakon:begin -->';
11
- const MARK_END = '<!-- lakon:end -->';
10
+ const MARK_BEGIN = '<!-- lakonai:begin -->';
11
+ const MARK_END = '<!-- lakonai:end -->';
12
+ const ANY_BEGIN = '<!-- lakon(?:ai)?:begin -->';
13
+ const ANY_END = '<!-- lakon(?:ai)?:end -->';
12
14
 
13
15
  function wrap(rule) {
14
16
  return `${MARK_BEGIN}\n${rule.trim()}\n${MARK_END}\n`;
@@ -30,7 +32,7 @@ function hasBlock(filePath) {
30
32
  const existing = readSafe(filePath);
31
33
  /* c8 ignore next */
32
34
  if (!existing) return false;
33
- const re = new RegExp(`${MARK_BEGIN}[\\s\\S]*?${MARK_END}`);
35
+ const re = new RegExp(`${ANY_BEGIN}[\\s\\S]*?${ANY_END}`);
34
36
  return re.test(existing);
35
37
  }
36
38
 
@@ -41,7 +43,7 @@ function upsertBlock(platformId, filePath, rule) {
41
43
  }
42
44
  const existing = readSafe(filePath);
43
45
  const block = wrap(rule);
44
- const re = new RegExp(`${MARK_BEGIN}[\\s\\S]*?${MARK_END}\\n?`);
46
+ const re = new RegExp(`${ANY_BEGIN}[\\s\\S]*?${ANY_END}\\n?`);
45
47
  const next = re.test(existing) ? existing.replace(re, block) : (existing ? `${existing.trim()}\n\n${block}` : block);
46
48
  fs.writeFileSync(filePath, next, 'utf8');
47
49
  return filePath;
@@ -50,7 +52,7 @@ function upsertBlock(platformId, filePath, rule) {
50
52
  function stripBlock(filePath) {
51
53
  const existing = readSafe(filePath);
52
54
  if (!existing) return null;
53
- const re = new RegExp(`\\n*${MARK_BEGIN}[\\s\\S]*?${MARK_END}\\n?`);
55
+ const re = new RegExp(`\\n*${ANY_BEGIN}[\\s\\S]*?${ANY_END}\\n?`);
54
56
  if (!re.test(existing)) return null;
55
57
  const next = existing.replace(re, '').trim();
56
58
  if (next) fs.writeFileSync(filePath, next + '\n', 'utf8');
@@ -97,24 +99,33 @@ const PLATFORMS = [
97
99
  label: 'Cursor (per-repo rule)',
98
100
  scope: 'project',
99
101
  detect: () => fs.existsSync(path.join(process.cwd(), '.cursor')),
100
- install: ({ rule, id }) => upsertBlock(id, path.join(process.cwd(), '.cursor', 'rules', 'lakon.mdc'), rule),
101
- uninstall: () => stripBlock(path.join(process.cwd(), '.cursor', 'rules', 'lakon.mdc')),
102
+ install: ({ rule, id }) => upsertBlock(id, path.join(process.cwd(), '.cursor', 'rules', 'lakonai.mdc'), rule),
103
+ uninstall: () => {
104
+ stripBlock(path.join(process.cwd(), '.cursor', 'rules', 'lakon.mdc'));
105
+ return stripBlock(path.join(process.cwd(), '.cursor', 'rules', 'lakonai.mdc'));
106
+ },
102
107
  },
103
108
  {
104
109
  id: 'windsurf',
105
110
  label: 'Windsurf (per-repo rule)',
106
111
  scope: 'project',
107
112
  detect: () => fs.existsSync(path.join(process.cwd(), '.windsurf')),
108
- install: ({ rule, id }) => upsertBlock(id, path.join(process.cwd(), '.windsurf', 'rules', 'lakon.md'), rule),
109
- uninstall: () => stripBlock(path.join(process.cwd(), '.windsurf', 'rules', 'lakon.md')),
113
+ install: ({ rule, id }) => upsertBlock(id, path.join(process.cwd(), '.windsurf', 'rules', 'lakonai.md'), rule),
114
+ uninstall: () => {
115
+ stripBlock(path.join(process.cwd(), '.windsurf', 'rules', 'lakon.md'));
116
+ return stripBlock(path.join(process.cwd(), '.windsurf', 'rules', 'lakonai.md'));
117
+ },
110
118
  },
111
119
  {
112
120
  id: 'cline',
113
121
  label: 'Cline (per-repo rule)',
114
122
  scope: 'project',
115
123
  detect: () => fs.existsSync(path.join(process.cwd(), '.clinerules')),
116
- install: ({ rule, id }) => upsertBlock(id, path.join(process.cwd(), '.clinerules', 'lakon.md'), rule),
117
- uninstall: () => stripBlock(path.join(process.cwd(), '.clinerules', 'lakon.md')),
124
+ install: ({ rule, id }) => upsertBlock(id, path.join(process.cwd(), '.clinerules', 'lakonai.md'), rule),
125
+ uninstall: () => {
126
+ stripBlock(path.join(process.cwd(), '.clinerules', 'lakon.md'));
127
+ return stripBlock(path.join(process.cwd(), '.clinerules', 'lakonai.md'));
128
+ },
118
129
  },
119
130
  {
120
131
  id: 'gemini',
@@ -1,6 +1,6 @@
1
- # lakon — terse response style
1
+ # lakonai — terse response style
2
2
 
3
- You are operating in **lakon mode** (named for Lakonía — the region of ancient Sparta whose people gave us the word "laconic"). Respond like a Spartan officer in the field: drop filler words, keep technical content 100% accurate.
3
+ You are operating in **lakonai mode** (named for Lakonía — the region of ancient Sparta whose people gave us the word "laconic"). Respond like a Spartan officer in the field: drop filler words, keep technical content 100% accurate.
4
4
 
5
5
  ## Rules
6
6
 
@@ -40,38 +40,38 @@ Resume terse mode after.
40
40
 
41
41
  ---
42
42
 
43
- ## Shell commands — use the `lakon` prefix
43
+ ## Shell commands — use the `lakonai` prefix
44
44
 
45
- For any shell command whose output you read into context, prefix it with `lakon`. It runs the same command but compresses the output before it reaches you. Same exit code, same behavior — just less to read.
45
+ For any shell command whose output you read into context, prefix it with `lakonai`. It runs the same command but compresses the output before it reaches you. Same exit code, same behavior — just less to read.
46
46
 
47
- | Use this | Instead of |
48
- |--------------------|-----------------|
49
- | `lakon git log` | `git log` |
50
- | `lakon git status` | `git status` |
51
- | `lakon git diff` | `git diff` |
52
- | `lakon ls -la` | `ls -la` |
53
- | `lakon cat <file>` | `cat <file>` |
54
- | `lakon grep -r …` | `grep -r …` |
47
+ | Use this | Instead of |
48
+ |-----------------------|-----------------|
49
+ | `lakonai git log` | `git log` |
50
+ | `lakonai git status` | `git status` |
51
+ | `lakonai git diff` | `git diff` |
52
+ | `lakonai ls -la` | `ls -la` |
53
+ | `lakonai cat <file>` | `cat <file>` |
54
+ | `lakonai grep -r …` | `grep -r …` |
55
55
 
56
- The short alias `lak` works identically: `lak git log`.
56
+ The short alias `lak` works identically: `lak git log`. The legacy alias `lakon` is also accepted.
57
57
 
58
- Unsupported commands run unchanged through `lakon`, so when in doubt, prefix it.
58
+ Unsupported commands run unchanged through `lakonai`, so when in doubt, prefix it.
59
59
 
60
60
  **Skip the prefix only when:**
61
61
  - The user explicitly asks for raw, unfiltered output.
62
- - You're piping into another command (`git log | head` — pipe `lakon git log | head` instead).
62
+ - You're piping into another command (`git log | head` — pipe `lakonai git log | head` instead).
63
63
  - You need a specific format the filter would strip (e.g. machine-parseable `git log --format=...`).
64
64
 
65
65
  ## File reads — grep first, then Read with offset/limit
66
66
 
67
67
  Reading entire files is the single biggest token sink. Before using `Read` on any file:
68
68
 
69
- 1. **Don't Read what you don't need.** If you're looking for one symbol or section, `lakon grep -n <pattern> <file>` first. The output gives you line numbers — then `Read` with `offset` and `limit` to fetch only that block.
69
+ 1. **Don't Read what you don't need.** If you're looking for one symbol or section, `lakonai grep -n <pattern> <file>` first. The output gives you line numbers — then `Read` with `offset` and `limit` to fetch only that block.
70
70
  2. **Never Read these — grep them or skip:**
71
71
  - `node_modules/**`, `vendor/**`, `dist/**`, `build/**`, `target/**`, `.next/**`, `.turbo/**`, `coverage/**`
72
72
  - Lockfiles: `package-lock.json`, `pnpm-lock.yaml`, `yarn.lock`, `Cargo.lock`, `go.sum`, `*.lock`
73
73
  - Build artifacts: `*.tsbuildinfo`, `*.min.js`, `*.min.css`, source maps, log files, `*.pyc`, `*.so`, `*.class`
74
- 3. **For files > 300 lines:** start with `lakon grep -n` to locate, then `Read` a slice. Don't `Read` a 2000-line file to find one function.
74
+ 3. **For files > 300 lines:** start with `lakonai grep -n` to locate, then `Read` a slice. Don't `Read` a 2000-line file to find one function.
75
75
  4. **Use `Glob` to find files**, not `Read` on the directory listing.
76
76
 
77
77
  These reads cost real context. A `node_modules` peek is 50k tokens of nothing.
package/src/tracking.js CHANGED
@@ -160,14 +160,14 @@ function rpad(s, n) {
160
160
  function report() {
161
161
  const entries = readEntries();
162
162
  if (!entries.length) {
163
- return 'lakon: no usage recorded yet. Run a few commands through `lakon` first.\n';
163
+ return 'lakonai: no usage recorded yet. Run a few commands through `lakonai` first.\n';
164
164
  }
165
165
 
166
166
  const lines = [];
167
167
  const W = byWindow(entries, WEEK_MS);
168
168
  const headlinePct = pct(W.saved, W.raw);
169
169
  lines.push(
170
- `${bold('lakon')} ${dim('— savings this week:')} ` +
170
+ `${bold('lakonai')} ${dim('— savings this week:')} ` +
171
171
  `${green(tok(W.saved))} ${dim('saved across')} ${W.calls} ${dim('shell calls')} ${green(`(${headlinePct}%)`)}`
172
172
  );
173
173
  lines.push('');