@shibanet0/datamitsu-config 0.0.3-alpha-27 → 0.0.4

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,1090 +0,0 @@
1
- // prettier-ignore
2
- declare global {
3
- /**
4
- * Color functions for terminal output. All functions accept any number of arguments,
5
- * join them with spaces, and return a string with ANSI color codes applied.
6
- * Respects NO_COLOR, FORCE_COLOR, and CLICOLOR environment variables.
7
- * Colors are composable: `colors.bold(colors.red("error"))`.
8
- */
9
- const colors: {
10
- // Background colors
11
- bgBlack(...args: unknown[]): string;
12
- bgBlue(...args: unknown[]): string;
13
- bgCyan(...args: unknown[]): string;
14
- bgGreen(...args: unknown[]): string;
15
- // Bright background colors
16
- bgHiBlack(...args: unknown[]): string;
17
- bgHiBlue(...args: unknown[]): string;
18
- bgHiCyan(...args: unknown[]): string;
19
- bgHiGreen(...args: unknown[]): string;
20
-
21
- bgHiMagenta(...args: unknown[]): string;
22
- bgHiRed(...args: unknown[]): string;
23
- bgHiWhite(...args: unknown[]): string;
24
- bgHiYellow(...args: unknown[]): string;
25
- bgMagenta(...args: unknown[]): string;
26
- bgRed(...args: unknown[]): string;
27
- bgWhite(...args: unknown[]): string;
28
- bgYellow(...args: unknown[]): string;
29
-
30
- // Foreground colors
31
- black(...args: unknown[]): string;
32
- blink(...args: unknown[]): string;
33
- blinkRapid(...args: unknown[]): string;
34
- blue(...args: unknown[]): string;
35
- // Text attributes
36
- bold(...args: unknown[]): string;
37
- concealed(...args: unknown[]): string;
38
- cyan(...args: unknown[]): string;
39
- faint(...args: unknown[]): string;
40
- green(...args: unknown[]): string;
41
-
42
- // Bright foreground colors
43
- hiBlack(...args: unknown[]): string;
44
- hiBlue(...args: unknown[]): string;
45
- hiCyan(...args: unknown[]): string;
46
- hiGreen(...args: unknown[]): string;
47
- hiMagenta(...args: unknown[]): string;
48
- hiRed(...args: unknown[]): string;
49
- hiWhite(...args: unknown[]): string;
50
- hiYellow(...args: unknown[]): string;
51
-
52
- italic(...args: unknown[]): string;
53
- magenta(...args: unknown[]): string;
54
- red(...args: unknown[]): string;
55
- reverse(...args: unknown[]): string;
56
- strikethrough(...args: unknown[]): string;
57
- underline(...args: unknown[]): string;
58
- white(...args: unknown[]): string;
59
- yellow(...args: unknown[]): string;
60
- };
61
-
62
- function getConfig(config: config.Config): config.Config;
63
-
64
- /**
65
- * Returns the minimum datamitsu version required by this config (semver format).
66
- * The tool validates this version during config loading and fails early with
67
- * upgrade instructions if the current version is too old.
68
- * Every config must export this function.
69
- * @example
70
- * function getMinVersion() {
71
- * return "1.2.0";
72
- * }
73
- */
74
- function getMinVersion(): string;
75
-
76
- /**
77
- * Optional export. Declares remote parent configs to load before this config.
78
- * Remote configs are resolved depth-first and their results are chained as input.
79
- * Hash is REQUIRED for every entry — missing or empty hash causes an immediate error.
80
- * @example
81
- * function getRemoteConfigs() {
82
- * return [{ url: "https://example.com/base-config.ts", hash: "sha256:abcdef..." }];
83
- * }
84
- */
85
- function getRemoteConfigs(): Array<{ hash: string; url: string }>;
86
-
87
- namespace SysList {
88
- type ArchType = "aarch64" | "amd64" | "arm64";
89
-
90
- type OsType = "darwin" | "freebsd" | "linux" | "openbsd" | "windows";
91
- }
92
-
93
- /**
94
- * Tools namespace with utility functions
95
- */
96
- namespace tools {
97
- /**
98
- * Path utilities for working with file paths
99
- */
100
- namespace Path {
101
- /**
102
- * Get absolute path from relative path
103
- * @param path - Path to convert to absolute
104
- * @returns Absolute path
105
- * @throws Error if path cannot be resolved
106
- * @example
107
- * const absPath = tools.Path.abs("./file.txt");
108
- * // Returns: "/current/working/directory/file.txt"
109
- */
110
- function abs(path: string): string;
111
-
112
- /**
113
- * Convert a relative path to an ES module import-compatible format.
114
- * Ensures the path starts with `./` or `../` as required by JavaScript/TypeScript imports.
115
- * The path is cleaned/normalized before processing.
116
- * Idempotent: paths already starting with `./` or `../` are returned unchanged.
117
- *
118
- * @param path - Relative path to convert
119
- * @returns Import-compatible relative path (always starts with `./` or `../`)
120
- * @throws TypeError if path is absolute (imports must be relative)
121
- * @throws TypeError if no argument is provided
122
- *
123
- * @example
124
- * // Basic usage with datamitsuDir context
125
- * const importPath = tools.Path.forImport(
126
- * tools.Path.join(context.datamitsuDir, "eslint.config.js")
127
- * );
128
- * // ".datamitsu/eslint.config.js" → "./.datamitsu/eslint.config.js"
129
- *
130
- * @example
131
- * // Idempotent — already-valid paths are unchanged
132
- * tools.Path.forImport("./.datamitsu/file.js"); // "./.datamitsu/file.js"
133
- * tools.Path.forImport("../.datamitsu/file.js"); // "../.datamitsu/file.js"
134
- *
135
- * @example
136
- * // Composing with linkPath for managed config imports
137
- * const configPath = tools.Config.linkPath("my-app", "eslint-config", context.cwdPath);
138
- * const importPath = tools.Path.forImport(configPath);
139
- * // Use in generated config: `import config from "${importPath}";`
140
- */
141
- function forImport(path: string): string;
142
-
143
- /**
144
- * Join path segments together using the OS-specific separator
145
- * @param paths - Path segments to join
146
- * @returns Joined path
147
- * @example
148
- * const fullPath = tools.Path.join("/home", "user", "file.txt");
149
- * // Returns: "/home/user/file.txt" on Unix, "\\home\\user\\file.txt" on Windows
150
- */
151
- function join(...paths: string[]): string;
152
-
153
- /**
154
- * Get relative path from base to target
155
- * @param targetPath - Target path
156
- * @param basePath - Base path (defaults to git repository root, or cwd if not in a git repo)
157
- * @returns Relative path from base to target
158
- * @throws Error if relative path cannot be computed
159
- * @example
160
- * // Relative to rootPath (git root)
161
- * const relPath = tools.Path.rel("/home/user/project/file.txt");
162
- * // If rootPath is "/home/user/project", returns: "file.txt"
163
- *
164
- * @example
165
- * // Relative to custom base
166
- * const relPath = tools.Path.rel("/home/user/project/file.txt", "/home");
167
- * // Returns: "user/project/file.txt"
168
- */
169
- function rel(targetPath: string, basePath?: string): string;
170
- }
171
-
172
- /**
173
- * .gitignore parser and stringifier
174
- */
175
- namespace Ignore {
176
- type IgnoreMap<T extends string = string> = Partial<Record<T, string[]>>;
177
-
178
- interface ParseResult<T extends string = string> {
179
- groupOrder: T[];
180
- groups: IgnoreMap<T>;
181
- }
182
-
183
- /**
184
- * Parse .gitignore file to grouped structure with preserved order
185
- * @param content - .gitignore file content
186
- * @returns Object with groups and their original order
187
- * @example
188
- * const { groups, groupOrder } = tools.Ignore.parse(fileContent);
189
- * // groups: { "Dependencies": ["node_modules/"], "Build": ["dist/"] }
190
- * // groupOrder: ["Dependencies", "Build"]
191
- *
192
- * // Use the original order when saving back
193
- * const updated = tools.Ignore.stringify(groups, groupOrder);
194
- */
195
- function parse<T extends string = string>(content: string): ParseResult<T>;
196
-
197
- /**
198
- * Convert grouped structure back to .gitignore format
199
- * @param groups - Object with group names as keys and rule arrays as values
200
- * @param groupOrder - Optional partial array specifying the priority order of groups.
201
- * Groups in this array will appear first in the specified order.
202
- * Remaining groups will follow in alphabetical order.
203
- * @returns Formatted .gitignore content
204
- * @example
205
- * // All groups in alphabetical order
206
- * const content1 = tools.Ignore.stringify({
207
- * "Testing": ["coverage/"],
208
- * "Build": ["dist/"],
209
- * "Dependencies": ["node_modules/"]
210
- * });
211
- * // Result order: Build, Dependencies, Testing
212
- *
213
- * @example
214
- * // Priority groups first, then alphabetical
215
- * const content2 = tools.Ignore.stringify(
216
- * {
217
- * "Testing": ["coverage/"],
218
- * "Build": ["dist/"],
219
- * "Dependencies": ["node_modules/"],
220
- * "IDE": [".vscode/"]
221
- * },
222
- * ["Dependencies", "Build"]
223
- * );
224
- * // Result order: Dependencies, Build, IDE, Testing
225
- *
226
- * @example
227
- * // Preserve original order
228
- * const { groups, groupOrder } = tools.Ignore.parse(original);
229
- * groups["New Group"] = ["new/rule"];
230
- * const updated = tools.Ignore.stringify(groups, groupOrder);
231
- */
232
- function stringify<T extends string>(groups: IgnoreMap<T>, groupOrder?: T[]): string;
233
- }
234
-
235
- /**
236
- * Config link utilities for referencing managed config files in .datamitsu/
237
- */
238
- namespace Config {
239
- /**
240
- * Get relative path from a directory to a managed config link in .datamitsu/
241
- * @param ownerName - The app or bundle that owns the link
242
- * @param linkName - The link name in .datamitsu/
243
- * @param fromPath - The directory to compute the relative path from
244
- * @returns Relative path from fromPath to .datamitsu/linkName
245
- * @throws TypeError if linkName is not found or doesn't belong to ownerName
246
- */
247
- function linkPath(ownerName: string, linkName: string, fromPath: string): string;
248
- }
249
-
250
- /**
251
- * Hashing utilities for content verification and change detection.
252
- */
253
- namespace Hash {
254
- /**
255
- * Asserts content matches expectedHash (BLAKE2b-256).
256
- * No-op if hashes match. If mismatched: prints file name + current hash to stderr and throws.
257
- * Pass hash: "" on first use — the error will show the hash to copy.
258
- * @throws Error if hashes do not match
259
- */
260
- function assert(opts: { content: string; file: string; hash: string }): void;
261
- /** BLAKE2b-256 hex digest. Fast; used internally by assert(). */
262
- function blake2b256(content: string): string;
263
- /** SHA-256 hex digest. */
264
- function sha256(content: string): string;
265
- }
266
- }
267
-
268
- namespace config {
269
- // ========================================
270
- // Project Type Detection
271
- // ========================================
272
-
273
- interface Config {
274
- /**
275
- * Binary/app definitions
276
- */
277
- apps?: BinManager.MapOfApps;
278
-
279
- /**
280
- * Bundle definitions for managed content (files/archives with symlinks).
281
- * Bundles are not executable — they store files in a hash-keyed directory
282
- * and create symlinks in .datamitsu/ for zero-conflict content updates.
283
- */
284
- bundles?: BinManager.MapOfBundles;
285
-
286
- /**
287
- * Ignore rules in .datamitsuignore syntax.
288
- * Applied alongside file-based .datamitsuignore rules.
289
- * Rules from multiple configs are concatenated (append).
290
- * @example ["**\/*.generated.ts: eslint, prettier", "vendor/**: *"]
291
- */
292
- ignoreRules?: string[];
293
-
294
- /**
295
- * Config file initialization
296
- */
297
- init?: MapOfConfigInit;
298
-
299
- /**
300
- * Init commands to run after setup
301
- */
302
- initCommands?: MapOfInitCommands;
303
-
304
- /**
305
- * Project type definitions
306
- */
307
- projectTypes?: MapOfProjectTypes;
308
-
309
- /**
310
- * Runtime definitions for managed package managers (UV, PNPM)
311
- */
312
- runtimes?: BinManager.MapOfRuntimes;
313
-
314
- /**
315
- * Arbitrary key-value storage that flows through the config chain.
316
- * Any config layer can read/write values via input.sharedStorage.
317
- * Useful for passing data between config layers that doesn't fit
318
- * the typed config structure.
319
- * @example
320
- * return { ...input, sharedStorage: { ...input.sharedStorage, "my-key": "my-value" } };
321
- */
322
- sharedStorage?: Record<string, string>;
323
-
324
- /**
325
- * Tool definitions
326
- */
327
- tools?: MapOfTools;
328
- }
329
-
330
- /**
331
- * Context passed to config content generator
332
- */
333
- interface ConfigContext {
334
- /**
335
- * Current working directory
336
- */
337
- cwdPath: string;
338
-
339
- /**
340
- * Relative path from cwdPath to the .datamitsu/ directory at git root.
341
- * Simplifies referencing managed config links in content generators.
342
- * @example "../../.datamitsu" // from packages/frontend/
343
- * @example ".datamitsu" // from git root
344
- */
345
- datamitsuDir: string;
346
-
347
- /**
348
- * Content of existing file (if it exists)
349
- * This may be modified content from previous merge operations
350
- */
351
- existingContent?: string;
352
-
353
- /**
354
- * Path to existing file (if it exists)
355
- */
356
- existingPath?: string;
357
-
358
- /**
359
- * Whether the current working directory is the git root
360
- */
361
- isRoot: boolean;
362
-
363
- /**
364
- * Original content of the file as it exists on disk
365
- * This is always the unmodified content, even when existingContent has been transformed
366
- */
367
- originalContent?: string;
368
-
369
- /**
370
- * Detected project types
371
- */
372
- projectTypes: string[];
373
-
374
- /**
375
- * Git root path
376
- */
377
- rootPath: string;
378
- }
379
-
380
- // ========================================
381
- // Tool Execution Configuration
382
- // ========================================
383
-
384
- /**
385
- * Configuration file initialization (enhanced from existing)
386
- */
387
- interface ConfigInit {
388
- /**
389
- * Function that generates file content
390
- * Receives context about the project including existing file content if present
391
- * Optional when deleteOnly is true or linkTarget is set
392
- */
393
- content?: (context: ConfigContext) => string;
394
-
395
- /**
396
- * If true, only delete files from otherFileNameList without creating any new file
397
- * Content function is ignored when deleteOnly is true
398
- * @default false
399
- */
400
- deleteOnly?: boolean;
401
-
402
- /**
403
- * Relative path to the symlink target, resolved from the directory of the symlink itself.
404
- * When set, creates a symlink instead of writing file content.
405
- * Content function is ignored when linkTarget is set.
406
- * @example "AGENTS.md" // symlink in same directory
407
- * @example "../AGENTS.md" // symlink to parent directory
408
- */
409
- linkTarget?: string;
410
-
411
- /**
412
- * All other known filenames for this config
413
- * These will be DELETED during install to avoid conflicts
414
- * @example [".eslintrc.js", ".eslintrc.json", ".eslintrc.yml", "eslint.config.js"]
415
- */
416
- otherFileNameList?: string[];
417
-
418
- /**
419
- * Which project type this config applies to
420
- * If not specified, applies to all projects
421
- */
422
- projectTypes?: string[];
423
-
424
- /**
425
- * Controls where the config file is created.
426
- * - "project" (default): creates in the current project directory
427
- * - "git-root": creates only at the git repository root (runs once)
428
- */
429
- scope?: "git-root" | "project";
430
- }
431
-
432
- /**
433
- * Initialization command to run after clone/install
434
- */
435
- interface InitCommand {
436
- /**
437
- * Arguments
438
- */
439
- args: string[];
440
-
441
- /**
442
- * Command to execute (app name from MapOfApps)
443
- */
444
- command: string;
445
-
446
- /**
447
- * Description
448
- */
449
- description?: string;
450
-
451
- /**
452
- * Which project types this applies to
453
- * Empty = all project types
454
- */
455
- projectTypes?: string[];
456
-
457
- /**
458
- * Only run if this file/directory exists
459
- */
460
- when?: string;
461
- }
462
-
463
- /**
464
- * Map of configuration init with mainFilename as key
465
- * @example
466
- * {
467
- * ".gitignore": { content: () => "..." },
468
- * "lefthook.yaml": { content: () => "..." },
469
- * ".vscode/settings.json": { content: () => "..." }
470
- * }
471
- */
472
- type MapOfConfigInit = Record<string, ConfigInit>;
473
-
474
- // ========================================
475
- // Init Commands
476
- // ========================================
477
-
478
- type MapOfInitCommands = Record<string, InitCommand>;
479
-
480
- type MapOfProjectTypes = Record<string, ProjectType>;
481
-
482
- // ========================================
483
- // Config File Management (ENHANCED)
484
- // ========================================
485
-
486
- type MapOfTools = Record<string, Tool>;
487
-
488
- /**
489
- * Operation type
490
- */
491
- type OperationType = "fix" | "lint";
492
-
493
- /**
494
- * Project type detector - defines when this project type is detected
495
- */
496
- interface ProjectType {
497
- /**
498
- * Human-readable description
499
- */
500
- description?: string;
501
-
502
- /**
503
- * Marker files that indicate this project type
504
- * If ANY of these files exist in the root, project type is detected
505
- * Supports glob patterns in repo root
506
- * @example ["package.json", "yarn.lock"]
507
- * @example ["go.mod"]
508
- * @example ["*.tf"]
509
- */
510
- markers: string[];
511
- }
512
-
513
- // ========================================
514
- // Git Hook Configuration
515
- // ========================================
516
-
517
- /**
518
- * Tool definition - what operations a tool supports
519
- */
520
- interface Tool {
521
- /**
522
- * Tool name/description
523
- */
524
- name: string;
525
-
526
- /**
527
- * Operations this tool supports
528
- */
529
- operations: Partial<Record<OperationType, ToolOperation>>;
530
-
531
- /**
532
- * Which project types this tool applies to
533
- * Empty array or undefined = applies to all project types
534
- * @example ["npm-package", "typescript-project"]
535
- */
536
- projectTypes?: string[];
537
- }
538
-
539
- /**
540
- * Tool operation configuration - how to run a tool for a specific operation
541
- */
542
- interface ToolOperation {
543
- /**
544
- * App to execute (app name from MapOfApps)
545
- */
546
- app: string;
547
-
548
- /**
549
- * Arguments to pass to the command.
550
- * Template placeholders are expanded by the executor before execution:
551
- * - {file} - single file path (per-file scope)
552
- * - {files} - space-separated file list (batch mode)
553
- * - {root} - git repository root (or cwd if not in a git repo)
554
- * - {cwd} - per-project working directory
555
- * - {toolCache} - per-project, per-tool cache directory (cache/{projectPath}/{toolName}/)
556
- * @example ["--fix", "{file}"]
557
- * @example ["--noEmit", "--project", "{root}"]
558
- * @example ["--cache-location", "{toolCache}/eslint"]
559
- */
560
- args: string[];
561
-
562
- /**
563
- * Batch mode - process files in groups or one at a time
564
- * Only used for scope: "per-project" or "repository"
565
- * @default true for "per-project" and "repository", false for "per-file"
566
- */
567
- batch?: boolean;
568
-
569
- /**
570
- * Extra environment variables for this operation
571
- * Merge priority: OS env < app env < tool operation env
572
- * @example { "NODE_ENV": "production", "ESLINT_USE_FLAT_CONFIG": "true" }
573
- */
574
- env?: Record<string, string>;
575
-
576
- /**
577
- * File glob patterns this tool operates on
578
- * Uses gitignore-style patterns
579
- * @example ["**\/*.ts", "**\/*.tsx"]
580
- * @example ["**\/*.md"]
581
- */
582
- globs: string[];
583
-
584
- /**
585
- * Files that should invalidate the cache when changed
586
- * Paths are relative to project root
587
- * @example ["eslint.config.js", "tsconfig.json"]
588
- * @example [".prettierrc", "package.json"]
589
- */
590
- invalidateOn?: string[];
591
-
592
- /**
593
- * Priority/order when tools have overlapping globs
594
- * Lower number = runs first
595
- * Tools with same priority and overlapping globs run sequentially in definition order
596
- * Tools with different globs or no overlap run in parallel
597
- * @default 0
598
- */
599
- priority?: number;
600
-
601
- /**
602
- * Scope defines the execution area and working directory
603
- * - "repository": run once from git root for the entire repository
604
- * - "per-project": run for each detected project in its directory
605
- * - "per-file": run for each file in its directory
606
- * @default "per-project"
607
- * @example
608
- * // ESLint - runs in each project
609
- * {
610
- * scope: "per-project",
611
- * app: "eslint",
612
- * args: ["--quiet", "{files}"],
613
- * globs: ["**\/*.ts", "**\/*.js"]
614
- * }
615
- * @example
616
- * // syncpack - runs once for the entire monorepo
617
- * {
618
- * scope: "repository",
619
- * app: "syncpack",
620
- * args: ["lint"],
621
- * globs: ["**\/package.json"]
622
- * }
623
- * @example
624
- * // shfmt - formats each shell file separately
625
- * {
626
- * scope: "per-file",
627
- * app: "shfmt",
628
- * args: ["-w", "{file}"],
629
- * globs: ["**\/*.sh"]
630
- * }
631
- */
632
- scope: ToolScope;
633
- }
634
-
635
- /**
636
- * Scope defines the execution area and automatically determines the working directory
637
- */
638
- type ToolScope =
639
- | "per-file" // Run for each file in its directory
640
- | "per-project" // Run for each detected project in its directory
641
- | "repository"; // Run once from git root for the entire repository
642
-
643
- // ========================================
644
- // Main Config (ENHANCED)
645
- // ========================================
646
- }
647
-
648
- namespace BinManager {
649
- interface App {
650
- /**
651
- * Named archives to extract into the app's install directory.
652
- * Archive names can be referenced in Links to create symlinks.
653
- * Archives are extracted before Files are written, allowing Files to override.
654
- */
655
- archives?: Record<string, ArchiveSpec>;
656
- binary?: AppConfigBinary;
657
- /**
658
- * Human-readable description of the app, shown in exec listing.
659
- */
660
- description?: string;
661
- files?: Record<string, string>;
662
- fnm?: AppConfigFNM;
663
- jvm?: AppConfigJVM;
664
- /**
665
- * Symlinks to create in .datamitsu/ directory, mapping link name to relative path in install directory.
666
- */
667
- links?: Record<string, string>;
668
- required?: boolean;
669
- shell?: AppConfigShell;
670
- uv?: AppConfigUV;
671
- /**
672
- * Version check configuration for verify-all command.
673
- * Absent: use default ["--version"] args.
674
- * { disabled: true }: skip version check.
675
- * { args: ["version"] }: use custom args.
676
- */
677
- versionCheck?: AppVersionCheck;
678
- }
679
-
680
- interface AppConfigBinary {
681
- binaries: MapOfBinaries;
682
- /**
683
- * Version string for display purposes (e.g. from GitHub release tag).
684
- */
685
- version?: string;
686
- }
687
-
688
- interface AppConfigFNM {
689
- binPath: string;
690
- dependencies?: Record<string, string>;
691
- /**
692
- * Lock file content for reproducible installs.
693
- * Required for all FNM apps. Validation fails if omitted.
694
- * When prefixed with "br:", the content is brotli-compressed and base64-encoded.
695
- * Plain text is also accepted for backward compatibility.
696
- * Generate via: datamitsu config lockfile <appName>
697
- */
698
- lockFile: string;
699
- packageName: string;
700
- runtime?: string;
701
- version: string;
702
- }
703
-
704
- interface AppConfigJVM {
705
- jarHash: string;
706
- jarUrl: string;
707
- /**
708
- * Optional main class for JARs that aren't executable.
709
- */
710
- mainClass?: string;
711
- runtime?: string;
712
- version: string;
713
- }
714
-
715
- interface AppConfigShell {
716
- args?: string[];
717
- env?: Record<string, string>;
718
- name: string;
719
- }
720
-
721
- interface AppConfigUV {
722
- /**
723
- * Lock file content for reproducible installs.
724
- * Required for all UV apps. Validation fails if omitted.
725
- * When prefixed with "br:", the content is brotli-compressed and base64-encoded.
726
- * Plain text is also accepted for backward compatibility.
727
- * Generate via: datamitsu config lockfile <appName>
728
- */
729
- lockFile: string;
730
- packageName: string;
731
- /**
732
- * Python version constraint for pyproject.toml requires-python field.
733
- * If not set, defaults to ">=3.12".
734
- * @example ">=3.10"
735
- */
736
- requiresPython?: string;
737
- runtime?: string;
738
- version: string;
739
- }
740
-
741
- interface AppVersionCheck {
742
- /**
743
- * Custom arguments for version check. Defaults to ["--version"] if absent.
744
- */
745
- args?: string[];
746
- /**
747
- * Skip version check for this app.
748
- */
749
- disabled?: boolean;
750
- }
751
-
752
- /**
753
- * Archive specification for bundling directory trees with apps.
754
- * Supports inline (brotli-compressed tar) and external (URL) formats.
755
- * Archives are extracted before Files are written, allowing Files to override.
756
- */
757
- interface ArchiveSpec {
758
- /** Archive format (tar-based only) */
759
- format?: "tar" | "tar.bz2" | "tar.gz" | "tar.xz" | "tar.zst";
760
-
761
- /**
762
- * SHA-256 hash (64 lowercase hex characters).
763
- * Required for external archives per security policy.
764
- */
765
- hash?: string;
766
-
767
- /**
768
- * Inline archive: brotli-compressed tar + base64 with "tar.br:" prefix.
769
- * Maximum decompressed size: 50 MiB.
770
- * @example "tar.br:GxsAACBdU6xBxGN0YXIg..."
771
- */
772
- inline?: string;
773
-
774
- /**
775
- * External archive URL (requires hash and format).
776
- * Downloaded and SHA-256 verified before extraction.
777
- */
778
- url?: string;
779
- }
780
-
781
- interface BinaryOsArchInfo {
782
- binaryPath?: string;
783
- contentType: BinContentType;
784
- /**
785
- * When true, extracts the entire archive to a directory instead of a single binary.
786
- * Used for runtimes like JDK that need the full directory tree (bin/, lib/, etc.).
787
- */
788
- extractDir?: boolean;
789
-
790
- hash: string;
791
- /** @default sha256 */
792
- hashType?: BinHashType;
793
- url: string;
794
- }
795
-
796
- type BinContentType =
797
- | "binary"
798
- | "bz2"
799
- | "gz"
800
- | "tar"
801
- | "tar.bz2"
802
- | "tar.gz"
803
- | "tar.xz"
804
- | "tar.zst"
805
- | "xz"
806
- | "zip"
807
- | "zst";
808
-
809
- type BinHashType = "blake2b" | "md5" | "sha1" | "sha256" | "sha384" | "sha512";
810
-
811
- interface Bundle {
812
- /**
813
- * Named archives to extract into the bundle's install directory.
814
- * Supports inline (brotli-compressed tar) and external (URL with hash) formats.
815
- */
816
- archives?: Record<string, ArchiveSpec>;
817
-
818
- /**
819
- * Static file contents to write into the bundle's install directory.
820
- */
821
- files?: Record<string, string>;
822
-
823
- /**
824
- * Symlinks to create in .datamitsu/ directory, mapping link name to relative path in install directory.
825
- * Values can point to files or directories within the bundle.
826
- * Use "." to link the entire bundle directory.
827
- */
828
- links?: Record<string, string>;
829
-
830
- /**
831
- * Version string for cache invalidation. Changing this produces a new hash directory.
832
- */
833
- version?: string;
834
- }
835
-
836
- type LibcType = "glibc" | "musl" | "unknown";
837
-
838
- type MapOfApps = Record<string, App>;
839
-
840
- type MapOfBinaries = Partial<
841
- Record<
842
- SysList.OsType,
843
- Partial<Record<SysList.ArchType, Partial<Record<LibcType, BinaryOsArchInfo>>>>
844
- >
845
- >;
846
-
847
- type MapOfBundles = Record<string, Bundle>;
848
-
849
- type MapOfRuntimes = Record<string, RuntimeConfig>;
850
-
851
- interface RuntimeConfig {
852
- /**
853
- * FNM-specific runtime configuration (nodeVersion, pnpmVersion).
854
- * Required when kind is "fnm".
855
- */
856
- fnm?: RuntimeConfigFNM;
857
- /**
858
- * JVM-specific runtime configuration (javaVersion).
859
- * Required when kind is "jvm".
860
- */
861
- jvm?: RuntimeConfigJVM;
862
- kind: RuntimeKind;
863
- managed?: RuntimeConfigManaged;
864
- mode: RuntimeMode;
865
- system?: RuntimeConfigSystem;
866
- /**
867
- * UV-specific runtime configuration (pythonVersion).
868
- * Optional when kind is "uv".
869
- */
870
- uv?: RuntimeConfigUV;
871
- }
872
-
873
- interface RuntimeConfigFNM {
874
- nodeVersion: string;
875
- /**
876
- * SHA-256 hash of the PNPM tarball for integrity verification.
877
- * Required per security policy: all downloads must have a pinned hash.
878
- */
879
- pnpmHash: string;
880
- pnpmVersion: string;
881
- }
882
-
883
- interface RuntimeConfigJVM {
884
- javaVersion: string;
885
- }
886
-
887
- interface RuntimeConfigManaged {
888
- binaries: MapOfBinaries;
889
- }
890
-
891
- interface RuntimeConfigSystem {
892
- command: string;
893
- /**
894
- * Optional version string for manual cache invalidation when system runtime version changes.
895
- */
896
- systemVersion?: string;
897
- }
898
-
899
- interface RuntimeConfigUV {
900
- pythonVersion?: string;
901
- }
902
-
903
- type RuntimeKind = "fnm" | "jvm" | "uv";
904
-
905
- type RuntimeMode = "managed" | "system";
906
- }
907
-
908
- /**
909
- * Facts about the project environment.
910
- * Collected automatically on engine initialization.
911
- *
912
- * Path-related fields have been removed. Use template placeholders in tool
913
- * operation args instead:
914
- * - `{cwd}` - current working directory
915
- * - `{root}` - git repository root (or cwd if not in git)
916
- * - `{toolCache}` - per-project, per-tool cache directory (cache/{projectPath}/{toolName}/)
917
- */
918
- interface Facts {
919
- /**
920
- * CPU architecture (amd64, arm64, aarch64)
921
- */
922
- arch: SysList.ArchType;
923
-
924
- /**
925
- * Command to run this binary (can be overridden via --binary-command flag or DATAMITSU_BINARY_COMMAND env var)
926
- * Useful for npm package wrappers that need to call the actual binary
927
- */
928
- binaryCommand: string;
929
-
930
- /**
931
- * Absolute path to the currently running binary
932
- */
933
- binaryPath: string;
934
-
935
- /**
936
- * Environment variables with the package prefix (e.g., CHANGE_ME_*)
937
- * Only includes variables that start with the prefix defined in ldflags.EnvPrefix
938
- * @example { "CHANGE_ME_DEBUG": "true", "CHANGE_ME_LOG_LEVEL": "info" }
939
- */
940
- env: Record<string, string>;
941
-
942
- /**
943
- * Whether we're inside a git repository
944
- */
945
- isInGitRepo: boolean;
946
-
947
- /**
948
- * Whether we're in a subdirectory of git root (potential monorepo)
949
- */
950
- isMonorepo: boolean;
951
-
952
- /**
953
- * Libc implementation on the host system.
954
- * "glibc" or "musl" on Linux, "unknown" on non-Linux systems.
955
- */
956
- libc: "glibc" | "musl" | "unknown";
957
-
958
- /**
959
- * Operating system (darwin, linux, windows, freebsd, openbsd)
960
- */
961
- os: SysList.OsType;
962
-
963
- /**
964
- * Package name from ldflags
965
- */
966
- packageName: string;
967
- }
968
-
969
- /**
970
- * Function that returns Facts object
971
- * Facts are collected once during engine initialization
972
- */
973
- const facts: () => Facts;
974
-
975
- /**
976
- * YAML parser and stringifier
977
- */
978
- namespace YAML {
979
- /**
980
- * Parse YAML string to JavaScript object
981
- * @param text - YAML string to parse
982
- * @returns Parsed object
983
- * @throws Error if YAML is invalid
984
- */
985
- function parse(text: string): any;
986
-
987
- /**
988
- * Convert JavaScript object to YAML string
989
- * @param value - Object to stringify
990
- * @returns YAML string
991
- * @throws Error if object cannot be serialized
992
- */
993
- function stringify(value: any): string;
994
- }
995
-
996
- /**
997
- * TOML parser and stringifier
998
- */
999
- namespace TOML {
1000
- /**
1001
- * Parse TOML string to JavaScript object
1002
- * @param text - TOML string to parse
1003
- * @returns Parsed object
1004
- * @throws Error if TOML is invalid
1005
- */
1006
- function parse(text: string): any;
1007
-
1008
- /**
1009
- * Convert JavaScript object to TOML string
1010
- * @param value - Object to stringify
1011
- * @returns TOML string
1012
- * @throws Error if object cannot be serialized
1013
- */
1014
- function stringify(value: any): string;
1015
- }
1016
-
1017
- /**
1018
- * INI parser and stringifier
1019
- */
1020
- namespace INI {
1021
- /**
1022
- * INI section structure
1023
- */
1024
- type Section = Record<string, string>;
1025
-
1026
- /**
1027
- * INI section entry with name and properties
1028
- */
1029
- interface SectionEntry {
1030
- name: string;
1031
- properties: Section;
1032
- }
1033
-
1034
- /**
1035
- * Parse INI string to array of sections
1036
- * @param text - INI string to parse
1037
- * @returns Array of sections (preserves order and allows duplicate section names)
1038
- * @throws Error if INI is invalid
1039
- * @example
1040
- * const ini = INI.parse(`
1041
- * [database]
1042
- * host = localhost
1043
- * port = 5432
1044
- * [*.py]
1045
- * indent_size = 4
1046
- * [*.py]
1047
- * indent_size = 2
1048
- * `);
1049
- * // Returns: [
1050
- * // { name: "database", properties: { host: "localhost", port: "5432" } },
1051
- * // { name: "*.py", properties: { indent_size: "4" } },
1052
- * // { name: "*.py", properties: { indent_size: "2" } }
1053
- * // ]
1054
- */
1055
- function parse(text: string): Array<SectionEntry>;
1056
-
1057
- /**
1058
- * Convert array of sections to INI string
1059
- * @param sections - Array of section entries
1060
- * @returns INI string
1061
- * @throws Error if object cannot be serialized
1062
- * @example
1063
- * const sections = [
1064
- * { name: "database", properties: { host: "localhost", port: "5432" } },
1065
- * { name: "*.py", properties: { indent_size: "2" } }
1066
- * ];
1067
- * console.log(INI.stringify(sections));
1068
- */
1069
- function stringify(sections: Array<SectionEntry>): string;
1070
-
1071
- /**
1072
- * Convert array of sections to a record, merging sections with the same name
1073
- * @param sections - Array of section entries from INI.parse
1074
- * @returns Record mapping section names to their merged properties
1075
- * @example
1076
- * const sections = INI.parse(`
1077
- * [*.py]
1078
- * indent_size = 4
1079
- * [*.py]
1080
- * indent_size = 2
1081
- * `);
1082
- * const record = INI.toRecord(sections);
1083
- * // Returns: { "*.py": { indent_size: "2" } }
1084
- * // Later values override earlier ones for the same section name
1085
- */
1086
- function toRecord(sections: Array<SectionEntry>): Record<string, Section>;
1087
- }
1088
- }
1089
-
1090
- export {};