@rendotdev/rig 0.0.17 → 0.0.19

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 (28) hide show
  1. package/README.md +4 -0
  2. package/dist/{run-y66hvyxg.js → cli-113n7c3t.js} +158 -16
  3. package/dist/{cli-ne7ed594.js → cli-13q90bjr.js} +12 -0
  4. package/dist/{cli-vx11bmzr.js → cli-1hm5dxfw.js} +2 -2
  5. package/dist/{cli-dshh1cp9.js → cli-884hpkjc.js} +1 -1
  6. package/dist/cli-es8j6mma.js +226 -0
  7. package/dist/{cli-7zqnqrah.js → cli-f7p31fzm.js} +106 -42
  8. package/dist/{cli-xv4m20sx.js → cli-nk194xv0.js} +198 -71
  9. package/dist/{cli-mswdavqx.js → cli-zgw1jbeg.js} +3 -3
  10. package/dist/{config-24gwe08t.js → config-20f90shh.js} +2 -3
  11. package/dist/{create-59myk91d.js → create-pvym2abv.js} +7 -8
  12. package/dist/cron-aw908dzn.js +18 -0
  13. package/dist/{dev-link-jpte1gq9.js → dev-link-e1mj8w17.js} +7 -4
  14. package/dist/{discover-fd9e6j9j.js → discover-95bpzy46.js} +3 -4
  15. package/dist/{help-6k8m07yv.js → help-qj75r0x3.js} +5 -6
  16. package/dist/{inspect-ks3x7s4n.js → inspect-0ckw7bs5.js} +5 -6
  17. package/dist/list-reekhy3q.js +13 -0
  18. package/dist/{paths-hq1vy0wh.js → paths-3vxw7dek.js} +1 -1
  19. package/dist/{registry-gng9br0x.js → registry-fzc3aeb8.js} +2 -3
  20. package/dist/rig.js +101 -32
  21. package/dist/run-thx15p83.js +13 -0
  22. package/dist/{runtime-comment-gvmkkcyh.js → runtime-comment-07cpchsr.js} +15 -9
  23. package/dist/{sync-zsc35m3f.js → sync-kkqh3axx.js} +33 -16
  24. package/dist/{typecheck-c2k87ppw.js → typecheck-971tmqbp.js} +5 -7
  25. package/dist/{update-check-87p71vrc.js → update-check-dpkh7hc6.js} +8 -5
  26. package/package.json +2 -2
  27. package/dist/cli-aj56a1ja.js +0 -48
  28. package/dist/list-f7r354tq.js +0 -14
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  ToolDiscoveryService
3
- } from "./cli-vx11bmzr.js";
3
+ } from "./cli-1hm5dxfw.js";
4
4
  import {
5
5
  exports_external
6
- } from "./cli-xv4m20sx.js";
6
+ } from "./cli-nk194xv0.js";
7
7
  import {
8
8
  RigError
9
9
  } from "./cli-1c7te5cg.js";
@@ -12,8 +12,6 @@ import {
12
12
  } from "./cli-b7jgjgy7.js";
13
13
 
14
14
  // src/tools/types.ts
15
- var RigSchemaRoleSymbol = Symbol.for("rig.schemaRole");
16
-
17
15
  class CommandIds {
18
16
  static from(tool, command) {
19
17
  return `${tool}.${command}`;
@@ -238,7 +236,7 @@ class RigCommandRunnerRuntime {
238
236
  }
239
237
  async run(options) {
240
238
  const target = this.commandTarget(options);
241
- const { ToolRunner } = await import("./run-y66hvyxg.js");
239
+ const { ToolRunner } = await import("./run-thx15p83.js");
242
240
  const result = await new ToolRunner(this.options).run(target.tool, target.command, {
243
241
  ...this.options,
244
242
  args: options.args,
@@ -272,9 +270,7 @@ class RigToolKitFactory {
272
270
  return {
273
271
  z: exports_external,
274
272
  defineTool: (definition) => definition,
275
- command: (definition) => definition,
276
- input: (value) => this.schema(value, "input"),
277
- output: (value) => this.schema(value, "output"),
273
+ defineCommand: (definition) => definition,
278
274
  run: (options) => new RigCommandRunnerRuntime(this.options).run(options),
279
275
  $: (strings, ...values) => shell.$(strings, ...values),
280
276
  args: () => new RigArgsRuntime,
@@ -282,27 +278,9 @@ class RigToolKitFactory {
282
278
  shell
283
279
  };
284
280
  }
285
- schema(value, role) {
286
- const schema = this.isZodSchema(value) ? value : exports_external.object(value);
287
- const existingRole = schema[RigSchemaRoleSymbol];
288
- if (existingRole === role)
289
- return schema;
290
- Object.defineProperty(schema, RigSchemaRoleSymbol, {
291
- value: role,
292
- configurable: false,
293
- enumerable: false,
294
- writable: false
295
- });
296
- return schema;
297
- }
298
- isZodSchema(value) {
299
- return typeof value === "object" && value !== null && typeof value.safeParse === "function";
300
- }
301
281
  }
302
282
  var rig = new RigToolKitFactory().create();
303
- var command = rig.command;
304
- var input = rig.input;
305
- var output = rig.output;
283
+ var defineCommand = rig.defineCommand;
306
284
  var run = rig.run;
307
285
  var args = rig.args;
308
286
  var paths = rig.paths;
@@ -311,6 +289,9 @@ function createRigToolKit(options = {}) {
311
289
  }
312
290
 
313
291
  // src/tools/loader.ts
292
+ import { existsSync as existsSync2 } from "node:fs";
293
+ import { readFile } from "node:fs/promises";
294
+ import { dirname as dirname2, join as join2 } from "node:path";
314
295
  import { pathToFileURL } from "node:url";
315
296
  class ToolDefinitionValidator {
316
297
  validateToolName(name) {
@@ -346,6 +327,14 @@ class ToolDefinitionValidator {
346
327
  expected: "non-empty string"
347
328
  });
348
329
  }
330
+ if (value.setupDb !== undefined && typeof value.setupDb !== "function") {
331
+ throw new RigError("TOOL_INVALID", `Tool ${value.name} setupDb must be a function.`, {
332
+ expected: "function"
333
+ });
334
+ }
335
+ if (value.env !== undefined) {
336
+ this.validateSchema(value.env, "env", value.name);
337
+ }
349
338
  if (!this.isRecord(value.commands)) {
350
339
  throw new RigError("TOOL_INVALID", `Tool ${value.name} needs a commands object.`, {
351
340
  expected: "object"
@@ -355,8 +344,8 @@ class ToolDefinitionValidator {
355
344
  if (entries.length === 0) {
356
345
  throw new RigError("TOOL_INVALID", `Tool ${value.name} must define at least one command.`);
357
346
  }
358
- for (const [commandName, command2] of entries) {
359
- this.validateCommand(commandName, command2, value.name);
347
+ for (const [commandName, command] of entries) {
348
+ this.validateCommand(commandName, command, value.name);
360
349
  }
361
350
  return value;
362
351
  }
@@ -406,15 +395,8 @@ class ToolDefinitionValidator {
406
395
  }
407
396
  validateSchema(value, role, id) {
408
397
  if (!this.hasSafeParse(value)) {
409
- throw new RigError("TOOL_INVALID", `Command ${id} needs a Rig ${role} schema.`, {
410
- expected: `schema created with rig.${role}(...)`
411
- });
412
- }
413
- const actualRole = value[RigSchemaRoleSymbol];
414
- if (actualRole !== role) {
415
- throw new RigError("TOOL_INVALID", `Command ${id} needs a Rig ${role} schema.`, {
416
- expected: `rig.${role}(...)`,
417
- actual: actualRole ?? "unbranded Zod schema"
398
+ throw new RigError("TOOL_INVALID", `Command ${id} needs a Zod schema for ${role}.`, {
399
+ expected: `rig.z.object({ ... })`
418
400
  });
419
401
  }
420
402
  }
@@ -426,9 +408,90 @@ class ToolDefinitionValidator {
426
408
  }
427
409
  }
428
410
 
411
+ class ToolEnvFileParser {
412
+ parse(source, path) {
413
+ const env = {};
414
+ for (const [index, line] of source.split(/\r?\n/).entries()) {
415
+ const parsed = this.parseLine(line, path, index + 1);
416
+ if (parsed)
417
+ env[parsed.key] = parsed.value;
418
+ }
419
+ return env;
420
+ }
421
+ parseLine(line, path, lineNumber) {
422
+ const trimmed = line.trim();
423
+ if (!trimmed || trimmed.startsWith("#"))
424
+ return;
425
+ const match = /^(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/.exec(trimmed);
426
+ if (!match) {
427
+ throw new RigError("TOOL_INVALID", "Invalid .env line.", {
428
+ path,
429
+ line: lineNumber
430
+ });
431
+ }
432
+ return { key: match[1], value: this.parseValue(match[2]) };
433
+ }
434
+ parseValue(value) {
435
+ const trimmed = value.trim();
436
+ if (trimmed.length < 2)
437
+ return trimmed;
438
+ const quote = trimmed[0];
439
+ if (quote !== '"' && quote !== "'" || trimmed.at(-1) !== quote)
440
+ return trimmed;
441
+ const inner = trimmed.slice(1, -1);
442
+ if (quote === "'")
443
+ return inner;
444
+ return inner.replaceAll("\\n", `
445
+ `).replaceAll("\\r", "\r").replaceAll("\\t", "\t").replaceAll("\\\"", '"').replaceAll("\\\\", "\\");
446
+ }
447
+ }
448
+
449
+ class ToolEnvLoader {
450
+ parser = new ToolEnvFileParser;
451
+ async load(tool, definition) {
452
+ const envPath = join2(dirname2(tool.toolPath), ".env");
453
+ const fileExists = await this.exists(envPath);
454
+ if (!definition.env) {
455
+ if (fileExists) {
456
+ throw new RigError("TOOL_INVALID", `Tool ${definition.name} has .env but no env schema.`, {
457
+ path: envPath
458
+ });
459
+ }
460
+ return {};
461
+ }
462
+ const rawEnv = fileExists ? this.parser.parse(await this.readText(envPath), envPath) : {};
463
+ const result = definition.env.safeParse(rawEnv);
464
+ if (!result.success) {
465
+ throw new RigError("TOOL_INVALID", `Tool ${definition.name} env is invalid.`, {
466
+ path: envPath,
467
+ errors: result.error.flatten()
468
+ });
469
+ }
470
+ return result.data;
471
+ }
472
+ async exists(path) {
473
+ const bunFile = this.bunFile();
474
+ if (bunFile) {
475
+ return bunFile(path).exists();
476
+ }
477
+ return existsSync2(path);
478
+ }
479
+ async readText(path) {
480
+ const bunFile = this.bunFile();
481
+ if (bunFile)
482
+ return bunFile(path).text();
483
+ return readFile(path, "utf8");
484
+ }
485
+ bunFile() {
486
+ const candidate = globalThis.Bun?.file;
487
+ return typeof candidate === "function" ? candidate : undefined;
488
+ }
489
+ }
490
+
429
491
  class ToolLoader {
430
492
  discovery;
431
493
  validator;
494
+ envLoader = new ToolEnvLoader;
432
495
  constructor(options = {}) {
433
496
  this.discovery = new ToolDiscoveryService(options);
434
497
  this.validator = new ToolDefinitionValidator;
@@ -453,7 +516,8 @@ class ToolLoader {
453
516
  const moduleRecord = moduleValue;
454
517
  const definitionValue = await this.evaluateModuleDefault(moduleRecord.default, tool.name);
455
518
  const definition = this.validator.validateToolDefinition(definitionValue, tool.name);
456
- return { name: definition.name, path: tool.toolPath, definition };
519
+ const env = await this.envLoader.load(tool, definition);
520
+ return { name: definition.name, path: tool.toolPath, env, definition };
457
521
  }
458
522
  async evaluateModuleDefault(value, toolName) {
459
523
  const awaitedValue = await Promise.resolve(value);
@@ -475,15 +539,15 @@ class ToolLoader {
475
539
  async loadCommand(toolName, commandName) {
476
540
  const tool = await this.load(toolName);
477
541
  this.validator.validateCommandName(commandName);
478
- const command2 = tool.definition.commands[commandName];
479
- if (!command2) {
542
+ const command = tool.definition.commands[commandName];
543
+ if (!command) {
480
544
  throw new RigError("COMMAND_NOT_FOUND", `Command not found: ${CommandIds.from(toolName, commandName)}`, {
481
545
  tool: toolName,
482
546
  command: commandName,
483
547
  available: Object.keys(tool.definition.commands)
484
548
  });
485
549
  }
486
- return { tool, commandName, command: command2 };
550
+ return { tool, commandName, command };
487
551
  }
488
552
  }
489
553
 
@@ -1,25 +1,71 @@
1
- import {
2
- RigPackageRoot
3
- } from "./cli-aj56a1ja.js";
4
1
  import {
5
2
  RigError
6
3
  } from "./cli-1c7te5cg.js";
7
4
  import {
8
5
  RigPaths
9
- } from "./cli-ne7ed594.js";
6
+ } from "./cli-13q90bjr.js";
10
7
  import {
11
8
  __export
12
9
  } from "./cli-b7jgjgy7.js";
13
10
 
14
11
  // src/config/config.ts
15
- import { mkdir as mkdir2, readFile as readFile2, rename, writeFile as writeFile2 } from "node:fs/promises";
16
- import { existsSync as existsSync2 } from "node:fs";
17
- import { dirname } from "node:path";
12
+ import { mkdir as mkdir3, readFile as readFile3, rename as rename2, writeFile as writeFile3 } from "node:fs/promises";
13
+ import { existsSync as existsSync4 } from "node:fs";
14
+ import { dirname as dirname2 } from "node:path";
18
15
 
19
16
  // src/runtime/support.ts
20
- import { existsSync } from "node:fs";
17
+ import { existsSync as existsSync2 } from "node:fs";
21
18
  import { mkdir, readFile, writeFile } from "node:fs/promises";
22
- import { join } from "node:path";
19
+ import { join as join2 } from "node:path";
20
+
21
+ // src/runtime/package-root.ts
22
+ import { existsSync, realpathSync } from "node:fs";
23
+ import { basename, dirname, join, resolve } from "node:path";
24
+ import { fileURLToPath } from "node:url";
25
+
26
+ class RigPackageRoot {
27
+ static find(metaUrl) {
28
+ if (process.env.RIG_PACKAGE_ROOT)
29
+ return resolve(process.env.RIG_PACKAGE_ROOT);
30
+ const argvRoot = this.fromEntrypoint(process.argv[1]);
31
+ if (argvRoot)
32
+ return argvRoot;
33
+ const execRoot = this.fromEntrypoint(process.execPath);
34
+ if (execRoot)
35
+ return execRoot;
36
+ if (this.isBunBinary(metaUrl))
37
+ return dirname(process.execPath);
38
+ return join(dirname(fileURLToPath(metaUrl)), "..", "..");
39
+ }
40
+ static packageFile(metaUrl, ...parts) {
41
+ return join(this.find(metaUrl), ...parts);
42
+ }
43
+ static isBunBinary(metaUrl) {
44
+ return metaUrl.includes("$bunfs") || metaUrl.includes("~BUN") || metaUrl.includes("%7EBUN");
45
+ }
46
+ static fromEntrypoint(entrypoint) {
47
+ if (!entrypoint)
48
+ return;
49
+ const resolved = this.safeRealpath(entrypoint);
50
+ if (!resolved)
51
+ return;
52
+ const parent = dirname(resolved);
53
+ const parentName = basename(parent);
54
+ if (parentName === "src" || parentName === "dist")
55
+ return dirname(parent);
56
+ return;
57
+ }
58
+ static safeRealpath(pathValue) {
59
+ try {
60
+ return realpathSync(pathValue);
61
+ } catch {
62
+ const absolute = resolve(pathValue);
63
+ return existsSync(absolute) ? absolute : undefined;
64
+ }
65
+ }
66
+ }
67
+
68
+ // src/runtime/support.ts
23
69
  class RuntimeSupport {
24
70
  paths;
25
71
  constructor(options = {}) {
@@ -37,7 +83,7 @@ class RuntimeSupport {
37
83
  }
38
84
  async ensureRegistryTsconfig(registryDir) {
39
85
  await mkdir(registryDir, { recursive: true });
40
- const tsconfigPath = join(registryDir, "tsconfig.json");
86
+ const tsconfigPath = join2(registryDir, "tsconfig.json");
41
87
  const content = this.registryTsconfigSource();
42
88
  const existing = await this.readTextIfExists(tsconfigPath);
43
89
  if (existing !== undefined && !existing.startsWith("// Generated by Rig."))
@@ -62,7 +108,7 @@ class RuntimeSupport {
62
108
  return;
63
109
  return file.text();
64
110
  }
65
- if (!existsSync(path))
111
+ if (!existsSync2(path))
66
112
  return;
67
113
  return readFile(path, "utf8");
68
114
  }
@@ -87,7 +133,6 @@ import type { RigToolDefinition, RigToolFactory, RigToolKit } from "./types";
87
133
  import * as zodModule from ${JSON.stringify(zodImport)};
88
134
 
89
135
  export const z: typeof zodNamespace = (zodModule as any).z ?? zodModule;
90
- export const rigSchemaRoleSymbol = Symbol.for("rig.schemaRole");
91
136
 
92
137
  class RigPathRuntime {
93
138
  home() { return homedir(); }
@@ -193,30 +238,12 @@ class RigCommandRunnerRuntime {
193
238
  }
194
239
  }
195
240
 
196
- function isZodSchema(value) {
197
- return typeof value === "object" && value !== null && typeof value.safeParse === "function";
198
- }
199
-
200
- function schema(value, role) {
201
- const result = isZodSchema(value) ? value : z.object(value);
202
- if (result[rigSchemaRoleSymbol] === role) return result;
203
- Object.defineProperty(result, rigSchemaRoleSymbol, {
204
- value: role,
205
- configurable: false,
206
- enumerable: false,
207
- writable: false,
208
- });
209
- return result;
210
- }
211
-
212
241
  const rigShell = new RigShellRuntime();
213
242
 
214
243
  export const rig: RigToolKit = {
215
244
  z,
216
245
  defineTool: (definition) => definition,
217
- command: (definition) => definition,
218
- input: (value) => schema(value, "input"),
219
- output: (value) => schema(value, "output"),
246
+ defineCommand: (definition) => definition,
220
247
  run: (options) => new RigCommandRunnerRuntime().run(options),
221
248
  $: (strings, ...values) => rigShell.$(strings, ...values),
222
249
  args: () => new RigArgsRuntime(),
@@ -237,24 +264,10 @@ export class RigTool {
237
264
  }
238
265
  typesSource() {
239
266
  return `// Generated by Rig. Safe to overwrite.
267
+ import type { Database } from "bun:sqlite";
240
268
  import type { z } from "zod";
241
269
 
242
- declare const RigInputSchemaBrand: unique symbol;
243
- declare const RigOutputSchemaBrand: unique symbol;
244
-
245
- export type RigInputSchema<T extends z.ZodTypeAny = z.ZodTypeAny> = T & {
246
- readonly [RigInputSchemaBrand]: T;
247
- };
248
-
249
- export type RigOutputSchema<T extends z.ZodTypeAny = z.ZodTypeAny> = T & {
250
- readonly [RigOutputSchemaBrand]: T;
251
- };
252
-
253
- export type RigSchemaFromValue<T extends z.ZodTypeAny | z.ZodRawShape> = T extends z.ZodTypeAny
254
- ? T
255
- : T extends z.ZodRawShape
256
- ? z.ZodObject<T>
257
- : never;
270
+ export type RigSchema = z.ZodTypeAny;
258
271
 
259
272
  export type RigShellOptions = {
260
273
  cwd?: string;
@@ -300,11 +313,17 @@ export type RigRunOptions = {
300
313
  dryRun?: boolean;
301
314
  };
302
315
 
303
- export type RigToolRunContext<Input> = {
316
+ export type RigToolDatabase = Database & {
317
+ readonly path: string;
318
+ migrate(version: number, name: string, sql: string): void;
319
+ };
320
+
321
+ export type RigToolRunContext<Input, Env = unknown> = {
304
322
  input: Input;
305
- env: NodeJS.ProcessEnv;
323
+ env: Env;
324
+ processEnv: NodeJS.ProcessEnv;
306
325
  cwd: string;
307
- shell: RigShell;
326
+ db: RigToolDatabase;
308
327
  rig: RigToolKit;
309
328
  };
310
329
 
@@ -316,28 +335,29 @@ export type RigToolExample<Input = any, Output = any> = {
316
335
  };
317
336
 
318
337
  export type RigCommandDefinition<
319
- Input extends RigInputSchema = RigInputSchema,
320
- Output extends RigOutputSchema = RigOutputSchema,
338
+ Input extends RigSchema = RigSchema,
339
+ Output extends RigSchema = RigSchema,
340
+ Env = unknown,
321
341
  > = {
322
342
  description: string;
323
343
  input: Input;
324
344
  output: Output;
325
345
  examples?: RigToolExample<z.input<Input>, z.output<Output>>[];
326
- run: (ctx: RigToolRunContext<z.output<Input>>) => z.input<Output> | Promise<z.input<Output>>;
346
+ run: (ctx: RigToolRunContext<z.output<Input>, Env>) => z.input<Output> | Promise<z.input<Output>>;
327
347
  };
328
348
 
329
- export type RigToolDefinition = {
349
+ export type RigToolDefinition<Env extends RigSchema = RigSchema> = {
330
350
  name: string;
331
351
  description: string;
332
- commands: Record<string, RigCommandDefinition>;
352
+ env?: Env;
353
+ setupDb?: (db: RigToolDatabase) => void | Promise<void>;
354
+ commands: Record<string, RigCommandDefinition<RigSchema, RigSchema, z.output<Env>>>;
333
355
  };
334
356
 
335
357
  export type RigToolKit = {
336
358
  z: typeof z;
337
359
  defineTool<T extends RigToolDefinition>(definition: T): T;
338
- command<I extends RigInputSchema, O extends RigOutputSchema>(definition: RigCommandDefinition<I, O>): RigCommandDefinition<I, O>;
339
- input<T extends z.ZodTypeAny | z.ZodRawShape>(value: T): RigInputSchema<RigSchemaFromValue<T>>;
340
- output<T extends z.ZodTypeAny | z.ZodRawShape>(value: T): RigOutputSchema<RigSchemaFromValue<T>>;
360
+ defineCommand<I extends RigSchema, O extends RigSchema>(definition: RigCommandDefinition<I, O>): RigCommandDefinition<I, O>;
341
361
  run<T = unknown>(options: RigRunOptions): Promise<T>;
342
362
  $(strings: TemplateStringsArray, ...values: unknown[]): Promise<RigShellResult>;
343
363
  args(): RigArgBuilder;
@@ -375,10 +395,10 @@ ${JSON.stringify({
375
395
  jsx: "preserve",
376
396
  lib: ["ES2023", "DOM"],
377
397
  types: ["bun"],
378
- typeRoots: [join(this.repoRoot(), "node_modules/@types")],
398
+ typeRoots: [join2(this.repoRoot(), "node_modules/@types")],
379
399
  baseUrl: this.repoRoot(),
380
400
  paths: {
381
- zod: [join(this.repoRoot(), "node_modules/zod/index.d.ts")]
401
+ zod: [join2(this.repoRoot(), "node_modules/zod/index.d.ts")]
382
402
  }
383
403
  },
384
404
  files: [this.paths.runtimeGlobalsPath, this.paths.runtimeTypesPath],
@@ -397,6 +417,100 @@ ${JSON.stringify({
397
417
  }
398
418
  }
399
419
 
420
+ // src/config/migration.ts
421
+ import { existsSync as existsSync3 } from "node:fs";
422
+ import { mkdir as mkdir2, readdir, readFile as readFile2, rename, rm, stat, writeFile as writeFile2 } from "node:fs/promises";
423
+ import { join as join3 } from "node:path";
424
+
425
+ class RigDirectoryMigrationService {
426
+ paths;
427
+ constructor(paths) {
428
+ this.paths = paths;
429
+ }
430
+ async migrateIfNeeded() {
431
+ const legacyDir = this.paths.legacyRigDir;
432
+ const currentDir = this.paths.rigDir;
433
+ if (!await this.hasLegacyState(legacyDir))
434
+ return;
435
+ const currentExists = existsSync3(currentDir);
436
+ if (currentExists && !await this.canReplaceCurrentDirectory(currentDir)) {
437
+ return {
438
+ status: "manual",
439
+ legacyDir,
440
+ currentDir,
441
+ configUpdated: false,
442
+ reason: "Rig found data in both the old and new folders."
443
+ };
444
+ }
445
+ if (currentExists)
446
+ await rm(currentDir, { recursive: true, force: true });
447
+ await mkdir2(this.paths.homeDir, { recursive: true });
448
+ await rename(legacyDir, currentDir);
449
+ return {
450
+ status: "migrated",
451
+ legacyDir,
452
+ currentDir,
453
+ configUpdated: await this.rewriteMigratedConfig()
454
+ };
455
+ }
456
+ async hasLegacyState(legacyDir) {
457
+ return await this.directoryExists(legacyDir) && (existsSync3(join3(legacyDir, "rig.json")) || existsSync3(join3(legacyDir, "tools")));
458
+ }
459
+ async canReplaceCurrentDirectory(currentDir) {
460
+ return await this.hasDefaultCurrentConfig(currentDir) && await this.hasEmptyGeneratedRegistry(currentDir) && await this.hasEmptyCronDirectory(currentDir) && await this.hasOnlyGeneratedCurrentEntries(currentDir);
461
+ }
462
+ async hasDefaultCurrentConfig(currentDir) {
463
+ try {
464
+ const parsed = JSON.parse(await readFile2(join3(currentDir, "rig.json"), "utf8"));
465
+ return parsed.version === 1 && parsed.baseRegistryDir === this.paths.defaultBaseRegistryDir && Array.isArray(parsed.customRegistries) && parsed.customRegistries.length === 0 && (parsed.cronJobs === undefined || Array.isArray(parsed.cronJobs) && parsed.cronJobs.length === 0);
466
+ } catch {
467
+ return false;
468
+ }
469
+ }
470
+ async hasEmptyGeneratedRegistry(currentDir) {
471
+ const toolsDir = join3(currentDir, "tools");
472
+ if (!await this.directoryExists(toolsDir))
473
+ return true;
474
+ const entries = await this.visibleEntries(toolsDir);
475
+ return entries.every((entry) => entry === "tsconfig.json");
476
+ }
477
+ async hasEmptyCronDirectory(currentDir) {
478
+ const cronDir = join3(currentDir, "cron");
479
+ if (!await this.directoryExists(cronDir))
480
+ return true;
481
+ return (await this.visibleEntries(cronDir)).length === 0;
482
+ }
483
+ async hasOnlyGeneratedCurrentEntries(currentDir) {
484
+ const entries = await this.visibleEntries(currentDir);
485
+ return entries.every((entry) => ["rig.json", "runtime", "tools", "update-check.json", "cron"].includes(entry));
486
+ }
487
+ async rewriteMigratedConfig() {
488
+ const configPath = this.paths.configPath;
489
+ if (!existsSync3(configPath))
490
+ return false;
491
+ const parsed = JSON.parse(await readFile2(configPath, "utf8"));
492
+ if (!this.isLegacyBaseRegistry(parsed.baseRegistryDir))
493
+ return false;
494
+ parsed.baseRegistryDir = this.paths.defaultBaseRegistryDir;
495
+ await writeFile2(configPath, `${JSON.stringify(parsed, null, 2)}
496
+ `, "utf8");
497
+ return true;
498
+ }
499
+ isLegacyBaseRegistry(value) {
500
+ return typeof value === "string" && (value === this.paths.legacyDefaultBaseRegistryDir || this.paths.resolve(value) === join3(this.paths.legacyRigDir, "tools"));
501
+ }
502
+ async visibleEntries(path) {
503
+ return (await readdir(path)).filter((entry) => entry !== ".DS_Store");
504
+ }
505
+ async directoryExists(path) {
506
+ try {
507
+ return (await stat(path)).isDirectory();
508
+ } catch {
509
+ return false;
510
+ }
511
+ }
512
+ }
513
+
400
514
  // node_modules/zod/v4/classic/external.js
401
515
  var exports_external = {};
402
516
  __export(exports_external, {
@@ -14674,18 +14788,26 @@ function date4(params) {
14674
14788
  // node_modules/zod/v4/classic/external.js
14675
14789
  config(en_default());
14676
14790
  // src/config/schema.ts
14791
+ var RigCronJobSchema = exports_external.object({
14792
+ name: exports_external.string().regex(/^[A-Za-z0-9_-]+$/),
14793
+ command: exports_external.string().min(1),
14794
+ schedule: exports_external.string().min(1),
14795
+ input: exports_external.unknown().optional()
14796
+ });
14677
14797
  var RigConfigSchema = exports_external.object({
14678
14798
  version: exports_external.literal(1),
14679
14799
  baseRegistryDir: exports_external.string().min(1),
14680
- customRegistries: exports_external.array(exports_external.string())
14800
+ customRegistries: exports_external.array(exports_external.string()),
14801
+ cronJobs: exports_external.array(RigCronJobSchema).default([])
14681
14802
  });
14682
14803
 
14683
14804
  class RigConfigDefaults {
14684
14805
  static create() {
14685
14806
  return {
14686
14807
  version: 1,
14687
- baseRegistryDir: "~/.rig/tools",
14688
- customRegistries: []
14808
+ baseRegistryDir: "~/rig/tools",
14809
+ customRegistries: [],
14810
+ cronJobs: []
14689
14811
  };
14690
14812
  }
14691
14813
  }
@@ -14694,25 +14816,30 @@ class RigConfigDefaults {
14694
14816
  class RigConfigStore {
14695
14817
  paths;
14696
14818
  runtimeSupport;
14819
+ migration;
14697
14820
  constructor(options = {}) {
14698
14821
  this.paths = new RigPaths(options);
14699
14822
  this.runtimeSupport = new RuntimeSupport(options);
14700
14823
  }
14824
+ migrationResult() {
14825
+ return this.migration;
14826
+ }
14701
14827
  async ensure() {
14702
- await mkdir2(this.paths.rigDir, { recursive: true });
14703
- if (!existsSync2(this.paths.configPath)) {
14828
+ this.migration = await new RigDirectoryMigrationService(this.paths).migrateIfNeeded();
14829
+ await mkdir3(this.paths.rigDir, { recursive: true });
14830
+ if (!existsSync4(this.paths.configPath)) {
14704
14831
  await this.write(RigConfigDefaults.create());
14705
14832
  }
14706
14833
  const config2 = await this.read();
14707
14834
  const registries2 = this.registryEntries(config2);
14708
- await mkdir2(this.resolvedBaseRegistry(config2), { recursive: true });
14835
+ await mkdir3(this.resolvedBaseRegistry(config2), { recursive: true });
14709
14836
  await this.runtimeSupport.ensure(registries2.map((registry2) => registry2.path));
14710
14837
  return config2;
14711
14838
  }
14712
14839
  async read() {
14713
14840
  let raw;
14714
14841
  try {
14715
- raw = await readFile2(this.paths.configPath, "utf8");
14842
+ raw = await readFile3(this.paths.configPath, "utf8");
14716
14843
  } catch (error51) {
14717
14844
  throw new RigError("CONFIG_INVALID", `Could not read config at ${this.paths.configPath}.`, {
14718
14845
  error: error51
@@ -14737,11 +14864,11 @@ class RigConfigStore {
14737
14864
  if (!result.success) {
14738
14865
  throw new RigError("CONFIG_INVALID", "Rig config is invalid.", result.error.flatten());
14739
14866
  }
14740
- await mkdir2(dirname(this.paths.configPath), { recursive: true });
14867
+ await mkdir3(dirname2(this.paths.configPath), { recursive: true });
14741
14868
  const tmpPath = `${this.paths.configPath}.tmp-${process.pid}`;
14742
- await writeFile2(tmpPath, `${JSON.stringify(result.data, null, 2)}
14869
+ await writeFile3(tmpPath, `${JSON.stringify(result.data, null, 2)}
14743
14870
  `, "utf8");
14744
- await rename(tmpPath, this.paths.configPath);
14871
+ await rename2(tmpPath, this.paths.configPath);
14745
14872
  }
14746
14873
  resolvedBaseRegistry(config2) {
14747
14874
  return this.paths.resolve(config2.baseRegistryDir || this.paths.defaultBaseRegistryDir);
@@ -14757,4 +14884,4 @@ class RigConfigStore {
14757
14884
  }
14758
14885
  }
14759
14886
 
14760
- export { exports_external, RigConfigStore };
14887
+ export { RigPackageRoot, exports_external, RigConfigStore };
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  SchemaRenderer
3
- } from "./cli-dshh1cp9.js";
3
+ } from "./cli-884hpkjc.js";
4
4
  import {
5
5
  CommandIds,
6
6
  ToolLoader
7
- } from "./cli-7zqnqrah.js";
7
+ } from "./cli-f7p31fzm.js";
8
8
  import {
9
9
  ToolDiscoveryService
10
- } from "./cli-vx11bmzr.js";
10
+ } from "./cli-1hm5dxfw.js";
11
11
 
12
12
  // src/tools/list.ts
13
13
  class CommandRunExampleRenderer {
@@ -1,9 +1,8 @@
1
1
  import {
2
2
  RigConfigStore
3
- } from "./cli-xv4m20sx.js";
4
- import"./cli-aj56a1ja.js";
3
+ } from "./cli-nk194xv0.js";
5
4
  import"./cli-1c7te5cg.js";
6
- import"./cli-ne7ed594.js";
5
+ import"./cli-13q90bjr.js";
7
6
  import"./cli-b7jgjgy7.js";
8
7
  export {
9
8
  RigConfigStore