@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
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, test } from 'bun:test'
|
|
2
|
+
|
|
3
|
+
import addCommand from '../add'
|
|
4
|
+
import listCommand from '../list'
|
|
5
|
+
|
|
6
|
+
class ExitError extends Error {}
|
|
7
|
+
|
|
8
|
+
const commit = 'a'.repeat(40)
|
|
9
|
+
const item = {
|
|
10
|
+
name: 'pattern-chart-line-basic',
|
|
11
|
+
type: 'registry:block',
|
|
12
|
+
title: 'Line chart',
|
|
13
|
+
description: 'A controlled chart.',
|
|
14
|
+
dependencies: ['@astrale-os/ui@^0.3.0-beta.0'],
|
|
15
|
+
files: [
|
|
16
|
+
{
|
|
17
|
+
path: 'registry/patterns/chart/line-basic.tsx',
|
|
18
|
+
type: 'registry:component',
|
|
19
|
+
target: 'components/astrale/pattern/chart/line-basic.tsx',
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
meta: { canonicalAddress: 'pattern/chart/line/basic' },
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let stdout = ''
|
|
26
|
+
let stderr = ''
|
|
27
|
+
let originalArgv: string[]
|
|
28
|
+
let originalExit: typeof process.exit
|
|
29
|
+
let originalFetch: typeof globalThis.fetch
|
|
30
|
+
let originalStdout: typeof process.stdout.write
|
|
31
|
+
let originalStderr: typeof process.stderr.write
|
|
32
|
+
|
|
33
|
+
beforeEach(() => {
|
|
34
|
+
stdout = ''
|
|
35
|
+
stderr = ''
|
|
36
|
+
originalArgv = process.argv
|
|
37
|
+
originalExit = process.exit
|
|
38
|
+
originalFetch = globalThis.fetch
|
|
39
|
+
originalStdout = process.stdout.write
|
|
40
|
+
originalStderr = process.stderr.write
|
|
41
|
+
process.stdout.write = ((chunk: string | Uint8Array) => {
|
|
42
|
+
stdout += String(chunk)
|
|
43
|
+
return true
|
|
44
|
+
}) as typeof process.stdout.write
|
|
45
|
+
process.stderr.write = ((chunk: string | Uint8Array) => {
|
|
46
|
+
stderr += String(chunk)
|
|
47
|
+
return true
|
|
48
|
+
}) as typeof process.stderr.write
|
|
49
|
+
process.exit = (() => {
|
|
50
|
+
throw new ExitError()
|
|
51
|
+
}) as typeof process.exit
|
|
52
|
+
globalThis.fetch = mockFetch()
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
afterEach(() => {
|
|
56
|
+
process.argv = originalArgv
|
|
57
|
+
process.exit = originalExit
|
|
58
|
+
globalThis.fetch = originalFetch
|
|
59
|
+
process.stdout.write = originalStdout
|
|
60
|
+
process.stderr.write = originalStderr
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
describe('UI command machine contracts', () => {
|
|
64
|
+
test('list emits exactly one parseable JSON value', async () => {
|
|
65
|
+
const action = listCommand.action as (
|
|
66
|
+
query: string | undefined,
|
|
67
|
+
options: { json?: boolean; limit?: string },
|
|
68
|
+
) => Promise<void>
|
|
69
|
+
await action('line-basic', { json: true, limit: '100' })
|
|
70
|
+
|
|
71
|
+
expect(stderr).toBe('')
|
|
72
|
+
expect(JSON.parse(stdout)).toEqual([item])
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
test('list forwards an explicit release without consulting the beta channel', async () => {
|
|
76
|
+
const seen: string[] = []
|
|
77
|
+
globalThis.fetch = mockFetch(seen)
|
|
78
|
+
const action = listCommand.action as (
|
|
79
|
+
query: string | undefined,
|
|
80
|
+
options: { json?: boolean; limit?: string; version?: string },
|
|
81
|
+
) => Promise<void>
|
|
82
|
+
|
|
83
|
+
await action('line-basic', { json: true, limit: '100', version: '0.3.0-beta.1' })
|
|
84
|
+
|
|
85
|
+
expect(JSON.parse(stdout)).toEqual([item])
|
|
86
|
+
expect(seen.some((url) => url.endsWith('/@astrale-os/ui/beta'))).toBe(false)
|
|
87
|
+
expect(seen.some((url) => url.includes('/git/ref/tags/v0.3.0-beta.1'))).toBe(true)
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
test('add rejects missing items without prompting in machine mode', async () => {
|
|
91
|
+
process.argv = ['node', 'astrale', '--no-prompt', 'ui', 'add']
|
|
92
|
+
const add = addCommand.action as (items: string[], options: { json?: boolean }) => Promise<void>
|
|
93
|
+
await expect(add([], { json: true })).rejects.toBeInstanceOf(ExitError)
|
|
94
|
+
expect(JSON.parse(stderr)).toMatchObject({ error: 'UI_ITEM_NOT_FOUND' })
|
|
95
|
+
expect(stdout).toBe('')
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
test('registry failures retain a stable code without leaking transport secrets', async () => {
|
|
99
|
+
globalThis.fetch = (async () => {
|
|
100
|
+
throw new Error('Authorization: Bearer npm_super_secret_value_that_must_not_escape')
|
|
101
|
+
}) as unknown as typeof fetch
|
|
102
|
+
const action = listCommand.action as (
|
|
103
|
+
query: string | undefined,
|
|
104
|
+
options: { json?: boolean; limit?: string },
|
|
105
|
+
) => Promise<void>
|
|
106
|
+
await expect(action('line-basic', { json: true, limit: '100' })).rejects.toBeInstanceOf(
|
|
107
|
+
ExitError,
|
|
108
|
+
)
|
|
109
|
+
expect(JSON.parse(stderr)).toEqual({
|
|
110
|
+
error: 'UI_REGISTRY_UNAVAILABLE',
|
|
111
|
+
message: 'Unable to reach npm UI release.',
|
|
112
|
+
})
|
|
113
|
+
expect(stderr).not.toContain('super_secret')
|
|
114
|
+
})
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
function mockFetch(seen: string[] = []): typeof fetch {
|
|
118
|
+
return (async (input: string | URL | Request) => {
|
|
119
|
+
const url = String(input)
|
|
120
|
+
seen.push(url)
|
|
121
|
+
if (url.endsWith('/@astrale-os/ui/beta')) return Response.json({ version: '0.3.0-beta.1' })
|
|
122
|
+
if (url.includes('/git/ref/tags/')) {
|
|
123
|
+
return Response.json({ object: { type: 'commit', sha: commit, url: '' } })
|
|
124
|
+
}
|
|
125
|
+
if (url.endsWith('/tooling/compatibility.json')) {
|
|
126
|
+
return Response.json({
|
|
127
|
+
version: 1,
|
|
128
|
+
shadcn: '4.18.0',
|
|
129
|
+
base: 'base',
|
|
130
|
+
style: 'nova',
|
|
131
|
+
baseUi: '1.7.0',
|
|
132
|
+
react: '^18.3.1 || ^19.0.0',
|
|
133
|
+
tailwind: '^4.3.3',
|
|
134
|
+
presets: ['astrale', 'compact', 'expressive'],
|
|
135
|
+
})
|
|
136
|
+
}
|
|
137
|
+
if (url.endsWith('/registry/patterns/chart/registry.json')) {
|
|
138
|
+
return Response.json({
|
|
139
|
+
items: [
|
|
140
|
+
{
|
|
141
|
+
...item,
|
|
142
|
+
files: item.files.map((file) => ({ ...file, path: 'line-basic.tsx' })),
|
|
143
|
+
},
|
|
144
|
+
],
|
|
145
|
+
})
|
|
146
|
+
}
|
|
147
|
+
if (url.endsWith('/registry.json')) {
|
|
148
|
+
return Response.json({ include: ['registry/patterns/chart/registry.json'] })
|
|
149
|
+
}
|
|
150
|
+
return new Response('not found', { status: 404 })
|
|
151
|
+
}) as typeof fetch
|
|
152
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { CommandDefinition } from '../../program'
|
|
2
|
+
|
|
3
|
+
import { promptMultiSelect } from '../../lib/prompt'
|
|
4
|
+
import { addUi, listLockedUi, UiError } from '../../ui'
|
|
5
|
+
import { UI_JSON_OPTION, UI_PROJECT_OPTION, runUiCommand, type UiCommandOptions } from './shared'
|
|
6
|
+
|
|
7
|
+
type Options = UiCommandOptions & { dryRun?: boolean; overwrite?: boolean; yes?: boolean }
|
|
8
|
+
|
|
9
|
+
export default {
|
|
10
|
+
name: 'add',
|
|
11
|
+
description: 'Install consumer-owned Astrale pattern, block, or theme source',
|
|
12
|
+
arguments: [
|
|
13
|
+
{
|
|
14
|
+
name: 'items',
|
|
15
|
+
description: 'Canonical registry addresses or a local exported theme CSS file',
|
|
16
|
+
required: false,
|
|
17
|
+
variadic: true,
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
options: [
|
|
21
|
+
UI_PROJECT_OPTION,
|
|
22
|
+
{ flags: '--dry-run', description: 'Show exact files and dependencies without writing' },
|
|
23
|
+
{ flags: '--overwrite', description: 'Allow replacing locally changed installed source' },
|
|
24
|
+
{ flags: '--yes', description: 'Confirm the planned operation non-interactively' },
|
|
25
|
+
UI_JSON_OPTION,
|
|
26
|
+
],
|
|
27
|
+
afterHelpText:
|
|
28
|
+
'\nInstalled source belongs to the application. Use theme/<name> for a released theme or ./theme.css for a playground export.\nOrdinary add never overwrites local edits. Run astrale ui doctor before intentionally replacing local source with --overwrite --yes.\n',
|
|
29
|
+
action: async (items: string[], options: Options) =>
|
|
30
|
+
runUiCommand(options, async () => {
|
|
31
|
+
let selected = items
|
|
32
|
+
if (selected.length === 0) {
|
|
33
|
+
if (process.argv.includes('--ci') || process.argv.includes('--no-prompt')) {
|
|
34
|
+
throw new UiError('UI_ITEM_NOT_FOUND', 'No UI item was provided in non-interactive mode.')
|
|
35
|
+
}
|
|
36
|
+
const available = await listLockedUi(options.project)
|
|
37
|
+
selected =
|
|
38
|
+
(await promptMultiSelect(
|
|
39
|
+
'Choose Astrale UI source to install',
|
|
40
|
+
available.map((item) => ({
|
|
41
|
+
name: item.title ?? item.meta.canonicalAddress,
|
|
42
|
+
value: item.meta.canonicalAddress,
|
|
43
|
+
description: item.description,
|
|
44
|
+
})),
|
|
45
|
+
)) ?? []
|
|
46
|
+
if (selected.length === 0)
|
|
47
|
+
throw new UiError('UI_ITEM_NOT_FOUND', 'No UI item was selected.')
|
|
48
|
+
}
|
|
49
|
+
return addUi(selected, options)
|
|
50
|
+
}),
|
|
51
|
+
} satisfies CommandDefinition
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { CommandDefinition } from '../../program'
|
|
2
|
+
|
|
3
|
+
import { doctorUi, UiError } from '../../ui'
|
|
4
|
+
import { UI_JSON_OPTION, UI_PROJECT_OPTION, runUiCommand, type UiCommandOptions } from './shared'
|
|
5
|
+
|
|
6
|
+
export default {
|
|
7
|
+
name: 'doctor',
|
|
8
|
+
description: 'Verify Astrale UI package, CSS, config, lock, and installed source integrity',
|
|
9
|
+
arguments: [{ name: 'path', description: 'Application directory', required: false }],
|
|
10
|
+
options: [UI_PROJECT_OPTION, UI_JSON_OPTION],
|
|
11
|
+
action: async (path: string | undefined, options: UiCommandOptions) =>
|
|
12
|
+
runUiCommand(options, () => {
|
|
13
|
+
if (path && options.project) {
|
|
14
|
+
throw new UiError(
|
|
15
|
+
'UI_ITEM_CONFLICT',
|
|
16
|
+
'Choose either the positional application path or --project, not both.',
|
|
17
|
+
)
|
|
18
|
+
}
|
|
19
|
+
return doctorUi(options.project ?? path)
|
|
20
|
+
}),
|
|
21
|
+
} satisfies CommandDefinition
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { CommandDefinition } from '../../program'
|
|
2
|
+
|
|
3
|
+
import { initUi, type UiPreset } from '../../ui'
|
|
4
|
+
import { UI_JSON_OPTION, runUiCommand, type UiCommandOptions } from './shared'
|
|
5
|
+
|
|
6
|
+
type Options = UiCommandOptions & {
|
|
7
|
+
preset?: UiPreset
|
|
8
|
+
version?: string
|
|
9
|
+
dryRun?: boolean
|
|
10
|
+
force?: boolean
|
|
11
|
+
install?: boolean
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default {
|
|
15
|
+
name: 'init',
|
|
16
|
+
description: 'Initialize Astrale UI in an existing React and Tailwind v4 application',
|
|
17
|
+
arguments: [{ name: 'path', description: 'Application directory', required: false }],
|
|
18
|
+
options: [
|
|
19
|
+
{
|
|
20
|
+
flags: '--preset <name>',
|
|
21
|
+
description: 'Visual preset',
|
|
22
|
+
choices: ['astrale', 'compact', 'expressive'],
|
|
23
|
+
default: 'astrale',
|
|
24
|
+
},
|
|
25
|
+
{ flags: '--version <version>', description: 'Exact @astrale-os/ui version or release tag' },
|
|
26
|
+
{ flags: '--dry-run', description: 'Print the complete plan without writing or installing' },
|
|
27
|
+
{ flags: '--force', description: 'Replace an existing Astrale UI lock intentionally' },
|
|
28
|
+
{
|
|
29
|
+
flags: '--no-install',
|
|
30
|
+
description: 'Write configuration without running the package manager',
|
|
31
|
+
},
|
|
32
|
+
UI_JSON_OPTION,
|
|
33
|
+
],
|
|
34
|
+
afterHelpText:
|
|
35
|
+
'\nExamples:\n $ astrale ui init --preset astrale\n $ astrale ui init ./app --dry-run --json\n',
|
|
36
|
+
action: async (path: string | undefined, options: Options) =>
|
|
37
|
+
runUiCommand(options, () => initUi({ path, ...options })),
|
|
38
|
+
} satisfies CommandDefinition
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { CommandDefinition } from '../../program'
|
|
2
|
+
|
|
3
|
+
import { listUi } from '../../ui'
|
|
4
|
+
import { UI_JSON_OPTION, runUiCommand, type UiCommandOptions } from './shared'
|
|
5
|
+
|
|
6
|
+
type Options = UiCommandOptions & { type?: string; limit?: string; version?: string }
|
|
7
|
+
|
|
8
|
+
export default {
|
|
9
|
+
name: 'list',
|
|
10
|
+
description: 'List or search Astrale patterns, blocks, and themes',
|
|
11
|
+
arguments: [{ name: 'query', description: 'Optional search text', required: false }],
|
|
12
|
+
options: [
|
|
13
|
+
{
|
|
14
|
+
flags: '--type <type>',
|
|
15
|
+
description: 'Restrict to pattern, block, or theme',
|
|
16
|
+
choices: ['pattern', 'block', 'theme'],
|
|
17
|
+
},
|
|
18
|
+
{ flags: '--limit <n>', description: 'Maximum results', default: '100' },
|
|
19
|
+
{ flags: '--version <version>', description: 'Exact release to inspect' },
|
|
20
|
+
UI_JSON_OPTION,
|
|
21
|
+
],
|
|
22
|
+
action: async (query: string | undefined, options: Options) =>
|
|
23
|
+
runUiCommand(options, () =>
|
|
24
|
+
listUi(query, { type: options.type, limit: Number(options.limit), version: options.version }),
|
|
25
|
+
),
|
|
26
|
+
} satisfies CommandDefinition
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { CommandDefinition } from '../../program'
|
|
2
|
+
|
|
3
|
+
import { applyPreset, type UiPreset } from '../../ui'
|
|
4
|
+
import { UI_JSON_OPTION, UI_PROJECT_OPTION, runUiCommand, type UiCommandOptions } from './shared'
|
|
5
|
+
|
|
6
|
+
type Options = UiCommandOptions & { dryRun?: boolean }
|
|
7
|
+
|
|
8
|
+
export default {
|
|
9
|
+
name: 'apply',
|
|
10
|
+
description: 'Change the preset CSS import without rewriting component source',
|
|
11
|
+
arguments: [{ name: 'name', description: 'Preset name' }],
|
|
12
|
+
options: [
|
|
13
|
+
UI_PROJECT_OPTION,
|
|
14
|
+
{ flags: '--dry-run', description: 'Show the CSS and lock change without writing' },
|
|
15
|
+
UI_JSON_OPTION,
|
|
16
|
+
],
|
|
17
|
+
action: async (name: UiPreset, options: Options) =>
|
|
18
|
+
runUiCommand(options, () => applyPreset(name, options)),
|
|
19
|
+
} satisfies CommandDefinition
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CommandDefinition } from '../../program'
|
|
2
|
+
|
|
3
|
+
import { UI_PRESETS } from '../../ui'
|
|
4
|
+
import { UI_JSON_OPTION, runUiCommand, type UiCommandOptions } from './shared'
|
|
5
|
+
|
|
6
|
+
export default {
|
|
7
|
+
name: 'list',
|
|
8
|
+
description: 'List qualified Astrale UI visual presets',
|
|
9
|
+
options: [UI_JSON_OPTION],
|
|
10
|
+
action: async (options: UiCommandOptions) =>
|
|
11
|
+
runUiCommand(options, async () => UI_PRESETS.map((name) => ({ name }))),
|
|
12
|
+
} satisfies CommandDefinition
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { fatal } from '../../lib/log'
|
|
2
|
+
import { output } from '../../lib/output'
|
|
3
|
+
|
|
4
|
+
export type UiCommandOptions = { json?: boolean; project?: string }
|
|
5
|
+
|
|
6
|
+
export async function runUiCommand(
|
|
7
|
+
options: UiCommandOptions,
|
|
8
|
+
operation: () => Promise<unknown>,
|
|
9
|
+
): Promise<void> {
|
|
10
|
+
try {
|
|
11
|
+
output(await operation(), { json: options.json })
|
|
12
|
+
} catch (error) {
|
|
13
|
+
fatal(error, { json: options.json })
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const UI_PROJECT_OPTION = {
|
|
18
|
+
flags: '--project <path>',
|
|
19
|
+
description: 'Existing application root (defaults to the current project)',
|
|
20
|
+
} as const
|
|
21
|
+
|
|
22
|
+
export const UI_JSON_OPTION = {
|
|
23
|
+
flags: '--json',
|
|
24
|
+
description: 'Emit one machine-readable JSON value',
|
|
25
|
+
} as const
|
package/src/commands/update.ts
CHANGED
|
@@ -11,8 +11,13 @@ import {
|
|
|
11
11
|
inDomainProject,
|
|
12
12
|
type SdkOutdated,
|
|
13
13
|
} from '../lib/sdk-deps'
|
|
14
|
-
import {
|
|
15
|
-
|
|
14
|
+
import {
|
|
15
|
+
checkAstraleSkills,
|
|
16
|
+
type SkillApplyResult,
|
|
17
|
+
type SkillCheckResult,
|
|
18
|
+
syncAstraleSkills,
|
|
19
|
+
} from '../lib/skills'
|
|
20
|
+
import { DEFAULT_UPDATE_CHANNEL, packageManagedUpdateError, updateAstrale } from '../lib/update'
|
|
16
21
|
|
|
17
22
|
type UpdateOpts = RawOutputOpts & {
|
|
18
23
|
check?: boolean
|
|
@@ -23,26 +28,26 @@ type UpdateOpts = RawOutputOpts & {
|
|
|
23
28
|
yes?: boolean
|
|
24
29
|
}
|
|
25
30
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
log.
|
|
42
|
-
if (
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
log.warn(`
|
|
31
|
+
async function refreshSkills(): Promise<SkillApplyResult> {
|
|
32
|
+
log.step('Ensuring Astrale agent skills are current and healthy')
|
|
33
|
+
const result = await syncAstraleSkills()
|
|
34
|
+
if (result.status === 'unchanged') log.success('Astrale skills already up to date')
|
|
35
|
+
else if (result.status === 'installed') log.success('Astrale skills installed')
|
|
36
|
+
else if (result.status === 'updated') log.success('Astrale skills updated')
|
|
37
|
+
else if (result.status === 'repaired') log.success('Astrale skills repaired and updated')
|
|
38
|
+
return result
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function skillCheckStale(skills: SkillCheckResult): boolean {
|
|
42
|
+
return skills.status === 'update-available' || skills.status === 'repair-needed'
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function printSkillCheck(skills: SkillCheckResult): void {
|
|
46
|
+
if (skills.status === 'current') log.success('Astrale skills are up to date')
|
|
47
|
+
else if (skills.status === 'update-available') log.info('Astrale skills update available')
|
|
48
|
+
else if (skills.status === 'repair-needed') log.warn('Astrale skills need repair')
|
|
49
|
+
else if (skills.status === 'unavailable') {
|
|
50
|
+
log.warn(`Could not verify Astrale skills${skills.error ? `: ${skills.error}` : ''}`)
|
|
46
51
|
}
|
|
47
52
|
}
|
|
48
53
|
|
|
@@ -104,14 +109,23 @@ async function refreshSdkDeps(check: boolean, assumeYes = false): Promise<boolea
|
|
|
104
109
|
/**
|
|
105
110
|
* Read-only staleness report for tooling — `astrale update --check --json`.
|
|
106
111
|
* domain-studio polls this on load to drive its "update available" badge. It is
|
|
107
|
-
* unified and NON-THROWING:
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
112
|
+
* unified and NON-THROWING: an explicit package-managed result uses npm release
|
|
113
|
+
* identity, while script-install failures remain script failures in `error`
|
|
114
|
+
* instead of being recategorized. The SDK axis is already best-effort. Skills
|
|
115
|
+
* report meaningful health/freshness states. A current cohort also exposes its exact
|
|
116
|
+
* source revision, skill trees, and entrypoints without leaking installer-local paths.
|
|
111
117
|
*/
|
|
112
118
|
export type StaleReport = {
|
|
113
119
|
stale: boolean
|
|
114
|
-
cli: {
|
|
120
|
+
cli: {
|
|
121
|
+
stale: boolean
|
|
122
|
+
managed: boolean
|
|
123
|
+
current?: string
|
|
124
|
+
latest?: string
|
|
125
|
+
channel?: string
|
|
126
|
+
error?: string
|
|
127
|
+
}
|
|
128
|
+
skills: SkillCheckResult
|
|
115
129
|
sdk: { stale: boolean; inProject: boolean; outdated: SdkOutdated[] }
|
|
116
130
|
}
|
|
117
131
|
|
|
@@ -138,6 +152,15 @@ export async function cliStale(
|
|
|
138
152
|
version: target.version,
|
|
139
153
|
currentVersion: running,
|
|
140
154
|
})
|
|
155
|
+
if (r.status === 'managed') {
|
|
156
|
+
const latest = await dependencies.fetchPackageVersion(target).catch(() => undefined)
|
|
157
|
+
return {
|
|
158
|
+
stale: latest !== undefined && latest !== running,
|
|
159
|
+
managed: true,
|
|
160
|
+
current: running,
|
|
161
|
+
...(latest === undefined ? {} : { latest, channel: 'npm' }),
|
|
162
|
+
}
|
|
163
|
+
}
|
|
141
164
|
if (r.status === 'updated') {
|
|
142
165
|
return {
|
|
143
166
|
stale: false,
|
|
@@ -154,13 +177,12 @@ export async function cliStale(
|
|
|
154
177
|
latest: r.latestVersion,
|
|
155
178
|
channel: r.channel,
|
|
156
179
|
}
|
|
157
|
-
} catch {
|
|
158
|
-
const latest = await dependencies.fetchPackageVersion(target).catch(() => undefined)
|
|
180
|
+
} catch (error) {
|
|
159
181
|
return {
|
|
160
|
-
stale:
|
|
161
|
-
managed:
|
|
182
|
+
stale: false,
|
|
183
|
+
managed: false,
|
|
162
184
|
current: running,
|
|
163
|
-
|
|
185
|
+
error: error instanceof Error ? error.message : String(error),
|
|
164
186
|
}
|
|
165
187
|
}
|
|
166
188
|
}
|
|
@@ -202,7 +224,7 @@ export default {
|
|
|
202
224
|
default: DEFAULT_UPDATE_CHANNEL,
|
|
203
225
|
},
|
|
204
226
|
{ flags: '--version <version>', description: 'Update to an exact version tag' },
|
|
205
|
-
{ flags: '--no-skills', description: 'Skip
|
|
227
|
+
{ flags: '--no-skills', description: 'Skip ensuring the Astrale agent skills' },
|
|
206
228
|
{ flags: '--no-deps', description: 'Skip checking @astrale-os SDK dependency versions' },
|
|
207
229
|
{
|
|
208
230
|
flags: '--yes',
|
|
@@ -215,23 +237,22 @@ Behavior:
|
|
|
215
237
|
Keeps three things current, in order. (1) The CLI binary: updates official
|
|
216
238
|
script installs only — if Astrale was installed by another package manager this
|
|
217
239
|
command refuses so that manager stays in charge; downloads are checksum-verified
|
|
218
|
-
before the binary is replaced. (2) The agent skills:
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
240
|
+
before the binary is replaced. (2) The Astrale agent skills: installs every
|
|
241
|
+
top-level skill published from one resolved astrale-os/cli main commit, updates healthy older
|
|
242
|
+
installs, repairs inconsistent installs, and verifies the result before
|
|
243
|
+
reporting success. (3) SDK deps: inside a pnpm domain
|
|
222
244
|
project, proposes any @astrale-os/* dependency with a newer release and, on
|
|
223
245
|
confirm, runs "pnpm update --latest --lockfile-only" (updates package.json AND
|
|
224
246
|
the lockfile, honoring your registry + supply-chain age policy; run "pnpm
|
|
225
247
|
install" to materialize).
|
|
226
248
|
|
|
227
249
|
The default release channel is beta; --channel overrides it for one run.
|
|
228
|
-
--check is a dry run (binary + SDK deps; exit 10 if anything is available) and
|
|
250
|
+
--check is a dry run (binary + skills + SDK deps; exit 10 if anything is available) and
|
|
229
251
|
never writes. With --json it emits a unified staleness report
|
|
230
|
-
({ stale, cli, sdk }) for tooling
|
|
231
|
-
along with an update). --yes applies all three non-interactively (no prompts) and
|
|
252
|
+
({ stale, cli, skills, sdk }) for tooling. --yes applies all three non-interactively and
|
|
232
253
|
is resilient — a binary that can't self-update (package-managed) warns but never
|
|
233
|
-
blocks the skills/deps steps;
|
|
234
|
-
--no-skills / --no-deps skip those
|
|
254
|
+
blocks the skills/deps steps; a skill failure fails the command rather than
|
|
255
|
+
claiming a partial success. --no-skills / --no-deps explicitly skip those axes.
|
|
235
256
|
|
|
236
257
|
Examples:
|
|
237
258
|
$ astrale update
|
|
@@ -246,11 +267,18 @@ Examples:
|
|
|
246
267
|
try {
|
|
247
268
|
// Tooling path: a machine-readable `--check` (e.g. domain-studio's update
|
|
248
269
|
// badge polling `astrale update --check --json`) gets a unified,
|
|
249
|
-
// non-throwing staleness report
|
|
270
|
+
// non-throwing staleness report and exits.
|
|
250
271
|
if (opts.check && isMachine(opts)) {
|
|
251
272
|
const cli = await cliStale(opts)
|
|
273
|
+
const skills: SkillCheckResult =
|
|
274
|
+
opts.skills === false ? { status: 'skipped' } : await checkAstraleSkills()
|
|
252
275
|
const sdk = await sdkStale()
|
|
253
|
-
const report: StaleReport = {
|
|
276
|
+
const report: StaleReport = {
|
|
277
|
+
stale: cli.stale || skillCheckStale(skills) || sdk.stale,
|
|
278
|
+
cli,
|
|
279
|
+
skills,
|
|
280
|
+
sdk,
|
|
281
|
+
}
|
|
254
282
|
output(report, opts)
|
|
255
283
|
if (report.stale) process.exitCode = 10
|
|
256
284
|
return
|
|
@@ -294,11 +322,25 @@ Examples:
|
|
|
294
322
|
log.success(`Updated astrale ${result.previousVersion} -> ${result.currentVersion}`)
|
|
295
323
|
log.dim(` channel: ${result.channel}`)
|
|
296
324
|
log.dim(` binary: ${result.bin}`)
|
|
325
|
+
} else if (result?.status === 'managed') {
|
|
326
|
+
const error = packageManagedUpdateError(result.executable)
|
|
327
|
+
if (!opts.yes) throw error
|
|
328
|
+
log.warn(`CLI self-update skipped: ${error.message}`)
|
|
297
329
|
}
|
|
298
330
|
|
|
299
|
-
// Axis B — agent skills.
|
|
300
|
-
//
|
|
301
|
-
if (
|
|
331
|
+
// Axis B — agent skills. A successful real update guarantees a verified
|
|
332
|
+
// latest cohort; --check remains read-only and reports its status.
|
|
333
|
+
if (opts.skills !== false) {
|
|
334
|
+
if (opts.check) {
|
|
335
|
+
const skills = await checkAstraleSkills()
|
|
336
|
+
printSkillCheck(skills)
|
|
337
|
+
if (skillCheckStale(skills)) anyAvailable = true
|
|
338
|
+
} else {
|
|
339
|
+
await refreshSkills()
|
|
340
|
+
}
|
|
341
|
+
} else if (!opts.check) {
|
|
342
|
+
log.dim(' Astrale skills skipped (--no-skills)')
|
|
343
|
+
}
|
|
302
344
|
|
|
303
345
|
// Axis C — first-party @astrale-os/* deps in the current domain project.
|
|
304
346
|
// Runs on --check too (reports availability); --yes applies without a prompt.
|
|
@@ -308,7 +350,7 @@ Examples:
|
|
|
308
350
|
|
|
309
351
|
if (opts.check && anyAvailable) process.exitCode = 10
|
|
310
352
|
} catch (e) {
|
|
311
|
-
fatal(e)
|
|
353
|
+
fatal(e, opts)
|
|
312
354
|
}
|
|
313
355
|
},
|
|
314
356
|
} satisfies CommandDefinition
|