@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.
- package/AGENTS.md +90 -5
- package/README.md +54 -1
- package/demos.json +3 -2
- package/dist/cli.js +1327 -303
- package/example-argo-estate/README.md +8 -8
- package/example-argo-estate/app-a/package.json +2 -2
- package/example-argo-estate/app-b/package.json +2 -2
- package/example-argo-estate/chant.workspace.json +27 -0
- package/example-argo-estate/control-plane/package.json +2 -2
- package/example-argo-estate/package-lock.json +133 -56
- package/example-carve/README.md +14 -14
- package/example-carve/app/package-lock.json +72 -9
- package/example-carve/app/package.json +2 -2
- package/example-carve/legacy-tf/versions.tf +1 -1
- package/example-choudoufu-estate/README.md +4 -4
- package/example-choudoufu-estate/chant.workspace.json +32 -0
- package/example-choudoufu-estate/scripts/choudoufu-up.sh +21 -0
- package/example-flux-estate/README.md +5 -5
- package/example-flux-estate/app-a/package.json +2 -2
- package/example-flux-estate/app-b/package.json +2 -2
- package/example-flux-estate/chant.workspace.json +27 -0
- package/example-flux-estate/control-plane/package.json +2 -2
- package/example-flux-estate/package-lock.json +133 -56
- package/example-k8s/README.md +20 -20
- package/example-k8s/chant.config.ts +1 -1
- package/example-k8s/ops/k3d-apply.op.ts +1 -1
- package/example-k8s/package-lock.json +129 -211
- package/example-k8s/package.json +2 -3
- package/example-terraform-estate/README.md +5 -5
- package/example-terraform-estate/chant.workspace.json +22 -0
- package/example-writes/README.md +5 -5
- package/example-writes/chant.config.ts +1 -1
- package/example-writes/ops/apply.op.ts +1 -1
- package/example-writes/ops/floci.op.ts +2 -2
- package/example-writes/ops/reconcile.op.ts +1 -1
- package/example-writes/package-lock.json +62 -175
- package/example-writes/package.json +2 -3
- package/package.json +6 -6
- package/web/app.js +431 -17
- package/web/behaviour-scale.js +32 -0
- package/web/behaviour-scale.test.js +39 -0
- package/web/embed.js +76 -0
- package/web/embed.test.js +45 -0
- package/web/index.html +20 -0
- package/web/operator.js +14 -1
- package/web/panel.js +11 -3
- package/web/run-playhead.js +13 -1
- package/web/view-url.js +138 -0
- package/web/view-url.test.js +84 -0
- package/web/workspace-gates.js +44 -0
- package/web/workspace-gates.test.js +34 -0
- 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.
|
|
10
|
-
"@intentius/chant-lexicon-aws": "^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.
|
|
446
|
-
"resolved": "https://registry.npmjs.org/@intentius/chant/-/chant-0.
|
|
447
|
-
"integrity": "sha512-
|
|
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.
|
|
464
|
-
"resolved": "https://registry.npmjs.org/@intentius/chant-lexicon-aws/-/chant-lexicon-aws-0.
|
|
465
|
-
"integrity": "sha512-
|
|
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.
|
|
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.
|
|
11
|
-
"@intentius/chant-lexicon-aws": "^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 @
|
|
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
|
|
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/**
|
|
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
|
|
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
|
|
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
|
|
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
|
|
9
|
+
- **app-a/.** A small web workload with explicit `metadata.namespace` on
|
|
10
10
|
every object: the fully-resolved half.
|
|
11
|
-
- **app-b
|
|
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
|
|
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
|
|
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
|
|
@@ -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
|
+
}
|