@robota-sdk/agent-cli 3.0.0-beta.88 → 3.0.0-beta.90

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,54 @@
1
1
  # @robota-sdk/agent-cli
2
2
 
3
+ ## 3.0.0-beta.90
4
+ ### Minor Changes
5
+
6
+ - 7116367: Credentials the runtime holds for itself no longer reach the commands it runs.
7
+
8
+ - `agent-cli` — once a workspace's settings are admitted, every variable a provider profile or
9
+ definition names as its credential (`$ENV:` references, and defaults such as `OPENAI_API_KEY`)
10
+ leaves the process environment, so tools, hooks, background shells, a skill's `!` commands and
11
+ the environment an MCP header helper inherits no longer carry it, a hosted worker's broker token
12
+ included (a variable an MCP definition references explicitly still resolves); the provider keeps
13
+ authenticating from the startup snapshot. A user or managed settings layer can let
14
+ commands see one with `"commandEnvAllow": ["NAME"]`; project settings cannot. With the OS sandbox
15
+ on, confined commands can no longer read `settings.json`, `credentials/`, `mcp-credentials/` or
16
+ `remote-host-identity.json` under the user state directory. **Behavior change:** a command that
17
+ relied on inheriting a provider key now needs the opt-in, and a host embedding `startCli` finds
18
+ those variables gone from its own `process.env` afterwards — a later in-process call must pass them
19
+ in its `environment`.
20
+ - `agent-framework` — the settings schema gains `commandEnvAllow`; `checkSettingsDocument` and
21
+ `buildProviderProfilesSnapshot` take an optional environment map to resolve `$ENV:` references
22
+ against instead of the live process environment.
23
+ - `agent-command` — provider startup checks credentials against the host's environment snapshot.
24
+ - `agent-tools` — `OsSandboxClient` takes `hiddenPaths`, always hidden from confined commands and
25
+ not changeable by sandbox settings.
26
+ - `agent-subagent-runner` — a child-process subagent removes its provider credential variable from
27
+ its own environment once its provider is built, unless the start payload says the owner opted it in
28
+ (`keepProviderCredential`).
29
+ - `dag-node-instant-node` — prompt nodes accept an env resolver (`createPromptBackedNodeDefinition`'s
30
+ third argument, `rehydrateInstantNode`'s `resolveEnv`) for their `$ENV:` credential default.
31
+ - `agent-command-workflows` — `/workflows create` and `/workflows run` resolve prompt-node credentials
32
+ from the host's environment snapshot.
33
+
34
+ ### Patch Changes
35
+
36
+ - 5bb675a: Provider commands check a profile's `$ENV:` or default credential against the host's environment snapshot, so `/provider switch`, `/provider test`, `/provider add`, `/provider edit` and a cross-profile `/model` keep working while the runtime withholds its own credentials from `process.env`.
37
+
38
+ - `IProviderCommandModuleOptions` takes an optional `env`, and `createDefaultCommandModules` takes `providerEnvironment`. The CLI passes its startup snapshot.
39
+ - The git that isolated subagents run, and so the repository's hooks, now get the command environment instead of the full snapshot.
40
+
41
+ ## 3.0.0-beta.89
42
+ ### Minor Changes
43
+
44
+ - 3427887: `--serve --http-port` can serve the agent HTTP API as an OAuth resource server: with `--http-public-url`, `--oauth-issuer`, `--oauth-scopes` and `--oauth-allowed-subjects` (plus optional `--http-host` and `--trusted-proxy`) it may bind a non-loopback address and admits access tokens through the same shared resource-server gate as `mcp serve`. Without them it stays loopback with the `PRODUCT_HTTP_TOKEN` bearer.
45
+
46
+ The refusal answer shared by both resource-server carriers (503 for unavailable issuer keys, uncounted; counted challenge otherwise) is now `refuseAccessToken` in `@robota-sdk/agent-transport/node`.
47
+
48
+ ### Patch Changes
49
+
50
+ - ca44ac6: HTTP clients can now receive and answer permission and ask prompts. `POST /submit` with `receivePrompts: true` streams `permission_request`, `ask_request` and `prompt_resolved`. `GET /prompts` lists the prompts still open, so a client that attaches later can see them, and `POST /prompts/:id` answers one; an id that is not open returns 404, and an answer the session did not take returns 409. Clients that omit `receivePrompts` see no change. `IHttpTransportSession` now also requires `resolvePermission` and `resolveAsk`, which `InteractiveSession` already implements. The `--serve --http-port` API gains these routes as well.
51
+
3
52
  ## 3.0.0-beta.88
4
53
 
5
54
  ### Minor Changes
package/README.md CHANGED
@@ -308,22 +308,33 @@ application or service can use it without a Robota client library. Every request
308
308
  bearer you choose in `PRODUCT_HTTP_TOKEN` (at least 32 characters); the runtime removes it from its
309
309
  environment, so the commands it runs do not inherit it. A command running as the same OS user can
310
310
  still read the server's launch environment unless the OS sandbox confines it (or the server runs
311
- as a separate user), so enable the sandbox on a server. Reach the API from elsewhere through your own
312
- reverse proxy or tunnel: it binds loopback only.
311
+ as a separate user), so enable the sandbox on a server. With the bearer it binds loopback only.
312
+
313
+ To reach it from elsewhere, either put your own reverse proxy or tunnel in front, or serve it as an
314
+ OAuth resource server, the same way `robota mcp serve` does: give `--http-public-url`, `--oauth-issuer`,
315
+ `--oauth-scopes` and `--oauth-allowed-subjects` (optionally `--http-host <ip>` and `--trusted-proxy`)
316
+ and no `PRODUCT_HTTP_TOKEN`. Clients then present access tokens from that issuer whose audience is the
317
+ public URL, which carry the scopes and name an allowed subject. The routes below are served under the
318
+ public URL's path, and its RFC 9728 metadata at `/.well-known/oauth-protected-resource<path>`.
313
319
 
314
320
  ```bash
315
321
  PRODUCT_HTTP_TOKEN="$(openssl rand -hex 32)" robota --serve --http-port 8787
322
+ robota --serve --http-port 8787 --http-host 0.0.0.0 \
323
+ --http-public-url https://agents.example.com/agent --oauth-issuer https://auth.example.com \
324
+ --oauth-scopes agent.run --oauth-allowed-subjects client-a
316
325
  ```
317
326
 
318
327
  | Request | Does |
319
328
  | --- | --- |
320
- | `POST /submit` `{"prompt": "..."}` | Runs a turn and streams it as SSE (`text_delta`, `complete`, `error`); `409` while a turn is running |
329
+ | `POST /submit` `{"prompt": "...", "receivePrompts"?: true}` | Runs a turn and streams it as SSE (`text_delta`, `complete`, `error`; with `receivePrompts`, also `permission_request`, `ask_request`, `prompt_resolved`); `409` while a turn is running |
330
+ | `GET /prompts` · `POST /prompts/<id>` `{"result": true}` | Lists the open permission/ask prompts · answers one (`{"response": ...}` for an ask) |
321
331
  | `POST /command` `{"name": "help", "args": ""}` | Runs a slash command |
322
332
  | `POST /abort` · `POST /cancel-queue` | Aborts the running turn · drops the queued prompt |
323
333
  | `GET /messages` · `/context` · `/executing` · `/pending` | Reads the conversation and its state |
324
334
 
325
- No one can answer a permission prompt over HTTP, so a question no other client answers is denied;
326
- choose the permission mode and rules the server runs under.
335
+ A client that submits with `receivePrompts: true` answers the permission and ask prompts its turn
336
+ raises; without it, a question no other client answers is denied, so choose the permission mode and
337
+ rules the server runs under.
327
338
 
328
339
  ### Reach other sessions and your other devices
329
340
 
package/dist/node/bin.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  ;(function(){var v=parseInt(process.versions.node.split('.')[0],10);if(v<22){process.stderr.write('\n✗ Node.js 22+ is required (current: '+process.version+')\n\nUpgrade:\n nvm: nvm install 22 && nvm use 22\n Volta: volta install node@22\n Download: https://nodejs.org/en/download\n\n');process.exit(1);}})();
3
- import{Bt as e,J as t,Pt as n,dt as r,f as i,ht as a,n as o,xt as s}from"./node-BUERQysz.js";import{A as c,C as l,D as u,E as d,I as f,L as p,M as m,N as h,O as g,S as _,T as ee,_ as te,b as v,d as ne,f as y,g as re,h as ie,j as ae,k as oe,l as se,m as ce,o as le,p as b,s as ue,t as x,u as de,v as fe,w as S,x as C,y as pe}from"./cli-core-CEWWF4d6.js";import{watch as me}from"node:fs";import{basename as he,dirname as ge,join as _e}from"node:path";import{mkdir as ve,readFile as ye,writeFile as w}from"node:fs/promises";import{Readable as be}from"node:stream";import T,{Chalk as xe,backgroundColorNames as Se,foregroundColorNames as Ce}from"chalk";import{Box as E,Static as D,Text as we,render as O,useApp as Te,useBoxMetrics as Ee,useCursor as k,useInput as De,usePaste as Oe,useStdout as ke,useWindowSize as A}from"ink";import j,{createContext as M,useCallback as N,useContext as P,useEffect as F,useLayoutEffect as Ae,useMemo as I,useRef as L,useState as R}from"react";import{Fragment as z,jsx as B,jsxs as V}from"react/jsx-runtime";import je from"string-width";import{marked as Me}from"marked";import Ne from"marked-terminal";const Pe=e=>typeof e==`string`,Fe=e=>t=>t===void 0||e(t),Ie={user:!0,"agent-wakeup":!0,peer:!0,external:!0},H={driverId:Fe(Pe)};({...H}),{...H},{...H},{...H},{...H},{...H},{...H},{...H},{...H},Object.keys(Ie);const Le=new Set([`get-messages`,`get-history`,`get-context`,`get-status`,`get-commands`,`list-models`,`get-executing`,`get-pending`,`get-execution-workspace`,`read-execution-detail`,`get-agent-definitions`,`get-usage-report`,`list-sessions`,`get-background-tasks`,`get-background-task`,`get-background-job-groups`,`get-background-job-group`,`wait-background-job-group`,`read-background-task-log`,`get-settings`,`project-status`,`project-diff`,`project-memory`]);function U(e){return Le.has(e)}const Re=new Set([` `,`
3
+ import{Bt as e,J as t,Pt as n,dt as r,f as i,ht as a,n as o,xt as s}from"./node-BUERQysz.js";import{A as c,C as l,D as u,E as d,I as f,L as p,M as m,N as h,O as g,S as _,T as ee,_ as te,b as v,d as ne,f as y,g as re,h as ie,j as ae,k as oe,l as se,m as ce,o as le,p as b,s as ue,t as x,u as de,v as fe,w as S,x as C,y as pe}from"./cli-core-YR-wNxJu.js";import{watch as me}from"node:fs";import{basename as he,dirname as ge,join as _e}from"node:path";import{mkdir as ve,readFile as ye,writeFile as w}from"node:fs/promises";import{Readable as be}from"node:stream";import T,{Chalk as xe,backgroundColorNames as Se,foregroundColorNames as Ce}from"chalk";import{Box as E,Static as D,Text as we,render as O,useApp as Te,useBoxMetrics as Ee,useCursor as k,useInput as De,usePaste as Oe,useStdout as ke,useWindowSize as A}from"ink";import j,{createContext as M,useCallback as N,useContext as P,useEffect as F,useLayoutEffect as Ae,useMemo as I,useRef as L,useState as R}from"react";import{Fragment as z,jsx as B,jsxs as V}from"react/jsx-runtime";import je from"string-width";import{marked as Me}from"marked";import Ne from"marked-terminal";const Pe=e=>typeof e==`string`,Fe=e=>t=>t===void 0||e(t),Ie={user:!0,"agent-wakeup":!0,peer:!0,external:!0},H={driverId:Fe(Pe)};({...H}),{...H},{...H},{...H},{...H},{...H},{...H},{...H},{...H},Object.keys(Ie);const Le=new Set([`get-messages`,`get-history`,`get-context`,`get-status`,`get-commands`,`list-models`,`get-executing`,`get-pending`,`get-execution-workspace`,`read-execution-detail`,`get-agent-definitions`,`get-usage-report`,`list-sessions`,`get-background-tasks`,`get-background-task`,`get-background-job-groups`,`get-background-job-group`,`wait-background-job-group`,`read-background-task-log`,`get-settings`,`project-status`,`project-diff`,`project-memory`]);function U(e){return Le.has(e)}const Re=new Set([` `,`
4
4
  `]),ze=/\r\n/g,Be=/\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)?|\x9d[^\x07\x1b\x9c]*(?:\x07|\x9c|\x1b\\)?|\x1b[P^_X][\s\S]*?(?:\x1b\\|\x07)|\x1b[P^_X][\s\S]*$|[\x90\x98\x9e\x9f][\s\S]*?(?:\x9c|\x1b\\|\x07)|[\x90\x98\x9e\x9f][\s\S]*$|\x1b\[[0-?]*[ -/]*[@-~]|\x9b[0-?]*[ -/]*[@-~]|\x1b[@-Z\\-_]|[\x00-\x1f\x7f]|[\x80-\x9f]/g;function W(e){return e.replace(ze,`
5
5
  `).replace(Be,e=>Re.has(e)?e:``)}function Ve(e){return typeof e==`string`?W(e):typeof e==`number`||typeof e==`boolean`||e==null?e:Array.isArray(e)?e.map(e=>Ve(e)):e}function G(e){let{children:t,...n}=e;return B(we,{...n,children:Ve(t)})}function He(e){return B(we,{...e})}const Ue={id:`dark`,name:`Dark`,appearance:`dark`,source:`built-in`,colors:{text:{accent:`cyan`,emphasis:`white`,success:`green`,warning:`yellow`,error:`red`,session:`magenta`,muted:`gray`,onAccent:`black`},border:{attention:`yellow`,focused:`cyan`,active:`green`,muted:`gray`,error:`red`},status:{running:`yellow`,success:`green`,error:`red`,denied:`yellowBright`,waiting:`yellow`,cancelled:`yellow`,idle:`gray`}},markdown:{heading:`green`,firstHeading:`magenta`,code:`yellow`,codespan:`yellow`,link:`blue`,href:`blue`,blockquote:`gray`,del:`gray`,html:`gray`,diffAdded:`ansi256(120)`,diffRemoved:`ansi256(210)`,diffAddedBackground:`ansi256(22)`,diffRemovedBackground:`ansi256(52)`,diffHunk:`cyan`},syntax:{keyword:`blue`,built_in:`cyan`,type:`cyan`,literal:`blue`,number:`green`,regexp:`red`,string:`red`,class:`blue`,function:`yellow`,comment:`green`,doctag:`green`,meta:`gray`,tag:`gray`,name:`blue`,attr:`cyan`,addition:`green`,deletion:`red`},motion:{wave:[`#555555`,`#777777`,`#999999`,`#bbbbbb`]}},We=[Ue,{id:`light`,name:`Light`,appearance:`light`,source:`built-in`,colors:{text:{accent:`ansi256(24)`,emphasis:`black`,success:`ansi256(28)`,warning:`ansi256(130)`,error:`ansi256(124)`,session:`ansi256(90)`,muted:`ansi256(243)`,onAccent:`white`},border:{attention:`ansi256(130)`,focused:`ansi256(24)`,active:`ansi256(28)`,muted:`ansi256(249)`,error:`ansi256(124)`},status:{running:`ansi256(130)`,success:`ansi256(28)`,error:`ansi256(124)`,denied:`ansi256(166)`,waiting:`ansi256(130)`,cancelled:`ansi256(130)`,idle:`ansi256(243)`}},markdown:{heading:`ansi256(28)`,firstHeading:`ansi256(90)`,code:`ansi256(94)`,codespan:`ansi256(94)`,link:`ansi256(26)`,href:`ansi256(26)`,blockquote:`ansi256(243)`,del:`ansi256(243)`,html:`ansi256(243)`,diffAdded:`ansi256(22)`,diffRemoved:`ansi256(52)`,diffAddedBackground:`ansi256(194)`,diffRemovedBackground:`ansi256(224)`,diffHunk:`ansi256(24)`},syntax:{keyword:`ansi256(26)`,built_in:`ansi256(24)`,type:`ansi256(24)`,literal:`ansi256(26)`,number:`ansi256(28)`,regexp:`ansi256(124)`,string:`ansi256(124)`,class:`ansi256(26)`,function:`ansi256(94)`,comment:`ansi256(28)`,doctag:`ansi256(28)`,meta:`ansi256(243)`,tag:`ansi256(243)`,name:`ansi256(26)`,attr:`ansi256(24)`,addition:`ansi256(22)`,deletion:`ansi256(52)`},motion:{wave:[`#bbbbbb`,`#999999`,`#777777`,`#555555`]}},{id:`dark-daltonized`,name:`Dark (daltonized)`,appearance:`dark`,source:`built-in`,colors:{text:{accent:`#56b4e9`,emphasis:`#ffffff`,success:`#56b4e9`,warning:`#e69f00`,error:`#d55e00`,session:`#cc79a7`,muted:`#999999`,onAccent:`#000000`},border:{attention:`#e69f00`,focused:`#56b4e9`,active:`#56b4e9`,muted:`#999999`,error:`#d55e00`},status:{running:`#e69f00`,success:`#56b4e9`,error:`#d55e00`,denied:`#f0e442`,waiting:`#e69f00`,cancelled:`#cc79a7`,idle:`#999999`}},markdown:{heading:`#56b4e9`,firstHeading:`#cc79a7`,code:`#e69f00`,codespan:`#e69f00`,link:`#56b4e9`,href:`#56b4e9`,blockquote:`#999999`,del:`#999999`,html:`#999999`,diffAdded:`#8ecdf5`,diffRemoved:`#ffb066`,diffAddedBackground:`#00335c`,diffRemovedBackground:`#5c3000`,diffHunk:`#56b4e9`},syntax:{keyword:`#56b4e9`,built_in:`#8ecdf5`,type:`#8ecdf5`,literal:`#56b4e9`,number:`#e69f00`,regexp:`#d55e00`,string:`#d55e00`,class:`#56b4e9`,function:`#f0e442`,comment:`#999999`,doctag:`#999999`,meta:`#999999`,tag:`#999999`,name:`#56b4e9`,attr:`#8ecdf5`,addition:`#8ecdf5`,deletion:`#ffb066`},motion:{wave:[`#3d3d3d`,`#5c5c5c`,`#7a7a7a`,`#999999`]}},{id:`light-daltonized`,name:`Light (daltonized)`,appearance:`light`,source:`built-in`,colors:{text:{accent:`#0072b2`,emphasis:`#000000`,success:`#0072b2`,warning:`#b35900`,error:`#8c3d00`,session:`#a8477f`,muted:`#5c5c5c`,onAccent:`#ffffff`},border:{attention:`#b35900`,focused:`#0072b2`,active:`#0072b2`,muted:`#a3a3a3`,error:`#8c3d00`},status:{running:`#b35900`,success:`#0072b2`,error:`#8c3d00`,denied:`#8a7500`,waiting:`#b35900`,cancelled:`#a8477f`,idle:`#5c5c5c`}},markdown:{heading:`#0072b2`,firstHeading:`#a8477f`,code:`#8a5a00`,codespan:`#8a5a00`,link:`#0072b2`,href:`#0072b2`,blockquote:`#5c5c5c`,del:`#5c5c5c`,html:`#5c5c5c`,diffAdded:`#004c77`,diffRemoved:`#7a3300`,diffAddedBackground:`#d6ecf9`,diffRemovedBackground:`#fbe5cd`,diffHunk:`#0072b2`},syntax:{keyword:`#0072b2`,built_in:`#004c77`,type:`#004c77`,literal:`#0072b2`,number:`#b35900`,regexp:`#8c3d00`,string:`#8c3d00`,class:`#0072b2`,function:`#8a7500`,comment:`#5c5c5c`,doctag:`#5c5c5c`,meta:`#5c5c5c`,tag:`#5c5c5c`,name:`#0072b2`,attr:`#004c77`,addition:`#004c77`,deletion:`#7a3300`},motion:{wave:[`#c7c7c7`,`#a3a3a3`,`#7a7a7a`,`#5c5c5c`]}}],Ge=Ue.id;function Ke(){return We}function qe(e){return e??Ue}const Je=M(!1);function Ye({enabled:e,children:t}){return B(Je.Provider,{value:e,children:t})}function K(){return P(Je)}function Xe(){if(`NO_COLOR`in process.env)return!1;let e=process.env.FORCE_COLOR;return e===`0`?!1:e!==void 0&&e!==``||!!process.stdout.isTTY}function Ze(e={}){return e.override===!0?!0:e.override===!1||process.env.TERM_PROGRAM===`Apple_Terminal`?!1:!!process.stdout.isTTY}function Qe(e={}){return e.override===!0?!0:e.override===!1||process.env.TERM_PROGRAM===`WezTerm`?!1:!!process.stdout.isTTY}function $e(e={}){return e.override===!0||e.override!==!1&&!!process.stdin.isTTY&&!!process.stdout.isTTY}const et=M(Ue),tt=M(!1),nt=M(!0);function rt({theme:e,reducedMotion:t=!1,syntaxHighlighting:n=!0,children:r}){return B(et.Provider,{value:qe(e),children:B(tt.Provider,{value:t,children:B(nt.Provider,{value:n,children:r})})})}function it(){return P(et)}function q(){return it().colors}function at(){return it().motion}function ot(){let e=K(),t=P(tt);return Xe()&&!e&&!t}function st(){return P(nt)}const ct=[`keyword`,`built_in`,`type`,`literal`,`number`,`regexp`,`string`,`class`,`function`,`comment`,`doctag`,`meta`,`tag`,`name`,`attr`,`addition`,`deletion`],lt=/^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/iu,ut=/^ansi256\((\d{1,3})\)$/iu,dt=/^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/iu,ft=`<chalk name> | #rgb | #rrggbb | ansi256(n) | rgb(r,g,b)`,pt=new Map([...Ce,...Se].map(e=>[e,T[e]])),mt=new Set(Ce);function ht(e){return mt.has(e)}function gt(e){if(lt.test(e))return!0;let t=ut.exec(e);if(t)return Number(t[1])<=255;let n=dt.exec(e);return n?n.slice(1).every(e=>Number(e)<=255):ht(e)}function _t(e){throw Error(`Theme colour ${JSON.stringify(e)} is not in Ink's colour grammar (${ft}).`)}function J(e,t=T){if(lt.test(e))return t.hex(e);let n=ut.exec(e);if(n)return t.ansi256(Number(n[1]));let r=dt.exec(e);if(r)return t.rgb(Number(r[1]),Number(r[2]),Number(r[3]));let i=ht(e)?pt.get(e):void 0;return i===void 0&&_t(e),Reflect.get(t,e)??i}function vt(e,t=T){if(lt.test(e))return t.bgHex(e);let n=ut.exec(e);if(n)return t.bgAnsi256(Number(n[1]));let r=dt.exec(e);if(r)return t.bgRgb(Number(r[1]),Number(r[2]),Number(r[3]));let i=`bg${e.charAt(0).toUpperCase()}${e.slice(1)}`;return Reflect.get(t,i)??_t(e)}const yt=new xe({level:3});function bt(){return T.level===0?yt:T}function xt(e){return{heading:J(e.heading).bold,firstHeading:J(e.firstHeading).underline.bold,code:J(e.code),codespan:J(e.codespan),link:J(e.link),href:J(e.href).underline,blockquote:J(e.blockquote).italic,del:J(e.del,T.dim).strikethrough,html:J(e.html)}}function St(e){let t={};for(let n of ct)t[n]=n===`type`?J(e[n]).dim:J(e[n]);return t}function Ct(e){let{markdown:t}=e,n=bt(),r=vt(t.diffAddedBackground,n),i=J(t.diffAdded,n),a=vt(t.diffRemovedBackground,n),o=J(t.diffRemoved,n);return{added:e=>r(i(e)),removed:e=>a(o(e)),hunk:J(t.diffHunk,n),meta:e=>n.dim(e)}}function wt(e){return e.split(/\s+/u).map(Number)}wt(`0 95 135 175 215 255`),wt(`0.1121 0.8853 -0.0005`),wt(`0.1127 0.8897 -0.0001`),wt(`0.0045 0.0 1.0019`),wt(`0.292 0.7054 -0.0003`),wt(`0.2934 0.7089 0.0`),wt(`-0.0209 0.4614 0.5677`),wt(`0.4124 0.3576 0.1805`),wt(`0.2126 0.7152 0.0722`),wt(`0.0193 0.1192 0.9505`),wt(`0.95047 1 1.08883`);function Tt(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}const Et=new Set([`name`,`base`,`overrides`]),Dt=/[\u0000-\u001F\u007F-\u009F]/u,Ot=new RegExp(Dt.source,`gu`);function kt(e){return JSON.stringify(e).replace(Ot,e=>`\\u${(e.codePointAt(0)??0).toString(16).padStart(4,`0`)}`)}function At(e){return kt(e).slice(1,-1)}function jt(e){return W(e).replaceAll(`
6
6
  `,` `).replaceAll(` `,` `).trim()}function Mt(e){return Dt.test(e)?kt(e):e}function Nt(e){return{ok:!1,error:e}}function Pt(e,t){return typeof e==`string`?gt(e)?{ok:!0,value:e}:{ok:!1,error:`${t}: ${kt(e)} is not a colour in Ink's grammar (${ft})`}:{ok:!1,error:`${t}: expected a colour string`}}function Ft(e,t,n){if(!Array.isArray(t)||t.length!==e.length)return{ok:!1,error:`${n}: expected exactly ${e.length} colours`};let r=[];for(let[i,a]of e.entries()){let e=Lt(a,t[i]??null,`${n}[${i}]`);if(!e.ok)return e;r.push(e.value)}return{ok:!0,value:r}}function It(e,t,n){if(!Tt(t))return{ok:!1,error:`${n}: expected an object of tokens`};let r={...e};for(let i of Object.keys(t)){if(!Object.prototype.hasOwnProperty.call(e,i))return{ok:!1,error:`${n}.${Mt(i)} is not a theme token`};let a=Lt(e[i]??null,t[i]??null,`${n}.${Mt(i)}`);if(!a.ok)return a;r[i]=a.value}return{ok:!0,value:r}}function Lt(e,t,n){return typeof e==`string`?Pt(t,n):Array.isArray(e)?Ft(e,t,n):Tt(e)?It(e,t,n):{ok:!1,error:`${n} is not a theme token`}}function Rt(e){return JSON.parse(JSON.stringify(e))}function zt(e){return JSON.parse(JSON.stringify({colors:e.colors,markdown:e.markdown,syntax:e.syntax,motion:e.motion}))}function Bt(e){let t;try{t=JSON.parse(e)}catch(e){return{ok:!1,error:`$: ${e instanceof Error?jt(e.message):`invalid JSON`}`}}if(!Tt(t))return{ok:!1,error:`$: expected an object`};for(let e of Object.keys(t))if(!Et.has(e))return{ok:!1,error:`$.${Mt(e)} is not a theme token`};return{ok:!0,value:t}}function Vt(e,t){let n=e.name;return n===void 0?Dt.test(t)?{ok:!1,error:`$.name: the minted id must not contain control characters`}:t.length>60?{ok:!1,error:`$.name: the minted id must be at most 60 characters`}:{ok:!0,value:t}:typeof n!=`string`||n.trim().length===0?{ok:!1,error:`$.name: expected a non-empty string`}:Dt.test(n)?{ok:!1,error:`$.name: must not contain control characters`}:n.length>60?{ok:!1,error:`$.name: must be at most 60 characters`}:{ok:!0,value:n}}function Ht(e){let t=e.base===void 0?Ge:e.base;if(typeof t!=`string`)return{ok:!1,error:`$.base: expected a built-in theme id`};let n=We.find(e=>e.id===t);return n?{ok:!0,theme:n}:{ok:!1,error:`$.base: ${kt(t)} is not a built-in theme`}}function Ut(e){let t=Bt(e.text);if(!t.ok)return Nt(t.error);let n=t.value,r=Ht(n);if(!r.ok)return Nt(r.error);let i=Vt(n,e.id);if(!i.ok)return Nt(i.error);let a=n.overrides===void 0?{}:n.overrides,o=Lt(zt(r.theme),a,`$.overrides`);if(!o.ok)return Nt(o.error);let{colors:s,markdown:c,syntax:l,motion:u}=Rt(o.value);return{ok:!0,theme:{id:e.id,name:i.value,appearance:r.theme.appearance,source:e.source,colors:s,markdown:c,syntax:l,motion:u}}}function Wt({version:e}){return V(E,{flexDirection:`column`,paddingX:1,marginBottom:1,children:[B(G,{color:q().text.accent,bold:!0,children:`