adamantite 0.19.0 → 0.22.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 CHANGED
@@ -2,18 +2,48 @@
2
2
  import yargs from "yargs";
3
3
  import { hideBin } from "yargs/helpers";
4
4
 
5
- // src/commands/check.ts
5
+ // src/commands/analyze.ts
6
6
  import process3 from "node:process";
7
7
  import { log } from "@clack/prompts";
8
8
  import { Fault as Fault3 } from "faultier";
9
9
  import { ok as ok3, safeTry as safeTry3 } from "neverthrow";
10
10
  import { dlxCommand } from "nypm";
11
11
 
12
- // src/helpers/packages/oxlint.ts
12
+ // src/helpers/packages/knip.ts
13
13
  import { readFile as readFile2, writeFile } from "node:fs/promises";
14
14
  import { join as join2 } from "node:path";
15
15
  import { Fault as Fault2 } from "faultier";
16
16
  import { err as err2, fromPromise as fromPromise2, ok as ok2, safeTry as safeTry2 } from "neverthrow";
17
+ // presets/knip.json
18
+ var knip_default = {
19
+ $schema: "https://unpkg.com/knip@5/schema.json",
20
+ rules: {
21
+ files: "error",
22
+ dependencies: "error",
23
+ devDependencies: "error",
24
+ optionalPeerDependencies: "warn",
25
+ unlisted: "error",
26
+ binaries: "error",
27
+ unresolved: "error",
28
+ exports: "warn",
29
+ nsExports: "warn",
30
+ types: "warn",
31
+ nsTypes: "warn",
32
+ enumMembers: "off",
33
+ classMembers: "off",
34
+ duplicates: "warn"
35
+ },
36
+ ignoreExportsUsedInFile: true,
37
+ ignoreFiles: [
38
+ "**/dist/**",
39
+ "**/build/**",
40
+ "**/coverage/**",
41
+ "**/.next/**",
42
+ "**/.vercel/**",
43
+ "**/.turbo/**"
44
+ ],
45
+ ignore: ["**/*.d.ts"]
46
+ };
17
47
 
18
48
  // src/utils.ts
19
49
  import { spawnSync } from "node:child_process";
@@ -42,6 +72,15 @@ var runCommand = (command) => {
42
72
  };
43
73
  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
74
  var checkIfExists = (path) => fromPromise(access(path), () => new Error("File not found")).match(() => true, () => false);
75
+ var checkCliExists = (command) => {
76
+ const result = spawnSync(process2.platform === "win32" ? "where" : "which", [command], {
77
+ stdio: "pipe"
78
+ });
79
+ if (result.status !== 0) {
80
+ return err(Fault.create("CLI_NOT_FOUND").withDescription(`CLI '${command}' not found`, `The '${command}' command is not available in your PATH.`).withContext({ command }));
81
+ }
82
+ return ok(true);
83
+ };
45
84
  var parseJson = (content) => {
46
85
  const errors = [];
47
86
  const parsed = parse(content, errors);
@@ -81,16 +120,100 @@ d8( 888 888 888 d8( 888 888 888 888 d8( 888 888 888 888 .
81
120
  }
82
121
  }
83
122
 
123
+ // src/helpers/packages/knip.ts
124
+ var knip = {
125
+ name: "knip",
126
+ version: "5.79.0",
127
+ config: knip_default,
128
+ exists: async () => {
129
+ if (await checkIfExists(join2(process.cwd(), "knip.json"))) {
130
+ return { path: join2(process.cwd(), "knip.json") };
131
+ }
132
+ if (await checkIfExists(join2(process.cwd(), "knip.jsonc"))) {
133
+ return { path: join2(process.cwd(), "knip.jsonc") };
134
+ }
135
+ return { path: null };
136
+ },
137
+ create: () => fromPromise2(writeFile(join2(process.cwd(), "knip.json"), JSON.stringify(knip.config, null, 2)), (error) => Fault2.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write knip configuration", "We're unable to write the knip configuration to the current directory.")),
138
+ update: () => safeTry2(async function* () {
139
+ const exists = await knip.exists();
140
+ if (!exists.path) {
141
+ return err2(Fault2.create("FILE_NOT_FOUND").withDescription("No `knip.json` or `knip.jsonc` found", "We're unable to find a knip configuration in the current directory."));
142
+ }
143
+ const knipFile = yield* fromPromise2(readFile2(exists.path, "utf8"), (error) => Fault2.wrap(error).withTag("FAILED_TO_READ_FILE").withDescription("Failed to read knip configuration", "We're unable to read the knip configuration from the current directory."));
144
+ const existingConfig = yield* parseJson(knipFile);
145
+ if (!isJsonObject(existingConfig)) {
146
+ return err2(Fault2.create("INVALID_CONFIG_FORMAT").withDescription("Invalid knip configuration format", "The knip configuration must be a JSON object."));
147
+ }
148
+ const mergedConfig = yield* mergeConfig(existingConfig, knip.config);
149
+ const isJsonc = exists.path.endsWith(".jsonc");
150
+ mergedConfig.$schema = isJsonc ? "https://unpkg.com/knip@5/schema-jsonc.json" : "https://unpkg.com/knip@5/schema.json";
151
+ yield* fromPromise2(writeFile(exists.path, JSON.stringify(mergedConfig, null, 2)), (error) => Fault2.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write knip configuration", "We're unable to write the knip configuration to the current directory.").withContext({ path: exists.path }));
152
+ return ok2();
153
+ })
154
+ };
155
+
156
+ // src/commands/analyze.ts
157
+ var analyze_default = defineCommand({
158
+ command: "analyze [files..]",
159
+ describe: "Find unused dependencies, exports, and files using knip",
160
+ builder: (yargs) => yargs.positional("files", {
161
+ describe: "Specific files to analyze (optional)",
162
+ type: "string",
163
+ array: true
164
+ }).option("fix", {
165
+ type: "boolean",
166
+ description: "Automatically fix issues"
167
+ }).option("strict", {
168
+ type: "boolean",
169
+ description: "Enable strict mode"
170
+ }),
171
+ handler: (argv) => safeTry3(async function* () {
172
+ const packageManager = yield* getPackageManagerName();
173
+ const args = [];
174
+ if (argv.fix) {
175
+ args.push("--fix", "--allow-remove-files");
176
+ }
177
+ if (argv.strict) {
178
+ args.push("--production", "--strict");
179
+ }
180
+ if (argv.files && argv.files.length > 0) {
181
+ args.push(...argv.files);
182
+ }
183
+ const command = dlxCommand(packageManager, knip.name, { args });
184
+ yield* runCommand(command);
185
+ return ok3();
186
+ }).match(() => {
187
+ process3.exit(0);
188
+ }, (error) => {
189
+ if (Fault3.isFault(error) && error.tag === "NO_PACKAGE_MANAGER") {
190
+ log.error(error.flatten());
191
+ }
192
+ process3.exit(1);
193
+ })
194
+ });
195
+
196
+ // src/commands/check.ts
197
+ import process4 from "node:process";
198
+ import { log as log2 } from "@clack/prompts";
199
+ import { Fault as Fault5 } from "faultier";
200
+ import { ok as ok5, safeTry as safeTry5 } from "neverthrow";
201
+ import { dlxCommand as dlxCommand2 } from "nypm";
202
+
84
203
  // src/helpers/packages/oxlint.ts
204
+ import { readFile as readFile3, writeFile as writeFile2 } from "node:fs/promises";
205
+ import { join as join3 } from "node:path";
206
+ import { Fault as Fault4 } from "faultier";
207
+ import { err as err3, fromPromise as fromPromise3, ok as ok4, safeTry as safeTry4 } from "neverthrow";
85
208
  var oxlint = {
86
209
  name: "oxlint",
87
- version: "1.35.0",
210
+ version: "1.36.0",
88
211
  config: {
89
212
  $schema: "./node_modules/oxlint/configuration_schema.json"
90
213
  },
91
214
  exists: async () => {
92
- if (await checkIfExists(join2(process.cwd(), ".oxlintrc.json"))) {
93
- return { path: join2(process.cwd(), ".oxlintrc.json") };
215
+ if (await checkIfExists(join3(process.cwd(), ".oxlintrc.json"))) {
216
+ return { path: join3(process.cwd(), ".oxlintrc.json") };
94
217
  }
95
218
  return { path: null };
96
219
  },
@@ -99,17 +222,17 @@ var oxlint = {
99
222
  for (const preset of presets) {
100
223
  extendsArray.push(`adamantite/lint/${preset}`);
101
224
  }
102
- return fromPromise2(writeFile(join2(process.cwd(), ".oxlintrc.json"), JSON.stringify({ ...oxlint.config, extends: extendsArray }, null, 2)), (error) => Fault2.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write oxlint configuration", "We're unable to write the oxlint configuration to the current directory."));
225
+ return fromPromise3(writeFile2(join3(process.cwd(), ".oxlintrc.json"), JSON.stringify({ ...oxlint.config, extends: extendsArray }, null, 2)), (error) => Fault4.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write oxlint configuration", "We're unable to write the oxlint configuration to the current directory."));
103
226
  },
104
- update: (presets = []) => safeTry2(async function* () {
227
+ update: (presets = []) => safeTry4(async function* () {
105
228
  const exists = await oxlint.exists();
106
229
  if (!exists.path) {
107
- return err2(Fault2.create("FILE_NOT_FOUND").withDescription("No `.oxlintrc.json` found", "We're unable to find an oxlint configuration in the current directory."));
230
+ return err3(Fault4.create("FILE_NOT_FOUND").withDescription("No `.oxlintrc.json` found", "We're unable to find an oxlint configuration in the current directory."));
108
231
  }
109
- const oxlintFile = yield* fromPromise2(readFile2(exists.path, "utf8"), (error) => Fault2.wrap(error).withTag("FAILED_TO_READ_FILE").withDescription("Failed to read oxlint configuration", "We're unable to read the oxlint configuration from the current directory."));
232
+ const oxlintFile = yield* fromPromise3(readFile3(exists.path, "utf8"), (error) => Fault4.wrap(error).withTag("FAILED_TO_READ_FILE").withDescription("Failed to read oxlint configuration", "We're unable to read the oxlint configuration from the current directory."));
110
233
  const existingConfig = yield* parseJson(oxlintFile);
111
234
  if (!isJsonObject(existingConfig)) {
112
- return err2(Fault2.create("INVALID_CONFIG_FORMAT").withDescription("Invalid oxlint configuration format", "The oxlint configuration must be a JSON object."));
235
+ return err3(Fault4.create("INVALID_CONFIG_FORMAT").withDescription("Invalid oxlint configuration format", "The oxlint configuration must be a JSON object."));
113
236
  }
114
237
  const newConfig = { ...existingConfig };
115
238
  const extendsArray = Array.isArray(newConfig.extends) ? newConfig.extends : typeof newConfig.extends === "string" ? [newConfig.extends] : [];
@@ -126,13 +249,13 @@ var oxlint = {
126
249
  newConfig.extends = extendsArray;
127
250
  const mergedConfig = yield* mergeConfig(newConfig, oxlint.config);
128
251
  mergedConfig.$schema = oxlint.config.$schema;
129
- yield* fromPromise2(writeFile(exists.path, JSON.stringify(mergedConfig, null, 2)), (error) => Fault2.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write oxlint configuration", "We're unable to write the oxlint configuration to the current directory.").withContext({ path: exists.path }));
130
- return ok2();
252
+ yield* fromPromise3(writeFile2(exists.path, JSON.stringify(mergedConfig, null, 2)), (error) => Fault4.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write oxlint configuration", "We're unable to write the oxlint configuration to the current directory.").withContext({ path: exists.path }));
253
+ return ok4();
131
254
  })
132
255
  };
133
256
  var tsgolint = {
134
257
  name: "oxlint-tsgolint",
135
- version: "0.10.0"
258
+ version: "0.10.1"
136
259
  };
137
260
 
138
261
  // src/commands/check.ts
@@ -144,31 +267,31 @@ var check_default = defineCommand({
144
267
  type: "string",
145
268
  array: true
146
269
  }),
147
- handler: (argv) => safeTry3(async function* () {
270
+ handler: (argv) => safeTry5(async function* () {
148
271
  const packageManager = yield* getPackageManagerName();
149
272
  const args = ["--type-aware"];
150
273
  if (argv.files && argv.files.length > 0) {
151
274
  args.push(...argv.files);
152
275
  }
153
- const command = dlxCommand(packageManager, oxlint.name, { args });
276
+ const command = dlxCommand2(packageManager, oxlint.name, { args });
154
277
  const result = yield* runCommand(command);
155
- return ok3(result);
278
+ return ok5(result);
156
279
  }).match(() => {
157
- process3.exit(0);
280
+ process4.exit(0);
158
281
  }, (error) => {
159
- if (Fault3.isFault(error) && error.tag === "NO_PACKAGE_MANAGER") {
160
- log.error(error.flatten());
282
+ if (Fault5.isFault(error) && error.tag === "NO_PACKAGE_MANAGER") {
283
+ log2.error(error.flatten());
161
284
  }
162
- process3.exit(1);
285
+ process4.exit(1);
163
286
  })
164
287
  });
165
288
 
166
289
  // src/commands/fix.ts
167
- import process4 from "node:process";
168
- import { log as log2 } from "@clack/prompts";
169
- import { Fault as Fault4 } from "faultier";
170
- import { ok as ok4, safeTry as safeTry4 } from "neverthrow";
171
- import { dlxCommand as dlxCommand2 } from "nypm";
290
+ import process5 from "node:process";
291
+ import { log as log3 } from "@clack/prompts";
292
+ import { Fault as Fault6 } from "faultier";
293
+ import { ok as ok6, safeTry as safeTry6 } from "neverthrow";
294
+ import { dlxCommand as dlxCommand3 } from "nypm";
172
295
  var fix_default = defineCommand({
173
296
  command: "fix [files..]",
174
297
  describe: "Fix issues in code using oxlint",
@@ -189,7 +312,7 @@ var fix_default = defineCommand({
189
312
  description: "Apply all fixes, including suggested and dangerous fixes",
190
313
  default: false
191
314
  }),
192
- handler: (argv) => safeTry4(async function* () {
315
+ handler: (argv) => safeTry6(async function* () {
193
316
  const packageManager = yield* getPackageManagerName();
194
317
  const args = new Set(["--type-aware", "--fix"]);
195
318
  if (argv.suggested) {
@@ -207,31 +330,31 @@ var fix_default = defineCommand({
207
330
  args.add(file);
208
331
  }
209
332
  }
210
- const command = dlxCommand2(packageManager, oxlint.name, { args: Array.from(args) });
333
+ const command = dlxCommand3(packageManager, oxlint.name, { args: Array.from(args) });
211
334
  yield* runCommand(command);
212
- return ok4();
335
+ return ok6();
213
336
  }).match(() => {
214
- process4.exit(0);
337
+ process5.exit(0);
215
338
  }, (error) => {
216
- if (Fault4.isFault(error) && error.tag === "NO_PACKAGE_MANAGER") {
217
- log2.error(error.flatten());
339
+ if (Fault6.isFault(error) && error.tag === "NO_PACKAGE_MANAGER") {
340
+ log3.error(error.flatten());
218
341
  }
219
- process4.exit(1);
342
+ process5.exit(1);
220
343
  })
221
344
  });
222
345
 
223
346
  // src/commands/format.ts
224
- import process5 from "node:process";
225
- import { log as log3 } from "@clack/prompts";
226
- import { Fault as Fault6 } from "faultier";
227
- import { ok as ok6, safeTry as safeTry6 } from "neverthrow";
228
- import { dlxCommand as dlxCommand3 } from "nypm";
347
+ import process6 from "node:process";
348
+ import { log as log4 } from "@clack/prompts";
349
+ import { Fault as Fault8 } from "faultier";
350
+ import { ok as ok8, safeTry as safeTry8 } from "neverthrow";
351
+ import { dlxCommand as dlxCommand4 } from "nypm";
229
352
 
230
353
  // src/helpers/packages/oxfmt.ts
231
- import { readFile as readFile3, writeFile as writeFile2 } from "node:fs/promises";
232
- import { join as join3 } from "node:path";
233
- import { Fault as Fault5 } from "faultier";
234
- import { err as err3, fromPromise as fromPromise3, ok as ok5, safeTry as safeTry5 } from "neverthrow";
354
+ import { readFile as readFile4, writeFile as writeFile3 } from "node:fs/promises";
355
+ import { join as join4 } from "node:path";
356
+ import { Fault as Fault7 } from "faultier";
357
+ import { err as err4, fromPromise as fromPromise4, ok as ok7, safeTry as safeTry7 } from "neverthrow";
235
358
  // presets/oxfmt.json
236
359
  var oxfmt_default = {
237
360
  arrowParens: "always",
@@ -274,35 +397,35 @@ var oxfmt_default = {
274
397
  // src/helpers/packages/oxfmt.ts
275
398
  var oxfmt = {
276
399
  name: "oxfmt",
277
- version: "0.20.0",
400
+ version: "0.21.0",
278
401
  config: {
279
402
  $schema: "./node_modules/oxfmt/configuration_schema.json",
280
403
  ...oxfmt_default
281
404
  },
282
405
  exists: async () => {
283
- if (await checkIfExists(join3(process.cwd(), ".oxfmtrc.jsonc"))) {
284
- return { path: join3(process.cwd(), ".oxfmtrc.jsonc") };
406
+ if (await checkIfExists(join4(process.cwd(), ".oxfmtrc.jsonc"))) {
407
+ return { path: join4(process.cwd(), ".oxfmtrc.jsonc") };
285
408
  }
286
- if (await checkIfExists(join3(process.cwd(), ".oxfmtrc.json"))) {
287
- return { path: join3(process.cwd(), ".oxfmtrc.json") };
409
+ if (await checkIfExists(join4(process.cwd(), ".oxfmtrc.json"))) {
410
+ return { path: join4(process.cwd(), ".oxfmtrc.json") };
288
411
  }
289
412
  return { path: null };
290
413
  },
291
- create: () => fromPromise3(writeFile2(join3(process.cwd(), ".oxfmtrc.jsonc"), JSON.stringify(oxfmt.config, null, 2)), (error) => Fault5.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.")),
292
- update: () => safeTry5(async function* () {
414
+ create: () => fromPromise4(writeFile3(join4(process.cwd(), ".oxfmtrc.jsonc"), JSON.stringify(oxfmt.config, null, 2)), (error) => Fault7.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.")),
415
+ update: () => safeTry7(async function* () {
293
416
  const exists = await oxfmt.exists();
294
417
  if (!exists.path) {
295
- return err3(Fault5.create("FILE_NOT_FOUND").withDescription("No `.oxfmtrc.jsonc` or `.oxfmtrc.json` found", "We're unable to find an oxfmt configuration in the current directory."));
418
+ return err4(Fault7.create("FILE_NOT_FOUND").withDescription("No `.oxfmtrc.jsonc` or `.oxfmtrc.json` found", "We're unable to find an oxfmt configuration in the current directory."));
296
419
  }
297
- const oxfmtFile = yield* fromPromise3(readFile3(exists.path, "utf8"), (error) => Fault5.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."));
420
+ const oxfmtFile = yield* fromPromise4(readFile4(exists.path, "utf8"), (error) => Fault7.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."));
298
421
  const existingConfig = yield* parseJson(oxfmtFile);
299
422
  if (!isJsonObject(existingConfig)) {
300
- return err3(Fault5.create("INVALID_CONFIG_FORMAT").withDescription("Invalid oxfmt configuration format", "The oxfmt configuration must be a JSON object."));
423
+ return err4(Fault7.create("INVALID_CONFIG_FORMAT").withDescription("Invalid oxfmt configuration format", "The oxfmt configuration must be a JSON object."));
301
424
  }
302
425
  const mergedConfig = yield* mergeConfig(existingConfig, oxfmt.config);
303
426
  mergedConfig.$schema = oxfmt.config.$schema;
304
- yield* fromPromise3(writeFile2(exists.path, JSON.stringify(mergedConfig, null, 2)), (error) => Fault5.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 }));
305
- return ok5();
427
+ yield* fromPromise4(writeFile3(exists.path, JSON.stringify(mergedConfig, null, 2)), (error) => Fault7.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 }));
428
+ return ok7();
306
429
  })
307
430
  };
308
431
 
@@ -318,7 +441,7 @@ var format_default = defineCommand({
318
441
  type: "boolean",
319
442
  description: "Check if files are formatted without writing"
320
443
  }),
321
- handler: (argv) => safeTry6(async function* () {
444
+ handler: (argv) => safeTry8(async function* () {
322
445
  const packageManager = yield* getPackageManagerName();
323
446
  const args = [];
324
447
  if (argv.check) {
@@ -327,34 +450,34 @@ var format_default = defineCommand({
327
450
  if (argv.files && argv.files.length > 0) {
328
451
  args.push(...argv.files);
329
452
  }
330
- const command = dlxCommand3(packageManager, oxfmt.name, { args });
453
+ const command = dlxCommand4(packageManager, oxfmt.name, { args });
331
454
  const result = yield* runCommand(command);
332
- return ok6(result);
455
+ return ok8(result);
333
456
  }).match(() => {
334
- process5.exit(0);
457
+ process6.exit(0);
335
458
  }, (error) => {
336
- if (Fault6.isFault(error) && error.tag === "NO_PACKAGE_MANAGER") {
337
- log3.error(error.flatten());
459
+ if (Fault8.isFault(error) && error.tag === "NO_PACKAGE_MANAGER") {
460
+ log4.error(error.flatten());
338
461
  }
339
- process5.exit(1);
462
+ process6.exit(1);
340
463
  })
341
464
  });
342
465
 
343
466
  // src/commands/init.ts
344
- import { writeFile as writeFile6 } from "node:fs/promises";
345
- import { join as join7 } from "node:path";
346
- import process7 from "node:process";
467
+ import { writeFile as writeFile7 } from "node:fs/promises";
468
+ import { join as join8 } from "node:path";
469
+ import process8 from "node:process";
347
470
  import * as p from "@clack/prompts";
348
- import { Fault as Fault10 } from "faultier";
349
- import { err as err6, fromPromise as fromPromise7, fromSafePromise, ok as ok10, safeTry as safeTry10 } from "neverthrow";
471
+ import { Fault as Fault12 } from "faultier";
472
+ import { err as err7, fromPromise as fromPromise8, fromSafePromise, ok as ok12, safeTry as safeTry12 } from "neverthrow";
350
473
  import { addDevDependency } from "nypm";
351
474
 
352
475
  // src/helpers/ci/github.ts
353
- import { mkdir, writeFile as writeFile3 } from "node:fs/promises";
354
- import { join as join4 } from "node:path";
355
- import process6 from "node:process";
356
- import { Fault as Fault7 } from "faultier";
357
- import { fromPromise as fromPromise4, ok as ok7, safeTry as safeTry7 } from "neverthrow";
476
+ import { mkdir, writeFile as writeFile4 } from "node:fs/promises";
477
+ import { join as join5 } from "node:path";
478
+ import process7 from "node:process";
479
+ import { Fault as Fault9 } from "faultier";
480
+ import { fromPromise as fromPromise5, ok as ok9, safeTry as safeTry9 } from "neverthrow";
358
481
  import { runScriptCommand } from "nypm";
359
482
  var setupSteps = {
360
483
  bun: ` - name: Setup Bun
@@ -432,6 +555,12 @@ var generateWorkflow = ({ packageManager, scripts }) => {
432
555
  command: buildCommand(packageManager, "check:monorepo")
433
556
  });
434
557
  }
558
+ if (scripts.includes("analyze")) {
559
+ matrixEntries.push({
560
+ name: "analyze",
561
+ command: buildCommand(packageManager, "analyze")
562
+ });
563
+ }
435
564
  if (matrixEntries.length === 0) {
436
565
  return null;
437
566
  }
@@ -476,65 +605,108 @@ ${setupSteps[packageManager]}
476
605
  return `${workflow}
477
606
  `;
478
607
  };
479
- var hasCICompatibleScripts = (scripts) => scripts.some((script) => ["check", "format", "typecheck", "check:monorepo"].includes(script));
608
+ var CI_COMPATIBLE_SCRIPTS = new Set([
609
+ "check",
610
+ "format",
611
+ "typecheck",
612
+ "check:monorepo",
613
+ "analyze"
614
+ ]);
615
+ var hasCICompatibleScripts = (scripts) => scripts.some((script) => CI_COMPATIBLE_SCRIPTS.has(script));
480
616
  var github = {
481
617
  workflowPath: ".github/workflows/adamantite.yml",
482
- exists: () => checkIfExists(join4(process6.cwd(), ".github", "workflows", "adamantite.yml")),
483
- create: (options) => safeTry7(async function* () {
484
- const workflowDir = join4(process6.cwd(), ".github", "workflows");
485
- yield* fromPromise4(mkdir(workflowDir, { recursive: true }), (error) => Fault7.wrap(error).withTag("FAILED_TO_CREATE_DIRECTORY").withDescription("Failed to create .github/workflows directory", "We're unable to create the .github/workflows directory in the current directory.").withContext({ path: workflowDir }));
618
+ exists: () => checkIfExists(join5(process7.cwd(), ".github", "workflows", "adamantite.yml")),
619
+ create: (options) => safeTry9(async function* () {
620
+ const workflowDir = join5(process7.cwd(), ".github", "workflows");
621
+ yield* fromPromise5(mkdir(workflowDir, { recursive: true }), (error) => Fault9.wrap(error).withTag("FAILED_TO_CREATE_DIRECTORY").withDescription("Failed to create .github/workflows directory", "We're unable to create the .github/workflows directory in the current directory.").withContext({ path: workflowDir }));
486
622
  const workflowContent = generateWorkflow(options);
487
623
  if (!workflowContent) {
488
- return ok7();
624
+ return ok9();
489
625
  }
490
- yield* fromPromise4(writeFile3(join4(workflowDir, "adamantite.yml"), workflowContent), (error) => Fault7.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write GitHub Actions workflow", "We're unable to write the GitHub Actions workflow file.").withContext({ path: join4(workflowDir, "adamantite.yml") }));
491
- return ok7();
626
+ yield* fromPromise5(writeFile4(join5(workflowDir, "adamantite.yml"), workflowContent), (error) => Fault9.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write GitHub Actions workflow", "We're unable to write the GitHub Actions workflow file.").withContext({ path: join5(workflowDir, "adamantite.yml") }));
627
+ return ok9();
492
628
  }),
493
- update: (options) => safeTry7(async function* () {
494
- const workflowPath = join4(process6.cwd(), ".github", "workflows", "adamantite.yml");
629
+ update: (options) => safeTry9(async function* () {
630
+ const workflowPath = join5(process7.cwd(), ".github", "workflows", "adamantite.yml");
495
631
  const workflowContent = generateWorkflow(options);
496
632
  if (!workflowContent) {
497
- return ok7();
633
+ return ok9();
498
634
  }
499
- yield* fromPromise4(writeFile3(workflowPath, workflowContent), (error) => Fault7.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write GitHub Actions workflow", "We're unable to update the GitHub Actions workflow file.").withContext({ path: workflowPath }));
500
- return ok7();
635
+ yield* fromPromise5(writeFile4(workflowPath, workflowContent), (error) => Fault9.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write GitHub Actions workflow", "We're unable to update the GitHub Actions workflow file.").withContext({ path: workflowPath }));
636
+ return ok9();
501
637
  })
502
638
  };
503
639
 
504
640
  // src/helpers/editors/vscode.ts
505
- import { mkdir as mkdir2, readFile as readFile4, writeFile as writeFile4 } from "node:fs/promises";
506
- import { join as join5 } from "node:path";
507
- import { Fault as Fault8 } from "faultier";
508
- import { err as err4, fromPromise as fromPromise5, ok as ok8, safeTry as safeTry8 } from "neverthrow";
641
+ import { mkdir as mkdir2, readFile as readFile5, writeFile as writeFile5 } from "node:fs/promises";
642
+ import { join as join6 } from "node:path";
643
+ import { Fault as Fault10 } from "faultier";
644
+ import { err as err5, fromPromise as fromPromise6, ok as ok10, safeTry as safeTry10 } from "neverthrow";
509
645
  var vscode = {
510
646
  config: {
511
647
  "typescript.tsdk": "node_modules/typescript/lib",
648
+ "editor.defaultFormatter": "oxc.oxc-vscode",
512
649
  "editor.formatOnSave": true,
513
650
  "editor.formatOnPaste": true,
514
651
  "editor.codeActionsOnSave": {
515
652
  "source.fixAll.oxc": "explicit"
516
653
  },
517
- "[javascript][typescript][javascriptreact][typescriptreact][json][jsonc][css][graphql]": {
654
+ "[javascript]": {
655
+ "editor.defaultFormatter": "oxc.oxc-vscode"
656
+ },
657
+ "[typescript]": {
658
+ "editor.defaultFormatter": "oxc.oxc-vscode"
659
+ },
660
+ "[javascriptreact]": {
661
+ "editor.defaultFormatter": "oxc.oxc-vscode"
662
+ },
663
+ "[typescriptreact]": {
664
+ "editor.defaultFormatter": "oxc.oxc-vscode"
665
+ },
666
+ "[json]": {
667
+ "editor.defaultFormatter": "oxc.oxc-vscode"
668
+ },
669
+ "[jsonc]": {
670
+ "editor.defaultFormatter": "oxc.oxc-vscode"
671
+ },
672
+ "[css]": {
673
+ "editor.defaultFormatter": "oxc.oxc-vscode"
674
+ },
675
+ "[graphql]": {
518
676
  "editor.defaultFormatter": "oxc.oxc-vscode"
519
677
  }
520
678
  },
521
- exists: () => checkIfExists(join5(process.cwd(), ".vscode", "settings.json")),
522
- create: () => safeTry8(async function* () {
523
- const vscodePath = join5(process.cwd(), ".vscode");
524
- yield* fromPromise5(mkdir2(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 }));
525
- yield* fromPromise5(writeFile4(join5(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."));
526
- return ok8();
679
+ exists: () => checkIfExists(join6(process.cwd(), ".vscode", "settings.json")),
680
+ cliExists: () => checkCliExists("code").mapErr((error) => Fault10.wrap(error).withTag("VSCODE_CLI_NOT_FOUND").withDescription("VS Code CLI not found", "The 'code' CLI command is not available. Please install the VS Code command-line tools by opening VS Code and running 'Shell Command: Install code command in PATH' from the command palette (Cmd+Shift+P).")),
681
+ create: () => safeTry10(async function* () {
682
+ const vscodePath = join6(process.cwd(), ".vscode");
683
+ yield* fromPromise6(mkdir2(vscodePath, { recursive: true }), (error) => Fault10.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 }));
684
+ yield* fromPromise6(writeFile5(join6(vscodePath, "settings.json"), JSON.stringify(vscode.config, null, 2)), (error) => Fault10.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."));
685
+ return ok10();
527
686
  }),
528
- update: () => safeTry8(async function* () {
529
- const vscodePath = join5(process.cwd(), ".vscode", "settings.json");
530
- const vscodeFile = yield* fromPromise5(readFile4(vscodePath, "utf8"), (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 }));
687
+ update: () => safeTry10(async function* () {
688
+ const vscodePath = join6(process.cwd(), ".vscode", "settings.json");
689
+ const vscodeFile = yield* fromPromise6(readFile5(vscodePath, "utf8"), (error) => Fault10.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 }));
531
690
  const existingConfig = yield* parseJson(vscodeFile);
532
691
  if (!isJsonObject(existingConfig)) {
533
- return err4(Fault8.create("INVALID_CONFIG_FORMAT").withDescription("Invalid .vscode/settings.json format", "The VS Code settings file must be a JSON object."));
692
+ return err5(Fault10.create("INVALID_CONFIG_FORMAT").withDescription("Invalid .vscode/settings.json format", "The VS Code settings file must be a JSON object."));
534
693
  }
535
694
  const newConfig = yield* mergeConfig(vscode.config, existingConfig);
536
- yield* fromPromise5(writeFile4(join5(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 }));
537
- return ok8();
695
+ yield* fromPromise6(writeFile5(join6(process.cwd(), ".vscode", "settings.json"), JSON.stringify(newConfig, null, 2)), (error) => Fault10.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 }));
696
+ return ok10();
697
+ }),
698
+ extension: (scripts = []) => safeTry10(function* () {
699
+ yield* vscode.cliExists();
700
+ if (scripts.includes("check") || scripts.includes("fix") || scripts.includes("format")) {
701
+ yield* runCommand("code --install-extension oxc.oxc-vscode").mapErr((error) => Fault10.wrap(error).withTag("FAILED_TO_INSTALL_EXTENSION").withDescription("Failed to install VS Code extension", "An error occurred while installing the VS Code extension."));
702
+ }
703
+ if (scripts.includes("analyze")) {
704
+ yield* runCommand("code --install-extension webpro.vscode-knip").mapErr((error) => Fault10.wrap(error).withTag("FAILED_TO_INSTALL_EXTENSION").withDescription("Failed to install VS Code extension", "An error occurred while installing the VS Code extension."));
705
+ }
706
+ if (scripts.includes("typecheck")) {
707
+ yield* runCommand("code --install-extension TypeScriptTeam.native-preview").mapErr((error) => Fault10.wrap(error).withTag("FAILED_TO_INSTALL_EXTENSION").withDescription("Failed to install VS Code extension", "An error occurred while installing the VS Code extension."));
708
+ }
709
+ return ok10();
538
710
  })
539
711
  };
540
712
 
@@ -545,42 +717,42 @@ var sherif = {
545
717
  };
546
718
 
547
719
  // src/helpers/packages/typescript.ts
548
- import { readFile as readFile5, writeFile as writeFile5 } from "node:fs/promises";
549
- import { join as join6 } from "node:path";
550
- import { Fault as Fault9 } from "faultier";
551
- import { err as err5, fromPromise as fromPromise6, ok as ok9, safeTry as safeTry9 } from "neverthrow";
720
+ import { readFile as readFile6, writeFile as writeFile6 } from "node:fs/promises";
721
+ import { join as join7 } from "node:path";
722
+ import { Fault as Fault11 } from "faultier";
723
+ import { err as err6, fromPromise as fromPromise7, ok as ok11, safeTry as safeTry11 } from "neverthrow";
552
724
  var typescript = {
553
725
  name: "@typescript/native-preview",
554
- version: "7.0.0-dev.20251227.1",
726
+ version: "7.0.0-dev.20260103.1",
555
727
  command: "tsgo",
556
728
  config: { extends: "adamantite/typescript" },
557
- exists: () => checkIfExists(join6(process.cwd(), "tsconfig.json")),
558
- create: () => fromPromise6(writeFile5(join6(process.cwd(), "tsconfig.json"), JSON.stringify(typescript.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.")),
559
- update: () => safeTry9(async function* () {
560
- const tsconfigFile = yield* fromPromise6(readFile5(join6(process.cwd(), "tsconfig.json"), "utf8"), (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."));
729
+ exists: () => checkIfExists(join7(process.cwd(), "tsconfig.json")),
730
+ create: () => fromPromise7(writeFile6(join7(process.cwd(), "tsconfig.json"), JSON.stringify(typescript.config, null, 2)), (error) => Fault11.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.")),
731
+ update: () => safeTry11(async function* () {
732
+ const tsconfigFile = yield* fromPromise7(readFile6(join7(process.cwd(), "tsconfig.json"), "utf8"), (error) => Fault11.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."));
561
733
  const existingConfig = yield* parseJson(tsconfigFile);
562
734
  if (!isJsonObject(existingConfig)) {
563
- return err5(Fault9.create("INVALID_CONFIG_FORMAT").withDescription("Invalid tsconfig.json format", "The tsconfig.json file must be a JSON object."));
735
+ return err6(Fault11.create("INVALID_CONFIG_FORMAT").withDescription("Invalid tsconfig.json format", "The tsconfig.json file must be a JSON object."));
564
736
  }
565
737
  const newConfig = yield* mergeConfig(typescript.config, existingConfig);
566
- yield* fromPromise6(writeFile5(join6(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."));
567
- return ok9();
738
+ yield* fromPromise7(writeFile6(join7(process.cwd(), "tsconfig.json"), JSON.stringify(newConfig, null, 2)), (error) => Fault11.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."));
739
+ return ok11();
568
740
  })
569
741
  };
570
742
 
571
743
  // src/commands/init.ts
572
- var installDependencies = (packages) => safeTry10(async function* () {
744
+ var installDependencies = (packages) => safeTry12(async function* () {
573
745
  const s = p.spinner();
574
746
  s.start("Installing dependencies...");
575
747
  const isMonorepo = yield* checkIsMonorepo();
576
748
  for (const pkg of packages) {
577
749
  s.message(`Installing dependency: ${pkg}...`);
578
- yield* fromPromise7(addDevDependency(pkg, { silent: true, workspace: isMonorepo }), (error) => Fault10.wrap(error).withTag("FAILED_TO_INSTALL_DEPENDENCY").withMessage(`Failed to install ${pkg}`));
750
+ yield* fromPromise8(addDevDependency(pkg, { silent: true, workspace: isMonorepo }), (error) => Fault12.wrap(error).withTag("FAILED_TO_INSTALL_DEPENDENCY").withMessage(`Failed to install ${pkg}`));
579
751
  }
580
752
  s.stop("Dependencies installed.");
581
- return ok10();
753
+ return ok12();
582
754
  });
583
- var setupOxlintConfig = (presets) => safeTry10(async function* () {
755
+ var setupOxlintConfig = (presets) => safeTry12(async function* () {
584
756
  const spinner2 = p.spinner();
585
757
  spinner2.start("Setting up oxlint config...");
586
758
  const oxlintPath = await oxlint.exists();
@@ -593,9 +765,9 @@ var setupOxlintConfig = (presets) => safeTry10(async function* () {
593
765
  yield* oxlint.create(presets);
594
766
  spinner2.stop("oxlint config created successfully.");
595
767
  }
596
- return ok10();
768
+ return ok12();
597
769
  });
598
- var setupOxfmtConfig = () => safeTry10(async function* () {
770
+ var setupOxfmtConfig = () => safeTry12(async function* () {
599
771
  const spinner2 = p.spinner();
600
772
  spinner2.start("Setting up oxfmt config...");
601
773
  const oxfmtPath = await oxfmt.exists();
@@ -608,10 +780,10 @@ var setupOxfmtConfig = () => safeTry10(async function* () {
608
780
  yield* oxfmt.create();
609
781
  spinner2.stop("oxfmt config created successfully.");
610
782
  }
611
- return ok10();
783
+ return ok12();
612
784
  });
613
- var addScripts = (scripts) => safeTry10(async function* () {
614
- const cwd = process7.cwd();
785
+ var addScripts = (scripts) => safeTry12(async function* () {
786
+ const cwd = process8.cwd();
615
787
  const packageJson = yield* readPackageJson();
616
788
  const spinner2 = p.spinner();
617
789
  spinner2.start("Adding scripts to your `package.json`...");
@@ -636,15 +808,33 @@ var addScripts = (scripts) => safeTry10(async function* () {
636
808
  case "fix:monorepo":
637
809
  packageJson.scripts["fix:monorepo"] = "adamantite monorepo --fix";
638
810
  break;
811
+ case "analyze":
812
+ packageJson.scripts.analyze = "adamantite analyze";
813
+ break;
639
814
  default:
640
- return err6(Fault10.create("UNKNOWN_SCRIPT").withContext({ script }));
815
+ return err7(Fault12.create("UNKNOWN_SCRIPT").withContext({ script }));
641
816
  }
642
817
  }
643
- yield* fromPromise7(writeFile6(join7(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: join7(cwd, "package.json") }));
818
+ yield* fromPromise8(writeFile7(join8(cwd, "package.json"), JSON.stringify(packageJson, null, 2)), (error) => Fault12.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write package.json", "We're unable to update the package.json file.").withContext({ path: join8(cwd, "package.json") }));
644
819
  spinner2.stop("Scripts added to your `package.json`");
645
- return ok10();
820
+ return ok12();
646
821
  });
647
- var setupTypescript = () => safeTry10(async function* () {
822
+ var setupKnipConfig = () => safeTry12(async function* () {
823
+ const spinner2 = p.spinner();
824
+ spinner2.start("Setting up knip config...");
825
+ const knipPath = await knip.exists();
826
+ if (knipPath.path) {
827
+ spinner2.message(`Found \`${knipPath.path}\`, updating...`);
828
+ yield* knip.update();
829
+ spinner2.stop("knip config updated successfully.");
830
+ } else {
831
+ spinner2.message("`knip.json` not found, creating...");
832
+ yield* knip.create();
833
+ spinner2.stop("knip config created successfully.");
834
+ }
835
+ return ok12();
836
+ });
837
+ var setupTypescript = () => safeTry12(async function* () {
648
838
  const spinner2 = p.spinner();
649
839
  spinner2.start("Setting up TypeScript config...");
650
840
  if (await typescript.exists()) {
@@ -656,9 +846,9 @@ var setupTypescript = () => safeTry10(async function* () {
656
846
  yield* typescript.create();
657
847
  spinner2.stop("`tsconfig.json` created successfully");
658
848
  }
659
- return ok10();
849
+ return ok12();
660
850
  });
661
- var setupEditors = (editors) => safeTry10(async function* () {
851
+ var setupEditors = (editors) => safeTry12(async function* () {
662
852
  if (editors.includes("vscode")) {
663
853
  const spinner2 = p.spinner();
664
854
  spinner2.start("Checking for `.vscode/settings.json`...");
@@ -673,9 +863,20 @@ var setupEditors = (editors) => safeTry10(async function* () {
673
863
  }
674
864
  }
675
865
  if (editors.includes("zed")) {}
676
- return ok10();
866
+ return ok12();
677
867
  });
678
- var setupGitHubActions = (packageManager, scripts) => safeTry10(async function* () {
868
+ var installEditorExtensions = (editors, scripts) => safeTry12(function* () {
869
+ const spinner2 = p.spinner();
870
+ spinner2.start("Installing editor extensions...");
871
+ if (editors.includes("vscode")) {
872
+ spinner2.message("Installing VS Code extension...");
873
+ yield* vscode.extension(scripts);
874
+ }
875
+ if (editors.includes("zed")) {}
876
+ spinner2.stop("Editor extensions installed successfully.");
877
+ return ok12();
878
+ });
879
+ var setupGitHubActions = (packageManager, scripts) => safeTry12(async function* () {
679
880
  const spinner2 = p.spinner();
680
881
  spinner2.start("Setting up GitHub Actions workflow...");
681
882
  if (await github.exists()) {
@@ -687,13 +888,13 @@ var setupGitHubActions = (packageManager, scripts) => safeTry10(async function*
687
888
  yield* github.create({ packageManager, scripts });
688
889
  spinner2.stop("GitHub Actions workflow created successfully.");
689
890
  }
690
- return ok10();
891
+ return ok12();
691
892
  });
692
893
  var init_default = defineCommand({
693
894
  command: "init",
694
895
  describe: "Initialize Adamantite in the current directory",
695
896
  builder: (yargs) => yargs,
696
- handler: () => safeTry10(async function* () {
897
+ handler: () => safeTry12(async function* () {
697
898
  const packageManager = yield* getPackageManagerName();
698
899
  printTitle();
699
900
  p.intro("\uD83D\uDCA0 adamantite init");
@@ -736,16 +937,20 @@ var init_default = defineCommand({
736
937
  value: "fix:monorepo",
737
938
  hint: isMonorepo ? undefined : "available for monorepo projects",
738
939
  disabled: !isMonorepo
940
+ },
941
+ {
942
+ label: "analyze - find unused dependencies, exports, and files using knip",
943
+ value: "analyze"
739
944
  }
740
945
  ]
741
946
  }));
742
947
  if (p.isCancel(scripts)) {
743
- return err6(Fault10.create("OPERATION_CANCELLED"));
948
+ return err7(Fault12.create("OPERATION_CANCELLED"));
744
949
  }
745
950
  const hasOxlint = scripts.includes("check") || scripts.includes("fix");
746
951
  let presets = [];
747
952
  if (hasOxlint) {
748
- const presetsResponse = yield* fromSafePromise(p.multiselect({
953
+ presets = yield* fromSafePromise(p.multiselect({
749
954
  message: "Which presets do you want to install? (core is always included)",
750
955
  options: [
751
956
  { label: "React", value: "react" },
@@ -757,10 +962,9 @@ var init_default = defineCommand({
757
962
  ],
758
963
  required: false
759
964
  }));
760
- if (p.isCancel(presetsResponse)) {
761
- return err6(Fault10.create("OPERATION_CANCELLED"));
965
+ if (p.isCancel(presets)) {
966
+ return err7(Fault12.create("OPERATION_CANCELLED"));
762
967
  }
763
- presets = presetsResponse;
764
968
  }
765
969
  const editors = yield* fromSafePromise(p.multiselect({
766
970
  message: "Which editors do you want to configure? (optional)",
@@ -771,23 +975,33 @@ var init_default = defineCommand({
771
975
  required: false
772
976
  }));
773
977
  if (p.isCancel(editors)) {
774
- return err6(Fault10.create("OPERATION_CANCELLED"));
978
+ return err7(Fault12.create("OPERATION_CANCELLED"));
979
+ }
980
+ let installExtensions = false;
981
+ if (editors.length > 0) {
982
+ const installExtensionsResponse = yield* fromSafePromise(p.confirm({
983
+ message: "Do you want to install the recommended editor extensions?",
984
+ initialValue: true
985
+ }));
986
+ if (p.isCancel(installExtensionsResponse)) {
987
+ return err7(Fault12.create("OPERATION_CANCELLED"));
988
+ }
989
+ installExtensions = installExtensionsResponse;
775
990
  }
776
991
  const hasCIScripts = hasCICompatibleScripts(scripts);
777
992
  let enableGitHubActions = false;
778
993
  if (hasCIScripts) {
779
- const response = yield* fromSafePromise(p.confirm({
780
- message: "Do you want to add a GitHub Actions workflow to run checks in CI?",
781
- initialValue: false
994
+ enableGitHubActions = yield* fromSafePromise(p.confirm({
995
+ message: "Do you want to add a GitHub Actions workflow to run checks in CI?"
782
996
  }));
783
- if (p.isCancel(response)) {
784
- return err6(Fault10.create("OPERATION_CANCELLED"));
997
+ if (p.isCancel(enableGitHubActions)) {
998
+ return err7(Fault12.create("OPERATION_CANCELLED"));
785
999
  }
786
- enableGitHubActions = response;
787
1000
  }
788
1001
  const hasOxfmt = scripts.includes("format");
789
1002
  const hasSherif = scripts.includes("check:monorepo") || scripts.includes("fix:monorepo");
790
1003
  const hasTypecheck = scripts.includes("typecheck");
1004
+ const hasKnip = scripts.includes("analyze");
791
1005
  const dependencies = ["adamantite"];
792
1006
  if (hasOxlint) {
793
1007
  dependencies.push(`${oxlint.name}@${oxlint.version}`);
@@ -802,6 +1016,9 @@ var init_default = defineCommand({
802
1016
  if (hasTypecheck) {
803
1017
  dependencies.push(`${typescript.name}@${typescript.version}`);
804
1018
  }
1019
+ if (hasKnip) {
1020
+ dependencies.push(`${knip.name}@${knip.version}`);
1021
+ }
805
1022
  yield* installDependencies(dependencies);
806
1023
  if (hasOxfmt) {
807
1024
  yield* setupOxfmtConfig();
@@ -809,40 +1026,46 @@ var init_default = defineCommand({
809
1026
  if (hasOxlint) {
810
1027
  yield* setupOxlintConfig(presets);
811
1028
  }
1029
+ if (hasKnip) {
1030
+ yield* setupKnipConfig();
1031
+ }
812
1032
  yield* addScripts(scripts);
813
1033
  if (hasTypecheck) {
814
1034
  yield* setupTypescript();
815
1035
  }
816
1036
  yield* setupEditors(editors);
1037
+ if (installExtensions) {
1038
+ yield* installEditorExtensions(editors, scripts);
1039
+ }
817
1040
  if (enableGitHubActions) {
818
1041
  yield* setupGitHubActions(packageManager, scripts);
819
1042
  }
820
- return ok10();
1043
+ return ok12();
821
1044
  }).match(() => {
822
1045
  p.outro("\uD83D\uDCA0 Adamantite initialized successfully!");
823
- process7.exit(0);
1046
+ process8.exit(0);
824
1047
  }, (error) => {
825
- if (Fault10.isFault(error) && error.tag === "OPERATION_CANCELLED") {
1048
+ if (Fault12.isFault(error) && error.tag === "OPERATION_CANCELLED") {
826
1049
  p.cancel("You've cancelled the initialization process.");
827
- process7.exit(0);
1050
+ process8.exit(0);
828
1051
  }
829
- if (!Fault10.isFault(error)) {
1052
+ if (!Fault12.isFault(error)) {
830
1053
  p.log.error(`An unexpected error occurred: ${String(error)}`);
831
1054
  p.cancel("Failed to initialize Adamantite");
832
- process7.exit(1);
1055
+ process8.exit(1);
833
1056
  }
834
1057
  p.log.error(error.flatten());
835
1058
  p.cancel("Failed to initialize Adamantite");
836
- process7.exit(1);
1059
+ process8.exit(1);
837
1060
  })
838
1061
  });
839
1062
 
840
1063
  // src/commands/monorepo.ts
841
- import process8 from "node:process";
842
- import { log as log5 } from "@clack/prompts";
843
- import { Fault as Fault11 } from "faultier";
844
- import { ok as ok11, safeTry as safeTry11 } from "neverthrow";
845
- import { dlxCommand as dlxCommand4 } from "nypm";
1064
+ import process9 from "node:process";
1065
+ import { log as log6 } from "@clack/prompts";
1066
+ import { Fault as Fault13 } from "faultier";
1067
+ import { ok as ok13, safeTry as safeTry13 } from "neverthrow";
1068
+ import { dlxCommand as dlxCommand5 } from "nypm";
846
1069
  var monorepo_default = defineCommand({
847
1070
  command: "monorepo",
848
1071
  describe: "Find and fix monorepo-specific issues using Sherif",
@@ -850,31 +1073,31 @@ var monorepo_default = defineCommand({
850
1073
  type: "boolean",
851
1074
  description: "Automatically fix issues"
852
1075
  }),
853
- handler: (argv) => safeTry11(async function* () {
1076
+ handler: (argv) => safeTry13(async function* () {
854
1077
  const packageManager = yield* getPackageManagerName();
855
1078
  const args = [];
856
1079
  if (argv.fix) {
857
1080
  args.push("--fix");
858
1081
  }
859
- const command = dlxCommand4(packageManager, sherif.name, { args });
1082
+ const command = dlxCommand5(packageManager, sherif.name, { args });
860
1083
  yield* runCommand(command);
861
- return ok11();
1084
+ return ok13();
862
1085
  }).match(() => {
863
- process8.exit(0);
1086
+ process9.exit(0);
864
1087
  }, (error) => {
865
- if (Fault11.isFault(error) && error.tag === "NO_PACKAGE_MANAGER") {
866
- log5.error(error.flatten());
1088
+ if (Fault13.isFault(error) && error.tag === "NO_PACKAGE_MANAGER") {
1089
+ log6.error(error.flatten());
867
1090
  }
868
- process8.exit(1);
1091
+ process9.exit(1);
869
1092
  })
870
1093
  });
871
1094
 
872
1095
  // src/commands/typecheck.ts
873
- import process9 from "node:process";
874
- import { log as log6 } from "@clack/prompts";
875
- import { Fault as Fault12 } from "faultier";
876
- import { ok as ok12, safeTry as safeTry12 } from "neverthrow";
877
- import { dlxCommand as dlxCommand5 } from "nypm";
1096
+ import process10 from "node:process";
1097
+ import { log as log7 } from "@clack/prompts";
1098
+ import { Fault as Fault14 } from "faultier";
1099
+ import { ok as ok14, safeTry as safeTry14 } from "neverthrow";
1100
+ import { dlxCommand as dlxCommand6 } from "nypm";
878
1101
  var typecheck_default = defineCommand({
879
1102
  command: "typecheck",
880
1103
  describe: "Run TypeScript type checking",
@@ -887,7 +1110,7 @@ var typecheck_default = defineCommand({
887
1110
  type: "boolean",
888
1111
  description: "Run in watch mode"
889
1112
  }),
890
- handler: (argv) => safeTry12(async function* () {
1113
+ handler: (argv) => safeTry14(async function* () {
891
1114
  const packageManager = yield* getPackageManagerName();
892
1115
  const args = ["--noEmit"];
893
1116
  if (argv.project) {
@@ -896,30 +1119,30 @@ var typecheck_default = defineCommand({
896
1119
  if (argv.watch) {
897
1120
  args.push("--watch");
898
1121
  }
899
- const command = dlxCommand5(packageManager, typescript.command, { args });
1122
+ const command = dlxCommand6(packageManager, typescript.command, { args });
900
1123
  const result = yield* runCommand(command);
901
- return ok12(result);
1124
+ return ok14(result);
902
1125
  }).match(() => {
903
- process9.exit(0);
1126
+ process10.exit(0);
904
1127
  }, (error) => {
905
- if (Fault12.isFault(error) && error.tag === "NO_PACKAGE_MANAGER") {
906
- log6.error(error.flatten());
1128
+ if (Fault14.isFault(error) && error.tag === "NO_PACKAGE_MANAGER") {
1129
+ log7.error(error.flatten());
907
1130
  }
908
- process9.exit(1);
1131
+ process10.exit(1);
909
1132
  })
910
1133
  });
911
1134
 
912
1135
  // src/commands/update.ts
913
- import process10 from "node:process";
914
- 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";
915
- import { Fault as Fault13 } from "faultier";
916
- import { err as err7, fromPromise as fromPromise8, fromSafePromise as fromSafePromise2, ok as ok13, safeTry as safeTry13 } from "neverthrow";
1136
+ import process11 from "node:process";
1137
+ import { cancel as cancel2, confirm as confirm2, intro as intro2, isCancel as isCancel2, log as log8, outro as outro2, spinner as spinner2 } from "@clack/prompts";
1138
+ import { Fault as Fault15 } from "faultier";
1139
+ import { err as err8, fromPromise as fromPromise9, fromSafePromise as fromSafePromise2, ok as ok15, safeTry as safeTry15 } from "neverthrow";
917
1140
  import { addDevDependency as addDevDependency2 } from "nypm";
918
1141
  var update_default = defineCommand({
919
1142
  command: "update",
920
1143
  describe: "Update adamantite dependencies to latest compatible versions",
921
1144
  builder: (yargs) => yargs,
922
- handler: () => safeTry13(async function* () {
1145
+ handler: () => safeTry15(async function* () {
923
1146
  const packageJson = yield* readPackageJson();
924
1147
  printTitle();
925
1148
  intro2("\uD83D\uDCA0 adamantite update");
@@ -936,31 +1159,31 @@ var update_default = defineCommand({
936
1159
  }
937
1160
  }
938
1161
  if (updates.length === 0) {
939
- log7.success("All adamantite dependencies are already up to date!");
940
- return ok13("no-updates");
1162
+ log8.success("All adamantite dependencies are already up to date!");
1163
+ return ok15("no-updates");
941
1164
  }
942
- log7.message("The following dependencies will be updated:");
943
- log7.message("");
1165
+ log8.message("The following dependencies will be updated:");
1166
+ log8.message("");
944
1167
  for (const dep of updates) {
945
- log7.message(` ${dep.name}: ${dep.currentVersion} → ${dep.targetVersion}`);
1168
+ log8.message(` ${dep.name}: ${dep.currentVersion} → ${dep.targetVersion}`);
946
1169
  }
947
- log7.message("");
1170
+ log8.message("");
948
1171
  const shouldUpdate = yield* fromSafePromise2(confirm2({
949
1172
  message: "Do you want to proceed with these updates?"
950
1173
  }));
951
1174
  if (isCancel2(shouldUpdate)) {
952
- return err7(Fault13.create("OPERATION_CANCELLED"));
1175
+ return err8(Fault15.create("OPERATION_CANCELLED"));
953
1176
  }
954
1177
  if (!shouldUpdate) {
955
- return ok13("cancelled");
1178
+ return ok15("cancelled");
956
1179
  }
957
1180
  const s = spinner2();
958
1181
  s.start("Updating dependencies...");
959
1182
  for (const dep of updates) {
960
- yield* fromPromise8(addDevDependency2(`${dep.name}@${dep.targetVersion}`), (error) => Fault13.wrap(error).withTag("FAILED_TO_INSTALL_DEPENDENCY").withMessage(`Failed to update ${dep.name}`));
1183
+ yield* fromPromise9(addDevDependency2(`${dep.name}@${dep.targetVersion}`), (error) => Fault15.wrap(error).withTag("FAILED_TO_INSTALL_DEPENDENCY").withMessage(`Failed to update ${dep.name}`));
961
1184
  }
962
1185
  s.stop("Dependencies updated successfully");
963
- return ok13("updated");
1186
+ return ok15("updated");
964
1187
  }).match((value) => {
965
1188
  if (value === "no-updates") {
966
1189
  outro2("✅ No updates needed");
@@ -969,22 +1192,22 @@ var update_default = defineCommand({
969
1192
  } else if (value === "updated") {
970
1193
  outro2("✅ Dependencies updated successfully!");
971
1194
  }
972
- process10.exit(0);
1195
+ process11.exit(0);
973
1196
  }, (error) => {
974
- if (Fault13.isFault(error) && error.tag === "OPERATION_CANCELLED") {
1197
+ if (Fault15.isFault(error) && error.tag === "OPERATION_CANCELLED") {
975
1198
  cancel2("You've cancelled the update process.");
976
- process10.exit(0);
1199
+ process11.exit(0);
977
1200
  }
978
- if (Fault13.isFault(error)) {
979
- log7.error(error.flatten());
1201
+ if (Fault15.isFault(error)) {
1202
+ log8.error(error.flatten());
980
1203
  } else {
981
- log7.error(String(error));
1204
+ log8.error(String(error));
982
1205
  }
983
1206
  cancel2("Failed to update dependencies");
984
- process10.exit(1);
1207
+ process11.exit(1);
985
1208
  })
986
1209
  });
987
1210
 
988
1211
  // src/index.ts
989
- var version = await "0.19.0";
990
- yargs(hideBin(process.argv)).scriptName("adamantite").version(version).command(check_default).command(fix_default).command(format_default).command(init_default).command(monorepo_default).command(typecheck_default).command(update_default).demandCommand(1).strict().help().parse();
1212
+ var version = await "0.22.0";
1213
+ yargs(hideBin(process.argv)).scriptName("adamantite").version(version).command(analyze_default).command(check_default).command(fix_default).command(format_default).command(init_default).command(monorepo_default).command(typecheck_default).command(update_default).demandCommand(1).strict().help().parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adamantite",
3
- "version": "0.19.0",
3
+ "version": "0.22.0",
4
4
  "description": "An strict and opinionated set of presets for modern TypeScript applications",
5
5
  "keywords": [
6
6
  "adamantite",
@@ -37,13 +37,15 @@
37
37
  "#presets/*": "./presets/*"
38
38
  },
39
39
  "exports": {
40
+ "./analyze": "./presets/knip.json",
41
+ "./format": "./presets/oxfmt.json",
40
42
  "./lint": "./presets/oxlint/core.json",
41
43
  "./lint/*": "./presets/oxlint/*.json",
42
- "./format": "./presets/oxfmt.json",
43
44
  "./typescript": "./presets/tsconfig.json",
44
45
  "./presets/*": "./presets/*"
45
46
  },
46
47
  "scripts": {
48
+ "analyze": "bun run src/index.ts analyze",
47
49
  "build": "bunup",
48
50
  "bump:deps": "bun update --interactive",
49
51
  "check": "bun run src/index.ts check",
@@ -59,7 +61,6 @@
59
61
  },
60
62
  "dependencies": {
61
63
  "@clack/prompts": "1.0.0-alpha.9",
62
- "consola": "3.4.2",
63
64
  "defu": "6.1.4",
64
65
  "faultier": "^1.1.0",
65
66
  "jsonc-parser": "3.3.1",
@@ -71,11 +72,12 @@
71
72
  "@changesets/cli": "2.29.8",
72
73
  "@types/bun": "1.3.5",
73
74
  "@types/yargs": "17.0.35",
74
- "@typescript/native-preview": "7.0.0-dev.20251227.1",
75
- "bunup": "0.16.11",
76
- "oxfmt": "0.20.0",
77
- "oxlint": "1.35.0",
78
- "oxlint-tsgolint": "0.10.0",
75
+ "@typescript/native-preview": "7.0.0-dev.20260103.1",
76
+ "bunup": "0.16.17",
77
+ "knip": "5.79.0",
78
+ "oxfmt": "0.21.0",
79
+ "oxlint": "1.36.0",
80
+ "oxlint-tsgolint": "0.10.1",
79
81
  "sherif": "1.9.0",
80
82
  "type-fest": "5.3.1",
81
83
  "typescript": "5.9.3"
@@ -0,0 +1,29 @@
1
+ {
2
+ "$schema": "https://unpkg.com/knip@5/schema.json",
3
+ "rules": {
4
+ "files": "error",
5
+ "dependencies": "error",
6
+ "devDependencies": "error",
7
+ "optionalPeerDependencies": "warn",
8
+ "unlisted": "error",
9
+ "binaries": "error",
10
+ "unresolved": "error",
11
+ "exports": "warn",
12
+ "nsExports": "warn",
13
+ "types": "warn",
14
+ "nsTypes": "warn",
15
+ "enumMembers": "off",
16
+ "classMembers": "off",
17
+ "duplicates": "warn"
18
+ },
19
+ "ignoreExportsUsedInFile": true,
20
+ "ignoreFiles": [
21
+ "**/dist/**",
22
+ "**/build/**",
23
+ "**/coverage/**",
24
+ "**/.next/**",
25
+ "**/.vercel/**",
26
+ "**/.turbo/**"
27
+ ],
28
+ "ignore": ["**/*.d.ts"]
29
+ }
@@ -44,7 +44,10 @@
44
44
  "no-unsafe-finally": "error",
45
45
  "no-unsafe-negation": "error",
46
46
  "no-unsafe-optional-chaining": "error",
47
- "no-unused-expressions": "error",
47
+ "no-unused-expressions": [
48
+ "error",
49
+ { "allowTaggedTemplates": true, "allowTernary": true, "enforceForJSX": true }
50
+ ],
48
51
  "no-unused-labels": "error",
49
52
  "no-unused-private-class-members": "error",
50
53
  "no-unused-vars": "error",