@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
@@ -1,9 +1,9 @@
1
- import { existsSync } from 'node:fs'
2
1
  import { join, relative } from 'node:path'
3
2
  import { Node, type SourceFile, SyntaxKind } from 'ts-morph'
4
3
 
5
4
  import type { ViewInfo } from '../../../../shared/types'
6
5
 
6
+ import { resolveApplicationEntry } from '../../../domain'
7
7
  import { defineSchemaCalls, schemaProject } from '../schema-definition'
8
8
  import {
9
9
  addSource,
@@ -44,27 +44,29 @@ export function buildSchemaViewSources(root: string, schemaDirName: string): Map
44
44
  return sources
45
45
  }
46
46
 
47
- function frontendKind(
48
- frontendName: string,
49
- input: Node,
50
- source: SourceFile,
51
- ): { kind: ViewInfo['kind']; external: boolean } {
52
- if (frontendName === 'reactFrontend') return { kind: 'spa', external: false }
53
- const sourceName = callName(objectProperty(input, 'source', source))
54
- if (sourceName === 'generatedFrontend') return { kind: 'inline-html', external: false }
55
- if (sourceName === 'viteFrontend' || sourceName === 'prebuiltFrontend') {
56
- return { kind: 'spa', external: false }
57
- }
58
- if (sourceName === 'externalFrontend') return { kind: 'spa', external: true }
59
- return { kind: 'unknown', external: false }
47
+ function defaultRoute(name: string): string {
48
+ return `/${name
49
+ .replace(/([a-z0-9])([A-Z])/gu, '$1-$2')
50
+ .replace(/[_\s]+/gu, '-')
51
+ .toLowerCase()}`
52
+ }
53
+
54
+ function frontendSource(input: Node, source: SourceFile): { externalOrigin?: string } {
55
+ const value = objectProperty(input, 'source', source)
56
+ if (!value || !Node.isCallExpression(value)) return {}
57
+ if (callName(value) !== 'external') return {}
58
+ const origin = literalString(value.getArguments()[0], source)
59
+ return origin === undefined ? {} : { externalOrigin: origin }
60
60
  }
61
61
 
62
- export function buildFrontendViews(root: string): ViewInfo[] {
62
+ export function buildFrontendViews(
63
+ root: string,
64
+ canonicalViewNames: readonly string[],
65
+ ): ViewInfo[] {
63
66
  const project = makeProject()
64
- const compositionFiles = ['implementation.ts', 'domain.ts']
65
- .map((file) => join(root, file))
66
- .filter((file) => existsSync(file))
67
- const sources = [...new Set([...listSourceFiles(join(root, 'views')), ...compositionFiles])]
67
+ const application = resolveApplicationEntry(root)
68
+ const applicationFiles = application === null ? [] : [application]
69
+ const sources = [...new Set([...listSourceFiles(join(root, 'views')), ...applicationFiles])]
68
70
  .map((file) => addSource(project, file))
69
71
  .filter((source): source is SourceFile => source !== null)
70
72
  const views: ViewInfo[] = []
@@ -72,30 +74,37 @@ export function buildFrontendViews(root: string): ViewInfo[] {
72
74
  for (const source of sources) {
73
75
  for (const call of source.getDescendantsOfKind(SyntaxKind.CallExpression)) {
74
76
  const frontendName = callName(call)
75
- if (frontendName !== 'frontendArtifact' && frontendName !== 'reactFrontend') continue
77
+ if (frontendName !== 'defineFrontend') continue
76
78
  const input = objectValue(call.getArguments()[0], source)
77
79
  if (!input) continue
78
80
  const routes = objectValue(objectProperty(input, 'routes', source) ?? undefined, source)
79
- if (!routes || !Node.isObjectLiteralExpression(routes)) continue
80
- const artifact = frontendKind(frontendName, input, source)
81
-
82
- for (const property of routes.getProperties()) {
83
- const slug = propertySlug(property)
84
- const routeValue = propertyValue(property, source)
85
- if (!slug || !routeValue) continue
86
- const routeName = callName(routeValue)
87
- const routeInput = Node.isCallExpression(routeValue)
88
- ? objectValue(routeValue.getArguments()[0], source)
89
- : objectValue(routeValue, source)
90
- if (!routeInput) continue
81
+ const declared = new Map<string, string>()
82
+ if (routes && Node.isObjectLiteralExpression(routes)) {
83
+ for (const property of routes.getProperties()) {
84
+ const slug = propertySlug(property)
85
+ const routeValue = propertyValue(property, source)
86
+ if (!slug || !routeValue) continue
87
+ const direct = literalString(routeValue, source)
88
+ const routeInput = objectValue(routeValue, source)
89
+ const path =
90
+ direct ??
91
+ (routeInput
92
+ ? literalString(objectProperty(routeInput, 'path', source) ?? undefined, source)
93
+ : undefined)
94
+ if (path) declared.set(slug, path)
95
+ }
96
+ }
97
+ const frontend = frontendSource(input, source)
91
98
 
92
- const path = literalString(objectProperty(routeInput, 'path', source) ?? undefined, source)
93
- const href = literalString(objectProperty(routeInput, 'href', source) ?? undefined, source)
99
+ for (const slug of canonicalViewNames) {
100
+ const path = declared.get(slug) ?? defaultRoute(slug)
101
+ const url = frontend.externalOrigin
102
+ ? new URL(path, `${frontend.externalOrigin}/`).toString()
103
+ : undefined
94
104
  views.push({
95
105
  slug,
96
- kind: routeName === 'reactRoute' ? 'spa' : artifact.kind,
97
- ...(href ? { url: href } : { url: undefined }),
98
- ...(!href && (path || !artifact.external) ? { mount: path ?? `/ui/${slug}` } : {}),
106
+ kind: 'spa',
107
+ ...(url ? { url } : { mount: path }),
99
108
  file: relative(root, source.getFilePath()).replaceAll('\\', '/'),
100
109
  })
101
110
  }
@@ -1,6 +1,5 @@
1
1
  import type { SchemaIR, ViewInfo } from '../../../shared/types'
2
2
 
3
- import { buildLegacyViews } from './views/legacy'
4
3
  import { buildFrontendViews, buildSchemaViewSources } from './views/routes'
5
4
 
6
5
  function mergeRoute(target: ViewInfo, incoming: ViewInfo): void {
@@ -16,7 +15,6 @@ function canonicalViewInfo(slug: string, view: NonNullable<SchemaIR['views']>[st
16
15
  return {
17
16
  slug,
18
17
  kind: 'unknown',
19
- auth: view.auth,
20
18
  ...(view.description ? { description: view.description } : {}),
21
19
  ...(targets.length === 1
22
20
  ? { viewFor: targets[0] }
@@ -29,8 +27,8 @@ function canonicalViewInfo(slug: string, view: NonNullable<SchemaIR['views']>[st
29
27
  /**
30
28
  * Join canonical View definitions with route/source metadata. Passing a
31
29
  * canonical map (including an empty map) makes it authoritative: static routes
32
- * cannot invent Views or override identity, target, auth, or description.
33
- * Without it, the legacy defineView registry remains the compatibility source.
30
+ * cannot invent Views or override identity, target, or description.
31
+ * Without admitted canonical Views, Studio does not invent authoring semantics.
34
32
  */
35
33
  export function buildViews(
36
34
  root: string,
@@ -38,21 +36,17 @@ export function buildViews(
38
36
  canonicalViews?: NonNullable<SchemaIR['views']>,
39
37
  ): ViewInfo[] {
40
38
  const merged = new Map<string, ViewInfo>()
41
- if (canonicalViews !== undefined) {
42
- for (const [slug, view] of Object.entries(canonicalViews)) {
43
- merged.set(slug, canonicalViewInfo(slug, view))
44
- }
45
- for (const [slug, file] of buildSchemaViewSources(root, _schemaDirName)) {
46
- const current = merged.get(slug)
47
- if (current) current.file = file
48
- }
49
- } else {
50
- for (const view of buildLegacyViews(root)) merged.set(view.slug, view)
39
+ const admittedViews = canonicalViews ?? {}
40
+ for (const [slug, view] of Object.entries(admittedViews)) {
41
+ merged.set(slug, canonicalViewInfo(slug, view))
51
42
  }
52
- for (const view of buildFrontendViews(root)) {
43
+ for (const [slug, file] of buildSchemaViewSources(root, _schemaDirName)) {
44
+ const current = merged.get(slug)
45
+ if (current) current.file = file
46
+ }
47
+ for (const view of buildFrontendViews(root, Object.keys(admittedViews))) {
53
48
  const current = merged.get(view.slug)
54
49
  if (current) mergeRoute(current, view)
55
- else if (canonicalViews === undefined) merged.set(view.slug, view)
56
50
  }
57
51
  return [...merged.values()]
58
52
  }
@@ -46,7 +46,7 @@ test('reads the discovered client directory', () => {
46
46
  })
47
47
  })
48
48
 
49
- test('resolves views declared in the registry file itself', () => {
49
+ test('does not treat a removed view registry as Schema authority', () => {
50
50
  const root = mkdtempSync(join(tmpdir(), 'studio-inline-view-registry-'))
51
51
  roots.push(root)
52
52
  const viewsDir = join(root, 'views')
@@ -55,12 +55,10 @@ test('resolves views declared in the registry file itself', () => {
55
55
  join(viewsDir, 'index.ts'),
56
56
  `import { defineView } from '@astrale-os/sdk'
57
57
  const services = defineView({
58
- auth: 'required',
59
58
  mount: '/ui/services',
60
59
  description: 'Browse services.',
61
60
  })
62
61
  const service = defineView({
63
- auth: 'required',
64
62
  mount: '/ui/service',
65
63
  viewFor: [selfOf(CloudflareWorker)],
66
64
  })
@@ -68,29 +66,10 @@ export const views = { services, service }
68
66
  `,
69
67
  )
70
68
 
71
- expect(buildViews(root)).toEqual([
72
- {
73
- slug: 'services',
74
- kind: 'spa',
75
- url: undefined,
76
- file: 'views/index.ts',
77
- auth: 'required',
78
- mount: '/ui/services',
79
- description: 'Browse services.',
80
- },
81
- {
82
- slug: 'service',
83
- kind: 'spa',
84
- url: undefined,
85
- file: 'views/index.ts',
86
- auth: 'required',
87
- mount: '/ui/service',
88
- viewFor: 'CloudflareWorker',
89
- },
90
- ])
69
+ expect(buildViews(root)).toEqual([])
91
70
  })
92
71
 
93
- test('joins canonical Bundle Views with reactFrontend route metadata', () => {
72
+ test('joins canonical Bundle Views with defineFrontend route metadata', () => {
94
73
  const root = mkdtempSync(join(tmpdir(), 'studio-current-react-view-'))
95
74
  roots.push(root)
96
75
  mkdirSync(join(root, 'schema', 'application'), { recursive: true })
@@ -108,7 +87,6 @@ const schemaInput = {
108
87
  views: {
109
88
  issue: view({
110
89
  target: [Issue, Group],
111
- auth: 'optional',
112
90
  description: 'Inspect an issue.',
113
91
  }),
114
92
  },
@@ -118,11 +96,13 @@ export const schema = defineSchema(ORIGIN, schemaInput)
118
96
  )
119
97
  writeFileSync(
120
98
  join(root, 'views', 'routes.ts'),
121
- `import { reactFrontend, reactRoute } from '@astrale-os/sdk/react'
122
- const routes = {
123
- issue: reactRoute({ path: '/ui/issues/:id', component: { module: './views/issue.tsx' } }),
124
- }
125
- export const frontend = reactFrontend({ schema, routes, entrypoint: 'issue' })
99
+ `import { defineFrontend, vite } from '@astrale-os/sdk/application'
100
+ export const frontend = defineFrontend({
101
+ schema,
102
+ source: vite(),
103
+ routes: { issue: '/ui/issues/:id' },
104
+ entrypoint: 'issue',
105
+ })
126
106
  `,
127
107
  )
128
108
 
@@ -131,13 +111,12 @@ export const frontend = reactFrontend({ schema, routes, entrypoint: 'issue' })
131
111
  buildViews(root, 'schema', {
132
112
  issue: {
133
113
  name: 'issue',
134
- auth: 'optional',
135
114
  description: 'Inspect an issue.',
136
115
  target: {
137
116
  kind: 'definition',
138
117
  definitions: [
139
118
  { origin: 'issues.example.dev', kind: 'class', name: 'Issue' },
140
- { origin: 'accounts.example.dev', kind: 'interface', name: 'Group' },
119
+ { origin: 'accounts.example.dev', kind: 'class', name: 'Group' },
141
120
  ],
142
121
  },
143
122
  },
@@ -146,7 +125,6 @@ export const frontend = reactFrontend({ schema, routes, entrypoint: 'issue' })
146
125
  {
147
126
  slug: 'issue',
148
127
  kind: 'spa',
149
- auth: 'optional',
150
128
  mount: '/ui/issues/:id',
151
129
  url: undefined,
152
130
  viewFor: ['Issue', 'Group'],
@@ -156,7 +134,7 @@ export const frontend = reactFrontend({ schema, routes, entrypoint: 'issue' })
156
134
  ])
157
135
  })
158
136
 
159
- test('discovers generated frontend routes without deriving canonical View defaults', () => {
137
+ test('discovers Vite frontend default routes from canonical View names', () => {
160
138
  const root = mkdtempSync(join(tmpdir(), 'studio-current-generated-view-'))
161
139
  roots.push(root)
162
140
  mkdirSync(join(root, 'schema'), { recursive: true })
@@ -170,11 +148,10 @@ test('discovers generated frontend routes without deriving canonical View defaul
170
148
  )
171
149
  writeFileSync(
172
150
  join(root, 'views', 'summary', 'index.ts'),
173
- `const source = generatedFrontend({ files: [{ path: 'index.html', content: '<h1>Hi</h1>' }] })
174
- export const frontend = frontendArtifact({
151
+ `const source = vite()
152
+ export const frontend = defineFrontend({
175
153
  schema,
176
154
  source,
177
- routes: { summary: frontendRoute({}) },
178
155
  entrypoint: 'summary',
179
156
  })
180
157
  `,
@@ -184,16 +161,14 @@ export const frontend = frontendArtifact({
184
161
  buildViews(root, 'schema', {
185
162
  summary: {
186
163
  name: 'summary',
187
- auth: 'required',
188
164
  target: { kind: 'domain' },
189
165
  },
190
166
  }),
191
167
  ).toEqual([
192
168
  {
193
169
  slug: 'summary',
194
- kind: 'inline-html',
195
- auth: 'required',
196
- mount: '/ui/summary',
170
+ kind: 'spa',
171
+ mount: '/summary',
197
172
  url: undefined,
198
173
  file: 'views/summary/index.ts',
199
174
  },
@@ -208,19 +183,20 @@ test('canonical Bundle views reject static schema and route-only identities', ()
208
183
  join(root, 'schema', 'index.ts'),
209
184
  `export const schema = defineSchema('static.invalid', {
210
185
  views: {
211
- account: view({ target: WrongTarget, auth: 'public', description: 'Static guess.' }),
212
- sourceOnly: view({ target: WrongTarget, auth: 'public', description: 'Static guess.' }),
213
- invented: view({ target: 'domain', auth: 'public' }),
186
+ account: view({ target: WrongTarget, description: 'Static guess.' }),
187
+ sourceOnly: view({ target: WrongTarget, description: 'Static guess.' }),
188
+ invented: view({ target: 'domain' }),
214
189
  },
215
190
  })`,
216
191
  )
217
192
  writeFileSync(
218
- join(root, 'implementation.ts'),
219
- `export const frontend = frontendArtifact({
220
- source: externalFrontend({ href: 'https://shell.example.dev' }),
193
+ join(root, 'application.ts'),
194
+ `export const frontend = defineFrontend({
195
+ schema,
196
+ source: external('https://shell.example.dev'),
221
197
  routes: {
222
- account: frontendRoute({ href: 'https://shell.example.dev/account' }),
223
- routeOnly: frontendRoute({ href: 'https://shell.example.dev/route-only' }),
198
+ account: '/account',
199
+ routeOnly: '/route-only',
224
200
  },
225
201
  })`,
226
202
  )
@@ -229,7 +205,6 @@ test('canonical Bundle views reject static schema and route-only identities', ()
229
205
  buildViews(root, 'schema', {
230
206
  account: {
231
207
  name: 'account',
232
- auth: 'required',
233
208
  description: 'Admitted account view.',
234
209
  target: {
235
210
  kind: 'definition',
@@ -238,7 +213,6 @@ test('canonical Bundle views reject static schema and route-only identities', ()
238
213
  },
239
214
  sourceOnly: {
240
215
  name: 'sourceOnly',
241
- auth: 'optional',
242
216
  description: 'Admitted source-only view.',
243
217
  target: { kind: 'domain' },
244
218
  },
@@ -247,18 +221,17 @@ test('canonical Bundle views reject static schema and route-only identities', ()
247
221
  {
248
222
  slug: 'account',
249
223
  kind: 'spa',
250
- auth: 'required',
251
224
  description: 'Admitted account view.',
252
225
  viewFor: 'Account',
253
226
  url: 'https://shell.example.dev/account',
254
- file: 'implementation.ts',
227
+ file: 'application.ts',
255
228
  },
256
229
  {
257
230
  slug: 'sourceOnly',
258
- kind: 'unknown',
259
- auth: 'optional',
231
+ kind: 'spa',
260
232
  description: 'Admitted source-only view.',
261
- file: 'schema/index.ts',
233
+ url: 'https://shell.example.dev/source-only',
234
+ file: 'application.ts',
262
235
  },
263
236
  ])
264
237
  expect(buildViews(root, 'schema', {})).toEqual([])
@@ -6,28 +6,36 @@ import { join } from 'node:path'
6
6
  import { buildAnatomy } from './anatomy'
7
7
 
8
8
  const roots: string[] = []
9
-
10
9
  afterEach(() => {
11
10
  for (const root of roots.splice(0)) rmSync(root, { recursive: true, force: true })
12
11
  })
13
12
 
14
- function project(entry: 'implementation.ts' | 'domain.ts') {
15
- const root = mkdtempSync(join(tmpdir(), 'studio-anatomy-entry-'))
13
+ function project(nested: boolean) {
14
+ const root = mkdtempSync(join(tmpdir(), 'studio-anatomy-application-'))
16
15
  roots.push(root)
17
- mkdirSync(join(root, 'schema'), { recursive: true })
16
+ const owner = nested ? join(root, 'domain') : root
17
+ mkdirSync(join(owner, 'schema'), { recursive: true })
18
18
  writeFileSync(join(root, 'package.json'), '{}\n')
19
- writeFileSync(join(root, 'astrale.config.ts'), 'export default {}\n')
20
- writeFileSync(join(root, entry), 'export const domain = {}\n')
21
- writeFileSync(join(root, 'schema/index.ts'), "defineSchema('example.astrale.ai', {})\n")
22
- return root
19
+ writeFileSync(
20
+ join(root, 'astrale.config.ts'),
21
+ nested
22
+ ? "import application from './domain/application.js'\nexport default { application }\n"
23
+ : 'export default {}\n',
24
+ )
25
+ writeFileSync(join(owner, 'application.ts'), 'export const application = {}\n')
26
+ writeFileSync(
27
+ join(owner, 'schema/index.ts'),
28
+ "defineSchema('example.astrale.ai', { classes: {} })\n",
29
+ )
30
+ return { root, schemaDirName: nested ? 'domain/schema' : 'schema' }
23
31
  }
24
32
 
25
- test('overview anchors current projects to implementation.ts', () => {
26
- const anatomy = buildAnatomy({ root: project('implementation.ts'), schemaDirName: 'schema' })
27
- expect(anatomy.overview.compositionFile).toBe('implementation.ts')
33
+ test('overview anchors a root Application', () => {
34
+ const input = project(false)
35
+ expect(buildAnatomy(input).overview.applicationFile).toBe('application.ts')
28
36
  })
29
37
 
30
- test('overview preserves domain.ts as the legacy composition entry', () => {
31
- const anatomy = buildAnatomy({ root: project('domain.ts'), schemaDirName: 'schema' })
32
- expect(anatomy.overview.compositionFile).toBe('domain.ts')
38
+ test('overview preserves the config-imported nested Application path', () => {
39
+ const input = project(true)
40
+ expect(buildAnatomy(input).overview.applicationFile).toBe('domain/application.ts')
33
41
  })
@@ -12,6 +12,7 @@ import { join, relative } from 'node:path'
12
12
 
13
13
  import type { DomainAnatomy, DomainOverview, SchemaIR } from '../../shared/types'
14
14
 
15
+ import { resolveApplicationEntry } from '../domain'
15
16
  import { asJsonRecord, asString, parseJson } from '../json'
16
17
  import { readSettings } from '../state/settings'
17
18
  import { buildClientTree, buildEnvFields, buildViews, findSchemaDefinition } from './anatomy-extras'
@@ -59,15 +60,11 @@ function buildOverview(
59
60
 
60
61
  const config = readConfigPreview(root)
61
62
 
62
- const compositionFile = existsSync(join(root, 'implementation.ts'))
63
- ? 'implementation.ts'
64
- : existsSync(join(root, 'domain.ts'))
65
- ? 'domain.ts'
66
- : undefined
67
- const domainSrc = compositionFile ? readTextSafe(join(root, compositionFile)) : ''
63
+ const application = resolveApplicationEntry(root)
64
+ const applicationSrc = application === null ? '' : readTextSafe(application)
68
65
  const origin =
69
66
  schemaOrigin ??
70
- domainSrc.match(/defineSchema\(\s*['"]([^'"]+)['"]/)?.[1] ??
67
+ applicationSrc.match(/defineSchema\(\s*['"]([^'"]+)['"]/)?.[1] ??
71
68
  readTextSafe(join(root, schemaDirName, 'index.ts')).match(
72
69
  /defineSchema\(\s*['"]([^'"]+)['"]/,
73
70
  )?.[1] ??
@@ -75,11 +72,11 @@ function buildOverview(
75
72
 
76
73
  return {
77
74
  origin,
78
- compositionFile,
75
+ applicationFile:
76
+ application === null ? undefined : relative(root, application).replaceAll('\\', '/'),
79
77
  adapter: config.adapter,
80
78
  prodTarget: config.prodTarget,
81
79
  devSecrets: config.devSecrets,
82
- postInstall: undefined,
83
80
  requires: [],
84
81
  packageName: pkg?.name,
85
82
  packageVersion: pkg?.version,
@@ -18,7 +18,6 @@ export async function buildBundle(handle: DomainHandle): Promise<StudioSchemaBun
18
18
  let schemaRoot: unknown | undefined
19
19
  let schemaMode: StudioSchemaBundle['schemaMode'] = 'unavailable'
20
20
  let schemaRevision: StudioSchemaBundle['schemaRevision']
21
- let importedInterfaces: StudioSchemaBundle['importedInterfaces']
22
21
  let error: StudioSchemaBundle['error'] = null
23
22
  let extractedBy: StudioSchemaBundle['extractedBy'] = 'runtime-bun'
24
23
 
@@ -33,7 +32,6 @@ export async function buildBundle(handle: DomainHandle): Promise<StudioSchemaBun
33
32
  if (r.root !== null) schemaRoot = r.root
34
33
  schemaMode = r.schemaMode
35
34
  if (r.revision !== null) schemaRevision = r.revision
36
- importedInterfaces = r.importedInterfaces
37
35
  } else {
38
36
  error = { message: r.error?.message ?? 'schema failed to compile' }
39
37
  extractedBy = 'static-tsmorph-fallback'
@@ -65,7 +63,6 @@ export async function buildBundle(handle: DomainHandle): Promise<StudioSchemaBun
65
63
  ir,
66
64
  ...(schemaRoot === undefined ? {} : { schemaRoot }),
67
65
  overlay,
68
- importedInterfaces,
69
66
  error,
70
67
  extractedAt: new Date().toISOString(),
71
68
  }