tegami 0.1.0-beta.4 → 0.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.
@@ -1,4 +1,4 @@
1
- import { C as PublishResult, O as DraftPlan, _ as Tegami, t as Awaitable } from "../types-Cx-uvEWw.js";
1
+ import { C as PublishResult, O as DraftPlan, _ as Tegami, t as Awaitable } from "../types-UjsZkz42.js";
2
2
  import { Command } from "commander";
3
3
 
4
4
  //#region src/cli/index.d.ts
package/dist/cli/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { a as changelogFilename, t as assertPublishPlanFinished } from "../checks-BQISvt_o.js";
2
2
  import { n as handlePluginError } from "../error-DBK-9uBa.js";
3
- import { r as formatNpmDistTag, t as bumpDepth } from "../semver-CPtl0XNq.js";
3
+ import { n as formatNpmDistTag } from "../semver-mWK2Khi2.js";
4
4
  import { t as isCI } from "../constants-B9qjNfvr.js";
5
5
  import { mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
6
6
  import path, { basename, isAbsolute, join, normalize, relative, resolve } from "node:path";
@@ -89,8 +89,7 @@ async function buildPrPreview(context, draft, options = {}) {
89
89
  const pullRequest = await resolvePullRequest(context, options);
90
90
  const tegamiCommand = await formatRunScriptCommand(context.cwd, "tegami", context.options.npm?.client);
91
91
  const prChangelogFiles = await listPullRequestChangelogFiles(context, pullRequest.baseSha, pullRequest.headSha);
92
- const changelogDir = relative(context.cwd, context.changelogDir) || ".tegami";
93
- const createLink = createChangelogUrl(pullRequest.headRepo, pullRequest.headRef, changelogDir, changelogFilename());
92
+ const createLink = createChangelogUrl(context, pullRequest.headRepo, pullRequest.headRef, changelogFilename());
94
93
  const lines = [
95
94
  "### Tegami",
96
95
  "",
@@ -270,9 +269,9 @@ async function listPullRequestChangelogFiles(context, baseSha, headSha) {
270
269
  }
271
270
  return files;
272
271
  }
273
- function createChangelogUrl(repo, branch, changelogDir, filename) {
274
- const segments = [...changelogDir.split("/").filter(Boolean), filename].map((part) => encodeURIComponent(part));
275
- return `https://github.com/${repo}/new/${branch.split("/").map(encodeURIComponent).join("/")}/${segments.join("/")}`;
272
+ function createChangelogUrl(context, repo, branch, filename) {
273
+ const filePath = join(relative(context.cwd, context.changelogDir), filename).replaceAll("\\", "/");
274
+ return `https://github.com/${repo}/new/${branch.split("/").map(encodeURIComponent).join("/")}?${new URLSearchParams({ filename: filePath })}`;
276
275
  }
277
276
  //#endregion
278
277
  //#region src/utils/git-changes.ts
@@ -400,7 +399,7 @@ async function createChangelogs(tegami, _options) {
400
399
  for (const [group, changed] of groups) {
401
400
  const members = group.packages.map(getPackageLabel).join(", ");
402
401
  selectOptions.push({
403
- label: `Group ${group.name}`,
402
+ label: `(Group) ${group.name}`,
404
403
  value: `group:${group.name}`,
405
404
  hint: changed ? `changed · ${members}` : members
406
405
  });
@@ -440,7 +439,8 @@ async function createChangelogs(tegami, _options) {
440
439
  outro("Changelogs ready.");
441
440
  return;
442
441
  }
443
- const type = await select({
442
+ const packageBumpMap = {};
443
+ const bumpType = await select({
444
444
  message: "Select release type",
445
445
  options: [
446
446
  {
@@ -454,10 +454,36 @@ async function createChangelogs(tegami, _options) {
454
454
  {
455
455
  value: "major",
456
456
  label: "major"
457
+ },
458
+ {
459
+ value: "per-package",
460
+ label: "choose per-package"
457
461
  }
458
462
  ]
459
463
  });
460
- if (isCancel(type)) throw new CancelledError();
464
+ if (isCancel(bumpType)) throw new CancelledError();
465
+ if (bumpType === "per-package") for (const pkg of selectedPackages) {
466
+ const bumpType = await select({
467
+ message: `Select release type for "${pkg}"`,
468
+ options: [
469
+ {
470
+ value: "patch",
471
+ label: "patch"
472
+ },
473
+ {
474
+ value: "minor",
475
+ label: "minor"
476
+ },
477
+ {
478
+ value: "major",
479
+ label: "major"
480
+ }
481
+ ]
482
+ });
483
+ if (isCancel(bumpType)) throw new CancelledError();
484
+ packageBumpMap[pkg] = bumpType;
485
+ }
486
+ else for (const pkg of selectedPackages) packageBumpMap[pkg] = bumpType;
461
487
  const message = await multiline({
462
488
  message: "Describe change (Markdown supported, press tab then enter to exit)",
463
489
  placeholder: "The first line is heading\n\nAdditional description.",
@@ -471,9 +497,11 @@ async function createChangelogs(tegami, _options) {
471
497
  const s = spinner();
472
498
  s.start("Creating changelog");
473
499
  await mkdir(context.changelogDir, { recursive: true });
474
- await writeFile(join(context.changelogDir, filename), renderManualChangelog(selectedPackages, type, message.trim()));
500
+ await writeFile(join(context.changelogDir, filename), renderManualChangelog(packageBumpMap, message.trim()));
475
501
  s.stop("Created changelog file");
476
- note(`${filename}\n${selectedPackages.join(", ")}: ${type}`, "Created changelog");
502
+ const notes = [filename];
503
+ for (const pkg of selectedPackages) notes.push(`${pkg}: ${packageBumpMap[pkg]}`);
504
+ note(notes.join("\n"), "Created changelog");
477
505
  outro("Changelog ready.");
478
506
  }
479
507
  async function versionPackages(tegami, options) {
@@ -563,16 +591,13 @@ async function runCleanup(tegami) {
563
591
  }
564
592
  outro(`Publish plan at ${planPath} is still pending. Publish it before cleanup.`);
565
593
  }
566
- function renderManualChangelog(packages, type, message) {
567
- const prefix = "#".repeat(bumpDepth(type));
568
- const packageMap = {};
569
- for (const name of packages) packageMap[name] = type;
594
+ function renderManualChangelog(packageBumpMap, message) {
570
595
  return [
571
596
  "---",
572
- dump({ packages: packageMap }).trim(),
597
+ dump({ packages: packageBumpMap }).trim(),
573
598
  "---",
574
599
  "",
575
- `${prefix} ${message}`,
600
+ `## ${message}`,
576
601
  ""
577
602
  ].join("\n");
578
603
  }
@@ -1,4 +1,4 @@
1
- import { r as LogGenerator } from "../types-Cx-uvEWw.js";
1
+ import { r as LogGenerator } from "../types-UjsZkz42.js";
2
2
 
3
3
  //#region src/generators/simple.d.ts
4
4
  declare function simpleGenerator(): LogGenerator;
@@ -1,4 +1,4 @@
1
- import { i as formatPackageVersion } from "../semver-CPtl0XNq.js";
1
+ import { r as formatPackageVersion } from "../semver-mWK2Khi2.js";
2
2
  //#region src/generators/simple.ts
3
3
  function simpleGenerator() {
4
4
  return { generate({ changelogs, version, packageName, plan }) {
@@ -1,4 +1,4 @@
1
- import { n as bumpVersion } from "./semver-CPtl0XNq.js";
1
+ import { t as bumpVersion } from "./semver-mWK2Khi2.js";
2
2
  //#region src/graph.ts
3
3
  /** Package discovered in the workspace. */
4
4
  var WorkspacePackage = class {
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { C as PublishResult, D as WorkspacePackage, E as PackageGroup, O as DraftPlan, S as PublishOptions, T as PackageGraph, _ as Tegami, a as RegistryClient, b as CreatedChangelog, c as TegamiPluginOption, i as PackageOptions, k as PackagePlan, n as GroupOptions, o as TegamiOptions, r as LogGenerator, s as TegamiPlugin, v as tegami, x as PackagePublishResult, y as CreateChangelogOptions } from "./types-Cx-uvEWw.js";
1
+ import { C as PublishResult, D as WorkspacePackage, E as PackageGroup, O as DraftPlan, S as PublishOptions, T as PackageGraph, _ as Tegami, a as RegistryClient, b as CreatedChangelog, c as TegamiPluginOption, i as PackageOptions, k as PackagePlan, n as GroupOptions, o as TegamiOptions, r as LogGenerator, s as TegamiPlugin, v as tegami, x as PackagePublishResult, y as CreateChangelogOptions } from "./types-UjsZkz42.js";
2
2
  export { type CreateChangelogOptions, type CreatedChangelog, type DraftPlan, type GroupOptions, type LogGenerator, type PackageGraph, type PackageGroup, type PackageOptions, type PackagePlan, type PackagePublishResult, type PublishOptions, type PublishResult, type RegistryClient, Tegami, type TegamiOptions, type TegamiPlugin, type TegamiPluginOption, type WorkspacePackage, tegami };
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { a as changelogFilename, i as readPlanStore, n as publishPlanStatus, r as createPlanStore, t as assertPublishPlanFinished } from "./checks-BQISvt_o.js";
2
2
  import { n as handlePluginError, t as execFailure } from "./error-DBK-9uBa.js";
3
- import { a as maxBump } from "./semver-CPtl0XNq.js";
4
- import { t as PackageGraph } from "./graph-B22NBRUG.js";
3
+ import { i as maxBump } from "./semver-mWK2Khi2.js";
4
+ import { t as PackageGraph } from "./graph-CUgwuRW5.js";
5
5
  import { cargo } from "./providers/cargo.js";
6
6
  import { t as bumpTypeSchema } from "./schemas-CurBAaW5.js";
7
7
  import { npm } from "./providers/npm.js";
@@ -1,4 +1,4 @@
1
- import { s as TegamiPlugin } from "../types-Cx-uvEWw.js";
1
+ import { s as TegamiPlugin } from "../types-UjsZkz42.js";
2
2
 
3
3
  //#region src/plugins/git.d.ts
4
4
  interface GitPluginOptions {
@@ -1,4 +1,4 @@
1
- import { O as DraftPlan, s as TegamiPlugin, t as Awaitable, w as TegamiContext, x as PackagePublishResult } from "../types-Cx-uvEWw.js";
1
+ import { O as DraftPlan, s as TegamiPlugin, t as Awaitable, w as TegamiContext, x as PackagePublishResult } from "../types-UjsZkz42.js";
2
2
  import { GitPluginOptions } from "./git.js";
3
3
 
4
4
  //#region src/plugins/github.d.ts
@@ -1,5 +1,5 @@
1
1
  import { t as execFailure } from "../error-DBK-9uBa.js";
2
- import { i as formatPackageVersion, r as formatNpmDistTag } from "../semver-CPtl0XNq.js";
2
+ import { n as formatNpmDistTag, r as formatPackageVersion } from "../semver-mWK2Khi2.js";
3
3
  import { t as isCI } from "../constants-B9qjNfvr.js";
4
4
  import { git } from "./git.js";
5
5
  import { join, relative } from "node:path";
@@ -1,2 +1,2 @@
1
- import { d as CargoRegistryClient, f as cargo, l as CargoPackage, u as CargoPluginOptions } from "../types-Cx-uvEWw.js";
1
+ import { d as CargoRegistryClient, f as cargo, l as CargoPackage, u as CargoPluginOptions } from "../types-UjsZkz42.js";
2
2
  export { CargoPackage, CargoPluginOptions, CargoRegistryClient, cargo };
@@ -1,10 +1,10 @@
1
1
  import { r as isNodeError } from "../error-DBK-9uBa.js";
2
- import { n as WorkspacePackage } from "../graph-B22NBRUG.js";
2
+ import { n as WorkspacePackage } from "../graph-CUgwuRW5.js";
3
3
  import { readFile, writeFile } from "node:fs/promises";
4
4
  import { join, normalize } from "node:path";
5
5
  import { x } from "tinyexec";
6
+ import initToml, { edit, parse } from "@rainbowatcher/toml-edit-js";
6
7
  import * as semver from "semver";
7
- import { parse as parse$1, stringify } from "smol-toml";
8
8
  import { glob } from "tinyglobby";
9
9
  //#region src/providers/cargo.ts
10
10
  const DEP_FIELDS = [
@@ -15,12 +15,14 @@ const DEP_FIELDS = [
15
15
  var CargoPackage = class extends WorkspacePackage {
16
16
  path;
17
17
  manifest;
18
+ content;
18
19
  workspaceManifest;
19
20
  manager = "cargo";
20
- constructor(path, manifest, workspaceManifest) {
21
+ constructor(path, manifest, content, workspaceManifest) {
21
22
  super();
22
23
  this.path = path;
23
24
  this.manifest = manifest;
25
+ this.content = content;
24
26
  this.workspaceManifest = workspaceManifest;
25
27
  }
26
28
  get name() {
@@ -34,8 +36,15 @@ var CargoPackage = class extends WorkspacePackage {
34
36
  defaults.publish ??= this.packageInfo.publish !== false;
35
37
  return defaults;
36
38
  }
39
+ setVersion(version) {
40
+ this.packageInfo.version = version;
41
+ this.patch("package.version", version);
42
+ }
37
43
  async write() {
38
- await writeFile(join(this.path, "Cargo.toml"), stringify(this.manifest));
44
+ await writeFile(join(this.path, "Cargo.toml"), this.content);
45
+ }
46
+ patch(path, value) {
47
+ this.content = edit(this.content, path, value);
39
48
  }
40
49
  get packageInfo() {
41
50
  this.manifest.package ??= {};
@@ -90,7 +99,7 @@ function cargo({ bumpDep: getBumpDepType = ({ kind }) => {
90
99
  onUpdate({ pkg, plan }) {
91
100
  for (const other of graph.getPackages()) {
92
101
  if (!(other instanceof CargoPackage)) continue;
93
- for (const { table, kind } of dependencyTables(other.manifest)) for (const [rawName, rawSpec] of Object.entries(table)) {
102
+ for (const { table, kind } of dependencyTables(other.manifest, "")) for (const [rawName, rawSpec] of Object.entries(table)) {
94
103
  const spec = parseSpec(rawSpec);
95
104
  if (!spec) continue;
96
105
  const packageName = spec.package ?? rawName;
@@ -114,6 +123,9 @@ function cargo({ bumpDep: getBumpDepType = ({ kind }) => {
114
123
  return {
115
124
  name: "cargo",
116
125
  enforce: "pre",
126
+ async init() {
127
+ await initToml();
128
+ },
117
129
  async resolve() {
118
130
  await discoverCargoPackages(this.cwd, (pkg) => this.graph.add(pkg));
119
131
  },
@@ -129,11 +141,11 @@ function cargo({ bumpDep: getBumpDepType = ({ kind }) => {
129
141
  for (const pkg of graph.getPackages()) {
130
142
  if (!(pkg instanceof CargoPackage)) continue;
131
143
  const plan = draft.getPackagePlan(pkg.id);
132
- if (plan) pkg.packageInfo.version = plan.bumpVersion(pkg);
144
+ if (plan) pkg.setVersion(plan.bumpVersion(pkg));
133
145
  }
134
146
  for (const pkg of graph.getPackages()) {
135
147
  if (!(pkg instanceof CargoPackage)) continue;
136
- for (const { table } of dependencyTables(pkg.manifest)) for (const [rawName, rawSpec] of Object.entries(table)) {
148
+ for (const { table, path: tablePath } of dependencyTables(pkg.manifest, "")) for (const [rawName, rawSpec] of Object.entries(table)) {
137
149
  const spec = parseSpec(rawSpec);
138
150
  if (!spec) continue;
139
151
  const packageName = spec.package ?? rawName;
@@ -142,6 +154,7 @@ function cargo({ bumpDep: getBumpDepType = ({ kind }) => {
142
154
  const result = updateRange(spec.version, linked.version);
143
155
  if (result === false) continue;
144
156
  table[rawName] = spec.setVersion(result);
157
+ pkg.patch(typeof rawSpec === "string" ? `${tablePath}.${rawName}` : `${tablePath}.${rawName}.version`, result);
145
158
  }
146
159
  writes.push(pkg.write());
147
160
  }
@@ -155,8 +168,8 @@ async function discoverCargoPackages(cwd, add) {
155
168
  throw error;
156
169
  });
157
170
  if (!root) return;
158
- addCargoPackage(cwd, root, root, add);
159
- const workspace = tableValue(root.workspace);
171
+ addCargoPackage(cwd, root.manifest, root.content, root.manifest, add);
172
+ const workspace = tableValue(root.manifest.workspace);
160
173
  const members = workspace?.members;
161
174
  if (!workspace || !Array.isArray(members)) return;
162
175
  const exclude = Array.isArray(workspace.exclude) ? workspace.exclude.filter((member) => typeof member === "string") : [];
@@ -165,14 +178,14 @@ async function discoverCargoPackages(cwd, add) {
165
178
  path,
166
179
  manifest
167
180
  })).catch(() => void 0)));
168
- for (const entry of manifests) if (entry) addCargoPackage(entry.path, entry.manifest, root, add);
181
+ for (const entry of manifests) if (entry) addCargoPackage(entry.path, entry.manifest.manifest, entry.manifest.content, root.manifest, add);
169
182
  }
170
- function addCargoPackage(path, manifest, workspaceManifest, add) {
183
+ function addCargoPackage(path, manifest, content, workspaceManifest, add) {
171
184
  const packageInfo = tableValue(manifest.package);
172
185
  const workspacePackage = tableValue(workspaceManifest.workspace)?.package;
173
186
  if (!packageInfo?.name) return;
174
187
  if (!packageInfo.version && !tableValue(workspacePackage)?.version) return;
175
- add(new CargoPackage(path, manifest, workspaceManifest));
188
+ add(new CargoPackage(path, manifest, content, workspaceManifest));
176
189
  }
177
190
  async function expandWorkspaceMembers(cwd, members, exclude) {
178
191
  const paths = members.includes(".") ? [cwd] : [];
@@ -186,24 +199,30 @@ async function expandWorkspaceMembers(cwd, members, exclude) {
186
199
  }));
187
200
  return paths.map(normalize);
188
201
  }
189
- function dependencyTables(manifest) {
202
+ function dependencyTables(manifest, prefix) {
190
203
  const tables = [];
191
204
  for (const field of DEP_FIELDS) {
192
205
  const table = tableValue(manifest[field]);
193
- if (table) tables.push({
194
- kind: field,
195
- table
196
- });
206
+ if (table) {
207
+ const path = prefix ? `${prefix}.${field}` : field;
208
+ tables.push({
209
+ kind: field,
210
+ table,
211
+ path
212
+ });
213
+ }
197
214
  }
198
215
  const target = tableValue(manifest.target);
199
- if (target) for (const targetConfig of Object.values(target)) {
216
+ if (target) for (const [targetKey, targetConfig] of Object.entries(target)) {
200
217
  const targetTable = tableValue(targetConfig);
201
218
  if (!targetTable) continue;
219
+ const targetPath = prefix ? `${prefix}.target.${targetKey}` : `target.${targetKey}`;
202
220
  for (const field of DEP_FIELDS) {
203
221
  const table = tableValue(targetTable[field]);
204
222
  if (table) tables.push({
205
223
  kind: field,
206
- table
224
+ table,
225
+ path: `${targetPath}.${field}`
207
226
  });
208
227
  }
209
228
  }
@@ -228,7 +247,11 @@ function parseSpec(v) {
228
247
  };
229
248
  }
230
249
  async function readCargoManifest(path) {
231
- return parse$1(await readFile(join(path, "Cargo.toml"), "utf8"));
250
+ const content = await readFile(join(path, "Cargo.toml"), "utf8");
251
+ return {
252
+ manifest: parse(content),
253
+ content
254
+ };
232
255
  }
233
256
  function isTableValue(value) {
234
257
  return value !== null && typeof value === "object" && !Array.isArray(value);
@@ -1,2 +1,2 @@
1
- import { g as npm, h as NpmRegistryClient, m as NpmPluginOptions, p as NpmPackage } from "../types-Cx-uvEWw.js";
1
+ import { g as npm, h as NpmRegistryClient, m as NpmPluginOptions, p as NpmPackage } from "../types-UjsZkz42.js";
2
2
  export { NpmPackage, NpmPluginOptions, NpmRegistryClient, npm };
@@ -1,5 +1,5 @@
1
1
  import { r as isNodeError, t as execFailure } from "../error-DBK-9uBa.js";
2
- import { n as WorkspacePackage } from "../graph-B22NBRUG.js";
2
+ import { n as WorkspacePackage } from "../graph-CUgwuRW5.js";
3
3
  import { i as pnpmWorkspaceSchema, r as packageManifestSchema } from "../schemas-CurBAaW5.js";
4
4
  import { readFile, writeFile } from "node:fs/promises";
5
5
  import path from "node:path";
@@ -11,11 +11,6 @@ const WEIGHTS = {
11
11
  minor: 2,
12
12
  patch: 1
13
13
  };
14
- const DEPTH = {
15
- major: 1,
16
- minor: 2,
17
- patch: 3
18
- };
19
14
  const PRE = {
20
15
  major: "premajor",
21
16
  minor: "preminor",
@@ -25,9 +20,6 @@ function maxBump(a, b) {
25
20
  if (WEIGHTS[a] > WEIGHTS[b]) return a;
26
21
  return b;
27
22
  }
28
- function bumpDepth(type) {
29
- return DEPTH[type];
30
- }
31
23
  function bumpVersion(version, type, prerelease) {
32
24
  let next = version;
33
25
  if (prerelease) {
@@ -38,4 +30,4 @@ function bumpVersion(version, type, prerelease) {
38
30
  return next;
39
31
  }
40
32
  //#endregion
41
- export { maxBump as a, formatPackageVersion as i, bumpVersion as n, formatNpmDistTag as r, bumpDepth as t };
33
+ export { maxBump as i, formatNpmDistTag as n, formatPackageVersion as r, bumpVersion as t };
@@ -1,4 +1,3 @@
1
- import { TomlTable } from "smol-toml";
2
1
  import z$1, { z } from "zod";
3
2
  import { AgentName } from "package-manager-detector";
4
3
 
@@ -355,17 +354,24 @@ declare function npm({
355
354
  }?: NpmPluginOptions): TegamiPlugin;
356
355
  //#endregion
357
356
  //#region src/providers/cargo.d.ts
357
+ interface TomlTable {
358
+ [key: string]: TomlValue;
359
+ }
360
+ type TomlValue = string | number | boolean | TomlTable | TomlValue[];
358
361
  declare const DEP_FIELDS: readonly ["dependencies", "dev-dependencies", "build-dependencies"];
359
362
  declare class CargoPackage extends WorkspacePackage {
360
363
  readonly path: string;
361
364
  readonly manifest: TomlTable;
365
+ private content;
362
366
  private readonly workspaceManifest?;
363
367
  readonly manager = "cargo";
364
- constructor(path: string, manifest: TomlTable, workspaceManifest?: TomlTable | undefined);
368
+ constructor(path: string, manifest: TomlTable, content: string, workspaceManifest?: TomlTable | undefined);
365
369
  get name(): string;
366
370
  get version(): string;
367
371
  onPlan(context: TegamiContext): PackagePlan;
372
+ setVersion(version: string): void;
368
373
  write(): Promise<void>;
374
+ patch(path: string, value: unknown): void;
369
375
  get packageInfo(): TomlTable;
370
376
  private get workspaceVersion();
371
377
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tegami",
3
- "version": "0.1.0-beta.4",
3
+ "version": "0.1.0",
4
4
  "description": "Utility for package versioning & publish",
5
5
  "license": "MIT",
6
6
  "author": "Fuma Nama",
@@ -27,13 +27,13 @@
27
27
  },
28
28
  "dependencies": {
29
29
  "@clack/prompts": "^1.5.1",
30
+ "@rainbowatcher/toml-edit-js": "^0.6.5",
30
31
  "commander": "^15.0.0",
31
32
  "js-yaml": "^4.2.0",
32
33
  "mdast-util-from-markdown": "^2.0.3",
33
34
  "mdast-util-to-markdown": "^2.1.2",
34
35
  "package-manager-detector": "^1.6.0",
35
36
  "semver": "^7.8.4",
36
- "smol-toml": "^1.6.1",
37
37
  "tinyexec": "^1.2.4",
38
38
  "tinyglobby": "^0.2.17",
39
39
  "zod": "^4.4.3"