clispark 1.20.0 → 1.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/cli.js CHANGED
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/cli.ts
4
- import path21 from "path";
4
+ import path22 from "path";
5
5
  import { Command } from "commander";
6
6
 
7
7
  // src/wizard.ts
8
8
  import { intro, outro, text as text2, select as select2, log, isCancel as isCancel2, cancel as cancel2 } from "@clack/prompts";
9
9
 
10
10
  // src/languages/packs/node-oclif.ts
11
- import path6 from "path";
11
+ import path7 from "path";
12
12
 
13
13
  // src/package-root.ts
14
14
  import { existsSync, readFileSync } from "fs";
@@ -31,8 +31,8 @@ function findPackageRoot() {
31
31
  }
32
32
 
33
33
  // src/update/adapters/node-oclif.ts
34
- import { readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
35
- import path3 from "path";
34
+ import { readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
35
+ import path4 from "path";
36
36
 
37
37
  // src/update/reconcile.ts
38
38
  function reconcileEntry(currentLiveValue, oldManifestValue, newTemplateValue, isEqual) {
@@ -73,6 +73,24 @@ async function stripLintTooling(targetDir) {
73
73
  await writeFile(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
74
74
  }
75
75
 
76
+ // src/languages/autocomplete-support/node.ts
77
+ import { readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
78
+ import path3 from "path";
79
+ var AUTOCOMPLETE_DEPENDENCY_NAME = "@oclif/plugin-autocomplete";
80
+ function withoutAutocompletePlugin(oclif) {
81
+ if (!oclif || typeof oclif !== "object") return oclif;
82
+ const shape = oclif;
83
+ if (!Array.isArray(shape.plugins)) return oclif;
84
+ return { ...shape, plugins: shape.plugins.filter((name) => name !== AUTOCOMPLETE_DEPENDENCY_NAME) };
85
+ }
86
+ async function stripAutocompleteSupport(targetDir) {
87
+ const pkgPath = path3.join(targetDir, "package.json");
88
+ const pkg = JSON.parse(await readFile2(pkgPath, "utf8"));
89
+ delete pkg.dependencies?.[AUTOCOMPLETE_DEPENDENCY_NAME];
90
+ pkg.oclif = withoutAutocompletePlugin(pkg.oclif);
91
+ await writeFile2(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
92
+ }
93
+
76
94
  // src/update/adapters/node-oclif.ts
77
95
  var CORE_FILE_PATHS = [
78
96
  "bin/run.ts",
@@ -117,7 +135,7 @@ function mergePackageJson(currentPkg, oldManifest, newTemplatePkg) {
117
135
  const coreDependencies = {};
118
136
  const dependencyNames = new Set(
119
137
  [...Object.keys(newTemplatePkg.dependencies ?? {}), ...Object.keys(newTemplatePkg.devDependencies ?? {})].filter(
120
- (name) => oldManifest.lintEnabled || !LINT_DEPENDENCY_NAMES.includes(name)
138
+ (name) => (oldManifest.lintEnabled || !LINT_DEPENDENCY_NAMES.includes(name)) && (oldManifest.autocompleteEnabled || name !== AUTOCOMPLETE_DEPENDENCY_NAME)
121
139
  )
122
140
  );
123
141
  for (const name of dependencyNames) {
@@ -169,7 +187,8 @@ function mergePackageJson(currentPkg, oldManifest, newTemplatePkg) {
169
187
  }
170
188
  }
171
189
  if (newTemplatePkg.oclif !== void 0) {
172
- const oclifResult = reconcileEntry(currentPkg.oclif, oldCoreFields.oclif, newTemplatePkg.oclif, deepEquals);
190
+ const effectiveTemplateOclif = oldManifest.autocompleteEnabled ? newTemplatePkg.oclif : withoutAutocompletePlugin(newTemplatePkg.oclif);
191
+ const oclifResult = reconcileEntry(currentPkg.oclif, oldCoreFields.oclif, effectiveTemplateOclif, deepEquals);
173
192
  fields.push({ key: "oclif", outcome: oclifResult.outcome });
174
193
  oclifValue = oclifResult.value;
175
194
  if (oclifResult.outcome !== "skipped" && !deepEquals(oclifResult.value, currentPkg.oclif)) {
@@ -197,11 +216,11 @@ var nodeOclifAdapter = {
197
216
  },
198
217
  manifestFileName: "package.json",
199
218
  async readManifestFile(dir) {
200
- const content = await readFile2(path3.join(dir, "package.json"), "utf8");
219
+ const content = await readFile3(path4.join(dir, "package.json"), "utf8");
201
220
  return JSON.parse(content);
202
221
  },
203
222
  async writeManifestFile(dir, content) {
204
- await writeFile2(path3.join(dir, "package.json"), JSON.stringify(content, null, 2) + "\n");
223
+ await writeFile3(path4.join(dir, "package.json"), JSON.stringify(content, null, 2) + "\n");
205
224
  },
206
225
  parseManifestFile(rawContent) {
207
226
  return JSON.parse(rawContent);
@@ -218,8 +237,8 @@ var nodeOclifAdapter = {
218
237
  };
219
238
 
220
239
  // src/languages/registry-checkers/npm.ts
221
- import { readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
222
- import path4 from "path";
240
+ import { readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
241
+ import path5 from "path";
223
242
  var NPM_DEFAULT_REGISTRY_URL = "https://registry.npmjs.org";
224
243
  var FETCH_TIMEOUT_MS = 5e3;
225
244
  async function checkNameAvailability(name, registryUrl) {
@@ -234,13 +253,13 @@ async function checkNameAvailability(name, registryUrl) {
234
253
  }
235
254
  }
236
255
  async function applyPrivateIntent(targetDir) {
237
- const packageJsonPath = path4.join(targetDir, "package.json");
238
- const pkg = JSON.parse(await readFile3(packageJsonPath, "utf8"));
256
+ const packageJsonPath = path5.join(targetDir, "package.json");
257
+ const pkg = JSON.parse(await readFile4(packageJsonPath, "utf8"));
239
258
  pkg.private = true;
240
- await writeFile3(packageJsonPath, JSON.stringify(pkg, null, 2) + "\n");
259
+ await writeFile4(packageJsonPath, JSON.stringify(pkg, null, 2) + "\n");
241
260
  }
242
261
  async function applyRegistryUrl(targetDir, registryUrl) {
243
- await writeFile3(path4.join(targetDir, ".npmrc"), `registry=${registryUrl}
262
+ await writeFile4(path5.join(targetDir, ".npmrc"), `registry=${registryUrl}
244
263
  `);
245
264
  }
246
265
  var npmRegistryChecker = {
@@ -250,8 +269,8 @@ var npmRegistryChecker = {
250
269
  };
251
270
 
252
271
  // src/languages/command-generators/node-oclif.ts
253
- import { mkdir, readdir, writeFile as writeFile4 } from "fs/promises";
254
- import path5 from "path";
272
+ import { mkdir, readdir, writeFile as writeFile5 } from "fs/promises";
273
+ import path6 from "path";
255
274
 
256
275
  // src/languages/command-generator.ts
257
276
  function buildCommandTree(paths2) {
@@ -283,20 +302,20 @@ async function collectCommandFiles(dir, baseDir = dir) {
283
302
  const entries = await readdir(dir, { withFileTypes: true });
284
303
  const files = [];
285
304
  for (const entry of entries) {
286
- const fullPath = path5.join(dir, entry.name);
305
+ const fullPath = path6.join(dir, entry.name);
287
306
  if (entry.isDirectory()) {
288
307
  files.push(...await collectCommandFiles(fullPath, baseDir));
289
308
  } else if (entry.name.endsWith(".ts") && !entry.name.endsWith(".test.ts")) {
290
- files.push(path5.relative(baseDir, fullPath));
309
+ files.push(path6.relative(baseDir, fullPath));
291
310
  }
292
311
  }
293
312
  return files;
294
313
  }
295
314
  function toCommandPath(relativeFilePath) {
296
- return relativeFilePath.replace(/\.ts$/, "").split(path5.sep).join(" ");
315
+ return relativeFilePath.replace(/\.ts$/, "").split(path6.sep).join(" ");
297
316
  }
298
317
  async function listExistingCommands(targetDir) {
299
- const commandsDir = path5.join(targetDir, "src", "commands");
318
+ const commandsDir = path6.join(targetDir, "src", "commands");
300
319
  const files = await collectCommandFiles(commandsDir);
301
320
  return buildCommandTree(files.map(toCommandPath));
302
321
  }
@@ -356,13 +375,13 @@ describe('${commandInvocation}', () => {
356
375
  `;
357
376
  }
358
377
  async function generateCommand(targetDir, spec) {
359
- const relDir = path5.join("src", "commands", ...spec.pathSegments.slice(0, -1));
378
+ const relDir = path6.join("src", "commands", ...spec.pathSegments.slice(0, -1));
360
379
  const fileName = spec.pathSegments[spec.pathSegments.length - 1];
361
- const commandRelPath = path5.join(relDir, `${fileName}.ts`);
362
- const testRelPath = path5.join(relDir, `${fileName}.test.ts`);
363
- await mkdir(path5.join(targetDir, relDir), { recursive: true });
364
- await writeFile4(path5.join(targetDir, commandRelPath), generateCommandFileContent(spec));
365
- await writeFile4(path5.join(targetDir, testRelPath), generateTestFileContent(spec));
380
+ const commandRelPath = path6.join(relDir, `${fileName}.ts`);
381
+ const testRelPath = path6.join(relDir, `${fileName}.test.ts`);
382
+ await mkdir(path6.join(targetDir, relDir), { recursive: true });
383
+ await writeFile5(path6.join(targetDir, commandRelPath), generateCommandFileContent(spec));
384
+ await writeFile5(path6.join(targetDir, testRelPath), generateTestFileContent(spec));
366
385
  return { commandFile: commandRelPath, testFile: testRelPath };
367
386
  }
368
387
  var nodeOclifCommandGenerator = {
@@ -381,7 +400,7 @@ function validateProjectName(value) {
381
400
  var nodeOclifPack = {
382
401
  id: "node",
383
402
  displayName: "Node.js / TypeScript (oclif)",
384
- templateDir: path6.join(findPackageRoot(), "templates", "node"),
403
+ templateDir: path7.join(findPackageRoot(), "templates", "node"),
385
404
  scaffoldCommands: [
386
405
  { command: "npm", args: ["install"] },
387
406
  { command: "npm", args: ["run", "build"] }
@@ -396,15 +415,17 @@ var nodeOclifPack = {
396
415
  applyRegistryUrl: npmRegistryChecker.applyRegistryUrl
397
416
  },
398
417
  commandGenerator: nodeOclifCommandGenerator,
399
- stripLintTooling
418
+ stripLintTooling,
419
+ supportsAutocompleteOptIn: true,
420
+ stripAutocompleteSupport
400
421
  };
401
422
 
402
423
  // src/languages/packs/dotnet.ts
403
- import path11 from "path";
424
+ import path12 from "path";
404
425
 
405
426
  // src/update/adapters/dotnet.ts
406
- import { readFile as readFile4, writeFile as writeFile5 } from "fs/promises";
407
- import path7 from "path";
427
+ import { readFile as readFile5, writeFile as writeFile6 } from "fs/promises";
428
+ import path8 from "path";
408
429
  var CORE_FILE_PATHS2 = [
409
430
  "Cli.slnx",
410
431
  "src/Program.cs",
@@ -564,11 +585,11 @@ var dotnetAdapter = {
564
585
  },
565
586
  manifestFileName: "src/Cli.csproj",
566
587
  async readManifestFile(dir) {
567
- const content = await readFile4(path7.join(dir, "src", "Cli.csproj"), "utf8");
588
+ const content = await readFile5(path8.join(dir, "src", "Cli.csproj"), "utf8");
568
589
  return parseManifestFile(content);
569
590
  },
570
591
  async writeManifestFile(dir, content) {
571
- await writeFile5(path7.join(dir, "src", "Cli.csproj"), content.raw);
592
+ await writeFile6(path8.join(dir, "src", "Cli.csproj"), content.raw);
572
593
  },
573
594
  parseManifestFile,
574
595
  readProjectName(manifestFile) {
@@ -583,8 +604,8 @@ var dotnetAdapter = {
583
604
  };
584
605
 
585
606
  // src/languages/registry-checkers/nuget.ts
586
- import { mkdir as mkdir2, readFile as readFile5, writeFile as writeFile6 } from "fs/promises";
587
- import path8 from "path";
607
+ import { mkdir as mkdir2, readFile as readFile6, writeFile as writeFile7 } from "fs/promises";
608
+ import path9 from "path";
588
609
  var NUGET_DEFAULT_REGISTRY_URL = "https://api.nuget.org/v3/index.json";
589
610
  var NUGET_FLATCONTAINER_BASE = "https://api.nuget.org/v3-flatcontainer";
590
611
  var FETCH_TIMEOUT_MS2 = 5e3;
@@ -600,13 +621,13 @@ async function checkNameAvailability2(name) {
600
621
  }
601
622
  }
602
623
  async function applyPrivateIntent2(targetDir) {
603
- const csprojPath = path8.join(targetDir, "src", "Cli.csproj");
604
- const content = await readFile5(csprojPath, "utf8");
624
+ const csprojPath = path9.join(targetDir, "src", "Cli.csproj");
625
+ const content = await readFile6(csprojPath, "utf8");
605
626
  const updated = content.replace(
606
627
  /(<PropertyGroup>\s*\n)/,
607
628
  "$1 <IsPackable>false</IsPackable>\n"
608
629
  );
609
- await writeFile6(csprojPath, updated);
630
+ await writeFile7(csprojPath, updated);
610
631
  }
611
632
  async function applyRegistryUrl2(targetDir, registryUrl) {
612
633
  const config = [
@@ -620,7 +641,7 @@ async function applyRegistryUrl2(targetDir, registryUrl) {
620
641
  ""
621
642
  ].join("\n");
622
643
  await mkdir2(targetDir, { recursive: true });
623
- await writeFile6(path8.join(targetDir, "NuGet.config"), config);
644
+ await writeFile7(path9.join(targetDir, "NuGet.config"), config);
624
645
  }
625
646
  var nugetRegistryChecker = {
626
647
  checkNameAvailability: checkNameAvailability2,
@@ -629,15 +650,15 @@ var nugetRegistryChecker = {
629
650
  };
630
651
 
631
652
  // src/languages/command-generators/dotnet.ts
632
- import { mkdir as mkdir3, readFile as readFile6, readdir as readdir2, writeFile as writeFile7 } from "fs/promises";
633
- import path9 from "path";
653
+ import { mkdir as mkdir3, readFile as readFile7, readdir as readdir2, writeFile as writeFile8 } from "fs/promises";
654
+ import path10 from "path";
634
655
  async function listExistingCommands2(targetDir) {
635
- const commandsDir = path9.join(targetDir, "src", "Commands");
656
+ const commandsDir = path10.join(targetDir, "src", "Commands");
636
657
  const files = await readdir2(commandsDir);
637
658
  const paths2 = [];
638
659
  for (const file of files) {
639
660
  if (!file.endsWith(".cs")) continue;
640
- const content = await readFile6(path9.join(commandsDir, file), "utf8");
661
+ const content = await readFile7(path10.join(commandsDir, file), "utf8");
641
662
  const match = content.match(/\[CommandPath\("([^"]+)"\)\]/);
642
663
  if (match) paths2.push(match[1]);
643
664
  }
@@ -729,12 +750,12 @@ public class ${className}Tests
729
750
  }
730
751
  async function generateCommand2(targetDir, spec) {
731
752
  const className = toClassName2(spec.pathSegments);
732
- const commandRelPath = path9.join("src", "Commands", `${className}.cs`);
733
- const testRelPath = path9.join("tests", `${className}Tests.cs`);
734
- await mkdir3(path9.join(targetDir, "src", "Commands"), { recursive: true });
735
- await mkdir3(path9.join(targetDir, "tests"), { recursive: true });
736
- await writeFile7(path9.join(targetDir, commandRelPath), generateCommandFileContent2(spec));
737
- await writeFile7(path9.join(targetDir, testRelPath), generateTestFileContent2(spec));
753
+ const commandRelPath = path10.join("src", "Commands", `${className}.cs`);
754
+ const testRelPath = path10.join("tests", `${className}Tests.cs`);
755
+ await mkdir3(path10.join(targetDir, "src", "Commands"), { recursive: true });
756
+ await mkdir3(path10.join(targetDir, "tests"), { recursive: true });
757
+ await writeFile8(path10.join(targetDir, commandRelPath), generateCommandFileContent2(spec));
758
+ await writeFile8(path10.join(targetDir, testRelPath), generateTestFileContent2(spec));
738
759
  return { commandFile: commandRelPath, testFile: testRelPath };
739
760
  }
740
761
  var dotnetCommandGenerator = {
@@ -743,16 +764,16 @@ var dotnetCommandGenerator = {
743
764
  };
744
765
 
745
766
  // src/languages/lint-support/dotnet.ts
746
- import { readFile as readFile7, writeFile as writeFile8 } from "fs/promises";
747
- import path10 from "path";
767
+ import { readFile as readFile8, writeFile as writeFile9 } from "fs/promises";
768
+ import path11 from "path";
748
769
  async function stripLintTooling2(targetDir) {
749
- const csprojPath = path10.join(targetDir, "src", "Cli.csproj");
750
- const content = await readFile7(csprojPath, "utf8");
770
+ const csprojPath = path11.join(targetDir, "src", "Cli.csproj");
771
+ const content = await readFile8(csprojPath, "utf8");
751
772
  const updated = content.replace(
752
773
  /\r?\n\s*<PropertyGroup>\s*\r?\n\s*<EnableNETAnalyzers>[\s\S]*?<\/PropertyGroup>\r?\n/,
753
774
  "\n"
754
775
  );
755
- await writeFile8(csprojPath, updated);
776
+ await writeFile9(csprojPath, updated);
756
777
  }
757
778
 
758
779
  // src/languages/packs/dotnet.ts
@@ -766,7 +787,7 @@ function validateProjectName2(value) {
766
787
  var dotnetPack = {
767
788
  id: "dotnet",
768
789
  displayName: ".NET / C# (System.CommandLine)",
769
- templateDir: path11.join(findPackageRoot(), "templates", "dotnet"),
790
+ templateDir: path12.join(findPackageRoot(), "templates", "dotnet"),
770
791
  scaffoldCommands: [
771
792
  { command: "dotnet", args: ["restore"] },
772
793
  { command: "dotnet", args: ["build"] }
@@ -781,15 +802,18 @@ var dotnetPack = {
781
802
  applyRegistryUrl: nugetRegistryChecker.applyRegistryUrl
782
803
  },
783
804
  commandGenerator: dotnetCommandGenerator,
784
- stripLintTooling: stripLintTooling2
805
+ stripLintTooling: stripLintTooling2,
806
+ supportsAutocompleteOptIn: false,
807
+ stripAutocompleteSupport: async () => {
808
+ }
785
809
  };
786
810
 
787
811
  // src/languages/packs/powershell.ts
788
- import path15 from "path";
812
+ import path16 from "path";
789
813
 
790
814
  // src/update/adapters/powershell.ts
791
- import { readFile as readFile8, writeFile as writeFile9 } from "fs/promises";
792
- import path12 from "path";
815
+ import { readFile as readFile9, writeFile as writeFile10 } from "fs/promises";
816
+ import path13 from "path";
793
817
  import spawn from "cross-spawn";
794
818
  var CORE_FILE_PATHS3 = [
795
819
  "Module.psm1",
@@ -910,8 +934,8 @@ var powershellAdapter = {
910
934
  },
911
935
  manifestFileName: "Module.psd1",
912
936
  async readManifestFile(dir) {
913
- const manifestPath = path12.join(dir, "Module.psd1");
914
- const raw = await readFile8(manifestPath, "utf8");
937
+ const manifestPath = path13.join(dir, "Module.psd1");
938
+ const raw = await readFile9(manifestPath, "utf8");
915
939
  const parsedViaPwsh = await readManifestViaPwsh(manifestPath);
916
940
  return {
917
941
  raw,
@@ -920,7 +944,7 @@ var powershellAdapter = {
920
944
  };
921
945
  },
922
946
  async writeManifestFile(dir, content) {
923
- await writeFile9(path12.join(dir, "Module.psd1"), content.raw);
947
+ await writeFile10(path13.join(dir, "Module.psd1"), content.raw);
924
948
  },
925
949
  parseManifestFile: parseManifestFile2,
926
950
  readProjectName() {
@@ -935,8 +959,8 @@ var powershellAdapter = {
935
959
  };
936
960
 
937
961
  // src/languages/registry-checkers/powershell-gallery.ts
938
- import { mkdir as mkdir4, writeFile as writeFile10 } from "fs/promises";
939
- import path13 from "path";
962
+ import { mkdir as mkdir4, writeFile as writeFile11 } from "fs/promises";
963
+ import path14 from "path";
940
964
  var POWERSHELL_GALLERY_DEFAULT_URL = "https://www.powershellgallery.com/api/v2";
941
965
  var FETCH_TIMEOUT_MS3 = 5e3;
942
966
  async function checkNameAvailability3(name, registryUrl) {
@@ -962,7 +986,7 @@ async function applyRegistryUrl3(targetDir, registryUrl) {
962
986
  ""
963
987
  ].join("\n");
964
988
  await mkdir4(targetDir, { recursive: true });
965
- await writeFile10(path13.join(targetDir, ".psresource-repository"), content);
989
+ await writeFile11(path14.join(targetDir, ".psresource-repository"), content);
966
990
  }
967
991
  var powershellGalleryRegistryChecker = {
968
992
  checkNameAvailability: checkNameAvailability3,
@@ -971,8 +995,8 @@ var powershellGalleryRegistryChecker = {
971
995
  };
972
996
 
973
997
  // src/languages/command-generators/powershell.ts
974
- import { mkdir as mkdir5, readdir as readdir3, writeFile as writeFile11 } from "fs/promises";
975
- import path14 from "path";
998
+ import { mkdir as mkdir5, readdir as readdir3, writeFile as writeFile12 } from "fs/promises";
999
+ import path15 from "path";
976
1000
  import { select, text, isCancel, cancel } from "@clack/prompts";
977
1001
  var APPROVED_VERBS = [
978
1002
  "Get",
@@ -996,7 +1020,7 @@ function exitIfCancelled(value) {
996
1020
  }
997
1021
  }
998
1022
  async function listExistingCommands3(targetDir) {
999
- const publicDir = path14.join(targetDir, "Public");
1023
+ const publicDir = path15.join(targetDir, "Public");
1000
1024
  const files = await readdir3(publicDir);
1001
1025
  const paths2 = files.filter((f) => f.endsWith(".ps1")).map((f) => f.replace(/\.ps1$/, ""));
1002
1026
  return buildCommandTree(paths2);
@@ -1051,12 +1075,12 @@ function generateTestFileContent3(spec) {
1051
1075
  }
1052
1076
  async function generateCommand3(targetDir, spec) {
1053
1077
  const funcName = spec.pathSegments[spec.pathSegments.length - 1];
1054
- const commandRelPath = path14.join("Public", `${funcName}.ps1`);
1055
- const testRelPath = path14.join("tests", `${funcName}.Tests.ps1`);
1056
- await mkdir5(path14.join(targetDir, "Public"), { recursive: true });
1057
- await mkdir5(path14.join(targetDir, "tests"), { recursive: true });
1058
- await writeFile11(path14.join(targetDir, commandRelPath), generateCommandFileContent3(spec));
1059
- await writeFile11(path14.join(targetDir, testRelPath), generateTestFileContent3(spec));
1078
+ const commandRelPath = path15.join("Public", `${funcName}.ps1`);
1079
+ const testRelPath = path15.join("tests", `${funcName}.Tests.ps1`);
1080
+ await mkdir5(path15.join(targetDir, "Public"), { recursive: true });
1081
+ await mkdir5(path15.join(targetDir, "tests"), { recursive: true });
1082
+ await writeFile12(path15.join(targetDir, commandRelPath), generateCommandFileContent3(spec));
1083
+ await writeFile12(path15.join(targetDir, testRelPath), generateTestFileContent3(spec));
1060
1084
  return { commandFile: commandRelPath.replace(/\\/g, "/"), testFile: testRelPath.replace(/\\/g, "/") };
1061
1085
  }
1062
1086
  async function promptCommandIdentity(_pathSegments, existingPaths) {
@@ -1094,7 +1118,7 @@ function validateProjectName3(value) {
1094
1118
  var powershellPack = {
1095
1119
  id: "powershell",
1096
1120
  displayName: "PowerShell (7.4+)",
1097
- templateDir: path15.join(findPackageRoot(), "templates", "powershell"),
1121
+ templateDir: path16.join(findPackageRoot(), "templates", "powershell"),
1098
1122
  scaffoldCommands: [
1099
1123
  {
1100
1124
  command: "pwsh",
@@ -1112,6 +1136,9 @@ var powershellPack = {
1112
1136
  },
1113
1137
  commandGenerator: powershellCommandGenerator,
1114
1138
  stripLintTooling: async () => {
1139
+ },
1140
+ supportsAutocompleteOptIn: false,
1141
+ stripAutocompleteSupport: async () => {
1115
1142
  }
1116
1143
  };
1117
1144
 
@@ -1186,6 +1213,19 @@ async function runWizard(deps = defaultDeps) {
1186
1213
  });
1187
1214
  exitIfCancelled2(lintEnabledValue);
1188
1215
  const lintEnabled = lintEnabledValue;
1216
+ let autocompleteEnabled = false;
1217
+ if (pack.supportsAutocompleteOptIn) {
1218
+ const autocompleteEnabledValue = await select2({
1219
+ message: "Set up shell autocompletion?",
1220
+ options: [
1221
+ { value: false, label: "No" },
1222
+ { value: true, label: "Yes" }
1223
+ ],
1224
+ initialValue: false
1225
+ });
1226
+ exitIfCancelled2(autocompleteEnabledValue);
1227
+ autocompleteEnabled = autocompleteEnabledValue;
1228
+ }
1189
1229
  let nameAvailability = "skipped";
1190
1230
  if (publishIntent) {
1191
1231
  nameAvailability = await pack.registry.checkNameAvailability(projectName, registryUrl);
@@ -1204,19 +1244,28 @@ async function runWizard(deps = defaultDeps) {
1204
1244
  }
1205
1245
  }
1206
1246
  outro(`Ready to scaffold "${projectName}".`);
1207
- return { language: pack.id, projectName, profile, registryUrl, publishIntent, nameAvailability, lintEnabled };
1247
+ return {
1248
+ language: pack.id,
1249
+ projectName,
1250
+ profile,
1251
+ registryUrl,
1252
+ publishIntent,
1253
+ nameAvailability,
1254
+ lintEnabled,
1255
+ autocompleteEnabled
1256
+ };
1208
1257
  }
1209
1258
 
1210
1259
  // src/scaffold.ts
1211
- import { cp, readdir as readdir4, readFile as readFile10, rename, writeFile as writeFile13 } from "fs/promises";
1212
- import path17 from "path";
1260
+ import { cp, readdir as readdir4, readFile as readFile11, rename, writeFile as writeFile14 } from "fs/promises";
1261
+ import path18 from "path";
1213
1262
  import spawn2 from "cross-spawn";
1214
1263
 
1215
1264
  // src/update/manifest.ts
1216
1265
  import { createHash } from "crypto";
1217
1266
  import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
1218
- import { mkdir as mkdir6, readFile as readFile9, writeFile as writeFile12 } from "fs/promises";
1219
- import path16 from "path";
1267
+ import { mkdir as mkdir6, readFile as readFile10, writeFile as writeFile13 } from "fs/promises";
1268
+ import path17 from "path";
1220
1269
  import { fileURLToPath as fileURLToPath2 } from "url";
1221
1270
 
1222
1271
  // src/errors.ts
@@ -1234,27 +1283,30 @@ function hashContent(content) {
1234
1283
  async function hashCoreFiles(dir, adapter, flags) {
1235
1284
  const entries = await Promise.all(
1236
1285
  adapter.coreFilePaths(flags).map(async (relativePath) => {
1237
- const content = await readFile9(path16.join(dir, relativePath), "utf8");
1286
+ const content = await readFile10(path17.join(dir, relativePath), "utf8");
1238
1287
  return [relativePath, hashContent(content)];
1239
1288
  })
1240
1289
  );
1241
1290
  return Object.fromEntries(entries);
1242
1291
  }
1243
- async function buildManifest(targetDir, generatorVersion, language, adapter, lintEnabled) {
1244
- const coreFiles = await hashCoreFiles(targetDir, adapter, { lintEnabled });
1292
+ async function buildManifest(targetDir, generatorVersion, language, adapter, lintEnabled, autocompleteEnabled) {
1293
+ const coreFiles = await hashCoreFiles(targetDir, adapter, { lintEnabled, autocompleteEnabled });
1245
1294
  const manifestFile = await adapter.readManifestFile(targetDir);
1246
- const { coreDependencies, coreScripts, coreFields } = adapter.extractCoreFields(manifestFile, { lintEnabled });
1247
- return { generatorVersion, language, lintEnabled, coreFiles, coreDependencies, coreScripts, coreFields };
1295
+ const { coreDependencies, coreScripts, coreFields } = adapter.extractCoreFields(manifestFile, {
1296
+ lintEnabled,
1297
+ autocompleteEnabled
1298
+ });
1299
+ return { generatorVersion, language, lintEnabled, autocompleteEnabled, coreFiles, coreDependencies, coreScripts, coreFields };
1248
1300
  }
1249
- var MANIFEST_RELATIVE_PATH = path16.join(".clispark", "manifest.json");
1301
+ var MANIFEST_RELATIVE_PATH = path17.join(".clispark", "manifest.json");
1250
1302
  async function writeManifest(targetDir, manifest) {
1251
- const manifestPath = path16.join(targetDir, MANIFEST_RELATIVE_PATH);
1252
- await mkdir6(path16.dirname(manifestPath), { recursive: true });
1253
- await writeFile12(manifestPath, JSON.stringify(manifest, null, 2) + "\n");
1303
+ const manifestPath = path17.join(targetDir, MANIFEST_RELATIVE_PATH);
1304
+ await mkdir6(path17.dirname(manifestPath), { recursive: true });
1305
+ await writeFile13(manifestPath, JSON.stringify(manifest, null, 2) + "\n");
1254
1306
  }
1255
1307
  async function readManifest(targetDir) {
1256
1308
  try {
1257
- const content = await readFile9(path16.join(targetDir, MANIFEST_RELATIVE_PATH), "utf8");
1309
+ const content = await readFile10(path17.join(targetDir, MANIFEST_RELATIVE_PATH), "utf8");
1258
1310
  return JSON.parse(content);
1259
1311
  } catch {
1260
1312
  return void 0;
@@ -1270,14 +1322,14 @@ async function requireManifest(targetDir) {
1270
1322
  return manifest;
1271
1323
  }
1272
1324
  function getGeneratorVersion() {
1273
- let dir = path16.dirname(fileURLToPath2(import.meta.url));
1325
+ let dir = path17.dirname(fileURLToPath2(import.meta.url));
1274
1326
  while (true) {
1275
- const pkgPath = path16.join(dir, "package.json");
1327
+ const pkgPath = path17.join(dir, "package.json");
1276
1328
  if (existsSync2(pkgPath)) {
1277
1329
  const pkg = JSON.parse(readFileSync2(pkgPath, "utf8"));
1278
1330
  if (pkg.name === "clispark") return pkg.version;
1279
1331
  }
1280
- const parentDir = path16.dirname(dir);
1332
+ const parentDir = path17.dirname(dir);
1281
1333
  if (parentDir === dir) {
1282
1334
  throw new Error("Could not locate clispark's own package.json.");
1283
1335
  }
@@ -1304,7 +1356,7 @@ async function collectFiles(dir) {
1304
1356
  const entries = await readdir4(dir, { withFileTypes: true });
1305
1357
  const files = await Promise.all(
1306
1358
  entries.map((entry) => {
1307
- const fullPath = path17.join(dir, entry.name);
1359
+ const fullPath = path18.join(dir, entry.name);
1308
1360
  return entry.isDirectory() ? collectFiles(fullPath) : Promise.resolve([fullPath]);
1309
1361
  })
1310
1362
  );
@@ -1314,9 +1366,9 @@ async function replacePlaceholdersInTree(targetDir, projectName) {
1314
1366
  const files = await collectFiles(targetDir);
1315
1367
  await Promise.all(
1316
1368
  files.map(async (filePath) => {
1317
- const content = await readFile10(filePath, "utf8");
1369
+ const content = await readFile11(filePath, "utf8");
1318
1370
  if (content.includes("{{projectName}}")) {
1319
- await writeFile13(filePath, applyPlaceholders(content, projectName));
1371
+ await writeFile14(filePath, applyPlaceholders(content, projectName));
1320
1372
  }
1321
1373
  })
1322
1374
  );
@@ -1325,7 +1377,7 @@ async function copyTemplate(options, pack) {
1325
1377
  const { projectName, targetDir, registryUrl, publishIntent } = options;
1326
1378
  await assertTargetDirIsUsable(targetDir);
1327
1379
  await cp(pack.templateDir, targetDir, { recursive: true });
1328
- await rename(path17.join(targetDir, "gitignore"), path17.join(targetDir, ".gitignore"));
1380
+ await rename(path18.join(targetDir, "gitignore"), path18.join(targetDir, ".gitignore"));
1329
1381
  await replacePlaceholdersInTree(targetDir, projectName);
1330
1382
  if (publishIntent === false) {
1331
1383
  await pack.registry.applyPrivateIntent(targetDir);
@@ -1355,7 +1407,18 @@ async function scaffoldProject(options, pack, deps = defaultScaffoldDeps) {
1355
1407
  if (!lintEnabled) {
1356
1408
  await pack.stripLintTooling(targetDir);
1357
1409
  }
1358
- const manifest = await buildManifest(targetDir, getGeneratorVersion(), pack.id, pack.updateAdapter, lintEnabled);
1410
+ const autocompleteEnabled = options.autocompleteEnabled ?? false;
1411
+ if (!autocompleteEnabled) {
1412
+ await pack.stripAutocompleteSupport(targetDir);
1413
+ }
1414
+ const manifest = await buildManifest(
1415
+ targetDir,
1416
+ getGeneratorVersion(),
1417
+ pack.id,
1418
+ pack.updateAdapter,
1419
+ lintEnabled,
1420
+ autocompleteEnabled
1421
+ );
1359
1422
  await writeManifest(targetDir, manifest);
1360
1423
  await deps.runCommand("git", ["init"], targetDir);
1361
1424
  await deps.runCommand("git", ["add", "-A"], targetDir);
@@ -1368,7 +1431,7 @@ async function scaffoldProject(options, pack, deps = defaultScaffoldDeps) {
1368
1431
  // src/logger.ts
1369
1432
  import { randomBytes } from "crypto";
1370
1433
  import { mkdirSync, readdirSync, statSync, unlinkSync, writeFileSync } from "fs";
1371
- import path18 from "path";
1434
+ import path19 from "path";
1372
1435
  import envPaths from "env-paths";
1373
1436
  import pino from "pino";
1374
1437
  var paths = envPaths("clispark", { suffix: "" });
@@ -1404,7 +1467,7 @@ var SWEEP_MARKER_FILE = ".last-sweep";
1404
1467
  var SWEEP_THROTTLE_MS = 24 * 60 * 60 * 1e3;
1405
1468
  function sweepOldLogs(logDir) {
1406
1469
  safely(() => {
1407
- const markerPath = path18.join(logDir, SWEEP_MARKER_FILE);
1470
+ const markerPath = path19.join(logDir, SWEEP_MARKER_FILE);
1408
1471
  let shouldSweep = true;
1409
1472
  try {
1410
1473
  shouldSweep = Date.now() - statSync(markerPath).mtimeMs >= SWEEP_THROTTLE_MS;
@@ -1414,7 +1477,7 @@ function sweepOldLogs(logDir) {
1414
1477
  const cutoffMs = Date.now() - getRetentionDays() * 24 * 60 * 60 * 1e3;
1415
1478
  for (const file of readdirSync(logDir)) {
1416
1479
  if (file === SWEEP_MARKER_FILE) continue;
1417
- const filePath = path18.join(logDir, file);
1480
+ const filePath = path19.join(logDir, file);
1418
1481
  if (statSync(filePath).mtimeMs < cutoffMs) {
1419
1482
  unlinkSync(filePath);
1420
1483
  }
@@ -1425,7 +1488,7 @@ function sweepOldLogs(logDir) {
1425
1488
  function createLogger(commandName, logDir = paths.log) {
1426
1489
  mkdirSync(logDir, { recursive: true });
1427
1490
  sweepOldLogs(logDir);
1428
- const logFilePath = path18.join(logDir, buildLogFileName(commandName));
1491
+ const logFilePath = path19.join(logDir, buildLogFileName(commandName));
1429
1492
  const fileDestination = pino.destination({ dest: logFilePath, sync: true, mode: 384 });
1430
1493
  const destination = process.env.DEBUG ? pino.multistream([{ stream: fileDestination }, { stream: process.stdout }]) : fileDestination;
1431
1494
  const logger = pino({ redact: buildRedactPaths([...SENSITIVE_LOG_KEYS, "registryUrl"]) }, destination);
@@ -1463,8 +1526,8 @@ function withLogging(commandName, action, logDir = paths.log, loggerFactory = cr
1463
1526
  }
1464
1527
 
1465
1528
  // src/update/update.ts
1466
- import { mkdir as mkdir7, readFile as readFile11, writeFile as writeFile14 } from "fs/promises";
1467
- import path19 from "path";
1529
+ import { mkdir as mkdir7, readFile as readFile12, writeFile as writeFile15 } from "fs/promises";
1530
+ import path20 from "path";
1468
1531
  import spawn3 from "cross-spawn";
1469
1532
 
1470
1533
  // src/update/releasenotes.ts
@@ -1550,7 +1613,7 @@ async function updateProject(targetDir, adapter, templateDir, language, deps = d
1550
1613
  const currentManifestFile = await adapter.readManifestFile(targetDir);
1551
1614
  const projectName = adapter.readProjectName(currentManifestFile);
1552
1615
  const newTemplateRaw = applyPlaceholders(
1553
- await readFile11(path19.join(templateDir, adapter.manifestFileName), "utf8"),
1616
+ await readFile12(path20.join(templateDir, adapter.manifestFileName), "utf8"),
1554
1617
  projectName
1555
1618
  );
1556
1619
  const newTemplateManifestFile = adapter.parseManifestFile(newTemplateRaw);
@@ -1560,13 +1623,13 @@ async function updateProject(targetDir, adapter, templateDir, language, deps = d
1560
1623
  const perFileResults = await Promise.all(
1561
1624
  adapter.coreFilePaths(oldManifest).map(async (relativePath) => {
1562
1625
  const newContent = applyPlaceholders(
1563
- await readFile11(path19.join(templateDir, adapter.templateSourcePath(relativePath)), "utf8"),
1626
+ await readFile12(path20.join(templateDir, adapter.templateSourcePath(relativePath)), "utf8"),
1564
1627
  projectName
1565
1628
  );
1566
1629
  const newHash = hashContent(newContent);
1567
1630
  let currentHash;
1568
1631
  try {
1569
- currentHash = hashContent(await readFile11(path19.join(targetDir, relativePath), "utf8"));
1632
+ currentHash = hashContent(await readFile12(path20.join(targetDir, relativePath), "utf8"));
1570
1633
  } catch {
1571
1634
  currentHash = void 0;
1572
1635
  }
@@ -1578,13 +1641,13 @@ async function updateProject(targetDir, adapter, templateDir, language, deps = d
1578
1641
  files.push({ path: relativePath, outcome: result.outcome });
1579
1642
  newCoreFiles[relativePath] = result.value;
1580
1643
  if (result.outcome === "added" || result.outcome === "replaced") {
1581
- fileWrites.push({ targetPath: path19.join(targetDir, relativePath), content: newContent });
1644
+ fileWrites.push({ targetPath: path20.join(targetDir, relativePath), content: newContent });
1582
1645
  }
1583
1646
  }
1584
1647
  for (const relativePath of Object.keys(oldManifest.coreFiles)) {
1585
1648
  if (adapter.coreFilePaths(oldManifest).includes(relativePath)) continue;
1586
1649
  try {
1587
- await readFile11(path19.join(targetDir, relativePath), "utf8");
1650
+ await readFile12(path20.join(targetDir, relativePath), "utf8");
1588
1651
  files.push({ path: relativePath, outcome: "no-longer-core" });
1589
1652
  } catch {
1590
1653
  }
@@ -1606,8 +1669,8 @@ async function updateProject(targetDir, adapter, templateDir, language, deps = d
1606
1669
  };
1607
1670
  }
1608
1671
  for (const write of fileWrites) {
1609
- await mkdir7(path19.dirname(write.targetPath), { recursive: true });
1610
- await writeFile14(write.targetPath, write.content);
1672
+ await mkdir7(path20.dirname(write.targetPath), { recursive: true });
1673
+ await writeFile15(write.targetPath, write.content);
1611
1674
  }
1612
1675
  if (fileMerge.changed) {
1613
1676
  await adapter.writeManifestFile(targetDir, fileMerge.updatedFile);
@@ -1616,6 +1679,7 @@ async function updateProject(targetDir, adapter, templateDir, language, deps = d
1616
1679
  generatorVersion: toVersion,
1617
1680
  language,
1618
1681
  lintEnabled: oldManifest.lintEnabled ?? false,
1682
+ autocompleteEnabled: oldManifest.autocompleteEnabled ?? false,
1619
1683
  coreFiles: newCoreFiles,
1620
1684
  coreDependencies: fileMerge.coreDependencies,
1621
1685
  coreScripts: fileMerge.coreScripts,
@@ -1925,11 +1989,11 @@ ${getConfetti(randomFn)}
1925
1989
 
1926
1990
  // src/hooks.ts
1927
1991
  import { existsSync as existsSync3 } from "fs";
1928
- import path20 from "path";
1992
+ import path21 from "path";
1929
1993
  import { pathToFileURL } from "url";
1930
1994
  import envPaths2 from "env-paths";
1931
1995
  function getPostScaffoldHookPath(configDir = envPaths2("clispark", { suffix: "" }).config) {
1932
- return path20.join(configDir, "hooks", "post-scaffold.mjs");
1996
+ return path21.join(configDir, "hooks", "post-scaffold.mjs");
1933
1997
  }
1934
1998
  var defaultDeps2 = {
1935
1999
  fileExists: existsSync3,
@@ -1972,7 +2036,7 @@ function resolvePack(language) {
1972
2036
  program.action(
1973
2037
  (options) => withLogging("scaffold", async (logger) => {
1974
2038
  const answers = await runWizard();
1975
- const targetDir = path21.join(process.cwd(), answers.projectName);
2039
+ const targetDir = path22.join(process.cwd(), answers.projectName);
1976
2040
  const pack = resolvePack(answers.language);
1977
2041
  logger.info({ projectName: answers.projectName, targetDir, language: pack.id }, "scaffold started");
1978
2042
  await scaffoldProject(
@@ -1981,7 +2045,8 @@ program.action(
1981
2045
  targetDir,
1982
2046
  registryUrl: answers.registryUrl,
1983
2047
  publishIntent: answers.publishIntent,
1984
- lintEnabled: answers.lintEnabled
2048
+ lintEnabled: answers.lintEnabled,
2049
+ autocompleteEnabled: answers.autocompleteEnabled
1985
2050
  },
1986
2051
  pack
1987
2052
  );