@intentius/behold 0.19.0 → 0.21.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 (52) hide show
  1. package/AGENTS.md +90 -5
  2. package/README.md +54 -1
  3. package/demos.json +3 -2
  4. package/dist/cli.js +1327 -303
  5. package/example-argo-estate/README.md +8 -8
  6. package/example-argo-estate/app-a/package.json +2 -2
  7. package/example-argo-estate/app-b/package.json +2 -2
  8. package/example-argo-estate/chant.workspace.json +27 -0
  9. package/example-argo-estate/control-plane/package.json +2 -2
  10. package/example-argo-estate/package-lock.json +133 -56
  11. package/example-carve/README.md +14 -14
  12. package/example-carve/app/package-lock.json +72 -9
  13. package/example-carve/app/package.json +2 -2
  14. package/example-carve/legacy-tf/versions.tf +1 -1
  15. package/example-choudoufu-estate/README.md +4 -4
  16. package/example-choudoufu-estate/chant.workspace.json +32 -0
  17. package/example-choudoufu-estate/scripts/choudoufu-up.sh +21 -0
  18. package/example-flux-estate/README.md +5 -5
  19. package/example-flux-estate/app-a/package.json +2 -2
  20. package/example-flux-estate/app-b/package.json +2 -2
  21. package/example-flux-estate/chant.workspace.json +27 -0
  22. package/example-flux-estate/control-plane/package.json +2 -2
  23. package/example-flux-estate/package-lock.json +133 -56
  24. package/example-k8s/README.md +20 -20
  25. package/example-k8s/chant.config.ts +1 -1
  26. package/example-k8s/ops/k3d-apply.op.ts +1 -1
  27. package/example-k8s/package-lock.json +129 -211
  28. package/example-k8s/package.json +2 -3
  29. package/example-terraform-estate/README.md +5 -5
  30. package/example-terraform-estate/chant.workspace.json +22 -0
  31. package/example-writes/README.md +5 -5
  32. package/example-writes/chant.config.ts +1 -1
  33. package/example-writes/ops/apply.op.ts +1 -1
  34. package/example-writes/ops/floci.op.ts +2 -2
  35. package/example-writes/ops/reconcile.op.ts +1 -1
  36. package/example-writes/package-lock.json +62 -175
  37. package/example-writes/package.json +2 -3
  38. package/package.json +6 -6
  39. package/web/app.js +431 -17
  40. package/web/behaviour-scale.js +32 -0
  41. package/web/behaviour-scale.test.js +39 -0
  42. package/web/embed.js +76 -0
  43. package/web/embed.test.js +45 -0
  44. package/web/index.html +20 -0
  45. package/web/operator.js +14 -1
  46. package/web/panel.js +11 -3
  47. package/web/run-playhead.js +13 -1
  48. package/web/view-url.js +138 -0
  49. package/web/view-url.test.js +84 -0
  50. package/web/workspace-gates.js +44 -0
  51. package/web/workspace-gates.test.js +34 -0
  52. package/example-choudoufu-estate/.behold.json +0 -8
@@ -6,8 +6,8 @@
6
6
  "": {
7
7
  "name": "behold-example-carve-app",
8
8
  "dependencies": {
9
- "@intentius/chant": "^0.54.0",
10
- "@intentius/chant-lexicon-aws": "^0.54.0"
9
+ "@intentius/chant": "^0.95.0",
10
+ "@intentius/chant-lexicon-aws": "^0.95.0"
11
11
  }
12
12
  },
13
13
  "node_modules/@dagrejs/dagre": {
@@ -442,14 +442,16 @@
442
442
  }
443
443
  },
444
444
  "node_modules/@intentius/chant": {
445
- "version": "0.54.0",
446
- "resolved": "https://registry.npmjs.org/@intentius/chant/-/chant-0.54.0.tgz",
447
- "integrity": "sha512-ETYVPvDWqJiEsaaaYK+1U2lGrZZqHPU6/bOH797oQNw5gd7ESkEoYZxlh0qO90FQGVdx1pQMvmlCWskWD4xIlA==",
445
+ "version": "0.95.0",
446
+ "resolved": "https://registry.npmjs.org/@intentius/chant/-/chant-0.95.0.tgz",
447
+ "integrity": "sha512-zhReqEbP7apFyI9bwHATxSKPbc9HK8W2lJvZpib0YNEgSafydm+dd31Hn+7o3AcHhYbAkLpHFQwlFYbM2uVYCg==",
448
448
  "license": "Apache-2.0",
449
449
  "dependencies": {
450
450
  "@dagrejs/dagre": "^3.0.0",
451
+ "ajv": "^8.20.0",
451
452
  "esbuild": "^0.28.1",
452
453
  "fflate": "^0.8.2",
454
+ "js-yaml": "^4.3.1",
453
455
  "picomatch": "^4.0.3",
454
456
  "tsx": "^4.0.0",
455
457
  "typescript": "^5.5.0",
@@ -457,22 +459,46 @@
457
459
  },
458
460
  "bin": {
459
461
  "chant": "bin/chant"
462
+ },
463
+ "peerDependencies": {
464
+ "vitest": ">=2"
465
+ },
466
+ "peerDependenciesMeta": {
467
+ "vitest": {
468
+ "optional": true
469
+ }
460
470
  }
461
471
  },
462
472
  "node_modules/@intentius/chant-lexicon-aws": {
463
- "version": "0.54.0",
464
- "resolved": "https://registry.npmjs.org/@intentius/chant-lexicon-aws/-/chant-lexicon-aws-0.54.0.tgz",
465
- "integrity": "sha512-HVyTEmOu73WJXpVpI9C/TyVo34Rbms9uKohb6sob5Y9Oa/T4yly9P5aqsuE6fMDyLwoLZmknW4v7qxENilrFLg==",
473
+ "version": "0.95.0",
474
+ "resolved": "https://registry.npmjs.org/@intentius/chant-lexicon-aws/-/chant-lexicon-aws-0.95.0.tgz",
475
+ "integrity": "sha512-DHW/cHL4JEU1foEvFK1i2/1Ur4O9meu4dpuyh1o+rnr8DJwW2Ktf7g+84nVDhTjcPVPGE1DROnnQlSuAlu4u8g==",
466
476
  "license": "Apache-2.0",
467
477
  "dependencies": {
468
478
  "fflate": "^0.8.2",
469
479
  "js-yaml": "^4.3.1"
470
480
  },
471
481
  "peerDependencies": {
472
- "@intentius/chant": "^0.54.0",
482
+ "@intentius/chant": "^0.95.0",
473
483
  "typescript": "^5.9.3"
474
484
  }
475
485
  },
486
+ "node_modules/ajv": {
487
+ "version": "8.20.0",
488
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz",
489
+ "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==",
490
+ "license": "MIT",
491
+ "dependencies": {
492
+ "fast-deep-equal": "^3.1.3",
493
+ "fast-uri": "^3.0.1",
494
+ "json-schema-traverse": "^1.0.0",
495
+ "require-from-string": "^2.0.2"
496
+ },
497
+ "funding": {
498
+ "type": "github",
499
+ "url": "https://github.com/sponsors/epoberezkin"
500
+ }
501
+ },
476
502
  "node_modules/argparse": {
477
503
  "version": "2.0.1",
478
504
  "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
@@ -520,6 +546,28 @@
520
546
  "@esbuild/win32-x64": "0.28.2"
521
547
  }
522
548
  },
549
+ "node_modules/fast-deep-equal": {
550
+ "version": "3.1.3",
551
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
552
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
553
+ "license": "MIT"
554
+ },
555
+ "node_modules/fast-uri": {
556
+ "version": "3.1.8",
557
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.8.tgz",
558
+ "integrity": "sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==",
559
+ "funding": [
560
+ {
561
+ "type": "github",
562
+ "url": "https://github.com/sponsors/fastify"
563
+ },
564
+ {
565
+ "type": "opencollective",
566
+ "url": "https://opencollective.com/fastify"
567
+ }
568
+ ],
569
+ "license": "BSD-3-Clause"
570
+ },
523
571
  "node_modules/fflate": {
524
572
  "version": "0.8.3",
525
573
  "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.3.tgz",
@@ -562,6 +610,12 @@
562
610
  "js-yaml": "bin/js-yaml.js"
563
611
  }
564
612
  },
613
+ "node_modules/json-schema-traverse": {
614
+ "version": "1.0.0",
615
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
616
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
617
+ "license": "MIT"
618
+ },
565
619
  "node_modules/picomatch": {
566
620
  "version": "4.0.5",
567
621
  "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz",
@@ -574,6 +628,15 @@
574
628
  "url": "https://github.com/sponsors/jonschlinkert"
575
629
  }
576
630
  },
631
+ "node_modules/require-from-string": {
632
+ "version": "2.0.2",
633
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
634
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
635
+ "license": "MIT",
636
+ "engines": {
637
+ "node": ">=0.10.0"
638
+ }
639
+ },
577
640
  "node_modules/tsx": {
578
641
  "version": "4.23.12",
579
642
  "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.23.12.tgz",
@@ -7,7 +7,7 @@
7
7
  "build": "./node_modules/.bin/chant build src --lexicon aws -o template.json"
8
8
  },
9
9
  "dependencies": {
10
- "@intentius/chant": "^0.54.0",
11
- "@intentius/chant-lexicon-aws": "^0.54.0"
10
+ "@intentius/chant": "^0.95.0",
11
+ "@intentius/chant-lexicon-aws": "^0.95.0"
12
12
  }
13
13
  }
@@ -8,7 +8,7 @@
8
8
  # the account id in it is 000000000000, and every ARN is fake. Values are
9
9
  # boring-realistic on purpose: the walkthrough video pauses on the inspect pane.
10
10
  #
11
- # `chant carve advise` parses these files with @cdktf/hcl2json — no terraform
11
+ # `chant carve advise` parses these files with @cdktn/hcl2json — no terraform
12
12
  # binary, no provider download, no network. See ../README.md for the scores this
13
13
  # estate is tuned to produce and why each one lands where it does.
14
14
 
@@ -7,18 +7,18 @@ cache that is allowed to be stale, and an estate is split by retagging. The
7
7
  estates here are the live-mv workbench's own fixture (`examples/live-mv-workbench`
8
8
  in the choudoufu repo), copied:
9
9
 
10
- - **monolith/** — the terralith: three teams' IAM roles, policies, inline
10
+ - **monolith/.** The terralith: three teams' IAM roles, policies, inline
11
11
  policies, attachments and log groups in one estate. `scripts/choudoufu-up.sh`
12
12
  applies it, so every one of its 21 resources is live and marked
13
13
  `tofu-estate = tlmig-sample-monolith`.
14
- - **team-a/**, **team-b/**, **team-c/** — the estates the teams would own.
14
+ - **team-a/**, **team-b/**, **team-c/** are the estates the teams would own.
15
15
  Each declares its own seven resources, which are the monolith's: served
16
16
  live, every card reads *owned by tlmig-sample-monolith*, with a dashed
17
17
  edge to the monolith's card of the same address. team-a also declares a VPC
18
18
  the monolith does not, and team-b reads it through a data source filtered
19
- on team-a's marker tags — the cross-estate reference `live-check -json`
19
+ on team-a's marker tags, the cross-estate reference `live-check -json`
20
20
  states, drawn as an edge between the two boxes.
21
- - **monolith/carve.json** — the plan: team-a's five taggable resources move to
21
+ - **monolith/carve.json.** The plan: team-a's five taggable resources move to
22
22
  `tlmig-sample-team-a`. The scope panel shows each move with the
23
23
  `choudoufu live-mv` line to run and a link to the morph; behold never runs
24
24
  the write.
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "example-choudoufu-estate",
3
+ "schema": 1,
4
+ "pins": [
5
+ {
6
+ "package": "@intentius/chant-lexicon-terraform",
7
+ "version": "0.95.0"
8
+ }
9
+ ],
10
+ "members": [
11
+ {
12
+ "name": "monolith",
13
+ "dir": "monolith",
14
+ "kind": "choudoufu"
15
+ },
16
+ {
17
+ "name": "team-a",
18
+ "dir": "team-a",
19
+ "kind": "choudoufu"
20
+ },
21
+ {
22
+ "name": "team-b",
23
+ "dir": "team-b",
24
+ "kind": "choudoufu"
25
+ },
26
+ {
27
+ "name": "team-c",
28
+ "dir": "team-c",
29
+ "kind": "choudoufu"
30
+ }
31
+ ]
32
+ }
@@ -59,4 +59,25 @@ done
59
59
  echo "→ choudoufu apply in monolith (the terralith: 21 resources, three teams in one estate)"
60
60
  (cd monolith && "$CHOUDOUFU" apply -auto-approve -input=false -no-color | tail -1)
61
61
 
62
+ # behold#415: the adoptable card's subject. team-a declares `aws_vpc.main` at
63
+ # 10.77.0.0/16 and nothing applies that estate, so it has no marker and no
64
+ # identity a configuration can reconstruct — EC2 assigns the `vpc-…` id. That
65
+ # makes it NEEDS_DISCOVERY, and `aws_vpc` is in choudoufu's content-match table
66
+ # keyed on `cidr_block`, so the estate-wide sweep can match it to a live VPC
67
+ # carrying the same cidr and no marker.
68
+ #
69
+ # Created out of band on purpose: a VPC choudoufu applied would wear the estate
70
+ # markers and read `bound`, which is the opposite of what this demonstrates.
71
+ # `aws` is not a requirement of this demo, so a machine without it gets the
72
+ # whole estate minus one card and is told which one.
73
+ if command -v aws >/dev/null 2>&1; then
74
+ echo "→ seeding an unmarked VPC at 10.77.0.0/16 (the adoptable card — behold#415)"
75
+ AWS_ENDPOINT_URL="http://127.0.0.1:${PORT}" AWS_ACCESS_KEY_ID=test \
76
+ AWS_SECRET_ACCESS_KEY=test AWS_REGION=us-east-1 \
77
+ aws ec2 create-vpc --cidr-block 10.77.0.0/16 --query 'Vpc.VpcId' --output text >/dev/null 2>&1 \
78
+ || echo " (floci refused the create — the adoptable card will not appear)"
79
+ else
80
+ echo "→ no 'aws' on PATH, so the adoptable card is skipped; everything else stands up"
81
+ fi
82
+
62
83
  echo "choudoufu-estate demo: up. behold serves it next; the plan in monolith/carve.json moves team-a's resources out."
@@ -2,20 +2,20 @@
2
2
 
3
3
  Three chant projects served as one composed estate:
4
4
 
5
- - **control-plane/** — the Flux machinery: a `GitRepository` pointing at
5
+ - **control-plane/.** The Flux machinery: a `GitRepository` pointing at
6
6
  behold's own public repo and one `Kustomization` per app, app-b's gated on
7
7
  app-a's with `dependsOn` (behold#223). The reconcilers deploy the apps; this
8
8
  project never applies a workload itself.
9
- - **app-a/** — a small web workload with explicit `metadata.namespace` on
9
+ - **app-a/.** A small web workload with explicit `metadata.namespace` on
10
10
  every object: the fully-resolved half.
11
- - **app-b/** — the same workload with **no** namespace anywhere: the control
11
+ - **app-b/.** The same workload with **no** namespace anywhere: the control
12
12
  plane's `targetNamespace` stamps it at apply time. Idiomatic Flux, and the
13
13
  deliberate exhibit of the estate namespace join (behold#221). Served alone,
14
14
  app-b's live read scopes to `default`, finds nothing, and behold explains
15
15
  the all-pending paint with the namespace-mismatch note (behold#192) instead
16
16
  of letting it read as "not deployed". Served composed, the estate reads the
17
17
  binding off the control plane's own `Kustomization` and scopes app-b's read
18
- to `app-b` — the answer neither project holds by itself.
18
+ to `app-b`, the answer neither project holds by itself.
19
19
 
20
20
  ```sh
21
21
  npx @intentius/behold demo flux-estate
@@ -28,7 +28,7 @@ this repo, and serves the three projects composed. What to look at:
28
28
 
29
29
  - The **estate**: per-project boundary boxes, the `sourceRef` edges wiring
30
30
  Kustomization → GitRepository across stacks, and the `dependsOn` edge from
31
- app-b's Kustomization to app-a's — the estate's reconcile ordering.
31
+ app-b's Kustomization to app-a's, the estate's reconcile ordering.
32
32
  - The **overlay** (env `local`): app-a green, the control plane's CRs green,
33
33
  and app-b green too — read in the namespace the control plane binds it to,
34
34
  with a note naming where it looked. Serve `app-b` on its own to see the
@@ -7,7 +7,7 @@
7
7
  "build": "chant build src -o manifests/app.yaml --format yaml"
8
8
  },
9
9
  "dependencies": {
10
- "@intentius/chant": "^0.54.0",
11
- "@intentius/chant-lexicon-k8s": "^0.54.0"
10
+ "@intentius/chant": "^0.95.0",
11
+ "@intentius/chant-lexicon-k8s": "^0.95.0"
12
12
  }
13
13
  }
@@ -7,7 +7,7 @@
7
7
  "build": "chant build src -o manifests/app.yaml --format yaml"
8
8
  },
9
9
  "dependencies": {
10
- "@intentius/chant": "^0.54.0",
11
- "@intentius/chant-lexicon-k8s": "^0.54.0"
10
+ "@intentius/chant": "^0.95.0",
11
+ "@intentius/chant-lexicon-k8s": "^0.95.0"
12
12
  }
13
13
  }
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "example-flux-estate",
3
+ "schema": 1,
4
+ "pins": [
5
+ {
6
+ "package": "@intentius/chant",
7
+ "version": "0.95.0"
8
+ }
9
+ ],
10
+ "members": [
11
+ {
12
+ "name": "control-plane",
13
+ "dir": "control-plane",
14
+ "kind": "chant"
15
+ },
16
+ {
17
+ "name": "app-a",
18
+ "dir": "app-a",
19
+ "kind": "chant"
20
+ },
21
+ {
22
+ "name": "app-b",
23
+ "dir": "app-b",
24
+ "kind": "chant"
25
+ }
26
+ ]
27
+ }
@@ -7,7 +7,7 @@
7
7
  "build": "chant build src -o dist/control-plane.yaml --format yaml"
8
8
  },
9
9
  "dependencies": {
10
- "@intentius/chant": "^0.54.0",
11
- "@intentius/chant-lexicon-k8s": "^0.54.0"
10
+ "@intentius/chant": "^0.95.0",
11
+ "@intentius/chant-lexicon-k8s": "^0.95.0"
12
12
  }
13
13
  }