anpord 0.1.8 → 0.1.9

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/README.md CHANGED
@@ -72,8 +72,8 @@ suites concurrently. Pass files or directories to run a smaller set.
72
72
 
73
73
  ## Mock MCP servers
74
74
 
75
- Define local MCP dependencies once and Anpord gives every OpenCode trial a
76
- fresh stdio server:
75
+ Define local MCP dependencies once and Anpord gives every built-in agent trial
76
+ a fresh stdio server:
77
77
 
78
78
  ```ts
79
79
  import { z } from "zod";
package/dist/cli.cjs CHANGED
@@ -2,14 +2,14 @@
2
2
  const require_client = require("./client-Ci0woWLW.cjs");
3
3
  const require_errors = require("./errors-Boum34f5.cjs");
4
4
  const require_config = require("./config.cjs");
5
- const require_compiler = require("./compiler-DpQHrrv6.cjs");
5
+ const require_compiler = require("./compiler-SWgcA32c.cjs");
6
6
  let _effect_cli = require("@effect/cli");
7
7
  let _effect_platform = require("@effect/platform");
8
8
  let _effect_platform_node = require("@effect/platform-node");
9
9
  let effect = require("effect");
10
10
  let yaml = require("yaml");
11
11
  //#region package.json
12
- var version$1 = "0.1.8";
12
+ var version$1 = "0.1.9";
13
13
  //#endregion
14
14
  //#region ../template/src/extract.ts
15
15
  /**
package/dist/cli.mjs CHANGED
@@ -2,14 +2,14 @@
2
2
  import { a as ChannelName, o as PromptId, s as VersionNumber, t as AnpordApi } from "./client-5K3dMI5Q.mjs";
3
3
  import { i as tokenMatcher, r as asAnpordError } from "./errors-C9bQUcA3.mjs";
4
4
  import { ClientLayer, webUrlConfig } from "./config.mjs";
5
- import { n as compileEvalEffect } from "./compiler-Dj-0uzC6.mjs";
5
+ import { n as compileEvalEffect } from "./compiler-iVu8fped.mjs";
6
6
  import { Args, Command, Options } from "@effect/cli";
7
7
  import { FetchHttpClient, FileSystem, HttpClient, HttpClientError, HttpClientRequest } from "@effect/platform";
8
8
  import { NodeContext, NodeRuntime } from "@effect/platform-node";
9
9
  import { Cause, Clock, Config, Console, Data, Duration, Effect, Layer, Option, ParseResult, Redacted, Ref, Schema } from "effect";
10
10
  import { parseDocument } from "yaml";
11
11
  //#region package.json
12
- var version$1 = "0.1.8";
12
+ var version$1 = "0.1.9";
13
13
  //#endregion
14
14
  //#region ../template/src/extract.ts
15
15
  /**
@@ -10,6 +10,7 @@ let node_os = require("node:os");
10
10
  let node_child_process = require("node:child_process");
11
11
  let node_util = require("node:util");
12
12
  let node_zlib = require("node:zlib");
13
+ let smol_toml = require("smol-toml");
13
14
  //#region src/evals/eval-bundle.ts
14
15
  const authoringExports = ["export const defineEval = value => value;", `export { empty, files, repo } from "./source";`].join("\n");
15
16
  const authoringDir = (0, node_path.dirname)((0, node_url.fileURLToPath)(require("url").pathToFileURL(__filename).href));
@@ -232,7 +233,15 @@ const loadDefinition = (entry) => bundle(definitionEntry(entry), entry).pipe(eff
232
233
  force: true,
233
234
  recursive: true
234
235
  })).pipe(effect.Effect.ignore))));
235
- const isDefinition = (value) => typeof value === "object" && value !== null && typeof value.name === "string" && typeof value.prompt === "string" && Array.isArray(value.cases) && Array.isArray(value.tasks) && Number.isInteger(value.trials);
236
+ const DefinitionShape = effect.Schema.Struct({
237
+ cases: effect.Schema.Array(effect.Schema.Unknown),
238
+ name: effect.Schema.String,
239
+ prompt: effect.Schema.String,
240
+ tasks: effect.Schema.Array(effect.Schema.Unknown),
241
+ trials: effect.Schema.Int
242
+ });
243
+ const decodeShape = effect.Schema.decodeUnknownOption(DefinitionShape);
244
+ const isDefinition = (value) => effect.Option.isSome(decodeShape(value));
236
245
  //#endregion
237
246
  //#region src/evals/local-repo.ts
238
247
  const run = (0, node_util.promisify)(node_child_process.execFile);
@@ -268,13 +277,111 @@ const localRepo = (cwd) => effect.Effect.gen(function* () {
268
277
  });
269
278
  }).pipe(effect.Effect.withSpan("Eval.localRepo"));
270
279
  //#endregion
271
- //#region src/evals/mcp-profile.ts
272
- const CHUNK_SIZE = 9e4;
280
+ //#region src/evals/mcp-harness.ts
273
281
  const Entries = effect.Schema.Record({
274
282
  key: effect.Schema.String,
275
283
  value: effect.Schema.Unknown
276
284
  });
277
- const OpenCodeConfig = effect.Schema.parseJson(effect.Schema.Struct({ mcp: effect.Schema.optional(Entries) }, Entries));
285
+ const JsonConfig = effect.Schema.parseJson(effect.Schema.Struct({
286
+ mcp: effect.Schema.optional(Entries),
287
+ mcpServers: effect.Schema.optional(Entries)
288
+ }, Entries));
289
+ const CodexConfig = effect.Schema.Struct({ mcp_servers: effect.Schema.optional(Entries) }, Entries);
290
+ const relativeEntry = ({ entry }) => entry.slice(10);
291
+ const addServers = (current, harness, servers, configure) => {
292
+ const configured = { ...current };
293
+ for (const server of servers) {
294
+ if (configured[server.name] !== void 0) throw new Error(`${harness} MCP server ${server.name} is already configured`);
295
+ configured[server.name] = configure(server);
296
+ }
297
+ return configured;
298
+ };
299
+ const configureJson = (content, key, harness, servers, configure) => {
300
+ const config = effect.Schema.decodeUnknownSync(JsonConfig)(content);
301
+ return effect.Schema.encodeSync(JsonConfig)({
302
+ ...config,
303
+ [key]: addServers(config[key], harness, servers, configure)
304
+ });
305
+ };
306
+ const jsonAdapter = (harness, path, configure, key = "mcpServers") => ({ apply: (profile, servers) => {
307
+ const files = { ...profile.files };
308
+ files[path] = configureJson(files[path] ?? "{}", key, harness, servers, configure);
309
+ return {
310
+ ...profile,
311
+ files
312
+ };
313
+ } });
314
+ const stdio = (server) => ({
315
+ args: [relativeEntry(server)],
316
+ command: "node"
317
+ });
318
+ const trustedStdio = (server) => ({
319
+ ...stdio(server),
320
+ trust: true
321
+ });
322
+ const claude = jsonAdapter("Claude", "workspace/.mcp.json", stdio);
323
+ const cursor = jsonAdapter("Cursor", "workspace/.cursor/mcp.json", stdio);
324
+ const gemini = jsonAdapter("Gemini", "workspace/.gemini/settings.json", trustedStdio);
325
+ const qwen = jsonAdapter("Qwen", "workspace/.qwen/settings.json", trustedStdio);
326
+ const piBase = jsonAdapter("Pi", "home/.pi/agent/mcp.json", stdio);
327
+ const adapters = {
328
+ claude,
329
+ codex: { apply: (profile, servers) => {
330
+ const path = "home/.codex/config.toml";
331
+ const files = { ...profile.files };
332
+ const config = effect.Schema.decodeUnknownSync(CodexConfig)((0, smol_toml.parse)(files[path] ?? ""));
333
+ files[path] = (0, smol_toml.stringify)({
334
+ ...config,
335
+ mcp_servers: addServers(config.mcp_servers, "Codex", servers, (server) => ({
336
+ ...stdio(server),
337
+ default_tools_approval_mode: "approve",
338
+ required: true
339
+ }))
340
+ });
341
+ return {
342
+ ...profile,
343
+ files
344
+ };
345
+ } },
346
+ command: null,
347
+ cursor,
348
+ fx: jsonAdapter("FX", "home/.fx/mcp.json", (server) => ({
349
+ command: ["node", relativeEntry(server)],
350
+ enabled: true,
351
+ required: true,
352
+ type: "local"
353
+ }), "mcp"),
354
+ gemini,
355
+ opencode: { apply: (profile, servers) => {
356
+ const env = { ...profile.env };
357
+ env.OPENCODE_CONFIG_CONTENT = configureJson(env.OPENCODE_CONFIG_CONTENT ?? "{}", "mcp", "OpenCode", servers, (server) => ({
358
+ command: ["node", relativeEntry(server)],
359
+ enabled: true,
360
+ type: "local"
361
+ }));
362
+ return {
363
+ ...profile,
364
+ env
365
+ };
366
+ } },
367
+ pi: { apply: (profile, servers) => {
368
+ const configured = piBase.apply(profile, servers);
369
+ const install = "~/.local/bin/pi install npm:pi-mcp-adapter@2.32.1";
370
+ return {
371
+ ...configured,
372
+ install: profile.install ? `${profile.install} && ${install}` : install
373
+ };
374
+ } },
375
+ qwen
376
+ };
377
+ const applyMcpHarness = (harness, profile, servers) => {
378
+ const adapter = adapters[harness];
379
+ if (adapter === null) throw new Error(`MCP mock servers are not supported by ${harness}`);
380
+ return effect.Schema.decodeUnknownSync(require_harness_profile.HarnessProfile)(adapter.apply(profile, servers));
381
+ };
382
+ //#endregion
383
+ //#region src/evals/mcp-profile.ts
384
+ const CHUNK_SIZE = 9e4;
278
385
  const packaged = (index, source) => {
279
386
  const root = `workspace/.anpord/mcp/${index}`;
280
387
  const archive = (0, node_zlib.gzipSync)(source).toString("base64");
@@ -297,7 +404,6 @@ const compileMcpServers = (entry, definitions) => effect.Effect.gen(function* ()
297
404
  });
298
405
  const withMcpServers = (task, servers) => {
299
406
  if (servers.length === 0) return task;
300
- if (task.harness !== "opencode") throw new Error(`MCP mock servers are not supported by the ${task.harness} harness`);
301
407
  const profile = task.profile ?? {
302
408
  files: {},
303
409
  name: "anpord-mcp"
@@ -307,28 +413,12 @@ const withMcpServers = (task, servers) => {
307
413
  if (files[path] !== void 0) throw new Error(`Profile file ${path} is reserved for MCP mocks`);
308
414
  files[path] = source;
309
415
  }
310
- const env = { ...profile.env };
311
- const config = effect.Schema.decodeUnknownSync(OpenCodeConfig)(env.OPENCODE_CONFIG_CONTENT ?? "{}");
312
- const mcp = { ...config.mcp };
313
- for (const item of servers) {
314
- if (mcp[item.name] !== void 0) throw new Error(`OpenCode MCP server ${item.name} is already configured`);
315
- mcp[item.name] = {
316
- command: ["node", item.entry.slice(10)],
317
- enabled: true,
318
- type: "local"
319
- };
320
- }
321
- env.OPENCODE_CONFIG_CONTENT = effect.Schema.encodeSync(OpenCodeConfig)({
322
- ...config,
323
- mcp
324
- });
325
416
  return {
326
417
  ...task,
327
- profile: effect.Schema.decodeUnknownSync(require_harness_profile.HarnessProfile)({
418
+ profile: applyMcpHarness(task.harness, {
328
419
  ...profile,
329
- env,
330
420
  files
331
- })
421
+ }, servers)
332
422
  };
333
423
  };
334
424
  //#endregion
@@ -10,6 +10,7 @@ import { tmpdir } from "node:os";
10
10
  import { execFile } from "node:child_process";
11
11
  import { promisify } from "node:util";
12
12
  import { gzipSync } from "node:zlib";
13
+ import { parse, stringify } from "smol-toml";
13
14
  //#region src/evals/eval-bundle.ts
14
15
  const authoringExports = ["export const defineEval = value => value;", `export { empty, files, repo } from "./source";`].join("\n");
15
16
  const authoringDir = dirname(fileURLToPath(import.meta.url));
@@ -232,7 +233,15 @@ const loadDefinition = (entry) => bundle(definitionEntry(entry), entry).pipe(Eff
232
233
  force: true,
233
234
  recursive: true
234
235
  })).pipe(Effect.ignore))));
235
- const isDefinition = (value) => typeof value === "object" && value !== null && typeof value.name === "string" && typeof value.prompt === "string" && Array.isArray(value.cases) && Array.isArray(value.tasks) && Number.isInteger(value.trials);
236
+ const DefinitionShape = Schema.Struct({
237
+ cases: Schema.Array(Schema.Unknown),
238
+ name: Schema.String,
239
+ prompt: Schema.String,
240
+ tasks: Schema.Array(Schema.Unknown),
241
+ trials: Schema.Int
242
+ });
243
+ const decodeShape = Schema.decodeUnknownOption(DefinitionShape);
244
+ const isDefinition = (value) => Option.isSome(decodeShape(value));
236
245
  //#endregion
237
246
  //#region src/evals/local-repo.ts
238
247
  const run = promisify(execFile);
@@ -268,13 +277,111 @@ const localRepo = (cwd) => Effect.gen(function* () {
268
277
  });
269
278
  }).pipe(Effect.withSpan("Eval.localRepo"));
270
279
  //#endregion
271
- //#region src/evals/mcp-profile.ts
272
- const CHUNK_SIZE = 9e4;
280
+ //#region src/evals/mcp-harness.ts
273
281
  const Entries = Schema.Record({
274
282
  key: Schema.String,
275
283
  value: Schema.Unknown
276
284
  });
277
- const OpenCodeConfig = Schema.parseJson(Schema.Struct({ mcp: Schema.optional(Entries) }, Entries));
285
+ const JsonConfig = Schema.parseJson(Schema.Struct({
286
+ mcp: Schema.optional(Entries),
287
+ mcpServers: Schema.optional(Entries)
288
+ }, Entries));
289
+ const CodexConfig = Schema.Struct({ mcp_servers: Schema.optional(Entries) }, Entries);
290
+ const relativeEntry = ({ entry }) => entry.slice(10);
291
+ const addServers = (current, harness, servers, configure) => {
292
+ const configured = { ...current };
293
+ for (const server of servers) {
294
+ if (configured[server.name] !== void 0) throw new Error(`${harness} MCP server ${server.name} is already configured`);
295
+ configured[server.name] = configure(server);
296
+ }
297
+ return configured;
298
+ };
299
+ const configureJson = (content, key, harness, servers, configure) => {
300
+ const config = Schema.decodeUnknownSync(JsonConfig)(content);
301
+ return Schema.encodeSync(JsonConfig)({
302
+ ...config,
303
+ [key]: addServers(config[key], harness, servers, configure)
304
+ });
305
+ };
306
+ const jsonAdapter = (harness, path, configure, key = "mcpServers") => ({ apply: (profile, servers) => {
307
+ const files = { ...profile.files };
308
+ files[path] = configureJson(files[path] ?? "{}", key, harness, servers, configure);
309
+ return {
310
+ ...profile,
311
+ files
312
+ };
313
+ } });
314
+ const stdio = (server) => ({
315
+ args: [relativeEntry(server)],
316
+ command: "node"
317
+ });
318
+ const trustedStdio = (server) => ({
319
+ ...stdio(server),
320
+ trust: true
321
+ });
322
+ const claude = jsonAdapter("Claude", "workspace/.mcp.json", stdio);
323
+ const cursor = jsonAdapter("Cursor", "workspace/.cursor/mcp.json", stdio);
324
+ const gemini = jsonAdapter("Gemini", "workspace/.gemini/settings.json", trustedStdio);
325
+ const qwen = jsonAdapter("Qwen", "workspace/.qwen/settings.json", trustedStdio);
326
+ const piBase = jsonAdapter("Pi", "home/.pi/agent/mcp.json", stdio);
327
+ const adapters = {
328
+ claude,
329
+ codex: { apply: (profile, servers) => {
330
+ const path = "home/.codex/config.toml";
331
+ const files = { ...profile.files };
332
+ const config = Schema.decodeUnknownSync(CodexConfig)(parse(files[path] ?? ""));
333
+ files[path] = stringify({
334
+ ...config,
335
+ mcp_servers: addServers(config.mcp_servers, "Codex", servers, (server) => ({
336
+ ...stdio(server),
337
+ default_tools_approval_mode: "approve",
338
+ required: true
339
+ }))
340
+ });
341
+ return {
342
+ ...profile,
343
+ files
344
+ };
345
+ } },
346
+ command: null,
347
+ cursor,
348
+ fx: jsonAdapter("FX", "home/.fx/mcp.json", (server) => ({
349
+ command: ["node", relativeEntry(server)],
350
+ enabled: true,
351
+ required: true,
352
+ type: "local"
353
+ }), "mcp"),
354
+ gemini,
355
+ opencode: { apply: (profile, servers) => {
356
+ const env = { ...profile.env };
357
+ env.OPENCODE_CONFIG_CONTENT = configureJson(env.OPENCODE_CONFIG_CONTENT ?? "{}", "mcp", "OpenCode", servers, (server) => ({
358
+ command: ["node", relativeEntry(server)],
359
+ enabled: true,
360
+ type: "local"
361
+ }));
362
+ return {
363
+ ...profile,
364
+ env
365
+ };
366
+ } },
367
+ pi: { apply: (profile, servers) => {
368
+ const configured = piBase.apply(profile, servers);
369
+ const install = "~/.local/bin/pi install npm:pi-mcp-adapter@2.32.1";
370
+ return {
371
+ ...configured,
372
+ install: profile.install ? `${profile.install} && ${install}` : install
373
+ };
374
+ } },
375
+ qwen
376
+ };
377
+ const applyMcpHarness = (harness, profile, servers) => {
378
+ const adapter = adapters[harness];
379
+ if (adapter === null) throw new Error(`MCP mock servers are not supported by ${harness}`);
380
+ return Schema.decodeUnknownSync(HarnessProfile)(adapter.apply(profile, servers));
381
+ };
382
+ //#endregion
383
+ //#region src/evals/mcp-profile.ts
384
+ const CHUNK_SIZE = 9e4;
278
385
  const packaged = (index, source) => {
279
386
  const root = `workspace/.anpord/mcp/${index}`;
280
387
  const archive = gzipSync(source).toString("base64");
@@ -297,7 +404,6 @@ const compileMcpServers = (entry, definitions) => Effect.gen(function* () {
297
404
  });
298
405
  const withMcpServers = (task, servers) => {
299
406
  if (servers.length === 0) return task;
300
- if (task.harness !== "opencode") throw new Error(`MCP mock servers are not supported by the ${task.harness} harness`);
301
407
  const profile = task.profile ?? {
302
408
  files: {},
303
409
  name: "anpord-mcp"
@@ -307,28 +413,12 @@ const withMcpServers = (task, servers) => {
307
413
  if (files[path] !== void 0) throw new Error(`Profile file ${path} is reserved for MCP mocks`);
308
414
  files[path] = source;
309
415
  }
310
- const env = { ...profile.env };
311
- const config = Schema.decodeUnknownSync(OpenCodeConfig)(env.OPENCODE_CONFIG_CONTENT ?? "{}");
312
- const mcp = { ...config.mcp };
313
- for (const item of servers) {
314
- if (mcp[item.name] !== void 0) throw new Error(`OpenCode MCP server ${item.name} is already configured`);
315
- mcp[item.name] = {
316
- command: ["node", item.entry.slice(10)],
317
- enabled: true,
318
- type: "local"
319
- };
320
- }
321
- env.OPENCODE_CONFIG_CONTENT = Schema.encodeSync(OpenCodeConfig)({
322
- ...config,
323
- mcp
324
- });
325
416
  return {
326
417
  ...task,
327
- profile: Schema.decodeUnknownSync(HarnessProfile)({
418
+ profile: applyMcpHarness(task.harness, {
328
419
  ...profile,
329
- env,
330
420
  files
331
- })
421
+ }, servers)
332
422
  };
333
423
  };
334
424
  //#endregion
package/dist/eval.cjs CHANGED
@@ -1,4 +1,4 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_compiler = require("./compiler-DpQHrrv6.cjs");
2
+ const require_compiler = require("./compiler-SWgcA32c.cjs");
3
3
  exports.compileEval = require_compiler.compileEval;
4
4
  exports.compileEvalEffect = require_compiler.compileEvalEffect;
package/dist/eval.d.cts CHANGED
@@ -98,7 +98,7 @@ declare const compileEvalEffect: (path: string) => Effect.Effect<{
98
98
  name: string;
99
99
  prompt: string;
100
100
  tasks: {
101
- readonly harness: "cursor" | "codex" | "opencode" | "pi" | "fx" | "claude" | "gemini" | "qwen" | "command";
101
+ readonly harness: "codex" | "opencode" | "pi" | "fx" | "claude" | "gemini" | "qwen" | "cursor" | "command";
102
102
  readonly model: string;
103
103
  readonly profile?: {
104
104
  readonly name: string;
package/dist/eval.d.mts CHANGED
@@ -98,7 +98,7 @@ declare const compileEvalEffect: (path: string) => Effect.Effect<{
98
98
  name: string;
99
99
  prompt: string;
100
100
  tasks: {
101
- readonly harness: "cursor" | "codex" | "opencode" | "pi" | "fx" | "claude" | "gemini" | "qwen" | "command";
101
+ readonly harness: "codex" | "opencode" | "pi" | "fx" | "claude" | "gemini" | "qwen" | "cursor" | "command";
102
102
  readonly model: string;
103
103
  readonly profile?: {
104
104
  readonly name: string;
package/dist/eval.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { n as compileEvalEffect, t as compileEval } from "./compiler-Dj-0uzC6.mjs";
1
+ import { n as compileEvalEffect, t as compileEval } from "./compiler-iVu8fped.mjs";
2
2
  export { compileEval, compileEvalEffect };
package/dist/mcp.cjs CHANGED
@@ -8,12 +8,14 @@ const resource = (definition) => ({
8
8
  ...definition,
9
9
  _tag: "Resource"
10
10
  });
11
+ const SERVER_NAME = /^[A-Za-z0-9_-]{1,64}$/;
11
12
  const unique = (label, values) => {
12
13
  const duplicate = values.find((value, index) => values.indexOf(value) !== index);
13
14
  if (duplicate !== void 0) throw new Error(`Duplicate MCP ${label}: ${duplicate}`);
14
15
  };
15
16
  const server = (definition) => {
16
- if (!(definition.name.trim() && definition.version.trim())) throw new Error("MCP servers need a name and version");
17
+ if (!SERVER_NAME.test(definition.name)) throw new Error("MCP server names need 1-64 letters, digits, underscores, or hyphens");
18
+ if (!definition.version.trim()) throw new Error("MCP servers need a name and version");
17
19
  const resources = definition.resources ?? [];
18
20
  const tools = definition.tools ?? [];
19
21
  unique("tool", tools.map(({ name }) => name));
package/dist/mcp.mjs CHANGED
@@ -7,12 +7,14 @@ const resource = (definition) => ({
7
7
  ...definition,
8
8
  _tag: "Resource"
9
9
  });
10
+ const SERVER_NAME = /^[A-Za-z0-9_-]{1,64}$/;
10
11
  const unique = (label, values) => {
11
12
  const duplicate = values.find((value, index) => values.indexOf(value) !== index);
12
13
  if (duplicate !== void 0) throw new Error(`Duplicate MCP ${label}: ${duplicate}`);
13
14
  };
14
15
  const server = (definition) => {
15
- if (!(definition.name.trim() && definition.version.trim())) throw new Error("MCP servers need a name and version");
16
+ if (!SERVER_NAME.test(definition.name)) throw new Error("MCP server names need 1-64 letters, digits, underscores, or hyphens");
17
+ if (!definition.version.trim()) throw new Error("MCP servers need a name and version");
16
18
  const resources = definition.resources ?? [];
17
19
  const tools = definition.tools ?? [];
18
20
  unique("tool", tools.map(({ name }) => name));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "anpord",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "TypeScript SDK and CLI for coding agent evals and prompt management.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -105,6 +105,7 @@
105
105
  "@modelcontextprotocol/server": "^2.0.0",
106
106
  "effect": "^3.21.2",
107
107
  "esbuild": "^0.25.12",
108
+ "smol-toml": "^1.8.0",
108
109
  "yaml": "^2.9.0"
109
110
  },
110
111
  "bin": {