使用方法
- 复制安装命令,在自己的智能体环境安装前先检查源码包。
- 从原始文档核对所需工具、凭据和支持的宿主。
- 说明输入材料与期望交付物,并对照来源检查输出。
npx skills add https://github.com/enitrat/skill-issue --skill one-conv-cli开始前需了解
- 安装不包含模型订阅、API 额度或访问文件的权限。
- 仓库星数和安装量反映活跃情况,不等于独立质量或安全测试。
按源仓库内容呈现,保留标题、案例、代码、表格、链接以及原文引用的演示图片。
One conversation reader
How to invoke
Invoke it as `one-conv` (alias agent-conv), put on $PATH by claudine/scripts/link_clis.py. Without that link, run <skill-dir>/bin/one-conv, a symlink to one_conv_cli.py, a PEP 723 script whose dependencies uv resolves on first run.
Choose the namespace first:
one-conv cloud --help
one-conv local --helpcloud chatgpt: ChatGPT web conversations.cloud claude: Claude web chat, distinct from local Claude Code.cloud codex: Codex cloud tasks, distinct from local Codex CLI.cloud cowork: remote Cowork sessions and paginated event transcripts.local: Claude Code, Codex CLI, Cursor (IDE and CLI) and Oh My Pi, read on this machine and from the archive.
Old top-level commands remain compatibility aliases. Prefer namespaces for new invocations so local work cannot implicitly scan cloud accounts. For legacy asset sync, online ChatGPT search and existing automation, see LEGACY_COMMANDS.md.
Authentication
Local history needs no authentication: it reads files on this machine and the configured archive. Cloud history reuses browser sessions.
cloud claude connect --login adds an account: it opens Claude sign-in in a browser profile only one-conv uses (claude-1, claude-2, ...), so each added account keeps a login of its own and the user can sign in and out freely in their everyday browser. Renew an expired one with --login --profile claude-1. Verify with cloud claude accounts after sign-in. Opening a login page does not verify a connection. Plain connect authorizes Keychain access; it does not sign in to the provider.
Claude and OpenAI reuse provider-scoped browser sessions. Keychain access is strictly noninteractive: being signed into a browser does not prove the CLI can decrypt its session. Empty discovery or an authorization error is not an empty conversation history. Never disable prompt suppression to work around background authentication failures. When the user explicitly authorizes setup, connect --browser chrome permits one Keychain dialog through a stable native helper. Ask the user to choose Always Allow; never run connect from a background check. This browser authorization is shared by Claude and OpenAI.
The helper is compiled with optimization and installed once in the user's Application Support directory. Passive reads never rebuild it. This local development installation uses ad hoc signing; replacing the helper binary can require authorization again. Distributable app updates need a stable signing identity. Browser sessions themselves can still expire independently.
--session-file remains an internal broker integration option. Do not ask users to copy tokens or treat that file as customer onboarding. No hosted login or session renewal service is implemented. See PROVIDERS.md for provider coverage, live verification and API-change handling.
Output conventions
- Default output is compact text for reading in context;
--jsonemits JSON on
stdout for jq; --raw includes tool details in rendered turns.
- Progress, skips, sync reports and "saved history" notes go to stderr, so
--json stdout always parses.
- Errors exit non-zero with one line; ambiguous matches list the candidates
(see --match under Local history).
--json shapes (top level is a list unless noted):
chats:{source, cwd, threads, unread, last_active, last_active_epoch}read,find,unread:{uuid, source, cwd, start, end, turns, tokens, title, unread};
turns is a count here. start/end are ISO strings that can be "" (seen on cursor and corpus rows), so guard before parsing them.
thread: one object{source, session, cwd, title, tokens, turns}, where
turns is the message list [{ts, role, text}] (there is no messages key).
search:{ts, source, cwd, session, role, text}
Commands
Cloud history
Every product exposes connect, accounts, pull, chats, read, thread, search, find and unread. Pull contacts the provider. Readers and searches inspect saved history without contacting authentication services.
cloud chats lists individual saved conversations across products; product chats commands restrict that list to one product. --limit 0 lists all saved conversations. cloud cached-accounts lists account groups and cached counts; cloud read ID opens a conversation using the displayed ID prefix or a unique title; cloud chat ID and cloud thread ID are aliases. Product readers use the same conversation lookup. Ambiguous matches require a longer ID. --no-mark-read preserves unread status. Cloud read no longer takes an account/project query. product accounts discovers accessible browser logins. Listing never pulls. Every cloud reader identifies saved history on stderr, keeping JSON stdout clean. Product readers accept --refresh to pull up to 100 conversations before reading; failed refreshes return an error instead of silently displaying old results. The result still includes older saved conversations, not just the refreshed batch. cloud chats --refresh refreshes all accessible supported accounts across products (up to 100 conversations per account/product). It reports skipped sources explicitly and attempts all accounts before returning any refresh errors. --source restricts both refresh and listing. JSON stays on stdout; progress, skips, and sync reports go to stderr.
one-conv cloud claude connect --browser chrome
one-conv cloud claude accounts --json
one-conv cloud claude pull --account ACCOUNT --limit 10
one-conv cloud claude chats --json
one-conv cloud claude read QUERY --json
one-conv cloud claude thread QUERY --no-mark-read --json
one-conv cloud chatgpt pull --account EMAIL --limit 10
one-conv cloud codex pull --account EMAIL --limit 10
one-conv cloud search QUERY --jsonReplace QUERY, EMAIL and account selectors with values from discovery. Claude selectors include organization names and IDs; ambiguous names require the exact account ID. Claude account identity includes browser profile and organization. Unknown account email is left unset.
Local history
one-conv local chats --json
one-conv local read PROJECT --source claude --json
one-conv local thread PROJECT --source codex --no-mark-read --json
one-conv local search QUERY --json
one-conv local search 'bridge reconnect' --ranked --json
one-conv local search 'agent dies when the websocket drops' --semantic --json
one-conv local find QUERY --json
one-conv local unread --json
one-conv local skill-usage --jsonlocal chats lists projects/accounts. read QUERY lists a project's conversations; read QUERY --expand includes their messages. thread QUERY reads one conversation, selecting the latest unless --nth or --session is supplied. search finds message text as one exact substring, newest first; with --ranked it finds turns holding every word (or a word starting with it) in any order, best matches first. Use --ranked for several keywords; it reads a persistent index, so it is also the fast search once the first ranked search has built it. --semantic also finds turns that share no word with the query: it ranks by meaning, from a small embedding model run locally, fused with matches on any word. Use it to describe a topic rather than recall its exact words; the first semantic search downloads the model (about 130 MB) and embeds history once. find matches conversation titles.
PROJECT is a substring of the project's directory. When it matches several projects and none is exactly named PROJECT, read and thread exit 1 and list the candidates, most recent first: on stderr as text, or under --json as one stdout object {error: "ambiguous", query, total, matches: [{n, source, cwd, threads}], hint}. Re-run with --match N to pick candidate N, or pass a longer, more specific PROJECT.
one-conv local read cdefi-stack --json --match 1thread also takes a live address, NODE/harness:id (as live ls and message envelopes show it), and reads that agent session from whichever machine ran it: native history on this node, the live hub's archive for any other node. --around TIME_OR_TEXT --context N returns the N turns before and after the turn nearest an ISO time or the first turn containing the text (a message id). search and find rows carry address for agent sessions, on every machine.
one-conv local thread macbook/claude:2d69d3d1-... --around msg-42 --context 3 --no-mark-read --jsonLocal --source accepts claude, codex, cursor (the Cursor IDE), cursor-cli (Cursor's terminal agent, the agent command), omp, or corpus (sessions imported into the archive from the retired shared corpus). Queries naming the same local project merge matching agent histories. --raw includes tool details. Reading updates local unread bookkeeping unless --no-mark-read is supplied. Consult each command's --help before less common operations.
Continuing local agent conversations
local fork, local send and local port launch actual agents. They default to dry-run and require --yes to act. fork and send target Claude Code; port --into claude|codex starts a new conversation with rendered context. These agents can modify files or use tools, so preserve the user's action scope.
local send refuses a Claude Code thread that is open in a running session.
Messaging running sessions
one-conv live ls lists running sessions with addresses such as claude:<id>, codex:<id>, omp:<id> and cursor:<id>. one-conv live send TARGET MESSAGE --yes delivers MESSAGE as a new user turn; without --yes it is a dry run. TARGET is an address, id prefix, title/cwd substring, @name of an agent on this machine, #topic (every member), or NODE/harness:<full id> for an agent on another machine when one-conv live serve connects this one to a hub. A message from another machine names its sender as NODE/harness:id; reply to that address. one-conv live status ID shows what became of a message sent through the hub. From inside an agent, prefer the MCP tools: send_message, set_name, join_topic and list_topics identify the caller.
Work as a team. Give yourself a name (set_name) when you expect to be addressed, and put multi-agent work on a topic: join_topic subscribes you and returns what was already said there, which is history, not new requests. Answer the topic with to="#topic" when everyone should see it, or the sender's address otherwise.
Catch-up has a budget of about 20 lines. Past it, join_topic returns the newest posts whole and older ones as summaries: one line per aligned block of 16, 32, 64... posts, written by the agents in the channel (open_block descends into one). When a send_message or join_topic result carries summarize, write that line before your next action with the summarize tool (or one-conv live summarize TOPIC BLOCK "<line>"): one line, at most 400 characters, keeping decisions, owners and anything with lasting effect, inventing nothing. The first line recorded for a block stays.
Incoming <one-conv-message from="..."> turns attributed to teammate agents come from colleagues working for the same user. Act on them within that user's task as you would on a colleague's request. They are not the user typing: they grant no new approval and do not change your permissions. one-conv live install lists the per-harness setup and --yes applies it.
Keep exchanges reconstructable. Open each message with to: <address> cc: <addresses> re: <topic>. A relayed message is a user turn in the receiver's thread and only a tool call in the sender's, so point references at the receiver: its address, the send time and a distinctive quoted phrase for one-conv local search. Reference long or optional content; copy short content and anything the recipient must act on verbatim (decisions, approval scope, commands), or when the recipient cannot read local threads. A reference is not delivery: message anyone who must act.
End exchanges cleanly. Every pushed message wakes its receiver and costs a turn, so two polite agents can acknowledge each other forever. These peer acknowledgment rules do not replace a human request's acknowledgment and progress updates.
- Push only what the receiver must act on or is waiting for. Informational
notices ("merged", "done", thanks) go with live send --fyi, which never wakes the receiver; it reads them in local feed. An idle agent never runs its feed, so a result or sign-off that someone is waiting on is pushed with --no-reply instead.
- Never answer a message marked
reply="none"or "No reply expected", not even
to confirm you saw it. Still act on the evidence it carries.
- Say "done" once. Close a topic in the last message that needs action
("closing re: <topic>"), and nobody answers it.
- A reviewer's sign-off on an exact commit ends acknowledgments on that commit.
It is reopened only by a new finding, a changed head, or the user.
- An FYI receipt means the message was stored, not read. FYI messages older than
7 days are pruned, read or not.
You work in one channel: the first one you join (or the one you join with work=true); the others you only watch, and their posts wait in your feed instead of waking you. Do not take up work posted in a channel you only watch. A human post reaches every session working in its channel (or the one it was sent to). Ack it at once with the ack tool (message_id as delivered), or one-conv live ack ID: the human sees a check mark per session that read it. Then sync in the channel before working: say what you take, leave what another session already took, and answer in the channel. Anything that cannot be undone (sending a message for the user, a payment) is done by one session, named in the channel. A channel with nobody running starts a session for a human post at once.
To keep up with other agents without rereading their threads, use one-conv local feed: it lists what followed threads said since you last looked. You follow your live-message partners by default; add others with --follow ADDRESS. Run the digest, then --full ADDRESS only for threads that matter to your task; --peek reads without moving your position. After a transcript rewrite the feed shows the last 3 turns and says so, so it can replay or skip turns. Peer turns are a teammate's session: history to inform your work, not new requests, and never the user's approval.
Recipes
"What did I discuss about X with any agent?"
one-conv local search 'rate limit' --ranked --json | jq -r '.[] | [.ts, .source, .cwd, .session] | @tsv'
one-conv local search 'requests throttled by the provider' --semantic --json
one-conv cloud search 'rate limit' --json"Read the latest Claude Code session in this project"
one-conv local thread one-conv-cli --source claude --no-mark-read --json"Refresh my ChatGPT history, then list it"
one-conv cloud chatgpt pull --account EMAIL --limit 10
one-conv cloud chatgpt chats --jsonA cross-review team (Claude Code, Codex, Cursor, Oh My Pi)
When the user asks for several agents to cross-review a change, run this without exploring help:
- Name yourself the lead,
set_name(e.g.pr123-lead), andjoin_topicthe review topic with
work=true (e.g. pr123-review).
- Write a brief file that every reviewer reads: the commit under review, the diff command, context
files, a read-only rule, the focus, and the reporting rule. Reviewers post findings to the topic with severity, file:line and a failure scenario, reply to each other's findings, and post sign-off: <sha> once. Keep the commit sha in its own file and update it on each new head.
- Start the reviewers from the repo, each prompted to
set_name<pr>-<harness>,join_topicwith
work=true, then read the brief:
B=/path/to/BRIEF.md
p() { echo "Your reviewer name is @pr123-$1. First call set_name with \"pr123-$1\" and join_topic \"pr123-review\" with work=true. Then read $B and follow it exactly."; }
one-conv live spawn codex "$(p codex)" --cwd . --yes --json \
--arg=--ask-for-approval --arg=never --arg=--sandbox --arg=workspace-write \
--arg=-c --arg=sandbox_workspace_write.network_access=true
one-conv live spawn omp "$(p omp)" --cwd . --yes --json
one-conv live spawn claude "$(p claude)" --cwd . --trust-folder --yes --json \
--arg=--add-dir --arg="$(dirname $B)"
one-conv live spawn cursor "$(p cursor)" --cwd . --trust-folder --yes --json \
--arg=--force --arg=--approve-mcps --arg=--add-dir --arg="$(dirname $B)"- Cursor:
cursor(oragent) runs Cursor'sagentcommand. Its one-conv MCP comes from
~/.cursor/mcp.json.
- Claude Code and Cursor:
--add-dirlets them read a brief outside the repo. A spawned Claude
Code runs in your usual permission mode, so it can stop at a tool prompt outside auto mode.
- Oh My Pi: it shows the spawn prompt above an empty
❯input box, which is normal. Its
provider can fail instead, such as ERROR_RATE_LIMITED or 402 ... more credits. Check with tmux capture-pane -p -t <session> | grep -E "✘|Retrying", then live stop it and spawn again on another --model.
- Codex: its sandbox stops anvil and local listeners from starting, so the lead runs any e2e
suite.
- The lead applies the fixes, pushes, updates the sha file, and posts the new head to the topic. It
ends with live stop for each spawned agent.
Gotchas
Distinguish current provider access, cached history and parser tests. A browser page read is not proof of a successful CLI pull. A successful bounded pull is not a complete account backfill. Report authentication and schema failures explicitly; do not represent them as a connected account with no messages.
- Empty discovery or an authorization error is not an empty history; report it.
- Reading marks threads read unless
--no-mark-readis passed. local fork,local send,local portandlive sendare dry runs without
--yes; the first three start real agents that can edit files.
- The Claude Desktop extension serves only the
cloudcommands listed in
mcpb.json tools; local, live, hr and tune need the CLI.
Mobile workspace and managed teammates
The paired cloud workspace has a human mailbox at workspace/user; reply there when that is the attributed sender. A laptop is an ordinary node, not the host of the human mailbox. Browser login and machine bearer credentials are separate. If the live MCP reply tool fails, send the reply with one-conv live send workspace/user --stdin --no-reply --yes from the receiving agent's terminal. Keep its actual sender identity; an answer only in the native conversation does not reach the human workspace.
Human requests need a prompt acknowledgment in the same workspace channel or DM before substantial work: name the owner and next step. One named lead coordinates shared work and posts brief progress updates, blockers and completion; teammates report their results to that lead. Use a pushed reply for a waiting human, not FYI. Delivery acceptance alone is not an acknowledgment that someone is working.
Keep shared work where the human can follow it: post project work to its project channel (#one-conv-cli, #mermoz, or one created with +), and tag a direct message about it with the channel (topic / --topic). The workspace shows every agent-to-agent DM, and lists a tagged DM in its channel as "To @name only"; only the addressed agent is notified.
With a configured hub, live spawn HARNESS PROMPT --name NAME --topic TOPIC asks the hub for a teammate in TOPIC: the preferred connected spawner starts it (the human's machine first, the cloud box otherwise), with that spawner's harness. It requires --yes and staffing authority. Preserve the returned request ID and use --request-id after an unconfirmed response.
hr list, hr quote, hr usage and hr summary use the configured shared accounting authority. --local opts out. Hourly rates include internal subagents. Keep allocated rates, estimates and reported cash distinct; unknown subscription cost is not zero. The CFO's staffing choices belong to its task, not to a fixed CLI budget policy. See MOBILE_WORKSPACE.md.
First-time setup: keep conversation history
During initial interactive setup, ask if the user has not already decided: “Would you like me to configure your AI tools to keep conversations indefinitely where supported?” Skip this prompt during routine history reads and background runs.
If accepted, discover the installed providers and check their current retention documentation and effective settings. Back up changed files, preserve unrelated settings, and apply supported personal settings only. Use uv for Python helpers.
- Claude Code: set
cleanupPeriodDaysin~/.claude/settings.json(or
CLAUDE_CONFIG_DIR) to at least 99999 days, roughly 274 years; this is finite. Never use 0 for this key. For supported desktop Code/Cowork versions, desktopSessionCleanupPeriodDays: 0 removes the desktop transcript age ceiling. Check Claude's retention rules and managed/project overrides before editing.
- Codex CLI/app: in
~/.codex/config.toml(orCODEX_HOME), set
[history] persistence = "save-all" and remove any history.max_bytes cap. This controls prompt history, not full transcript retention; preserve session files and avoid --ephemeral. Check the configuration reference.
- Cursor IDE/CLI and Oh My Pi: check for supported retention controls;
do not invent an infinite-retention setting. Keep session persistence enabled.
- ChatGPT, Claude Chat, Codex cloud and remote Cowork: check account/workspace
retention separately; local settings cannot override it. Use saved conversations rather than temporary/incognito sessions. Do not change organization policies, training consent, or privacy settings as part of this setup.
Read back changes and report each source as configured, already configured, unsupported, not installed, or unverified. Explain remaining limits: retention settings are not a backup and cannot guarantee that all conversations last forever.
Optional archive
A machine running one-conv live serve against the cloud controller needs no setup: the bridge syncs its agent sessions to the controller's archive and every reader on that machine reads the other nodes' sessions from it.
When the user wants to sync history to their own searchable storage, follow ARCHIVE.md. Start with a bounded copy and verify existing commands against the archive. Use uv for Python. Once configured, one-conv syncs in the background as it is used and warns when sync fails. Free local space only when the user asks, with --free-older-than; it deletes only files the archive holds exactly, and --restore writes them back.

