Repository navigation
fix: keep runtime error text on device and copy unsupported attachments into the workspace - #391
Merged
Merged
Conversation
Providers reject file parts outside images/PDF (for example `'file part media type application/zip' functionality not supported`), so a zip or other binary attachment could not be sent at all. When the composer attaches a MIME a runtime cannot carry as a file part, copy it into the workspace under `.andcode-attachments/` and reference the path in the prompt text instead. Images and PDFs keep going as file parts. This only applies to the on-device runtime, whose `/workspace` is a local mount (`BackendKind.LOCAL`); a remote runtime is unaffected and still receives the attachment directly, since there is no local mount to copy into. PromptAttachment gains a `workspacePath`; ChatViewModel partitions attachments into model parts and workspace references so the on-disk copy is never sent. The `.andcode-attachments` directory name is now shared with Antigravity's inline-attachment path.
…s on opt-in A runtime/provider session failure was reported to Crashlytics as the raw provider message wrapped in an exception. That text is free-form - it can quote prompts, model output, file paths and hosts - and Crashlytics shares its collection switch with Analytics, which was opt-in. A user who never enabled analytics still had crash reports collected in release builds. - Report a session failure as a fixed category only: `Runtime session error: <runtime>/<errorType>`, where errorType is accepted only if identifier-shaped (ProviderAuthError, ...) and otherwise becomes `unknown`. The raw message stays on-device in the notification. - Disable Crashlytics collection by default in the manifest (firebase_crashlytics_collection_enabled=false) and follow the analytics/crash opt-in via CrashReporter.setEnabled(); debug builds stay off regardless. - Turn off advertising-ID collection and remove the AD_ID permission. - Broaden SecretRedaction: the credential behind a Basic Authorization header, every Cookie pair, quoted JSON credential fields, env-style key names (ANTHROPIC_API_KEY, refresh_token) and URL userinfo are now redacted. - Refresh the bundled legal docs (EN and JA) to match.
yuga-hashimoto
pushed a commit
that referenced
this pull request
Oct 18, 2026
Conflicts with #391 (workspace attachments) in ChatViewModel and ChatHomeScreen, resolved by keeping both sides: - ChatViewModel constructor: keep workspaceAttachmentNoteTemplate and the Codex fast-mode parameters. - Prompt request: send the Codex service tier together with modelAttachments. #391 split pendingAttachments into modelAttachments and workspaceAttachments, and #389 still passed pendingAttachments to the request; pendingAttachments stays for the optimistic message and previews. - ChatHomeScreen imports: keep Role and the semantics imports. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xw2ucui6t6dQdyGRrnCbHb
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.
Summary
Two fixes, one per issue.
#386 — keep runtime error text on device, and make crash reporting opt-in
Runtime session error: <runtime>/<errorType>, whereerrorTypeis accepted only if it is identifier-shaped (ProviderAuthError,MessageAbortedError, …) and otherwise becomesunknown. The free-form message stays on-device, in the notification.CrashReporter.setEnabled), is off by default in the manifest (firebase_crashlytics_collection_enabled=false), and stays off in debug builds regardless of the setting.google_analytics_adid_collection_enabled=false) and theAD_IDpermission is removed from the merged manifest.SecretRedactionnow also strips the credential behind aBasicAuthorization header, everyCookiepair, quoted JSON credential fields, env-style key names (ANTHROPIC_API_KEY,refresh_token) and URL userinfo.#387 — copy unsupported attachments into the workspace
Providers reject file parts outside images/PDF (
'file part media type application/zip' functionality not supported), so a zip could not be sent at all. When the composer attaches such a MIME and the current runtime is the on-device one (BackendKind.LOCAL, whose/workspaceis a real local mount), the file is copied to<workspace>/.andcode-attachments/and referenced by path in the prompt text instead. Images/PDFs still go as file parts, and a remote runtime is unaffected — it still receives the attachment directly, since there is no local mount to copy into.hostWorkspacere-checks the resolved path so a..segment cannot escape the workspace root.Notes / trade-offs
text/plainis treated as non-sendable and therefore path-referenced, not inlined.detekt,spotlessCheck,:app:testGithubDebugUnitTest(1350 tests),:app:lintGithubDebug,:app:compileFdroidDebugKotlin, and the i18n key-parity check. CI builds/assembles the rest.Closes #386
Closes #387
Pre-PR review
判定: APPROVE
ブロッカー
提案(非ブロッキング)
app/src/main/java/com/yugahashimoto/andcode/ui/AndCodeApp.kt:544/app/src/main/java/com/yugahashimoto/andcode/feature/chat/ChatViewModel.kt:1320— ワークスペース参照ノートはモデルへのプロンプト断片ですが、同時にユーザー自身のメッセージバブル本文(userMessage.parts/outgoingText)にもそのまま表示されます。translatable="false"のため非英語ロケールでも英語表示になります。プロンプトとして英語固定なのは repo ルール通りで妥当ですが、「モデルに送る本文」と「画面に出す本文」を分けたい場合は分離を検討してください(前回承認時の既存挙動なので情報提供)。app/src/main/java/com/yugahashimoto/andcode/runtime/local/AttachmentImporter.kt:67— コピー先が<workspace>/.andcode-attachments/<name>直下で、Antigravity の.../<session>/<turn>/のような階層がありません。添付のたびにファイルが蓄積し、リポジトリの未追跡ファイルとして見え続けます。セッション別サブディレクトリかクリーンアップを検討してもよいかもしれません(非ブロッキング)。app/src/main/java/com/yugahashimoto/andcode/runtime/local/AttachmentSupport.kt:53—guestWorkspacePathはリテラル"/"で比較し、hostWorkspaceはFile.separatorを使っています。Android では等価なので実害はありませんが、軽微な不統一です。チェック済み項目
git diff origin/main...HEADを網羅確認(privacy ドキュメント・assets・manifest・両 Flavor のCrashReporter・API モデル・サニタイザ・redaction・repository・DI・ViewModel・runtime・UI・テスト)。hostWorkspaceの canonical 検証を手計算で検証。/workspace/../etc・/workspace/proj/../../etcはcandidate.canonicalPathが root 外になりnull(attachmentは従来通り送信にフォールバック)。/workspace・/workspace/proj・/workspace/proj/はassertEqualsを満たす。canonicalPathが例外を投げる場合はrunCatching{}.getOrNull()→null(fail-safe)。relativeはtrim('/')で先頭/を除去するため絶対パス注入は不可。ガードは妥当。analytics_row(テキスト変更)と新規chat_workspace_attachment_noteはいずれもtranslatable="false"でvalues/strings.xmlのみに存在 →i18n-check.yml(non-translatable 除外ロジック)は通る。他ロケールに重複定義なし。ハードコード文字列なし(ViewModel は英語デフォルト注入、ViewModelModule/AndCodeAppの両構築経路でgetStringを注入済み)。CrashReporterにsetEnabled・recordRuntimeSessionErrorを追加。install()は常に false、setEnabledはenabled && !DEBUG。AndCodeApplicationでinstall()→setEnabled(settings.analyticsEnabled)の順を確認。AppPreferencesRepository.setAnalyticsEnabledを更新。xmlns:tools宣言済みで AD_ID のtools:node="remove"、firebase_crashlytics_collection_enabled=false、google_analytics_adid_collection_enabled=falseを追加。妥当。RuntimeActivityRepositoryのonSessionErrorを(sessionId, message, errorType, runtimeId)に変更し全呼び出し元(Application/AppModule/テスト)を更新。CrashReportSanitizer.errorCategoryは識別子形状のみ採用(SAFE_TYPE不一致はunknown)。recordExceptionを生メッセージで呼ぶ箇所が他に無いことを確認。PromptAttachment.workspacePathを追加したが、API 送信ボディはOpenCodeApiClient/OpenCodeV2ApiClientでbuildJsonObjectにより mime/filename/url のみを手組みするため、workspacePathがワイヤに出ない(encodeDefaults=trueでも無関係)。退行なし。ワークスペース添付は送信前にpartitionで除外されmodelAttachmentsのみ送信。key:value/引用符付き JSON、URL userinfo)を既存・追加テストの入力で手計算し、既存テストの期待(<redacted>含有、通常文非改変、クエリ除去)を壊さないことを確認。破滅的バックトラックの懸念なし。ChatViewModel(backend, workspaceAttachmentNoteTemplate=...)の名前付き引数はコンストラクタ定義(最後のデフォルト引数)と整合。変更ファイルに行長 >140 なし(.editorconfigで ktlint max-line-length は無効、detekt 140)。hostWorkspaceの return は 4(detektReturnCountmax=4 以内)、新規の関数数・複雑度も閾値内。