@hublo/sentinel 1.1.4 → 1.1.5

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.
@@ -16,7 +16,7 @@ import {
16
16
  registerAdapters,
17
17
  resolve,
18
18
  resolveBin
19
- } from "../chunk-HNE774F7.js";
19
+ } from "../chunk-RLVLDC5H.js";
20
20
 
21
21
  // bin/sentinel.ts
22
22
  import { program } from "commander";
@@ -140,12 +140,106 @@ var PRESET_NAMES = ["react", "nest", "svelte", "node", "tools"];
140
140
 
141
141
  // src/roles/format/adapters/oxfmt/oxfmt.adapter.ts
142
142
  import { spawnSync } from "child_process";
143
- import { existsSync as existsSync10, readFileSync as readFileSync8 } from "fs";
144
- import { join as join11 } from "path";
143
+ import { existsSync as existsSync10, readFileSync as readFileSync9 } from "fs";
144
+ import { join as join12 } from "path";
145
+
146
+ // src/core/config/existing-command.ts
147
+ import { readFileSync as readFileSync3 } from "fs";
148
+ import { join as join3 } from "path";
149
+
150
+ // src/shared/jsonc.ts
151
+ import { parse, printParseErrorCode } from "jsonc-parser";
152
+ function parseJsonc(text, source = "config") {
153
+ const errors = [];
154
+ const value = parse(text, errors, { allowTrailingComma: true });
155
+ if (errors.length > 0) {
156
+ const details = errors.map((error) => printParseErrorCode(error.error)).join(", ");
157
+ throw new Error(`${source}: malformed JSONC (${details}).`);
158
+ }
159
+ return value;
160
+ }
161
+
162
+ // src/core/config/manifest.ts
163
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
164
+ import { basename, join as join2 } from "path";
165
+ function moduleScripts(cwd) {
166
+ try {
167
+ const pkg = JSON.parse(readFileSync2(join2(cwd, "package.json"), "utf8"));
168
+ return pkg.scripts ?? {};
169
+ } catch {
170
+ return {};
171
+ }
172
+ }
173
+ function moduleName(cwd) {
174
+ try {
175
+ const pkg = JSON.parse(readFileSync2(join2(cwd, "package.json"), "utf8"));
176
+ return pkg.name;
177
+ } catch {
178
+ return void 0;
179
+ }
180
+ }
181
+ function isSelfAdoption(cwd) {
182
+ return moduleName(cwd) === readOwnPackage().name;
183
+ }
184
+ function selfCommand(cwd, flags) {
185
+ const own = readOwnPackage();
186
+ if (!isSelfAdoption(cwd) || !own.bin) return void 0;
187
+ return `node ${own.bin.replace(/^\.\//, "")} ${flags}`;
188
+ }
189
+ function manifestOperation(cwd, scripts) {
190
+ const own = readOwnPackage();
191
+ const value = {
192
+ scripts,
193
+ devDependencies: { [own.name]: isSelfAdoption(cwd) ? "link:." : own.version }
194
+ };
195
+ if (existsSync2(join2(cwd, "package.json"))) {
196
+ return { kind: "merge-json", path: "package.json", value };
197
+ }
198
+ return {
199
+ kind: "merge-json",
200
+ path: "package.json",
201
+ value: { name: readNxProjectName(cwd) ?? basename(cwd), private: true, ...value }
202
+ };
203
+ }
204
+
205
+ // src/core/config/existing-command.ts
206
+ function nxTargetCommand(cwd, target) {
207
+ let project;
208
+ try {
209
+ project = parseJsonc(
210
+ readFileSync3(join3(cwd, "project.json"), "utf8"),
211
+ "project.json"
212
+ );
213
+ } catch {
214
+ return void 0;
215
+ }
216
+ const entry = project.targets?.[target];
217
+ if (!entry || entry.executor !== "nx:run-commands") return void 0;
218
+ const { command, commands, cwd: targetCwd } = entry.options ?? {};
219
+ const ranInModule = typeof targetCwd === "string" && targetCwd.trim() !== "";
220
+ if (typeof command === "string" && command.trim() !== "") {
221
+ return { command: command.trim(), ranInModule };
222
+ }
223
+ if (Array.isArray(commands)) {
224
+ const parts = commands.filter((c) => typeof c === "string" && c.trim() !== "");
225
+ if (parts.length > 0) return { command: parts.map((c) => c.trim()).join(" && "), ranInModule };
226
+ }
227
+ return void 0;
228
+ }
229
+ function rootedForScript(command) {
230
+ return command.replace(/(^|&&\s*)pnpm exec /g, "$1pnpm --workspace-root exec ");
231
+ }
232
+ function existingCommand(cwd, target) {
233
+ const script = moduleScripts(cwd)[target];
234
+ if (script !== void 0 && script.trim() !== "") return script;
235
+ const fromTarget = nxTargetCommand(cwd, target);
236
+ if (fromTarget === void 0) return void 0;
237
+ return fromTarget.ranInModule ? fromTarget.command : rootedForScript(fromTarget.command);
238
+ }
145
239
 
146
240
  // src/core/config/has-source.ts
147
241
  import { readdirSync } from "fs";
148
- import { extname, join as join2 } from "path";
242
+ import { extname, join as join4 } from "path";
149
243
  var SKIP_DIRECTORIES = /* @__PURE__ */ new Set([
150
244
  "node_modules",
151
245
  "dist",
@@ -196,7 +290,7 @@ function hasSourceFiles(cwd, extensions) {
196
290
  }
197
291
  for (const entry of entries) {
198
292
  if (entry.isDirectory()) {
199
- if (!SKIP_DIRECTORIES.has(entry.name)) queue.push(join2(dir, entry.name));
293
+ if (!SKIP_DIRECTORIES.has(entry.name)) queue.push(join4(dir, entry.name));
200
294
  continue;
201
295
  }
202
296
  if (wanted.has(extname(entry.name))) return true;
@@ -205,58 +299,15 @@ function hasSourceFiles(cwd, extensions) {
205
299
  return false;
206
300
  }
207
301
 
208
- // src/core/config/manifest.ts
209
- import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
210
- import { basename, join as join3 } from "path";
211
- function moduleScripts(cwd) {
212
- try {
213
- const pkg = JSON.parse(readFileSync2(join3(cwd, "package.json"), "utf8"));
214
- return pkg.scripts ?? {};
215
- } catch {
216
- return {};
217
- }
218
- }
219
- function moduleName(cwd) {
220
- try {
221
- const pkg = JSON.parse(readFileSync2(join3(cwd, "package.json"), "utf8"));
222
- return pkg.name;
223
- } catch {
224
- return void 0;
225
- }
226
- }
227
- function isSelfAdoption(cwd) {
228
- return moduleName(cwd) === readOwnPackage().name;
229
- }
230
- function selfCommand(cwd, flags) {
231
- const own = readOwnPackage();
232
- if (!isSelfAdoption(cwd) || !own.bin) return void 0;
233
- return `node ${own.bin.replace(/^\.\//, "")} ${flags}`;
234
- }
235
- function manifestOperation(cwd, scripts) {
236
- const own = readOwnPackage();
237
- const value = {
238
- scripts,
239
- devDependencies: { [own.name]: isSelfAdoption(cwd) ? "link:." : own.version }
240
- };
241
- if (existsSync2(join3(cwd, "package.json"))) {
242
- return { kind: "merge-json", path: "package.json", value };
243
- }
244
- return {
245
- kind: "merge-json",
246
- path: "package.json",
247
- value: { name: readNxProjectName(cwd) ?? basename(cwd), private: true, ...value }
248
- };
249
- }
250
-
251
302
  // src/core/config/nx-target.ts
252
303
  import { existsSync as existsSync3 } from "fs";
253
- import { join as join4 } from "path";
304
+ import { join as join5 } from "path";
254
305
  function nxTargetOperations(options) {
255
306
  const { cwd, targets } = options;
256
307
  const names = Object.keys(targets);
257
308
  if (names.length === 0) return [];
258
309
  const operations = [];
259
- if (existsSync3(join4(cwd, "project.json"))) {
310
+ if (existsSync3(join5(cwd, "project.json"))) {
260
311
  operations.push({
261
312
  kind: "remove-json-keys",
262
313
  path: "project.json",
@@ -294,8 +345,8 @@ var WORKSPACE_ROOT_MARKER = "nx.json";
294
345
  var DEFAULT_MAX_DIAGNOSTICS = 100;
295
346
 
296
347
  // src/core/workspace-prep.ts
297
- import { existsSync as existsSync5, readFileSync as readFileSync3, writeFileSync } from "fs";
298
- import { dirname as dirname2, join as join5, relative } from "path";
348
+ import { existsSync as existsSync5, readFileSync as readFileSync4, writeFileSync } from "fs";
349
+ import { dirname as dirname2, join as join6, relative } from "path";
299
350
  var OVERRIDE_KEY = "i18next>typescript";
300
351
  var NATIVE_TS_ALIAS = "@typescript/native";
301
352
  var WORKSPACE_YAML = "pnpm-workspace.yaml";
@@ -304,7 +355,7 @@ var LIST_ITEM = /^(\s*)-\s+(.*?)\s*$/;
304
355
  function findWorkspaceRoot(startDir) {
305
356
  let dir = startDir;
306
357
  for (; ; ) {
307
- if (existsSync5(join5(dir, WORKSPACE_ROOT_MARKER))) return dir;
358
+ if (existsSync5(join6(dir, WORKSPACE_ROOT_MARKER))) return dir;
308
359
  const parent = dirname2(dir);
309
360
  if (parent === dir) return void 0;
310
361
  dir = parent;
@@ -317,9 +368,9 @@ function declaredNativeTs(pkg) {
317
368
  return version || void 0;
318
369
  }
319
370
  function ensureI18nextSingleton(root, dryRun) {
320
- const pkgPath = join5(root, "package.json");
371
+ const pkgPath = join6(root, "package.json");
321
372
  if (!existsSync5(pkgPath)) return void 0;
322
- const pkg = JSON.parse(readFileSync3(pkgPath, "utf8"));
373
+ const pkg = JSON.parse(readFileSync4(pkgPath, "utf8"));
323
374
  const want = declaredNativeTs(pkg);
324
375
  if (!want) return void 0;
325
376
  const have = pkg.pnpm?.overrides?.[OVERRIDE_KEY];
@@ -332,10 +383,10 @@ function ensureI18nextSingleton(root, dryRun) {
332
383
  return `pinned ${OVERRIDE_KEY} to ${want} in package.json (i18next singleton)`;
333
384
  }
334
385
  function ensureReleaseAgeAllowList(root, dryRun) {
335
- const yamlPath = join5(root, WORKSPACE_YAML);
386
+ const yamlPath = join6(root, WORKSPACE_YAML);
336
387
  if (!existsSync5(yamlPath)) return void 0;
337
388
  const own = readOwnPackage().name;
338
- const lines = readFileSync3(yamlPath, "utf8").split("\n");
389
+ const lines = readFileSync4(yamlPath, "utf8").split("\n");
339
390
  const keyIdx = lines.findIndex((line) => line.replace(/\s+$/, "") === `${RELEASE_AGE_KEY}:`);
340
391
  if (keyIdx === -1) return void 0;
341
392
  let lastItemIdx = keyIdx;
@@ -370,11 +421,11 @@ var ROOT_PRETTIER_CONFIGS = [
370
421
  function ensureFormatterExclusion(root, moduleDir, dryRun) {
371
422
  const rel = relative(root, moduleDir).replaceAll("\\", "/");
372
423
  if (rel === "" || rel.startsWith("..")) return void 0;
373
- const ignorePath = join5(root, PRETTIER_IGNORE);
374
- const hasPrettier = existsSync5(ignorePath) || ROOT_PRETTIER_CONFIGS.some((name) => existsSync5(join5(root, name)));
424
+ const ignorePath = join6(root, PRETTIER_IGNORE);
425
+ const hasPrettier = existsSync5(ignorePath) || ROOT_PRETTIER_CONFIGS.some((name) => existsSync5(join6(root, name)));
375
426
  if (!hasPrettier) return void 0;
376
427
  const pattern = `/${rel}/`;
377
- const existing = existsSync5(ignorePath) ? readFileSync3(ignorePath, "utf8") : "";
428
+ const existing = existsSync5(ignorePath) ? readFileSync4(ignorePath, "utf8") : "";
378
429
  const lines = existing.split("\n");
379
430
  if (lines.some((line) => line.trim().replace(/\/$/, "") === pattern.replace(/\/$/, ""))) {
380
431
  return void 0;
@@ -411,12 +462,12 @@ function ensureWorkspacePrep(opts) {
411
462
  // src/shared/resolve-bin.ts
412
463
  import { existsSync as existsSync6 } from "fs";
413
464
  import { createRequire } from "module";
414
- import { delimiter, dirname as dirname3, join as join6 } from "path";
465
+ import { delimiter, dirname as dirname3, join as join7 } from "path";
415
466
  var require2 = createRequire(import.meta.url);
416
467
  function resolveBin(fromDir, name) {
417
468
  let dir = fromDir;
418
469
  for (; ; ) {
419
- const candidate = join6(dir, "node_modules", ".bin", name);
470
+ const candidate = join7(dir, "node_modules", ".bin", name);
420
471
  if (existsSync6(candidate)) return candidate;
421
472
  const parent = dirname3(dir);
422
473
  if (parent === dir) return void 0;
@@ -429,7 +480,7 @@ function binFromOwnInstall(packageName, binName) {
429
480
  const bin = require2(manifest).bin;
430
481
  const relative3 = typeof bin === "string" ? bin : bin?.[binName];
431
482
  if (!relative3) return void 0;
432
- const executable = join6(dirname3(manifest), relative3);
483
+ const executable = join7(dirname3(manifest), relative3);
433
484
  return existsSync6(executable) ? executable : void 0;
434
485
  } catch {
435
486
  return void 0;
@@ -556,8 +607,8 @@ function writesWhenRewritten(name, command) {
556
607
  var CHECK_SCRIPT_NAMES = /* @__PURE__ */ new Set(["lint", "format", "check", "test", "typecheck", "verify"]);
557
608
 
558
609
  // src/roles/format/inherited-ignores.ts
559
- import { existsSync as existsSync7, readFileSync as readFileSync4 } from "fs";
560
- import { join as join7 } from "path";
610
+ import { existsSync as existsSync7, readFileSync as readFileSync5 } from "fs";
611
+ import { join as join8 } from "path";
561
612
  var ROOT_IGNORE_FILE = ".prettierignore";
562
613
  function isPattern(line) {
563
614
  const trimmed = line.trim();
@@ -572,11 +623,11 @@ function toModulePattern(pattern) {
572
623
  }
573
624
  function inheritedIgnorePatterns(workspaceRoot) {
574
625
  if (!workspaceRoot) return [];
575
- const path = join7(workspaceRoot, ROOT_IGNORE_FILE);
626
+ const path = join8(workspaceRoot, ROOT_IGNORE_FILE);
576
627
  if (!existsSync7(path)) return [];
577
628
  let contents;
578
629
  try {
579
- contents = readFileSync4(path, "utf8");
630
+ contents = readFileSync5(path, "utf8");
580
631
  } catch {
581
632
  return [];
582
633
  }
@@ -663,25 +714,13 @@ function formatPresetFor(preset) {
663
714
  }
664
715
 
665
716
  // src/roles/format/prettier-config.ts
666
- import { existsSync as existsSync8, readFileSync as readFileSync6 } from "fs";
667
- import { join as join9 } from "path";
668
-
669
- // src/shared/jsonc.ts
670
- import { parse, printParseErrorCode } from "jsonc-parser";
671
- function parseJsonc(text, source = "config") {
672
- const errors = [];
673
- const value = parse(text, errors, { allowTrailingComma: true });
674
- if (errors.length > 0) {
675
- const details = errors.map((error) => printParseErrorCode(error.error)).join(", ");
676
- throw new Error(`${source}: malformed JSONC (${details}).`);
677
- }
678
- return value;
679
- }
717
+ import { existsSync as existsSync8, readFileSync as readFileSync7 } from "fs";
718
+ import { join as join10 } from "path";
680
719
 
681
720
  // src/roles/format/resolve-oxfmt.ts
682
- import { readFileSync as readFileSync5 } from "fs";
721
+ import { readFileSync as readFileSync6 } from "fs";
683
722
  import { createRequire as createRequire2 } from "module";
684
- import { dirname as dirname4, join as join8 } from "path";
723
+ import { dirname as dirname4, join as join9 } from "path";
685
724
  function resolveOxfmt(cwd) {
686
725
  return resolveBin(cwd, "oxfmt") ?? binFromOwnInstall("oxfmt", "oxfmt");
687
726
  }
@@ -710,8 +749,8 @@ function configSchema() {
710
749
  function readConfigSchema() {
711
750
  try {
712
751
  const manifest = createRequire2(import.meta.url).resolve("oxfmt/package.json");
713
- const schemaPath = join8(dirname4(manifest), "configuration_schema.json");
714
- return JSON.parse(readFileSync5(schemaPath, "utf8"));
752
+ const schemaPath = join9(dirname4(manifest), "configuration_schema.json");
753
+ return JSON.parse(readFileSync6(schemaPath, "utf8"));
715
754
  } catch {
716
755
  return void 0;
717
756
  }
@@ -742,14 +781,14 @@ function toOxfmtOverrides(value) {
742
781
  return { overrides, unresolved };
743
782
  }
744
783
  function readPrettierSettings(cwd) {
745
- const file = PRETTIER_CONFIG_FILES.find((name) => existsSync8(join9(cwd, name)));
784
+ const file = PRETTIER_CONFIG_FILES.find((name) => existsSync8(join10(cwd, name)));
746
785
  if (!file) return { options: {}, unresolved: [] };
747
786
  if (/\.(js|cjs|mjs)$/.test(file)) {
748
787
  return { options: {}, file, unresolved: [`${file} is JavaScript, so it was not executed`] };
749
788
  }
750
789
  let parsed;
751
790
  try {
752
- parsed = parseJsonc(readFileSync6(join9(cwd, file), "utf8"), file);
791
+ parsed = parseJsonc(readFileSync7(join10(cwd, file), "utf8"), file);
753
792
  } catch {
754
793
  return { options: {}, file, unresolved: [`${file} could not be parsed`] };
755
794
  }
@@ -779,8 +818,8 @@ function readPrettierSettings(cwd) {
779
818
  }
780
819
 
781
820
  // src/roles/format/read-adoption.ts
782
- import { existsSync as existsSync9, readFileSync as readFileSync7 } from "fs";
783
- import { join as join10 } from "path";
821
+ import { existsSync as existsSync9, readFileSync as readFileSync8 } from "fs";
822
+ import { join as join11 } from "path";
784
823
  var NOT_ADOPTED = (configFile, unreadable = null) => ({
785
824
  configFile,
786
825
  preset: null,
@@ -796,11 +835,11 @@ function sameValue(a, b) {
796
835
  return JSON.stringify(a) === JSON.stringify(b);
797
836
  }
798
837
  function readFormatAdoption(cwd) {
799
- const path = join10(cwd, FORMAT_CONFIG_FILE);
838
+ const path = join11(cwd, FORMAT_CONFIG_FILE);
800
839
  if (!existsSync9(path)) return NOT_ADOPTED(null);
801
840
  let parsed;
802
841
  try {
803
- parsed = parseJsonc(readFileSync7(path, "utf8"), FORMAT_CONFIG_FILE);
842
+ parsed = parseJsonc(readFileSync8(path, "utf8"), FORMAT_CONFIG_FILE);
804
843
  } catch (error) {
805
844
  const reason = error instanceof Error ? error.message : String(error);
806
845
  return NOT_ADOPTED(FORMAT_CONFIG_FILE, `${FORMAT_CONFIG_FILE} could not be parsed (${reason})`);
@@ -907,7 +946,7 @@ var OxfmtAdapter = class extends BaseAdapter {
907
946
  manifestOperation(context.cwd, this.formatScripts(context.cwd))
908
947
  ];
909
948
  const prettierConfigs = PRETTIER_CONFIG_FILES.filter(
910
- (name) => existsSync10(join11(context.cwd, name))
949
+ (name) => existsSync10(join12(context.cwd, name))
911
950
  );
912
951
  for (const name of prettierConfigs) operations.push({ kind: "delete", path: name });
913
952
  const removableDeps = this.modulePrettierDependencies(context.cwd);
@@ -1143,7 +1182,7 @@ var OxfmtAdapter = class extends BaseAdapter {
1143
1182
  modulePrettierDependencies(cwd) {
1144
1183
  const isPrettierPackage = (name) => name === "prettier" || name.startsWith("prettier-plugin-") || name.startsWith("@prettier/");
1145
1184
  try {
1146
- const manifest = JSON.parse(readFileSync8(join11(cwd, "package.json"), "utf8"));
1185
+ const manifest = JSON.parse(readFileSync9(join12(cwd, "package.json"), "utf8"));
1147
1186
  return Object.keys(manifest.devDependencies ?? {}).filter(isPrettierPackage).map((name) => ["devDependencies", name]);
1148
1187
  } catch {
1149
1188
  return [];
@@ -1166,7 +1205,9 @@ var OxfmtAdapter = class extends BaseAdapter {
1166
1205
  const ownCommand = selfCommand(cwd, "--run --format");
1167
1206
  const compose = (existing, keepFix) => composeFormatScript(existing, { keepFix, command: ownCommand });
1168
1207
  const rewritten = {
1169
- [FORMAT_SCRIPT_NAME]: compose(scripts[FORMAT_SCRIPT_NAME], false),
1208
+ // `existingCommand` for the role's own script: the command can live in an
1209
+ // `nx:run-commands` target that adoption deletes, taking anything else it ran with it.
1210
+ [FORMAT_SCRIPT_NAME]: compose(existingCommand(cwd, FORMAT_SCRIPT_NAME), false),
1170
1211
  [`${FORMAT_SCRIPT_NAME}:fix`]: compose(scripts[`${FORMAT_SCRIPT_NAME}:fix`], true)
1171
1212
  };
1172
1213
  for (const [name, command] of Object.entries(scripts)) {
@@ -1223,8 +1264,8 @@ function registerFormat() {
1223
1264
 
1224
1265
  // src/roles/lint/adapters/oxlint/oxlint.adapter.ts
1225
1266
  import { spawnSync as spawnSync2 } from "child_process";
1226
- import { existsSync as existsSync16, readFileSync as readFileSync14, rmSync, writeFileSync as writeFileSync2 } from "fs";
1227
- import { join as join18 } from "path";
1267
+ import { existsSync as existsSync16, readFileSync as readFileSync15, rmSync, writeFileSync as writeFileSync2 } from "fs";
1268
+ import { join as join19 } from "path";
1228
1269
 
1229
1270
  // src/core/config/deferred-rules.ts
1230
1271
  function deferredRuleNames(rules) {
@@ -3120,8 +3161,8 @@ function errorCountsByConfigRule(stdout) {
3120
3161
  }
3121
3162
 
3122
3163
  // src/core/config/read-adoption.ts
3123
- import { existsSync as existsSync12, readFileSync as readFileSync10 } from "fs";
3124
- import { join as join13 } from "path";
3164
+ import { existsSync as existsSync12, readFileSync as readFileSync11 } from "fs";
3165
+ import { join as join14 } from "path";
3125
3166
 
3126
3167
  // src/core/config/owned-keys.ts
3127
3168
  function presetOwnedKeys(config, permitted, presetSets) {
@@ -3136,12 +3177,12 @@ function localOnlyKeys(config, permitted, presetSets) {
3136
3177
  }
3137
3178
 
3138
3179
  // src/core/config/resolve-config-target.ts
3139
- import { existsSync as existsSync11, readFileSync as readFileSync9 } from "fs";
3140
- import { join as join12 } from "path";
3180
+ import { existsSync as existsSync11, readFileSync as readFileSync10 } from "fs";
3181
+ import { join as join13 } from "path";
3141
3182
  function readExtends(absolutePath) {
3142
3183
  let parsed;
3143
3184
  try {
3144
- parsed = parseJsonc(readFileSync9(absolutePath, "utf8"), absolutePath);
3185
+ parsed = parseJsonc(readFileSync10(absolutePath, "utf8"), absolutePath);
3145
3186
  } catch {
3146
3187
  return [];
3147
3188
  }
@@ -3155,7 +3196,7 @@ function resolveConfigTarget(moduleDir, { candidates, markers, fallback }) {
3155
3196
  let existing;
3156
3197
  let existingExtendsSomething = false;
3157
3198
  for (const candidate of candidates) {
3158
- const absolutePath = join12(moduleDir, candidate);
3199
+ const absolutePath = join13(moduleDir, candidate);
3159
3200
  if (!existsSync11(absolutePath)) continue;
3160
3201
  const chain = readExtends(absolutePath);
3161
3202
  if (existing === void 0) {
@@ -3189,12 +3230,12 @@ var NOT_ADOPTED2 = (configFile, unreadable = null) => ({
3189
3230
  });
3190
3231
  function readAdoption(cwd, options) {
3191
3232
  const target = resolveConfigTarget(cwd, options);
3192
- if (target.reason === "none" || !existsSync12(join13(cwd, target.path))) {
3233
+ if (target.reason === "none" || !existsSync12(join14(cwd, target.path))) {
3193
3234
  return NOT_ADOPTED2(target.reason === "none" ? null : target.path);
3194
3235
  }
3195
3236
  let parsed;
3196
3237
  try {
3197
- parsed = parseJsonc(readFileSync10(join13(cwd, target.path), "utf8"), target.path);
3238
+ parsed = parseJsonc(readFileSync11(join14(cwd, target.path), "utf8"), target.path);
3198
3239
  } catch (error) {
3199
3240
  const reason = error instanceof Error ? error.message : String(error);
3200
3241
  return NOT_ADOPTED2(target.path, `${target.path} could not be parsed (${reason})`);
@@ -3230,7 +3271,7 @@ function readLintAdoption(cwd) {
3230
3271
  // src/roles/lint/resolve-oxlint.ts
3231
3272
  import { existsSync as existsSync13 } from "fs";
3232
3273
  import { createRequire as createRequire3 } from "module";
3233
- import { delimiter as delimiter2, dirname as dirname5, join as join14 } from "path";
3274
+ import { delimiter as delimiter2, dirname as dirname5, join as join15 } from "path";
3234
3275
  import { fileURLToPath as fileURLToPath2 } from "url";
3235
3276
  var PACKAGE_OF = {
3236
3277
  oxlint: "oxlint",
@@ -3255,14 +3296,14 @@ function tsgolintShim(cwd) {
3255
3296
  for (const owner of ["oxlint-tsgolint", "oxlint"]) {
3256
3297
  try {
3257
3298
  const packageDir = dirname5(require3.resolve(`${owner}/package.json`));
3258
- candidates.push(join14(packageDir, "node_modules", ".bin", "tsgolint"));
3259
- candidates.push(join14(packageDir, "..", ".bin", "tsgolint"));
3299
+ candidates.push(join15(packageDir, "node_modules", ".bin", "tsgolint"));
3300
+ candidates.push(join15(packageDir, "..", ".bin", "tsgolint"));
3260
3301
  } catch {
3261
3302
  }
3262
3303
  }
3263
3304
  try {
3264
3305
  const ownRoot = dirname5(require3.resolve("@hublo/sentinel/package.json"));
3265
- candidates.push(join14(ownRoot, "node_modules", ".bin", "tsgolint"));
3306
+ candidates.push(join15(ownRoot, "node_modules", ".bin", "tsgolint"));
3266
3307
  } catch {
3267
3308
  candidates.push(resolveBin(dirname5(fileURLToPath2(import.meta.url)), "tsgolint") ?? "");
3268
3309
  }
@@ -3273,12 +3314,12 @@ function oxlintSearchPath(cwd) {
3273
3314
  }
3274
3315
 
3275
3316
  // src/roles/lint/adapters/oxlint/plan.ts
3276
- import { existsSync as existsSync15, readFileSync as readFileSync13 } from "fs";
3277
- import { join as join17 } from "path";
3317
+ import { existsSync as existsSync15, readFileSync as readFileSync14 } from "fs";
3318
+ import { join as join18 } from "path";
3278
3319
 
3279
3320
  // src/roles/lint/eslint-ignores.ts
3280
- import { existsSync as existsSync14, readFileSync as readFileSync11 } from "fs";
3281
- import { join as join15 } from "path";
3321
+ import { existsSync as existsSync14, readFileSync as readFileSync12 } from "fs";
3322
+ import { join as join16 } from "path";
3282
3323
  var IGNORE_BLOCKS = [/\bignores\s*:\s*\[([^\]]*)\]/g, /\bglobalIgnores\s*\(\s*\[([^\]]*)\]/g];
3283
3324
  var STRING_LITERAL = /['"`]([^'"`]+)['"`]/g;
3284
3325
  var OPAQUE_SOURCE = /\b(includeIgnoreFile)\s*\([^)]*\)/g;
@@ -3291,11 +3332,11 @@ function readRootEslintIgnores(root) {
3291
3332
  return { patterns: patterns.filter((pattern) => pattern.startsWith("**/")), unresolved };
3292
3333
  }
3293
3334
  function readEslintIgnores(cwd) {
3294
- const config = ESLINT_CONFIG_FILES.map((name) => join15(cwd, name)).find((path) => existsSync14(path));
3335
+ const config = ESLINT_CONFIG_FILES.map((name) => join16(cwd, name)).find((path) => existsSync14(path));
3295
3336
  if (!config) return { patterns: [], unresolved: [] };
3296
3337
  let source;
3297
3338
  try {
3298
- source = readFileSync11(config, "utf8");
3339
+ source = readFileSync12(config, "utf8");
3299
3340
  } catch {
3300
3341
  return { patterns: [], unresolved: [] };
3301
3342
  }
@@ -3349,8 +3390,8 @@ function lintPresetFor(preset) {
3349
3390
  }
3350
3391
 
3351
3392
  // src/roles/lint/rename-suppressions.ts
3352
- import { readdirSync as readdirSync2, readFileSync as readFileSync12, statSync } from "fs";
3353
- import { join as join16, relative as relative2 } from "path";
3393
+ import { readdirSync as readdirSync2, readFileSync as readFileSync13, statSync } from "fs";
3394
+ import { join as join17, relative as relative2 } from "path";
3354
3395
  var SOURCE_EXTENSIONS = [
3355
3396
  ".ts",
3356
3397
  ".tsx",
@@ -3397,7 +3438,7 @@ function* sourceFiles(dir) {
3397
3438
  return;
3398
3439
  }
3399
3440
  for (const entry of entries) {
3400
- const full = join16(dir, entry);
3441
+ const full = join17(dir, entry);
3401
3442
  let isDirectory;
3402
3443
  try {
3403
3444
  isDirectory = statSync(full).isDirectory();
@@ -3417,7 +3458,7 @@ function findSuppressionRenames(cwd, renames) {
3417
3458
  for (const file of sourceFiles(cwd)) {
3418
3459
  let content;
3419
3460
  try {
3420
- content = readFileSync12(file, "utf8");
3461
+ content = readFileSync13(file, "utf8");
3421
3462
  } catch {
3422
3463
  continue;
3423
3464
  }
@@ -3535,7 +3576,7 @@ function plan(context) {
3535
3576
  keys: removableDeps
3536
3577
  });
3537
3578
  }
3538
- const eslintConfigs = ESLINT_CONFIG_FILES.filter((name) => existsSync15(join17(context.cwd, name)));
3579
+ const eslintConfigs = ESLINT_CONFIG_FILES.filter((name) => existsSync15(join18(context.cwd, name)));
3539
3580
  for (const name of eslintConfigs) operations.push({ kind: "delete", path: name });
3540
3581
  operations.push(
3541
3582
  ...nxTargetOperations({
@@ -3611,7 +3652,10 @@ function plan(context) {
3611
3652
  function lintScripts(cwd) {
3612
3653
  const scripts = moduleScripts(cwd);
3613
3654
  const rewritten = {
3614
- [LINT_SCRIPT_NAME]: composeLintScript(scripts[LINT_SCRIPT_NAME], {
3655
+ // `existingCommand`, not `scripts[...]`: the command can live in an `nx:run-commands`
3656
+ // target instead of a script, and adoption deletes that target. Composing against only
3657
+ // the script threw away whatever else the target ran.
3658
+ [LINT_SCRIPT_NAME]: composeLintScript(existingCommand(cwd, LINT_SCRIPT_NAME), {
3615
3659
  command: selfCommand(cwd, "--run --lint")
3616
3660
  })
3617
3661
  };
@@ -3630,7 +3674,7 @@ function lintScripts(cwd) {
3630
3674
  function committedIgnorePatterns(cwd) {
3631
3675
  try {
3632
3676
  const parsed = parseJsonc(
3633
- readFileSync13(join17(cwd, LINT_CONFIG_FILE), "utf8"),
3677
+ readFileSync14(join18(cwd, LINT_CONFIG_FILE), "utf8"),
3634
3678
  LINT_CONFIG_FILE
3635
3679
  );
3636
3680
  return Array.isArray(parsed.ignorePatterns) ? parsed.ignorePatterns.filter((entry) => typeof entry === "string") : [];
@@ -3642,7 +3686,7 @@ function moduleEslintDependencies(cwd) {
3642
3686
  const isEslintPackage = (name) => name === "eslint" || name === "@types/eslint" || name === "typescript-eslint" || name.startsWith("@typescript-eslint/") || name.startsWith("eslint-plugin-") || name.startsWith("eslint-config-") || name.startsWith("@eslint/");
3643
3687
  let manifest;
3644
3688
  try {
3645
- manifest = JSON.parse(readFileSync13(join17(cwd, "package.json"), "utf8"));
3689
+ manifest = JSON.parse(readFileSync14(join18(cwd, "package.json"), "utf8"));
3646
3690
  } catch {
3647
3691
  return [];
3648
3692
  }
@@ -3761,20 +3805,20 @@ var OxlintAdapter = class extends BaseAdapter {
3761
3805
  * build the developer can see, rather than a silent half-adoption they cannot.
3762
3806
  */
3763
3807
  writeModuleBaseline(ctx, oxlint, env) {
3764
- const configPath = join18(ctx.cwd, LINT_CONFIG_FILE);
3765
- const baselinePath = join18(ctx.cwd, LINT_BASELINE_FILE);
3808
+ const configPath = join19(ctx.cwd, LINT_CONFIG_FILE);
3809
+ const baselinePath = join19(ctx.cwd, LINT_BASELINE_FILE);
3766
3810
  if (!existsSync16(configPath)) return;
3767
3811
  let config;
3768
3812
  try {
3769
3813
  config = parseJsonc(
3770
- readFileSync14(configPath, "utf8"),
3814
+ readFileSync15(configPath, "utf8"),
3771
3815
  LINT_CONFIG_FILE
3772
3816
  );
3773
3817
  } catch {
3774
3818
  return;
3775
3819
  }
3776
3820
  const current = Array.isArray(config.extends) ? config.extends : [];
3777
- const measurePath = join18(ctx.cwd, LINT_MEASURE_FILE);
3821
+ const measurePath = join19(ctx.cwd, LINT_MEASURE_FILE);
3778
3822
  let measured;
3779
3823
  try {
3780
3824
  writeFileSync2(
@@ -3822,7 +3866,7 @@ var OxlintAdapter = class extends BaseAdapter {
3822
3866
  }
3823
3867
  }
3824
3868
  async run(ctx) {
3825
- if (!existsSync16(join18(ctx.cwd, LINT_CONFIG_FILE))) {
3869
+ if (!existsSync16(join19(ctx.cwd, LINT_CONFIG_FILE))) {
3826
3870
  process.stderr.write(
3827
3871
  `sentinel lint(oxlint): no ${LINT_CONFIG_FILE} in this module; run \`sentinel --init --lint\` to adopt.
3828
3872
  `
@@ -3937,7 +3981,7 @@ var OxlintAdapter = class extends BaseAdapter {
3937
3981
  let stub;
3938
3982
  try {
3939
3983
  stub = parseJsonc(
3940
- readFileSync14(join18(cwd, LINT_CONFIG_FILE), "utf8"),
3984
+ readFileSync15(join19(cwd, LINT_CONFIG_FILE), "utf8"),
3941
3985
  LINT_CONFIG_FILE
3942
3986
  );
3943
3987
  } catch {
@@ -3947,7 +3991,7 @@ var OxlintAdapter = class extends BaseAdapter {
3947
3991
  for (const entry of stub.extends ?? []) {
3948
3992
  try {
3949
3993
  const preset = parseJsonc(
3950
- readFileSync14(join18(cwd, entry), "utf8"),
3994
+ readFileSync15(join19(cwd, entry), "utf8"),
3951
3995
  entry
3952
3996
  );
3953
3997
  for (const rule of Object.keys(preset.rules ?? {})) names.add(rule);
@@ -4017,14 +4061,14 @@ var OxlintAdapter = class extends BaseAdapter {
4017
4061
  let parsed;
4018
4062
  try {
4019
4063
  parsed = parseJsonc(
4020
- readFileSync14(join18(cwd, LINT_CONFIG_FILE), "utf8"),
4064
+ readFileSync15(join19(cwd, LINT_CONFIG_FILE), "utf8"),
4021
4065
  LINT_CONFIG_FILE
4022
4066
  );
4023
4067
  } catch {
4024
4068
  return void 0;
4025
4069
  }
4026
4070
  const targets = Array.isArray(parsed.extends) ? parsed.extends.filter((entry) => typeof entry === "string") : typeof parsed.extends === "string" ? [parsed.extends] : [];
4027
- return targets.find((target) => !existsSync16(join18(cwd, target)));
4071
+ return targets.find((target) => !existsSync16(join19(cwd, target)));
4028
4072
  }
4029
4073
  /** Announce what is not enforced, so reduced coverage is never silent. */
4030
4074
  announceDisabled(preset) {
@@ -4056,9 +4100,9 @@ function registerLint() {
4056
4100
 
4057
4101
  // src/roles/typescript/adapters/tsc/tsc.adapter.ts
4058
4102
  import { spawnSync as spawnSync3 } from "child_process";
4059
- import { existsSync as existsSync17, readFileSync as readFileSync16 } from "fs";
4103
+ import { existsSync as existsSync17, readFileSync as readFileSync17 } from "fs";
4060
4104
  import { createRequire as createRequire4 } from "module";
4061
- import { join as join20 } from "path";
4105
+ import { join as join21 } from "path";
4062
4106
 
4063
4107
  // src/roles/typescript/presets/base.json
4064
4108
  var base_default3 = {
@@ -4239,8 +4283,8 @@ function readTsconfigAdoption(cwd) {
4239
4283
  }
4240
4284
 
4241
4285
  // src/roles/typescript/adapters/tsc/plan.ts
4242
- import { readFileSync as readFileSync15 } from "fs";
4243
- import { join as join19 } from "path";
4286
+ import { readFileSync as readFileSync16 } from "fs";
4287
+ import { join as join20 } from "path";
4244
4288
 
4245
4289
  // src/roles/typescript/typecheck-script.ts
4246
4290
  var SENTINEL_TYPECHECK_COMMAND = "sentinel --run --typescript";
@@ -4265,7 +4309,10 @@ var INSTALL_NOTE = "run `pnpm install` to fetch @hublo/sentinel (added to the mo
4265
4309
  var TYPECHECK_TARGET = { cache: true, inputs: ["default", "{projectRoot}/tsconfig.json"] };
4266
4310
  function typecheckScripts(cwd) {
4267
4311
  return {
4268
- [TYPECHECK_SCRIPT_NAME]: composeTypecheckScript(moduleScripts(cwd)[TYPECHECK_SCRIPT_NAME])
4312
+ // Reads the nx target too, not only the npm script: five modules in this repo keep a
4313
+ // real prerequisite (the brand-token generator) in an `nx:run-commands` typecheck
4314
+ // target, and adoption used to delete it along with the target.
4315
+ [TYPECHECK_SCRIPT_NAME]: composeTypecheckScript(existingCommand(cwd, TYPECHECK_SCRIPT_NAME))
4269
4316
  };
4270
4317
  }
4271
4318
  function composeExtends(current, preset) {
@@ -4325,7 +4372,7 @@ function planAdoption(context) {
4325
4372
  };
4326
4373
  }
4327
4374
  const existing = parseJsonc(
4328
- readFileSync15(join19(context.cwd, target.path), "utf8"),
4375
+ readFileSync16(join20(context.cwd, target.path), "utf8"),
4329
4376
  target.path
4330
4377
  );
4331
4378
  const extendsChain = composeExtends(existing.extends, preset);
@@ -4463,7 +4510,7 @@ var TscAdapter = class _TscAdapter extends BaseAdapter {
4463
4510
  let chain;
4464
4511
  try {
4465
4512
  const parsed = parseJsonc(
4466
- readFileSync16(join20(cwd, target.path), "utf8"),
4513
+ readFileSync17(join21(cwd, target.path), "utf8"),
4467
4514
  target.path
4468
4515
  );
4469
4516
  chain = parsed.extends;
@@ -4476,7 +4523,7 @@ var TscAdapter = class _TscAdapter extends BaseAdapter {
4476
4523
  );
4477
4524
  if (preset === void 0) return void 0;
4478
4525
  try {
4479
- createRequire4(join20(cwd, "noop.js")).resolve(preset);
4526
+ createRequire4(join21(cwd, "noop.js")).resolve(preset);
4480
4527
  return void 0;
4481
4528
  } catch {
4482
4529
  return preset;
@@ -4572,7 +4619,7 @@ var TscAdapter = class _TscAdapter extends BaseAdapter {
4572
4619
  referencedProjects(cwd, config) {
4573
4620
  try {
4574
4621
  const parsed = parseJsonc(
4575
- readFileSync16(join20(cwd, config), "utf8"),
4622
+ readFileSync17(join21(cwd, config), "utf8"),
4576
4623
  config
4577
4624
  );
4578
4625
  const referenced = (parsed.references ?? []).map((reference) => reference.path).filter((path) => typeof path === "string" && path.length > 0);
@@ -4588,7 +4635,7 @@ var TscAdapter = class _TscAdapter extends BaseAdapter {
4588
4635
  * check.
4589
4636
  */
4590
4637
  typecheckTarget(cwd) {
4591
- if (existsSync17(join20(cwd, "tsconfig.json"))) return "tsconfig.json";
4638
+ if (existsSync17(join21(cwd, "tsconfig.json"))) return "tsconfig.json";
4592
4639
  const target = resolveTsconfigTarget(cwd);
4593
4640
  return target.reason === "none" ? null : target.path;
4594
4641
  }
@@ -4791,7 +4838,7 @@ function replaceLines(current, replacements) {
4791
4838
  }
4792
4839
 
4793
4840
  // src/core/apply-plan.ts
4794
- import { existsSync as existsSync18, readFileSync as readFileSync17, renameSync, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "fs";
4841
+ import { existsSync as existsSync18, readFileSync as readFileSync18, renameSync, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "fs";
4795
4842
  import { resolve as resolve3, sep } from "path";
4796
4843
  import { applyEdits, findNodeAtLocation, modify, parseTree } from "jsonc-parser";
4797
4844
 
@@ -4810,7 +4857,7 @@ function resolveWithinRoot(cwd, relativePath) {
4810
4857
  return absolutePath;
4811
4858
  }
4812
4859
  function readIfExists(absolutePath) {
4813
- return existsSync18(absolutePath) ? readFileSync17(absolutePath, "utf8") : void 0;
4860
+ return existsSync18(absolutePath) ? readFileSync18(absolutePath, "utf8") : void 0;
4814
4861
  }
4815
4862
  function* leaves(value, prefix = []) {
4816
4863
  for (const [key, keyValue] of Object.entries(value)) {
@@ -4928,8 +4975,8 @@ function applyPlan(cwd, plan2) {
4928
4975
  }
4929
4976
 
4930
4977
  // src/core/config/preset-evidence.ts
4931
- import { existsSync as existsSync19, readdirSync as readdirSync3, readFileSync as readFileSync18 } from "fs";
4932
- import { join as join21 } from "path";
4978
+ import { existsSync as existsSync19, readdirSync as readdirSync3, readFileSync as readFileSync19 } from "fs";
4979
+ import { join as join22 } from "path";
4933
4980
  var PATH_SIGNALS = [
4934
4981
  {
4935
4982
  preset: "nest",
@@ -4943,11 +4990,11 @@ var DEPENDENCY_SIGNALS = [
4943
4990
  { preset: "nest", pattern: /^@nestjs\// }
4944
4991
  ];
4945
4992
  function dependencyNames(cwd) {
4946
- const path = join21(cwd, "package.json");
4993
+ const path = join22(cwd, "package.json");
4947
4994
  if (!existsSync19(path)) return [];
4948
4995
  try {
4949
4996
  const manifest = parseJsonc(
4950
- readFileSync18(path, "utf8"),
4997
+ readFileSync19(path, "utf8"),
4951
4998
  path
4952
4999
  );
4953
5000
  return [
@@ -4970,7 +5017,7 @@ function declaresJsx(cwd) {
4970
5017
  for (const name of entries) {
4971
5018
  try {
4972
5019
  const config = parseJsonc(
4973
- readFileSync18(join21(cwd, name), "utf8"),
5020
+ readFileSync19(join22(cwd, name), "utf8"),
4974
5021
  name
4975
5022
  );
4976
5023
  if (config.compilerOptions?.jsx !== void 0) return true;
@@ -5130,4 +5177,4 @@ export {
5130
5177
  detectFramework,
5131
5178
  dispatch
5132
5179
  };
5133
- //# sourceMappingURL=chunk-HNE774F7.js.map
5180
+ //# sourceMappingURL=chunk-RLVLDC5H.js.map
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  registerAdapters,
8
8
  resolve,
9
9
  setDefaultRunner
10
- } from "./chunk-HNE774F7.js";
10
+ } from "./chunk-RLVLDC5H.js";
11
11
  export {
12
12
  BaseAdapter,
13
13
  all,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hublo/sentinel",
3
- "version": "1.1.4",
3
+ "version": "1.1.5",
4
4
  "description": "One CLI that guards code health across Hublo repos: shared lint/typescript/build/test presets, static & dynamic analysis, and architecture checks.",
5
5
  "type": "module",
6
6
  "license": "MIT",