@astrale-os/cli 1.0.0-beta.22 → 1.0.0-beta.23
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/astrale.js +650 -620
- package/dist/public/connect-core.js +4 -4
- package/dist/types/admin/contract.d.ts +2 -2
- package/package.json +4 -4
- package/src/admin/contract.ts +3 -2
- package/src/commands/__tests__/read-commands.test.ts +56 -0
- package/src/commands/__tests__/view.test.ts +1 -2
- package/src/commands/introspect.ts +8 -9
- package/src/ui/.spec/architecture.md +8 -7
- package/src/ui/.spec/laws.ts +7 -0
- package/src/ui/__tests__/ui.test.ts +147 -2
- package/src/ui/operations.ts +73 -12
- package/src/ui/release.ts +9 -2
- package/studio/client/dist/assets/{index-7YHdeCxp.js → index-OeJK1TjG.js} +2 -2
- package/studio/client/dist/assets/{schema-studio-CABpTfvH.js → schema-studio-DRdfu_cQ.js} +2 -2
- package/studio/client/dist/index.html +1 -1
- package/studio/package.json +3 -3
- package/studio/server/cli-consumers.test.ts +0 -1
- package/studio/server/introspect/anatomy/views.ts +1 -2
- package/studio/server/introspect/anatomy-extras.test.ts +3 -14
- package/studio/server/introspect/canonical-schema.test.ts +1 -1
- package/studio/server/introspect/canonical-schema.ts +0 -4
- package/studio/server/introspect/diff.test.ts +10 -2
- package/studio/server/introspect/diff.ts +1 -9
- package/studio/server/introspect/runtime.test.ts +1 -1
- package/studio/server/introspect/schema-ir-json.test.ts +12 -1
- package/studio/server/introspect/schema-ir-json.ts +1 -1
- package/studio/server/views/target.test.ts +1 -2
- package/studio/shared/contracts/schema.ts +1 -3
- package/studio/tsconfig.json +2 -1
- package/viewer/dist/main.js +13 -13
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>Domain Studio</title>
|
|
7
|
-
<script type="module" crossorigin src="/assets/index-
|
|
7
|
+
<script type="module" crossorigin src="/assets/index-OeJK1TjG.js"></script>
|
|
8
8
|
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-Dd_uD5pT.js">
|
|
9
9
|
<link rel="stylesheet" crossorigin href="/assets/index-C0FAnwNw.css">
|
|
10
10
|
</head>
|
package/studio/package.json
CHANGED
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"typecheck": "tsgo --noEmit"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@astrale-os/sdk": "0.5.0-beta.
|
|
25
|
-
"@astrale-os/shell": "0.4.2-beta.
|
|
24
|
+
"@astrale-os/sdk": "0.5.0-beta.51",
|
|
25
|
+
"@astrale-os/shell": "0.4.2-beta.6",
|
|
26
26
|
"@dagrejs/dagre": "^3.0.0",
|
|
27
27
|
"@radix-ui/react-collapsible": "^1.1.0",
|
|
28
28
|
"@radix-ui/react-dialog": "^1.1.6",
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"@types/react-dom": "^19.2.0",
|
|
59
59
|
"@typescript/native-preview": "7.0.0-dev.20260707.2",
|
|
60
60
|
"@vitejs/plugin-react": "^6.0.5",
|
|
61
|
-
"bun-types": "
|
|
61
|
+
"bun-types": "1.4.0",
|
|
62
62
|
"tailwindcss": "^4.0.6",
|
|
63
63
|
"typescript": "~6.0.3",
|
|
64
64
|
"vite": "^8.2.1"
|
|
@@ -15,7 +15,6 @@ function canonicalViewInfo(slug: string, view: NonNullable<SchemaIR['views']>[st
|
|
|
15
15
|
return {
|
|
16
16
|
slug,
|
|
17
17
|
kind: 'unknown',
|
|
18
|
-
auth: view.auth,
|
|
19
18
|
...(view.description ? { description: view.description } : {}),
|
|
20
19
|
...(targets.length === 1
|
|
21
20
|
? { viewFor: targets[0] }
|
|
@@ -28,7 +27,7 @@ function canonicalViewInfo(slug: string, view: NonNullable<SchemaIR['views']>[st
|
|
|
28
27
|
/**
|
|
29
28
|
* Join canonical View definitions with route/source metadata. Passing a
|
|
30
29
|
* canonical map (including an empty map) makes it authoritative: static routes
|
|
31
|
-
* cannot invent Views or override identity, target,
|
|
30
|
+
* cannot invent Views or override identity, target, or description.
|
|
32
31
|
* Without admitted canonical Views, Studio does not invent authoring semantics.
|
|
33
32
|
*/
|
|
34
33
|
export function buildViews(
|
|
@@ -55,12 +55,10 @@ test('does not treat a removed view registry as Schema authority', () => {
|
|
|
55
55
|
join(viewsDir, 'index.ts'),
|
|
56
56
|
`import { defineView } from '@astrale-os/sdk'
|
|
57
57
|
const services = defineView({
|
|
58
|
-
auth: 'required',
|
|
59
58
|
mount: '/ui/services',
|
|
60
59
|
description: 'Browse services.',
|
|
61
60
|
})
|
|
62
61
|
const service = defineView({
|
|
63
|
-
auth: 'required',
|
|
64
62
|
mount: '/ui/service',
|
|
65
63
|
viewFor: [selfOf(CloudflareWorker)],
|
|
66
64
|
})
|
|
@@ -89,7 +87,6 @@ const schemaInput = {
|
|
|
89
87
|
views: {
|
|
90
88
|
issue: view({
|
|
91
89
|
target: [Issue, Group],
|
|
92
|
-
auth: 'optional',
|
|
93
90
|
description: 'Inspect an issue.',
|
|
94
91
|
}),
|
|
95
92
|
},
|
|
@@ -114,7 +111,6 @@ export const frontend = defineFrontend({
|
|
|
114
111
|
buildViews(root, 'schema', {
|
|
115
112
|
issue: {
|
|
116
113
|
name: 'issue',
|
|
117
|
-
auth: 'optional',
|
|
118
114
|
description: 'Inspect an issue.',
|
|
119
115
|
target: {
|
|
120
116
|
kind: 'definition',
|
|
@@ -129,7 +125,6 @@ export const frontend = defineFrontend({
|
|
|
129
125
|
{
|
|
130
126
|
slug: 'issue',
|
|
131
127
|
kind: 'spa',
|
|
132
|
-
auth: 'optional',
|
|
133
128
|
mount: '/ui/issues/:id',
|
|
134
129
|
url: undefined,
|
|
135
130
|
viewFor: ['Issue', 'Group'],
|
|
@@ -166,7 +161,6 @@ export const frontend = defineFrontend({
|
|
|
166
161
|
buildViews(root, 'schema', {
|
|
167
162
|
summary: {
|
|
168
163
|
name: 'summary',
|
|
169
|
-
auth: 'required',
|
|
170
164
|
target: { kind: 'domain' },
|
|
171
165
|
},
|
|
172
166
|
}),
|
|
@@ -174,7 +168,6 @@ export const frontend = defineFrontend({
|
|
|
174
168
|
{
|
|
175
169
|
slug: 'summary',
|
|
176
170
|
kind: 'spa',
|
|
177
|
-
auth: 'required',
|
|
178
171
|
mount: '/summary',
|
|
179
172
|
url: undefined,
|
|
180
173
|
file: 'views/summary/index.ts',
|
|
@@ -190,9 +183,9 @@ test('canonical Bundle views reject static schema and route-only identities', ()
|
|
|
190
183
|
join(root, 'schema', 'index.ts'),
|
|
191
184
|
`export const schema = defineSchema('static.invalid', {
|
|
192
185
|
views: {
|
|
193
|
-
account: view({ target: WrongTarget,
|
|
194
|
-
sourceOnly: view({ target: WrongTarget,
|
|
195
|
-
invented: view({ target: 'domain'
|
|
186
|
+
account: view({ target: WrongTarget, description: 'Static guess.' }),
|
|
187
|
+
sourceOnly: view({ target: WrongTarget, description: 'Static guess.' }),
|
|
188
|
+
invented: view({ target: 'domain' }),
|
|
196
189
|
},
|
|
197
190
|
})`,
|
|
198
191
|
)
|
|
@@ -212,7 +205,6 @@ test('canonical Bundle views reject static schema and route-only identities', ()
|
|
|
212
205
|
buildViews(root, 'schema', {
|
|
213
206
|
account: {
|
|
214
207
|
name: 'account',
|
|
215
|
-
auth: 'required',
|
|
216
208
|
description: 'Admitted account view.',
|
|
217
209
|
target: {
|
|
218
210
|
kind: 'definition',
|
|
@@ -221,7 +213,6 @@ test('canonical Bundle views reject static schema and route-only identities', ()
|
|
|
221
213
|
},
|
|
222
214
|
sourceOnly: {
|
|
223
215
|
name: 'sourceOnly',
|
|
224
|
-
auth: 'optional',
|
|
225
216
|
description: 'Admitted source-only view.',
|
|
226
217
|
target: { kind: 'domain' },
|
|
227
218
|
},
|
|
@@ -230,7 +221,6 @@ test('canonical Bundle views reject static schema and route-only identities', ()
|
|
|
230
221
|
{
|
|
231
222
|
slug: 'account',
|
|
232
223
|
kind: 'spa',
|
|
233
|
-
auth: 'required',
|
|
234
224
|
description: 'Admitted account view.',
|
|
235
225
|
viewFor: 'Account',
|
|
236
226
|
url: 'https://shell.example.dev/account',
|
|
@@ -239,7 +229,6 @@ test('canonical Bundle views reject static schema and route-only identities', ()
|
|
|
239
229
|
{
|
|
240
230
|
slug: 'sourceOnly',
|
|
241
231
|
kind: 'spa',
|
|
242
|
-
auth: 'optional',
|
|
243
232
|
description: 'Admitted source-only view.',
|
|
244
233
|
url: 'https://shell.example.dev/source-only',
|
|
245
234
|
file: 'application.ts',
|
|
@@ -74,7 +74,6 @@ const root = {
|
|
|
74
74
|
views: {
|
|
75
75
|
documents: {
|
|
76
76
|
target: { kind: 'definition', definitions: [localRef] },
|
|
77
|
-
auth: 'optional',
|
|
78
77
|
},
|
|
79
78
|
},
|
|
80
79
|
core: {
|
|
@@ -126,6 +125,7 @@ describe('canonical Schema projection', () => {
|
|
|
126
125
|
])
|
|
127
126
|
expect(ir.functions.search).toMatchObject({ auth: 'authenticated', output: { mode: 'stream' } })
|
|
128
127
|
expect(ir.views?.documents.target).toEqual({ kind: 'definition', definitions: [localRef] })
|
|
128
|
+
expect(ir.views?.documents).not.toHaveProperty('auth')
|
|
129
129
|
})
|
|
130
130
|
|
|
131
131
|
test('projects canonical Core coordinates without importing Application or Runtime', () => {
|
|
@@ -328,10 +328,6 @@ function projectView(name: string, value: unknown): IrView {
|
|
|
328
328
|
target?.kind === 'definition'
|
|
329
329
|
? { kind: 'definition', definitions: refsOf(target.definitions) }
|
|
330
330
|
: { kind: 'domain' },
|
|
331
|
-
auth:
|
|
332
|
-
declaration.auth === 'optional' || declaration.auth === 'public'
|
|
333
|
-
? declaration.auth
|
|
334
|
-
: 'required',
|
|
335
331
|
...(typeof declaration.description === 'string'
|
|
336
332
|
? { description: declaration.description }
|
|
337
333
|
: {}),
|
|
@@ -97,7 +97,7 @@ describe('canonical standalone Function diffs', () => {
|
|
|
97
97
|
orientation: 'directed',
|
|
98
98
|
endpoints: [],
|
|
99
99
|
}),
|
|
100
|
-
views: { home: { name: 'home', target: { kind: 'domain' }
|
|
100
|
+
views: { home: { name: 'home', target: { kind: 'domain' } } },
|
|
101
101
|
policies: { canRead: { anyOf: [] } },
|
|
102
102
|
dependencies: [{ origin: 'kernel.astrale.ai', revision: 'sha256:one' }],
|
|
103
103
|
core: { nodes: {}, edges: [] },
|
|
@@ -107,7 +107,15 @@ describe('canonical standalone Function diffs', () => {
|
|
|
107
107
|
classes: {
|
|
108
108
|
owns: { ...before.classes.owns, orientation: 'undirected' },
|
|
109
109
|
},
|
|
110
|
-
views: {
|
|
110
|
+
views: {
|
|
111
|
+
home: {
|
|
112
|
+
...before.views.home,
|
|
113
|
+
target: {
|
|
114
|
+
kind: 'definition',
|
|
115
|
+
definitions: [{ origin: 'example.test', kind: 'class', name: 'owns' }],
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
},
|
|
111
119
|
policies: { canRead: { anyOf: [{ name: 'owner' }] } },
|
|
112
120
|
dependencies: [{ origin: 'kernel.astrale.ai', revision: 'sha256:two' }],
|
|
113
121
|
core: { nodes: { root: {} }, edges: [] },
|
|
@@ -124,15 +124,7 @@ function diffViews(
|
|
|
124
124
|
out.push({ kind: 'view-removed', target: name })
|
|
125
125
|
continue
|
|
126
126
|
}
|
|
127
|
-
if (
|
|
128
|
-
!same(
|
|
129
|
-
{ target: prev[name].target, auth: prev[name].auth },
|
|
130
|
-
{
|
|
131
|
-
target: next[name].target,
|
|
132
|
-
auth: next[name].auth,
|
|
133
|
-
},
|
|
134
|
-
)
|
|
135
|
-
) {
|
|
127
|
+
if (!same(prev[name].target, next[name].target)) {
|
|
136
128
|
out.push({ kind: 'view-changed', target: name })
|
|
137
129
|
}
|
|
138
130
|
if (prev[name].description !== next[name].description) {
|
|
@@ -77,7 +77,7 @@ describe('SDK V1 schema extractor', () => {
|
|
|
77
77
|
},
|
|
78
78
|
ir: {
|
|
79
79
|
domain: 'documents.runtime.test',
|
|
80
|
-
views: { editor: {
|
|
80
|
+
views: { editor: { target: { kind: 'definition' } } },
|
|
81
81
|
importsByKey: {
|
|
82
82
|
'directory.runtime.test:class.Named': {
|
|
83
83
|
ref: { origin: 'directory.runtime.test', kind: 'class', name: 'Named' },
|
|
@@ -36,7 +36,12 @@ function canonicalIr() {
|
|
|
36
36
|
auth: 'authenticated',
|
|
37
37
|
},
|
|
38
38
|
},
|
|
39
|
-
views: {
|
|
39
|
+
views: {
|
|
40
|
+
documents: {
|
|
41
|
+
name: 'documents',
|
|
42
|
+
target: { kind: 'domain' },
|
|
43
|
+
},
|
|
44
|
+
},
|
|
40
45
|
policies: {},
|
|
41
46
|
dependencies: [],
|
|
42
47
|
core: {},
|
|
@@ -59,6 +64,12 @@ test('rejects stale projections that lost canonical callable contracts', () => {
|
|
|
59
64
|
expect(decodeSchemaIR(input)).toBeUndefined()
|
|
60
65
|
})
|
|
61
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
|
+
|
|
62
73
|
test('rejects unversioned and incomplete projection roots', () => {
|
|
63
74
|
const withoutFormat = canonicalIr() as Record<string, unknown>
|
|
64
75
|
delete withoutFormat.format
|
|
@@ -116,7 +116,7 @@ function isView(value: unknown): boolean {
|
|
|
116
116
|
const target = asJsonRecord(record?.target)
|
|
117
117
|
return (
|
|
118
118
|
typeof record?.name === 'string' &&
|
|
119
|
-
|
|
119
|
+
record.auth === undefined &&
|
|
120
120
|
!!target &&
|
|
121
121
|
(target.kind === 'domain' ||
|
|
122
122
|
(target.kind === 'definition' &&
|
|
@@ -16,7 +16,6 @@ describe('View target definitions', () => {
|
|
|
16
16
|
views: {
|
|
17
17
|
named: {
|
|
18
18
|
name: 'named',
|
|
19
|
-
auth: 'required',
|
|
20
19
|
target: {
|
|
21
20
|
kind: 'definition',
|
|
22
21
|
definitions: [
|
|
@@ -37,7 +36,7 @@ describe('View target definitions', () => {
|
|
|
37
36
|
test('treats a canonical Domain target as authoritative', () => {
|
|
38
37
|
const view = { slug: 'home', kind: 'unknown', viewFor: 'User' } satisfies ViewInfo
|
|
39
38
|
const bundle = {
|
|
40
|
-
ir: { views: { home: { name: 'home',
|
|
39
|
+
ir: { views: { home: { name: 'home', target: { kind: 'domain' } } } },
|
|
41
40
|
} as unknown as StudioSchemaBundle
|
|
42
41
|
expect(viewDefinitionBindings('shell.astrale.ai', view, bundle)).toEqual([])
|
|
43
42
|
})
|
|
@@ -37,7 +37,7 @@ export function isSchemaRevision(value: unknown): value is SchemaRevision {
|
|
|
37
37
|
* Version of Studio's lossy canonical-schema -> render-IR projection. Persisted
|
|
38
38
|
* baselines must match this value before their IR can be compared.
|
|
39
39
|
*/
|
|
40
|
-
export const STUDIO_SCHEMA_PROJECTION_VERSION =
|
|
40
|
+
export const STUDIO_SCHEMA_PROJECTION_VERSION = 2
|
|
41
41
|
|
|
42
42
|
export type IrCallableAuth = 'anonymous' | 'authenticated' | 'authorized'
|
|
43
43
|
|
|
@@ -107,7 +107,6 @@ export type IrViewTarget = { kind: 'domain' } | { kind: 'definition'; definition
|
|
|
107
107
|
export interface IrView {
|
|
108
108
|
name: string
|
|
109
109
|
target: IrViewTarget
|
|
110
|
-
auth: 'required' | 'optional' | 'public'
|
|
111
110
|
description?: string
|
|
112
111
|
}
|
|
113
112
|
|
|
@@ -225,7 +224,6 @@ export interface DomainOverview {
|
|
|
225
224
|
export interface ViewInfo {
|
|
226
225
|
slug: string
|
|
227
226
|
kind: 'inline-html' | 'spa' | 'unknown'
|
|
228
|
-
auth?: string
|
|
229
227
|
mount?: string
|
|
230
228
|
url?: string
|
|
231
229
|
/** the class(es) this view binds to via `viewFor: selfOf(Class)` (DSL allows an array);
|
package/studio/tsconfig.json
CHANGED
|
@@ -19,5 +19,6 @@
|
|
|
19
19
|
"@shared/*": ["./shared/*"]
|
|
20
20
|
}
|
|
21
21
|
},
|
|
22
|
-
"include": ["server", "shared", "client/src", "e2e", "playwright.config.ts", "vite.config.ts"]
|
|
22
|
+
"include": ["server", "shared", "client/src", "e2e", "playwright.config.ts", "vite.config.ts"],
|
|
23
|
+
"exclude": ["e2e/fixture"]
|
|
23
24
|
}
|