feat: support --json#150
Conversation
|
@greptile review |
@loongphy/codex-auth-darwin-arm64
@loongphy/codex-auth-darwin-x64
@loongphy/codex-auth-linux-arm64
@loongphy/codex-auth-linux-x64
@loongphy/codex-auth-win32-arm64
@loongphy/codex-auth-win32-x64
@loongphy/codex-auth
commit: |
Greptile SummaryThis PR adds a
Confidence Score: 5/5Safe to merge — the JSON path is fully additive and the existing CLI paths are unchanged except for a refactor of selector resolution and plan-type normalisation that is well-covered by the expanded test suite. All three JSON workflows use careful errdefer chains and ownership flags to prevent leaks. The schema migration logic is gated cleanly on schema_version and the enum rename (team→business, +go) propagates consistently through parse, storage, auth, session, and api layers. No data-loss or incorrect-state scenarios were found in normal or error paths. No files require special attention. The two P2 observations (warnings not serialised, usageSource triple-maps to cache) are documentation/design clarification points rather than defects. Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant CLI as CLI (commands/*.zig)
participant Root as workflows/root.zig
participant WF as workflow (list/switch/remove)
participant Reg as registry
participant JSON as cli/json_output.zig
participant Results as workflows/results.zig
CLI->>Root: "parse() → Command{json:true}"
Root->>Root: commandWantsJson() → true
Root->>Reg: resolveCodexHome() [error→printJsonStartupError]
Root->>WF: "handleList/Switch/Remove(opts{json:true})"
alt list --json
WF->>WF: computeListState()
WF->>Reg: loadRegistry, syncActive, refreshUsage
WF->>Results: buildListResult(reg, usage_state)
Results->>Results: buildAccountViewsForIndices
Results-->>WF: ListResult
WF->>JSON: printListResult(result)
JSON-->>CLI: stdout JSON
else switch query --json
WF->>Reg: loadRegistry, syncActive
WF->>Reg: resolveSwitchQueryLocally(query)
alt not_found / multiple
WF->>JSON: printError(account_not_found or ambiguous_query)
else direct
WF->>Reg: activateAccountByKey + saveRegistry
WF->>Results: buildSwitchResult(reg, account_key)
Results-->>WF: SwitchResult
WF->>JSON: printSwitchResult(result)
end
JSON-->>CLI: stdout JSON
else remove selectors --json
WF->>Reg: loadRegistry, syncActive
WF->>WF: resolveRemoveSelectors(selectors)
alt hasNotFound or hasAmbiguous
WF->>Results: buildSelectorResolutionViews
WF->>JSON: printSelectorResolutionError
else all resolved
WF->>Results: buildAccountViewsForIndices (snapshot before removal)
WF->>Reg: removeSelectedAccountsAndPersist
WF->>JSON: printRemoveResult(result)
end
JSON-->>CLI: stdout JSON
end
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant CLI as CLI (commands/*.zig)
participant Root as workflows/root.zig
participant WF as workflow (list/switch/remove)
participant Reg as registry
participant JSON as cli/json_output.zig
participant Results as workflows/results.zig
CLI->>Root: "parse() → Command{json:true}"
Root->>Root: commandWantsJson() → true
Root->>Reg: resolveCodexHome() [error→printJsonStartupError]
Root->>WF: "handleList/Switch/Remove(opts{json:true})"
alt list --json
WF->>WF: computeListState()
WF->>Reg: loadRegistry, syncActive, refreshUsage
WF->>Results: buildListResult(reg, usage_state)
Results->>Results: buildAccountViewsForIndices
Results-->>WF: ListResult
WF->>JSON: printListResult(result)
JSON-->>CLI: stdout JSON
else switch query --json
WF->>Reg: loadRegistry, syncActive
WF->>Reg: resolveSwitchQueryLocally(query)
alt not_found / multiple
WF->>JSON: printError(account_not_found or ambiguous_query)
else direct
WF->>Reg: activateAccountByKey + saveRegistry
WF->>Results: buildSwitchResult(reg, account_key)
Results-->>WF: SwitchResult
WF->>JSON: printSwitchResult(result)
end
JSON-->>CLI: stdout JSON
else remove selectors --json
WF->>Reg: loadRegistry, syncActive
WF->>WF: resolveRemoveSelectors(selectors)
alt hasNotFound or hasAmbiguous
WF->>Results: buildSelectorResolutionViews
WF->>JSON: printSelectorResolutionError
else all resolved
WF->>Results: buildAccountViewsForIndices (snapshot before removal)
WF->>Reg: removeSelectedAccountsAndPersist
WF->>JSON: printRemoveResult(result)
end
JSON-->>CLI: stdout JSON
end
Reviews (3): Last reviewed commit: "docs: streamline JSON API guidance" | Re-trigger Greptile |
|
@greptile review |
Summary
list,switch, andremovewhile keeping their human-facing CLI behavior aligned.Why
The GUI and CLI ship together and need one stable command contract. The CLI now owns plan normalization and workflow decisions, so JSON consumers receive final product semantics instead of reimplementing backend-value interpretation.