adamantite 0.14.0 → 0.15.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.
package/dist/index.js ADDED
@@ -0,0 +1,757 @@
1
+ // src/index.ts
2
+ import yargs from "yargs";
3
+ import { hideBin } from "yargs/helpers";
4
+
5
+ // src/commands/check.ts
6
+ import process3 from "node:process";
7
+ import { log } from "@clack/prompts";
8
+ import { Fault as Fault3 } from "faultier";
9
+ import { ok as ok3, safeTry as safeTry3 } from "neverthrow";
10
+ import { dlxCommand } from "nypm";
11
+
12
+ // src/helpers/packages/biome.ts
13
+ import { readFile as readFile2, writeFile } from "node:fs/promises";
14
+ import { join as join2 } from "node:path";
15
+ import { Fault as Fault2 } from "faultier";
16
+ import { err as err2, fromPromise as fromPromise2, ok as ok2, safeTry as safeTry2 } from "neverthrow";
17
+
18
+ // src/utils.ts
19
+ import { spawnSync } from "node:child_process";
20
+ import { access, readFile } from "node:fs/promises";
21
+ import { join } from "node:path";
22
+ import process2 from "node:process";
23
+ import defu from "defu";
24
+ import { Fault } from "faultier";
25
+ import { parse } from "jsonc-parser";
26
+ import { err, fromPromise, fromThrowable, ok, safeTry } from "neverthrow";
27
+ import { detectPackageManager } from "nypm";
28
+ function defineCommand(input) {
29
+ return input;
30
+ }
31
+ var runCommand = (command) => {
32
+ const result = spawnSync(command, {
33
+ stdio: "inherit",
34
+ shell: true,
35
+ maxBuffer: 100 * 1024 * 1024
36
+ });
37
+ if (result.error || result.status !== 0) {
38
+ const message = result.error?.message ?? "An unknown error occurred while running the command";
39
+ return err(Fault.wrap(result.error ?? new Error(message)).withTag("FAILED_TO_RUN_COMMAND").withDebug(`Failed to run command: ${message}`));
40
+ }
41
+ return ok(result);
42
+ };
43
+ var getPackageManagerName = () => fromPromise(detectPackageManager(process2.cwd()), () => "Failed to detect package manager").andThen((result) => result ? ok(result.name) : err("Failed to resolve package manager")).mapErr((message) => Fault.create("NO_PACKAGE_MANAGER").withDescription(message, "We're unable to detect the package manager used in this project. Please ensure you have a package.json file in the current directory."));
44
+ var checkIfExists = (path) => fromPromise(access(path), () => new Error("File not found")).match(() => true, () => false);
45
+ var parseJson = (content) => {
46
+ const errors = [];
47
+ const parsed = parse(content, errors);
48
+ if (errors.length > 0) {
49
+ return err(Fault.create("FAILED_TO_PARSE_FILE").withDescription("Failed to parse JSON", "We're unable to parse the provided JSON file.").withContext({ errors }));
50
+ }
51
+ return ok(parsed);
52
+ };
53
+ var WORKSPACE_PREFIX_REGEX = /^workspace:/;
54
+ var RANGE_PREFIX_REGEX = /^[\^~]/;
55
+ var normalizeDependencyVersion = (specifier) => specifier.trim().replace(WORKSPACE_PREFIX_REGEX, "").replace(RANGE_PREFIX_REGEX, "");
56
+ var mergeConfig = fromThrowable(defu, (error) => Fault.wrap(error).withTag("FAILED_TO_MERGE_CONFIG").withDescription("Failed to merge configuration", "We're unable to merge the configuration files."));
57
+ var readPackageJson = (cwd = process2.cwd()) => fromPromise(readFile(join(cwd, "package.json"), "utf-8"), (error) => Fault.wrap(error).withTag("FAILED_TO_READ_FILE").withDescription("Failed to read package.json", "We're unable to read the package.json file in the current directory.").withContext({ path: join(cwd, "package.json") })).andThen((content) => parseJson(content)).andThen((parsed) => ok(parsed));
58
+ var checkIsMonorepo = () => safeTry(async function* () {
59
+ const pnpmWorkspace = await checkIfExists(join(process2.cwd(), "pnpm-workspace.yaml"));
60
+ if (pnpmWorkspace) {
61
+ return ok(true);
62
+ }
63
+ const packageJson = yield* readPackageJson();
64
+ return ok(packageJson?.workspaces !== undefined);
65
+ });
66
+ var TITLE = `
67
+ o ooooooooo o oooo oooo o oooo oooo ooooooooooo ooooo ooooooooooo ooooooooooo
68
+ 888 888 88o 888 8888o 888 888 8888o 88 88 888 88 888 88 888 88 888 88
69
+ 8 88 888 888 8 88 88 888o8 88 8 88 88 888o88 888 888 888 888ooo8
70
+ 8oooo88 888 888 8oooo88 88 888 88 8oooo88 88 8888 888 888 888 888 oo
71
+ o88o o888o o888ooo88 o88o o888o o88o 8 o88o o88o o888o o88o 88 o888o o888o o888o o888ooo8888
72
+ `;
73
+ function printTitle() {
74
+ const columns = TITLE.split(`
75
+ `).reduce((max, line) => Math.max(max, line.trim().length), 0);
76
+ if (process2.stdout.columns && process2.stdout.columns >= columns) {
77
+ console.log(TITLE);
78
+ }
79
+ }
80
+
81
+ // src/helpers/packages/biome.ts
82
+ var biome = {
83
+ name: "@biomejs/biome",
84
+ version: "2.3.10",
85
+ config: {
86
+ $schema: "./node_modules/@biomejs/biome/configuration_schema.json"
87
+ },
88
+ exists: async () => {
89
+ if (await checkIfExists(join2(process.cwd(), "biome.jsonc"))) {
90
+ return { path: join2(process.cwd(), "biome.jsonc") };
91
+ }
92
+ if (await checkIfExists(join2(process.cwd(), "biome.json"))) {
93
+ return { path: join2(process.cwd(), "biome.json") };
94
+ }
95
+ return { path: null };
96
+ },
97
+ create: () => fromPromise2(writeFile(join2(process.cwd(), "biome.jsonc"), JSON.stringify({ ...biome.config, extends: ["adamantite"] }, null, 2)), (error) => Fault2.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write Biome configuration", "We're unable to write the Biome configuration to the current directory.")),
98
+ update: () => safeTry2(async function* () {
99
+ const exists = await biome.exists();
100
+ if (!exists.path) {
101
+ return err2(Fault2.create("FILE_NOT_FOUND").withDescription("No `biome.jsonc` or `biome.json` found", "We're unable to find a Biome configuration in the current directory."));
102
+ }
103
+ const biomeFile = yield* fromPromise2(readFile2(exists.path, "utf-8"), (error) => Fault2.wrap(error).withTag("FAILED_TO_READ_FILE").withDescription("Failed to read Biome configuration", "We're unable to read the Biome configuration from the current directory."));
104
+ const existingConfig = yield* parseJson(biomeFile);
105
+ if (!existingConfig || Object.keys(existingConfig).length === 0) {
106
+ return err2(Fault2.create("INVALID_BIOME_CONFIG").withDescription("Invalid Biome configuration", "The Biome configuration file is empty or invalid.").withContext({ path: exists.path }));
107
+ }
108
+ const newConfig = { ...existingConfig };
109
+ if (!Array.isArray(newConfig.extends)) {
110
+ newConfig.extends = newConfig.extends ? [newConfig.extends] : [];
111
+ }
112
+ if (!newConfig.extends.includes("adamantite")) {
113
+ newConfig.extends.push("adamantite");
114
+ }
115
+ const mergedConfig = yield* mergeConfig(newConfig, biome.config);
116
+ mergedConfig.$schema = biome.config.$schema;
117
+ yield* fromPromise2(writeFile(exists.path, JSON.stringify(mergedConfig, null, 2)), (error) => Fault2.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write Biome configuration", "We're unable to write the Biome configuration to the current directory.").withContext({ path: exists.path }));
118
+ return ok2();
119
+ })
120
+ };
121
+
122
+ // src/commands/check.ts
123
+ var check_default = defineCommand({
124
+ command: "check [files..]",
125
+ describe: "Find issues in code using Biome",
126
+ builder: (yargs) => yargs.positional("files", {
127
+ describe: "Specific files to lint (optional)",
128
+ type: "string",
129
+ array: true
130
+ }).option("summary", {
131
+ type: "boolean",
132
+ description: "Show summary of lint results"
133
+ }),
134
+ handler: (argv) => safeTry3(async function* () {
135
+ const packageManager = yield* getPackageManagerName();
136
+ const args = ["check"];
137
+ if (argv.summary) {
138
+ args.push("--reporter", "summary");
139
+ }
140
+ if (argv.files && argv.files.length > 0) {
141
+ args.push(...argv.files);
142
+ }
143
+ const command = dlxCommand(packageManager, biome.name, { args });
144
+ const result = yield* runCommand(command);
145
+ return ok3(result);
146
+ }).match(() => {
147
+ process3.exit(0);
148
+ }, (error) => {
149
+ if (Fault3.isFault(error) && error.tag === "NO_PACKAGE_MANAGER") {
150
+ log.error(error.flatten());
151
+ }
152
+ process3.exit(1);
153
+ })
154
+ });
155
+
156
+ // src/commands/ci.ts
157
+ import process4 from "node:process";
158
+ import { log as log2 } from "@clack/prompts";
159
+ import { Fault as Fault5 } from "faultier";
160
+ import { ok as ok5, safeTry as safeTry5 } from "neverthrow";
161
+ import { dlxCommand as dlxCommand2 } from "nypm";
162
+
163
+ // src/helpers/packages/oxfmt.ts
164
+ import { readFile as readFile3, writeFile as writeFile2 } from "node:fs/promises";
165
+ import { join as join3 } from "node:path";
166
+ import { Fault as Fault4 } from "faultier";
167
+ import { err as err3, fromPromise as fromPromise3, ok as ok4, safeTry as safeTry4 } from "neverthrow";
168
+ // presets/oxfmt.json
169
+ var oxfmt_default = {
170
+ arrowParens: "always",
171
+ bracketSameLine: false,
172
+ bracketSpacing: true,
173
+ embeddedLanguageFormatting: "auto",
174
+ endOfLine: "lf",
175
+ experimentalSortImports: {
176
+ groups: [
177
+ ["value-builtin", "type-import"],
178
+ ["value-external"],
179
+ ["type-internal"],
180
+ ["value-internal"],
181
+ ["type-subpath"],
182
+ ["value-subpath"],
183
+ ["type-parent", "type-sibling", "type-index"],
184
+ ["value-parent", "value-sibling", "value-index"],
185
+ ["unknown"]
186
+ ],
187
+ ignoreCase: true,
188
+ newlinesBetween: false,
189
+ partitionByNewline: true,
190
+ order: "asc",
191
+ partitionByComment: true,
192
+ sortSideEffects: false
193
+ },
194
+ insertFinalNewline: true,
195
+ jsxSingleQuote: false,
196
+ objectWrap: "preserve",
197
+ printWidth: 100,
198
+ quoteProps: "as-needed",
199
+ semi: false,
200
+ singleAttributePerLine: false,
201
+ singleQuote: false,
202
+ tabWidth: 2,
203
+ trailingComma: "es5",
204
+ useTabs: false
205
+ };
206
+
207
+ // src/helpers/packages/oxfmt.ts
208
+ var oxfmt = {
209
+ name: "oxfmt",
210
+ version: "0.20.0",
211
+ config: {
212
+ $schema: "./node_modules/oxfmt/configuration_schema.json",
213
+ ...oxfmt_default
214
+ },
215
+ exists: async () => {
216
+ if (await checkIfExists(join3(process.cwd(), ".oxfmtrc.jsonc"))) {
217
+ return { path: join3(process.cwd(), ".oxfmtrc.jsonc") };
218
+ }
219
+ if (await checkIfExists(join3(process.cwd(), ".oxfmtrc.json"))) {
220
+ return { path: join3(process.cwd(), ".oxfmtrc.json") };
221
+ }
222
+ return { path: null };
223
+ },
224
+ create: () => fromPromise3(writeFile2(join3(process.cwd(), ".oxfmtrc.jsonc"), JSON.stringify(oxfmt.config, null, 2)), (error) => Fault4.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write oxfmt configuration", "We're unable to write the oxfmt configuration to the current directory.")),
225
+ update: () => safeTry4(async function* () {
226
+ const exists = await oxfmt.exists();
227
+ if (!exists.path) {
228
+ return err3(Fault4.create("FILE_NOT_FOUND").withDescription("No `.oxfmtrc.jsonc` or `.oxfmtrc.json` found", "We're unable to find an oxfmt configuration in the current directory."));
229
+ }
230
+ const oxfmtFile = yield* fromPromise3(readFile3(exists.path, "utf-8"), (error) => Fault4.wrap(error).withTag("FAILED_TO_READ_FILE").withDescription("Failed to read oxfmt configuration", "We're unable to read the oxfmt configuration from the current directory."));
231
+ const existingConfig = yield* parseJson(oxfmtFile);
232
+ if (!existingConfig || Object.keys(existingConfig).length === 0) {
233
+ return err3(Fault4.create("INVALID_OXFMT_CONFIG").withDescription("Invalid oxfmt configuration", "The oxfmt configuration file is empty or invalid.").withContext({ path: exists.path }));
234
+ }
235
+ const mergedConfig = yield* mergeConfig(existingConfig, oxfmt.config);
236
+ mergedConfig.$schema = oxfmt.config.$schema;
237
+ yield* fromPromise3(writeFile2(exists.path, JSON.stringify(mergedConfig, null, 2)), (error) => Fault4.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write oxfmt configuration", "We're unable to write the oxfmt configuration to the current directory.").withContext({ path: exists.path }));
238
+ return ok4();
239
+ })
240
+ };
241
+
242
+ // src/helpers/packages/sherif.ts
243
+ var sherif = {
244
+ name: "sherif",
245
+ version: "1.9.0"
246
+ };
247
+
248
+ // src/commands/ci.ts
249
+ var ci_default = defineCommand({
250
+ command: "ci",
251
+ describe: "Run Adamantite in a CI environment",
252
+ builder: (yargs) => yargs.option("monorepo", {
253
+ type: "boolean",
254
+ description: "Run additional monorepo-specific checks"
255
+ }).option("github", {
256
+ type: "boolean",
257
+ description: "Use GitHub reporter"
258
+ }),
259
+ handler: (argv) => safeTry5(async function* () {
260
+ const packageManager = yield* getPackageManagerName();
261
+ const tools = [
262
+ {
263
+ package: biome.name,
264
+ args: ["ci", ...argv.github ? ["--reporter", "github"] : []]
265
+ }
266
+ ];
267
+ const oxfmtConfig = await oxfmt.exists();
268
+ if (oxfmtConfig.path) {
269
+ tools.push({
270
+ package: oxfmt.name,
271
+ args: ["--check"]
272
+ });
273
+ }
274
+ if (argv.monorepo) {
275
+ tools.push({ package: sherif.name, args: [] });
276
+ }
277
+ for (const tool of tools) {
278
+ const command = dlxCommand2(packageManager, tool.package, {
279
+ args: tool.args
280
+ });
281
+ yield* runCommand(command);
282
+ }
283
+ return ok5();
284
+ }).match(() => {
285
+ process4.exit(0);
286
+ }, (error) => {
287
+ if (Fault5.isFault(error) && error.tag === "NO_PACKAGE_MANAGER") {
288
+ log2.error(error.flatten());
289
+ }
290
+ process4.exit(1);
291
+ })
292
+ });
293
+
294
+ // src/commands/fix.ts
295
+ import process5 from "node:process";
296
+ import { log as log3 } from "@clack/prompts";
297
+ import { Fault as Fault6 } from "faultier";
298
+ import { ok as ok6, safeTry as safeTry6 } from "neverthrow";
299
+ import { dlxCommand as dlxCommand3 } from "nypm";
300
+ var fix_default = defineCommand({
301
+ command: "fix [files..]",
302
+ describe: "Fix issues in code using Biome",
303
+ builder: (yargs) => yargs.positional("files", {
304
+ describe: "Specific files to fix (optional)",
305
+ type: "string",
306
+ array: true
307
+ }).option("unsafe", {
308
+ type: "boolean",
309
+ description: "Apply unsafe fixes"
310
+ }),
311
+ handler: (argv) => safeTry6(async function* () {
312
+ const packageManager = yield* getPackageManagerName();
313
+ const args = ["check", "--write"];
314
+ if (argv.unsafe) {
315
+ args.push("--unsafe");
316
+ }
317
+ if (argv.files && argv.files.length > 0) {
318
+ args.push(...argv.files);
319
+ }
320
+ const command = dlxCommand3(packageManager, biome.name, { args });
321
+ yield* runCommand(command);
322
+ return ok6();
323
+ }).match(() => {
324
+ process5.exit(0);
325
+ }, (error) => {
326
+ if (Fault6.isFault(error) && error.tag === "NO_PACKAGE_MANAGER") {
327
+ log3.error(error.flatten());
328
+ }
329
+ process5.exit(1);
330
+ })
331
+ });
332
+
333
+ // src/commands/format.ts
334
+ import process6 from "node:process";
335
+ import { log as log4 } from "@clack/prompts";
336
+ import { Fault as Fault7 } from "faultier";
337
+ import { ok as ok7, safeTry as safeTry7 } from "neverthrow";
338
+ import { dlxCommand as dlxCommand4 } from "nypm";
339
+ var format_default = defineCommand({
340
+ command: "format [files..]",
341
+ describe: "Format files using oxfmt",
342
+ builder: (yargs) => yargs.positional("files", {
343
+ describe: "Specific files to format (optional)",
344
+ type: "string",
345
+ array: true
346
+ }).option("check", {
347
+ type: "boolean",
348
+ description: "Check if files are formatted without writing"
349
+ }),
350
+ handler: (argv) => safeTry7(async function* () {
351
+ const packageManager = yield* getPackageManagerName();
352
+ const args = [];
353
+ if (argv.check) {
354
+ args.push("--check");
355
+ }
356
+ if (argv.files && argv.files.length > 0) {
357
+ args.push(...argv.files);
358
+ }
359
+ const command = dlxCommand4(packageManager, oxfmt.name, { args });
360
+ const result = yield* runCommand(command);
361
+ return ok7(result);
362
+ }).match(() => {
363
+ process6.exit(0);
364
+ }, (error) => {
365
+ if (Fault7.isFault(error) && error.tag === "NO_PACKAGE_MANAGER") {
366
+ log4.error(error.flatten());
367
+ }
368
+ process6.exit(1);
369
+ })
370
+ });
371
+
372
+ // src/commands/init.ts
373
+ import { writeFile as writeFile5 } from "node:fs/promises";
374
+ import { join as join6 } from "node:path";
375
+ import process7 from "node:process";
376
+ import * as p from "@clack/prompts";
377
+ import { Fault as Fault10 } from "faultier";
378
+ import { err as err4, fromPromise as fromPromise6, fromSafePromise, ok as ok10, safeTry as safeTry10 } from "neverthrow";
379
+ import { addDevDependency } from "nypm";
380
+
381
+ // src/helpers/editors/vscode.ts
382
+ import { mkdir, readFile as readFile4, writeFile as writeFile3 } from "node:fs/promises";
383
+ import { join as join4 } from "node:path";
384
+ import { Fault as Fault8 } from "faultier";
385
+ import { fromPromise as fromPromise4, ok as ok8, safeTry as safeTry8 } from "neverthrow";
386
+ var vscode = {
387
+ config: {
388
+ "typescript.tsdk": "node_modules/typescript/lib",
389
+ "editor.formatOnSave": true,
390
+ "editor.formatOnPaste": true,
391
+ "editor.codeActionsOnSave": {
392
+ "source.fixAll.biome": "explicit"
393
+ },
394
+ "[javascript][typescript][javascriptreact][typescriptreact][json][jsonc][css][graphql]": {
395
+ "editor.defaultFormatter": "oxc.oxc-vscode"
396
+ }
397
+ },
398
+ exists: () => checkIfExists(join4(process.cwd(), ".vscode", "settings.json")),
399
+ create: () => safeTry8(async function* () {
400
+ const vscodePath = join4(process.cwd(), ".vscode");
401
+ yield* fromPromise4(mkdir(vscodePath, { recursive: true }), (error) => Fault8.wrap(error).withTag("FAILED_TO_CREATE_DIRECTORY").withDescription("Failed to create .vscode directory", "We're unable to create the .vscode directory in the current directory.").withContext({ path: vscodePath }));
402
+ yield* fromPromise4(writeFile3(join4(vscodePath, "settings.json"), JSON.stringify(vscode.config, null, 2)), (error) => Fault8.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write .vscode/settings.json", "We're unable to write the .vscode/settings.json file in the current directory."));
403
+ return ok8();
404
+ }),
405
+ update: () => safeTry8(async function* () {
406
+ const vscodePath = join4(process.cwd(), ".vscode", "settings.json");
407
+ const vscodeFile = yield* fromPromise4(readFile4(vscodePath, "utf-8"), (error) => Fault8.wrap(error).withTag("FAILED_TO_READ_FILE").withDescription("Failed to read .vscode/settings.json", "We're unable to read the .vscode/settings.json file in the current directory.").withContext({ path: vscodePath }));
408
+ const existingConfig = yield* parseJson(vscodeFile);
409
+ const newConfig = yield* mergeConfig(vscode.config, existingConfig);
410
+ yield* fromPromise4(writeFile3(join4(process.cwd(), ".vscode", "settings.json"), JSON.stringify(newConfig, null, 2)), (error) => Fault8.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write .vscode/settings.json", "We're unable to write the .vscode/settings.json file in the current directory.").withContext({ path: vscodePath }));
411
+ return ok8();
412
+ })
413
+ };
414
+
415
+ // src/helpers/tsconfig.ts
416
+ import { readFile as readFile5, writeFile as writeFile4 } from "node:fs/promises";
417
+ import { join as join5 } from "node:path";
418
+ import { Fault as Fault9 } from "faultier";
419
+ import { fromPromise as fromPromise5, ok as ok9, safeTry as safeTry9 } from "neverthrow";
420
+ var tsconfig = {
421
+ config: { extends: "adamantite/tsconfig" },
422
+ exists: () => checkIfExists(join5(process.cwd(), "tsconfig.json")),
423
+ create: () => fromPromise5(writeFile4(join5(process.cwd(), "tsconfig.json"), JSON.stringify(tsconfig.config, null, 2)), (error) => Fault9.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write tsconfig.json", "We're unable to write the tsconfig.json file in the current directory.")),
424
+ update: () => safeTry9(async function* () {
425
+ const tsconfigFile = yield* fromPromise5(readFile5(join5(process.cwd(), "tsconfig.json"), "utf-8"), (error) => Fault9.wrap(error).withTag("FAILED_TO_READ_FILE").withDescription("Failed to read tsconfig.json", "We're unable to read the tsconfig.json file in the current directory."));
426
+ const existingConfig = yield* parseJson(tsconfigFile);
427
+ const newConfig = yield* mergeConfig(tsconfig.config, existingConfig);
428
+ yield* fromPromise5(writeFile4(join5(process.cwd(), "tsconfig.json"), JSON.stringify(newConfig, null, 2)), (error) => Fault9.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write tsconfig.json", "We're unable to write the tsconfig.json file in the current directory."));
429
+ return ok9();
430
+ })
431
+ };
432
+
433
+ // src/commands/init.ts
434
+ var installDependencies = (packages) => safeTry10(async function* () {
435
+ const s = p.spinner();
436
+ s.start("Installing dependencies...");
437
+ const isMonorepo = yield* checkIsMonorepo();
438
+ for (const pkg of packages) {
439
+ yield* fromPromise6(addDevDependency(pkg, { silent: true, workspace: isMonorepo }), (error) => Fault10.wrap(error).withTag("FAILED_TO_INSTALL_DEPENDENCY").withMessage(`Failed to install ${pkg}`));
440
+ }
441
+ s.stop("Dependencies installed.");
442
+ return ok10();
443
+ });
444
+ var setupBiomeConfig = () => safeTry10(async function* () {
445
+ const spinner2 = p.spinner();
446
+ spinner2.start("Setting up Biome config...");
447
+ const biomePath = await biome.exists();
448
+ if (biomePath.path) {
449
+ spinner2.message(`Found \`${biomePath.path}\`, updating...`);
450
+ yield* biome.update();
451
+ spinner2.stop("Biome config updated successfully.");
452
+ } else {
453
+ spinner2.message("`.biome.jsonc` or `.biome.json` not found, creating...");
454
+ yield* biome.create();
455
+ spinner2.stop("Biome config created successfully.");
456
+ }
457
+ return ok10();
458
+ });
459
+ var setupOxfmtConfig = () => safeTry10(async function* () {
460
+ const spinner2 = p.spinner();
461
+ spinner2.start("Setting up oxfmt config...");
462
+ const oxfmtPath = await oxfmt.exists();
463
+ if (oxfmtPath.path) {
464
+ spinner2.message(`Found \`${oxfmtPath.path}\`, updating...`);
465
+ yield* oxfmt.update();
466
+ spinner2.stop("oxfmt config updated successfully.");
467
+ } else {
468
+ spinner2.message("`.oxfmtrc.jsonc` or `.oxfmtrc.json` not found, creating...");
469
+ yield* oxfmt.create();
470
+ spinner2.stop("oxfmt config created successfully.");
471
+ }
472
+ return ok10();
473
+ });
474
+ var addScripts = (scripts) => safeTry10(async function* () {
475
+ const cwd = process7.cwd();
476
+ const packageJson = yield* readPackageJson();
477
+ const spinner2 = p.spinner();
478
+ spinner2.start("Adding scripts to your `package.json`...");
479
+ if (!packageJson.scripts) {
480
+ packageJson.scripts = {};
481
+ }
482
+ for (const script of scripts) {
483
+ switch (script) {
484
+ case "check":
485
+ packageJson.scripts.check = "adamantite check";
486
+ break;
487
+ case "fix":
488
+ packageJson.scripts.fix = "adamantite fix";
489
+ break;
490
+ case "format":
491
+ packageJson.scripts.format = "adamantite format";
492
+ break;
493
+ case "check:monorepo":
494
+ packageJson.scripts["check:monorepo"] = "adamantite monorepo";
495
+ break;
496
+ case "fix:monorepo":
497
+ packageJson.scripts["fix:monorepo"] = "adamantite monorepo --fix";
498
+ break;
499
+ default:
500
+ return err4(Fault10.create("UNKNOWN_SCRIPT").withContext({ script }));
501
+ }
502
+ }
503
+ yield* fromPromise6(writeFile5(join6(cwd, "package.json"), JSON.stringify(packageJson, null, 2)), (error) => Fault10.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write package.json", "We're unable to update the package.json file.").withContext({ path: join6(cwd, "package.json") }));
504
+ spinner2.stop("Scripts added to your `package.json`");
505
+ return ok10();
506
+ });
507
+ var setupTypescript = () => safeTry10(async function* () {
508
+ const spinner2 = p.spinner();
509
+ spinner2.start("Setting up TypeScript config...");
510
+ if (await tsconfig.exists()) {
511
+ spinner2.message("`tsconfig.json` found, updating...");
512
+ yield* tsconfig.update();
513
+ spinner2.stop("`tsconfig.json` updated successfully");
514
+ } else {
515
+ spinner2.message("`tsconfig.json` not found, creating...");
516
+ yield* tsconfig.create();
517
+ spinner2.stop("`tsconfig.json` created successfully");
518
+ }
519
+ return ok10();
520
+ });
521
+ var setupEditors = (editors) => safeTry10(async function* () {
522
+ if (editors.includes("vscode")) {
523
+ const spinner2 = p.spinner();
524
+ spinner2.start("Checking for `.vscode/settings.json`...");
525
+ if (await vscode.exists()) {
526
+ spinner2.message("`.vscode/settings.json` found, updating...");
527
+ yield* vscode.update();
528
+ spinner2.stop("`.vscode/settings.json` updated with Adamantite preset.");
529
+ } else {
530
+ spinner2.message("`.vscode/settings.json` not found, creating...");
531
+ yield* vscode.create();
532
+ spinner2.stop("`.vscode/settings.json` created with Adamantite preset.");
533
+ }
534
+ }
535
+ if (editors.includes("zed")) {}
536
+ return ok10();
537
+ });
538
+ var init_default = defineCommand({
539
+ command: "init",
540
+ describe: "Initialize Adamantite in the current directory",
541
+ builder: (yargs) => yargs,
542
+ handler: () => safeTry10(async function* () {
543
+ const packageManager = yield* getPackageManagerName();
544
+ printTitle();
545
+ p.intro("\uD83D\uDCA0 adamantite init");
546
+ p.log.info(`Detected package manager: ${packageManager}`);
547
+ const isMonorepo = yield* checkIsMonorepo();
548
+ if (isMonorepo) {
549
+ p.log.info("We've detected a monorepo setup in your project.");
550
+ }
551
+ const scripts = yield* fromSafePromise(p.multiselect({
552
+ message: "Which scripts do you want to add to your `package.json`?",
553
+ options: [
554
+ {
555
+ label: "check - find issues in code using Biome",
556
+ value: "check",
557
+ hint: "recommended"
558
+ },
559
+ {
560
+ label: "fix - fix code issues using Biome",
561
+ value: "fix",
562
+ hint: "recommended"
563
+ },
564
+ {
565
+ label: "format - code formatting using oxfmt",
566
+ value: "format",
567
+ hint: "recommended"
568
+ },
569
+ {
570
+ label: "check:monorepo - check for monorepo-specific issues using Sherif",
571
+ value: "check:monorepo",
572
+ hint: isMonorepo ? undefined : "available for monorepo projects",
573
+ disabled: !isMonorepo
574
+ },
575
+ {
576
+ label: "fix:monorepo - fix monorepo-specific issues using Sherif",
577
+ value: "fix:monorepo",
578
+ hint: isMonorepo ? undefined : "available for monorepo projects",
579
+ disabled: !isMonorepo
580
+ }
581
+ ]
582
+ }));
583
+ if (p.isCancel(scripts)) {
584
+ return err4(Fault10.create("OPERATION_CANCELLED"));
585
+ }
586
+ const typescriptPreset = yield* fromSafePromise(p.confirm({
587
+ message: "Adamantite provides a TypeScript preset to enforce strict type-safety. Would you like to install it?"
588
+ }));
589
+ if (p.isCancel(typescriptPreset)) {
590
+ return err4(Fault10.create("OPERATION_CANCELLED"));
591
+ }
592
+ const editors = yield* fromSafePromise(p.multiselect({
593
+ message: "Which editors do you want to configure? (optional)",
594
+ options: [
595
+ { label: "VSCode / Cursor / Windsurf", value: "vscode" },
596
+ { label: "Zed", value: "zed", disabled: true, hint: "coming soon" }
597
+ ],
598
+ required: false
599
+ }));
600
+ if (p.isCancel(editors)) {
601
+ return err4(Fault10.create("OPERATION_CANCELLED"));
602
+ }
603
+ const hasBiome = scripts.includes("check") || scripts.includes("fix");
604
+ const hasOxfmt = scripts.includes("format");
605
+ const hasSherif = scripts.includes("check:monorepo") || scripts.includes("fix:monorepo");
606
+ const dependencies = ["adamantite"];
607
+ if (hasBiome) {
608
+ dependencies.push(`${biome.name}@${biome.version}`);
609
+ }
610
+ if (hasOxfmt) {
611
+ dependencies.push(`${oxfmt.name}@${oxfmt.version}`);
612
+ }
613
+ if (hasSherif) {
614
+ dependencies.push(`${sherif.name}@${sherif.version}`);
615
+ }
616
+ yield* installDependencies(dependencies);
617
+ if (hasOxfmt) {
618
+ yield* setupOxfmtConfig();
619
+ }
620
+ if (hasBiome) {
621
+ yield* setupBiomeConfig();
622
+ }
623
+ yield* addScripts(scripts);
624
+ if (typescriptPreset) {
625
+ yield* setupTypescript();
626
+ }
627
+ yield* setupEditors(editors);
628
+ return ok10();
629
+ }).match(() => {
630
+ p.outro("\uD83D\uDCA0 Adamantite initialized successfully!");
631
+ process7.exit(0);
632
+ }, (error) => {
633
+ if (Fault10.isFault(error) && error.tag === "OPERATION_CANCELLED") {
634
+ p.cancel("You've cancelled the initialization process.");
635
+ process7.exit(0);
636
+ }
637
+ if (!Fault10.isFault(error)) {
638
+ p.log.error(`An unexpected error occurred: ${String(error)}`);
639
+ p.cancel("Failed to initialize Adamantite");
640
+ process7.exit(1);
641
+ }
642
+ p.log.error(error.flatten());
643
+ p.cancel("Failed to initialize Adamantite");
644
+ process7.exit(1);
645
+ })
646
+ });
647
+
648
+ // src/commands/monorepo.ts
649
+ import process8 from "node:process";
650
+ import { log as log6 } from "@clack/prompts";
651
+ import { Fault as Fault11 } from "faultier";
652
+ import { ok as ok11, safeTry as safeTry11 } from "neverthrow";
653
+ import { dlxCommand as dlxCommand5 } from "nypm";
654
+ var monorepo_default = defineCommand({
655
+ command: "monorepo",
656
+ describe: "Find and fix monorepo-specific issues using Sherif",
657
+ builder: (yargs) => yargs.option("fix", {
658
+ type: "boolean",
659
+ description: "Automatically fix issues"
660
+ }),
661
+ handler: (argv) => safeTry11(async function* () {
662
+ const packageManager = yield* getPackageManagerName();
663
+ const args = [];
664
+ if (argv.fix) {
665
+ args.push("--fix");
666
+ }
667
+ const command = dlxCommand5(packageManager, sherif.name, { args });
668
+ yield* runCommand(command);
669
+ return ok11(undefined);
670
+ }).match(() => {
671
+ process8.exit(0);
672
+ }, (error) => {
673
+ if (Fault11.isFault(error) && error.tag === "NO_PACKAGE_MANAGER") {
674
+ log6.error(error.flatten());
675
+ }
676
+ process8.exit(1);
677
+ })
678
+ });
679
+
680
+ // src/commands/update.ts
681
+ import process9 from "node:process";
682
+ import { cancel as cancel2, confirm as confirm2, intro as intro2, isCancel as isCancel2, log as log7, outro as outro2, spinner as spinner2 } from "@clack/prompts";
683
+ import { Fault as Fault12 } from "faultier";
684
+ import { err as err5, fromPromise as fromPromise7, fromSafePromise as fromSafePromise2, ok as ok12, safeTry as safeTry12 } from "neverthrow";
685
+ import { addDevDependency as addDevDependency2 } from "nypm";
686
+ var update_default = defineCommand({
687
+ command: "update",
688
+ describe: "Update adamantite dependencies to latest compatible versions",
689
+ builder: (yargs) => yargs,
690
+ handler: async () => safeTry12(async function* () {
691
+ const packageJson = yield* readPackageJson();
692
+ printTitle();
693
+ intro2("\uD83D\uDCA0 adamantite update");
694
+ const updates = [];
695
+ for (const pkg of [biome, oxfmt, sherif]) {
696
+ const dependency = packageJson.devDependencies?.[pkg.name];
697
+ if (dependency && normalizeDependencyVersion(dependency) !== pkg.version) {
698
+ updates.push({
699
+ name: pkg.name,
700
+ currentVersion: dependency,
701
+ targetVersion: pkg.version,
702
+ isDevDependency: true
703
+ });
704
+ }
705
+ }
706
+ if (updates.length === 0) {
707
+ log7.success("All adamantite dependencies are already up to date!");
708
+ return ok12("no-updates");
709
+ }
710
+ log7.message("The following dependencies will be updated:");
711
+ log7.message("");
712
+ for (const dep of updates) {
713
+ log7.message(` ${dep.name}: ${dep.currentVersion} → ${dep.targetVersion}`);
714
+ }
715
+ log7.message("");
716
+ const shouldUpdate = yield* fromSafePromise2(confirm2({
717
+ message: "Do you want to proceed with these updates?"
718
+ }));
719
+ if (isCancel2(shouldUpdate)) {
720
+ return err5(Fault12.create("OPERATION_CANCELLED"));
721
+ }
722
+ if (!shouldUpdate) {
723
+ return ok12("cancelled");
724
+ }
725
+ const s = spinner2();
726
+ s.start("Updating dependencies...");
727
+ for (const dep of updates) {
728
+ yield* fromPromise7(addDevDependency2(`${dep.name}@${dep.targetVersion}`), (error) => Fault12.wrap(error).withTag("FAILED_TO_INSTALL_DEPENDENCY").withMessage(`Failed to update ${dep.name}`));
729
+ }
730
+ s.stop("Dependencies updated successfully");
731
+ return ok12("updated");
732
+ }).match((value) => {
733
+ if (value === "no-updates") {
734
+ outro2("✅ No updates needed");
735
+ } else if (value === "cancelled") {
736
+ outro2("⚠️ Update cancelled");
737
+ } else if (value === "updated") {
738
+ outro2("✅ Dependencies updated successfully!");
739
+ }
740
+ process9.exit(0);
741
+ }, (error) => {
742
+ if (Fault12.isFault(error) && error.tag === "OPERATION_CANCELLED") {
743
+ cancel2("You've cancelled the update process.");
744
+ process9.exit(0);
745
+ }
746
+ if (Fault12.isFault(error)) {
747
+ log7.error(error.flatten());
748
+ } else {
749
+ log7.error(String(error));
750
+ }
751
+ cancel2("Failed to update dependencies");
752
+ process9.exit(1);
753
+ })
754
+ });
755
+
756
+ // src/index.ts
757
+ yargs(hideBin(process.argv)).scriptName("adamantite").version("0.15.0").command(check_default).command(ci_default).command(fix_default).command(format_default).command(init_default).command(monorepo_default).command(update_default).demandCommand(1).strict().help().parse();