@astrale-os/cli 1.0.0-beta.3 → 1.0.0-beta.31
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/README.md +84 -6
- package/dist/astrale.js +57586 -60753
- package/dist/public/connect-core.js +2158 -30706
- package/dist/public/keys/index.js +1016 -29541
- package/dist/public/paths/index.js +370 -28654
- package/dist/types/admin/contract.d.ts +26 -0
- package/dist/types/admin/instance/client.d.ts +20 -0
- package/dist/types/admin/instance/index.d.ts +2 -0
- package/dist/types/admin/instance/model.d.ts +6 -10
- package/dist/types/connection/auth.d.ts +3 -0
- package/dist/types/connection/call.d.ts +3 -0
- package/dist/types/connection/command.d.ts +27 -0
- package/dist/types/connection/credential.d.ts +14 -0
- package/dist/types/connection/errors.d.ts +1 -0
- package/dist/types/connection/exchange.d.ts +9 -0
- package/dist/types/connection/failure/classify.d.ts +2 -0
- package/dist/types/connection/failure/index.d.ts +5 -0
- package/dist/types/connection/failure/model.d.ts +25 -0
- package/dist/types/connection/failure/render.d.ts +3 -0
- package/dist/types/connection/index.d.ts +8 -0
- package/dist/types/connection/reasons.d.ts +37 -0
- package/dist/types/connection/self.d.ts +37 -0
- package/dist/types/connection/session.d.ts +31 -0
- package/dist/types/connection/target.d.ts +38 -0
- package/dist/types/errors.d.ts +1 -1
- package/dist/types/lib/admin-instance.d.ts +17 -0
- package/dist/types/lib/admin-target.d.ts +11 -36
- package/dist/types/lib/config.d.ts +13 -59
- package/dist/types/lib/failure-debug.d.ts +1 -0
- package/dist/types/lib/idp.d.ts +25 -173
- package/dist/types/lib/instance-target.d.ts +1 -1
- package/dist/types/lib/instance.d.ts +30 -88
- package/dist/types/lib/log.d.ts +5 -3
- package/dist/types/lib/output.d.ts +1 -1
- package/dist/types/lib/proc.d.ts +43 -0
- package/dist/types/lib/self.d.ts +9 -0
- package/dist/types/lib/update.d.ts +109 -0
- package/dist/types/lib/validation.d.ts +4 -1
- package/dist/types/state/exchange-credentials.d.ts +6 -2
- package/dist/types/state/files.d.ts +2 -0
- package/dist/types/state/index.d.ts +3 -2
- package/dist/types/state/paths.d.ts +2 -0
- package/dist/types/state/session-routes.d.ts +10 -0
- package/package.json +16 -19
- package/src/__tests__/fixtures/publication.ts +20 -0
- package/src/admin/.spec/architecture.md +12 -5
- package/src/admin/__tests__/fixture.ts +25 -0
- package/src/admin/catalog/.spec/api.d.ts +1 -3
- package/src/admin/catalog/.spec/architecture.md +5 -4
- package/src/admin/catalog/__tests__/client.test.ts +143 -69
- package/src/admin/catalog/client.ts +40 -54
- package/src/admin/catalog/model.ts +3 -4
- package/src/admin/contract.ts +47 -0
- package/src/admin/graph/.spec/api.d.ts +4 -10
- package/src/admin/graph/nodes.ts +1 -1
- package/src/admin/instance/.spec/api.d.ts +5 -9
- package/src/admin/instance/.spec/architecture.md +7 -7
- package/src/admin/instance/__tests__/client.test.ts +157 -175
- package/src/admin/instance/client.ts +39 -128
- package/src/admin/instance/index.ts +1 -2
- package/src/admin/instance/model.ts +12 -18
- package/src/commands/__tests__/admin-instance.test.ts +11 -8
- package/src/commands/__tests__/call-describe.test.ts +46 -33
- package/src/commands/__tests__/call.test.ts +34 -0
- package/src/commands/__tests__/domain-install-operation.test.ts +30 -22
- package/src/commands/__tests__/domain-install-owned.test.ts +1 -1
- package/src/commands/__tests__/domain-list.test.ts +5 -25
- package/src/commands/__tests__/install-direct.test.ts +115 -8
- package/src/commands/__tests__/install-identity-override.test.ts +6 -17
- package/src/commands/__tests__/instance-list-rows.test.ts +1 -1
- package/src/commands/__tests__/instance-status.test.ts +139 -0
- package/src/commands/__tests__/introspect-parse.test.ts +80 -1
- package/src/commands/__tests__/logs.test.ts +250 -2
- package/src/commands/__tests__/read-commands.test.ts +119 -11
- package/src/commands/__tests__/token-ttl.test.ts +49 -4
- package/src/commands/__tests__/update.test.ts +25 -3
- package/src/commands/__tests__/view.test.ts +50 -2
- package/src/commands/auth/logout.ts +2 -1
- package/src/commands/browser.ts +29 -0
- package/src/commands/call-describe.ts +60 -68
- package/src/commands/call.ts +71 -59
- package/src/commands/domain/install.ts +73 -46
- package/src/commands/domain/list.ts +1 -1
- package/src/commands/domain/publish.ts +14 -11
- package/src/commands/domain/uninstall.ts +2 -2
- package/src/commands/get.ts +15 -16
- package/src/commands/identity/__tests__/register.test.ts +3 -3
- package/src/commands/identity/register.ts +8 -8
- package/src/commands/instance/create.ts +8 -16
- package/src/commands/instance/delete.ts +12 -9
- package/src/commands/instance/list.ts +2 -2
- package/src/commands/instance/status.ts +66 -20
- package/src/commands/instance/use.ts +16 -12
- package/src/commands/introspect.ts +53 -41
- package/src/commands/logs.ts +123 -36
- package/src/commands/mutate.ts +6 -5
- package/src/commands/query.ts +39 -36
- package/src/commands/session/analyze.ts +26 -4
- package/src/commands/token.ts +42 -27
- package/src/commands/ui/__tests__/commands.test.ts +152 -0
- package/src/commands/ui/add.ts +51 -0
- package/src/commands/ui/doctor.ts +21 -0
- package/src/commands/ui/init.ts +38 -0
- package/src/commands/ui/list.ts +26 -0
- package/src/commands/ui/preset-apply.ts +19 -0
- package/src/commands/ui/preset-list.ts +12 -0
- package/src/commands/ui/shared.ts +25 -0
- package/src/commands/update.ts +90 -48
- package/src/commands/view.ts +82 -37
- package/src/connection/.spec/api.d.ts +7 -8
- package/src/connection/.spec/architecture.md +14 -5
- package/src/connection/.spec/flows/session.ts +2 -2
- package/src/connection/.spec/laws/connection.ts +6 -2
- package/src/connection/.spec/layout.ts +1 -0
- package/src/connection/__tests__/auth.test.ts +1 -0
- package/src/connection/__tests__/credential.test.ts +21 -1
- package/src/connection/__tests__/errors.test.ts +27 -20
- package/src/connection/__tests__/exchange.test.ts +64 -11
- package/src/connection/__tests__/failure-fixtures.ts +39 -0
- package/src/connection/__tests__/failure-safety.test.ts +75 -0
- package/src/connection/__tests__/self.test.ts +31 -11
- package/src/connection/__tests__/session.test.ts +8 -4
- package/src/connection/__tests__/target.test.ts +2 -0
- package/src/connection/auth.ts +13 -0
- package/src/connection/call.ts +1 -1
- package/src/connection/credential.ts +2 -2
- package/src/connection/errors.ts +1 -355
- package/src/connection/exchange.ts +110 -61
- package/src/connection/failure/classify.ts +110 -0
- package/src/connection/failure/index.ts +18 -0
- package/src/connection/failure/model.ts +28 -0
- package/src/connection/failure/render.ts +116 -0
- package/src/connection/reasons.ts +16 -0
- package/src/connection/self.ts +39 -21
- package/src/connection/session.ts +27 -9
- package/src/errors.ts +3 -2
- package/src/graph/.spec/api.d.ts +13 -6
- package/src/graph/.spec/laws/documents.ts +7 -7
- package/src/graph/.spec/layout.ts +9 -1
- package/src/graph/__tests__/mutation.test.ts +2 -2
- package/src/graph/__tests__/query.test.ts +35 -9
- package/src/graph/class.ts +30 -0
- package/src/graph/index.ts +1 -0
- package/src/graph/query.ts +27 -40
- package/src/identity/.spec/api.d.ts +2 -2
- package/src/identity/__tests__/fixtures/registry-journey.ts +13 -1
- package/src/identity/__tests__/registration.test.ts +1 -1
- package/src/identity/__tests__/registry.test.ts +4 -0
- package/src/identity/registration.ts +3 -3
- package/src/identity/registry.ts +2 -0
- package/src/keys/__tests__/keys.test.ts +4 -0
- package/src/keys/credential.ts +1 -0
- package/src/lib/__tests__/admin-target.test.ts +12 -0
- package/src/lib/__tests__/binary.test.ts +16 -1
- package/src/lib/__tests__/browser-retention.test.ts +212 -0
- package/src/lib/__tests__/command-dx.test.ts +1 -1
- package/src/lib/__tests__/config.test.ts +27 -0
- package/src/lib/__tests__/domain-publication.test.ts +10 -16
- package/src/lib/__tests__/idp.test.ts +34 -4
- package/src/lib/__tests__/instance-candidates.test.ts +1 -3
- package/src/lib/__tests__/instance-target.test.ts +7 -39
- package/src/lib/__tests__/log-errors.test.ts +64 -0
- package/src/lib/__tests__/skills.test.ts +834 -0
- package/src/lib/__tests__/studio-server-deps.test.ts +1 -1
- package/src/lib/__tests__/update.test.ts +264 -11
- package/src/lib/__tests__/view-assets.test.ts +25 -0
- package/src/lib/__tests__/view-external-open-intent.test.ts +150 -0
- package/src/lib/__tests__/view-external-open-origins.test.ts +27 -0
- package/src/lib/__tests__/view-open-intent.test.ts +0 -2
- package/src/lib/__tests__/view-server.test.ts +26 -3
- package/src/lib/__tests__/view-session.test.ts +2 -1
- package/src/lib/admin-instance.ts +14 -8
- package/src/lib/admin-target.ts +21 -2
- package/src/lib/binary.ts +22 -5
- package/src/lib/browser-retention.ts +210 -0
- package/src/lib/command-dx.ts +9 -9
- package/src/lib/config.ts +12 -1
- package/src/lib/domain-publication.ts +9 -7
- package/src/lib/failure-debug.ts +26 -0
- package/src/lib/idp.ts +34 -3
- package/src/lib/instance-candidates.ts +2 -2
- package/src/lib/instance-target.ts +3 -14
- package/src/lib/instance.ts +16 -11
- package/src/lib/log.ts +16 -9
- package/src/lib/output.ts +1 -1
- package/src/lib/proc.ts +7 -2
- package/src/lib/provision-instance.ts +34 -57
- package/src/lib/skills/lock.ts +117 -0
- package/src/lib/skills/sync.ts +878 -0
- package/src/lib/skills.ts +1 -52
- package/src/lib/update.ts +298 -45
- package/src/lib/validation.ts +2 -2
- package/src/lib/view/assets.ts +11 -2
- package/src/lib/view/external-open-intent.ts +41 -0
- package/src/lib/view/external-open-origins.ts +37 -0
- package/src/lib/view/host-capabilities.ts +17 -0
- package/src/lib/view/resolve.ts +1 -1
- package/src/lib/view/server.ts +18 -3
- package/src/lib/view/session.ts +2 -0
- package/src/program/.spec/api.d.ts +1 -0
- package/src/program/__tests__/program.test.ts +201 -7
- package/src/program/argv.ts +14 -0
- package/src/program/build.ts +26 -4
- package/src/program/command.ts +1 -0
- package/src/program/index.ts +1 -0
- package/src/program/registry.ts +2 -1
- package/src/setup/__tests__/instance-step.test.ts +27 -10
- package/src/setup/steps/instance.ts +22 -15
- package/src/setup/steps/skills.ts +40 -38
- package/src/state/.spec/api.d.ts +21 -2
- package/src/state/.spec/architecture.md +18 -4
- package/src/state/.spec/layout.ts +1 -0
- package/src/state/__tests__/exchange-credentials.test.ts +88 -42
- package/src/state/__tests__/files.test.ts +24 -1
- package/src/state/__tests__/fixtures/session-route-process.ts +93 -0
- package/src/state/__tests__/paths.test.ts +1 -0
- package/src/state/__tests__/session-routes.test.ts +138 -0
- package/src/state/exchange-credentials.ts +22 -9
- package/src/state/files.ts +41 -0
- package/src/state/index.ts +3 -1
- package/src/state/paths.ts +3 -0
- package/src/state/session-routes.ts +34 -0
- package/src/telemetry/__tests__/analyze-log.test.ts +38 -0
- package/src/telemetry/__tests__/recorder.test.ts +1 -0
- package/src/telemetry/__tests__/retention.test.ts +267 -0
- package/src/telemetry/__tests__/settings.test.ts +102 -0
- package/src/telemetry/__tests__/store-scan.test.ts +128 -0
- package/src/telemetry/__tests__/trigger.test.ts +33 -4
- package/src/telemetry/analyze.ts +24 -2
- package/src/telemetry/recorder.ts +15 -4
- package/src/telemetry/retention.ts +176 -0
- package/src/telemetry/session.ts +18 -12
- package/src/telemetry/settings.ts +64 -11
- package/src/telemetry/store.ts +92 -9
- package/src/telemetry/trigger.ts +16 -28
- package/src/ui/.spec/api.d.ts +14 -0
- package/src/ui/.spec/architecture.md +14 -0
- package/src/ui/.spec/laws.ts +50 -0
- package/src/ui/.spec/layout.ts +16 -0
- package/src/ui/__tests__/ui.test.ts +1742 -0
- package/src/ui/index.ts +13 -0
- package/src/ui/lock.ts +89 -0
- package/src/ui/model.ts +83 -0
- package/src/ui/operations.ts +1044 -0
- package/src/ui/project.ts +333 -0
- package/src/ui/release.ts +398 -0
- package/src/ui/runner.ts +18 -0
- package/studio/client/dist/assets/elk-api-DjmKsHXc.js +1 -0
- package/studio/client/dist/assets/index-BFVFs_8x.js +81 -0
- package/studio/client/dist/assets/index-DuB9iUdu.css +2 -0
- package/studio/client/dist/assets/rolldown-runtime-Dd_uD5pT.js +1 -0
- package/studio/client/dist/assets/schema-studio--a0kX3QU.css +1 -0
- package/studio/client/dist/assets/schema-studio-DH6oEWME.js +8 -0
- package/studio/client/dist/index.html +4 -3
- package/studio/package.json +8 -14
- package/studio/server/agent/ask.test.ts +1 -1
- package/studio/server/agent/bridge/grant.test.ts +1 -1
- package/studio/server/agent/bridge/routes.test.ts +1 -1
- package/studio/server/agent/harness/claude/adapter.test.ts +15 -5
- package/studio/server/agent/harness/gateway/token.test.ts +1 -1
- package/studio/server/agent/harness/gateway/token.ts +3 -3
- package/studio/server/agent/prompts/anchors.test.ts +41 -32
- package/studio/server/agent/prompts/anchors.ts +23 -51
- package/studio/server/agent/prompts/system.test.ts +4 -4
- package/studio/server/agent/prompts/system.ts +5 -5
- package/studio/server/agent/routes.test.ts +1 -1
- package/studio/server/agent/run/coordinator.test.ts +1 -1
- package/studio/server/agent/run/preparation.ts +1 -1
- package/studio/server/api/canvas.ts +0 -1
- package/studio/server/api/context.ts +1 -1
- package/studio/server/api/deployment.ts +1 -1
- package/studio/server/api/views.ts +2 -2
- package/studio/server/api/workspace.ts +1 -1
- package/studio/server/api-agent-loadout.test.ts +1 -1
- package/studio/server/api.test.ts +1 -1
- package/studio/server/cache.test.ts +24 -18
- package/studio/server/cache.ts +10 -54
- package/studio/server/cli-consumers.test.ts +32 -4
- package/studio/server/cli.test.ts +2 -2
- package/studio/server/domain.test.ts +50 -68
- package/studio/server/domain.ts +82 -63
- package/studio/server/handoff/copy.ts +2 -2
- package/studio/server/index.ts +1 -1
- package/studio/server/instances/probe.test.ts +1 -1
- package/studio/server/introspect/anatomy/views/routes.ts +46 -37
- package/studio/server/introspect/anatomy/views.ts +10 -16
- package/studio/server/introspect/anatomy-extras.test.ts +29 -56
- package/studio/server/introspect/anatomy.test.ts +22 -14
- package/studio/server/introspect/anatomy.ts +6 -9
- package/studio/server/introspect/bundle.ts +0 -3
- package/studio/server/introspect/canonical-schema.test.ts +155 -424
- package/studio/server/introspect/canonical-schema.ts +248 -601
- package/studio/server/introspect/core.ts +14 -22
- package/studio/server/introspect/diff.test.ts +21 -9
- package/studio/server/introspect/diff.ts +19 -64
- package/studio/server/introspect/extractor.ts +23 -122
- package/studio/server/introspect/overlay-tsmorph.test.ts +116 -241
- package/studio/server/introspect/overlay-tsmorph.ts +0 -1
- package/studio/server/introspect/overlay.ts +3 -51
- package/studio/server/introspect/revision.test.ts +24 -28
- package/studio/server/introspect/revision.ts +11 -22
- package/studio/server/introspect/runtime.test.ts +77 -195
- package/studio/server/introspect/runtime.ts +5 -67
- package/studio/server/introspect/schema-ir-json.test.ts +81 -0
- package/studio/server/introspect/schema-ir-json.ts +39 -69
- package/studio/server/introspect/schema-refs.test.ts +43 -88
- package/studio/server/introspect/schema-refs.ts +14 -49
- package/studio/server/introspect/source-overlay/handlers.ts +116 -636
- package/studio/server/introspect/source-overlay/kernel-calls.ts +0 -3
- package/studio/server/introspect/source-overlay/spans.ts +15 -45
- package/studio/server/lifecycle.ts +4 -1
- package/studio/server/state/baseline.test.ts +14 -9
- package/studio/server/state/baseline.ts +3 -5
- package/studio/server/state/documents.test.ts +69 -0
- package/studio/server/state/documents.ts +57 -10
- package/studio/server/state/visibility.ts +1 -5
- package/studio/server/views/model.ts +3 -3
- package/studio/server/views/target.test.ts +18 -76
- package/studio/server/views/target.ts +25 -51
- package/studio/server/watch.test.ts +11 -11
- package/studio/server/watch.ts +8 -4
- package/studio/server/workspace/updates.ts +23 -1
- package/studio/server/workspace-watch.ts +2 -2
- package/studio/shared/contracts/runtime.ts +4 -0
- package/studio/shared/contracts/schema.ts +44 -131
- package/studio/shared/contracts/surface.test.ts +15 -17
- package/studio/shared/contracts/workspace.ts +5 -11
- package/studio/shared/schema/identity.test.ts +20 -44
- package/studio/shared/schema/identity.ts +9 -24
- package/studio/tsconfig.json +2 -1
- package/tsconfig.json +1 -1
- package/viewer/dist/index.html +21 -0
- package/viewer/dist/main.js +41 -62
- package/.check-workspace.cjs +0 -40
- package/src/admin/binding.ts +0 -168
- package/src/commands/__tests__/instance-create-hosts.test.ts +0 -29
- package/studio/client/dist/assets/elk-api-lwhFo7vB.js +0 -1
- package/studio/client/dist/assets/index-B-c-smo9.js +0 -8
- package/studio/client/dist/assets/index-BckHuAWk.js +0 -81
- package/studio/client/dist/assets/index-C4aNQ6dz.css +0 -1
- package/studio/client/dist/assets/index-ChOr3yP0.css +0 -1
- package/studio/server/introspect/anatomy/views/legacy.ts +0 -232
- package/studio/server/introspect/core-extractor.ts +0 -139
- package/studio/server/introspect/overlay.test.ts +0 -72
- package/studio/server/introspect/source-overlay/annotations.ts +0 -14
|
@@ -6,12 +6,12 @@ import { join } from 'node:path'
|
|
|
6
6
|
import type { DomainHandle } from '../domain'
|
|
7
7
|
|
|
8
8
|
import { buildBundle } from './bundle'
|
|
9
|
+
import { buildCore } from './core'
|
|
9
10
|
import { renderFingerprintOf } from './hash'
|
|
10
11
|
import { admittedBundleRevision } from './revision'
|
|
11
|
-
import {
|
|
12
|
+
import { runtimeExtract } from './runtime'
|
|
12
13
|
|
|
13
14
|
const roots: string[] = []
|
|
14
|
-
|
|
15
15
|
afterEach(() => {
|
|
16
16
|
while (roots.length > 0) rmSync(roots.pop()!, { recursive: true, force: true })
|
|
17
17
|
})
|
|
@@ -22,254 +22,136 @@ function fixtureRoot(label: string): string {
|
|
|
22
22
|
mkdirSync(join(root, 'schema'), { recursive: true })
|
|
23
23
|
writeFileSync(join(root, 'package.json'), '{"type":"module"}\n')
|
|
24
24
|
writeFileSync(join(root, 'astrale.config.ts'), 'export default {}\n')
|
|
25
|
-
return root
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function linkCurrentSdk(root: string): void {
|
|
29
25
|
const sdk = realpathSync(join(import.meta.dir, '../../../node_modules/@astrale-os/sdk'))
|
|
30
26
|
const scope = join(root, 'node_modules', '@astrale-os')
|
|
31
27
|
mkdirSync(scope, { recursive: true })
|
|
32
28
|
symlinkSync(sdk, join(scope, 'sdk'), 'dir')
|
|
29
|
+
return root
|
|
33
30
|
}
|
|
34
31
|
|
|
35
32
|
function currentFixture(): DomainHandle {
|
|
36
33
|
const root = fixtureRoot('canonical-runtime')
|
|
37
|
-
|
|
38
|
-
const
|
|
39
|
-
const domainFile = join(root, 'implementation.ts')
|
|
34
|
+
const schemaIndex = join(root, 'schema/index.ts')
|
|
35
|
+
const applicationFile = join(root, 'application.ts')
|
|
40
36
|
writeFileSync(
|
|
41
37
|
schemaIndex,
|
|
42
38
|
`
|
|
43
|
-
import {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
output: { type: 'boolean' },
|
|
59
|
-
auth: 'authenticated',
|
|
60
|
-
})
|
|
61
|
-
const Document = nodeClass({
|
|
62
|
-
implements: [Named],
|
|
63
|
-
properties: { title: property({ type: 'string' }, { required: true }) },
|
|
64
|
-
methods: { rename },
|
|
65
|
-
})
|
|
66
|
-
const owned_by = edgeClass.directed({
|
|
67
|
-
source: { as: 'document', accepts: [Document], outgoing: '0..*' },
|
|
68
|
-
target: { as: 'owner', accepts: [Document], incoming: '0..*' },
|
|
69
|
-
})
|
|
70
|
-
const welcome = node(Document, { title: 'Welcome' })
|
|
71
|
-
|
|
72
|
-
export const schema = defineSchema('documents.runtime.test', {
|
|
73
|
-
dependencies: [Directory],
|
|
74
|
-
classes: { Document, owned_by },
|
|
75
|
-
functions: {
|
|
76
|
-
exportAll: fn({
|
|
77
|
-
input: { type: 'object', properties: {}, required: [], additionalProperties: false },
|
|
78
|
-
output: output.binary(),
|
|
79
|
-
auth: 'authenticated',
|
|
80
|
-
}),
|
|
81
|
-
},
|
|
82
|
-
views: { editor: view({ target: Document, auth: 'optional' }) },
|
|
83
|
-
core: {
|
|
84
|
-
nodes: { welcome },
|
|
85
|
-
edges: [edge(welcome, owned_by, domain(), {})],
|
|
86
|
-
},
|
|
87
|
-
})
|
|
88
|
-
export const installedBundle = bundle.create(schema)
|
|
89
|
-
`,
|
|
39
|
+
import { bundle, core, defineSchema, nodeClass, view } from '@astrale-os/sdk/schema'
|
|
40
|
+
const Named = nodeClass({ properties: {} })
|
|
41
|
+
export const DirectorySchema = defineSchema('directory.runtime.test', {
|
|
42
|
+
classes: { Named },
|
|
43
|
+
})
|
|
44
|
+
const Document = nodeClass({ extends: [Named], properties: {} })
|
|
45
|
+
const welcome = core.node(Document, {})
|
|
46
|
+
export const schema = defineSchema('documents.runtime.test', {
|
|
47
|
+
dependencies: { directory: DirectorySchema },
|
|
48
|
+
classes: { Document },
|
|
49
|
+
views: { editor: view({ target: Document }) },
|
|
50
|
+
core: { nodes: { welcome } },
|
|
51
|
+
})
|
|
52
|
+
export const installedBundle = bundle.create(schema)
|
|
53
|
+
`,
|
|
90
54
|
)
|
|
91
|
-
|
|
92
|
-
writeFileSync(domainFile, `throw new Error('composition entry was imported')\n`)
|
|
55
|
+
writeFileSync(applicationFile, `throw new Error('Application entry was imported')\n`)
|
|
93
56
|
return {
|
|
94
57
|
id: 'documents-runtime-test',
|
|
95
58
|
root,
|
|
96
59
|
configFile: join(root, 'astrale.config.ts'),
|
|
97
|
-
|
|
60
|
+
applicationFile,
|
|
98
61
|
schemaDirName: 'schema',
|
|
99
62
|
schemaDir: join(root, 'schema'),
|
|
100
63
|
schemaIndex,
|
|
101
64
|
}
|
|
102
65
|
}
|
|
103
66
|
|
|
104
|
-
describe('
|
|
105
|
-
test('
|
|
67
|
+
describe('SDK V1 schema extractor', () => {
|
|
68
|
+
test('uses the authored SDK for admission and projects exact imported Classes', async () => {
|
|
106
69
|
const handle = currentFixture()
|
|
107
70
|
const result = await runtimeExtract(handle.schemaIndex, handle.root)
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
origin: 'documents.runtime.test',
|
|
116
|
-
})
|
|
117
|
-
expect(result.ir).toMatchObject({
|
|
118
|
-
format: 'astrale.dsl',
|
|
119
|
-
domain: 'documents.runtime.test',
|
|
120
|
-
functions: {
|
|
121
|
-
exportAll: {
|
|
122
|
-
static: true,
|
|
123
|
-
inheritance: 'default',
|
|
124
|
-
output: { mode: 'binary' },
|
|
125
|
-
},
|
|
71
|
+
expect(result).toMatchObject({
|
|
72
|
+
ok: true,
|
|
73
|
+
schemaMode: 'canonical-admitted',
|
|
74
|
+
root: {
|
|
75
|
+
format: 'astrale.dsl',
|
|
76
|
+
version: 'v1',
|
|
77
|
+
origin: 'documents.runtime.test',
|
|
126
78
|
},
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
79
|
+
ir: {
|
|
80
|
+
domain: 'documents.runtime.test',
|
|
81
|
+
views: { editor: { target: { kind: 'definition' } } },
|
|
82
|
+
importsByKey: {
|
|
83
|
+
'directory.runtime.test:class.Named': {
|
|
84
|
+
ref: { origin: 'directory.runtime.test', kind: 'class', name: 'Named' },
|
|
85
|
+
},
|
|
131
86
|
},
|
|
132
87
|
},
|
|
133
88
|
})
|
|
134
|
-
expect(result.
|
|
135
|
-
name: 'Named',
|
|
136
|
-
origin: 'directory.runtime.test',
|
|
137
|
-
})
|
|
89
|
+
expect(result.revision).toMatch(/^sha256:[0-9a-f]{64}$/)
|
|
138
90
|
})
|
|
139
91
|
|
|
140
|
-
test('transports the DSL revision
|
|
92
|
+
test('transports the DSL revision while keeping render identity separate', async () => {
|
|
141
93
|
const handle = currentFixture()
|
|
142
94
|
const extracted = await runtimeExtract(handle.schemaIndex, handle.root)
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
expect(
|
|
148
|
-
expect(
|
|
149
|
-
expect(bundle.schemaRevision).toBe(extracted.revision)
|
|
150
|
-
expect(bundle.renderFingerprint).toBe(renderFingerprintOf(extracted.root))
|
|
151
|
-
expect(bundle.renderFingerprint).not.toBe(renderFingerprintOf(extracted.ir))
|
|
95
|
+
if (extracted.revision === null) throw new Error('expected an admitted Schema revision')
|
|
96
|
+
const built = await buildBundle(handle)
|
|
97
|
+
expect(built.schemaRoot).toEqual(extracted.root)
|
|
98
|
+
expect(built.schemaRevision).toBe(extracted.revision)
|
|
99
|
+
expect(built.renderFingerprint).toBe(renderFingerprintOf(extracted.root))
|
|
100
|
+
expect(built.renderFingerprint).not.toBe(renderFingerprintOf(extracted.ir))
|
|
152
101
|
})
|
|
153
102
|
|
|
154
|
-
test('re-admits installed Bundle JSON before comparing its
|
|
103
|
+
test('re-admits installed Bundle JSON before comparing its revision', async () => {
|
|
155
104
|
const handle = currentFixture()
|
|
156
105
|
const extracted = await runtimeExtract(handle.schemaIndex, handle.root)
|
|
157
|
-
if (extracted.revision === null) throw new Error('expected an admitted
|
|
106
|
+
if (extracted.revision === null) throw new Error('expected an admitted Schema revision')
|
|
158
107
|
const fixture = (await import(handle.schemaIndex)) as { installedBundle: unknown }
|
|
159
108
|
const installedWire = JSON.parse(JSON.stringify(fixture.installedBundle))
|
|
160
|
-
|
|
161
109
|
expect(await admittedBundleRevision(handle.root, installedWire)).toBe(extracted.revision)
|
|
162
110
|
})
|
|
163
111
|
|
|
164
|
-
test('renders a V1-shaped
|
|
112
|
+
test('renders a V1-shaped root as preview when SDK admission fails', async () => {
|
|
165
113
|
const root = fixtureRoot('canonical-preview')
|
|
166
|
-
|
|
167
|
-
const schemaIndex = join(root, 'schema', 'index.ts')
|
|
114
|
+
const schemaIndex = join(root, 'schema/index.ts')
|
|
168
115
|
writeFileSync(
|
|
169
116
|
schemaIndex,
|
|
170
117
|
`export const schema = {
|
|
171
118
|
format: 'astrale.dsl', version: 'v1', origin: 'not an origin',
|
|
172
|
-
dependencies:
|
|
173
|
-
|
|
119
|
+
dependencies: {}, classes: {}, functions: {}, policies: {}, views: {},
|
|
120
|
+
core: { nodes: {}, edges: [] },
|
|
174
121
|
}\n`,
|
|
175
122
|
)
|
|
176
|
-
|
|
177
|
-
const result = await runtimeExtract(schemaIndex, root)
|
|
178
|
-
expect(result.ok).toBe(true)
|
|
179
|
-
expect(result.schemaMode).toBe('canonical-preview')
|
|
180
|
-
expect(result.revision).toBeNull()
|
|
181
|
-
expect(result.root).toMatchObject({ format: 'astrale.dsl', version: 'v1' })
|
|
182
|
-
})
|
|
183
|
-
|
|
184
|
-
test('extracts canonical core without importing implementation.ts', async () => {
|
|
185
|
-
const handle = currentFixture()
|
|
186
|
-
const result = await coreExtract(handle.schemaIndex, handle.domainFile, handle.root)
|
|
187
|
-
|
|
188
|
-
expect(result).toEqual({
|
|
123
|
+
expect(await runtimeExtract(schemaIndex, root)).toMatchObject({
|
|
189
124
|
ok: true,
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
nodes: [
|
|
193
|
-
{
|
|
194
|
-
path: '/:documents.runtime.test:core.welcome',
|
|
195
|
-
className: 'Document',
|
|
196
|
-
data: { 'documents.runtime.test:class.Document.property.title': 'Welcome' },
|
|
197
|
-
},
|
|
198
|
-
],
|
|
199
|
-
edges: [
|
|
200
|
-
{
|
|
201
|
-
from: '/:documents.runtime.test:core.welcome',
|
|
202
|
-
to: '/:documents.runtime.test',
|
|
203
|
-
edgeName: 'owned_by',
|
|
204
|
-
data: {},
|
|
205
|
-
},
|
|
206
|
-
],
|
|
207
|
-
},
|
|
125
|
+
schemaMode: 'canonical-preview',
|
|
126
|
+
revision: null,
|
|
208
127
|
})
|
|
209
128
|
})
|
|
210
|
-
})
|
|
211
|
-
|
|
212
|
-
test('runtime extractor preserves the legacy compiled-IR envelope', async () => {
|
|
213
|
-
const root = fixtureRoot('legacy-runtime')
|
|
214
|
-
const schemaIndex = join(root, 'schema', 'index.ts')
|
|
215
|
-
writeFileSync(
|
|
216
|
-
schemaIndex,
|
|
217
|
-
`export const D = { $: { ir: {
|
|
218
|
-
version: 'legacy', domain: 'legacy.runtime.test', types: {}, interfaces: {},
|
|
219
|
-
classes: {}, imports: {}, functions: {},
|
|
220
|
-
} } }\n`,
|
|
221
|
-
)
|
|
222
|
-
|
|
223
|
-
const result = await runtimeExtract(schemaIndex, root)
|
|
224
|
-
expect(result).toMatchObject({
|
|
225
|
-
ok: true,
|
|
226
|
-
schemaMode: 'legacy',
|
|
227
|
-
revision: null,
|
|
228
|
-
root: null,
|
|
229
|
-
ir: { domain: 'legacy.runtime.test', functions: {} },
|
|
230
|
-
})
|
|
231
|
-
})
|
|
232
129
|
|
|
233
|
-
test('
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
writeFileSync(
|
|
239
|
-
domainFile,
|
|
240
|
-
`
|
|
241
|
-
const Item = { config: { name: 'Item' } }
|
|
242
|
-
const linked = { config: { name: 'linked' } }
|
|
243
|
-
const schema = { interfaces: {}, classes: { Item, linked }, imports: [] }
|
|
244
|
-
export const core = {
|
|
245
|
-
domain: 'legacy.runtime.test', schema,
|
|
246
|
-
__nodes: [
|
|
247
|
-
{ path: '/legacy/left', def: Item, data: { name: 'Left' } },
|
|
248
|
-
{ path: '/legacy/right', def: Item, data: { name: 'Right' } },
|
|
249
|
-
],
|
|
250
|
-
__edges: [
|
|
251
|
-
{ from: '/legacy/left', to: '/legacy/right', edge: linked, data: { order: 1 } },
|
|
252
|
-
],
|
|
253
|
-
}
|
|
254
|
-
`,
|
|
255
|
-
)
|
|
256
|
-
|
|
257
|
-
expect(await coreExtract(schemaIndex, domainFile, root)).toEqual({
|
|
258
|
-
ok: true,
|
|
259
|
-
core: {
|
|
260
|
-
domain: 'legacy.runtime.test',
|
|
130
|
+
test('extracts Core through the pure Schema entry without importing Application', async () => {
|
|
131
|
+
const handle = currentFixture()
|
|
132
|
+
const bundle = await buildBundle(handle)
|
|
133
|
+
expect(buildCore(handle, bundle)).toMatchObject({
|
|
134
|
+
domain: 'documents.runtime.test',
|
|
261
135
|
nodes: [
|
|
262
|
-
{ path: '/legacy/left', className: 'Item', data: { name: 'Left' } },
|
|
263
|
-
{ path: '/legacy/right', className: 'Item', data: { name: 'Right' } },
|
|
264
|
-
],
|
|
265
|
-
edges: [
|
|
266
136
|
{
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
data: { order: 1 },
|
|
137
|
+
path: '/:documents.runtime.test:core.welcome',
|
|
138
|
+
className: 'Document',
|
|
139
|
+
data: {},
|
|
271
140
|
},
|
|
272
141
|
],
|
|
273
|
-
|
|
142
|
+
edges: [],
|
|
143
|
+
error: null,
|
|
144
|
+
})
|
|
145
|
+
})
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
test('rejects the removed compiled-IR compatibility envelope', async () => {
|
|
149
|
+
const root = fixtureRoot('removed-runtime')
|
|
150
|
+
const schemaIndex = join(root, 'schema/index.ts')
|
|
151
|
+
writeFileSync(schemaIndex, `export const D = { $: { ir: { domain: 'legacy' } } }\n`)
|
|
152
|
+
expect(await runtimeExtract(schemaIndex, root)).toMatchObject({
|
|
153
|
+
ok: false,
|
|
154
|
+
schemaMode: 'unavailable',
|
|
155
|
+
revision: null,
|
|
274
156
|
})
|
|
275
157
|
})
|
|
@@ -5,29 +5,20 @@
|
|
|
5
5
|
* render IR plus the raw canonical root (when present), or an error render-state
|
|
6
6
|
* — never throws.
|
|
7
7
|
*/
|
|
8
|
-
import type {
|
|
9
|
-
IrInterface,
|
|
10
|
-
SchemaIR,
|
|
11
|
-
SchemaRevision,
|
|
12
|
-
StudioCore,
|
|
13
|
-
StudioSchemaBundle,
|
|
14
|
-
} from '../../shared/types'
|
|
8
|
+
import type { SchemaIR, SchemaRevision, StudioSchemaBundle } from '../../shared/types'
|
|
15
9
|
|
|
16
10
|
import { isSchemaRevision } from '../../shared/types'
|
|
17
11
|
|
|
18
12
|
const EXTRACTOR = new URL('./extractor.ts', import.meta.url).pathname
|
|
19
|
-
const CORE_EXTRACTOR = new URL('./core-extractor.ts', import.meta.url).pathname
|
|
20
13
|
|
|
21
14
|
export interface RuntimeExtractResult {
|
|
22
15
|
ok: boolean
|
|
23
16
|
ir: SchemaIR | null
|
|
24
|
-
/** Portable canonical V1 document. Null for
|
|
17
|
+
/** Portable canonical V1 document. Null only for failures. */
|
|
25
18
|
root: unknown | null
|
|
26
19
|
schemaMode: StudioSchemaBundle['schemaMode']
|
|
27
|
-
/** Present only when the Domain
|
|
20
|
+
/** Present only when the Domain's installed SDK admitted `root`. */
|
|
28
21
|
revision: SchemaRevision | null
|
|
29
|
-
/** member bodies of imported (kernel + cross-domain) interfaces, by name */
|
|
30
|
-
importedInterfaces?: Record<string, IrInterface>
|
|
31
22
|
error?: { message: string }
|
|
32
23
|
}
|
|
33
24
|
|
|
@@ -70,16 +61,10 @@ export async function runtimeExtract(
|
|
|
70
61
|
}
|
|
71
62
|
const schemaMode = parsed.schemaMode
|
|
72
63
|
const revision = parsed.revision
|
|
73
|
-
const validMode =
|
|
74
|
-
schemaMode === 'canonical-admitted' ||
|
|
75
|
-
schemaMode === 'canonical-preview' ||
|
|
76
|
-
schemaMode === 'legacy'
|
|
64
|
+
const validMode = schemaMode === 'canonical-admitted' || schemaMode === 'canonical-preview'
|
|
77
65
|
const validRevision =
|
|
78
66
|
schemaMode === 'canonical-admitted' ? isSchemaRevision(revision) : revision == null
|
|
79
|
-
const validRoot =
|
|
80
|
-
schemaMode === 'legacy'
|
|
81
|
-
? parsed.root == null
|
|
82
|
-
: parsed.root !== null && parsed.root !== undefined
|
|
67
|
+
const validRoot = parsed.root !== null && parsed.root !== undefined
|
|
83
68
|
if (!validMode || !validRevision || !validRoot) {
|
|
84
69
|
return {
|
|
85
70
|
ok: false,
|
|
@@ -96,7 +81,6 @@ export async function runtimeExtract(
|
|
|
96
81
|
root: parsed.root ?? null,
|
|
97
82
|
schemaMode,
|
|
98
83
|
revision: revision ?? null,
|
|
99
|
-
importedInterfaces: (parsed.importedInterfaces ?? {}) as Record<string, IrInterface>,
|
|
100
84
|
}
|
|
101
85
|
} catch (e: any) {
|
|
102
86
|
return {
|
|
@@ -109,49 +93,3 @@ export async function runtimeExtract(
|
|
|
109
93
|
}
|
|
110
94
|
}
|
|
111
95
|
}
|
|
112
|
-
|
|
113
|
-
export interface CoreExtractResult {
|
|
114
|
-
ok: boolean
|
|
115
|
-
/** the resolved core graph, or null when the domain defines no core */
|
|
116
|
-
core: Pick<StudioCore, 'domain' | 'nodes' | 'edges'> | null
|
|
117
|
-
error?: { message: string }
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Spawn the core-extractor island over the pure schema entry first, retaining the
|
|
122
|
-
* composition entry only as the legacy `defineCore` fallback. Returns the
|
|
123
|
-
* resolved core graph or an error — never throws.
|
|
124
|
-
*/
|
|
125
|
-
export async function coreExtract(
|
|
126
|
-
schemaIndexPath: string,
|
|
127
|
-
domainFile: string,
|
|
128
|
-
domainDir: string,
|
|
129
|
-
timeoutMs = 20000,
|
|
130
|
-
): Promise<CoreExtractResult> {
|
|
131
|
-
try {
|
|
132
|
-
const proc = Bun.spawn(['bun', 'run', CORE_EXTRACTOR, schemaIndexPath, domainFile, domainDir], {
|
|
133
|
-
cwd: domainDir,
|
|
134
|
-
stdout: 'pipe',
|
|
135
|
-
stderr: 'pipe',
|
|
136
|
-
})
|
|
137
|
-
const timer = setTimeout(() => proc.kill(9), timeoutMs)
|
|
138
|
-
const out = await new Response(proc.stdout).text()
|
|
139
|
-
await proc.exited
|
|
140
|
-
clearTimeout(timer)
|
|
141
|
-
|
|
142
|
-
if (!out.trim()) {
|
|
143
|
-
const err = await new Response(proc.stderr).text()
|
|
144
|
-
return {
|
|
145
|
-
ok: false,
|
|
146
|
-
core: null,
|
|
147
|
-
error: { message: err.trim() || 'core extractor produced no output' },
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
const parsed = JSON.parse(out)
|
|
151
|
-
if (!parsed.ok)
|
|
152
|
-
return { ok: false, core: null, error: parsed.error ?? { message: 'core extraction failed' } }
|
|
153
|
-
return { ok: true, core: (parsed.core ?? null) as CoreExtractResult['core'] }
|
|
154
|
-
} catch (e: any) {
|
|
155
|
-
return { ok: false, core: null, error: { message: String(e?.message ?? e) } }
|
|
156
|
-
}
|
|
157
|
-
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { expect, test } from 'bun:test'
|
|
2
|
+
|
|
3
|
+
import { decodeSchemaIR } from './schema-ir-json'
|
|
4
|
+
|
|
5
|
+
function canonicalIr() {
|
|
6
|
+
return {
|
|
7
|
+
format: 'astrale.dsl',
|
|
8
|
+
version: 'v1',
|
|
9
|
+
domain: 'example.test',
|
|
10
|
+
classes: {
|
|
11
|
+
Document: {
|
|
12
|
+
type: 'node',
|
|
13
|
+
name: 'Document',
|
|
14
|
+
origin: 'example.test',
|
|
15
|
+
ref: { origin: 'example.test', kind: 'class', name: 'Document' },
|
|
16
|
+
properties: {},
|
|
17
|
+
methods: {
|
|
18
|
+
rename: {
|
|
19
|
+
name: 'rename',
|
|
20
|
+
input: { type: 'object', properties: {} },
|
|
21
|
+
output: { mode: 'value', schema: { type: 'boolean' } },
|
|
22
|
+
static: false,
|
|
23
|
+
inheritance: 'default',
|
|
24
|
+
auth: 'authorized',
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
importsByKey: {},
|
|
30
|
+
importedClassesByKey: {},
|
|
31
|
+
functions: {
|
|
32
|
+
search: {
|
|
33
|
+
name: 'search',
|
|
34
|
+
input: { type: 'object', properties: {} },
|
|
35
|
+
output: { mode: 'stream', item: { type: 'string' } },
|
|
36
|
+
auth: 'authenticated',
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
views: {
|
|
40
|
+
documents: {
|
|
41
|
+
name: 'documents',
|
|
42
|
+
target: { kind: 'domain' },
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
policies: {},
|
|
46
|
+
dependencies: [],
|
|
47
|
+
core: {},
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
test('admits the complete canonical Studio projection', () => {
|
|
52
|
+
expect(decodeSchemaIR(canonicalIr())).toMatchObject({
|
|
53
|
+
format: 'astrale.dsl',
|
|
54
|
+
domain: 'example.test',
|
|
55
|
+
})
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
test('rejects stale projections that lost canonical callable contracts', () => {
|
|
59
|
+
const input = canonicalIr()
|
|
60
|
+
const rename = input.classes.Document.methods.rename as Record<string, unknown>
|
|
61
|
+
delete rename.input
|
|
62
|
+
delete rename.output
|
|
63
|
+
Object.assign(rename, { params: {}, returns: { type: 'boolean' } })
|
|
64
|
+
expect(decodeSchemaIR(input)).toBeUndefined()
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
test('rejects projections that retain retired View auth metadata', () => {
|
|
68
|
+
const input = canonicalIr()
|
|
69
|
+
Object.assign(input.views.documents, { auth: 'required' })
|
|
70
|
+
expect(decodeSchemaIR(input)).toBeUndefined()
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
test('rejects unversioned and incomplete projection roots', () => {
|
|
74
|
+
const withoutFormat = canonicalIr() as Record<string, unknown>
|
|
75
|
+
delete withoutFormat.format
|
|
76
|
+
expect(decodeSchemaIR(withoutFormat)).toBeUndefined()
|
|
77
|
+
|
|
78
|
+
const withoutViews = canonicalIr() as Record<string, unknown>
|
|
79
|
+
delete withoutViews.views
|
|
80
|
+
expect(decodeSchemaIR(withoutViews)).toBeUndefined()
|
|
81
|
+
})
|