arcane-cli 0.16.3 → 0.17.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
@@ -87,10 +87,28 @@ var ManifestCorruptError = class extends Error {
87
87
  this.name = "ManifestCorruptError";
88
88
  }
89
89
  };
90
+ var ManifestInvalidFieldError = class extends Error {
91
+ constructor(manifestPath2, field, value) {
92
+ super(
93
+ `Manifest at "${manifestPath2}" has an unsupported value for "${field}": ${JSON.stringify(value)}.`
94
+ );
95
+ this.name = "ManifestInvalidFieldError";
96
+ }
97
+ };
90
98
  var MANIFEST_FILE = ".arcane.json";
99
+ var VALID_TRACKING_MODES = ["internal", "external"];
100
+ var VALID_EXTERNAL_PROVIDERS = ["ado", "jira", "other"];
91
101
  function manifestPath(targetDir) {
92
102
  return path2.join(targetDir, MANIFEST_FILE);
93
103
  }
104
+ function validateTrackingFields(manifest, filePath) {
105
+ if (manifest.tracking_mode !== void 0 && !VALID_TRACKING_MODES.includes(manifest.tracking_mode)) {
106
+ throw new ManifestInvalidFieldError(filePath, "tracking_mode", manifest.tracking_mode);
107
+ }
108
+ if (manifest.external_provider !== void 0 && manifest.external_provider !== null && !VALID_EXTERNAL_PROVIDERS.includes(manifest.external_provider)) {
109
+ throw new ManifestInvalidFieldError(filePath, "external_provider", manifest.external_provider);
110
+ }
111
+ }
94
112
  async function readManifest(targetDir) {
95
113
  const filePath = manifestPath(targetDir);
96
114
  let content;
@@ -102,11 +120,14 @@ async function readManifest(targetDir) {
102
120
  }
103
121
  throw err;
104
122
  }
123
+ let manifest;
105
124
  try {
106
- return JSON.parse(content);
125
+ manifest = JSON.parse(content);
107
126
  } catch {
108
127
  throw new ManifestCorruptError(filePath);
109
128
  }
129
+ validateTrackingFields(manifest, filePath);
130
+ return manifest;
110
131
  }
111
132
  async function writeManifest(targetDir, manifest) {
112
133
  const filePath = manifestPath(targetDir);
@@ -2018,12 +2039,40 @@ async function runInit(options, targetDir, assetsDir, packageVersion) {
2018
2039
  });
2019
2040
  role = isHub ? "hub" : "consumer";
2020
2041
  }
2042
+ let tracking_mode;
2043
+ let external_provider;
2044
+ if (profile === "governance-only" || profile === "methodology") {
2045
+ tracking_mode = "internal";
2046
+ external_provider = null;
2047
+ } else if (!options.profile) {
2048
+ console.log();
2049
+ tracking_mode = await select2({
2050
+ message: "How will work be tracked in this repo?",
2051
+ choices: [
2052
+ { value: "internal", name: "Track work in this repo (TODO.md / PRDs)" },
2053
+ { value: "external", name: "Track work in an external tracker (Azure DevOps / Jira / other)" }
2054
+ ]
2055
+ });
2056
+ if (tracking_mode === "external") {
2057
+ external_provider = await select2({
2058
+ message: "Which external tracker?",
2059
+ choices: [
2060
+ { value: "ado", name: "Azure DevOps" },
2061
+ { value: "jira", name: "Jira" },
2062
+ { value: "other", name: "Other" }
2063
+ ]
2064
+ });
2065
+ } else {
2066
+ external_provider = null;
2067
+ }
2068
+ }
2021
2069
  const manifest = {
2022
2070
  version: packageVersion,
2023
2071
  profile,
2024
2072
  installedAt: (/* @__PURE__ */ new Date()).toISOString(),
2025
2073
  components: installedComponents,
2026
- ...role ? { role } : {}
2074
+ ...role ? { role } : {},
2075
+ ...tracking_mode ? { tracking_mode, external_provider } : {}
2027
2076
  };
2028
2077
  await writeManifest(targetDir, manifest);
2029
2078
  printSuccess(`Initialized with profile "${profile}" \u2014 ${fileCount} files installed`);
@@ -2150,7 +2199,7 @@ async function runAdd(name, options, targetDir, assetsDir, packageVersion) {
2150
2199
  import { join as join7 } from "path";
2151
2200
 
2152
2201
  // src/modules/hub.ts
2153
- import { confirm as confirm2 } from "@inquirer/prompts";
2202
+ import { confirm as confirm2, select as select3 } from "@inquirer/prompts";
2154
2203
  import { readdir as readdir3, writeFile as writeFile5 } from "fs/promises";
2155
2204
  import { join as join6 } from "path";
2156
2205
  var MANIFEST_RETROFITS = [
@@ -2164,6 +2213,36 @@ var MANIFEST_RETROFITS = [
2164
2213
  });
2165
2214
  return { role: isHub ? "hub" : "consumer" };
2166
2215
  }
2216
+ },
2217
+ {
2218
+ field: "tracking_mode",
2219
+ needsRetrofit: (m) => m.tracking_mode === void 0,
2220
+ // Mirrors init.ts's Step 5b branching exactly (EF-14 D5): docs-only
2221
+ // profiles get a silent default, full/lite get asked.
2222
+ ask: async (manifest) => {
2223
+ if (manifest.profile === "governance-only" || manifest.profile === "methodology") {
2224
+ return { tracking_mode: "internal", external_provider: null };
2225
+ }
2226
+ const tracking_mode = await select3({
2227
+ message: "How will work be tracked in this repo?",
2228
+ choices: [
2229
+ { value: "internal", name: "Track work in this repo (TODO.md / PRDs)" },
2230
+ { value: "external", name: "Track work in an external tracker (Azure DevOps / Jira / other)" }
2231
+ ]
2232
+ });
2233
+ if (tracking_mode === "external") {
2234
+ const external_provider = await select3({
2235
+ message: "Which external tracker?",
2236
+ choices: [
2237
+ { value: "ado", name: "Azure DevOps" },
2238
+ { value: "jira", name: "Jira" },
2239
+ { value: "other", name: "Other" }
2240
+ ]
2241
+ });
2242
+ return { tracking_mode, external_provider };
2243
+ }
2244
+ return { tracking_mode, external_provider: null };
2245
+ }
2167
2246
  }
2168
2247
  ];
2169
2248
  async function runManifestRetrofits(manifest) {
@@ -2175,7 +2254,7 @@ async function runManifestRetrofits(manifest) {
2175
2254
  );
2176
2255
  let patch = {};
2177
2256
  for (const retrofit of applicable) {
2178
- const answer = await retrofit.ask();
2257
+ const answer = await retrofit.ask({ ...manifest, ...patch });
2179
2258
  patch = { ...patch, ...answer };
2180
2259
  }
2181
2260
  return patch;