feat: flatten opportunity commands, add config management, fix completions

- Flatten opportunity into top-level portfolio and opportunity commands
- Add interactive config get/set/key/secret with type coercion
- Rewrite --doc to show TUI vs JSON schema per command
- Unify agent mode output to JSON only
- Make init prompt for API key/secret interactively
- Fix coin tab completion alias binding
- Fix set_config_value reading from wrong path
- Fail loudly on invalid numeric config values

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-04-20 08:43:30 +08:00
parent 3855477155
commit e37993c8b5
6 changed files with 941 additions and 171 deletions

View File

@@ -426,10 +426,7 @@ def _render_tui(payload: Any) -> None:
def print_output(payload: Any, *, agent: bool = False) -> None:
if agent:
if _is_large_dataset(payload):
_print_compact(payload)
else:
print_json(payload)
print_json(payload)
else:
_render_tui(payload)
@@ -509,6 +506,13 @@ def install_shell_completion(parser: argparse.ArgumentParser) -> dict[str, Any]:
return {"shell": None, "installed": False, "reason": "unable to detect shell from $SHELL"}
script = shtab.complete(parser, shell=shell, preamble="")
# Also register completion for the "coinhunter" alias
prog = parser.prog.replace("-", "_")
func = f"_shtab_{prog}"
if shell == "bash":
script += f"\ncomplete -o filenames -F {func} coinhunter\n"
elif shell == "zsh":
script += f"\ncompdef {func} coinhunter\n"
installed_path: Path | None = None
hint: str | None = None