@astrale-os/cli 1.0.0-beta.1 → 1.0.0-beta.11

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 (329) hide show
  1. package/README.md +23 -12
  2. package/dist/astrale.js +48048 -56798
  3. package/dist/public/connect-core.js +2011 -30765
  4. package/dist/public/keys/index.js +884 -29483
  5. package/dist/public/paths/index.js +13101 -41459
  6. package/dist/types/admin/binding.d.ts +19 -0
  7. package/dist/types/admin/instance/client.d.ts +22 -0
  8. package/dist/types/admin/instance/index.d.ts +2 -0
  9. package/dist/types/admin/instance/model.d.ts +5 -12
  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 +7 -59
  29. package/dist/types/lib/failure-debug.d.ts +1 -0
  30. package/dist/types/lib/idp.d.ts +26 -168
  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/meta.d.ts +2 -2
  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 +91 -0
  38. package/dist/types/lib/validation.d.ts +4 -1
  39. package/package.json +16 -19
  40. package/src/__tests__/fixtures/publication.ts +20 -0
  41. package/src/admin/__tests__/binding.test.ts +31 -0
  42. package/src/admin/__tests__/fixture.ts +101 -0
  43. package/src/admin/binding.ts +98 -0
  44. package/src/admin/catalog/.spec/api.d.ts +2 -2
  45. package/src/admin/catalog/__tests__/client.test.ts +20 -49
  46. package/src/admin/catalog/client.ts +36 -32
  47. package/src/admin/catalog/model.ts +3 -4
  48. package/src/admin/graph/.spec/api.d.ts +4 -10
  49. package/src/admin/graph/nodes.ts +1 -1
  50. package/src/admin/instance/.spec/api.d.ts +2 -2
  51. package/src/admin/instance/__tests__/client.test.ts +39 -164
  52. package/src/admin/instance/client.ts +35 -124
  53. package/src/admin/instance/index.ts +1 -2
  54. package/src/admin/instance/model.ts +11 -20
  55. package/src/commands/__tests__/admin-instance.test.ts +11 -8
  56. package/src/commands/__tests__/auth-login.test.ts +54 -1
  57. package/src/commands/__tests__/call-describe.test.ts +46 -33
  58. package/src/commands/__tests__/call.test.ts +5 -1
  59. package/src/commands/__tests__/domain-install-operation.test.ts +12 -7
  60. package/src/commands/__tests__/domain-install-owned.test.ts +6 -2
  61. package/src/commands/__tests__/domain-list.test.ts +63 -4
  62. package/src/commands/__tests__/install-identity-override.test.ts +19 -19
  63. package/src/commands/__tests__/instance-list-rows.test.ts +1 -1
  64. package/src/commands/__tests__/instance-status.test.ts +139 -0
  65. package/src/commands/__tests__/read-commands.test.ts +35 -10
  66. package/src/commands/__tests__/studio-descriptor.test.ts +22 -0
  67. package/src/commands/__tests__/update.test.ts +48 -19
  68. package/src/commands/call-describe.ts +60 -68
  69. package/src/commands/call.ts +43 -56
  70. package/src/commands/domain/install.ts +13 -17
  71. package/src/commands/domain/list.ts +18 -13
  72. package/src/commands/domain/publish.ts +14 -11
  73. package/src/commands/domain/uninstall.ts +2 -2
  74. package/src/commands/get.ts +14 -15
  75. package/src/commands/identity/__tests__/register.test.ts +3 -3
  76. package/src/commands/identity/register.ts +5 -4
  77. package/src/commands/instance/create.ts +8 -16
  78. package/src/commands/instance/delete.ts +12 -9
  79. package/src/commands/instance/list.ts +2 -2
  80. package/src/commands/instance/status.ts +66 -20
  81. package/src/commands/instance/use.ts +16 -12
  82. package/src/commands/introspect.ts +9 -16
  83. package/src/commands/logs.ts +24 -25
  84. package/src/commands/mutate.ts +6 -5
  85. package/src/commands/query.ts +27 -30
  86. package/src/commands/studio.ts +20 -0
  87. package/src/commands/token.ts +8 -7
  88. package/src/commands/update.ts +38 -14
  89. package/src/commands/view.ts +7 -6
  90. package/src/connection/.spec/api.d.ts +7 -8
  91. package/src/connection/.spec/architecture.md +5 -4
  92. package/src/connection/.spec/flows/session.ts +2 -2
  93. package/src/connection/.spec/laws/connection.ts +6 -2
  94. package/src/connection/.spec/layout.ts +1 -0
  95. package/src/connection/__tests__/credential.test.ts +20 -1
  96. package/src/connection/__tests__/errors.test.ts +43 -32
  97. package/src/connection/__tests__/exchange.test.ts +36 -6
  98. package/src/connection/__tests__/failure-fixtures.ts +39 -0
  99. package/src/connection/__tests__/failure-safety.test.ts +75 -0
  100. package/src/connection/__tests__/self.test.ts +31 -11
  101. package/src/connection/__tests__/session.test.ts +3 -3
  102. package/src/connection/__tests__/target.test.ts +1 -0
  103. package/src/connection/auth.ts +13 -0
  104. package/src/connection/call.ts +1 -1
  105. package/src/connection/credential.ts +2 -2
  106. package/src/connection/errors.ts +1 -355
  107. package/src/connection/exchange.ts +52 -27
  108. package/src/connection/failure/classify.ts +110 -0
  109. package/src/connection/failure/index.ts +18 -0
  110. package/src/connection/failure/model.ts +28 -0
  111. package/src/connection/failure/render.ts +116 -0
  112. package/src/connection/reasons.ts +16 -0
  113. package/src/connection/self.ts +39 -21
  114. package/src/connection/session.ts +19 -8
  115. package/src/errors.ts +3 -2
  116. package/src/graph/.spec/api.d.ts +12 -5
  117. package/src/graph/.spec/layout.ts +9 -1
  118. package/src/graph/__tests__/mutation.test.ts +2 -2
  119. package/src/graph/__tests__/query.test.ts +25 -6
  120. package/src/graph/class.ts +30 -0
  121. package/src/graph/index.ts +1 -0
  122. package/src/graph/query.ts +21 -32
  123. package/src/identity/.spec/api.d.ts +2 -2
  124. package/src/identity/__tests__/registration.test.ts +1 -1
  125. package/src/identity/registration.ts +3 -3
  126. package/src/keys/__tests__/keys.test.ts +4 -0
  127. package/src/keys/credential.ts +1 -0
  128. package/src/lib/__tests__/admin-target.test.ts +12 -0
  129. package/src/lib/__tests__/command-dx.test.ts +1 -1
  130. package/src/lib/__tests__/domain-publication.test.ts +138 -0
  131. package/src/lib/__tests__/idp-session.test.ts +22 -0
  132. package/src/lib/__tests__/idp.test.ts +36 -4
  133. package/src/lib/__tests__/instance-candidates.test.ts +1 -3
  134. package/src/lib/__tests__/instance-target.test.ts +7 -39
  135. package/src/lib/__tests__/instance.test.ts +6 -0
  136. package/src/lib/__tests__/log-errors.test.ts +64 -0
  137. package/src/lib/__tests__/studio-server-deps.test.ts +53 -16
  138. package/src/lib/__tests__/update.test.ts +113 -8
  139. package/src/lib/__tests__/view-open-intent.test.ts +0 -2
  140. package/src/lib/__tests__/view-server.test.ts +18 -3
  141. package/src/lib/__tests__/view-session.test.ts +1 -1
  142. package/src/lib/admin-instance.ts +14 -8
  143. package/src/lib/admin-target.ts +21 -2
  144. package/src/lib/command-dx.ts +9 -9
  145. package/src/lib/domain-publication.ts +104 -0
  146. package/src/lib/failure-debug.ts +26 -0
  147. package/src/lib/idp.ts +39 -4
  148. package/src/lib/instance-candidates.ts +2 -2
  149. package/src/lib/instance-target.ts +3 -14
  150. package/src/lib/instance.ts +22 -12
  151. package/src/lib/log.ts +16 -9
  152. package/src/lib/login-flow.ts +13 -3
  153. package/src/lib/meta.ts +2 -2
  154. package/src/lib/provision-instance.ts +34 -57
  155. package/src/lib/update.ts +124 -30
  156. package/src/lib/validation.ts +2 -2
  157. package/src/lib/view/resolve.ts +1 -1
  158. package/src/lib/view/server.ts +17 -3
  159. package/src/program/__tests__/program.test.ts +20 -4
  160. package/src/program/build.ts +2 -2
  161. package/src/setup/__tests__/instance-step.test.ts +27 -10
  162. package/src/setup/steps/instance.ts +22 -15
  163. package/studio/client/dist/assets/elk-api-DjmKsHXc.js +1 -0
  164. package/studio/client/dist/assets/index-7YHdeCxp.js +81 -0
  165. package/studio/client/dist/assets/index-C0FAnwNw.css +2 -0
  166. package/studio/client/dist/assets/rolldown-runtime-Dd_uD5pT.js +1 -0
  167. package/studio/client/dist/assets/schema-studio-BilUNb6Z.css +1 -0
  168. package/studio/client/dist/assets/schema-studio-CABpTfvH.js +8 -0
  169. package/studio/client/dist/index.html +3 -2
  170. package/studio/package.json +10 -14
  171. package/studio/server/agent/ask.test.ts +1 -1
  172. package/studio/server/agent/bridge/grant.test.ts +1 -1
  173. package/studio/server/agent/bridge/routes.test.ts +1 -1
  174. package/studio/server/agent/bridge/stdio.ts +8 -1
  175. package/studio/server/agent/conversation.test.ts +10 -5
  176. package/studio/server/agent/conversation.ts +56 -8
  177. package/studio/server/agent/harness/claude/adapter.test.ts +15 -5
  178. package/studio/server/agent/harness/codex/loadout.ts +18 -21
  179. package/studio/server/agent/harness/gateway/config.ts +20 -18
  180. package/studio/server/agent/harness/selection.ts +9 -1
  181. package/studio/server/agent/prompts/anchors.test.ts +32 -36
  182. package/studio/server/agent/prompts/anchors.ts +20 -49
  183. package/studio/server/agent/prompts/system.test.ts +3 -2
  184. package/studio/server/agent/prompts/system.ts +6 -5
  185. package/studio/server/agent/prompts/turn.ts +13 -4
  186. package/studio/server/agent/routes.test.ts +1 -1
  187. package/studio/server/agent/run/completion.ts +2 -2
  188. package/studio/server/agent/run/coordinator.test.ts +1 -1
  189. package/studio/server/agent/run/preparation.ts +6 -5
  190. package/studio/server/agent/run/transcript.test.ts +35 -1
  191. package/studio/server/agent/run/transcript.ts +169 -3
  192. package/studio/server/agent/run/usage.test.ts +24 -0
  193. package/studio/server/agent/run/usage.ts +26 -1
  194. package/studio/server/api/canvas.ts +43 -0
  195. package/studio/server/api/comments.ts +85 -0
  196. package/studio/server/api/context.ts +61 -0
  197. package/studio/server/api/deployment.ts +39 -0
  198. package/studio/server/api/documents.ts +55 -0
  199. package/studio/server/api/domain.ts +59 -0
  200. package/studio/server/api/http.ts +45 -0
  201. package/studio/server/api/project.ts +57 -0
  202. package/studio/server/api/schema.ts +12 -0
  203. package/studio/server/api/views.ts +57 -0
  204. package/studio/server/api/workspace.ts +60 -0
  205. package/studio/server/api-agent-loadout.test.ts +1 -1
  206. package/studio/server/api.test.ts +147 -0
  207. package/studio/server/api.ts +20 -422
  208. package/studio/server/cache.test.ts +122 -0
  209. package/studio/server/cache.ts +162 -11
  210. package/studio/server/cli-consumers.test.ts +494 -0
  211. package/studio/server/cli.test.ts +88 -0
  212. package/studio/server/cli.ts +240 -0
  213. package/studio/server/client-package.ts +25 -1
  214. package/studio/server/domain.test.ts +50 -40
  215. package/studio/server/domain.ts +83 -52
  216. package/studio/server/environment/dotenv-preview.test.ts +39 -0
  217. package/studio/server/environment/dotenv-preview.ts +27 -0
  218. package/studio/server/environment/files.test.ts +53 -0
  219. package/studio/server/{state/env.ts → environment/files.ts} +7 -48
  220. package/studio/server/{state → handoff}/copy.ts +21 -6
  221. package/studio/server/handoff/service.test.ts +22 -0
  222. package/studio/server/{state/handoff.ts → handoff/service.ts} +21 -14
  223. package/studio/server/index.ts +1 -1
  224. package/studio/server/instances/active.ts +72 -0
  225. package/studio/server/instances/deploy-record.test.ts +31 -0
  226. package/studio/server/instances/deploy-record.ts +37 -0
  227. package/studio/server/instances/deploy.ts +56 -0
  228. package/studio/server/{state/instance.test.ts → instances/probe.test.ts} +25 -21
  229. package/studio/server/instances/probe.ts +67 -0
  230. package/studio/server/instances/status.test.ts +12 -0
  231. package/studio/server/instances/status.ts +49 -0
  232. package/studio/server/introspect/anatomy/client-tree.ts +57 -0
  233. package/studio/server/introspect/anatomy/env-fields.ts +66 -0
  234. package/studio/server/introspect/anatomy/schema-definition.ts +53 -0
  235. package/studio/server/introspect/anatomy/source.ts +181 -0
  236. package/studio/server/introspect/anatomy/views/routes.ts +114 -0
  237. package/studio/server/introspect/anatomy/views.ts +53 -0
  238. package/studio/server/introspect/anatomy-extras.test.ts +106 -35
  239. package/studio/server/introspect/anatomy-extras.ts +7 -726
  240. package/studio/server/introspect/anatomy.test.ts +22 -14
  241. package/studio/server/introspect/anatomy.ts +52 -28
  242. package/studio/server/introspect/bundle.ts +15 -9
  243. package/studio/server/introspect/canonical-schema.test.ts +93 -309
  244. package/studio/server/introspect/canonical-schema.ts +257 -425
  245. package/studio/server/introspect/config-preview.test.ts +32 -0
  246. package/studio/server/introspect/config-preview.ts +119 -0
  247. package/studio/server/introspect/core-extractor.ts +18 -127
  248. package/studio/server/introspect/core.ts +1 -2
  249. package/studio/server/introspect/diff.test.ts +18 -18
  250. package/studio/server/introspect/diff.ts +44 -90
  251. package/studio/server/introspect/extractor.ts +23 -116
  252. package/studio/server/introspect/hash.ts +5 -2
  253. package/studio/server/introspect/overlay-tsmorph.test.ts +119 -240
  254. package/studio/server/introspect/overlay-tsmorph.ts +7 -1305
  255. package/studio/server/introspect/overlay.test.ts +26 -54
  256. package/studio/server/introspect/overlay.ts +10 -37
  257. package/studio/server/introspect/revision.test.ts +54 -0
  258. package/studio/server/introspect/revision.ts +49 -0
  259. package/studio/server/introspect/runtime.test.ts +83 -143
  260. package/studio/server/introspect/runtime.ts +40 -11
  261. package/studio/server/introspect/schema-ir-json.test.ts +70 -0
  262. package/studio/server/introspect/schema-ir-json.ts +151 -0
  263. package/studio/server/introspect/schema-refs.test.ts +43 -88
  264. package/studio/server/introspect/schema-refs.ts +14 -49
  265. package/studio/server/introspect/source-overlay/annotations.ts +14 -0
  266. package/studio/server/introspect/source-overlay/handlers.ts +161 -0
  267. package/studio/server/introspect/source-overlay/kernel-calls.ts +46 -0
  268. package/studio/server/introspect/source-overlay/project.ts +248 -0
  269. package/studio/server/introspect/source-overlay/spans.ts +330 -0
  270. package/studio/server/json.ts +46 -0
  271. package/studio/server/lifecycle.ts +5 -1
  272. package/studio/server/sse.test.ts +26 -0
  273. package/studio/server/sse.ts +4 -1
  274. package/studio/server/state/baseline.test.ts +223 -7
  275. package/studio/server/state/baseline.ts +148 -34
  276. package/studio/server/state/comments.test.ts +66 -1
  277. package/studio/server/state/comments.ts +173 -10
  278. package/studio/server/state/context.ts +34 -2
  279. package/studio/server/state/documents.ts +42 -1
  280. package/studio/server/state/integrations.ts +27 -1
  281. package/studio/server/state/layout.test.ts +34 -0
  282. package/studio/server/state/layout.ts +44 -17
  283. package/studio/server/state/settings.ts +29 -22
  284. package/studio/server/state/store.test.ts +122 -0
  285. package/studio/server/state/store.ts +66 -17
  286. package/studio/server/state/visibility.ts +22 -11
  287. package/studio/server/views/model.test.ts +57 -0
  288. package/studio/server/views/model.ts +66 -0
  289. package/studio/server/views/runtime.ts +40 -0
  290. package/studio/server/views/selection-repository.test.ts +31 -0
  291. package/studio/server/views/selection-repository.ts +60 -0
  292. package/studio/server/views/session.test.ts +73 -0
  293. package/studio/server/views/session.ts +166 -0
  294. package/studio/server/views/target.test.ts +78 -0
  295. package/studio/server/views/target.ts +222 -0
  296. package/studio/server/watch.test.ts +11 -11
  297. package/studio/server/watch.ts +9 -5
  298. package/studio/server/workspace/catalog.test.ts +17 -0
  299. package/studio/server/workspace/catalog.ts +43 -0
  300. package/studio/server/{state → workspace}/create.test.ts +1 -1
  301. package/studio/server/{state → workspace}/create.ts +1 -1
  302. package/studio/server/{state → workspace}/git.ts +1 -1
  303. package/studio/server/workspace/updates.ts +83 -0
  304. package/studio/server/workspace-state.ts +1 -1
  305. package/studio/server/workspace-watch.ts +2 -2
  306. package/studio/shared/contracts/README.md +16 -0
  307. package/studio/shared/contracts/agent.ts +270 -0
  308. package/studio/shared/contracts/runtime.ts +50 -0
  309. package/studio/shared/contracts/schema.ts +393 -0
  310. package/studio/shared/contracts/surface.test.ts +317 -0
  311. package/studio/shared/contracts/workspace.ts +265 -0
  312. package/studio/shared/layout.test.ts +116 -0
  313. package/studio/shared/schema/identity.test.ts +34 -0
  314. package/studio/shared/schema/identity.ts +68 -0
  315. package/studio/shared/types.ts +11 -1099
  316. package/studio/tsconfig.json +1 -1
  317. package/viewer/dist/main.js +40 -61
  318. package/.check-workspace.cjs +0 -40
  319. package/src/commands/__tests__/instance-create-hosts.test.ts +0 -29
  320. package/studio/client/dist/assets/elk-api-D2xgMJvi.js +0 -1
  321. package/studio/client/dist/assets/index-BMdnsIJA.css +0 -1
  322. package/studio/client/dist/assets/index-ChOr3yP0.css +0 -1
  323. package/studio/client/dist/assets/index-D-vRV8w7.js +0 -8
  324. package/studio/client/dist/assets/index-LGSWRrk8.js +0 -81
  325. package/studio/server/state/catalog.ts +0 -117
  326. package/studio/server/state/instance.ts +0 -280
  327. package/studio/server/state/updates.ts +0 -63
  328. package/studio/server/state/views.test.ts +0 -286
  329. package/studio/server/state/views.ts +0 -535
@@ -1,17 +1,13 @@
1
1
  /**
2
- * diff.ts — structural diff of two Schema IRs + breaking/additive classification.
3
- * Shared by change tracking (baseline) and data versioning. Pure.
2
+ * diff.ts — indicative structural diff of two Studio render IRs. Pure.
4
3
  *
5
4
  * Canonical V1 keeps optionality in the owning `required` arrays and nullability
6
- * in each value schema. Legacy nullable projections remain supported. Contract
7
- * changes are classified conservatively: removals, tightened value schemas,
8
- * callable/auth/policy changes, topology changes, dependency revisions and Core
9
- * changes are breaking; pure additions and descriptions are additive.
5
+ * in each value schema. This inventory makes no installation or data-migration claim;
6
+ * only the Kernel Runtime can assess those transitions against installed data.
10
7
  */
11
8
  import type {
12
9
  IrClass,
13
10
  IrFunction,
14
- IrInterface,
15
11
  IrMethod,
16
12
  JsonSchema,
17
13
  SchemaChange,
@@ -34,28 +30,11 @@ export function baseType(s: JsonSchema | undefined): string {
34
30
  return s.enum ? `enum(${s.enum.join(',')})` : 'unknown'
35
31
  }
36
32
 
37
- function requiredParams(m: IrMethod | IrFunction): string[] {
38
- return (
39
- m.requiredParams ??
40
- Object.entries(m.params ?? {}).flatMap(([name, schema]) => (isOptional(schema) ? [] : [name]))
41
- )
42
- }
43
-
44
33
  function callableContract(m: IrMethod | IrFunction): unknown {
45
- const required = requiredParams(m)
46
34
  return {
47
- input:
48
- m.input ??
49
- ({
50
- type: 'object',
51
- properties: m.params ?? {},
52
- required,
53
- additionalProperties: false,
54
- } satisfies JsonSchema),
55
- required,
56
- output: m.output ?? { mode: 'value', schema: m.returns },
57
- static: m.static,
58
- inheritance: m.inheritance,
35
+ input: m.input,
36
+ output: m.output,
37
+ ...('static' in m ? { static: m.static, inheritance: m.inheritance } : {}),
59
38
  auth: m.auth,
60
39
  policy: m.policy,
61
40
  }
@@ -75,24 +54,17 @@ export function diffSchemas(prev: SchemaIR | null, next: SchemaIR | null): Schem
75
54
  },
76
55
  )
77
56
  ) {
78
- changes.push({ kind: 'schema-metadata-changed', target: next.domain, breaking: true })
57
+ changes.push({ kind: 'schema-metadata-changed', target: next.domain })
79
58
  }
80
59
 
81
- diffValueRecord(prev.types ?? {}, next.types ?? {}, 'type', changes)
82
- diffValueRecord(
83
- prev.importsByKey ?? prev.imports ?? {},
84
- next.importsByKey ?? next.imports ?? {},
85
- 'import',
86
- changes,
87
- )
88
- diffMembers(prev.interfaces ?? {}, next.interfaces ?? {}, 'interface', changes)
89
- diffMembers(prev.classes ?? {}, next.classes ?? {}, 'class', changes)
60
+ diffValueRecord(prev.importsByKey, next.importsByKey, 'import', changes)
61
+ diffMembers(prev.classes, next.classes, changes)
90
62
  diffFunctions(prev.functions ?? {}, next.functions ?? {}, changes)
91
63
  diffViews(prev.views ?? {}, next.views ?? {}, changes)
92
64
  diffValueRecord(prev.policies ?? {}, next.policies ?? {}, 'policy', changes)
93
65
  diffDependencies(prev.dependencies ?? [], next.dependencies ?? [], changes)
94
66
  if (!same(prev.core, next.core) && (prev.core !== undefined || next.core !== undefined)) {
95
- changes.push({ kind: 'core-changed', target: next.domain, breaking: prev.core !== undefined })
67
+ changes.push({ kind: 'core-changed', target: next.domain })
96
68
  }
97
69
  return changes
98
70
  }
@@ -100,19 +72,19 @@ export function diffSchemas(prev: SchemaIR | null, next: SchemaIR | null): Schem
100
72
  function diffValueRecord(
101
73
  prev: Record<string, unknown>,
102
74
  next: Record<string, unknown>,
103
- scope: 'type' | 'import' | 'policy',
75
+ scope: 'import' | 'policy',
104
76
  out: SchemaChange[],
105
77
  ): void {
106
78
  for (const name of sortedKeys(next)) {
107
79
  if (!(name in prev)) {
108
- out.push({ kind: `${scope}-added`, target: name, breaking: false })
80
+ out.push({ kind: `${scope}-added`, target: name })
109
81
  }
110
82
  }
111
83
  for (const name of sortedKeys(prev)) {
112
84
  if (!(name in next)) {
113
- out.push({ kind: `${scope}-removed`, target: name, breaking: true })
85
+ out.push({ kind: `${scope}-removed`, target: name })
114
86
  } else if (!same(prev[name], next[name])) {
115
- out.push({ kind: `${scope}-changed`, target: name, breaking: true })
87
+ out.push({ kind: `${scope}-changed`, target: name })
116
88
  }
117
89
  }
118
90
  }
@@ -123,18 +95,18 @@ function diffFunctions(
123
95
  out: SchemaChange[],
124
96
  ): void {
125
97
  for (const name of sortedKeys(next)) {
126
- if (!prev[name]) out.push({ kind: 'function-added', target: name, breaking: false })
98
+ if (!prev[name]) out.push({ kind: 'function-added', target: name })
127
99
  }
128
100
  for (const name of sortedKeys(prev)) {
129
101
  if (!next[name]) {
130
- out.push({ kind: 'function-removed', target: name, breaking: true })
102
+ out.push({ kind: 'function-removed', target: name })
131
103
  continue
132
104
  }
133
105
  if (!same(callableContract(prev[name]), callableContract(next[name]))) {
134
- out.push({ kind: 'function-signature-changed', target: name, breaking: true })
106
+ out.push({ kind: 'function-signature-changed', target: name })
135
107
  }
136
108
  if (prev[name].description !== next[name].description) {
137
- out.push({ kind: 'function-metadata-changed', target: name, breaking: false })
109
+ out.push({ kind: 'function-metadata-changed', target: name })
138
110
  }
139
111
  }
140
112
  }
@@ -145,11 +117,11 @@ function diffViews(
145
117
  out: SchemaChange[],
146
118
  ): void {
147
119
  for (const name of sortedKeys(next)) {
148
- if (!(name in prev)) out.push({ kind: 'view-added', target: name, breaking: false })
120
+ if (!(name in prev)) out.push({ kind: 'view-added', target: name })
149
121
  }
150
122
  for (const name of sortedKeys(prev)) {
151
123
  if (!(name in next)) {
152
- out.push({ kind: 'view-removed', target: name, breaking: true })
124
+ out.push({ kind: 'view-removed', target: name })
153
125
  continue
154
126
  }
155
127
  if (
@@ -161,10 +133,10 @@ function diffViews(
161
133
  },
162
134
  )
163
135
  ) {
164
- out.push({ kind: 'view-changed', target: name, breaking: true })
136
+ out.push({ kind: 'view-changed', target: name })
165
137
  }
166
138
  if (prev[name].description !== next[name].description) {
167
- out.push({ kind: 'view-metadata-changed', target: name, breaking: false })
139
+ out.push({ kind: 'view-metadata-changed', target: name })
168
140
  }
169
141
  }
170
142
  }
@@ -182,56 +154,48 @@ function diffDependencies(
182
154
  )
183
155
  for (const origin of sortedKeys(after)) {
184
156
  if (!(origin in before)) {
185
- out.push({ kind: 'dependency-added', target: origin, breaking: true })
157
+ out.push({ kind: 'dependency-added', target: origin })
186
158
  }
187
159
  }
188
160
  for (const origin of sortedKeys(before)) {
189
161
  if (!(origin in after)) {
190
- out.push({ kind: 'dependency-removed', target: origin, breaking: true })
162
+ out.push({ kind: 'dependency-removed', target: origin })
191
163
  } else if (before[origin] !== after[origin]) {
192
164
  out.push({
193
165
  kind: 'dependency-changed',
194
166
  target: origin,
195
167
  detail: `${before[origin]} → ${after[origin]}`,
196
- breaking: true,
197
168
  })
198
169
  }
199
170
  }
200
171
  }
201
172
 
202
- function memberKind(m: IrClass | IrInterface): 'class' | 'edge' | 'interface' {
203
- if ((m as IrInterface).type === 'interface') return 'interface'
204
- return (m as IrClass).type === 'edge' ? 'edge' : 'class'
173
+ function memberKind(member: IrClass): 'class' | 'edge' {
174
+ return member.type === 'edge' ? 'edge' : 'class'
205
175
  }
206
176
 
207
177
  function diffMembers(
208
- prev: Record<string, IrClass | IrInterface>,
209
- next: Record<string, IrClass | IrInterface>,
210
- _scope: 'class' | 'interface',
178
+ prev: Record<string, IrClass>,
179
+ next: Record<string, IrClass>,
211
180
  out: SchemaChange[],
212
181
  ): void {
213
182
  for (const name of sortedKeys(next)) {
214
183
  if (!prev[name]) {
215
184
  const k = memberKind(next[name])
216
- out.push({ kind: `${k}-added` as SchemaChange['kind'], target: name, breaking: false })
185
+ out.push({ kind: `${k}-added` as SchemaChange['kind'], target: name })
217
186
  }
218
187
  }
219
188
  for (const name of sortedKeys(prev)) {
220
189
  if (!next[name]) {
221
190
  const k = memberKind(prev[name])
222
- out.push({ kind: `${k}-removed` as SchemaChange['kind'], target: name, breaking: true })
191
+ out.push({ kind: `${k}-removed` as SchemaChange['kind'], target: name })
223
192
  continue
224
193
  }
225
194
  diffMemberBody(name, prev[name], next[name], out)
226
195
  }
227
196
  }
228
197
 
229
- function diffMemberBody(
230
- name: string,
231
- a: IrClass | IrInterface,
232
- b: IrClass | IrInterface,
233
- out: SchemaChange[],
234
- ): void {
198
+ function diffMemberBody(name: string, a: IrClass, b: IrClass, out: SchemaChange[]): void {
235
199
  const pa = a.properties ?? {}
236
200
  const pb = b.properties ?? {}
237
201
  for (const p of sortedKeys(pb)) {
@@ -241,13 +205,12 @@ function diffMemberBody(
241
205
  kind: 'prop-added',
242
206
  target: `${name}.${p}`,
243
207
  detail: required ? 'required' : 'optional',
244
- breaking: required,
245
208
  })
246
209
  }
247
210
  }
248
211
  for (const p of sortedKeys(pa)) {
249
212
  if (!pb[p]) {
250
- out.push({ kind: 'prop-removed', target: `${name}.${p}`, breaking: true })
213
+ out.push({ kind: 'prop-removed', target: `${name}.${p}` })
251
214
  continue
252
215
  }
253
216
  if (!same(pa[p], pb[p])) {
@@ -258,7 +221,6 @@ function diffMemberBody(
258
221
  detail: baseChanged
259
222
  ? `${baseType(pa[p])} → ${baseType(pb[p])}`
260
223
  : 'value constraints changed',
261
- breaking: true,
262
224
  })
263
225
  }
264
226
  const wasOpt = !propertyRequired(a, p)
@@ -268,7 +230,6 @@ function diffMemberBody(
268
230
  kind: 'prop-required-changed',
269
231
  target: `${name}.${p}`,
270
232
  detail: wasOpt ? 'optional → required' : 'required → optional',
271
- breaking: wasOpt && !nowOpt, // optional→required is breaking
272
233
  })
273
234
  }
274
235
  }
@@ -280,20 +241,19 @@ function diffMemberBody(
280
241
  out.push({
281
242
  kind: 'method-added',
282
243
  target: `${name}.${m}`,
283
- breaking: b.type === 'interface' && mb[m].inheritance === 'abstract',
284
244
  })
285
245
  }
286
246
  }
287
247
  for (const m of sortedKeys(ma)) {
288
248
  if (!mb[m]) {
289
- out.push({ kind: 'method-removed', target: `${name}.${m}`, breaking: true })
249
+ out.push({ kind: 'method-removed', target: `${name}.${m}` })
290
250
  continue
291
251
  }
292
252
  if (!same(callableContract(ma[m]), callableContract(mb[m]))) {
293
- out.push({ kind: 'method-signature-changed', target: `${name}.${m}`, breaking: true })
253
+ out.push({ kind: 'method-signature-changed', target: `${name}.${m}` })
294
254
  }
295
255
  if (ma[m].description !== mb[m].description) {
296
- out.push({ kind: 'method-metadata-changed', target: `${name}.${m}`, breaking: false })
256
+ out.push({ kind: 'method-metadata-changed', target: `${name}.${m}` })
297
257
  }
298
258
  }
299
259
 
@@ -302,39 +262,34 @@ function diffMemberBody(
302
262
  out.push({
303
263
  kind: `${kind}-contract-changed`,
304
264
  target: name,
305
- breaking: true,
306
265
  })
307
266
  }
308
267
  if (!same(memberMetadata(a), memberMetadata(b))) {
309
- out.push({ kind: 'definition-metadata-changed', target: name, breaking: false })
268
+ out.push({ kind: 'definition-metadata-changed', target: name })
310
269
  }
311
270
  }
312
271
 
313
- function propertyRequired(member: IrClass | IrInterface, name: string): boolean {
272
+ function propertyRequired(member: IrClass, name: string): boolean {
314
273
  return member.required ? member.required.includes(name) : !isOptional(member.properties?.[name])
315
274
  }
316
275
 
317
- function memberContract(member: IrClass | IrInterface): unknown {
318
- const cls = member as IrClass
319
- const iface = member as IrInterface
276
+ function memberContract(member: IrClass): unknown {
320
277
  return {
321
278
  type: member.type,
322
279
  origin: member.origin,
323
280
  ref: member.ref,
324
- family: iface.family,
325
- extends: iface.extendsRefs ?? iface.extends,
326
- implements: cls.implementsRefs ?? cls.implements,
281
+ extends: member.extendsRefs ?? member.extends,
327
282
  endpoints: member.endpoints,
328
283
  orientation: member.orientation,
329
284
  constraints: member.constraints,
330
285
  propertyMetadata: member.propertyMetadata,
331
286
  data: member.data,
332
- policies: cls.policies,
287
+ policies: member.policies,
333
288
  }
334
289
  }
335
290
 
336
- function memberMetadata(member: IrClass | IrInterface): unknown {
337
- return { description: member.description, icon: (member as IrClass).icon }
291
+ function memberMetadata(member: IrClass): unknown {
292
+ return { description: member.description, icon: member.icon }
338
293
  }
339
294
 
340
295
  function sortedKeys(value: Record<string, unknown>): string[] {
@@ -356,7 +311,6 @@ function canonical(value: unknown): unknown {
356
311
  )
357
312
  }
358
313
 
359
- export function classify(changes: SchemaChange[]): 'none' | 'additive' | 'breaking' {
360
- if (changes.length === 0) return 'none'
361
- return changes.some((c) => c.breaking) ? 'breaking' : 'additive'
314
+ export function structuralStatusOf(changes: SchemaChange[]): 'none' | 'changed' {
315
+ return changes.length === 0 ? 'none' : 'changed'
362
316
  }
@@ -1,134 +1,41 @@
1
- /**
2
- * extractor.ts — the Bun-executed island. Spawned as a short-lived subprocess by
3
- * runtime.ts. It imports ONLY the domain's pure `schema/index.ts` module graph
4
- * (never astrale.config.ts or the composition entry → integrations). Canonical
5
- * DomainSchema V1 roots are projected directly; legacy `D.$.ir` / serialize
6
- * domains retain their existing fallback.
7
- *
8
- * bun extractor.ts <schemaIndexPath> <domainDir>
9
- *
10
- * A thrown error prints { ok:false } and exits 0 — the driver treats it as a
11
- * render state, never a crash.
12
- */
1
+ /** Bun subprocess that imports only the authored Schema entry and its installed SDK. */
13
2
  import {
14
- closureFromSdk,
3
+ admitCanonicalSchemaFromSdk,
15
4
  findCanonicalDomainSchemaExport,
16
- normalizeLegacySchemaIR,
17
5
  projectCanonicalSchema,
18
6
  } from './canonical-schema'
19
7
 
20
8
  const schemaPath = process.argv[2]
21
- const domainDir = process.argv[3] ?? process.cwd()
22
-
23
- async function main() {
24
- if (!schemaPath) throw new Error('extractor: missing <schemaIndexPath>')
25
- const mod: Record<string, any> = await import(schemaPath)
26
-
27
- // Resolve through the DOMAIN's dependency graph. This prevents Studio's own
28
- // SDK version from accepting or resolving a root authored by another cohort.
29
- let sdk: Record<string, any> | null = null
30
- const loadSdkSchema = async (): Promise<Record<string, any>> => {
31
- if (sdk) return sdk
32
- const loaded: Record<string, any> = await import(
33
- Bun.resolveSync('@astrale-os/sdk/schema', domainDir)
34
- )
35
- sdk = loaded
36
- return loaded
37
- }
38
-
39
- const canonicalRoot = findCanonicalDomainSchemaExport(mod)
40
- if (canonicalRoot) {
41
- const domainSdk = await loadSdkSchema()
42
- const projected = projectCanonicalSchema(
43
- canonicalRoot,
44
- closureFromSdk(domainSdk, canonicalRoot),
45
- )
46
- process.stdout.write(
47
- JSON.stringify({
48
- ok: true,
49
- ir: projected.ir,
50
- root: canonicalRoot,
51
- importedInterfaces: projected.importedInterfaces,
52
- }),
53
- )
54
- return
55
- }
56
-
57
- // Prefer the conventional `D` (compiled), but accept a compiled domain exported
58
- // under ANY name — e.g. ai-gateway exports its `compileDomain(...)` result as
59
- // `Gateway`, not `D`. A compiled domain is recognized by shape (`.$.ir`).
60
- let ir: unknown = mod?.D?.$?.ir
61
- if (!ir) {
62
- for (const v of Object.values(mod)) {
63
- const candidate = (v as any)?.$?.ir
64
- if (candidate) {
65
- ir = candidate
66
- break
67
- }
68
- }
9
+ const projectRoot = process.argv[3] ?? process.cwd()
10
+
11
+ async function main(): Promise<void> {
12
+ if (!schemaPath) throw new Error('extractor: missing <schemaPath>')
13
+ const exports = (await import(schemaPath)) as Record<string, unknown>
14
+ const candidate = findCanonicalDomainSchemaExport(exports)
15
+ if (candidate === null) {
16
+ throw new Error('Schema entry exports no canonical V1 DomainSchema.')
69
17
  }
70
- if (!ir) {
71
- // Fallback: serialize a raw schema — the conventional `schema`, else any
72
- // exported `defineSchema(...)` result (recognized by its `kind === 'schema'`).
73
- const schema =
74
- mod?.schema ??
75
- Object.values(mod).find(
76
- (v) =>
77
- typeof (v as any)?.domain === 'string' && !!(v as any)?.classes && !!(v as any)?.imports,
78
- )
79
- if (!schema) {
80
- throw new Error(
81
- 'schema entry exports no compiled domain (a `compileDomain(...)` value with `.$.ir`, e.g. `D`) nor a raw `schema`',
82
- )
83
- }
84
- const d = await loadSdkSchema()
85
- if (typeof d.serialize !== 'function') throw new Error('kernel-dsl.serialize unavailable')
86
- ir = d.serialize(schema)
87
- }
88
-
89
- // Recover member bodies of IMPORTED interfaces (kernel mixins + cross-domain
90
- // interfaces). `serialize()` emits them in `ir.imports` as name-only
91
- // descriptors, so re-serialize each imported schema (KernelSchema, other
92
- // domains) and collect its interface definitions. Best-effort: a single import
93
- // failing to serialize must never break extraction of the primary IR.
94
- const importedInterfaces: Record<string, unknown> = {}
95
- const importSchemas: any[] = Array.isArray(mod?.schema?.imports) ? mod.schema.imports : []
96
- if (importSchemas.length > 0) {
97
- try {
98
- const d = await loadSdkSchema()
99
- if (typeof d.serialize === 'function') {
100
- for (const imp of importSchemas) {
101
- try {
102
- const sub = d.serialize(imp)
103
- for (const [name, def] of Object.entries(sub?.interfaces ?? {})) {
104
- if (!(name in importedInterfaces)) importedInterfaces[name] = def
105
- }
106
- } catch {
107
- /* skip this import — keep going */
108
- }
109
- }
110
- }
111
- } catch {
112
- /* dsl unavailable — degrade gracefully (no imported-interface bodies) */
113
- }
114
- }
115
-
18
+ const sdk = (await import(Bun.resolveSync('@astrale-os/sdk/schema', projectRoot))) as Record<
19
+ string,
20
+ unknown
21
+ >
22
+ const admission = admitCanonicalSchemaFromSdk(sdk, candidate)
23
+ const projected = projectCanonicalSchema(admission.root, admission.closure)
116
24
  process.stdout.write(
117
25
  JSON.stringify({
118
26
  ok: true,
119
- ir: normalizeLegacySchemaIR(ir),
120
- root: null,
121
- importedInterfaces,
27
+ ir: projected.ir,
28
+ root: admission.root,
29
+ schemaMode: admission.status === 'admitted' ? 'canonical-admitted' : 'canonical-preview',
30
+ revision: admission.revision,
122
31
  }),
123
32
  )
124
33
  }
125
34
 
126
- main().catch((err: any) => {
35
+ main().catch((cause: unknown) => {
36
+ const error = cause instanceof Error ? cause : new Error(String(cause))
127
37
  process.stdout.write(
128
- JSON.stringify({
129
- ok: false,
130
- error: { message: String(err?.message ?? err), stack: String(err?.stack ?? '') },
131
- }),
38
+ JSON.stringify({ ok: false, error: { message: error.message, stack: error.stack ?? '' } }),
132
39
  )
133
40
  process.exit(0)
134
41
  })
@@ -15,7 +15,10 @@ function sortKeys(v: any): any {
15
15
  return v
16
16
  }
17
17
 
18
- /** sha256 over canonical JSON, short-prefixed — the schemaHash (identifies a schema version). */
19
- export function schemaHashOf(value: unknown): string {
18
+ /**
19
+ * Short, deterministic identity for Studio rendering/cache invalidation only.
20
+ * This is deliberately not the DSL-owned `schema.revision()`.
21
+ */
22
+ export function renderFingerprintOf(value: unknown): string {
20
23
  return 'sha-' + createHash('sha256').update(canonicalJSON(value)).digest('hex').slice(0, 12)
21
24
  }