@ai-ecoverse/slicc-agent 3.52.1 → 4.1.0

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 (94) hide show
  1. package/README.md +17 -13
  2. package/dist/client.js +3 -1
  3. package/dist/client.js.map +2 -2
  4. package/dist/control.js +4 -1
  5. package/dist/control.js.map +2 -2
  6. package/dist/freezer/index.js +27 -68
  7. package/dist/freezer/index.js.map +2 -2
  8. package/dist/host.js +2 -0
  9. package/dist/host.js.map +2 -2
  10. package/dist/index.js +0 -3
  11. package/dist/index.js.map +2 -2
  12. package/dist/kernel/agent-users.js +3 -0
  13. package/dist/kernel/agent-users.js.map +2 -2
  14. package/dist/main.js +111 -26
  15. package/dist/main.js.map +2 -2
  16. package/dist/mcp/accounts.js +18 -14
  17. package/dist/mcp/accounts.js.map +2 -2
  18. package/dist/mcp/connection.js +0 -2
  19. package/dist/mcp/connection.js.map +2 -2
  20. package/dist/mcp/credentials.js +6 -15
  21. package/dist/mcp/credentials.js.map +2 -2
  22. package/dist/mcp/index.js +0 -1
  23. package/dist/mcp/index.js.map +2 -2
  24. package/dist/mcp/oauth.js +15 -20
  25. package/dist/mcp/oauth.js.map +2 -2
  26. package/dist/mcp/runtime.js +36 -14
  27. package/dist/mcp/runtime.js.map +2 -2
  28. package/dist/mcp/tools.js +4 -6
  29. package/dist/mcp/tools.js.map +2 -2
  30. package/dist/models/index.js +7 -4
  31. package/dist/models/index.js.map +2 -2
  32. package/dist/monitor/index.js +5 -10
  33. package/dist/monitor/index.js.map +2 -2
  34. package/dist/monitor/redact.js +4 -5
  35. package/dist/monitor/redact.js.map +2 -2
  36. package/dist/secrets/credentials.js +32 -0
  37. package/dist/secrets/credentials.js.map +7 -0
  38. package/dist/secrets/endpoints.js +111 -0
  39. package/dist/secrets/endpoints.js.map +7 -0
  40. package/dist/secrets/extension.js +6 -3
  41. package/dist/secrets/extension.js.map +2 -2
  42. package/dist/secrets/fetch.js +160 -0
  43. package/dist/secrets/fetch.js.map +7 -0
  44. package/dist/secrets/records.js +35 -0
  45. package/dist/secrets/records.js.map +7 -0
  46. package/dist/secrets/store.js +50 -0
  47. package/dist/secrets/store.js.map +7 -0
  48. package/dist/secrets/vault.js +58 -13
  49. package/dist/secrets/vault.js.map +2 -2
  50. package/dist/services.js.map +2 -2
  51. package/dist/settings.js +85 -23
  52. package/dist/settings.js.map +2 -2
  53. package/dist/skills/index.js +20 -3
  54. package/dist/skills/index.js.map +3 -3
  55. package/dist/spectrum/agent-port.js +29 -1
  56. package/dist/spectrum/agent-port.js.map +2 -2
  57. package/dist/spectrum/settings-port.js +24 -6
  58. package/dist/spectrum/settings-port.js.map +2 -2
  59. package/dist/titles/extension.js +110 -0
  60. package/dist/titles/extension.js.map +7 -0
  61. package/dist/{freezer/title.js → titles/generate.js} +21 -2
  62. package/dist/titles/generate.js.map +7 -0
  63. package/dist/types/client.d.ts +2 -1
  64. package/dist/types/control.d.ts +1 -1
  65. package/dist/types/freezer/index.d.ts +2 -5
  66. package/dist/types/host.d.ts +1 -1
  67. package/dist/types/index.d.ts +0 -1
  68. package/dist/types/main.d.ts +7 -2
  69. package/dist/types/mcp/accounts.d.ts +10 -4
  70. package/dist/types/mcp/connection.d.ts +0 -2
  71. package/dist/types/mcp/credentials.d.ts +6 -4
  72. package/dist/types/mcp/oauth.d.ts +3 -2
  73. package/dist/types/mcp/runtime.d.ts +18 -4
  74. package/dist/types/models/index.d.ts +2 -0
  75. package/dist/types/monitor/index.d.ts +0 -1
  76. package/dist/types/monitor/redact.d.ts +2 -2
  77. package/dist/types/secrets/credentials.d.ts +5 -0
  78. package/dist/types/secrets/endpoints.d.ts +27 -0
  79. package/dist/types/secrets/fetch.d.ts +13 -0
  80. package/dist/types/secrets/records.d.ts +13 -0
  81. package/dist/types/secrets/store.d.ts +7 -0
  82. package/dist/types/secrets/vault.d.ts +31 -1
  83. package/dist/types/services.d.ts +13 -1
  84. package/dist/types/settings.d.ts +17 -2
  85. package/dist/types/skills/index.d.ts +4 -1
  86. package/dist/types/spectrum/agent-port.d.ts +1 -1
  87. package/dist/types/spectrum/settings-port.d.ts +6 -4
  88. package/dist/types/titles/extension.d.ts +19 -0
  89. package/dist/types/{freezer/title.d.ts → titles/generate.d.ts} +4 -0
  90. package/package.json +6 -4
  91. package/dist/credentials.js +0 -100
  92. package/dist/credentials.js.map +0 -7
  93. package/dist/freezer/title.js.map +0 -7
  94. package/dist/types/credentials.d.ts +0 -12
package/dist/main.js CHANGED
@@ -14,9 +14,7 @@ import {
14
14
  locateWasm,
15
15
  sandboxFactory
16
16
  } from "./codemode/index.js";
17
- import { EncryptedCredentialStore } from "./credentials.js";
18
17
  import { attachFreezer } from "./freezer/index.js";
19
- import { settingsText, titler } from "./freezer/title.js";
20
18
  import { lateGelatiere } from "./gelatiere/index.js";
21
19
  import { hostAgent } from "./host.js";
22
20
  import { imageReads } from "./images/index.js";
@@ -36,14 +34,25 @@ import { sliccPrompt } from "./prompt.js";
36
34
  import { createPages } from "./remote/pages.js";
37
35
  import { identity } from "./scoops/identity.js";
38
36
  import { packageAssets, setupScoops } from "./scoops/index.js";
37
+ import { vaultCredentials } from "./secrets/credentials.js";
38
+ import {
39
+ BEDROCK_ENDPOINTS,
40
+ modelRoute,
41
+ vaultEndpoints
42
+ } from "./secrets/endpoints.js";
39
43
  import { repin, secretsExtension, shellGrants } from "./secrets/extension.js";
44
+ import { grantFetch, mcpFetch, vaultFetch } from "./secrets/fetch.js";
40
45
  import { secretNames } from "./secrets/names.js";
46
+ import { vaultRecords } from "./secrets/records.js";
41
47
  import { scrubWith } from "./secrets/scrub.js";
48
+ import { fileStore } from "./secrets/store.js";
42
49
  import { listenVault, Vault } from "./secrets/vault.js";
43
50
  import {
51
+ BEDROCK,
44
52
  createAgentSettings,
45
53
  createSliccModels,
46
54
  DEFAULT_MODEL,
55
+ providerFields,
47
56
  sliccProviders
48
57
  } from "./settings.js";
49
58
  import { RELOAD_MS, setupSkills } from "./skills/index.js";
@@ -56,6 +65,8 @@ import {
56
65
  kernelBoot,
57
66
  transportName
58
67
  } from "./system.js";
68
+ import { titlesExtension } from "./titles/extension.js";
69
+ import { settingsText, titler } from "./titles/generate.js";
59
70
  import { kernelPorts, serveConnections } from "./worker.js";
60
71
  function usersOf(admin, wanted, attach) {
61
72
  if (!admin) return void 0;
@@ -66,6 +77,7 @@ function usersOf(admin, wanted, attach) {
66
77
  return userClients(adminOver(admin), attach);
67
78
  }
68
79
  const STORE_DIR = "/.slicc";
80
+ const ACCOUNTS_FILE = `${STORE_DIR}/accounts.json`;
69
81
  async function attached(ports, options) {
70
82
  const attach = options.attach ?? attachKernel;
71
83
  const { kernel, admin } = await ports;
@@ -110,10 +122,59 @@ async function secretsFor(home, vault) {
110
122
  await names.refresh(BACKGROUND_CONTEXT);
111
123
  return names;
112
124
  }
113
- async function modelsOf(options, version) {
114
- const credentials = await (options.credentials ?? (() => EncryptedCredentialStore.open()))();
125
+ function modelBases(providers, models) {
126
+ return providers.map((provider) => ({
127
+ provider: provider.id,
128
+ urls: [
129
+ ...new Set(
130
+ [
131
+ provider.baseUrl,
132
+ ...models.getModels(provider.id).map((model) => model.baseUrl),
133
+ ...provider.id === BEDROCK ? BEDROCK_ENDPOINTS : []
134
+ ].filter((url) => typeof url === "string" && url !== "")
135
+ )
136
+ ]
137
+ }));
138
+ }
139
+ function mcpVault(vault, made) {
140
+ const { store, records, endpoints } = made;
141
+ return {
142
+ store,
143
+ vault: {
144
+ records,
145
+ fetch: (server, base) => mcpFetch(vault, base, server),
146
+ grant: (server, base) => grantFetch(vault, server, base),
147
+ servers: endpoints.servers,
148
+ token: endpoints.token
149
+ }
150
+ };
151
+ }
152
+ function hostSecrets(vault, names, parts) {
153
+ return {
154
+ vault: vault.state,
155
+ list: () => names.state.value,
156
+ close: () => {
157
+ for (const part of parts) part.close();
158
+ }
159
+ };
160
+ }
161
+ async function modelsOf(scope, options, given) {
162
+ const { vault, home, transport, version } = given;
163
+ const store = await (options.store ?? (async () => fileStore(home, ACCOUNTS_FILE)))();
164
+ const records = vaultRecords(vault);
165
+ void records.refresh(BACKGROUND_CONTEXT).catch(() => void 0);
115
166
  const providers = options.providers ?? sliccProviders(version);
116
- return { credentials, providers, models: createSliccModels(credentials, providers) };
167
+ const fields = await providerFields(store, providers);
168
+ const models = createSliccModels(vaultCredentials(records, fields.env), providers);
169
+ const bases = () => modelBases(providers, models);
170
+ scope.fetch = vaultFetch(
171
+ vault,
172
+ transport,
173
+ modelRoute(bases, () => records.state.value)
174
+ );
175
+ const endpoints = vaultEndpoints(vault);
176
+ void endpoints.models(bases()).catch(() => void 0);
177
+ return { store, records, providers, fields, models, bases, endpoints };
117
178
  }
118
179
  function baseRegistry(facts) {
119
180
  const registry = createRegistry();
@@ -136,25 +197,47 @@ async function factsOf(client, native) {
136
197
  function routeFetch(scope, client) {
137
198
  const native = scope.fetch.bind(scope);
138
199
  const loopback = client.loopbackFetch?.bind(client);
139
- scope.fetch = transportFetch(client.transport, scope.location.origin, native, loopback);
140
- return native;
200
+ const transport = transportFetch(client.transport, scope.location.origin, native, loopback);
201
+ scope.fetch = transport;
202
+ return { native, transport };
141
203
  }
142
204
  async function prepare(scope, kernel, options) {
143
205
  const names = await secretsFor(kernel.home, kernel.vault);
144
- const native = routeFetch(scope, kernel.client);
206
+ const { native, transport } = routeFetch(scope, kernel.client);
145
207
  const facts = await factsOf(kernel.client, native);
146
- return {
147
- names,
148
- native,
149
- facts,
150
- ...await modelsOf(options, facts.version),
151
- registry: baseRegistry(facts)
152
- };
208
+ const made = await modelsOf(scope, options, {
209
+ vault: kernel.vault,
210
+ home: kernel.home,
211
+ transport,
212
+ version: facts.version
213
+ });
214
+ return { names, native, transport, facts, ...made, registry: baseRegistry(facts) };
215
+ }
216
+ function modelsOfAgent(agent, settings, catalog, vault) {
217
+ const locked = () => vault.state.value.locked !== "no";
218
+ return modelsCommand({ agents: agent.agents, settings, catalog, locked });
219
+ }
220
+ async function settingsOf(made, mcp) {
221
+ const { models, records, fields, providers, bases, endpoints } = made;
222
+ const settings = await createAgentSettings(models, { records, fields }, providers, { mcp });
223
+ settings.state.subscribe(() => void endpoints.models(bases()).catch(() => void 0));
224
+ return settings;
225
+ }
226
+ function setupTitles(registry, models, home, at, opened) {
227
+ const titleFn = titler(models, settingsText(home, HOME, at.agentDir));
228
+ const titles = titlesExtension({
229
+ agents: () => opened()?.agents,
230
+ harness: () => opened()?.harness,
231
+ title: () => titleFn
232
+ });
233
+ registry.install(titles.extension);
234
+ return { titleFn, cancel: titles.cancel };
153
235
  }
154
236
  async function start(scope, ports, options, vault) {
155
237
  const { client, users, home, at } = await attached(ports, options);
156
238
  const ready = await prepare(scope, { client, home, vault }, options);
157
- const { names, native, facts, credentials, providers, models, registry } = ready;
239
+ const { names, native, transport, facts, models, registry } = ready;
240
+ const { records, endpoints } = ready;
158
241
  const memory = setupMemory(registry);
159
242
  const coding = CodingTools.tools;
160
243
  registry.install(browserGuard([scope.location.origin], coding));
@@ -166,8 +249,8 @@ async function start(scope, ports, options, vault) {
166
249
  const scoops = setupScoops(registry, licks.licks, [...coding, ...codemode, ...memory.tools]);
167
250
  const skills = setupSkills(registry, licks.licks);
168
251
  registry.install(secretsExtension({ names, vault }));
169
- const activity = createActivity();
170
- const groups = processGroups(client);
252
+ const titles = setupTitles(registry, models, home, at, () => opened);
253
+ const [activity, groups] = [createActivity(), processGroups(client)];
171
254
  const model = options.model ?? DEFAULT_MODEL;
172
255
  let opened;
173
256
  const people = users ? agentUsers(users, client, home, () => opened?.agents) : void 0;
@@ -207,9 +290,9 @@ async function start(scope, ports, options, vault) {
207
290
  {
208
291
  env: home,
209
292
  ...at,
210
- credentials,
293
+ ...mcpVault(vault, ready),
211
294
  licks: licks.licks,
212
- fetch: scope.fetch,
295
+ fetch: transport,
213
296
  version: facts.version,
214
297
  reloadMs: RELOAD_MS,
215
298
  codemode: codemode.length > 0,
@@ -251,11 +334,12 @@ async function start(scope, ports, options, vault) {
251
334
  agents: agent.agents,
252
335
  env: home,
253
336
  extract: memory.extract,
254
- title: titler(models, settingsText(home, HOME, at.agentDir)),
337
+ title: titles.titleFn,
338
+ cancelTitle: titles.cancel,
255
339
  ...people ? { layout: people.layout } : {}
256
340
  });
257
341
  licks.licks.guard(freezer.frozenTarget);
258
- const settings = await createAgentSettings(models, credentials, providers, { mcp: mcpRuntime });
342
+ const settings = await settingsOf(ready, mcpRuntime);
259
343
  const pages = createPages({ claim: sprinkles.claim });
260
344
  const runtime = await scoops.attach(
261
345
  {
@@ -270,7 +354,7 @@ async function start(scope, ports, options, vault) {
270
354
  memory: memoryRuntime.command,
271
355
  gelatiere: gelatiere.command,
272
356
  freezer: freezer.command,
273
- models: modelsCommand({ agents: agent.agents, settings, catalog: models }),
357
+ models: modelsOfAgent(agent, settings, models, vault),
274
358
  panel: pages.command,
275
359
  mcp: mcp.direct,
276
360
  ...options.assets ? { assets: options.assets } : {}
@@ -305,7 +389,7 @@ async function start(scope, ports, options, vault) {
305
389
  pages,
306
390
  mcp: mcpRuntime,
307
391
  ...users ? { users } : {},
308
- secrets: { vault: vault.state, list: () => names.state.value, close: names.close },
392
+ secrets: hostSecrets(vault, names, [names, records, endpoints]),
309
393
  uploads: {
310
394
  env: environment,
311
395
  sees: (ref) => seesImages(models, ref)
@@ -313,8 +397,7 @@ async function start(scope, ports, options, vault) {
313
397
  monitor: {
314
398
  kernel: client,
315
399
  groups,
316
- ...users ? { users: () => users.users.list() } : {},
317
- secrets: () => mcpRuntime.secrets()
400
+ ...users ? { users: () => users.users.list() } : {}
318
401
  }
319
402
  });
320
403
  }
@@ -333,9 +416,11 @@ function runAgentWorker(scope, options = {}) {
333
416
  return host;
334
417
  }
335
418
  export {
419
+ ACCOUNTS_FILE,
336
420
  MCP_CALLBACK,
337
421
  STORE_DIR,
338
422
  alive,
423
+ modelBases,
339
424
  runAgentWorker,
340
425
  seesImages,
341
426
  usersOf
package/dist/main.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/main.ts"],
4
- "sourcesContent": ["import { attachKernel } from '@ai-ecoverse/slicc-kernel';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { CredentialStore, Provider } from '@earendil-works/pi-ai';\nimport type { Models } from '@earendil-works/pi-ai/models';\nimport {\n createRegistry,\n type ModelRef,\n type Storage,\n type ToolRegistration,\n} from '@earendil-works/pi-durable';\nimport { CodingTools } from '@earendil-works/pi-durable/tools';\nimport { type Agent, type AgentOptions, openAgent } from './agent.ts';\nimport { browserGuard } from './browser/guard.ts';\nimport { attachChanges, CHANGES_MS } from './changes/index.ts';\nimport {\n codemodeExtension,\n codemodeTool,\n disabledBySettings,\n locateWasm,\n sandboxFactory,\n} from './codemode/index.ts';\nimport { EncryptedCredentialStore } from './credentials.ts';\nimport { attachFreezer } from './freezer/index.ts';\nimport { settingsText, titler } from './freezer/title.ts';\nimport { lateGelatiere } from './gelatiere/index.ts';\nimport { type AgentHost, hostAgent } from './host.ts';\nimport { imageReads } from './images/index.ts';\nimport { createActivity } from './kernel/activity.ts';\nimport { agentUsers, warnSupport } from './kernel/agent-users.ts';\nimport type { KernelClient } from './kernel/client.ts';\nimport { HOME, kernelEnvironment, SliccKernelEnv } from './kernel/env.ts';\nimport { processGroups } from './kernel/groups.ts';\nimport { adminOver, type UserClient, type UserClients, userClients } from './kernel/users.ts';\nimport { AGENT_DIR, ROOT_HOME } from './layout.ts';\nimport { setupLicks } from './licks/index.ts';\nimport { lickTriage } from './licks/triage.ts';\nimport { setupMcp } from './mcp/index.ts';\nimport { setupMemory } from './memory/index.ts';\nimport { modelsCommand } from './models/index.ts';\nimport { pageOnly, type Transport, transportFetch } from './net.ts';\nimport { sliccPrompt } from './prompt.ts';\nimport { createPages } from './remote/pages.ts';\nimport { identity } from './scoops/identity.ts';\nimport { type Assets, packageAssets, type ScoopsRuntime, setupScoops } from './scoops/index.ts';\nimport { repin, secretsExtension, shellGrants } from './secrets/extension.ts';\nimport { secretNames } from './secrets/names.ts';\nimport { scrubWith } from './secrets/scrub.ts';\nimport { listenVault, Vault } from './secrets/vault.ts';\nimport {\n createAgentSettings,\n createSliccModels,\n DEFAULT_MODEL,\n sliccProviders,\n} from './settings.ts';\nimport { RELOAD_MS, setupSkills } from './skills/index.ts';\nimport { setupSprinkles } from './sprinkles/index.ts';\nimport { openOpfsSqliteStorage } from './sqlite.ts';\nimport {\n agentVersion,\n browserConnected,\n commandsOnPath,\n kernelBoot,\n transportName,\n} from './system.ts';\nimport { type KernelPorts, kernelPorts, serveConnections, type WorkerScope } from './worker.ts';\n\nexport interface AgentWorkerScope extends WorkerScope {\n fetch: typeof fetch;\n location: { origin: string };\n}\n\nexport type KernelAttach = (port: MessagePort) => Promise<KernelClient & { transport: Transport }>;\n\nexport interface AgentWorkerOptions {\n model?: ModelRef;\n providers?: Provider[];\n attach?: KernelAttach;\n credentials?: () => Promise<CredentialStore>;\n storage?: () => Promise<Storage>;\n assets?: Assets;\n codemodeWasm?: () => Promise<WebAssembly.Module | undefined>;\n codemodeWorker?: string | URL;\n catalog?: string;\n users?: boolean;\n mcpRedirect?: string;\n}\n\nexport function usersOf(\n admin: MessagePort | undefined,\n wanted: boolean | undefined,\n attach: KernelAttach\n): UserClients | undefined {\n if (!admin) return undefined;\n if (wanted === false) {\n admin.close();\n return undefined;\n }\n return userClients(adminOver(admin), attach as (port: MessagePort) => Promise<UserClient>);\n}\n\nexport const STORE_DIR = '/.slicc';\n\nasync function attached(ports: Promise<KernelPorts>, options: AgentWorkerOptions) {\n const attach: KernelAttach = options.attach ?? attachKernel;\n const { kernel, admin } = await ports;\n const client = await attach(kernel);\n const users = usersOf(admin, options.users, attach);\n await warnSupport(users, client, options.users);\n const home = new SliccKernelEnv(client, { cwd: HOME });\n await privateStore(home);\n return { client, users, home, at: { home: HOME, ...(users ? { agentDir: AGENT_DIR } : {}) } };\n}\n\nfunction privateStore(env: SliccKernelEnv): Promise<unknown> {\n return env.exec(`mkdir -p ${STORE_DIR} && chmod 700 ${STORE_DIR}`, undefined, BACKGROUND_CONTEXT);\n}\n\nasync function codemodeTools(\n client: KernelClient,\n options: AgentWorkerOptions,\n native: typeof fetch,\n extra: Parameters<typeof codemodeTool>[0]['extra'],\n dir = `${HOME}/.pi/agent`\n) {\n const settings = await client.fs.readFile(`${dir}/settings.json`).catch(() => undefined);\n if (disabledBySettings(settings === undefined ? undefined : new TextDecoder().decode(settings)))\n return [];\n const sandbox = sandboxFactory(\n options.codemodeWasm ?? (() => locateWasm(native, new URL(import.meta.url))),\n options.codemodeWorker\n );\n return [\n codemodeTool({ declared: CodingTools.tools as readonly ToolRegistration[], sandbox, extra }),\n ];\n}\n\nexport function seesImages(models: Pick<Models, 'getModel'>, ref: ModelRef | undefined): boolean {\n const found = ref && models.getModel(ref.provider, ref.modelId);\n return found ? found.input.includes('image') : true;\n}\n\nexport const MCP_CALLBACK = '/oauth/mcp-callback';\n\nasync function openRepinned(\n options: AgentWorkerOptions,\n base: Omit<AgentOptions, 'storage' | 'beforeResume'>\n): Promise<Agent> {\n const storage = await (options.storage ?? (() => openOpfsSqliteStorage()))();\n return openAgent({\n ...base,\n storage,\n beforeResume: (harness, using) => repin(harness, storage, using),\n });\n}\n\nasync function secretsFor(home: SliccKernelEnv, vault: Vault) {\n scrubWith(vault);\n const names = secretNames(home, vault);\n await names.refresh(BACKGROUND_CONTEXT);\n return names;\n}\n\nasync function modelsOf(options: AgentWorkerOptions, version: string) {\n const credentials = await (options.credentials ?? (() => EncryptedCredentialStore.open()))();\n const providers = options.providers ?? sliccProviders(version);\n return { credentials, providers, models: createSliccModels(credentials, providers) };\n}\n\nfunction baseRegistry(facts: Awaited<ReturnType<typeof factsOf>>) {\n const registry = createRegistry();\n registry.install(CodingTools);\n registry.install(sliccPrompt(facts));\n const read = (CodingTools.tools as readonly ToolRegistration[]).find(\n (tool) => tool.name === 'read'\n ) as ToolRegistration;\n registry.install(imageReads(read));\n return registry;\n}\n\nasync function factsOf(client: KernelClient & { transport: Transport }, native: typeof fetch) {\n return {\n version: await agentVersion((url) => native(url)),\n commands: await commandsOnPath(client),\n transport: transportName(client.transport),\n browser: await browserConnected(client),\n };\n}\n\nfunction routeFetch(scope: AgentWorkerScope, client: KernelClient & { transport: Transport }) {\n const native = scope.fetch.bind(scope);\n const loopback = client.loopbackFetch?.bind(client);\n scope.fetch = transportFetch(client.transport, scope.location.origin, native, loopback);\n return native;\n}\n\nasync function prepare(\n scope: AgentWorkerScope,\n kernel: { client: KernelClient & { transport: Transport }; home: SliccKernelEnv; vault: Vault },\n options: AgentWorkerOptions\n) {\n const names = await secretsFor(kernel.home, kernel.vault);\n const native = routeFetch(scope, kernel.client);\n const facts = await factsOf(kernel.client, native);\n return {\n names,\n native,\n facts,\n ...(await modelsOf(options, facts.version)),\n registry: baseRegistry(facts),\n };\n}\n\nasync function start(\n scope: AgentWorkerScope,\n ports: Promise<KernelPorts>,\n options: AgentWorkerOptions,\n vault: Vault\n): Promise<AgentHost> {\n const { client, users, home, at } = await attached(ports, options);\n const ready = await prepare(scope, { client, home, vault }, options);\n const { names, native, facts, credentials, providers, models, registry } = ready;\n const memory = setupMemory(registry);\n const coding = CodingTools.tools as readonly ToolRegistration[];\n registry.install(browserGuard([scope.location.origin], coding));\n const mcp = setupMcp(registry);\n const codemode = await codemodeTools(client, options, native, mcp.codemode, at.agentDir);\n registry.install(codemodeExtension(codemode));\n const licks = setupLicks(registry);\n licks.licks.triage(lickTriage(models));\n const scoops = setupScoops(registry, licks.licks, [...coding, ...codemode, ...memory.tools]);\n const skills = setupSkills(registry, licks.licks);\n registry.install(secretsExtension({ names, vault }));\n const activity = createActivity();\n const groups = processGroups(client);\n const model = options.model ?? DEFAULT_MODEL;\n let opened: Agent | undefined;\n const people = users ? agentUsers(users, client, home, () => opened?.agents) : undefined;\n const environment = kernelEnvironment(client, {\n activity,\n groups,\n identify: identity(() => opened?.agents, model),\n scrub: vault,\n spawn: shellGrants(names),\n ...(people ? { route: people.route } : {}),\n });\n const agent = await openRepinned(options, { models, model, registry, env: environment });\n opened = agent;\n await people?.start(agent.agents);\n const sources = licks.attach(agent, {\n env: home,\n home: HOME,\n activity,\n ...(people ? { dirs: () => people.lickDirs() } : {}),\n });\n await sources.start(BACKGROUND_CONTEXT);\n await sources.boot(\n { version: facts.version, boot: await kernelBoot(client) },\n BACKGROUND_CONTEXT\n );\n const skillsRuntime = await skills.attach(\n {\n env: home,\n ...at,\n assets: options.assets ?? packageAssets(),\n reloadMs: RELOAD_MS,\n ...(people ? { people: people.people } : {}),\n },\n BACKGROUND_CONTEXT\n );\n const mcpRuntime = await mcp.attach(\n {\n env: home,\n ...at,\n credentials,\n licks: licks.licks,\n fetch: scope.fetch,\n version: facts.version,\n reloadMs: RELOAD_MS,\n codemode: codemode.length > 0,\n cors: pageOnly(client.transport),\n redirect: options.mcpRedirect ?? new URL(MCP_CALLBACK, scope.location.origin).href,\n },\n BACKGROUND_CONTEXT\n );\n const gelatiere = lateGelatiere();\n const sprinkles = await setupSprinkles().attach(\n {\n intercept: gelatiere.intercept,\n harness: agent.harness,\n agents: agent.agents,\n licks: licks.licks,\n env: home,\n assets: options.assets ?? packageAssets(),\n reloadMs: RELOAD_MS,\n ...(people?.sprinkles() ?? {}),\n },\n BACKGROUND_CONTEXT\n );\n people?.follow([sources, skillsRuntime, sprinkles]);\n let roles: ScoopsRuntime | undefined;\n const memoryRuntime = await memory.attach(\n {\n harness: agent.harness,\n agents: agent.agents,\n env: home,\n ...at,\n ...(people ? { home: ROOT_HOME } : {}),\n reloadMs: RELOAD_MS,\n roles: async (using) => roles?.roles(using),\n },\n BACKGROUND_CONTEXT\n );\n const freezer = attachFreezer({\n harness: agent.harness,\n agents: agent.agents,\n env: home,\n extract: memory.extract,\n title: titler(models, settingsText(home, HOME, at.agentDir)),\n ...(people ? { layout: people.layout } : {}),\n });\n licks.licks.guard(freezer.frozenTarget);\n const settings = await createAgentSettings(models, credentials, providers, { mcp: mcpRuntime });\n const pages = createPages({ claim: sprinkles.claim });\n const runtime = await scoops.attach(\n {\n harness: agent.harness,\n agents: agent.agents,\n groups,\n env: home,\n ...at,\n ...(people\n ? { layout: people.layout, spools: people.spools, enforced: people.enforced }\n : {}),\n alive: alive(client),\n reads: skillsRuntime.dirs,\n memory: memoryRuntime.command,\n gelatiere: gelatiere.command,\n freezer: freezer.command,\n models: modelsCommand({ agents: agent.agents, settings, catalog: models }),\n panel: pages.command,\n mcp: mcp.direct,\n ...(options.assets ? { assets: options.assets } : {}),\n },\n BACKGROUND_CONTEXT\n );\n roles = runtime;\n gelatiere.attach({\n agents: agent.agents,\n licks: licks.licks,\n env: home,\n home: HOME,\n ...(await people?.gelatiere(home)),\n scoops: scoops.scoops,\n roles: runtime.roles,\n assets: options.assets ?? packageAssets(),\n fetch: scope.fetch,\n skills: skillsRuntime.skills,\n ...(options.catalog ? { catalog: options.catalog } : {}),\n });\n await memoryRuntime.reload(BACKGROUND_CONTEXT).catch(() => undefined);\n const changes = attachChanges({ agents: agent.agents, env: home, reloadMs: CHANGES_MS });\n return hostAgent(agent, {\n settings,\n licks: { licks: licks.licks, sources },\n scoops: { scoops: scoops.scoops, runtime },\n skills: skillsRuntime,\n sprinkles,\n memory: memoryRuntime,\n freezer,\n changes,\n pages,\n mcp: mcpRuntime,\n ...(users ? { users } : {}),\n secrets: { vault: vault.state, list: () => names.state.value, close: names.close },\n uploads: {\n env: environment,\n sees: (ref) => seesImages(models, ref),\n },\n monitor: {\n kernel: client,\n groups,\n ...(users ? { users: () => users.users.list() } : {}),\n secrets: () => mcpRuntime.secrets(),\n },\n });\n}\n\nexport function alive(client: KernelClient) {\n return async (pid: number): Promise<boolean> => {\n if (!client.ps) return true;\n return (await client.ps()).some((process) => process.pid === pid);\n };\n}\n\nexport function runAgentWorker(\n scope: AgentWorkerScope,\n options: AgentWorkerOptions = {}\n): Promise<AgentHost> {\n const vault = new Vault();\n listenVault(scope, vault);\n const host = start(scope, kernelPorts(scope), options, vault);\n host.catch(() => undefined);\n serveConnections(scope, host);\n return host;\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { attachKernel } from '@ai-ecoverse/slicc-kernel';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { Provider } from '@earendil-works/pi-ai';\nimport type { Models } from '@earendil-works/pi-ai/models';\nimport {\n createRegistry,\n type ModelRef,\n type Storage,\n type ToolRegistration,\n} from '@earendil-works/pi-durable';\nimport { CodingTools } from '@earendil-works/pi-durable/tools';\nimport { type Agent, type AgentOptions, openAgent } from './agent.ts';\nimport { browserGuard } from './browser/guard.ts';\nimport { attachChanges, CHANGES_MS } from './changes/index.ts';\nimport {\n codemodeExtension,\n codemodeTool,\n disabledBySettings,\n locateWasm,\n sandboxFactory,\n} from './codemode/index.ts';\nimport { attachFreezer } from './freezer/index.ts';\nimport { lateGelatiere } from './gelatiere/index.ts';\nimport { type AgentHost, hostAgent } from './host.ts';\nimport { imageReads } from './images/index.ts';\nimport { createActivity } from './kernel/activity.ts';\nimport { agentUsers, warnSupport } from './kernel/agent-users.ts';\nimport type { KernelClient } from './kernel/client.ts';\nimport { HOME, kernelEnvironment, SliccKernelEnv } from './kernel/env.ts';\nimport { processGroups } from './kernel/groups.ts';\nimport { adminOver, type UserClient, type UserClients, userClients } from './kernel/users.ts';\nimport { AGENT_DIR, ROOT_HOME } from './layout.ts';\nimport { setupLicks } from './licks/index.ts';\nimport { lickTriage } from './licks/triage.ts';\nimport { type McpAccounts, setupMcp } from './mcp/index.ts';\nimport { setupMemory } from './memory/index.ts';\nimport { modelsCommand } from './models/index.ts';\nimport { pageOnly, type Transport, transportFetch } from './net.ts';\nimport { sliccPrompt } from './prompt.ts';\nimport { createPages } from './remote/pages.ts';\nimport { identity } from './scoops/identity.ts';\nimport { type Assets, packageAssets, type ScoopsRuntime, setupScoops } from './scoops/index.ts';\nimport { vaultCredentials } from './secrets/credentials.ts';\nimport {\n BEDROCK_ENDPOINTS,\n type ModelBases,\n modelRoute,\n vaultEndpoints,\n} from './secrets/endpoints.ts';\nimport { repin, secretsExtension, shellGrants } from './secrets/extension.ts';\nimport { grantFetch, mcpFetch, vaultFetch } from './secrets/fetch.ts';\nimport { secretNames } from './secrets/names.ts';\nimport { type VaultRecords, vaultRecords } from './secrets/records.ts';\nimport { scrubWith } from './secrets/scrub.ts';\nimport { fileStore, type PlainStore } from './secrets/store.ts';\nimport { listenVault, Vault } from './secrets/vault.ts';\nimport {\n BEDROCK,\n createAgentSettings,\n createSliccModels,\n DEFAULT_MODEL,\n providerFields,\n sliccProviders,\n} from './settings.ts';\nimport { RELOAD_MS, setupSkills } from './skills/index.ts';\nimport { setupSprinkles } from './sprinkles/index.ts';\nimport { openOpfsSqliteStorage } from './sqlite.ts';\nimport {\n agentVersion,\n browserConnected,\n commandsOnPath,\n kernelBoot,\n transportName,\n} from './system.ts';\nimport { titlesExtension } from './titles/extension.ts';\nimport { settingsText, titler } from './titles/generate.ts';\nimport { type KernelPorts, kernelPorts, serveConnections, type WorkerScope } from './worker.ts';\n\nexport interface AgentWorkerScope extends WorkerScope {\n fetch: typeof fetch;\n location: { origin: string };\n}\n\nexport type KernelAttach = (port: MessagePort) => Promise<KernelClient & { transport: Transport }>;\n\nexport interface AgentWorkerOptions {\n model?: ModelRef;\n providers?: Provider[];\n attach?: KernelAttach;\n store?: () => Promise<PlainStore>;\n storage?: () => Promise<Storage>;\n assets?: Assets;\n codemodeWasm?: () => Promise<WebAssembly.Module | undefined>;\n codemodeWorker?: string | URL;\n catalog?: string;\n users?: boolean;\n mcpRedirect?: string;\n}\n\nexport function usersOf(\n admin: MessagePort | undefined,\n wanted: boolean | undefined,\n attach: KernelAttach\n): UserClients | undefined {\n if (!admin) return undefined;\n if (wanted === false) {\n admin.close();\n return undefined;\n }\n return userClients(adminOver(admin), attach as (port: MessagePort) => Promise<UserClient>);\n}\n\nexport const STORE_DIR = '/.slicc';\nexport const ACCOUNTS_FILE = `${STORE_DIR}/accounts.json`;\n\nasync function attached(ports: Promise<KernelPorts>, options: AgentWorkerOptions) {\n const attach: KernelAttach = options.attach ?? attachKernel;\n const { kernel, admin } = await ports;\n const client = await attach(kernel);\n const users = usersOf(admin, options.users, attach);\n await warnSupport(users, client, options.users);\n const home = new SliccKernelEnv(client, { cwd: HOME });\n await privateStore(home);\n return { client, users, home, at: { home: HOME, ...(users ? { agentDir: AGENT_DIR } : {}) } };\n}\n\nfunction privateStore(env: SliccKernelEnv): Promise<unknown> {\n return env.exec(`mkdir -p ${STORE_DIR} && chmod 700 ${STORE_DIR}`, undefined, BACKGROUND_CONTEXT);\n}\n\nasync function codemodeTools(\n client: KernelClient,\n options: AgentWorkerOptions,\n native: typeof fetch,\n extra: Parameters<typeof codemodeTool>[0]['extra'],\n dir = `${HOME}/.pi/agent`\n) {\n const settings = await client.fs.readFile(`${dir}/settings.json`).catch(() => undefined);\n if (disabledBySettings(settings === undefined ? undefined : new TextDecoder().decode(settings)))\n return [];\n const sandbox = sandboxFactory(\n options.codemodeWasm ?? (() => locateWasm(native, new URL(import.meta.url))),\n options.codemodeWorker\n );\n return [\n codemodeTool({ declared: CodingTools.tools as readonly ToolRegistration[], sandbox, extra }),\n ];\n}\n\nexport function seesImages(models: Pick<Models, 'getModel'>, ref: ModelRef | undefined): boolean {\n const found = ref && models.getModel(ref.provider, ref.modelId);\n return found ? found.input.includes('image') : true;\n}\n\nexport const MCP_CALLBACK = '/oauth/mcp-callback';\n\nasync function openRepinned(\n options: AgentWorkerOptions,\n base: Omit<AgentOptions, 'storage' | 'beforeResume'>\n): Promise<Agent> {\n const storage = await (options.storage ?? (() => openOpfsSqliteStorage()))();\n return openAgent({\n ...base,\n storage,\n beforeResume: (harness, using) => repin(harness, storage, using),\n });\n}\n\nasync function secretsFor(home: SliccKernelEnv, vault: Vault) {\n scrubWith(vault);\n const names = secretNames(home, vault);\n await names.refresh(BACKGROUND_CONTEXT);\n return names;\n}\n\nexport function modelBases(\n providers: readonly Provider[],\n models: Pick<ReturnType<typeof createSliccModels>, 'getModels'>\n): ModelBases[] {\n return providers.map((provider) => ({\n provider: provider.id,\n urls: [\n ...new Set(\n [\n provider.baseUrl,\n ...models.getModels(provider.id).map((model) => model.baseUrl),\n ...(provider.id === BEDROCK ? BEDROCK_ENDPOINTS : []),\n ].filter((url): url is string => typeof url === 'string' && url !== '')\n ),\n ],\n }));\n}\n\nfunction mcpVault(\n vault: Vault,\n made: { store: PlainStore; records: VaultRecords; endpoints: ReturnType<typeof vaultEndpoints> }\n) {\n const { store, records, endpoints } = made;\n return {\n store,\n vault: {\n records,\n fetch: (server: string, base: typeof fetch) => mcpFetch(vault, base, server),\n grant: (server: string, base: typeof fetch) => grantFetch(vault, server, base),\n servers: endpoints.servers,\n token: endpoints.token,\n },\n };\n}\n\nfunction hostSecrets(\n vault: Vault,\n names: Awaited<ReturnType<typeof secretsFor>>,\n parts: readonly { close(): void }[]\n) {\n return {\n vault: vault.state,\n list: () => names.state.value,\n close: () => {\n for (const part of parts) part.close();\n },\n };\n}\n\nasync function modelsOf(\n scope: AgentWorkerScope,\n options: AgentWorkerOptions,\n given: { vault: Vault; home: SliccKernelEnv; transport: typeof fetch; version: string }\n) {\n const { vault, home, transport, version } = given;\n const store = await (options.store ?? (async () => fileStore(home, ACCOUNTS_FILE)))();\n const records = vaultRecords(vault);\n void records.refresh(BACKGROUND_CONTEXT).catch(() => undefined);\n const providers = options.providers ?? sliccProviders(version);\n const fields = await providerFields(store, providers);\n const models = createSliccModels(vaultCredentials(records, fields.env), providers);\n const bases = () => modelBases(providers, models);\n scope.fetch = vaultFetch(\n vault,\n transport,\n modelRoute(bases, () => records.state.value)\n );\n const endpoints = vaultEndpoints(vault);\n void endpoints.models(bases()).catch(() => undefined);\n return { store, records, providers, fields, models, bases, endpoints };\n}\n\nfunction baseRegistry(facts: Awaited<ReturnType<typeof factsOf>>) {\n const registry = createRegistry();\n registry.install(CodingTools);\n registry.install(sliccPrompt(facts));\n const read = (CodingTools.tools as readonly ToolRegistration[]).find(\n (tool) => tool.name === 'read'\n ) as ToolRegistration;\n registry.install(imageReads(read));\n return registry;\n}\n\nasync function factsOf(client: KernelClient & { transport: Transport }, native: typeof fetch) {\n return {\n version: await agentVersion((url) => native(url)),\n commands: await commandsOnPath(client),\n transport: transportName(client.transport),\n browser: await browserConnected(client),\n };\n}\n\nfunction routeFetch(scope: AgentWorkerScope, client: KernelClient & { transport: Transport }) {\n const native = scope.fetch.bind(scope);\n const loopback = client.loopbackFetch?.bind(client);\n const transport = transportFetch(client.transport, scope.location.origin, native, loopback);\n scope.fetch = transport;\n return { native, transport };\n}\n\nasync function prepare(\n scope: AgentWorkerScope,\n kernel: { client: KernelClient & { transport: Transport }; home: SliccKernelEnv; vault: Vault },\n options: AgentWorkerOptions\n) {\n const names = await secretsFor(kernel.home, kernel.vault);\n const { native, transport } = routeFetch(scope, kernel.client);\n const facts = await factsOf(kernel.client, native);\n const made = await modelsOf(scope, options, {\n vault: kernel.vault,\n home: kernel.home,\n transport,\n version: facts.version,\n });\n return { names, native, transport, facts, ...made, registry: baseRegistry(facts) };\n}\n\nfunction modelsOfAgent(\n agent: Agent,\n settings: Awaited<ReturnType<typeof createAgentSettings>>,\n catalog: Models,\n vault: Vault\n) {\n const locked = () => vault.state.value.locked !== 'no';\n return modelsCommand({ agents: agent.agents, settings, catalog, locked });\n}\n\nasync function settingsOf(made: Awaited<ReturnType<typeof modelsOf>>, mcp: McpAccounts) {\n const { models, records, fields, providers, bases, endpoints } = made;\n const settings = await createAgentSettings(models, { records, fields }, providers, { mcp });\n settings.state.subscribe(() => void endpoints.models(bases()).catch(() => undefined));\n return settings;\n}\n\nfunction setupTitles(\n registry: ReturnType<typeof createRegistry>,\n models: Models,\n home: SliccKernelEnv,\n at: { home: string; agentDir?: string },\n opened: () => Agent | undefined\n) {\n const titleFn = titler(models, settingsText(home, HOME, at.agentDir));\n const titles = titlesExtension({\n agents: () => opened()?.agents,\n harness: () => opened()?.harness,\n title: () => titleFn,\n });\n registry.install(titles.extension);\n return { titleFn, cancel: titles.cancel };\n}\n\nasync function start(\n scope: AgentWorkerScope,\n ports: Promise<KernelPorts>,\n options: AgentWorkerOptions,\n vault: Vault\n): Promise<AgentHost> {\n const { client, users, home, at } = await attached(ports, options);\n const ready = await prepare(scope, { client, home, vault }, options);\n const { names, native, transport, facts, models, registry } = ready;\n const { records, endpoints } = ready;\n const memory = setupMemory(registry);\n const coding = CodingTools.tools as readonly ToolRegistration[];\n registry.install(browserGuard([scope.location.origin], coding));\n const mcp = setupMcp(registry);\n const codemode = await codemodeTools(client, options, native, mcp.codemode, at.agentDir);\n registry.install(codemodeExtension(codemode));\n const licks = setupLicks(registry);\n licks.licks.triage(lickTriage(models));\n const scoops = setupScoops(registry, licks.licks, [...coding, ...codemode, ...memory.tools]);\n const skills = setupSkills(registry, licks.licks);\n registry.install(secretsExtension({ names, vault }));\n const titles = setupTitles(registry, models, home, at, () => opened);\n const [activity, groups] = [createActivity(), processGroups(client)];\n const model = options.model ?? DEFAULT_MODEL;\n let opened: Agent | undefined;\n const people = users ? agentUsers(users, client, home, () => opened?.agents) : undefined;\n const environment = kernelEnvironment(client, {\n activity,\n groups,\n identify: identity(() => opened?.agents, model),\n scrub: vault,\n spawn: shellGrants(names),\n ...(people ? { route: people.route } : {}),\n });\n const agent = await openRepinned(options, { models, model, registry, env: environment });\n opened = agent;\n await people?.start(agent.agents);\n const sources = licks.attach(agent, {\n env: home,\n home: HOME,\n activity,\n ...(people ? { dirs: () => people.lickDirs() } : {}),\n });\n await sources.start(BACKGROUND_CONTEXT);\n await sources.boot(\n { version: facts.version, boot: await kernelBoot(client) },\n BACKGROUND_CONTEXT\n );\n const skillsRuntime = await skills.attach(\n {\n env: home,\n ...at,\n assets: options.assets ?? packageAssets(),\n reloadMs: RELOAD_MS,\n ...(people ? { people: people.people } : {}),\n },\n BACKGROUND_CONTEXT\n );\n const mcpRuntime = await mcp.attach(\n {\n env: home,\n ...at,\n ...mcpVault(vault, ready),\n licks: licks.licks,\n fetch: transport,\n version: facts.version,\n reloadMs: RELOAD_MS,\n codemode: codemode.length > 0,\n cors: pageOnly(client.transport),\n redirect: options.mcpRedirect ?? new URL(MCP_CALLBACK, scope.location.origin).href,\n },\n BACKGROUND_CONTEXT\n );\n const gelatiere = lateGelatiere();\n const sprinkles = await setupSprinkles().attach(\n {\n intercept: gelatiere.intercept,\n harness: agent.harness,\n agents: agent.agents,\n licks: licks.licks,\n env: home,\n assets: options.assets ?? packageAssets(),\n reloadMs: RELOAD_MS,\n ...(people?.sprinkles() ?? {}),\n },\n BACKGROUND_CONTEXT\n );\n people?.follow([sources, skillsRuntime, sprinkles]);\n let roles: ScoopsRuntime | undefined;\n const memoryRuntime = await memory.attach(\n {\n harness: agent.harness,\n agents: agent.agents,\n env: home,\n ...at,\n ...(people ? { home: ROOT_HOME } : {}),\n reloadMs: RELOAD_MS,\n roles: async (using) => roles?.roles(using),\n },\n BACKGROUND_CONTEXT\n );\n const freezer = attachFreezer({\n harness: agent.harness,\n agents: agent.agents,\n env: home,\n extract: memory.extract,\n title: titles.titleFn,\n cancelTitle: titles.cancel,\n ...(people ? { layout: people.layout } : {}),\n });\n licks.licks.guard(freezer.frozenTarget);\n const settings = await settingsOf(ready, mcpRuntime);\n const pages = createPages({ claim: sprinkles.claim });\n const runtime = await scoops.attach(\n {\n harness: agent.harness,\n agents: agent.agents,\n groups,\n env: home,\n ...at,\n ...(people\n ? { layout: people.layout, spools: people.spools, enforced: people.enforced }\n : {}),\n alive: alive(client),\n reads: skillsRuntime.dirs,\n memory: memoryRuntime.command,\n gelatiere: gelatiere.command,\n freezer: freezer.command,\n models: modelsOfAgent(agent, settings, models, vault),\n panel: pages.command,\n mcp: mcp.direct,\n ...(options.assets ? { assets: options.assets } : {}),\n },\n BACKGROUND_CONTEXT\n );\n roles = runtime;\n gelatiere.attach({\n agents: agent.agents,\n licks: licks.licks,\n env: home,\n home: HOME,\n ...(await people?.gelatiere(home)),\n scoops: scoops.scoops,\n roles: runtime.roles,\n assets: options.assets ?? packageAssets(),\n fetch: scope.fetch,\n skills: skillsRuntime.skills,\n ...(options.catalog ? { catalog: options.catalog } : {}),\n });\n await memoryRuntime.reload(BACKGROUND_CONTEXT).catch(() => undefined);\n const changes = attachChanges({ agents: agent.agents, env: home, reloadMs: CHANGES_MS });\n return hostAgent(agent, {\n settings,\n licks: { licks: licks.licks, sources },\n scoops: { scoops: scoops.scoops, runtime },\n skills: skillsRuntime,\n sprinkles,\n memory: memoryRuntime,\n freezer,\n changes,\n pages,\n mcp: mcpRuntime,\n ...(users ? { users } : {}),\n secrets: hostSecrets(vault, names, [names, records, endpoints]),\n uploads: {\n env: environment,\n sees: (ref) => seesImages(models, ref),\n },\n monitor: {\n kernel: client,\n groups,\n ...(users ? { users: () => users.users.list() } : {}),\n },\n });\n}\n\nexport function alive(client: KernelClient) {\n return async (pid: number): Promise<boolean> => {\n if (!client.ps) return true;\n return (await client.ps()).some((process) => process.pid === pid);\n };\n}\n\nexport function runAgentWorker(\n scope: AgentWorkerScope,\n options: AgentWorkerOptions = {}\n): Promise<AgentHost> {\n const vault = new Vault();\n listenVault(scope, vault);\n const host = start(scope, kernelPorts(scope), options, vault);\n host.catch(() => undefined);\n serveConnections(scope, host);\n return host;\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,8 @@
1
- import { credentialKey, secretNames } from "./credentials.js";
1
+ import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context";
2
+ import { resolveHeaders, secretNames } from "./credentials.js";
2
3
  import { MCP_ACCOUNT } from "./label.js";
3
4
  import { beginSignIn, finishSignIn } from "./oauth.js";
5
+ const TOKENS_IN_VAULT = "MCP tokens are kept in seven's vault: update seven";
4
6
  function kindOf(connection) {
5
7
  return secretNames(connection.entry.config).length ? "token" : "oauth";
6
8
  }
@@ -14,11 +16,12 @@ function row(connection, kind, stored) {
14
16
  auth: kind === "token" ? "api-key" : "oauth",
15
17
  needs: null,
16
18
  group: "mcp",
19
+ store: "vault",
17
20
  ...kind === "token" ? { secret: "token" } : {}
18
21
  };
19
22
  }
20
23
  function mcpAccounts(catalog, sources, restart, listeners) {
21
- const { credentials } = sources;
24
+ const { records } = sources;
22
25
  const find = (id, want) => {
23
26
  const connection = id.startsWith(MCP_ACCOUNT) ? catalog.connections.get(id.slice(MCP_ACCOUNT.length)) : void 0;
24
27
  const kind = connection && kindOf(connection);
@@ -28,13 +31,13 @@ function mcpAccounts(catalog, sources, restart, listeners) {
28
31
  );
29
32
  return { connection, kind };
30
33
  };
31
- const keyOf = (connection) => credentialKey(connection.name, connection.entry.config.url);
34
+ const reread = () => records.refresh(BACKGROUND_CONTEXT).catch(() => void 0);
32
35
  return {
33
36
  async accounts() {
34
37
  const rows = [];
35
38
  for (const connection of catalog.connections.values()) {
36
39
  const kind = kindOf(connection);
37
- const stored = kind === "token" ? await credentials.read(await keyOf(connection)) !== void 0 : await sources.oauth(connection.entry).signedIn();
40
+ const stored = kind === "token" ? resolveHeaders(connection.name, connection.entry.config, records).ok : await sources.oauth(connection.entry).signedIn();
38
41
  if (kind === "oauth" && !stored && connection.state !== "needs-auth") continue;
39
42
  rows.push(row(connection, kind, stored));
40
43
  }
@@ -43,28 +46,28 @@ function mcpAccounts(catalog, sources, restart, listeners) {
43
46
  async signIn(id) {
44
47
  const { connection } = find(id, "oauth");
45
48
  return beginSignIn(sources.oauth(connection.entry), connection.entry, {
46
- fetch: sources.fetch
49
+ fetch: sources.fetch(connection.name),
50
+ register: (tokenUrl) => sources.register(connection.name, tokenUrl)
47
51
  });
48
52
  },
49
53
  async connect(id, secret) {
50
54
  const { connection, kind } = find(id);
51
- if (kind === "oauth")
55
+ if (kind === "oauth") {
56
+ if (secret === null) throw new Error(`${id} needs a sign-in`);
52
57
  await finishSignIn(
53
58
  sources.oauth(connection.entry),
54
59
  connection.entry,
55
60
  secret,
56
- sources.fetch
61
+ sources.grant(connection.name)
57
62
  );
58
- else
59
- await credentials.modify(await keyOf(connection), async () => ({
60
- type: "api_key",
61
- key: secret
62
- }));
63
+ } else if (secret !== null) throw new Error(TOKENS_IN_VAULT);
64
+ await reread();
63
65
  restart(connection);
64
66
  },
65
67
  async disconnect(id) {
66
- const { connection } = find(id);
67
- await credentials.delete(await keyOf(connection));
68
+ const { connection, kind } = find(id);
69
+ if (kind === "oauth") await sources.oauth(connection.entry).forget();
70
+ await reread();
68
71
  restart(connection);
69
72
  },
70
73
  onChange(listener) {
@@ -74,6 +77,7 @@ function mcpAccounts(catalog, sources, restart, listeners) {
74
77
  };
75
78
  }
76
79
  export {
80
+ TOKENS_IN_VAULT,
77
81
  mcpAccounts
78
82
  };
79
83
  //# sourceMappingURL=accounts.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/mcp/accounts.ts"],
4
- "sourcesContent": ["import type { CredentialStore } from '@earendil-works/pi-ai';\nimport type { McpFetch } from '@earendil-works/pi-mcp';\nimport type { AccountState } from '../services.ts';\nimport type { McpCatalog } from './catalog.ts';\nimport type { McpServerEntry } from './config.ts';\nimport type { McpServerConnection } from './connection.ts';\nimport { credentialKey, secretNames } from './credentials.ts';\nimport { MCP_ACCOUNT } from './label.ts';\nimport { beginSignIn, finishSignIn, type McpSignIn, type StoredOAuth } from './oauth.ts';\n\nexport interface McpAccounts {\n accounts(): Promise<AccountState[]>;\n signIn(id: string): Promise<McpSignIn>;\n connect(id: string, secret: string): Promise<void>;\n disconnect(id: string): Promise<void>;\n onChange(listener: () => void): () => void;\n}\n\nexport interface AccountSources {\n credentials: CredentialStore;\n oauth: (entry: McpServerEntry) => StoredOAuth;\n fetch: McpFetch;\n}\n\ntype Kind = 'token' | 'oauth';\n\nfunction kindOf(connection: McpServerConnection): Kind {\n return secretNames(connection.entry.config).length ? 'token' : 'oauth';\n}\n\nfunction row(connection: McpServerConnection, kind: Kind, stored: boolean): AccountState {\n const rejected = connection.state === 'needs-auth';\n return {\n id: `${MCP_ACCOUNT}${connection.name}`,\n provider: connection.name,\n identity: new URL(connection.entry.config.url).host,\n status:\n rejected && (kind === 'token' || stored)\n ? 'expired'\n : stored && connection.live\n ? 'connected'\n : 'disconnected',\n auth: kind === 'token' ? 'api-key' : 'oauth',\n needs: null,\n group: 'mcp',\n ...(kind === 'token' ? { secret: 'token' as const } : {}),\n };\n}\n\nexport function mcpAccounts(\n catalog: McpCatalog,\n sources: AccountSources,\n restart: (connection: McpServerConnection) => void,\n listeners: Set<() => void>\n): McpAccounts {\n const { credentials } = sources;\n const find = (id: string, want?: Kind) => {\n const connection = id.startsWith(MCP_ACCOUNT)\n ? catalog.connections.get(id.slice(MCP_ACCOUNT.length))\n : undefined;\n const kind = connection && kindOf(connection);\n if (!connection || (want && kind !== want))\n throw new Error(\n `${id} is not an MCP server that ${want === 'oauth' ? 'signs in' : 'takes a token or a sign-in'}`\n );\n return { connection, kind: kind as Kind };\n };\n const keyOf = (connection: McpServerConnection) =>\n credentialKey(connection.name, connection.entry.config.url);\n return {\n async accounts() {\n const rows: AccountState[] = [];\n for (const connection of catalog.connections.values()) {\n const kind = kindOf(connection);\n const stored =\n kind === 'token'\n ? (await credentials.read(await keyOf(connection))) !== undefined\n : await sources.oauth(connection.entry).signedIn();\n if (kind === 'oauth' && !stored && connection.state !== 'needs-auth') continue;\n rows.push(row(connection, kind, stored));\n }\n return rows;\n },\n async signIn(id) {\n const { connection } = find(id, 'oauth');\n return beginSignIn(sources.oauth(connection.entry), connection.entry, {\n fetch: sources.fetch,\n });\n },\n async connect(id, secret) {\n const { connection, kind } = find(id);\n if (kind === 'oauth')\n await finishSignIn(\n sources.oauth(connection.entry),\n connection.entry,\n secret,\n sources.fetch\n );\n else\n await credentials.modify(await keyOf(connection), async () => ({\n type: 'api_key',\n key: secret,\n }));\n restart(connection);\n },\n async disconnect(id) {\n const { connection } = find(id);\n await credentials.delete(await keyOf(connection));\n restart(connection);\n },\n onChange(listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n };\n}\n"],
5
- "mappings": "AAMA,SAAS,eAAe,mBAAmB;AAC3C,SAAS,mBAAmB;AAC5B,SAAS,aAAa,oBAAsD;AAkB5E,SAAS,OAAO,YAAuC;AACrD,SAAO,YAAY,WAAW,MAAM,MAAM,EAAE,SAAS,UAAU;AACjE;AAEA,SAAS,IAAI,YAAiC,MAAY,QAA+B;AACvF,QAAM,WAAW,WAAW,UAAU;AACtC,SAAO;AAAA,IACL,IAAI,GAAG,WAAW,GAAG,WAAW,IAAI;AAAA,IACpC,UAAU,WAAW;AAAA,IACrB,UAAU,IAAI,IAAI,WAAW,MAAM,OAAO,GAAG,EAAE;AAAA,IAC/C,QACE,aAAa,SAAS,WAAW,UAC7B,YACA,UAAU,WAAW,OACnB,cACA;AAAA,IACR,MAAM,SAAS,UAAU,YAAY;AAAA,IACrC,OAAO;AAAA,IACP,OAAO;AAAA,IACP,GAAI,SAAS,UAAU,EAAE,QAAQ,QAAiB,IAAI,CAAC;AAAA,EACzD;AACF;AAEO,SAAS,YACd,SACA,SACA,SACA,WACa;AACb,QAAM,EAAE,YAAY,IAAI;AACxB,QAAM,OAAO,CAAC,IAAY,SAAgB;AACxC,UAAM,aAAa,GAAG,WAAW,WAAW,IACxC,QAAQ,YAAY,IAAI,GAAG,MAAM,YAAY,MAAM,CAAC,IACpD;AACJ,UAAM,OAAO,cAAc,OAAO,UAAU;AAC5C,QAAI,CAAC,cAAe,QAAQ,SAAS;AACnC,YAAM,IAAI;AAAA,QACR,GAAG,EAAE,8BAA8B,SAAS,UAAU,aAAa,4BAA4B;AAAA,MACjG;AACF,WAAO,EAAE,YAAY,KAAmB;AAAA,EAC1C;AACA,QAAM,QAAQ,CAAC,eACb,cAAc,WAAW,MAAM,WAAW,MAAM,OAAO,GAAG;AAC5D,SAAO;AAAA,IACL,MAAM,WAAW;AACf,YAAM,OAAuB,CAAC;AAC9B,iBAAW,cAAc,QAAQ,YAAY,OAAO,GAAG;AACrD,cAAM,OAAO,OAAO,UAAU;AAC9B,cAAM,SACJ,SAAS,UACJ,MAAM,YAAY,KAAK,MAAM,MAAM,UAAU,CAAC,MAAO,SACtD,MAAM,QAAQ,MAAM,WAAW,KAAK,EAAE,SAAS;AACrD,YAAI,SAAS,WAAW,CAAC,UAAU,WAAW,UAAU,aAAc;AACtE,aAAK,KAAK,IAAI,YAAY,MAAM,MAAM,CAAC;AAAA,MACzC;AACA,aAAO;AAAA,IACT;AAAA,IACA,MAAM,OAAO,IAAI;AACf,YAAM,EAAE,WAAW,IAAI,KAAK,IAAI,OAAO;AACvC,aAAO,YAAY,QAAQ,MAAM,WAAW,KAAK,GAAG,WAAW,OAAO;AAAA,QACpE,OAAO,QAAQ;AAAA,MACjB,CAAC;AAAA,IACH;AAAA,IACA,MAAM,QAAQ,IAAI,QAAQ;AACxB,YAAM,EAAE,YAAY,KAAK,IAAI,KAAK,EAAE;AACpC,UAAI,SAAS;AACX,cAAM;AAAA,UACJ,QAAQ,MAAM,WAAW,KAAK;AAAA,UAC9B,WAAW;AAAA,UACX;AAAA,UACA,QAAQ;AAAA,QACV;AAAA;AAEA,cAAM,YAAY,OAAO,MAAM,MAAM,UAAU,GAAG,aAAa;AAAA,UAC7D,MAAM;AAAA,UACN,KAAK;AAAA,QACP,EAAE;AACJ,cAAQ,UAAU;AAAA,IACpB;AAAA,IACA,MAAM,WAAW,IAAI;AACnB,YAAM,EAAE,WAAW,IAAI,KAAK,EAAE;AAC9B,YAAM,YAAY,OAAO,MAAM,MAAM,UAAU,CAAC;AAChD,cAAQ,UAAU;AAAA,IACpB;AAAA,IACA,SAAS,UAAU;AACjB,gBAAU,IAAI,QAAQ;AACtB,aAAO,MAAM,UAAU,OAAO,QAAQ;AAAA,IACxC;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { McpFetch } from '@earendil-works/pi-mcp';\nimport type { AccountState } from '../services.ts';\nimport type { McpCatalog } from './catalog.ts';\nimport type { McpServerEntry } from './config.ts';\nimport type { McpServerConnection } from './connection.ts';\nimport { type McpRecords, resolveHeaders, secretNames } from './credentials.ts';\nimport { MCP_ACCOUNT } from './label.ts';\nimport { beginSignIn, finishSignIn, type McpSignIn, type StoredOAuth } from './oauth.ts';\n\nexport const TOKENS_IN_VAULT = \"MCP tokens are kept in seven's vault: update seven\";\n\nexport interface McpAccounts {\n accounts(): Promise<AccountState[]>;\n signIn(id: string): Promise<McpSignIn>;\n connect(id: string, secret: string | null): Promise<void>;\n disconnect(id: string): Promise<void>;\n onChange(listener: () => void): () => void;\n}\n\nexport interface AccountSources {\n records: McpRecords & { refresh(context: Context): Promise<void> };\n oauth: (entry: McpServerEntry) => StoredOAuth;\n fetch: (server: string) => McpFetch;\n grant: (server: string) => McpFetch;\n register: (server: string, tokenUrl: string) => Promise<void>;\n}\n\ntype Kind = 'token' | 'oauth';\n\nfunction kindOf(connection: McpServerConnection): Kind {\n return secretNames(connection.entry.config).length ? 'token' : 'oauth';\n}\n\nfunction row(connection: McpServerConnection, kind: Kind, stored: boolean): AccountState {\n const rejected = connection.state === 'needs-auth';\n return {\n id: `${MCP_ACCOUNT}${connection.name}`,\n provider: connection.name,\n identity: new URL(connection.entry.config.url).host,\n status:\n rejected && (kind === 'token' || stored)\n ? 'expired'\n : stored && connection.live\n ? 'connected'\n : 'disconnected',\n auth: kind === 'token' ? 'api-key' : 'oauth',\n needs: null,\n group: 'mcp',\n store: 'vault',\n ...(kind === 'token' ? { secret: 'token' as const } : {}),\n };\n}\n\nexport function mcpAccounts(\n catalog: McpCatalog,\n sources: AccountSources,\n restart: (connection: McpServerConnection) => void,\n listeners: Set<() => void>\n): McpAccounts {\n const { records } = sources;\n const find = (id: string, want?: Kind) => {\n const connection = id.startsWith(MCP_ACCOUNT)\n ? catalog.connections.get(id.slice(MCP_ACCOUNT.length))\n : undefined;\n const kind = connection && kindOf(connection);\n if (!connection || (want && kind !== want))\n throw new Error(\n `${id} is not an MCP server that ${want === 'oauth' ? 'signs in' : 'takes a token or a sign-in'}`\n );\n return { connection, kind: kind as Kind };\n };\n const reread = () => records.refresh(BACKGROUND_CONTEXT).catch(() => undefined);\n return {\n async accounts() {\n const rows: AccountState[] = [];\n for (const connection of catalog.connections.values()) {\n const kind = kindOf(connection);\n const stored =\n kind === 'token'\n ? resolveHeaders(connection.name, connection.entry.config, records).ok\n : await sources.oauth(connection.entry).signedIn();\n if (kind === 'oauth' && !stored && connection.state !== 'needs-auth') continue;\n rows.push(row(connection, kind, stored));\n }\n return rows;\n },\n async signIn(id) {\n const { connection } = find(id, 'oauth');\n return beginSignIn(sources.oauth(connection.entry), connection.entry, {\n fetch: sources.fetch(connection.name),\n register: (tokenUrl) => sources.register(connection.name, tokenUrl),\n });\n },\n async connect(id, secret) {\n const { connection, kind } = find(id);\n if (kind === 'oauth') {\n if (secret === null) throw new Error(`${id} needs a sign-in`);\n await finishSignIn(\n sources.oauth(connection.entry),\n connection.entry,\n secret,\n sources.grant(connection.name)\n );\n } else if (secret !== null) throw new Error(TOKENS_IN_VAULT);\n await reread();\n restart(connection);\n },\n async disconnect(id) {\n const { connection, kind } = find(id);\n if (kind === 'oauth') await sources.oauth(connection.entry).forget();\n await reread();\n restart(connection);\n },\n onChange(listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n };\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -56,7 +56,6 @@ class McpServerConnection {
56
56
  resources = [];
57
57
  resourceTemplates = [];
58
58
  instructions;
59
- secrets = [];
60
59
  #client;
61
60
  #opening;
62
61
  #shutdown = new AbortController();
@@ -179,7 +178,6 @@ class McpServerConnection {
179
178
  this.missing = made.missing;
180
179
  throw new MissingSecret(made.missing);
181
180
  }
182
- this.secrets = made.secrets;
183
181
  const client = new McpClient({
184
182
  name: CLIENT_NAME,
185
183
  version: this.#options.version,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/mcp/connection.ts"],
4
- "sourcesContent": ["import {\n type CallToolResult,\n JSON_RPC_ERROR_CODES,\n type ListResourcesResult,\n type ListResourceTemplatesResult,\n McpAuthRequiredError,\n McpClient,\n McpError,\n McpHttpError,\n type McpRequestOptions,\n McpSessionExpiredError,\n type Tool as McpTool,\n type McpTransport,\n type ReadResourceResult,\n type Resource,\n type ResourceTemplate,\n} from '@earendil-works/pi-mcp';\nimport { McpOAuthAuthorizationRequiredError } from '@earendil-works/pi-mcp/oauth';\nimport { DEFAULT_TIMEOUT_SECONDS, type McpServerEntry, usesOAuth } from './config.ts';\nimport { secretNames } from './credentials.ts';\n\nexport type ServerState =\n | 'connecting'\n | 'connected'\n | 'needs-auth'\n | 'needs-secret'\n | 'failed'\n | 'closed';\n\nexport type TransportFactory = (\n entry: McpServerEntry\n) => Promise<{ transport: McpTransport; secrets: string[] } | { missing: string[] }>;\n\nexport const CONNECT_RETRY_DELAYS_MS = [250, 1_000];\nexport const CLIENT_NAME = 'slicc';\n\nexport function signInNeeded(error: unknown): boolean {\n return (\n error instanceof McpAuthRequiredError || error instanceof McpOAuthAuthorizationRequiredError\n );\n}\n\nexport function errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nexport function isTransient(error: unknown): boolean {\n if (error instanceof McpHttpError)\n return (\n error.status === 408 || error.status === 429 || (error.status >= 500 && error.status !== 501)\n );\n return error instanceof TypeError;\n}\n\nexport function isMcpApp(item: { uri?: string; uriTemplate?: string; mimeType?: string }): boolean {\n const uri = item.uri ?? item.uriTemplate ?? '';\n return uri.startsWith('ui://') || /;\\s*profile\\s*=\\s*\"?mcp-app\"?/i.test(item.mimeType ?? '');\n}\n\nasync function withoutTemplates<T>(list: () => Promise<T>, empty: T): Promise<T> {\n try {\n return await list();\n } catch (error) {\n if (error instanceof McpError && error.code === JSON_RPC_ERROR_CODES.methodNotFound)\n return empty;\n throw error;\n }\n}\n\nconst sleep = (ms: number, signal: AbortSignal) =>\n new Promise<void>((resolve) => {\n const timer = setTimeout(resolve, ms);\n signal.addEventListener(\n 'abort',\n () => {\n clearTimeout(timer);\n resolve();\n },\n { once: true }\n );\n });\n\nexport interface ConnectionOptions {\n entry: McpServerEntry;\n version: string;\n transport: TransportFactory;\n onTools: (connection: McpServerConnection) => void;\n onChange?: (connection: McpServerConnection) => void;\n onLog?: (connection: McpServerConnection, params: unknown) => void;\n}\n\nexport class McpServerConnection {\n readonly entry: McpServerEntry;\n state: ServerState = 'connecting';\n error: string | undefined;\n missing: string[] = [];\n tools: McpTool[] = [];\n hasResources = false;\n resources: Resource[] = [];\n resourceTemplates: ResourceTemplate[] = [];\n instructions: string | undefined;\n secrets: string[] = [];\n #client: McpClient | undefined;\n #opening: Promise<McpClient> | undefined;\n readonly #shutdown = new AbortController();\n readonly #busy = new Map<McpClient, number>();\n #seen = false;\n readonly #expired = new Set<McpClient>();\n readonly #options: ConnectionOptions;\n\n constructor(options: ConnectionOptions) {\n this.entry = options.entry;\n this.#options = options;\n }\n\n get name(): string {\n return this.entry.name;\n }\n\n get timeoutMs(): number {\n return (this.entry.config.timeout ?? DEFAULT_TIMEOUT_SECONDS) * 1000;\n }\n\n get live(): boolean {\n return this.state === 'connected' || (this.state === 'connecting' && this.#seen);\n }\n\n get closed(): boolean {\n return this.#shutdown.signal.aborted;\n }\n\n getClient(): Promise<McpClient> {\n if (this.closed) return Promise.reject(new Error(`MCP server \"${this.name}\" is shut down`));\n if (this.#client?.connectionState === 'connected') return Promise.resolve(this.#client);\n this.#opening ??= this.#open().finally(() => {\n this.#opening = undefined;\n });\n return this.#opening;\n }\n\n callTool(\n name: string,\n args: Record<string, unknown>,\n options: McpRequestOptions\n ): Promise<CallToolResult> {\n return this.#with((client) => client.callTool(name, args, options));\n }\n\n readResource(uri: string, options: McpRequestOptions): Promise<ReadResourceResult> {\n return this.#with((client) => client.readResource(uri, options), true);\n }\n\n resourcesPage(\n cursor: string | undefined,\n options: McpRequestOptions\n ): Promise<ListResourcesResult> {\n return this.#with((client) => client.listResourcesPage(cursor, options), true);\n }\n\n resourceTemplatesPage(\n cursor: string | undefined,\n options: McpRequestOptions\n ): Promise<ListResourceTemplatesResult> {\n return this.#with(\n (client) =>\n withoutTemplates(() => client.listResourceTemplatesPage(cursor, options), {\n resourceTemplates: [],\n }),\n true\n );\n }\n\n allResources(options: McpRequestOptions): Promise<Resource[]> {\n return this.#with((client) => client.listResources(options), true);\n }\n\n allResourceTemplates(options: McpRequestOptions): Promise<ResourceTemplate[]> {\n return this.#with(\n (client) => withoutTemplates(() => client.listResourceTemplates(options), []),\n true\n );\n }\n\n async #with<T>(run: (client: McpClient) => Promise<T>, readOnly = false): Promise<T> {\n for (let attempt = 1; ; attempt++) {\n const client = await this.getClient();\n this.#busy.set(client, (this.#busy.get(client) ?? 0) + 1);\n try {\n return await run(client);\n } catch (error) {\n if (readOnly && attempt === 1 && error instanceof McpHttpError && isTransient(error)) {\n await sleep(CONNECT_RETRY_DELAYS_MS[0] as number, this.#shutdown.signal);\n continue;\n }\n if (error instanceof McpSessionExpiredError && attempt === 1) {\n if (this.#client === client) {\n this.#client = undefined;\n this.#expired.add(client);\n }\n continue;\n }\n if (!signInNeeded(error)) throw error;\n await this.#drop(client);\n this.#mark('needs-auth');\n throw new Error(this.signInMessage());\n } finally {\n this.#release(client);\n }\n }\n }\n\n #release(client: McpClient): void {\n const left = (this.#busy.get(client) as number) - 1;\n this.#busy.set(client, left);\n if (left > 0 || !this.#expired.delete(client)) return;\n this.#busy.delete(client);\n void this.#drop(client);\n }\n\n signInMessage(): string {\n return usesOAuth(this.entry.config) && !secretNames(this.entry.config).length\n ? `MCP server \"${this.name}\" needs you to sign in. Sign in under Settings \u203A MCP servers.`\n : `MCP server \"${this.name}\" rejected its token (401). Update it in Settings \u203A MCP servers.`;\n }\n\n #mark(state: ServerState, error?: string): void {\n this.state = state;\n this.error = error;\n this.#options.onChange?.(this);\n }\n\n async #drop(client: McpClient): Promise<void> {\n if (this.#client === client) this.#client = undefined;\n await client.close().catch(() => undefined);\n }\n\n async #open(): Promise<McpClient> {\n this.#mark('connecting');\n for (let attempt = 0; ; attempt++) {\n try {\n return await this.#connectOnce();\n } catch (error) {\n const delay = CONNECT_RETRY_DELAYS_MS[attempt];\n if (this.closed || delay === undefined || !isTransient(error)) throw this.#failed(error);\n await sleep(delay, this.#shutdown.signal);\n if (this.closed) throw this.#failed(error);\n }\n }\n }\n\n async #connectOnce(): Promise<McpClient> {\n const made = await this.#options.transport(this.entry);\n if ('missing' in made) {\n this.missing = made.missing;\n throw new MissingSecret(made.missing);\n }\n this.secrets = made.secrets;\n const client = new McpClient({\n name: CLIENT_NAME,\n version: this.#options.version,\n requestTimeoutMs: this.timeoutMs,\n });\n const log = this.#options.onLog;\n if (log) client.onNotification('notifications/message', (params) => log(this, params));\n let closing: Promise<void> | undefined;\n const closeClient = () => {\n closing ??= client.close().catch(() => undefined);\n return closing;\n };\n this.#shutdown.signal.addEventListener('abort', closeClient, { once: true });\n try {\n await client.connect(made.transport);\n client.onNotification('notifications/tools/list_changed', () => {\n void this.#refreshTools(client);\n });\n client.onNotification('notifications/resources/list_changed', () => {\n void this.#refreshResources(client);\n });\n const hasResources = client.serverCapabilities?.resources !== undefined;\n const [tools, resources] = await Promise.all([\n client.serverCapabilities?.tools ? client.listTools() : [],\n hasResources ? this.#fetchResources(client) : { resources: [], resourceTemplates: [] },\n ]);\n if (this.closed) throw new Error('shut down while connecting');\n if (client.connectionState !== 'connected') throw new Error('connection closed during setup');\n this.#client = client;\n this.tools = tools;\n this.hasResources = hasResources;\n this.resources = resources.resources;\n this.resourceTemplates = resources.resourceTemplates;\n this.instructions = client.instructions?.trim() || undefined;\n this.missing = [];\n this.#seen = true;\n this.state = 'connected';\n this.error = undefined;\n this.#options.onTools(this);\n this.#options.onChange?.(this);\n return client;\n } catch (error) {\n await closeClient();\n throw error;\n } finally {\n this.#shutdown.signal.removeEventListener('abort', closeClient);\n }\n }\n\n async #fetchResources(client: McpClient) {\n const [resources, resourceTemplates] = await Promise.all([\n client.listResources().catch(() => [] as Resource[]),\n withoutTemplates(() => client.listResourceTemplates(), [] as ResourceTemplate[]).catch(\n () => [] as ResourceTemplate[]\n ),\n ]);\n return {\n resources: resources.filter((resource) => !isMcpApp(resource)),\n resourceTemplates: resourceTemplates.filter((template) => !isMcpApp(template)),\n };\n }\n\n #failed(error: unknown): Error {\n if (error instanceof MissingSecret) {\n this.#mark('needs-secret');\n return new Error(error.message);\n }\n if (signInNeeded(error) && !this.closed) {\n this.#mark('needs-auth');\n return new Error(this.signInMessage());\n }\n this.#mark(this.closed ? 'closed' : 'failed', errorMessage(error));\n return new Error(`MCP server \"${this.name}\" failed to connect: ${this.error}`);\n }\n\n async #refreshTools(client: McpClient): Promise<void> {\n try {\n const tools = await client.listTools();\n if (this.#client !== client || this.closed) return;\n this.tools = tools;\n this.#options.onTools(this);\n } catch (error) {\n this.error = `Failed to refresh tools: ${errorMessage(error)}`;\n }\n this.#options.onChange?.(this);\n }\n\n async #refreshResources(client: McpClient): Promise<void> {\n const { resources, resourceTemplates } = await this.#fetchResources(client);\n if (this.#client !== client || this.closed) return;\n this.resources = resources;\n this.resourceTemplates = resourceTemplates;\n this.#options.onTools(this);\n this.#options.onChange?.(this);\n }\n\n async close(): Promise<void> {\n this.#shutdown.abort();\n this.state = 'closed';\n this.#options.onChange?.(this);\n const client = this.#client;\n this.#client = undefined;\n await Promise.allSettled([client?.close(), this.#opening]);\n }\n}\n\nexport class MissingSecret extends Error {\n readonly names: string[];\n\n constructor(names: string[]) {\n super(\n `needs ${names.map((name) => `\\${${name}}`).join(', ')}: add the value in Settings \u203A MCP servers`\n );\n this.names = names;\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n type CallToolResult,\n JSON_RPC_ERROR_CODES,\n type ListResourcesResult,\n type ListResourceTemplatesResult,\n McpAuthRequiredError,\n McpClient,\n McpError,\n McpHttpError,\n type McpRequestOptions,\n McpSessionExpiredError,\n type Tool as McpTool,\n type McpTransport,\n type ReadResourceResult,\n type Resource,\n type ResourceTemplate,\n} from '@earendil-works/pi-mcp';\nimport { McpOAuthAuthorizationRequiredError } from '@earendil-works/pi-mcp/oauth';\nimport { DEFAULT_TIMEOUT_SECONDS, type McpServerEntry, usesOAuth } from './config.ts';\nimport { secretNames } from './credentials.ts';\n\nexport type ServerState =\n | 'connecting'\n | 'connected'\n | 'needs-auth'\n | 'needs-secret'\n | 'failed'\n | 'closed';\n\nexport type TransportFactory = (\n entry: McpServerEntry\n) => Promise<{ transport: McpTransport } | { missing: string[] }>;\n\nexport const CONNECT_RETRY_DELAYS_MS = [250, 1_000];\nexport const CLIENT_NAME = 'slicc';\n\nexport function signInNeeded(error: unknown): boolean {\n return (\n error instanceof McpAuthRequiredError || error instanceof McpOAuthAuthorizationRequiredError\n );\n}\n\nexport function errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nexport function isTransient(error: unknown): boolean {\n if (error instanceof McpHttpError)\n return (\n error.status === 408 || error.status === 429 || (error.status >= 500 && error.status !== 501)\n );\n return error instanceof TypeError;\n}\n\nexport function isMcpApp(item: { uri?: string; uriTemplate?: string; mimeType?: string }): boolean {\n const uri = item.uri ?? item.uriTemplate ?? '';\n return uri.startsWith('ui://') || /;\\s*profile\\s*=\\s*\"?mcp-app\"?/i.test(item.mimeType ?? '');\n}\n\nasync function withoutTemplates<T>(list: () => Promise<T>, empty: T): Promise<T> {\n try {\n return await list();\n } catch (error) {\n if (error instanceof McpError && error.code === JSON_RPC_ERROR_CODES.methodNotFound)\n return empty;\n throw error;\n }\n}\n\nconst sleep = (ms: number, signal: AbortSignal) =>\n new Promise<void>((resolve) => {\n const timer = setTimeout(resolve, ms);\n signal.addEventListener(\n 'abort',\n () => {\n clearTimeout(timer);\n resolve();\n },\n { once: true }\n );\n });\n\nexport interface ConnectionOptions {\n entry: McpServerEntry;\n version: string;\n transport: TransportFactory;\n onTools: (connection: McpServerConnection) => void;\n onChange?: (connection: McpServerConnection) => void;\n onLog?: (connection: McpServerConnection, params: unknown) => void;\n}\n\nexport class McpServerConnection {\n readonly entry: McpServerEntry;\n state: ServerState = 'connecting';\n error: string | undefined;\n missing: string[] = [];\n tools: McpTool[] = [];\n hasResources = false;\n resources: Resource[] = [];\n resourceTemplates: ResourceTemplate[] = [];\n instructions: string | undefined;\n #client: McpClient | undefined;\n #opening: Promise<McpClient> | undefined;\n readonly #shutdown = new AbortController();\n readonly #busy = new Map<McpClient, number>();\n #seen = false;\n readonly #expired = new Set<McpClient>();\n readonly #options: ConnectionOptions;\n\n constructor(options: ConnectionOptions) {\n this.entry = options.entry;\n this.#options = options;\n }\n\n get name(): string {\n return this.entry.name;\n }\n\n get timeoutMs(): number {\n return (this.entry.config.timeout ?? DEFAULT_TIMEOUT_SECONDS) * 1000;\n }\n\n get live(): boolean {\n return this.state === 'connected' || (this.state === 'connecting' && this.#seen);\n }\n\n get closed(): boolean {\n return this.#shutdown.signal.aborted;\n }\n\n getClient(): Promise<McpClient> {\n if (this.closed) return Promise.reject(new Error(`MCP server \"${this.name}\" is shut down`));\n if (this.#client?.connectionState === 'connected') return Promise.resolve(this.#client);\n this.#opening ??= this.#open().finally(() => {\n this.#opening = undefined;\n });\n return this.#opening;\n }\n\n callTool(\n name: string,\n args: Record<string, unknown>,\n options: McpRequestOptions\n ): Promise<CallToolResult> {\n return this.#with((client) => client.callTool(name, args, options));\n }\n\n readResource(uri: string, options: McpRequestOptions): Promise<ReadResourceResult> {\n return this.#with((client) => client.readResource(uri, options), true);\n }\n\n resourcesPage(\n cursor: string | undefined,\n options: McpRequestOptions\n ): Promise<ListResourcesResult> {\n return this.#with((client) => client.listResourcesPage(cursor, options), true);\n }\n\n resourceTemplatesPage(\n cursor: string | undefined,\n options: McpRequestOptions\n ): Promise<ListResourceTemplatesResult> {\n return this.#with(\n (client) =>\n withoutTemplates(() => client.listResourceTemplatesPage(cursor, options), {\n resourceTemplates: [],\n }),\n true\n );\n }\n\n allResources(options: McpRequestOptions): Promise<Resource[]> {\n return this.#with((client) => client.listResources(options), true);\n }\n\n allResourceTemplates(options: McpRequestOptions): Promise<ResourceTemplate[]> {\n return this.#with(\n (client) => withoutTemplates(() => client.listResourceTemplates(options), []),\n true\n );\n }\n\n async #with<T>(run: (client: McpClient) => Promise<T>, readOnly = false): Promise<T> {\n for (let attempt = 1; ; attempt++) {\n const client = await this.getClient();\n this.#busy.set(client, (this.#busy.get(client) ?? 0) + 1);\n try {\n return await run(client);\n } catch (error) {\n if (readOnly && attempt === 1 && error instanceof McpHttpError && isTransient(error)) {\n await sleep(CONNECT_RETRY_DELAYS_MS[0] as number, this.#shutdown.signal);\n continue;\n }\n if (error instanceof McpSessionExpiredError && attempt === 1) {\n if (this.#client === client) {\n this.#client = undefined;\n this.#expired.add(client);\n }\n continue;\n }\n if (!signInNeeded(error)) throw error;\n await this.#drop(client);\n this.#mark('needs-auth');\n throw new Error(this.signInMessage());\n } finally {\n this.#release(client);\n }\n }\n }\n\n #release(client: McpClient): void {\n const left = (this.#busy.get(client) as number) - 1;\n this.#busy.set(client, left);\n if (left > 0 || !this.#expired.delete(client)) return;\n this.#busy.delete(client);\n void this.#drop(client);\n }\n\n signInMessage(): string {\n return usesOAuth(this.entry.config) && !secretNames(this.entry.config).length\n ? `MCP server \"${this.name}\" needs you to sign in. Sign in under Settings \u203A MCP servers.`\n : `MCP server \"${this.name}\" rejected its token (401). Update it in Settings \u203A MCP servers.`;\n }\n\n #mark(state: ServerState, error?: string): void {\n this.state = state;\n this.error = error;\n this.#options.onChange?.(this);\n }\n\n async #drop(client: McpClient): Promise<void> {\n if (this.#client === client) this.#client = undefined;\n await client.close().catch(() => undefined);\n }\n\n async #open(): Promise<McpClient> {\n this.#mark('connecting');\n for (let attempt = 0; ; attempt++) {\n try {\n return await this.#connectOnce();\n } catch (error) {\n const delay = CONNECT_RETRY_DELAYS_MS[attempt];\n if (this.closed || delay === undefined || !isTransient(error)) throw this.#failed(error);\n await sleep(delay, this.#shutdown.signal);\n if (this.closed) throw this.#failed(error);\n }\n }\n }\n\n async #connectOnce(): Promise<McpClient> {\n const made = await this.#options.transport(this.entry);\n if ('missing' in made) {\n this.missing = made.missing;\n throw new MissingSecret(made.missing);\n }\n const client = new McpClient({\n name: CLIENT_NAME,\n version: this.#options.version,\n requestTimeoutMs: this.timeoutMs,\n });\n const log = this.#options.onLog;\n if (log) client.onNotification('notifications/message', (params) => log(this, params));\n let closing: Promise<void> | undefined;\n const closeClient = () => {\n closing ??= client.close().catch(() => undefined);\n return closing;\n };\n this.#shutdown.signal.addEventListener('abort', closeClient, { once: true });\n try {\n await client.connect(made.transport);\n client.onNotification('notifications/tools/list_changed', () => {\n void this.#refreshTools(client);\n });\n client.onNotification('notifications/resources/list_changed', () => {\n void this.#refreshResources(client);\n });\n const hasResources = client.serverCapabilities?.resources !== undefined;\n const [tools, resources] = await Promise.all([\n client.serverCapabilities?.tools ? client.listTools() : [],\n hasResources ? this.#fetchResources(client) : { resources: [], resourceTemplates: [] },\n ]);\n if (this.closed) throw new Error('shut down while connecting');\n if (client.connectionState !== 'connected') throw new Error('connection closed during setup');\n this.#client = client;\n this.tools = tools;\n this.hasResources = hasResources;\n this.resources = resources.resources;\n this.resourceTemplates = resources.resourceTemplates;\n this.instructions = client.instructions?.trim() || undefined;\n this.missing = [];\n this.#seen = true;\n this.state = 'connected';\n this.error = undefined;\n this.#options.onTools(this);\n this.#options.onChange?.(this);\n return client;\n } catch (error) {\n await closeClient();\n throw error;\n } finally {\n this.#shutdown.signal.removeEventListener('abort', closeClient);\n }\n }\n\n async #fetchResources(client: McpClient) {\n const [resources, resourceTemplates] = await Promise.all([\n client.listResources().catch(() => [] as Resource[]),\n withoutTemplates(() => client.listResourceTemplates(), [] as ResourceTemplate[]).catch(\n () => [] as ResourceTemplate[]\n ),\n ]);\n return {\n resources: resources.filter((resource) => !isMcpApp(resource)),\n resourceTemplates: resourceTemplates.filter((template) => !isMcpApp(template)),\n };\n }\n\n #failed(error: unknown): Error {\n if (error instanceof MissingSecret) {\n this.#mark('needs-secret');\n return new Error(error.message);\n }\n if (signInNeeded(error) && !this.closed) {\n this.#mark('needs-auth');\n return new Error(this.signInMessage());\n }\n this.#mark(this.closed ? 'closed' : 'failed', errorMessage(error));\n return new Error(`MCP server \"${this.name}\" failed to connect: ${this.error}`);\n }\n\n async #refreshTools(client: McpClient): Promise<void> {\n try {\n const tools = await client.listTools();\n if (this.#client !== client || this.closed) return;\n this.tools = tools;\n this.#options.onTools(this);\n } catch (error) {\n this.error = `Failed to refresh tools: ${errorMessage(error)}`;\n }\n this.#options.onChange?.(this);\n }\n\n async #refreshResources(client: McpClient): Promise<void> {\n const { resources, resourceTemplates } = await this.#fetchResources(client);\n if (this.#client !== client || this.closed) return;\n this.resources = resources;\n this.resourceTemplates = resourceTemplates;\n this.#options.onTools(this);\n this.#options.onChange?.(this);\n }\n\n async close(): Promise<void> {\n this.#shutdown.abort();\n this.state = 'closed';\n this.#options.onChange?.(this);\n const client = this.#client;\n this.#client = undefined;\n await Promise.allSettled([client?.close(), this.#opening]);\n }\n}\n\nexport class MissingSecret extends Error {\n readonly names: string[];\n\n constructor(names: string[]) {\n super(\n `needs ${names.map((name) => `\\${${name}}`).join(', ')}: add the value in Settings \u203A MCP servers`\n );\n this.names = names;\n }\n}\n"],
5
+ "mappings": "AAAA;AAAA,EAEE;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,OAMK;AACP,SAAS,0CAA0C;AACnD,SAAS,yBAA8C,iBAAiB;AACxE,SAAS,mBAAmB;AAcrB,MAAM,0BAA0B,CAAC,KAAK,GAAK;AAC3C,MAAM,cAAc;AAEpB,SAAS,aAAa,OAAyB;AACpD,SACE,iBAAiB,wBAAwB,iBAAiB;AAE9D;AAEO,SAAS,aAAa,OAAwB;AACnD,SAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D;AAEO,SAAS,YAAY,OAAyB;AACnD,MAAI,iBAAiB;AACnB,WACE,MAAM,WAAW,OAAO,MAAM,WAAW,OAAQ,MAAM,UAAU,OAAO,MAAM,WAAW;AAE7F,SAAO,iBAAiB;AAC1B;AAEO,SAAS,SAAS,MAA0E;AACjG,QAAM,MAAM,KAAK,OAAO,KAAK,eAAe;AAC5C,SAAO,IAAI,WAAW,OAAO,KAAK,iCAAiC,KAAK,KAAK,YAAY,EAAE;AAC7F;AAEA,eAAe,iBAAoB,MAAwB,OAAsB;AAC/E,MAAI;AACF,WAAO,MAAM,KAAK;AAAA,EACpB,SAAS,OAAO;AACd,QAAI,iBAAiB,YAAY,MAAM,SAAS,qBAAqB;AACnE,aAAO;AACT,UAAM;AAAA,EACR;AACF;AAEA,MAAM,QAAQ,CAAC,IAAY,WACzB,IAAI,QAAc,CAAC,YAAY;AAC7B,QAAM,QAAQ,WAAW,SAAS,EAAE;AACpC,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AACJ,mBAAa,KAAK;AAClB,cAAQ;AAAA,IACV;AAAA,IACA,EAAE,MAAM,KAAK;AAAA,EACf;AACF,CAAC;AAWI,MAAM,oBAAoB;AAAA,EACtB;AAAA,EACT,QAAqB;AAAA,EACrB;AAAA,EACA,UAAoB,CAAC;AAAA,EACrB,QAAmB,CAAC;AAAA,EACpB,eAAe;AAAA,EACf,YAAwB,CAAC;AAAA,EACzB,oBAAwC,CAAC;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACS,YAAY,IAAI,gBAAgB;AAAA,EAChC,QAAQ,oBAAI,IAAuB;AAAA,EAC5C,QAAQ;AAAA,EACC,WAAW,oBAAI,IAAe;AAAA,EAC9B;AAAA,EAET,YAAY,SAA4B;AACtC,SAAK,QAAQ,QAAQ;AACrB,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,IAAI,OAAe;AACjB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EAEA,IAAI,YAAoB;AACtB,YAAQ,KAAK,MAAM,OAAO,WAAW,2BAA2B;AAAA,EAClE;AAAA,EAEA,IAAI,OAAgB;AAClB,WAAO,KAAK,UAAU,eAAgB,KAAK,UAAU,gBAAgB,KAAK;AAAA,EAC5E;AAAA,EAEA,IAAI,SAAkB;AACpB,WAAO,KAAK,UAAU,OAAO;AAAA,EAC/B;AAAA,EAEA,YAAgC;AAC9B,QAAI,KAAK,OAAQ,QAAO,QAAQ,OAAO,IAAI,MAAM,eAAe,KAAK,IAAI,gBAAgB,CAAC;AAC1F,QAAI,KAAK,SAAS,oBAAoB,YAAa,QAAO,QAAQ,QAAQ,KAAK,OAAO;AACtF,SAAK,aAAa,KAAK,MAAM,EAAE,QAAQ,MAAM;AAC3C,WAAK,WAAW;AAAA,IAClB,CAAC;AACD,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,SACE,MACA,MACA,SACyB;AACzB,WAAO,KAAK,MAAM,CAAC,WAAW,OAAO,SAAS,MAAM,MAAM,OAAO,CAAC;AAAA,EACpE;AAAA,EAEA,aAAa,KAAa,SAAyD;AACjF,WAAO,KAAK,MAAM,CAAC,WAAW,OAAO,aAAa,KAAK,OAAO,GAAG,IAAI;AAAA,EACvE;AAAA,EAEA,cACE,QACA,SAC8B;AAC9B,WAAO,KAAK,MAAM,CAAC,WAAW,OAAO,kBAAkB,QAAQ,OAAO,GAAG,IAAI;AAAA,EAC/E;AAAA,EAEA,sBACE,QACA,SACsC;AACtC,WAAO,KAAK;AAAA,MACV,CAAC,WACC,iBAAiB,MAAM,OAAO,0BAA0B,QAAQ,OAAO,GAAG;AAAA,QACxE,mBAAmB,CAAC;AAAA,MACtB,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA,EAEA,aAAa,SAAiD;AAC5D,WAAO,KAAK,MAAM,CAAC,WAAW,OAAO,cAAc,OAAO,GAAG,IAAI;AAAA,EACnE;AAAA,EAEA,qBAAqB,SAAyD;AAC5E,WAAO,KAAK;AAAA,MACV,CAAC,WAAW,iBAAiB,MAAM,OAAO,sBAAsB,OAAO,GAAG,CAAC,CAAC;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,MAAS,KAAwC,WAAW,OAAmB;AACnF,aAAS,UAAU,KAAK,WAAW;AACjC,YAAM,SAAS,MAAM,KAAK,UAAU;AACpC,WAAK,MAAM,IAAI,SAAS,KAAK,MAAM,IAAI,MAAM,KAAK,KAAK,CAAC;AACxD,UAAI;AACF,eAAO,MAAM,IAAI,MAAM;AAAA,MACzB,SAAS,OAAO;AACd,YAAI,YAAY,YAAY,KAAK,iBAAiB,gBAAgB,YAAY,KAAK,GAAG;AACpF,gBAAM,MAAM,wBAAwB,CAAC,GAAa,KAAK,UAAU,MAAM;AACvE;AAAA,QACF;AACA,YAAI,iBAAiB,0BAA0B,YAAY,GAAG;AAC5D,cAAI,KAAK,YAAY,QAAQ;AAC3B,iBAAK,UAAU;AACf,iBAAK,SAAS,IAAI,MAAM;AAAA,UAC1B;AACA;AAAA,QACF;AACA,YAAI,CAAC,aAAa,KAAK,EAAG,OAAM;AAChC,cAAM,KAAK,MAAM,MAAM;AACvB,aAAK,MAAM,YAAY;AACvB,cAAM,IAAI,MAAM,KAAK,cAAc,CAAC;AAAA,MACtC,UAAE;AACA,aAAK,SAAS,MAAM;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,SAAS,QAAyB;AAChC,UAAM,OAAQ,KAAK,MAAM,IAAI,MAAM,IAAe;AAClD,SAAK,MAAM,IAAI,QAAQ,IAAI;AAC3B,QAAI,OAAO,KAAK,CAAC,KAAK,SAAS,OAAO,MAAM,EAAG;AAC/C,SAAK,MAAM,OAAO,MAAM;AACxB,SAAK,KAAK,MAAM,MAAM;AAAA,EACxB;AAAA,EAEA,gBAAwB;AACtB,WAAO,UAAU,KAAK,MAAM,MAAM,KAAK,CAAC,YAAY,KAAK,MAAM,MAAM,EAAE,SACnE,eAAe,KAAK,IAAI,uEACxB,eAAe,KAAK,IAAI;AAAA,EAC9B;AAAA,EAEA,MAAM,OAAoB,OAAsB;AAC9C,SAAK,QAAQ;AACb,SAAK,QAAQ;AACb,SAAK,SAAS,WAAW,IAAI;AAAA,EAC/B;AAAA,EAEA,MAAM,MAAM,QAAkC;AAC5C,QAAI,KAAK,YAAY,OAAQ,MAAK,UAAU;AAC5C,UAAM,OAAO,MAAM,EAAE,MAAM,MAAM,MAAS;AAAA,EAC5C;AAAA,EAEA,MAAM,QAA4B;AAChC,SAAK,MAAM,YAAY;AACvB,aAAS,UAAU,KAAK,WAAW;AACjC,UAAI;AACF,eAAO,MAAM,KAAK,aAAa;AAAA,MACjC,SAAS,OAAO;AACd,cAAM,QAAQ,wBAAwB,OAAO;AAC7C,YAAI,KAAK,UAAU,UAAU,UAAa,CAAC,YAAY,KAAK,EAAG,OAAM,KAAK,QAAQ,KAAK;AACvF,cAAM,MAAM,OAAO,KAAK,UAAU,MAAM;AACxC,YAAI,KAAK,OAAQ,OAAM,KAAK,QAAQ,KAAK;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,eAAmC;AACvC,UAAM,OAAO,MAAM,KAAK,SAAS,UAAU,KAAK,KAAK;AACrD,QAAI,aAAa,MAAM;AACrB,WAAK,UAAU,KAAK;AACpB,YAAM,IAAI,cAAc,KAAK,OAAO;AAAA,IACtC;AACA,UAAM,SAAS,IAAI,UAAU;AAAA,MAC3B,MAAM;AAAA,MACN,SAAS,KAAK,SAAS;AAAA,MACvB,kBAAkB,KAAK;AAAA,IACzB,CAAC;AACD,UAAM,MAAM,KAAK,SAAS;AAC1B,QAAI,IAAK,QAAO,eAAe,yBAAyB,CAAC,WAAW,IAAI,MAAM,MAAM,CAAC;AACrF,QAAI;AACJ,UAAM,cAAc,MAAM;AACxB,kBAAY,OAAO,MAAM,EAAE,MAAM,MAAM,MAAS;AAChD,aAAO;AAAA,IACT;AACA,SAAK,UAAU,OAAO,iBAAiB,SAAS,aAAa,EAAE,MAAM,KAAK,CAAC;AAC3E,QAAI;AACF,YAAM,OAAO,QAAQ,KAAK,SAAS;AACnC,aAAO,eAAe,oCAAoC,MAAM;AAC9D,aAAK,KAAK,cAAc,MAAM;AAAA,MAChC,CAAC;AACD,aAAO,eAAe,wCAAwC,MAAM;AAClE,aAAK,KAAK,kBAAkB,MAAM;AAAA,MACpC,CAAC;AACD,YAAM,eAAe,OAAO,oBAAoB,cAAc;AAC9D,YAAM,CAAC,OAAO,SAAS,IAAI,MAAM,QAAQ,IAAI;AAAA,QAC3C,OAAO,oBAAoB,QAAQ,OAAO,UAAU,IAAI,CAAC;AAAA,QACzD,eAAe,KAAK,gBAAgB,MAAM,IAAI,EAAE,WAAW,CAAC,GAAG,mBAAmB,CAAC,EAAE;AAAA,MACvF,CAAC;AACD,UAAI,KAAK,OAAQ,OAAM,IAAI,MAAM,4BAA4B;AAC7D,UAAI,OAAO,oBAAoB,YAAa,OAAM,IAAI,MAAM,gCAAgC;AAC5F,WAAK,UAAU;AACf,WAAK,QAAQ;AACb,WAAK,eAAe;AACpB,WAAK,YAAY,UAAU;AAC3B,WAAK,oBAAoB,UAAU;AACnC,WAAK,eAAe,OAAO,cAAc,KAAK,KAAK;AACnD,WAAK,UAAU,CAAC;AAChB,WAAK,QAAQ;AACb,WAAK,QAAQ;AACb,WAAK,QAAQ;AACb,WAAK,SAAS,QAAQ,IAAI;AAC1B,WAAK,SAAS,WAAW,IAAI;AAC7B,aAAO;AAAA,IACT,SAAS,OAAO;AACd,YAAM,YAAY;AAClB,YAAM;AAAA,IACR,UAAE;AACA,WAAK,UAAU,OAAO,oBAAoB,SAAS,WAAW;AAAA,IAChE;AAAA,EACF;AAAA,EAEA,MAAM,gBAAgB,QAAmB;AACvC,UAAM,CAAC,WAAW,iBAAiB,IAAI,MAAM,QAAQ,IAAI;AAAA,MACvD,OAAO,cAAc,EAAE,MAAM,MAAM,CAAC,CAAe;AAAA,MACnD,iBAAiB,MAAM,OAAO,sBAAsB,GAAG,CAAC,CAAuB,EAAE;AAAA,QAC/E,MAAM,CAAC;AAAA,MACT;AAAA,IACF,CAAC;AACD,WAAO;AAAA,MACL,WAAW,UAAU,OAAO,CAAC,aAAa,CAAC,SAAS,QAAQ,CAAC;AAAA,MAC7D,mBAAmB,kBAAkB,OAAO,CAAC,aAAa,CAAC,SAAS,QAAQ,CAAC;AAAA,IAC/E;AAAA,EACF;AAAA,EAEA,QAAQ,OAAuB;AAC7B,QAAI,iBAAiB,eAAe;AAClC,WAAK,MAAM,cAAc;AACzB,aAAO,IAAI,MAAM,MAAM,OAAO;AAAA,IAChC;AACA,QAAI,aAAa,KAAK,KAAK,CAAC,KAAK,QAAQ;AACvC,WAAK,MAAM,YAAY;AACvB,aAAO,IAAI,MAAM,KAAK,cAAc,CAAC;AAAA,IACvC;AACA,SAAK,MAAM,KAAK,SAAS,WAAW,UAAU,aAAa,KAAK,CAAC;AACjE,WAAO,IAAI,MAAM,eAAe,KAAK,IAAI,wBAAwB,KAAK,KAAK,EAAE;AAAA,EAC/E;AAAA,EAEA,MAAM,cAAc,QAAkC;AACpD,QAAI;AACF,YAAM,QAAQ,MAAM,OAAO,UAAU;AACrC,UAAI,KAAK,YAAY,UAAU,KAAK,OAAQ;AAC5C,WAAK,QAAQ;AACb,WAAK,SAAS,QAAQ,IAAI;AAAA,IAC5B,SAAS,OAAO;AACd,WAAK,QAAQ,4BAA4B,aAAa,KAAK,CAAC;AAAA,IAC9D;AACA,SAAK,SAAS,WAAW,IAAI;AAAA,EAC/B;AAAA,EAEA,MAAM,kBAAkB,QAAkC;AACxD,UAAM,EAAE,WAAW,kBAAkB,IAAI,MAAM,KAAK,gBAAgB,MAAM;AAC1E,QAAI,KAAK,YAAY,UAAU,KAAK,OAAQ;AAC5C,SAAK,YAAY;AACjB,SAAK,oBAAoB;AACzB,SAAK,SAAS,QAAQ,IAAI;AAC1B,SAAK,SAAS,WAAW,IAAI;AAAA,EAC/B;AAAA,EAEA,MAAM,QAAuB;AAC3B,SAAK,UAAU,MAAM;AACrB,SAAK,QAAQ;AACb,SAAK,SAAS,WAAW,IAAI;AAC7B,UAAM,SAAS,KAAK;AACpB,SAAK,UAAU;AACf,UAAM,QAAQ,WAAW,CAAC,QAAQ,MAAM,GAAG,KAAK,QAAQ,CAAC;AAAA,EAC3D;AACF;AAEO,MAAM,sBAAsB,MAAM;AAAA,EAC9B;AAAA,EAET,YAAY,OAAiB;AAC3B;AAAA,MACE,SAAS,MAAM,IAAI,CAAC,SAAS,MAAM,IAAI,GAAG,EAAE,KAAK,IAAI,CAAC;AAAA,IACxD;AACA,SAAK,QAAQ;AAAA,EACf;AACF;",
6
6
  "names": []
7
7
  }