@astrale-os/cli 1.0.0-beta.32 → 1.0.0-beta.43

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 (441) hide show
  1. package/CHANGELOG.md +928 -0
  2. package/README.md +53 -43
  3. package/THIRD-PARTY-NOTICES.md +37 -1
  4. package/dist/astrale.js +349631 -83669
  5. package/dist/public/connect-core.js +16 -47
  6. package/dist/public/keys/index.js +1 -1
  7. package/dist/types/admin/contract.d.ts +11 -0
  8. package/dist/types/admin/graph/index.d.ts +1 -0
  9. package/dist/types/admin/graph/nodes.d.ts +12 -0
  10. package/dist/types/admin/instance/client.d.ts +2 -0
  11. package/dist/types/connection/lifetime.d.ts +1 -1
  12. package/dist/types/errors.d.ts +3 -0
  13. package/dist/types/lib/proc.d.ts +1 -0
  14. package/dist/types/lib/update.d.ts +15 -7
  15. package/package.json +8 -6
  16. package/studio/client/dist/assets/index-5C1uT6ML.css +2 -0
  17. package/studio/client/dist/assets/index-C4kNlvwF.js +80 -0
  18. package/studio/client/dist/assets/schema-studio-BR9d0faB.js +8 -0
  19. package/studio/client/dist/index.html +13 -2
  20. package/studio/package.json +2 -1
  21. package/studio/server/agent/ask.test.ts +7 -1
  22. package/studio/server/agent/bridge/grant.ts +15 -3
  23. package/studio/server/agent/prompts/system.test.ts +5 -0
  24. package/studio/server/agent/prompts/system.ts +19 -4
  25. package/studio/server/agent/routes.test.ts +39 -1
  26. package/studio/server/agent/routes.ts +3 -0
  27. package/studio/server/agent/run/coordinator.test.ts +7 -1
  28. package/studio/server/agent/run/preparation.ts +1 -0
  29. package/studio/server/agent/run/transcript.test.ts +47 -2
  30. package/studio/server/agent/run/transcript.ts +32 -3
  31. package/studio/server/api/documents.test.ts +31 -0
  32. package/studio/server/api/documents.ts +35 -1
  33. package/studio/server/api-agent-loadout.test.ts +7 -1
  34. package/studio/server/api.test.ts +7 -1
  35. package/studio/server/cache.ts +4 -4
  36. package/studio/server/detect.ts +9 -12
  37. package/studio/server/domain.test.ts +83 -3
  38. package/studio/server/domain.ts +205 -27
  39. package/studio/server/handoff/service.ts +1 -1
  40. package/studio/server/index.ts +5 -8
  41. package/studio/server/introspect/extractor.ts +111 -17
  42. package/studio/server/introspect/overlay-tsmorph.test.ts +9 -9
  43. package/studio/server/introspect/overlay.ts +1 -1
  44. package/studio/server/introspect/runtime.ts +9 -1
  45. package/studio/server/introspect/source-overlay/spans.ts +2 -5
  46. package/studio/server/lifecycle.ts +1 -1
  47. package/studio/server/state/baseline.test.ts +14 -0
  48. package/studio/server/state/baseline.ts +16 -2
  49. package/studio/server/watch.test.ts +2 -1
  50. package/studio/server/watch.ts +5 -2
  51. package/studio/server/workspace/create.ts +9 -8
  52. package/studio/server/workspace-state.ts +4 -6
  53. package/studio/server/workspace-watch.ts +33 -22
  54. package/studio/shared/contracts/agent.ts +3 -0
  55. package/viewer/dist/main.js +12 -12
  56. package/src/__tests__/fixtures/publication.ts +0 -20
  57. package/src/admin/.spec/api.d.ts +0 -3
  58. package/src/admin/.spec/architecture.md +0 -22
  59. package/src/admin/.spec/icon.svg +0 -3
  60. package/src/admin/.spec/layout.ts +0 -6
  61. package/src/admin/__tests__/fixture.ts +0 -25
  62. package/src/admin/catalog/.spec/api.d.ts +0 -63
  63. package/src/admin/catalog/.spec/architecture.md +0 -7
  64. package/src/admin/catalog/.spec/icon.svg +0 -3
  65. package/src/admin/catalog/.spec/layout.ts +0 -6
  66. package/src/admin/catalog/__tests__/client.test.ts +0 -245
  67. package/src/admin/catalog/client.ts +0 -195
  68. package/src/admin/catalog/index.ts +0 -13
  69. package/src/admin/catalog/model.ts +0 -41
  70. package/src/admin/catalog/tsconfig.json +0 -8
  71. package/src/admin/contract.ts +0 -47
  72. package/src/admin/graph/.spec/api.d.ts +0 -22
  73. package/src/admin/graph/.spec/architecture.md +0 -5
  74. package/src/admin/graph/.spec/icon.svg +0 -3
  75. package/src/admin/graph/.spec/layout.ts +0 -3
  76. package/src/admin/graph/index.ts +0 -6
  77. package/src/admin/graph/nodes.ts +0 -56
  78. package/src/admin/index.ts +0 -2
  79. package/src/admin/instance/.spec/api.d.ts +0 -62
  80. package/src/admin/instance/.spec/architecture.md +0 -10
  81. package/src/admin/instance/.spec/icon.svg +0 -3
  82. package/src/admin/instance/.spec/layout.ts +0 -6
  83. package/src/admin/instance/__tests__/client.test.ts +0 -273
  84. package/src/admin/instance/client.ts +0 -191
  85. package/src/admin/instance/index.ts +0 -15
  86. package/src/admin/instance/model.ts +0 -59
  87. package/src/admin/instance/tsconfig.json +0 -8
  88. package/src/commands/__tests__/admin-instance.test.ts +0 -91
  89. package/src/commands/__tests__/auth-login.test.ts +0 -231
  90. package/src/commands/__tests__/auth-token.test.ts +0 -223
  91. package/src/commands/__tests__/call-describe.test.ts +0 -80
  92. package/src/commands/__tests__/call.test.ts +0 -63
  93. package/src/commands/__tests__/domain-install-operation.test.ts +0 -145
  94. package/src/commands/__tests__/domain-install-owned.test.ts +0 -191
  95. package/src/commands/__tests__/domain-list.test.ts +0 -133
  96. package/src/commands/__tests__/domain-uninstall.test.ts +0 -53
  97. package/src/commands/__tests__/install-direct.test.ts +0 -128
  98. package/src/commands/__tests__/install-identity-override.test.ts +0 -76
  99. package/src/commands/__tests__/instance-bookmark.test.ts +0 -166
  100. package/src/commands/__tests__/instance-list-admin.test.ts +0 -26
  101. package/src/commands/__tests__/instance-list-rows.test.ts +0 -64
  102. package/src/commands/__tests__/instance-status.test.ts +0 -139
  103. package/src/commands/__tests__/instance-use.test.ts +0 -67
  104. package/src/commands/__tests__/introspect-parse.test.ts +0 -100
  105. package/src/commands/__tests__/logs.test.ts +0 -345
  106. package/src/commands/__tests__/read-commands.test.ts +0 -377
  107. package/src/commands/__tests__/setup-plan.test.ts +0 -61
  108. package/src/commands/__tests__/studio-descriptor.test.ts +0 -22
  109. package/src/commands/__tests__/token-ttl.test.ts +0 -66
  110. package/src/commands/__tests__/update.test.ts +0 -95
  111. package/src/commands/__tests__/view-build.test.ts +0 -58
  112. package/src/commands/__tests__/view.test.ts +0 -197
  113. package/src/commands/admin/status.ts +0 -61
  114. package/src/commands/admin/use.ts +0 -100
  115. package/src/commands/auth/login.ts +0 -82
  116. package/src/commands/auth/logout.ts +0 -53
  117. package/src/commands/auth/status.ts +0 -86
  118. package/src/commands/auth/token.ts +0 -174
  119. package/src/commands/browser.ts +0 -236
  120. package/src/commands/call-describe.ts +0 -123
  121. package/src/commands/call.ts +0 -230
  122. package/src/commands/domain/install.ts +0 -575
  123. package/src/commands/domain/list.ts +0 -155
  124. package/src/commands/domain/publish.ts +0 -136
  125. package/src/commands/domain/uninstall.ts +0 -128
  126. package/src/commands/get.ts +0 -69
  127. package/src/commands/identity/__tests__/register.test.ts +0 -93
  128. package/src/commands/identity/create.ts +0 -35
  129. package/src/commands/identity/delete.ts +0 -24
  130. package/src/commands/identity/export.ts +0 -46
  131. package/src/commands/identity/import.ts +0 -61
  132. package/src/commands/identity/list.ts +0 -56
  133. package/src/commands/identity/register.ts +0 -195
  134. package/src/commands/identity/sync.ts +0 -38
  135. package/src/commands/identity/unsync.ts +0 -34
  136. package/src/commands/identity/use.ts +0 -24
  137. package/src/commands/identity/whoami.ts +0 -34
  138. package/src/commands/idp/add.ts +0 -150
  139. package/src/commands/idp/list.ts +0 -57
  140. package/src/commands/idp/refresh.ts +0 -38
  141. package/src/commands/idp/remove.ts +0 -36
  142. package/src/commands/idp/show.ts +0 -29
  143. package/src/commands/instance/active.ts +0 -73
  144. package/src/commands/instance/bookmark.ts +0 -101
  145. package/src/commands/instance/create.ts +0 -61
  146. package/src/commands/instance/delete.ts +0 -69
  147. package/src/commands/instance/forget.ts +0 -26
  148. package/src/commands/instance/list.ts +0 -197
  149. package/src/commands/instance/status.ts +0 -92
  150. package/src/commands/instance/use.ts +0 -263
  151. package/src/commands/introspect.ts +0 -129
  152. package/src/commands/logs.ts +0 -371
  153. package/src/commands/mutate.ts +0 -122
  154. package/src/commands/query.ts +0 -142
  155. package/src/commands/session/analyze.ts +0 -72
  156. package/src/commands/session/list.ts +0 -36
  157. package/src/commands/setup.ts +0 -54
  158. package/src/commands/status.ts +0 -60
  159. package/src/commands/studio.ts +0 -434
  160. package/src/commands/token.ts +0 -121
  161. package/src/commands/ui/__tests__/commands.test.ts +0 -152
  162. package/src/commands/ui/add.ts +0 -51
  163. package/src/commands/ui/doctor.ts +0 -21
  164. package/src/commands/ui/init.ts +0 -38
  165. package/src/commands/ui/list.ts +0 -26
  166. package/src/commands/ui/preset-apply.ts +0 -19
  167. package/src/commands/ui/preset-list.ts +0 -12
  168. package/src/commands/ui/shared.ts +0 -25
  169. package/src/commands/update.ts +0 -356
  170. package/src/commands/use.ts +0 -86
  171. package/src/commands/view-serve.ts +0 -26
  172. package/src/commands/view.ts +0 -658
  173. package/src/connect-core.test.ts +0 -38
  174. package/src/connect-core.ts +0 -42
  175. package/src/connection/.spec/api.d.ts +0 -110
  176. package/src/connection/.spec/architecture.md +0 -58
  177. package/src/connection/.spec/capabilities/connection.ts +0 -13
  178. package/src/connection/.spec/examples/call.ts +0 -7
  179. package/src/connection/.spec/flows/command.ts +0 -20
  180. package/src/connection/.spec/flows/session.ts +0 -62
  181. package/src/connection/.spec/laws/connection.ts +0 -213
  182. package/src/connection/.spec/layout.ts +0 -22
  183. package/src/connection/__tests__/auth.test.ts +0 -129
  184. package/src/connection/__tests__/ca-fetch.test.ts +0 -60
  185. package/src/connection/__tests__/call.test.ts +0 -17
  186. package/src/connection/__tests__/credential.test.ts +0 -254
  187. package/src/connection/__tests__/errors.test.ts +0 -577
  188. package/src/connection/__tests__/exchange.test.ts +0 -404
  189. package/src/connection/__tests__/failure-fixtures.ts +0 -39
  190. package/src/connection/__tests__/failure-safety.test.ts +0 -75
  191. package/src/connection/__tests__/fixtures/localhost-cert.pem +0 -19
  192. package/src/connection/__tests__/fixtures/localhost-key.base64 +0 -1
  193. package/src/connection/__tests__/managed.test.ts +0 -39
  194. package/src/connection/__tests__/reasons.test.ts +0 -78
  195. package/src/connection/__tests__/self.test.ts +0 -71
  196. package/src/connection/__tests__/session.test.ts +0 -144
  197. package/src/connection/__tests__/target.test.ts +0 -95
  198. package/src/connection/auth.ts +0 -265
  199. package/src/connection/call.ts +0 -7
  200. package/src/connection/command.ts +0 -67
  201. package/src/connection/credential.ts +0 -138
  202. package/src/connection/errors.ts +0 -1
  203. package/src/connection/exchange.ts +0 -394
  204. package/src/connection/failure/classify.ts +0 -110
  205. package/src/connection/failure/index.ts +0 -18
  206. package/src/connection/failure/model.ts +0 -28
  207. package/src/connection/failure/render.ts +0 -116
  208. package/src/connection/index.ts +0 -8
  209. package/src/connection/lifetime.ts +0 -25
  210. package/src/connection/reasons.ts +0 -209
  211. package/src/connection/self.ts +0 -138
  212. package/src/connection/session.ts +0 -203
  213. package/src/connection/target.ts +0 -112
  214. package/src/connection/tsconfig.json +0 -6
  215. package/src/errors.ts +0 -66
  216. package/src/graph/.spec/api.d.ts +0 -41
  217. package/src/graph/.spec/laws/documents.ts +0 -24
  218. package/src/graph/.spec/laws/projection.ts +0 -13
  219. package/src/graph/.spec/layout.ts +0 -14
  220. package/src/graph/__tests__/mutation.test.ts +0 -51
  221. package/src/graph/__tests__/projection.test.ts +0 -22
  222. package/src/graph/__tests__/query.test.ts +0 -180
  223. package/src/graph/class.ts +0 -30
  224. package/src/graph/index.ts +0 -4
  225. package/src/graph/mutation.ts +0 -46
  226. package/src/graph/projection.ts +0 -21
  227. package/src/graph/query.ts +0 -95
  228. package/src/graph/tsconfig.json +0 -6
  229. package/src/identity/.history/ard/bootstrap-root-transfer.md +0 -57
  230. package/src/identity/.history/ard/domain-mediated-registration.md +0 -36
  231. package/src/identity/.spec/api.d.ts +0 -124
  232. package/src/identity/.spec/architecture.md +0 -33
  233. package/src/identity/.spec/capabilities/identity.ts +0 -7
  234. package/src/identity/.spec/flows/bootstrap-root.ts +0 -79
  235. package/src/identity/.spec/flows/domain-mediated-registration.ts +0 -51
  236. package/src/identity/.spec/flows/import.ts +0 -29
  237. package/src/identity/.spec/laws/identity.ts +0 -56
  238. package/src/identity/.spec/layout.ts +0 -13
  239. package/src/identity/__tests__/fixtures/registry-journey.ts +0 -65
  240. package/src/identity/__tests__/registration.test.ts +0 -64
  241. package/src/identity/__tests__/registry.test.ts +0 -74
  242. package/src/identity/__tests__/transfer.test.ts +0 -198
  243. package/src/identity/index.ts +0 -23
  244. package/src/identity/registration.ts +0 -72
  245. package/src/identity/registry.ts +0 -181
  246. package/src/identity/transfer.ts +0 -187
  247. package/src/identity/tsconfig.json +0 -6
  248. package/src/index.ts +0 -1
  249. package/src/keys/.spec/api.d.ts +0 -74
  250. package/src/keys/.spec/architecture.md +0 -13
  251. package/src/keys/.spec/laws/keys.ts +0 -43
  252. package/src/keys/.spec/layout.ts +0 -6
  253. package/src/keys/__tests__/algorithm.test.ts +0 -39
  254. package/src/keys/__tests__/keys.test.ts +0 -172
  255. package/src/keys/algorithm.ts +0 -33
  256. package/src/keys/credential.ts +0 -113
  257. package/src/keys/index.ts +0 -14
  258. package/src/keys/pair.ts +0 -219
  259. package/src/keys/tsconfig.json +0 -6
  260. package/src/lib/__tests__/admin-target.test.ts +0 -184
  261. package/src/lib/__tests__/binary.test.ts +0 -70
  262. package/src/lib/__tests__/browser-retention.test.ts +0 -212
  263. package/src/lib/__tests__/command-dx.test.ts +0 -102
  264. package/src/lib/__tests__/concurrency.test.ts +0 -62
  265. package/src/lib/__tests__/config.test.ts +0 -81
  266. package/src/lib/__tests__/design.test.ts +0 -99
  267. package/src/lib/__tests__/domain-publication.test.ts +0 -138
  268. package/src/lib/__tests__/format.test.ts +0 -22
  269. package/src/lib/__tests__/idp-session.driver.ts +0 -60
  270. package/src/lib/__tests__/idp-session.test.ts +0 -404
  271. package/src/lib/__tests__/idp.test.ts +0 -415
  272. package/src/lib/__tests__/instance-candidates.test.ts +0 -146
  273. package/src/lib/__tests__/instance-target.test.ts +0 -213
  274. package/src/lib/__tests__/instance.test.ts +0 -192
  275. package/src/lib/__tests__/local-status.test.ts +0 -202
  276. package/src/lib/__tests__/log-errors.test.ts +0 -64
  277. package/src/lib/__tests__/log.test.ts +0 -31
  278. package/src/lib/__tests__/meta.test.ts +0 -55
  279. package/src/lib/__tests__/output.test.ts +0 -162
  280. package/src/lib/__tests__/panel.test.ts +0 -40
  281. package/src/lib/__tests__/port.test.ts +0 -44
  282. package/src/lib/__tests__/prompt.test.ts +0 -25
  283. package/src/lib/__tests__/sdk-deps.test.ts +0 -68
  284. package/src/lib/__tests__/self.test.ts +0 -50
  285. package/src/lib/__tests__/skills.test.ts +0 -834
  286. package/src/lib/__tests__/studio-server-deps.test.ts +0 -111
  287. package/src/lib/__tests__/table.test.ts +0 -53
  288. package/src/lib/__tests__/update.test.ts +0 -511
  289. package/src/lib/__tests__/use-target.test.ts +0 -56
  290. package/src/lib/__tests__/validation.test.ts +0 -34
  291. package/src/lib/__tests__/view-assets.test.ts +0 -171
  292. package/src/lib/__tests__/view-external-open-intent.test.ts +0 -150
  293. package/src/lib/__tests__/view-external-open-origins.test.ts +0 -27
  294. package/src/lib/__tests__/view-open-intent.test.ts +0 -280
  295. package/src/lib/__tests__/view-port-allocation.test.ts +0 -82
  296. package/src/lib/__tests__/view-server.test.ts +0 -91
  297. package/src/lib/__tests__/view-session.test.ts +0 -100
  298. package/src/lib/__tests__/view-snapshot.test.ts +0 -77
  299. package/src/lib/admin-domain.ts +0 -43
  300. package/src/lib/admin-instance.ts +0 -56
  301. package/src/lib/admin-target.ts +0 -290
  302. package/src/lib/binary.ts +0 -127
  303. package/src/lib/browser-retention.ts +0 -210
  304. package/src/lib/browser.ts +0 -150
  305. package/src/lib/ca-fetch.ts +0 -133
  306. package/src/lib/command-dx.ts +0 -191
  307. package/src/lib/concurrency.ts +0 -31
  308. package/src/lib/config.ts +0 -57
  309. package/src/lib/credential-lifetime.ts +0 -24
  310. package/src/lib/domain-publication.ts +0 -104
  311. package/src/lib/failure-debug.ts +0 -26
  312. package/src/lib/format.ts +0 -4
  313. package/src/lib/idp-session.ts +0 -156
  314. package/src/lib/idp.ts +0 -926
  315. package/src/lib/instance-candidates.ts +0 -49
  316. package/src/lib/instance-target.ts +0 -197
  317. package/src/lib/instance.ts +0 -468
  318. package/src/lib/invocation.ts +0 -11
  319. package/src/lib/local-status.ts +0 -152
  320. package/src/lib/log.ts +0 -143
  321. package/src/lib/login-flow.ts +0 -201
  322. package/src/lib/meta.ts +0 -90
  323. package/src/lib/output.ts +0 -238
  324. package/src/lib/panel.ts +0 -61
  325. package/src/lib/port.ts +0 -41
  326. package/src/lib/proc.ts +0 -87
  327. package/src/lib/prompt.ts +0 -136
  328. package/src/lib/provision-instance.ts +0 -139
  329. package/src/lib/sdk-deps.ts +0 -104
  330. package/src/lib/self.ts +0 -22
  331. package/src/lib/skills/lock.ts +0 -117
  332. package/src/lib/skills/sync.ts +0 -878
  333. package/src/lib/skills.ts +0 -120
  334. package/src/lib/table.ts +0 -62
  335. package/src/lib/update.ts +0 -568
  336. package/src/lib/use-target.ts +0 -24
  337. package/src/lib/validation.ts +0 -59
  338. package/src/lib/view/assets.ts +0 -87
  339. package/src/lib/view/external-open-intent.ts +0 -41
  340. package/src/lib/view/external-open-origins.ts +0 -37
  341. package/src/lib/view/host-capabilities.ts +0 -17
  342. package/src/lib/view/open-intent.ts +0 -67
  343. package/src/lib/view/port-allocation.ts +0 -19
  344. package/src/lib/view/resolve.ts +0 -111
  345. package/src/lib/view/server.ts +0 -259
  346. package/src/lib/view/session.ts +0 -154
  347. package/src/lib/view/snapshot.ts +0 -101
  348. package/src/paths/.spec/api.d.ts +0 -13
  349. package/src/paths/.spec/architecture.md +0 -5
  350. package/src/paths/.spec/layout.ts +0 -3
  351. package/src/paths/index.ts +0 -13
  352. package/src/program/.spec/api.d.ts +0 -43
  353. package/src/program/.spec/architecture.md +0 -18
  354. package/src/program/.spec/laws/program.ts +0 -29
  355. package/src/program/.spec/layout.ts +0 -14
  356. package/src/program/__tests__/program.test.ts +0 -556
  357. package/src/program/argv.ts +0 -14
  358. package/src/program/build.ts +0 -205
  359. package/src/program/command.ts +0 -43
  360. package/src/program/index.ts +0 -3
  361. package/src/program/options.ts +0 -41
  362. package/src/program/registry.ts +0 -64
  363. package/src/program/tsconfig.json +0 -6
  364. package/src/setup/__tests__/instance-step.test.ts +0 -256
  365. package/src/setup/__tests__/util.test.ts +0 -29
  366. package/src/setup/engine.ts +0 -83
  367. package/src/setup/render.ts +0 -107
  368. package/src/setup/steps/admin.ts +0 -93
  369. package/src/setup/steps/agent-browser.ts +0 -81
  370. package/src/setup/steps/auth.ts +0 -54
  371. package/src/setup/steps/domain.ts +0 -68
  372. package/src/setup/steps/index.ts +0 -18
  373. package/src/setup/steps/instance.ts +0 -206
  374. package/src/setup/steps/skills-bridge.ts +0 -70
  375. package/src/setup/steps/skills.ts +0 -61
  376. package/src/setup/types.ts +0 -61
  377. package/src/setup/util.ts +0 -34
  378. package/src/state/.spec/api.d.ts +0 -152
  379. package/src/state/.spec/architecture.md +0 -45
  380. package/src/state/.spec/capabilities/state.ts +0 -7
  381. package/src/state/.spec/flows/identity-update.ts +0 -22
  382. package/src/state/.spec/laws/state.ts +0 -73
  383. package/src/state/.spec/layout.ts +0 -15
  384. package/src/state/__tests__/exchange-credentials.test.ts +0 -341
  385. package/src/state/__tests__/files.test.ts +0 -136
  386. package/src/state/__tests__/fixtures/identity-transition.ts +0 -37
  387. package/src/state/__tests__/fixtures/session-route-process.ts +0 -93
  388. package/src/state/__tests__/identities.test.ts +0 -142
  389. package/src/state/__tests__/paths.test.ts +0 -28
  390. package/src/state/__tests__/session-routes.test.ts +0 -138
  391. package/src/state/exchange-credentials.ts +0 -250
  392. package/src/state/files.ts +0 -170
  393. package/src/state/identities.ts +0 -229
  394. package/src/state/index.ts +0 -31
  395. package/src/state/paths.ts +0 -64
  396. package/src/state/session-routes.ts +0 -34
  397. package/src/state/tsconfig.json +0 -6
  398. package/src/telemetry/__tests__/analyze-log.test.ts +0 -38
  399. package/src/telemetry/__tests__/gate.test.ts +0 -63
  400. package/src/telemetry/__tests__/recorder.test.ts +0 -111
  401. package/src/telemetry/__tests__/redact.test.ts +0 -79
  402. package/src/telemetry/__tests__/retention.test.ts +0 -267
  403. package/src/telemetry/__tests__/session.test.ts +0 -166
  404. package/src/telemetry/__tests__/settings.test.ts +0 -102
  405. package/src/telemetry/__tests__/store-scan.test.ts +0 -128
  406. package/src/telemetry/__tests__/trigger.test.ts +0 -78
  407. package/src/telemetry/adapters/__tests__/claude-code.test.ts +0 -89
  408. package/src/telemetry/adapters/__tests__/codex.test.ts +0 -138
  409. package/src/telemetry/adapters/__tests__/index.test.ts +0 -88
  410. package/src/telemetry/adapters/claude-code.ts +0 -90
  411. package/src/telemetry/adapters/codex.ts +0 -160
  412. package/src/telemetry/adapters/index.ts +0 -45
  413. package/src/telemetry/adapters/types.ts +0 -21
  414. package/src/telemetry/analyze.ts +0 -249
  415. package/src/telemetry/gate.ts +0 -79
  416. package/src/telemetry/recorder.ts +0 -68
  417. package/src/telemetry/redact.ts +0 -53
  418. package/src/telemetry/retention.ts +0 -176
  419. package/src/telemetry/session.ts +0 -94
  420. package/src/telemetry/settings.ts +0 -79
  421. package/src/telemetry/store.ts +0 -174
  422. package/src/telemetry/trigger.ts +0 -107
  423. package/src/telemetry/types.ts +0 -64
  424. package/src/test-utils.ts +0 -18
  425. package/src/ui/.spec/api.d.ts +0 -14
  426. package/src/ui/.spec/architecture.md +0 -14
  427. package/src/ui/.spec/laws.ts +0 -50
  428. package/src/ui/.spec/layout.ts +0 -16
  429. package/src/ui/__tests__/ui.test.ts +0 -1742
  430. package/src/ui/index.ts +0 -13
  431. package/src/ui/lock.ts +0 -89
  432. package/src/ui/model.ts +0 -83
  433. package/src/ui/operations.ts +0 -1044
  434. package/src/ui/project.ts +0 -333
  435. package/src/ui/release.ts +0 -398
  436. package/src/ui/runner.ts +0 -18
  437. package/studio/client/dist/assets/index-BFVFs_8x.js +0 -81
  438. package/studio/client/dist/assets/index-DuB9iUdu.css +0 -2
  439. package/studio/client/dist/assets/schema-studio-DH6oEWME.js +0 -8
  440. package/studio/tsconfig.json +0 -24
  441. package/viewer/tsconfig.json +0 -13
@@ -1,142 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, test } from 'bun:test'
2
- import { mkdtemp, readFile, rm, stat, writeFile } from 'node:fs/promises'
3
- import { tmpdir } from 'node:os'
4
- import { join } from 'node:path'
5
-
6
- import {
7
- IDENTITY_STORE_VERSION,
8
- IdentityStateError,
9
- readIdentityStore,
10
- updateIdentityStore,
11
- type IdentityStore,
12
- } from '../identities'
13
-
14
- let directory: string
15
- let path: string
16
-
17
- const legacy = JSON.stringify(
18
- {
19
- default: 'manager',
20
- identities: {
21
- manager: {
22
- subject: 'manager',
23
- createdAt: '2024-01-01T00:00:00.000Z',
24
- source: 'key',
25
- mode: 'local',
26
- },
27
- },
28
- },
29
- null,
30
- 2,
31
- )
32
-
33
- beforeEach(async () => {
34
- directory = await mkdtemp(join(tmpdir(), 'astrale-identity-state-'))
35
- path = join(directory, 'identities.json')
36
- })
37
-
38
- afterEach(async () => {
39
- await rm(directory, { recursive: true, force: true })
40
- })
41
-
42
- describe('identity state', () => {
43
- /** @evidence TEST-CLI-STATE-IDENTITY-READ-SAFE */
44
- test('reads missing, legacy, and current state without writing', async () => {
45
- const missing = await readIdentityStore({
46
- path,
47
- now: () => new Date('2025-01-01T00:00:00.000Z'),
48
- })
49
- expect(missing).toEqual({ default: '', identities: {} })
50
- await expect(readFile(path, 'utf-8')).rejects.toThrow()
51
-
52
- await writeFile(path, legacy)
53
- expect((await readIdentityStore({ path })).default).toBe('manager')
54
- expect(await readFile(path, 'utf-8')).toBe(legacy)
55
- await expect(readFile(`${path}.v0.bak`, 'utf-8')).rejects.toThrow()
56
-
57
- const current = `${JSON.stringify({ version: IDENTITY_STORE_VERSION, ...missing })}\n`
58
- await writeFile(path, current)
59
- expect((await readIdentityStore({ path })).identities).toEqual({})
60
- expect(await readFile(path, 'utf-8')).toBe(current)
61
- })
62
-
63
- /** @evidence TEST-CLI-STATE-IDENTITY-FAILS-CLOSED */
64
- test('rejects malformed and unsupported state without replacing it', async () => {
65
- for (const raw of ['{', JSON.stringify({ version: 2, default: 'manager', identities: {} })]) {
66
- await writeFile(path, raw)
67
- const error = await readIdentityStore({ path }).catch((caught) => caught)
68
- expect(error).toBeInstanceOf(IdentityStateError)
69
- expect((error as IdentityStateError).code).toBe(
70
- raw === '{' ? 'IDENTITY_STATE_INVALID' : 'IDENTITY_STATE_VERSION_UNSUPPORTED',
71
- )
72
- expect(await readFile(path, 'utf-8')).toBe(raw)
73
- }
74
- })
75
-
76
- /** @evidence TEST-CLI-STATE-IDENTITY-MIGRATES */
77
- test('backs up exact legacy bytes before the first V1 mutation', async () => {
78
- await writeFile(path, legacy)
79
-
80
- await updateIdentityStore(
81
- (current) => ({ next: { ...current, default: 'alice' }, value: undefined }),
82
- { path },
83
- )
84
-
85
- expect(await readFile(`${path}.v0.bak`, 'utf-8')).toBe(legacy)
86
- expect((await stat(`${path}.v0.bak`)).mode & 0o777).toBe(0o600)
87
- const written = JSON.parse(await readFile(path, 'utf-8')) as {
88
- version: number
89
- default: string
90
- }
91
- expect(written).toMatchObject({ version: 1, default: 'alice' })
92
- expect((await stat(path)).mode & 0o777).toBe(0o600)
93
- })
94
-
95
- /** @evidence TEST-CLI-STATE-IDENTITY-CONCURRENT */
96
- test('retains concurrent selection and registration from separate processes', async () => {
97
- const alice = {
98
- subject: 'alice',
99
- createdAt: '2025-01-01T00:00:00.000Z',
100
- source: 'key' as const,
101
- mode: 'local' as const,
102
- }
103
- const bob = { ...alice, subject: 'bob' }
104
- await writeFile(
105
- path,
106
- JSON.stringify({
107
- version: IDENTITY_STORE_VERSION,
108
- default: 'manager',
109
- identities: {
110
- manager: { ...alice, subject: 'manager' },
111
- alice,
112
- bob,
113
- },
114
- }),
115
- )
116
- const fixture = join(import.meta.dir, 'fixtures', 'identity-transition.ts')
117
- const commands = [
118
- ['default', 'alice'],
119
- ...Array.from({ length: 8 }, (_, index) => ['registration', 'bob', `instance-${index}`]),
120
- ]
121
- const processes = commands.map((args) =>
122
- Bun.spawn({
123
- cmd: ['bun', fixture, ...args],
124
- env: { ...process.env, ASTRALE_HOME: directory },
125
- stdout: 'pipe',
126
- stderr: 'pipe',
127
- }),
128
- )
129
- const outcomes = await Promise.all(
130
- processes.map(async (process) => ({
131
- code: await process.exited,
132
- stderr: await new Response(process.stderr).text(),
133
- })),
134
- )
135
- expect(outcomes).toEqual(outcomes.map(() => ({ code: 0, stderr: '' })))
136
-
137
- const store: IdentityStore = await readIdentityStore({ path })
138
- expect(store.default).toBe('alice')
139
- expect(Object.keys(store.identities.bob.registrations ?? {})).toHaveLength(8)
140
- await expect(readFile(`${path}.lock`, 'utf-8')).rejects.toThrow()
141
- })
142
- })
@@ -1,28 +0,0 @@
1
- import { describe, expect, test } from 'bun:test'
2
- import { join } from 'node:path'
3
-
4
- import { createPaths } from '../paths'
5
-
6
- describe('state paths', () => {
7
- /** @evidence TEST-CLI-STATE-PATHS-CAPTURED */
8
- test('captures explicit and environment coordinates once', () => {
9
- const environment: Record<string, string | undefined> = {
10
- ASTRALE_HOME: '/environment/home',
11
- ASTRALE_KEYS_DIR: '/environment/keys',
12
- ASTRALE_DATA_DIR: '/environment/data',
13
- }
14
- const explicit = createPaths('/explicit/home', environment)
15
- const inherited = createPaths(undefined, environment)
16
-
17
- environment.ASTRALE_HOME = '/changed/home'
18
- environment.ASTRALE_KEYS_DIR = '/changed/keys'
19
-
20
- expect(explicit.home).toBe('/explicit/home')
21
- expect(explicit.keys).toBe('/environment/keys')
22
- expect(explicit.config).toBe(join('/explicit/home', 'config.json'))
23
- expect(explicit.sessionRoutes).toBe(join('/explicit/home', 'session', 'routes.json'))
24
- expect(inherited.home).toBe('/environment/home')
25
- expect(inherited.keys).toBe('/environment/keys')
26
- expect(Object.isFrozen(explicit)).toBe(true)
27
- })
28
- })
@@ -1,138 +0,0 @@
1
- import type { SessionRouteArtifact } from '@astrale-os/sdk/client/session'
2
-
3
- import { afterEach, beforeEach, describe, expect, test } from 'bun:test'
4
- import { access, mkdir, mkdtemp, readFile, rm, stat, writeFile } from 'node:fs/promises'
5
- import { tmpdir } from 'node:os'
6
- import { join } from 'node:path'
7
-
8
- import { FileSessionRouteStore } from '../session-routes'
9
-
10
- let directory: string
11
- let path: string
12
-
13
- beforeEach(async () => {
14
- directory = await mkdtemp(join(tmpdir(), 'astrale-session-routes-'))
15
- path = join(directory, 'private', 'routes.json')
16
- })
17
-
18
- afterEach(async () => {
19
- await rm(directory, { recursive: true, force: true })
20
- })
21
-
22
- describe('session route file store', () => {
23
- test('round-trips the Kernel-owned artifact under owner-private filesystem modes', async () => {
24
- const artifact: SessionRouteArtifact = { version: 1, entries: {} }
25
- const store = new FileSessionRouteStore(path)
26
-
27
- store.write(artifact)
28
-
29
- expect(store.read()).toEqual(artifact)
30
- expect((await stat(path)).mode & 0o777).toBe(0o600)
31
- expect((await stat(join(directory, 'private'))).mode & 0o777).toBe(0o700)
32
- expect(await readFile(path, 'utf8')).toBe('{"version":1,"entries":{}}\n')
33
-
34
- store.clear()
35
- await expect(access(path)).rejects.toThrow()
36
- expect(() => store.clear()).not.toThrow()
37
- })
38
-
39
- test('leaves malformed representation recovery to Kernel Client as a cold miss', async () => {
40
- await mkdir(join(directory, 'private'))
41
- await writeFile(path, '{invalid')
42
- const fixture = join(import.meta.dir, 'fixtures', 'session-route-process.ts')
43
-
44
- expect(await runFixture(fixture, path)).toEqual({
45
- value: 'done',
46
- sourceAttempts: 1,
47
- destinationAttempts: 1,
48
- })
49
- expect(JSON.parse(await readFile(path, 'utf8'))).toMatchObject({ version: 1 })
50
- })
51
-
52
- test('reuses Kernel-admitted routing state in a separate operating-system process', async () => {
53
- const routePath = join(directory, 'private', 'routes.json')
54
- const fixture = join(import.meta.dir, 'fixtures', 'session-route-process.ts')
55
-
56
- const first = await runFixture(fixture, routePath)
57
- const second = await runFixture(fixture, routePath)
58
-
59
- expect(first).toEqual({ value: 'done', sourceAttempts: 1, destinationAttempts: 1 })
60
- expect(second).toEqual({ value: 'done', sourceAttempts: 0, destinationAttempts: 1 })
61
- })
62
-
63
- test('publishes only complete owner-private artifacts under concurrent process writers', async () => {
64
- const routePath = join(directory, 'private', 'routes.json')
65
- const fixture = join(import.meta.dir, 'fixtures', 'session-route-process.ts')
66
-
67
- const results = await Promise.all(
68
- Array.from({ length: 8 }, () => runFixture(fixture, routePath)),
69
- )
70
- expect(results).toHaveLength(8)
71
- expect(results.every((result) => result.destinationAttempts === 1)).toBe(true)
72
- expect(JSON.parse(await readFile(routePath, 'utf8'))).toMatchObject({ version: 1 })
73
- expect((await stat(routePath)).mode & 0o777).toBe(0o600)
74
- expect(await runFixture(fixture, routePath)).toEqual({
75
- value: 'done',
76
- sourceAttempts: 0,
77
- destinationAttempts: 1,
78
- })
79
- })
80
-
81
- test('auth logout clears every persisted bearer cache through the real CLI command', async () => {
82
- const routePath = join(directory, 'session', 'routes.json')
83
- const exchangePath = join(directory, 'exchange', 'credentials.json')
84
- await mkdir(join(directory, 'session'), { recursive: true })
85
- await mkdir(join(directory, 'exchange'), { recursive: true })
86
- await writeFile(routePath, '{"version":1,"entries":{"confidential":{}}}\n')
87
- await writeFile(
88
- exchangePath,
89
- '{"version":2,"entries":{"confidential":{"credential":"bearer"}}}\n',
90
- )
91
-
92
- const child = Bun.spawn(
93
- [
94
- process.execPath,
95
- join(import.meta.dir, '../../..', 'bin', 'astrale.ts'),
96
- 'auth',
97
- 'logout',
98
- '--all',
99
- '--json',
100
- ],
101
- {
102
- env: { ...process.env, ASTRALE_HOME: directory },
103
- stdout: 'pipe',
104
- stderr: 'pipe',
105
- },
106
- )
107
- const [exitCode, stdout, stderr] = await Promise.all([
108
- child.exited,
109
- new Response(child.stdout).text(),
110
- new Response(child.stderr).text(),
111
- ])
112
-
113
- expect(exitCode, stderr).toBe(0)
114
- expect(JSON.parse(stdout)).toEqual({ cleared: [] })
115
- await expect(access(routePath)).rejects.toThrow()
116
- expect(JSON.parse(await readFile(exchangePath, 'utf8'))).toEqual({ version: 2, entries: {} })
117
- })
118
- })
119
-
120
- interface FixtureResult {
121
- readonly value: string
122
- readonly sourceAttempts: number
123
- readonly destinationAttempts: number
124
- }
125
-
126
- async function runFixture(fixture: string, routePath: string): Promise<FixtureResult> {
127
- const child = Bun.spawn([process.execPath, fixture, routePath], {
128
- stdout: 'pipe',
129
- stderr: 'pipe',
130
- })
131
- const [exitCode, stdout, stderr] = await Promise.all([
132
- child.exited,
133
- new Response(child.stdout).text(),
134
- new Response(child.stderr).text(),
135
- ])
136
- expect(exitCode, stderr).toBe(0)
137
- return JSON.parse(stdout) as FixtureResult
138
- }
@@ -1,250 +0,0 @@
1
- import { credential, grant } from '@astrale-os/sdk/auth'
2
- import { chmod, mkdir, readFile } from 'node:fs/promises'
3
- import { dirname } from 'node:path'
4
-
5
- import { credentialLifetimeCovers } from '../lib/credential-lifetime'
6
- import { atomicWrite, withFileLock } from './files'
7
- import { EXCHANGE_CREDENTIALS_PATH } from './paths'
8
-
9
- const VERSION = 2
10
- const MINIMUM_REMAINING_SECONDS = 30
11
-
12
- export namespace exchange {
13
- export interface Artifact {
14
- readonly version: 2
15
- readonly entries: Record<string, Entry>
16
- }
17
-
18
- export interface Key {
19
- readonly kernelIssuer: string
20
- readonly domainIssuer: string
21
- readonly sourceIssuer: string
22
- readonly sourceSubject: string
23
- }
24
-
25
- export interface Entry {
26
- readonly credential: string
27
- readonly expiresAt: number
28
- readonly user: string
29
- readonly sourceIssuer: string
30
- readonly sourceSubject: string
31
- }
32
- }
33
-
34
- export class ExchangeCredentialCache {
35
- private readonly refreshing = new Map<string, Promise<string>>()
36
-
37
- constructor(private readonly path = EXCHANGE_CREDENTIALS_PATH) {}
38
-
39
- getOrRefresh(
40
- key: exchange.Key,
41
- minimumRemainingSeconds: number,
42
- refresh: () => Promise<exchange.Entry>,
43
- now = () => Math.floor(Date.now() / 1_000),
44
- ): Promise<string> {
45
- if (!Number.isSafeInteger(minimumRemainingSeconds) || minimumRemainingSeconds < 1) {
46
- throw new TypeError('Exchange credential minimum lifetime must be a positive safe integer.')
47
- }
48
- const encoded = encodeKey(key)
49
- const pendingKey = `${encoded}\0${minimumRemainingSeconds}`
50
- const current = this.refreshing.get(pendingKey)
51
- if (current !== undefined) return current
52
- const pending = this.getOrRefreshOnce(
53
- key,
54
- encoded,
55
- minimumRemainingSeconds,
56
- refresh,
57
- now,
58
- ).finally(() => {
59
- this.refreshing.delete(pendingKey)
60
- })
61
- this.refreshing.set(pendingKey, pending)
62
- return pending
63
- }
64
-
65
- async deleteKernel(kernelIssuer: string): Promise<void> {
66
- await this.transition((store) => {
67
- for (const encoded of Object.keys(store.entries)) {
68
- const key = decodeKey(encoded)
69
- if (key === undefined || key.kernelIssuer === kernelIssuer) delete store.entries[encoded]
70
- }
71
- })
72
- }
73
-
74
- async clear(): Promise<void> {
75
- await this.transition((store) => {
76
- for (const encoded of Object.keys(store.entries)) delete store.entries[encoded]
77
- })
78
- }
79
-
80
- private async getOrRefreshOnce(
81
- key: exchange.Key,
82
- encoded: string,
83
- minimumRemainingSeconds: number,
84
- refresh: () => Promise<exchange.Entry>,
85
- now: () => number,
86
- ): Promise<string> {
87
- return withFileLock(`${this.path}.lock`, async () => {
88
- await ensurePrivateDirectory(this.path)
89
- const store = await readStore(this.path)
90
- const changed = scrub(store, now())
91
- const cached = store.entries[encoded]
92
- if (cached !== undefined && validEntry(key, cached, now(), minimumRemainingSeconds)) {
93
- if (changed) await writeStore(this.path, store)
94
- return cached.credential
95
- }
96
-
97
- const next = await refresh()
98
- if (!validEntry(key, next, now(), minimumRemainingSeconds)) {
99
- throw new Error(
100
- 'Token exchange returned a credential inconsistent with its cache key or required lifetime.',
101
- )
102
- }
103
- store.entries[encoded] = Object.freeze({ ...next })
104
- await writeStore(this.path, store)
105
- return next.credential
106
- })
107
- }
108
-
109
- private async transition(change: (store: exchange.Artifact) => void): Promise<void> {
110
- await withFileLock(`${this.path}.lock`, async () => {
111
- await ensurePrivateDirectory(this.path)
112
- const store = await readStore(this.path)
113
- change(store)
114
- await writeStore(this.path, store)
115
- })
116
- }
117
- }
118
-
119
- async function readStore(path: string): Promise<exchange.Artifact> {
120
- try {
121
- const input = JSON.parse(await readFile(path, 'utf8')) as unknown
122
- if (input === null || typeof input !== 'object' || Array.isArray(input)) return emptyStore()
123
- const value = input as Record<string, unknown>
124
- if (
125
- value.version !== VERSION ||
126
- value.entries === null ||
127
- typeof value.entries !== 'object' ||
128
- Array.isArray(value.entries)
129
- ) {
130
- return emptyStore()
131
- }
132
- return { version: VERSION, entries: { ...(value.entries as Record<string, exchange.Entry>) } }
133
- } catch {
134
- return emptyStore()
135
- }
136
- }
137
-
138
- function emptyStore(): exchange.Artifact {
139
- return { version: VERSION, entries: {} }
140
- }
141
-
142
- async function writeStore(path: string, store: exchange.Artifact): Promise<void> {
143
- await atomicWrite(path, `${JSON.stringify(store, null, 2)}\n`)
144
- await chmod(path, 0o600)
145
- }
146
-
147
- async function ensurePrivateDirectory(path: string): Promise<void> {
148
- const directory = dirname(path)
149
- await mkdir(directory, { recursive: true, mode: 0o700 })
150
- await chmod(directory, 0o700)
151
- }
152
-
153
- function validEntry(
154
- key: exchange.Key,
155
- entry: exchange.Entry,
156
- now: number,
157
- minimumRemaining = MINIMUM_REMAINING_SECONDS,
158
- ): boolean {
159
- if (
160
- entry === null ||
161
- typeof entry !== 'object' ||
162
- Reflect.ownKeys(entry).length !== 5 ||
163
- typeof entry.credential !== 'string' ||
164
- entry.credential.length === 0 ||
165
- !Number.isSafeInteger(entry.expiresAt) ||
166
- entry.expiresAt - now < minimumRemaining ||
167
- typeof entry.user !== 'string' ||
168
- entry.user.length === 0 ||
169
- entry.sourceIssuer !== key.sourceIssuer ||
170
- entry.sourceSubject !== key.sourceSubject
171
- ) {
172
- return false
173
- }
174
- try {
175
- const inspected = credential.inspect(entry.credential)
176
- const carried = grant.acceptUnresolved(inspected.claims.grant).expr
177
- if (
178
- carried.kind !== 'identity' ||
179
- !('credential' in carried) ||
180
- typeof carried.credential !== 'string'
181
- ) {
182
- return false
183
- }
184
- const proof = credential.inspect(carried.credential)
185
- const issued = proof.claims.delegation
186
- if (
187
- issued === null ||
188
- typeof issued !== 'object' ||
189
- Array.isArray(issued) ||
190
- Reflect.ownKeys(issued).length !== 2 ||
191
- !Object.hasOwn(issued, 'v') ||
192
- !Object.hasOwn(issued, 'expr') ||
193
- Reflect.get(issued, 'v') !== 1
194
- ) {
195
- return false
196
- }
197
- grant.accept({ expr: Reflect.get(issued, 'expr') })
198
- return (
199
- inspected.iss === key.domainIssuer &&
200
- inspected.aud === key.kernelIssuer &&
201
- inspected.claims.exp === entry.expiresAt &&
202
- !Object.hasOwn(inspected.claims, 'delegation') &&
203
- proof.iss === key.kernelIssuer &&
204
- proof.sub === entry.user &&
205
- proof.aud === key.kernelIssuer &&
206
- typeof proof.claims.exp === 'number' &&
207
- Number.isSafeInteger(proof.claims.exp) &&
208
- credentialLifetimeCovers(proof.claims.exp, minimumRemaining, now)
209
- )
210
- } catch {
211
- return false
212
- }
213
- }
214
-
215
- function encodeKey(key: exchange.Key): string {
216
- return JSON.stringify([key.kernelIssuer, key.domainIssuer, key.sourceIssuer, key.sourceSubject])
217
- }
218
-
219
- function decodeKey(input: string): exchange.Key | undefined {
220
- try {
221
- const value = JSON.parse(input) as unknown
222
- if (
223
- !Array.isArray(value) ||
224
- value.length !== 4 ||
225
- value.some((part) => typeof part !== 'string' || part.length === 0)
226
- ) {
227
- return undefined
228
- }
229
- return {
230
- kernelIssuer: value[0]!,
231
- domainIssuer: value[1]!,
232
- sourceIssuer: value[2]!,
233
- sourceSubject: value[3]!,
234
- }
235
- } catch {
236
- return undefined
237
- }
238
- }
239
-
240
- function scrub(store: Pick<exchange.Artifact, 'entries'>, now: number): boolean {
241
- let changed = false
242
- for (const [encoded, entry] of Object.entries(store.entries)) {
243
- const key = decodeKey(encoded)
244
- if (key === undefined || !validEntry(key, entry, now, 1)) {
245
- delete store.entries[encoded]
246
- changed = true
247
- }
248
- }
249
- return changed
250
- }