@topogram/cli 0.3.63 → 0.3.65
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/package.json +1 -1
- package/src/adoption/plan/index.js +703 -0
- package/src/adoption/plan.d.ts +6 -0
- package/src/adoption/plan.js +12 -703
- package/src/adoption/reporting.d.ts +10 -0
- package/src/adoption/review-groups.d.ts +6 -0
- package/src/agent-brief.d.ts +3 -0
- package/src/agent-brief.js +495 -0
- package/src/agent-ops/query-builders/auth.js +375 -0
- package/src/agent-ops/query-builders/change-risk/change-plan.js +123 -0
- package/src/agent-ops/query-builders/change-risk/import-plan.js +49 -0
- package/src/agent-ops/query-builders/change-risk/maintained.js +286 -0
- package/src/agent-ops/query-builders/change-risk/review-packets.js +123 -0
- package/src/agent-ops/query-builders/change-risk/risk.js +189 -0
- package/src/agent-ops/query-builders/change-risk.js +25 -0
- package/src/agent-ops/query-builders/common.js +149 -0
- package/src/agent-ops/query-builders/maintained-risk.js +539 -0
- package/src/agent-ops/query-builders/maintained-shared.js +120 -0
- package/src/agent-ops/query-builders/multi-agent.js +547 -0
- package/src/agent-ops/query-builders/projection-impacts.js +514 -0
- package/src/agent-ops/query-builders/work-packets.js +417 -0
- package/src/agent-ops/query-builders/workflow-context-shared.js +300 -0
- package/src/agent-ops/query-builders/workflow-context.js +398 -0
- package/src/agent-ops/query-builders/workflow-presets-core.js +676 -0
- package/src/agent-ops/query-builders/workflow-presets.js +341 -0
- package/src/agent-ops/query-builders.d.ts +26 -0
- package/src/agent-ops/query-builders.js +42 -5021
- package/src/archive/archive.d.ts +2 -0
- package/src/archive/compact.d.ts +1 -0
- package/src/archive/unarchive.d.ts +1 -0
- package/src/catalog/constants.js +10 -0
- package/src/catalog/copy.js +60 -0
- package/src/catalog/diagnostics.js +15 -0
- package/src/catalog/entries.js +42 -0
- package/src/catalog/files.js +67 -0
- package/src/catalog/provenance.js +122 -0
- package/src/catalog/source.js +150 -0
- package/src/catalog/validation.js +252 -0
- package/src/catalog.d.ts +12 -0
- package/src/catalog.js +18 -750
- package/src/cli/catalog-alias.d.ts +1 -0
- package/src/cli/command-parser.js +38 -0
- package/src/cli/command-parsers/core.js +102 -0
- package/src/cli/command-parsers/generator.js +39 -0
- package/src/cli/command-parsers/import.js +44 -0
- package/src/cli/command-parsers/legacy-workflow.js +21 -0
- package/src/cli/command-parsers/project.js +47 -0
- package/src/cli/command-parsers/sdlc.js +47 -0
- package/src/cli/command-parsers/shared.js +51 -0
- package/src/cli/command-parsers/template.js +48 -0
- package/src/cli/commands/agent.js +47 -0
- package/src/cli/commands/catalog/check.js +31 -0
- package/src/cli/commands/catalog/copy.js +59 -0
- package/src/cli/commands/catalog/doctor.js +248 -0
- package/src/cli/commands/catalog/help.js +21 -0
- package/src/cli/commands/catalog/list.js +52 -0
- package/src/cli/commands/catalog/runner.js +92 -0
- package/src/cli/commands/catalog/shared.js +17 -0
- package/src/cli/commands/catalog/show.js +134 -0
- package/src/cli/commands/catalog.js +32 -0
- package/src/cli/commands/check.js +268 -0
- package/src/cli/commands/doctor.js +268 -0
- package/src/cli/commands/emit.js +149 -0
- package/src/cli/commands/generate.js +96 -0
- package/src/cli/commands/generator-policy/package-info.js +162 -0
- package/src/cli/commands/generator-policy/payloads.js +372 -0
- package/src/cli/commands/generator-policy/printers.js +159 -0
- package/src/cli/commands/generator-policy/runner.js +81 -0
- package/src/cli/commands/generator-policy/shared.js +39 -0
- package/src/cli/commands/generator-policy.js +17 -0
- package/src/cli/commands/generator.js +443 -0
- package/src/cli/commands/import/adopt.js +170 -0
- package/src/cli/commands/import/check.js +91 -0
- package/src/cli/commands/import/diff.js +84 -0
- package/src/cli/commands/import/help.js +47 -0
- package/src/cli/commands/import/paths.js +277 -0
- package/src/cli/commands/import/plan.js +284 -0
- package/src/cli/commands/import/refresh.js +470 -0
- package/src/cli/commands/import/status-history.js +196 -0
- package/src/cli/commands/import/workspace.js +230 -0
- package/src/cli/commands/import-runner.js +157 -0
- package/src/cli/commands/import.js +35 -0
- package/src/cli/commands/inspect.js +55 -0
- package/src/cli/commands/new.js +94 -0
- package/src/cli/commands/package/constants.js +17 -0
- package/src/cli/commands/package/doctor.js +240 -0
- package/src/cli/commands/package/help.js +27 -0
- package/src/cli/commands/package/lockfile.js +135 -0
- package/src/cli/commands/package/npm.js +97 -0
- package/src/cli/commands/package/reporting.js +35 -0
- package/src/cli/commands/package/runner.js +33 -0
- package/src/cli/commands/package/shared.js +9 -0
- package/src/cli/commands/package/update-cli.js +252 -0
- package/src/cli/commands/package/versions.js +35 -0
- package/src/cli/commands/package.js +31 -0
- package/src/cli/commands/query/change-plan.js +68 -0
- package/src/cli/commands/query/definitions.js +202 -0
- package/src/cli/commands/query/import-adopt.js +121 -0
- package/src/cli/commands/query/runner/artifacts.js +102 -0
- package/src/cli/commands/query/runner/boundaries.js +211 -0
- package/src/cli/commands/query/runner/change.js +182 -0
- package/src/cli/commands/query/runner/import-adopt.js +111 -0
- package/src/cli/commands/query/runner/index.js +31 -0
- package/src/cli/commands/query/runner/output.js +12 -0
- package/src/cli/commands/query/runner/workflow.js +241 -0
- package/src/cli/commands/query/runner.js +3 -0
- package/src/cli/commands/query/workflow-context.js +5 -0
- package/src/cli/commands/query/workspace.js +274 -0
- package/src/cli/commands/query.js +11 -0
- package/src/cli/commands/release-rollout.js +257 -0
- package/src/cli/commands/release-shared.js +528 -0
- package/src/cli/commands/release-status.js +429 -0
- package/src/cli/commands/release.js +107 -0
- package/src/cli/commands/sdlc.js +168 -0
- package/src/cli/commands/setup.js +76 -0
- package/src/cli/commands/source.js +291 -0
- package/src/cli/commands/template/baseline.js +100 -0
- package/src/cli/commands/template/check.js +466 -0
- package/src/cli/commands/template/constants.js +8 -0
- package/src/cli/commands/template/diagnostics.js +26 -0
- package/src/cli/commands/template/help.js +28 -0
- package/src/cli/commands/template/lifecycle.js +404 -0
- package/src/cli/commands/template/list-show.js +287 -0
- package/src/cli/commands/template/policy.js +422 -0
- package/src/cli/commands/template/shared.js +127 -0
- package/src/cli/commands/template/updates.js +352 -0
- package/src/cli/commands/template-runner.js +198 -0
- package/src/cli/commands/template.js +43 -0
- package/src/cli/commands/trust.js +219 -0
- package/src/cli/commands/version.js +40 -0
- package/src/cli/commands/widget.js +168 -0
- package/src/cli/commands/workflow.js +63 -0
- package/src/cli/dispatcher.js +392 -0
- package/src/cli/help-dispatch.js +188 -0
- package/src/cli/help.js +296 -0
- package/src/cli/migration-guidance.js +59 -0
- package/src/cli/options.js +96 -0
- package/src/cli/output-safety.js +107 -0
- package/src/cli/path-normalization.js +29 -0
- package/src/cli.js +47 -11711
- package/src/example-implementation.d.ts +2 -0
- package/src/format.d.ts +1 -0
- package/src/generator/api/contracts.js +497 -0
- package/src/generator/api/metadata.js +221 -0
- package/src/generator/api/openapi.js +559 -0
- package/src/generator/api/schema.js +124 -0
- package/src/generator/api/types.d.ts +98 -0
- package/src/generator/api.js +3 -1195
- package/src/generator/check.d.ts +1 -0
- package/src/generator/context/bundle.d.ts +1 -0
- package/src/generator/context/shared/domain-sdlc.js +282 -0
- package/src/generator/context/shared/maintained-boundary.js +665 -0
- package/src/generator/context/shared/metrics.js +85 -0
- package/src/generator/context/shared/primitives.js +64 -0
- package/src/generator/context/shared/relationships.js +453 -0
- package/src/generator/context/shared/summaries.js +263 -0
- package/src/generator/context/shared/types.d.ts +207 -0
- package/src/generator/context/shared.d.ts +44 -0
- package/src/generator/context/shared.js +80 -1390
- package/src/generator/context/slice/core.js +397 -0
- package/src/generator/context/slice/sdlc.js +417 -0
- package/src/generator/context/slice/ui-packets.js +183 -0
- package/src/generator/context/slice.js +2 -859
- package/src/generator/native/parity-bundle.js +2 -1
- package/src/generator/registry/index.js +507 -0
- package/src/generator/registry.js +18 -504
- package/src/generator/runtime/environment/index.js +666 -0
- package/src/generator/runtime/environment.js +4 -666
- package/src/generator/runtime/runtime-check/index.js +554 -0
- package/src/generator/runtime/runtime-check.js +4 -554
- package/src/generator/runtime/shared/index.js +572 -0
- package/src/generator/runtime/shared.js +19 -570
- package/src/generator/shared.d.ts +2 -0
- package/src/generator/surfaces/shared.d.ts +3 -0
- package/src/generator/surfaces/web/html-escape.js +22 -0
- package/src/generator/surfaces/web/react.js +10 -8
- package/src/generator/surfaces/web/sveltekit.js +7 -5
- package/src/generator/surfaces/web/vanilla.js +8 -4
- package/src/generator/widget-conformance/behavior-report.js +258 -0
- package/src/generator/widget-conformance/checks.js +371 -0
- package/src/generator/widget-conformance/projection-context.js +200 -0
- package/src/generator/widget-conformance/report.js +166 -0
- package/src/generator/widget-conformance/types.d.ts +121 -0
- package/src/generator/widget-conformance.js +3 -824
- package/src/generator.d.ts +2 -0
- package/src/github-client.js +520 -0
- package/src/import/core/context.d.ts +3 -0
- package/src/import/core/contracts.d.ts +1 -0
- package/src/import/core/registry.d.ts +4 -0
- package/src/import/core/runner/candidates.js +217 -0
- package/src/import/core/runner/options.js +22 -0
- package/src/import/core/runner/reports.js +50 -0
- package/src/import/core/runner/run.js +79 -0
- package/src/import/core/runner/tracks.js +150 -0
- package/src/import/core/runner/ui-drafts.js +337 -0
- package/src/import/core/runner.js +3 -698
- package/src/import/core/shared/api-routes.js +221 -0
- package/src/import/core/shared/candidates.js +97 -0
- package/src/import/core/shared/files.js +177 -0
- package/src/import/core/shared/next-app.js +389 -0
- package/src/import/core/shared/types.d.ts +51 -0
- package/src/import/core/shared/ui-routes.js +230 -0
- package/src/import/core/shared.js +67 -910
- package/src/import/extractors/api/flutter-dio.js +4 -8
- package/src/import/extractors/api/react-native-repository.js +4 -8
- package/src/import/index.d.ts +4 -0
- package/src/import/provenance.d.ts +4 -0
- package/src/new-project/constants.js +128 -0
- package/src/new-project/create.js +83 -0
- package/src/new-project/json.js +28 -0
- package/src/new-project/metadata.js +96 -0
- package/src/new-project/package-spec.js +161 -0
- package/src/new-project/project-files.js +348 -0
- package/src/new-project/template-policy.js +269 -0
- package/src/new-project/template-resolution.js +368 -0
- package/src/new-project/template-snapshots.js +430 -0
- package/src/new-project/template-updates.js +512 -0
- package/src/new-project/types.d.ts +83 -0
- package/src/new-project.js +6 -2188
- package/src/npm-safety.js +79 -0
- package/src/parser.d.ts +87 -0
- package/src/parser.js +118 -0
- package/src/path-helpers.d.ts +1 -0
- package/src/path-helpers.js +20 -0
- package/src/policy/review-boundaries.d.ts +15 -0
- package/src/project-config/index.js +564 -0
- package/src/project-config.js +19 -560
- package/src/reconcile/docs.d.ts +8 -0
- package/src/reconcile/journeys.d.ts +1 -0
- package/src/resolver/enrich/acceptance-criterion.js +2 -0
- package/src/resolver/enrich/bug.js +2 -0
- package/src/resolver/enrich/pitch.js +2 -0
- package/src/resolver/enrich/requirement.js +2 -0
- package/src/resolver/enrich/task.js +2 -0
- package/src/resolver/index.js +19 -2089
- package/src/resolver/normalize.js +384 -1
- package/src/resolver/plans.js +168 -0
- package/src/resolver/projections-api.js +494 -0
- package/src/resolver/projections-db.js +133 -0
- package/src/resolver/projections-ui.js +317 -0
- package/src/resolver/shapes.js +251 -0
- package/src/resolver/shared.js +278 -0
- package/src/resolver/widgets.js +132 -0
- package/src/resolver.d.ts +1 -0
- package/src/runtime-support.js +29 -0
- package/src/sdlc/adopt.d.ts +1 -0
- package/src/sdlc/check.d.ts +1 -0
- package/src/sdlc/explain.d.ts +1 -0
- package/src/sdlc/release.d.ts +1 -0
- package/src/sdlc/scaffold.d.ts +1 -0
- package/src/sdlc/transition.d.ts +1 -0
- package/src/template-trust/constants.js +62 -0
- package/src/template-trust/content.js +258 -0
- package/src/template-trust/diff.js +92 -0
- package/src/template-trust/policy.js +61 -0
- package/src/template-trust/record.js +90 -0
- package/src/template-trust/status.js +182 -0
- package/src/template-trust.js +24 -687
- package/src/text-helpers.d.ts +7 -0
- package/src/text-helpers.js +245 -0
- package/src/topogram-config.js +306 -0
- package/src/topogram-types.d.ts +69 -0
- package/src/validator/common.js +488 -0
- package/src/validator/data-model.js +237 -0
- package/src/validator/docs.js +167 -0
- package/src/validator/expressions.js +146 -1
- package/src/validator/index.d.ts +23 -0
- package/src/validator/index.js +32 -3585
- package/src/validator/kinds.d.ts +41 -0
- package/src/validator/kinds.js +2 -0
- package/src/validator/model-helpers.js +46 -0
- package/src/validator/per-kind/acceptance-criterion.js +5 -0
- package/src/validator/per-kind/bug.js +6 -0
- package/src/validator/per-kind/domain.js +15 -2
- package/src/validator/per-kind/pitch.js +7 -0
- package/src/validator/per-kind/requirement.js +5 -0
- package/src/validator/per-kind/task.js +7 -0
- package/src/validator/per-kind/widget.js +14 -0
- package/src/validator/projections/api-http-async.js +410 -0
- package/src/validator/projections/api-http-authz.js +88 -0
- package/src/validator/projections/api-http-core.js +205 -0
- package/src/validator/projections/api-http-policies.js +339 -0
- package/src/validator/projections/api-http-responses.js +233 -0
- package/src/validator/projections/api-http.js +44 -0
- package/src/validator/projections/db.js +353 -0
- package/src/validator/projections/generator-defaults.js +45 -0
- package/src/validator/projections/helpers.js +87 -0
- package/src/validator/projections/ui-helpers.js +214 -0
- package/src/validator/projections/ui-navigation.js +344 -0
- package/src/validator/projections/ui-structure.js +364 -0
- package/src/validator/projections/ui-widgets.js +493 -0
- package/src/validator/projections/ui.js +46 -0
- package/src/validator/registry.js +48 -1
- package/src/validator/utils.d.ts +20 -0
- package/src/validator/utils.js +115 -12
- package/src/validator.d.ts +2 -0
- package/src/widget-behavior.d.ts +1 -0
- package/src/workflows/adoption/index.js +26 -0
- package/src/workflows/docs-generate.js +262 -0
- package/src/workflows/docs-scan.js +703 -0
- package/src/workflows/docs.js +15 -0
- package/src/workflows/import-app/api/collect.js +221 -0
- package/src/workflows/import-app/api/openapi.js +257 -0
- package/src/workflows/import-app/api/routes.js +327 -0
- package/src/workflows/import-app/api/sources.js +22 -0
- package/src/workflows/import-app/api.js +4 -0
- package/src/workflows/import-app/db.js +538 -0
- package/src/workflows/import-app/index.js +30 -0
- package/src/workflows/import-app/shared.js +218 -0
- package/src/workflows/import-app/ui.js +443 -0
- package/src/workflows/import-app/workflow.js +159 -0
- package/src/workflows/reconcile/adoption-plan/build.js +208 -0
- package/src/workflows/reconcile/adoption-plan/dependencies.js +75 -0
- package/src/workflows/reconcile/adoption-plan/outputs.js +143 -0
- package/src/workflows/reconcile/adoption-plan/paths.js +58 -0
- package/src/workflows/reconcile/adoption-plan/projection-patches.js +177 -0
- package/src/workflows/reconcile/adoption-plan/reasons.js +107 -0
- package/src/workflows/reconcile/adoption-plan.js +32 -0
- package/src/workflows/reconcile/auth/closures.js +115 -0
- package/src/workflows/reconcile/auth/formatters.js +142 -0
- package/src/workflows/reconcile/auth/inference.js +330 -0
- package/src/workflows/reconcile/auth/roles.js +122 -0
- package/src/workflows/reconcile/auth.js +37 -0
- package/src/workflows/reconcile/bundle-core/index.js +600 -0
- package/src/workflows/reconcile/bundle-core.js +14 -0
- package/src/workflows/reconcile/bundle-shared.js +75 -0
- package/src/workflows/reconcile/candidate-model.js +477 -0
- package/src/workflows/reconcile/canonical-surface.js +264 -0
- package/src/workflows/reconcile/gap-report.js +333 -0
- package/src/workflows/reconcile/ids.js +6 -0
- package/src/workflows/reconcile/impacts/adoption-plan.js +192 -0
- package/src/workflows/reconcile/impacts/indexes.js +101 -0
- package/src/workflows/reconcile/impacts/patches.js +252 -0
- package/src/workflows/reconcile/impacts/reports.js +80 -0
- package/src/workflows/reconcile/impacts.js +16 -0
- package/src/workflows/reconcile/index.js +7 -0
- package/src/workflows/reconcile/renderers.js +461 -0
- package/src/workflows/reconcile/summary.js +90 -0
- package/src/workflows/reconcile/workflow.js +309 -0
- package/src/workflows/shared.js +189 -0
- package/src/workflows/types.d.ts +93 -0
- package/src/workflows.d.ts +1 -0
- package/src/workflows.js +10 -7652
- package/src/workspace-docs.d.ts +29 -0
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import { blockEntries, getFieldValue, symbolValues, valueAsArray } from "../validator.js";
|
|
2
|
+
|
|
3
|
+
export function groupBy(items, keyFn) {
|
|
4
|
+
const grouped = {};
|
|
5
|
+
for (const item of items) {
|
|
6
|
+
const key = keyFn(item);
|
|
7
|
+
if (!Object.hasOwn(grouped, key)) {
|
|
8
|
+
grouped[key] = [];
|
|
9
|
+
}
|
|
10
|
+
grouped[key].push(item);
|
|
11
|
+
}
|
|
12
|
+
return grouped;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function resolveReference(registry, id) {
|
|
16
|
+
return registry.get(id) || null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function toRef(target) {
|
|
20
|
+
if (!target) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
id: target.id,
|
|
26
|
+
kind: target.kind
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function resolveReferenceList(registry, value) {
|
|
31
|
+
return symbolValues(value).map((id) => ({
|
|
32
|
+
id,
|
|
33
|
+
target: toRef(resolveReference(registry, id))
|
|
34
|
+
}));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function resolveDomainTag(statement, registry) {
|
|
38
|
+
const domainField = statement.fields.find((field) => field.key === "domain");
|
|
39
|
+
if (!domainField || domainField.value.type !== "symbol") {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
const id = domainField.value.value;
|
|
43
|
+
return {
|
|
44
|
+
id,
|
|
45
|
+
target: toRef(resolveReference(registry, id))
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function normalizeDomainScopeList(statement, key) {
|
|
50
|
+
const field = statement.fields.find((f) => f.key === key);
|
|
51
|
+
if (!field) return [];
|
|
52
|
+
const items = field.value.type === "list" || field.value.type === "sequence"
|
|
53
|
+
? field.value.items
|
|
54
|
+
: [field.value];
|
|
55
|
+
return items
|
|
56
|
+
.map((item) => (item.type === "string" || item.type === "symbol" ? item.value : null))
|
|
57
|
+
.filter((value) => value !== null);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function normalizeSequence(items) {
|
|
61
|
+
return items.map((item) => {
|
|
62
|
+
if (item.type === "symbol" || item.type === "string") {
|
|
63
|
+
return item.value;
|
|
64
|
+
}
|
|
65
|
+
if (item.type === "list") {
|
|
66
|
+
return item.items.map((nested) => nested.value);
|
|
67
|
+
}
|
|
68
|
+
return item.type;
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function normalizeFieldsBlock(statement, key = "fields") {
|
|
73
|
+
return blockEntries(getFieldValue(statement, key)).map((entry) => {
|
|
74
|
+
const [name, type, requiredness, ...rest] = entry.items;
|
|
75
|
+
let defaultValue = null;
|
|
76
|
+
|
|
77
|
+
for (let i = 0; i < rest.length - 1; i += 1) {
|
|
78
|
+
if (rest[i].type === "symbol" && rest[i].value === "default") {
|
|
79
|
+
defaultValue = rest[i + 1]?.value ?? null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
name: name?.value ?? null,
|
|
85
|
+
fieldType: type?.value ?? null,
|
|
86
|
+
requiredness: requiredness?.value ?? null,
|
|
87
|
+
defaultValue,
|
|
88
|
+
raw: normalizeSequence(entry.items),
|
|
89
|
+
loc: entry.loc
|
|
90
|
+
};
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export function normalizeGenericBlock(statement, key) {
|
|
95
|
+
return blockEntries(getFieldValue(statement, key)).map((entry) => ({
|
|
96
|
+
raw: normalizeSequence(entry.items),
|
|
97
|
+
loc: entry.loc
|
|
98
|
+
}));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export function tokenValue(token) {
|
|
102
|
+
return token?.value ?? null;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export function parseDefaultLiteral(token) {
|
|
106
|
+
if (!token) return null;
|
|
107
|
+
if (token.type === "list") {
|
|
108
|
+
return (token.items || []).map((item) => parseDefaultLiteral(item));
|
|
109
|
+
}
|
|
110
|
+
if (token.type === "string") {
|
|
111
|
+
return token.value ?? null;
|
|
112
|
+
}
|
|
113
|
+
if (token.type === "symbol") {
|
|
114
|
+
if (token.value === "true") return true;
|
|
115
|
+
if (token.value === "false") return false;
|
|
116
|
+
if (token.value === "null") return null;
|
|
117
|
+
if (/^-?\d+$/.test(token.value)) return Number.parseInt(token.value, 10);
|
|
118
|
+
if (/^-?\d+\.\d+$/.test(token.value)) return Number.parseFloat(token.value);
|
|
119
|
+
return token.value;
|
|
120
|
+
}
|
|
121
|
+
return token.value ?? null;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export function parseLiteralToken(token) {
|
|
125
|
+
const value = tokenValue(token);
|
|
126
|
+
if (value == null) {
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (value === "true") {
|
|
131
|
+
return { kind: "boolean", value: true };
|
|
132
|
+
}
|
|
133
|
+
if (value === "false") {
|
|
134
|
+
return { kind: "boolean", value: false };
|
|
135
|
+
}
|
|
136
|
+
if (value === "null") {
|
|
137
|
+
return { kind: "null", value: null };
|
|
138
|
+
}
|
|
139
|
+
if (/^-?\d+$/.test(value)) {
|
|
140
|
+
return { kind: "integer", value: Number.parseInt(value, 10) };
|
|
141
|
+
}
|
|
142
|
+
if (/^-?\d+\.\d+$/.test(value)) {
|
|
143
|
+
return { kind: "number", value: Number.parseFloat(value) };
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return { kind: "symbol", value };
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export function parseComparison(left, operator, right) {
|
|
150
|
+
if (!left || !operator || !right) {
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return {
|
|
155
|
+
type: "comparison",
|
|
156
|
+
left: tokenValue(left),
|
|
157
|
+
operator,
|
|
158
|
+
right: parseLiteralToken(right)
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export function parseInvariantEntry(entry) {
|
|
163
|
+
const tokens = entry.items;
|
|
164
|
+
const values = tokens.map((item) => item.value);
|
|
165
|
+
const [a, b, c, d, e, f, g] = tokens;
|
|
166
|
+
|
|
167
|
+
if (tokenValue(b) === "requires") {
|
|
168
|
+
return {
|
|
169
|
+
type: "requires",
|
|
170
|
+
field: tokenValue(a),
|
|
171
|
+
predicate: parseComparison(c, tokenValue(d), e),
|
|
172
|
+
raw: values,
|
|
173
|
+
loc: entry.loc
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (tokenValue(b) === "length") {
|
|
178
|
+
return {
|
|
179
|
+
type: "length_check",
|
|
180
|
+
field: tokenValue(a),
|
|
181
|
+
operator: tokenValue(c),
|
|
182
|
+
value: parseLiteralToken(d),
|
|
183
|
+
raw: values,
|
|
184
|
+
loc: entry.loc
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (tokenValue(b) === "format") {
|
|
189
|
+
return {
|
|
190
|
+
type: "format_check",
|
|
191
|
+
field: tokenValue(a),
|
|
192
|
+
operator: tokenValue(c),
|
|
193
|
+
format: tokenValue(d),
|
|
194
|
+
raw: values,
|
|
195
|
+
loc: entry.loc
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (tokenValue(d) === "implies") {
|
|
200
|
+
return {
|
|
201
|
+
type: "implication",
|
|
202
|
+
when: parseComparison(a, tokenValue(b), c),
|
|
203
|
+
then:
|
|
204
|
+
tokenValue(f) === "is"
|
|
205
|
+
? {
|
|
206
|
+
type: "state_check",
|
|
207
|
+
field: tokenValue(e),
|
|
208
|
+
operator: "is",
|
|
209
|
+
value: parseLiteralToken(g)
|
|
210
|
+
}
|
|
211
|
+
: parseComparison(e, tokenValue(f), g),
|
|
212
|
+
raw: values,
|
|
213
|
+
loc: entry.loc
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (["==", "!=", "<", "<=", ">", ">="].includes(tokenValue(b))) {
|
|
218
|
+
return {
|
|
219
|
+
type: "comparison",
|
|
220
|
+
left: tokenValue(a),
|
|
221
|
+
operator: tokenValue(b),
|
|
222
|
+
right: parseLiteralToken(c),
|
|
223
|
+
raw: values,
|
|
224
|
+
loc: entry.loc
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return {
|
|
229
|
+
type: "unknown",
|
|
230
|
+
raw: values,
|
|
231
|
+
loc: entry.loc
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export function parseRuleExpression(value) {
|
|
236
|
+
const text = valueAsArray(value).map((item) => item.value).join(" ").trim();
|
|
237
|
+
const match = text.match(/^(.+?)\s*(==|!=|<=|>=|<|>)\s*(.+)$/);
|
|
238
|
+
if (!match) {
|
|
239
|
+
return {
|
|
240
|
+
type: "unknown",
|
|
241
|
+
raw: text
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return {
|
|
246
|
+
type: "comparison",
|
|
247
|
+
left: match[1].trim(),
|
|
248
|
+
operator: match[2],
|
|
249
|
+
right: {
|
|
250
|
+
kind: "symbol",
|
|
251
|
+
value: match[3].trim()
|
|
252
|
+
},
|
|
253
|
+
raw: text
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export function parseSymbolNode(value) {
|
|
258
|
+
return {
|
|
259
|
+
type: "symbol",
|
|
260
|
+
id: value
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
export function parseSymbolNodes(values) {
|
|
265
|
+
return values.map((value, index) => ({
|
|
266
|
+
...parseSymbolNode(value),
|
|
267
|
+
order: index
|
|
268
|
+
}));
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export function parseReferenceNodes(values) {
|
|
272
|
+
return values.map((entry, index) => ({
|
|
273
|
+
type: "reference",
|
|
274
|
+
id: entry.id,
|
|
275
|
+
target: entry.target || { id: entry.id, kind: null },
|
|
276
|
+
order: index
|
|
277
|
+
}));
|
|
278
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { blockEntries, getFieldValue, symbolValues } from "../validator.js";
|
|
2
|
+
import { normalizeSequence, parseDefaultLiteral, parseReferenceNodes, tokenValue } from "./shared.js";
|
|
3
|
+
|
|
4
|
+
export function normalizeWidgetProps(statement) {
|
|
5
|
+
return blockEntries(getFieldValue(statement, "props")).map((entry) => {
|
|
6
|
+
const [name, type, requiredness, ...rest] = entry.items;
|
|
7
|
+
let defaultValue = null;
|
|
8
|
+
|
|
9
|
+
for (let i = 0; i < rest.length - 1; i += 1) {
|
|
10
|
+
if (rest[i].type === "symbol" && rest[i].value === "default") {
|
|
11
|
+
defaultValue = parseDefaultLiteral(rest[i + 1]);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
name: name?.value ?? null,
|
|
17
|
+
fieldType: type?.value ?? null,
|
|
18
|
+
requiredness: requiredness?.value ?? null,
|
|
19
|
+
defaultValue,
|
|
20
|
+
raw: normalizeSequence(entry.items),
|
|
21
|
+
loc: entry.loc
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function normalizeWidgetEvents(statement, registry) {
|
|
27
|
+
return blockEntries(getFieldValue(statement, "events")).map((entry) => {
|
|
28
|
+
const [eventName, shapeRef] = entry.items;
|
|
29
|
+
const shapeId = tokenValue(shapeRef);
|
|
30
|
+
return {
|
|
31
|
+
id: tokenValue(eventName),
|
|
32
|
+
shape: shapeId
|
|
33
|
+
? {
|
|
34
|
+
id: shapeId,
|
|
35
|
+
kind: registry.get(shapeId)?.kind || null
|
|
36
|
+
}
|
|
37
|
+
: null,
|
|
38
|
+
raw: normalizeSequence(entry.items),
|
|
39
|
+
loc: entry.loc
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function normalizeWidgetSlots(statement) {
|
|
45
|
+
return blockEntries(getFieldValue(statement, "slots")).map((entry) => ({
|
|
46
|
+
id: tokenValue(entry.items[0]),
|
|
47
|
+
description: tokenValue(entry.items[1]),
|
|
48
|
+
raw: normalizeSequence(entry.items),
|
|
49
|
+
loc: entry.loc
|
|
50
|
+
}));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function normalizeBehaviorValue(token) {
|
|
54
|
+
if (!token) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
if (token.type === "list") {
|
|
58
|
+
return token.items.map((item) => normalizeBehaviorValue(item));
|
|
59
|
+
}
|
|
60
|
+
return parseDefaultLiteral(token);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function normalizeWidgetBehaviors(statement) {
|
|
64
|
+
const structured = blockEntries(getFieldValue(statement, "behaviors")).map((entry) => {
|
|
65
|
+
const kind = tokenValue(entry.items[0]);
|
|
66
|
+
const directives = {};
|
|
67
|
+
for (let i = 1; i < entry.items.length; i += 2) {
|
|
68
|
+
const key = tokenValue(entry.items[i]);
|
|
69
|
+
if (!key) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
directives[key] = normalizeBehaviorValue(entry.items[i + 1]);
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
kind,
|
|
76
|
+
directives,
|
|
77
|
+
source: "structured",
|
|
78
|
+
raw: normalizeSequence(entry.items),
|
|
79
|
+
loc: entry.loc
|
|
80
|
+
};
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
const structuredKinds = new Set(structured.map((entry) => entry.kind));
|
|
84
|
+
const shorthand = symbolValues(getFieldValue(statement, "behavior"))
|
|
85
|
+
.filter((kind) => !structuredKinds.has(kind))
|
|
86
|
+
.map((kind) => ({
|
|
87
|
+
kind,
|
|
88
|
+
directives: {},
|
|
89
|
+
source: "shorthand",
|
|
90
|
+
raw: [kind],
|
|
91
|
+
loc: null
|
|
92
|
+
}));
|
|
93
|
+
|
|
94
|
+
return [...structured, ...shorthand];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function buildWidgetContract(statement) {
|
|
98
|
+
return {
|
|
99
|
+
type: "ui_widget_contract",
|
|
100
|
+
id: statement.id,
|
|
101
|
+
name: statement.name || statement.id,
|
|
102
|
+
description: statement.description || null,
|
|
103
|
+
category: statement.category || null,
|
|
104
|
+
version: statement.version || null,
|
|
105
|
+
status: statement.status || null,
|
|
106
|
+
props: (statement.props || []).map((prop) => ({
|
|
107
|
+
name: prop.name,
|
|
108
|
+
type: prop.fieldType,
|
|
109
|
+
requiredness: prop.requiredness,
|
|
110
|
+
defaultValue: prop.defaultValue ?? null
|
|
111
|
+
})),
|
|
112
|
+
events: (statement.events || []).map((event) => ({
|
|
113
|
+
id: event.id,
|
|
114
|
+
shape: event.shape || null
|
|
115
|
+
})),
|
|
116
|
+
slots: (statement.slots || []).map((slot) => ({
|
|
117
|
+
id: slot.id,
|
|
118
|
+
description: slot.description || null
|
|
119
|
+
})),
|
|
120
|
+
behavior: [...(statement.behavior || [])],
|
|
121
|
+
behaviors: (statement.behaviors || []).map((behavior) => ({
|
|
122
|
+
kind: behavior.kind,
|
|
123
|
+
directives: { ...(behavior.directives || {}) },
|
|
124
|
+
source: behavior.source || null
|
|
125
|
+
})),
|
|
126
|
+
patterns: [...(statement.patterns || [])],
|
|
127
|
+
regions: [...(statement.regions || [])],
|
|
128
|
+
approvals: [...(statement.approvals || [])],
|
|
129
|
+
lookups: parseReferenceNodes(statement.lookups || []),
|
|
130
|
+
dependencies: parseReferenceNodes(statement.dependencies || [])
|
|
131
|
+
};
|
|
132
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function resolveWorkspace(ast: any): any;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
export const MINIMUM_NODE_MAJOR = 20;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @param {string} version
|
|
7
|
+
* @returns {{ ok: boolean, major: number, minimum: number, message: string|null }}
|
|
8
|
+
*/
|
|
9
|
+
export function nodeVersionSupport(version = process.versions.node) {
|
|
10
|
+
const major = Number.parseInt(String(version).split(".")[0] || "0", 10);
|
|
11
|
+
const ok = Number.isFinite(major) && major >= MINIMUM_NODE_MAJOR;
|
|
12
|
+
return {
|
|
13
|
+
ok,
|
|
14
|
+
major,
|
|
15
|
+
minimum: MINIMUM_NODE_MAJOR,
|
|
16
|
+
message: ok ? null : `Topogram requires Node.js ${MINIMUM_NODE_MAJOR}+; current runtime is ${version}.`
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @param {string} [version]
|
|
22
|
+
* @returns {void}
|
|
23
|
+
*/
|
|
24
|
+
export function assertSupportedNode(version = process.versions.node) {
|
|
25
|
+
const support = nodeVersionSupport(version);
|
|
26
|
+
if (!support.ok) {
|
|
27
|
+
throw new Error(support.message || `Topogram requires Node.js ${MINIMUM_NODE_MAJOR}+.`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function sdlcAdopt(...args: any[]): any;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function checkWorkspace(...args: any[]): any;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function explain(...args: any[]): any;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function runRelease(...args: any[]): any;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function scaffoldNew(...args: any[]): any;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function transitionStatement(...args: any[]): any;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
export const TEMPLATE_TRUST_FILE = ".topogram-template-trust.json";
|
|
4
|
+
export const TEMPLATE_TRUST_POLICY = "topogram-template-executable-implementation-v1";
|
|
5
|
+
export const IGNORED_IMPLEMENTATION_ENTRIES = new Set([".DS_Store", "node_modules", ".tmp"]);
|
|
6
|
+
export const MAX_TEXT_DIFF_BYTES = 256 * 1024;
|
|
7
|
+
export const TRUST_REVIEW_COMMANDS = "`topogram trust status`, `topogram trust diff`, and `topogram trust template`";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @param {string} value
|
|
11
|
+
* @returns {string}
|
|
12
|
+
*/
|
|
13
|
+
export function normalizeRoot(value) {
|
|
14
|
+
return String(value || "").replace(/\\/g, "/");
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @param {string} value
|
|
19
|
+
* @returns {string}
|
|
20
|
+
*/
|
|
21
|
+
export function normalizeRelativePath(value) {
|
|
22
|
+
return value.replace(/\\/g, "/");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @param {string} relativePath
|
|
27
|
+
* @returns {string}
|
|
28
|
+
*/
|
|
29
|
+
export function unsupportedImplementationSymlinkMessage(relativePath) {
|
|
30
|
+
return `Template implementation contains unsupported symlink '${relativePath}'. Implementation trust hashes real files under implementation/; symlinks can point outside the trusted root. Replace symlinks with real files under implementation/, then run ${TRUST_REVIEW_COMMANDS} after review.`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @param {string} modulePath
|
|
35
|
+
* @returns {string}
|
|
36
|
+
*/
|
|
37
|
+
export function implementationOutsideRootMessage(modulePath) {
|
|
38
|
+
return `Template implementation module '${modulePath}' must be under implementation/ for template-attached projects. Keep executable template code inside implementation/ so the trust record covers what topogram generate may load. Move the module back under implementation/, then run ${TRUST_REVIEW_COMMANDS} after review.`;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @param {string|string[]} issueOrIssues
|
|
43
|
+
* @returns {string}
|
|
44
|
+
*/
|
|
45
|
+
export function templateTrustRecoveryGuidance(issueOrIssues) {
|
|
46
|
+
const issues = Array.isArray(issueOrIssues) ? issueOrIssues : [issueOrIssues];
|
|
47
|
+
const text = issues.join("\n");
|
|
48
|
+
if (issues.length > 0 && issues.every((issue) =>
|
|
49
|
+
issue.includes("topogram trust status") &&
|
|
50
|
+
issue.includes("topogram trust diff") &&
|
|
51
|
+
issue.includes("topogram trust template")
|
|
52
|
+
)) {
|
|
53
|
+
return "";
|
|
54
|
+
}
|
|
55
|
+
if (text.includes("unsupported symlink")) {
|
|
56
|
+
return `Replace symlinks with real files under implementation/, then run ${TRUST_REVIEW_COMMANDS} after review.`;
|
|
57
|
+
}
|
|
58
|
+
if (text.includes("must be under implementation/")) {
|
|
59
|
+
return `Keep executable template code under implementation/ so it can be hashed and trusted; move the module back under implementation/, then run ${TRUST_REVIEW_COMMANDS} after review.`;
|
|
60
|
+
}
|
|
61
|
+
return `Run \`topogram trust status\` and \`topogram trust diff\` to review implementation changes; after review, run \`topogram trust template\` to trust the current files.`;
|
|
62
|
+
}
|