lonny-agent 0.1.8 → 0.2.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.
Files changed (68) hide show
  1. package/.kilo/plans/1780293725888-quick-wizard.md +62 -0
  2. package/.lonny/plan-web-cwd-status.md +38 -0
  3. package/dist/agent/compaction.d.ts +5 -0
  4. package/dist/agent/compaction.d.ts.map +1 -1
  5. package/dist/agent/compaction.js +5 -0
  6. package/dist/agent/compaction.js.map +1 -1
  7. package/dist/agent/prompt-builder.d.ts.map +1 -1
  8. package/dist/agent/prompt-builder.js +39 -4
  9. package/dist/agent/prompt-builder.js.map +1 -1
  10. package/dist/agent/providers/google.js +1 -1
  11. package/dist/agent/providers/google.js.map +1 -1
  12. package/dist/agent/providers/openai.js +1 -1
  13. package/dist/agent/providers/openai.js.map +1 -1
  14. package/dist/agent/session.d.ts.map +1 -1
  15. package/dist/agent/session.js +18 -2
  16. package/dist/agent/session.js.map +1 -1
  17. package/dist/config/__tests__/context-window.test.d.ts +2 -0
  18. package/dist/config/__tests__/context-window.test.d.ts.map +1 -0
  19. package/dist/config/__tests__/context-window.test.js +80 -0
  20. package/dist/config/__tests__/context-window.test.js.map +1 -0
  21. package/dist/config/index.d.ts +7 -0
  22. package/dist/config/index.d.ts.map +1 -1
  23. package/dist/config/index.js +211 -0
  24. package/dist/config/index.js.map +1 -1
  25. package/dist/pi-tui/tui.d.ts.map +1 -1
  26. package/dist/pi-tui/tui.js +7 -16
  27. package/dist/pi-tui/tui.js.map +1 -1
  28. package/dist/tools/__tests__/edit.test.js +139 -0
  29. package/dist/tools/__tests__/edit.test.js.map +1 -1
  30. package/dist/tools/__tests__/fetch.test.js +11 -9
  31. package/dist/tools/__tests__/fetch.test.js.map +1 -1
  32. package/dist/tools/edit.d.ts.map +1 -1
  33. package/dist/tools/edit.js +185 -32
  34. package/dist/tools/edit.js.map +1 -1
  35. package/dist/tools/install_superpowers.d.ts +3 -0
  36. package/dist/tools/install_superpowers.d.ts.map +1 -0
  37. package/dist/tools/install_superpowers.js +207 -0
  38. package/dist/tools/install_superpowers.js.map +1 -0
  39. package/dist/tui/index.d.ts.map +1 -1
  40. package/dist/tui/index.js +25 -1
  41. package/dist/tui/index.js.map +1 -1
  42. package/dist/web/index.d.ts.map +1 -1
  43. package/dist/web/index.js +56 -0
  44. package/dist/web/index.js.map +1 -1
  45. package/dist/web/public/app.js +8 -0
  46. package/dist/web/public/index.html +6 -0
  47. package/dist/web/public/style.css +11 -0
  48. package/m.role+' +0 -0
  49. package/package.json +1 -1
  50. package/src/agent/compaction.ts +6 -0
  51. package/src/agent/prompt-builder.ts +40 -4
  52. package/src/agent/providers/google.ts +1 -1
  53. package/src/agent/providers/openai.ts +1 -1
  54. package/src/agent/session.ts +19 -2
  55. package/src/config/__tests__/context-window.test.ts +94 -0
  56. package/src/config/index.ts +242 -0
  57. package/src/pi-tui/tui.ts +8 -14
  58. package/src/tools/__tests__/edit.test.ts +155 -0
  59. package/src/tools/__tests__/fetch.test.ts +12 -10
  60. package/src/tools/edit.ts +202 -33
  61. package/src/tools/registry.ts +265 -265
  62. package/src/tui/index.ts +23 -1
  63. package/src/web/index.ts +71 -0
  64. package/src/web/public/app.js +9 -0
  65. package/src/web/public/index.html +6 -0
  66. package/src/web/public/style.css +11 -0
  67. package/.lonny/fix-new-command-session-cleanup.md +0 -65
  68. package/.lonny/tui-autocomplete-above.md +0 -62
@@ -14,6 +14,7 @@
14
14
  const tokenCalls = document.getElementById('token-calls')
15
15
  const balanceDisplay = document.getElementById('balance-display')
16
16
  const balanceSep = document.getElementById('balance-sep')
17
+ const cwdDisplay = document.getElementById('cwd-display')
17
18
  const connectionOverlay = document.getElementById('connection-overlay')
18
19
  const chatContainer = document.getElementById('chat-container')
19
20
 
@@ -591,6 +592,12 @@
591
592
  balanceDisplay.style.display = 'none'
592
593
  balanceSep.style.display = 'none'
593
594
  }
595
+ // Show working directory
596
+ if (msg.cwd) {
597
+ const maxLen = 35
598
+ cwdDisplay.textContent =
599
+ msg.cwd.length > maxLen ? '...' + msg.cwd.slice(-maxLen) : msg.cwd
600
+ }
594
601
  break
595
602
 
596
603
  case 'chunk':
@@ -677,6 +684,8 @@
677
684
 
678
685
  case 'session_history':
679
686
  renderSessionHistory(msg.messages)
687
+ // Scroll to bottom after all messages are rendered
688
+ setTimeout(scrollToBottom, 50)
680
689
  break
681
690
 
682
691
  case 'plan_data':
@@ -16,6 +16,8 @@
16
16
  <span id="status-indicator" class="status-idle">○ idle</span>
17
17
  <span class="separator">|</span>
18
18
  <span id="mode-display" class="mode-badge">code</span>
19
+ <span class="separator">|</span>
20
+ <span id="cwd-display" class="cwd-text"></span>
19
21
  </div>
20
22
  <div class="status-right">
21
23
  <span id="model-display" class="model-name">loading...</span>
@@ -51,6 +53,10 @@
51
53
  <div class="slash-hint-item" data-cmd="mode code|plan|ask">/mode <span class="hint-arg">code|plan|ask</span> <span class="hint-desc">Switch mode</span></div>
52
54
  <div class="slash-hint-item" data-cmd="model ">/model <span class="hint-arg">&lt;name&gt;</span> <span class="hint-desc">Switch model</span></div>
53
55
  <div class="slash-hint-item" data-cmd="new">/new <span class="hint-desc">Start a new session</span></div>
56
+ <div class="slash-hint-item" data-cmd="stop">/stop <span class="hint-desc">Stop the running agent</span></div>
57
+ <div class="slash-hint-item" data-cmd="skills">/skills <span class="hint-desc">List active skills</span></div>
58
+ <div class="slash-hint-item" data-cmd="prompts">/prompts <span class="hint-desc">List prompt templates</span></div>
59
+ <div class="slash-hint-item" data-cmd="init">/init <span class="hint-desc">Create .lonny/skills/ &amp; prompts/</span></div>
54
60
  <div class="slash-hint-item" data-cmd="help">/help <span class="hint-desc">Show this help</span></div>
55
61
  </div>
56
62
  <textarea id="chat-input" rows="3" placeholder="Type a message... (type / for commands)"></textarea>
@@ -89,6 +89,17 @@ html, body {
89
89
  gap: 2px;
90
90
  }
91
91
 
92
+ .cwd-text {
93
+ color: var(--text-dim);
94
+ font-size: 12px;
95
+ max-width: 300px;
96
+ overflow: hidden;
97
+ text-overflow: ellipsis;
98
+ white-space: nowrap;
99
+ vertical-align: middle;
100
+ font-family: var(--font-mono);
101
+ }
102
+
92
103
  /* ── Chat Container ──────────────────────────────────────────── */
93
104
  #chat-container {
94
105
  flex: 1;
@@ -1,65 +0,0 @@
1
- # Plan: Fix /new Command Session Cleanup Issues
2
-
3
- ## Analysis
4
-
5
- Reviewing `src/tui/index.ts` lines 485-496, the `/new` command has two issues:
6
-
7
- ### Issue 1: No `session.stop()` when agent is running
8
-
9
- The slash command handler intentionally allows all commands even when `isRunning === true` (see comment on line 471: "Allow slash commands even when agent is running (critical for /stop)"). However, `/new` creates a **new** `Session` object while the **old** session's `session.chat()` promise may still be in-flight:
10
-
11
- - The old session continues consuming API tokens via its pending LLM stream
12
- - When the old `chat()` promise resolves, it writes to `chatContent` via the `output.write` closure — but `chatContent` was just cleared by `/new`, causing stale output to pollute the fresh chat display
13
- - The old promise's `.then()` callback sets `isRunning = false` and calls `updateFooter()` etc. (harmless but messy)
14
-
15
- ### Issue 2: Editor internal state not fully reset
16
-
17
- `editor.setText('')` (called at line 468 before the slash command handler) resets the text, cursor, and `scrollOffset`. But it does NOT clear:
18
-
19
- - `undoStack` — pressing Ctrl+Z after `/new` could restore old session content
20
- - `history` (command history for up/down navigation) — old commands linger
21
- - `killRing` (Emacs kill/yank ring) — old killed text is still accessible
22
-
23
- The Editor class declares these as `private` (see `editor.d.ts` lines 57-59, 64), so we need `(editor as any)` casts to access them at runtime.
24
-
25
- ## Fix
26
-
27
- Edit `src/tui/index.ts` lines 485-496, replacing the `/new` handler with:
28
-
29
- ```typescript
30
- if (cmd === 'new') {
31
- // If the agent is running, stop the old session gracefully first.
32
- // Without this, the pending chat() promise would continue consuming
33
- // tokens and write stale output into the freshly cleared chat display.
34
- if (isRunning) {
35
- session.stop()
36
- isRunning = false
37
- loader.setMessage('')
38
- tui.setShowHardwareCursor(true)
39
- }
40
- Session.clearSavedSession(config.cwd)
41
- resetTokenUsage(config.cwd)
42
- resetGlobalEventBus()
43
- session = new Session(config, output)
44
- session.onPlanWritten = planCb
45
- chatContent = ''
46
- chatMarkdown.setText('')
47
- plansList.clearFilter()
48
- // Reset editor internal state that setText('') doesn't clear
49
- ;(editor as any).undoStack.clear()
50
- ;(editor as any).history = []
51
- ;(editor as any).killRing = new (require('@earendil-works/pi-tui').KillRing)()
52
- updateFooter()
53
- return
54
- }
55
- ```
56
-
57
- > **Note about `KillRing` import**: The `KillRing` class is internal to pi-tui and not exported in the public types. Using `require('@earendil-works/pi-tui').KillRing` at runtime works because the package exports it internally. An alternative is to just set `(editor as any).killRing = { length: 0, ring: [], push: () => {}, peek: () => null, rotate: () => {} }` as a mock.
58
-
59
- > **Actual implementation**: Used `(editor as any).killRing.ring = []` instead of replacing the whole KillRing instance — simpler and avoids ESM `require` issues.
60
-
61
- ## Todo List
62
-
63
- - [x] Replace the `/new` command handler in `src/tui/index.ts` (around line 485) with the version above that calls `session.stop()` if running and resets editor internal state
64
- - [x] Run `npm run build` to verify compilation
65
- - [x] Test: start agent, let it run, type `/new`, verify no stale output appears and editor history/undo is clean
@@ -1,62 +0,0 @@
1
- # Plan: Adjust TUI Autocomplete to Render Above the Editor (Matching Web Style)
2
-
3
- ## Problem
4
-
5
- The TUI's slash command autocomplete list currently renders **below** the editor input area (after the bottom border). The web version displays command hints **above** the input (`bottom: 100%` via CSS). The user wants the TUI behavior to match the web — "向上的" (upward/above).
6
-
7
- ## Root Cause
8
-
9
- The `Editor` component from `@earendil-works/pi-tui` (`node_modules/@earendil-works/pi-tui/dist/components/editor.js`) appends the autocomplete `SelectList` lines **after** the editor's bottom border in its `render()` method (lines 418-426). To get the "above" behavior, these lines need to appear **before** the editor's top border instead.
10
-
11
- ## Approach (Final: patch-package + direct node_modules edit)
12
-
13
- Instead of monkey-patching at runtime (which had clipping issues with `maxHeight`), we:
14
-
15
- 1. **Directly edit** `node_modules/@earendil-works/pi-tui/dist/components/editor.js` to use `result.unshift(...acLines)` instead of `result.push(...)` — placing autocomplete BEFORE the top border
16
- 2. **Increase `maxHeight`** from 6 to 12 in `src/tui/index.ts` to accommodate both autocomplete and editor content
17
- 3. **Use `patch-package`** to persist the node_modules change across `npm install`
18
-
19
- This approach:
20
- - Renders autocomplete ABOVE the editor (matching web UI)
21
- - Eliminates the clipping bug (autocomplete no longer competes with editor content for the 6-line overlay)
22
- - Survives `npm install` via patch-package
23
-
24
- ## Files Changed
25
-
26
- ### 1. `node_modules/@earendil-works/pi-tui/dist/components/editor.js` (patched)
27
-
28
- Changed `result.push(...acLines)` to `result.unshift(...acLines)` so autocomplete renders BEFORE the top border.
29
-
30
- ### 2. `src/tui/index.ts`
31
-
32
- - Increased `maxHeight` from 6 to 12 on both editor overlay instances
33
- - Removed `applyEditorPatch()` import and call (old monkey-patch approach)
34
- - Deleted `src/tui/editor-patch.ts`
35
-
36
- ### 3. `package.json`
37
-
38
- - Added `"postinstall": "patch-package"` script
39
- - Added `patch-package` devDependency
40
-
41
- ### 4. `patches/@earendil-works+pi-tui+0.75.5.patch` (new)
42
-
43
- Created by `patch-package` to persist both changes:
44
- - `editor.js`: autocomplete unshifted to before top border
45
- - `tui.js`: alternate screen buffer handling
46
-
47
- ## Edge Cases Considered
48
-
49
- 1. **No autocomplete active** → `unshift` on empty array is a no-op; render output is unchanged
50
- 2. **Scrolled editor** → autocomplete still renders above the top border/indicator line
51
- 3. **Multiple autocomplete lines** → all moved above correctly
52
- 4. **Resize** → render is called again with new width, positioning stays correct
53
- 5. **npm install** → patch-package automatically reapplies the node_modules change
54
-
55
- ## Todo List
56
-
57
- - [x] Step 1: Edit `node_modules/@earendil-works/pi-tui/dist/components/editor.js` to use `unshift` instead of `push` for autocomplete lines
58
- - [x] Step 2: Increase `maxHeight` from 6 to 12 in `src/tui/index.ts`
59
- - [x] Step 3: Remove old monkey-patch (`editor-patch.ts`, `applyEditorPatch()` import/call)
60
- - [x] Step 4: Install `patch-package` and create patch file
61
- - [x] Step 5: Add `postinstall` script to `package.json`
62
- - [x] Step 6: Build and verify (`npm run build` succeeds)