jeo-code 0.5.15 → 0.5.16
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 +7 -0
- package/README.ja.md +1 -1
- package/README.ko.md +1 -1
- package/README.md +1 -1
- package/README.zh.md +1 -1
- package/package.json +1 -1
- package/src/commands/launch.ts +23 -30
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,13 @@ 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.5.16] - 2026-06-16
|
|
10
|
+
_`/resume` and Ctrl+O no longer corrupt the TUI — clean screen restore + scrollback expand._
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- **`/resume` corrupted the screen on a TTY.** After picking a session the resumed transcript was dumped on top of whatever was on screen (picker remnants, the prior conversation, the live input frame), so replayed ANSI/forge boxes from the old session collided with the live layout. Resume now wipes the screen + scrollback and re-renders the welcome banner BEFORE replaying the transcript — the same proven path `/clear` uses — so the restored view is a single, intact screen (verified live: one input box, one status bar, no picker remnants).
|
|
14
|
+
- **Ctrl+O at the prompt crammed the last response into the ~10-row footer**, clipping long/CJK content with "… N more line(s)" and risking a garbled box. Ctrl+O now expands the full last assistant response into scrollback (clean `disarm → print → re-arm` path), so it is fully scrollable and the input box + typed draft restore without corruption. Removed the now-dead footer history-panel machinery (`promptHistoryLines`, `historyPreviewLines`).
|
|
15
|
+
|
|
9
16
|
## [0.5.15] - 2026-06-16
|
|
10
17
|
_`jeo update` now actually upgrades — bare command installs the latest release instead of just printing a manual command._
|
|
11
18
|
|
package/README.ja.md
CHANGED
|
@@ -150,11 +150,11 @@ CI は `.github/workflows/npm-publish.yml` で公開します — GitHub リリ
|
|
|
150
150
|
## 変更履歴 (Changelog)
|
|
151
151
|
|
|
152
152
|
<!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
|
|
153
|
+
- **[0.5.16]** (2026-06-16) — `/resume` and Ctrl+O no longer corrupt the TUI — clean screen restore + scrollback expand.
|
|
153
154
|
- **[0.5.15]** (2026-06-16) — `jeo update` now actually upgrades — bare command installs the latest release instead of just printing a manual command.
|
|
154
155
|
- **[0.5.14]** (2026-06-16) — `jeo --tmux` live-verification harness — repeatable stability + behavior checks.
|
|
155
156
|
- **[0.5.13]** (2026-06-15) — Workflow `/` commands actually run — `/deep-interview`, `/team`, `/ultragoal`, `/ralplan` dispatch by name.
|
|
156
157
|
- **[0.5.12]** (2026-06-15) — Yellow status animation while a process runs, and elapsed `(Nms)` on every completed tool card.
|
|
157
|
-
- **[0.5.11]** (2026-06-15) — Backspace on an empty prompt line no longer quits jeo.
|
|
158
158
|
|
|
159
159
|
See [CHANGELOG.md](CHANGELOG.md) for the full history.
|
|
160
160
|
<!-- CHANGELOG:END -->
|
package/README.ko.md
CHANGED
|
@@ -150,11 +150,11 @@ CI는 `.github/workflows/npm-publish.yml`로 배포합니다 — GitHub 릴리
|
|
|
150
150
|
## 변경 이력 (Changelog)
|
|
151
151
|
|
|
152
152
|
<!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
|
|
153
|
+
- **[0.5.16]** (2026-06-16) — `/resume` and Ctrl+O no longer corrupt the TUI — clean screen restore + scrollback expand.
|
|
153
154
|
- **[0.5.15]** (2026-06-16) — `jeo update` now actually upgrades — bare command installs the latest release instead of just printing a manual command.
|
|
154
155
|
- **[0.5.14]** (2026-06-16) — `jeo --tmux` live-verification harness — repeatable stability + behavior checks.
|
|
155
156
|
- **[0.5.13]** (2026-06-15) — Workflow `/` commands actually run — `/deep-interview`, `/team`, `/ultragoal`, `/ralplan` dispatch by name.
|
|
156
157
|
- **[0.5.12]** (2026-06-15) — Yellow status animation while a process runs, and elapsed `(Nms)` on every completed tool card.
|
|
157
|
-
- **[0.5.11]** (2026-06-15) — Backspace on an empty prompt line no longer quits jeo.
|
|
158
158
|
|
|
159
159
|
See [CHANGELOG.md](CHANGELOG.md) for the full history.
|
|
160
160
|
<!-- CHANGELOG:END -->
|
package/README.md
CHANGED
|
@@ -150,11 +150,11 @@ Required npm token permissions (repository secret `NPM_TOKEN`):
|
|
|
150
150
|
## Changelog
|
|
151
151
|
|
|
152
152
|
<!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
|
|
153
|
+
- **[0.5.16]** (2026-06-16) — `/resume` and Ctrl+O no longer corrupt the TUI — clean screen restore + scrollback expand.
|
|
153
154
|
- **[0.5.15]** (2026-06-16) — `jeo update` now actually upgrades — bare command installs the latest release instead of just printing a manual command.
|
|
154
155
|
- **[0.5.14]** (2026-06-16) — `jeo --tmux` live-verification harness — repeatable stability + behavior checks.
|
|
155
156
|
- **[0.5.13]** (2026-06-15) — Workflow `/` commands actually run — `/deep-interview`, `/team`, `/ultragoal`, `/ralplan` dispatch by name.
|
|
156
157
|
- **[0.5.12]** (2026-06-15) — Yellow status animation while a process runs, and elapsed `(Nms)` on every completed tool card.
|
|
157
|
-
- **[0.5.11]** (2026-06-15) — Backspace on an empty prompt line no longer quits jeo.
|
|
158
158
|
|
|
159
159
|
See [CHANGELOG.md](CHANGELOG.md) for the full history.
|
|
160
160
|
<!-- CHANGELOG:END -->
|
package/README.zh.md
CHANGED
|
@@ -150,11 +150,11 @@ CI 通过 `.github/workflows/npm-publish.yml` 发布 — GitHub 发布 release
|
|
|
150
150
|
## 更新日志 (Changelog)
|
|
151
151
|
|
|
152
152
|
<!-- CHANGELOG:START (auto-generated from CHANGELOG.md — run `bun run changelog:sync`) -->
|
|
153
|
+
- **[0.5.16]** (2026-06-16) — `/resume` and Ctrl+O no longer corrupt the TUI — clean screen restore + scrollback expand.
|
|
153
154
|
- **[0.5.15]** (2026-06-16) — `jeo update` now actually upgrades — bare command installs the latest release instead of just printing a manual command.
|
|
154
155
|
- **[0.5.14]** (2026-06-16) — `jeo --tmux` live-verification harness — repeatable stability + behavior checks.
|
|
155
156
|
- **[0.5.13]** (2026-06-15) — Workflow `/` commands actually run — `/deep-interview`, `/team`, `/ultragoal`, `/ralplan` dispatch by name.
|
|
156
157
|
- **[0.5.12]** (2026-06-15) — Yellow status animation while a process runs, and elapsed `(Nms)` on every completed tool card.
|
|
157
|
-
- **[0.5.11]** (2026-06-15) — Backspace on an empty prompt line no longer quits jeo.
|
|
158
158
|
|
|
159
159
|
See [CHANGELOG.md](CHANGELOG.md) for the full history.
|
|
160
160
|
<!-- CHANGELOG:END -->
|
package/package.json
CHANGED
package/src/commands/launch.ts
CHANGED
|
@@ -2274,7 +2274,6 @@ export async function runLaunchCommand(args: string[]): Promise<void> {
|
|
|
2274
2274
|
}
|
|
2275
2275
|
};
|
|
2276
2276
|
let previewPending = false;
|
|
2277
|
-
let promptHistoryLines: string[] | null = null;
|
|
2278
2277
|
|
|
2279
2278
|
// Inline boxed-footer rendering with a FIXED reservation (the "@-mention typing
|
|
2280
2279
|
// pushes the box down" fix). The footer reserves its full `footerRows` height
|
|
@@ -2426,22 +2425,6 @@ export async function runLaunchCommand(args: string[]): Promise<void> {
|
|
|
2426
2425
|
const preview = (slash.length ? slash : args).map(l => chalk.gray(truncateAnsi(l, cols)));
|
|
2427
2426
|
return [statusBarLine(cols), "", ...input, ...preview].slice(0, footerRows);
|
|
2428
2427
|
};
|
|
2429
|
-
const historyPreviewLines = (detail: string[]): string[] => {
|
|
2430
|
-
const cols = Math.max(24, (process.stdout.columns ?? 80) - 1);
|
|
2431
|
-
const title = `${uiAccent("history")} ${chalk.dim("· Ctrl+O closes")}`;
|
|
2432
|
-
const budget = Math.max(0, footerRows - 2);
|
|
2433
|
-
const physical = detail.flatMap(line => line.split("\n")).map(line => truncateAnsi(line, cols));
|
|
2434
|
-
let body = physical;
|
|
2435
|
-
if (physical.length > budget) {
|
|
2436
|
-
const keep = Math.max(0, budget - 1);
|
|
2437
|
-
body = physical.slice(0, keep);
|
|
2438
|
-
body.push(chalk.gray(`… ${physical.length - keep} more line(s)`));
|
|
2439
|
-
} else {
|
|
2440
|
-
body = physical.slice(0, budget);
|
|
2441
|
-
}
|
|
2442
|
-
footerCursor = { row: Math.min(1, footerRows - 1), col: 1 };
|
|
2443
|
-
return [statusBarLine(cols), title, ...body].slice(0, footerRows);
|
|
2444
|
-
};
|
|
2445
2428
|
const drawFooter = (lines: string[]) => {
|
|
2446
2429
|
if (!previewArmed || footerRendered === 0) return;
|
|
2447
2430
|
// ALWAYS paint exactly footerRendered rows so the reservation is fully covered
|
|
@@ -2888,23 +2871,24 @@ export async function runLaunchCommand(args: string[]): Promise<void> {
|
|
|
2888
2871
|
return;
|
|
2889
2872
|
}
|
|
2890
2873
|
if (!previewArmed || pickerActive) return;
|
|
2891
|
-
// Ctrl+O:
|
|
2892
|
-
// uses LaunchTui.showDetail(); this
|
|
2893
|
-
//
|
|
2874
|
+
// Ctrl+O: expand the last assistant response into scrollback for a full,
|
|
2875
|
+
// scrollable read. The live-turn TUI path uses LaunchTui.showDetail(); this
|
|
2876
|
+
// idle-prompt path prints the same content above a cleanly re-armed footer.
|
|
2894
2877
|
// (Cmd+O is intercepted by macOS/terminal and never reaches the app.)
|
|
2895
2878
|
if (key?.ctrl && key.name === "o") {
|
|
2896
|
-
if (promptHistoryLines) {
|
|
2897
|
-
promptHistoryLines = null;
|
|
2898
|
-
drawFooter(previewLines(typedLine, navIdx));
|
|
2899
|
-
return;
|
|
2900
|
-
}
|
|
2901
2879
|
const detail = composeDetailLines();
|
|
2902
2880
|
if (detail.length === 0) return;
|
|
2903
|
-
|
|
2904
|
-
|
|
2881
|
+
// Expand the last response into scrollback CLEANLY instead of cramming it
|
|
2882
|
+
// into the ~10-row footer reservation (which clipped long/CJK content and
|
|
2883
|
+
// could garble the box). Disarm → print full detail → re-arm + repaint is
|
|
2884
|
+
// the same path the resize handler/main loop use, so the input box and the
|
|
2885
|
+
// typed draft restore without corruption.
|
|
2886
|
+
disarmPreview();
|
|
2887
|
+
logLines(detail);
|
|
2888
|
+
armPreview();
|
|
2889
|
+
drawFooter(previewLines(typedLine, navIdx));
|
|
2905
2890
|
return;
|
|
2906
2891
|
}
|
|
2907
|
-
if (promptHistoryLines) promptHistoryLines = null;
|
|
2908
2892
|
// Ctrl+V: attach a clipboard IMAGE to the next message. Terminal text paste
|
|
2909
2893
|
// never arrives as a ctrl+v keypress (it streams as plain stdin data), so this
|
|
2910
2894
|
// binding is image-only; when the clipboard holds no image it's a silent no-op.
|
|
@@ -2947,7 +2931,6 @@ export async function runLaunchCommand(args: string[]): Promise<void> {
|
|
|
2947
2931
|
if (!previewArmed) return;
|
|
2948
2932
|
try {
|
|
2949
2933
|
if (key && (key.name === "return" || key.name === "enter")) {
|
|
2950
|
-
promptHistoryLines = null;
|
|
2951
2934
|
drawFooter([]);
|
|
2952
2935
|
return;
|
|
2953
2936
|
}
|
|
@@ -3008,7 +2991,7 @@ export async function runLaunchCommand(args: string[]): Promise<void> {
|
|
|
3008
2991
|
try {
|
|
3009
2992
|
disarmPreview();
|
|
3010
2993
|
armPreview();
|
|
3011
|
-
drawFooter(
|
|
2994
|
+
drawFooter(previewLines(typedLine, navIdx));
|
|
3012
2995
|
} catch { /* ignore resize render races */ }
|
|
3013
2996
|
};
|
|
3014
2997
|
process.stdout.on("resize", idleResizeHandler);
|
|
@@ -3221,6 +3204,16 @@ export async function runLaunchCommand(args: string[]): Promise<void> {
|
|
|
3221
3204
|
if (rli.history[0] !== p) rli.history.unshift(p);
|
|
3222
3205
|
}
|
|
3223
3206
|
}
|
|
3207
|
+
// Clean restore: wipe the screen + scrollback BEFORE replaying the
|
|
3208
|
+
// transcript so it can't collide with picker remnants, the prior
|
|
3209
|
+
// conversation, or the live input frame — the "/resume corrupts the
|
|
3210
|
+
// TUI" fix. Same proven path as /clear; re-render the welcome banner
|
|
3211
|
+
// so the resumed view reads like a fresh, intact screen.
|
|
3212
|
+
if (process.stdout.isTTY) {
|
|
3213
|
+
disarmPreview();
|
|
3214
|
+
process.stdout.write("\x1b[2J\x1b[3J\x1b[H");
|
|
3215
|
+
console.log(renderWelcome(welcomeData).join("\n"));
|
|
3216
|
+
}
|
|
3224
3217
|
const sep = "─".repeat(Math.min(48, Math.max(20, (process.stdout.columns ?? 80) - 1)));
|
|
3225
3218
|
logLines([
|
|
3226
3219
|
sep,
|