@kybernesis/create 0.6.0 → 0.7.1

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.
@@ -1873,6 +1873,45 @@ client with an existing ChatGPT or Claude subscription pays no incremental
1873
1873
  inference cost for the pilot. Say the number out loud in the discovery
1874
1874
  conversation — it changes the shape of the deal.
1875
1875
 
1876
+ **Grok, on a SuperGrok or X Premium+ subscription.** Same arrangement, without
1877
+ the broker: xAI's Grok Build CLI does a device login and writes a credential
1878
+ that is a valid bearer for `https://api.x.ai/v1`. Proven in production on Sid —
1879
+ twelve evals, twenty-nine gates, green on the subscription.
1880
+
1881
+ ```bash
1882
+ # on the host, as the unix user the agent runs as
1883
+ curl -fsSL https://x.ai/cli/install.sh | bash
1884
+ grok login # device flow → ~/.grok/auth.json
1885
+ ```
1886
+
1887
+ ```ts title="agent/agent.ts"
1888
+ import { createOpenAI } from "@ai-sdk/openai";
1889
+ import { grokSubscription } from "@kybernesis/exe";
1890
+
1891
+ export default defineAgent({
1892
+ model: grokSubscription({ model: "grok-4.6", createOpenAI }),
1893
+ modelContextWindowTokens: 400_000,
1894
+ });
1895
+ ```
1896
+
1897
+ Three things to know before you promise it to a client:
1898
+
1899
+ - The credential is **per-machine and per-user**. It lives in a home directory.
1900
+ A different unix user cannot see it; a new host needs its own login.
1901
+ - It **expires in six hours** and the CLI refreshes it in place, so the agent
1902
+ must re-read the file per request. `grokSubscription` does this in a `fetch`
1903
+ wrapper. (Do not reach for a Proxy around the model object — the AI SDK's
1904
+ methods depend on their own `this` and every call dies inside the SDK.)
1905
+ - **Unattended refresh over days is unverified.** If nobody runs `grok` on that
1906
+ host for a week, it is an open question, and it would present to the client as
1907
+ the agent breaking for no reason.
1908
+
1909
+ **The model will lie about which model it is.** Sid, running Grok, stated it was
1910
+ "Claude Opus 4.6, Anthropic" and attributed it to an instruction that exists
1911
+ nowhere in its context. Verify from the host — the configured model id and the
1912
+ credential in use — never by asking the agent. Expect a client to ask it in a
1913
+ demo, and have the real answer ready.
1914
+
1876
1915
  ### 11.5 Third-party APIs: broker the credential, pin the version
1877
1916
 
1878
1917
  Do not put a client's API token on the agent host. Put it in an exe.dev
@@ -1974,6 +2013,48 @@ Also: a long-lived channel session caches the compiled agent. After changing
1974
2013
  capabilities, start a **fresh conversation** before deciding the change did not
1975
2014
  work.
1976
2015
 
2016
+ **A restart script must do two more things, and both were learned from a
2017
+ stranded user.**
2018
+
2019
+ *Serialize restarts.* `@kybernesis/manage` fires one 20s after any change, and
2020
+ you will also run one by hand. Two overlapping runs both finish killing before
2021
+ either starts, and you end up with **two supervisors and two servers writing to
2022
+ one durable store** — two executors racing over the same runs. That is not a
2023
+ slow agent, it is a corrupt one. Take a `flock` at the top of the script, and
2024
+ assert exactly one server process at the bottom.
2025
+
2026
+ *Wait for in-flight turns.* eve does **not** resume a step killed mid-flight.
2027
+ Restart into a live turn and that turn never emits another event, the session
2028
+ never parks, and every later message queues behind a turn that will never
2029
+ finish. The user watches a spinner forever, and no further restart fixes it,
2030
+ because the session is stranded rather than stuck. Poll
2031
+ `.eve/.workflow-data/runs/*.json` for a `turnWorkflow` in `running` state and
2032
+ wait for it to clear — with a cap, so a wedged turn cannot block the restart
2033
+ that would clear it.
2034
+
2035
+ *And build before you restart.* Proving the process started after the BUILD says
2036
+ nothing about whether the build reflects the SOURCE. A production agent ran for a
2037
+ day on a build ten hours older than its files, reporting "OK: serving the current
2038
+ build" every time. Worse, `@kybernesis/manage` calls the restart script after
2039
+ writing files — so **every capability installed from Studio reported success and
2040
+ changed nothing.** Build when the source has moved, and refuse to restart into a
2041
+ build that failed.
2042
+
2043
+ *And measure it correctly.* `pgrep -f 'server/index.mjs'` run over ssh matches
2044
+ **the shell running the pgrep** — the pattern is in its own command line — so it
2045
+ reports two servers when there is one. An entire investigation went into hunting
2046
+ a phantom supervisor that a `ps -eo pid,ppid,args` would have dismissed in
2047
+ thirty seconds. Same family as `pkill -f` killing its caller. Inside a script
2048
+ file it is safe (the script's command line is `bash restart.sh`); typed at a
2049
+ shell or sent over ssh it is not. When a process count surprises you, **list the
2050
+ matches before believing the number.**
2051
+
2052
+ The escape from an already-stranded session is a **session reset**
2053
+ (`ClientSession.reset()`, or Reset in Studio's agent settings), which releases
2054
+ the durable owner so the next message starts a fresh conversation. Cancelling
2055
+ often does not help: the executor that would honour the cancel is the one that
2056
+ died.
2057
+
1977
2058
  ### 11.9 Credential checklist — collect ALL of these from the client
1978
2059
 
1979
2060
  Nothing here can be borrowed from another agent or another account.
@@ -2047,8 +2128,14 @@ manage, since it cannot check a grant for a name it does not know.
2047
2128
  rebuilds, so it works on a VM and refuses on a read-only serverless bundle,
2048
2129
  with that reason. Set `restartCommand` in `agent/channels/kyb.ts` or an
2049
2130
  install completes without taking effect.
2050
- 4. **For `local`: the relay secret** (`LOCAL_EXEC_AGENT_SECRET`) matching the
2051
- control plane.
2131
+ 4. **For `local`: nothing to configure.** Setup is one switch in Studio — the
2132
+ agent's settings, *Work on this computer*. Behind it, Studio mints the
2133
+ agent's credential from the control plane, installs it over the manage
2134
+ channel, and records a standing grant for that machine; the agent restarts
2135
+ once to load it. Never hand anyone a credential to paste into an env file.
2136
+ The admin UI's "mint agent credential (shown once)" button remains for
2137
+ recovery and is not the path: a setup step that asks someone to carry a
2138
+ secret between two screens gets done wrong or skipped.
2052
2139
 
2053
2140
  ### 12.4 What consent looks like for the user
2054
2141
 
@@ -2065,11 +2152,23 @@ colleague knows "build me a demo" from "look at my repo".
2065
2152
 
2066
2153
  ### 12.5 State this plainly to the client
2067
2154
 
2068
- - **Local execution is not yet a governed capability.** The agent authenticates
2069
- to the relay with a shared secret, so anyone holding it can reach a connected
2070
- desktop in that org. It must become its own revocable grant, separate from
2071
- "may talk to this agent". Do not install `local` at a client who would treat
2072
- that as a surprise.
2155
+ - **Two things gate a laptop, and they fail differently.** *Identity* is the
2156
+ agent's signed credential "the local-execution relay rejected my
2157
+ credentials" means that. *Consent* is a standing per-device grant "you have
2158
+ not allowed this agent to work on this computer" means that. Neither alone
2159
+ reaches anything. The grant is permanent on purpose: "always allow" means
2160
+ always, from a chat window, a schedule, or a message sent from a phone, and it
2161
+ ends on revoke, device removal, or disabling the agent.
2162
+ - **Reaching a desktop is still not its own revocable capability.** "May talk to
2163
+ this agent" and "may run commands on my laptop" remain one decision, taken
2164
+ when the person allows the machine. Say so at a client who would treat it as a
2165
+ surprise.
2166
+ - **Installing the credential restarts the agent**, and a turn in flight during
2167
+ that restart is lost for good — eve does not resume a step killed mid-flight.
2168
+ It reads as a spinner that never resolves, often alongside a "credential is
2169
+ unset" error from the process that was replaced. Send a new message, and reset
2170
+ the conversation if the session itself is stranded. §11.8 is why a restart
2171
+ script must wait for in-flight turns.
2073
2172
  - **Reading a file sends it to the model.** Execution is local; the reasoning is
2074
2173
  not. Fine for most work, and a conversation to have before a Studio points at
2075
2174
  a regulated repository.
@@ -2077,6 +2176,129 @@ colleague knows "build me a demo" from "look at my repo".
2077
2176
  means the repository is no longer only yours. Agree who reviews what Studio
2078
2177
  writes — routines land as source files, so a normal review works.
2079
2178
 
2179
+ ### 12.7 Connectors — the apps library
2180
+
2181
+ The Apps tab in Studio is a shelf of services a person connects in one click:
2182
+ Gmail, Calendar, Drive, Slack, Notion, Linear, GitHub, Attio, Outlook, HubSpot.
2183
+ Connecting one makes its tools appear in that person's next session.
2184
+
2185
+ **Setup is one field, and it belongs to the client.** The org's own Composio key
2186
+ goes in their control plane at **Settings → Connectors**, set by an owner, the
2187
+ same way SSO is. It is never a deployment env var and never ours: each control
2188
+ plane belongs to one company, and nobody's people connect their mailboxes under
2189
+ another org's account. Direct them to composio.dev → Settings → API Keys.
2190
+
2191
+ **What makes it one click** is that Composio has already registered the OAuth
2192
+ app for each service. Without a broker, every client has to create a developer
2193
+ app per provider — which is exactly the hour lost to Notion on the first
2194
+ deployment, version pin and all.
2195
+
2196
+ **Two things on every card, because both are load-bearing:**
2197
+
2198
+ *Connects as you* versus *for the company*. A user-scoped connection cannot fire
2199
+ from a schedule — a routine at 8am has no signed-in person. Anything a briefing
2200
+ depends on must be the company's connection.
2201
+
2202
+ *An admin must approve*. True for Slack, Notion, and Google Workspace. Say it on
2203
+ the card; a client who discovers it at the end of a redirect chain reads the
2204
+ product as broken.
2205
+
2206
+ **How tools reach the agent.** `@kybernesis/connectors` mounts a dynamic
2207
+ resolver in `agent/tools/connectors.ts`. It resolves per session from the
2208
+ principal on the turn, asks the control plane what that person has connected,
2209
+ and calls back through it to execute. The agent never holds the broker key — it
2210
+ proves which agent it is with its own credential, and the control plane decides
2211
+ whose account the call runs against.
2212
+
2213
+ Resolution is per session, not per turn: a tool set is part of the prompt, and
2214
+ rebuilding it every turn re-ingests the conversation at uncached prices. Pass
2215
+ `perTurn: true` where people connect things mid-conversation and expect them to
2216
+ work immediately.
2217
+
2218
+ **Say this to the client.** Their Composio account holds refresh tokens for
2219
+ their Google Workspace and Slack — a fourth party alongside the model provider,
2220
+ the host, and us. Most will not blink; a regulated one will, and the answer for
2221
+ them is `eve-connect`, native eve connections with no broker. That is why every
2222
+ card carries a `provider`.
2223
+
2224
+ **And watch the bill.** Composio prices per action. An agent in a loop is a very
2225
+ different cost profile from a person clicking, and that belongs in the pricing
2226
+ conversation before the first invoice, not after.
2227
+
2228
+ ### 12.8 MCP servers — the client's own tools, local and remote
2229
+
2230
+ The MCP tab is the escape hatch from the shelf: anything with an MCP server
2231
+ becomes agent tools, whether it runs on the person's laptop or on a URL.
2232
+
2233
+ **Local** — a command Studio runs on that machine (`npx -y @acme/mcp`, with env
2234
+ vars if the server needs them). Studio keeps it alive, and the deployed agent
2235
+ reaches it through the same relay as local execution. This is how a client's
2236
+ internal tooling — the CLI nobody will ever expose to the internet — becomes
2237
+ something the agent can use, without opening a port.
2238
+
2239
+ **Remote** — a URL and optional headers. Studio runs the handshake before
2240
+ saving, so a bad URL fails at the moment someone types it rather than in the
2241
+ middle of a demo.
2242
+
2243
+ Consent is **per server**, and approving one does not approve the next. The
2244
+ discovery call (listing what a server offers) is exempt — otherwise a person is
2245
+ asked to approve something before they can see what it is.
2246
+
2247
+ The things that cost real sessions here:
2248
+
2249
+ - **The command in a vendor's README is often the installer**, not the server.
2250
+ Plaud's documented line runs an `install` subcommand and exits; the stdio
2251
+ server is the bare command. If a server "connects" and never answers, check
2252
+ that you are running the server.
2253
+ - **A server declares its arguments and you must honour them.** Studio passes
2254
+ the published `inputSchema` through to the model (`@kybernesis/local` ≥0.5.0).
2255
+ Before that it did not, and watching the result is the best argument for the
2256
+ fix: nine consecutive calls guessing the name of an argument the server had
2257
+ documented, steered only by error strings.
2258
+ - **Discovery must have a deadline.** These resolvers run before a turn and
2259
+ reach across a network to a laptop that might be shut. Budgeted at 6s with a
2260
+ five-minute cache; without that, one closed lid makes every turn hang.
2261
+
2262
+ ### 12.9 Rooms — several agents in one conversation
2263
+
2264
+ A client with a planner, a designer, and an engineer agent can put all three in
2265
+ one room and work with them the way they would with people. The room lives
2266
+ entirely in the desktop app: each member keeps its own session with its own
2267
+ deployment, and the app is what puts a message in front of all of them. **No
2268
+ agent needs to know the feature exists**, which is what makes it work with an
2269
+ agent the client wrote themselves.
2270
+
2271
+ **Addressing is the routing, and it is worth teaching in one line.** Name a
2272
+ member and only they answer. `@everyone` addresses the room. Name nobody and
2273
+ the room's lead answers — the first member — who brings the others in. Matching
2274
+ is literal and requires the `@`, because an agent called Design must not be
2275
+ summoned by the word "design" in an ordinary sentence.
2276
+
2277
+ **Hand-offs are how work moves.** An agent's reply reaches another agent only
2278
+ when it names them, and whoever is brought in receives what they missed since
2279
+ they last spoke. Without that catch-up a hand-off is incoherent: the engineer is
2280
+ asked to "build this" having never seen what "this" is.
2281
+
2282
+ Say these plainly to a client, because all three will come up:
2283
+
2284
+ - **Every hop is a billed turn** on a deployed agent. A three-agent hand-off
2285
+ chain is three turns, and there is a depth cap so a pair that keeps addressing
2286
+ each other cannot run away.
2287
+ - **The convention is a prompt, not a protocol.** Each turn carries a line
2288
+ telling the agent it is in a room and how to hand off. A well-behaved agent
2289
+ follows it; nothing enforces it. A misbehaving one is ignored rather than able
2290
+ to start a cascade — agent-to-agent relay has NO policy fallback, precisely so
2291
+ one reply cannot become a reply from everyone.
2292
+ - **A relayed message runs under the human's identity.** When the planner hands
2293
+ to the engineer, the engineer acts with that person's authority on another
2294
+ agent's say-so. Among a client's own agents that is usually what they want.
2295
+ It is still a governance decision, and it should be made rather than
2296
+ discovered.
2297
+
2298
+ What NOT to promise: emergent self-organisation. The chain works when someone —
2299
+ a person or an agent — explicitly hands off. It is a room where people and
2300
+ agents talk, not an autonomous workflow engine.
2301
+
2080
2302
  ## 13. Known gaps — state these plainly, do not sell around them
2081
2303
 
2082
2304
  Being straight about these is a feature. Clients have met vendors who were not.
@@ -2094,9 +2316,12 @@ Being straight about these is a feature. Clients have met vendors who were not.
2094
2316
  requester or a `manage`-grant holder may approve — are the planned governance half in
2095
2317
  `@kybernesis/enterprise`.
2096
2318
 
2097
- 3. **Eve Studio sign-in is specced, not built.** Employees who do not live in Slack have
2098
- no polished desktop door yet; HTTP access is token-by-hand via the device flow. The
2099
- implementation brief is in [[kybernesis-architecture-and-studio-signin]].
2319
+ 3. **The desktop door is built** KYBER Studio, signed and notarized, with device-flow
2320
+ sign-in and in-app updates. What is NOT built is a second consent system talking to
2321
+ the first: the control plane holds the standing per-device grant, Studio holds
2322
+ per-effect permissions in a local file, and revoking in one does not revoke the
2323
+ other. An off-boarding story that says "we revoke access centrally" must be qualified
2324
+ at any client that asks the follow-up question.
2100
2325
 
2101
2326
  4. **Off-boarding SLA equals the token TTL** (1h default) for already-minted sessions.
2102
2327
  Suspension is immediate; revocation is not. Tune `IDENTITY_TOKEN_TTL_SECONDS` to the
@@ -2107,9 +2332,20 @@ Being straight about these is a feature. Clients have met vendors who were not.
2107
2332
  a time per session — simultaneous speakers resolve in arrival order, with mid-turn
2108
2333
  messages folded into the next turn best-effort.
2109
2334
 
2110
- 6. **Per-user OAuth into personal SaaS and local-file work (the device bridge) are future
2111
- builds.** Org service accounts with static tokens cover most pilot asks. Subagents in
2112
- particular *cannot* use per-user OAuth at all no user principal.
2335
+ 6. **Per-user OAuth and local-file work are BUILT** §12.6 and §12.7, both proven end
2336
+ to end. The remaining edge is the one that bites unattended: anything without a
2337
+ signed-in person (a schedule, a subagent) has no user principal, so a user-scoped
2338
+ connection is not available to it. A morning briefing built on someone's personal
2339
+ Gmail connection does not fail loudly — it quietly has no tools. Company-scoped
2340
+ connections are the answer, and that path has not yet been exercised in production.
2341
+
2342
+ Two more, worth saying because a client will meet them:
2343
+
2344
+ - **Tool volume is unmanaged.** Gmail and Calendar alone are 51 tool definitions in
2345
+ every prompt. Real tokens per turn, and measurably worse tool selection as a client
2346
+ connects more. Curation is designed, not shipped — connect what the pilot needs.
2347
+ - **Local MCP servers are per-machine.** A person's second laptop silently has a
2348
+ different set, and nothing in the UI says which machine a server is on.
2113
2349
 
2114
2350
  7. **DM memory is per-workspace, not per-employee, unless you build it.** Splitting DMs
2115
2351
  into one Arcana workspace per person needs a Slack-user-id → workspace-slug map in the
@@ -1,10 +1,10 @@
1
1
  ---
2
- description: Use when installing, configuring, or debugging any @kybernesis package — arcana (memory), enterprise (governance), multiplayer (Slack), engineer (build+ship), dispatch (agent-to-agent), evals (QA), create (kyb CLI) — or the Kybernesis registry. Includes every production-learned gotcha.
2
+ description: Use when installing, configuring, or debugging any @kybernesis package — arcana (memory), enterprise (governance), multiplayer (Slack), engineer (build+ship), dispatch (agent-to-agent), connectors (Gmail/Calendar/remote MCP), local (the user's own machine), manage (Studio→agent), exe (off-Vercel hosting), evals (QA), create (kyb CLI) — or the Kybernesis registry. Includes every production-learned gotcha.
3
3
  ---
4
4
 
5
5
  # The Kybernesis packages
6
6
 
7
- Seven packages, npm-public under `@kybernesis`, Apache-2.0, monorepo
7
+ Eleven packages, npm-public under `@kybernesis`, Apache-2.0, monorepo
8
8
  `KybernesisAI/platform`. Registry: `https://registry.kybernesis.ai`
9
9
  (`eve registry add @kybernesis=https://registry.kybernesis.ai/r/{name}.json`,
10
10
  then `eve add @kybernesis/<item>`). Each covers one axis:
@@ -60,6 +60,28 @@ then `eve add @kybernesis/<item>`). Each covers one axis:
60
60
  0.2.1 lesson: eve resolves remote URLs at BOOT — url() must degrade
61
61
  (env → discovery-if-credentialed → fallbackUrl), never throw on a missing
62
62
  credential, or the whole agent (and its evals) fails to boot.
63
+ - **connectors** — the user's SaaS accounts, brokered. `connectorTools()` is a
64
+ dynamic resolver: at turn start it asks the control plane which services THIS
65
+ principal has connected and returns those tools. Composio is the broker; the
66
+ API key is per-org, held in the control plane (never an env var, never a
67
+ client's key in our account). Tools are named `<toolkit>_<action>`. Also
68
+ exports `toolInputSchema` (broker JSON Schema → zod) and a minimal MCP client
69
+ for `mcp-direct` servers that speaks BOTH JSON and text/event-stream.
70
+ - **local** — the user's own machine, through KYBER Studio. `localShellTool`,
71
+ `localRead/List/Write/Edit/SearchTool`, plus `localMcpTools()` for MCP servers
72
+ running on that machine, relayed. Every effect is consented in Studio; the
73
+ agent never holds a shell. `LOCAL_INSTRUCTIONS` explains the arrangement to
74
+ the model — mount it or the agent will offer to do things it cannot do.
75
+ - **manage** — the other direction: `manageChannel()` lets Studio install
76
+ capabilities and write schedules onto a running agent, and `routineTools()`
77
+ turns "every morning at 8, brief me" into a real schedule file. This is how a
78
+ routine gets created from chat without anyone touching the repo.
79
+ - **exe** — running off Vercel. `exeModel()` for exe.dev's LLM integration,
80
+ `grokSubscription()` / `readGrokCredential()` for a SuperGrok or X Premium+
81
+ login (`grok login` → `~/.grok/auth.json`, a valid bearer for api.x.ai —
82
+ same shape as eve's `experimental_chatgpt()`), `hostPreflight()`, Photon
83
+ iMessage credentials, and a `/preview` tool. Subpaths: `/slack`, `/photon`,
84
+ `/sandbox`, `/preview`. See the `self-hosting` skill.
63
85
  - **evals** — QA. `kybernesisBaseline({ agentDisplayName, routing,
64
86
  engineer? })` = smoke + 5 memory + routing per dept + optional vision-loop
65
87
  eval. Judge model ≠ model under test. Hermetic runs force all workspaces to
@@ -91,6 +113,36 @@ then `eve add @kybernesis/<item>`). Each covers one axis:
91
113
  company-general wording (dept-flavored prompts delegate and hide tool
92
114
  calls), no security vocabulary ("canary" triggers refusals), long routing
93
115
  timeouts. Do not "clean up" the odd-looking patterns.
116
+ - **A per-turn dynamic resolver needs a deadline.** `connectorTools()` and
117
+ `localMcpTools()` run before every turn and reach across a network. Without a
118
+ budget (6s) and a cache (60s connectors, 5min local discovery) one unreachable
119
+ laptop makes every turn hang — the agent looks broken and nothing in the log
120
+ says why.
121
+ - **Composio: one request per toolkit.** Repeating `toolkit_slug` in a single
122
+ `/api/v3/tools` call returns an EMPTY list, so connecting a second service
123
+ silently emptied the first. The logo is at `meta.logo`, not `logo`. A 200 can
124
+ still carry `successful: false` — check the body, not the status.
125
+ - **The broker's entity is the agent's REGISTERED name**, not its UUID.
126
+ `<agent>:<userId>`. Studio knows agents by id; normalize before you ask the
127
+ broker, or a connected account looks unconnected.
128
+ - **MCP requires the handshake.** `initialize` AND `notifications/initialized`
129
+ before `tools/list`, or the server never answers. Spawn through a LOGIN shell
130
+ (a bare spawn misses the user's PATH and node) and always bind
131
+ `child.on("error")` — without it a failed spawn is an unhandled rejection
132
+ that takes the process, not a error message.
133
+ - **Translate the MCP/broker inputSchema — never pass an open object.** A tool
134
+ with no declared arguments makes the model guess: nine calls to find a
135
+ `file_id` the server had documented all along. `mcpInputSchema` (local) and
136
+ `toolInputSchema` (connectors) do this; keep them permissive where the server
137
+ says nothing.
138
+ - **Never wrap a model object in a Proxy.** The AI SDK's model methods depend on
139
+ their own `this`; intercepting them detaches it and every call dies inside the
140
+ SDK on a missing internal. To swap a credential, wrap `fetch` instead — and
141
+ re-read the credential per request: a Grok login expires in six hours and the
142
+ CLI refreshes it in place.
143
+ - **Credentials are never a user's problem.** No client ever puts a key in a
144
+ `.env` — broker keys live per-org in the control plane, encrypted at rest, set
145
+ through an admin screen. A design that ends in "paste this token" is wrong.
94
146
  - **npm**: only the `kybernesis` account creates new packages in the scope;
95
147
  publishes need the human's browser auth; new versions take 1–3 min to
96
148
  propagate to anonymous reads.
@@ -25,7 +25,7 @@ kyb init <name> --host=exe --channel=<imessage|slack|telegram|none> --engineer
25
25
 
26
26
  | Capability | On Vercel | Self-hosted replacement |
27
27
  | --- | --- | --- |
28
- | Model access | AI Gateway | exe.dev LLM integration (`exeModel`) — managed, BYO key, or a **ChatGPT subscription** |
28
+ | Model access | AI Gateway | exe.dev LLM integration (`exeModel`) — managed, BYO key, or a **ChatGPT / Grok subscription** |
29
29
  | Slack/Photon/Linear credentials | Vercel Connect | **Portable/static credentials the client issues** |
30
30
  | Sandbox | `vercel()` hosted | `docker()` on the host |
31
31
  | File delivery | Vercel Blob | Blob **or** `DELIVER_DIR` + `DELIVER_BASE_URL` |
@@ -38,6 +38,44 @@ Vercel MCP connection, Linear, everything. Each becomes a static credential
38
38
  someone must issue and rotate. `kyb doctor` fails loudly if a `@vercel/connect`
39
39
  import survives into a self-hosted agent.
40
40
 
41
+ ## Running on the client's own subscription
42
+
43
+ A client who already pays for ChatGPT Plus/Pro or SuperGrok / X Premium+ can
44
+ run the agent on it instead of on metered API billing. Both work the same way:
45
+ a CLI performs a device login on the host, writes a credential to the home
46
+ directory, and that credential is a valid bearer for an OpenAI-compatible
47
+ endpoint. eve ships `experimental_chatgpt()` for the first;
48
+ `@kybernesis/exe` ships `grokSubscription()` for the second.
49
+
50
+ ```bash
51
+ # on the host, as the user the agent runs as
52
+ curl -fsSL https://x.ai/cli/install.sh | bash
53
+ grok login # device flow → ~/.grok/auth.json
54
+ ```
55
+
56
+ ```ts title="agent/agent.ts"
57
+ import { createOpenAI } from "@ai-sdk/openai";
58
+ import { grokSubscription } from "@kybernesis/exe";
59
+
60
+ export default defineAgent({
61
+ model: grokSubscription({ model: "grok-4.6", createOpenAI }),
62
+ modelContextWindowTokens: 400_000,
63
+ });
64
+ ```
65
+
66
+ What this arrangement costs you, and it is worth saying to the client:
67
+
68
+ - **It is per-machine and per-user.** The login belongs to the host's home
69
+ directory. Moving the agent means logging in again; running it as a different
70
+ unix user means it cannot see the credential at all.
71
+ - **The token expires in hours** (Grok: six) and the CLI refreshes it in place.
72
+ Read it per request, never once at boot, or the agent works all afternoon and
73
+ starts failing authentication at dinner for no reason a user can see.
74
+ - **Nobody has proven unattended refresh over days.** If no one runs `grok` on
75
+ that host, whether the refresh keeps happening is an open question — and it
76
+ presents as the agent "breaking".
77
+ - **Ask the vendor's terms question before a client demo**, not after.
78
+
41
79
  ## The failure modes, each of which cost a real session
42
80
 
43
81
  - **Docker ships disabled on some images.** exe.dev's exeuntu runs
@@ -144,3 +182,25 @@ yesterday's agent. Assert the process started AFTER the build it should serve
144
182
  (`scripts/eve-server.sh` and the restart pattern in `@kybernesis/exe` do this).
145
183
  Related: a long-lived channel session caches the compiled agent, so start a
146
184
  fresh conversation after changing capabilities.
185
+
186
+ A restart script also has to **serialize** (`flock`, released by the child with
187
+ `9>&-`) and **wait for in-flight turns** — eve does not resume a step killed
188
+ mid-flight, and restarting into a live turn strands the session behind a turn
189
+ that will never finish.
190
+
191
+ Run restarts **detached** from your ssh connection —
192
+ `setsid nohup bash restart.sh >/tmp/r.log 2>&1 </dev/null &` — or a dropped
193
+ connection SIGHUPs the script halfway through and leaves exactly the mess it
194
+ exists to prevent.
195
+
196
+ **Build before you restart.** Proving the process started after the build says
197
+ nothing about whether the build reflects the source — an agent served a build ten
198
+ hours older than its files while reporting success. It also breaks installs:
199
+ `@kybernesis/manage` writes files and then calls the restart script.
200
+
201
+ **And measure it correctly.** `pgrep -f 'server/index.mjs'` typed over ssh
202
+ matches the shell running it: the pattern is in that shell's own command line,
203
+ so it reports two servers when there is one. A whole investigation went into a
204
+ phantom "second server" that `ps -eo pid,ppid,args` would have dismissed
205
+ immediately. Inside a script file it is safe; typed at a shell it is not. List
206
+ the matches before you believe the count.