feat(cli): add interactive TUI config editor#1529
feat(cli): add interactive TUI config editor#1529WietRob wants to merge 2 commits intocode-yeongyu:devfrom
Conversation
Add new 'oh-my-opencode config' command with interactive TUI for managing:
- Agent configurations (model, category, fallback_model, permissions)
- Category settings (model, description)
- Root defaults (default_run_agent)
- Bulk operations (set model/fallback/permissions for all agents)
- Validation warnings (missing models, undefined categories)
Features:
- Uses @clack/prompts for consistent CLI UX
- Creates backup before saving (config.json.backup.{timestamp})
- Atomic config writes (temp file → rename)
- Graceful cancellation handling
- Model picker with common models + custom option
New files:
- src/cli/config/index.ts - main command and menu loop
- src/cli/config/agents.ts - agent configuration editor
- src/cli/config/categories.ts - category editor
- src/cli/config/bulk.ts - bulk operations
- src/cli/config/validation.ts - warning checks
- src/cli/config/types.ts - local types
|
Thank you for your contribution! Before we can merge this PR, we need you to sign our Contributor License Agreement (CLA). To sign the CLA, please comment on this PR with: This is a one-time requirement. Once signed, all your future contributions will be automatically accepted. I have read the CLA Document and I hereby sign the CLA You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot. |
There was a problem hiding this comment.
7 issues found across 7 files
Confidence score: 3/5
- There is some user-impacting risk in
src/cli/config/index.ts: canceling the discard prompt reloads from disk and drops unsaved in-memory edits, which could surprise users and lose changes. createBackupinsrc/cli/config/index.tsmoves the original config beforewriteConfigAtomically; if the write fails, the original path is left missing, which is a concrete configuration-loss scenario.- Several medium-severity config editor/validation inconsistencies (
src/cli/config/agents.ts,src/cli/config/types.ts,src/cli/config/validation.ts) can silently drop or fail to warn about fallback settings, adding behavioral uncertainty. - Pay close attention to
src/cli/config/index.ts,src/cli/config/agents.ts,src/cli/config/types.ts,src/cli/config/validation.ts- config editor data loss and warning/serialization mismatches.
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="src/cli/config/agents.ts">
<violation number="1" location="src/cli/config/agents.ts:251">
P2: Switching from simple to detailed bash permissions loses the existing simple value; a string permission is treated like a record so every command defaults to "ask".</violation>
</file>
<file name="src/cli/config/types.ts">
<violation number="1" location="src/cli/config/types.ts:20">
P2: The TUI editor adds a `fallback_model` field to agent overrides, but the official config schema (`AgentOverrideConfigSchema`) does not define this property. As a result, any `fallback_model` value saved by the editor will be stripped/ignored during schema validation and won’t be honored at runtime.</violation>
</file>
<file name="src/cli/config/validation.ts">
<violation number="1" location="src/cli/config/validation.ts:40">
P2: Fallback warning checks the primary model field instead of the configured fallback_model, so missing-fallback warnings are incorrect.</violation>
<violation number="2" location="src/cli/config/validation.ts:53">
P2: displayValidationWarnings ignores checkFallbackWarnings results, so "missing-fallback" warnings are never shown despite display logic for them.</violation>
</file>
<file name="src/cli/config/index.ts">
<violation number="1" location="src/cli/config/index.ts:40">
P2: createBackup uses renameSync (move) before writeConfigAtomically; if the write fails, the original config is no longer at configPath and is not restored, risking configuration loss.</violation>
<violation number="2" location="src/cli/config/index.ts:50">
P2: TUI save path re-serializes JSONC with JSON.stringify, which strips all comments/trailing commas from oh-my-opencode.jsonc files.</violation>
<violation number="3" location="src/cli/config/index.ts:169">
P2: Canceling the discard prompt restarts the editor and reloads config from disk, which drops the user's unsaved in-memory changes instead of returning to the current menu state.</violation>
</file>
Since this is your first cubic review, here's how it works:
- cubic automatically reviews your code and comments on bugs and improvements
- Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
- Ask questions if you need clarification on any suggestion
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| export type BashPermission = BashPermissionValue | Record<string, BashPermissionValue> | ||
|
|
||
| export interface AgentConfigExtended extends AgentOverrideConfig { | ||
| fallback_model?: string |
There was a problem hiding this comment.
P2: The TUI editor adds a fallback_model field to agent overrides, but the official config schema (AgentOverrideConfigSchema) does not define this property. As a result, any fallback_model value saved by the editor will be stripped/ignored during schema validation and won’t be honored at runtime.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/cli/config/types.ts, line 20:
<comment>The TUI editor adds a `fallback_model` field to agent overrides, but the official config schema (`AgentOverrideConfigSchema`) does not define this property. As a result, any `fallback_model` value saved by the editor will be stripped/ignored during schema validation and won’t be honored at runtime.</comment>
<file context>
@@ -0,0 +1,78 @@
+export type BashPermission = BashPermissionValue | Record<string, BashPermissionValue>
+
+export interface AgentConfigExtended extends AgentOverrideConfig {
+ fallback_model?: string
+}
+
</file context>
| function writeConfigAtomically(configPath: string, config: OhMyOpenCodeConfig): boolean { | ||
| try { | ||
| const tempPath = `${configPath}.tmp` | ||
| writeFileSync(tempPath, JSON.stringify(config, null, 2) + "\n") |
There was a problem hiding this comment.
P2: TUI save path re-serializes JSONC with JSON.stringify, which strips all comments/trailing commas from oh-my-opencode.jsonc files.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/cli/config/index.ts, line 50:
<comment>TUI save path re-serializes JSONC with JSON.stringify, which strips all comments/trailing commas from oh-my-opencode.jsonc files.</comment>
<file context>
@@ -0,0 +1,199 @@
+function writeConfigAtomically(configPath: string, config: OhMyOpenCodeConfig): boolean {
+ try {
+ const tempPath = `${configPath}.tmp`
+ writeFileSync(tempPath, JSON.stringify(config, null, 2) + "\n")
+ renameSync(tempPath, configPath)
+ return true
</file context>
|
🙏 thank you so much I really need this feature |
- Fix createBackup to use copyFileSync instead of renameSync Prevents config loss if write fails after moving original - Fix cancel/discard flow to preserve in-memory unsaved changes Return to menu loop instead of restarting editor - Fix bash permission switching from simple to detailed mode Preserve existing simple value as default for all commands - Fix checkFallbackWarnings to check fallback_model field Was incorrectly checking model field instead - Fix displayValidationWarnings to include fallback warnings Now combines both model and fallback warnings Addresses issues raised by @cubic-dev-ai in PR code-yeongyu#1529
|
I have read the CLA Document and I hereby sign the CLA |
|
Thanks @cubic-dev-ai for the thorough review! I've addressed all the issues in commit ca09979: Fixed Issues✅ P2: createBackup uses move instead of copy - Now uses ✅ P2: Cancel discard restarts editor, loses unsaved changes - Refactored to use ✅ P2: Bash permission switching loses existing simple value - Now detects if existing value is a string and uses it as default for all commands ✅ P2: Fallback warning checks wrong field - Fixed to check ✅ P2: displayValidationWarnings ignores checkFallbackWarnings - Now combines both Deferred⏸️ P2: JSON.stringify strips JSONC comments - This matches the existing project pattern in Regarding
|
|
Thanks @acamq! 🙏 I built this because I needed it too - manually editing JSON configs was painful. Let me know if you find any issues when testing! |
Summary
Add new
oh-my-opencode configcommand - an interactive TUI for managing oh-my-opencode configuration files.Problem
Currently, editing
oh-my-opencode.jsonrequires:~/.config/opencode/oh-my-opencode.json)Solution
An interactive TUI (using
@clack/prompts) that provides:Main Features:
default_run_agentfor theruncommandSafety Features:
config.json.backup.{timestamp}Type of Change
Testing
Files Added
src/cli/config/index.tssrc/cli/config/agents.tssrc/cli/config/categories.tssrc/cli/config/bulk.tssrc/cli/config/validation.tssrc/cli/config/types.tsScreenshots
Checklist
@clack/promptslikeinstall.ts)Summary by cubic
Adds a new interactive TUI command, oh-my-opencode config, to edit the config file with validation and safe saves. This makes configuring agents and categories faster and less error-prone.
Written for commit ca09979. Summary will update on new commits.