# -*- coding: utf-8 -*- """ CLI entry point: argv dispatch for account-manager v2. Subcommand tree: platform list/get account add-web|add-secret|get|list|pick-web|mark-session|mark-error|mark-used credential pick|resolve lease release|list|cleanup (legacy) add|list|get|list-json|pick-web|open|delete Machine commands output single-line JSON where appropriate. """ import sys from service.account_service import ( cmd_account_add_secret, cmd_account_add_web, cmd_account_get, cmd_account_list, cmd_account_mark_error, cmd_account_mark_session, cmd_account_mark_used, cmd_account_pick_web, cmd_credential_pick, cmd_credential_resolve, cmd_delete_by_id, cmd_delete_by_platform, cmd_delete_by_platform_phone, cmd_get, cmd_lease_cleanup, cmd_lease_list, cmd_lease_release, cmd_list, cmd_list_json, cmd_pick_web, cmd_platform_get, cmd_platform_list, ) from service.browser_service import cmd_open from util.constants import LOG_LOGGER_NAME, SKILL_SLUG from util.logging_config import get_skill_logger, setup_skill_logging from util.platforms import _platform_list_cn_for_help, resolve_platform_key from util.runtime_paths import _maybe_print_paths_debug_cli # ========================================================================= # Help text # ========================================================================= _USAGE = """account-manager v2 — Credential & Browser Profile Manager 平台管理: platform list [--domain logistics|llm|content] platform get 账号管理: account add-web --platform

--login-id --login-id-type [--label

--credential-type --secret-storage env|windows_credential|none [--secret-ref ] [--secret-stdin] [--label

] [--environment ] [--tenant-id ] [--role ] [--limit N] account pick-web --platform

[--environment ] [--tenant-id ] [--role ] [--lease] [--ttl-sec 900] [--holder ] [--purpose ] account mark-session --session-status account mark-error --code --message account mark-used account open 凭据管理: credential pick --platform

[--type ] [--environment ] [--role ] [--reveal] credential resolve --id [--reveal] 租约管理: lease release lease list [--active] lease cleanup 浏览器: account open open # 兼容别名 兼容入口(旧版): get list-json [--limit N] pick-web list [platform|all] add delete id|platform <...> """ # ========================================================================= # Argument parsing helpers # ========================================================================= def _get_opt(argv: list[str], flag: str, default=None): """Get value of --flag from argv, returning default if not found.""" if flag in argv: idx = argv.index(flag) if idx + 1 < len(argv): return argv[idx + 1] return default def _has_flag(argv: list[str], flag: str) -> bool: return flag in argv def _get_int_opt(argv: list[str], flag: str, default: int) -> int: v = _get_opt(argv, flag) if v is not None: try: return int(v) except ValueError: return default return default # ========================================================================= # Main dispatch # ========================================================================= def main() -> None: setup_skill_logging(SKILL_SLUG, LOG_LOGGER_NAME) log = get_skill_logger() if len(sys.argv) < 2: print(_USAGE) sys.exit(1) log.info("cli_start argv=%s", sys.argv) av = sys.argv cmd = av[1] _maybe_print_paths_debug_cli() # Determine if first arg is a platform key (for legacy shorthand) plat_from_first = resolve_platform_key(cmd) # ---- platform subcommand ---- if cmd == "platform": if len(av) < 3: print("ERROR:CLI_BAD_ARGS platform 需要子命令:list | get") sys.exit(1) sub = av[2] if sub == "list": domain = _get_opt(av, "--domain") cmd_platform_list(domain) elif sub == "get": if len(av) < 4: print("ERROR:CLI_BAD_ARGS platform get 需要 。") sys.exit(1) cmd_platform_get(av[3]) else: print("ERROR:CLI_BAD_ARGS platform 子命令必须是 list 或 get。") sys.exit(1) # ---- account subcommand ---- elif cmd == "account": if len(av) < 3: print("ERROR:CLI_BAD_ARGS account 需要子命令(add-web / get / …)。") print(_USAGE) sys.exit(1) sub = av[2] if sub == "add-web": _cmd_add_web(av) elif sub == "add-secret": _cmd_add_secret(av) elif sub == "get": if len(av) < 4: print("ERROR:CLI_BAD_ARGS account get 需要 。") sys.exit(1) aid = av[3] with_creds = _has_flag(av, "--with-credentials") cmd_account_get(aid, include_credentials=with_creds) elif sub == "list": _cmd_account_list(av) elif sub == "pick-web": _cmd_pick_web_new(av) elif sub == "mark-session": if len(av) < 4: print("ERROR:CLI_BAD_ARGS account mark-session 需要 。") sys.exit(1) aid = av[3] ss = _get_opt(av, "--session-status", "unknown") cmd_account_mark_session(aid, ss) elif sub == "mark-error": if len(av) < 4: print("ERROR:CLI_BAD_ARGS account mark-error 需要 。") sys.exit(1) aid = av[3] ec = _get_opt(av, "--code", "") em = _get_opt(av, "--message", "") cmd_account_mark_error(aid, ec, em) elif sub == "mark-used": if len(av) < 4: print("ERROR:CLI_BAD_ARGS account mark-used 需要 。") sys.exit(1) aid = av[3] cmd_account_mark_used(aid) elif sub == "open": if len(av) < 4: print("ERROR:CLI_BAD_ARGS account open 需要 。") sys.exit(1) cmd_open(av[3]) else: print("ERROR:CLI_BAD_ARGS 未知的 account 子命令。") print(_USAGE) sys.exit(1) # ---- credential subcommand ---- elif cmd == "credential": if len(av) < 3: print("ERROR:CLI_BAD_ARGS credential 需要子命令:pick | resolve") sys.exit(1) sub = av[2] if sub == "pick": _cmd_cred_pick(av) elif sub == "resolve": _cmd_cred_resolve(av) else: print("ERROR:CLI_BAD_ARGS credential 子命令必须是 pick 或 resolve。") sys.exit(1) # ---- lease subcommand ---- elif cmd == "lease": if len(av) < 3: print("ERROR:CLI_BAD_ARGS lease 需要子命令:release | list | cleanup") sys.exit(1) sub = av[2] if sub == "release": if len(av) < 4: print("ERROR:CLI_BAD_ARGS lease release 需要 。") sys.exit(1) cmd_lease_release(av[3]) elif sub == "list": active = _has_flag(av, "--active") cmd_lease_list(active) elif sub == "cleanup": cmd_lease_cleanup() else: print("ERROR:CLI_BAD_ARGS lease 子命令必须是 release、list 或 cleanup。") sys.exit(1) # ---- Legacy aliases ---- elif cmd == "get": if len(sys.argv) < 3: print("ERROR:CLI_GET_MISSING_ID") sys.exit(1) cmd_get(sys.argv[2]) elif cmd == "list-json": if len(sys.argv) < 3: print("ERROR:CLI_LIST_JSON_MISSING_PLATFORM") sys.exit(1) av = sys.argv[2:] platform_arg = av[0] lim = 200 if "--limit" in av: i = av.index("--limit") if i + 1 < len(av): try: lim = int(av[i + 1]) except ValueError: pass cmd_list_json(platform_arg, limit=lim) elif cmd == "pick-web": if len(sys.argv) < 3: print("ERROR:CLI_PICK_WEB_MISSING_ARGS") sys.exit(1) cmd_pick_web(sys.argv[2]) elif cmd == "open": if len(sys.argv) < 3: print("ERROR:CLI_OPEN_MISSING_ID") sys.exit(1) cmd_open(sys.argv[2]) elif cmd == "list": platform_arg = sys.argv[2] if len(sys.argv) >= 3 else "all" cmd_list(platform_arg) elif cmd == "add": if len(sys.argv) < 4: print("ERROR:CLI_ADD_MISSING_ARGS") sys.exit(1) # Legacy add maps to add-web for backward compat cmd_account_add_web( platform_input=sys.argv[2], login_id=sys.argv[3], login_id_type="phone", label=None, tenant_id=None, environment="production", role="default", provider_code=None, url=None, extra_json_str=None, profile_dir_override=None, ) elif cmd == "delete": if len(sys.argv) < 4: print("ERROR:CLI_DELETE_MISSING_ARGS") sys.exit(1) mode = (sys.argv[2] or "").strip().lower() if mode == "id": cmd_delete_by_id(sys.argv[3]) elif mode == "platform": if len(sys.argv) >= 5: cmd_delete_by_platform_phone(sys.argv[3], sys.argv[4]) else: cmd_delete_by_platform(sys.argv[3]) else: print(f"ERROR:CLI_DELETE_BAD_MODE 不支持的删除方式「{sys.argv[2]}」。") sys.exit(1) # ---- Platform shorthand: "python main.py " ---- elif plat_from_first: cmd_list(sys.argv[1]) # ---- Unknown ---- else: print(f"ERROR:CLI_UNKNOWN_OR_BAD_ARGS 子命令「{cmd}」无法识别。") print() print(_USAGE) sys.exit(1) # ========================================================================= # Sub-parsers for complex commands # ========================================================================= def _cmd_add_web(argv: list[str]) -> None: plat = _get_opt(argv, "--platform", "") login_id = _get_opt(argv, "--login-id") login_id_type = _get_opt(argv, "--login-id-type", "unknown") label = _get_opt(argv, "--label") tenant_id = _get_opt(argv, "--tenant-id") environment = _get_opt(argv, "--environment", "production") role = _get_opt(argv, "--role", "default") provider_code = _get_opt(argv, "--provider-code") url = _get_opt(argv, "--url") extra_json_str = _get_opt(argv, "--extra-json") profile_dir_override = _get_opt(argv, "--profile-dir") if not plat: print("ERROR:CLI_BAD_ARGS account add-web 需要 --platform 。") return cmd_account_add_web( platform_input=plat, login_id=login_id, login_id_type=login_id_type, label=label, tenant_id=tenant_id, environment=environment, role=role, provider_code=provider_code, url=url, extra_json_str=extra_json_str, profile_dir_override=profile_dir_override, ) def _cmd_add_secret(argv: list[str]) -> None: plat = _get_opt(argv, "--platform", "") ctype = _get_opt(argv, "--credential-type", "api_key") label = _get_opt(argv, "--label") storage = _get_opt(argv, "--secret-storage", "env") stdin_mode = _has_flag(argv, "--secret-stdin") sref = _get_opt(argv, "--secret-ref") aid = _get_int_opt(argv, "--account-id", 0) or None env = _get_opt(argv, "--environment", "production") role = _get_opt(argv, "--role", "api") extra_json_str = _get_opt(argv, "--extra-json") if not plat: print("ERROR:CLI_BAD_ARGS account add-secret 需要 --platform 。") return cmd_account_add_secret( platform_input=plat, credential_type=ctype, label=label, secret_storage=storage, secret_stdin=stdin_mode, secret_ref=sref, account_id=aid, environment=env, role=role, extra_json_str=extra_json_str, ) def _cmd_account_list(argv: list[str]) -> None: plat = _get_opt(argv, "--platform") env = _get_opt(argv, "--environment") tenant = _get_opt(argv, "--tenant-id") role = _get_opt(argv, "--role") limit = _get_int_opt(argv, "--limit", 200) cmd_account_list( platform_input=plat, environment=env, tenant_id=tenant, role=role, limit=limit, ) def _cmd_pick_web_new(argv: list[str]) -> None: plat = _get_opt(argv, "--platform", "") env = _get_opt(argv, "--environment") tenant = _get_opt(argv, "--tenant-id") role = _get_opt(argv, "--role") do_lease = _has_flag(argv, "--lease") ttl = _get_int_opt(argv, "--ttl-sec", 900) holder = _get_opt(argv, "--holder") purpose = _get_opt(argv, "--purpose") if not plat: print("ERROR:CLI_BAD_ARGS account pick-web 需要 --platform 。") return cmd_account_pick_web( platform_input=plat, environment=env, tenant_id=tenant, role=role, do_lease=do_lease, ttl_sec=ttl, holder=holder, purpose=purpose, ) def _cmd_cred_pick(argv: list[str]) -> None: plat = _get_opt(argv, "--platform", "") ctype = _get_opt(argv, "--type") env = _get_opt(argv, "--environment") role = _get_opt(argv, "--role") reveal = _has_flag(argv, "--reveal") if not plat: print("ERROR:CLI_BAD_ARGS credential pick 需要 --platform 。") return cmd_credential_pick( platform_input=plat, credential_type=ctype, environment=env, role=role, reveal=reveal, ) def _cmd_cred_resolve(argv: list[str]) -> None: cid = _get_int_opt(argv, "--id", 0) reveal = _has_flag(argv, "--reveal") if cid <= 0: print("ERROR:CLI_BAD_ARGS credential resolve 需要 --id 。") return cmd_credential_resolve(cid, reveal=reveal) if __name__ == "__main__": main()