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