jeo-code 0.7.25 → 0.7.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -6,6 +6,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  The README mirrors the latest 5 entries — regenerate with `bun run changelog:sync`.
8
8
 
9
+ ## [0.7.26] - 2026-07-02
10
+ _Esc/Ctrl+C reliably clears the input box (fixes a gate the earlier reorder missed), and un-bracketed multi-line pastes no longer shred into premature per-line submits._
11
+
12
+ ### Fixed
13
+ - **Esc (and meta-mapped Cmd+C) at the prompt intermittently did nothing.** A prior fix reordered the Esc check ahead of the `previewPending` reentrancy gate, but missed an earlier, more totalizing `!previewArmed || pickerActive` gate that Ctrl+C already bypassed (checked first) while Esc did not — so a fresh session's very first Esc after typing could be silently swallowed. The Esc/meta+C check now runs immediately after the Ctrl+C check, before that gate, mirroring Ctrl+C's existing precedent. Verified live in a real `jeo` TUI (tmux-driven keystrokes): 10/10 fresh-session repro attempts now clear the box; previously flaky.
14
+ - **Un-bracketed multi-line paste shredded into separate premature submits.** Terminals/paths that deliver a multi-line paste as ONE stdin chunk WITHOUT bracketed-paste markers (DECSET 2004) — e.g. a raw X11 primary-selection middle-click paste, some SSH clients, or a tmux `paste-buffer` binding without `-p` — hit `filterPromptInputChunk`'s bare `\r`/`\n` pass-through and had each embedded line submitted as its own message mid-composition instead of landing as one multi-line draft. Reproduced live: pasting `"first line\nsecond line\nthird line"` via an un-bracketed tmux paste immediately submitted line 1 to the model, leaving the rest to leak in as orphaned lines. Fixed with a guard in `src/commands/launch/input.ts`: outside an active bracketed paste, a linebreak with MORE data after it in the SAME synchronous chunk (impossible for a genuine standalone Enter keypress, which always arrives as the last byte of its read) now folds to the multi-line sentinel instead of submitting — matching the bracketed-paste contract (review the whole block, then press Enter once). A trailing linebreak with nothing after it is unaffected and still submits normally.
15
+
16
+ ### Verified
17
+ - `bun run typecheck` clean; full suite green — 2077 pass / 0 fail across 239 files (4 new cases in `test/prompt-key-filter.test.ts` covering the un-bracketed paste guard, including a no-false-positive check for ordinary single-line typing).
18
+ - Both fixes reproduced and confirmed live in a real running `jeo --no-session` TUI inside tmux (not just unit tests): the exact 3-line un-bracketed paste that previously triggered a premature submit now stays as one multi-line draft, and Esc immediately clears it.
19
+
9
20
  ## [0.7.25] - 2026-07-02
10
21
  _Shift+Enter now reliably distinguishable from Enter on kitty/WezTerm/iTerm2/xterm via modifyOtherKeys + kitty keyboard protocol; row-aware Home/End and Cmd+Left/Right in multi-row drafts._
11
22
 
package/README.ja.md CHANGED
@@ -205,11 +205,11 @@ CI は `.github/workflows/npm-publish.yml` で公開します — GitHub リリ
205
205
  ## 変更履歴 (Changelog)
206
206
 
207
207
  <!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
208
+ - **[0.7.26]** (2026-07-02) — Esc/Ctrl+C reliably clears the input box (fixes a gate the earlier reorder missed), and un-bracketed multi-line pastes no longer shred into premature per-line submits.
208
209
  - **[0.7.25]** (2026-07-02) — Shift+Enter now reliably distinguishable from Enter on kitty/WezTerm/iTerm2/xterm via modifyOtherKeys + kitty keyboard protocol; row-aware Home/End and Cmd+Left/Right in multi-row drafts.
209
210
  - **[0.7.24]** (2026-07-02) — OAuth callback page redesign with embedded jeo wordmark + Close button; memory budget O(n²)→O(n) incremental tracking fix.
210
211
  - **[0.7.23]** (2026-07-01) — Anthropic 5th-generation model catalog: adds Sonnet 5, Fable 5, and Mythos 5, promotes the 4.6 generation to 1M context / 128k output, and retires the superseded 4.5/3.5/4.1 ids. Bumps the default model to Sonnet 4.6, prices the new tiers, and fixes the thinking transport for Haiku 4.5 and every 5th-gen model.
211
212
  - **[0.7.22]** (2026-06-30) — gajae-code 0.7.3–0.7.8 parity sweep: terminal-bell notifications, a gruvbox-dark TUI theme, a resilient `jeo update` runtime check, and an ultragoal artifact gate. Ports the user-facing improvements from upstream gajae-code that jeo did not yet have, re-implemented to fit jeo's config, command, theming, and skill surfaces.
212
- - **[0.7.21]** (2026-06-26) — Global llm-wiki vault integration, Gemini/Antigravity thinking indicators, generous file-reading windows, and autopilot flag validation. Adds a shared global wiki root configuration with a /wiki slash command, fires reasoning start signals up front for Gemini/Antigravity models, adjusts the large-file reading discipline to use generous windows, and validates autopilot goal and integer flags.
213
213
 
214
214
  See [CHANGELOG.md](CHANGELOG.md) for the full history.
215
215
  <!-- CHANGELOG:END -->
package/README.ko.md CHANGED
@@ -205,11 +205,11 @@ CI는 `.github/workflows/npm-publish.yml`로 배포합니다 — GitHub 릴리
205
205
  ## 변경 이력 (Changelog)
206
206
 
207
207
  <!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
208
+ - **[0.7.26]** (2026-07-02) — Esc/Ctrl+C reliably clears the input box (fixes a gate the earlier reorder missed), and un-bracketed multi-line pastes no longer shred into premature per-line submits.
208
209
  - **[0.7.25]** (2026-07-02) — Shift+Enter now reliably distinguishable from Enter on kitty/WezTerm/iTerm2/xterm via modifyOtherKeys + kitty keyboard protocol; row-aware Home/End and Cmd+Left/Right in multi-row drafts.
209
210
  - **[0.7.24]** (2026-07-02) — OAuth callback page redesign with embedded jeo wordmark + Close button; memory budget O(n²)→O(n) incremental tracking fix.
210
211
  - **[0.7.23]** (2026-07-01) — Anthropic 5th-generation model catalog: adds Sonnet 5, Fable 5, and Mythos 5, promotes the 4.6 generation to 1M context / 128k output, and retires the superseded 4.5/3.5/4.1 ids. Bumps the default model to Sonnet 4.6, prices the new tiers, and fixes the thinking transport for Haiku 4.5 and every 5th-gen model.
211
212
  - **[0.7.22]** (2026-06-30) — gajae-code 0.7.3–0.7.8 parity sweep: terminal-bell notifications, a gruvbox-dark TUI theme, a resilient `jeo update` runtime check, and an ultragoal artifact gate. Ports the user-facing improvements from upstream gajae-code that jeo did not yet have, re-implemented to fit jeo's config, command, theming, and skill surfaces.
212
- - **[0.7.21]** (2026-06-26) — Global llm-wiki vault integration, Gemini/Antigravity thinking indicators, generous file-reading windows, and autopilot flag validation. Adds a shared global wiki root configuration with a /wiki slash command, fires reasoning start signals up front for Gemini/Antigravity models, adjusts the large-file reading discipline to use generous windows, and validates autopilot goal and integer flags.
213
213
 
214
214
  See [CHANGELOG.md](CHANGELOG.md) for the full history.
215
215
  <!-- CHANGELOG:END -->
package/README.md CHANGED
@@ -232,11 +232,11 @@ Huge thanks to [gajae-code](https://github.com/Yeachan-Heo/gajae-code) for the i
232
232
  ## Changelog
233
233
 
234
234
  <!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
235
+ - **[0.7.26]** (2026-07-02) — Esc/Ctrl+C reliably clears the input box (fixes a gate the earlier reorder missed), and un-bracketed multi-line pastes no longer shred into premature per-line submits.
235
236
  - **[0.7.25]** (2026-07-02) — Shift+Enter now reliably distinguishable from Enter on kitty/WezTerm/iTerm2/xterm via modifyOtherKeys + kitty keyboard protocol; row-aware Home/End and Cmd+Left/Right in multi-row drafts.
236
237
  - **[0.7.24]** (2026-07-02) — OAuth callback page redesign with embedded jeo wordmark + Close button; memory budget O(n²)→O(n) incremental tracking fix.
237
238
  - **[0.7.23]** (2026-07-01) — Anthropic 5th-generation model catalog: adds Sonnet 5, Fable 5, and Mythos 5, promotes the 4.6 generation to 1M context / 128k output, and retires the superseded 4.5/3.5/4.1 ids. Bumps the default model to Sonnet 4.6, prices the new tiers, and fixes the thinking transport for Haiku 4.5 and every 5th-gen model.
238
239
  - **[0.7.22]** (2026-06-30) — gajae-code 0.7.3–0.7.8 parity sweep: terminal-bell notifications, a gruvbox-dark TUI theme, a resilient `jeo update` runtime check, and an ultragoal artifact gate. Ports the user-facing improvements from upstream gajae-code that jeo did not yet have, re-implemented to fit jeo's config, command, theming, and skill surfaces.
239
- - **[0.7.21]** (2026-06-26) — Global llm-wiki vault integration, Gemini/Antigravity thinking indicators, generous file-reading windows, and autopilot flag validation. Adds a shared global wiki root configuration with a /wiki slash command, fires reasoning start signals up front for Gemini/Antigravity models, adjusts the large-file reading discipline to use generous windows, and validates autopilot goal and integer flags.
240
240
 
241
241
  See [CHANGELOG.md](CHANGELOG.md) for the full history.
242
242
  <!-- CHANGELOG:END -->
package/README.zh.md CHANGED
@@ -205,11 +205,11 @@ CI 通过 `.github/workflows/npm-publish.yml` 发布 — GitHub 发布 release
205
205
  ## 更新日志 (Changelog)
206
206
 
207
207
  <!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
208
+ - **[0.7.26]** (2026-07-02) — Esc/Ctrl+C reliably clears the input box (fixes a gate the earlier reorder missed), and un-bracketed multi-line pastes no longer shred into premature per-line submits.
208
209
  - **[0.7.25]** (2026-07-02) — Shift+Enter now reliably distinguishable from Enter on kitty/WezTerm/iTerm2/xterm via modifyOtherKeys + kitty keyboard protocol; row-aware Home/End and Cmd+Left/Right in multi-row drafts.
209
210
  - **[0.7.24]** (2026-07-02) — OAuth callback page redesign with embedded jeo wordmark + Close button; memory budget O(n²)→O(n) incremental tracking fix.
210
211
  - **[0.7.23]** (2026-07-01) — Anthropic 5th-generation model catalog: adds Sonnet 5, Fable 5, and Mythos 5, promotes the 4.6 generation to 1M context / 128k output, and retires the superseded 4.5/3.5/4.1 ids. Bumps the default model to Sonnet 4.6, prices the new tiers, and fixes the thinking transport for Haiku 4.5 and every 5th-gen model.
211
212
  - **[0.7.22]** (2026-06-30) — gajae-code 0.7.3–0.7.8 parity sweep: terminal-bell notifications, a gruvbox-dark TUI theme, a resilient `jeo update` runtime check, and an ultragoal artifact gate. Ports the user-facing improvements from upstream gajae-code that jeo did not yet have, re-implemented to fit jeo's config, command, theming, and skill surfaces.
212
- - **[0.7.21]** (2026-06-26) — Global llm-wiki vault integration, Gemini/Antigravity thinking indicators, generous file-reading windows, and autopilot flag validation. Adds a shared global wiki root configuration with a /wiki slash command, fires reasoning start signals up front for Gemini/Antigravity models, adjusts the large-file reading discipline to use generous windows, and validates autopilot goal and integer flags.
213
213
 
214
214
  See [CHANGELOG.md](CHANGELOG.md) for the full history.
215
215
  <!-- CHANGELOG:END -->
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "jeo-code",
3
- "version": "0.7.25",
3
+ "version": "0.7.26",
4
+
4
5
  "description": "Clean, highly optimized AI coding agent using spec-first loop",
5
6
  "type": "module",
6
7
  "main": "src/cli.ts",
@@ -751,7 +751,25 @@ export function filterPromptInputChunk(
751
751
  }
752
752
  out += data.slice(i, i + 3); i += 3; continue;
753
753
  }
754
+ // Un-bracketed multi-line paste guard: some terminals/multiplexers (a raw X11
755
+ // primary-selection middle-click paste, certain SSH clients, or a tmux binding
756
+ // that omits `-p`) deliver a multi-line paste as ONE stdin chunk WITHOUT the
757
+ // bracketed-paste markers this filter otherwise relies on (PASTE_START/PASTE_END
758
+ // above). Outside an active bracketed paste, readline treats every bare `\r`/`\n`
759
+ // as Enter — so an un-bracketed 3-line paste submitted line 1 immediately, mid-
760
+ // composition, and left the rest to leak in as separate prompts (the "붙여넣기가
761
+ // 잘 안됨" bug: works for single-line/bracketed paste, corrupts multi-line paste
762
+ // when the terminal doesn't negotiate DECSET 2004). A genuine Enter keypress is
763
+ // always the LAST byte of its chunk — raw mode delivers one keystroke per read —
764
+ // so a linebreak with MORE data after it in the SAME synchronous chunk can only be
765
+ // a paste (or a scripted multi-line feed); fold it to the sentinel instead of
766
+ // submitting, matching the bracketed-paste contract (review the whole block, then
767
+ // press Enter once to submit). A trailing linebreak (nothing after it) keeps the
768
+ // existing behavior below — including the opt-in lone-LF Shift+Enter rule.
769
+ const bareBreakLen = data.startsWith("\r\n", i) ? 2 : (data[i] === "\r" || data[i] === "\n") ? 1 : 0;
770
+ if (bareBreakLen > 0 && i + bareBreakLen < data.length) { out += MULTILINE_SENTINEL; i += bareBreakLen; continue; }
754
771
  if (env.loneLfShiftEnter && data[i] === "\n") { out += MULTILINE_SENTINEL; i += 1; continue; } // lone LF = Shift+Enter (opt-in)
772
+
755
773
  // Ctrl+L (form feed): the prompt redraw hotkey, handled on the process.stdin keypress
756
774
  // listener — never forward it to readline as a literal char.
757
775
  if (data[i] === "\u000c") { i += 1; continue; }
@@ -1902,12 +1902,16 @@ export async function runLaunchCommand(args: string[]): Promise<void> {
1902
1902
  // the prompt never carries a trailing/floating blank block.
1903
1903
  const setFooterRows = (n: number) => {
1904
1904
  n = Math.max(1, Math.min(n, footerRows));
1905
+
1905
1906
  if (!previewArmed || n === footerRendered) return;
1907
+
1906
1908
  let s = footerParkedRow > 0 ? cursorUp(footerParkedRow) : "";
1907
1909
  s += toColumn(1) + clearToEnd(); // wipe old region; cursor now at its top (after output)
1908
1910
  if (n > 1) s += "\n".repeat(n - 1) + cursorUp(n - 1);
1909
1911
  s += toColumn(1);
1912
+
1910
1913
  out.write(s);
1914
+
1911
1915
  footerRendered = n;
1912
1916
  footerParkedRow = 0;
1913
1917
  lastFooterKey = ""; // force a full repaint into the resized region
@@ -2112,6 +2116,7 @@ export async function runLaunchCommand(args: string[]): Promise<void> {
2112
2116
  // Re-pin the reservation to the height the latest preview/panel wants (compact at
2113
2117
  // idle, grown for a dropdown) BEFORE painting, so no reserved blank trails the prompt.
2114
2118
  setFooterRows(footerWantRows);
2119
+
2115
2120
  // ALWAYS paint exactly footerRendered rows so the reservation is fully covered
2116
2121
  // and no row can spill past it — the bug fix that kept `@folder<more text>`
2117
2122
  // typing from scrolling the input box (and prior output) off the top.
@@ -2186,7 +2191,9 @@ export async function runLaunchCommand(args: string[]): Promise<void> {
2186
2191
  const clearTypedInput = (): boolean => {
2187
2192
  const rli = rl as unknown as { line: string; cursor: number; _refreshLine?: () => void };
2188
2193
  const hadPastedQueue = queuedPromptInput.pastedLines.length > 0;
2194
+
2189
2195
  if (!promptHasContent()) return false;
2196
+
2190
2197
  // ESC is the escape hatch for an accidental giant paste: drop the queued batch.
2191
2198
  if (hadPastedQueue) {
2192
2199
  const dropped = queuedPromptInput.pastedLines.splice(0).length;
@@ -2732,6 +2739,20 @@ export async function runLaunchCommand(args: string[]): Promise<void> {
2732
2739
  handleCtrlC();
2733
2740
  return;
2734
2741
  }
2742
+ // ESC (or a meta-mapped Cmd+C) at the prompt: wipe the typed text. Checked HERE,
2743
+ // before the `!previewArmed || pickerActive` gate below — mirroring Ctrl+C right
2744
+ // above, which already bypasses that gate. Without this, a transient window where
2745
+ // `previewArmed` is momentarily false (the same class of race Ctrl+C was already
2746
+ // immune to) silently swallowed the ESC keypress: the box stayed unaffected and
2747
+ // `clearTypedInput()` never ran (the "esc 입력 후 안 먹힘" bug — Esc after typing
2748
+ // intermittently did nothing). `clearTypedInput()` itself already no-ops safely
2749
+ // when there is nothing to clear or no armed box to redraw into, so running it
2750
+ // unconditionally here is safe even mid-picker or pre-arm.
2751
+ if (key && ((key.name === "escape" && !key.ctrl) || (key.meta && key.name === "c"))) {
2752
+ clearTypedInput();
2753
+ return;
2754
+ }
2755
+
2735
2756
  if (!previewArmed || pickerActive) return;
2736
2757
  // Drag-and-drop file attach: a terminal delivers a dropped file as its PATH typed
2737
2758
  // into the box, wrapped in a bracketed paste. On paste-end, swap any readable image
@@ -2838,20 +2859,8 @@ export async function runLaunchCommand(args: string[]): Promise<void> {
2838
2859
  })();
2839
2860
  return;
2840
2861
  }
2841
- // ESC (or a meta-mapped Cmd+C) at the prompt: wipe the typed text. A bare
2842
- // ESC decodes as `escape` (meta is set for a lone ESC byte — accept both)
2843
- // only after readline's escape-sequence timeout, so arrow/wheel sequences
2844
- // never trigger this. Checked BEFORE the `previewPending` reentrancy gate
2845
- // (like Ctrl+C above) — a fast typist/paste can deliver several keypress
2846
- // events in ONE synchronous stdin read, all before the first keystroke's
2847
- // setImmediate fires; gating this after `previewPending` silently dropped
2848
- // an ESC that lands in the same burst as preceding keystrokes (the
2849
- // "esc 입력 후 안 먹힘" bug — Esc right after typing intermittently did nothing).
2850
- if (key && ((key.name === "escape" && !key.ctrl) || (key.meta && key.name === "c"))) {
2851
- clearTypedInput();
2852
- return;
2853
- }
2854
2862
  if (previewPending) return;
2863
+
2855
2864
  // Ctrl+C is handled above (clear-or-exit); keep this guard for defensive ordering only.
2856
2865
  if (key?.ctrl && key.name === "c") return;
2857
2866