wtt-connect
v0.2.111
Published
WTT-native connector daemon for Codex, Claude Code, Gemini, DeepSeek Harness, ACP, and other coding agent surfaces.
Readme
wtt-connect
For the opt-in WTT Paseo host runtime, see Host Runtime Foundation. This is not yet a desktop/QR remote-access release.
wtt-connect is the WTT-native connector daemon. It is not intended to be a reduced cc-connect clone: the goal is feature parity and then WTT-specific extensions while keeping surfaces such as TTS, agent adapters, task routing, chat routing, artifacts, and permission control as first-class modules.
Implemented production-oriented surfaces:
- Long-lived WTT WebSocket client
- WTT chat and task event intake
- Per-session mailbox/actor queue (
topic_id/task_id) so busy acks are never treated as final replies - Durable local state store for session/thread ids, dedupe, and artifact ledger
- Multi-adapter registry and routing, aligned with cc-connect's agent backend matrix without depending on a cc-connect process:
codexviacodex exec --jsonclaude-codeviaclaude -p --output-format stream-jsoncursorvia Cursor Agent CLI (agent --print --output-format stream-json)geminivia Gemini CLI (gemini --output-format stream-json)qoderviaqodercli -f stream-jsonopencode/crushvia OpenCode-stylerun --format jsoniflowvia iFlow CLIkimivia Kimi CLI (kimi --print --output-format stream-json)pivia Cursor Background Agent (pi --mode json)acpfor any Agent Client Protocol compatible agentdevinthrough ACP (devin acp)dshthrough DeepSeek Harness native session RPC
- Normalized tool/progress event publishing
- TTS extension point:
nonemacos-sayusing the macOSsaycommand, emitted as WAV when upload is enabled
- HTTP task status update path
- Permission broker for agent modes; Codex, Claude Code, Gemini, and DeepSeek Harness default to
yolono-approval/full-access mode when bound throughwtt-connect up - Optional WTT media artifact upload path (
/media/sign→ direct upload →/media/commit) - Agent-generated file artifacts for WTT feed chat (
.docx,.pptx,.xlsx,.pdf,.csv,.zip) using explicit final-response markers that are converted into WTT file cards - Attachment staging for WTT message media/files; image attachments are passed to adapters that support image inputs, such as Codex with
--image; Claude Code stays on the Claude Code adapter and returns its own result if the selected model cannot reason over images - STT extension point (
commandand OpenAI/Whisper providers) for audio attachments - Setup/claim-code command, smoke-task/smoke-chat commands, start script, and macOS launchd installer
- npm-installable Node.js implementation (Node >= 22) with runtime dependencies installed by npm
Why this exists
cc-connect is a broad IM-to-agent bridge. WTT needs a connector that is native to WTT's identity, task, runner, artifact, permission, and observability model. wtt-connect should eventually cover cc-connect's useful capabilities instead of dropping them.
Quick start
Install once, then bind each WTT agent identity with one command:
npm install -g wtt-connect
wtt-connect up codex agent-001 'wtt-tok-001'
wtt-connect up claude-code agent-002 'wtt-tok-002'
wtt-connect up gemini agent-003 'wtt-tok-003'
wtt-connect up dsh agent-004 'wtt-tok-004'up writes a profile, installs a background service, enables it for the current user, starts it immediately, and prints status. On Linux it installs a systemd --user service; on macOS it installs a LaunchAgent. The npm install step installs package dependencies such as node-pty; users should not need to run npm install inside a cloned source tree.
Common management commands:
wtt-connect list
wtt-connect status all
wtt-connect restart all
wtt-connect logs agent-001-codex --lines 100
wtt-connect down agent-001-codexFor source-tree development:
cd tools/wtt-connect
node ./bin/wtt-connect.js setup --claim-code
npm run doctor
npm startOr run directly:
node ./bin/wtt-connect.js doctor
node ./bin/wtt-connect.js startConfiguration
Environment variables are loaded from tools/wtt-connect/.env and current working directory .env.
For multiple WTT agent identities, pass an explicit dotenv file with --env-file or WTT_CONNECT_ENV_FILE; that file is loaded before the default .env files, so it wins for that process.
Important settings:
WTT_BASE_URLWTT_AGENT_IDWTT_TOKENWTT_CONNECT_ADAPTER=codex|claude-code|cursor|gemini|qoder|opencode|crush|iflow|kimi|pi|acp|devin|dshWTT_CONNECT_ADAPTERS=codex,claude-code,cursor,gemini,qoder,opencode,iflow,kimi,pi,acp,devin,dshWTT_CONNECT_WORKDIRWTT_CONNECT_MODE=full-auto|auto-edit|yolo|suggest- Codex, Claude Code, Gemini, and DeepSeek Harness default to
yolono-approval/full-access mode when no explicit mode is set. Codex runs with--dangerously-bypass-approvals-and-sandbox; Claude Code runs with--dangerously-skip-permissions --permission-mode bypassPermissions; Gemini runs with-y; DSH selects its nativefull-accessworkspace policy. WTT_CONNECT_AGENT_ALIASES=alias1,alias2for extra @mention names in discussion/collaborative topics;WTT_AGENT_IDalways worksWTT_CONNECT_ALLOW_YOLO=1only when intentionally usingyoloWTT_CONNECT_STATE_DIR/WTT_CONNECT_STORE_FILEfor durable sessionsWTT_CONNECT_UPLOAD_ARTIFACTS=1to upload generated summaries/TTS through WTT mediaWTT_CONNECT_TTS_PROVIDER=none|macos-sayWTT_CONNECT_STT_PROVIDER=none|command|openai|whisperandWTT_CONNECT_STT_COMMAND='...'WTT_CONNECT_STT_OPENAI_API_KEY,WTT_CONNECT_STT_OPENAI_BASE_URL,WTT_CONNECT_STT_OPENAI_MODEL,WTT_CONNECT_STT_OPENAI_TRANSPORT=auto|fetch|curl,WTT_CONNECT_STT_LANGUAGEfor OpenAI-compatible speech-to-textWTT_CONNECT_ENABLE_SHELL=1exposes an interactive agent-side Terminal from wtt-web for claimed online agentsWTT_CONNECT_SHELL_MODE=unsafe|readonly|off; defaultunsaferuns one-shot shell commands without command filtering. The interactive Terminal always opens a real PTY shell on the agent host.WTT_CONNECT_SHELL_TIMEOUT_SECONDSandWTT_CONNECT_SHELL_MAX_OUTPUT_CHARSonly bound legacy one-shot command execution and returned outputWTT_CONNECT_MODELis only a fallback default. Per-messagemetadata.model_config.modelfrom WTT Web overrides it for that run.WTT_DSH_BIN=dsh,WTT_DSH_WEB_URL,WTT_DSH_WORK_DIR, andWTT_DSH_PROVIDER=deepseek-officialconfigure the native DeepSeek Harness adapter. LeaveWTT_DSH_WEB_URLempty to letwtt-connectstart a loopback-only authenticateddsh websidecar. To attach an existing sidecar, use the complete tokenized URL printed bydsh web. DSH credentials such asDEEPSEEK_API_KEYremain on the agent host.
Optional model/provider switcher:
WTT_CONNECT_MODEL_SWITCH_MODE=off|cc-switch|command|customWTT_CONNECT_MODEL_SWITCH_COMMAND=cc-switchWTT_CONNECT_MODEL_SWITCH_ARGS='["use","{adapter}","{provider}","--model","{model}"]'WTT_CONNECT_MODEL_SWITCH_TEMPLATE='cc-switch use {adapter} {provider} --model {model}'WTT_CONNECT_MODEL_SWITCH_STRICT=0|1; when false, switcher failures are logged and the adapter still runsWTT_CONNECT_MODEL_SWITCH_TIMEOUT_MS=15000WTT_CONNECT_MODEL_PROVIDER_MAP='{"openai-codex/*":{"adapter":"codex","provider":"openai"},"deepseek/*":{"adapter":"claude-code","provider":"deepseek"}}'
This hook is for Cloud Agent hosts that use cc-switch or a compatible local provider/config switcher. WTT Web still only sends per-message metadata.model_config; wtt-connect resolves adapter/provider/model, invokes the switcher inside the agent runtime, then runs the selected Claude Code or Codex adapter. When the switcher is enabled, each container serializes switcher plus CLI execution so concurrent topic runs do not race over a shared provider config.
Session continuity:
wtt-connectuses the WTT topic/task id plus adapter and model as the local session key, for examplewtt:topic:<topic_id>:codex:gpt-5.6-sol:high.- Codex stores
codexThreadIdand resumes withcodex exec resume. - Claude Code stores
claudeSessionIdand resumes the same topic withclaude --resume <session_id> -p .... - Gemini stores
geminiSessionIdand resumes withgemini --resume <session_id> --output-format stream-json. - DeepSeek Harness stores
dshSessionIdand resumes through its native session RPC. One DSH sidecar can run independent WTT topic sessions concurrently; messages within one topic remain serialized. - Keep
WTT_CONNECT_STATE_DIR,WTT_CONNECT_STORE_FILE, andWTT_CONNECT_WORKDIRstable per claimed agent. If they are changed or deleted, the adapter cannot resume previous local sessions.
A JSON config may also be supplied:
node ./bin/wtt-connect.js start --config ./config.jsonGenerated files in feed chat
Codex, Claude Code, and other adapters can generate user-facing files on the agent host and send them back to WTT feed chat as clickable file cards.
Supported generated artifact types:
.doc .docx .ppt .pptx .xls .xlsx .pdf .csv .md .txt .zip .html .png .jpg .webp .mp4 .webm .movWhen an agent creates a deliverable file, it can save the file anywhere under its own WTT workspace (~/.wtt-connect/<agentID> by default, or WTT_CONNECT_WORKDIR when set). The agent should then explicitly publish it with:
wtt-connect upload-file --topic-id <topic_id> --title "Project Report" ./report.pdf
wtt-connect upload-file --topic-id <topic_id> --title "Design Pack" ./a.pdf ./slides.pptx ./notes.mdupload-file uploads the file through WTT media and publishes a clickable file card into the topic. If several files are passed, it packages them into one zip before publishing. wtt-connect does not scan the workspace automatically.
Agents can also include one final-response marker per file to provide a better display title:
[WTT_ARTIFACT_FILE path="report.docx" title="Project Report"]
[WTT_ARTIFACT_FILE path="/absolute/workspace/slides.pptx" title="Review Slides"]wtt-connect removes those marker lines from the visible reply, uploads each file through WTT media, and publishes file cards like:
[file:Project Report](https://...)Notes:
- Generated files published through
upload-fileand explicit markers are user-facing uploads; they are uploaded even whenWTT_CONNECT_UPLOAD_ARTIFACTS=0. - Files outside the configured workspace, state directory, inbox directory, or artifact directory are ignored to avoid accidental leakage.
WTT_CONNECT_UPLOAD_ARTIFACTS=1still controls automatic summary/TTS uploads; it is not required for explicit generated file markers.
One-command service binding
The recommended install path for users is npm + up:
npm install -g wtt-connect
wtt-connect up <agenttype> <agent_id> <token>Examples:
wtt-connect up codex agent-alice 'wtt-tok-alice'
wtt-connect up codex agent-bob 'wtt-tok-bob'
wtt-connect up claude-code agent-claude 'wtt-tok-claude'
wtt-connect up gemini agent-gemini 'wtt-tok-gemini'Gemini CLI uses Google OAuth by default. Install/authenticate Gemini on the agent host first, then bind it to WTT:
npm install -g @google/gemini-cli
gemini
npm install -g wtt-connect
wtt-connect up gemini agent-gemini 'wtt-tok-gemini'If the gemini binary is not on PATH, set WTT_GEMINI_BIN in the profile or shell before starting:
WTT_GEMINI_BIN="$HOME/.local/bin/gemini" wtt-connect up gemini agent-gemini 'wtt-tok-gemini'Each call creates an independent profile and service:
~/.config/wtt-connect/profiles/agent-alice-codex.env
~/.local/state/wtt-connect/agent-alice-codex/state.json
~/.config/systemd/user/[email protected]On macOS the same profile and state paths are used, while the service file is:
~/Library/LaunchAgents/com.wtt.connect.agent-alice-codex.plistA profile contains exactly one WTT identity: WTT_AGENT_ID, WTT_TOKEN, adapter, workdir, permission mode, and state directory. Multiple profiles may point at the same local codex, claude, or gemini CLI binary; they must not share WTT_AGENT_ID, WTT_TOKEN, or WTT_CONNECT_STATE_DIR.
Workdir rules:
- If
--workdirorWTT_CONNECT_WORKDIRis provided, that exact directory is used for agent execution, shell, terminal, runtime info, and adapter cwd. - If no workdir is provided,
wtt-connectuses~/.wtt-connect/<agent_id>. This gives every claimed WTT agent identity its own stable workspace independent of the npm package install directory. - For an existing profile, run
wtt-connect workdir <profile> /path/to/workspace --restart. This updates~/.config/wtt-connect/profiles/<profile>.env, creates the directory, and restarts the service.
Useful flags:
wtt-connect up codex agent-alice 'wtt-tok-alice' \
--workdir /data/workspaces/alice \
--base-url https://www.waxbyte.com \
--enable-lingercodex, claude-code, and gemini already default to --mode yolo with WTT_CONNECT_ALLOW_YOLO=1. Pass --mode suggest or --mode auto-edit only when you intentionally want stricter behavior.
--enable-linger asks systemd to start the Linux user service at boot before an interactive login. Without it, the service starts when the user session starts. On macOS LaunchAgents start at user login; --enable-linger is ignored with a warning.
Start an already-created profile in the foreground:
wtt-connect start --profile agent-alice-codex
wtt-connect doctor --profile agent-alice-codexService names are platform-specific:
Linux: [email protected]
macOS: com.wtt.connect.agent-alice-codexLogs are read with the same command on both platforms:
wtt-connect logs agent-alice-codex --lines 100On Linux this reads journalctl --user; on macOS it tails files under the profile state directory.
Multiple WTT agent identities
Use one wtt-connect process per WTT agent identity. wtt-connect up is the preferred way to create those processes. Each process should have its own WTT_AGENT_ID, WTT_TOKEN, adapter default, and state directory:
# .env.codex
WTT_AGENT_ID=agent-codex
WTT_TOKEN=***
WTT_CONNECT_ADAPTER=codex
WTT_CONNECT_ADAPTERS=codex
WTT_CONNECT_STATE_DIR=.wtt-connect-codex# .env.claude
WTT_AGENT_ID=agent-claude
WTT_TOKEN=***
WTT_CONNECT_ADAPTER=claude-code
WTT_CONNECT_ADAPTERS=claude-code
WTT_CONNECT_STATE_DIR=.wtt-connect-claude# .env.gemini
WTT_AGENT_ID=agent-gemini
WTT_TOKEN=***
WTT_CONNECT_ADAPTER=gemini
WTT_CONNECT_ADAPTERS=gemini
WTT_CONNECT_STATE_DIR=.wtt-connect-gemini
WTT_GEMINI_BIN=geminiStart them separately:
./start.sh --env-file .env.codex
./start.sh --env-file .env.claude
./start.sh --env-file .env.geminiInstall them as separate macOS LaunchAgents:
./scripts/install-launchd.sh --name codex --env-file .env.codex
./scripts/install-launchd.sh --name claude --env-file .env.claude
./scripts/install-launchd.sh --name gemini --env-file .env.geminiInstall them as separate Linux systemd --user services from a source checkout if you are not using npm:
./scripts/install-agent.sh codex agent-codex '***'
./scripts/install-agent.sh claude-code agent-claude '***'
./scripts/install-agent.sh gemini agent-gemini '***'The npm equivalent is preferred for end users:
wtt-connect up codex agent-codex '***'
wtt-connect up claude-code agent-claude '***'
wtt-connect up gemini agent-gemini '***'Use named options when you need a custom service name, a stricter permission mode, or boot-before-login behavior:
./scripts/install-systemd-user.sh \
--name alice-codex \
--agent-id agent-codex \
--token '***' \
--adapter codex \
--mode full-auto \
--publish-progress \
--enable-linger
./scripts/install-systemd-user.sh \
--name alice-claude \
--agent-id agent-claude \
--token '***' \
--adapter claude-code \
--publish-progress \
--enable-linger
./scripts/install-systemd-user.sh \
--name alice-gemini \
--agent-id agent-gemini \
--token '***' \
--adapter gemini \
--publish-progress \
--enable-lingerEach invocation writes a separate .env.<name>, .wtt-connect-<name> state directory, and wtt-connect-<name>.service. Multiple WTT agent identities may share the same local codex, claude, or gemini CLI binary; only the WTT identity and state directory need to be unique.
Uninstall one identity with:
./scripts/uninstall-launchd.sh --name codex
./scripts/uninstall-systemd-user.sh --name alice-codexDiscussion/collaborative topics are mention-gated: wtt-connect only replies when the message targets its WTT_AGENT_ID, one of WTT_CONNECT_AGENT_ALIASES, backend-resolved runner_agent_id, a multi-mention mention_target_agent_ids entry, or a broadcast mention (@all, @everyone, @全体, @所有人). P2P and task topics still run normally.
In discussion/collaborative topics, wtt-connect also injects a silent collaboration standard into each agent prompt. Agents should treat the topic as a shared workboard, preserve shared state, split non-trivial work into owned tasks, state concrete done criteria, report execution evidence, challenge weak assumptions, and only @mention the next specific agent when handoff is required.
Adapter routing can be explicit through task fields such as exec_mode=gemini, through message metadata.model_config.adapter, or through message mentions such as @codex, @claude, @cursor, @gemini, @qoder, @opencode, @iflow, @kimi, @pi, @acp, or @devin when those adapters are enabled. If metadata.model_config.model is present, OpenAI/OpenAI-Codex model IDs route to Codex and Claude/DeepSeek/Kimi-style model IDs route to Claude Code. When the optional model switcher is enabled, the same resolved adapter/provider/model is passed to the configured cc-switch-compatible command before the adapter starts.
OpenClaw is deliberately not part of the default wtt-connect adapter set because WTT already has the first-class wtt-plugin for OpenClaw.
CLI session library
WTT Web /sessions can discover native Codex and Claude Code conversations created directly on a bound host. Discovery is user-triggered from the page; wtt-connect does not upload local CLI history during normal startup.
The flow has four explicit operations:
cli_session_catalog_requestscans metadata fromCODEX_HOME/sessionsandCLAUDE_CONFIG_DIR/projectsand returns at most the 500 most recently updated sessions.cli_session_import_requestreads one selected JSONL transcript, normalizes visible user/assistant messages and tool names, skips hidden reasoning, and uploads idempotent batches.cli_session_continue_requestresumes the native Codex thread or Claude Code session in its original project directory. Strict resume is used, so a missing native session reports an error instead of silently starting an unrelated fresh session.cli_session_fusion_requestinitializes a new native Codex or Claude Code session from two to eight user-selected visible histories. WTT stores source provenance and a bounded memory capsule, keeps every source session unchanged, and replaces the pending target ID with the real native session ID returned by the CLI.
Authentication files, API keys, environment variables, raw tool arguments, and whole CLI configuration directories are not part of this sync. The source Agent must remain online for exact native continuation; imported WTT history remains viewable while it is offline.
Local session fusion
wtt-connect sessions is a separate, local-only command surface. It does not create a WTTClient/WTTApi, does not require WTT_AGENT_ID or WTT_TOKEN, and never uploads session history. It scans $CODEX_HOME/sessions (default ~/.codex/sessions) and $CLAUDE_CONFIG_DIR/projects (default ~/.claude/projects).
Run wtt-connect sessions merge in a terminal for an interactive selector: use Up/Down to move, Space to select two to eight source sessions, and Enter to continue. Then select the target Codex/Claude CLI and workspace. Sessions previously generated by fusion are marked [FUSION:n] in sessions list and omitted from this selector by default so repeated merges do not accidentally nest memory capsules. Pass --include-fusions only when nesting is intentional. Scripted usage is also supported:
wtt-connect sessions merge \
--from codex:<session-id> \
--from claude-code:<session-id> \
--target codex \
--workdir ~/workspace/project \
--yesThe command creates a new native session and stores a private archive under ~/.wtt-connect/fusions/<fusion-id>/ with mode 0700; archive files use mode 0600. The archive contains source provenance, gzip-compressed visible user/assistant history, a bounded fusion capsule, and the resulting native session ID. Source JSONL files are read-only and unchanged.
The new Codex/Claude session contains the bounded capsule as working memory; it does not rewrite proprietary native JSONL files to insert every old turn into the CLI transcript. Its first native prompt starts with WTT Fusion: <fusion-id> · <title>, so the archive identity remains visible in Codex/Claude resume history. Use wtt-connect sessions show <fusion-id> to display the complete archived source conversations, sessions resume <fusion-id> to continue the initialized native session, and sessions recover <fusion-id> to create a replacement from the same capsule. sessions show <adapter:session-id> still displays a normal native transcript. Other local commands are sessions list, sessions search, and sessions export.
Local session web
wtt-connect web starts a loopback-only local workspace for native Codex, Claude Code, and DeepSeek Harness sessions. It does not require WTT login, an Agent ID, or a token, and it never uploads local transcripts to the WTT backend.
wtt-connect web
wtt-connect web --port 3210 --no-openThe browser renders a searchable, collapsible workspace tree with each workspace's native sessions underneath it, shows visible user/assistant history without hidden reasoning, reports native input/output/cache/reasoning token usage, and resumes the selected session in its original work directory. Add an existing local workspace from the left rail, then use New Session to start Codex, Claude Code, or DSH there. Codex and Claude drafts become ordinary native sessions after the first successful turn; DSH sessions are created immediately through its native RPC. Logs larger than 32 MB initially show their most recent 32 MB so multi-hundred-megabyte sessions remain responsive; the UI labels that window explicitly. Codex uses codex exec resume, Claude Code uses claude --resume, and both use strict resume so missing native state cannot silently fork into a different conversation.
The composer supports up to eight local images/files per turn (100 MiB each), native model and reasoning-effort selectors, and per-turn workspace access. Read Only, Workspace Write, and Full Access map to each harness's native sandbox/permission flags; Full Access requires browser confirmation and does not modify global CLI configuration. Type / to open a searchable command menu. DSH commands come from and execute through its native command registry; Codex and Claude Code expose only the deterministic commands that Local Web can execute without pretending an interactive TUI command succeeded. Unknown slash lines are rejected and never become model prompts. Files are streamed into private ~/.wtt-connect/web/uploads storage and are never uploaded to the WTT backend. Codex images use native --image; DSH images use native image content blocks; Claude Code and ordinary files receive private local paths for the harness file/image tools. Codex reads available models and reasoning levels from its local model cache, Claude exposes its supported effort presets, and DSH reads and switches through its native session.models and session.selectModel RPCs.
Attachment cards show real XHR upload progress as a circular indicator. Every chat message displays its native event time, and the session and usage rails can be collapsed independently; rail state is remembered in browser-local storage. Session log下载 exports the selected session's complete visible conversation, timestamps, metadata, and token usage as readable Markdown without exposing hidden reasoning or raw CLI events.
The Explore rail also transfers files directly between the browser device and the selected session workspace. Drop one or more files on the workspace root or a directory to stream them into that directory, or use the upload button; Workspace Write or Full Access is required, existing files require explicit replacement confirmation, and incomplete uploads are removed. Open a file and use its download button for a streamed, range-capable download. Chromium browsers can also drag a file row out of Explore and drop it on the desktop or file manager; the download button remains the portable fallback for browsers that do not implement DownloadURL. These workspace transfers are separate from composer attachments and retain the 100 MiB per-file Local Web upload limit.
When dsh is installed, WTT starts one private dsh web sidecar and uses DSH's loopback session RPC instead of parsing or mutating compressed DSH logs. Set WTT_DSH_WEB_URL or pass --dsh-web-url with the complete http://127.0.0.1:<port>/?token=... URL printed by an already running DSH Web instance; the plain origin is not authenticated. Do not edit the same DSH session concurrently from multiple Web/CLI writers; DSH sessions have one live writer at a time.
Select two to eight sessions in the left rail to merge Codex, Claude Code, and DSH visible histories. Fusion stores a private source archive under ~/.wtt-connect/fusions, builds a bounded memory capsule, and initializes a new native Codex or Claude Code target session. Source sessions remain unchanged. Local Web itself only binds to 127.0.0.1, ::1, or localhost; expose it remotely only through an authenticated tunnel.
Direction
Near-term parity targets with cc-connect:
- Rich attachment rendering in WTT Web and task artifact schema persistence
- Fine-grained permission broker with per-task policy, not just env-level modes
- TTS/STT providers beyond macOS
say - Multiple concurrent local adapters under one claimed WTT agent
- Durable session store expanded across all native adapters
- Tool/progress event normalization for WTT Web observability
- Installer/claim flow integrated with wtt-web
- Artifact schema in task rows, not only topic messages
Production helpers
./start.sh
./scripts/install-launchd.sh
./scripts/uninstall-launchd.shSmoke tests
Run the connector in one terminal, then:
node ./bin/wtt-connect.js smoke-task --expected WTT_CONNECT_TASK_READY
node ./bin/wtt-connect.js smoke-chat --expected WTT_CONNECT_CHAT_READYsmoke-chat requires a second sender agent via WTT_SMOKE_SENDER_AGENT_ID and WTT_SMOKE_SENDER_TOKEN.
