@clearlydev/nx-archweave 0.1.1 → 0.2.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.
Files changed (54) hide show
  1. package/README.md +1 -1
  2. package/dist/eslint/fsd-boundaries.d.ts +25 -8
  3. package/dist/eslint/fsd-policy.d.ts +38 -0
  4. package/dist/eslint/index.d.ts +10 -9
  5. package/dist/eslint/index.js +227 -34
  6. package/dist/eslint/slice-groups.d.ts +12 -0
  7. package/dist/generators/add-agent-rules/generator.js +1175 -23
  8. package/dist/generators/add-backend/generator.js +1127 -75
  9. package/dist/generators/add-fsd-lite/generator.js +1274 -96
  10. package/dist/generators/add-review/files/dependabot.yml +7 -0
  11. package/dist/generators/add-review/generator.js +1100 -46
  12. package/dist/generators/doctor/generator.js +780 -96
  13. package/dist/generators/entity/generator.js +251 -32
  14. package/dist/generators/feature/generator.js +251 -32
  15. package/dist/generators/init/generator.js +1955 -549
  16. package/dist/generators/page/generator.js +251 -32
  17. package/dist/generators/shared/generator.js +251 -32
  18. package/dist/generators/widget/generator.js +251 -32
  19. package/package.json +4 -1
  20. package/src/generators/add-agent-rules/schema.json +5 -0
  21. package/src/generators/add-fsd-lite/schema.json +2 -2
  22. package/src/generators/entity/schema.json +11 -1
  23. package/src/generators/feature/schema.json +11 -1
  24. package/src/generators/init/schema.json +13 -2
  25. package/src/generators/page/schema.json +15 -3
  26. package/src/generators/shared/schema.json +7 -1
  27. package/src/generators/widget/schema.json +11 -1
  28. package/dist/eslint/fsd-boundaries.js +0 -144
  29. package/dist/eslint/tsconfig-aliases.js +0 -114
  30. package/dist/generators/add-agent-rules/render.js +0 -46
  31. package/dist/generators/add-backend/render.js +0 -102
  32. package/dist/generators/add-fsd-lite/render.js +0 -72
  33. package/dist/generators/add-github-templates/render.js +0 -26
  34. package/dist/generators/add-integration/render.js +0 -34
  35. package/dist/generators/add-review/render.js +0 -96
  36. package/dist/generators/allow-builds/render.js +0 -82
  37. package/dist/generators/doctor/integration-report.js +0 -70
  38. package/dist/generators/doctor/render.js +0 -10
  39. package/dist/generators/init/render.js +0 -125
  40. package/dist/generators/init/validation.js +0 -74
  41. package/dist/generators/install-integration/render.js +0 -128
  42. package/dist/generators/record-integration/render.js +0 -31
  43. package/dist/generators/shared/dry-run.js +0 -12
  44. package/dist/generators/shared/frontend-app.js +0 -57
  45. package/dist/generators/shared/project-type.js +0 -39
  46. package/dist/generators/shared/record-pipeline.js +0 -34
  47. package/dist/generators/shared/run-nx.js +0 -24
  48. package/dist/generators/shared/template-files.js +0 -38
  49. package/dist/generators/shared/toolkit-config-file.js +0 -110
  50. package/dist/generators/slice/core.js +0 -185
  51. package/dist/generators/slice/render.js +0 -70
  52. package/dist/lib/nx-plugin.js +0 -7
  53. package/dist/runtime/integrations-composition-root.js +0 -20
  54. package/dist/runtime/node-command-runner.js +0 -81
@@ -285,6 +285,33 @@ var AGENT_RULE_SECTIONS = {
285
285
  ko: KO_SECTIONS
286
286
  };
287
287
 
288
+ // ../templates/dist/agents/fsd-policy-notes.js
289
+ var NOTES = {
290
+ en: {
291
+ heading: "This workspace also configures:",
292
+ groups: "- A folder that only groups slices (`features/mypage/{order,claims}`) holds no code and no `index.ts`; each slice in it is separate, and slices in one group never import each other either. Create one with `--group=<name>`.",
293
+ component: "- `shared` exposes each component through its own `index.ts` (`shared/ui/button`); import that, not the files inside it.",
294
+ file: "- Inside `shared`, files may be imported directly (`shared/lib/format/currency`); `shared` still never imports a layer above it.",
295
+ tests: "- Test files (`*.spec.ts`, `*.test.ts`, `__tests__/`) may import another slice's internals; upward imports stay forbidden there too."
296
+ },
297
+ ko: {
298
+ heading: "\uC774 \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4\uB294 \uB2E4\uC74C\uB3C4 \uC124\uC815\uD588\uB2E4:",
299
+ groups: "- \uC2AC\uB77C\uC774\uC2A4\uB97C \uBB36\uAE30\uB9CC \uD558\uB294 \uD3F4\uB354(`features/mypage/{order,claims}`)\uC5D0\uB294 \uCF54\uB4DC\uB3C4 `index.ts`\uB3C4 \uB450\uC9C0 \uC54A\uB294\uB2E4. \uADF8 \uC548\uC758 \uC2AC\uB77C\uC774\uC2A4\uB294 \uAC01\uAC01 \uB3C5\uB9BD\uC774\uB77C, \uAC19\uC740 \uADF8\uB8F9 \uC548\uC5D0\uC11C\uB3C4 \uC11C\uB85C import\uD558\uC9C0 \uC54A\uB294\uB2E4. \uADF8\uB8F9 \uC548\uC5D0 \uB9CC\uB4E4 \uB54C\uB294 `--group=<\uC774\uB984>`\uC744 \uC4F4\uB2E4.",
300
+ component: "- `shared`\uB294 \uCEF4\uD3EC\uB10C\uD2B8\uB9C8\uB2E4 \uC790\uAE30 `index.ts`\uB85C \uACF5\uAC1C\uD55C\uB2E4(`shared/ui/button`). \uADF8 index\uB97C import\uD558\uACE0, \uC548\uCABD \uD30C\uC77C\uC5D0\uB294 \uB2FF\uC9C0 \uC54A\uB294\uB2E4.",
301
+ file: "- `shared` \uC548\uC758 \uD30C\uC77C\uC740 \uC9C1\uC811 import\uD574\uB3C4 \uB41C\uB2E4(`shared/lib/format/currency`). \uB2E4\uB9CC `shared`\uB294 \uC5EC\uC804\uD788 \uC704 \uB808\uC774\uC5B4\uB97C import\uD558\uC9C0 \uC54A\uB294\uB2E4.",
302
+ tests: "- \uD14C\uC2A4\uD2B8 \uD30C\uC77C(`*.spec.ts`, `*.test.ts`, `__tests__/`)\uC740 \uB2E4\uB978 \uC2AC\uB77C\uC774\uC2A4\uC758 \uB0B4\uBD80 \uD30C\uC77C\uC744 import\uD574\uB3C4 \uB41C\uB2E4. \uC704 \uB808\uC774\uC5B4 import\uB294 \uD14C\uC2A4\uD2B8\uC5D0\uC11C\uB3C4 \uAE08\uC9C0\uB2E4."
303
+ }
304
+ };
305
+ function buildFsdPolicyNotes(locale, notes) {
306
+ const text = NOTES[locale];
307
+ const lines = [
308
+ ...notes.sliceGroups ? [text.groups] : [],
309
+ ...notes.sharedPublicApi === "component" ? [text.component] : notes.sharedPublicApi === "file" ? [text.file] : [],
310
+ ...notes.testFiles ? [text.tests] : []
311
+ ];
312
+ return lines.length === 0 ? "" : [text.heading, ...lines].join("\n");
313
+ }
314
+
288
315
  // ../template-engine/dist/ai-hosts/ai-hosts.js
289
316
  var AI_HOSTS = [
290
317
  { id: "claude-code", label: "Claude Code", nxAgent: "claude", rulesFile: "CLAUDE.md", reviewProvider: "claude" },
@@ -333,7 +360,13 @@ ${section.body}`).join("\n\n")}
333
360
  }
334
361
  function composeAgentRules(input) {
335
362
  const sectionIds = input.sections ?? resolveDefaultAgentSectionIds(input.teamRules ?? false, input.fsdStructure ?? false);
336
- const sections = sectionIds.map((id) => AGENT_RULE_SECTIONS[input.locale][id]);
363
+ const notes = input.fsdPolicy === void 0 ? "" : buildFsdPolicyNotes(input.locale, input.fsdPolicy);
364
+ const sections = sectionIds.map((id) => {
365
+ const section = AGENT_RULE_SECTIONS[input.locale][id];
366
+ return id === FSD_AGENT_SECTION_ID && notes !== "" ? { ...section, body: `${section.body}
367
+
368
+ ${notes}` } : section;
369
+ });
337
370
  const content = renderSections(sections);
338
371
  return input.files.map((filePath) => ({ filePath, content }));
339
372
  }
@@ -349,41 +382,63 @@ function validateAgentRules(content, extraRequired = []) {
349
382
  }
350
383
 
351
384
  // ../template-engine/dist/agent-rules/marker-block.js
385
+ import { createHash } from "node:crypto";
352
386
  var AGENT_RULES_BLOCK_START = "<!-- nx-archweave:agent-rules start -->";
353
387
  var AGENT_RULES_BLOCK_END = "<!-- nx-archweave:agent-rules end -->";
388
+ var START_MARKER = /<!-- nx-archweave:agent-rules start(?: hash=([0-9a-f]{12}))? -->/g;
389
+ function normalizeForHash(text) {
390
+ return text.replace(/\r\n/g, "\n").replace(/[ \t]+$/gm, "");
391
+ }
392
+ function hashOf(body) {
393
+ return createHash("sha256").update(normalizeForHash(body)).digest("hex").slice(0, 12);
394
+ }
395
+ function withFinalNewline(body) {
396
+ return body.endsWith("\n") ? body : `${body}
397
+ `;
398
+ }
354
399
  function renderAgentRulesBlock(body, eol = "\n") {
355
- const lines = `${AGENT_RULES_BLOCK_START}
356
- ${body.endsWith("\n") ? body : `${body}
357
- `}${AGENT_RULES_BLOCK_END}`;
400
+ const content = withFinalNewline(normalizeForHash(body));
401
+ const lines = `<!-- nx-archweave:agent-rules start hash=${hashOf(content)} -->
402
+ ${content}${AGENT_RULES_BLOCK_END}`;
358
403
  return eol === "\n" ? lines : lines.replace(/\r?\n/g, eol);
359
404
  }
360
405
  function countOf(text, needle) {
361
406
  return text.split(needle).length - 1;
362
407
  }
363
- function applyAgentRulesBlock(existing, body) {
408
+ function applyAgentRulesBlock(existing, body, options = {}) {
364
409
  if (existing === null || existing.length === 0)
365
410
  return { kind: "create", text: `${renderAgentRulesBlock(body)}
366
411
  ` };
367
412
  const eol = existing.includes("\r\n") ? "\r\n" : "\n";
368
413
  const block = renderAgentRulesBlock(body, eol);
369
- const starts = countOf(existing, AGENT_RULES_BLOCK_START);
414
+ const starts = [...existing.matchAll(START_MARKER)];
370
415
  const ends = countOf(existing, AGENT_RULES_BLOCK_END);
371
- if (starts === 0 && ends === 0) {
416
+ if (starts.length === 0 && ends === 0) {
372
417
  const head = existing.endsWith("\n") ? existing : `${existing}${eol}`;
373
418
  return { kind: "append", text: `${head}${eol}${block}${eol}` };
374
419
  }
375
- if (starts !== 1 || ends !== 1) {
420
+ if (starts.length !== 1 || ends !== 1) {
376
421
  return {
377
422
  kind: "unrecognized",
378
- reason: `expected one ${AGENT_RULES_BLOCK_START} \u2026 ${AGENT_RULES_BLOCK_END} pair, found ${starts} start and ${ends} end marker(s)`
423
+ reason: `expected one ${AGENT_RULES_BLOCK_START} \u2026 ${AGENT_RULES_BLOCK_END} pair, found ${starts.length} start and ${ends} end marker(s)`
379
424
  };
380
425
  }
381
- const start = existing.indexOf(AGENT_RULES_BLOCK_START);
426
+ const startMatch = starts[0];
427
+ const start = startMatch.index ?? 0;
382
428
  const end = existing.indexOf(AGENT_RULES_BLOCK_END);
383
429
  if (end < start)
384
430
  return { kind: "unrecognized", reason: "the end marker comes before the start marker" };
385
431
  const text = existing.slice(0, start) + block + existing.slice(end + AGENT_RULES_BLOCK_END.length);
386
- return text === existing ? { kind: "unchanged" } : { kind: "replace", text };
432
+ if (text === existing)
433
+ return { kind: "unchanged" };
434
+ const bodyStart = start + startMatch[0].length + (existing.startsWith("\r\n", start + startMatch[0].length) ? 2 : 1);
435
+ const existingBody = normalizeForHash(existing.slice(bodyStart, end));
436
+ const generatedBody = withFinalNewline(normalizeForHash(body));
437
+ const recordedHash = startMatch[1];
438
+ const untouched = recordedHash !== void 0 ? hashOf(existingBody) === recordedHash : existingBody === generatedBody;
439
+ if (!untouched && options.overwrite !== true)
440
+ return { kind: "user-modified", existingBody, generatedBody };
441
+ return { kind: "replace", text };
387
442
  }
388
443
 
389
444
  // src/generators/shared/dry-run.ts
@@ -391,8 +446,933 @@ function resolveDryRun(options) {
391
446
  return process.env["NX_DRY_RUN"] === "true" || (options.dryRun ?? false);
392
447
  }
393
448
 
394
- // src/generators/shared/toolkit-config-file.ts
395
- var TOOLKIT_CONFIG_PATH = "toolkit.config.json";
449
+ // ../../node_modules/.pnpm/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/scanner.js
450
+ function createScanner(text, ignoreTrivia = false) {
451
+ const len = text.length;
452
+ let pos = 0, value = "", tokenOffset = 0, token = 16, lineNumber = 0, lineStartOffset = 0, tokenLineStartOffset = 0, prevTokenLineStartOffset = 0, scanError = 0;
453
+ function scanHexDigits(count, exact) {
454
+ let digits = 0;
455
+ let value2 = 0;
456
+ while (digits < count || !exact) {
457
+ let ch = text.charCodeAt(pos);
458
+ if (ch >= 48 && ch <= 57) {
459
+ value2 = value2 * 16 + ch - 48;
460
+ } else if (ch >= 65 && ch <= 70) {
461
+ value2 = value2 * 16 + ch - 65 + 10;
462
+ } else if (ch >= 97 && ch <= 102) {
463
+ value2 = value2 * 16 + ch - 97 + 10;
464
+ } else {
465
+ break;
466
+ }
467
+ pos++;
468
+ digits++;
469
+ }
470
+ if (digits < count) {
471
+ value2 = -1;
472
+ }
473
+ return value2;
474
+ }
475
+ function setPosition(newPosition) {
476
+ pos = newPosition;
477
+ value = "";
478
+ tokenOffset = 0;
479
+ token = 16;
480
+ scanError = 0;
481
+ }
482
+ function scanNumber() {
483
+ let start = pos;
484
+ if (text.charCodeAt(pos) === 48) {
485
+ pos++;
486
+ } else {
487
+ pos++;
488
+ while (pos < text.length && isDigit(text.charCodeAt(pos))) {
489
+ pos++;
490
+ }
491
+ }
492
+ if (pos < text.length && text.charCodeAt(pos) === 46) {
493
+ pos++;
494
+ if (pos < text.length && isDigit(text.charCodeAt(pos))) {
495
+ pos++;
496
+ while (pos < text.length && isDigit(text.charCodeAt(pos))) {
497
+ pos++;
498
+ }
499
+ } else {
500
+ scanError = 3;
501
+ return text.substring(start, pos);
502
+ }
503
+ }
504
+ let end = pos;
505
+ if (pos < text.length && (text.charCodeAt(pos) === 69 || text.charCodeAt(pos) === 101)) {
506
+ pos++;
507
+ if (pos < text.length && text.charCodeAt(pos) === 43 || text.charCodeAt(pos) === 45) {
508
+ pos++;
509
+ }
510
+ if (pos < text.length && isDigit(text.charCodeAt(pos))) {
511
+ pos++;
512
+ while (pos < text.length && isDigit(text.charCodeAt(pos))) {
513
+ pos++;
514
+ }
515
+ end = pos;
516
+ } else {
517
+ scanError = 3;
518
+ }
519
+ }
520
+ return text.substring(start, end);
521
+ }
522
+ function scanString() {
523
+ let result = "", start = pos;
524
+ while (true) {
525
+ if (pos >= len) {
526
+ result += text.substring(start, pos);
527
+ scanError = 2;
528
+ break;
529
+ }
530
+ const ch = text.charCodeAt(pos);
531
+ if (ch === 34) {
532
+ result += text.substring(start, pos);
533
+ pos++;
534
+ break;
535
+ }
536
+ if (ch === 92) {
537
+ result += text.substring(start, pos);
538
+ pos++;
539
+ if (pos >= len) {
540
+ scanError = 2;
541
+ break;
542
+ }
543
+ const ch2 = text.charCodeAt(pos++);
544
+ switch (ch2) {
545
+ case 34:
546
+ result += '"';
547
+ break;
548
+ case 92:
549
+ result += "\\";
550
+ break;
551
+ case 47:
552
+ result += "/";
553
+ break;
554
+ case 98:
555
+ result += "\b";
556
+ break;
557
+ case 102:
558
+ result += "\f";
559
+ break;
560
+ case 110:
561
+ result += "\n";
562
+ break;
563
+ case 114:
564
+ result += "\r";
565
+ break;
566
+ case 116:
567
+ result += " ";
568
+ break;
569
+ case 117:
570
+ const ch3 = scanHexDigits(4, true);
571
+ if (ch3 >= 0) {
572
+ result += String.fromCharCode(ch3);
573
+ } else {
574
+ scanError = 4;
575
+ }
576
+ break;
577
+ default:
578
+ scanError = 5;
579
+ }
580
+ start = pos;
581
+ continue;
582
+ }
583
+ if (ch >= 0 && ch <= 31) {
584
+ if (isLineBreak(ch)) {
585
+ result += text.substring(start, pos);
586
+ scanError = 2;
587
+ break;
588
+ } else {
589
+ scanError = 6;
590
+ }
591
+ }
592
+ pos++;
593
+ }
594
+ return result;
595
+ }
596
+ function scanNext() {
597
+ value = "";
598
+ scanError = 0;
599
+ tokenOffset = pos;
600
+ lineStartOffset = lineNumber;
601
+ prevTokenLineStartOffset = tokenLineStartOffset;
602
+ if (pos >= len) {
603
+ tokenOffset = len;
604
+ return token = 17;
605
+ }
606
+ let code = text.charCodeAt(pos);
607
+ if (isWhiteSpace(code)) {
608
+ do {
609
+ pos++;
610
+ value += String.fromCharCode(code);
611
+ code = text.charCodeAt(pos);
612
+ } while (isWhiteSpace(code));
613
+ return token = 15;
614
+ }
615
+ if (isLineBreak(code)) {
616
+ pos++;
617
+ value += String.fromCharCode(code);
618
+ if (code === 13 && text.charCodeAt(pos) === 10) {
619
+ pos++;
620
+ value += "\n";
621
+ }
622
+ lineNumber++;
623
+ tokenLineStartOffset = pos;
624
+ return token = 14;
625
+ }
626
+ switch (code) {
627
+ // tokens: []{}:,
628
+ case 123:
629
+ pos++;
630
+ return token = 1;
631
+ case 125:
632
+ pos++;
633
+ return token = 2;
634
+ case 91:
635
+ pos++;
636
+ return token = 3;
637
+ case 93:
638
+ pos++;
639
+ return token = 4;
640
+ case 58:
641
+ pos++;
642
+ return token = 6;
643
+ case 44:
644
+ pos++;
645
+ return token = 5;
646
+ // strings
647
+ case 34:
648
+ pos++;
649
+ value = scanString();
650
+ return token = 10;
651
+ // comments
652
+ case 47:
653
+ const start = pos - 1;
654
+ if (text.charCodeAt(pos + 1) === 47) {
655
+ pos += 2;
656
+ while (pos < len) {
657
+ if (isLineBreak(text.charCodeAt(pos))) {
658
+ break;
659
+ }
660
+ pos++;
661
+ }
662
+ value = text.substring(start, pos);
663
+ return token = 12;
664
+ }
665
+ if (text.charCodeAt(pos + 1) === 42) {
666
+ pos += 2;
667
+ const safeLength = len - 1;
668
+ let commentClosed = false;
669
+ while (pos < safeLength) {
670
+ const ch = text.charCodeAt(pos);
671
+ if (ch === 42 && text.charCodeAt(pos + 1) === 47) {
672
+ pos += 2;
673
+ commentClosed = true;
674
+ break;
675
+ }
676
+ pos++;
677
+ if (isLineBreak(ch)) {
678
+ if (ch === 13 && text.charCodeAt(pos) === 10) {
679
+ pos++;
680
+ }
681
+ lineNumber++;
682
+ tokenLineStartOffset = pos;
683
+ }
684
+ }
685
+ if (!commentClosed) {
686
+ pos++;
687
+ scanError = 1;
688
+ }
689
+ value = text.substring(start, pos);
690
+ return token = 13;
691
+ }
692
+ value += String.fromCharCode(code);
693
+ pos++;
694
+ return token = 16;
695
+ // numbers
696
+ case 45:
697
+ value += String.fromCharCode(code);
698
+ pos++;
699
+ if (pos === len || !isDigit(text.charCodeAt(pos))) {
700
+ return token = 16;
701
+ }
702
+ // found a minus, followed by a number so
703
+ // we fall through to proceed with scanning
704
+ // numbers
705
+ case 48:
706
+ case 49:
707
+ case 50:
708
+ case 51:
709
+ case 52:
710
+ case 53:
711
+ case 54:
712
+ case 55:
713
+ case 56:
714
+ case 57:
715
+ value += scanNumber();
716
+ return token = 11;
717
+ // literals and unknown symbols
718
+ default:
719
+ while (pos < len && isUnknownContentCharacter(code)) {
720
+ pos++;
721
+ code = text.charCodeAt(pos);
722
+ }
723
+ if (tokenOffset !== pos) {
724
+ value = text.substring(tokenOffset, pos);
725
+ switch (value) {
726
+ case "true":
727
+ return token = 8;
728
+ case "false":
729
+ return token = 9;
730
+ case "null":
731
+ return token = 7;
732
+ }
733
+ return token = 16;
734
+ }
735
+ value += String.fromCharCode(code);
736
+ pos++;
737
+ return token = 16;
738
+ }
739
+ }
740
+ function isUnknownContentCharacter(code) {
741
+ if (isWhiteSpace(code) || isLineBreak(code)) {
742
+ return false;
743
+ }
744
+ switch (code) {
745
+ case 125:
746
+ case 93:
747
+ case 123:
748
+ case 91:
749
+ case 34:
750
+ case 58:
751
+ case 44:
752
+ case 47:
753
+ return false;
754
+ }
755
+ return true;
756
+ }
757
+ function scanNextNonTrivia() {
758
+ let result;
759
+ do {
760
+ result = scanNext();
761
+ } while (result >= 12 && result <= 15);
762
+ return result;
763
+ }
764
+ return {
765
+ setPosition,
766
+ getPosition: () => pos,
767
+ scan: ignoreTrivia ? scanNextNonTrivia : scanNext,
768
+ getToken: () => token,
769
+ getTokenValue: () => value,
770
+ getTokenOffset: () => tokenOffset,
771
+ getTokenLength: () => pos - tokenOffset,
772
+ getTokenStartLine: () => lineStartOffset,
773
+ getTokenStartCharacter: () => tokenOffset - prevTokenLineStartOffset,
774
+ getTokenError: () => scanError
775
+ };
776
+ }
777
+ function isWhiteSpace(ch) {
778
+ return ch === 32 || ch === 9;
779
+ }
780
+ function isLineBreak(ch) {
781
+ return ch === 10 || ch === 13;
782
+ }
783
+ function isDigit(ch) {
784
+ return ch >= 48 && ch <= 57;
785
+ }
786
+ var CharacterCodes;
787
+ (function(CharacterCodes2) {
788
+ CharacterCodes2[CharacterCodes2["lineFeed"] = 10] = "lineFeed";
789
+ CharacterCodes2[CharacterCodes2["carriageReturn"] = 13] = "carriageReturn";
790
+ CharacterCodes2[CharacterCodes2["space"] = 32] = "space";
791
+ CharacterCodes2[CharacterCodes2["_0"] = 48] = "_0";
792
+ CharacterCodes2[CharacterCodes2["_1"] = 49] = "_1";
793
+ CharacterCodes2[CharacterCodes2["_2"] = 50] = "_2";
794
+ CharacterCodes2[CharacterCodes2["_3"] = 51] = "_3";
795
+ CharacterCodes2[CharacterCodes2["_4"] = 52] = "_4";
796
+ CharacterCodes2[CharacterCodes2["_5"] = 53] = "_5";
797
+ CharacterCodes2[CharacterCodes2["_6"] = 54] = "_6";
798
+ CharacterCodes2[CharacterCodes2["_7"] = 55] = "_7";
799
+ CharacterCodes2[CharacterCodes2["_8"] = 56] = "_8";
800
+ CharacterCodes2[CharacterCodes2["_9"] = 57] = "_9";
801
+ CharacterCodes2[CharacterCodes2["a"] = 97] = "a";
802
+ CharacterCodes2[CharacterCodes2["b"] = 98] = "b";
803
+ CharacterCodes2[CharacterCodes2["c"] = 99] = "c";
804
+ CharacterCodes2[CharacterCodes2["d"] = 100] = "d";
805
+ CharacterCodes2[CharacterCodes2["e"] = 101] = "e";
806
+ CharacterCodes2[CharacterCodes2["f"] = 102] = "f";
807
+ CharacterCodes2[CharacterCodes2["g"] = 103] = "g";
808
+ CharacterCodes2[CharacterCodes2["h"] = 104] = "h";
809
+ CharacterCodes2[CharacterCodes2["i"] = 105] = "i";
810
+ CharacterCodes2[CharacterCodes2["j"] = 106] = "j";
811
+ CharacterCodes2[CharacterCodes2["k"] = 107] = "k";
812
+ CharacterCodes2[CharacterCodes2["l"] = 108] = "l";
813
+ CharacterCodes2[CharacterCodes2["m"] = 109] = "m";
814
+ CharacterCodes2[CharacterCodes2["n"] = 110] = "n";
815
+ CharacterCodes2[CharacterCodes2["o"] = 111] = "o";
816
+ CharacterCodes2[CharacterCodes2["p"] = 112] = "p";
817
+ CharacterCodes2[CharacterCodes2["q"] = 113] = "q";
818
+ CharacterCodes2[CharacterCodes2["r"] = 114] = "r";
819
+ CharacterCodes2[CharacterCodes2["s"] = 115] = "s";
820
+ CharacterCodes2[CharacterCodes2["t"] = 116] = "t";
821
+ CharacterCodes2[CharacterCodes2["u"] = 117] = "u";
822
+ CharacterCodes2[CharacterCodes2["v"] = 118] = "v";
823
+ CharacterCodes2[CharacterCodes2["w"] = 119] = "w";
824
+ CharacterCodes2[CharacterCodes2["x"] = 120] = "x";
825
+ CharacterCodes2[CharacterCodes2["y"] = 121] = "y";
826
+ CharacterCodes2[CharacterCodes2["z"] = 122] = "z";
827
+ CharacterCodes2[CharacterCodes2["A"] = 65] = "A";
828
+ CharacterCodes2[CharacterCodes2["B"] = 66] = "B";
829
+ CharacterCodes2[CharacterCodes2["C"] = 67] = "C";
830
+ CharacterCodes2[CharacterCodes2["D"] = 68] = "D";
831
+ CharacterCodes2[CharacterCodes2["E"] = 69] = "E";
832
+ CharacterCodes2[CharacterCodes2["F"] = 70] = "F";
833
+ CharacterCodes2[CharacterCodes2["G"] = 71] = "G";
834
+ CharacterCodes2[CharacterCodes2["H"] = 72] = "H";
835
+ CharacterCodes2[CharacterCodes2["I"] = 73] = "I";
836
+ CharacterCodes2[CharacterCodes2["J"] = 74] = "J";
837
+ CharacterCodes2[CharacterCodes2["K"] = 75] = "K";
838
+ CharacterCodes2[CharacterCodes2["L"] = 76] = "L";
839
+ CharacterCodes2[CharacterCodes2["M"] = 77] = "M";
840
+ CharacterCodes2[CharacterCodes2["N"] = 78] = "N";
841
+ CharacterCodes2[CharacterCodes2["O"] = 79] = "O";
842
+ CharacterCodes2[CharacterCodes2["P"] = 80] = "P";
843
+ CharacterCodes2[CharacterCodes2["Q"] = 81] = "Q";
844
+ CharacterCodes2[CharacterCodes2["R"] = 82] = "R";
845
+ CharacterCodes2[CharacterCodes2["S"] = 83] = "S";
846
+ CharacterCodes2[CharacterCodes2["T"] = 84] = "T";
847
+ CharacterCodes2[CharacterCodes2["U"] = 85] = "U";
848
+ CharacterCodes2[CharacterCodes2["V"] = 86] = "V";
849
+ CharacterCodes2[CharacterCodes2["W"] = 87] = "W";
850
+ CharacterCodes2[CharacterCodes2["X"] = 88] = "X";
851
+ CharacterCodes2[CharacterCodes2["Y"] = 89] = "Y";
852
+ CharacterCodes2[CharacterCodes2["Z"] = 90] = "Z";
853
+ CharacterCodes2[CharacterCodes2["asterisk"] = 42] = "asterisk";
854
+ CharacterCodes2[CharacterCodes2["backslash"] = 92] = "backslash";
855
+ CharacterCodes2[CharacterCodes2["closeBrace"] = 125] = "closeBrace";
856
+ CharacterCodes2[CharacterCodes2["closeBracket"] = 93] = "closeBracket";
857
+ CharacterCodes2[CharacterCodes2["colon"] = 58] = "colon";
858
+ CharacterCodes2[CharacterCodes2["comma"] = 44] = "comma";
859
+ CharacterCodes2[CharacterCodes2["dot"] = 46] = "dot";
860
+ CharacterCodes2[CharacterCodes2["doubleQuote"] = 34] = "doubleQuote";
861
+ CharacterCodes2[CharacterCodes2["minus"] = 45] = "minus";
862
+ CharacterCodes2[CharacterCodes2["openBrace"] = 123] = "openBrace";
863
+ CharacterCodes2[CharacterCodes2["openBracket"] = 91] = "openBracket";
864
+ CharacterCodes2[CharacterCodes2["plus"] = 43] = "plus";
865
+ CharacterCodes2[CharacterCodes2["slash"] = 47] = "slash";
866
+ CharacterCodes2[CharacterCodes2["formFeed"] = 12] = "formFeed";
867
+ CharacterCodes2[CharacterCodes2["tab"] = 9] = "tab";
868
+ })(CharacterCodes || (CharacterCodes = {}));
869
+
870
+ // ../../node_modules/.pnpm/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/string-intern.js
871
+ var cachedSpaces = new Array(20).fill(0).map((_, index) => {
872
+ return " ".repeat(index);
873
+ });
874
+ var maxCachedValues = 200;
875
+ var cachedBreakLinesWithSpaces = {
876
+ " ": {
877
+ "\n": new Array(maxCachedValues).fill(0).map((_, index) => {
878
+ return "\n" + " ".repeat(index);
879
+ }),
880
+ "\r": new Array(maxCachedValues).fill(0).map((_, index) => {
881
+ return "\r" + " ".repeat(index);
882
+ }),
883
+ "\r\n": new Array(maxCachedValues).fill(0).map((_, index) => {
884
+ return "\r\n" + " ".repeat(index);
885
+ })
886
+ },
887
+ " ": {
888
+ "\n": new Array(maxCachedValues).fill(0).map((_, index) => {
889
+ return "\n" + " ".repeat(index);
890
+ }),
891
+ "\r": new Array(maxCachedValues).fill(0).map((_, index) => {
892
+ return "\r" + " ".repeat(index);
893
+ }),
894
+ "\r\n": new Array(maxCachedValues).fill(0).map((_, index) => {
895
+ return "\r\n" + " ".repeat(index);
896
+ })
897
+ }
898
+ };
899
+
900
+ // ../../node_modules/.pnpm/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/parser.js
901
+ var ParseOptions;
902
+ (function(ParseOptions2) {
903
+ ParseOptions2.DEFAULT = {
904
+ allowTrailingComma: false
905
+ };
906
+ })(ParseOptions || (ParseOptions = {}));
907
+ function parseTree(text, errors = [], options = ParseOptions.DEFAULT) {
908
+ let currentParent = { type: "array", offset: -1, length: -1, children: [], parent: void 0 };
909
+ function ensurePropertyComplete(endOffset) {
910
+ if (currentParent.type === "property") {
911
+ currentParent.length = endOffset - currentParent.offset;
912
+ currentParent = currentParent.parent;
913
+ }
914
+ }
915
+ function onValue(valueNode) {
916
+ currentParent.children.push(valueNode);
917
+ return valueNode;
918
+ }
919
+ const visitor = {
920
+ onObjectBegin: (offset) => {
921
+ currentParent = onValue({ type: "object", offset, length: -1, parent: currentParent, children: [] });
922
+ },
923
+ onObjectProperty: (name, offset, length) => {
924
+ currentParent = onValue({ type: "property", offset, length: -1, parent: currentParent, children: [] });
925
+ currentParent.children.push({ type: "string", value: name, offset, length, parent: currentParent });
926
+ },
927
+ onObjectEnd: (offset, length) => {
928
+ ensurePropertyComplete(offset + length);
929
+ currentParent.length = offset + length - currentParent.offset;
930
+ currentParent = currentParent.parent;
931
+ ensurePropertyComplete(offset + length);
932
+ },
933
+ onArrayBegin: (offset, length) => {
934
+ currentParent = onValue({ type: "array", offset, length: -1, parent: currentParent, children: [] });
935
+ },
936
+ onArrayEnd: (offset, length) => {
937
+ currentParent.length = offset + length - currentParent.offset;
938
+ currentParent = currentParent.parent;
939
+ ensurePropertyComplete(offset + length);
940
+ },
941
+ onLiteralValue: (value, offset, length) => {
942
+ onValue({ type: getNodeType(value), offset, length, parent: currentParent, value });
943
+ ensurePropertyComplete(offset + length);
944
+ },
945
+ onSeparator: (sep, offset, length) => {
946
+ if (currentParent.type === "property") {
947
+ if (sep === ":") {
948
+ currentParent.colonOffset = offset;
949
+ } else if (sep === ",") {
950
+ ensurePropertyComplete(offset);
951
+ }
952
+ }
953
+ },
954
+ onError: (error, offset, length) => {
955
+ errors.push({ error, offset, length });
956
+ }
957
+ };
958
+ visit(text, visitor, options);
959
+ const result = currentParent.children[0];
960
+ if (result) {
961
+ delete result.parent;
962
+ }
963
+ return result;
964
+ }
965
+ function findNodeAtLocation(root, path) {
966
+ if (!root) {
967
+ return void 0;
968
+ }
969
+ let node = root;
970
+ for (let segment of path) {
971
+ if (typeof segment === "string") {
972
+ if (node.type !== "object" || !Array.isArray(node.children)) {
973
+ return void 0;
974
+ }
975
+ let found = false;
976
+ for (const propertyNode of node.children) {
977
+ if (Array.isArray(propertyNode.children) && propertyNode.children[0].value === segment && propertyNode.children.length === 2) {
978
+ node = propertyNode.children[1];
979
+ found = true;
980
+ break;
981
+ }
982
+ }
983
+ if (!found) {
984
+ return void 0;
985
+ }
986
+ } else {
987
+ const index = segment;
988
+ if (node.type !== "array" || index < 0 || !Array.isArray(node.children) || index >= node.children.length) {
989
+ return void 0;
990
+ }
991
+ node = node.children[index];
992
+ }
993
+ }
994
+ return node;
995
+ }
996
+ function visit(text, visitor, options = ParseOptions.DEFAULT) {
997
+ const _scanner = createScanner(text, false);
998
+ const _jsonPath = [];
999
+ let suppressedCallbacks = 0;
1000
+ function toNoArgVisit(visitFunction) {
1001
+ return visitFunction ? () => suppressedCallbacks === 0 && visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()) : () => true;
1002
+ }
1003
+ function toOneArgVisit(visitFunction) {
1004
+ return visitFunction ? (arg) => suppressedCallbacks === 0 && visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()) : () => true;
1005
+ }
1006
+ function toOneArgVisitWithPath(visitFunction) {
1007
+ return visitFunction ? (arg) => suppressedCallbacks === 0 && visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter(), () => _jsonPath.slice()) : () => true;
1008
+ }
1009
+ function toBeginVisit(visitFunction) {
1010
+ return visitFunction ? () => {
1011
+ if (suppressedCallbacks > 0) {
1012
+ suppressedCallbacks++;
1013
+ } else {
1014
+ let cbReturn = visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter(), () => _jsonPath.slice());
1015
+ if (cbReturn === false) {
1016
+ suppressedCallbacks = 1;
1017
+ }
1018
+ }
1019
+ } : () => true;
1020
+ }
1021
+ function toEndVisit(visitFunction) {
1022
+ return visitFunction ? () => {
1023
+ if (suppressedCallbacks > 0) {
1024
+ suppressedCallbacks--;
1025
+ }
1026
+ if (suppressedCallbacks === 0) {
1027
+ visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter());
1028
+ }
1029
+ } : () => true;
1030
+ }
1031
+ const onObjectBegin = toBeginVisit(visitor.onObjectBegin), onObjectProperty = toOneArgVisitWithPath(visitor.onObjectProperty), onObjectEnd = toEndVisit(visitor.onObjectEnd), onArrayBegin = toBeginVisit(visitor.onArrayBegin), onArrayEnd = toEndVisit(visitor.onArrayEnd), onLiteralValue = toOneArgVisitWithPath(visitor.onLiteralValue), onSeparator = toOneArgVisit(visitor.onSeparator), onComment = toNoArgVisit(visitor.onComment), onError = toOneArgVisit(visitor.onError);
1032
+ const disallowComments = options && options.disallowComments;
1033
+ const allowTrailingComma = options && options.allowTrailingComma;
1034
+ function scanNext() {
1035
+ while (true) {
1036
+ const token = _scanner.scan();
1037
+ switch (_scanner.getTokenError()) {
1038
+ case 4:
1039
+ handleError(
1040
+ 14
1041
+ /* ParseErrorCode.InvalidUnicode */
1042
+ );
1043
+ break;
1044
+ case 5:
1045
+ handleError(
1046
+ 15
1047
+ /* ParseErrorCode.InvalidEscapeCharacter */
1048
+ );
1049
+ break;
1050
+ case 3:
1051
+ handleError(
1052
+ 13
1053
+ /* ParseErrorCode.UnexpectedEndOfNumber */
1054
+ );
1055
+ break;
1056
+ case 1:
1057
+ if (!disallowComments) {
1058
+ handleError(
1059
+ 11
1060
+ /* ParseErrorCode.UnexpectedEndOfComment */
1061
+ );
1062
+ }
1063
+ break;
1064
+ case 2:
1065
+ handleError(
1066
+ 12
1067
+ /* ParseErrorCode.UnexpectedEndOfString */
1068
+ );
1069
+ break;
1070
+ case 6:
1071
+ handleError(
1072
+ 16
1073
+ /* ParseErrorCode.InvalidCharacter */
1074
+ );
1075
+ break;
1076
+ }
1077
+ switch (token) {
1078
+ case 12:
1079
+ case 13:
1080
+ if (disallowComments) {
1081
+ handleError(
1082
+ 10
1083
+ /* ParseErrorCode.InvalidCommentToken */
1084
+ );
1085
+ } else {
1086
+ onComment();
1087
+ }
1088
+ break;
1089
+ case 16:
1090
+ handleError(
1091
+ 1
1092
+ /* ParseErrorCode.InvalidSymbol */
1093
+ );
1094
+ break;
1095
+ case 15:
1096
+ case 14:
1097
+ break;
1098
+ default:
1099
+ return token;
1100
+ }
1101
+ }
1102
+ }
1103
+ function handleError(error, skipUntilAfter = [], skipUntil = []) {
1104
+ onError(error);
1105
+ if (skipUntilAfter.length + skipUntil.length > 0) {
1106
+ let token = _scanner.getToken();
1107
+ while (token !== 17) {
1108
+ if (skipUntilAfter.indexOf(token) !== -1) {
1109
+ scanNext();
1110
+ break;
1111
+ } else if (skipUntil.indexOf(token) !== -1) {
1112
+ break;
1113
+ }
1114
+ token = scanNext();
1115
+ }
1116
+ }
1117
+ }
1118
+ function parseString(isValue) {
1119
+ const value = _scanner.getTokenValue();
1120
+ if (isValue) {
1121
+ onLiteralValue(value);
1122
+ } else {
1123
+ onObjectProperty(value);
1124
+ _jsonPath.push(value);
1125
+ }
1126
+ scanNext();
1127
+ return true;
1128
+ }
1129
+ function parseLiteral() {
1130
+ switch (_scanner.getToken()) {
1131
+ case 11:
1132
+ const tokenValue = _scanner.getTokenValue();
1133
+ let value = Number(tokenValue);
1134
+ if (isNaN(value)) {
1135
+ handleError(
1136
+ 2
1137
+ /* ParseErrorCode.InvalidNumberFormat */
1138
+ );
1139
+ value = 0;
1140
+ }
1141
+ onLiteralValue(value);
1142
+ break;
1143
+ case 7:
1144
+ onLiteralValue(null);
1145
+ break;
1146
+ case 8:
1147
+ onLiteralValue(true);
1148
+ break;
1149
+ case 9:
1150
+ onLiteralValue(false);
1151
+ break;
1152
+ default:
1153
+ return false;
1154
+ }
1155
+ scanNext();
1156
+ return true;
1157
+ }
1158
+ function parseProperty() {
1159
+ if (_scanner.getToken() !== 10) {
1160
+ handleError(3, [], [
1161
+ 2,
1162
+ 5
1163
+ /* SyntaxKind.CommaToken */
1164
+ ]);
1165
+ return false;
1166
+ }
1167
+ parseString(false);
1168
+ if (_scanner.getToken() === 6) {
1169
+ onSeparator(":");
1170
+ scanNext();
1171
+ if (!parseValue()) {
1172
+ handleError(4, [], [
1173
+ 2,
1174
+ 5
1175
+ /* SyntaxKind.CommaToken */
1176
+ ]);
1177
+ }
1178
+ } else {
1179
+ handleError(5, [], [
1180
+ 2,
1181
+ 5
1182
+ /* SyntaxKind.CommaToken */
1183
+ ]);
1184
+ }
1185
+ _jsonPath.pop();
1186
+ return true;
1187
+ }
1188
+ function parseObject() {
1189
+ onObjectBegin();
1190
+ scanNext();
1191
+ let needsComma = false;
1192
+ while (_scanner.getToken() !== 2 && _scanner.getToken() !== 17) {
1193
+ if (_scanner.getToken() === 5) {
1194
+ if (!needsComma) {
1195
+ handleError(4, [], []);
1196
+ }
1197
+ onSeparator(",");
1198
+ scanNext();
1199
+ if (_scanner.getToken() === 2 && allowTrailingComma) {
1200
+ break;
1201
+ }
1202
+ } else if (needsComma) {
1203
+ handleError(6, [], []);
1204
+ }
1205
+ if (!parseProperty()) {
1206
+ handleError(4, [], [
1207
+ 2,
1208
+ 5
1209
+ /* SyntaxKind.CommaToken */
1210
+ ]);
1211
+ }
1212
+ needsComma = true;
1213
+ }
1214
+ onObjectEnd();
1215
+ if (_scanner.getToken() !== 2) {
1216
+ handleError(7, [
1217
+ 2
1218
+ /* SyntaxKind.CloseBraceToken */
1219
+ ], []);
1220
+ } else {
1221
+ scanNext();
1222
+ }
1223
+ return true;
1224
+ }
1225
+ function parseArray() {
1226
+ onArrayBegin();
1227
+ scanNext();
1228
+ let isFirstElement = true;
1229
+ let needsComma = false;
1230
+ while (_scanner.getToken() !== 4 && _scanner.getToken() !== 17) {
1231
+ if (_scanner.getToken() === 5) {
1232
+ if (!needsComma) {
1233
+ handleError(4, [], []);
1234
+ }
1235
+ onSeparator(",");
1236
+ scanNext();
1237
+ if (_scanner.getToken() === 4 && allowTrailingComma) {
1238
+ break;
1239
+ }
1240
+ } else if (needsComma) {
1241
+ handleError(6, [], []);
1242
+ }
1243
+ if (isFirstElement) {
1244
+ _jsonPath.push(0);
1245
+ isFirstElement = false;
1246
+ } else {
1247
+ _jsonPath[_jsonPath.length - 1]++;
1248
+ }
1249
+ if (!parseValue()) {
1250
+ handleError(4, [], [
1251
+ 4,
1252
+ 5
1253
+ /* SyntaxKind.CommaToken */
1254
+ ]);
1255
+ }
1256
+ needsComma = true;
1257
+ }
1258
+ onArrayEnd();
1259
+ if (!isFirstElement) {
1260
+ _jsonPath.pop();
1261
+ }
1262
+ if (_scanner.getToken() !== 4) {
1263
+ handleError(8, [
1264
+ 4
1265
+ /* SyntaxKind.CloseBracketToken */
1266
+ ], []);
1267
+ } else {
1268
+ scanNext();
1269
+ }
1270
+ return true;
1271
+ }
1272
+ function parseValue() {
1273
+ switch (_scanner.getToken()) {
1274
+ case 3:
1275
+ return parseArray();
1276
+ case 1:
1277
+ return parseObject();
1278
+ case 10:
1279
+ return parseString(true);
1280
+ default:
1281
+ return parseLiteral();
1282
+ }
1283
+ }
1284
+ scanNext();
1285
+ if (_scanner.getToken() === 17) {
1286
+ if (options.allowEmptyContent) {
1287
+ return true;
1288
+ }
1289
+ handleError(4, [], []);
1290
+ return false;
1291
+ }
1292
+ if (!parseValue()) {
1293
+ handleError(4, [], []);
1294
+ return false;
1295
+ }
1296
+ if (_scanner.getToken() !== 17) {
1297
+ handleError(9, [], []);
1298
+ }
1299
+ return true;
1300
+ }
1301
+ function getNodeType(value) {
1302
+ switch (typeof value) {
1303
+ case "boolean":
1304
+ return "boolean";
1305
+ case "number":
1306
+ return "number";
1307
+ case "string":
1308
+ return "string";
1309
+ case "object": {
1310
+ if (!value) {
1311
+ return "null";
1312
+ } else if (Array.isArray(value)) {
1313
+ return "array";
1314
+ }
1315
+ return "object";
1316
+ }
1317
+ default:
1318
+ return "null";
1319
+ }
1320
+ }
1321
+
1322
+ // ../../node_modules/.pnpm/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/main.js
1323
+ var ScanError;
1324
+ (function(ScanError2) {
1325
+ ScanError2[ScanError2["None"] = 0] = "None";
1326
+ ScanError2[ScanError2["UnexpectedEndOfComment"] = 1] = "UnexpectedEndOfComment";
1327
+ ScanError2[ScanError2["UnexpectedEndOfString"] = 2] = "UnexpectedEndOfString";
1328
+ ScanError2[ScanError2["UnexpectedEndOfNumber"] = 3] = "UnexpectedEndOfNumber";
1329
+ ScanError2[ScanError2["InvalidUnicode"] = 4] = "InvalidUnicode";
1330
+ ScanError2[ScanError2["InvalidEscapeCharacter"] = 5] = "InvalidEscapeCharacter";
1331
+ ScanError2[ScanError2["InvalidCharacter"] = 6] = "InvalidCharacter";
1332
+ })(ScanError || (ScanError = {}));
1333
+ var SyntaxKind;
1334
+ (function(SyntaxKind2) {
1335
+ SyntaxKind2[SyntaxKind2["OpenBraceToken"] = 1] = "OpenBraceToken";
1336
+ SyntaxKind2[SyntaxKind2["CloseBraceToken"] = 2] = "CloseBraceToken";
1337
+ SyntaxKind2[SyntaxKind2["OpenBracketToken"] = 3] = "OpenBracketToken";
1338
+ SyntaxKind2[SyntaxKind2["CloseBracketToken"] = 4] = "CloseBracketToken";
1339
+ SyntaxKind2[SyntaxKind2["CommaToken"] = 5] = "CommaToken";
1340
+ SyntaxKind2[SyntaxKind2["ColonToken"] = 6] = "ColonToken";
1341
+ SyntaxKind2[SyntaxKind2["NullKeyword"] = 7] = "NullKeyword";
1342
+ SyntaxKind2[SyntaxKind2["TrueKeyword"] = 8] = "TrueKeyword";
1343
+ SyntaxKind2[SyntaxKind2["FalseKeyword"] = 9] = "FalseKeyword";
1344
+ SyntaxKind2[SyntaxKind2["StringLiteral"] = 10] = "StringLiteral";
1345
+ SyntaxKind2[SyntaxKind2["NumericLiteral"] = 11] = "NumericLiteral";
1346
+ SyntaxKind2[SyntaxKind2["LineCommentTrivia"] = 12] = "LineCommentTrivia";
1347
+ SyntaxKind2[SyntaxKind2["BlockCommentTrivia"] = 13] = "BlockCommentTrivia";
1348
+ SyntaxKind2[SyntaxKind2["LineBreakTrivia"] = 14] = "LineBreakTrivia";
1349
+ SyntaxKind2[SyntaxKind2["Trivia"] = 15] = "Trivia";
1350
+ SyntaxKind2[SyntaxKind2["Unknown"] = 16] = "Unknown";
1351
+ SyntaxKind2[SyntaxKind2["EOF"] = 17] = "EOF";
1352
+ })(SyntaxKind || (SyntaxKind = {}));
1353
+ var parseTree2 = parseTree;
1354
+ var findNodeAtLocation2 = findNodeAtLocation;
1355
+ var ParseErrorCode;
1356
+ (function(ParseErrorCode2) {
1357
+ ParseErrorCode2[ParseErrorCode2["InvalidSymbol"] = 1] = "InvalidSymbol";
1358
+ ParseErrorCode2[ParseErrorCode2["InvalidNumberFormat"] = 2] = "InvalidNumberFormat";
1359
+ ParseErrorCode2[ParseErrorCode2["PropertyNameExpected"] = 3] = "PropertyNameExpected";
1360
+ ParseErrorCode2[ParseErrorCode2["ValueExpected"] = 4] = "ValueExpected";
1361
+ ParseErrorCode2[ParseErrorCode2["ColonExpected"] = 5] = "ColonExpected";
1362
+ ParseErrorCode2[ParseErrorCode2["CommaExpected"] = 6] = "CommaExpected";
1363
+ ParseErrorCode2[ParseErrorCode2["CloseBraceExpected"] = 7] = "CloseBraceExpected";
1364
+ ParseErrorCode2[ParseErrorCode2["CloseBracketExpected"] = 8] = "CloseBracketExpected";
1365
+ ParseErrorCode2[ParseErrorCode2["EndOfFileExpected"] = 9] = "EndOfFileExpected";
1366
+ ParseErrorCode2[ParseErrorCode2["InvalidCommentToken"] = 10] = "InvalidCommentToken";
1367
+ ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfComment"] = 11] = "UnexpectedEndOfComment";
1368
+ ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfString"] = 12] = "UnexpectedEndOfString";
1369
+ ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfNumber"] = 13] = "UnexpectedEndOfNumber";
1370
+ ParseErrorCode2[ParseErrorCode2["InvalidUnicode"] = 14] = "InvalidUnicode";
1371
+ ParseErrorCode2[ParseErrorCode2["InvalidEscapeCharacter"] = 15] = "InvalidEscapeCharacter";
1372
+ ParseErrorCode2[ParseErrorCode2["InvalidCharacter"] = 16] = "InvalidCharacter";
1373
+ })(ParseErrorCode || (ParseErrorCode = {}));
1374
+
1375
+ // src/generators/shared/json-edit.ts
396
1376
  function detectIndent(raw) {
397
1377
  for (const line of raw.split("\n")) {
398
1378
  const match = /^(\t+| +)/.exec(line);
@@ -400,6 +1380,81 @@ function detectIndent(raw) {
400
1380
  }
401
1381
  return " ";
402
1382
  }
1383
+ function styleOf(raw) {
1384
+ return { eol: raw.includes("\r\n") ? "\r\n" : "\n", unit: detectIndent(raw) };
1385
+ }
1386
+ function lineIndentAt(raw, offset) {
1387
+ const lineStart = raw.lastIndexOf("\n", offset - 1) + 1;
1388
+ return /^[ \t]*/.exec(raw.slice(lineStart))?.[0] ?? "";
1389
+ }
1390
+ function isMultiline(raw, node) {
1391
+ return raw.slice(node.offset, node.offset + node.length).includes("\n");
1392
+ }
1393
+ function isPrimitive(value) {
1394
+ return value === null || ["string", "number", "boolean"].includes(typeof value);
1395
+ }
1396
+ function renderValue(value, indent, style) {
1397
+ if (isPrimitive(value)) return JSON.stringify(value);
1398
+ if (Array.isArray(value)) {
1399
+ if (value.every(isPrimitive)) return `[${value.map((item) => JSON.stringify(item)).join(", ")}]`;
1400
+ const inner2 = `${indent}${style.unit}`;
1401
+ return `[${style.eol}${value.map((item) => `${inner2}${renderValue(item, inner2, style)}`).join(`,${style.eol}`)}${style.eol}${indent}]`;
1402
+ }
1403
+ const entries = Object.entries(value);
1404
+ if (entries.length === 0) return "{}";
1405
+ const inner = `${indent}${style.unit}`;
1406
+ const body = entries.map(([key, item]) => `${inner}${JSON.stringify(key)}: ${renderValue(item, inner, style)}`).join(`,${style.eol}`);
1407
+ return `{${style.eol}${body}${style.eol}${indent}}`;
1408
+ }
1409
+ function splice(raw, start, end, text) {
1410
+ return raw.slice(0, start) + text + raw.slice(end);
1411
+ }
1412
+ function nest(keys, value) {
1413
+ return keys.reduceRight((inner, key) => ({ [key]: inner }), value);
1414
+ }
1415
+ function insertProperty(raw, object, key, value, style) {
1416
+ const properties = object.children ?? [];
1417
+ const objectIndent = lineIndentAt(raw, object.offset);
1418
+ if (properties.length === 0) {
1419
+ const inner = `${objectIndent}${style.unit}`;
1420
+ const text = `{${style.eol}${inner}${JSON.stringify(String(key))}: ${renderValue(value, inner, style)}${style.eol}${objectIndent}}`;
1421
+ return splice(raw, object.offset, object.offset + object.length, text);
1422
+ }
1423
+ const last = properties[properties.length - 1];
1424
+ const end = last.offset + last.length;
1425
+ if (!isMultiline(raw, object)) {
1426
+ return splice(raw, end, end, `, ${JSON.stringify(String(key))}: ${renderValue(value, "", style)}`);
1427
+ }
1428
+ const indent = lineIndentAt(raw, last.offset);
1429
+ return splice(raw, end, end, `,${style.eol}${indent}${JSON.stringify(String(key))}: ${renderValue(value, indent, style)}`);
1430
+ }
1431
+ function setJsonValue(raw, path, value) {
1432
+ const style = styleOf(raw);
1433
+ const root = parseTree2(raw);
1434
+ if (root === void 0) throw new Error("setJsonValue: not a JSON document");
1435
+ const existing = findNodeAtLocation2(root, path);
1436
+ if (existing !== void 0) {
1437
+ return splice(raw, existing.offset, existing.offset + existing.length, renderValue(value, lineIndentAt(raw, existing.offset), style));
1438
+ }
1439
+ for (let depth = path.length - 1; depth >= 0; depth--) {
1440
+ const parent = depth === 0 ? root : findNodeAtLocation2(root, path.slice(0, depth));
1441
+ if (parent === void 0) continue;
1442
+ if (parent.type !== "object") throw new Error(`setJsonValue: ${path.slice(0, depth).join(".") || "the root"} is not an object`);
1443
+ return insertProperty(raw, parent, path[depth], nest(path.slice(depth + 1), value), style);
1444
+ }
1445
+ throw new Error("setJsonValue: unreachable");
1446
+ }
1447
+ function applyJsonEdits(raw, edits) {
1448
+ if (raw === null) {
1449
+ let text = "{}\n";
1450
+ for (const [path, value] of edits) text = setJsonValue(text, path, value);
1451
+ return text;
1452
+ }
1453
+ return edits.reduce((text, [path, value]) => setJsonValue(text, path, value), raw);
1454
+ }
1455
+
1456
+ // src/generators/shared/toolkit-config-file.ts
1457
+ var TOOLKIT_CONFIG_PATH = "toolkit.config.json";
403
1458
  function readToolkitConfigFile(tree) {
404
1459
  const raw = tree.read(TOOLKIT_CONFIG_PATH, "utf-8");
405
1460
  if (raw === null) return { raw: null, parsed: null };
@@ -435,12 +1490,7 @@ function recordAiHosts(tree, hosts, write) {
435
1490
  if (Array.isArray(recorded) && recorded.length === hosts.length && recorded.every((id, index) => id === hosts[index])) {
436
1491
  return "unchanged";
437
1492
  }
438
- if (write) {
439
- const indent = raw === null ? " " : detectIndent(raw);
440
- const body = JSON.stringify({ ...existing, aiHosts: [...hosts] }, null, indent);
441
- tree.write(TOOLKIT_CONFIG_PATH, raw === null || raw.endsWith("\n") ? `${body}
442
- ` : body);
443
- }
1493
+ if (write) tree.write(TOOLKIT_CONFIG_PATH, applyJsonEdits(raw, [[["aiHosts"], [...hosts]]]));
444
1494
  return raw === null ? "created" : "updated";
445
1495
  }
446
1496
 
@@ -450,7 +1500,8 @@ var ACTION_LINE = {
450
1500
  appended: (result) => `${result.filePath}: nx-archweave block added after the existing content (nothing else changed)`,
451
1501
  updated: (result) => `${result.filePath}: nx-archweave block updated (nothing outside it changed)`,
452
1502
  unchanged: (result) => `${result.filePath}: unchanged`,
453
- unrecognized: (result) => `${result.filePath}: not written \u2014 ${result.reason ?? "the nx-archweave markers could not be placed"}`
1503
+ unrecognized: (result) => `${result.filePath}: not written \u2014 ${result.reason ?? "the nx-archweave markers could not be placed"}`,
1504
+ "user-modified": (result) => `${result.filePath}: not written \u2014 the nx-archweave block was edited by hand, so it is kept`
454
1505
  };
455
1506
  function renderAddAgentRulesReport(report) {
456
1507
  const lines = [];
@@ -461,6 +1512,11 @@ function renderAddAgentRulesReport(report) {
461
1512
  lines.push("");
462
1513
  for (const file of report.files) {
463
1514
  lines.push(` ${ACTION_LINE[file.action](file)}`);
1515
+ if (file.action === "user-modified") {
1516
+ lines.push(" What this run would write instead (your block \u2192 generated):");
1517
+ for (const line of (file.diff ?? "").split("\n")) lines.push(` ${line}`);
1518
+ lines.push(" Rerun with --overwriteBlock to replace the block with the generated one.");
1519
+ }
464
1520
  }
465
1521
  const RECORD_LINE = {
466
1522
  created: "toolkit.config.json: aiHosts recorded (file created)",
@@ -474,7 +1530,7 @@ function renderAddAgentRulesReport(report) {
474
1530
  if (recordLine !== null) lines.push(` ${recordLine}`);
475
1531
  if (report.files.some((file) => file.action === "unrecognized")) {
476
1532
  lines.push("");
477
- lines.push('Manual fix needed: keep exactly one "<!-- nx-archweave:agent-rules start -->" \u2026 "<!-- nx-archweave:agent-rules end -->"');
1533
+ lines.push('Manual fix needed: keep exactly one "<!-- nx-archweave:agent-rules start \u2026 -->" \u2026 "<!-- nx-archweave:agent-rules end -->"');
478
1534
  lines.push("pair in the file (or remove both markers), then rerun add-agent-rules.");
479
1535
  }
480
1536
  if (report.dryRun) {
@@ -490,6 +1546,87 @@ function renderAddAgentRulesReport(report) {
490
1546
  return lines.join("\n");
491
1547
  }
492
1548
 
1549
+ // src/generators/add-review/render.ts
1550
+ function renderLineDiff(existing, generated) {
1551
+ const a = existing.split("\n");
1552
+ const b = generated.split("\n");
1553
+ const m = a.length;
1554
+ const n = b.length;
1555
+ const lcs = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
1556
+ for (let i2 = m - 1; i2 >= 0; i2--) {
1557
+ for (let j2 = n - 1; j2 >= 0; j2--) {
1558
+ lcs[i2][j2] = a[i2] === b[j2] ? lcs[i2 + 1][j2 + 1] + 1 : Math.max(lcs[i2 + 1][j2], lcs[i2][j2 + 1]);
1559
+ }
1560
+ }
1561
+ const out = ["--- existing", "+++ generated"];
1562
+ let i = 0;
1563
+ let j = 0;
1564
+ while (i < m && j < n) {
1565
+ if (a[i] === b[j]) {
1566
+ out.push(` ${a[i]}`);
1567
+ i++;
1568
+ j++;
1569
+ } else if (lcs[i + 1][j] >= lcs[i][j + 1]) {
1570
+ out.push(`- ${a[i]}`);
1571
+ i++;
1572
+ } else {
1573
+ out.push(`+ ${b[j]}`);
1574
+ j++;
1575
+ }
1576
+ }
1577
+ while (i < m) out.push(`- ${a[i++]}`);
1578
+ while (j < n) out.push(`+ ${b[j++]}`);
1579
+ return out.join("\n");
1580
+ }
1581
+
1582
+ // src/eslint/fsd-policy.ts
1583
+ var PRESETS = {
1584
+ basic: {
1585
+ sliceGroups: { auto: true, include: [], exclude: [] },
1586
+ sharedPublicApi: "segment",
1587
+ testFiles: false,
1588
+ segments: [],
1589
+ platformSuffixes: [],
1590
+ routerDirs: []
1591
+ },
1592
+ practical: {
1593
+ sliceGroups: { auto: true, include: [], exclude: [] },
1594
+ sharedPublicApi: "file",
1595
+ testFiles: ["**/*.{spec,test}.*", "**/__tests__/**"],
1596
+ segments: [],
1597
+ platformSuffixes: [],
1598
+ routerDirs: []
1599
+ }
1600
+ };
1601
+ var isStringArray = (value) => Array.isArray(value) && value.every((item) => typeof item === "string");
1602
+ function resolveFsdPolicy(recorded, overrides = {}) {
1603
+ const fsd = typeof recorded === "object" && recorded !== null ? recorded : {};
1604
+ const preset = fsd["preset"] === "practical" ? "practical" : "basic";
1605
+ const policy = { ...PRESETS[preset] };
1606
+ const groups = fsd["sliceGroups"];
1607
+ if (groups === false) policy.sliceGroups = false;
1608
+ else if (groups === "auto") policy.sliceGroups = { auto: true, include: [], exclude: [] };
1609
+ else if (typeof groups === "object" && groups !== null) {
1610
+ const value = groups;
1611
+ policy.sliceGroups = {
1612
+ auto: value["auto"] !== false,
1613
+ include: isStringArray(value["include"]) ? value["include"] : [],
1614
+ exclude: isStringArray(value["exclude"]) ? value["exclude"] : []
1615
+ };
1616
+ }
1617
+ const shared = fsd["sharedPublicApi"];
1618
+ if (shared === "segment" || shared === "component" || shared === "file") policy.sharedPublicApi = shared;
1619
+ const tests = fsd["testFiles"];
1620
+ if (tests === false || isStringArray(tests)) policy.testFiles = tests;
1621
+ if (isStringArray(fsd["segments"])) policy.segments = fsd["segments"];
1622
+ if (isStringArray(fsd["platformSuffixes"])) policy.platformSuffixes = fsd["platformSuffixes"];
1623
+ if (isStringArray(fsd["routerDirs"])) policy.routerDirs = fsd["routerDirs"];
1624
+ for (const [key, value] of Object.entries(overrides)) {
1625
+ if (value !== void 0) policy[key] = value;
1626
+ }
1627
+ return policy;
1628
+ }
1629
+
493
1630
  // src/generators/add-agent-rules/generator.ts
494
1631
  function resolveTeamRules(option, config) {
495
1632
  if (option !== void 0) return option;
@@ -504,6 +1641,13 @@ function resolveFsdStructure(config) {
504
1641
  const frontend = config?.["frontend"];
505
1642
  return typeof frontend === "string" && frontend !== "none";
506
1643
  }
1644
+ var POLICY_KEYS = ["preset", "sliceGroups", "sharedPublicApi", "testFiles"];
1645
+ function resolveFsdPolicyNotes(config) {
1646
+ const fsd = config?.["fsd"];
1647
+ if (typeof fsd !== "object" || fsd === null || !POLICY_KEYS.some((key) => key in fsd)) return void 0;
1648
+ const policy = resolveFsdPolicy(fsd);
1649
+ return { sliceGroups: policy.sliceGroups !== false, sharedPublicApi: policy.sharedPublicApi, testFiles: policy.testFiles !== false };
1650
+ }
507
1651
  function runAddAgentRules(tree, options, { recordHosts = true, fsdStructure } = {}) {
508
1652
  const config = readToolkitConfig(tree);
509
1653
  const hosts = resolveAiHostsOption(options.hosts, config);
@@ -511,7 +1655,7 @@ function runAddAgentRules(tree, options, { recordHosts = true, fsdStructure } =
511
1655
  const locale = resolveLocaleOption(options.locale, config);
512
1656
  const teamRules = resolveTeamRules(options.teamRules, config);
513
1657
  const dryRun = options.dryRun ?? false;
514
- const composed = composeAgentRules({ files, locale, teamRules, fsdStructure: fsdStructure ?? resolveFsdStructure(config) });
1658
+ const composed = composeAgentRules({ files, locale, teamRules, fsdStructure: fsdStructure ?? resolveFsdStructure(config), fsdPolicy: resolveFsdPolicyNotes(config) });
515
1659
  const results = composed.map(({ filePath, content }) => {
516
1660
  if (!validateAgentRules(content, teamRules ? ["team-rules"] : [])) {
517
1661
  throw new Error(
@@ -519,12 +1663,20 @@ function runAddAgentRules(tree, options, { recordHosts = true, fsdStructure } =
519
1663
  );
520
1664
  }
521
1665
  const existing = tree.read(filePath, "utf-8");
522
- const outcome = applyAgentRulesBlock(existing, content);
1666
+ const outcome = applyAgentRulesBlock(existing, content, { overwrite: options.overwriteBlock === true });
523
1667
  switch (outcome.kind) {
524
1668
  case "unchanged":
525
1669
  return { filePath, action: "unchanged", reason: null, content: null };
526
1670
  case "unrecognized":
527
1671
  return { filePath, action: "unrecognized", reason: outcome.reason, content: null };
1672
+ case "user-modified":
1673
+ return {
1674
+ filePath,
1675
+ action: "user-modified",
1676
+ reason: null,
1677
+ content: null,
1678
+ diff: renderLineDiff(outcome.existingBody, outcome.generatedBody)
1679
+ };
528
1680
  case "create":
529
1681
  case "append":
530
1682
  case "replace": {