Skip to content

feat: deep-merge opencode config via modify_ scripts - #860

Merged
yxtay merged 5 commits into
mainfrom
feat/opencode-modify-merge
Jul 3, 2026
Merged

feat: deep-merge opencode config via modify_ scripts#860
yxtay merged 5 commits into
mainfrom
feat/opencode-modify-merge

Conversation

@yxtay

@yxtay yxtay commented Jul 3, 2026

Copy link
Copy Markdown
Owner

Summary

  • Convert opencode.json and tui.json from create_ (write-once) to modify_ scripts that deep-merge managed config into any existing local file
  • Base JSON moved to .chezmoitemplates/ for easy diffing; modify_ scripts parse stdin + template and mergeOverwrite
  • Preserves local-only keys (e.g. extra MCP servers) while managed keys win on conflict

Notes

  • modify_ scripts must not carry a .tmpl extension — the chezmoi:modify-template marker is only honored on modify scripts; .tmpl makes chezmoi treat it as a regular template and exec the output (exec format error)
  • Arrays (plugin, mcp.*.command) are replaced wholesale by mergeOverwrite, not element-merged
  • {{- if .chezmoi.stdin -}} guard required: target-absent → empty stdin → fromJson "" errors

Test

chezmoi cat ~/.config/opencode/{opencode,tui}.json renders merged output; local codebase-memory-mcp entry survives.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Improved configuration updates to merge existing settings with new defaults, helping preserve customizations when config files are regenerated.
    • Added support for cleaner, formatted JSON output during config generation.

Convert opencode.json and tui.json from create_ (write-once) to
modify_ scripts that deep-merge the managed config into any existing
local file. Base JSON lives in .chezmoitemplates for easy diffing;
modify_ scripts parse stdin + template and mergeOverwrite.

Preserves local-only keys (e.g. extra mcp servers) while letting
managed keys win on conflict.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@yxtay, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 48 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 5cf88f5b-e63b-4a14-988c-f1de4ea32dbf

📥 Commits

Reviewing files that changed from the base of the PR and between 0861f18 and b17e7a4.

📒 Files selected for processing (4)
  • chezmoi/private_dot_claude/modify_CLAUDE.md
  • chezmoi/private_dot_config/opencode/modify_AGENTS.md
  • chezmoi/private_dot_config/opencode/modify_opencode.json
  • chezmoi/private_dot_config/opencode/modify_tui.json
📝 Walkthrough

Walkthrough

This PR adds two new chezmoi modify-template files for opencode configuration: modify_opencode.json and modify_tui.json. Each template optionally merges JSON provided via stdin into the base template output, using mergeOverwrite, then renders the result as pretty-printed JSON.

Changes

Modify-template additions

Layer / File(s) Summary
Stdin-merging modify templates
chezmoi/private_dot_config/opencode/modify_opencode.json, chezmoi/private_dot_config/opencode/modify_tui.json
Each file adds a chezmoi modify-template that optionally parses stdin JSON, loads the corresponding base config template's JSON, deep-merges via mergeOverwrite, and outputs pretty-printed JSON.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Poem

Two little templates, hopping in line,
Merging stdin whispers with JSON so fine,
mergeOverwrite blends what once stood apart,
Pretty-printed output, a tidy rabbit art. 🐇
Config carrots, freshly stacked!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: switching opencode config to deep-merge via modify_ scripts.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/opencode-modify-merge

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

⚠️MegaLinter analysis: Success with warnings

Descriptor Linter Files Fixed Errors Warnings Elapsed time
✅ BASH shfmt 3 0 0 0 0.02s
⚠️ JSON prettier 6 0 1 0 0.36s
⚠️ MARKDOWN markdownlint 7 0 2 0 0.65s
✅ MARKDOWN markdown-table-formatter 7 0 0 0 0.17s
✅ YAML prettier 10 0 0 0 0.5s

Detailed Issues

⚠️ MARKDOWN / markdownlint - 2 errors
chezmoi/private_dot_claude/modify_CLAUDE.md:1 error MD041/first-line-heading/first-line-h1 First line in a file should be a top-level heading [Context: "{{- /*chezmoi:modify-template*..."]
chezmoi/private_dot_config/opencode/modify_AGENTS.md:1 error MD041/first-line-heading/first-line-h1 First line in a file should be a top-level heading [Context: "{{- /*chezmoi:modify-template*..."]
⚠️ JSON / prettier - 1 error
chezmoi/.chezmoitemplates/opencode.json 52ms (unchanged)
chezmoi/.chezmoitemplates/tui.json 2ms (unchanged)
chezmoi/private_dot_config/mcp/mcp_servers.json 4ms (unchanged)
[error] chezmoi/private_dot_config/opencode/modify_opencode.json: SyntaxError: Unexpected token (1:2)
[error] > 1 | {{- /* chezmoi:modify-template */ -}}
[error]     |  ^
[error]   2 | {{- $current := dict -}}
[error]   3 | {{- if .chezmoi.stdin | trim -}}
[error]   4 | {{-   $current = fromJson .chezmoi.stdin -}}
[error] chezmoi/private_dot_config/opencode/modify_tui.json: SyntaxError: Unexpected token (1:2)
[error] > 1 | {{- /* chezmoi:modify-template */ -}}
[error]     |  ^
[error]   2 | {{- $current := dict -}}
[error]   3 | {{- if .chezmoi.stdin | trim -}}
[error]   4 | {{-   $current = fromJson .chezmoi.stdin -}}
renovate.json 5ms (unchanged)

Notices

📣 MegaLinter 9.5.0 is out! Discover the new features and security recommendations in the release announcement. (Skip this info by defining SECURITY_SUGGESTIONS: false)

See detailed reports in MegaLinter artifacts

Your project could benefit from a custom flavor, which would allow you to run only the linters you need, and thus improve runtime performances. (Skip this info by defining FLAVOR_SUGGESTIONS: false)

  • Documentation: Custom Flavors
  • Command: npx mega-linter-runner@9.5.0 --custom-flavor-setup --custom-flavor-linters BASH_SHFMT,JSON_PRETTIER,MARKDOWN_MARKDOWNLINT,MARKDOWN_MARKDOWN_TABLE_FORMATTER,YAML_PRETTIER

MegaLinter is graciously provided by OX Security
Show us your support by starring ⭐ the repository

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

⚠️MegaLinter analysis: Success with warnings

Descriptor Linter Files Fixed Errors Warnings Elapsed time
✅ BASH bash-exec 3 0 0 0.01s
✅ BASH shellcheck 3 0 0 0.1s
✅ REPOSITORY checkov yes no no 22.43s
✅ REPOSITORY devskim yes no no 2.0s
✅ REPOSITORY dustilock yes no no 0.03s
✅ REPOSITORY gitleaks yes no no 1.73s
✅ REPOSITORY grype yes no no 48.88s
✅ REPOSITORY kingfisher yes no no 9.38s
⚠️ REPOSITORY osv-scanner yes 1 no 0.13s
✅ REPOSITORY secretlint yes no no 2.15s
✅ REPOSITORY syft yes no no 2.09s
✅ REPOSITORY trivy yes no no 10.18s
✅ REPOSITORY trivy-sbom yes no no 0.13s
✅ REPOSITORY trufflehog yes no no 3.86s

Detailed Issues

⚠️ REPOSITORY / osv-scanner - 1 error
Scanning dir .
Starting filesystem walk for root: /
End status: 43 dirs visited, 141 inodes visited, 0 Extract calls, 2.822545ms elapsed, 2.822714ms wall time
No package sources found, --help for usage information.

Notices

📣 MegaLinter 9.5.0 is out! Discover the new features and security recommendations in the release announcement. (Skip this info by defining SECURITY_SUGGESTIONS: false)

See detailed reports in MegaLinter artifacts

Your project could benefit from a custom flavor, which would allow you to run only the linters you need, and thus improve runtime performances. (Skip this info by defining FLAVOR_SUGGESTIONS: false)

  • Documentation: Custom Flavors
  • Command: npx mega-linter-runner@9.5.0 --custom-flavor-setup --custom-flavor-linters BASH_EXEC,BASH_SHELLCHECK,REPOSITORY_CHECKOV,REPOSITORY_DEVSKIM,REPOSITORY_DUSTILOCK,REPOSITORY_GITLEAKS,REPOSITORY_GRYPE,REPOSITORY_OSV_SCANNER,REPOSITORY_SECRETLINT,REPOSITORY_SYFT,REPOSITORY_TRIVY,REPOSITORY_TRIVY_SBOM,REPOSITORY_TRUFFLEHOG,REPOSITORY_KINGFISHER

MegaLinter is graciously provided by OX Security
Show us your support by starring ⭐ the repository

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces two new chezmoi modify-template scripts (modify_opencode.json and modify_tui.json) to merge local configurations with template defaults. The review feedback highlights a potential parsing error when .chezmoi.stdin contains only whitespace or newlines, and suggests trimming the input before checking and parsing it as JSON.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread chezmoi/private_dot_config/opencode/modify_opencode.json Outdated
Comment thread chezmoi/private_dot_config/opencode/modify_tui.json Outdated
@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

⚠️MegaLinter analysis: Success with warnings

Descriptor Linter Files Fixed Errors Warnings Elapsed time
✅ ACTION actionlint 5 0 0 0.27s
✅ ACTION zizmor 5 0 0 0 0.59s
✅ BASH bash-exec 3 0 0 0.01s
✅ BASH shellcheck 3 0 0 0.16s
✅ BASH shfmt 3 0 0 0 0.02s
✅ COPYPASTE jscpd yes no no 0.85s
✅ EDITORCONFIG editorconfig-checker 67 0 0 0.14s
⚠️ JSON prettier 6 0 1 0 0.87s
✅ JSON v8r 6 0 0 3.62s
⚠️ MARKDOWN markdownlint 7 0 2 0 0.67s
✅ MARKDOWN markdown-table-formatter 7 0 0 0 0.24s
✅ REPOSITORY checkov yes no no 22.4s
✅ REPOSITORY gitleaks yes no no 1.65s
✅ REPOSITORY git_diff yes no no 0.08s
✅ REPOSITORY grype yes no no 47.77s
⚠️ REPOSITORY osv-scanner yes 1 no 0.2s
✅ REPOSITORY secretlint yes no no 1.5s
✅ REPOSITORY syft yes no no 3.87s
✅ REPOSITORY trivy yes no no 9.9s
✅ REPOSITORY trivy-sbom yes no no 0.15s
✅ REPOSITORY trufflehog yes no no 3.65s
⚠️ SPELL lychee 23 2 0 0.96s
✅ YAML prettier 10 0 0 0 0.66s
✅ YAML v8r 10 0 0 8.2s
✅ YAML yamllint 10 0 0 0.5s

Detailed Issues

⚠️ SPELL / lychee - 2 errors
📝 Summary
---------------------
🔍 Total...........20
🔗 Unique..........15
✅ Successful......18
⏳ Timeouts.........0
🔀 Redirected.......3
👻 Excluded.........0
❓ Unknown..........0
🚫 Errors...........2
⛔ Unsupported......2

Errors in chezmoi/.chezmoitemplates/opencode.json
[406] https://mcp.deepwiki.com/mcp (at 23:15) | Rejected status code: 406 Not Acceptable

Errors in chezmoi/private_dot_config/mcp/mcp_servers.json
[406] https://mcp.deepwiki.com/mcp (at 11:15) | Rejected status code: 406 Not Acceptable

Hint: Followed 3 redirects. You might want to consider replacing redirecting URLs with the resolved URLs. Use verbose mode (`-v`/`-vv`) to see redirection details.
Hint: You can configure accepted/rejected response codes with `-a` or `--accept`
⚠️ MARKDOWN / markdownlint - 2 errors
chezmoi/private_dot_claude/modify_CLAUDE.md:1 error MD041/first-line-heading/first-line-h1 First line in a file should be a top-level heading [Context: "{{- /*chezmoi:modify-template*..."]
chezmoi/private_dot_config/opencode/modify_AGENTS.md:1 error MD041/first-line-heading/first-line-h1 First line in a file should be a top-level heading [Context: "{{- /*chezmoi:modify-template*..."]
⚠️ REPOSITORY / osv-scanner - 1 error
Scanning dir .
Starting filesystem walk for root: /
End status: 43 dirs visited, 141 inodes visited, 0 Extract calls, 6.384509ms elapsed, 6.384719ms wall time
No package sources found, --help for usage information.
⚠️ JSON / prettier - 1 error
chezmoi/.chezmoitemplates/opencode.json 109ms (unchanged)
chezmoi/.chezmoitemplates/tui.json 3ms (unchanged)
chezmoi/private_dot_config/mcp/mcp_servers.json 3ms (unchanged)
[error] chezmoi/private_dot_config/opencode/modify_opencode.json: SyntaxError: Unexpected token (1:2)
[error] > 1 | {{- /* chezmoi:modify-template */ -}}
[error]     |  ^
[error]   2 | {{- $current := dict -}}
[error]   3 | {{- if .chezmoi.stdin | trim -}}
[error]   4 | {{-   $current = fromJson .chezmoi.stdin -}}
[error] chezmoi/private_dot_config/opencode/modify_tui.json: SyntaxError: Unexpected token (1:2)
[error] > 1 | {{- /* chezmoi:modify-template */ -}}
[error]     |  ^
[error]   2 | {{- $current := dict -}}
[error]   3 | {{- if .chezmoi.stdin | trim -}}
[error]   4 | {{-   $current = fromJson .chezmoi.stdin -}}
renovate.json 9ms (unchanged)

Notices

📣 MegaLinter 9.5.0 is out! Discover the new features and security recommendations in the release announcement. (Skip this info by defining SECURITY_SUGGESTIONS: false)

See detailed reports in MegaLinter artifacts

Your project could benefit from a custom flavor, which would allow you to run only the linters you need, and thus improve runtime performances. (Skip this info by defining FLAVOR_SUGGESTIONS: false)

  • Documentation: Custom Flavors
  • Command: npx mega-linter-runner@9.5.0 --custom-flavor-setup --custom-flavor-linters ACTION_ACTIONLINT,ACTION_ZIZMOR,BASH_EXEC,BASH_SHELLCHECK,BASH_SHFMT,COPYPASTE_JSCPD,EDITORCONFIG_EDITORCONFIG_CHECKER,JSON_V8R,JSON_PRETTIER,MARKDOWN_MARKDOWNLINT,MARKDOWN_MARKDOWN_TABLE_FORMATTER,REPOSITORY_CHECKOV,REPOSITORY_GIT_DIFF,REPOSITORY_GITLEAKS,REPOSITORY_GRYPE,REPOSITORY_OSV_SCANNER,REPOSITORY_SECRETLINT,REPOSITORY_SYFT,REPOSITORY_TRIVY,REPOSITORY_TRIVY_SBOM,REPOSITORY_TRUFFLEHOG,SPELL_LYCHEE,YAML_PRETTIER,YAML_YAMLLINT,YAML_V8R

MegaLinter is graciously provided by OX Security
Show us your support by starring ⭐ the repository

yxtay and others added 4 commits July 3, 2026 12:25
Whitespace-only local config (e.g. "\n") is non-empty so passed the
guard but broke fromJson. Trim before the check and parse the
trimmed value.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fromJson tolerates surrounding whitespace, so trimming the guard
alone is enough to reject whitespace-only input; parse raw stdin.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added size/M and removed size/S labels Jul 3, 2026
@yxtay
yxtay merged commit f45650a into main Jul 3, 2026
19 of 20 checks passed
@yxtay
yxtay deleted the feat/opencode-modify-merge branch July 3, 2026 04:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant