@stacksjs/defaults 0.75.361 → 0.75.362
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/ai/skills/stacks-ai/SKILL.md +22 -0
- package/ai/skills/stacks-native/CATALOG.md +2 -2
- package/ai/skills/stacks-technical-diagrams/LICENSE +202 -22
- package/ai/skills/stacks-technical-diagrams/LICENSE-MIT +22 -0
- package/ai/skills/stacks-technical-diagrams/NOTICE +26 -0
- package/ai/skills/stacks-technical-diagrams/SKILL.md +106 -266
- package/ai/skills/stacks-technical-diagrams/THIRD_PARTY_NOTICES.md +11 -2
- package/ai/skills/stacks-technical-diagrams/UPSTREAM.json +12 -0
- package/ai/skills/stacks-technical-diagrams/agents/openai.yaml +2 -2
- package/ai/skills/stacks-technical-diagrams/assets/template.html +3655 -3798
- package/ai/skills/stacks-technical-diagrams/bin/archify.mjs +7290 -0
- package/ai/skills/stacks-technical-diagrams/bin/delivery-update.mjs +7 -0
- package/ai/skills/stacks-technical-diagrams/bin/diagrams +1 -0
- package/ai/skills/stacks-technical-diagrams/bin/finalize.mjs +1056 -0
- package/ai/skills/stacks-technical-diagrams/bin/open-artifact.mjs +72 -12
- package/ai/skills/stacks-technical-diagrams/bin/preview.mjs +348 -31
- package/ai/skills/stacks-technical-diagrams/bin/recover-output.mjs +41 -0
- package/ai/skills/stacks-technical-diagrams/bin/technical-diagrams.mjs +3 -2097
- package/ai/skills/stacks-technical-diagrams/bin/visual-check.mjs +2142 -157
- package/ai/skills/stacks-technical-diagrams/brand-marks/README.md +3 -3
- package/ai/skills/stacks-technical-diagrams/delta/architecture-delta.mjs +130 -33
- package/ai/skills/stacks-technical-diagrams/examples/agent-run.lifecycle.json +25 -30
- package/ai/skills/stacks-technical-diagrams/examples/agent-tool-call.workflow.json +0 -20
- package/ai/skills/stacks-technical-diagrams/examples/archify-dev-activity.timeline.json +176 -0
- package/ai/skills/stacks-technical-diagrams/examples/archify-repository.tree.json +197 -0
- package/ai/skills/stacks-technical-diagrams/examples/async-job-roundtrip.sequence.json +1 -6
- package/ai/skills/stacks-technical-diagrams/examples/brand-aware-delivery.architecture.json +3 -16
- package/ai/skills/stacks-technical-diagrams/examples/cache-miss-request.sequence.json +2 -7
- package/ai/skills/stacks-technical-diagrams/examples/checkout-platform.base.architecture.json +2 -1
- package/ai/skills/stacks-technical-diagrams/examples/checkout-platform.head.architecture.json +2 -1
- package/ai/skills/stacks-technical-diagrams/examples/checkout-request.waterfall.json +20 -0
- package/ai/skills/stacks-technical-diagrams/examples/class-payment-processors-rendered.html +14987 -0
- package/ai/skills/stacks-technical-diagrams/examples/class-payments-rendered.html +14787 -0
- package/ai/skills/stacks-technical-diagrams/examples/dataflow-product-analytics.html +14880 -0
- package/ai/skills/stacks-technical-diagrams/examples/delivery.explainer.json +155 -0
- package/ai/skills/stacks-technical-diagrams/examples/deployment-release.lifecycle.json +57 -34
- package/ai/skills/stacks-technical-diagrams/examples/erd-orders-rendered.html +15112 -0
- package/ai/skills/stacks-technical-diagrams/examples/event-stream.dataflow.json +1 -6
- package/ai/skills/stacks-technical-diagrams/examples/example-rebuild.waterfall.json +212 -0
- package/ai/skills/stacks-technical-diagrams/examples/holiday-planning.workflow.json +143 -0
- package/ai/skills/stacks-technical-diagrams/examples/incident-response.workflow.json +1 -6
- package/ai/skills/stacks-technical-diagrams/examples/lifecycle-agent-run.html +14892 -0
- package/ai/skills/stacks-technical-diagrams/examples/locales/de.json +463 -0
- package/ai/skills/stacks-technical-diagrams/examples/locales/fr.json +463 -0
- package/ai/skills/stacks-technical-diagrams/examples/locales/fr.partial.json +22 -0
- package/ai/skills/stacks-technical-diagrams/examples/locales/it.json +463 -0
- package/ai/skills/stacks-technical-diagrams/examples/locales/ja.json +463 -0
- package/ai/skills/stacks-technical-diagrams/examples/locales/pt.json +463 -0
- package/ai/skills/stacks-technical-diagrams/examples/locales/ru.json +463 -0
- package/ai/skills/stacks-technical-diagrams/examples/orders.erd.json +337 -0
- package/ai/skills/stacks-technical-diagrams/examples/payment-incident.timeline.json +24 -0
- package/ai/skills/stacks-technical-diagrams/examples/payment-platform.tree.json +22 -0
- package/ai/skills/stacks-technical-diagrams/examples/payment-processors.class.json +177 -0
- package/ai/skills/stacks-technical-diagrams/examples/payments.class.json +85 -0
- package/ai/skills/stacks-technical-diagrams/examples/product-analytics.dataflow.json +1 -6
- package/ai/skills/stacks-technical-diagrams/examples/production-deployment.architecture.json +3 -23
- package/ai/skills/stacks-technical-diagrams/examples/release-delivery.workflow.json +1 -6
- package/ai/skills/stacks-technical-diagrams/examples/sequence-cache-miss-request.html +14895 -0
- package/ai/skills/stacks-technical-diagrams/examples/subscription-billing-rendered.html +15369 -0
- package/ai/skills/stacks-technical-diagrams/examples/subscription-billing.erd.json +548 -0
- package/ai/skills/stacks-technical-diagrams/examples/timeline-archify-dev-activity-rendered.html +15002 -0
- package/ai/skills/stacks-technical-diagrams/examples/timeline-payment-incident-rendered.html +14772 -0
- package/ai/skills/stacks-technical-diagrams/examples/tree-archify-repository-rendered.html +15071 -0
- package/ai/skills/stacks-technical-diagrams/examples/tree-payment-platform-rendered.html +14810 -0
- package/ai/skills/stacks-technical-diagrams/examples/waterfall-checkout-request-rendered.html +14754 -0
- package/ai/skills/stacks-technical-diagrams/examples/waterfall-example-rebuild-rendered.html +14940 -0
- package/ai/skills/stacks-technical-diagrams/examples/web-app-rendered.html +14889 -0
- package/ai/skills/stacks-technical-diagrams/examples/web-app.architecture.json +1 -6
- package/ai/skills/stacks-technical-diagrams/examples/workflow-agent-tool-call-rendered.html +14907 -0
- package/ai/skills/stacks-technical-diagrams/explainer/browser-check.mjs +208 -0
- package/ai/skills/stacks-technical-diagrams/explainer/charts.mjs +70 -0
- package/ai/skills/stacks-technical-diagrams/explainer/check.mjs +168 -0
- package/ai/skills/stacks-technical-diagrams/explainer/diagrams.mjs +518 -0
- package/ai/skills/stacks-technical-diagrams/explainer/diff.mjs +124 -0
- package/ai/skills/stacks-technical-diagrams/explainer/inline.mjs +155 -0
- package/ai/skills/stacks-technical-diagrams/explainer/layout.mjs +35 -0
- package/ai/skills/stacks-technical-diagrams/explainer/page-bundle.mjs +16 -0
- package/ai/skills/stacks-technical-diagrams/explainer/parse.mjs +300 -0
- package/ai/skills/stacks-technical-diagrams/explainer/patch.mjs +117 -0
- package/ai/skills/stacks-technical-diagrams/explainer/prepare.mjs +131 -0
- package/ai/skills/stacks-technical-diagrams/explainer/reader.css +472 -0
- package/ai/skills/stacks-technical-diagrams/explainer/reader.js +667 -0
- package/ai/skills/stacks-technical-diagrams/explainer/render.mjs +224 -0
- package/ai/skills/stacks-technical-diagrams/explainer/revision.mjs +20 -0
- package/ai/skills/stacks-technical-diagrams/explainer/sources.mjs +318 -0
- package/ai/skills/stacks-technical-diagrams/explainer/validate.mjs +138 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/LICENSE +40 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/README.md +5 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/3DKXF73K.js +4 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/42UTT654.js +3 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/DKTLEL5E.js +1 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/EEIX5ZYH.js +2 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/EJ5KOXYD.js +25 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/GUJTEFZK.js +1 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/IZOKQ2GT.js +4 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/L4LY553T.js +3 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/MSKIJHB2.js +2 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/RVARI57O.js +1 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/UKSIWDDN.js +2 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/UPTXNAXN.js +2 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/XTDUIGUI.js +9 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/YAYTP6L5.js +9 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/core.js +1 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/diagrams/pie.js +1 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/diagrams/quadrantChart.js +1 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/diagrams/radar.js +1 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/diagrams/sankey.js +1 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/diagrams/venn.js +1 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/diagrams/xychart.js +1 -0
- package/ai/skills/stacks-technical-diagrams/explainer/writing.mjs +139 -0
- package/ai/skills/stacks-technical-diagrams/locales/README.md +40 -0
- package/ai/skills/stacks-technical-diagrams/locales/ar.json +488 -0
- package/ai/skills/stacks-technical-diagrams/locales/en.json +488 -0
- package/ai/skills/stacks-technical-diagrams/locales/es.json +488 -0
- package/ai/skills/stacks-technical-diagrams/locales/ko.json +488 -0
- package/ai/skills/stacks-technical-diagrams/locales/manifest.json +10 -0
- package/ai/skills/stacks-technical-diagrams/locales/zh-CN.json +488 -0
- package/ai/skills/stacks-technical-diagrams/locales/zh-TW.json +488 -0
- package/ai/skills/stacks-technical-diagrams/migrations/workflow-v2.mjs +1 -0
- package/ai/skills/stacks-technical-diagrams/recipes/scenarios.mjs +115 -51
- package/ai/skills/stacks-technical-diagrams/references/architecture-layout-repair.md +18 -0
- package/ai/skills/stacks-technical-diagrams/references/authoring-contract.md +453 -51
- package/ai/skills/stacks-technical-diagrams/references/authoring-defaults.md +57 -0
- package/ai/skills/stacks-technical-diagrams/references/brand-marks.md +57 -3
- package/ai/skills/stacks-technical-diagrams/references/delivery-contract.md +603 -58
- package/ai/skills/stacks-technical-diagrams/references/explainer-authoring.md +274 -0
- package/ai/skills/stacks-technical-diagrams/references/repository-authoring.md +126 -0
- package/ai/skills/stacks-technical-diagrams/references/update-awareness.md +13 -0
- package/ai/skills/stacks-technical-diagrams/references/viewer-runtime.md +18 -11
- package/ai/skills/stacks-technical-diagrams/renderers/architecture/grid.mjs +1 -1
- package/ai/skills/stacks-technical-diagrams/renderers/architecture/labels.mjs +2 -0
- package/ai/skills/stacks-technical-diagrams/renderers/architecture/render-architecture.mjs +550 -424
- package/ai/skills/stacks-technical-diagrams/renderers/architecture/routing.mjs +1469 -0
- package/ai/skills/stacks-technical-diagrams/renderers/class/README.md +129 -0
- package/ai/skills/stacks-technical-diagrams/renderers/class/render-class.mjs +1095 -0
- package/ai/skills/stacks-technical-diagrams/renderers/dataflow/README.md +89 -17
- package/ai/skills/stacks-technical-diagrams/renderers/dataflow/dataflow-compiler.mjs +1605 -0
- package/ai/skills/stacks-technical-diagrams/renderers/dataflow/joint-label-routing.mjs +165 -0
- package/ai/skills/stacks-technical-diagrams/renderers/dataflow/label-capacity.mjs +81 -0
- package/ai/skills/stacks-technical-diagrams/renderers/dataflow/render-dataflow.mjs +14 -474
- package/ai/skills/stacks-technical-diagrams/renderers/erd/README.md +246 -0
- package/ai/skills/stacks-technical-diagrams/renderers/erd/grid.mjs +150 -0
- package/ai/skills/stacks-technical-diagrams/renderers/erd/render-erd.mjs +1588 -0
- package/ai/skills/stacks-technical-diagrams/renderers/explainer/render-explainer.mjs +42 -0
- package/ai/skills/stacks-technical-diagrams/renderers/lifecycle/README.md +83 -94
- package/ai/skills/stacks-technical-diagrams/renderers/lifecycle/render-lifecycle.mjs +990 -417
- package/ai/skills/stacks-technical-diagrams/renderers/sequence/README.md +49 -17
- package/ai/skills/stacks-technical-diagrams/renderers/sequence/render-sequence.mjs +735 -94
- package/ai/skills/stacks-technical-diagrams/renderers/shared/atomic-output.mjs +1982 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/automatic-labels.mjs +290 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/brand-marks.mjs +169 -26
- package/ai/skills/stacks-technical-diagrams/renderers/shared/cli.mjs +266 -54
- package/ai/skills/stacks-technical-diagrams/renderers/shared/desktop-readability.mjs +106 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/diagnostics.mjs +0 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/generated-validators.mjs +268 -2
- package/ai/skills/stacks-technical-diagrams/renderers/shared/geometry.mjs +774 -124
- package/ai/skills/stacks-technical-diagrams/renderers/shared/i18n.mjs +289 -556
- package/ai/skills/stacks-technical-diagrams/renderers/shared/layout-report.mjs +18 -1
- package/ai/skills/stacks-technical-diagrams/renderers/shared/legend.mjs +16 -6
- package/ai/skills/stacks-technical-diagrams/renderers/shared/node-card-style.mjs +32 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/output-path.mjs +329 -229
- package/ai/skills/stacks-technical-diagrams/renderers/shared/owned-temp-directory.mjs +82 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/path-semantics.mjs +1017 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/portable-path.mjs +408 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/repository-evidence.mjs +235 -79
- package/ai/skills/stacks-technical-diagrams/renderers/shared/repository-location.mjs +17 -4
- package/ai/skills/stacks-technical-diagrams/renderers/shared/route-quality.mjs +670 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/sidecar-path.mjs +38 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/software-notices.mjs +6 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/spatial-grid.mjs +66 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/svg-path-analysis.mjs +135 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/text-fit.mjs +59 -3
- package/ai/skills/stacks-technical-diagrams/renderers/shared/utils.mjs +63 -35
- package/ai/skills/stacks-technical-diagrams/renderers/shared/validator.mjs +2 -5
- package/ai/skills/stacks-technical-diagrams/renderers/timeline/README.md +76 -0
- package/ai/skills/stacks-technical-diagrams/renderers/timeline/render-timeline.mjs +576 -0
- package/ai/skills/stacks-technical-diagrams/renderers/tree/README.md +96 -0
- package/ai/skills/stacks-technical-diagrams/renderers/tree/render-tree.mjs +573 -0
- package/ai/skills/stacks-technical-diagrams/renderers/waterfall/README.md +73 -0
- package/ai/skills/stacks-technical-diagrams/renderers/waterfall/render-waterfall.mjs +413 -0
- package/ai/skills/stacks-technical-diagrams/renderers/workflow/README.md +137 -23
- package/ai/skills/stacks-technical-diagrams/renderers/workflow/render-workflow.mjs +18 -6
- package/ai/skills/stacks-technical-diagrams/renderers/workflow/workflow-compiler.mjs +2230 -710
- package/ai/skills/stacks-technical-diagrams/renderers/workflow/workflow-migration-geometry.mjs +17 -0
- package/ai/skills/stacks-technical-diagrams/renderers/workflow/workflow-placement-repair.mjs +94 -0
- package/ai/skills/stacks-technical-diagrams/schemas/README.md +87 -40
- package/ai/skills/stacks-technical-diagrams/schemas/architecture.schema.json +7 -33
- package/ai/skills/stacks-technical-diagrams/schemas/class.schema.json +345 -0
- package/ai/skills/stacks-technical-diagrams/schemas/common.schema.json +68 -2
- package/ai/skills/stacks-technical-diagrams/schemas/dataflow.schema.json +14 -3
- package/ai/skills/stacks-technical-diagrams/schemas/erd.schema.json +381 -0
- package/ai/skills/stacks-technical-diagrams/schemas/explainer.schema.json +927 -0
- package/ai/skills/stacks-technical-diagrams/schemas/lifecycle.schema.json +23 -110
- package/ai/skills/stacks-technical-diagrams/schemas/sequence.schema.json +15 -4
- package/ai/skills/stacks-technical-diagrams/schemas/timeline.schema.json +160 -0
- package/ai/skills/stacks-technical-diagrams/schemas/tree.schema.json +141 -0
- package/ai/skills/stacks-technical-diagrams/schemas/waterfall.schema.json +147 -0
- package/ai/skills/stacks-technical-diagrams/schemas/workflow.schema.json +14 -3
- package/ai/skills/stacks-technical-diagrams/scripts/check-render-output.mjs +876 -243
- package/ai/skills/stacks-technical-diagrams/scripts/check-update.mjs +1717 -0
- package/ai/skills/stacks-technical-diagrams/scripts/delivery-update-child.mjs +26 -0
- package/ai/skills/stacks-technical-diagrams/scripts/generate-brand-marks.mjs +141 -0
- package/ai/skills/stacks-technical-diagrams/scripts/generate-validators.mjs +105 -0
- package/ai/skills/stacks-technical-diagrams/scripts/render-examples.mjs +11 -1
- package/ai/skills/stacks-technical-diagrams/scripts/update-contract.mjs +187 -0
- package/ai/skills/stacks-technical-diagrams/skill-release.json +10 -0
- package/ide/vscode/package.json +1 -1
- package/package.json +2 -2
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# Built-in brand marks
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Archify ships a bounded catalogue of 107 commonly used brands for architecture,
|
|
4
4
|
workflow, sequence, data-flow, and lifecycle nodes. The mark is optional authored
|
|
5
5
|
identity: it never replaces the node's semantic `type`, color, label, or
|
|
6
6
|
relationships.
|
|
7
7
|
|
|
8
8
|
Unknown sites are handled by an explicit two-stage workflow. Run
|
|
9
|
-
|
|
9
|
+
`node bin/archify.mjs brands capture <url> --json`, then author the returned
|
|
10
10
|
digest-pinned `brand` value. Normal render and validate commands do not perform
|
|
11
11
|
an unpinned capture, and changed or unavailable content fails closed.
|
|
12
12
|
|
|
@@ -18,7 +18,7 @@ metadata in `renderers/shared/generated-brand-marks.mjs`.
|
|
|
18
18
|
Brand names and logos may be trademarks of their respective owners. Simple
|
|
19
19
|
Icons' CC0 license covers its collection work, not every underlying trademark or
|
|
20
20
|
artwork. Contributors must review the recorded source, current brand guidelines,
|
|
21
|
-
and intended referential use before adding or updating a mark.
|
|
21
|
+
and intended referential use before adding or updating a mark. Archify does not
|
|
22
22
|
imply sponsorship, endorsement, or partnership.
|
|
23
23
|
|
|
24
24
|
Edit `catalog.json`, then regenerate the committed zero-runtime-dependency bundle:
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { softwareNoticesHtml } from '../renderers/shared/software-notices.mjs';
|
|
1
2
|
import { parseRepositoryRemote } from '../renderers/shared/repository-location.mjs';
|
|
2
3
|
|
|
3
4
|
const COMPARATOR_VERSION = 1;
|
|
@@ -35,16 +36,42 @@ function sortedBy(values, keyFor) {
|
|
|
35
36
|
|
|
36
37
|
function normalizeRepository(repository) {
|
|
37
38
|
if (!repository) return undefined;
|
|
38
|
-
const location = parseRepositoryRemote(repository.url, { authored: true });
|
|
39
|
+
const location = parseRepositoryRemote(repository.url, { authored: true, provider: repository.provider });
|
|
39
40
|
const url = location?.url || String(repository.url || '');
|
|
40
41
|
return {
|
|
41
|
-
url: location?.provider === 'github' ? url.toLowerCase() : url,
|
|
42
|
+
url: location?.provider === 'github' || location?.provider === 'gitlab' ? url.toLowerCase() : url,
|
|
42
43
|
revision: String(repository.revision || '').toLowerCase(),
|
|
43
44
|
...(repository.provider !== undefined ? { provider: repository.provider } : {}),
|
|
44
45
|
...(repository.link_mode !== undefined ? { link_mode: repository.link_mode } : {}),
|
|
45
46
|
};
|
|
46
47
|
}
|
|
47
48
|
|
|
49
|
+
const PROVENANCE_FIELDS = ['url', 'revision', 'provider', 'link_mode'];
|
|
50
|
+
|
|
51
|
+
function provenanceSide(repository) {
|
|
52
|
+
if (!repository) return null;
|
|
53
|
+
return {
|
|
54
|
+
revision: repository.revision,
|
|
55
|
+
...(repository.provider !== undefined ? { provider: repository.provider } : {}),
|
|
56
|
+
...(repository.link_mode !== undefined ? { linkMode: repository.link_mode } : {}),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function provenanceChange(base, head) {
|
|
61
|
+
if (equal(base, head)) return undefined;
|
|
62
|
+
const changedFields = !base || !head
|
|
63
|
+
? ['/repository']
|
|
64
|
+
: PROVENANCE_FIELDS
|
|
65
|
+
.filter((field) => !equal(base[field], head[field]))
|
|
66
|
+
.map((field) => `/${field}`)
|
|
67
|
+
.sort(codepointOrder);
|
|
68
|
+
return {
|
|
69
|
+
changedFields,
|
|
70
|
+
base: provenanceSide(base),
|
|
71
|
+
head: provenanceSide(head),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
48
75
|
function normalizeComponent(component) {
|
|
49
76
|
return {
|
|
50
77
|
...component,
|
|
@@ -155,7 +182,7 @@ function fieldChanges(before, after, groups) {
|
|
|
155
182
|
}
|
|
156
183
|
|
|
157
184
|
const COMPONENT_FIELDS = {
|
|
158
|
-
semantic: ['type', 'label', 'sublabel', 'tag'],
|
|
185
|
+
semantic: ['type', 'label', 'sublabel', 'tag', 'brand', 'icon'],
|
|
159
186
|
evidence: ['sources'],
|
|
160
187
|
geometry: ['row', 'col', 'pos', 'size'],
|
|
161
188
|
};
|
|
@@ -202,26 +229,26 @@ function summaryFor(changes, shape) {
|
|
|
202
229
|
function presentationChanged(base, head) {
|
|
203
230
|
const basePresentation = {
|
|
204
231
|
title: base.meta?.title,
|
|
232
|
+
locale: base.meta?.locale,
|
|
205
233
|
subtitle: base.meta?.subtitle,
|
|
206
234
|
animation: base.meta?.animation,
|
|
207
235
|
visual_preset: base.meta?.visual_preset,
|
|
208
236
|
quality_profile: base.meta?.quality_profile,
|
|
209
237
|
engineering_profile: base.meta?.engineering_profile,
|
|
210
238
|
legend: base.meta?.legend,
|
|
211
|
-
views: base.meta?.views,
|
|
212
239
|
viewBox: base.meta?.viewBox,
|
|
213
240
|
layout: base.layout,
|
|
214
241
|
cards: base.cards,
|
|
215
242
|
};
|
|
216
243
|
const headPresentation = {
|
|
217
244
|
title: head.meta?.title,
|
|
245
|
+
locale: head.meta?.locale,
|
|
218
246
|
subtitle: head.meta?.subtitle,
|
|
219
247
|
animation: head.meta?.animation,
|
|
220
248
|
visual_preset: head.meta?.visual_preset,
|
|
221
249
|
quality_profile: head.meta?.quality_profile,
|
|
222
250
|
engineering_profile: head.meta?.engineering_profile,
|
|
223
251
|
legend: head.meta?.legend,
|
|
224
|
-
views: head.meta?.views,
|
|
225
252
|
viewBox: head.meta?.viewBox,
|
|
226
253
|
layout: head.layout,
|
|
227
254
|
cards: head.cards,
|
|
@@ -236,7 +263,7 @@ export function compareArchitecture(base, head, evidence = {}) {
|
|
|
236
263
|
const headComponents = stableIndex(head.components, 'components', 'head');
|
|
237
264
|
const shared = sorted([...baseComponents.keys()].filter((id) => headComponents.has(id)));
|
|
238
265
|
if (!shared.length) {
|
|
239
|
-
fail('delta/no-shared-component-id', 'The snapshots share no component id, so
|
|
266
|
+
fail('delta/no-shared-component-id', 'The snapshots share no component id, so Archify cannot prove that they describe the same system.', {
|
|
240
267
|
supportedFixes: ['preserve at least one authored component id across snapshots'],
|
|
241
268
|
});
|
|
242
269
|
}
|
|
@@ -248,7 +275,7 @@ export function compareArchitecture(base, head, evidence = {}) {
|
|
|
248
275
|
|
|
249
276
|
const baseRepository = normalizeRepository(base.meta?.repository);
|
|
250
277
|
const headRepository = normalizeRepository(head.meta?.repository);
|
|
251
|
-
const identity = (repository) => parseRepositoryRemote(repository.url, { authored: true })?.identity || repository.url;
|
|
278
|
+
const identity = (repository) => parseRepositoryRemote(repository.url, { authored: true, provider: repository.provider })?.identity || repository.url;
|
|
252
279
|
if (baseRepository && headRepository && identity(baseRepository) !== identity(headRepository)) {
|
|
253
280
|
fail('delta/repository-mismatch', 'The snapshots name different repositories.', {
|
|
254
281
|
baseRepository: baseRepository.url,
|
|
@@ -278,7 +305,8 @@ export function compareArchitecture(base, head, evidence = {}) {
|
|
|
278
305
|
kind: (after || before).kind,
|
|
279
306
|
label: (after || before).label,
|
|
280
307
|
}));
|
|
281
|
-
const
|
|
308
|
+
const provenance = provenanceChange(baseRepository, headRepository);
|
|
309
|
+
const provenanceChanged = Boolean(provenance);
|
|
282
310
|
|
|
283
311
|
return {
|
|
284
312
|
schemaVersion: 1,
|
|
@@ -311,6 +339,7 @@ export function compareArchitecture(base, head, evidence = {}) {
|
|
|
311
339
|
provenanceChanged,
|
|
312
340
|
},
|
|
313
341
|
changes: { components, connections, boundaries },
|
|
342
|
+
...(provenance ? { provenance } : {}),
|
|
314
343
|
identity: {
|
|
315
344
|
components: 'components[].id',
|
|
316
345
|
connections: 'connections[].id (required)',
|
|
@@ -462,11 +491,11 @@ export function annotateArchitectureSideSvg(svg, receipt, side) {
|
|
|
462
491
|
if (!change) return markup;
|
|
463
492
|
if (part === 'frame') {
|
|
464
493
|
return addState(markup, change, side)
|
|
465
|
-
.replace(/\/>$/, ` data-delta-boundary-key="${esc(change.key)}"/>`);
|
|
494
|
+
.replace(/\/>$/, () => ` data-delta-boundary-key="${esc(change.key)}"/>`);
|
|
466
495
|
}
|
|
467
496
|
return markup.replace(
|
|
468
497
|
/<text[^>]*>/,
|
|
469
|
-
(tag) => tag.replace(/>$/, ` data-delta-state="${change.status}" data-delta-boundary-state="${change.status}" data-delta-boundary-key="${esc(change.key)}">`),
|
|
498
|
+
(tag) => tag.replace(/>$/, () => ` data-delta-state="${change.status}" data-delta-boundary-state="${change.status}" data-delta-boundary-key="${esc(change.key)}">`),
|
|
470
499
|
);
|
|
471
500
|
});
|
|
472
501
|
result = transformNodeGroups(result, (group, id) => {
|
|
@@ -519,13 +548,13 @@ function boundaryMarkupParts(markup) {
|
|
|
519
548
|
|
|
520
549
|
function forceBoundaryState(markup, state, key, classifications = []) {
|
|
521
550
|
return markup
|
|
522
|
-
.replace(/^<rect[^>]+\/>/, (tag) => addState(tag, { classifications }, 'delta', state).replace(/\/>$/, ` data-delta-boundary-key="${esc(key)}"/>`))
|
|
551
|
+
.replace(/^<rect[^>]+\/>/, (tag) => addState(tag, { classifications }, 'delta', state).replace(/\/>$/, () => ` data-delta-boundary-key="${esc(key)}"/>`))
|
|
523
552
|
.replace(
|
|
524
553
|
/<rect data-graph-role="structural-frame-label-mask"[^>]*\/>/,
|
|
525
554
|
(tag) => addState(tag, { classifications }, 'delta', state)
|
|
526
|
-
.replace(/\/>$/, ` data-delta-boundary-state="${state}" data-delta-boundary-mask-key="${esc(key)}"/>`),
|
|
555
|
+
.replace(/\/>$/, () => ` data-delta-boundary-state="${state}" data-delta-boundary-mask-key="${esc(key)}"/>`),
|
|
527
556
|
)
|
|
528
|
-
.replace(/<text[^>]*>/, (tag) => tag.replace(/>$/, ` data-delta-state="${state}" data-delta-boundary-state="${state}" data-delta-boundary-key="${esc(key)}">`));
|
|
557
|
+
.replace(/<text[^>]*>/, (tag) => tag.replace(/>$/, () => ` data-delta-state="${state}" data-delta-boundary-state="${state}" data-delta-boundary-key="${esc(key)}">`));
|
|
529
558
|
}
|
|
530
559
|
|
|
531
560
|
function viewBoxSize(svg) {
|
|
@@ -553,6 +582,9 @@ function boundarySymbolMarkup(markup, state) {
|
|
|
553
582
|
export function buildDeltaSvg(baseSvg, headSvg, receipt) {
|
|
554
583
|
const [baseW, baseH] = viewBoxSize(baseSvg);
|
|
555
584
|
const [headW, headH] = viewBoxSize(headSvg);
|
|
585
|
+
// Baseline paths and their definitions must travel together in a namespace
|
|
586
|
+
// distinct from the current snapshot before the final Delta prefix is added.
|
|
587
|
+
const baseRelationshipsSvg = prefixSvgIds(baseSvg, 'base');
|
|
556
588
|
const nodes = changeMap(receipt.changes.components);
|
|
557
589
|
const edges = changeMap(receipt.changes.connections);
|
|
558
590
|
const boundaries = boundaryChangeMap(receipt.changes.boundaries);
|
|
@@ -569,11 +601,11 @@ export function buildDeltaSvg(baseSvg, headSvg, receipt) {
|
|
|
569
601
|
}
|
|
570
602
|
for (const change of edges.values()) {
|
|
571
603
|
if (change.status === 'removed' || change.classifications.includes('topology')) {
|
|
572
|
-
const phantom = forceElementState(elementById(
|
|
604
|
+
const phantom = forceElementState(elementById(baseRelationshipsSvg, 'edge', change.id), 'removed', change.classifications);
|
|
573
605
|
baseEdgePhantoms.push(phantom);
|
|
574
606
|
edgeMarkers.push(edgeSymbolMarkup(phantom, 'removed'));
|
|
575
607
|
} else if (change.classifications.includes('geometry')) {
|
|
576
|
-
const phantom = forceElementState(elementById(
|
|
608
|
+
const phantom = forceElementState(elementById(baseRelationshipsSvg, 'edge', change.id), 'moved-from', change.classifications);
|
|
577
609
|
baseEdgePhantoms.push(phantom);
|
|
578
610
|
edgeMarkers.push(edgeSymbolMarkup(phantom, 'moved-from'));
|
|
579
611
|
}
|
|
@@ -595,11 +627,17 @@ export function buildDeltaSvg(baseSvg, headSvg, receipt) {
|
|
|
595
627
|
}
|
|
596
628
|
}
|
|
597
629
|
|
|
630
|
+
// Insert generated markup literally: authored labels can contain replacement
|
|
631
|
+
// tokens such as $$, $&, and $` that string replacements would interpret.
|
|
598
632
|
let delta = annotateArchitectureSideSvg(headSvg, receipt, 'head');
|
|
633
|
+
if (baseEdgePhantoms.length) {
|
|
634
|
+
const baseDefinitions = baseRelationshipsSvg.match(/<defs>([\s\S]*?)<\/defs>/)?.[1] || '';
|
|
635
|
+
delta = delta.replace('</defs>', () => `${baseDefinitions}</defs>`);
|
|
636
|
+
}
|
|
599
637
|
delta = delta.replace(/^<svg[^>]+>/, (tag) => tag.replace(/viewBox="[^"]+"/, `viewBox="0 0 ${Math.max(baseW, headW) + 24} ${Math.max(baseH, headH) + 24}"`));
|
|
600
|
-
delta = delta.replace(' <!-- Boundaries (behind everything) -->', ` <!-- Baseline boundary frame phantoms -->\n${baseBoundaryFramePhantoms.filter(Boolean).join('\n')}\n\n <!-- Boundaries (behind everything) -->`);
|
|
601
|
-
delta = delta.replace(' <!-- Connection paths (before components for correct z-order) -->', ` <!-- Baseline relationship phantoms -->\n${baseEdgePhantoms.join('\n')}\n\n <!-- Connection paths (before components for correct z-order) -->`);
|
|
602
|
-
delta = delta.replace(' <!-- Components -->', ` <!-- Baseline boundary label phantoms (below current components) -->\n${baseBoundaryLabelPhantoms.filter(Boolean).join('\n')}\n\n <!-- Baseline removed and move-from component phantoms -->\n${baseNodePhantoms.join('\n')}\n\n <!-- Components -->`);
|
|
638
|
+
delta = delta.replace(' <!-- Boundaries (behind everything) -->', () => ` <!-- Baseline boundary frame phantoms -->\n${baseBoundaryFramePhantoms.filter(Boolean).join('\n')}\n\n <!-- Boundaries (behind everything) -->`);
|
|
639
|
+
delta = delta.replace(' <!-- Connection paths (before components for correct z-order) -->', () => ` <!-- Baseline relationship phantoms -->\n${baseEdgePhantoms.join('\n')}\n\n <!-- Connection paths (before components for correct z-order) -->`);
|
|
640
|
+
delta = delta.replace(' <!-- Components -->', () => ` <!-- Baseline boundary label phantoms (below current components) -->\n${baseBoundaryLabelPhantoms.filter(Boolean).join('\n')}\n\n <!-- Baseline removed and move-from component phantoms -->\n${baseNodePhantoms.join('\n')}\n\n <!-- Components -->`);
|
|
603
641
|
|
|
604
642
|
for (const change of edges.values()) {
|
|
605
643
|
if (change.status === 'added' || change.status === 'changed' || change.status === 'rerouted') {
|
|
@@ -612,7 +650,7 @@ export function buildDeltaSvg(baseSvg, headSvg, receipt) {
|
|
|
612
650
|
const renderedKey = `${change.kind}:${esc(change.label)}`;
|
|
613
651
|
boundaryMarkers.push(boundarySymbolMarkup(boundaryMarkupByKey(delta, renderedKey), change.status));
|
|
614
652
|
}
|
|
615
|
-
delta = delta.replace(' <!-- Legend -->', ` <!-- Delta relationship symbols -->\n${edgeMarkers.filter(Boolean).join('\n')}\n\n <!-- Delta boundary symbols -->\n${boundaryMarkers.filter(Boolean).join('\n')}\n\n <!-- Legend -->`);
|
|
653
|
+
delta = delta.replace(' <!-- Legend -->', () => ` <!-- Delta relationship symbols -->\n${edgeMarkers.filter(Boolean).join('\n')}\n\n <!-- Delta boundary symbols -->\n${boundaryMarkers.filter(Boolean).join('\n')}\n\n <!-- Legend -->`);
|
|
616
654
|
return prefixSvgIds(staticize(delta), 'delta');
|
|
617
655
|
}
|
|
618
656
|
|
|
@@ -694,15 +732,39 @@ function expectedReviewTargetSignature(row) {
|
|
|
694
732
|
|
|
695
733
|
const total = (summary, key) => summary.components[key] + summary.connections[key] + summary.boundaries[key];
|
|
696
734
|
|
|
735
|
+
function provenanceDetail(provenance) {
|
|
736
|
+
if (provenance === undefined) return 'Repository metadata changed; field details are unavailable in this receipt.';
|
|
737
|
+
const value = (side, field) => {
|
|
738
|
+
if (!side) return 'undeclared';
|
|
739
|
+
if (field === '/revision') return side.revision?.slice(0, 8) || 'none';
|
|
740
|
+
if (field === '/provider') return side.provider ?? 'automatic';
|
|
741
|
+
if (field === '/link_mode') return side.linkMode ?? 'default';
|
|
742
|
+
if (field === '/repository') return 'declared';
|
|
743
|
+
return 'changed';
|
|
744
|
+
};
|
|
745
|
+
return provenance.changedFields.map((field) => {
|
|
746
|
+
if (field === '/url') return '/url: repository location changed';
|
|
747
|
+
return `${field}: ${value(provenance.base, field)} → ${value(provenance.head, field)}`;
|
|
748
|
+
}).join(' · ');
|
|
749
|
+
}
|
|
750
|
+
|
|
697
751
|
export function renderArchitectureDeltaHtml({ receipt, baseSvg, deltaSvg, headSvg, baseHtml = '', headHtml = '', artifactCss }) {
|
|
698
752
|
const rows = architectureDeltaChangeRows(receipt);
|
|
699
753
|
const changed = total(receipt.summary, 'changed');
|
|
700
754
|
const proof = receipt.proofLevel === 'revision-pinned' ? 'REVISION-PINNED INPUTS' : 'AUTHORED SNAPSHOTS';
|
|
755
|
+
const provenanceChanged = receipt.summary.provenanceChanged === true;
|
|
756
|
+
const provenanceFields = receipt.provenance?.changedFields?.join(', ') || 'repository metadata';
|
|
757
|
+
const provenanceDescription = provenanceChanged ? provenanceDetail(receipt.provenance) : '';
|
|
758
|
+
const provenanceNotice = provenanceChanged
|
|
759
|
+
? `<aside class="provenance-change" data-provenance-changed="true" data-provenance-fields="${esc(provenanceFields)}"><strong>Repository provenance changed</strong><span>${esc(provenanceDescription)}</span></aside>`
|
|
760
|
+
: '';
|
|
701
761
|
const rowHtml = rows.length ? rows.map((row, index) => {
|
|
702
762
|
const label = row.headLabel || row.baseLabel || row.head?.label || row.base?.label || row.label || row.id;
|
|
703
763
|
const targetSignature = expectedReviewTargetSignature(row);
|
|
704
764
|
return `<li data-change-status="${esc(row.status)}"><button class="change-row" type="button" data-change-index="${index}" data-change-key="${esc(row.key)}" data-change-kind="${esc(row.kindKey)}" data-change-id="${esc(row.id)}" data-change-label="${esc(label)}" data-change-status="${esc(row.status)}" data-change-classifications="${esc(row.classifications.join(', '))}" data-change-target-signature="${esc(targetSignature)}"><span class="token">${esc(markerFor(row.status) || '~')}</span><span>${esc(row.kind)}</span><strong>${esc(label)}</strong><code>${esc(row.id)}</code><span>${esc(row.classifications.join(', '))}</span><span>${esc(row.changedFields.join(', ') || 'identity')}</span></button></li>`;
|
|
705
|
-
}).join('\n') :
|
|
765
|
+
}).join('\n') : provenanceChanged
|
|
766
|
+
? '<li class="empty">No component, relationship, or boundary changes; repository provenance changed.</li>'
|
|
767
|
+
: '<li class="empty">No authored architecture changes.</li>';
|
|
706
768
|
const baseView = baseHtml
|
|
707
769
|
? `<iframe class="snapshot-frame" title="Before architecture explorer" srcdoc="${esc(baseHtml)}"></iframe>`
|
|
708
770
|
: baseSvg;
|
|
@@ -711,23 +773,24 @@ export function renderArchitectureDeltaHtml({ receipt, baseSvg, deltaSvg, headSv
|
|
|
711
773
|
: headSvg;
|
|
712
774
|
const html = `<!doctype html>
|
|
713
775
|
<html lang="en" data-theme="dark" data-preset="${esc(receipt.view.visualPreset)}">
|
|
714
|
-
<head><meta charset="utf-8"
|
|
776
|
+
<head><meta charset="utf-8">${softwareNoticesHtml}<meta name="viewport" content="width=device-width,initial-scale=1"><title>${esc(receipt.head.title)} Architecture Delta</title>
|
|
715
777
|
<style>
|
|
716
778
|
${artifactCss}
|
|
717
779
|
:root{color-scheme:dark;--d-add:#34d399;--d-remove:#fb7185;--d-change:#fbbf24;--d-move:#7dd3fc;--d-focus:#7dd3fc;--d-ink:#e6edf5;--d-muted:#8aa0b5;--d-line:#25384a}
|
|
718
780
|
*{box-sizing:border-box}body{margin:0;overflow-x:hidden;background:#071019;color:var(--d-ink);font-family:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,monospace}.proof-page{width:min(1600px,calc(100vw - 64px));margin:auto;padding:30px 0 42px}.proof-head{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:28px;align-items:end;padding-bottom:20px;border-bottom:1px solid var(--d-line)}.eyebrow{margin:0 0 8px;color:#7dd3fc;font:700 11px/1.2 ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.14em}.proof-head h1{margin:0;font-size:clamp(32px,4vw,56px);line-height:.96;letter-spacing:-.04em}.subtitle{margin:12px 0 0;color:var(--d-muted);font-size:14px}.metrics{display:flex;gap:9px}.metric{min-width:86px;padding:11px 13px;border:1px solid var(--d-line);border-radius:8px;background:#0b1722}.metric strong{display:block;font:700 23px/1 ui-monospace,SFMono-Regular,Menlo,monospace}.metric span{display:block;margin-top:6px;color:var(--d-muted);font:700 9px/1 ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.1em}.add strong{color:var(--d-add)}.remove strong{color:var(--d-remove)}.change strong{color:var(--d-change)}
|
|
719
781
|
.proof-tools{display:flex;align-items:center;justify-content:space-between;gap:20px;margin:16px 0 10px}.view-switch{display:inline-flex;padding:3px;border:1px solid var(--d-line);border-radius:8px;background:#0a141e}.view-switch button,.utility,.review-step{border:0;border-radius:6px;background:transparent;color:var(--d-muted);padding:8px 14px;font:700 11px/1 ui-monospace,SFMono-Regular,Menlo,monospace;cursor:pointer}.view-switch button[aria-selected="true"]{background:#173047;color:#fff}.utility{border:1px solid var(--d-line)}.view-switch button:focus-visible,.utility:focus-visible,.review-step:focus-visible,.change-row:focus-visible{outline:2px solid var(--d-focus);outline-offset:2px}.utility:disabled,.review-step:disabled{cursor:not-allowed;opacity:.45}.legend{display:flex;gap:16px;color:var(--d-muted);font:650 10px/1 ui-monospace,SFMono-Regular,Menlo,monospace}.legend span{display:inline-flex;align-items:center;gap:6px}.legend i{width:22px;border-top:3px solid currentColor}.legend .add{color:var(--d-add)}.legend .remove{color:var(--d-remove)}.legend .remove i{border-top-style:dashed}.legend .change{color:var(--d-change)}.legend .change i{border-top-style:dotted}.legend .move{color:var(--d-move)}.legend .move i{border-top-style:double}
|
|
782
|
+
.provenance-change{display:flex;align-items:center;gap:12px;margin:14px 0 0;padding:10px 13px;border:1px solid rgba(125,211,252,.45);border-radius:8px;background:rgba(125,211,252,.07);color:var(--d-muted);font:650 11px/1.35 ui-monospace,SFMono-Regular,Menlo,monospace}.provenance-change strong{color:var(--d-focus)}.provenance-change span{margin-left:auto;color:var(--d-muted)}
|
|
720
783
|
.review-strip{display:grid;grid-template-columns:auto auto auto auto minmax(0,1fr);align-items:center;gap:5px;margin:0 0 10px;padding:7px 8px;border-block:1px solid var(--d-line);font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.review-step{min-height:34px;border:1px solid var(--d-line);padding-inline:11px}.review-step[aria-pressed="true"]{border-color:var(--d-focus);color:var(--d-ink)}.review-status{min-width:0;padding-left:9px;color:var(--d-muted);font-size:10px;line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.review-status strong{color:var(--d-ink);font-weight:750}.review-status[data-state="unavailable"]{color:var(--d-remove)}
|
|
721
784
|
.canvas{overflow:hidden;border:1px solid var(--d-line);border-radius:10px;background:#09141e;padding:12px;min-height:520px}.canvas svg{display:block;width:100%;height:auto;max-height:72vh}.canvas[hidden]{display:none}.snapshot-frame{display:block;width:100%;height:min(76vh,920px);min-height:620px;border:0;border-radius:6px;background:#071019}.canvas[data-view="base"],.canvas[data-view="head"]{padding:0}.canvas[data-view="delta"] [data-delta-state="same"]{opacity:.38}.canvas[data-delta-review-active]{--review-same-opacity:.14;--review-change-opacity:.28}.canvas[data-delta-review-active] [data-delta-state="same"]{opacity:var(--review-same-opacity)!important}.canvas[data-delta-review-active] [data-delta-state]:not([data-delta-state="same"]):not([data-delta-review-current]){opacity:var(--review-change-opacity)!important}.canvas[data-delta-review-active] [data-delta-review-current]{opacity:1!important;transition:opacity .16s ease-out}g[data-node-id][data-delta-state="added"]>rect:last-of-type{stroke:var(--d-add)!important;stroke-width:3!important}g[data-node-id][data-delta-state="removed"]>rect:last-of-type{stroke:var(--d-remove)!important;stroke-width:3!important;stroke-dasharray:7 5}g[data-node-id][data-delta-state="changed"]>rect:last-of-type{stroke:var(--d-change)!important;stroke-width:3!important;stroke-dasharray:2 3}g[data-node-id][data-delta-state="moved"]>rect:last-of-type,g[data-node-id][data-delta-state="moved-from"]>rect:last-of-type{stroke:var(--d-move)!important;stroke-width:3!important;stroke-dasharray:8 3 2 3}g[data-node-id][data-delta-state="moved-from"],path[data-delta-state="moved-from"]{opacity:.42}path[data-delta-state="added"]{stroke:var(--d-add)!important;stroke-width:3!important}path[data-delta-state="removed"]{stroke:var(--d-remove)!important;stroke-width:3!important;stroke-dasharray:7 5!important}path[data-delta-state="changed"]{stroke:var(--d-change)!important;stroke-width:3!important;stroke-dasharray:2 3!important}path[data-delta-state="rerouted"],path[data-delta-state="moved-from"]{stroke:var(--d-move)!important;stroke-width:2.5!important;stroke-dasharray:8 3 2 3!important}.delta-node-marker circle{fill:#071019;stroke:currentColor;stroke-width:1.5}.delta-node-marker text,.delta-edge-marker,.delta-boundary-marker{fill:currentColor;font:800 9px ui-monospace,SFMono-Regular,Menlo,monospace}[data-delta-state="added"] .delta-node-marker,.delta-edge-marker[data-delta-state="added"],.delta-boundary-marker[data-delta-state="added"]{color:var(--d-add)}[data-delta-state="removed"] .delta-node-marker,.delta-edge-marker[data-delta-state="removed"],.delta-boundary-marker[data-delta-state="removed"]{color:var(--d-remove)}[data-delta-state="changed"] .delta-node-marker,.delta-edge-marker[data-delta-state="changed"],.delta-boundary-marker[data-delta-state="changed"]{color:var(--d-change)}[data-delta-state="moved"] .delta-node-marker,[data-delta-state="moved-from"] .delta-node-marker,.delta-edge-marker[data-delta-state="moved-from"],.delta-edge-marker[data-delta-state="rerouted"],.delta-boundary-marker[data-delta-state="geometry-changed"]{color:var(--d-move)}.delta-edge-marker,.delta-boundary-marker{paint-order:stroke;stroke:#071019;stroke-width:3px}
|
|
722
785
|
rect[data-graph-role="structural-frame"][data-delta-state="added"]{stroke:var(--d-add)!important;stroke-width:2.5!important}rect[data-graph-role="structural-frame"][data-delta-state="removed"]{stroke:var(--d-remove)!important;stroke-width:2.5!important;stroke-dasharray:7 5!important}rect[data-graph-role="structural-frame"][data-delta-state="changed"]{stroke:var(--d-change)!important;stroke-width:2.5!important;stroke-dasharray:2 3!important}rect[data-graph-role="structural-frame"][data-delta-state="moved-from"]{stroke:var(--d-move)!important;stroke-width:2!important;stroke-dasharray:8 3 2 3!important;opacity:.42}text[data-delta-boundary-state="added"]{fill:var(--d-add)!important}text[data-delta-boundary-state="removed"]{fill:var(--d-remove)!important}text[data-delta-boundary-state="changed"]{fill:var(--d-change)!important}text[data-delta-boundary-state="moved-from"]{fill:var(--d-move)!important;opacity:.55}
|
|
723
786
|
details{margin-top:12px;border:1px solid var(--d-line);border-radius:9px;background:#0a141e}summary{padding:13px 15px;cursor:pointer;font-weight:700}.changes{list-style:none;margin:0;padding:0 8px 8px}.changes li{border-top:1px solid rgba(138,160,181,.16)}.change-row{display:grid;grid-template-columns:30px 90px minmax(140px,1fr) minmax(100px,.7fr) minmax(120px,.8fr) minmax(140px,1.2fr);gap:10px;width:100%;margin:0;padding:9px 7px;border:0;border-radius:5px;background:transparent;color:inherit;font:inherit;font-size:11px;text-align:left;align-items:baseline;cursor:pointer}.change-row:hover{background:rgba(125,211,252,.06)}.change-row[aria-current="step"]{background:rgba(125,211,252,.1);box-shadow:inset 0 0 0 1px var(--d-focus)}.change-row:disabled{cursor:default}.token{font:800 13px/1 ui-monospace,SFMono-Regular,Menlo,monospace}.changes code,.change-row>span:last-child{color:var(--d-muted)}.proof-foot{display:flex;justify-content:space-between;gap:24px;margin-top:14px;color:var(--d-muted);font:650 10px/1.4 ui-monospace,SFMono-Regular,Menlo,monospace}
|
|
724
787
|
html[data-theme="dark"] body{background:#071019!important;background-image:none!important}html[data-theme="light"]{color-scheme:light;--d-ink:#10283c;--d-muted:#587187;--d-line:#c8d6e2;--d-focus:#006b8f}html[data-theme="light"] body{background:#eef3f7!important;background-image:none!important;color:var(--d-ink)}html[data-theme="light"] .metric,html[data-theme="light"] .view-switch,html[data-theme="light"] details{background:#fff}html[data-theme="light"] .canvas{background:#f8fbfd}html[data-theme="light"] .view-switch button[aria-selected="true"]{background:#dbeaf5;color:#10283c}html[data-theme="light"] .delta-node-marker circle{fill:#fff}html[data-preset="blueprint"] body{background-image:none!important}
|
|
725
|
-
@media(max-width:760px){.proof-page{width:100%;padding:12px}.proof-head{grid-template-columns:1fr;gap:14px;align-items:start}.proof-head h1{font-size:32px}.metrics{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));width:100%}.metric{min-width:0}.proof-tools{align-items:stretch;flex-wrap:wrap;gap:8px}.view-switch{display:flex;flex:1 1 100%}.view-switch button{flex:1;padding-inline:8px}.legend{flex-wrap:wrap;gap:8px}.proof-tools>div:last-child{margin-left:auto}.review-strip{grid-template-columns:auto auto auto auto}.review-status{grid-column:1/-1;padding:4px 2px 0}.canvas{min-height:0;padding:6px;overflow:auto}.canvas svg{min-width:720px;max-height:none}.snapshot-frame{min-width:720px}.changes{overflow-x:auto}.change-row{min-width:820px}.proof-foot{flex-direction:column;gap:4px}}
|
|
788
|
+
@media(max-width:760px){.proof-page{width:100%;padding:12px}.proof-head{grid-template-columns:1fr;gap:14px;align-items:start}.proof-head h1{font-size:32px}.metrics{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));width:100%}.metric{min-width:0}.provenance-change{align-items:flex-start;flex-wrap:wrap}.provenance-change span{width:100%;margin-left:0}.proof-tools{align-items:stretch;flex-wrap:wrap;gap:8px}.view-switch{display:flex;flex:1 1 100%}.view-switch button{flex:1;padding-inline:8px}.legend{flex-wrap:wrap;gap:8px}.proof-tools>div:last-child{margin-left:auto}.review-strip{grid-template-columns:auto auto auto auto}.review-status{grid-column:1/-1;padding:4px 2px 0}.canvas{min-height:0;padding:6px;overflow:auto}.canvas svg{min-width:720px;max-height:none}.snapshot-frame{min-width:720px}.changes{overflow-x:auto}.change-row{min-width:820px}.proof-foot{flex-direction:column;gap:4px}}
|
|
726
789
|
@media(prefers-reduced-motion:reduce){*{scroll-behavior:auto!important}.canvas[data-delta-review-active] [data-delta-review-current]{transition:none!important}}@media print{body{min-width:0;background:#fff;color:#111}.proof-page{width:100%;padding:0}.proof-tools,.review-strip,details{display:none!important}.canvas{display:none!important}.canvas[data-view="delta"]{display:block!important;border:0}.canvas[data-view="delta"] [data-delta-state="same"]{opacity:1!important;transition:none!important}.canvas[data-delta-review-active]{--review-same-opacity:1;--review-change-opacity:1}.canvas[data-delta-review-active] [data-delta-review-current]{opacity:1!important;transition:none!important}.proof-foot{color:#444}}
|
|
727
790
|
</style></head>
|
|
728
|
-
<body><main class="proof-page"><header class="proof-head"><div><p class="eyebrow">ARCHITECTURE DELTA · ${proof}</p><h1>See what changed<br>before you merge.</h1><p class="subtitle">${esc(receipt.base.title)} → ${esc(receipt.head.title)}</p></div><div class="metrics"><div class="metric add"><strong>${total(receipt.summary, 'added')}</strong><span>ADDED</span></div><div class="metric remove"><strong>${total(receipt.summary, 'removed')}</strong><span>REMOVED</span></div><div class="metric change"><strong>${changed}</strong><span>CHANGED</span></div></div></header
|
|
791
|
+
<body><main class="proof-page"><header class="proof-head"><div><p class="eyebrow">ARCHITECTURE DELTA · ${proof}</p><h1>See what changed<br>before you merge.</h1><p class="subtitle">${esc(receipt.base.title)} → ${esc(receipt.head.title)}</p></div><div class="metrics"><div class="metric add"><strong>${total(receipt.summary, 'added')}</strong><span>ADDED</span></div><div class="metric remove"><strong>${total(receipt.summary, 'removed')}</strong><span>REMOVED</span></div><div class="metric change"><strong>${changed}</strong><span>CHANGED</span></div></div></header>${provenanceNotice}
|
|
729
792
|
<div class="proof-tools"><div class="view-switch" role="tablist" aria-label="Architecture snapshot"><button role="tab" data-target="base" aria-selected="false">Before</button><button role="tab" data-target="delta" aria-selected="true">Delta</button><button role="tab" data-target="head" aria-selected="false">After</button></div><div class="legend"><span class="add"><i></i>+ ADD</span><span class="remove"><i></i>− DEL</span><span class="change"><i></i>~ MOD</span><span class="move"><i></i>↔ MOVE</span></div><div><button class="utility" id="export-svg" type="button">Export SVG</button> <button class="utility" id="share-card" type="button">Share Card</button> <button class="utility" id="preset" type="button">Preset</button> <button class="utility" id="theme" type="button">Theme</button></div></div>
|
|
730
|
-
<nav class="review-strip" aria-label="Authored change review"><button class="review-step" id="review-overview" type="button" disabled>Overview</button><button class="review-step" id="review-previous" type="button" aria-label="Previous authored change" disabled>←</button><button class="review-step" id="review-play" type="button" aria-pressed="false"${rows.length ? '' : ' disabled'}>Review</button><button class="review-step" id="review-next" type="button" aria-label="Next authored change" disabled>→</button><div class="review-status" id="review-status" role="status" aria-live="polite">Overview · ${rows.length} authored changes</div></nav>
|
|
793
|
+
<nav class="review-strip" aria-label="Authored change review"><button class="review-step" id="review-overview" type="button" disabled>Overview</button><button class="review-step" id="review-previous" type="button" aria-label="Previous authored change" disabled>←</button><button class="review-step" id="review-play" type="button" aria-pressed="false"${rows.length ? '' : ' disabled'}>Review</button><button class="review-step" id="review-next" type="button" aria-label="Next authored change" disabled>→</button><div class="review-status" id="review-status" role="status" aria-live="polite">Overview · ${rows.length} authored ${provenanceChanged ? 'graph changes · provenance changed' : 'changes'}</div></nav>
|
|
731
794
|
<section class="canvas" data-view="base" hidden>${baseView}</section><section class="canvas" data-view="delta">${deltaSvg}</section><section class="canvas" data-view="head" hidden>${headView}</section>
|
|
732
795
|
<details${rows.length <= 10 ? ' open' : ''}><summary>Exact authored changes · ${rows.length}</summary><ul class="changes">${rowHtml}</ul></details>
|
|
733
796
|
<footer class="proof-foot"><span>Stable IDs only · completeness: complete · ${proof}</span><span>Authored IR only · no risk or mergeability inference</span></footer></main>
|
|
@@ -937,6 +1000,10 @@ html[data-theme="dark"] body{background:#071019!important;background-image:none!
|
|
|
937
1000
|
const source = deltaCanvas?.querySelector(':scope > svg');
|
|
938
1001
|
if (!source) throw new Error('Canonical Delta SVG is unavailable.');
|
|
939
1002
|
const clone = source.cloneNode(true);
|
|
1003
|
+
const metadata = document.createElementNS('http://www.w3.org/2000/svg', 'metadata');
|
|
1004
|
+
metadata.setAttribute('id', 'archify-software-notices');
|
|
1005
|
+
metadata.textContent = JSON.parse(document.getElementById('archify-software-notices').textContent);
|
|
1006
|
+
clone.insertBefore(metadata, clone.firstChild);
|
|
940
1007
|
clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
|
|
941
1008
|
clone.removeAttribute('style');
|
|
942
1009
|
clone.querySelectorAll('[data-delta-review-current]').forEach((element) => element.removeAttribute('data-delta-review-current'));
|
|
@@ -957,7 +1024,9 @@ html[data-theme="dark"] body{background:#071019!important;background-image:none!
|
|
|
957
1024
|
'text[data-delta-boundary-state="added"]{fill:#34d399!important}text[data-delta-boundary-state="removed"]{fill:#fb7185!important}text[data-delta-boundary-state="changed"]{fill:#fbbf24!important}text[data-delta-boundary-state="moved-from"]{fill:#7dd3fc!important;opacity:.55}' +
|
|
958
1025
|
'.delta-node-marker circle{fill:#071019;stroke:currentColor;stroke-width:1.5}.delta-node-marker text,.delta-edge-marker,.delta-boundary-marker{fill:currentColor;font:800 9px ui-monospace,SFMono-Regular,Menlo,monospace}';
|
|
959
1026
|
clone.insertBefore(style, clone.firstChild);
|
|
960
|
-
|
|
1027
|
+
// The XML declaration pins UTF-8: without it, consumers that guess an
|
|
1028
|
+
// encoding instead of defaulting to UTF-8 mangle non-ASCII text.
|
|
1029
|
+
return '<?xml version="1.0" encoding="UTF-8"?>\\n' + new XMLSerializer().serializeToString(clone);
|
|
961
1030
|
}
|
|
962
1031
|
|
|
963
1032
|
function artifactName(suffix) {
|
|
@@ -1041,18 +1110,31 @@ html[data-theme="dark"] body{background:#071019!important;background-image:none!
|
|
|
1041
1110
|
ctx.fillText(connectionLine, 420, 151);
|
|
1042
1111
|
ctx.fillText(boundaryLine, 786, 151);
|
|
1043
1112
|
ctx.font = '650 14px ui-monospace, SFMono-Regular, Menlo, monospace';
|
|
1044
|
-
const
|
|
1045
|
-
|
|
1046
|
-
return sum + summary.added + summary.changed + summary.removed;
|
|
1047
|
-
}, 0);
|
|
1113
|
+
const graphChanges = ['components', 'connections', 'boundaries'].reduce((sum, collection) => sum + (receipt.changes[collection] || []).length, 0);
|
|
1114
|
+
const provenanceSummary = ${safeJson(provenanceChanged ? `provenance changed · ${provenanceFields}` : '')};
|
|
1048
1115
|
const movementSummary = '↔ moved ' + receipt.summary.components.moved + ' · rerouted ' + receipt.summary.connections.rerouted + ' · presentation ' + (receipt.summary.presentationChanged ? 'changed' : 'unchanged');
|
|
1049
|
-
const secondary =
|
|
1050
|
-
?
|
|
1051
|
-
|
|
1052
|
-
|
|
1116
|
+
const secondary = graphChanges === 0
|
|
1117
|
+
? receipt.summary.provenanceChanged
|
|
1118
|
+
? 'No graph changes · ' + provenanceSummary
|
|
1119
|
+
: 'No authored architecture changes · ' + movementSummary
|
|
1120
|
+
: movementSummary + (provenanceSummary ? ' · ' + provenanceSummary : '');
|
|
1053
1121
|
const proofLine = receipt.proofLevel === 'revision-pinned'
|
|
1054
1122
|
? 'REV ' + String(receipt.base.revision).slice(0, 8) + ' → ' + String(receipt.head.revision).slice(0, 8) + ' · REVISION-PINNED INPUTS'
|
|
1055
1123
|
: 'AUTHORED SNAPSHOTS';
|
|
1124
|
+
function fitCanvasLine(text, maxWidth) {
|
|
1125
|
+
if (ctx.measureText(text).width <= maxWidth) return text;
|
|
1126
|
+
let low = 0;
|
|
1127
|
+
let high = text.length;
|
|
1128
|
+
while (low < high) {
|
|
1129
|
+
const middle = Math.ceil((low + high) / 2);
|
|
1130
|
+
if (ctx.measureText(text.slice(0, middle) + '…').width <= maxWidth) low = middle;
|
|
1131
|
+
else high = middle - 1;
|
|
1132
|
+
}
|
|
1133
|
+
return text.slice(0, low).trimEnd() + '…';
|
|
1134
|
+
}
|
|
1135
|
+
const proofWidth = ctx.measureText(proofLine).width;
|
|
1136
|
+
const secondaryWidth = Math.max(0, 1044 - proofWidth);
|
|
1137
|
+
ctx.fillText(fitCanvasLine(secondary, secondaryWidth), 66, 181);
|
|
1056
1138
|
ctx.textAlign = 'right';
|
|
1057
1139
|
ctx.fillText(proofLine, 1134, 181);
|
|
1058
1140
|
ctx.textAlign = 'left';
|
|
@@ -1185,6 +1267,21 @@ export function validateArchitectureDeltaHtml(html, receipt) {
|
|
|
1185
1267
|
}
|
|
1186
1268
|
if (!svgBalanced || svgDepth !== 0 || svgRoots !== 1 || deltaMarkup.slice(0, rootStart).trim() || deltaMarkup.slice(rootEnd).trim()) failures.push('expected exactly one root SVG in the Delta canvas');
|
|
1187
1269
|
if ((html.match(/id="archify-compare-receipt"/g) || []).length !== 1) failures.push('expected exactly one embedded compare receipt');
|
|
1270
|
+
const provenanceChanged = receipt.summary?.provenanceChanged === true;
|
|
1271
|
+
const provenanceNotices = (html.match(/data-provenance-changed="true"/g) || []).length;
|
|
1272
|
+
const provenanceFields = receipt.provenance?.changedFields;
|
|
1273
|
+
const legacyProvenance = receipt.provenance === undefined;
|
|
1274
|
+
const validProvenanceFields = Array.isArray(provenanceFields) && provenanceFields.length > 0;
|
|
1275
|
+
const provenanceDescription = provenanceChanged && (legacyProvenance || validProvenanceFields) ? provenanceDetail(receipt.provenance) : '';
|
|
1276
|
+
const provenanceFieldLabel = legacyProvenance ? 'repository metadata' : validProvenanceFields ? provenanceFields.join(', ') : '';
|
|
1277
|
+
if (provenanceNotices !== (provenanceChanged ? 1 : 0)
|
|
1278
|
+
|| (!provenanceChanged && !legacyProvenance)
|
|
1279
|
+
|| (provenanceChanged && !legacyProvenance && !validProvenanceFields)
|
|
1280
|
+
|| (provenanceChanged && !html.includes(`data-provenance-fields="${esc(provenanceFieldLabel)}"`))
|
|
1281
|
+
|| (provenanceChanged && !html.includes(`<span>${esc(provenanceDescription)}</span>`))) {
|
|
1282
|
+
failures.push('provenance change notice does not match the receipt');
|
|
1283
|
+
}
|
|
1284
|
+
if (provenanceChanged && rows.length === 0 && html.includes('No authored architecture changes.')) failures.push('provenance-only delta claims no authored changes');
|
|
1188
1285
|
if (!html.includes('aria-label="Authored change review"')) failures.push('missing exact-ID change navigator');
|
|
1189
1286
|
if ((html.match(/class="change-row"/g) || []).length !== rows.length) failures.push('change navigator row count does not match the receipt');
|
|
1190
1287
|
if (!html.includes('id="export-svg"') || !html.includes('id="share-card"')
|
|
@@ -1,43 +1,38 @@
|
|
|
1
1
|
{
|
|
2
|
-
"schema_version":
|
|
2
|
+
"schema_version": 3,
|
|
3
3
|
"diagram_type": "lifecycle",
|
|
4
4
|
"meta": {
|
|
5
5
|
"title": "Agent Run Lifecycle",
|
|
6
6
|
"output": "examples/lifecycle-agent-run.html",
|
|
7
|
-
"viewBox": [1030, 630],
|
|
8
7
|
"animation": "trace",
|
|
9
|
-
"quality_profile": "showcase"
|
|
10
|
-
"views": [
|
|
11
|
-
{ "id": "main-lifecycle", "label": "Main lifecycle", "focus": ["queued", "planning", "executing", "reviewing", "completed"], "note": "Follow the ordered phases from accepted request to completed response." },
|
|
12
|
-
{ "id": "human-waits", "label": "Human and input waits", "focus": ["executing", "approval", "reviewing", "blocked"], "note": "See where the run pauses without becoming terminal." },
|
|
13
|
-
{ "id": "recovery-and-exits", "label": "Recovery and terminal exits", "focus": ["executing", "failed", "blocked", "cancelled", "expired"], "note": "Separate retryable failure from cancellation and expiry." }
|
|
14
|
-
]
|
|
8
|
+
"quality_profile": "showcase"
|
|
15
9
|
},
|
|
16
|
-
"
|
|
17
|
-
{ "id": "main", "label": "Lifecycle phases" },
|
|
18
|
-
{ "id": "waiting", "label": "Interruptions" },
|
|
19
|
-
{ "id": "exceptions", "label": "Recovery loop" },
|
|
20
|
-
{ "id": "terminal", "label": "Terminal exits" }
|
|
21
|
-
],
|
|
10
|
+
"mainPath": ["queued", "planning", "executing", "reviewing", "completed"],
|
|
22
11
|
"states": [
|
|
23
|
-
{ "id": "queued", "type": "start", "label": "Queued", "sublabel": "request accepted", "
|
|
24
|
-
{ "id": "planning", "type": "active", "label": "Planning", "sublabel": "build task graph", "
|
|
25
|
-
{ "id": "executing", "type": "active", "label": "Executing", "sublabel": "tool calls", "
|
|
26
|
-
{ "id": "reviewing", "type": "decision", "label": "Reviewing", "sublabel": "quality gate", "
|
|
27
|
-
{ "id": "completed", "type": "success", "label": "Completed", "sublabel": "final response", "
|
|
28
|
-
{ "id": "approval", "type": "waiting", "label": "Needs Approval", "sublabel": "human gate", "
|
|
29
|
-
{ "id": "
|
|
30
|
-
{ "id": "
|
|
31
|
-
{ "id": "cancelled", "type": "failure", "label": "Cancelled", "sublabel": "user stopped", "
|
|
32
|
-
{ "id": "expired", "type": "failure", "label": "Expired", "sublabel": "timeout", "
|
|
12
|
+
{ "id": "queued", "type": "start", "label": "Queued", "sublabel": "request accepted", "tag": "entry", "step": "01" },
|
|
13
|
+
{ "id": "planning", "type": "active", "label": "Planning", "sublabel": "build task graph", "tag": "model", "step": "02" },
|
|
14
|
+
{ "id": "executing", "type": "active", "label": "Executing", "sublabel": "tool calls", "tag": "work", "step": "03" },
|
|
15
|
+
{ "id": "reviewing", "type": "decision", "label": "Reviewing", "sublabel": "quality gate", "tag": "check", "step": "04" },
|
|
16
|
+
{ "id": "completed", "type": "success", "label": "Completed", "sublabel": "final response", "tag": "done", "step": "05" },
|
|
17
|
+
{ "id": "approval", "type": "waiting", "label": "Needs Approval", "sublabel": "human gate", "tag": "pause" },
|
|
18
|
+
{ "id": "failed", "type": "failure", "label": "Failed", "sublabel": "recoverable error", "tag": "retryable" },
|
|
19
|
+
{ "id": "blocked", "type": "waiting", "label": "Blocked", "sublabel": "missing input", "tag": "wait" },
|
|
20
|
+
{ "id": "cancelled", "type": "failure", "label": "Cancelled", "sublabel": "user stopped", "tag": "terminal" },
|
|
21
|
+
{ "id": "expired", "type": "failure", "label": "Expired", "sublabel": "timeout", "tag": "terminal" }
|
|
33
22
|
],
|
|
34
23
|
"transitions": [
|
|
35
|
-
{ "id": "
|
|
36
|
-
{ "id": "
|
|
37
|
-
{ "id": "
|
|
38
|
-
{ "id": "
|
|
39
|
-
{ "id": "
|
|
40
|
-
{ "id": "approval-
|
|
24
|
+
{ "id": "queued-planning", "from": "queued", "to": "planning", "label": "start" },
|
|
25
|
+
{ "id": "planning-executing", "from": "planning", "to": "executing", "label": "plan ready" },
|
|
26
|
+
{ "id": "executing-reviewing", "from": "executing", "to": "reviewing", "label": "steps done" },
|
|
27
|
+
{ "id": "reviewing-completed", "from": "reviewing", "to": "completed", "label": "pass" },
|
|
28
|
+
{ "id": "executing-approval", "from": "executing", "to": "approval", "label": "risky tool", "variant": "security" },
|
|
29
|
+
{ "id": "approval-executing", "from": "approval", "to": "executing", "label": "approved" },
|
|
30
|
+
{ "id": "approval-cancelled", "from": "approval", "to": "cancelled", "label": "user denies", "variant": "security" },
|
|
31
|
+
{ "id": "executing-failed", "from": "executing", "to": "failed", "label": "tool error", "variant": "security" },
|
|
32
|
+
{ "id": "failed-executing", "from": "failed", "to": "executing", "label": "retry", "variant": "dashed" },
|
|
33
|
+
{ "id": "reviewing-blocked", "from": "reviewing", "to": "blocked", "label": "needs input" },
|
|
34
|
+
{ "id": "blocked-reviewing", "from": "blocked", "to": "reviewing", "label": "input given" },
|
|
35
|
+
{ "id": "blocked-expired", "from": "blocked", "to": "expired", "label": "no reply 24h", "variant": "security" }
|
|
41
36
|
],
|
|
42
37
|
"cards": [
|
|
43
38
|
{
|
|
@@ -6,26 +6,6 @@
|
|
|
6
6
|
"animation": "trace",
|
|
7
7
|
"visual_preset": "signal-flow",
|
|
8
8
|
"quality_profile": "showcase",
|
|
9
|
-
"views": [
|
|
10
|
-
{
|
|
11
|
-
"id": "happy-path",
|
|
12
|
-
"label": "Request to result",
|
|
13
|
-
"focus": ["user", "chat", "planner", "router", "approval", "tool", "external", "final"],
|
|
14
|
-
"note": "Follow the successful request from user intent to the final reply."
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
"id": "safety-gate",
|
|
18
|
-
"label": "Policy and recovery",
|
|
19
|
-
"focus": ["router", "approval", "blocked", "retry"],
|
|
20
|
-
"note": "See where risky work stops, waits for consent, or returns for revision."
|
|
21
|
-
},
|
|
22
|
-
{
|
|
23
|
-
"id": "evidence-loop",
|
|
24
|
-
"label": "Evidence and memory",
|
|
25
|
-
"focus": ["external", "store", "trace"],
|
|
26
|
-
"note": "Isolate the durable trace and context path behind the visible answer."
|
|
27
|
-
}
|
|
28
|
-
],
|
|
29
9
|
"output": "examples/workflow-agent-tool-call-rendered.html"
|
|
30
10
|
},
|
|
31
11
|
"lanes": [
|