@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
@@ -6,6 +6,7 @@ import type { CommandDefinition } from '../../program/index'
6
6
 
7
7
  import { listAdminDomains, type DomainInfo } from '../../lib/admin-domain'
8
8
  import { ADMIN_TARGET_OPTIONS, type AdminTargetCommandOpts } from '../../lib/admin-target'
9
+ import { fetchDomainPublication } from '../../lib/domain-publication'
9
10
  import { fatal, withSpinner } from '../../lib/log'
10
11
  import { isMachine, presentList } from '../../lib/output'
11
12
 
@@ -23,7 +24,7 @@ type ListOpts = KernelCommandOpts &
23
24
  /** A catalog entry, optionally enriched with a live `--check` probe. */
24
25
  export type DomainRow = DomainInfo & {
25
26
  reachable?: boolean
26
- schemaHash?: string
27
+ schemaRevision?: string
27
28
  checkError?: string | null
28
29
  }
29
30
 
@@ -72,9 +73,9 @@ Behavior:
72
73
  or with --json/--raw (agent-friendly — full DomainInfo objects). -q prints
73
74
  one install URL per line (pipeable into \`domain install\`); --count prints
74
75
  only the number. --default-only keeps the install-by-default entries (what
75
- every new instance gets via alphaCreate). --check probes each published URL's
76
- /meta and adds a live/unreachable STATUS column (+ reachable/schemaHash in
77
- machine output).
76
+ every new instance receives during Admin-managed provisioning). --check probes each published URL's
77
+ canonical Publication and adds a live/unreachable STATUS column
78
+ (+ reachable/schemaRevision in machine output).
78
79
 
79
80
  The admin kernel is selected like every admin op — the configured default,
80
81
  or --admin <bookmark> / --admin-url <url>.
@@ -87,7 +88,10 @@ Examples:
87
88
  `,
88
89
  options: [
89
90
  ...ADMIN_TARGET_OPTIONS,
90
- { flags: '--check', description: "Probe each domain's URL for reachability + schema hash" },
91
+ {
92
+ flags: '--check',
93
+ description: "Probe each domain's canonical Publication + schema revision",
94
+ },
91
95
  { flags: '--default-only', description: 'Only show install-by-default domains' },
92
96
  { flags: '-q, --quiet', description: 'One install URL per line (unix-pipeable)' },
93
97
  { flags: '--count', description: 'Print only the number of published domains' },
@@ -103,7 +107,7 @@ Examples:
103
107
  const filtered = opts.defaultOnly ? list.filter((d) => d.installByDefault) : list
104
108
  filtered.sort(byDefaultThenName)
105
109
  if (!opts.check) return filtered as DomainRow[]
106
- // Reachability is a direct client-side /meta fetch per entry, in
110
+ // Reachability is a direct client-side Publication fetch per entry, in
107
111
  // parallel — no admin round-trip, and version-independent of the
108
112
  // admin worker (mirrors `domain install`'s probeDeclaredOrigin).
109
113
  return Promise.all(filtered.map(probe))
@@ -129,19 +133,20 @@ export function byDefaultThenName(a: DomainInfo, b: DomainInfo): number {
129
133
 
130
134
  /**
131
135
  * Enrich one entry with a reachability probe: fetch the published worker's
132
- * `/meta` (the same endpoint the admin `DomainEntry.check` hits) and read its
133
- * schema hash. A dead / missing url is itself a result, not a throw.
136
+ * canonical Publication and read its schema revision. A dead or missing URL is
137
+ * itself a result, not a throw.
134
138
  */
135
- async function probe(d: DomainInfo): Promise<DomainRow> {
139
+ export async function probe(d: DomainInfo): Promise<DomainRow> {
136
140
  if (!d.url) return { ...d, reachable: false, checkError: 'no url published' }
137
141
  try {
138
- const res = await fetch(new URL('/meta', d.url), { signal: AbortSignal.timeout(10_000) })
139
- if (!res.ok) return { ...d, reachable: false, checkError: `meta HTTP ${res.status}` }
140
- const meta = (await res.json()) as { schemaHash?: unknown }
142
+ const deployed = await fetchDomainPublication(d.url, AbortSignal.timeout(10_000))
143
+ if (deployed.origin !== d.origin) {
144
+ throw new Error(`Domain origin mismatch: deployed=${deployed.origin} expected=${d.origin}`)
145
+ }
141
146
  return {
142
147
  ...d,
143
148
  reachable: true,
144
- ...(typeof meta.schemaHash === 'string' ? { schemaHash: meta.schemaHash } : {}),
149
+ schemaRevision: deployed.schema.revision,
145
150
  checkError: null,
146
151
  }
147
152
  } catch (err) {
@@ -3,9 +3,11 @@ import chalk from 'chalk'
3
3
  import type { KernelCommandOpts } from '../../connection'
4
4
  import type { CommandDefinition } from '../../program/index'
5
5
 
6
+ import { formatKernelError } from '../../connection/errors'
6
7
  import { publishAdminDomain } from '../../lib/admin-domain'
7
8
  import { ADMIN_TARGET_OPTIONS, type AdminTargetCommandOpts } from '../../lib/admin-target'
8
- import { fatal, withSpinner } from '../../lib/log'
9
+ import { domainPublicationUrl } from '../../lib/domain-publication'
10
+ import { withSpinner } from '../../lib/log'
9
11
  import { isMachine, output } from '../../lib/output'
10
12
  import { promptText } from '../../lib/prompt'
11
13
  import { isHttpUrl, validateName, validateUrl } from '../../lib/validation'
@@ -48,9 +50,9 @@ Behavior:
48
50
 
49
51
  Publishing only makes the domain INSTALLABLE. Mount it on an instance with
50
52
  \`astrale domain install <url>\` (or rely on the admin's install-by-default
51
- policy). This is usually invoked for you by \`astrale-domain publish\` (which
52
- registers the already-deployed URL it does NOT deploy) or by
53
- \`astrale-domain deploy --publish\` (deploy AND register in one step).
53
+ policy). Deployment and catalog publication are separate owners: run the
54
+ project's \`astrale-domain deploy <environment>\`, then publish its observed
55
+ public URL with this command.
54
56
 
55
57
  Run in a terminal with flags omitted and it PROMPTS for origin / name /
56
58
  public-url (origin defaults to the URL host, name to the origin's first
@@ -68,17 +70,16 @@ Examples:
68
70
  { flags: '--description <text>', description: 'Optional human description for the catalog' },
69
71
  {
70
72
  flags: '--install-by-default',
71
- description: 'Mark the domain for install on every new instance (alphaCreate)',
73
+ description: 'Mark the domain for install on every new instance',
72
74
  },
73
75
  ],
74
76
  // No positional arguments → Commander passes (opts, command); `opts` is first.
75
77
  action: async (opts: PublishOpts) => {
76
78
  try {
77
79
  // Interactive fill (TTY only): a human running this by hand is prompted for
78
- // any missing field. The primary caller `astrale-domain publish` always
79
- // passes every flag, so it never prompts. No TTY / --ci / --no-prompt / CI
80
- // env no prompt: fall straight through to the required-flag error below,
81
- // so a piped / agent / LLM run fails fast instead of hanging on a read.
80
+ // any missing field. Automation passes every flag. No TTY / --ci /
81
+ // --no-prompt / CI env means no prompt: fall straight through to the
82
+ // required-flag error below so a piped or agent run fails fast.
82
83
  const interactive = !!process.stdin.isTTY && !(opts.ci || opts.noPrompt || process.env.CI)
83
84
  let { origin, name, publicUrl } = opts
84
85
  if (interactive) {
@@ -102,6 +103,7 @@ Examples:
102
103
  validateName(origin, 'origin')
103
104
  validateName(name, 'domain')
104
105
  validateUrl(publicUrl)
106
+ const discoveryUrl = domainPublicationUrl(publicUrl).href
105
107
 
106
108
  const result = await withSpinner(
107
109
  `Publishing ${name} → ${publicUrl}`,
@@ -110,7 +112,7 @@ Examples:
110
112
  publishAdminDomain(opts, {
111
113
  origin,
112
114
  name,
113
- url: publicUrl,
115
+ url: discoveryUrl,
114
116
  ...(opts.description ? { description: opts.description } : {}),
115
117
  ...(opts.installByDefault ? { installByDefault: true } : {}),
116
118
  }),
@@ -127,7 +129,8 @@ Examples:
127
129
  return
128
130
  }
129
131
  } catch (e) {
130
- fatal(e)
132
+ await formatKernelError(e, isMachine(opts), undefined, opts.debug)
133
+ process.exit(1)
131
134
  }
132
135
  },
133
136
  } satisfies CommandDefinition
@@ -1,5 +1,5 @@
1
1
  import { Path } from '@astrale-os/sdk/graph/path'
2
- import { syscalls } from '@astrale-os/sdk/schema/kernel'
2
+ import { K } from '@astrale-os/sdk/schema'
3
3
  import chalk from 'chalk'
4
4
 
5
5
  import type { KernelCommandOpts } from '../../connection'
@@ -77,7 +77,7 @@ Examples:
77
77
  label: `Uninstalling domain ${origin}`,
78
78
  fn: async ({ session }) =>
79
79
  (await session.call(
80
- createPathCall(Path.project(syscalls.uninstall.ref).raw, uninstallCallInput(origin)),
80
+ createPathCall(Path.project(K.functions.uninstall.ref).raw, uninstallCallInput(origin)),
81
81
  )) as UninstallResult,
82
82
  format: (result, formatOpts, machine) => {
83
83
  if (machine) {
@@ -4,40 +4,39 @@ import type { KernelCommandOpts } from '../connection'
4
4
  import type { CommandDefinition } from '../program/index'
5
5
 
6
6
  import { expandSelfInPath, runKernelCommand, withSelfHint } from '../connection'
7
- import { formatKernelError } from '../connection/errors'
8
7
  import { AstraleError } from '../errors'
9
- import { denoise, isMachine, output } from '../lib/output'
8
+ import { failInput, fatal } from '../lib/log'
9
+ import { denoise, output } from '../lib/output'
10
10
 
11
11
  type GetOpts = KernelCommandOpts & { schema?: boolean }
12
12
 
13
13
  /** Read one exact canonical Node. The caller's Path is not fabricated into the Node value. */
14
14
  export async function getCommand(target: string, opts: GetOpts): Promise<void> {
15
- let path: string
16
- let meta
17
15
  let parsed
18
16
  try {
19
- ;({ path, meta } = await expandSelfInPath(target, opts))
20
- parsed = Path.parse(path)
17
+ parsed = Path.parse(target)
21
18
  } catch (error) {
22
- await formatKernelError(error, isMachine(opts), undefined, opts.debug)
23
- process.exit(1)
19
+ failInput(error, opts)
24
20
  }
25
21
 
26
22
  const last = parsed.ast.steps.at(-1)
27
23
  if (last?.kind === 'method') {
28
24
  const error = new AstraleError(
29
25
  'NOT_A_NODE',
30
- `${path} is a callable Path, not a Node.`,
31
- `Use \`astrale call ${path}\` or \`astrale introspect ${path}\`.`,
26
+ `${target} is a callable Path, not a Node.`,
27
+ `Use \`astrale call ${target}\` or \`astrale introspect ${target}\`.`,
32
28
  )
33
- await formatKernelError(error, isMachine(opts), undefined, opts.debug)
34
- process.exit(1)
29
+ fatal(error, opts)
35
30
  }
36
31
 
37
32
  await runKernelCommand({
38
33
  opts,
39
- label: `Node ${path}`,
40
- fn: ({ graph }) => withSelfHint(() => graph.getOrThrow(parsed), meta),
34
+ label: `Node ${target}`,
35
+ fn: async (context) => {
36
+ const { path, meta } = await expandSelfInPath(target, context)
37
+ const resolved = meta === undefined ? parsed : Path.parse(path)
38
+ return withSelfHint(() => context.graph.getOrThrow(resolved), meta)
39
+ },
41
40
  format: (node, format) => output(opts.schema === true ? node : denoise(node), format),
42
41
  })
43
42
  }
@@ -60,7 +59,7 @@ Examples:
60
59
  $ astrale get /:notes.example.dev:class.Note
61
60
  $ astrale get @abc123 --json
62
61
  $ astrale get @self
63
- $ astrale get /:host.astrale.ai --schema
62
+ $ astrale get /:kernel.astrale.ai --schema
64
63
  `,
65
64
  arguments: [{ name: 'target', description: 'Canonical Node Path or @id' }],
66
65
  options: [{ flags: '--schema', description: 'Include schema-valued properties' }],
@@ -1,9 +1,9 @@
1
1
  import { issuer, jwk, provision } from '@astrale-os/sdk/auth'
2
- import { ClassPath } from '@astrale-os/sdk/graph/class'
3
2
  import { normalizeProperties } from '@astrale-os/sdk/graph/properties'
4
3
  import { expect, mock, test } from 'bun:test'
5
4
  import { exportJWK, generateKeyPair, jwtVerify } from 'jose'
6
5
 
6
+ import { classKey } from '../../../graph'
7
7
  import { formatIdentityRegistration, prepareIdentityProvision } from '../register'
8
8
 
9
9
  /** @evidence TEST-CLI-IDENTITY-REGISTER-JSON-EXACT */
@@ -46,7 +46,7 @@ test('builds one exact Mutation V3 identity birth bound to a self proof', async
46
46
  kid: 'alice-key',
47
47
  })
48
48
  const kernelIssuer = issuer.accept('https://kernel.example')
49
- const classPath = ClassPath.parse('/:accounts.example:class.User')
49
+ const classPath = classKey('/:accounts.example:class.User', '--class')
50
50
  const properties = normalizeProperties({
51
51
  'accounts.example:class.User.property.name': 'Alice',
52
52
  })
@@ -70,7 +70,7 @@ test('builds one exact Mutation V3 identity birth bound to a self proof', async
70
70
  {
71
71
  op: 'node.create',
72
72
  as: 'identity',
73
- class: '/:accounts.example:class.User',
73
+ class: 'accounts.example:class.User',
74
74
  props: { 'accounts.example:class.User.property.name': 'Alice' },
75
75
  },
76
76
  ],
@@ -1,9 +1,9 @@
1
1
  import type { IssuerId, JsonWebKey, ProvisionRequest } from '@astrale-os/sdk/auth'
2
+ import type { ClassKey as ClassKeyValue } from '@astrale-os/sdk/graph/class'
2
3
  import type { JWK } from 'jose'
3
4
 
4
5
  import { provision, jwk } from '@astrale-os/sdk/auth'
5
- import { ClassPath } from '@astrale-os/sdk/graph/class'
6
- import { LocalBinding } from '@astrale-os/sdk/graph/model'
6
+ import { LocalBinding } from '@astrale-os/sdk/graph'
7
7
  import { normalizeProperties } from '@astrale-os/sdk/graph/properties'
8
8
  import { MutationAST } from '@astrale-os/sdk/mutation'
9
9
  import { importJWK, SignJWT } from 'jose'
@@ -14,6 +14,7 @@ import type { IdentityRegistrationResult } from '../../identity/index'
14
14
  import type { CommandDefinition } from '../../program/index'
15
15
 
16
16
  import { registrationKeyForTarget, runKernelCommand } from '../../connection'
17
+ import { classKey } from '../../graph'
17
18
  import { getIdentity, setRegistration, submitIdentityProvision } from '../../identity/index'
18
19
  import { fileExists, keypairPaths } from '../../keys/index'
19
20
  import { fatal, log } from '../../lib/log'
@@ -83,7 +84,7 @@ Example:
83
84
 
84
85
  const privateKey = await readJwk(privatePath)
85
86
  const publicKey = jwk.acceptPublic(await readJwk(publicPath))
86
- const classPath = ClassPath.parse(opts.class)
87
+ const classPath = classKey(opts.class, '--class')
87
88
  const properties = normalizeProperties(opts.props ? JSON.parse(opts.props) : {})
88
89
 
89
90
  await runKernelCommand<IdentityRegistrationResult>({
@@ -142,7 +143,7 @@ export function formatIdentityRegistration(
142
143
  /** Build and self-prove one exact canonical provision request for the target Kernel. */
143
144
  export async function prepareIdentityProvision(input: {
144
145
  readonly name: string
145
- readonly classPath: ReturnType<typeof ClassPath.parse>
146
+ readonly classPath: ClassKeyValue
146
147
  readonly properties: ReturnType<typeof normalizeProperties>
147
148
  readonly privateKey: JWK
148
149
  readonly publicKey: JsonWebKey
@@ -1,15 +1,12 @@
1
1
  import type { CommandDefinition } from '../../program/index'
2
2
 
3
+ import { formatKernelError } from '../../connection/errors'
3
4
  import { ADMIN_TARGET_OPTIONS } from '../../lib/admin-target'
4
- import { fatal } from '../../lib/log'
5
5
  import { isMachine, output } from '../../lib/output'
6
6
  import { promptText } from '../../lib/prompt'
7
7
  import { provisionInstance, type ProvisionOpts } from '../../lib/provision-instance'
8
8
  import { validateSlug } from '../../lib/validation'
9
9
 
10
- // Re-exported for tests + `astrale setup`, which share the provisioning saga.
11
- export { assertAlphaCreateIdentity, parseEligibleHostIds } from '../../lib/provision-instance'
12
-
13
10
  /** inquirer `validate` for a slug: true when valid, else the human message. */
14
11
  function slugError(value: string): true | string {
15
12
  try {
@@ -22,12 +19,12 @@ function slugError(value: string): true | string {
22
19
 
23
20
  export default {
24
21
  name: 'create',
25
- description: 'Provision an alpha instance through the admin kernel (Instance.alphaCreate)',
22
+ description: 'Provision an instance through the Admin control plane',
26
23
  afterHelpText: `
27
24
  Behavior:
28
- Calls Instance.alphaCreate on the configured admin kernel. The caller must be
29
- logged in with WorkOS. When --host-id is omitted, the admin kernel chooses the
30
- caller's single eligible host. The new instance becomes the active instance.
25
+ Requests a new Instance from the configured Admin Domain. The caller must be
26
+ logged in with WorkOS. Admin owns infrastructure placement. The new instance
27
+ becomes the active instance.
31
28
 
32
29
  Run with no slug in a terminal and it prompts for one (validated live). With
33
30
  no TTY — or --ci / --no-prompt — the slug argument is required up front, so
@@ -38,13 +35,7 @@ Examples:
38
35
  $ astrale instance create demo
39
36
  `,
40
37
  arguments: [{ name: 'id', description: 'Instance slug', required: false }],
41
- options: [
42
- ...ADMIN_TARGET_OPTIONS,
43
- {
44
- flags: '--host-id <id>',
45
- description: 'Advanced: host node id to provision on when multiple hosts are available',
46
- },
47
- ],
38
+ options: [...ADMIN_TARGET_OPTIONS],
48
39
  action: async (id: string | undefined, opts: ProvisionOpts) => {
49
40
  try {
50
41
  // Interactive (TTY only): prompt for the slug when omitted, with live
@@ -63,7 +54,8 @@ Examples:
63
54
  return
64
55
  }
65
56
  } catch (e) {
66
- fatal(e, opts)
57
+ await formatKernelError(e, isMachine(opts), undefined, opts.debug)
58
+ process.exit(1)
67
59
  }
68
60
  },
69
61
  } satisfies CommandDefinition
@@ -1,10 +1,12 @@
1
1
  import type { KernelCommandOpts } from '../../connection'
2
2
  import type { CommandDefinition } from '../../program/index'
3
3
 
4
+ import { AdminInstanceNotFoundError } from '../../admin/instance'
5
+ import { formatKernelError } from '../../connection/errors'
4
6
  import { deleteOwnedInstance } from '../../lib/admin-instance'
5
7
  import { ADMIN_TARGET_OPTIONS, type AdminTargetCommandOpts } from '../../lib/admin-target'
6
8
  import { clearActive, readInstances, removeInstance, resolveInstanceKey } from '../../lib/instance'
7
- import { fatal, log, withSpinner } from '../../lib/log'
9
+ import { log, withSpinner } from '../../lib/log'
8
10
  import { isMachine, output } from '../../lib/output'
9
11
 
10
12
  type DeleteOpts = KernelCommandOpts &
@@ -18,10 +20,9 @@ export default {
18
20
  afterHelpText: `
19
21
  Behavior:
20
22
  Calls Instance.delete on the configured admin kernel: best-effort decommission
21
- of the instance's routing-registry entry + WorkOS org (frees the slug), then
22
- removes the Instance record. The host kernel itself is NOT deregistered (the
23
- deprovisioning saga is a follow-up). A same-name local bookmark is removed
24
- after the delete succeeds unless --keep-bookmark is passed.
23
+ of the instance's route and tenant reservation, then removes the Instance
24
+ projection. A same-name local bookmark is removed after the delete succeeds
25
+ unless --keep-bookmark is passed.
25
26
  `,
26
27
  arguments: [{ name: 'id', description: 'Instance slug', required: true }],
27
28
  options: [
@@ -53,14 +54,16 @@ Behavior:
53
54
  } catch (e) {
54
55
  // Bookmark-only id → no admin Instance → kernel NOT_FOUND. Point to
55
56
  // `forget` (local drop) instead of surfacing the raw path error.
56
- const notManaged =
57
- e instanceof Error && (e.name === 'NotFoundError' || e.message.startsWith('Path not found'))
58
- if (notManaged && resolveInstanceKey(await readInstances(), id)) {
57
+ if (
58
+ e instanceof AdminInstanceNotFoundError &&
59
+ resolveInstanceKey(await readInstances(), id)
60
+ ) {
59
61
  log.error(`No admin-managed instance "${id}".`)
60
62
  log.dim(` hint: it's a local bookmark — drop it with: astrale instance forget ${id}`)
61
63
  process.exit(1)
62
64
  }
63
- fatal(e, opts)
65
+ await formatKernelError(e, isMachine(opts), undefined, opts.debug)
66
+ process.exit(1)
64
67
  }
65
68
  },
66
69
  } satisfies CommandDefinition
@@ -7,7 +7,7 @@ import type { CommandDefinition } from '../../program/index'
7
7
  import { AstraleError } from '../../errors'
8
8
  import { listOwnedInstances } from '../../lib/admin-instance'
9
9
  import {
10
- formatInstanceLocation,
10
+ formatInstanceState,
11
11
  type InstanceInfo,
12
12
  type OwnedInstanceInfo,
13
13
  } from '../../lib/admin-instance'
@@ -136,7 +136,7 @@ export function buildInstanceRows(
136
136
  name: twin?.active ? `${item.slug} ${chalk.green('*')}` : item.slug,
137
137
  kind: 'managed',
138
138
  url: item.url ?? '',
139
- extra: [formatInstanceLocation(item), twin ? formatBookmarkConnection(twin) : '']
139
+ extra: [formatInstanceState(item), twin ? formatBookmarkConnection(twin) : '']
140
140
  .filter(Boolean)
141
141
  .join(' · '),
142
142
  })
@@ -3,44 +3,90 @@ import chalk from 'chalk'
3
3
  import type { KernelCommandOpts } from '../../connection'
4
4
  import type { CommandDefinition } from '../../program/index'
5
5
 
6
+ import { formatKernelError } from '../../connection/errors'
6
7
  import { AstraleError } from '../../errors'
7
- import { statusOwnedInstance } from '../../lib/admin-instance'
8
+ import { statusOwnedInstance, type InstanceInfo } from '../../lib/admin-instance'
8
9
  import { ADMIN_TARGET_OPTIONS, type AdminTargetCommandOpts } from '../../lib/admin-target'
9
- import { fatal, log, withSpinner } from '../../lib/log'
10
+ import { resolveInstance } from '../../lib/instance'
11
+ import { log, withSpinner } from '../../lib/log'
10
12
  import { isMachine, output, type RawOutputOpts } from '../../lib/output'
13
+ import { probeBookmark } from './use'
11
14
 
12
- type StatusOpts = KernelCommandOpts & AdminTargetCommandOpts & RawOutputOpts
15
+ type StatusOpts = KernelCommandOpts &
16
+ AdminTargetCommandOpts &
17
+ RawOutputOpts & { bookmarked?: boolean }
18
+
19
+ interface BookmarkStatus {
20
+ readonly slug: string
21
+ readonly url: string
22
+ readonly issuer: string
23
+ readonly kind: 'bookmark'
24
+ readonly state: 'ready'
25
+ }
13
26
 
14
27
  export default {
15
28
  name: 'status',
16
- description: 'Show admin instance status',
29
+ description: 'Show managed instance status or probe a bookmark',
17
30
  arguments: [{ name: 'id', description: 'Instance slug', required: true }],
18
- options: [...ADMIN_TARGET_OPTIONS],
31
+ options: [
32
+ ...ADMIN_TARGET_OPTIONS,
33
+ { flags: '--bookmarked', description: 'Probe a locally bookmarked kernel connection' },
34
+ ],
19
35
  action: async (id: string, opts: StatusOpts) => {
20
36
  try {
21
37
  const result = await withSpinner(`Fetching instance ${id}`, !isMachine(opts), () =>
22
- statusOwnedInstance(opts, id).catch((error) => {
23
- if (!(error instanceof Error) || error.name !== 'NotFoundError') throw error
24
- throw new AstraleError(
25
- 'INSTANCE_NOT_FOUND',
26
- `No owned instance matches "${id}".`,
27
- 'Run `astrale instance list` to see your instances.',
28
- )
29
- }),
38
+ resolveStatus(id, opts),
30
39
  )
31
40
  if (isMachine(opts)) {
32
41
  output(result, opts)
33
42
  return
34
43
  }
35
44
  console.log(`${chalk.bold(result.slug)} ${chalk.dim(result.url)}`)
36
- log.dim(` state: ${result.state}${result.phase ? ` (${result.phase})` : ''}`)
37
- if (result.error) log.dim(` error: ${result.error}`)
38
- if (result.region) log.dim(` region: ${result.region}`)
39
- if (result.hostId) log.dim(` host: ${result.hostId}`)
40
- if (result.organizationId) log.dim(` organization: ${result.organizationId}`)
41
- if (result.createdAt) log.dim(` created: ${result.createdAt}`)
45
+ const phase = 'phase' in result ? result.phase : undefined
46
+ log.dim(` state: ${result.state}${phase ? ` (${phase})` : ''}`)
47
+ if ('error' in result && result.error) log.dim(` error: ${result.error}`)
48
+ if ('organizationId' in result && result.organizationId)
49
+ log.dim(` organization: ${result.organizationId}`)
50
+ if ('createdAt' in result && result.createdAt) log.dim(` created: ${result.createdAt}`)
42
51
  } catch (e) {
43
- fatal(e, opts)
52
+ await formatKernelError(e, isMachine(opts), undefined, opts.debug)
53
+ process.exit(1)
44
54
  }
45
55
  },
46
56
  } satisfies CommandDefinition
57
+
58
+ export interface StatusDependencies {
59
+ readonly statusOwnedInstance: typeof statusOwnedInstance
60
+ readonly resolveInstance: typeof resolveInstance
61
+ readonly probeBookmark: typeof probeBookmark
62
+ }
63
+
64
+ const defaultStatusDependencies: StatusDependencies = Object.freeze({
65
+ statusOwnedInstance,
66
+ resolveInstance,
67
+ probeBookmark,
68
+ })
69
+
70
+ export async function resolveStatus(
71
+ id: string,
72
+ opts: StatusOpts,
73
+ dependencies: StatusDependencies = defaultStatusDependencies,
74
+ ): Promise<InstanceInfo | BookmarkStatus> {
75
+ if (!opts.bookmarked) return dependencies.statusOwnedInstance(opts, id)
76
+ if (opts.admin !== undefined || opts.adminUrl !== undefined || opts.domainIssuer !== undefined) {
77
+ throw new AstraleError(
78
+ 'INVALID_FLAG',
79
+ '--bookmarked cannot be combined with Admin target options.',
80
+ 'Remove --bookmarked to inspect managed lifecycle, or remove the Admin options to probe a local bookmark.',
81
+ )
82
+ }
83
+ const bookmark = await dependencies.resolveInstance(id, undefined, { persist: false })
84
+ await dependencies.probeBookmark(bookmark)
85
+ return Object.freeze({
86
+ slug: bookmark.name,
87
+ url: bookmark.url,
88
+ issuer: bookmark.issuer ?? bookmark.url,
89
+ kind: 'bookmark',
90
+ state: 'ready',
91
+ })
92
+ }
@@ -3,7 +3,7 @@ import type { CommandDefinition } from '../../program/index'
3
3
 
4
4
  import { AstraleError } from '../../errors'
5
5
  import { getDefault, setDefault } from '../../identity/index'
6
- import { listOwnedInstances } from '../../lib/admin-instance'
6
+ import { listOwnedInstancesWithIdentity } from '../../lib/admin-instance'
7
7
  import { ADMIN_TARGET_OPTIONS } from '../../lib/admin-target'
8
8
  import { fetchWithCaFile } from '../../lib/ca-fetch'
9
9
  import {
@@ -143,7 +143,7 @@ const defaultBookmarkProbeDependencies: BookmarkProbeDependencies = Object.freez
143
143
 
144
144
  async function resolveUseTarget(name: string, opts: UseOpts): Promise<ResolvedInstance> {
145
145
  const [store, managed] = await Promise.all([readInstances(), fetchManagedInstances(name, opts)])
146
- const candidates = collectInstanceCandidates(name, store, managed)
146
+ const candidates = collectInstanceCandidates(name, store, managed.instances)
147
147
 
148
148
  if (candidates.length === 0) {
149
149
  throw new AstraleError(
@@ -168,12 +168,13 @@ async function resolveUseTarget(name: string, opts: UseOpts): Promise<ResolvedIn
168
168
  }
169
169
 
170
170
  assertManagedReady(chosen.info)
171
- const { repointedFrom } = await upsertManagedBookmark(
172
- chosen.key,
173
- chosen.info.slug,
174
- chosen.url,
175
- chosen.info.organizationId,
176
- )
171
+ const { repointedFrom } = await upsertManagedBookmark({
172
+ key: chosen.key,
173
+ slug: chosen.info.slug,
174
+ url: chosen.url,
175
+ ...(chosen.info.organizationId ? { organizationId: chosen.info.organizationId } : {}),
176
+ ...(managed.identity ? { defaultIdentity: managed.identity } : {}),
177
+ })
177
178
  if (repointedFrom) {
178
179
  log.warn(`Bookmark "${chosen.key}" repointed: ${repointedFrom} → ${chosen.url}`)
179
180
  }
@@ -185,16 +186,19 @@ async function resolveUseTarget(name: string, opts: UseOpts): Promise<ResolvedIn
185
186
  * Best-effort: an unreachable or unauthenticated admin kernel degrades to
186
187
  * bookmark-only resolution.
187
188
  */
188
- async function fetchManagedInstances(name: string, opts: UseOpts): Promise<OwnedInstanceInfo[]> {
189
+ async function fetchManagedInstances(
190
+ name: string,
191
+ opts: UseOpts,
192
+ ): Promise<{ readonly instances: OwnedInstanceInfo[]; readonly identity?: string }> {
189
193
  try {
190
194
  validateSlug(name)
191
195
  } catch {
192
- return []
196
+ return { instances: [] }
193
197
  }
194
198
  try {
195
- return await listOwnedInstances(opts)
199
+ return await listOwnedInstancesWithIdentity(opts)
196
200
  } catch {
197
- return []
201
+ return { instances: [] }
198
202
  }
199
203
  }
200
204