@astrale-os/cli 1.0.0-beta.26 → 1.0.0-beta.27
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 +5 -2
- package/dist/astrale.js +963 -287
- package/package.json +3 -2
- package/src/commands/update.ts +61 -40
- package/src/lib/__tests__/skills.test.ts +803 -0
- package/src/lib/skills/lock.ts +117 -0
- package/src/lib/skills/sync.ts +814 -0
- package/src/lib/skills.ts +1 -52
- package/src/program/__tests__/program.test.ts +1 -1
- package/src/setup/steps/skills.ts +40 -38
- package/studio/client/dist/assets/{index-OeJK1TjG.js → index-CpBed0V1.js} +3 -3
- package/studio/client/dist/assets/{schema-studio-DRdfu_cQ.js → schema-studio-DJm9guI8.js} +1 -1
- package/studio/client/dist/index.html +1 -1
- package/studio/server/cli-consumers.test.ts +31 -2
- package/studio/server/workspace/updates.ts +23 -1
- package/studio/shared/contracts/runtime.ts +4 -0
- package/tsconfig.json +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astrale-os/cli",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.27",
|
|
4
4
|
"description": "Astrale CLI — connect to existing Astrale kernels",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"astrale",
|
|
@@ -68,8 +68,8 @@
|
|
|
68
68
|
"@astrale/commitlint-config": "npm:@jsr/astrale__commitlint-config@~2.0.1",
|
|
69
69
|
"@commitlint/cli": "21.2.2",
|
|
70
70
|
"@commitlint/config-conventional": "21.2.2",
|
|
71
|
-
"@types/bun": "^1.1.16",
|
|
72
71
|
"@types/node": "^22.0.0",
|
|
72
|
+
"bun-types": "1.4.0",
|
|
73
73
|
"husky": "~9.1.7",
|
|
74
74
|
"lint-staged": "17.3.0",
|
|
75
75
|
"msgpackr": "^2.0.5",
|
|
@@ -105,6 +105,7 @@
|
|
|
105
105
|
"format": "pnpm exec oxfmt --write .",
|
|
106
106
|
"format:check": "pnpm exec oxfmt --check .",
|
|
107
107
|
"test": "node scripts/qualification/source-boundary.mjs --target && bun test src studio/client/src studio/server studio/shared && node --test scripts/*.test.mjs",
|
|
108
|
+
"test:skills-e2e": "node scripts/qualification/skills-update-e2e.mjs",
|
|
108
109
|
"test:studio": "pnpm --dir studio test",
|
|
109
110
|
"test:watch": "bun test --watch src"
|
|
110
111
|
}
|
package/src/commands/update.ts
CHANGED
|
@@ -11,7 +11,12 @@ import {
|
|
|
11
11
|
inDomainProject,
|
|
12
12
|
type SdkOutdated,
|
|
13
13
|
} from '../lib/sdk-deps'
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
checkAstraleSkills,
|
|
16
|
+
type SkillApplyResult,
|
|
17
|
+
type SkillCheckResult,
|
|
18
|
+
syncAstraleSkills,
|
|
19
|
+
} from '../lib/skills'
|
|
15
20
|
import { DEFAULT_UPDATE_CHANNEL, packageManagedUpdateError, updateAstrale } from '../lib/update'
|
|
16
21
|
|
|
17
22
|
type UpdateOpts = RawOutputOpts & {
|
|
@@ -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
|
|
|
@@ -106,9 +111,8 @@ async function refreshSdkDeps(check: boolean, assumeYes = false): Promise<boolea
|
|
|
106
111
|
* domain-studio polls this on load to drive its "update available" badge. It is
|
|
107
112
|
* unified and NON-THROWING: an explicit package-managed result uses npm release
|
|
108
113
|
* identity, while script-install failures remain script failures in `error`
|
|
109
|
-
* instead of being recategorized. The SDK axis is already best-effort. Skills
|
|
110
|
-
*
|
|
111
|
-
* SDK is the only signal worth surfacing.
|
|
114
|
+
* instead of being recategorized. The SDK axis is already best-effort. Skills
|
|
115
|
+
* report meaningful health/freshness states without exposing installer metadata.
|
|
112
116
|
*/
|
|
113
117
|
export type StaleReport = {
|
|
114
118
|
stale: boolean
|
|
@@ -120,6 +124,7 @@ export type StaleReport = {
|
|
|
120
124
|
channel?: string
|
|
121
125
|
error?: string
|
|
122
126
|
}
|
|
127
|
+
skills: SkillCheckResult
|
|
123
128
|
sdk: { stale: boolean; inProject: boolean; outdated: SdkOutdated[] }
|
|
124
129
|
}
|
|
125
130
|
|
|
@@ -218,7 +223,7 @@ export default {
|
|
|
218
223
|
default: DEFAULT_UPDATE_CHANNEL,
|
|
219
224
|
},
|
|
220
225
|
{ flags: '--version <version>', description: 'Update to an exact version tag' },
|
|
221
|
-
{ flags: '--no-skills', description: 'Skip
|
|
226
|
+
{ flags: '--no-skills', description: 'Skip ensuring the Astrale agent skills' },
|
|
222
227
|
{ flags: '--no-deps', description: 'Skip checking @astrale-os SDK dependency versions' },
|
|
223
228
|
{
|
|
224
229
|
flags: '--yes',
|
|
@@ -231,23 +236,22 @@ Behavior:
|
|
|
231
236
|
Keeps three things current, in order. (1) The CLI binary: updates official
|
|
232
237
|
script installs only — if Astrale was installed by another package manager this
|
|
233
238
|
command refuses so that manager stays in charge; downloads are checksum-verified
|
|
234
|
-
before the binary is replaced. (2) The agent skills:
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
239
|
+
before the binary is replaced. (2) The Astrale agent skills: installs every
|
|
240
|
+
top-level skill published from astrale-os/cli main, updates healthy older
|
|
241
|
+
installs, repairs inconsistent installs, and verifies the result before
|
|
242
|
+
reporting success. (3) SDK deps: inside a pnpm domain
|
|
238
243
|
project, proposes any @astrale-os/* dependency with a newer release and, on
|
|
239
244
|
confirm, runs "pnpm update --latest --lockfile-only" (updates package.json AND
|
|
240
245
|
the lockfile, honoring your registry + supply-chain age policy; run "pnpm
|
|
241
246
|
install" to materialize).
|
|
242
247
|
|
|
243
248
|
The default release channel is beta; --channel overrides it for one run.
|
|
244
|
-
--check is a dry run (binary + SDK deps; exit 10 if anything is available) and
|
|
249
|
+
--check is a dry run (binary + skills + SDK deps; exit 10 if anything is available) and
|
|
245
250
|
never writes. With --json it emits a unified staleness report
|
|
246
|
-
({ stale, cli, sdk }) for tooling
|
|
247
|
-
along with an update). --yes applies all three non-interactively (no prompts) and
|
|
251
|
+
({ stale, cli, skills, sdk }) for tooling. --yes applies all three non-interactively and
|
|
248
252
|
is resilient — a binary that can't self-update (package-managed) warns but never
|
|
249
|
-
blocks the skills/deps steps;
|
|
250
|
-
--no-skills / --no-deps skip those
|
|
253
|
+
blocks the skills/deps steps; a skill failure fails the command rather than
|
|
254
|
+
claiming a partial success. --no-skills / --no-deps explicitly skip those axes.
|
|
251
255
|
|
|
252
256
|
Examples:
|
|
253
257
|
$ astrale update
|
|
@@ -262,11 +266,18 @@ Examples:
|
|
|
262
266
|
try {
|
|
263
267
|
// Tooling path: a machine-readable `--check` (e.g. domain-studio's update
|
|
264
268
|
// badge polling `astrale update --check --json`) gets a unified,
|
|
265
|
-
// non-throwing staleness report
|
|
269
|
+
// non-throwing staleness report and exits.
|
|
266
270
|
if (opts.check && isMachine(opts)) {
|
|
267
271
|
const cli = await cliStale(opts)
|
|
272
|
+
const skills: SkillCheckResult =
|
|
273
|
+
opts.skills === false ? { status: 'skipped' } : await checkAstraleSkills()
|
|
268
274
|
const sdk = await sdkStale()
|
|
269
|
-
const report: StaleReport = {
|
|
275
|
+
const report: StaleReport = {
|
|
276
|
+
stale: cli.stale || skillCheckStale(skills) || sdk.stale,
|
|
277
|
+
cli,
|
|
278
|
+
skills,
|
|
279
|
+
sdk,
|
|
280
|
+
}
|
|
270
281
|
output(report, opts)
|
|
271
282
|
if (report.stale) process.exitCode = 10
|
|
272
283
|
return
|
|
@@ -316,9 +327,19 @@ Examples:
|
|
|
316
327
|
log.warn(`CLI self-update skipped: ${error.message}`)
|
|
317
328
|
}
|
|
318
329
|
|
|
319
|
-
// Axis B — agent skills.
|
|
320
|
-
//
|
|
321
|
-
if (
|
|
330
|
+
// Axis B — agent skills. A successful real update guarantees a verified
|
|
331
|
+
// latest cohort; --check remains read-only and reports its status.
|
|
332
|
+
if (opts.skills !== false) {
|
|
333
|
+
if (opts.check) {
|
|
334
|
+
const skills = await checkAstraleSkills()
|
|
335
|
+
printSkillCheck(skills)
|
|
336
|
+
if (skillCheckStale(skills)) anyAvailable = true
|
|
337
|
+
} else {
|
|
338
|
+
await refreshSkills()
|
|
339
|
+
}
|
|
340
|
+
} else if (!opts.check) {
|
|
341
|
+
log.dim(' Astrale skills skipped (--no-skills)')
|
|
342
|
+
}
|
|
322
343
|
|
|
323
344
|
// Axis C — first-party @astrale-os/* deps in the current domain project.
|
|
324
345
|
// Runs on --check too (reports availability); --yes applies without a prompt.
|
|
@@ -328,7 +349,7 @@ Examples:
|
|
|
328
349
|
|
|
329
350
|
if (opts.check && anyAvailable) process.exitCode = 10
|
|
330
351
|
} catch (e) {
|
|
331
|
-
fatal(e)
|
|
352
|
+
fatal(e, opts)
|
|
332
353
|
}
|
|
333
354
|
},
|
|
334
355
|
} satisfies CommandDefinition
|