@intentius/chant 0.52.0 → 0.52.2

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 (74) hide show
  1. package/dist/agents/checks.d.ts +35 -0
  2. package/dist/agents/checks.d.ts.map +1 -0
  3. package/dist/agents/discover.d.ts +86 -0
  4. package/dist/agents/discover.d.ts.map +1 -0
  5. package/dist/agents/importer.d.ts +46 -0
  6. package/dist/agents/importer.d.ts.map +1 -0
  7. package/dist/agents/index.d.ts +14 -0
  8. package/dist/agents/index.d.ts.map +1 -0
  9. package/dist/agents/types.d.ts +196 -0
  10. package/dist/agents/types.d.ts.map +1 -0
  11. package/dist/audit/catalog.d.ts +4 -1
  12. package/dist/audit/catalog.d.ts.map +1 -1
  13. package/dist/audit/report.d.ts +8 -0
  14. package/dist/audit/report.d.ts.map +1 -1
  15. package/dist/audit/rules-doc.d.ts.map +1 -1
  16. package/dist/cli/commands/audit-agents.d.ts +83 -0
  17. package/dist/cli/commands/audit-agents.d.ts.map +1 -0
  18. package/dist/cli/commands/carve-bridge.d.ts.map +1 -1
  19. package/dist/cli/commands/carve-emit.d.ts.map +1 -1
  20. package/dist/cli/commands/import-agents.d.ts +64 -0
  21. package/dist/cli/commands/import-agents.d.ts.map +1 -0
  22. package/dist/cli/handlers/carve-emit.d.ts.map +1 -1
  23. package/dist/cli/handlers/misc.d.ts.map +1 -1
  24. package/dist/cli/main.d.ts.map +1 -1
  25. package/dist/cli/registry.d.ts +15 -0
  26. package/dist/cli/registry.d.ts.map +1 -1
  27. package/dist/discovery/fold-import.d.ts.map +1 -1
  28. package/dist/lexicon.d.ts +21 -9
  29. package/dist/lexicon.d.ts.map +1 -1
  30. package/dist/lifecycle/assert-live.d.ts +2 -3
  31. package/dist/lifecycle/assert-live.d.ts.map +1 -1
  32. package/dist/ownership.d.ts +5 -4
  33. package/dist/ownership.d.ts.map +1 -1
  34. package/dist/terraform/adopt-state.d.ts +4 -1
  35. package/dist/terraform/adopt-state.d.ts.map +1 -1
  36. package/dist/terraform/bridge.d.ts.map +1 -1
  37. package/dist/terraform/tier-map.d.ts +17 -0
  38. package/dist/terraform/tier-map.d.ts.map +1 -1
  39. package/dist/yaml.d.ts.map +1 -1
  40. package/package.json +6 -1
  41. package/src/agents/checks.test.ts +228 -0
  42. package/src/agents/checks.ts +429 -0
  43. package/src/agents/discover.test.ts +310 -0
  44. package/src/agents/discover.ts +939 -0
  45. package/src/agents/importer.ts +49 -0
  46. package/src/agents/index.ts +29 -0
  47. package/src/agents/types.ts +207 -0
  48. package/src/audit/catalog.ts +90 -1
  49. package/src/audit/report.ts +9 -1
  50. package/src/audit/rules-doc.ts +6 -0
  51. package/src/cli/commands/audit-agents.test.ts +260 -0
  52. package/src/cli/commands/audit-agents.ts +387 -0
  53. package/src/cli/commands/carve-bridge.test.ts +30 -0
  54. package/src/cli/commands/carve-bridge.ts +19 -1
  55. package/src/cli/commands/carve-emit.test.ts +72 -1
  56. package/src/cli/commands/carve-emit.ts +43 -20
  57. package/src/cli/commands/import-agents.test.ts +208 -0
  58. package/src/cli/commands/import-agents.ts +196 -0
  59. package/src/cli/handlers/carve-emit.ts +2 -0
  60. package/src/cli/handlers/misc.ts +111 -0
  61. package/src/cli/main.ts +17 -0
  62. package/src/cli/registry.ts +15 -0
  63. package/src/discovery/fold-import.test.ts +102 -0
  64. package/src/discovery/fold-import.ts +54 -4
  65. package/src/lexicon.ts +22 -9
  66. package/src/lifecycle/assert-live.ts +2 -3
  67. package/src/ownership.ts +5 -4
  68. package/src/terraform/adopt-state.ts +7 -4
  69. package/src/terraform/aws-resources.test.ts +24 -1
  70. package/src/terraform/bridge.test.ts +12 -0
  71. package/src/terraform/bridge.ts +4 -1
  72. package/src/terraform/tier-map.ts +28 -1
  73. package/src/yaml.test.ts +54 -0
  74. package/src/yaml.ts +24 -3
package/src/yaml.test.ts CHANGED
@@ -484,3 +484,57 @@ describe("parseYAML — sibling keys after a nested block in a sequence item (#1
484
484
  });
485
485
  });
486
486
  });
487
+
488
+ // #2013 — a colon opens a mapping only when whitespace or the end of the line
489
+ // follows it (YAML 1.2 §7.4.2). The item/key disambiguation used to accept a
490
+ // colon anywhere, which turned a bare URL in a sequence into a single-key
491
+ // object and made the CRD-schema check reject a string list the emitter here
492
+ // had written itself.
493
+ describe("parseYAML — a colon without following space is not a mapping (#2013)", () => {
494
+ test("a bare URL in a sequence is a string", () => {
495
+ expect(parseYAML("sourceRepos:\n- https://github.com/INTENTIUS/behold\n")).toEqual({
496
+ sourceRepos: ["https://github.com/INTENTIUS/behold"],
497
+ });
498
+ });
499
+
500
+ test("an AppProject's sourceRepos round-trips through emit and parse", () => {
501
+ const repos = ["https://github.com/INTENTIUS/behold", "ssh://git@github.com:22/INTENTIUS/behold.git"];
502
+ expect(parseYAML(`spec:${emitYAML({ sourceRepos: repos }, 1)}\n`)).toEqual({ spec: { sourceRepos: repos } });
503
+ });
504
+
505
+ test("a real `- key: value` item is still a mapping", () => {
506
+ expect(parseYAML("items:\n- name: x\n url: https://example.com/a\n")).toEqual({
507
+ items: [{ name: "x", url: "https://example.com/a" }],
508
+ });
509
+ });
510
+
511
+ test("a mapping item whose first value is a URL keeps its siblings", () => {
512
+ expect(parseYAML("sources:\n- repoURL: https://github.com/o/r\n path: ./chart\n")).toEqual({
513
+ sources: [{ repoURL: "https://github.com/o/r", path: "./chart" }],
514
+ });
515
+ });
516
+
517
+ test("a quoted URL in a sequence still works", () => {
518
+ expect(parseYAML("sourceRepos:\n- 'https://github.com/o/r'\n- \"https://github.com/o/s\"\n")).toEqual({
519
+ sourceRepos: ["https://github.com/o/r", "https://github.com/o/s"],
520
+ });
521
+ });
522
+
523
+ test("`- key:value` with no space after the colon is a scalar, per the spec", () => {
524
+ expect(parseYAML("items:\n- key:value\n")).toEqual({ items: ["key:value"] });
525
+ });
526
+
527
+ test("`- key:` with nothing after the colon is still a mapping with a null value", () => {
528
+ expect(parseYAML("items:\n- key:\n")).toEqual({ items: [{ key: null }] });
529
+ });
530
+
531
+ test("a URL on a mapping line, not a sequence item, is unaffected", () => {
532
+ expect(parseYAML("url: https://example.com/a\n")).toEqual({ url: "https://example.com/a" });
533
+ });
534
+
535
+ test("a bare URL among mapping-shaped siblings inside one item", () => {
536
+ expect(parseYAML("items:\n- name: x\n args:\n - --endpoint\n - https://example.com/a\n image: nginx\n")).toEqual({
537
+ items: [{ name: "x", args: ["--endpoint", "https://example.com/a"], image: "nginx" }],
538
+ });
539
+ });
540
+ });
package/src/yaml.ts CHANGED
@@ -155,6 +155,27 @@ export interface ParseResult {
155
155
  endIndex: number;
156
156
  }
157
157
 
158
+ /**
159
+ * `key: value` on a line of its own (`KEY_LINE`, capturing the indent) and the
160
+ * same after a sequence item's `- ` (`ITEM_KEY`).
161
+ *
162
+ * The lookahead is the rule both patterns used to miss: a `:` opens a mapping
163
+ * only when what follows it is whitespace or the end of the line, and a plain
164
+ * scalar may carry any other colon (YAML 1.2 §7.4.2). Written as `:\s*`, which
165
+ * matches zero whitespace, EVERY colon opened one — so a bare URL in a
166
+ * sequence,
167
+ *
168
+ * sourceRepos:
169
+ * - https://github.com/INTENTIUS/behold
170
+ *
171
+ * came back as `{ https: "//github.com/INTENTIUS/behold" }`, and the CRD-schema
172
+ * post-synth check (#1372) re-reading emitted YAML reported the string list
173
+ * this file's own emitter had just written as a list of objects (#2013). By the
174
+ * same rule `- key:value` is the scalar `"key:value"`, not a mapping.
175
+ */
176
+ const KEY_LINE = /^(\s*)([^\s:][^:]*?):(?=\s|$)\s*(.*)$/;
177
+ const ITEM_KEY = /^([^\s:][^:]*?):(?=\s|$)\s*(.*)$/;
178
+
158
179
  /**
159
180
  * Parse a YAML document (or JSON document) into a plain object.
160
181
  *
@@ -274,7 +295,7 @@ export function parseYAMLLines(
274
295
  if (indent < baseIndent) break; // Dedented — done with this block
275
296
  if (indent > baseIndent && startIndex > 0) break; // Unexpected indent
276
297
 
277
- const keyMatch = line.match(/^(\s*)([^\s:][^:]*?):\s*(.*)$/);
298
+ const keyMatch = line.match(KEY_LINE);
278
299
  if (keyMatch) {
279
300
  const key = keyMatch[2].trim();
280
301
  const inlineValue = keyMatch[3].trim();
@@ -472,7 +493,7 @@ export function parseYAMLArray(
472
493
  const isQuotedScalar =
473
494
  (itemValue.startsWith('"') && itemValue.endsWith('"')) ||
474
495
  (itemValue.startsWith("'") && itemValue.endsWith("'"));
475
- const kvMatch = !isQuotedScalar && itemValue.match(/^([^\s:][^:]*?):\s*(.*)$/);
496
+ const kvMatch = !isQuotedScalar && itemValue.match(ITEM_KEY);
476
497
  if (kvMatch) {
477
498
  const obj: Record<string, unknown> = {};
478
499
  obj[kvMatch[1].trim()] = parseArrayItemValue(kvMatch[2].trim(), lines, i, indent + 2);
@@ -506,7 +527,7 @@ export function parseYAMLArray(
506
527
  const ni = nextLine.search(/\S/);
507
528
  if (ni < nextIndent) break;
508
529
  if (ni > nextIndent) break; // belongs to a nested block already consumed
509
- const nextKV = nextLine.match(/^(\s*)([^\s:][^:]*?):\s*(.*)$/);
530
+ const nextKV = nextLine.match(KEY_LINE);
510
531
  if (nextKV) {
511
532
  const nextVal = nextKV[3].trim();
512
533
  obj[nextKV[2].trim()] = parseArrayItemValue(nextVal, lines, j, ni);