@@ -51,7 +51,7 @@ def set_plugins(data: dict, plugins: list[str]) -> None:
5151
5252def usage () -> int :
5353 print (
54- "usage: /plugin status | /plugin doctor | /plugin setup-keys | /plugin profile <lean|stable|experimental> | /plugin enable <name|all> | /plugin disable <name|all>"
54+ "usage: /plugin status | /plugin doctor [--json] | /plugin setup-keys | /plugin profile <lean|stable|experimental> | /plugin enable <name|all> | /plugin disable <name|all>"
5555 )
5656 print ("names: notifier, supermemory, morph, worktree, wakatime" )
5757 print ("note: 'all' applies stable plugins only: notifier, supermemory, wakatime" )
@@ -111,24 +111,24 @@ def has_wakatime_key() -> bool:
111111 return bool (re .search (r"(?im)^\s*api_key\s*=\s*\S+" , content ))
112112
113113
114- def print_doctor (plugins : list [str ]) -> int :
114+ def collect_doctor (plugins : list [str ]) -> dict :
115115 problems : list [str ] = []
116116 warnings : list [str ] = []
117-
118- print ("plugin doctor" )
119- print ("-------------" )
120- print (f"config: { CONFIG_PATH } " )
121- print (f"python: { sys .executable } " )
122-
123- if not CONFIG_PATH .exists ():
124- problems .append (f"missing config file: { CONFIG_PATH } " )
117+ plugin_states : dict [str , dict [str , str ]] = {}
125118
126119 for alias in PLUGIN_ORDER :
127120 package = KNOWN_PLUGINS [alias ]
128121 enabled = package in plugins
129122 status = "enabled" if enabled else "disabled"
130123 kind = "stable" if alias in STABLE_ALIASES else "experimental"
131- print (f"- { alias } : { status } [{ kind } ]" )
124+ plugin_states [alias ] = {
125+ "status" : status ,
126+ "kind" : kind ,
127+ "package" : package ,
128+ }
129+
130+ if not CONFIG_PATH .exists ():
131+ problems .append (f"missing config file: { CONFIG_PATH } " )
132132
133133 if KNOWN_PLUGINS ["supermemory" ] in plugins and not has_supermemory_key ():
134134 problems .append (
@@ -157,21 +157,51 @@ def print_doctor(plugins: list[str]) -> int:
157157 if not cache_dir .exists ():
158158 warnings .append ("plugin cache not found yet (~/.cache/opencode/node_modules)" )
159159
160- if warnings :
160+ return {
161+ "result" : "PASS" if not problems else "FAIL" ,
162+ "config" : str (CONFIG_PATH ),
163+ "python" : sys .executable ,
164+ "plugins" : plugin_states ,
165+ "warnings" : warnings ,
166+ "problems" : problems ,
167+ "quick_fixes" : [
168+ "set SUPERMEMORY_API_KEY and/or create ~/.config/opencode/supermemory.jsonc" ,
169+ "add api_key to ~/.wakatime.cfg" ,
170+ "disable unmet plugins with: /plugin disable <name>" ,
171+ ]
172+ if problems
173+ else [],
174+ }
175+
176+
177+ def print_doctor (plugins : list [str ], json_output : bool = False ) -> int :
178+ report = collect_doctor (plugins )
179+
180+ if json_output :
181+ print (json .dumps (report , indent = 2 ))
182+ return 0 if report ["result" ] == "PASS" else 1
183+
184+ print ("plugin doctor" )
185+ print ("-------------" )
186+ print (f"config: { report ['config' ]} " )
187+ print (f"python: { report ['python' ]} " )
188+
189+ for alias in PLUGIN_ORDER :
190+ state = report ["plugins" ][alias ]
191+ print (f"- { alias } : { state ['status' ]} [{ state ['kind' ]} ]" )
192+
193+ if report ["warnings" ]:
161194 print ("\n warnings:" )
162- for item in warnings :
195+ for item in report [ " warnings" ] :
163196 print (f"- { item } " )
164197
165- if problems :
198+ if report [ " problems" ] :
166199 print ("\n problems:" )
167- for item in problems :
200+ for item in report [ " problems" ] :
168201 print (f"- { item } " )
169202 print ("\n quick fixes:" )
170- print (
171- "- set SUPERMEMORY_API_KEY and/or create ~/.config/opencode/supermemory.jsonc"
172- )
173- print ("- add api_key to ~/.wakatime.cfg" )
174- print ("- disable unmet plugins with: /plugin disable <name>" )
203+ for item in report ["quick_fixes" ]:
204+ print (f"- { item } " )
175205 print ("\n result: FAIL" )
176206 return 1
177207
@@ -253,7 +283,10 @@ def main(argv: list[str]) -> int:
253283 return 0
254284
255285 if argv [0 ] == "doctor" :
256- return print_doctor (plugins )
286+ json_output = len (argv ) > 1 and argv [1 ] == "--json"
287+ if len (argv ) > 1 and not json_output :
288+ return usage ()
289+ return print_doctor (plugins , json_output = json_output )
257290
258291 if argv [0 ] == "setup-keys" :
259292 return print_setup_keys (plugins )
0 commit comments