Conversation
This reverts commit 98b3340.
This reverts commit 546748a.
The stale-issues workflow was hitting the default 30 operations limit, preventing it from processing all 2900+ issues/PRs. Increased to 1000 to handle the full backlog. Also pinned to exact v10.2.0 for reproducibility.
- Create script/github/close-issues.ts to close stale issues after 60 days - Add GitHub Action workflow to run daily at 2 AM - Remove old stale-issues workflow to avoid conflicts
- Add contents: read permission for checkout - Use github.token instead of secrets.GITHUB_TOKEN
…f instance is global) (anomalyco#19058)
This reverts commit a379eb3.
This reverts commit cbe1337.
This reverts commit 898456a.
…ls (anomalyco#16952) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Nate Williams <50088025+natewill@users.noreply.github.com>
…lyco#20695) process.memoryUsage().rss underreports ~60x in Bun on Linux because bmalloc mmap regions aren't counted. Read /proc/self/statm instead so the 2 GB snapshot threshold actually fires. Falls back to process.memoryUsage().rss on non-Linux. Per sjawhar's megathread analysis: anomalyco#20695
…S bloat (anomalyco#20695) FileDiff.before/after store full file contents as strings. Persisting them in the summary_diffs JSON column caused in-memory retention on every Session.get(). sjawhar measured 22 copies of one 20 MB JSON file = 440 MB from a single file. Full diffs still persist to session_diff file storage via storage.write([session_diff, sessionID], diffs) and are retrievable on demand via Session.diff(sessionID). The column is kept in the schema for backwards compatibility but we now always write null. Message-level message.summary.diffs (different code path) untouched; UI consumers (session-turn, message-nav, session.tsx) use that path. Ref: anomalyco#20695
Previously Log.init() called fs.truncate() on dev.log at every startup, destroying the prior session's logs. When opencode crashed with a bun int3 trap, restart wiped the evidence within seconds. Now in dev mode we rotate dev.log to dev.log.<timestamp> instead. Cleanup trims rotated files to the most recent 10 (matching the existing policy for timestamped production logs). Related: bun allocator assertion crashes in anomalyco#20695 megathread.
|
Important Review skippedToo many files! This PR contains 296 files, which is 146 over the limit of 150. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (4)
📒 Files selected for processing (296)
You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Hey! Your PR title Please update it to start with one of:
Where See CONTRIBUTING.md for details. |
|
This PR doesn't fully meet our contributing guidelines and PR template. What needs to be fixed:
Please edit this PR description to address the above within 2 hours, or it will be automatically closed. If you believe this was flagged incorrectly, please let a maintainer know. |
There was a problem hiding this comment.
Code Review
This pull request introduces extensive updates across the repository, including a major refactor of the application's startup and synchronization logic, the addition of a performance debug bar, and improved terminal reconnection handling. It also expands internationalization support with new translations and glossaries, updates core dependencies like the AI SDK and Drizzle, and establishes a specification for simplifying reactive effects. Feedback was provided regarding a syntax error in a Tailwind CSS selector within the server selection dialog.
| } | ||
| : undefined | ||
| } | ||
| class="px-5 [&_[data-slot=list-search-wrapper]]:w-full [&_[data-slot=list-scroll]]h-[300px] [&_[data-slot=list-scroll]]:overflow-y-auto [&_[data-slot=list-items]]:bg-surface-base [&_[data-slot=list-items]]:rounded-md [&_[data-slot=list-item]]:min-h-14 [&_[data-slot=list-item]]:p-3 [&_[data-slot=list-item]]:!bg-transparent" |
There was a problem hiding this comment.
There is a syntax error in the Tailwind arbitrary value selector. A colon is missing before h-[300px]. It should be [&_[data-slot=list-scroll]]:h-[300px] (or max-h if the previous behavior was intended) to correctly target the nested element.
| class="px-5 [&_[data-slot=list-search-wrapper]]:w-full [&_[data-slot=list-scroll]]h-[300px] [&_[data-slot=list-scroll]]:overflow-y-auto [&_[data-slot=list-items]]:bg-surface-base [&_[data-slot=list-items]]:rounded-md [&_[data-slot=list-item]]:min-h-14 [&_[data-slot=list-item]]:p-3 [&_[data-slot=list-item]]:!bg-transparent" | |
| class="px-5 [&_[data-slot=list-search-wrapper]]:w-full [&_[data-slot=list-scroll]]:h-[300px] [&_[data-slot=list-scroll]]:overflow-y-auto [&_[data-slot=list-items]]:bg-surface-base [&_[data-slot=list-items]]:rounded-md [&_[data-slot=list-item]]:min-h-14 [&_[data-slot=list-item]]:p-3 [&_[data-slot=list-item]]:!bg-transparent" |
…nomalyco#20695) Live-caught crash @ 2026-04-21T00:17:07Z: RSS=4.03 GB after 60 s of runtime on session resume. Our auto-heap-snapshot fired and produced a 646 MB + 413 MB pair before a bun int3 assertion killed the process 8 min later. Root cause: /session/<id>/diff is fetched 45 times at TUI startup (once per session in sidebar) and each fetch loads a Snapshot.FileDiff[] with full before/after file contents. Disk measured 6.5 GB across 7438 session_diff files, largest 2.1 GB with 780 before/after string pairs. Per Oracle recommendation: 1. sync.tsx: drop session.diff() from the per-session eager Promise.all; bus events still populate the store reactively when diffs actually change. The TUI itself never renders diffs (only the plugin API reads them), so there's no user-visible regression. 2. Snapshot.capFileDiffs(): replace before/after with empty strings when either field exceeds 256 KB. UI (file.tsx large() threshold @ 500 K chars) already disables line-level diffing past that anyway; empty strings integrate cleanly with session-review.tsx's beforeText().length === 0 added/deleted check. 3. Applied at write time in summary.ts:122 + revert.ts:78 BEFORE both storage.write() and bus.publish() so cached UI state never sees the uncapped form. 4. Applied at read time in Session.diff() + SessionSummary.diff() so the existing 6.5 GB of legacy data on disk is capped progressively on first access without needing a migration script. Skipped PR anomalyco#21244 (unified-patch storage): the @pierre/diffs FileDiff component requires full before/after strings, so reconstructing at render time would restore the memory spike. Capping at the source is simpler, doesn't diverge further from upstream, and remains compatible with a future anomalyco#21244 port. Ref: anomalyco#20695
… diff pipeline FileDiff schema gains patch?: string. computeDiff now generates a unified diff string via createTwoFilesPatch for each non-binary file diff. Binary files skip patch generation (patch: undefined). The patch field enables @pierre/diffs patch-mode rendering (isPartial: true) which uses ~5-10% of the memory vs full before/after strings. FIELD_CAP comment updated to document its defense-in-depth role. Ref: anomalyco#20695
DiffViewer and DiffSSRViewer now check for a patch prop. When present,
getSingularPatch() parses it into a FileDiffMetadata (isPartial: true)
and passes it directly to FileDiff.render()/hydrate() — no full file
contents needed. Falls back to oldFile/newFile on parse error or when
patch is absent (legacy data).
session-review.tsx passes patch={item().patch} through to File component.
SDK types regenerated to include patch field.
Ref: anomalyco#20695
9 unit tests (capFileDiffs with/without patch, boundary, mixed arrays) 4 integration tests (large file pipeline, patch size savings, mixed array, JSON roundtrip). All verify getSingularPatch produces valid isPartial FileDiffMetadata from the generated patches. Ref: anomalyco#20695
|
This pull request has been automatically closed because it was not updated to meet our contributing guidelines within the 2-hour window. Feel free to open a new pull request that follows our guidelines. |
Pull Request Summary by devActivityMetricsAchievements
|
…o#20695) Bun 1.3.13-canary's default SIGINT/SIGTERM handler crashes with SIGSEGV at 0xF038EC when opentui's FFI JSCallback objects are torn down during process exit. Classic N-API-style UAF — the Zig side holds raw function pointers into JSCallback thunks that get freed during bun's exit cleanup, triggering a jump into non-executable .eh_frame memory. Install explicit SIGINT/SIGTERM/SIGHUP handlers that: 1. Restore terminal state (raw-mode off, alt-buffer exit, show cursor, disable mouse tracking modes) 2. Call process.exit() immediately with the correct signal exit code This bypasses bun's default exit path before the FFI teardown can crash. Verified via reliable reproducer (session ses_253dacbc... + SIGINT after 15s): pre-patch crashed deterministically at 0xF038EC; post-patch exits cleanly with code 130. Related bun issues: - oven-sh/bun#27471 (N-API vtable corruption) - oven-sh/bun#27003 (N-API cleanup race) - oven-sh/bun#29412 (DFG JIT crash) Ref: anomalyco#20695
Pull Request Summary by devActivityMetricsAchievements
|
There was a problem hiding this comment.
AI Code Review by LlamaPReview
🎯 TL;DR & Recommendation
Recommendation: Request Changes
This PR introduces a critical CI-breaking syntax error in the test workflow configuration, which will cause all subsequent runs to fail immediately. Additionally, it expands signing and Electron build pipelines with increased complexity that risks configuration errors.
🌟 Strengths
- Proactively denies agent edits to migration files, enhancing security.
- Updates team assignments and tool logic to reflect current availability.
| Priority | File | Category | Impact Summary (≤12 words) | Anchors |
|---|---|---|---|---|
| P0 | .github/workflows/test.yml |
Bug | Broken CI due to invalid GitHub Actions syntax causing workflow failures. | |
| P2 | .github/.../docs-locale-sync.yml |
Maintainability | Overly permissive agent permissions could allow unintended file edits. | |
| P2 | .opencode/tool/github-triage.ts |
Maintainability | Default assignee and override logic may confuse users for web issues. | |
| P2 | .opencode/opencode.jsonc |
Security | Denies agent edits to migration files, preventing data corruption. | |
| P2 | .github/workflows/publish.yml |
Architecture | Complex signing and Electron steps increase risk of configuration errors. | path:setup-bun/action.yml |
🔍 Notable Themes
- CI/CD Configuration Stability: The P0 syntax error and the expanded signing workflow introduce immediate and latent risks to build reliability.
- Agent Security and Clarity: Permission changes and tool updates improve security but require validation to avoid unintended access or user confusion.
📈 Risk Diagram
This diagram illustrates the immediate workflow failure due to the invalid concurrency group syntax.
sequenceDiagram
participant GA as GitHub Actions
participant WF as Workflow Runner
GA->>WF: Trigger test workflow
WF->>WF: Parse concurrency group expression
note over WF: R1(P0): Invalid 'case' function causes syntax error
WF-->>GA: Workflow fails immediately
⚠️ **Unanchored Suggestions (Manual Review Recommended)**
The following suggestions could not be precisely anchored to a specific line in the diff. This can happen if the code is outside the changed lines, has been significantly refactored, or if the suggestion is a general observation. Please review them carefully in the context of the full file.
📁 File: .github/workflows/docs-locale-sync.yml
Speculative: The workflow now directly invokes the opencode CLI via a shell command, replacing the previous dedicated GitHub Action (sst/opencode/github). This increases flexibility but also introduces new dependencies: the opencode CLI must be installed (via a prior curl command) and the OPENCODE_API_KEY must be valid. The permission configuration has been drastically simplified from a granular, deny-by-default policy to an allow-all policy ("read": "allow", "edit": "allow", ...). This could inadvertently grant the agent broader access than intended during translation tasks, potentially allowing modifications outside the target locale directories. While no immediate breakage is certain, the change represents a significant relaxation of security controls and should be reviewed to ensure it aligns with the principle of least privilege.
Related Code:
- name: Sync locale docs with OpenCode
if: steps.changes.outputs.has_changes == 'true'
env:
OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
OPENCODE_CONFIG_CONTENT: |
{
"permission": {
"*": "deny",
"read": "allow",
"edit": "allow",
"glob": "allow",
"task": "allow"
}
}
run: |
opencode run --agent docs --model opencode/gpt-5.3-codex <<'EOF'
Update localized docs to match the latest English docs changes.
...
EOF📁 File: .opencode/tool/github-triage.ts
The github-triage tool's team list has been updated, notably adding rekram1-node back to the tui and core teams and setting them as the new default assignee. This change aligns with the PR description's note "rekram1-node is no longer on vacation." However, the tool's logic for assigning web issues (line 68) has also been adjusted: const assignee = nix ? "rekram1-node" : web ? pick(TEAM.desktop) : args.assignee. This means for a web issue (non-nix), the assignee will be randomly picked from the desktop team, overriding the user-provided or default args.assignee. This behavior may be intentional but is non-obvious; a user specifying an assignee for a web issue will be ignored. The interaction between the default assignee and the web/nix override logic should be documented or made explicit in the tool's description.
Related Code:
const TEAM = {
desktop: ["adamdotdevin", "iamdavidhill", "Brendonovich", "nexxeln"],
zen: ["fwang", "MrMushrooooom"],
tui: ["thdxr", "kommander", "rekram1-node"],
core: ["thdxr", "rekram1-node", "jlongster"],
docs: ["R44VC0RP"],
windows: ["Hona"],
} as const
// ...
args: {
assignee: tool.schema
.enum(ASSIGNEES as [string, ...string[]])
.describe("The username of the assignee")
.default("rekram1-node"),💡 Have feedback? We'd love to hear it in our GitHub Discussions.
✨ This review was generated by LlamaPReview Advanced, which is free for all open-source projects. Learn more.
| concurrency: | ||
| # Keep every run on dev so cancelled checks do not pollute the default branch | ||
| # commit history. PRs and other branches still share a group and cancel stale runs. | ||
| group: ${{ case(github.ref == 'refs/heads/dev', format('{0}-{1}', github.workflow, github.run_id), format('{0}-{1}', github.workflow, github.event.pull_request.number || github.ref)) }} | ||
| cancel-in-progress: true |
There was a problem hiding this comment.
P0 | Confidence: High
The concurrency.group expression uses a non-existent case function in GitHub Actions. The GitHub Actions expression language does not support a case function; valid functions include format, contains, startsWith, endsWith, fromJSON, toJSON, etc. This syntax error will cause the workflow to fail immediately on any trigger, breaking all CI runs for the test workflow. The intended logic is to create a unique group for each run on the dev branch (to avoid cancellation) and a shared group for PRs/other branches. The expression must be rewritten using conditional logic (e.g., using the ternary operator ? : or separate if conditions).
| concurrency: | |
| # Keep every run on dev so cancelled checks do not pollute the default branch | |
| # commit history. PRs and other branches still share a group and cancel stale runs. | |
| group: ${{ case(github.ref == 'refs/heads/dev', format('{0}-{1}', github.workflow, github.run_id), format('{0}-{1}', github.workflow, github.event.pull_request.number || github.ref)) }} | |
| cancel-in-progress: true | |
| concurrency: | |
| group: ${{ github.ref == 'refs/heads/dev' && format('{0}-{1}', github.workflow, github.run_id) || format('{0}-{1}', github.workflow, github.event.pull_request.number || github.ref) }} | |
| cancel-in-progress: true |
| - name: Azure login | ||
| if: runner.os == 'Windows' | ||
| uses: azure/login@v2 | ||
| with: | ||
| client-id: ${{ env.AZURE_CLIENT_ID }} | ||
| tenant-id: ${{ env.AZURE_TENANT_ID }} | ||
| subscription-id: ${{ env.AZURE_SUBSCRIPTION_ID }} |
There was a problem hiding this comment.
P2 | Confidence: Medium
Speculative: The publish workflow has undergone a substantial expansion to integrate Azure artifact signing for Windows CLI and Electron builds, and to add Electron as a new desktop target. While the changes appear comprehensive, the increased complexity (over 300 lines added) and introduction of new external dependencies (Azure services, electron-builder) heighten the risk of configuration errors, especially in conditional steps across multiple OS targets. For example, the OPENCODE_CLI_ARTIFACT environment variable logic (${{ (runner.os == 'Windows' && 'opencode-cli-windows') || 'opencode-cli' }}) must correctly correspond to the uploaded artifact names. A mismatch could cause builds to fail or use unsigned binaries. Furthermore, the workflow now runs on multiple runner types (including windows-2025 for ARM64), which may have different toolchains or environment defaults. These changes should be validated with a dry-run on a non-production branch to ensure all signing and packaging steps execute correctly across all matrix combinations.
| @@ -5,6 +5,11 @@ | |||
| "options": {}, | |||
There was a problem hiding this comment.
[Contextual Comment]
This comment refers to code near real line 1. Anchored to nearest_changed(5) line 5.
P2 | Confidence: High
A new deny rule has been added to prevent edits to migration files (packages/opencode/migration/*). This is a proactive security and stability measure to prevent agents from accidentally modifying database migration scripts, which could lead to data corruption or broken deployments. The change is well-scoped and follows the principle of least privilege. No negative impact is expected, as migrations are typically auto-generated and should not be manually edited by agents.
…mory telemetry (anomalyco#20695) Follow-up to PR #5. Heap dump analysis (PID 723876, 10 pre/post-GC pairs) showed closure allocations from registry.tools() consuming memory faster than GC could reclaim under rapid LLM messaging. Changes: - tool/registry.ts: cache tool.init({agent}) result per (toolID, agent.name) in InstanceState. Before: every ToolRegistry.tools() call allocated 17+ fresh wrapper closures via tool.init. After: init runs once per (tool, agent), closures reused across messages. - tool/registry.ts: register() now invalidates init cache for the updated tool id so plugin reloads propagate. - snapshot/index.ts: capFileDiffs now logs when it fires (capped count, saved bytes, retained bytes) so oversized sessions are visible in dev.log. Threshold: any capping event OR >500 diffs OR >64 MB retained. - app session-cache.ts: new sessionDiffStats() + warnOversizedSessionDiff() helpers. Logs sessions exceeding 500 diffs or 64 MB. dropSessionCaches() logs total MB freed when eviction reclaims >16 MB. - script/heap-analyze.ts: new CLI for retention analysis on existing .heapsnapshot files. Computes node-type histogram, top-N largest retained objects, closure name distribution, top-N most-referenced nodes, top-N string frequencies. Run: bun run script/heap-analyze.ts <path> [topN=20]. Verified: bun typecheck clean on opencode+app. 49 tests pass (snapshot patch-mode + pipeline, tool-define, registry, global-sync). Note: LEAK A (session_diff cache) was verified already-mitigated by PR #5's capFileDiffs + patch-mode (5-10% of raw). Telemetry added defensively. LEAK B (closure allocation) is addressed by the init cache here.
sessiontable (feat(core): add workspace_id tosessiontable anomalyco/opencode#15410)run --attachagent validation (fix:run --attachagent validation anomalyco/opencode#11812)run --attach(fix(opencode): pass missing auth headers inrun --attachanomalyco/opencode#16097)workspaceIDinto session create endpoint (feat(core): allow passingworkspaceIDinto session create endpoint anomalyco/opencode#16798)base64Decodeimport in workspaces.spec.ts (Fixbase64Decodeimport in workspaces.spec.ts anomalyco/opencode#18274)Summary by cubic
Fix critical memory leaks and add automatic heap snapshots to keep
opencode, the CLI, and the TUI/server stable under heavy load. Addresses Linear 20695 by measuring RSS correctly on Linux and reducing session memory pressure.Bug Fixes
summary_diffscolumn to eliminate RSS bloat.dev.logacross restarts for crash forensics.Performance
diffFullsnapshot blob reads to reduce memory spikes.Written for commit 354ef97. Summary will update on new commits.