arkclaw-webchat-cli 0.3.0__tar.gz → 0.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. {arkclaw_webchat_cli-0.3.0 → arkclaw_webchat_cli-0.4.0}/PKG-INFO +4 -4
  2. {arkclaw_webchat_cli-0.3.0 → arkclaw_webchat_cli-0.4.0}/README.md +3 -3
  3. {arkclaw_webchat_cli-0.3.0 → arkclaw_webchat_cli-0.4.0}/pyproject.toml +1 -1
  4. {arkclaw_webchat_cli-0.3.0 → arkclaw_webchat_cli-0.4.0}/src/ee_claw/flows.py +35 -64
  5. {arkclaw_webchat_cli-0.3.0 → arkclaw_webchat_cli-0.4.0}/.gitignore +0 -0
  6. {arkclaw_webchat_cli-0.3.0 → arkclaw_webchat_cli-0.4.0}/src/ee_claw/__init__.py +0 -0
  7. {arkclaw_webchat_cli-0.3.0 → arkclaw_webchat_cli-0.4.0}/src/ee_claw/attachments.py +0 -0
  8. {arkclaw_webchat_cli-0.3.0 → arkclaw_webchat_cli-0.4.0}/src/ee_claw/cli.py +0 -0
  9. {arkclaw_webchat_cli-0.3.0 → arkclaw_webchat_cli-0.4.0}/src/ee_claw/config.py +0 -0
  10. {arkclaw_webchat_cli-0.3.0 → arkclaw_webchat_cli-0.4.0}/src/ee_claw/control.py +0 -0
  11. {arkclaw_webchat_cli-0.3.0 → arkclaw_webchat_cli-0.4.0}/src/ee_claw/core.py +0 -0
  12. {arkclaw_webchat_cli-0.3.0 → arkclaw_webchat_cli-0.4.0}/src/ee_claw/doctor.py +0 -0
  13. {arkclaw_webchat_cli-0.3.0 → arkclaw_webchat_cli-0.4.0}/src/ee_claw/errors.py +0 -0
  14. {arkclaw_webchat_cli-0.3.0 → arkclaw_webchat_cli-0.4.0}/src/ee_claw/identity.py +0 -0
  15. {arkclaw_webchat_cli-0.3.0 → arkclaw_webchat_cli-0.4.0}/src/ee_claw/oauth.py +0 -0
  16. {arkclaw_webchat_cli-0.3.0 → arkclaw_webchat_cli-0.4.0}/src/ee_claw/output.py +0 -0
  17. {arkclaw_webchat_cli-0.3.0 → arkclaw_webchat_cli-0.4.0}/src/ee_claw/policy.py +0 -0
  18. {arkclaw_webchat_cli-0.3.0 → arkclaw_webchat_cli-0.4.0}/src/ee_claw/providers.py +0 -0
  19. {arkclaw_webchat_cli-0.3.0 → arkclaw_webchat_cli-0.4.0}/src/ee_claw/secrets_store.py +0 -0
  20. {arkclaw_webchat_cli-0.3.0 → arkclaw_webchat_cli-0.4.0}/src/ee_claw/sts.py +0 -0
  21. {arkclaw_webchat_cli-0.3.0 → arkclaw_webchat_cli-0.4.0}/src/ee_claw/transport/__init__.py +0 -0
  22. {arkclaw_webchat_cli-0.3.0 → arkclaw_webchat_cli-0.4.0}/src/ee_claw/transport/a2a.py +0 -0
  23. {arkclaw_webchat_cli-0.3.0 → arkclaw_webchat_cli-0.4.0}/src/ee_claw/transport/base.py +0 -0
  24. {arkclaw_webchat_cli-0.3.0 → arkclaw_webchat_cli-0.4.0}/src/ee_claw/transport/openclaw.py +0 -0
  25. {arkclaw_webchat_cli-0.3.0 → arkclaw_webchat_cli-0.4.0}/src/ee_claw/update.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: arkclaw-webchat-cli
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: CLI to chat with an ArkClaw EE space's Claw over enterprise SSO — zero permanent AK/SK.
5
5
  Author: ArkClaw Team
6
6
  Keywords: arkclaw,cli,ee,openclaw,sso,sts
@@ -40,7 +40,7 @@ arkclaw chat ci-xxxxxxxx
40
40
  ## What it can do
41
41
 
42
42
  - **Log in as you** — browser SSO (PKCE), short-lived token, auto-refresh. No AK/SK, no client secret, nothing permanent on disk but a token in your OS keychain.
43
- - **List your agents** — `arkclaw agents` shows the claws you can chat with.
43
+ - **List your agents** — `arkclaw agents` shows the claws you've chatted with (kept locally; add one with `arkclaw chat ci-...`).
44
44
  - **Chat** — interactive REPL or one-shot `-m`, streaming token-by-token, with a live "what's it doing" spinner and tool-event trace.
45
45
  - **Talk to a specific claw** — by id (`chat ci-...`) or by name (`chat 答疑助手`).
46
46
  - **Manage a claw's files** — read/write its managed workspace files (`AGENTS.md`, `SOUL.md`, `MEMORY.md`, …) with `ls` / `pull` / `push`.
@@ -77,7 +77,7 @@ arkclaw init
77
77
  # 1. log in (a browser opens; sign in with SSO)
78
78
  arkclaw login
79
79
 
80
- # 2. see which claws you can talk to
80
+ # 2. list the claws you've used (empty at first — you add them by chatting)
81
81
  arkclaw agents
82
82
 
83
83
  # 3. chat — interactive…
@@ -99,7 +99,7 @@ straight to `arkclaw login https://your-space...`. See **[Configuration](#config
99
99
  |---|---|
100
100
  | `arkclaw init [address]` | One-time interactive setup. Saves the address + (only what isn't auto-discovered) the CLI client and STS role to `~/.arkclaw/defaults.json`, so later commands need no env/flags. |
101
101
  | `arkclaw login [space-url]` | Browser SSO login. Uses `init` defaults if you omit the URL. `--transport a2a --endpoint <url>` for an agent endpoint. `--clawid ci-...` sets a default claw. Bare `arkclaw login` re-logs into the previous space. |
102
- | `arkclaw agents` | List the claws/agents you can chat with. |
102
+ | `arkclaw agents` | List the claws you've used from this machine (local history, newest first) + your default claw. Add a claw by chatting it once (`arkclaw chat ci-...`). Not a space-wide directory. |
103
103
  | `arkclaw chat [TARGET] [MSG]` | Chat. `TARGET` = a claw id (`ci-...`), an agent name (from `agents`), or a profile. With `MSG` → one-shot; without → interactive REPL. `-f` attach files, `-o` write the reply, `--session NAME` name the conversation, `--approve-all` auto-approve tool runs. |
104
104
  | `arkclaw <name>` | Shortcut: `arkclaw 答疑助手` ≡ `arkclaw chat 答疑助手`. |
105
105
  | `arkclaw ls` | List the claw's managed workspace files. |
@@ -16,7 +16,7 @@ arkclaw chat ci-xxxxxxxx
16
16
  ## What it can do
17
17
 
18
18
  - **Log in as you** — browser SSO (PKCE), short-lived token, auto-refresh. No AK/SK, no client secret, nothing permanent on disk but a token in your OS keychain.
19
- - **List your agents** — `arkclaw agents` shows the claws you can chat with.
19
+ - **List your agents** — `arkclaw agents` shows the claws you've chatted with (kept locally; add one with `arkclaw chat ci-...`).
20
20
  - **Chat** — interactive REPL or one-shot `-m`, streaming token-by-token, with a live "what's it doing" spinner and tool-event trace.
21
21
  - **Talk to a specific claw** — by id (`chat ci-...`) or by name (`chat 答疑助手`).
22
22
  - **Manage a claw's files** — read/write its managed workspace files (`AGENTS.md`, `SOUL.md`, `MEMORY.md`, …) with `ls` / `pull` / `push`.
@@ -53,7 +53,7 @@ arkclaw init
53
53
  # 1. log in (a browser opens; sign in with SSO)
54
54
  arkclaw login
55
55
 
56
- # 2. see which claws you can talk to
56
+ # 2. list the claws you've used (empty at first — you add them by chatting)
57
57
  arkclaw agents
58
58
 
59
59
  # 3. chat — interactive…
@@ -75,7 +75,7 @@ straight to `arkclaw login https://your-space...`. See **[Configuration](#config
75
75
  |---|---|
76
76
  | `arkclaw init [address]` | One-time interactive setup. Saves the address + (only what isn't auto-discovered) the CLI client and STS role to `~/.arkclaw/defaults.json`, so later commands need no env/flags. |
77
77
  | `arkclaw login [space-url]` | Browser SSO login. Uses `init` defaults if you omit the URL. `--transport a2a --endpoint <url>` for an agent endpoint. `--clawid ci-...` sets a default claw. Bare `arkclaw login` re-logs into the previous space. |
78
- | `arkclaw agents` | List the claws/agents you can chat with. |
78
+ | `arkclaw agents` | List the claws you've used from this machine (local history, newest first) + your default claw. Add a claw by chatting it once (`arkclaw chat ci-...`). Not a space-wide directory. |
79
79
  | `arkclaw chat [TARGET] [MSG]` | Chat. `TARGET` = a claw id (`ci-...`), an agent name (from `agents`), or a profile. With `MSG` → one-shot; without → interactive REPL. `-f` attach files, `-o` write the reply, `--session NAME` name the conversation, `--approve-all` auto-approve tool runs. |
80
80
  | `arkclaw <name>` | Shortcut: `arkclaw 答疑助手` ≡ `arkclaw chat 答疑助手`. |
81
81
  | `arkclaw ls` | List the claw's managed workspace files. |
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "arkclaw-webchat-cli"
7
- version = "0.3.0"
7
+ version = "0.4.0"
8
8
  description = "CLI to chat with an ArkClaw EE space's Claw over enterprise SSO — zero permanent AK/SK."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -11,7 +11,6 @@ and every error is a typed :class:`~ee_claw.errors.ArkclawError`.
11
11
  from __future__ import annotations
12
12
 
13
13
  import asyncio
14
- import dataclasses
15
14
  import json
16
15
  import os
17
16
  import pathlib
@@ -870,11 +869,16 @@ def _ago(ts: object) -> str:
870
869
 
871
870
 
872
871
  def do_agents(emitter: Emitter) -> dict[str, Any]:
873
- """``arkclaw agents``: the agents/claws you can chat with — nothing else.
874
- openclaw → the claws across your space(s) (space auto-discovered if login
875
- didn't pin one); a2a the agent at the endpoint (its card). Each is
876
- recorded so ``chat <name>`` works. Profiles live under ``arkclaw profile``,
877
- recent sessions under ``arkclaw sessions``. Human view is tabular."""
872
+ """``arkclaw agents``: the agents/claws you can chat with.
873
+
874
+ openclaw the claws YOU have used from this machine (kept locally, newest
875
+ first), plus your default claw. This is deliberately NOT a server-side
876
+ enumeration of the space that API returns every member's claws to anyone
877
+ (no per-user scoping is reachable by the CLI's role), so we don't call it.
878
+ You add a claw to this list by chatting it once: ``arkclaw chat ci-...``.
879
+
880
+ a2a → the agent at the endpoint (its card). Profiles live under ``arkclaw
881
+ profile``, full conversation history under ``arkclaw sessions``."""
878
882
  cfg = config_mod.load_config()
879
883
  if not cfg or not cfg.space:
880
884
  raise NoLoginError("尚未登录。", hint="先运行: arkclaw login <空间地址>")
@@ -931,73 +935,40 @@ def do_agents(emitter: Emitter) -> dict[str, Any]:
931
935
  )
932
936
  elif cfg.transport == "openclaw":
933
937
  emitter.line(f"★ 当前登录(openclaw)· 空间 {cfg.space}")
934
- _, id_token = _load_session()
935
- try:
936
- creds: dict[str, str] | None = _openclaw_creds(cfg, id_token)
937
- except ArkclawError as e:
938
- creds = None
939
- current["claws_error"] = {"code": e.code, "message": e.message}
940
- claws: list[dict[str, Any]] = []
941
- if creds is not None:
942
- # Which space(s) to list? If login didn't pin a space_id, discover
943
- # the user's spaces so `agents` lists the chat-able claws from the
944
- # address alone. Listing may be denied by a least-privilege role.
945
- space_ids: list[str] = [str(cfg.space_id)] if cfg.space_id else []
946
- if not space_ids:
947
- try:
948
- spaces = control.call_action(
949
- "ListClawSpaces", {"ProjectName": "default", "MaxResults": 50},
950
- region=str(cfg.region), creds=creds,
951
- )
952
- assert isinstance(spaces, dict)
953
- space_ids = [
954
- str(s["SpaceId"]) for s in (spaces.get("Spaces") or [])
955
- if isinstance(s, dict) and s.get("SpaceId")
956
- ]
957
- if len(space_ids) == 1: # cache it so later calls skip discovery
958
- config_mod.save_config(dataclasses.replace(cfg, space_id=space_ids[0]))
959
- except ArkclawError as e:
960
- current["claws_error"] = {"code": e.code, "message": e.message}
961
- for sid in space_ids:
962
- try:
963
- result = redact_obj(control.call_action(
964
- "ListClawInstances",
965
- {"SpaceId": sid, "ProjectName": "default", "MaxResults": 100},
966
- region=str(cfg.region), creds=creds,
967
- ))
968
- assert isinstance(result, dict)
969
- items = result.get("Items") or result.get("ClawInstances") or []
970
- claws += [it for it in items if isinstance(it, dict)]
971
- except ArkclawError as e:
972
- current["claws_error"] = {"code": e.code, "message": e.message}
938
+ # The claws you can chat = the ones YOU have used from this machine,
939
+ # remembered locally — NOT a server enumeration of the space. The
940
+ # space-wide ListClawInstances returns every member's claws to anyone
941
+ # (no per-user scoping reachable by the CLI's role), so we don't call it.
942
+ # New claws enter via `arkclaw chat ci-...`; each chat is recorded
943
+ # (record_session) and shows up here next time.
944
+ seen: dict[str, float] = {}
945
+ for s in config_mod.list_sessions():
946
+ cid = s.get("claw")
947
+ if s.get("space") == cfg.space and cid:
948
+ ts = s.get("last_used")
949
+ seen[str(cid)] = max(seen.get(str(cid), 0.0), float(ts) if isinstance(ts, (int, float)) else 0.0)
950
+ if cfg.claw and str(cfg.claw) not in seen:
951
+ seen[str(cfg.claw)] = 0.0 # the default claw, even if not chatted yet
952
+ claws = [
953
+ {"ClawInstanceId": cid, "last_used": ts}
954
+ for cid, ts in sorted(seen.items(), key=lambda kv: kv[1], reverse=True)
955
+ ]
973
956
  current["claws"] = claws
974
- for it in claws: # claw Name → chat <名字>
975
- cid = it.get("ClawInstanceId") or it.get("Id")
976
- if it.get("Name") and cid:
977
- config_mod.record_agent(str(it["Name"]), dataclasses.replace(cfg, claw=str(cid)))
957
+ current["source"] = "local-history"
978
958
  if claws:
979
959
  emitter.table(
980
- ["Claw(可 chat)", "名称", "状态", "默认"],
960
+ ["Claw(可 chat)", "上次使用", "默认"],
981
961
  [
982
962
  [
983
- it.get("ClawInstanceId") or it.get("Id") or "—",
984
- it.get("Name", ""),
985
- it.get("Status", ""),
986
- "★" if (it.get("ClawInstanceId") or it.get("Id")) == cfg.claw else "",
963
+ str(c["ClawInstanceId"]),
964
+ _ago(c["last_used"]) if c["last_used"] else "—",
965
+ "" if c["ClawInstanceId"] == cfg.claw else "",
987
966
  ]
988
- for it in claws
967
+ for c in claws
989
968
  ],
990
969
  )
991
970
  else:
992
- err = current.get("claws_error")
993
- emitter.table(
994
- ["Claw(可 chat)", "状态", "说明"],
995
- [[
996
- cfg.claw or "(用 --clawid 直连)",
997
- "默认目标" if cfg.claw else "—",
998
- f"列表不可用: {err['code']}" if isinstance(err, dict) else "没有可用 claw",
999
- ]],
1000
- )
971
+ emitter.line(" 还没用过任何 claw。用 `arkclaw chat ci-xxxx` 开始,之后这里会记住它。")
1001
972
 
1002
973
  # `agents` is the list of agents you can chat — nothing else. Saved
1003
974
  # profiles live under `arkclaw profile`, recent sessions under