skykoi 2026.3.340 → 2026.3.342

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 (157) hide show
  1. package/README.md +485 -121
  2. package/dist/{acp-cli-ouJ50hG-.js → acp-cli-CVYseS7Z.js} +7 -7
  3. package/dist/{admin-unlock-gj-MQxKm.js → admin-unlock-D9kdgQ8v.js} +2 -2
  4. package/dist/{archive-eBq7w-zH.js → archive-B9j5NN2P.js} +1 -1
  5. package/dist/{audit-DUfENGRE.js → audit-CLnOGwlN.js} +10 -10
  6. package/dist/{auth-C6B1VxVI.js → auth-DqeAy3Cg.js} +1 -1
  7. package/dist/{auth-health-C2fV9Fd9.js → auth-health-DmoN4lSG.js} +1 -1
  8. package/dist/{bonjour-discovery-_EttiPSR.js → bonjour-discovery-Ci5LSWeP.js} +1 -1
  9. package/dist/build-info.json +3 -3
  10. package/dist/{call-Cz24IGHi.js → call-C9UVp1hU.js} +1 -1
  11. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  12. package/dist/{channel-options-yVVJPj4e.js → channel-options-C7JjASQk.js} +3 -3
  13. package/dist/{channel-selection-OgVBkPDG.js → channel-selection-DTkEBU1F.js} +1 -1
  14. package/dist/{channel-summary-CiOkD9OF.js → channel-summary-BhjG7k3r.js} +18 -12
  15. package/dist/{channels-cli-BxDh4GsQ.js → channels-cli-CepGnugL.js} +40 -40
  16. package/dist/{channels-status-issues-T19-LXup.js → channels-status-issues-RnlrwtQu.js} +1 -1
  17. package/dist/{chrome-B-IUYNJz.js → chrome-Dw_3cCvP.js} +1 -1
  18. package/dist/cli/daemon-cli.js +1 -1
  19. package/dist/{cli-if-Ko0qj.js → cli-CYYhBs_X.js} +28 -28
  20. package/dist/{cli-auto-update-CqfV4Qg9.js → cli-auto-update-CcDCuLjd.js} +3 -3
  21. package/dist/{completion-cli-DlUzivk_.js → completion-cli-Cjh9ubPc.js} +1 -1
  22. package/dist/{config-CPGRZ_aH.js → config-CiBJ5Sw5.js} +2 -2
  23. package/dist/{config-guard-BUqZzzk4.js → config-guard-CU0vhDta.js} +40 -32
  24. package/dist/{configure-wTTIDt4c.js → configure-DezWAGQv.js} +12 -12
  25. package/dist/{control-service-cGhUATjJ.js → control-service-cHrnSFJb.js} +4 -4
  26. package/dist/{control-ui-assets-ulSPw_yr.js → control-ui-assets-CUfeis07.js} +1 -1
  27. package/dist/{cron-cli-D3p3bDgW.js → cron-cli-Bb8Wjjx7.js} +7 -7
  28. package/dist/{daemon-cli-unyrNDAd.js → daemon-cli-CP_7sKo5.js} +11 -11
  29. package/dist/{daemon-runtime-1yCOQiPN.js → daemon-runtime-jG1eA54U.js} +1 -1
  30. package/dist/{deliver-B5ZswfDv.js → deliver-Bwg-2xqp.js} +6 -6
  31. package/dist/{deps-B1uCRuzU.js → deps-B8Evgtv2.js} +2 -2
  32. package/dist/{devices-cli-DOWnFiLF.js → devices-cli-DuyM7cNa.js} +5 -5
  33. package/dist/{diagnostics-C-YMJXl4.js → diagnostics-BPo5b-50.js} +1 -1
  34. package/dist/{directory-cli-BZ84RlbK.js → directory-cli-X1J3xQaI.js} +6 -6
  35. package/dist/{dispatcher-NZrhMfvo.js → dispatcher-C-LUVlX7.js} +1 -1
  36. package/dist/{dns-cli-Cmpp6Vvg.js → dns-cli-DQca2NRC.js} +4 -4
  37. package/dist/{docs-cli-CPoQHqu9.js → docs-cli-B3EGr-2u.js} +1 -1
  38. package/dist/{doctor-CCImfxGD.js → doctor-CgqYyyXq.js} +26 -26
  39. package/dist/{doctor-completion-dXSUt_OC.js → doctor-completion-C419330G.js} +2 -2
  40. package/dist/{ensure-local-gateway-D5bQEnlk.js → ensure-local-gateway-iBqdIUtF.js} +5 -5
  41. package/dist/entry.js +1 -1
  42. package/dist/{exec-XH65-wH1.js → exec-DdlIawm8.js} +4 -2
  43. package/dist/{exec-approvals-cli-C86FOoQ8.js → exec-approvals-cli-DFZSyoP-.js} +10 -10
  44. package/dist/extension-api.js +28 -28
  45. package/dist/{gateway-cli-DO1vovtZ.js → gateway-cli-MrrB_fKC.js} +278 -81
  46. package/dist/{gateway-rpc-oeoShcHu.js → gateway-rpc-CBIir0rS.js} +1 -1
  47. package/dist/{github-copilot-auth-4_9zPSb_.js → github-copilot-auth-DxfhSFQ_.js} +4 -4
  48. package/dist/{gmail-setup-utils-aNLlRREc.js → gmail-setup-utils-DB6uypHo.js} +1 -1
  49. package/dist/{health-format-DwTibEYB.js → health-format-jVkaZtVp.js} +8 -8
  50. package/dist/{hooks-cli-pszRNmom.js → hooks-cli-BoaojBdA.js} +30 -30
  51. package/dist/{image-D1F8mGc7.js → image-C4yRDi5t.js} +3 -3
  52. package/dist/{image-ops-bY5IHCXb.js → image-ops-BL6a_ptF.js} +1 -1
  53. package/dist/index.js +68 -68
  54. package/dist/{installs-_Nw5_GV7.js → installs-CQUqC8Z-.js} +2 -2
  55. package/dist/{koi-BZzxHK5u.js → koi-DQfgxiWT.js} +9 -9
  56. package/dist/{koi-scope-je0O-Kk9.js → koi-scope-7GA83nWp.js} +1 -1
  57. package/dist/live-broadcast-CJlPQO-e.js +19 -0
  58. package/dist/{login-CE8OQXwu.js → login-Bx9HuAKm.js} +3 -3
  59. package/dist/{login-qr-BDQuOnVJ.js → login-qr-S9XrlXNU.js} +1 -1
  60. package/dist/{logs-cli-C9Skr-Jt.js → logs-cli-Cj-sYnjj.js} +6 -6
  61. package/dist/{manager-CheecE6N.js → manager-YridT1O9.js} +2 -2
  62. package/dist/{model-selection-LWVUzs_N.js → model-selection-DvRURdJc.js} +1 -1
  63. package/dist/{models-cli-R-qiE0Gs.js → models-cli-CCCu5IgB.js} +30 -30
  64. package/dist/{node-cli-Ci0YkLY9.js → node-cli-DfisfQlb.js} +16 -16
  65. package/dist/{node-service-DrS2vIzq.js → node-service-WjDdCaA0.js} +1 -1
  66. package/dist/{nodes-cli-3WP99fZd.js → nodes-cli-DL7LKJ8a.js} +6 -6
  67. package/dist/{onboard-channels-Uq6qT-Gu.js → onboard-channels-C3se7IsJ.js} +5 -5
  68. package/dist/{onboard-helpers-CUeATAB3.js → onboard-helpers-BaUchcq-.js} +4 -4
  69. package/dist/{onboard-skills-CmC8vaO5.js → onboard-skills-B9wJcaBv.js} +9 -9
  70. package/dist/{onboarding-DnrWsLch.js → onboarding-C9XpjOmT.js} +28 -28
  71. package/dist/{pairing-cli-B5uRZQBj.js → pairing-cli-DSsU0b-2.js} +7 -7
  72. package/dist/{pairing-labels-C-enUdKD.js → pairing-labels-D8IFbrVc.js} +1 -1
  73. package/dist/{pairing-store-T6gWH6ac.js → pairing-store-Dbohn32C.js} +1 -1
  74. package/dist/{pi-embedded-helpers-BFUPvX5r.js → pi-embedded-helpers-BZAEqMf-.js} +2 -2
  75. package/dist/{pi-tool-definition-adapter-B5Zq7e5d.js → pi-tool-definition-adapter-Dwkg58f2.js} +2 -2
  76. package/dist/{pi-tools.policy-BG0SSlKz.js → pi-tools.policy-DYfYE2sn.js} +2 -2
  77. package/dist/{plugin-auto-enable-I5V3wp0J.js → plugin-auto-enable-mgOtVka_.js} +1 -1
  78. package/dist/{plugin-registry-DiLPdufR.js → plugin-registry-KBuh-OQA.js} +3 -3
  79. package/dist/plugin-sdk/index.js +4 -2
  80. package/dist/{plugins-Ct7Mnq1x.js → plugins-BXfIVhTg.js} +1 -1
  81. package/dist/{plugins-cli-Bqo0OANi.js → plugins-cli-eOkD8OvR.js} +32 -32
  82. package/dist/{ports-BamXUQot.js → ports-aBOzofHh.js} +1 -1
  83. package/dist/{program-Debrr07Q.js → program-Qzt0jo9-.js} +6 -10
  84. package/dist/{pw-ai-CthVTO-M.js → pw-ai-CJee2_B3.js} +2 -2
  85. package/dist/{qmd-manager-C_tc1Xq0.js → qmd-manager-riWCwj7I.js} +2 -2
  86. package/dist/{register.subclis-hGo_4GqB.js → register.subclis-cYZ1CREN.js} +28 -28
  87. package/dist/{reply-ChoZCU8C.js → reply-B4yWcAqR.js} +37 -37
  88. package/dist/{routes-JUT9n8s1.js → routes-CzrvdV1c.js} +4 -4
  89. package/dist/{rpc-CWVZKlO2.js → rpc-B5uz9rXs.js} +1 -1
  90. package/dist/{run-code-tool-Dr8reO_d.js → run-code-tool-2drimmAk.js} +1 -1
  91. package/dist/{run-main-Dz44r7PK.js → run-main-B-W02rRR.js} +73 -73
  92. package/dist/{runner-BCSvAzGx.js → runner-CTmglsQg.js} +6 -6
  93. package/dist/{sandbox-KwxQsP2x.js → sandbox-QDi_zGUk.js} +6 -6
  94. package/dist/{sandbox-cli-gWIPQICB.js → sandbox-cli-BR0YcK8N.js} +11 -11
  95. package/dist/{security-cli-2ugDu_E3.js → security-cli-CpjTGtzu.js} +17 -17
  96. package/dist/{server-context-aoJXOi8y.js → server-context-DYbJ3M1S.js} +5 -5
  97. package/dist/{server-node-events-B5_zmtbC.js → server-node-events-DqwK-QAY.js} +30 -30
  98. package/dist/{service-CKHP-LSk.js → service-BNfl9qMX.js} +1 -1
  99. package/dist/{service-audit-HStmtL1x.js → service-audit-C5l53T2M.js} +3 -3
  100. package/dist/{sessions-Cbom-8vC.js → sessions-BJGLVqv9.js} +2 -2
  101. package/dist/{shared-Ce8XPMG6.js → shared-DhCLX1Xs.js} +1 -1
  102. package/dist/{shared-DahLhw06.js → shared-tKwE9ewx.js} +1 -1
  103. package/dist/{skills-cli-CZJ2wYWK.js → skills-cli-DdUZpkjO.js} +4 -4
  104. package/dist/{status-Bj3xOBqB.js → status-Cfr442Jt.js} +3 -3
  105. package/dist/{system-cli-LqXPMhHk.js → system-cli-Qcedodyn.js} +6 -6
  106. package/dist/{system-prompt-snippet-DVjt3zCc.js → system-prompt-snippet-tk2ZN4CE.js} +1 -1
  107. package/dist/{systemd-D9YMYUVJ.js → systemd-CRc2L6q9.js} +1 -1
  108. package/dist/{systemd-linger-Bp3jN74v.js → systemd-linger-Qf-ZNSXE.js} +1 -1
  109. package/dist/{tailscale-D0cB8Nyf.js → tailscale-CBmv5qCh.js} +1 -1
  110. package/dist/{tool-images-DOz9yj-z.js → tool-images-f3YACc5J.js} +1 -1
  111. package/dist/{tui-BI8Lmspl.js → tui-CtblgdWZ.js} +15 -7
  112. package/dist/{tui-cli-BSmOxOHh.js → tui-cli-3SsKIL5I.js} +22 -22
  113. package/dist/{update-gn_ePcl0.js → update-O979f8y9.js} +1 -1
  114. package/dist/{update-cli-r_q7gMLS.js → update-cli-Cyb4m9f7.js} +52 -52
  115. package/dist/{update-runner-16zZxRyN.js → update-runner--zLQ4p6m.js} +2 -2
  116. package/dist/{webhooks-cli-Cdw6b1wo.js → webhooks-cli-C-7x9fuA.js} +5 -5
  117. package/extensions/bluebubbles/package.json +1 -1
  118. package/extensions/copilot-proxy/package.json +1 -1
  119. package/extensions/diagnostics-otel/package.json +1 -1
  120. package/extensions/discord/package.json +1 -1
  121. package/extensions/feishu/package.json +1 -1
  122. package/extensions/google-antigravity-auth/package.json +1 -1
  123. package/extensions/google-gemini-cli-auth/package.json +1 -1
  124. package/extensions/googlechat/package.json +1 -1
  125. package/extensions/imessage/package.json +1 -1
  126. package/extensions/line/package.json +1 -1
  127. package/extensions/llm-task/package.json +1 -1
  128. package/extensions/lobster/package.json +1 -1
  129. package/extensions/matrix/CHANGELOG.md +5 -0
  130. package/extensions/matrix/package.json +1 -1
  131. package/extensions/mattermost/package.json +1 -1
  132. package/extensions/memory-core/package.json +1 -1
  133. package/extensions/memory-lancedb/package.json +1 -1
  134. package/extensions/minimax-portal-auth/package.json +1 -1
  135. package/extensions/msteams/CHANGELOG.md +5 -0
  136. package/extensions/msteams/package.json +1 -1
  137. package/extensions/nextcloud-talk/package.json +1 -1
  138. package/extensions/nostr/CHANGELOG.md +5 -0
  139. package/extensions/nostr/package.json +1 -1
  140. package/extensions/open-prose/package.json +1 -1
  141. package/extensions/signal/package.json +1 -1
  142. package/extensions/slack/package.json +1 -1
  143. package/extensions/telegram/package.json +1 -1
  144. package/extensions/tlon/package.json +1 -1
  145. package/extensions/twitch/CHANGELOG.md +5 -0
  146. package/extensions/twitch/package.json +1 -1
  147. package/extensions/voice-call/CHANGELOG.md +5 -0
  148. package/extensions/voice-call/package.json +1 -1
  149. package/extensions/whatsapp/package.json +1 -1
  150. package/extensions/zalo/CHANGELOG.md +5 -0
  151. package/extensions/zalo/package.json +1 -1
  152. package/extensions/zalouser/CHANGELOG.md +5 -0
  153. package/extensions/zalouser/package.json +1 -1
  154. package/package.json +1 -1
  155. /package/dist/{declarations-CjH61_I7.js → declarations-CL-Br5Ll.js} +0 -0
  156. /package/dist/{koi-event-bridge-Cvm1fCDd.js → koi-event-bridge-D4fNtU2m.js} +0 -0
  157. /package/dist/{koi-utterance-trigger-D8-wlyEh.js → koi-utterance-trigger-C9FSuJKQ.js} +0 -0
package/README.md CHANGED
@@ -1,175 +1,539 @@
1
1
  # SkyKoi Runtime
2
2
 
3
- The Koi runtime that powers [SkyKoi](https://www.skykoi.com). This is the npm package (`skykoi`) that runs on each user's dedicated EC2 instance, handling the Koi gateway, LLM inference, tool execution, and channel integrations.
4
-
5
- **npm:** `skykoi` (latest: v2026.3.83)
6
- **Platform:** [www.skykoi.com](https://www.skykoi.com)
3
+ > The engine behind a **koi**: a personal AI agent that lives on a device, talks to its
4
+ > owner across every messaging channel, runs real work with tools, and remembers.
5
+
6
+ ![npm](https://img.shields.io/npm/v/skykoi?color=cb3837&logo=npm&label=skykoi)
7
+ ![node](https://img.shields.io/badge/node-%E2%89%A5%2022-339933?logo=node.js&logoColor=white)
8
+ ![language](https://img.shields.io/badge/TypeScript-ESM-3178C6?logo=typescript&logoColor=white)
9
+ ![license](https://img.shields.io/badge/license-BUSL--1.1-blue)
10
+ ![docs](https://img.shields.io/badge/docs-docs.skykoi.com-0aa)
11
+
12
+ This repository is the npm package **`skykoi`** (CLI binaries `koi` and `skykoi`). One
13
+ install bundles three things into one process: an **agent**, a **gateway**, and a
14
+ **multi-channel front door**.
15
+
16
+ ```mermaid
17
+ flowchart LR
18
+ A["One npm install: skykoi"] --> B["Agent<br/>reasons, calls tools, remembers"]
19
+ A --> C["Gateway<br/>always-on WS / RPC server"]
20
+ A --> D["Front door<br/>WhatsApp, iMessage, Telegram..."]
21
+ ```
7
22
 
8
- ## What This Is
23
+ ---
24
+
25
+ ## Table of contents
26
+
27
+ - [What it is](#what-it-is)
28
+ - [System architecture](#system-architecture)
29
+ - [Core vocabulary](#core-vocabulary)
30
+ - [Quick start](#quick-start)
31
+ - [How the program starts](#how-the-program-starts)
32
+ - [Repository map](#repository-map)
33
+ - [Core subsystems](#core-subsystems)
34
+ - [The koi agent loop](#the-koi-agent-loop)
35
+ - [The gateway](#the-gateway)
36
+ - [Channels, routing and pairing](#channels-routing-and-pairing)
37
+ - [Providers and models](#providers-and-models)
38
+ - [Configuration](#configuration)
39
+ - [Memory](#memory)
40
+ - [Cron, infra and self-update](#cron-infra-and-self-update)
41
+ - [Device and browser](#device-and-browser)
42
+ - [Plugins, extensions and native apps](#plugins-extensions-and-native-apps)
43
+ - [Lifecycle of an inbound message](#lifecycle-of-an-inbound-message)
44
+ - [Where to add things](#where-to-add-things)
45
+ - [Build, test and release](#build-test-and-release)
46
+ - [Contributor conventions](#contributor-conventions)
47
+ - [Security model](#security-model)
48
+ - [Further reading](#further-reading)
49
+
50
+ > **How to read this doc.** It is the onboarding map, not the full manual. It is written
51
+ > to stay correct as the code moves, so it follows three rules. Please keep them when you
52
+ > edit: **point to the source of truth, do not duplicate it** (counts, versions and line
53
+ > numbers are deliberately avoided); **key on directories, not files** (directories are
54
+ > stable, files churn); and **explain the why**. The exhaustive manual is
55
+ > [docs.skykoi.com](https://docs.skykoi.com); contributor rules live in
56
+ > [`AGENTS.md`](./AGENTS.md). This README bridges the two.
57
+
58
+ ---
59
+
60
+ ## What it is
61
+
62
+ SkyKoi Runtime is the program that *is* a koi. It is published to npm and runs **wherever
63
+ the koi lives**: today that is primarily the **user's own device** (the macOS menubar app,
64
+ or any Mac/Linux/Windows host), reachable from the cloud through a tunnel. It can also run
65
+ on a server or VM. (It is host-agnostic, so do not assume EC2; an earlier managed fleet has
66
+ been retired.)
67
+
68
+ A single koi is an LLM-driven loop with a persistent **workspace** and **memory**. The
69
+ runtime wraps that loop in an always-on **gateway** and connects it to the outside world
70
+ through pluggable **channels**, the **CLI/TUI**, and native **apps**.
71
+
72
+ ---
73
+
74
+ ## System architecture
75
+
76
+ The whole runtime at a glance: every way a message can arrive, funneled into one agent loop
77
+ that is backed by a handful of subsystems.
78
+
79
+ ```mermaid
80
+ flowchart TB
81
+ owner(["Owner"])
82
+
83
+ subgraph ways["Ways in"]
84
+ direction LR
85
+ CH["Channels<br/>WhatsApp - iMessage<br/>Telegram - Discord - Slack..."]
86
+ GWc["Gateway clients<br/>web - mobile / desktop apps<br/>platform connect"]
87
+ CLI["CLI / TUI<br/>local terminal"]
88
+ end
89
+
90
+ owner --> CH & GWc & CLI
91
+
92
+ CH & GWc & CLI --> RP["Routing + Pairing<br/>which koi? who is this?"]
93
+ RP --> KOI["The koi agent loop<br/>prompt then tool then result"]
94
+
95
+ KOI --> PROV["LLM providers"]
96
+ KOI --> TOOLS["Tools<br/>exec - browser - files - device"]
97
+ KOI --> MEM["Memory<br/>sqlite + vectors"]
98
+ KOI --> WSP["Workspace<br/>KOI / SOUL / USER / MEMORY.md"]
99
+ KOI --> CRON["Cron<br/>scheduled turns"]
100
+
101
+ classDef hot fill:#0aa,stroke:#066,color:#fff;
102
+ class KOI hot;
103
+ ```
9
104
 
10
- SkyKoi Runtime is a personal Koi runtime forked from [SKYKOI](https://github.com/nicepkg/SKYKOI-runtime) (MIT License). It runs as a gateway process on an EC2 instance and provides:
105
+ Viewed as layers, the same system stacks like this. Surfaces depend on the gateway, which
106
+ hosts the agent, which rests on the foundational services:
107
+
108
+ ```mermaid
109
+ flowchart TB
110
+ subgraph L4["Surfaces"]
111
+ direction LR
112
+ s1["CLI / TUI"]
113
+ s2["Native apps"]
114
+ s3["Channels"]
115
+ end
116
+ subgraph L3["Gateway · src/gateway"]
117
+ g1["WebSocket / RPC · sessions · heartbeat · control UI"]
118
+ end
119
+ subgraph L2["Agent · src/koi"]
120
+ k1["agent loop · tools · prompt · sessions"]
121
+ end
122
+ subgraph L1["Foundations"]
123
+ direction LR
124
+ f1["providers"]
125
+ f2["config"]
126
+ f3["memory"]
127
+ f4["infra"]
128
+ end
129
+ L4 --> L3 --> L2 --> L1
130
+ ```
11
131
 
12
- - Real-time chat via WebSocket
13
- - LLM inference through AWS Bedrock (Claude Opus 4.6) or any supported provider
14
- - Tool execution (bash, browser, file operations, cron, etc.)
15
- - Channel integrations (Discord, Telegram, WhatsApp, Slack, Signal, iMessage, and more)
16
- - Koi workspace with persistent memory
17
- - Self-update capability for fleet-wide rolling updates
132
+ ---
18
133
 
19
- ## Architecture
134
+ ## Core vocabulary
20
135
 
21
- ```
22
- User (browser/app)
23
- |
24
- v WebSocket (wss://<id>.gw.skykoi.com)
25
- +---------------------------+
26
- | SkyKoi Gateway |
27
- | (Node.js process) |
28
- | |
29
- | - WebSocket server |
30
- | - Session management |
31
- | - Koi runtime (Pi) |
32
- | - Tool execution |
33
- | - Channel routing |
34
- | - Heartbeat system |
35
- | - Cron scheduler |
36
- +---------------------------+
37
- |
38
- v Bedrock API / Provider APIs
39
- LLM Inference
40
- ```
136
+ These seven terms unlock the codebase.
41
137
 
42
- ## Key Modules
138
+ | Term | Meaning |
139
+ |---|---|
140
+ | **koi** | One agent identity. Has a workspace, memory, model config, and sessions. A host can run several. |
141
+ | **gateway** | The always-on process. Hosts the WebSocket/RPC server, channels, cron, and the koi runtime. |
142
+ | **session** | One conversation thread with a koi, keyed by `(koi, channel, account, peer)`. Persisted as a transcript. |
143
+ | **channel** | A messaging surface (Telegram, iMessage, web...). A pluggable adapter translating native to internal messages. |
144
+ | **command** vs **tool** | A **command** is owner-typed chat text (`/model`, `/reset`) intercepted *before* the LLM. A **tool** is an action the LLM itself calls (`exec`, `browser`, `email`). |
145
+ | **the "Pi" runtime** | The embedded agent core (`@mariozechner/pi-*`). The koi loop wraps it; see `src/koi/pi-embedded*`. |
146
+ | **workspace** | `~/.skykoi/...`: the koi's editable brain on disk (`KOI.md`, `SOUL.md`, `USER.md`, `MEMORY.md`, sessions). |
43
147
 
44
- ```
45
- src/
46
- kois/ - Koi runtime, tool definitions (exec, process, browser)
47
- auto-reply/ - Message handling, Koi turn execution, command registry
48
- channels/ - Channel plugin system (Discord, Telegram, WhatsApp, etc.)
49
- config/ - Configuration loading, validation, schema
50
- cron/ - Scheduled jobs, isolated Koi turns
51
- gateway/ - WebSocket server, RPC handlers, session management
52
- infra/ - Retry logic, backoff, error handling, updates
53
- memory/ - Embedding-based memory with SQLite + vector search
54
- node-host/ - Node device management (camera, screen, location)
55
- providers/ - LLM provider adapters (Bedrock, Anthropic, OpenAI, Google, etc.)
56
- browser/ - Chrome/Chromium automation via CDP
57
- tui/ - Terminal UI for local development
58
- ```
148
+ ---
59
149
 
60
- ## Install
150
+ ## Quick start
61
151
 
62
- Typically installed automatically by the platform's cloud-init during EC2 provisioning:
152
+ > **Requirements:** Node `>= 22`, and **pnpm** (the version is pinned in `package.json`).
63
153
 
64
154
  ```bash
65
- npm install -g skykoi@latest
66
- ```
67
-
68
- ## Running
155
+ pnpm install
156
+ pnpm build # compile src/ to dist/ (tsdown). The CLI always runs dist/.
69
157
 
70
- The gateway runs as a long-lived process:
158
+ # Run the CLI from source during development:
159
+ pnpm dev <command> # node scripts/run-node.mjs (rebuilds stale dist, then runs)
160
+ pnpm skykoi --help # list every command
71
161
 
72
- ```bash
73
- skykoi gateway --port 18789 --verbose
162
+ # Common loops:
163
+ pnpm gateway:dev # run the gateway locally (channels skipped, fast)
164
+ pnpm gateway:watch # gateway with auto-reload on change
165
+ pnpm tui:dev # the terminal chat UI against a dev profile
74
166
  ```
75
167
 
76
- Or with the daemon (auto-restart on crash):
168
+ Quality gates, before pushing anything with logic changes:
77
169
 
78
170
  ```bash
79
- skykoi onboard --install-daemon
171
+ pnpm check # tsgo (typecheck) + lint + format
172
+ pnpm test # vitest suite (colocated *.test.ts)
80
173
  ```
81
174
 
82
- ## Configuration
175
+ > [!IMPORTANT]
176
+ > **`dist/` vs `src/`.** The `koi` binary (`skykoi.mjs`) imports `dist/entry.js`, so a code
177
+ > change is not live on the CLI until it is built. `pnpm dev` and `pnpm gateway:watch`
178
+ > rebuild for you; a bare `koi ...` runs whatever is already in `dist/`.
83
179
 
84
- Configuration lives at `~/.skykoi/skykoi.json`:
180
+ ---
85
181
 
86
- ```json
87
- {
88
- "koi": {
89
- "model": "amazon-bedrock/us.anthropic.claude-opus-4-6-v1"
90
- },
91
- "gateway": {
92
- "port": 18789
93
- }
94
- }
95
- ```
96
-
97
- On cloud instances, configuration is pushed via SSM after the instance is claimed from the warm pool. The runtime reads it on startup and connects to the platform.
182
+ ## How the program starts
98
183
 
99
- ## Development
184
+ Follow this chain once and the entire CLI makes sense.
100
185
 
101
- ```bash
102
- git clone https://github.com/ricardoamartinez/skykoi-runtime.git
103
- cd skykoi-runtime
186
+ ```mermaid
187
+ flowchart TB
188
+ bin["skykoi.mjs<br/><i>npm bin</i>"] --> entry["src/entry.ts<br/>title, env, re-spawn, profiles"]
189
+ entry --> main["src/cli/run-main.ts<br/>dotenv, first-run, parse argv"]
190
+ main --> reg["src/cli/program/command-registry.ts<br/>catalog of subcommands"]
191
+ reg --> cmd["src/commands/*<br/>the command implementation"]
192
+ cmd --> deps["createDefaultDeps()<br/>injected config + helpers"]
193
+ ```
104
194
 
105
- pnpm install
106
- pnpm build
195
+ | Piece | Role |
196
+ |---|---|
197
+ | `src/cli/` | Commander-based CLI: program construction, argv helpers, help/version, and a **fast-path router** (`src/cli/route.ts`) that shortcuts common read-only commands past full parsing. |
198
+ | `src/cli/deps.ts` | `createDefaultDeps()`: the dependency-injection container (config, workspace, koi helpers) passed into commands so they are testable. |
199
+ | `src/runtime.ts` | The injectable `log` / `error` / `exit` surface, so tests can capture output. |
200
+
201
+ > The default action: `koi` with no args checks login, then drops into the **TUI** chat, or
202
+ > shows the first-run welcome on a fresh machine.
203
+
204
+ ---
205
+
206
+ ## Repository map
207
+
208
+ The product is a **pnpm workspace**: the root package (`skykoi`) plus `extensions/*` (plugins)
209
+ and `apps/*` (native apps). Start with `src/`.
210
+
211
+ | Path | What lives here | Start here |
212
+ |---|---|---|
213
+ | `src/entry.ts`, `src/index.ts`, `src/runtime.ts` | Process bootstrap + public library entry | `src/entry.ts` |
214
+ | `src/cli/`, `src/commands/` | The CLI: command registry + every subcommand | `command-registry.ts` |
215
+ | **`src/koi/`** | **The agent.** The Pi-embedded loop, tools, prompt assembly, sessions, models, sandbox | `pi-embedded-runner/run.ts` |
216
+ | `src/auto-reply/` | Inbound message to command-gating to koi turn to streamed reply | `reply.ts` |
217
+ | **`src/gateway/`** | **The server.** WebSocket + RPC, sessions, heartbeat, control UI, OpenAI-compatible HTTP | `server.impl.ts` |
218
+ | `src/gateway-client.ts` | The WS client apps/devices use to connect | `gateway-client.ts` |
219
+ | `src/channels/` | Channel **plugin system**: adapter interfaces, discovery, allowlists, gating | `plugins/types.core.ts` |
220
+ | `src/telegram/ discord/ slack/ signal/ imessage/ web/ whatsapp/ line/` | Per-channel adapters (native API to internal messages) | each dir entry |
221
+ | `src/routing/`, `src/pairing/` | Map `(channel, account, peer)` to `(koi, session)`; DM pairing and allowlists | `routing/resolve-route.ts` |
222
+ | `src/providers/`, `src/koi/models-config*.ts` | LLM provider adapters and model selection | `models-config.providers.ts` |
223
+ | `src/config/` | Config schema, load/validate `~/.skykoi/skykoi.json`, hot-reload, migrations | `zod-schema.ts`, `paths.ts` |
224
+ | `src/memory/` | Long-term memory: SQLite + vectors (`sqlite-vec`) + hybrid search | `manager.ts` |
225
+ | `src/world-model/` | The per-koi context block injected into the system prompt | `renderer.ts` |
226
+ | `src/cron/` | Scheduled, isolated koi turns | `service.ts` |
227
+ | `src/infra/` | Backoff/retry, update/self-update, exec-approval policy, heartbeat | by filename |
228
+ | `src/node-host/`, `src/browser/` | Device capabilities + Chrome automation (the `nodes` and `browser` tools) | `node-host/runner.ts`, `browser/client.ts` |
229
+ | `src/security/`, `src/gateway/device-auth.ts` | Auth tokens, device pairing, exec policy | `device-auth.ts` |
230
+ | `src/plugins/`, `src/plugin-sdk/` | The plugin loader + the public SDK `extensions/*` build against | `plugin-sdk/index.ts` |
231
+ | `src/tui/` | The terminal chat UI | `tui/` |
232
+ | `extensions/*` | Workspace plugins: extra channels and memory backends | each `package.json` |
233
+ | `apps/macos ios android shared` | Native clients (Swift/Kotlin) that speak the gateway protocol | per-app folder |
234
+ | `docs/` | The Mintlify docs site (docs.skykoi.com) | `docs/index.md` |
235
+ | `dist/` | **Build output. Generated, never edit.** | - |
236
+
237
+ > Some directories hold hundreds of files. The "start here" file is the door; the imports
238
+ > take you the rest of the way. A directory's own `README.md` or doc page outranks this table.
239
+
240
+ ---
241
+
242
+ ## Core subsystems
243
+
244
+ ### The koi agent loop
245
+
246
+ `src/koi/` is the heart. A koi "turn" builds context, calls the LLM, runs any tools it asks
247
+ for, feeds results back, and repeats until done. It wraps the embedded **Pi** agent core
248
+ (`@mariozechner/pi-*`; local tweaks live in `patches/`).
249
+
250
+ ```mermaid
251
+ flowchart LR
252
+ A["Build context<br/>system prompt + world model<br/>+ workspace + tools"] --> B["Call the LLM"]
253
+ B --> C{"Tool calls?"}
254
+ C -->|yes| D["Run tools<br/>exec - browser - files - email..."]
255
+ D --> E["Feed results back"]
256
+ E --> B
257
+ C -->|no| F["Persist session<br/>stream the final reply"]
258
+ classDef done fill:#0a6,stroke:#063,color:#fff;
259
+ class F done;
260
+ ```
107
261
 
108
- # Dev loop (auto-reload)
109
- pnpm gateway:watch
262
+ | Area | Where | Notes |
263
+ |---|---|---|
264
+ | Orchestration | `pi-embedded-runner/` | `run.ts` drives the loop; `attempt.ts` is one step; `compact.ts` trims history; `model.ts` picks the model and fails over. |
265
+ | System prompt | `system-prompt.ts` + `src/world-model/` | Assembled from runtime metadata, the world model, workspace files, tools, and channel rules. |
266
+ | Tools | `src/koi/tools/` | One file per capability: `exec`, `browser-tool`, file read/write, `email-tool`, `memory-tool`, `nodes-tool`, `cron-tool`, sub-agents, per-channel `*-actions`. |
267
+ | Sessions | `src/koi/` | Persisted per `(koi, sessionKey)`, guarded against concurrent writes and corruption. |
268
+ | Auth and models | `auth-profiles/`, `model-selection.ts`, `models-config*.ts` | Resolve provider/key/model and fail over when one is unavailable. |
269
+ | Sandbox | `src/koi/sandbox/` | Docker isolation for non-main (group/channel) sessions and risky tool runs. |
270
+
271
+ **The koi's brain on disk** is plain Markdown it reads each turn and can edit:
272
+
273
+ ```mermaid
274
+ flowchart LR
275
+ subgraph ws["~/.skykoi workspace"]
276
+ direction TB
277
+ SOUL["SOUL.md<br/>behavior + rules"]
278
+ KOIf["KOI.md<br/>config / personality"]
279
+ IDN["IDENTITY.md<br/>name / avatar"]
280
+ USR["USER.md + profile.json<br/>who the owner is"]
281
+ MEMf["MEMORY.md + memory/*<br/>long-term memory"]
282
+ HB["HEARTBEAT.md<br/>live state / tasks"]
283
+ end
284
+ ws --> sp["into every system prompt"]
110
285
  ```
111
286
 
112
- ### Testing
287
+ ### The gateway
288
+
289
+ `src/gateway/` is the always-on process that exposes the koi to the world. `server.impl.ts`
290
+ boots the WebSocket server, an HTTP surface (control UI plus an OpenAI-compatible
291
+ `/v1/chat/completions`), the channel manager, cron, heartbeat, and **config hot-reload**.
292
+
293
+ ```mermaid
294
+ flowchart TB
295
+ subgraph clients["Clients"]
296
+ direction LR
297
+ c1["macOS / iOS / Android apps"]
298
+ c2["skykoi-live web surface"]
299
+ c3["CLI / TUI"]
300
+ c4["platform connect"]
301
+ end
302
+ clients -->|"WebSocket + RPC"| gw
303
+
304
+ subgraph gw["Gateway process - src/gateway"]
305
+ direction TB
306
+ ws["WS server + RPC handlers<br/>server-methods*.ts"]
307
+ chat["event fan-out<br/>server-chat.ts"]
308
+ cm["channel manager"]
309
+ http["HTTP: control UI + OpenAI-compatible API"]
310
+ end
311
+
312
+ gw --> koi["koi runtime - src/koi"]
313
+ cm --> chans["Channels"]
314
+ ```
113
315
 
114
- ```bash
115
- pnpm test # Full suite: 6790/7001 passing
116
- pnpm test:config # Config tests: 304/305 passing
316
+ > [!NOTE]
317
+ > The **wire protocol** schema is defined in TypeScript and generated to
318
+ > `dist/protocol.schema.json` (plus Swift models) via `scripts/protocol-gen*.ts`. Breaking
319
+ > changes require updating all clients together: run `pnpm protocol:check`.
320
+
321
+ ### Channels, routing and pairing
322
+
323
+ Every messaging surface implements the **same adapter interfaces**
324
+ (`src/channels/plugins/types.core.ts`: messaging / auth / outbound / group / command /
325
+ setup). Channels are **discovered and lazy-loaded**; a configured channel that is not
326
+ installed is logged, not fatal. Built-ins live in their own top-level dirs; extra channels
327
+ are `extensions/*` packages built on the `plugin-sdk`.
328
+
329
+ ```mermaid
330
+ flowchart TB
331
+ M["Inbound native message"] --> ENV["Envelope<br/>normalized"]
332
+ ENV --> RES["resolve-route.ts"]
333
+ RES --> SK["session-key.ts<br/>channel + account + peer + scope"]
334
+ RES --> PAIR{"known sender?"}
335
+ PAIR -->|no| P["pairing + allowlist<br/>src/pairing"]
336
+ PAIR -->|yes| T["target koi + session"]
337
+ P --> T
338
+ T --> KOI["koi loop"]
117
339
  ```
118
340
 
119
- Known test gaps: Worker crash cascades on Windows, browser E2E flakes.
341
+ > [!WARNING]
342
+ > When you change shared **routing / allowlist / pairing / gating** logic, change it for
343
+ > **all** channels at once. That is a recurring source of bugs (see `AGENTS.md`).
120
344
 
121
- ### Build
345
+ ### Providers and models
122
346
 
123
- ```bash
124
- pnpm build # Produces dist/ (26MB optimized)
347
+ Adapters for Anthropic, OpenAI, AWS Bedrock, Google Gemini, Ollama, and others, plus the
348
+ custom **"skykoi" provider** that proxies through the platform so a shared key never lands
349
+ on the device. The actual LLM calls go through the Pi core.
350
+
351
+ ```mermaid
352
+ flowchart LR
353
+ sel["model-selection.ts<br/>capability + cost + availability"] --> p1{"primary<br/>available?"}
354
+ p1 -->|yes| use["use it"]
355
+ p1 -->|no| fb["fallback chain"]
356
+ fb --> use
357
+ use --> pi["Pi core makes the call"]
358
+ cfg["models-config.providers.ts<br/>+ ~/.skykoi/models.json"] -.-> sel
125
359
  ```
126
360
 
127
- The build uses SWC for compilation. tsconfig targets es2020. TypeScript has 0 errors.
361
+ ### Configuration
128
362
 
129
- ## How It Connects to the Platform
363
+ Config is `~/.skykoi/skykoi.json` (JSON5: comments and trailing commas allowed, with
364
+ `${ENV}` substitution). `paths.ts` resolves locations; **`zod-schema.ts` is the runtime
365
+ source of truth** for valid shape; TypeScript types mirror it in `types*.ts`. Old formats
366
+ are upgraded by `legacy-migrate.ts`, and the gateway hot-reloads most changes.
130
367
 
131
- 1. The platform provisions an EC2 instance and pushes config via SSM
132
- 2. The runtime starts and reads the config (gateway token, model settings, etc.)
133
- 3. The gateway opens a WebSocket server on the configured port
134
- 4. A wildcard TLS cert from S3 enables `wss://<instanceId>.gw.skykoi.com`
135
- 5. The platform's frontend connects and sends/receives messages via WebSocket RPC
136
- 6. The Koi processes messages through the LLM provider and streams responses back
137
- 7. The runtime heartbeats to the platform every 30 seconds to report health
368
+ > [!NOTE]
369
+ > The root `.env.example` is a stale leftover, ignore it. Real configuration is
370
+ > `~/.skykoi/skykoi.json` plus a handful of provider env vars; see the docs config pages.
138
371
 
139
- ## Self-Update
372
+ ### Memory
140
373
 
141
- The runtime can update itself in place:
374
+ Long-term recall beyond the live context window: messages and notes are embedded and stored
375
+ in SQLite (`sqlite-vec`); retrieval fuses keyword (BM25) and vector similarity.
142
376
 
143
- ```bash
144
- skykoi gateway update
377
+ ```mermaid
378
+ flowchart LR
379
+ msg["messages + notes"] --> emb["embeddings"]
380
+ emb --> db[("SQLite + sqlite-vec")]
381
+ q["koi memory search"] --> hyb["hybrid: BM25 + vectors"]
382
+ db --> hyb
383
+ hyb --> ctx["into the prompt"]
384
+ ```
385
+
386
+ > Embeddings index asynchronously, so the newest items can lag the index slightly.
387
+
388
+ ### Cron, infra and self-update
389
+
390
+ `src/cron/` runs scheduled, **isolated** koi turns (a reminder, a daily digest) with no live
391
+ channel input, delivering the result to a target. `src/infra/` is the cross-cutting glue:
392
+ backoff, the exec-approval policy engine, heartbeat visibility, and the **self-update** path
393
+ that pulls the latest npm version and restarts the gateway in place (how the fleet rolls
394
+ forward).
395
+
396
+ ### Device and browser
397
+
398
+ `src/node-host/` exposes the local machine's capabilities (screenshot, screen frames,
399
+ location) that the koi drives via the `nodes` tool. `src/browser/` is full Chrome automation
400
+ over CDP plus Playwright, powering the `browser` tool and web-page capture.
401
+
402
+ ### Plugins, extensions and native apps
403
+
404
+ The plugin loader (`src/plugins/`) discovers packages declaring a `skykoi.extensions` entry
405
+ and built against `skykoi/plugin-sdk`. This is how you add a channel or feature **without
406
+ touching core**. `apps/` holds the native clients (`apps/macos` is the menubar app that
407
+ hosts the gateway today); they are clients of the gateway protocol.
408
+
409
+ ---
410
+
411
+ ## Lifecycle of an inbound message
412
+
413
+ End to end, what happens when a message arrives from a channel:
414
+
415
+ ```mermaid
416
+ sequenceDiagram
417
+ actor User
418
+ participant Ch as Channel adapter
419
+ participant AR as auto-reply
420
+ participant Rt as routing
421
+ participant Koi as koi loop
422
+ participant LLM as LLM provider
423
+ participant Tool as Tools
424
+
425
+ User->>Ch: native message
426
+ Ch->>AR: normalize to Envelope
427
+ AR->>AR: command? authorized?
428
+ AR->>Rt: resolve koi + session
429
+ Rt->>Koi: run turn
430
+ loop until done
431
+ Koi->>LLM: messages + tools
432
+ LLM-->>Koi: text or tool call
433
+ Koi->>Tool: execute tool
434
+ Tool-->>Koi: result
435
+ end
436
+ Koi-->>AR: streamed events
437
+ AR-->>Ch: final reply
438
+ Ch-->>User: delivered
145
439
  ```
146
440
 
147
- This pulls the latest npm version and restarts the gateway without losing the Koi workspace or memory. Used for fleet-wide rolling updates.
441
+ The gateway/app path is the same picture, except the entry point is a `chat.send` RPC
442
+ instead of a channel adapter.
443
+
444
+ ---
445
+
446
+ ## Where to add things
447
+
448
+ | You want to... | Go to | Notes |
449
+ |---|---|---|
450
+ | Add a **tool** the koi can call | `src/koi/tools/` | One file per tool; register it in the runner's toolset. Mind the tool-schema guardrails in `AGENTS.md`. |
451
+ | Add a **CLI command** | `src/commands/` + register in `command-registry.ts` | Take `deps` from `createDefaultDeps()`. |
452
+ | Add a **gateway RPC method** | `src/gateway/server-methods*.ts` + protocol schema | Run `pnpm protocol:gen` and update clients. |
453
+ | Add a **channel** | `extensions/<name>/` against `plugin-sdk` (or a `src/<channel>/` adapter) | Implement the `types.core.ts` interfaces; wire routing/allowlist/gating. |
454
+ | Add an **LLM provider/model** | `models-config.providers.ts` | Add the client init + model defs; selection picks it up. |
455
+ | Change the **system prompt / context** | `system-prompt.ts`, `src/world-model/` | Affects every koi; test broadly. |
456
+ | Change **config shape** | `zod-schema.ts` (+ `types*.ts`, add a migration) | Schema is the runtime source of truth. |
148
457
 
149
- ## Koi Workspace
458
+ ---
150
459
 
151
- Each Koi has a workspace at `~/.skykoi/workspace/` containing:
460
+ ## Build, test and release
152
461
 
153
- - `KOI.md` - Koi behavior instructions
154
- - `SOUL.md` - Personality and tone
155
- - `USER.md` - User profile (built over time)
156
- - `MEMORY.md` - Long-term memory
157
- - `memory/` - Daily logs and state
158
- - `BACKLOG.md` - Task tracking
462
+ Everything is in `package.json` scripts (`pnpm run` lists them). The ones you will use most:
159
463
 
160
- The Koi can modify all of these files. Updates must preserve this workspace.
464
+ ```bash
465
+ pnpm build # tsdown: src/ to dist/ (config: tsdown.config.ts)
466
+ pnpm check # typecheck + lint + format (oxlint / oxfmt)
467
+ pnpm test # vitest; pnpm test:coverage for V8 coverage
468
+ pnpm test:live # tests that hit real provider keys (SKYKOI_LIVE_TEST=1)
469
+ pnpm test:docker:* # end-to-end onboarding / gateway / install flows in Docker
470
+ pnpm protocol:check # fail if the generated wire protocol is out of date
471
+ ```
472
+
473
+ <details>
474
+ <summary><b>Release and native-version details</b></summary>
475
+
476
+ - **Tests** are colocated `*.test.ts` (e2e: `*.e2e.test.ts`); the full kit is documented in
477
+ `docs/help/testing.md`.
478
+ - **Releases** are gated and manual: read `docs/reference/RELEASING.md` and
479
+ `docs/platforms/mac/release.md` first, and never bump versions or `npm publish` without
480
+ explicit owner sign-off (see `AGENTS.md`).
481
+ - **Native version bumps** touch several files at once: see `AGENTS.md` -> "Version
482
+ locations".
483
+ </details>
484
+
485
+ ---
486
+
487
+ ## Contributor conventions
488
+
489
+ [`AGENTS.md`](./AGENTS.md) is the detailed playbook (commit/PR flow, docs/i18n rules,
490
+ multi-koi git safety, channel-refactor checklists, release guardrails). The essentials:
491
+
492
+ - **TypeScript, ESM, strict.** Avoid `any`. Keep files reasonably small (~500 LOC guideline;
493
+ `pnpm check:loc`). Run `pnpm check` before you commit.
494
+ - **Add brief comments for non-obvious logic.** Match the surrounding style.
495
+ - **Touch one channel, consider them all** when the change is to shared routing / allowlist /
496
+ pairing / gating / onboarding logic.
497
+ - **Never edit `node_modules` or `dist/`.** Both are generated.
498
+ - **Dependency patches/overrides need explicit approval** and must be pinned to an exact version.
499
+
500
+ ---
501
+
502
+ ## Security model
503
+
504
+ ```mermaid
505
+ flowchart TB
506
+ subgraph trusted["Host - full access"]
507
+ main["main session<br/>tools run on the host"]
508
+ end
509
+ subgraph sandboxed["Docker sandbox"]
510
+ grp["group / channel sessions<br/>+ risky tool runs"]
511
+ end
512
+ unknown(["Unknown sender"]) --> pair["DM pairing required"]
513
+ pair --> main
514
+ sensitive["Sensitive command"] --> approve["exec-approval system"]
515
+ approve --> main
516
+ device(["Gateway client"]) --> auth["device auth"] --> main
517
+ creds["provider keys"] --> proxy["platform proxy<br/>keys stay off device"]
518
+ ```
161
519
 
162
- ## Security
520
+ In one breath: the **main** session runs tools on the host with full access; **non-main**
521
+ sessions can be **Docker-sandboxed**; unknown senders must pass **DM pairing**; sensitive
522
+ commands go through **exec-approval**; **device auth** guards the gateway; and the shared-key
523
+ **platform proxy** keeps provider credentials off the device. Report vulnerabilities per
524
+ [`docs/SECURITY.md`](./docs/SECURITY.md).
163
525
 
164
- - Tools run on the host for the main session (full access)
165
- - Non-main sessions (groups/channels) can be sandboxed via Docker
166
- - DM pairing by default: unknown senders must authenticate
167
- - Exec approval system for sensitive commands
526
+ ---
168
527
 
169
- ## Origins
528
+ ## Further reading
170
529
 
171
- Forked from [SKYKOI](https://github.com/nicepkg/SKYKOI-runtime) (MIT License). See [THIRD_PARTY_LICENSES.txt](./docs/THIRD_PARTY_LICENSES.txt).
530
+ - **Full docs:** [docs.skykoi.com](https://docs.skykoi.com) (sources in `docs/`: channels,
531
+ gateway, tools, providers, platforms, config, releasing).
532
+ - **Contributor playbook:** [`AGENTS.md`](./AGENTS.md).
533
+ - **The web/voice surface that talks to this runtime:** the `skykoi-live` repo (it connects
534
+ to this gateway for deep work).
172
535
 
173
536
  ## License
174
537
 
175
- MIT
538
+ BUSL-1.1: see [`LICENSE`](./LICENSE) and
539
+ [`docs/THIRD_PARTY_LICENSES.txt`](./docs/THIRD_PARTY_LICENSES.txt).