Documentation
¶
Overview ¶
Package cliskychat cmd/skywire-cli/commands/skychat/chat.go c4-vis-cli interactive split-pane chat against the local skychat app's HTTP/SSE interface.
Top: scrolling message history (sent + received). Bottom: an input to compose. Enter sends; Esc / Ctrl+C quits. A background goroutine reads the /sse stream and pushes incoming messages into the screen; outgoing messages POST to /message synchronously on Enter.
`--to <pk>` pins the conversation to one remote. Messages from other senders still appear in the history (so you can see other peers trying to reach you) but Enter always sends to --to.
Package cliskychat cmd/skywire-cli/commands/skychat/chat_tui.go c5-cli-skychat
The 1:1 chat screen, drawn with progkit. The command spec stays in chat.go. In websh the message line is a real text field and the conversation selectable text.
Package cliskychat cmd/skywire-cli/commands/skychat/escape.go c4-vis-cli helpers for keeping `skychat listen` and `skychat group listen` output strictly one-line-per-message.
Why this exists: agent monitor harnesses and most log aggregators treat each stdout line as a separate event. When a chat body contains embedded newlines, the default fmt.Fprintf(out, "... %s\n", body) emits multiple lines for one logical message — the harness either fragments them into N events (losing per-message correlation) or clips at line N due to per-event size limits. The wire is fine (/status.inbound_msg_count and chat-app logs still see the full body); the issue is purely the CLI's stdout shape.
escapeForOneLine renders a body so each chat message renders as exactly ONE line of stdout. We pick literal `\n` / `\r` / `\\` escapes (visible to humans, machine-detectable) rather than dropping the characters: an operator reading the log can still tell the message contained newlines, and any consumer that wants the raw content can pass --raw (or --json, which handles multi-line bodies natively via JSON string encoding).
Package skychat cmd/skywire-cli/commands/skychat/events.go c4-vis-cli NDJSON stream of chat events from the chat app's GET /events SSE endpoint.
Replaces fragile `tail -F | awk | grep` log monitors (which broke under logrotate copytruncate). Each event carries a monotonic seq cursor; on reconnect the CLI resends --since=<last seq> so no events are missed, and dedupes by id. Agreed schema (Beta+Gamma consensus).
Package cliskychat cmd/skywire-cli/commands/skychat/group.go c4-vis-cli operator-facing CLI for D1 group chat. Thin wrappers over the visor's GroupX RPC methods.
Subcommands:
skywire cli skychat group create --name <name> [--kind public|private|channel] [--member <pk> ...] skywire cli skychat group list skywire cli skychat group info <group-id> skywire cli skychat group invite <group-id> # re-emits the invite link skywire cli skychat group address <group-id> # short skychat:// address skywire cli skychat group resolve <address> # what does this address point at? skywire cli skychat group catalog [host-pk] # what does a visor publish? skywire cli skychat group publish <group-id> <on|off> # publish in the catalog skywire cli skychat group join <invite-link|address> skywire cli skychat group add <group-id> <pk> # admin: extend allowlist skywire cli skychat group promote <group-id> <pk> # admin: grant roster authority skywire cli skychat group demote <group-id> <pk> # admin: revoke roster authority (founder is immutable) skywire cli skychat group send <group-id> <text> # owner only in v1 skywire cli skychat group listen [--since RFC3339] # poll inbox, stream skywire cli skychat group leave <group-id> # member side skywire cli skychat group delete <group-id> # owner side
All commands talk to the LOCAL visor via clirpc.Client; the visor owns the group.Manager. No DMSG dial happens in the CLI itself.
Package cliskychat cmd/skywire-cli/commands/skychat/pair.go c4-vis-cli CLI surface for the CXO-backed 1:1 chat path (test-matrix row 1c).
Distinguishes from `cli skychat send`: that one POSTs /message which writes a chat-msg envelope over dmsg-pair or a skynet route — no CXO, no persistence. These subcommands target the chat-app's /pair endpoints which sit on top of the visor's Pair-RPC (PairAdd / PairSend / PairList / PairPoll). Each pair is a 2-member CXO group with per-side per-peer feeds; the underlying mechanism is the same shape as skychat-group's federated send (#2580) restricted to N=2.
Operator use case: validate that CXO p2p works (catches bugs in CXO itself) before piling on the multi-subscriber convergence case (1d, full-mesh group) or the admin-aggregator topology (2, federated). If 1c (this surface) works but 1d breaks, we know the bug is in CXO multi-subscriber convergence, not in CXO itself.
Pair-rpc is gated by `--pair-enable` on the chat-app — chat-app surfaces /pair endpoints only when that flag is set. CLI emits a clear "pair-rpc-disabled" error rather than a confused 404 when the chat-app side hasn't enabled it.
Package cliskychat cmd/skywire-cli/commands/skychat/root.go c4-vis-cli
Package cliskychat cmd/skywire-cli/commands/skychat/sendfile.go c4-vis-cli
`skywire-cli skychat send-file` sends a local file to a peer (1:1) or to the active CXO group, via the running skychat app's HTTP API (POST /send-file). The file itself streams peer-to-peer over an encrypted skywire transport (skyenv.SkychatFilePort, skynet or dmsg) — the HTTP call only hands the app a local path to read. Files are conversation messages: the transfer surfaces in history / SSE like any other message.
Package cliskychat cmd/skywire-cli/commands/skychat/tcp_via.go c4-vis-cli `cli skychat send --via tcp://<pk>@host:port`. Mirrors the dmsgpty `--via tcp://` pattern: dial the remote chat-app's --tcp-listen port, run noise XK with the remote's PK pinned, write a chat-msg envelope, optionally wait for chat-ack, close.
Distinct from the default send path (which POSTs to the local chat-app's /message HTTP endpoint and lets the chat-app pick a transport). --via tcp:// bypasses the local chat-app entirely — the CLI process IS the dialer. This is the reliability-floor transport: works when the local visor is down, when dmsg-disc is unreachable, when the chat-app itself is wedged.
Identity resolution (--sk → DMSGCURL_SK → -c skywire.json → ephemeral) matches the chat-app's tcp-direct path so operators have one mental model for "what identity goes on the wire".
Package cliskychat cmd/skywire-cli/commands/skychat/tui_unified.go c4-vis-cli
The unified skychat screen, drawn with progkit: a picker listing every conversation the local visor knows (1:1 peers and group memberships), and the conversation picked. New conversations start from the picker too.
`skywire cli skychat chat -t <pk>` goes straight to the 1:1 screen (chat_tui.go); with no -t and no -g it lands on the picker.
Package cliskychat cmd/skywire-cli/commands/skychat/verbose.go c4-vis-cli
statusCounters: minimal snapshot of the chat-app's /status counter surface used by `cli skychat send --verbose` to compute pre/post deltas around a single send. Surfacing the deltas at the CLI lets operators see WHICH layer absorbed a failure (HTTP retry path? transport-fallback path? chat-app outbound-fail path?) without having to grep visor logs after the fact.
Why not just re-use a struct from cmd/apps/skychat/commands: that package is the chat-app implementation; the CLI is a thin client over /status JSON. Importing the chat-app's full struct here would pull in its dependency graph (persistent-stores, …). The trimmed shape here is just the counters the verbose path needs.
Package cliskychat cmd/skywire-cli/commands/skychat/voice.go c4-vis-cli
Package cliskychat cmd/skywire-cli/commands/skychat/voice_answer.go c4-vis-cli
Explicit-answer controls for inbound voice calls. Incoming calls RING instead of auto-answering, so the microphone is never streamed without an explicit answer. `voice incoming` lists ringing calls; `voice answer`/`voice decline` act on one by id.
Package cliskychat cmd/skywire-cli/commands/skychat/voice_ringback.go c4-vis-cli
Outbound-call progress and the ringback tone. `voice dialing` shows how the calls this visor is placing are going — connecting, ringing, or why one did not connect. `voice ringback` manages the tone people hear while THIS visor rings: set it from an audio file, show it, or clear it back to the plain ring.
Package cliskychat cmd/skywire-cli/commands/skychat/voice_spectrogram.go c4-vis-cli
`skywire-cli skychat voice spectrogram` renders a live audio spectrogram in the terminal — the CLI-side "see the audio" view for voice chat (stands in for video). It captures local audio via the pure-Go PulseAudio backend (mic, or --monitor for whatever the system is playing, no mic needed) and feeds it to the vendored audioprism DSP core. Linux only; press q / Esc / Ctrl-C to quit.
The rendering deliberately MIRRORS the operator's audioprism-go tcell UI (github.com/0magnet/audioprism-go/pkg/ui/tcell) so this view looks the same: capture at spectrogram.SampleRate, overlap-stepped FFT columns (one per StepSize samples), a fixed 2048×1024 circular history downscaled to the terminal, the vertical axis mapped linearly to 0–12 kHz with low frequencies at the bottom, and the same MagnitudeToPixel colormap. The same renderer feeds the two-panel sent/received view during an actual call (follow-up).
Index ¶
Constants ¶
This section is empty.
Variables ¶
var RootCmd = &cobra.Command{
Use: "skychat",
Short: "Skychat messaging",
Long: "Send and receive messages via skychat.",
}
RootCmd contains skychat commands
Functions ¶
This section is empty.
Types ¶
type AckResponse ¶
type AckResponse struct {
Acked bool `json:"acked"`
ID string `json:"id,omitempty"`
MS int64 `json:"ms,omitempty"`
Reason string `json:"reason,omitempty"`
}
AckResponse is the JSON body the skychat app's /message endpoint returns when wait_ms > 0. Exported so the TUI / scripted callers can consume the same shape.