@fml-inc/fml 0.8.9 → 0.8.10

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.
@@ -19,7 +19,7 @@ import {
19
19
  readObserverAuthToken,
20
20
  readObserverState,
21
21
  recordHookInboxLoss
22
- } from "./chunk-H5LWJ5PH.js";
22
+ } from "./chunk-XB7EIDWY.js";
23
23
  import {
24
24
  resolveRepositoryRootFromCwd,
25
25
  resolveRepositorySlugFromCwd
@@ -231,17 +231,17 @@ function isSubsequentUserPrompt(sessionId, eventSyncId, stateDir = FML_HOOK_CONT
231
231
  }
232
232
  }
233
233
  }
234
- function pathContextWasEmitted(sessionId, filePath, stateDir) {
234
+ function contextWasEmitted(sessionId, contextKey, stateDir) {
235
235
  try {
236
236
  return fs2.existsSync(
237
- markerPath(stateDir, "path", `${sessionId}:${filePath}`)
237
+ markerPath(stateDir, "path", `${sessionId}:${contextKey}`)
238
238
  );
239
239
  } catch {
240
240
  return true;
241
241
  }
242
242
  }
243
- function claimPathContext(sessionId, filePath, stateDir) {
244
- const claim = markerPath(stateDir, "path", `${sessionId}:${filePath}`);
243
+ function claimContextEmission(sessionId, contextKey, stateDir) {
244
+ const claim = markerPath(stateDir, "path", `${sessionId}:${contextKey}`);
245
245
  if (!ensureMarkerDirectory(claim)) return false;
246
246
  try {
247
247
  fs2.writeFileSync(claim, "", { flag: "wx", mode: 384 });
@@ -300,7 +300,7 @@ function canonicalHookContextFilePath(filePath, cwd, repositoryRoot) {
300
300
  return resolved.replace(/\\/g, "/");
301
301
  }
302
302
  function buildServerHookContextRequest(target2, event, stateDir = FML_HOOK_CONTEXT_STATE_DIR, repositoryRoot = null) {
303
- if (target2 !== "claude" && target2 !== "codex" && target2 !== "pi") {
303
+ if (target2 !== "claude" && target2 !== "codex" && target2 !== "pi" && target2 !== "mini-swe-agent") {
304
304
  return null;
305
305
  }
306
306
  if (!event.repository) return null;
@@ -312,6 +312,21 @@ function buildServerHookContextRequest(target2, event, stateDir = FML_HOOK_CONTE
312
312
  injectionId: hookContextInjectionId(target2, event.syncId),
313
313
  nowMs: event.timestampMs
314
314
  };
315
+ if (target2 === "mini-swe-agent") {
316
+ const payload = event.payload;
317
+ if (!payload || typeof payload !== "object" || Array.isArray(payload) || !("prompt" in payload)) {
318
+ return null;
319
+ }
320
+ const prompt = payload.prompt;
321
+ if (event.eventType !== "BeforeModel" || typeof prompt !== "string" || !prompt.trim() || contextWasEmitted(markerSessionId, `model:${event.syncId}`, stateDir)) {
322
+ return null;
323
+ }
324
+ return isSubsequentUserPrompt(markerSessionId, event.syncId, stateDir) ? {
325
+ ...base,
326
+ eventType: "UserPromptSubmit",
327
+ prompt: prompt.slice(0, MAX_PROMPT_CHARS)
328
+ } : { ...base, eventType: "SessionStart" };
329
+ }
315
330
  if (event.eventType === "SessionStart") {
316
331
  return { ...base, eventType: "SessionStart" };
317
332
  }
@@ -336,7 +351,7 @@ function buildServerHookContextRequest(target2, event, stateDir = FML_HOOK_CONTE
336
351
  event.cwd,
337
352
  repositoryRoot
338
353
  );
339
- if (pathContextWasEmitted(
354
+ if (contextWasEmitted(
340
355
  markerSessionId,
341
356
  `${event.repository}:${filePath}`,
342
357
  stateDir
@@ -627,6 +642,9 @@ async function requestServerHookContextInjection(request, destination, opts = {}
627
642
  }
628
643
  }
629
644
  function hookOutput(request, injection) {
645
+ if (request.target === "mini-swe-agent") {
646
+ return { context: injection.additionalContext };
647
+ }
630
648
  return {
631
649
  ...injection.receipt ? { systemMessage: injection.receipt } : {},
632
650
  hookSpecificOutput: {
@@ -652,9 +670,16 @@ async function requestServerHookContext(target2, event, destination, opts = {})
652
670
  opts
653
671
  );
654
672
  if (injection === null) return {};
673
+ if (target2 === "mini-swe-agent" && !claimContextEmission(
674
+ `${target2}:${request.sessionId}`,
675
+ `model:${event.syncId}`,
676
+ stateDir
677
+ )) {
678
+ return {};
679
+ }
655
680
  if (injection.additionalContext === null) {
656
681
  if (request.eventType === "PreToolUse" && request.filePath) {
657
- claimPathContext(
682
+ claimContextEmission(
658
683
  `${target2}:${request.sessionId}`,
659
684
  `${request.repository}:${request.filePath}`,
660
685
  stateDir
@@ -662,7 +687,7 @@ async function requestServerHookContext(target2, event, destination, opts = {})
662
687
  }
663
688
  return {};
664
689
  }
665
- if (request.eventType === "PreToolUse" && request.filePath && !claimPathContext(
690
+ if (request.eventType === "PreToolUse" && request.filePath && !claimContextEmission(
666
691
  `${target2}:${request.sessionId}`,
667
692
  `${request.repository}:${request.filePath}`,
668
693
  stateDir
@@ -681,7 +706,8 @@ var INSTALLED_HOOK_TARGETS = Object.freeze([
681
706
  "claude",
682
707
  "codex",
683
708
  "gemini",
684
- "grok"
709
+ "grok",
710
+ "mini-swe-agent"
685
711
  ]);
686
712
  function parseHookTarget(value) {
687
713
  return INSTALLED_HOOK_TARGETS.includes(
@@ -917,6 +943,8 @@ async function runHookHandlerForOutput(target2, opts = {}) {
917
943
  }
918
944
 
919
945
  // src/hook-handler.ts
920
- var target = parseHookTarget(process.argv[2]);
946
+ var target = parseHookTarget(
947
+ process.argv[2] === "hook" ? process.argv[3] === "--target" && process.argv.length === 5 ? process.argv[4] : void 0 : process.argv[2]
948
+ );
921
949
  var output = target ? await runHookHandlerForOutput(target).catch(() => ({})) : {};
922
950
  process.stdout.write(JSON.stringify(output));
@@ -309,7 +309,7 @@ function registerTools(server2, environment = getActiveEnv()) {
309
309
  timeRange: z.enum(["1h", "6h", "24h", "7d", "30d"]).optional().describe("Preset time range. Default '7d'."),
310
310
  since: z.string().optional().describe("ISO 8601 start timestamp. Overrides timeRange."),
311
311
  until: z.string().optional().describe("ISO 8601 end timestamp."),
312
- target: z.enum(["claude", "codex", "gemini", "mastra"]).optional().describe("Filter by agent type. Omit for all."),
312
+ target: z.enum(["claude", "codex", "gemini", "mastra", "mini-swe-agent"]).optional().describe("Filter by agent type. Omit for all."),
313
313
  scope: z.enum(["org", "project", "user"]).optional().describe("Query scope. 'org' (default), 'project', or 'user'."),
314
314
  githubUsername: z.string().optional().describe("Required when scope is 'user'. GitHub username.")
315
315
  },
@@ -317,10 +317,10 @@ function registerTools(server2, environment = getActiveEnv()) {
317
317
  );
318
318
  server2.tool(
319
319
  "list_engineering_sessions",
320
- "List agent sessions (Claude Code, Codex, Gemini CLI, Mastra). Each session includes first prompt preview and event counts.",
320
+ "List agent sessions (Claude Code, Codex, Gemini CLI, Mastra, mini-swe-agent). Each session includes first prompt preview and event counts.",
321
321
  {
322
322
  scope: z.enum(["org", "project"]).optional().describe("Query scope. Default 'org'."),
323
- target: z.enum(["claude", "codex", "gemini", "mastra"]).optional().describe("Filter by agent type. Omit for all."),
323
+ target: z.enum(["claude", "codex", "gemini", "mastra", "mini-swe-agent"]).optional().describe("Filter by agent type. Omit for all."),
324
324
  githubUsername: z.string().optional().describe("Filter to sessions by this GitHub username."),
325
325
  timeRange: z.enum(["1h", "6h", "24h", "7d", "30d"]).optional(),
326
326
  since: z.string().optional().describe("ISO 8601 start timestamp."),
@@ -348,7 +348,7 @@ function registerTools(server2, environment = getActiveEnv()) {
348
348
  since: z.string().optional().describe("ISO 8601 start timestamp."),
349
349
  until: z.string().optional().describe("ISO 8601 end timestamp."),
350
350
  groupBy: z.enum(["session", "model", "day", "user"]).optional().describe("How to group results."),
351
- target: z.enum(["claude", "codex", "gemini", "mastra"]).optional().describe("Filter by agent type. Omit for all."),
351
+ target: z.enum(["claude", "codex", "gemini", "mastra", "mini-swe-agent"]).optional().describe("Filter by agent type. Omit for all."),
352
352
  timezone: z.string().optional().describe(
353
353
  "IANA timezone fallback for day grouping when a session's author has no recorded timezone (author-recorded timezones win). Defaults to UTC."
354
354
  ),
@@ -365,7 +365,7 @@ function registerTools(server2, environment = getActiveEnv()) {
365
365
  timeRange: z.enum(["1h", "6h", "24h", "7d", "30d"]).optional(),
366
366
  since: z.string().optional(),
367
367
  until: z.string().optional(),
368
- target: z.enum(["claude", "codex", "gemini", "mastra"]).optional().describe("Filter by agent type. Omit for all."),
368
+ target: z.enum(["claude", "codex", "gemini", "mastra", "mini-swe-agent"]).optional().describe("Filter by agent type. Omit for all."),
369
369
  limit: z.number().optional().describe("Max results (default 20).")
370
370
  },
371
371
  async (args) => handleTool("search-engineering-sessions", args)
@@ -5,7 +5,7 @@ import {
5
5
  isWinShim,
6
6
  quoteWinArg,
7
7
  resolveBin
8
- } from "./chunk-TWJ62CZX.js";
8
+ } from "./chunk-U4BM27VN.js";
9
9
  import {
10
10
  createHookSyncLoop,
11
11
  getActiveHookDestinationBinding
@@ -30,16 +30,16 @@ import {
30
30
  removeObserverStateIfOwned,
31
31
  retireHookInboxEntry,
32
32
  updateObserverState
33
- } from "./chunk-H5LWJ5PH.js";
33
+ } from "./chunk-XB7EIDWY.js";
34
34
  import "./chunk-7V7G7NVF.js";
35
35
  import {
36
36
  ObserverSyncCycleAbortedError,
37
37
  runObserverSyncCycleSubprocess
38
- } from "./chunk-2DGHAVVR.js";
38
+ } from "./chunk-OUXFHL3I.js";
39
39
  import {
40
40
  createCliRawSync,
41
41
  invalidateCliRawSyncDiscoveryCache
42
- } from "./chunk-JPHN4VKM.js";
42
+ } from "./chunk-PTDADW47.js";
43
43
  import "./chunk-F57IFY3K.js";
44
44
  import {
45
45
  FML_OBSERVER_AUTH_TOKEN_FILE,
@@ -225,7 +225,6 @@ var MAX_ERROR_TEXT_BYTES = 1e3;
225
225
  var MAX_REJECTION_REASON_BYTES = 3 * 1024;
226
226
  var MAX_OTLP_RESPONSE_BYTES = 64 * 1024;
227
227
  var MAX_OTLP_UPLOAD_ATTEMPTS = 10;
228
- var MAX_OTLP_RETRY_AGE_MS = 24 * 60 * 6e4;
229
228
  var OUTBOX_BATCH_SIZE = 1;
230
229
  var DRAIN_INTERVAL_MS = 25;
231
230
  function combineWarnings(...warnings) {
@@ -675,6 +674,7 @@ async function runOtlpSyncCycle(opts) {
675
674
  if (totalPending === 0) {
676
675
  return { kind: "drained", pending: 0, uploaded: 0 };
677
676
  }
677
+ const maxAgeMs = opts.database.getOtlpSpoolStatus().maxAgeMs;
678
678
  const destinationResolution = await resolveDestination();
679
679
  if (destinationResolution.kind !== "ready") {
680
680
  return {
@@ -736,7 +736,7 @@ async function runOtlpSyncCycle(opts) {
736
736
  };
737
737
  for (const envelope of envelopes) {
738
738
  if (opts.signal?.aborted) throw opts.signal.reason;
739
- if (cycleStartedAtMs - envelope.capturedAtMs >= MAX_OTLP_RETRY_AGE_MS) {
739
+ if (cycleStartedAtMs - envelope.capturedAtMs >= maxAgeMs) {
740
740
  dropped += opts.database.dropOtlpEnvelopes(
741
741
  destination,
742
742
  [
@@ -1046,6 +1046,17 @@ function parseOtlpSpoolMaxBytes(configured) {
1046
1046
  }
1047
1047
  return bytes;
1048
1048
  }
1049
+ function parseOtlpSpoolMaxAgeMs(configured) {
1050
+ if (configured === void 0) return void 0;
1051
+ const value = configured.trim();
1052
+ const milliseconds = Number(value) * 60 * 60 * 1e3;
1053
+ if (!POSITIVE_INTEGER_PATTERN.test(value) || !Number.isSafeInteger(milliseconds)) {
1054
+ throw new Error(
1055
+ "FML_OTLP_SPOOL_MAX_AGE_HOURS must be a positive safe integer number of hours"
1056
+ );
1057
+ }
1058
+ return milliseconds;
1059
+ }
1049
1060
 
1050
1061
  // src/observer/sync-loop.ts
1051
1062
  var OBSERVER_IDLE_INTERVAL_MS = 5 * 6e4;
@@ -1348,7 +1359,8 @@ var HOOK_INBOX_DRAIN_INTERVAL_MS = 15e3;
1348
1359
  var HOOK_INBOX_DRAIN_BUDGET_MS = 5e3;
1349
1360
  var HOOK_INBOX_DRAIN_ENTRIES = 100;
1350
1361
  var HOOK_INBOX_DRAIN_BULK_ENTRIES = 1e3;
1351
- var HOOK_QUARANTINE_PRUNE_INTERVAL_MS = 5 * 60 * 1e3;
1362
+ var SPOOL_CLEANUP_INTERVAL_MS = 5 * 60 * 1e3;
1363
+ var OTLP_CLEANUP_BATCH_DELAY_MS = 100;
1352
1364
  var OBSERVER_DIRECTORY_LEASE = {
1353
1365
  stateFile: FML_OBSERVER_STATE_FILE,
1354
1366
  lockFile: FML_OBSERVER_LOCK_FILE
@@ -1452,6 +1464,9 @@ var hookQuarantineMaxAgeMs = parseHookQuarantineMaxAgeMs(
1452
1464
  var otlpSpoolMaxBytes = parseOtlpSpoolMaxBytes(
1453
1465
  process.env.FML_OTLP_SPOOL_MAX_BYTES
1454
1466
  );
1467
+ var otlpSpoolMaxAgeMs = parseOtlpSpoolMaxAgeMs(
1468
+ process.env.FML_OTLP_SPOOL_MAX_AGE_HOURS
1469
+ );
1455
1470
  ensureDirs();
1456
1471
  var isolationWarning = observerOnlyOverrideWarning();
1457
1472
  if (isolationWarning) console.warn(isolationWarning);
@@ -1486,6 +1501,7 @@ var fatalShutdownScheduled = false;
1486
1501
  var heartbeatTimer = null;
1487
1502
  var hookInboxDrainTimer = null;
1488
1503
  var hookInboxDrainPromise = null;
1504
+ var otlpPruneTimer = null;
1489
1505
  var hookQuarantinePruneTimer = null;
1490
1506
  var stateUpdateRetryTimer = null;
1491
1507
  var syncLoop = null;
@@ -1510,9 +1526,10 @@ try {
1510
1526
  // FML_STATE_DIR can be caller-managed. Keep SQLite payload files private
1511
1527
  // without changing permissions on the shared parent directory.
1512
1528
  restrictDatabaseDirectory: false,
1529
+ maxOtlpSpoolAgeMs: otlpSpoolMaxAgeMs,
1530
+ maxOtlpSpoolBytes: otlpSpoolMaxBytes,
1513
1531
  ...hookSpoolMaxBytes === void 0 ? {} : { maxHookSpoolBytes: hookSpoolMaxBytes },
1514
- ...hookQuarantineMaxAgeMs === void 0 ? {} : { maxHookQuarantineAgeMs: hookQuarantineMaxAgeMs },
1515
- ...otlpSpoolMaxBytes === void 0 ? {} : { maxOtlpSpoolBytes: otlpSpoolMaxBytes }
1532
+ ...hookQuarantineMaxAgeMs === void 0 ? {} : { maxHookQuarantineAgeMs: hookQuarantineMaxAgeMs }
1516
1533
  });
1517
1534
  } catch (error) {
1518
1535
  removeInitialLeasesBestEffort(initial.instanceId);
@@ -1546,7 +1563,7 @@ var hookRejectionStatus = () => ({
1546
1563
  ...lastRejectedReason !== void 0 ? { lastRejectedReason } : {},
1547
1564
  ...lastRejectedTarget !== void 0 ? { lastRejectedTarget } : {}
1548
1565
  });
1549
- var packageVersion = true ? "0.8.9+6863d154" : "dev";
1566
+ var packageVersion = true ? "0.8.10+45913c27" : "dev";
1550
1567
  var health = () => ({
1551
1568
  status: "ok",
1552
1569
  service: OBSERVER_SERVICE_NAME,
@@ -1611,6 +1628,7 @@ var shutdown = async () => {
1611
1628
  if (heartbeatTimer) clearInterval(heartbeatTimer);
1612
1629
  if (hookInboxDrainTimer) clearInterval(hookInboxDrainTimer);
1613
1630
  if (hookQuarantinePruneTimer) clearInterval(hookQuarantinePruneTimer);
1631
+ if (otlpPruneTimer) clearTimeout(otlpPruneTimer);
1614
1632
  if (stateUpdateRetryTimer) clearTimeout(stateUpdateRetryTimer);
1615
1633
  sessionEndSyncWakeScheduler.stop();
1616
1634
  autoUpdater?.stop();
@@ -1866,8 +1884,30 @@ try {
1866
1884
  } catch (error) {
1867
1885
  scheduleFatalShutdown(error);
1868
1886
  }
1869
- }, HOOK_QUARANTINE_PRUNE_INTERVAL_MS);
1887
+ }, SPOOL_CLEANUP_INTERVAL_MS);
1870
1888
  hookQuarantinePruneTimer.unref();
1889
+ let nextOtlpAgeCheckAtMs = 0;
1890
+ const pruneOtlp = () => {
1891
+ if (shuttingDown) return;
1892
+ try {
1893
+ const nowMs = Date.now();
1894
+ let removed = 0;
1895
+ if (nowMs >= nextOtlpAgeCheckAtMs) {
1896
+ removed = database.pruneExpiredOtlpEnvelopes(nowMs);
1897
+ if (removed < 100)
1898
+ nextOtlpAgeCheckAtMs = nowMs + SPOOL_CLEANUP_INTERVAL_MS;
1899
+ }
1900
+ if (removed === 0) removed = database.pruneOtlpCapacity(nowMs);
1901
+ otlpPruneTimer = setTimeout(
1902
+ pruneOtlp,
1903
+ removed > 0 ? OTLP_CLEANUP_BATCH_DELAY_MS : SPOOL_CLEANUP_INTERVAL_MS
1904
+ );
1905
+ otlpPruneTimer.unref();
1906
+ } catch (error) {
1907
+ scheduleFatalShutdown(error);
1908
+ }
1909
+ };
1910
+ pruneOtlp();
1871
1911
  hookSyncLoop = createHookSyncLoop({
1872
1912
  database,
1873
1913
  version: packageVersion
@@ -1776,7 +1776,8 @@ var HOOK_TARGETS = Object.freeze([
1776
1776
  "codex",
1777
1777
  "gemini",
1778
1778
  "grok",
1779
- "pi"
1779
+ "pi",
1780
+ "mini-swe-agent"
1780
1781
  ]);
1781
1782
 
1782
1783
  // ../../packages/agent-targets/src/catalog/hook-events.json
@@ -1853,6 +1854,14 @@ var hook_events_default = {
1853
1854
  "PreCompact",
1854
1855
  "PostCompact",
1855
1856
  "SessionEnd"
1857
+ ],
1858
+ "mini-swe-agent": [
1859
+ "SessionStart",
1860
+ "UserPromptSubmit",
1861
+ "BeforeModel",
1862
+ "PostToolUse",
1863
+ "Stop",
1864
+ "SessionEnd"
1856
1865
  ]
1857
1866
  };
1858
1867
 
@@ -1870,6 +1879,9 @@ var GROK_HOOK_EVENTS = Object.freeze([
1870
1879
  ...hook_events_default.grok
1871
1880
  ]);
1872
1881
  var PI_HOOK_EVENTS = Object.freeze([...hook_events_default.pi]);
1882
+ var MINI_SWE_AGENT_HOOK_EVENTS = Object.freeze([
1883
+ ...hook_events_default["mini-swe-agent"]
1884
+ ]);
1873
1885
 
1874
1886
  // ../../packages/agent-targets/src/hooks/read-command.ts
1875
1887
  import path2 from "node:path";
@@ -2245,9 +2257,9 @@ function normalizedEvent(target, payload, context) {
2245
2257
  "command"
2246
2258
  );
2247
2259
  const toolName = firstString(payload, ["tool_name", "toolName", "name"]);
2248
- const filePath = firstString(payload, ["file_path", "filePath", "path"]) ?? (toolInput ? firstString(toolInput, ["file_path", "filePath", "path"]) : void 0) ?? (command && toolName && SHELL_TOOL_NAMES.has(toolName.toLowerCase()) ? extractReadFilePathFromCommand(command) ?? void 0 : void 0);
2260
+ const filePath = firstString(payload, ["file_path", "filePath", "path"]) ?? (toolInput ? firstString(toolInput, ["file_path", "filePath", "path"]) : void 0) ?? (target !== "mini-swe-agent" && command && toolName && SHELL_TOOL_NAMES.has(toolName.toLowerCase()) ? extractReadFilePathFromCommand(command) ?? void 0 : void 0);
2249
2261
  const userPrompt = boundedExtractedText(
2250
- firstText(payload, ["prompt", "user_prompt", "userPrompt"]) ?? (target === "gemini" ? geminiUserPrompt(payload) : void 0),
2262
+ target === "mini-swe-agent" && eventType !== "UserPromptSubmit" ? void 0 : firstText(payload, ["prompt", "user_prompt", "userPrompt"]) ?? (target === "gemini" ? geminiUserPrompt(payload) : void 0),
2251
2263
  "user_prompt"
2252
2264
  );
2253
2265
  const plan = boundedExtractedText(firstText(payload, ["plan"]), "plan");
@@ -2303,7 +2315,8 @@ var HOOK_NORMALIZATION_CAPABILITIES = Object.freeze([
2303
2315
  capability("codex", CODEX_HOOK_EVENTS),
2304
2316
  capability("gemini", GEMINI_HOOK_EVENTS),
2305
2317
  capability("grok", GROK_HOOK_EVENTS),
2306
- capability("pi", PI_HOOK_EVENTS)
2318
+ capability("pi", PI_HOOK_EVENTS),
2319
+ capability("mini-swe-agent", MINI_SWE_AGENT_HOOK_EVENTS)
2307
2320
  ]);
2308
2321
 
2309
2322
  // src/hooks/context.ts
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runObserverSyncCycle
4
- } from "./chunk-2DGHAVVR.js";
5
- import "./chunk-JPHN4VKM.js";
4
+ } from "./chunk-OUXFHL3I.js";
5
+ import "./chunk-PTDADW47.js";
6
6
  import "./chunk-F57IFY3K.js";
7
7
  import "./chunk-HDAFEHUY.js";
8
8
  import "./chunk-MLKGABMK.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fml-inc/fml",
3
- "version": "0.8.9",
3
+ "version": "0.8.10",
4
4
  "description": "FML CLI and agent tools",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "type": "module",
@@ -33,7 +33,7 @@
33
33
  "open": "^10.1.0",
34
34
  "ora": "^8.2.0",
35
35
  "picocolors": "^1.1.1",
36
- "smol-toml": "1.7.0",
36
+ "smol-toml": "1.7.1",
37
37
  "zod": "4.1.12"
38
38
  },
39
39
  "devDependencies": {