feat: ai session attach — live WebSocket streaming + interactive chat#278
Merged
feat: ai session attach — live WebSocket streaming + interactive chat#278
Conversation
…ive chat Adds a new CLI subcommand that attaches to a running AI session over WebSocket and streams messages in real time, with an optional interactive mode that turns the terminal into a chat with the agent. - new `limacharlie.sdk.ai_session.SessionAttachment` async helper wrapping the ai-sessions WebSocket protocol (prompt, interrupt, tool_approval_response, ask_user_question_response, heartbeat) - `AI.attach_session()` factory on the SDK, selecting the owner-interactive or org-scoped read-only endpoint - `limacharlie ai session attach --id <sid> [--interactive] [--read-only] [--raw] [--no-history]` command with colour-coded pretty printing and transparent 403 fallback to the read-only org endpoint when the caller is not the session owner - interactive loop surfaces tool approval requests and `ask_user_question` messages as live prompts - `websockets>=13.0` added as a runtime dependency - 39 unit tests covering URL derivation, send/receive plumbing, read-only enforcement, message rendering, and CLI registration Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Reworks `limacharlie ai start-session` so the ai_agent hive record is a
starting template and every profile field can be overridden from the
CLI for a single run.
Adds override flags matching the full server ProfileContent schema:
* --model, --max-turns, --max-budget-usd, --task-budget-tokens,
--ttl-seconds, --one-shot/--no-one-shot, --permission-mode,
--allowed-tools, --denied-tools, --plugin (repeatable)
* --env KEY=VALUE (repeatable) - merged with the template's
environment; override wins on key collisions
* --anthropic-key, --lc-api-key, --lc-uid - credential overrides
that accept literal values or "hive://secret/<name>" refs
Scalars and lists REPLACE the template value when passed. Environment
MERGES. Omitted flags leave the template untouched. Override values
that start with hive://secret/ are resolved before sending, so secrets
never appear in argv.
SDK: AI.start_session grows keyword-only override parameters.
Adds 30 new unit tests covering every override path: scalar replace,
list replace, env merge with collision, env secret resolution on
overrides, credential literal vs secret-ref overrides, CSV parsing
edge cases (empty list vs None), --env KEY=VALUE parsing validation,
and a help-text assertion that every flag is documented.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
maximelb
added a commit
to refractionPOINT/documentation
that referenced
this pull request
Apr 18, 2026
…tart-session` overrides Adds a dedicated CLI reference page for AI Sessions and cross-links from the surrounding pages: - New `docs/9-ai-sessions/cli.md` covering `ai session list/get/history/terminate`, `ai session attach` (flags, interactive controls, 403 fallback, output format with colour-coded message table), and `ai start-session` with its full override flag set (model, max-turns, max-budget-usd, task-budget-tokens, ttl-seconds, one-shot, permission-mode, allowed/denied-tools, plugin, env, anthropic-key, lc-api-key, lc-uid). - mkdocs.yml nav: add the new Command Line Interface entry under AI Sessions. - user-sessions.md: add a tip box pointing to the CLI attach command alongside the existing WebSocket example. - dr-sessions.md: note at the end of Example 5 that the same `ai_agent` Hive record can be reused as a CLI template via `ai start-session`. - 6-developer-guide/sdk-overview.md: add an AI Sessions section under Commands with the common invocations and a cross-link to the new page. Cross-links: * python-limacharlie: refractionPOINT/python-limacharlie#278 * lc-ai: (see matching PR) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
maximelb
added a commit
to refractionPOINT/lc-ai
that referenced
this pull request
Apr 18, 2026
Adds CLI usage notes to the lc-ai READMEs so deployed `ai_agent` records can be invoked ad-hoc with per-run overrides, not just triggered by D&R events. - README.md: new "Running Agents from the CLI" section under "Installing Agents" with `ai start-session --definition` and `ai session attach` examples. - ai-agents/README.md: new "Running Agents Manually from the CLI" section after Installation covering template override semantics (scalars replace, env merges, `hive://secret/` refs work in overrides) and showing start-and-attach in one step via jq. Links out to docs.limacharlie.io/9-ai-sessions/cli/ for the full reference. Cross-links: * python-limacharlie: refractionPOINT/python-limacharlie#278 * documentation: (see matching PR) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The GCP load balancer fronting ai.limacharlie.io routes /v1/sessions/*
to session-manager (REST API) and only /v1/ws/* to interaction-proxy
(WebSocket). The legacy /v1/sessions/{id}/ws path registered on the
proxy service isn't reachable through the LB, so attach was 404-ing
in prod and staging.
Switch _derive_ws_url to the GCP-routable form:
owner: /v1/ws/sessions/{id}
read-only: /v1/ws/org/sessions/{id}
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Splits the interactive chat flow out from `ai start-session` so the
two kinds of ai-sessions the backend supports each have their own
clear CLI surface:
* `ai start-session` continues to create org-owned sessions from an
ai_agent hive template, runs against the org's anthropic_secret,
and is designed for automation (DR-rule triggers, cron jobs).
These sessions are read-only over the WebSocket by design on the
backend, so `ai session attach --interactive` against them would
always fall back to read-only.
* `ai chat` creates a user-owned session via POST /v1/sessions,
billed against the caller's registered Claude credential, and
drops straight into an interactive WebSocket chat. Supports the
same profile overrides as start-session minus the org-only credential
fields (--anthropic-key, --lc-api-key, --lc-uid).
* `ai auth claude {status,login,set-key,logout}` manages the per-user
Claude credential that `ai chat` consumes. `login` walks the
browser OAuth flow; `set-key` accepts a raw Anthropic API key
(with hive://secret/<name> support and --key-from-stdin for piping).
Also extends the existing `_ai_attach.run_attach` with an optional
initial_prompt arg so `ai chat "question"` seeds the first turn
without duplicating the attach runtime.
New SDK methods on `limacharlie.sdk.ai.AI`:
register_user, claude_auth_status, claude_login_start,
claude_login_get_url, claude_login_submit_code, claude_set_apikey,
claude_logout, create_user_session.
All routed through a new `_user_request` helper that omits X-LC-OID
and uses JWT auth (matching the ai-sessions user-scoped route auth
middleware).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
POST /v1/sessions returns the session nested under a "session" key
(same shape as GET /v1/sessions/{id}), not flat. Caught during
live white-sands testing: the CLI raised "server response missing
session id" even though creation succeeded.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two follow-ups discovered during the white-sands round.
`ai chats {list,get,terminate,history}` is the user-owned counterpart
to the existing `ai session` group. Both groups share the same
shape, but each calls a distinct backend route family — `ai session`
hits /v1/org/sessions/* (org-owned, OwnerOID-keyed) and `ai chats`
hits /v1/sessions/* (user-owned, OwnerUID-keyed). Without this
split, sessions created by `ai chat` were unreachable from the CLI:
they'd accumulate, eventually hit the concurrent-session cap, and
required raw SDK calls or TTL expiry to clean up.
`ai chat` no longer consumes stdin as the initial prompt. The old
behaviour silently glued multi-line stdin into one prompt and left
nothing for the interactive input loop to read; users got a
one-shot exchange when they expected a back-and-forth. Now the
opening prompt is supplied via the PROMPT argument only, and stdin
is reserved for the interactive loop after attach (which is what a
TTY user would expect).
New SDK helpers on AI: list_user_sessions, get_user_session,
terminate_user_session, get_user_session_history.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
maximelb
added a commit
to refractionPOINT/documentation
that referenced
this pull request
Apr 19, 2026
…fix WS paths Three sets of changes to docs/9-ai-sessions/cli.md and the surrounding pages, matching the additions in refractionPOINT/python-limacharlie#278: * New "Two session ownership models" section near the top of cli.md spelling out the org-vs-user split, since the CLI now has parallel command groups for each (`ai start-session` + `ai session` for org-owned; `ai chat` + `ai chats` for user-owned). * New `ai auth claude {status,login,set-key,logout}`, `ai chat`, and `ai chats {list,get,history,terminate}` sections covering the user-owned interactive chat path. Clarifies that `ai chat` requires a per-user Claude credential (set via `auth claude`) and that `ai chats` is the lifecycle counterpart to `ai session` for user-owned sessions, with sessions of one ownership model being invisible to the other group's commands. * WebSocket URL paths corrected from the legacy `/v1/sessions/{id}/ws` and `/v1/org/sessions/{id}/ws` forms (which are unreachable through the GCP load balancer and return 404) to the new `/v1/ws/sessions/{id}` and `/v1/ws/org/sessions/{id}` forms the LB actually routes to the interaction-proxy. Plus knock-on edits: - "Endpoint selection and fallback" gains a tip box explaining that `--interactive` only sends prompts for user-owned sessions; org sessions transparently fall back to read-only by design. - The start-and-attach example under `ai start-session` no longer passes `--interactive`, since that flag is moot for the org-owned session it just created. - user-sessions.md tip retargeted from `ai session attach --interactive` to `ai chat` (the natural CLI entry point now). - sdk-overview.md AI Sessions section restructured to show both ownership paths side by side with the credential setup step. Cross-links: * python-limacharlie: refractionPOINT/python-limacharlie#278 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
maximelb
added a commit
to refractionPOINT/lc-ai
that referenced
this pull request
Apr 19, 2026
`ai_agent` Hive records run as org-owned sessions, and the ai-sessions backend exposes only a read-only WebSocket for those by design. Adding a one-liner to ai-agents/README.md so readers trying `attach` understand the read-only behaviour and know that `limacharlie ai chat` is the separate path for an interactive terminal chat with Claude. Cross-links: * python-limacharlie: refractionPOINT/python-limacharlie#278 * documentation: (matching PR) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Both `ai session list` and `ai chats list` were exposing raw
`--cursor` / `next_cursor` plumbing, pushing the pagination loop onto
the user. Switch to the convention used by `detection list` /
`audit list`: the CLI drains every matching session by default.
SDK changes
-----------
Split each list method into two layers:
- `list_sessions_page(...)` / `list_user_sessions_page(...)`: the
original single-page call, kept for callers that want explicit
pagination control (scripts, resumable iteration, streaming).
- `list_sessions(...)` / `list_user_sessions(...)`: generators that
drain `next_cursor` internally. `limit` caps total yielded rows
client-side; `page_size` maps to the server's per-request limit.
Mirrors `Organization.get_detections` / `get_audit_logs`.
CLI changes
-----------
`ai session list` / `ai chats list`:
- Default (no `--cursor`): drain the generator and output a plain
list of sessions — same shape as `detection list`.
- `--cursor <CURSOR>`: fall through to the single-page API and output
the raw `{sessions, next_cursor}` dict so callers can resume
pagination themselves. `--limit` under `--cursor` acts as the
server-side per-page cap; without `--cursor` it is a total cap.
Tests
-----
- Moved the existing single-page tests onto the `_page` methods.
- Added generator-side tests: multi-page drain, `limit` early-stops,
empty-string `next_cursor` is treated the same as None,
`page_size` shows up in the request but client-side `limit` does not.
- CLI: verified the default invocation routes through the generator
and never touches `_page`, and that `--cursor` routes through
`_page` and preserves the raw response.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Default pretty output was a firehose: empty assistant/user/result
frames, plumbing system subtypes (init_received, hook_started,
autoinit_loaded, ...), raw session_status JSON, full ISO timestamps,
and a stray ">" caret that landed on the next streamed line.
- Filter noisy message types (session_status, usage_delta) and system
subtypes (bridge + Claude SDK plumbing) by default.
- Skip assistant frames with only tool_use blocks, user frames that
wrap a tool_result, and result pings without a summary.
- Shorten timestamps to HH:MM:SS; add --verbose/-v to both
`ai session attach` and `ai chat` to restore the firehose.
- Fix user-content extraction: server sends {"content": [blocks]},
not {"text": ...}, so the "user:" line was always blank.
- Strip leading/trailing whitespace and whitespace-only blocks in
assistant text so Claude's "\n\n..." openers stop rendering as
empty indented lines.
- Drop the eager "> " input caret — under concurrent streaming it
interleaved with output; the terminal echoes keystrokes anyway.
- Share the noise set with `ai session history` / `ai chats history`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
lcbill
approved these changes
Apr 19, 2026
maximelb
added a commit
to refractionPOINT/documentation
that referenced
this pull request
Apr 20, 2026
…ions, attach, chat, auth claude) (#189) * docs(ai-sessions): document `limacharlie ai session attach` and `ai start-session` overrides Adds a dedicated CLI reference page for AI Sessions and cross-links from the surrounding pages: - New `docs/9-ai-sessions/cli.md` covering `ai session list/get/history/terminate`, `ai session attach` (flags, interactive controls, 403 fallback, output format with colour-coded message table), and `ai start-session` with its full override flag set (model, max-turns, max-budget-usd, task-budget-tokens, ttl-seconds, one-shot, permission-mode, allowed/denied-tools, plugin, env, anthropic-key, lc-api-key, lc-uid). - mkdocs.yml nav: add the new Command Line Interface entry under AI Sessions. - user-sessions.md: add a tip box pointing to the CLI attach command alongside the existing WebSocket example. - dr-sessions.md: note at the end of Example 5 that the same `ai_agent` Hive record can be reused as a CLI template via `ai start-session`. - 6-developer-guide/sdk-overview.md: add an AI Sessions section under Commands with the common invocations and a cross-link to the new page. Cross-links: * python-limacharlie: refractionPOINT/python-limacharlie#278 * lc-ai: (see matching PR) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(ai-sessions): document `ai chat`, `ai chats`, `ai auth claude`; fix WS paths Three sets of changes to docs/9-ai-sessions/cli.md and the surrounding pages, matching the additions in refractionPOINT/python-limacharlie#278: * New "Two session ownership models" section near the top of cli.md spelling out the org-vs-user split, since the CLI now has parallel command groups for each (`ai start-session` + `ai session` for org-owned; `ai chat` + `ai chats` for user-owned). * New `ai auth claude {status,login,set-key,logout}`, `ai chat`, and `ai chats {list,get,history,terminate}` sections covering the user-owned interactive chat path. Clarifies that `ai chat` requires a per-user Claude credential (set via `auth claude`) and that `ai chats` is the lifecycle counterpart to `ai session` for user-owned sessions, with sessions of one ownership model being invisible to the other group's commands. * WebSocket URL paths corrected from the legacy `/v1/sessions/{id}/ws` and `/v1/org/sessions/{id}/ws` forms (which are unreachable through the GCP load balancer and return 404) to the new `/v1/ws/sessions/{id}` and `/v1/ws/org/sessions/{id}` forms the LB actually routes to the interaction-proxy. Plus knock-on edits: - "Endpoint selection and fallback" gains a tip box explaining that `--interactive` only sends prompts for user-owned sessions; org sessions transparently fall back to read-only by design. - The start-and-attach example under `ai start-session` no longer passes `--interactive`, since that flag is moot for the org-owned session it just created. - user-sessions.md tip retargeted from `ai session attach --interactive` to `ai chat` (the natural CLI entry point now). - sdk-overview.md AI Sessions section restructured to show both ownership paths side by side with the credential setup step. Cross-links: * python-limacharlie: refractionPOINT/python-limacharlie#278 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(ai-sessions): document `--verbose` and default noise filter for `ai session attach` / `ai chat` Matches refractionPOINT/python-limacharlie@4f1e200, which cleaned up the pretty-printed live stream so `ai chat` is actually readable: - Plumbing `system` subtypes (credential_diagnostics, model_set, hook_started, autoinit_loaded, ttl_added_to_system_prompt, ...), `session_status` startup pings and `usage_delta` frames are hidden by default. - Empty assistant-tool-use-only frames, user tool_result wrappers and summary-less `result` pings are skipped. - Timestamps are abbreviated to `HH:MM:SS`. - A new `--verbose`/`-v` flag on both `ai session attach` and `ai chat` restores the firehose (useful when debugging session startup or correlating with server logs). Changes in docs/9-ai-sessions/cli.md: - Flag tables for `ai session attach` and `ai chat` gain a `--verbose`/`-v` row that cross-links the new "Default noise filter" subsection. - New "Default noise filter" subsection under "Output format" enumerates the filtered types / subtypes / empty-frame rules and calls out that the same set is used by `ai session history` / `ai chats history`. - The existing one-liner under `ai session history` now cross-links the shared filter section so readers see both surfaces share it. - Output-format section notes that timestamps default to `HH:MM:SS` and `--verbose` preserves the full ISO-8601 value. No behavioural change elsewhere — `--raw` semantics, endpoint selection, interactive controls and the colour-coded table are unchanged. Cross-links: * python-limacharlie: refractionPOINT/python-limacharlie@4f1e200 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
maximelb
added a commit
to refractionPOINT/lc-ai
that referenced
this pull request
Apr 20, 2026
* docs: explain running ai_agent Hive records from the CLI Adds CLI usage notes to the lc-ai READMEs so deployed `ai_agent` records can be invoked ad-hoc with per-run overrides, not just triggered by D&R events. - README.md: new "Running Agents from the CLI" section under "Installing Agents" with `ai start-session --definition` and `ai session attach` examples. - ai-agents/README.md: new "Running Agents Manually from the CLI" section after Installation covering template override semantics (scalars replace, env merges, `hive://secret/` refs work in overrides) and showing start-and-attach in one step via jq. Links out to docs.limacharlie.io/9-ai-sessions/cli/ for the full reference. Cross-links: * python-limacharlie: refractionPOINT/python-limacharlie#278 * documentation: (see matching PR) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs: clarify `ai session attach` is read-only for deployed agents `ai_agent` Hive records run as org-owned sessions, and the ai-sessions backend exposes only a read-only WebSocket for those by design. Adding a one-liner to ai-agents/README.md so readers trying `attach` understand the read-only behaviour and know that `limacharlie ai chat` is the separate path for an interactive terminal chat with Claude. Cross-links: * python-limacharlie: refractionPOINT/python-limacharlie#278 * documentation: (matching PR) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three related additions to the
aiCLI, on top of cli-v2. Together they cover the two distinct session models the ai-sessions backend exposes — org-owned automation and user-owned interactive — plus the WebSocket attach that streams both.1.
limacharlie ai session attach— live session streaming + interactive chatai.limacharlie.ioand streams session messages in real time with colour-coded pretty-printing (--rawfor JSON).--interactive/-iturns the terminal into a chat: stdin lines are sent aspromptmessages;tool_approval_requestandask_user_questionmessages are surfaced as live prompts;/interruptand/quitbuilt in.--read-onlyconnects to the org-scoped/v1/ws/org/sessions/{id}endpoint. When the owner endpoint returns 403 (the caller isn't the session owner), the CLI transparently falls back to read-only with a notice./v1/ws/...form — the only prefix the GCP load balancer routes to the interaction-proxy. The legacy/v1/sessions/{id}/wsform registered on the proxy service isn't reachable through the LB and returns 404.limacharlie.sdk.ai_session.SessionAttachmentasync helper wrapping the full WebSocket protocol (seeai-sessions/api/WEBSOCKET_PROTOCOL.md): prompt, interrupt, tool_approval_response, ask_user_question_response, heartbeat.AI.attach_session(session_id, read_only=...)factory on the SDK.websockets>=13.0to runtime dependencies.Important: sessions created by
ai start-session(below) are org-owned (OwnerOIDset,OwnerUIDempty,SessionType=API). The backend exposes those only through the read-only org-scoped WS endpoint, soai session attach --interactiveagainst an org-started session will always auto-fall back to read-only. Useai chat(below) to get a real interactive session.2.
limacharlie ai start-session+ai session {list,get,terminate,history}— org-owned sessionsai start-sessionruns anai_agenthive record as a template; every field on the server'sProfileContentschema can be overridden for a single run:--model,--max-turns,--max-budget-usd,--task-budget-tokens,--ttl-seconds,--one-shot/--no-one-shot,--permission-mode,--allowed-tools,--denied-tools,--plugin(repeatable).--env KEY=VALUE(repeatable) — merged with the template's environment; override wins on key collisions.--anthropic-key,--lc-api-key,--lc-uid— credential overrides that accept literal values orhive://secret/<name>refs.Scalars and lists REPLACE the template value when passed. Environment MERGES. Omitted flags leave the template untouched. Override values starting with
hive://secret/are resolved before sending so secrets never appear in argv.The
ai sessiongroup manages org-owned sessions through their lifecycle:list,get,terminate,history,attach.Examples:
```
limacharlie ai start-session --definition my-agent
--model claude-sonnet-4-6 --max-budget-usd 2.50
limacharlie ai start-session --definition my-agent
--env SLACK_WEBHOOK=hive://secret/slack-webhook
limacharlie ai start-session --definition my-agent
--allowed-tools Read,Grep --denied-tools Bash,Write --no-one-shot
```
3.
limacharlie ai chat+ai chats {list,get,terminate,history}+ai auth claude— user-owned interactive sessionsai start-sessioncreates org-owned sessions (read-only over the WS by design).ai chatcreates user-owned sessions billed against the caller's registered Claude credential, opens the owner WS endpoint, and hands the terminal off to the interactive attach loop — the setup the existing--interactiveflag was always describing.ai chatsis the user-scoped counterpart toai session: same subcommand shape (list,get,terminate,history), but it routes to/v1/sessions/*(user-owned, keyed by the caller's UID) instead of/v1/org/sessions/*. Sessions of one kind are not visible from the other group's commands; they live in distinct ownership models on the backend.New credential-management surface (one-time setup before
ai chatworks):ai auth claude status— returnshas_credentials,credential_type(oauth_token/apikey),created_at.ai auth claude login— full browser OAuth flow: calls/v1/auth/claude/start, polls/v1/auth/claude/urlfor the URL, prompts the user for the returned code, posts it to/v1/auth/claude/code.ai auth claude set-key --key <VALUE>(or--key-from-stdin) — stores a raw Anthropic API key;hive://secret/<name>is resolved before sending.ai auth claude logout—DELETE /v1/auth/claude.ai chatflow:claude_auth_status; ifhas_credentials=false, exits non-zero with a pointer toauth claude login/set-key. No silent fallback.POST /v1/register(idempotent).POST /v1/sessionswith any supplied overrides (--model,--max-turns,--max-budget-usd,--task-budget-tokens,--permission-mode,--allowed-tools,--denied-tools,--plugin,--name,--idempotent-key).PROMPTargument is given it's sent as the opening prompt; further turns come from the interactive stdin loop. Stdin is not consumed as the opening prompt — supply that via the argument so multi-line piping doesn't get glued into one message.Examples:
```
limacharlie ai auth claude login
limacharlie ai chat "what sensors pinged in the last hour?"
limacharlie ai chat --model claude-sonnet-4-6 --max-budget-usd 0.50
limacharlie ai chats list --status running
limacharlie ai chats terminate --id
```
The existing
ai session attachstill works for either kind of session — use it to rejoin an existing session or view an org-owned one live in read-only mode.Cross-linked PRs
aiCLI surface (org + user sessions, attach, chat, auth claude) documentation#189Protocol references
ai-sessions/internal/proxy/handler.go:111-397andai-sessions/api/WEBSOCKET_PROTOCOL.md. GCP LB URL map:ai-sessions/terraform/modules/load-balancer/main.tf:137-190—/v1/ws/*routes to the interaction-proxy.ai-sessions/pkg/api/types.go(SessionRequest/ProfileContent).ai-sessions/internal/sessionmanager/models.go(CreateSessionRequest). Routes:handler.go:36-43.ai-sessions/internal/claudeauth/handler.go.ai-sessions/internal/common/jwt.go— acceptsAuthorization: Bearer <jwt>andSec-WebSocket-Protocol: access_token, <jwt>; the CLI uses the header form viaClient.get_jwt().Test plan
pytest tests/unit/— 3075 passed, 5 pre-existing platform/docstring skips. 39 intests/unit/test_ai_session_attach.pyplus 73 in the extendedtests/unit/test_sdk_ai_sessions.py(org SDK + user SDK + auth + chat + chats CLI groups).ai start-sessionoverride propagation verified on-wire (model/max_turns/max_budget_set in session init);max_budget_usd=0.10cap triggered precisely at $0.10530.ai session attachconnects via/v1/ws/sessions/{id}; pretty +--raw | jqboth work; owner endpoint 403 → transparent read-only fallback notice emitted.ai auth claude statusreturns the live credential state.ai chat "What is the capital of France?"against a registered user — assistant replied "Paris" in interactive mode (no read-only fallback).ai session attach --interactiveto the same session and send a follow-up — assistant replied "56" to "What is 7 times 8?".ai chats list/ai chats get --id <id>show user-owned sessions invisible toai session list.ai auth claude loginagainst a fresh user — walk through browser flow, confirm credential stored.ai auth claude set-key --key-from-stdinwith a raw Anthropic key.