lucid-train 0.1.0__tar.gz

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 (84) hide show
  1. lucid_train-0.1.0/.env.example +0 -0
  2. lucid_train-0.1.0/.github/workflows/release.yml +285 -0
  3. lucid_train-0.1.0/.gitignore +3 -0
  4. lucid_train-0.1.0/.lucid/CHANGELOG.md +6 -0
  5. lucid_train-0.1.0/.lucid/knowledge.md +31 -0
  6. lucid_train-0.1.0/CHANGELOG.md +46 -0
  7. lucid_train-0.1.0/Cargo.lock +2451 -0
  8. lucid_train-0.1.0/Cargo.toml +51 -0
  9. lucid_train-0.1.0/Makefile +91 -0
  10. lucid_train-0.1.0/PKG-INFO +211 -0
  11. lucid_train-0.1.0/PUBLISHING.md +102 -0
  12. lucid_train-0.1.0/README.md +194 -0
  13. lucid_train-0.1.0/backend/.env.example +7 -0
  14. lucid_train-0.1.0/backend/.gitignore +3 -0
  15. lucid_train-0.1.0/backend/README.md +56 -0
  16. lucid_train-0.1.0/backend/go.mod +25 -0
  17. lucid_train-0.1.0/backend/go.sum +53 -0
  18. lucid_train-0.1.0/backend/main.go +160 -0
  19. lucid_train-0.1.0/backend/main_test.go +111 -0
  20. lucid_train-0.1.0/backend/proxy.go +136 -0
  21. lucid_train-0.1.0/backend/run.sh +9 -0
  22. lucid_train-0.1.0/backend/store.go +86 -0
  23. lucid_train-0.1.0/backend/stripe.go +182 -0
  24. lucid_train-0.1.0/bench/RESULTS.md +32 -0
  25. lucid_train-0.1.0/bench/run.sh +73 -0
  26. lucid_train-0.1.0/landing/.gitignore +7 -0
  27. lucid_train-0.1.0/landing/README.md +36 -0
  28. lucid_train-0.1.0/landing/next.config.ts +11 -0
  29. lucid_train-0.1.0/landing/package-lock.json +2053 -0
  30. lucid_train-0.1.0/landing/package.json +28 -0
  31. lucid_train-0.1.0/landing/postcss.config.mjs +7 -0
  32. lucid_train-0.1.0/landing/public/install.sh +123 -0
  33. lucid_train-0.1.0/landing/src/app/docs/commands/page.tsx +90 -0
  34. lucid_train-0.1.0/landing/src/app/docs/configuration/page.tsx +95 -0
  35. lucid_train-0.1.0/landing/src/app/docs/install/page.tsx +74 -0
  36. lucid_train-0.1.0/landing/src/app/docs/layout.tsx +16 -0
  37. lucid_train-0.1.0/landing/src/app/docs/models/page.tsx +104 -0
  38. lucid_train-0.1.0/landing/src/app/docs/page.tsx +71 -0
  39. lucid_train-0.1.0/landing/src/app/globals.css +277 -0
  40. lucid_train-0.1.0/landing/src/app/layout.tsx +67 -0
  41. lucid_train-0.1.0/landing/src/app/not-found.tsx +17 -0
  42. lucid_train-0.1.0/landing/src/app/page.tsx +166 -0
  43. lucid_train-0.1.0/landing/src/app/privacy/page.tsx +78 -0
  44. lucid_train-0.1.0/landing/src/app/terms/page.tsx +87 -0
  45. lucid_train-0.1.0/landing/src/components/CodeBlock.tsx +37 -0
  46. lucid_train-0.1.0/landing/src/components/CopyButton.tsx +24 -0
  47. lucid_train-0.1.0/landing/src/components/DocsSidebar.tsx +57 -0
  48. lucid_train-0.1.0/landing/src/components/DreamTrain.tsx +322 -0
  49. lucid_train-0.1.0/landing/src/components/Footer.tsx +64 -0
  50. lucid_train-0.1.0/landing/src/components/Nav.tsx +22 -0
  51. lucid_train-0.1.0/landing/src/components/NebulaBackdrop.tsx +114 -0
  52. lucid_train-0.1.0/landing/src/components/OsTabs.tsx +49 -0
  53. lucid_train-0.1.0/landing/src/components/Reveal.tsx +23 -0
  54. lucid_train-0.1.0/landing/src/components/TemplateBanner.tsx +14 -0
  55. lucid_train-0.1.0/landing/src/components/icons.tsx +63 -0
  56. lucid_train-0.1.0/landing/src/lib/site.ts +5 -0
  57. lucid_train-0.1.0/landing/tailwind.config.ts +79 -0
  58. lucid_train-0.1.0/landing/tsconfig.json +41 -0
  59. lucid_train-0.1.0/landing/vercel.json +6 -0
  60. lucid_train-0.1.0/pyproject.toml +39 -0
  61. lucid_train-0.1.0/src/agent.rs +888 -0
  62. lucid_train-0.1.0/src/config.rs +590 -0
  63. lucid_train-0.1.0/src/exec.rs +201 -0
  64. lucid_train-0.1.0/src/guard.rs +230 -0
  65. lucid_train-0.1.0/src/hardware.rs +276 -0
  66. lucid_train-0.1.0/src/llm.rs +424 -0
  67. lucid_train-0.1.0/src/main.rs +145 -0
  68. lucid_train-0.1.0/src/mcp.rs +278 -0
  69. lucid_train-0.1.0/src/middleware.rs +232 -0
  70. lucid_train-0.1.0/src/prompt.rs +135 -0
  71. lucid_train-0.1.0/src/repomap.rs +256 -0
  72. lucid_train-0.1.0/src/security.rs +118 -0
  73. lucid_train-0.1.0/src/skills.rs +142 -0
  74. lucid_train-0.1.0/src/toolparse.rs +215 -0
  75. lucid_train-0.1.0/src/tools/background.rs +186 -0
  76. lucid_train-0.1.0/src/tools/edit.rs +200 -0
  77. lucid_train-0.1.0/src/tools/mod.rs +156 -0
  78. lucid_train-0.1.0/src/tools/read.rs +260 -0
  79. lucid_train-0.1.0/src/tools/shell.rs +220 -0
  80. lucid_train-0.1.0/src/tools/web.rs +354 -0
  81. lucid_train-0.1.0/src/tui/mod.rs +2208 -0
  82. lucid_train-0.1.0/src/tui/render.rs +1390 -0
  83. lucid_train-0.1.0/src/update.rs +78 -0
  84. lucid_train-0.1.0/tests/e2e.rs +259 -0
File without changes
@@ -0,0 +1,285 @@
1
+ name: release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ # Required permissions:
9
+ # contents: write -> create GitHub Release and upload assets
10
+ # id-token: write -> PyPI Trusted Publishing
11
+ permissions:
12
+ contents: write
13
+ id-token: write
14
+
15
+ env:
16
+ CARGO_TERM_COLOR: always
17
+ REGISTRY: ghcr.io
18
+
19
+ jobs:
20
+ # ─────────────────────────────────────────────────────────────────────────
21
+ # 1. Build release binaries and attach them to a GitHub Release.
22
+ # This runs on every tag and produces per-platform archives.
23
+ # ─────────────────────────────────────────────────────────────────────────
24
+ build-binaries:
25
+ name: build binaries (${{ matrix.name }})
26
+ runs-on: ${{ matrix.os }}
27
+ strategy:
28
+ fail-fast: false
29
+ matrix:
30
+ include:
31
+ - name: macos-arm64
32
+ os: macos-latest
33
+ target: aarch64-apple-darwin
34
+ - name: macos-x86_64
35
+ os: macos-13
36
+ target: x86_64-apple-darwin
37
+ - name: linux-x86_64
38
+ os: ubuntu-latest
39
+ target: x86_64-unknown-linux-gnu
40
+ - name: linux-aarch64
41
+ os: ubuntu-latest
42
+ target: aarch64-unknown-linux-gnu
43
+ - name: windows-x86_64
44
+ os: windows-latest
45
+ target: x86_64-pc-windows-msvc
46
+
47
+ steps:
48
+ - name: Checkout repository
49
+ uses: actions/checkout@v4
50
+
51
+ - name: Install Rust toolchain
52
+ uses: dtolnay/rust-toolchain@stable
53
+ with:
54
+ targets: ${{ matrix.target }}
55
+
56
+ - name: Cache Cargo registry
57
+ uses: Swatinem/rust-cache@v2
58
+ with:
59
+ key: ${{ matrix.target }}
60
+
61
+ - name: Install cross-compilation tools (Linux aarch64)
62
+ if: matrix.target == 'aarch64-unknown-linux-gnu'
63
+ run: |
64
+ sudo apt-get update
65
+ sudo apt-get install -y gcc-aarch64-linux-gnu
66
+ mkdir -p ~/.cargo
67
+ cat >> ~/.cargo/config.toml <<'EOF'
68
+ [target.aarch64-unknown-linux-gnu]
69
+ linker = "aarch64-linux-gnu-gcc"
70
+ EOF
71
+
72
+ - name: Build release binary
73
+ run: cargo build --release --target ${{ matrix.target }}
74
+
75
+ - name: Package binary
76
+ id: package
77
+ shell: bash
78
+ run: |
79
+ VERSION=${GITHUB_REF_NAME#v}
80
+ NAME="lucid-train-v${VERSION}-${{ matrix.target }}"
81
+ mkdir -p dist
82
+
83
+ if [[ "${{ matrix.target }}" == *windows* ]]; then
84
+ BIN="target/${{ matrix.target }}/release/lucid-train.exe"
85
+ ASSET="dist/${NAME}.zip"
86
+ 7z a "${ASSET}" "${BIN}"
87
+ else
88
+ BIN="target/${{ matrix.target }}/release/lucid-train"
89
+ ASSET="dist/${NAME}.tar.gz"
90
+ tar -czf "${ASSET}" -C "target/${{ matrix.target }}/release" "lucid-train"
91
+ fi
92
+
93
+ echo "asset=${ASSET}" >> "$GITHUB_OUTPUT"
94
+ echo "asset_name=$(basename "${ASSET}")" >> "$GITHUB_OUTPUT"
95
+
96
+ echo "checksum:"
97
+ if command -v sha256sum >/dev/null 2>&1; then
98
+ sha256sum "${ASSET}"
99
+ else
100
+ shasum -a 256 "${ASSET}"
101
+ fi
102
+
103
+ - name: Upload binary archive to GitHub Release
104
+ uses: softprops/action-gh-release@v2
105
+ with:
106
+ draft: true
107
+ files: ${{ steps.package.outputs.asset }}
108
+ env:
109
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
110
+
111
+ - name: Upload build artifact for attestation
112
+ uses: actions/upload-artifact@v4
113
+ with:
114
+ name: binaries-${{ matrix.name }}
115
+ path: dist/*
116
+
117
+ # ─────────────────────────────────────────────────────────────────────────
118
+ # 2. Build a stable source tarball and publish the GitHub Release.
119
+ # Homebrew should point at this tarball (or the release asset) so its
120
+ # SHA256 does not change when Homebrew re-generates the auto archive.
121
+ # ─────────────────────────────────────────────────────────────────────────
122
+ publish-release:
123
+ name: publish GitHub Release
124
+ needs: build-binaries
125
+ runs-on: ubuntu-latest
126
+ outputs:
127
+ source_sha256: ${{ steps.source.outputs.sha256 }}
128
+ version: ${{ steps.source.outputs.version }}
129
+ steps:
130
+ - name: Checkout repository
131
+ uses: actions/checkout@v4
132
+
133
+ - name: Build stable source tarball
134
+ id: source
135
+ run: |
136
+ VERSION="${GITHUB_REF_NAME#v}"
137
+ mkdir -p dist
138
+ git archive --format=tar.gz --prefix="lucid-train-${VERSION}/" "${GITHUB_REF_NAME}" \
139
+ > "dist/lucid-train-${VERSION}.tar.gz"
140
+ echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
141
+ echo "sha256=$(sha256sum dist/lucid-train-${VERSION}.tar.gz | awk '{print $1}')" >> "$GITHUB_OUTPUT"
142
+
143
+ - name: Publish GitHub Release
144
+ uses: softprops/action-gh-release@v2
145
+ with:
146
+ draft: false
147
+ files: dist/*.tar.gz
148
+ generate_release_notes: true
149
+ env:
150
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
151
+
152
+ # ─────────────────────────────────────────────────────────────────────────
153
+ # 3. Build PyPI wheels per platform.
154
+ # ─────────────────────────────────────────────────────────────────────────
155
+ build-wheels:
156
+ name: build wheel (${{ matrix.name }})
157
+ runs-on: ${{ matrix.os }}
158
+ strategy:
159
+ fail-fast: false
160
+ matrix:
161
+ include:
162
+ - name: macos-arm64
163
+ os: macos-latest
164
+ target: aarch64-apple-darwin
165
+ - name: macos-x86_64
166
+ os: macos-13
167
+ target: x86_64-apple-darwin
168
+ - name: linux-x86_64
169
+ os: ubuntu-latest
170
+ target: x86_64-unknown-linux-gnu
171
+ - name: linux-aarch64
172
+ os: ubuntu-latest
173
+ target: aarch64-unknown-linux-gnu
174
+ - name: windows-x86_64
175
+ os: windows-latest
176
+ target: x86_64-pc-windows-msvc
177
+
178
+ steps:
179
+ - uses: actions/checkout@v4
180
+ - uses: dtolnay/rust-toolchain@stable
181
+ with:
182
+ targets: ${{ matrix.target }}
183
+
184
+ - name: Install maturin
185
+ run: pip install maturin
186
+
187
+ - name: Build wheel
188
+ shell: bash
189
+ run: |
190
+ if [[ "${{ matrix.target }}" == *windows* ]]; then
191
+ maturin build --release --out dist
192
+ else
193
+ maturin build --release --target ${{ matrix.target }} --out dist
194
+ fi
195
+
196
+ - uses: actions/upload-artifact@v4
197
+ with:
198
+ name: wheels-${{ matrix.name }}
199
+ path: dist/*.whl
200
+
201
+ # ─────────────────────────────────────────────────────────────────────────
202
+ # 4. Publish all wheels to PyPI.
203
+ # ─────────────────────────────────────────────────────────────────────────
204
+ publish-pypi:
205
+ name: publish to PyPI
206
+ needs: build-wheels
207
+ runs-on: ubuntu-latest
208
+ environment:
209
+ name: release
210
+ url: https://pypi.org/p/lucid-train
211
+ permissions:
212
+ id-token: write
213
+ contents: read
214
+ steps:
215
+ - uses: actions/download-artifact@v4
216
+ with:
217
+ pattern: wheels-*
218
+ path: dist
219
+ merge-multiple: true
220
+
221
+ - name: Publish wheels to PyPI
222
+ uses: pypa/gh-action-pypi-publish@release/v1
223
+ with:
224
+ packages-dir: dist
225
+ # Use the API token stored in GitHub Secrets. Set PYPI_API_TOKEN at
226
+ # https://pypi.org/manage/project/lucid-train/settings/publishing/
227
+ # (or globally at pypi.org/manage/account/token/) and add it as a
228
+ # repository secret in GitHub. This bypasses OIDC trusted publishing
229
+ # so it works even if the PyPI-side OIDC configuration is missing.
230
+ password: ${{ secrets.PYPI_API_TOKEN }}
231
+
232
+ # ─────────────────────────────────────────────────────────────────────────
233
+ # 5. Publish source build to crates.io.
234
+ # continue-on-error: owner must provision CARGO_REGISTRY_TOKEN first.
235
+ # ─────────────────────────────────────────────────────────────────────────
236
+ publish-crates:
237
+ name: publish to crates.io
238
+ needs: publish-release
239
+ runs-on: ubuntu-latest
240
+ continue-on-error: true
241
+ steps:
242
+ - uses: actions/checkout@v4
243
+ - uses: dtolnay/rust-toolchain@stable
244
+ - run: cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }}
245
+ env:
246
+ CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
247
+
248
+ # ─────────────────────────────────────────────────────────────────────────
249
+ # 6. Open a PR in the Homebrew tap so `brew pr-pull` can bottle it.
250
+ # This follows the documented flow:
251
+ # https://brew.sh/2020/11/18/homebrew-tap-with-bottles-uploaded-to-github-releases/
252
+ # After the PR is green, label it `pr-pull` to build and upload bottles.
253
+ # continue-on-error: owner must provision the HOMEBREW_TAP_TOKEN first.
254
+ # ─────────────────────────────────────────────────────────────────────────
255
+ update-homebrew-tap:
256
+ name: update homebrew tap
257
+ needs: publish-release
258
+ runs-on: macos-latest
259
+ continue-on-error: true
260
+ permissions:
261
+ contents: read
262
+ steps:
263
+ - name: Set up Homebrew
264
+ id: set-up-homebrew
265
+ uses: Homebrew/actions/setup-homebrew@master
266
+
267
+ - name: Configure git
268
+ run: |
269
+ git config --global user.name "github-actions[bot]"
270
+ git config --global user.email "github-actions[bot]@users.noreply.github.com"
271
+
272
+ - name: Configure tap
273
+ run: brew tap ${{ github.repository_owner }}/lucid-train
274
+
275
+ - name: Bump formula PR
276
+ env:
277
+ HOMEBREW_GITHUB_API_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
278
+ VERSION: ${{ needs.publish-release.outputs.version }}
279
+ run: |
280
+ brew bump-formula-pr \
281
+ --no-browse \
282
+ --strict \
283
+ --tag "v${VERSION}" \
284
+ --revision "${GITHUB_SHA}" \
285
+ "${{ github.repository_owner }}/lucid-train/lucid-train"
@@ -0,0 +1,3 @@
1
+ /target
2
+ *.whl
3
+ __pycache__/
@@ -0,0 +1,6 @@
1
+ # Changelog
2
+
3
+ ## 2026-06-14
4
+
5
+ - Fixed TUI paste behavior so long error messages no longer trigger repeated/accidental submissions. Paste events are coalesced when they arrive in rapid bursts, trailing newlines are stripped, and internal line breaks are normalized to spaces.
6
+ - Fixed PyPI publish workflow by supplying `password: ${{ secrets.PYPI_API_TOKEN }}` to `pypa/gh-action-pypi-publish`, bypassing the OIDC trusted-publishing path that was failing with "403 Invalid or non-existent authentication information."
@@ -0,0 +1,31 @@
1
+ # Lucid Train — project knowledge
2
+
3
+ - 2026-06-12: AHE evolved-harness core lives in prompt.rs (8 working rules), middleware.rs, guard.rs — do not weaken when adding features.
4
+ - 2026-06-12: macOS binary installs MUST `rm` before `cp` then `codesign -s - -f`, or the kernel kills the binary (Code Signature Invalid → SIGKILL 137).
5
+ - 2026-06-12: Ollama needs OLLAMA_CONTEXT_LENGTH=16384 for the harness — default 4096 truncates the system prompt + tool schemas.
6
+ - 2026-06-12: DuckDuckGo bot-challenges (HTTP 202) datacenter-ish traffic; Mojeek is the reliable keyless fallback; SERPER_API_KEY upgrades to Google.
7
+ - 2026-06-12: ERNIE/Qwen text-format tool calls handled by toolparse.rs (ernie_x1 `<tool_call>{json}` + qwen `<function=` XML).
8
+ - 2026-06-12: skills.sh installs target `-a claude-code -g` so they land in ~/.claude/skills, which skills.rs discovers.
9
+ - 2026-06-13: Ollama memory tuning (spawn_ollama_serve in tui/mod.rs): OLLAMA_FLASH_ATTENTION=1, KV_CACHE_TYPE=q8_0 (halves KV memory), MAX_LOADED_MODELS=1, NUM_PARALLEL=1, KEEP_ALIVE=4m (unloads model after idle → RAM returns to other apps).
10
+ - 2026-06-13: TUI theme = frontend globals.css palette (accent #1a8fe3, secondary #6366f1, success #16a34a, error #dc2626, amber #d4a044) as ratatui Rgb consts in render.rs.
11
+ - 2026-06-13: Modes: /agent /plan /research (config::Mode) — plan strips all tools, research keeps web_search/read_url/update_plan; mode shown in status bar. Esc = interrupt (running) / clear+arm (idle); double-Esc within 1.5s quits.
12
+ - 2026-06-13: frontend/src/app/terminal/page.tsx = terminal landing page; frontend/public/install.sh = curl installer (cargo build from GitHub).
13
+ - 2026-06-13: Intro splash (draw_intro in render.rs): ASCII train rides rails L→R over ~56 ticks with rainbow smoke (RAINBOW palette) + shimmering title; any key skips (typed char carries into input). ApprovalKind enum {Tool, FullAuto, ImplementPlan} — plan-mode TurnComplete triggers ImplementPlan modal → y switches to agent mode + auto-submits "implement the plan". /copy [last|output|all] via pbcopy/wl-copy/xclip/clip.
14
+ - 2026-06-13: Intro v2 = deterministic particle scene (render.rs draw_intro): every star/smoke/dust particle is a pure function of tick clock (no state) rendered via f.buffer_mut() cell writes. Layers: parallax 3-depth starfield, ease-out train arrival (exp decay, settles center), ◴◷◶◵ wheel rotation, smoke emitted every 2 ticks living 26 (rainbow→grey lerp, sin sway), dust streaks while speed>0.15 blown backwards, scrolling ╪ sleepers, title shimmer after tick 34. INTRO_LIFE=115 (~9s), any key skips. PTY testing gotcha: script(1) with stdin=/dev/null hangs up instantly AND pty defaults to 0x0 — use `{ sleep N; printf q; } | script -q f sh -c 'stty rows 30 cols 100; cmd'`.
15
+ - 2026-06-13: Intro v3 "agent boot": typewriter boot log (BOOT const: core/tools/context/skills/models/engine, staggered start ticks, 3 chars/tick, spinner→✓, last line pulses rainbow ◉) + shimmering ">_ lucid-train" prompt title + "ready — departing now" at tick 62; train scene moved to bottom rails (h-4); stars confined to gap band. PTY verify gotcha: ratatui diffs mean fully-typed lines never re-emit as whole strings — grep for per-frame fragments instead.
16
+ - 2026-06-13: Lucid session animations (render.rs): rb(tick) = rainbow color helper; working line = drifting rainbow smoke puffs + mini ▟█▛ loco with rotating wheel + DREAM_VERBS rotating every 40 ticks ("full steam ahead", "laying tracks", "dreaming in code"…) + animated dots; thinking header = "✦ dreaming" with per-letter rainbow shimmer + ▏gutter on stream lines, collapsed = "✦ dreamt (N words)"; running exec/download bullets = pulsing rainbow ◉; plan in_progress arrow pulses; input border dream-indigo while running.
17
+ - 2026-06-13: Theme unified to single indigo family (user found rainbow cycling "triggering"): pulse(tick) = 2-step indigo breathing (#6366f1↔#818cf8, 8-tick period); DREAM_TERMS = ~102 status terms (lucid dream/galaxy/quantum/meditation/DNA-biotech/gen-z, first letter capitalized) chosen ONCE per step via dream_term(seed) — working line seeds by turn count, Reasoning cells carry a seed field; constellation() = static 4-star indigo prefix (✦ ⋆ ✧ ∘) for the dreaming header. rainbow_rgb/rb removed entirely; intro smoke = indigo→grey lerp, intro title/boot ◉ = azure/pulse.
18
+ - 2026-06-13: Lucid Cloud + monetization DISABLED for now (reversible): backend marginBP=0 (proxy.go, was 500), gstBP=0 (stripe.go, was 1800) → top-ups 1:1; tests + READMEs updated. CLI hides /login,/logout,/credits (removed from COMMANDS/help/setup/autocomplete; slash arms emit "Lucid Cloud is disabled for now"; spawn_login/spawn_credits kept with #[allow(dead_code)]); switch_model + RAM-too-big + ollama-unavailable messages only suggest /apikey now; /provider rejects "lucid". Provider::LucidCloud enum + CLOUD_MODELS catalog KEPT (cloud models still work via OpenRouter /apikey).
19
+ - 2026-06-13: Copy/links/local-models fixes. Mouse capture now OFF by default (run_tui: EnableMouseCapture removed from startup) so native terminal select/copy + Cmd-click links work; App.mouse_capture flag + /mouse toggle re-enables scroll-wheel (main loop diffs flag → execute! Enable/DisableMouseCapture). render.rs linkify_into() styles http(s) URLs underlined+ACCENT (terminals make them clickable when mouse off); wrap() uses break_words(false) so URLs stay intact. RAM gating softened: /download + switch_model now WARN (not block) when model > budget RAM — capable machines run big local models. Relabeled all user-facing "cloud" → "OpenRouter (your key)" / "bring your own OpenRouter key"; CLOUD_MODELS/find_cloud identifiers kept. Note: Kimi K2 (1T) / DeepSeek V3 (671B) have no consumer Ollama tag so remain OpenRouter-only; qwen3-coder:30b etc. are the runnable big locals.
20
+ - 2026-06-14: Code-edit display + multi-format read + vision. tools/edit.rs: write_file/edit_file compute line_diff (prefix/suffix trim, CONTEXT=3, trailing-newline-aware split_lines) → AgentEvent::FileEdit → Cell::Diff renders "● Update(path)" + "└ Added N lines, removed M" + gutter line numbers, green +/red -/dim context (exec.rs prints same). tools/read.rs: read_file parses text/code/json/csv/md direct, PDF via pdftotext, docx/pptx via unzip+strip_xml, xlsx→skill hint, images→dims via png/gif/jpeg header parse; image_data_url() = no-crate base64 → data URL. llm.rs ChatMessage.images Vec<String> → multimodal content array (image_url). /attach <path> adds to App.attachments → WorkerCmd::UserMessageImages → run_turn_with_images (vision models only). Prompt steers models to write_file/edit_file over shell redirection. VERIFIED live with kimi-k2.5 via OpenRouter: read_file→edit_file diff rendered correctly, file changed on disk; CSV read worked.
21
+ - 2026-06-14: 404 recovery + inline input. llm.rs LlmError::ModelNotFound/Unauthorized (is_model_not_found: 404/not_found_error/no endpoints/not a valid model; is_unauthorized: 401/403/invalid api key) returned immediately (no retry/failover). agent emits AgentEvent::ModelUnavailable{model,needs_key} + pop_pending_user() so retry doesn't double the user msg. TUI: PendingInput{label,hint,masked,action:InputAction::ApiKey{model}} → composer becomes masked prompt (WARNING border, • bullets, Esc cancels); finish_input saves via save_config_values (MERGES, never clobbers — verified max_iterations=42 preserved) then switch_model. ModelUnavailable handler: recommended_local(hw) → suggest /download if RAM fits, else warn can't run locally; if needs_key opens masked key prompt that retries the model on save. /apikey with no arg also opens the prompt. Configs in ~/.lucid-train/config.toml survive reinstalls (cp binary never touches it). VERIFIED: plaintext key never rendered (0 occurrences in capture), bullets shown, exit 1 on 404 in exec. NOTE: moonshotai/kimi-k2.5 actually works on OpenRouter now (earlier 404 was transient).
22
+ - 2026-06-14: Publishing + in-app updater. Wheel via maturin (pyproject.toml bindings="bin") → `pip install lucid-train` ships the Rust binary (ruff/uv pattern); VERIFIED builds + installs + runs in a venv. .github/workflows/release.yml = cross-platform wheel matrix → PyPI trusted publishing on tag. PUBLISHING.md covers PyPI/crates.io/Homebrew/GitHub Releases. update.rs: latest_version() hits PyPI JSON (LUCID_UPDATE_URL override, LUCID_NO_UPDATE_CHECK to disable), is_newer() semver compare, update_command() guesses pip/pipx/cargo/brew from exe path. TUI: background check on startup → ApprovalKind::Update modal [y]update/[n]skip; y runs spawn_update, n persists skipped_version (config save_config_values now type-infers bool/int). /update re-checks, /update on|off toggles (config update_check). VERIFIED live: modal shows for higher version, offline = silent no-crash, skip persists skipped_version=9.9.9. Bump Cargo.toml version each release → older installs auto-prompt.
23
+ - 2026-06-14: Landing site = standalone Next.js 16 (App Router) + Tailwind v4 app at terminal-agent/landing/ (NOT in frontend/, which is the IDE app). Deploys as its own Vercel project (Root Directory = terminal-agent/landing). Design ported from frontend home: tokens copied into landing/src/app/globals.css + landing/tailwind.config.ts, with explicit `@config "../../tailwind.config.ts"` in globals.css (critical — without it v4 emits no token utilities). next/font for Inter+JetBrains Mono. Routes: / (landing, all features), /docs + /docs/{install,configuration,commands,models} (sidebar via DocsSidebar usePathname), /terms /privacy (template placeholders [ENTITY]/[CONTACT_EMAIL]/[JURISDICTION]/[EFFECTIVE_DATE] + TemplateBanner), public/install.sh (curl|sh). ESLint removed (eslint-config-next + ESLint 9 FlatCompat crashes "circular structure"); use `npm run typecheck` (tsc) — build runs TS anyway. turbopack.root set in next.config.ts (monorepo has multiple lockfiles). Verified: npm run build = 10 static routes, all routes 200, /install.sh served, tsc clean.
24
+ - 2026-06-14: Publish-to-all: .github/workflows/release.yml (repo root) on tag v* → jobs wheels→PyPI (trusted publishing), crates (cargo publish, needs CARGO_REGISTRY_TOKEN, continue-on-error), binaries (5-target matrix tar.gz/zip) → release (softprops/action-gh-release), homebrew (mislav/bump-homebrew-formula, needs HOMEBREW_TAP_TOKEN + Arnab28122000/homebrew-lucid-train repo, continue-on-error), winget (vedantmgoyal2009/winget-releaser, needs WINGET_TOKEN, continue-on-error). Cargo.toml got [package.metadata.binstall] for cargo binstall + repo/homepage/keywords/categories. Secrets matrix documented in PUBLISHING.md. YAML validated (7 jobs).
25
+ - 2026-06-14: Blank-scroll bug FIX = mouse capture back ON by default (mouse_capture: true). With it off (prev), the wheel scrolled the empty alternate screen → blank; the screenshot had no TUI chrome confirming it was alt-screen scrollback. Wheel now scrolls the chat (MouseEventKind::ScrollUp/Down → scroll_from_bottom). Copy via /copy, Shift+drag, or /mouse off. Perf: render loop now only runs the 80ms animation tick when app.running||intro (tokio::select! `_ = tick.tick(), if animating`), so idle no longer rebuilds the whole history pane 12×/s.
26
+ - 2026-06-14: Legal pages filled — LUCIDTRAIN PRIVATE LIMITED, arnab@lucidtrain.com, Bengaluru Karnataka India, 2026 (landing/src/app/{terms,privacy}/page.tsx). TemplateBanner softened to a "not legal advice" note. Landing hero unsloppified per research (concrete outcomes + proof strip: single ~6MB binary / 100% offline / 15+ models one key / MIT) — headline "Ship code from the command line."
27
+ - 2026-06-15: Config-wipe bug FIXED. Root cause: load_file_config did all-or-nothing toml::from_str::<FileConfig> → one unknown/mistyped field silently reset whole config (api_key lost on every restart). Fix: parse_file_config(content) pulls each field individually from a toml::Table (lenient); save_config_values backs up (.toml.bak) instead of clobbering a non-empty unparseable file. 3 unit tests + e2e (api_key loads despite junk + bad-typed fields). FileConfig still derives Deserialize but it's no longer used for loading.
28
+ - 2026-06-15: Model catalogue refreshed (verified on OpenRouter): default + ★ Lucid's choice = moonshotai/kimi-k2.7-code ($0.75/$3.50, 262K, coding specialist). Added deepseek/deepseek-v4-pro ($0.44/$0.87, 1M, 80.6% SWE-bench — cheapest near-frontier), qwen/qwen3.7-max (1M), kimi-k2.7/k2.6, glm→z-ai/glm-5.1, minimax→minimax-m2.7. CloudModel got `recommended: bool` + recommended_cloud(); Config::default model = kimi-k2.7-code. MODEL_PRESETS (config.rs) + CLOUD_MODELS (hardware.rs) kept in sync. render_setup shows "★ Lucid's choice". Live-verified default + deepseek-v4-pro respond.
29
+ - 2026-06-15: Landing theme → terminal-forward (user choice). globals.css: removed .floating-orb*, added .tui-frame (box-drawn, data-title corner label), .scanlines (subtle CRT overlay), .prompt::before (">_ "), .mono-label, .ascii-rule; .card-dreamy reworked from glass-blur to terminal-window border. page.tsx eyebrows now mono-label+prompt, orbs gone, scanlines on hero+CTA. DocsSidebar ▹ active marker. docs/models has price/context table + Lucid's-choice/cheapest callouts. Build = 10 static routes, verified orbs gone + scanlines/mono present.
30
+ - 2026-06-15: Landing TUI redesign v2 (prior passes "looked the same" — kept sans body + SaaS cards). Now genuine monospace-web: body→JetBrains Mono globally (15px/1.6) in landing/src/app/globals.css; .tui-col (82ch) / .tui-col-wide (110ch) character columns replace max-w-7xl/3xl everywhere; Pane.tsx component = square box-drawing pane (┌┐└┘ corner glyphs + .tui-title chip on top border); .tui-list with ▸ markers; rainbow .gradient-text → single azure; .terminal + buttons squared (radius 0/2px). page.tsx rewritten: hero = one Pane terminal window ($ pip install + ▸ taglines + proof), features as titled ▸-list panes (the harness/models/tools/tui/security), modes panes, ASCII ─ rules between, scanlines on hero+CTA. Nav/Footer/docs/terms/privacy use tui-col(-wide). Research basis: owickstrom monospace-web (mono everywhere + ch-grid + box-drawing + one accent). Verified: build 10 routes, tsc clean, box chars/▸/tui-col present, rainbow gone, body mono in chunk CSS.
31
+ - 2026-06-15: Install URL → https://lucidtrain.com (user typo "lucidtrain..com"). site.ts SITE_URL, landing/public/install.sh comment, layout.tsx metadataBase, PUBLISHING.md, frontend/src/app/terminal/page.tsx all updated from lucid-train.vercel.app. CURL_CMD derives from SITE_URL.
@@ -0,0 +1,46 @@
1
+ # Changelog
2
+
3
+ All notable changes to Lucid Train. The agent also maintains per-project
4
+ memory in `.lucid/knowledge.md` and `.lucid/CHANGELOG.md` inside repos it
5
+ works on.
6
+
7
+ ## 0.1.0 — 2026-06-12
8
+
9
+ ### Harness (AHE core — kept intact throughout)
10
+ - Ported the evolved harness from Agentic Harness Engineering: single
11
+ `run_shell_command` tool + background tasks, evolved system prompt,
12
+ execution risk hints, publish-state guard, 75% context compaction,
13
+ round/token reminders.
14
+
15
+ ### Codex parity
16
+ - `update_plan` checklist tool with live TUI rendering.
17
+ - `web_search` + `read_url` (keyless DuckDuckGo → Mojeek chain, Serper
18
+ optional) with verify-don't-hallucinate prompt rules.
19
+ - Skills: Claude-Code-compatible SKILL.md discovery; in-session install from
20
+ skills.sh (`/skills search`, `/skills install`); system prompt refreshes
21
+ every turn so new skills apply immediately.
22
+ - MCP: stdio JSON-RPC client, `[mcp_servers]` config, `/mcp add|remove|list`,
23
+ tools exposed as `mcp__server__tool` (approval-gated under auto).
24
+
25
+ ### Models & providers
26
+ - OpenRouter, local Ollama, self-hosted OpenAI-compatible, and Lucid Cloud
27
+ (Go backend: email auth, SSE proxy with 5% margin billing, Stripe top-ups
28
+ with 18% India GST).
29
+ - Hardware-aware catalog (total + free RAM), quality-ranked suggestions,
30
+ `/download` auto-installs Ollama itself, `/delete` frees disk.
31
+ - ernie_x1 / Qwen-XML text-format tool-call fallback parser — ERNIE thinking
32
+ models and misbehaving Qwen serving stacks now drive the harness correctly.
33
+
34
+ ### Context engine
35
+ - Repo map on session start (git ls-files + symbol extraction, chunked),
36
+ keyword-scored retrieval injected per turn within a hard 8k-char budget —
37
+ large repos never blow the context window.
38
+ - Project memory: `.lucid/knowledge.md` + `.lucid/CHANGELOG.md` maintained by
39
+ the agent across sessions.
40
+
41
+ ### TUI
42
+ - Codex-style cells, live `✦ thinking` stream that collapses when output
43
+ starts, `• Wrote/Edited <file>` labels for file-writing commands,
44
+ autocomplete palette for every command with best→worst model sorting
45
+ (Enter/Tab accept, prefix commands like `/ski` resolve), token ↑in/↓out
46
+ counters, full-auto switch confirmation.