@astrale-os/cli 1.0.0-beta.5 → 1.0.0-beta.7
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 +66254 -64461
- package/dist/public/connect-core.js +14895 -33867
- package/dist/public/keys/index.js +1246 -34250
- package/dist/public/paths/index.js +866 -33833
- package/dist/types/admin/instance/model.d.ts +3 -4
- package/dist/types/errors.d.ts +1 -1
- package/dist/types/lib/instance-target.d.ts +1 -1
- package/dist/types/lib/log.d.ts +2 -2
- package/package.json +4 -9
- package/src/__tests__/fixtures/publication.ts +20 -0
- package/src/admin/__tests__/binding.test.ts +12 -19
- package/src/admin/__tests__/fixture.ts +101 -0
- package/src/admin/binding.ts +83 -3
- package/src/admin/catalog/.spec/api.d.ts +1 -1
- package/src/admin/catalog/__tests__/client.test.ts +20 -49
- package/src/admin/catalog/client.ts +35 -26
- package/src/admin/catalog/model.ts +3 -4
- 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 +1 -1
- package/src/admin/instance/__tests__/client.test.ts +58 -83
- package/src/admin/instance/client.ts +49 -39
- package/src/admin/instance/model.ts +9 -8
- package/src/commands/__tests__/call-describe.test.ts +46 -33
- package/src/commands/__tests__/domain-install-operation.test.ts +3 -14
- 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-identity-override.test.ts +3 -14
- package/src/commands/__tests__/read-commands.test.ts +35 -10
- package/src/commands/call-describe.ts +59 -67
- package/src/commands/call.ts +41 -54
- package/src/commands/domain/install.ts +2 -2
- package/src/commands/domain/uninstall.ts +2 -2
- package/src/commands/get.ts +13 -14
- package/src/commands/identity/__tests__/register.test.ts +3 -3
- package/src/commands/identity/register.ts +5 -4
- package/src/commands/instance/delete.ts +5 -3
- package/src/commands/instance/status.ts +1 -9
- package/src/commands/introspect.ts +4 -11
- package/src/commands/logs.ts +24 -25
- package/src/commands/mutate.ts +6 -5
- package/src/commands/query.ts +27 -30
- package/src/commands/token.ts +8 -7
- package/src/commands/view.ts +4 -3
- package/src/connection/.spec/api.d.ts +7 -8
- package/src/connection/.spec/architecture.md +5 -4
- 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__/credential.test.ts +1 -1
- package/src/connection/__tests__/errors.test.ts +27 -20
- package/src/connection/__tests__/exchange.test.ts +30 -1
- 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 +3 -3
- 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 +47 -23
- package/src/connection/failure/classify.ts +110 -0
- package/src/connection/failure/debug.ts +26 -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 +8 -8
- package/src/errors.ts +3 -2
- package/src/graph/.spec/api.d.ts +12 -5
- package/src/graph/.spec/layout.ts +9 -1
- package/src/graph/__tests__/mutation.test.ts +2 -2
- package/src/graph/__tests__/query.test.ts +25 -6
- package/src/graph/class.ts +30 -0
- package/src/graph/index.ts +1 -0
- package/src/graph/query.ts +21 -32
- package/src/identity/.spec/api.d.ts +2 -2
- package/src/identity/__tests__/registration.test.ts +1 -1
- package/src/identity/registration.ts +3 -3
- package/src/lib/__tests__/domain-publication.test.ts +4 -15
- package/src/lib/__tests__/instance-target.test.ts +6 -39
- package/src/lib/__tests__/log-errors.test.ts +53 -0
- package/src/lib/__tests__/studio-server-deps.test.ts +1 -1
- package/src/lib/command-dx.ts +1 -4
- package/src/lib/domain-publication.ts +1 -1
- package/src/lib/instance-target.ts +3 -14
- package/src/lib/log.ts +11 -6
- package/src/lib/validation.ts +2 -2
- package/src/lib/view/resolve.ts +1 -1
- package/src/program/__tests__/program.test.ts +1 -1
- package/studio/client/dist/assets/{elk-api-YEDvaNU-.js → elk-api-Di4OXGNH.js} +1 -1
- package/studio/client/dist/assets/index-BLm6J11H.js +81 -0
- package/studio/client/dist/assets/index-BiGR8Oo9.css +1 -0
- package/studio/client/dist/assets/index-DTjvkOUX.js +8 -0
- package/studio/client/dist/index.html +2 -2
- package/studio/package.json +2 -7
- 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/prompts/anchors.test.ts +32 -36
- package/studio/server/agent/prompts/anchors.ts +20 -49
- package/studio/server/agent/prompts/system.test.ts +3 -2
- package/studio/server/agent/prompts/system.ts +3 -3
- package/studio/server/agent/routes.test.ts +1 -1
- package/studio/server/agent/run/coordinator.test.ts +1 -1
- package/studio/server/api/canvas.ts +0 -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 +23 -12
- package/studio/server/cache.ts +12 -15
- package/studio/server/domain.test.ts +50 -68
- package/studio/server/domain.ts +82 -63
- package/studio/server/handoff/copy.ts +1 -1
- 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 +9 -14
- package/studio/server/introspect/anatomy-extras.test.ts +26 -42
- 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 +94 -389
- package/studio/server/introspect/canonical-schema.ts +227 -457
- package/studio/server/introspect/core-extractor.ts +18 -127
- package/studio/server/introspect/core.ts +1 -2
- package/studio/server/introspect/diff.test.ts +11 -7
- package/studio/server/introspect/diff.ts +18 -55
- package/studio/server/introspect/extractor.ts +22 -117
- package/studio/server/introspect/overlay-tsmorph.test.ts +119 -240
- package/studio/server/introspect/overlay.test.ts +26 -54
- package/studio/server/introspect/overlay.ts +10 -37
- package/studio/server/introspect/revision.test.ts +1 -1
- package/studio/server/introspect/revision.ts +1 -1
- package/studio/server/introspect/runtime.test.ts +65 -183
- package/studio/server/introspect/runtime.ts +8 -25
- package/studio/server/introspect/schema-ir-json.test.ts +70 -0
- package/studio/server/introspect/schema-ir-json.ts +38 -68
- 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/state/baseline.test.ts +14 -9
- package/studio/server/state/baseline.ts +3 -5
- package/studio/server/state/visibility.ts +1 -5
- package/studio/server/views/model.ts +3 -3
- package/studio/server/views/target.test.ts +17 -74
- package/studio/server/views/target.ts +24 -50
- package/studio/server/watch.test.ts +11 -11
- package/studio/server/watch.ts +8 -4
- package/studio/server/workspace-watch.ts +2 -2
- package/studio/shared/contracts/schema.ts +38 -107
- package/studio/shared/contracts/surface.test.ts +12 -15
- package/studio/shared/contracts/workspace.ts +2 -11
- package/studio/shared/schema/identity.test.ts +20 -44
- package/studio/shared/schema/identity.ts +9 -23
- package/viewer/dist/main.js +41 -38
- package/studio/client/dist/assets/index-C-PvAXV4.js +0 -81
- package/studio/client/dist/assets/index-C4aNQ6dz.css +0 -1
- package/studio/client/dist/assets/index-CzpmJD0j.js +0 -8
- package/studio/server/introspect/anatomy/views/legacy.ts +0 -232
package/src/graph/query.ts
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import type {
|
|
2
|
+
NodeQueryBuilder,
|
|
2
3
|
QueryAST as QueryASTValue,
|
|
3
|
-
QueryDefinitionRef,
|
|
4
4
|
QueryDirection,
|
|
5
|
+
QueryNodeInput,
|
|
5
6
|
} from '@astrale-os/sdk/query'
|
|
6
7
|
|
|
7
8
|
import { Path } from '@astrale-os/sdk/graph/path'
|
|
8
9
|
import { Query, QueryAST } from '@astrale-os/sdk/query'
|
|
9
10
|
|
|
11
|
+
import { classReference } from './class'
|
|
12
|
+
|
|
10
13
|
export interface QueryCommandInput {
|
|
11
14
|
readonly sources: readonly string[]
|
|
12
15
|
readonly definition?: string
|
|
@@ -51,43 +54,29 @@ export function prepareQuery(input: QueryCommandInput): PreparedQuery {
|
|
|
51
54
|
}
|
|
52
55
|
|
|
53
56
|
const paths = input.sources.map((source) => Path.parse(source))
|
|
54
|
-
const definition =
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
...(definition === undefined ? {} : { definitions: [definition] }),
|
|
61
|
-
})
|
|
62
|
-
: Query.from({ kind: 'node', definitions: [definition!] })
|
|
57
|
+
const definition =
|
|
58
|
+
input.definition === undefined ? undefined : classReference(input.definition, '--definition')
|
|
59
|
+
const nodes = definition === undefined ? paths : [...paths, definition]
|
|
60
|
+
const query: NodeQueryBuilder<unknown> = Query.from({
|
|
61
|
+
nodes: nodes as [QueryNodeInput, ...QueryNodeInput[]],
|
|
62
|
+
})
|
|
63
63
|
const ast =
|
|
64
64
|
input.edge === undefined
|
|
65
|
-
? query.select({ kind: 'graph' })
|
|
66
|
-
: query
|
|
67
|
-
.expand({
|
|
68
|
-
via: [definitionRef(input.edge)],
|
|
69
|
-
direction: input.direction ?? 'outgoing',
|
|
70
|
-
})
|
|
71
|
-
.select({ kind: 'graph' })
|
|
65
|
+
? query.select({ kind: 'graph', binding: query.node })
|
|
66
|
+
: expanded(query, input.edge, input.direction)
|
|
72
67
|
return withPage(ast, limit, input.cursor)
|
|
73
68
|
}
|
|
74
69
|
|
|
75
|
-
function
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
) {
|
|
84
|
-
throw new TypeError('--definition must be one canonical Class or Interface Path')
|
|
85
|
-
}
|
|
86
|
-
return Object.freeze({
|
|
87
|
-
origin: path.ast.anchor.origin,
|
|
88
|
-
kind: step.projection.kind,
|
|
89
|
-
name: step.projection.name,
|
|
70
|
+
function expanded(
|
|
71
|
+
query: NodeQueryBuilder<unknown>,
|
|
72
|
+
edge: string,
|
|
73
|
+
direction: QueryDirection | undefined,
|
|
74
|
+
): QueryASTValue {
|
|
75
|
+
const result = query.expand({
|
|
76
|
+
via: [classReference(edge, '--edge')],
|
|
77
|
+
direction: direction ?? 'outgoing',
|
|
90
78
|
})
|
|
79
|
+
return result.select({ kind: 'graph', binding: result.node })
|
|
91
80
|
}
|
|
92
81
|
|
|
93
82
|
function positiveInteger(raw: string | undefined, name: string, fallback: number): number {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Call } from '@astrale-os/kernel-client'
|
|
2
1
|
import type { ProvisionRequest } from '@astrale-os/sdk/auth'
|
|
3
|
-
import type {
|
|
2
|
+
import type { Call } from '@astrale-os/sdk/client'
|
|
3
|
+
import type { LocalBinding } from '@astrale-os/sdk/graph'
|
|
4
4
|
import type { JWK } from 'jose'
|
|
5
5
|
|
|
6
6
|
import type {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ProvisionRequest } from '@astrale-os/sdk/auth'
|
|
2
2
|
|
|
3
|
-
import { LocalBinding } from '@astrale-os/sdk/graph
|
|
3
|
+
import { LocalBinding } from '@astrale-os/sdk/graph'
|
|
4
4
|
import { expect, test } from 'bun:test'
|
|
5
5
|
|
|
6
6
|
import { submitIdentityProvision } from '../registration'
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { Call } from '@astrale-os/kernel-client'
|
|
2
1
|
import type { ProvisionRequest } from '@astrale-os/sdk/auth'
|
|
3
|
-
import type {
|
|
2
|
+
import type { Call } from '@astrale-os/sdk/client'
|
|
3
|
+
import type { LocalBinding } from '@astrale-os/sdk/graph'
|
|
4
4
|
|
|
5
|
-
import { call } from '@astrale-os/kernel-client'
|
|
6
5
|
import { issuer } from '@astrale-os/sdk/auth'
|
|
6
|
+
import { call } from '@astrale-os/sdk/client'
|
|
7
7
|
import { NodeId } from '@astrale-os/sdk/graph/node'
|
|
8
8
|
import { Path } from '@astrale-os/sdk/graph/path'
|
|
9
9
|
|
|
@@ -1,26 +1,15 @@
|
|
|
1
|
-
import { publication } from '@astrale-os/
|
|
2
|
-
import {
|
|
3
|
-
import { issuer } from '@astrale-os/sdk/auth'
|
|
4
|
-
import { createDeployment } from '@astrale-os/sdk/deployment'
|
|
5
|
-
import { defineSchema } from '@astrale-os/sdk/schema/v1'
|
|
1
|
+
import { publication } from '@astrale-os/sdk/publication'
|
|
2
|
+
import { defineSchema } from '@astrale-os/sdk/schema'
|
|
6
3
|
import { describe, expect, test } from 'bun:test'
|
|
7
4
|
|
|
5
|
+
import { releaseFor } from '../../__tests__/fixtures/publication'
|
|
8
6
|
import { fetchDomainPublication } from '../domain-publication'
|
|
9
7
|
|
|
10
8
|
const ROOT = 'https://publication-reader.example.dev'
|
|
11
9
|
const PUBLICATION_URL = `${ROOT}/.well-known/astrale/domain.json`
|
|
12
10
|
const MAXIMUM_PUBLICATION_BYTES = 1024 * 1024
|
|
13
11
|
const schema = defineSchema('publication-reader.example.dev', {})
|
|
14
|
-
const
|
|
15
|
-
schema,
|
|
16
|
-
handlers: { functions: {}, classes: {}, interfaces: {} },
|
|
17
|
-
})
|
|
18
|
-
const deployed = createDeployment({
|
|
19
|
-
definition,
|
|
20
|
-
issuer: issuer.accept(ROOT),
|
|
21
|
-
bundleHref: `${ROOT}/domain.bundle.json`,
|
|
22
|
-
bindings: { callables: [] },
|
|
23
|
-
}).publication
|
|
12
|
+
const deployed = releaseFor(schema, ROOT).publication
|
|
24
13
|
|
|
25
14
|
describe('Domain Publication reader', () => {
|
|
26
15
|
test('fetches only the canonical path with redirects disabled', async () => {
|
|
@@ -3,6 +3,7 @@ import { describe, expect, test } from 'bun:test'
|
|
|
3
3
|
import type { AstraleConfig } from '../config'
|
|
4
4
|
import type { InstanceStore } from '../instance'
|
|
5
5
|
|
|
6
|
+
import { AdminInstanceNotFoundError } from '../../admin/instance/model'
|
|
6
7
|
import { AstraleError } from '../../errors'
|
|
7
8
|
import { DEFAULT_CONFIG } from '../config'
|
|
8
9
|
import {
|
|
@@ -124,9 +125,6 @@ describe('resolveInstanceTarget', () => {
|
|
|
124
125
|
})
|
|
125
126
|
|
|
126
127
|
test('unknown slugs surface the original instance-not-found error', async () => {
|
|
127
|
-
const notFound = new Error('Path not found: "/admin/instances/missing"')
|
|
128
|
-
notFound.name = 'NotFoundError'
|
|
129
|
-
|
|
130
128
|
await expect(
|
|
131
129
|
resolveInstanceTarget(
|
|
132
130
|
{ source: 'name', name: 'missing' },
|
|
@@ -134,7 +132,7 @@ describe('resolveInstanceTarget', () => {
|
|
|
134
132
|
config: DEFAULT_CONFIG,
|
|
135
133
|
instances: emptyStore,
|
|
136
134
|
managed: async () => {
|
|
137
|
-
throw
|
|
135
|
+
throw new AdminInstanceNotFoundError('missing')
|
|
138
136
|
},
|
|
139
137
|
},
|
|
140
138
|
),
|
|
@@ -168,14 +166,8 @@ describe('instance target helpers', () => {
|
|
|
168
166
|
expect(couldBeConfiguredAdminInstance('bryan', directAdminConfig)).toBe(false)
|
|
169
167
|
})
|
|
170
168
|
|
|
171
|
-
test('treats
|
|
172
|
-
|
|
173
|
-
data?: unknown
|
|
174
|
-
}
|
|
175
|
-
wrapped.name = 'KernelError'
|
|
176
|
-
wrapped.data = { type: 'NotFoundError' }
|
|
177
|
-
|
|
178
|
-
expect(isManagedInstanceNotFound(wrapped)).toBe(true)
|
|
169
|
+
test('treats the owner-scoped Admin error as managed lookup not-found', () => {
|
|
170
|
+
expect(isManagedInstanceNotFound(new AdminInstanceNotFoundError('admin'))).toBe(true)
|
|
179
171
|
})
|
|
180
172
|
|
|
181
173
|
test('does not hide non-not-found managed lookup failures', () => {
|
|
@@ -194,37 +186,12 @@ describe('instance target helpers', () => {
|
|
|
194
186
|
})
|
|
195
187
|
})
|
|
196
188
|
|
|
197
|
-
describe('isManagedInstanceNotFound:
|
|
198
|
-
test('
|
|
199
|
-
const e = new Error('NOT_FOUND: no instance node for "knowledge"')
|
|
200
|
-
e.name = 'InternalKernelError'
|
|
201
|
-
expect(isManagedInstanceNotFound(e)).toBe(true)
|
|
202
|
-
})
|
|
203
|
-
test('other InternalKernelError messages are not swallowed', () => {
|
|
189
|
+
describe('isManagedInstanceNotFound: unknown errors', () => {
|
|
190
|
+
test('does not infer a miss from an InternalKernelError message', () => {
|
|
204
191
|
const e = new Error('DISPATCH_FAILED: handler crashed')
|
|
205
192
|
e.name = 'InternalKernelError'
|
|
206
193
|
expect(isManagedInstanceNotFound(e)).toBe(false)
|
|
207
194
|
})
|
|
208
|
-
test('resolveNamedInstanceTarget maps the wrap to typed INSTANCE_NOT_FOUND', async () => {
|
|
209
|
-
const managed = async () => {
|
|
210
|
-
const e = new Error('NOT_FOUND: no instance node for "ghost"')
|
|
211
|
-
e.name = 'InternalKernelError'
|
|
212
|
-
throw e
|
|
213
|
-
}
|
|
214
|
-
const opts = {
|
|
215
|
-
config: DEFAULT_CONFIG,
|
|
216
|
-
instances: { instances: {} },
|
|
217
|
-
managed,
|
|
218
|
-
} as unknown as Parameters<typeof resolveInstanceTarget>[1]
|
|
219
|
-
let caught: unknown
|
|
220
|
-
try {
|
|
221
|
-
await resolveInstanceTarget({ source: 'name', name: 'ghost' }, opts)
|
|
222
|
-
} catch (e) {
|
|
223
|
-
caught = e
|
|
224
|
-
}
|
|
225
|
-
expect(caught).toBeInstanceOf(AstraleError)
|
|
226
|
-
expect((caught as AstraleError).code).toBe('INSTANCE_NOT_FOUND')
|
|
227
|
-
})
|
|
228
195
|
|
|
229
196
|
test('maps Admin token-exchange failure to INSTANCE_NOT_FOUND', async () => {
|
|
230
197
|
const managed = async () => {
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, test } from 'bun:test'
|
|
2
|
+
|
|
3
|
+
import { AstraleError } from '../../errors'
|
|
4
|
+
import { failInput, fatal } from '../log'
|
|
5
|
+
|
|
6
|
+
class ExitError extends Error {}
|
|
7
|
+
|
|
8
|
+
let stderr = ''
|
|
9
|
+
let exit: typeof process.exit
|
|
10
|
+
let write: typeof process.stderr.write
|
|
11
|
+
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
stderr = ''
|
|
14
|
+
exit = process.exit
|
|
15
|
+
write = process.stderr.write
|
|
16
|
+
process.exit = (() => {
|
|
17
|
+
throw new ExitError()
|
|
18
|
+
}) as typeof process.exit
|
|
19
|
+
process.stderr.write = ((chunk: string | Uint8Array) => {
|
|
20
|
+
stderr += String(chunk)
|
|
21
|
+
return true
|
|
22
|
+
}) as typeof process.stderr.write
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
afterEach(() => {
|
|
26
|
+
process.exit = exit
|
|
27
|
+
process.stderr.write = write
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
describe('terminal error safety', () => {
|
|
31
|
+
test('renders an empty aggregate as an honest non-blank unexpected failure', () => {
|
|
32
|
+
expect(() => fatal(new AggregateError([], ''), { json: true })).toThrow(ExitError)
|
|
33
|
+
expect(JSON.parse(stderr)).toEqual({
|
|
34
|
+
error: 'UNEXPECTED_ERROR',
|
|
35
|
+
message: 'The CLI encountered an unexpected internal failure.',
|
|
36
|
+
})
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
test('rejects blank admitted CLI diagnostics', () => {
|
|
40
|
+
expect(() => new AstraleError('INVALID_INPUT', ' ')).toThrow(TypeError)
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
test('labels only expected admission failures as invalid input', () => {
|
|
44
|
+
expect(() => failInput(new TypeError('Authored value is invalid.'), { json: true })).toThrow(
|
|
45
|
+
ExitError,
|
|
46
|
+
)
|
|
47
|
+
expect(JSON.parse(stderr)).toMatchObject({ error: 'INVALID_INPUT' })
|
|
48
|
+
|
|
49
|
+
stderr = ''
|
|
50
|
+
expect(() => failInput(new AggregateError([], ''), { json: true })).toThrow(ExitError)
|
|
51
|
+
expect(JSON.parse(stderr)).toMatchObject({ error: 'UNEXPECTED_ERROR' })
|
|
52
|
+
})
|
|
53
|
+
})
|
|
@@ -103,7 +103,7 @@ describe('studio server runtime deps', () => {
|
|
|
103
103
|
describe('studio test gate', () => {
|
|
104
104
|
test('the root and Studio suites include all client, server, and shared tests', () => {
|
|
105
105
|
expect(cliPackage.scripts?.test).toBe(
|
|
106
|
-
'bun test src studio/client/src studio/server studio/shared && node --test scripts/*.test.mjs',
|
|
106
|
+
'node scripts/qualification/source-boundary.mjs --target && bun test src studio/client/src studio/server studio/shared && node --test scripts/*.test.mjs',
|
|
107
107
|
)
|
|
108
108
|
expect(cliPackage.scripts?.['test:studio']).toBe('pnpm --dir studio test')
|
|
109
109
|
expect(studioPackage.scripts?.test).toBe('bun test client/src server shared')
|
package/src/lib/command-dx.ts
CHANGED
|
@@ -41,12 +41,9 @@ export function renderCommanderError(
|
|
|
41
41
|
|
|
42
42
|
if (error.code === 'commander.missingArgument') {
|
|
43
43
|
const usage = usageFor(matched.path, matched.command)
|
|
44
|
-
const argName = error.message.match(/'([^']+)'/)?.[1]
|
|
45
44
|
return maybeMachine(
|
|
46
45
|
[
|
|
47
|
-
`Missing required argument
|
|
48
|
-
`astrale ${matched.path.join(' ')}`,
|
|
49
|
-
)}`,
|
|
46
|
+
`Missing required argument for ${chalk.bold(`astrale ${matched.path.join(' ')}`)}`,
|
|
50
47
|
'',
|
|
51
48
|
'Usage:',
|
|
52
49
|
` astrale ${usage}`,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { InstanceInfo } from '../admin/instance/model'
|
|
2
1
|
import type { AstraleConfig } from './config'
|
|
3
2
|
|
|
3
|
+
import { AdminInstanceNotFoundError, type InstanceInfo } from '../admin/instance/model'
|
|
4
4
|
import { AstraleError } from '../errors'
|
|
5
5
|
import {
|
|
6
6
|
DEFAULT_ADMIN_TARGET_NAME,
|
|
@@ -190,19 +190,8 @@ export function isAdminDiscoveryFailure(error: unknown): boolean {
|
|
|
190
190
|
}
|
|
191
191
|
|
|
192
192
|
export function isManagedInstanceNotFound(error: unknown): boolean {
|
|
193
|
-
if (error instanceof AstraleError && error.code === 'INSTANCE_NOT_FOUND') return true
|
|
194
|
-
if (!(error instanceof Error)) return false
|
|
195
|
-
if (error.name === 'NotFoundError') return true
|
|
196
|
-
// The admin kernel reports a missing instance node as InternalKernelError
|
|
197
|
-
// with a NOT_FOUND-prefixed message. In this lookup that's an instance
|
|
198
|
-
// miss (config problem), not a kernel fault — map it so callers get the
|
|
199
|
-
// typed INSTANCE_NOT_FOUND with remediation instead of a raw kernel error.
|
|
200
|
-
if (error.name === 'InternalKernelError' && /^NOT_FOUND\b/.test(error.message)) return true
|
|
201
|
-
const data = (error as Error & { data?: unknown }).data
|
|
202
193
|
return (
|
|
203
|
-
error
|
|
204
|
-
|
|
205
|
-
typeof data === 'object' &&
|
|
206
|
-
(data as { type?: unknown }).type === 'NotFoundError'
|
|
194
|
+
error instanceof AdminInstanceNotFoundError ||
|
|
195
|
+
(error instanceof AstraleError && error.code === 'INSTANCE_NOT_FOUND')
|
|
207
196
|
)
|
|
208
197
|
}
|
package/src/lib/log.ts
CHANGED
|
@@ -22,24 +22,29 @@ export function fatal(e: unknown, opts?: MachineOpts): never {
|
|
|
22
22
|
// Ctrl-C at an interactive (@inquirer/prompts) prompt — exit quietly with the
|
|
23
23
|
// SIGINT convention, not a red error line.
|
|
24
24
|
if (e instanceof Error && e.name === 'ExitPromptError') process.exit(130)
|
|
25
|
-
const msg =
|
|
26
|
-
|
|
25
|
+
const msg =
|
|
26
|
+
e instanceof AstraleError ? e.message : 'The CLI encountered an unexpected internal failure.'
|
|
27
|
+
const code = e instanceof AstraleError ? e.code : 'UNEXPECTED_ERROR'
|
|
27
28
|
if (isMachine(opts)) {
|
|
28
29
|
const payload: Record<string, unknown> = { error: code, message: msg }
|
|
29
30
|
if (e instanceof AstraleError && e.hint) payload.hint = e.hint
|
|
30
31
|
process.stderr.write(JSON.stringify(payload) + '\n')
|
|
31
32
|
process.exit(1)
|
|
32
33
|
}
|
|
33
|
-
log.error(
|
|
34
|
+
log.error(`${code}: ${msg}`)
|
|
34
35
|
if (e instanceof AstraleError && e.hint) log.dim(` hint: ${e.hint}`)
|
|
35
36
|
process.exit(1)
|
|
36
37
|
}
|
|
37
38
|
|
|
38
|
-
/**
|
|
39
|
-
export function
|
|
39
|
+
/** Project only a caller-authored admission failure into the CLI input family. */
|
|
40
|
+
export function failInput(error: unknown, opts?: MachineOpts): never {
|
|
40
41
|
if (error instanceof AstraleError) fatal(error, opts)
|
|
42
|
+
if (!(error instanceof TypeError)) fatal(error, opts)
|
|
41
43
|
fatal(
|
|
42
|
-
new AstraleError(
|
|
44
|
+
new AstraleError(
|
|
45
|
+
'INVALID_INPUT',
|
|
46
|
+
error.message.trim() ? error.message : 'CLI input is invalid.',
|
|
47
|
+
),
|
|
43
48
|
opts,
|
|
44
49
|
)
|
|
45
50
|
}
|
package/src/lib/validation.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isDnsLabel } from '@astrale-os/sdk/
|
|
1
|
+
import { isDnsLabel } from '@astrale-os/sdk/value'
|
|
2
2
|
import { z } from 'zod'
|
|
3
3
|
|
|
4
4
|
import { ReservedSlugError } from '../errors'
|
|
@@ -21,7 +21,7 @@ export function validateName(name: string, entity: string): void {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
export function validateSlug(slug: string): void {
|
|
24
|
-
// Canonical DNS-label rule
|
|
24
|
+
// Canonical Core DNS-label rule: a slug becomes a
|
|
25
25
|
// hostname label, so reject anything not DNS-safe (§4.7).
|
|
26
26
|
if (!slug || !isDnsLabel(slug)) {
|
|
27
27
|
throw new Error(
|
package/src/lib/view/resolve.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ResolvedView as SessionResolvedView } from '@astrale-os/
|
|
1
|
+
import type { ResolvedView as SessionResolvedView } from '@astrale-os/sdk/client/session'
|
|
2
2
|
import type { ResolvedView } from '@astrale-os/shell'
|
|
3
3
|
|
|
4
4
|
import { Path } from '@astrale-os/sdk/graph/path'
|
|
@@ -187,7 +187,7 @@ describe('program composition', () => {
|
|
|
187
187
|
'whoami',
|
|
188
188
|
])
|
|
189
189
|
expect(createHash('sha256').update(JSON.stringify(surface)).digest('hex')).toBe(
|
|
190
|
-
'
|
|
190
|
+
'42b4812abbbca3d54289a16d0b066dfb3b1caaf1df6597a425c675744466a728',
|
|
191
191
|
)
|
|
192
192
|
})
|
|
193
193
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{m as L}from"./index-
|
|
1
|
+
import{m as L}from"./index-BLm6J11H.js";function S(y,b){for(var u=0;u<b.length;u++){const a=b[u];if(typeof a!="string"&&!Array.isArray(a)){for(const i in a)if(i!=="default"&&!(i in y)){const n=Object.getOwnPropertyDescriptor(a,i);n&&Object.defineProperty(y,i,n.get?n:{enumerable:!0,get:()=>a[i]})}}}return Object.freeze(Object.defineProperty(y,Symbol.toStringTag,{value:"Module"}))}function w(y){throw new Error('Could not dynamically require "'+y+'". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.')}var O={exports:{}},j;function C(){return j||(j=1,(function(y,b){(function(u){y.exports=u()})(function(){return(function(){function u(a,i,n){function d(f,_){if(!i[f]){if(!a[f]){var h=typeof w=="function"&&w;if(!_&&h)return h(f,!0);if(g)return g(f,!0);var o=new Error("Cannot find module '"+f+"'");throw o.code="MODULE_NOT_FOUND",o}var e=i[f]={exports:{}};a[f][0].call(e.exports,function(r){var t=a[f][1][r];return d(t||r)},e,e.exports,u,a,i,n)}return i[f].exports}for(var g=typeof w=="function"&&w,m=0;m<n.length;m++)d(n[m]);return d}return u})()({1:[function(u,a,i){Object.defineProperty(i,"__esModule",{value:!0}),i.default=void 0;function n(o){"@babel/helpers - typeof";return n=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(e){return typeof e}:function(e){return e&&typeof Symbol=="function"&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},n(o)}function d(o,e){if(!(o instanceof e))throw new TypeError("Cannot call a class as a function")}function g(o,e){for(var r=0;r<e.length;r++){var t=e[r];t.enumerable=t.enumerable||!1,t.configurable=!0,"value"in t&&(t.writable=!0),Object.defineProperty(o,f(t.key),t)}}function m(o,e,r){return e&&g(o.prototype,e),Object.defineProperty(o,"prototype",{writable:!1}),o}function f(o){var e=_(o,"string");return n(e)=="symbol"?e:e+""}function _(o,e){if(n(o)!="object"||!o)return o;var r=o[Symbol.toPrimitive];if(r!==void 0){var t=r.call(o,e);if(n(t)!="object")return t;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(o)}i.default=(function(){function o(){var e=this,r=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},t=r.defaultLayoutOptions,s=t===void 0?{}:t,l=r.algorithms,v=l===void 0?["layered","stress","mrtree","radial","force","disco","sporeOverlap","sporeCompaction","rectpacking"]:l,c=r.workerFactory,p=r.workerUrl;if(d(this,o),this.defaultLayoutOptions=s,this.initialized=!1,typeof p>"u"&&typeof c>"u")throw new Error("Cannot construct an ELK without both 'workerUrl' and 'workerFactory'.");var k=c;typeof p<"u"&&typeof c>"u"&&(k=function(M){return new Worker(M)});var E=k(p);if(typeof E.postMessage!="function")throw new TypeError("Created worker does not provide the required 'postMessage' function.");this.worker=new h(E),this.worker.postMessage({cmd:"register",algorithms:v}).then(function(P){return e.initialized=!0}).catch(console.err)}return m(o,[{key:"layout",value:function(r){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},s=t.layoutOptions,l=s===void 0?this.defaultLayoutOptions:s,v=t.logging,c=v===void 0?!1:v,p=t.measureExecutionTime,k=p===void 0?!1:p;return r?this.worker.postMessage({cmd:"layout",graph:r,layoutOptions:l,options:{logging:c,measureExecutionTime:k}}):Promise.reject(new Error("Missing mandatory parameter 'graph'."))}},{key:"knownLayoutAlgorithms",value:function(){return this.worker.postMessage({cmd:"algorithms"})}},{key:"knownLayoutOptions",value:function(){return this.worker.postMessage({cmd:"options"})}},{key:"knownLayoutCategories",value:function(){return this.worker.postMessage({cmd:"categories"})}},{key:"terminateWorker",value:function(){this.worker&&this.worker.terminate()}}])})();var h=(function(){function o(e){var r=this;if(d(this,o),e===void 0)throw new Error("Missing mandatory parameter 'worker'.");this.resolvers={},this.worker=e,this.worker.onmessage=function(t){setTimeout(function(){r.receive(r,t)},0)}}return m(o,[{key:"postMessage",value:function(r){var t=this.id||0;this.id=t+1,r.id=t;var s=this;return new Promise(function(l,v){s.resolvers[t]=function(c,p){c?(s.convertGwtStyleError(c),v(c)):l(p)},s.worker.postMessage(r)})}},{key:"receive",value:function(r,t){var s=t.data,l=r.resolvers[s.id];l&&(delete r.resolvers[s.id],s.error?l(s.error):l(null,s.data))}},{key:"terminate",value:function(){this.worker&&this.worker.terminate()}},{key:"convertGwtStyleError",value:function(r){if(r){var t=r.__java$exception;t&&(t.cause&&t.cause.backingJsObject&&(r.cause=t.cause.backingJsObject,this.convertGwtStyleError(r.cause)),delete r.__java$exception)}}}])})()},{}],2:[function(u,a,i){var n=u("./elk-api.js").default;Object.defineProperty(a.exports,"__esModule",{value:!0}),a.exports=n,n.default=n},{"./elk-api.js":1}]},{},[2])(2)})})(O)),O.exports}var x=C();const A=L(x),q=S({__proto__:null,default:A},[x]);export{q as e};
|