@xemahq/xema 0.30.0 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/dev/infra-preflight.js +1 -1
- package/dist/dev/infra-preflight.js.map +1 -1
- package/dist/edition/verify-image-evidence.bundle.mjs +2921 -2290
- package/dist/edition/verify-image-evidence.bundle.provenance.json +481 -415
- package/dist/runtime/runner/helm-cli.d.ts.map +1 -1
- package/dist/runtime/runner/helm-cli.js.map +1 -1
- package/dist/runtime/store-submit.d.ts.map +1 -1
- package/dist/runtime/store-submit.js.map +1 -1
- package/edition/README.md +2 -3
- package/edition/assemble-producer-input.mjs +1 -1
- package/edition/biome-content.mjs +6 -0
- package/edition/build-platform-service-index.mjs +2 -0
- package/edition/build-runtime-image-source-index.mjs +21 -6
- package/edition/catalogue.mjs +5 -1
- package/edition/checkout-indexed-source-repositories.mjs +41 -6
- package/edition/dispatched-runtime-components.mjs +82 -0
- package/edition/edition-protocol.mjs +2 -2
- package/edition/external-source-walk.mjs +1 -1
- package/edition/image-evidence.mjs +1 -1
- package/edition/kernel-capability-domain.mjs +30 -0
- package/edition/lib.mjs +119 -3
- package/edition/operation-grant-admission.mjs +70 -0
- package/edition/operation-requirements.mjs +128 -0
- package/edition/platform-lock-readability.mjs +2 -2
- package/edition/platform-service-class.mjs +42 -0
- package/edition/platform-service-ownership.mjs +78 -0
- package/edition/remedy-command.mjs +2 -2
- package/edition/resolve-customer-edition.mjs +4 -1
- package/edition/resolve-distribution.mjs +65 -15
- package/edition/resolve-images.mjs +65 -4
- package/edition/seal-image-digests.mjs +1 -1
- package/package.json +4 -4
|
@@ -74,6 +74,7 @@ import {
|
|
|
74
74
|
sealEditionAuthorizationBase,
|
|
75
75
|
writeAuthorizationLock,
|
|
76
76
|
} from './authorization-base.mjs';
|
|
77
|
+
import { resolveDispatchedRuntimeComponents } from './dispatched-runtime-components.mjs';
|
|
77
78
|
import { fleetChartSetLockPath, writeEditionChartSet } from './edition-chart-set.mjs';
|
|
78
79
|
import { workspaceSection } from './edition-config.mjs';
|
|
79
80
|
import { WorkspaceRoot, biomeIndexPath, configureEditionWorkspaceFromProcess, editionsRoot, isEntryModule, kernelPackageDir, platformServiceIndexPath } from './edition-workspace.mjs';
|
|
@@ -92,7 +93,12 @@ import {
|
|
|
92
93
|
validateImmutableDistributionLock,
|
|
93
94
|
validateServiceDependencyOwnerParity,
|
|
94
95
|
} from './lib.mjs';
|
|
96
|
+
import {
|
|
97
|
+
assertOperationGrantsAdmitted,
|
|
98
|
+
assertOrganizationSweepsAdmitted,
|
|
99
|
+
} from './operation-grant-admission.mjs';
|
|
95
100
|
import { PUBLISHED_PIN_SOURCE, pinnedSource } from './pin-source.mjs';
|
|
101
|
+
import { verifiedPlatformServiceIndex } from './platform-service-ownership.mjs';
|
|
96
102
|
import { closureBiomeFacts } from './positive-closure.mjs';
|
|
97
103
|
import { assertReleaseContent, assertReleaseEditionTree } from './release-channel-guard.mjs';
|
|
98
104
|
import { commandFor } from './remedy-command.mjs';
|
|
@@ -1745,6 +1751,13 @@ export function resolveDistributionFromInputs(
|
|
|
1745
1751
|
// shipped provider. See `nexusBinder`.
|
|
1746
1752
|
const nexusBindings = nexusBinder(id, [...selected.values()], schemas);
|
|
1747
1753
|
|
|
1754
|
+
// (5d) Dispatched runtime components — every `runtime-image` edge of a
|
|
1755
|
+
// shipped biome must resolve to a runtime component of a biome in the index.
|
|
1756
|
+
// The target biome is not rostered (it enters no `biomes[]`, `requires` or
|
|
1757
|
+
// install set); the image plane adds its image row. Resolved here so an
|
|
1758
|
+
// unresolvable edge refuses the edition, not only its image lock.
|
|
1759
|
+
resolveDispatchedRuntimeComponents(`distribution "${id}"`, [...selected.values()], index);
|
|
1760
|
+
|
|
1748
1761
|
// (6) Build the lock — sort by (tier order, id, target, repo).
|
|
1749
1762
|
const biomes = [...selected.values()]
|
|
1750
1763
|
.map((e) => ({
|
|
@@ -1822,7 +1835,7 @@ export function resolveDistributionFromInputs(
|
|
|
1822
1835
|
// starts. Optional-in-the-new-schema and absent-from-the-old are different
|
|
1823
1836
|
// facts, and only the second one governs a deployed image.
|
|
1824
1837
|
//
|
|
1825
|
-
// MEASURED 2026-09-17. Emitting it took
|
|
1838
|
+
// MEASURED 2026-09-17. Emitting it took a customer environment's three
|
|
1826
1839
|
// distribution-lock consumers — biome-host-api, capability-registry-api,
|
|
1827
1840
|
// xema-capability-router — into CrashLoopBackOff on a sealed, signed,
|
|
1828
1841
|
// platform-verified edition. The seal was green; the lock was unparseable
|
|
@@ -1840,7 +1853,7 @@ export function resolveDistributionFromInputs(
|
|
|
1840
1853
|
// somebody raised the pin. Re-measured against the refs, not the comment:
|
|
1841
1854
|
// xema-base origin/main `'@xemahq/contracts': ^0.15.0`
|
|
1842
1855
|
// xema-base origin/develop `'@xemahq/contracts': ^0.16.0`
|
|
1843
|
-
// xema-base 2ef54a1 (the `sourceCommit`
|
|
1856
|
+
// xema-base 2ef54a1 (the `sourceCommit` a customer environment's images.lock.json
|
|
1844
1857
|
// names) resolves `@xemahq/contracts@0.15.0`, sole resolution.
|
|
1845
1858
|
// and against the published tarballs, two-sided, `npm pack` + grep:
|
|
1846
1859
|
// 0.9.2 -> 0 files name this key; 0.12.0 / 0.15.0 / 0.17.0 -> 2 each.
|
|
@@ -1848,7 +1861,7 @@ export function resolveDistributionFromInputs(
|
|
|
1848
1861
|
// past the deletion condition this comment states below.
|
|
1849
1862
|
//
|
|
1850
1863
|
// WHAT ACTUALLY BLOCKS IT IS THE ROLLOUT, and a pin is not a rollout.
|
|
1851
|
-
// Measured 2026-09-19 inside the running containers in `
|
|
1864
|
+
// Measured 2026-09-19 inside the running containers in `a customer environment`:
|
|
1852
1865
|
// `cat /app/node_modules/@xemahq/contracts/package.json` -> "0.9.2",
|
|
1853
1866
|
// one resolution each (`ls -d /app/node_modules/.pnpm/@xemahq+contracts@*`),
|
|
1854
1867
|
// and `dist/distribution/lib/distribution-lock.js` carries `.strict()`
|
|
@@ -1857,7 +1870,7 @@ export function resolveDistributionFromInputs(
|
|
|
1857
1870
|
// POSITIVE CONTROL, same tree, same probe: `grep -rl distribution` -> 64.
|
|
1858
1871
|
// So the zero is an absence, not a broken probe.
|
|
1859
1872
|
// And the three running digests are NOT the digests
|
|
1860
|
-
// `deployments
|
|
1873
|
+
// `deployments/<customer>-dev/images.lock.json` designates — the cluster is
|
|
1861
1874
|
// roughly one build behind its own lock, which is why a pin raised on the
|
|
1862
1875
|
// branch has not reached the parser.
|
|
1863
1876
|
//
|
|
@@ -1875,7 +1888,7 @@ export function resolveDistributionFromInputs(
|
|
|
1875
1888
|
// answers this. For each of biome-host-api, capability-registry-api and
|
|
1876
1889
|
// xema-capability-router:
|
|
1877
1890
|
//
|
|
1878
|
-
// kubectl -n
|
|
1891
|
+
// kubectl -n <customer>-dev exec deploy/<svc> -- \
|
|
1879
1892
|
// cat /app/node_modules/@xemahq/contracts/package.json
|
|
1880
1893
|
//
|
|
1881
1894
|
// must report >= 0.12.0 for ALL THREE. When it does, in ONE change:
|
|
@@ -1884,7 +1897,7 @@ export function resolveDistributionFromInputs(
|
|
|
1884
1897
|
// the withholding and will correctly go red;
|
|
1885
1898
|
// 3. re-seal the affected locks;
|
|
1886
1899
|
// 4. delete the `postgres.extensions` BRIDGE blocks from
|
|
1887
|
-
// `deployments
|
|
1900
|
+
// `deployments/<customer>-dev/secret-inputs.yaml` and
|
|
1888
1901
|
// `deployments/owl-xema-prod/secret-inputs.yaml` in xema-deploy —
|
|
1889
1902
|
// the deploy plane REFUSES that bridge by name the moment any biome
|
|
1890
1903
|
// in the lock carries this key, so 3 and 4 cannot be separated.
|
|
@@ -2000,6 +2013,20 @@ export function resolveDistributionFromInputs(
|
|
|
2000
2013
|
// throws), so an entry without the key is one whose manifest declares
|
|
2001
2014
|
// no such worker.
|
|
2002
2015
|
workerImages: e.workerImages ?? {},
|
|
2016
|
+
// The service-to-service operations each workload component requires,
|
|
2017
|
+
// forwarded verbatim from the index (already sorted and non-empty). The
|
|
2018
|
+
// seal admits them (`admitOperationGrants`). Omitted when none, so an
|
|
2019
|
+
// edition declaring none is byte-identical.
|
|
2020
|
+
...(e.operationRequirements !== undefined &&
|
|
2021
|
+
Object.keys(e.operationRequirements).length > 0
|
|
2022
|
+
? { operationRequirements: e.operationRequirements }
|
|
2023
|
+
: {}),
|
|
2024
|
+
// The organization sweeps each workload component may hold, forwarded
|
|
2025
|
+
// verbatim; the seal admits them (`admitOrganizationSweeps`).
|
|
2026
|
+
...(e.organizationSweepRequirements !== undefined &&
|
|
2027
|
+
Object.keys(e.organizationSweepRequirements).length > 0
|
|
2028
|
+
? { organizationSweepRequirements: e.organizationSweepRequirements }
|
|
2029
|
+
: {}),
|
|
2003
2030
|
// --- Catalog projection (consumed by biome-host's DistributionCatalogSource) ---
|
|
2004
2031
|
// Forwarded verbatim from the index so the lock is the SELF-CONTAINED
|
|
2005
2032
|
// single source of truth for the biome catalog: biome-host builds the
|
|
@@ -2069,7 +2096,15 @@ export function resolveDistributionFromInputs(
|
|
|
2069
2096
|
// widening it. That refusal is the right posture and this is the right
|
|
2070
2097
|
// side of it.
|
|
2071
2098
|
const { installationClass: _installationClass, ...locked } = service;
|
|
2072
|
-
return {
|
|
2099
|
+
return {
|
|
2100
|
+
...locked,
|
|
2101
|
+
// Copied verbatim from the index entry (sorted, unique, non-empty by
|
|
2102
|
+
// its schema); the grant admission reads it from the lock.
|
|
2103
|
+
...(source.ownsCapabilityDomains === undefined
|
|
2104
|
+
? {}
|
|
2105
|
+
: { ownsCapabilityDomains: source.ownsCapabilityDomains }),
|
|
2106
|
+
source,
|
|
2107
|
+
};
|
|
2073
2108
|
})
|
|
2074
2109
|
.sort((a, b) => {
|
|
2075
2110
|
const ta = TIER_WITH_EDGE.indexOf(a.tier);
|
|
@@ -2149,7 +2184,11 @@ export function resolveDistributionFromInputs(
|
|
|
2149
2184
|
schemas.resolveFirstPartyCapabilityDomains(lock);
|
|
2150
2185
|
|
|
2151
2186
|
// (8) Validate against the BUILT kernel schema — fail-fast.
|
|
2152
|
-
schemas.parseUnsealedDistributionLock(lock);
|
|
2187
|
+
const parsed = schemas.parseUnsealedDistributionLock(lock);
|
|
2188
|
+
// (9) Admit every declared service-to-service operation requirement; a
|
|
2189
|
+
// refusal throws, so a lock with one is never returned to be written.
|
|
2190
|
+
assertOperationGrantsAdmitted(schemas, parsed);
|
|
2191
|
+
assertOrganizationSweepsAdmitted(schemas, parsed);
|
|
2153
2192
|
return validateImmutableDistributionLock(lock);
|
|
2154
2193
|
}
|
|
2155
2194
|
|
|
@@ -2176,22 +2215,33 @@ export async function resolveDistribution(id) {
|
|
|
2176
2215
|
* `materialize` is the walk's one network seam, injectable for the contract
|
|
2177
2216
|
* suite exactly as it is on `walkDeclaredSources`.
|
|
2178
2217
|
*/
|
|
2179
|
-
export async function resolveDistributionWithIndex(id, { materialize, inputs } = {}) {
|
|
2218
|
+
export async function resolveDistributionWithIndex(id, { materialize, inputs, readManifest } = {}) {
|
|
2180
2219
|
const schemas = await loadKernelDistributionSchemas();
|
|
2220
|
+
// The manifest is composed FIRST, because it is what declares the sources and
|
|
2221
|
+
// what refuses a malformed definition before any other work. The walk then
|
|
2222
|
+
// runs once per resolve and its entries are merged into a per-resolution
|
|
2223
|
+
// index — never into `biome-index.json`, which is the platform's and is read
|
|
2224
|
+
// by every edition.
|
|
2225
|
+
const composed = inputs?.composed ?? composeEdition(schemas.parseDistribution, id);
|
|
2181
2226
|
// THE RELEASE READS THESE FROM DISK; A DEVELOP SNAPSHOT INJECTS THEM
|
|
2182
2227
|
// (`develop-snapshot-inputs.mjs`). Either way they pass through the one
|
|
2183
2228
|
// validation below, so there is a single resolve path and two sources.
|
|
2184
|
-
const
|
|
2229
|
+
const claimedPlatformServiceIndex =
|
|
2185
2230
|
inputs?.platformServiceIndex ?? readPlatformServiceIndex(schemas.parsePlatformServiceSourceIndex);
|
|
2231
|
+
// OWNERSHIP IS THE SERVICE'S OWN STATEMENT: each entry's capability domains
|
|
2232
|
+
// are re-derived from its pinned source manifest (hash-verified), so a
|
|
2233
|
+
// hand-edited index cannot move where grants land. Only the customer resolve
|
|
2234
|
+
// sets `sourcesAvailable: false` -- it has no vendor checkouts and trusts the
|
|
2235
|
+
// signed catalogue, which `buildCatalogue` verified where it was produced.
|
|
2236
|
+
// Any other caller without the sources is refused, never skipped.
|
|
2237
|
+
const platformServiceIndex =
|
|
2238
|
+
inputs?.sourcesAvailable === false
|
|
2239
|
+
? claimedPlatformServiceIndex
|
|
2240
|
+
: verifiedPlatformServiceIndex(claimedPlatformServiceIndex, { readManifest });
|
|
2186
2241
|
const platformIndex = validateServiceDependencyOwnerParity(
|
|
2187
2242
|
validateImmutableBiomeIndex(inputs?.biomeIndex ?? readBiomeIndex()),
|
|
2188
2243
|
platformServiceIndex,
|
|
2189
2244
|
);
|
|
2190
|
-
// The manifest is composed FIRST, because it is what declares the sources. The
|
|
2191
|
-
// walk then runs once per resolve and its entries are merged into a
|
|
2192
|
-
// per-resolution index — never into `biome-index.json`, which is the
|
|
2193
|
-
// platform's and is read by every edition.
|
|
2194
|
-
const composed = inputs?.composed ?? composeEdition(schemas.parseDistribution, id);
|
|
2195
2245
|
const { entries, sourceRecords } = await walkDeclaredSources({
|
|
2196
2246
|
sources: composed.declaredSources,
|
|
2197
2247
|
...(materialize === undefined ? {} : { materialize }),
|
|
@@ -36,6 +36,7 @@ import { execFileSync } from 'node:child_process';
|
|
|
36
36
|
import { writeFileSync } from 'node:fs';
|
|
37
37
|
import { join, relative, sep } from 'node:path';
|
|
38
38
|
|
|
39
|
+
import { resolveDispatchedRuntimeComponents } from './dispatched-runtime-components.mjs';
|
|
39
40
|
import {
|
|
40
41
|
assertCanonicalDistributionId,
|
|
41
42
|
distributionOutputPath,
|
|
@@ -281,7 +282,7 @@ export function resolveDistributionRequiredPlatforms(schemas, id) {
|
|
|
281
282
|
* the fully-qualified `imageRef`. It cannot travel in the lock to reach the
|
|
282
283
|
* resolver — `DistributionLockSchema` is `.strict()` and learned that key only
|
|
283
284
|
* in `@xemahq/contracts` 0.10.0, so a pinned image resolving `^0.9.x` refuses
|
|
284
|
-
* the whole lock at boot. Persisting it took
|
|
285
|
+
* the whole lock at boot. Persisting it took a customer environment's three lock
|
|
285
286
|
* consumers into CrashLoopBackOff on 2026-09-17.
|
|
286
287
|
*
|
|
287
288
|
* So the producer reads its OWN declaration, and `requiredPlatforms` one
|
|
@@ -396,8 +397,11 @@ function missingArtifactDependencyMessage(lock, serviceName, binding, biomeIndex
|
|
|
396
397
|
* refuse. What DOES refuse is a SELECTED service whose declared artifact
|
|
397
398
|
* dependency is absent from the closure (see `missingArtifactDependencyMessage`).
|
|
398
399
|
*
|
|
399
|
-
* `options.biomeIndex` is
|
|
400
|
-
* biome declares
|
|
400
|
+
* `options.biomeIndex` is the first-party biome index. It names, in a refusal,
|
|
401
|
+
* which biome declares a missing artifact, and it carries each rostered biome's
|
|
402
|
+
* `dispatchesRuntimeComponents`: the runtime components that biome launches,
|
|
403
|
+
* whose images enter this roster as runtime-component rows although their
|
|
404
|
+
* biomes are not rostered (see `dispatched-runtime-components.mjs`).
|
|
401
405
|
*/
|
|
402
406
|
export function resolveImageStructure(
|
|
403
407
|
lock,
|
|
@@ -414,6 +418,12 @@ export function resolveImageStructure(
|
|
|
414
418
|
`and there is no default; a silent default is the bug this replaced`,
|
|
415
419
|
);
|
|
416
420
|
}
|
|
421
|
+
if (!Array.isArray(biomeIndex)) {
|
|
422
|
+
throw new Error(
|
|
423
|
+
`distribution "${lock.distributionId}" resolved its images without the biome index — the index carries ` +
|
|
424
|
+
'the runtime components a rostered biome dispatches, so a roster without it can omit images',
|
|
425
|
+
);
|
|
426
|
+
}
|
|
417
427
|
const subjects = new Map();
|
|
418
428
|
const webBiomes = [];
|
|
419
429
|
const platformServiceBindings = [];
|
|
@@ -505,7 +515,7 @@ export function resolveImageStructure(
|
|
|
505
515
|
// is `.strict()` and learned the key only in 0.10.0.
|
|
506
516
|
//
|
|
507
517
|
// Removing it from the lock WITHOUT moving this read is what composed
|
|
508
|
-
// `<customer-registry>/pai-core-api` instead of `<customer-registry
|
|
518
|
+
// `<customer-registry>/pai-core-api` instead of `<customer-registry>/<customer>-pai-core-api`:
|
|
509
519
|
// the `?? ''` swallowed the absence, so an unqualified name in a shared
|
|
510
520
|
// organisation namespace resolved silently. That is worse than a 404 —
|
|
511
521
|
// the first collision overwrites another product's tags.
|
|
@@ -604,6 +614,57 @@ export function resolveImageStructure(
|
|
|
604
614
|
}
|
|
605
615
|
}
|
|
606
616
|
|
|
617
|
+
// Runtime components a rostered biome DISPATCHES enter the roster as
|
|
618
|
+
// runtime-component rows built from the TARGET biome's index entry, at its
|
|
619
|
+
// repository pin, exactly like a rostered biome's own runtime component. The
|
|
620
|
+
// owner is the rostered biome that dispatches it: the selection that brings
|
|
621
|
+
// the image into this edition. The target biome stays unrostered.
|
|
622
|
+
//
|
|
623
|
+
// A rostered biome's edges are read from ITS index entry, which must describe
|
|
624
|
+
// the very biome the lock pins; one from a declared source is refused at
|
|
625
|
+
// distribution resolve if it dispatches, and the first-party index carries
|
|
626
|
+
// none, so it is not looked up here.
|
|
627
|
+
const dispatchers = lock.biomes
|
|
628
|
+
.filter((biome) => biome.source === undefined && biome.target === 'server')
|
|
629
|
+
.map((biome) => {
|
|
630
|
+
const entries = biomeIndex.filter(
|
|
631
|
+
(entry) =>
|
|
632
|
+
entry.id === biome.id &&
|
|
633
|
+
entry.target === biome.target &&
|
|
634
|
+
entry.repo === biome.repo &&
|
|
635
|
+
entry.source === undefined,
|
|
636
|
+
);
|
|
637
|
+
if (entries.length !== 1 || entries[0].sourceManifestHash !== biome.sourceManifestHash) {
|
|
638
|
+
throw new Error(
|
|
639
|
+
`distribution "${lock.distributionId}" biome "${biome.id}" (${biome.repo}, ${biome.sourceManifestHash}) ` +
|
|
640
|
+
`has ${entries.length === 1 ? 'a stale' : `${entries.length}`} biome index ${entries.length === 1 ? 'entry' : 'entries'}, ` +
|
|
641
|
+
'so the runtime components it dispatches cannot be read — re-resolve the edition from the current index',
|
|
642
|
+
);
|
|
643
|
+
}
|
|
644
|
+
return entries[0];
|
|
645
|
+
});
|
|
646
|
+
for (const dispatched of resolveDispatchedRuntimeComponents(
|
|
647
|
+
`distribution "${lock.distributionId}"`,
|
|
648
|
+
dispatchers,
|
|
649
|
+
biomeIndex,
|
|
650
|
+
)) {
|
|
651
|
+
const { target } = dispatched;
|
|
652
|
+
addSubject(subjects, {
|
|
653
|
+
kind: enums.RuntimeImageSubjectKind.RuntimeComponent,
|
|
654
|
+
id: dispatched.image,
|
|
655
|
+
imageRef: imageRefForSubject(dispatched.image, firstPartyImageRegistry(), ''),
|
|
656
|
+
repo: target.repo,
|
|
657
|
+
path: target.path,
|
|
658
|
+
sourceCommit: requireRepositoryPin(target.repo).sourceCommit,
|
|
659
|
+
sourceManifestHash: target.sourceManifestHash,
|
|
660
|
+
requiredPlatforms,
|
|
661
|
+
owners: dispatched.consumers.map((biomeId) => ({
|
|
662
|
+
kind: enums.RuntimeImageOwnerKind.Biome,
|
|
663
|
+
biomeId,
|
|
664
|
+
})),
|
|
665
|
+
});
|
|
666
|
+
}
|
|
667
|
+
|
|
607
668
|
const runtimeBindings = new Map(
|
|
608
669
|
runtimeSourceIndex.platformServiceBindings.map((binding) => [
|
|
609
670
|
binding.platformService,
|
|
@@ -703,7 +703,7 @@ async function main() {
|
|
|
703
703
|
// `DistributionLockSchema` is `.strict()` — so a key the plane knows and a
|
|
704
704
|
// pinned repository does not makes the whole artifact unreadable AT BOOT.
|
|
705
705
|
// That is not hypothetical: on 2026-09-17 `imageNamePrefix` did exactly this
|
|
706
|
-
// to three
|
|
706
|
+
// to three a customer environment services at once, and the edition had sealed,
|
|
707
707
|
// published and installed perfectly first.
|
|
708
708
|
//
|
|
709
709
|
// It is asked of every pinned repository that SHIPS AN IMAGE INTO THIS
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xemahq/xema",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.31.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/xema-dev/xema-cli.git",
|
|
7
7
|
"directory": "apps/xema-cli"
|
|
8
8
|
},
|
|
9
9
|
"license": "Apache-2.0",
|
|
10
|
-
"description": "Xema
|
|
10
|
+
"description": "Xema global CLI. Single binary day-0 onboarding: `npm i -g @xemahq/xema && xema dev` boots the whole stack; `xema biome scaffold` / `install` / `publish` / `lint` author and ship biomes; `xema run <capability>` invokes through the local capability-router. Multi-platform: works without pnpm or any monorepo clone.",
|
|
11
11
|
"type": "commonjs",
|
|
12
12
|
"main": "dist/cli.js",
|
|
13
13
|
"exports": {
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"@xemahq/distribution-source-hash": "^0.3.0",
|
|
55
55
|
"@xemahq/dsl": "^0.23.0",
|
|
56
56
|
"@xemahq/identity-client": "^0.16.0",
|
|
57
|
-
"@xemahq/contracts": "^0.
|
|
57
|
+
"@xemahq/contracts": "^0.80.0",
|
|
58
58
|
"@xemahq/kernel-state-runtime": "^0.8.0",
|
|
59
59
|
"@xemahq/license-verifier": "^0.2.0",
|
|
60
60
|
"@xemahq/service-registry-nest": "^0.12.2",
|
|
@@ -92,6 +92,6 @@
|
|
|
92
92
|
"typecheck": "tsc --noEmit"
|
|
93
93
|
},
|
|
94
94
|
"xemaRelease": {
|
|
95
|
-
"sourceDigest": "sha256:
|
|
95
|
+
"sourceDigest": "sha256:2fc7a76e728752cf14eeb410921fb5c89cbffc9c3c398116a3c37dcd740587ea"
|
|
96
96
|
}
|
|
97
97
|
}
|