Repository navigation
chore: sync upstream main (interactive PTY terminal, dev-server detection, v1.2.28) - #38
Merged
Merged
Conversation
The terminal ran each line as its own `sh -lc`, killed it after 30 s and kept only the last 4,000 characters of output, so a dev server, a log follower or an interactive prompt could not be used. It also always started in /root, whatever workspace it was opened from (yuga-hashimoto#329). It now keeps one shell alive for as long as the screen is open: - PTY: the sandbox's `script -qefc` allocates the pty (the same trick the Claude Code and Antigravity sign-in flows use), so the shell has a real controlling terminal - line editing, password prompts and Ctrl+C work. `stty` sets the size the screen measured, since `script` otherwise reports 0x0 over pipes. - Streaming: output is read as it is produced and interpreted by AnsiTerminalEmulator, a line-oriented VT100/xterm subset (SGR colours, \r rewrites, line editing, clear, wrapping, 10,000 lines of scrollback). Unknown sequences are dropped instead of printed. - Input: the typed line is sent with Enter; Esc, Tab, Ctrl+C, Ctrl+D and the arrow keys have their own key row. - Starts in the workspace it was opened from, falling back to /root; the workspace folder is bound at /workspace. - A runtime work lease is held while the shell lives so the device does not suspend under a build. The runtime access lock is held only while the process is spawned, so a long-lived shell cannot stall an update. - The shell and anything it started end when the screen is left. Full-screen programs (vim, htop), resizing an open shell and the multi-terminal tab placeholder are not part of this change. Closes yuga-hashimoto#329 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ut parser Pre-PR review of the interactive terminal found two blockers and several smaller problems. Blockers: - Closing the screen only called destroyForcibly() on proot. A proot guest outlives that (the repo's own on-device finding, ProcessTree.kt): the `script`/`bash` and any dev server stayed running while the runtime lease was released. close() now walks /proc and kills the tree end first (killProcessTree, renamed from killAntigravityProcessTree since it is not Antigravity specific) on a background thread, then destroys the root even if the walk failed. - A CSI parameter such as ESC[2147483647@ overflowed Int arithmetic in the emulator and threw out of the collector, crashing the app from any `cat` of a hostile file. Numeric parameters are clamped to 9,999, a feed() failure is logged instead of propagated, CAN/SUB abort an escape sequence in progress, and the interned style table is bounded. Also fixed: - A shell that finished opening after the screen was closed was never owned by anyone and kept running; it is now ended on arrival. - The emulator was sized from the raw measured width while the pty was clamped to 20..240 columns; both use the same bounds now. - Tab and the arrow keys act on the shell's line editor, so text still in the input field is sent first. - Output following stopped when the soft keyboard shrank the viewport (it judged "at the end" by canScrollForward at that moment). It now follows until the reader drags away and resumes when they drag back to the end. - State publishes happen under the emulator lock so a late snapshot cannot bring back text that `clear` removed. - Removed the now unused terminal_banner / terminal_exit_code strings from all locales; documented the remaining limits (CJK width, OpenCode restarts ending the shell, the lease being held while a shell is open). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
- close() no longer walks the process tree of a shell that already ended: its pid has been reaped and may belong to something else. - The output safety net now also covers snapshot(), and a CSI sequence that carries a negative parameter is ignored whole (ESC[-1m used to be read as ESC[0m and reset the colours). - Typing, pressing a key and clearing bring the view back to the end of the output after the reader scrolled away. Scrolling away by hand still stops the following; mouse-wheel and TalkBack scrolling do not, which is written down in the docs rather than guessed at. - Documented that Tab and the arrow keys send the pending input first. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ub-issues-review-08495d feat(terminal): interactive PTY shell in the embedded terminal
Ships the work merged since v1.2.27: the interactive PTY terminal, local workspace file editing, clipboard image paste, Codex per-turn settings, the OpenCode V2 server API, and the privacy and stability fixes listed in the changelog.
…se-1.2.28 chore(release): v1.2.28
…in the browser
A dev server started in the embedded terminal had no status and no way to
reach it: the user had to remember the port and type the address into the
in-app browser by hand.
Read the ports servers announce on screen ("Local: http://localhost:5173/",
"Serving HTTP on 0.0.0.0 port 8000", "listening on :3000"), probe them with a
TCP connect to the loopback addresses, and show the ones that answer as chips
above the output. A chip opens http://localhost:PORT/ in the in-app browser;
a server that stops answering is shown as stopped, and forgotten after about
half a minute. A port is only shown once it has answered, because the echoed
command line ("curl http://localhost:8080") names ports nothing listens on.
Only the port number is taken from the output, never the host, so a program's
output cannot send the in-app browser anywhere but this device. Probing starts
when the output first names a server and ends with the shell, so a plain shell
costs nothing. Only screen lines that are new since the last look are
searched, so an old address still in the scrollback cannot revive a server
that was forgotten.
Refs yuga-hashimoto#402
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…real servers Apply the pre-PR review's suggestions. The terminal stores a line wider than the screen as several rows, so an address crossing the wrap point was whole in none of them: python's "Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/)" was missed on a narrow phone, and a cut-off "80" could be read as a port. Rows that fill the width are now joined to the next one before searching, and the trailing digits of a line that may still be growing are held back until it ends. When the slots are full, a new port now pushes out the oldest candidate that never answered (echoed commands, cut-off fragments) instead of being dropped; a port that has answered is never pushed out. Also: a failure while searching for servers no longer takes the output stream down; the probe loop is created inside the lock that decides to start it, so a close or an exit that comes in between cancels it before it runs; the chip's touch target is 48dp and its port number is always left-to-right; and onOpenServer is a required parameter. Refs yuga-hashimoto#402 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…eir length The pre-PR re-review noted that a row filling the width is joined to the next one whether it wrapped or merely ended in the last column. Say so in the KDoc and in LOCAL_RUNTIME.md, with what it costs. Comments and docs only. Refs yuga-hashimoto#402 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…lable-tasks-review-d887ba feat(terminal): list the dev servers started in the terminal and open them in the in-app browser
The MR branch now pins v1.2.28 (versionCode 67, commit 4a662c4) and the NonFreeNet reason also names the Codex binary download and the ChatGPT/OpenAI sign-in. The snapshot is byte-identical to the recipe that passed the fork pipeline, including the reproducible-build comparison against the published -fdroid-release.apk.
…elease-md-recipe-1.2.28 docs(release): sync the fdroiddata recipe snapshot to v1.2.28
# Conflicts: # app/src/main/java/com/yugahashimoto/andcode/feature/workspace/TerminalScreen.kt # app/src/main/java/com/yugahashimoto/andcode/ui/navigation/Routes.kt # app/src/main/java/com/yugahashimoto/andcode/ui/navigation/WorkspaceNavGraph.kt # fastlane/metadata/android/en-US/changelogs/67.txt # fastlane/metadata/android/ja-JP/changelogs/67.txt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Syncs upstream yuga-hashimoto/and-code
main(f0c0806, through their v1.2.28 + docs) into the fork.What comes in
AnsiTerminalEmulator,ProcessTerminalSession,LocalTerminalLauncher, aTerminalKeyRowextra-keys row,AntigravityProcessTreegeneralized toProcessTree— this closes the fork's landscape backlog item fix(chat): find artifacts in the files agents write, and tell agents about them #15.DevServerDetector/DevServerTracker/LoopbackDevServerProbe— servers the shell started are probe-verified, listed as chips, and open in the in-app browser.Conflict resolutions
TerminalScreen.kt: upstream's full rewrite taken; itsFontFamily.Monospaceswapped to the fork'sCodeFontFamily(the fork's only prior change there).Routes.kt/WorkspaceNavGraph.kt: both sides kept — upstream'sterminalRoute(directory)(opens the terminal in that workspace) plus the fork's Git-panel route.1.2.28 (67). The fork bumps to 1.2.29 (68) (.release-version,build.gradle.kts,ReleaseMetadataTest), upstream's 1.2.28 notes stay inchangelogs/67.txt, and the fork's unpublished notes roll forward intochangelogs/68.txtwith the PTY terminal line added (the fork never shipped 67, so 66→68 upgraders would otherwise miss it).Note for the re-author of #1: it follows this PR and rebases on top.
detekt + spotlessCheck pass locally; the test suite (including upstream's nine new terminal test files) runs in CI.
Pre-PR review
判定: APPROVE
ブロッカー
提案(非ブロッキング)
fastlane/metadata/android/{en-US,ja-JP}/changelogs/68.txt— このリリース(68)で実際に ships される最大の変更(upstream の対話型PTYターミナル)への言及が68.txtに無い。fork の前回公開版は67を出していないため、ユーザーは66→68で更新し、67.txt(upstream の 1.2.28 ノート)は二度と表示されない。結果、「ターミナルが本物のシェルになった」ことが変更履歴から読めない。en/ja 両方に1行(例: 「- New: the embedded terminal is now a real interactive shell / 内蔵ターミナルが本物の対話シェルになりました」)を足すことを検討してはどうか。構成自体(67=upstreamノート、68=forkノート繰り越し)は整合しているので、方針のままであればこのままで問題ない。docs/RELEASE.md— fdroiddata スナップショットが upstream の 1.2.28/67 のままで、fork の 1.2.29/68 と食い違う。upstream ドキュメントの鏡像という意図なら問題ないが、fork 利用者が混乱しないよう一行注記があってもよい。チェック済み項目
git diff origin/main...HEAD(46ファイル、+4246/−213)の全ハンクを読了。ブランチは origin/main(eaff7716)を起点とし、その上に upstream f0c0806 のマージのみ(worktree rule 準拠)。git diff 414c7806 eaff7716)。HEAD では upstream の PTY リライト全体を取り込み、FontFamily.Monospaceは0件(rg で確認)、CodeFontFamilyが OutputTextStyle / TerminalKeyButton / TerminalInput の3箇所+import(com.yugahashimoto ブロック内)で復元されている。fork 側の落下物なし。TERMINAL_ARG_DIRECTORY/TERMINAL_ROUTE_PATTERN/terminalRoute()と fork のROUTE_GIT(+fork 追加ルート群)が両方存在。encodeRouteArg/decodeRouteArg(Base64 URL)は既存で、RoutesTestが新規に往復をテスト。onOpenTerminal = terminalRoute(workspace.path)(upstream)とonOpenSourceControl = ROUTE_GIT(fork、GitScreen 配線ごと)が両方生存。terminal composable はTERMINAL_ROUTE_PATTERNに切り替わり、VM は(app.terminalSessions, app.runtimeWork, directory)で構築 — 後述の AndCodeApplication のterminalSessions初期化と型一致。AndCodeApplication.ktのLocalTerminalSessionFactory(runtimeDirectory, installer::installedRuntime, accessCoordinator)はすべてスコープ内の既存依存(行304-346で順序も確認)。.release-version=v1.2.29、versionCode=68/versionName="1.2.29"、ReleaseMetadataTest.assertEquals(68,...)が一致。changelogs は en-US/ja-JP とも67.txt=upstream 1.2.28ノート、68.txt=fork繰り越し+fix(artifacts): open artifacts written outside the workspace #37 artifact修正行で内容が一致。killAntigravityProcessTreeへの参照はコードベ全体で0件。AntigravityAbortTracker/AuthCoordinator/Runtime のKDocリンク・呼び出し3箇所がkillProcessTreeに更新。translatable="false"10)、全ロケール=1611キーで、i18n-check.yml の required キー過不足なし。ハードコードされたユーザー可視文字列なし(Esc/Tab/^C/^D はキーキャップとして意図的かつドキュメント化済み、矢印には contentDescription 付き)。cdは絶対パスのみ+shellQuote、失敗時 /root フォールバック→インジェクション不可)、DevServerDetector/Tracker/LoopbackDevServerProbe(ホスト名は再利用せずポートのみ、localhost 固定でブラウザを開く)— セキュリティ・リソース管理とも問題なし。adoptは close と open の競合を処理、publish は clear と出力のレースを単一ロックで防止。probe の無限ループは probeJob.cancel で終了し viewModelScope 内 — リークなし。git diff f0c08063 HEADで ReleaseMetadataTest の68更新以外のテスト変更なし)。fork 側テストの削除・改変なし。unitTests.isReturnDefaultValues = trueを確認済みで Log 呼び出しは JVM テストでも問題なし。Post-approval: 提案1(68.txt への対話型ターミナル1行、en/ja)をコミット 5772cbd でそのまま採用した。提案2(RELEASE.md 注記)は不採用 — あの文書は upstream の鏡像であり次回同期で置き換わるため。
Generated by Claude Code