@astrale-os/sdk 0.5.0-beta.99 → 0.6.0-beta.0

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 (270) hide show
  1. package/README.md +165 -2
  2. package/dist/application/action/action.d.ts +7 -4
  3. package/dist/application/action/authoring.d.ts +2 -1
  4. package/dist/application/action/context.d.ts +18 -13
  5. package/dist/application/action/define.d.ts +5 -1
  6. package/dist/application/action/define.js +6 -1
  7. package/dist/application/action/index.d.ts +2 -1
  8. package/dist/application/dependency/index.d.ts +1 -0
  9. package/dist/application/dependency/invoker.d.ts +26 -0
  10. package/dist/application/error/error.d.ts +23 -0
  11. package/dist/application/error/error.js +87 -0
  12. package/dist/application/error/index.d.ts +2 -0
  13. package/dist/application/error/index.js +1 -0
  14. package/dist/application/index.d.ts +2 -2
  15. package/dist/application/integration/authentication.d.ts +10 -0
  16. package/dist/application/integration/authentication.typecheck.js +18 -0
  17. package/dist/application/integration/client.d.ts +2 -0
  18. package/dist/application/integration/client.js +19 -2
  19. package/dist/application/integration/index.d.ts +1 -0
  20. package/dist/application/integration/operation.d.ts +3 -0
  21. package/dist/application/mutation/authoring/builder.js +2 -2
  22. package/dist/application/mutation/authoring/endpoint.d.ts +3 -3
  23. package/dist/application/mutation/authoring/endpoint.js +9 -0
  24. package/dist/application/mutation/failure.js +13 -7
  25. package/dist/application/mutation/index.d.ts +1 -0
  26. package/dist/application/requirements/{profiles.d.ts → core.d.ts} +5 -3
  27. package/dist/application/requirements/{profiles.js → core.js} +6 -6
  28. package/dist/application/requirements/index.d.ts +4 -4
  29. package/dist/application/requirements/index.js +5 -5
  30. package/dist/application/requirements/requirement.d.ts +3 -2
  31. package/dist/application/runtime/authoring.d.ts +1 -0
  32. package/dist/application/runtime/callables.js +2 -2
  33. package/dist/application/runtime/declarations.d.ts +43 -0
  34. package/dist/application/runtime/define.d.ts +2 -1
  35. package/dist/application/view/index.d.ts +1 -1
  36. package/dist/application/view/route.d.ts +4 -0
  37. package/dist/application/view/route.js +5 -1
  38. package/dist/application/workflow/authoring.d.ts +1 -0
  39. package/dist/application/workflow/context.d.ts +2 -1
  40. package/dist/application/workflow/define.d.ts +5 -1
  41. package/dist/application/workflow/define.js +6 -1
  42. package/dist/application/workflow/index.d.ts +1 -0
  43. package/dist/application/workflow/runner/runner.d.ts +3 -2
  44. package/dist/application/workflow/workflow.d.ts +4 -3
  45. package/dist/deployment/adapter/adapter.d.ts +12 -7
  46. package/dist/deployment/adapter/define.d.ts +5 -2
  47. package/dist/deployment/adapter/define.js +15 -17
  48. package/dist/deployment/adapter/deploy/context.d.ts +6 -0
  49. package/dist/deployment/adapter/deploy/result.d.ts +2 -0
  50. package/dist/deployment/adapter/index.d.ts +2 -3
  51. package/dist/deployment/adapter/index.js +1 -1
  52. package/dist/deployment/adapter/prepare/context.d.ts +13 -5
  53. package/dist/deployment/authoring.d.ts +1 -1
  54. package/dist/deployment/build/compile.js +21 -19
  55. package/dist/deployment/build/frontend/compilation.d.ts +2 -1
  56. package/dist/deployment/build/frontend/compilation.js +1 -0
  57. package/dist/deployment/build/material.js +5 -5
  58. package/dist/deployment/deploy.d.ts +10 -4
  59. package/dist/deployment/deploy.js +5 -5
  60. package/dist/deployment/deployment.d.ts +8 -5
  61. package/dist/deployment/deployment.js +10 -1
  62. package/dist/deployment/index.d.ts +5 -4
  63. package/dist/deployment/index.js +3 -2
  64. package/dist/deployment/release/addressing.d.ts +6 -2
  65. package/dist/deployment/release/addressing.js +9 -4
  66. package/dist/deployment/release/publication/callables.js +1 -1
  67. package/dist/deployment/release/publication/index.d.ts +1 -1
  68. package/dist/deployment/release/publication/index.js +1 -1
  69. package/dist/deployment/release/publication/routes.js +1 -1
  70. package/dist/deployment/release/publication/seal.d.ts +0 -1
  71. package/dist/deployment/release/publication/seal.js +4 -5
  72. package/dist/deployment/release/publication/views.js +2 -1
  73. package/dist/deployment/verify/preflight/artifact.js +1 -1
  74. package/dist/deployment/verify/readiness/deployment.js +7 -3
  75. package/dist/deployment/verify/readiness/identity.js +1 -1
  76. package/dist/deployment/verify/readiness/publication.js +2 -2
  77. package/dist/execution/identity/authentication.js +0 -1
  78. package/dist/execution/identity/exchange.d.ts +1 -0
  79. package/dist/execution/identity/exchange.js +1 -1
  80. package/dist/execution/identity/jwks.js +1 -1
  81. package/dist/execution/invocation/admission/authentication.d.ts +6 -3
  82. package/dist/execution/invocation/admission/authentication.js +16 -6
  83. package/dist/execution/invocation/admission/authority.d.ts +2 -2
  84. package/dist/execution/invocation/dependency/bind.d.ts +5 -0
  85. package/dist/execution/invocation/dependency/bind.js +68 -0
  86. package/dist/execution/invocation/dependency/index.d.ts +1 -0
  87. package/dist/execution/invocation/dependency/index.js +1 -0
  88. package/dist/execution/invocation/dispatch/action.js +19 -2
  89. package/dist/execution/invocation/dispatch/context.d.ts +4 -4
  90. package/dist/execution/invocation/dispatch/context.js +29 -9
  91. package/dist/execution/invocation/dispatch/workflow.js +17 -4
  92. package/dist/execution/invocation/integration/authentication.d.ts +5 -0
  93. package/dist/execution/invocation/integration/authentication.js +53 -0
  94. package/dist/execution/invocation/integration/call.d.ts +7 -1
  95. package/dist/execution/invocation/integration/call.js +8 -3
  96. package/dist/execution/invocation/integration/clients.d.ts +2 -2
  97. package/dist/execution/invocation/integration/clients.js +2 -2
  98. package/dist/execution/invocation/lifecycle/active.js +30 -5
  99. package/dist/execution/invocation/result/errors.d.ts +1 -0
  100. package/dist/execution/invocation/result/errors.js +15 -10
  101. package/dist/execution/service/create.js +3 -1
  102. package/dist/execution/service/service.d.ts +1 -1
  103. package/dist/index.d.ts +3 -1
  104. package/dist/index.js +1 -0
  105. package/dist/platform/auth/index.d.ts +1 -1
  106. package/dist/platform/auth/index.js +0 -1
  107. package/dist/platform/graph/alias.d.ts +6 -0
  108. package/dist/platform/graph/alias.js +6 -0
  109. package/dist/platform/graph/document/index.d.ts +2 -1
  110. package/dist/platform/graph/document/index.js +2 -1
  111. package/dist/platform/graph/index.d.ts +2 -1
  112. package/dist/platform/graph/index.js +2 -1
  113. package/dist/platform/schema/class-authoring.d.ts +37 -0
  114. package/dist/platform/schema/class-authoring.js +20 -0
  115. package/dist/platform/schema/class-icon.d.ts +15 -0
  116. package/dist/platform/schema/class-icon.js +46 -0
  117. package/dist/platform/schema/error.d.ts +11 -0
  118. package/dist/platform/schema/error.js +34 -0
  119. package/dist/platform/schema/errors/index.d.ts +3 -0
  120. package/dist/platform/schema/errors/index.js +2 -0
  121. package/dist/platform/schema/icons/index.d.ts +2 -0
  122. package/dist/platform/schema/icons/index.js +2 -0
  123. package/dist/platform/schema/index.d.ts +20 -13
  124. package/dist/platform/schema/index.js +9 -4
  125. package/dist/platform/schema/kernel.d.ts +22 -0
  126. package/dist/platform/schema/kernel.js +5 -0
  127. package/dist/platform/schema/node-id.d.ts +3 -0
  128. package/dist/platform/schema/node-id.js +6 -0
  129. package/dist/platform/schema/property.d.ts +12 -0
  130. package/dist/platform/schema/property.js +3 -0
  131. package/dist/platform/schema/schema-authoring.d.ts +48 -0
  132. package/dist/platform/schema/schema-authoring.js +3 -0
  133. package/dist/platform/schema/state-property.d.ts +11 -0
  134. package/dist/platform/schema/state-property.js +3 -0
  135. package/dist/project/admit.d.ts +4 -0
  136. package/dist/project/admit.js +22 -0
  137. package/dist/project/define.d.ts +12 -0
  138. package/dist/project/define.js +106 -0
  139. package/dist/project/index.d.ts +4 -0
  140. package/dist/project/index.js +2 -0
  141. package/dist/project/project.d.ts +24 -0
  142. package/dist/project/project.js +1 -0
  143. package/dist/testing/dataset/admission.d.ts +13 -0
  144. package/dist/testing/dataset/admission.js +107 -0
  145. package/dist/testing/dataset/builder.d.ts +42 -0
  146. package/dist/testing/dataset/builder.js +127 -0
  147. package/dist/testing/dataset/codec.d.ts +6 -0
  148. package/dist/testing/dataset/codec.js +113 -0
  149. package/dist/testing/dataset/dataset.d.ts +58 -0
  150. package/dist/testing/dataset/dataset.js +2 -0
  151. package/dist/testing/dataset/define.d.ts +33 -0
  152. package/dist/testing/dataset/define.js +105 -0
  153. package/dist/testing/dataset/index.d.ts +8 -0
  154. package/dist/testing/dataset/index.js +4 -0
  155. package/dist/testing/dataset/references.d.ts +14 -0
  156. package/dist/testing/dataset/references.js +56 -0
  157. package/dist/testing/index.d.ts +9 -0
  158. package/dist/testing/index.js +5 -0
  159. package/dist/testing/load.d.ts +14 -0
  160. package/dist/testing/load.js +44 -0
  161. package/dist/testing/reference.d.ts +11 -0
  162. package/dist/testing/reference.js +19 -0
  163. package/dist/testing/tests.d.ts +12 -0
  164. package/dist/testing/tests.js +31 -0
  165. package/dist/tooling/cli/arguments.d.ts +7 -4
  166. package/dist/tooling/cli/arguments.js +82 -107
  167. package/dist/tooling/cli/astrale/authority.d.ts +5 -0
  168. package/dist/tooling/cli/astrale/authority.js +11 -0
  169. package/dist/tooling/cli/astrale/executable.d.ts +2 -0
  170. package/dist/tooling/cli/astrale/executable.js +47 -0
  171. package/dist/tooling/cli/astrale/failure.d.ts +6 -0
  172. package/dist/tooling/cli/astrale/failure.js +48 -0
  173. package/dist/tooling/cli/astrale/instance.d.ts +11 -0
  174. package/dist/tooling/cli/astrale/instance.js +52 -0
  175. package/dist/tooling/cli/astrale/process.d.ts +13 -0
  176. package/dist/tooling/cli/astrale/process.js +94 -0
  177. package/dist/tooling/cli/astrale/version.d.ts +18 -0
  178. package/dist/tooling/cli/astrale/version.js +55 -0
  179. package/dist/tooling/cli/bun.js +1 -1
  180. package/dist/tooling/cli/credential.d.ts +2 -0
  181. package/dist/tooling/cli/credential.js +57 -0
  182. package/dist/tooling/cli/development/candidate.d.ts +25 -0
  183. package/dist/tooling/cli/development/candidate.js +176 -0
  184. package/dist/tooling/cli/development/deployment.d.ts +16 -0
  185. package/dist/tooling/cli/development/deployment.js +39 -0
  186. package/dist/tooling/cli/development/develop.d.ts +4 -3
  187. package/dist/tooling/cli/development/develop.js +125 -289
  188. package/dist/tooling/cli/development/lease.d.ts +18 -0
  189. package/dist/tooling/cli/development/lease.js +163 -0
  190. package/dist/tooling/cli/development/lifecycle.js +4 -0
  191. package/dist/tooling/cli/development/project-imports.d.ts +22 -0
  192. package/dist/tooling/cli/development/project-imports.js +39 -0
  193. package/dist/tooling/cli/development/project-lock.d.ts +3 -4
  194. package/dist/tooling/cli/development/project-lock.js +14 -166
  195. package/dist/tooling/cli/development/release-evidence.d.ts +4 -0
  196. package/dist/tooling/cli/development/release-evidence.js +10 -0
  197. package/dist/tooling/cli/development/report.d.ts +6 -0
  198. package/dist/tooling/cli/development/report.js +14 -0
  199. package/dist/tooling/cli/development/source-watch.js +53 -5
  200. package/dist/tooling/cli/development/sources.d.ts +7 -0
  201. package/dist/tooling/cli/development/sources.js +48 -0
  202. package/dist/tooling/cli/development/target-lock.d.ts +16 -0
  203. package/dist/tooling/cli/development/target-lock.js +68 -0
  204. package/dist/tooling/cli/development/view.d.ts +28 -0
  205. package/dist/tooling/cli/development/view.js +151 -0
  206. package/dist/tooling/cli/environment-release.d.ts +21 -0
  207. package/dist/tooling/cli/environment-release.js +46 -0
  208. package/dist/tooling/cli/evidence.d.ts +11 -0
  209. package/dist/tooling/cli/evidence.js +53 -0
  210. package/dist/tooling/cli/help.js +78 -34
  211. package/dist/tooling/cli/index.d.ts +1 -1
  212. package/dist/tooling/cli/index.js +1 -1
  213. package/dist/tooling/cli/installation/index.d.ts +2 -0
  214. package/dist/tooling/cli/installation/index.js +1 -0
  215. package/dist/tooling/cli/installation/observation.d.ts +10 -0
  216. package/dist/tooling/cli/installation/observation.js +44 -0
  217. package/dist/tooling/cli/installation/reconcile.d.ts +32 -0
  218. package/dist/tooling/cli/installation/reconcile.js +122 -0
  219. package/dist/tooling/cli/orchestrate.js +84 -44
  220. package/dist/tooling/cli/project.d.ts +17 -0
  221. package/dist/tooling/cli/project.js +18 -0
  222. package/dist/tooling/cli/test.d.ts +12 -0
  223. package/dist/tooling/cli/test.js +47 -0
  224. package/dist/tooling/cli/upgrade/index.d.ts +6 -0
  225. package/dist/tooling/cli/upgrade/index.js +115 -0
  226. package/dist/tooling/cli/upgrade/manifest.d.ts +18 -0
  227. package/dist/tooling/cli/upgrade/manifest.js +77 -0
  228. package/dist/tooling/cli/upgrade/process.d.ts +2 -0
  229. package/dist/tooling/cli/upgrade/process.js +57 -0
  230. package/dist/tooling/linter/adapters/typescript/imports.js +2 -0
  231. package/dist/tooling/linter/adapters/typescript/index.d.ts +1 -0
  232. package/dist/tooling/linter/adapters/typescript/index.js +1 -0
  233. package/dist/tooling/linter/adapters/typescript/query-collection-type.js +4 -51
  234. package/dist/tooling/linter/adapters/typescript/type-analysis.d.ts +9 -0
  235. package/dist/tooling/linter/adapters/typescript/type-analysis.js +55 -0
  236. package/dist/tooling/linter/implementations/source/callable-requirements.d.ts +28 -0
  237. package/dist/tooling/linter/implementations/source/callable-requirements.js +234 -0
  238. package/dist/tooling/linter/implementations/source/dependencies.d.ts +2 -0
  239. package/dist/tooling/linter/implementations/source/dependencies.js +219 -0
  240. package/dist/tooling/linter/implementations/source/global.js +52 -2
  241. package/dist/tooling/linter/implementations/source/mutations.js +520 -38
  242. package/dist/tooling/linter/implementations/source/providers.js +19 -164
  243. package/dist/tooling/linter/implementations/source/schema.js +454 -2
  244. package/dist/tooling/linter/implementations/source/verifiers.js +2 -0
  245. package/dist/tooling/linter/implementations/source/workflows.js +8 -35
  246. package/dist/tooling/linter/policy/generated.js +2 -2
  247. package/dist/tooling/linter/requirements/registry.js +9 -3
  248. package/dist/tooling/packaging/declarations/normalize.js +3 -38
  249. package/dist/tooling/packaging/declarations/paths.d.ts +5 -0
  250. package/dist/tooling/packaging/declarations/paths.js +38 -0
  251. package/dist/tooling/packaging/finalize.d.ts +13 -0
  252. package/dist/tooling/packaging/finalize.js +62 -0
  253. package/dist/tooling/packaging/index.d.ts +2 -0
  254. package/dist/tooling/packaging/index.js +1 -0
  255. package/dist/tooling/packaging/javascript.d.ts +3 -0
  256. package/dist/tooling/packaging/javascript.js +45 -2
  257. package/dist/tooling/packaging/packaging.d.ts +2 -5
  258. package/dist/tooling/packaging/packaging.js +6 -30
  259. package/package.json +42 -12
  260. package/CHANGELOG.md +0 -1506
  261. package/dist/deployment/adapter/development/context.d.ts +0 -18
  262. package/dist/deployment/adapter/development/index.d.ts +0 -4
  263. package/dist/deployment/adapter/development/input.d.ts +0 -6
  264. package/dist/deployment/adapter/development/placement.d.ts +0 -15
  265. package/dist/deployment/adapter/development/session.d.ts +0 -9
  266. /package/dist/{deployment/adapter/development → application/dependency}/index.js +0 -0
  267. /package/dist/{deployment/adapter/development/context.js → application/dependency/invoker.js} +0 -0
  268. /package/dist/{deployment/adapter/development/input.js → application/integration/authentication.js} +0 -0
  269. /package/dist/{deployment/adapter/development/placement.js → application/integration/authentication.typecheck.d.ts} +0 -0
  270. /package/dist/{deployment/adapter/development/session.js → application/runtime/declarations.js} +0 -0
@@ -0,0 +1,52 @@
1
+ import { astraleFailure } from './failure.js';
2
+ import { runAstrale } from './process.js';
3
+ /** Resolve and probe a bookmark through the pinned CLI, preserving its TLS trust. */
4
+ export async function resolveAstraleInstanceIssuer(input, dependencies = { run: runAstrale }) {
5
+ const result = await dependencies.run({
6
+ executable: input.executable,
7
+ projectDir: input.projectDir,
8
+ signal: input.signal,
9
+ timeoutMs: 30_000,
10
+ args: ['--ci', '--no-prompt', 'instance', 'status', input.instance, '--bookmarked', '--json'],
11
+ });
12
+ if (result.code !== 0)
13
+ throw astraleFailure('instance status', result);
14
+ let value;
15
+ try {
16
+ value = JSON.parse(result.stdout);
17
+ }
18
+ catch {
19
+ throw new TypeError('Astrale instance status did not return one JSON value.');
20
+ }
21
+ if (value === null ||
22
+ typeof value !== 'object' ||
23
+ Array.isArray(value) ||
24
+ !('kind' in value) ||
25
+ value.kind !== 'bookmark' ||
26
+ !('state' in value) ||
27
+ value.state !== 'ready' ||
28
+ !('issuer' in value) ||
29
+ typeof value.issuer !== 'string') {
30
+ throw new TypeError('Astrale instance status returned invalid Kernel identity evidence.');
31
+ }
32
+ let issuer;
33
+ try {
34
+ issuer = new URL(value.issuer);
35
+ }
36
+ catch {
37
+ throw new TypeError('Astrale instance status returned an invalid Kernel issuer.');
38
+ }
39
+ if (!['https:', 'http:'].includes(issuer.protocol) ||
40
+ issuer.username ||
41
+ issuer.password ||
42
+ issuer.search ||
43
+ issuer.hash) {
44
+ throw new TypeError('Astrale instance status returned an invalid Kernel issuer.');
45
+ }
46
+ // Child Kernels share an origin, but their path-qualified identities remain distinct.
47
+ const canonical = issuer.href.replace(/\/$/u, '');
48
+ if (input.expectedIssuer !== undefined && canonical !== input.expectedIssuer) {
49
+ throw new Error('Installation bookmark changed Kernel; restart pnpm dev to apply it.');
50
+ }
51
+ return canonical;
52
+ }
@@ -0,0 +1,13 @@
1
+ export interface AstraleProcessResult {
2
+ readonly code: number;
3
+ readonly stdout: string;
4
+ readonly stderr: string;
5
+ }
6
+ /** Run one exact Kernel CLI executable with bounded output, time, and termination. */
7
+ export declare function runAstrale(input: {
8
+ readonly executable: string;
9
+ readonly args: readonly string[];
10
+ readonly projectDir: string;
11
+ readonly signal: AbortSignal;
12
+ readonly timeoutMs: number;
13
+ }): Promise<AstraleProcessResult>;
@@ -0,0 +1,94 @@
1
+ import { spawn } from 'node:child_process';
2
+ const OUTPUT_LIMIT = 256 * 1024;
3
+ const TERMINATION_GRACE_MS = 1_000;
4
+ /** Run one exact Kernel CLI executable with bounded output, time, and termination. */
5
+ export function runAstrale(input) {
6
+ if (input.signal.aborted)
7
+ return Promise.reject(abortError(input.signal));
8
+ return new Promise((resolve, reject) => {
9
+ let child;
10
+ try {
11
+ child = spawn(input.executable, [...input.args], {
12
+ cwd: input.projectDir,
13
+ stdio: ['pipe', 'pipe', 'pipe'],
14
+ shell: false,
15
+ // This owner already forwards cancellation and enforces a deadline. Keep
16
+ // terminal group signals from killing installation observation/View cleanup.
17
+ detached: process.platform !== 'win32',
18
+ });
19
+ child.stdin.end();
20
+ }
21
+ catch (cause) {
22
+ reject(new Error('Astrale CLI is unavailable.', { cause }));
23
+ return;
24
+ }
25
+ let stdout = '';
26
+ let stderr = '';
27
+ let stdoutBytes = 0;
28
+ let stderrBytes = 0;
29
+ let settled = false;
30
+ let termination;
31
+ let escalation;
32
+ const abort = () => terminate(input.signal.reason instanceof Error
33
+ ? input.signal.reason
34
+ : new Error('Project operation interrupted.'));
35
+ input.signal.addEventListener('abort', abort, { once: true });
36
+ const cleanup = () => {
37
+ clearTimeout(timeout);
38
+ if (escalation !== undefined)
39
+ clearTimeout(escalation);
40
+ input.signal.removeEventListener('abort', abort);
41
+ };
42
+ const terminate = (cause) => {
43
+ if (settled || termination !== undefined)
44
+ return;
45
+ termination = cause;
46
+ child.stdin.destroy();
47
+ child.kill('SIGTERM');
48
+ escalation = setTimeout(() => {
49
+ if (child.exitCode === null && child.signalCode === null)
50
+ child.kill('SIGKILL');
51
+ }, TERMINATION_GRACE_MS);
52
+ };
53
+ const timeout = setTimeout(() => terminate(new Error('Astrale CLI command timed out.')), input.timeoutMs);
54
+ child.stdout.on('data', (chunk) => {
55
+ stdoutBytes += chunk.byteLength;
56
+ if (stdoutBytes > OUTPUT_LIMIT) {
57
+ terminate(new Error('Astrale CLI stdout exceeded the supported limit.'));
58
+ }
59
+ else
60
+ stdout += chunk.toString('utf8');
61
+ });
62
+ child.stderr.on('data', (chunk) => {
63
+ stderrBytes += chunk.byteLength;
64
+ if (stderrBytes > OUTPUT_LIMIT) {
65
+ terminate(new Error('Astrale CLI stderr exceeded the supported limit.'));
66
+ }
67
+ else
68
+ stderr += chunk.toString('utf8');
69
+ });
70
+ child.once('error', (cause) => {
71
+ if (settled)
72
+ return;
73
+ settled = true;
74
+ cleanup();
75
+ reject(new Error('Astrale CLI could not be started.', { cause }));
76
+ });
77
+ child.once('close', (code) => {
78
+ if (settled)
79
+ return;
80
+ settled = true;
81
+ cleanup();
82
+ if (termination !== undefined) {
83
+ reject(termination);
84
+ return;
85
+ }
86
+ resolve(Object.freeze({ code: code ?? 1, stdout, stderr }));
87
+ });
88
+ });
89
+ }
90
+ function abortError(signal) {
91
+ return signal.reason instanceof Error
92
+ ? signal.reason
93
+ : new Error('Project operation interrupted.');
94
+ }
@@ -0,0 +1,18 @@
1
+ import type { AstraleProcessResult } from './process.js';
2
+ import { resolveAstraleExecutable } from './executable.js';
3
+ export declare const MINIMUM_KERNEL_CLI_VERSION = "1.0.0-beta.48";
4
+ export interface CompatibleAstraleDependencies {
5
+ readonly resolveExecutable: typeof resolveAstraleExecutable;
6
+ readonly run: (input: {
7
+ readonly executable: string;
8
+ readonly args: readonly string[];
9
+ readonly projectDir: string;
10
+ readonly signal: AbortSignal;
11
+ readonly timeoutMs: number;
12
+ }) => Promise<AstraleProcessResult>;
13
+ }
14
+ /** Pin and admit one compatible CLI before any configured Kernel installation effect. */
15
+ export declare function resolveCompatibleAstrale(input: {
16
+ readonly projectDir: string;
17
+ readonly signal: AbortSignal;
18
+ }, dependencies?: CompatibleAstraleDependencies): Promise<string>;
@@ -0,0 +1,55 @@
1
+ import { resolveAstraleExecutable } from './executable.js';
2
+ import { astraleFailure } from './failure.js';
3
+ import { runAstrale } from './process.js';
4
+ export const MINIMUM_KERNEL_CLI_VERSION = '1.0.0-beta.48';
5
+ /** Pin and admit one compatible CLI before any configured Kernel installation effect. */
6
+ export async function resolveCompatibleAstrale(input, dependencies = {
7
+ resolveExecutable: resolveAstraleExecutable,
8
+ run: runAstrale,
9
+ }) {
10
+ const executable = await dependencies.resolveExecutable();
11
+ const result = await dependencies.run({
12
+ executable,
13
+ projectDir: input.projectDir,
14
+ args: ['--version'],
15
+ signal: input.signal,
16
+ timeoutMs: 10_000,
17
+ });
18
+ if (result.code !== 0)
19
+ throw astraleFailure('version', result);
20
+ const version = result.stdout.trim().replace(/^v/u, '');
21
+ if (!isCompatible(version)) {
22
+ const diagnostic = semver(version) === undefined ? '<invalid>' : version;
23
+ throw new TypeError(`Astrale CLI ${diagnostic} is incompatible; ${MINIMUM_KERNEL_CLI_VERSION} or newer is required.`);
24
+ }
25
+ return executable;
26
+ }
27
+ function isCompatible(input) {
28
+ const value = semver(input);
29
+ const minimum = semver(MINIMUM_KERNEL_CLI_VERSION);
30
+ if (value === undefined)
31
+ return false;
32
+ for (let index = 0; index < 3; index += 1) {
33
+ if (value.core[index] > minimum.core[index])
34
+ return true;
35
+ if (value.core[index] < minimum.core[index])
36
+ return false;
37
+ }
38
+ if (value.prerelease === undefined)
39
+ return true;
40
+ if (minimum.prerelease === undefined)
41
+ return false;
42
+ if (value.prerelease.name !== minimum.prerelease.name) {
43
+ return value.prerelease.name.localeCompare(minimum.prerelease.name) > 0;
44
+ }
45
+ return value.prerelease.number >= minimum.prerelease.number;
46
+ }
47
+ function semver(input) {
48
+ const match = /^(\d+)\.(\d+)\.(\d+)(?:-([a-z]+)\.(\d+))?$/u.exec(input);
49
+ if (match === null)
50
+ return undefined;
51
+ return {
52
+ core: [Number(match[1]), Number(match[2]), Number(match[3])],
53
+ ...(match[4] === undefined ? {} : { prerelease: { name: match[4], number: Number(match[5]) } }),
54
+ };
55
+ }
@@ -2,7 +2,7 @@ import { spawn } from 'node:child_process';
2
2
  import { lstatSync, readFileSync, realpathSync, statSync } from 'node:fs';
3
3
  import { createRequire } from 'node:module';
4
4
  import { dirname, isAbsolute, join, relative, resolve } from 'node:path';
5
- const FORWARDED_SIGNALS = ['SIGINT', 'SIGTERM'];
5
+ const FORWARDED_SIGNALS = ['SIGINT', 'SIGTERM', 'SIGHUP'];
6
6
  export class BunRequiredError extends Error {
7
7
  constructor(options) {
8
8
  super('astrale-domain requires Bun to import astrale.config.ts and its Runtime module.', options);
@@ -0,0 +1,2 @@
1
+ /** Admit one caller-owned credential without retaining its value outside this command. */
2
+ export declare function loadPrivateCredentialFile(path: string, platform?: NodeJS.Platform): string;
@@ -0,0 +1,57 @@
1
+ import { closeSync, constants, fstatSync, openSync, readSync } from 'node:fs';
2
+ const MAXIMUM_CREDENTIAL_BYTES = 64 * 1024;
3
+ /** Admit one caller-owned credential without retaining its value outside this command. */
4
+ export function loadPrivateCredentialFile(path, platform = process.platform) {
5
+ if (platform === 'win32') {
6
+ throw new Error('--credential-file is unavailable on Windows until private no-reparse file admission is supported.');
7
+ }
8
+ let descriptor;
9
+ try {
10
+ descriptor = openSync(path, constants.O_RDONLY | constants.O_NOFOLLOW);
11
+ }
12
+ catch (cause) {
13
+ if (errorCode(cause) === 'ENOENT') {
14
+ throw new Error(`Credential file '${path}' is missing.`, { cause });
15
+ }
16
+ if (errorCode(cause) === 'ELOOP') {
17
+ throw new Error(`Credential file '${path}' must be a regular file and not a symlink.`, {
18
+ cause,
19
+ });
20
+ }
21
+ throw cause;
22
+ }
23
+ try {
24
+ const info = fstatSync(descriptor);
25
+ if (!info.isFile())
26
+ throw new Error(`Credential file '${path}' must be a regular file.`);
27
+ if ((info.mode & 0o077) !== 0) {
28
+ throw new Error(`Credential file '${path}' must not be accessible by group or other users.`);
29
+ }
30
+ if (info.size === 0 || info.size > MAXIMUM_CREDENTIAL_BYTES) {
31
+ throw new Error(`Credential file '${path}' must contain one bounded credential.`);
32
+ }
33
+ const bytes = Buffer.allocUnsafe(info.size + 1);
34
+ let offset = 0;
35
+ while (offset < bytes.length) {
36
+ const read = readSync(descriptor, bytes, offset, bytes.length - offset, null);
37
+ if (read === 0)
38
+ break;
39
+ offset += read;
40
+ }
41
+ if (offset !== info.size)
42
+ throw new Error(`Credential file '${path}' changed while read.`);
43
+ const credential = bytes.subarray(0, offset).toString('utf8').trim();
44
+ if (credential.length === 0 || /[\r\n\0]/u.test(credential)) {
45
+ throw new Error(`Credential file '${path}' must contain exactly one credential.`);
46
+ }
47
+ return credential;
48
+ }
49
+ finally {
50
+ closeSync(descriptor);
51
+ }
52
+ }
53
+ function errorCode(input) {
54
+ return input !== null && typeof input === 'object' && 'code' in input
55
+ ? String(Reflect.get(input, 'code'))
56
+ : undefined;
57
+ }
@@ -0,0 +1,25 @@
1
+ import type { Adapter, InstallationTarget, PreparedArtifact } from '../../../deployment/adapter/index.js';
2
+ export interface DevelopmentCandidate {
3
+ readonly adapter: Adapter<object>;
4
+ readonly parameters: object;
5
+ readonly installation?: InstallationTarget;
6
+ readonly artifact: PreparedArtifact;
7
+ readonly secrets: Readonly<Record<string, string>>;
8
+ readonly sources: ReadonlySet<string>;
9
+ }
10
+ /** Rebuild one complete, isolated Environment candidate from authored sources. */
11
+ export declare class DevelopmentCandidateBuilder {
12
+ #private;
13
+ constructor(input: {
14
+ readonly configPath: string;
15
+ readonly projectDir: string;
16
+ readonly environment: string;
17
+ readonly runtimePath: string;
18
+ readonly overrideSecrets?: Readonly<Record<string, string>>;
19
+ });
20
+ prepare(signal: AbortSignal): Promise<DevelopmentCandidate>;
21
+ }
22
+ export declare function discoverRuntimePath(configPath: string): Promise<string>;
23
+ export declare function sameEnvironment(current: DevelopmentCandidate, candidate: DevelopmentCandidate): boolean;
24
+ /** Identify a rebuilt candidate that cannot change provider or installation state. */
25
+ export declare function sameDeploymentCandidate(current: DevelopmentCandidate, candidate: DevelopmentCandidate): boolean;
@@ -0,0 +1,176 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { mkdir, rm, writeFile } from 'node:fs/promises';
3
+ import { dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';
4
+ import { pathToFileURL } from 'node:url';
5
+ import { admitRuntime, compile, resolveRuntime, runtime, verifyPreflight, } from '../../../deployment/index.js';
6
+ import { admitProjectModule } from '../../../project/index.js';
7
+ import { loadDeclaredSecrets } from '../dotenv.js';
8
+ import { selectEnvironment } from '../project.js';
9
+ import { projectImportPlugin } from './project-imports.js';
10
+ import { DevelopmentSources } from './sources.js';
11
+ /** Rebuild one complete, isolated Environment candidate from authored sources. */
12
+ export class DevelopmentCandidateBuilder {
13
+ #configPath;
14
+ #projectDir;
15
+ #environment;
16
+ #runtimePath;
17
+ #overrideSecrets;
18
+ #generation = 0;
19
+ constructor(input) {
20
+ this.#configPath = input.configPath;
21
+ this.#projectDir = input.projectDir;
22
+ this.#environment = input.environment;
23
+ this.#runtimePath = input.runtimePath;
24
+ this.#overrideSecrets = input.overrideSecrets;
25
+ }
26
+ async prepare(signal) {
27
+ throwIfAborted(signal);
28
+ const directory = join(this.#projectDir, '.astrale', 'development', this.#environment, 'source', String(++this.#generation));
29
+ await mkdir(directory, { recursive: true });
30
+ const bridge = join(directory, 'bridge.ts');
31
+ const sources = new DevelopmentSources(this.#projectDir);
32
+ sources.record(join(this.#projectDir, 'package.json'));
33
+ const configImport = moduleSpecifier(dirname(bridge), this.#configPath);
34
+ const runtimeImport = moduleSpecifier(dirname(bridge), resolve(dirname(this.#configPath), this.#runtimePath));
35
+ await writeFile(bridge, `export { default as project } from ${JSON.stringify(configImport)}\n` +
36
+ `export { default as runtime } from ${JSON.stringify(runtimeImport)}\n`);
37
+ try {
38
+ const bunRuntime = bun();
39
+ const built = await bunRuntime.build({
40
+ entrypoints: [bridge],
41
+ outdir: directory,
42
+ naming: 'application.mjs',
43
+ target: 'bun',
44
+ format: 'esm',
45
+ packages: 'bundle',
46
+ plugins: [projectImportPlugin(this.#projectDir, bunRuntime)],
47
+ splitting: false,
48
+ sourcemap: 'inline',
49
+ metafile: true,
50
+ throw: false,
51
+ });
52
+ throwIfAborted(signal);
53
+ if (!built.success) {
54
+ const diagnostics = built.logs.map(({ message, position }) => position === undefined || position === null
55
+ ? message
56
+ : `${relative(this.#projectDir, position.file)}:${position.line}:${position.column}: ${message}`);
57
+ throw new Error(['Authored Application rebuild failed.', ...diagnostics].join('\n'));
58
+ }
59
+ const output = built.outputs.find((candidate) => candidate.path.endsWith('application.mjs'));
60
+ if (output === undefined)
61
+ throw new Error('Authored Application rebuild produced no module.');
62
+ const loaded = (await import(`${pathToFileURL(output.path).href}?development=${this.#generation}`));
63
+ if (Object.keys(loaded).some((key) => key !== 'project' && key !== 'runtime')) {
64
+ throw new TypeError('Development bridge produced unexpected exports.');
65
+ }
66
+ const project = admitProjectModule({ default: loaded.project });
67
+ if ((project.entrypoints?.runtime ?? './runtime.ts') !== this.#runtimePath) {
68
+ throw new Error('Runtime entrypoint changed; restart pnpm dev to apply it.');
69
+ }
70
+ const environment = selectEnvironment(project, this.#environment);
71
+ const resolved = await resolveRuntime(runtime(this.#runtimePath), async (path) => {
72
+ if (path !== this.#runtimePath) {
73
+ throw new Error('Runtime entrypoint changed; restart pnpm dev to apply it.');
74
+ }
75
+ return Object.freeze({ default: loaded.runtime });
76
+ });
77
+ const build = compile(project.application);
78
+ admitRuntime({ runtime: build.runtime }, resolved);
79
+ const adapter = environment.deployment.adapter;
80
+ const parameters = environment.deployment.parameters;
81
+ for (const path of Object.keys(built.metafile?.inputs ?? {}))
82
+ sources.record(path);
83
+ const source = await adapter.prepare(parameters, {
84
+ projectDir: this.#projectDir,
85
+ environment: this.#environment,
86
+ ...(environment.installation === undefined
87
+ ? {}
88
+ : { installation: environment.installation }),
89
+ mode: 'release',
90
+ recordSource: sources.record,
91
+ signal,
92
+ build,
93
+ runtime: resolved,
94
+ });
95
+ const artifact = verifyPreflight({ build, runtime: resolved, source });
96
+ const declared = this.#overrideSecrets === undefined
97
+ ? secretsFor(adapter, parameters, this.#projectDir, resolved.runtime)
98
+ : { values: this.#overrideSecrets };
99
+ if (declared.path !== undefined)
100
+ sources.record(declared.path);
101
+ return Object.freeze({
102
+ adapter,
103
+ parameters,
104
+ ...(environment.installation === undefined
105
+ ? {}
106
+ : { installation: environment.installation }),
107
+ artifact,
108
+ secrets: declared.values,
109
+ sources: sources.snapshot(),
110
+ });
111
+ }
112
+ finally {
113
+ await rm(directory, { recursive: true, force: true });
114
+ }
115
+ }
116
+ }
117
+ export async function discoverRuntimePath(configPath) {
118
+ const loaded = (await import(`${pathToFileURL(configPath).href}?discover=${Date.now()}`));
119
+ const project = admitProjectModule(loaded);
120
+ return project.entrypoints?.runtime ?? './runtime.ts';
121
+ }
122
+ export function sameEnvironment(current, candidate) {
123
+ return (candidate.adapter.name === current.adapter.name &&
124
+ candidate.adapter.version === current.adapter.version &&
125
+ candidate.artifact.build.schema.compiled.root.origin ===
126
+ current.artifact.build.schema.compiled.root.origin &&
127
+ stable(candidate.parameters) === stable(current.parameters) &&
128
+ stable(candidate.installation) === stable(current.installation));
129
+ }
130
+ /** Identify a rebuilt candidate that cannot change provider or installation state. */
131
+ export function sameDeploymentCandidate(current, candidate) {
132
+ return (sameEnvironment(current, candidate) &&
133
+ candidate.artifact.build.schema.compiled.root.revision ===
134
+ current.artifact.build.schema.compiled.root.revision &&
135
+ candidate.artifact.digest === current.artifact.digest &&
136
+ stable(candidate.secrets) === stable(current.secrets));
137
+ }
138
+ function secretsFor(adapter, parameters, projectDir, selectedRuntime) {
139
+ const file = adapter.secretsFile?.(parameters);
140
+ if (file === undefined)
141
+ return { values: Object.freeze({}) };
142
+ const path = isAbsolute(file) ? file : join(projectDir, file);
143
+ if (Object.keys(selectedRuntime.integrations).length === 0 && !existsSync(path)) {
144
+ return { values: Object.freeze({}) };
145
+ }
146
+ return { values: Object.freeze(loadDeclaredSecrets(path, file)), path };
147
+ }
148
+ function bun() {
149
+ const value = Reflect.get(globalThis, 'Bun');
150
+ if (value === undefined || typeof value.build !== 'function') {
151
+ throw new TypeError('Domain development requires the Bun runtime.');
152
+ }
153
+ return value;
154
+ }
155
+ function moduleSpecifier(from, target) {
156
+ const path = relative(from, target).split(sep).join('/');
157
+ return path.startsWith('.') ? path : `./${path}`;
158
+ }
159
+ function stable(input) {
160
+ if (input === undefined)
161
+ return 'undefined';
162
+ if (input === null || typeof input !== 'object')
163
+ return JSON.stringify(input);
164
+ if (Array.isArray(input))
165
+ return `[${input.map(stable).join(',')}]`;
166
+ const record = input;
167
+ return `{${Object.keys(record)
168
+ .sort()
169
+ .map((key) => `${JSON.stringify(key)}:${stable(record[key])}`)
170
+ .join(',')}}`;
171
+ }
172
+ function throwIfAborted(signal) {
173
+ if (signal.aborted) {
174
+ throw signal.reason instanceof Error ? signal.reason : new Error('Development interrupted.');
175
+ }
176
+ }
@@ -0,0 +1,16 @@
1
+ import type { ReadyDeployResult } from '../../../deployment/adapter/index.js';
2
+ import type { InstallationEvidence } from '../installation/index.js';
3
+ import type { DevelopmentCandidate } from './candidate.js';
4
+ export interface DevelopmentDeploymentInput {
5
+ readonly projectDir: string;
6
+ readonly environment: string;
7
+ readonly deployOnly: boolean;
8
+ readonly identity?: string;
9
+ readonly credential?: string;
10
+ readonly installationExecutable?: string;
11
+ }
12
+ /** Commit and verify one complete remote candidate, then reconcile its optional installation. */
13
+ export declare function deployDevelopmentCandidate(candidate: DevelopmentCandidate, input: DevelopmentDeploymentInput, signal: AbortSignal): Promise<{
14
+ readonly deployment: ReadyDeployResult;
15
+ readonly installation?: InstallationEvidence;
16
+ }>;
@@ -0,0 +1,39 @@
1
+ import { verifyDeployment } from '../../../deployment/index.js';
2
+ import { reconcileEnvironmentRelease } from '../environment-release.js';
3
+ /** Commit and verify one complete remote candidate, then reconcile its optional installation. */
4
+ export async function deployDevelopmentCandidate(candidate, input, signal) {
5
+ const deployed = await candidate.adapter.deploy(candidate.parameters, {
6
+ projectDir: input.projectDir,
7
+ environment: input.environment,
8
+ ...(candidate.installation === undefined ? {} : { installation: candidate.installation }),
9
+ ...(input.identity === undefined ? {} : { identity: input.identity }),
10
+ ...(input.credential === undefined ? {} : { credential: input.credential }),
11
+ secrets: candidate.secrets,
12
+ artifact: candidate.artifact,
13
+ signal,
14
+ });
15
+ const verified = verifyDeployment(candidate.artifact, deployed);
16
+ if (verified.status === 'failed') {
17
+ throw new Error(`Deployment failed during ${verified.phase}: ${verified.error.message}`, {
18
+ cause: verified.error,
19
+ });
20
+ }
21
+ const installation = await reconcileEnvironmentRelease({
22
+ projectDir: input.projectDir,
23
+ environment: input.environment,
24
+ adapter: candidate.adapter,
25
+ deployment: verified,
26
+ ...(candidate.installation === undefined ? {} : { installation: candidate.installation }),
27
+ deployOnly: input.deployOnly,
28
+ ...(input.installationExecutable === undefined
29
+ ? {}
30
+ : { installationExecutable: input.installationExecutable }),
31
+ ...(input.identity === undefined ? {} : { identity: input.identity }),
32
+ ...(input.credential === undefined ? {} : { credential: input.credential }),
33
+ signal,
34
+ });
35
+ return Object.freeze({
36
+ deployment: verified,
37
+ ...(installation === undefined ? {} : { installation }),
38
+ });
39
+ }
@@ -1,10 +1,11 @@
1
- import type { DevelopmentOverrides } from '../../../deployment/adapter/index.js';
2
- /** Run one complete provider-neutral development session until interruption. */
1
+ /** Watch one Project Environment and serialize complete remote deployment generations. */
3
2
  export declare function develop(input: {
4
3
  readonly configPath: string;
5
4
  readonly projectDir: string;
6
5
  readonly environment: string;
7
- readonly overrides: DevelopmentOverrides;
6
+ readonly deployOnly: boolean;
7
+ readonly identity?: string;
8
+ readonly credentialFile?: string;
8
9
  readonly sessionFile?: string;
9
10
  readonly secretsFile?: string;
10
11
  }): Promise<number>;