superresearch-agent 0.1.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 (57) hide show
  1. superresearch_agent-0.1.0/PKG-INFO +241 -0
  2. superresearch_agent-0.1.0/README.md +229 -0
  3. superresearch_agent-0.1.0/facade/__init__.py +19 -0
  4. superresearch_agent-0.1.0/facade/__main__.py +4 -0
  5. superresearch_agent-0.1.0/facade/autostart.py +375 -0
  6. superresearch_agent-0.1.0/facade/branding.py +275 -0
  7. superresearch_agent-0.1.0/facade/bridge.py +1861 -0
  8. superresearch_agent-0.1.0/facade/cli.py +1358 -0
  9. superresearch_agent-0.1.0/facade/config.py +132 -0
  10. superresearch_agent-0.1.0/facade/connect.py +571 -0
  11. superresearch_agent-0.1.0/facade/devicelogin.py +111 -0
  12. superresearch_agent-0.1.0/facade/firestore_rest.py +424 -0
  13. superresearch_agent-0.1.0/facade/logsetup.py +94 -0
  14. superresearch_agent-0.1.0/facade/prefs.py +216 -0
  15. superresearch_agent-0.1.0/facade/runview.py +90 -0
  16. superresearch_agent-0.1.0/facade/session.py +259 -0
  17. superresearch_agent-0.1.0/facade/skill/SKILL.md +237 -0
  18. superresearch_agent-0.1.0/facade/skill/scripts/sr.py +736 -0
  19. superresearch_agent-0.1.0/facade/skill/scripts/sr_attention_poll.py +216 -0
  20. superresearch_agent-0.1.0/facade/store.py +144 -0
  21. superresearch_agent-0.1.0/facade/web/icons/chatgpt.png +0 -0
  22. superresearch_agent-0.1.0/facade/web/icons/claude.png +0 -0
  23. superresearch_agent-0.1.0/facade/web/icons/notebooklm.png +0 -0
  24. superresearch_agent-0.1.0/facade/web/login.html +535 -0
  25. superresearch_agent-0.1.0/pyproject.toml +40 -0
  26. superresearch_agent-0.1.0/setup.cfg +4 -0
  27. superresearch_agent-0.1.0/superresearch_agent.egg-info/PKG-INFO +241 -0
  28. superresearch_agent-0.1.0/superresearch_agent.egg-info/SOURCES.txt +55 -0
  29. superresearch_agent-0.1.0/superresearch_agent.egg-info/dependency_links.txt +1 -0
  30. superresearch_agent-0.1.0/superresearch_agent.egg-info/entry_points.txt +3 -0
  31. superresearch_agent-0.1.0/superresearch_agent.egg-info/requires.txt +6 -0
  32. superresearch_agent-0.1.0/superresearch_agent.egg-info/top_level.txt +1 -0
  33. superresearch_agent-0.1.0/tests/test_agent_session.py +317 -0
  34. superresearch_agent-0.1.0/tests/test_app_plane_unchanged.py +94 -0
  35. superresearch_agent-0.1.0/tests/test_autostart.py +185 -0
  36. superresearch_agent-0.1.0/tests/test_branding.py +145 -0
  37. superresearch_agent-0.1.0/tests/test_bridge.py +109 -0
  38. superresearch_agent-0.1.0/tests/test_bridge_csrf.py +138 -0
  39. superresearch_agent-0.1.0/tests/test_bridge_device.py +665 -0
  40. superresearch_agent-0.1.0/tests/test_bridge_remote_login.py +142 -0
  41. superresearch_agent-0.1.0/tests/test_bridge_routes.py +361 -0
  42. superresearch_agent-0.1.0/tests/test_bridge_shutdown.py +26 -0
  43. superresearch_agent-0.1.0/tests/test_cli_commands.py +760 -0
  44. superresearch_agent-0.1.0/tests/test_cli_parser.py +141 -0
  45. superresearch_agent-0.1.0/tests/test_config.py +22 -0
  46. superresearch_agent-0.1.0/tests/test_connect.py +519 -0
  47. superresearch_agent-0.1.0/tests/test_devicelogin.py +62 -0
  48. superresearch_agent-0.1.0/tests/test_e2e_lifecycle.py +209 -0
  49. superresearch_agent-0.1.0/tests/test_firestore_rest.py +314 -0
  50. superresearch_agent-0.1.0/tests/test_logsetup.py +65 -0
  51. superresearch_agent-0.1.0/tests/test_prefs.py +127 -0
  52. superresearch_agent-0.1.0/tests/test_runview.py +59 -0
  53. superresearch_agent-0.1.0/tests/test_session.py +92 -0
  54. superresearch_agent-0.1.0/tests/test_session_custom_token.py +111 -0
  55. superresearch_agent-0.1.0/tests/test_sr_client.py +446 -0
  56. superresearch_agent-0.1.0/tests/test_sr_stream.py +189 -0
  57. superresearch_agent-0.1.0/tests/test_store.py +35 -0
@@ -0,0 +1,241 @@
1
+ Metadata-Version: 2.4
2
+ Name: superresearch-agent
3
+ Version: 0.1.0
4
+ Summary: Install Super Research into a chat runtime (Hermes / OpenClaw) with `uvx superresearch-agent connect` — an account-authed loopback bridge that drives the user's own Super Research from chat.
5
+ Requires-Python: >=3.11
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: requests>=2.31
8
+ Requires-Dist: keyring>=24
9
+ Provides-Extra: dev
10
+ Requires-Dist: pytest>=8; extra == "dev"
11
+ Requires-Dist: ruff>=0.5; extra == "dev"
12
+
13
+ # Super Agent — drive Super Research from chat (Hermes / OpenClaw)
14
+
15
+ Lets a chat runtime (Hermes / OpenClaw) drive **Super Research** as a *headless
16
+ session of your account*. You sign in once with Google (`/sr login`); the bridge
17
+ then enqueues research runs on your account's existing devices, and every run
18
+ shows up in the web app like a normal chat.
19
+
20
+ - **Research-only.** It can run / track / fetch research. It can **never**
21
+ control devices (add / remove / pair / share) — that stays owner-only.
22
+ - **One agent per account** (owner or sharer).
23
+ - **No dedicated worker, no separate logins, no identity minting.** It uses the
24
+ account's existing devices, on the app's normal Firestore plane.
25
+
26
+ Design source of truth: `../SuperAgentRecipe.md`.
27
+
28
+ ## The "nothing breaks" contract
29
+
30
+ This package is a **separate process** and never touches the existing app:
31
+
32
+ - No import of, or write to, `research-automate` or `research-app`.
33
+ - Its own secret-store namespace (`super-agent`, `~/.super-agent`) — **never**
34
+ the device daemon's `super-research` keystore. The account refresh token and
35
+ the device refresh token are different Firebase users; isolating them means a
36
+ refresh here can never disturb a paired device.
37
+ - Writes only what a normal account client may write under the **existing**
38
+ Firestore rules: research docs under your own tree + device-queue `start`
39
+ docs where you're a member. No rules change, no keystore change, no queue /
40
+ claim / pipeline change.
41
+
42
+ ## Running it (no install)
43
+
44
+ Run the agent as a **`research.py` command** — same front door as the rest of
45
+ the backend, from the repo root, **no install and no editable mode**:
46
+
47
+ ```sh
48
+ cd research-automate
49
+ python research.py agent <command> # e.g. agent connect / agent serve / agent login
50
+ python research.py --agent <command> # flag-style alias (consistent with --pair/--serve)
51
+ python research.py agent # bare → smart entry: status if set up, else connect
52
+ python research.py agent --help # the full command list
53
+ ```
54
+
55
+ The agent's only deps (`requests`, `keyring`) already ship in the backend's
56
+ `requirements.txt`, so once the backend is set up (`pip install -r
57
+ requirements.txt`) there is **nothing extra to install**. Requires **Python
58
+ 3.11+**.
59
+
60
+ > **Throughout this README, `agent <command>` is shorthand for
61
+ > `python research.py agent <command>`.**
62
+
63
+ The code itself lives in this isolated sub-package (`research-automate/agent/`,
64
+ its own process + its own two deps); `research.py` only *fronts* it so it's
65
+ invoked consistently — it never imports the package.
66
+
67
+ <details><summary>Optional — a bare <code>agent</code> command / dev setup</summary>
68
+
69
+ If you'd rather type a bare `agent` (outside the backend) or run the tests:
70
+
71
+ ```sh
72
+ cd research-automate/agent
73
+ pip install . # adds a standalone `agent` command (entry point)
74
+ python -m facade <command> # or run module-style, no install
75
+ pip install .[dev] # + test deps (pytest, ruff)
76
+ pip install -r requirements-dev.txt
77
+ ```
78
+
79
+ `requirements.txt` / `requirements-dev.txt` here mirror `pyproject.toml` for a
80
+ fresh venv. The `python research.py agent` path above needs none of this.
81
+ </details>
82
+
83
+ ## Use it from chat (Hermes / OpenClaw)
84
+
85
+ Install the Super Research skill into your chat runtime, then drive everything
86
+ with slash commands:
87
+
88
+ ```sh
89
+ cd research-automate
90
+ python research.py agent connect # branded 4-step flow; detects Windows + WSL runtimes
91
+ # step 4 offers to run the bridge in the background now + on every login
92
+ # then in chat: /reload-skills (once) → /sr login → approve on phone → /sr research <topic>
93
+ ```
94
+
95
+ `agent connect` is an interactive, branded flow — **Detect → Choose → Install →
96
+ Go live** — that finds your chat runtime on **Windows** (`~/.hermes`,
97
+ `~/.openclaw`) *and* inside **WSL** (`\\wsl.localhost\<distro>\home\<user>\…`),
98
+ lets you pick when more than one is found, copies a small dependency-free skill
99
+ (a `SKILL.md` + a `scripts/sr.py` client that calls the bridge over loopback)
100
+ into the runtime's skills dir, and offers to pin the always-up bridge.
101
+
102
+ The runtime registers a skill as a single slash command (`/<skill-name>`), so the
103
+ skill is **`/sr`** and the action follows it: `/sr login`, `/sr research <topic>`,
104
+ `/sr status [id]`, `/sr device [use <id>]`, `/sr podcast [id]`, `/sr skip <id>
105
+ <phases>`, `/sr cancel <id>`, `/sr logout`; a bare **`/sr`** is the welcome / help.
106
+ Natural phrasing works too ("research Tesla 2025", "send me the podcast"). It's
107
+ research-only — it can never control devices.
108
+
109
+ > **After connecting, run `/reload-skills` once in your chat** (the gateway caches
110
+ > its skill scan) so `/sr` registers without restarting the runtime.
111
+
112
+ **Reachability — Model A: the bridge runs WITH the runtime.** The bridge binds
113
+ **loopback only**, so it can only be reached by a runtime on its *own* machine —
114
+ which is why `connect` co-locates the bridge with the chat runtime:
115
+
116
+ - **Co-located** (runtime native on the same OS as the bridge — Win+Win,
117
+ Linux+Linux, macOS+macOS) → shares loopback, **zero setup**.
118
+ - **WSL runtime** → the bridge must run **inside WSL** too. `connect` detects a
119
+ WSL runtime and **offers to run connect there for you** — `uvx
120
+ superresearch-agent connect` inside the distro (or prints the command, with a
121
+ `python research.py agent connect` backend-checkout fallback for before the
122
+ package is on PyPI). The bridge then shares WSL's loopback with the runtime —
123
+ no Windows↔WSL networking, no `.wslconfig`.
124
+ - **Different machine** → can't reach a loopback-only bridge → **unsupported by
125
+ design** (exposing the bridge on the network would break its security model).
126
+
127
+ > Each side-effecting step still waits for your Y — `connect` never installs or
128
+ > runs anything inside WSL on its own.
129
+
130
+ **Keep it always-up.** `resurrect` pins a windowless logon autostart (Windows
131
+ Scheduled Task) **and** starts the bridge now, so it returns after a reboot; the
132
+ account session + device selection persist, so a restart resumes without
133
+ re-login. `retire` is the inverse.
134
+
135
+ ```sh
136
+ agent resurrect # background + on every login (windowless); starts it now too
137
+ agent retire # stop the background bridge + remove the logon pin
138
+ agent serve # foreground (this terminal) instead of background
139
+ agent stop # stop the running bridge
140
+ ```
141
+
142
+ **Disconnect.** `agent disconnect` is a full teardown — it removes the skill from
143
+ the runtime **and** signs out (the CLI twin of the app's **Revoke**). Use
144
+ `agent retire` as well if you also want the background bridge gone.
145
+
146
+ ## P0 — connect + prove the plane
147
+
148
+ ```sh
149
+ agent serve # start the loopback bridge (127.0.0.1:9876)
150
+ agent login # sign in on the SR web app (superresearch.io); --local = host page
151
+ agent status # → "Signed in as you@…"
152
+ agent doctor # health + token-refresh + connectivity checks
153
+ agent verify # reads your researches + lists reachable devices
154
+ agent verify --enqueue --device <id> --topic "Tesla 2025" # starts a real run
155
+ ```
156
+
157
+ `agent verify` (no `--enqueue`) is read-only. With `--enqueue` it creates a
158
+ research doc + a device-queue start doc — a real pipeline run that will appear
159
+ as an app chat.
160
+
161
+ ## P1 — remote sign-in + operational logging
162
+
163
+ **Remote sign-in (no localhost needed).** Approve from your phone via the
164
+ Super Research web app — the bridge brokers an OAuth device-style flow and makes
165
+ only outbound calls (see `SuperAgentRecipe.md` §11a):
166
+
167
+ ```sh
168
+ agent login --remote --runtime hermes
169
+ # → Open https://superresearch.io/connect-agent and enter code: AB-12
170
+ # (sign in to Super Research on your phone, tap Approve)
171
+ # ✓ Connected as you@…
172
+ ```
173
+
174
+ **`agent login` now defaults to the web app** (`superresearch.io` — the same page as
175
+ `/sr login` from chat + the connect Step 4 "Sign in"), so sign-in is one consistent
176
+ flow everywhere. The local Google page (`http://localhost:9876/login`) is the
177
+ `agent login --local` host-local fallback for dev / no-network.
178
+
179
+ **Logging.** `agent serve` writes a durable, rotating operational log to
180
+ `~/.super-agent/bridge.log` (request + run-lifecycle lines; never a token).
181
+ Add `-v` / `--verbose` (before or after the subcommand) for DEBUG.
182
+
183
+ **Pick a device.** List the devices your account can reach and choose which one
184
+ runs your research (the selection persists across restarts in
185
+ `~/.super-agent/prefs.json`):
186
+
187
+ ```sh
188
+ agent device # list (→ marks the selected one; (owned)/(shared))
189
+ agent device use <deviceId> # switch the target device
190
+ ```
191
+
192
+ `agent research`/`/sr research` resolves the device as: an explicit id → your
193
+ selection → the sole reachable device → an error asking you to pick one.
194
+
195
+ **Run, track, cancel.**
196
+
197
+ ```sh
198
+ agent research "Tesla 2025 outlook" # start a run → prints a run id immediately
199
+ agent runs # list recent runs (status + phase)
200
+ agent run [id] # one run's status + links (no id = latest)
201
+ agent watch [id] # stream per-phase links live until it finishes
202
+ agent skip <id> <phases…> # skip phases (1/3/4/5 or brief/podcast/video/report)
203
+ agent cancel <id> # stop a run (queued → dropped; running → stopped)
204
+ ```
205
+
206
+ `agent skip` tunes the run's config (Brief / Podcast → `skippedPhases`; Video →
207
+ `videoEnabled` off; Report → `emailEnabled` off); the device applies it when each
208
+ phase is reached.
209
+
210
+ `agent watch` polls and prints each new link (Brief → ChatGPT/Gemini/Claude →
211
+ NotebookLM/Audio → YouTube → Doc) as the device produces it, then stops at a
212
+ terminal status. The same signal feeds a runtime's streaming cron via
213
+ `GET /updates` (account-wide active runs + their current links) — a poller
214
+ dedups by `(runId, kind)`. (No `?since=` watermark: the backend doesn't bump
215
+ `updatedAt` on a per-phase link write, so the current link set is returned every
216
+ poll and deduped client-side.) Cancel writes a single `action:"cancel"` to the
217
+ run's device queue — dropped if queued, stopped if running.
218
+
219
+ > The web app's broker routes (`/api/agent/login/{start,approve,poll}` +
220
+ > `/connect-agent`) are built separately under review; this package is only the
221
+ > outbound client.
222
+
223
+ ## Layout
224
+
225
+ ```
226
+ facade/
227
+ config.py public Firebase config + bridge host/port/store + FE base
228
+ store.py secure session store (keyring + 0600 file fallback)
229
+ prefs.py non-secret prefs (selected device [uid-bound], runtime)
230
+ session.py AccountSession — refresh-token / custom-token → ID-token
231
+ firestore_rest.py minimal Firestore REST (researches/devices, upsert, enqueue, cancel)
232
+ devicelogin.py remote-login device-flow client (→ the SR web app broker)
233
+ logsetup.py rotating-file + console logging (--verbose)
234
+ runview.py flatten links.{kind} → ordered events; terminal-status set
235
+ connect.py install the skill into a chat runtime
236
+ bridge.py loopback HTTP server (/login, /login/remote/*, /devices,
237
+ /device, /research, /updates, …)
238
+ web/login.html Firebase Web SDK Google sign-in (TOTP MFA aware)
239
+ skill/ the chat-runtime bundle (SKILL.md + scripts/sr.py)
240
+ cli.py the `agent` command
241
+ ```
@@ -0,0 +1,229 @@
1
+ # Super Agent — drive Super Research from chat (Hermes / OpenClaw)
2
+
3
+ Lets a chat runtime (Hermes / OpenClaw) drive **Super Research** as a *headless
4
+ session of your account*. You sign in once with Google (`/sr login`); the bridge
5
+ then enqueues research runs on your account's existing devices, and every run
6
+ shows up in the web app like a normal chat.
7
+
8
+ - **Research-only.** It can run / track / fetch research. It can **never**
9
+ control devices (add / remove / pair / share) — that stays owner-only.
10
+ - **One agent per account** (owner or sharer).
11
+ - **No dedicated worker, no separate logins, no identity minting.** It uses the
12
+ account's existing devices, on the app's normal Firestore plane.
13
+
14
+ Design source of truth: `../SuperAgentRecipe.md`.
15
+
16
+ ## The "nothing breaks" contract
17
+
18
+ This package is a **separate process** and never touches the existing app:
19
+
20
+ - No import of, or write to, `research-automate` or `research-app`.
21
+ - Its own secret-store namespace (`super-agent`, `~/.super-agent`) — **never**
22
+ the device daemon's `super-research` keystore. The account refresh token and
23
+ the device refresh token are different Firebase users; isolating them means a
24
+ refresh here can never disturb a paired device.
25
+ - Writes only what a normal account client may write under the **existing**
26
+ Firestore rules: research docs under your own tree + device-queue `start`
27
+ docs where you're a member. No rules change, no keystore change, no queue /
28
+ claim / pipeline change.
29
+
30
+ ## Running it (no install)
31
+
32
+ Run the agent as a **`research.py` command** — same front door as the rest of
33
+ the backend, from the repo root, **no install and no editable mode**:
34
+
35
+ ```sh
36
+ cd research-automate
37
+ python research.py agent <command> # e.g. agent connect / agent serve / agent login
38
+ python research.py --agent <command> # flag-style alias (consistent with --pair/--serve)
39
+ python research.py agent # bare → smart entry: status if set up, else connect
40
+ python research.py agent --help # the full command list
41
+ ```
42
+
43
+ The agent's only deps (`requests`, `keyring`) already ship in the backend's
44
+ `requirements.txt`, so once the backend is set up (`pip install -r
45
+ requirements.txt`) there is **nothing extra to install**. Requires **Python
46
+ 3.11+**.
47
+
48
+ > **Throughout this README, `agent <command>` is shorthand for
49
+ > `python research.py agent <command>`.**
50
+
51
+ The code itself lives in this isolated sub-package (`research-automate/agent/`,
52
+ its own process + its own two deps); `research.py` only *fronts* it so it's
53
+ invoked consistently — it never imports the package.
54
+
55
+ <details><summary>Optional — a bare <code>agent</code> command / dev setup</summary>
56
+
57
+ If you'd rather type a bare `agent` (outside the backend) or run the tests:
58
+
59
+ ```sh
60
+ cd research-automate/agent
61
+ pip install . # adds a standalone `agent` command (entry point)
62
+ python -m facade <command> # or run module-style, no install
63
+ pip install .[dev] # + test deps (pytest, ruff)
64
+ pip install -r requirements-dev.txt
65
+ ```
66
+
67
+ `requirements.txt` / `requirements-dev.txt` here mirror `pyproject.toml` for a
68
+ fresh venv. The `python research.py agent` path above needs none of this.
69
+ </details>
70
+
71
+ ## Use it from chat (Hermes / OpenClaw)
72
+
73
+ Install the Super Research skill into your chat runtime, then drive everything
74
+ with slash commands:
75
+
76
+ ```sh
77
+ cd research-automate
78
+ python research.py agent connect # branded 4-step flow; detects Windows + WSL runtimes
79
+ # step 4 offers to run the bridge in the background now + on every login
80
+ # then in chat: /reload-skills (once) → /sr login → approve on phone → /sr research <topic>
81
+ ```
82
+
83
+ `agent connect` is an interactive, branded flow — **Detect → Choose → Install →
84
+ Go live** — that finds your chat runtime on **Windows** (`~/.hermes`,
85
+ `~/.openclaw`) *and* inside **WSL** (`\\wsl.localhost\<distro>\home\<user>\…`),
86
+ lets you pick when more than one is found, copies a small dependency-free skill
87
+ (a `SKILL.md` + a `scripts/sr.py` client that calls the bridge over loopback)
88
+ into the runtime's skills dir, and offers to pin the always-up bridge.
89
+
90
+ The runtime registers a skill as a single slash command (`/<skill-name>`), so the
91
+ skill is **`/sr`** and the action follows it: `/sr login`, `/sr research <topic>`,
92
+ `/sr status [id]`, `/sr device [use <id>]`, `/sr podcast [id]`, `/sr skip <id>
93
+ <phases>`, `/sr cancel <id>`, `/sr logout`; a bare **`/sr`** is the welcome / help.
94
+ Natural phrasing works too ("research Tesla 2025", "send me the podcast"). It's
95
+ research-only — it can never control devices.
96
+
97
+ > **After connecting, run `/reload-skills` once in your chat** (the gateway caches
98
+ > its skill scan) so `/sr` registers without restarting the runtime.
99
+
100
+ **Reachability — Model A: the bridge runs WITH the runtime.** The bridge binds
101
+ **loopback only**, so it can only be reached by a runtime on its *own* machine —
102
+ which is why `connect` co-locates the bridge with the chat runtime:
103
+
104
+ - **Co-located** (runtime native on the same OS as the bridge — Win+Win,
105
+ Linux+Linux, macOS+macOS) → shares loopback, **zero setup**.
106
+ - **WSL runtime** → the bridge must run **inside WSL** too. `connect` detects a
107
+ WSL runtime and **offers to run connect there for you** — `uvx
108
+ superresearch-agent connect` inside the distro (or prints the command, with a
109
+ `python research.py agent connect` backend-checkout fallback for before the
110
+ package is on PyPI). The bridge then shares WSL's loopback with the runtime —
111
+ no Windows↔WSL networking, no `.wslconfig`.
112
+ - **Different machine** → can't reach a loopback-only bridge → **unsupported by
113
+ design** (exposing the bridge on the network would break its security model).
114
+
115
+ > Each side-effecting step still waits for your Y — `connect` never installs or
116
+ > runs anything inside WSL on its own.
117
+
118
+ **Keep it always-up.** `resurrect` pins a windowless logon autostart (Windows
119
+ Scheduled Task) **and** starts the bridge now, so it returns after a reboot; the
120
+ account session + device selection persist, so a restart resumes without
121
+ re-login. `retire` is the inverse.
122
+
123
+ ```sh
124
+ agent resurrect # background + on every login (windowless); starts it now too
125
+ agent retire # stop the background bridge + remove the logon pin
126
+ agent serve # foreground (this terminal) instead of background
127
+ agent stop # stop the running bridge
128
+ ```
129
+
130
+ **Disconnect.** `agent disconnect` is a full teardown — it removes the skill from
131
+ the runtime **and** signs out (the CLI twin of the app's **Revoke**). Use
132
+ `agent retire` as well if you also want the background bridge gone.
133
+
134
+ ## P0 — connect + prove the plane
135
+
136
+ ```sh
137
+ agent serve # start the loopback bridge (127.0.0.1:9876)
138
+ agent login # sign in on the SR web app (superresearch.io); --local = host page
139
+ agent status # → "Signed in as you@…"
140
+ agent doctor # health + token-refresh + connectivity checks
141
+ agent verify # reads your researches + lists reachable devices
142
+ agent verify --enqueue --device <id> --topic "Tesla 2025" # starts a real run
143
+ ```
144
+
145
+ `agent verify` (no `--enqueue`) is read-only. With `--enqueue` it creates a
146
+ research doc + a device-queue start doc — a real pipeline run that will appear
147
+ as an app chat.
148
+
149
+ ## P1 — remote sign-in + operational logging
150
+
151
+ **Remote sign-in (no localhost needed).** Approve from your phone via the
152
+ Super Research web app — the bridge brokers an OAuth device-style flow and makes
153
+ only outbound calls (see `SuperAgentRecipe.md` §11a):
154
+
155
+ ```sh
156
+ agent login --remote --runtime hermes
157
+ # → Open https://superresearch.io/connect-agent and enter code: AB-12
158
+ # (sign in to Super Research on your phone, tap Approve)
159
+ # ✓ Connected as you@…
160
+ ```
161
+
162
+ **`agent login` now defaults to the web app** (`superresearch.io` — the same page as
163
+ `/sr login` from chat + the connect Step 4 "Sign in"), so sign-in is one consistent
164
+ flow everywhere. The local Google page (`http://localhost:9876/login`) is the
165
+ `agent login --local` host-local fallback for dev / no-network.
166
+
167
+ **Logging.** `agent serve` writes a durable, rotating operational log to
168
+ `~/.super-agent/bridge.log` (request + run-lifecycle lines; never a token).
169
+ Add `-v` / `--verbose` (before or after the subcommand) for DEBUG.
170
+
171
+ **Pick a device.** List the devices your account can reach and choose which one
172
+ runs your research (the selection persists across restarts in
173
+ `~/.super-agent/prefs.json`):
174
+
175
+ ```sh
176
+ agent device # list (→ marks the selected one; (owned)/(shared))
177
+ agent device use <deviceId> # switch the target device
178
+ ```
179
+
180
+ `agent research`/`/sr research` resolves the device as: an explicit id → your
181
+ selection → the sole reachable device → an error asking you to pick one.
182
+
183
+ **Run, track, cancel.**
184
+
185
+ ```sh
186
+ agent research "Tesla 2025 outlook" # start a run → prints a run id immediately
187
+ agent runs # list recent runs (status + phase)
188
+ agent run [id] # one run's status + links (no id = latest)
189
+ agent watch [id] # stream per-phase links live until it finishes
190
+ agent skip <id> <phases…> # skip phases (1/3/4/5 or brief/podcast/video/report)
191
+ agent cancel <id> # stop a run (queued → dropped; running → stopped)
192
+ ```
193
+
194
+ `agent skip` tunes the run's config (Brief / Podcast → `skippedPhases`; Video →
195
+ `videoEnabled` off; Report → `emailEnabled` off); the device applies it when each
196
+ phase is reached.
197
+
198
+ `agent watch` polls and prints each new link (Brief → ChatGPT/Gemini/Claude →
199
+ NotebookLM/Audio → YouTube → Doc) as the device produces it, then stops at a
200
+ terminal status. The same signal feeds a runtime's streaming cron via
201
+ `GET /updates` (account-wide active runs + their current links) — a poller
202
+ dedups by `(runId, kind)`. (No `?since=` watermark: the backend doesn't bump
203
+ `updatedAt` on a per-phase link write, so the current link set is returned every
204
+ poll and deduped client-side.) Cancel writes a single `action:"cancel"` to the
205
+ run's device queue — dropped if queued, stopped if running.
206
+
207
+ > The web app's broker routes (`/api/agent/login/{start,approve,poll}` +
208
+ > `/connect-agent`) are built separately under review; this package is only the
209
+ > outbound client.
210
+
211
+ ## Layout
212
+
213
+ ```
214
+ facade/
215
+ config.py public Firebase config + bridge host/port/store + FE base
216
+ store.py secure session store (keyring + 0600 file fallback)
217
+ prefs.py non-secret prefs (selected device [uid-bound], runtime)
218
+ session.py AccountSession — refresh-token / custom-token → ID-token
219
+ firestore_rest.py minimal Firestore REST (researches/devices, upsert, enqueue, cancel)
220
+ devicelogin.py remote-login device-flow client (→ the SR web app broker)
221
+ logsetup.py rotating-file + console logging (--verbose)
222
+ runview.py flatten links.{kind} → ordered events; terminal-status set
223
+ connect.py install the skill into a chat runtime
224
+ bridge.py loopback HTTP server (/login, /login/remote/*, /devices,
225
+ /device, /research, /updates, …)
226
+ web/login.html Firebase Web SDK Google sign-in (TOTP MFA aware)
227
+ skill/ the chat-runtime bundle (SKILL.md + scripts/sr.py)
228
+ cli.py the `agent` command
229
+ ```
@@ -0,0 +1,19 @@
1
+ """research-facade — the Super Agent bridge.
2
+
3
+ A standalone, account-authed client on Super Research's normal Firestore
4
+ plane. It lets a chat runtime (Hermes / OpenClaw) drive Super Research as a
5
+ *headless session of the user's account*: the user signs in once with Google
6
+ (`/login`), and the bridge then enqueues research runs on the account's
7
+ existing devices. Runs surface in the web app as normal chats.
8
+
9
+ Hard boundaries (the "nothing breaks" contract):
10
+ * This package NEVER imports or mutates research-automate or research-app.
11
+ * It uses its OWN secret store namespace ("super-agent"), never the device
12
+ daemon's keystore ("super-research") — so refresh-token rotation here can
13
+ never disturb a paired device.
14
+ * It writes only what a normal account client may write (research docs +
15
+ device-queue start docs), all gated by the existing Firestore rules.
16
+ * Research-only: it can never control devices (add/remove/pair/share).
17
+ """
18
+
19
+ __version__ = "0.0.1"
@@ -0,0 +1,4 @@
1
+ from .cli import main
2
+
3
+ if __name__ == "__main__":
4
+ raise SystemExit(main())