@tiangong-lca/cli 0.1.9 → 0.1.10

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 (70) hide show
  1. package/README.md +8 -5
  2. package/assets/runtime/cli-runtime-descriptor.schema.json +138 -0
  3. package/assets/runtime/cli-runtime-expectation.schema.json +38 -0
  4. package/assets/runtime/runtime-bootstrap-lock.schema.json +254 -0
  5. package/assets/runtime/runtime-command-result.schema.json +95 -0
  6. package/assets/runtime/runtime-manifest.schema.json +380 -0
  7. package/dist/src/cli.js +5 -1
  8. package/dist/src/cli.js.map +1 -1
  9. package/dist/src/lib/dataset-import-lca.js +2 -2
  10. package/dist/src/lib/dataset-import-lca.js.map +1 -1
  11. package/dist/src/lib/runtime/archive-writer.d.ts +7 -0
  12. package/dist/src/lib/runtime/archive-writer.js +89 -0
  13. package/dist/src/lib/runtime/archive-writer.js.map +1 -0
  14. package/dist/src/lib/runtime/archive.d.ts +2 -0
  15. package/dist/src/lib/runtime/archive.js +122 -0
  16. package/dist/src/lib/runtime/archive.js.map +1 -0
  17. package/dist/src/lib/runtime/command.d.ts +8 -0
  18. package/dist/src/lib/runtime/command.js +57 -0
  19. package/dist/src/lib/runtime/command.js.map +1 -0
  20. package/dist/src/lib/runtime/descriptor.d.ts +11 -0
  21. package/dist/src/lib/runtime/descriptor.js +126 -0
  22. package/dist/src/lib/runtime/descriptor.js.map +1 -0
  23. package/dist/src/lib/runtime/download.d.ts +9 -0
  24. package/dist/src/lib/runtime/download.js +118 -0
  25. package/dist/src/lib/runtime/download.js.map +1 -0
  26. package/dist/src/lib/runtime/exec-command.d.ts +7 -0
  27. package/dist/src/lib/runtime/exec-command.js +83 -0
  28. package/dist/src/lib/runtime/exec-command.js.map +1 -0
  29. package/dist/src/lib/runtime/execute.d.ts +11 -0
  30. package/dist/src/lib/runtime/execute.js +125 -0
  31. package/dist/src/lib/runtime/execute.js.map +1 -0
  32. package/dist/src/lib/runtime/files.d.ts +7 -0
  33. package/dist/src/lib/runtime/files.js +91 -0
  34. package/dist/src/lib/runtime/files.js.map +1 -0
  35. package/dist/src/lib/runtime/host.d.ts +8 -0
  36. package/dist/src/lib/runtime/host.js +37 -0
  37. package/dist/src/lib/runtime/host.js.map +1 -0
  38. package/dist/src/lib/runtime/leases.d.ts +12 -0
  39. package/dist/src/lib/runtime/leases.js +72 -0
  40. package/dist/src/lib/runtime/leases.js.map +1 -0
  41. package/dist/src/lib/runtime/managed-command.d.ts +6 -0
  42. package/dist/src/lib/runtime/managed-command.js +99 -0
  43. package/dist/src/lib/runtime/managed-command.js.map +1 -0
  44. package/dist/src/lib/runtime/manager.d.ts +33 -0
  45. package/dist/src/lib/runtime/manager.js +196 -0
  46. package/dist/src/lib/runtime/manager.js.map +1 -0
  47. package/dist/src/lib/runtime/manifest-types.d.ts +73 -0
  48. package/dist/src/lib/runtime/manifest-types.js +4 -0
  49. package/dist/src/lib/runtime/manifest-types.js.map +1 -0
  50. package/dist/src/lib/runtime/manifest-values.d.ts +15 -0
  51. package/dist/src/lib/runtime/manifest-values.js +124 -0
  52. package/dist/src/lib/runtime/manifest-values.js.map +1 -0
  53. package/dist/src/lib/runtime/manifest.d.ts +7 -0
  54. package/dist/src/lib/runtime/manifest.js +220 -0
  55. package/dist/src/lib/runtime/manifest.js.map +1 -0
  56. package/dist/src/lib/runtime/process.d.ts +3 -0
  57. package/dist/src/lib/runtime/process.js +55 -0
  58. package/dist/src/lib/runtime/process.js.map +1 -0
  59. package/dist/src/lib/runtime/storage.d.ts +8 -0
  60. package/dist/src/lib/runtime/storage.js +142 -0
  61. package/dist/src/lib/runtime/storage.js.map +1 -0
  62. package/dist/src/lib/runtime/types.d.ts +45 -0
  63. package/dist/src/lib/runtime/types.js +9 -0
  64. package/dist/src/lib/runtime/types.js.map +1 -0
  65. package/dist/src/main.js +13 -1
  66. package/dist/src/main.js.map +1 -1
  67. package/dist/src/runtime.d.ts +15 -0
  68. package/dist/src/runtime.js +22 -0
  69. package/dist/src/runtime.js.map +1 -0
  70. package/package.json +5 -1
@@ -0,0 +1,55 @@
1
+ import { spawn } from 'node:child_process';
2
+ /** Resolve only after close, including cancellation and output overflow, so callers retain component leases. */
3
+ export function spawnRuntimeProcess(executable, argv, options) {
4
+ return new Promise((resolve) => {
5
+ const child = spawn(executable, [...argv], {
6
+ cwd: options.cwd,
7
+ env: options.env,
8
+ shell: false,
9
+ windowsHide: true,
10
+ stdio: ['ignore', 'pipe', 'pipe'],
11
+ });
12
+ const stdout = [], stderr = [];
13
+ let bytes = 0;
14
+ let error;
15
+ let force;
16
+ const stop = () => {
17
+ child.kill('SIGTERM');
18
+ force ??= setTimeout(() => child.kill('SIGKILL'), 3000);
19
+ };
20
+ const abort = () => {
21
+ error = new Error('Runtime execution was interrupted.');
22
+ stop();
23
+ };
24
+ options.signal.addEventListener('abort', abort, { once: true });
25
+ if (options.signal.aborted)
26
+ abort();
27
+ const capture = (target, chunk) => {
28
+ bytes += chunk.length;
29
+ if (bytes > (options.maxBuffer ?? 16 * 1024 * 1024)) {
30
+ error = new Error('Runtime output exceeded its bound.');
31
+ stop();
32
+ return;
33
+ }
34
+ target.push(chunk);
35
+ };
36
+ child.stdout.on('data', (chunk) => capture(stdout, chunk));
37
+ child.stderr.on('data', (chunk) => capture(stderr, chunk));
38
+ child.once('error', (value) => {
39
+ error = value;
40
+ });
41
+ child.once('close', (status, signal) => {
42
+ if (force)
43
+ clearTimeout(force);
44
+ options.signal.removeEventListener('abort', abort);
45
+ resolve({
46
+ stdout: Buffer.concat(stdout).toString('utf8'),
47
+ stderr: Buffer.concat(stderr).toString('utf8'),
48
+ status,
49
+ signal,
50
+ ...(error ? { error } : {}),
51
+ });
52
+ });
53
+ });
54
+ }
55
+ //# sourceMappingURL=process.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process.js","sourceRoot":"","sources":["../../../../src/lib/runtime/process.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from 'node:child_process';\nimport type {\n FoundryCommandSpecAsyncSpawnOptions,\n FoundryCommandSpecSpawnResult,\n} from '../../command-spec.js';\n\n/** Resolve only after close, including cancellation and output overflow, so callers retain component leases. */\nexport function spawnRuntimeProcess(\n executable: string,\n argv: readonly string[],\n options: FoundryCommandSpecAsyncSpawnOptions,\n): Promise<FoundryCommandSpecSpawnResult> {\n return new Promise((resolve) => {\n const child = spawn(executable, [...argv], {\n cwd: options.cwd,\n env: options.env,\n shell: false,\n windowsHide: true,\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n const stdout: Buffer[] = [],\n stderr: Buffer[] = [];\n let bytes = 0;\n let error: Error | undefined;\n let force: NodeJS.Timeout | undefined;\n const stop = () => {\n child.kill('SIGTERM');\n force ??= setTimeout(() => child.kill('SIGKILL'), 3000);\n };\n const abort = () => {\n error = new Error('Runtime execution was interrupted.');\n stop();\n };\n options.signal.addEventListener('abort', abort, { once: true });\n if (options.signal.aborted) abort();\n const capture = (target: Buffer[], chunk: Buffer) => {\n bytes += chunk.length;\n if (bytes > (options.maxBuffer ?? 16 * 1024 * 1024)) {\n error = new Error('Runtime output exceeded its bound.');\n stop();\n return;\n }\n target.push(chunk);\n };\n child.stdout.on('data', (chunk: Buffer) => capture(stdout, chunk));\n child.stderr.on('data', (chunk: Buffer) => capture(stderr, chunk));\n child.once('error', (value) => {\n error = value;\n });\n child.once('close', (status, signal) => {\n if (force) clearTimeout(force);\n options.signal.removeEventListener('abort', abort);\n resolve({\n stdout: Buffer.concat(stdout).toString('utf8'),\n stderr: Buffer.concat(stderr).toString('utf8'),\n status,\n signal,\n ...(error ? { error } : {}),\n });\n });\n });\n}\n"]}
@@ -0,0 +1,8 @@
1
+ export declare function defaultRuntimeCache(env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform): string;
2
+ export declare function canonicalCacheRoot(value: string): string;
3
+ export declare function cachePath(root: string, relative: string): string;
4
+ export declare function writeAll(fd: number, bytes: Uint8Array): void;
5
+ export declare function writeOnce(root: string, relative: string, bytes: Uint8Array): void;
6
+ export declare function openRuntimeCache(value: string, create: boolean): string;
7
+ export declare function readCacheJson(root: string, relative: string, limit?: number): unknown;
8
+ export declare function ensureRuntimeCache(value: string): Promise<string>;
@@ -0,0 +1,142 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import os from 'node:os';
4
+ import { randomUUID } from 'node:crypto';
5
+ import { withBatchRunLock } from '../../batch.js';
6
+ import { runtimeError } from './files.js';
7
+ const marker = Buffer.from('{"schema":"tiangong-lca.runtime-cache.v1"}\n');
8
+ export function defaultRuntimeCache(env = process.env, platform = process.platform) {
9
+ const home = env.HOME || env.USERPROFILE || os.homedir();
10
+ const base = platform === 'darwin'
11
+ ? path.join(home, 'Library', 'Caches')
12
+ : platform === 'win32'
13
+ ? env.LOCALAPPDATA || path.join(home, 'AppData', 'Local')
14
+ : env.XDG_CACHE_HOME || path.join(home, '.cache');
15
+ return path.join(base, 'tiangong-lca', 'runtimes', 'v1');
16
+ }
17
+ export function canonicalCacheRoot(value) {
18
+ if (!path.isAbsolute(value))
19
+ runtimeError('RUNTIME_CACHE_PATH', 'Runtime cache must be an absolute directory.');
20
+ const missing = [];
21
+ let current = path.resolve(value);
22
+ while (!fs.existsSync(current)) {
23
+ missing.unshift(path.basename(current));
24
+ const parent = path.dirname(current);
25
+ if (parent === current)
26
+ runtimeError('RUNTIME_CACHE_PATH', 'Runtime cache has no existing parent.');
27
+ current = parent;
28
+ }
29
+ if (missing.length && !fs.statSync(current).isDirectory())
30
+ runtimeError('RUNTIME_CACHE_PATH', 'Runtime cache parent must be a directory.');
31
+ const root = path.join(fs.realpathSync(current), ...missing);
32
+ if (root === path.parse(root).root || root === os.homedir())
33
+ runtimeError('RUNTIME_CACHE_PATH', 'A filesystem or home root cannot be a runtime cache.');
34
+ return root;
35
+ }
36
+ export function cachePath(root, relative) {
37
+ if (!relative ||
38
+ relative.includes('\\') ||
39
+ path.isAbsolute(relative) ||
40
+ relative.split(/[\\/]/u).some((part) => !part || part === '.' || part === '..'))
41
+ runtimeError('RUNTIME_CACHE_PATH', 'Cache paths must remain within the owned root.');
42
+ let current = root;
43
+ for (const segment of ['', ...relative.split('/')]) {
44
+ if (segment)
45
+ current = path.join(current, segment);
46
+ try {
47
+ const stat = fs.lstatSync(current);
48
+ if (stat.isSymbolicLink() || (current !== path.join(root, relative) && !stat.isDirectory()))
49
+ runtimeError('RUNTIME_CACHE_PATH', 'Cache paths cannot traverse links or non-directories.');
50
+ }
51
+ catch (error) {
52
+ if (error.code !== 'ENOENT')
53
+ throw error;
54
+ }
55
+ }
56
+ return current;
57
+ }
58
+ export function writeAll(fd, bytes) {
59
+ let offset = 0;
60
+ while (offset < bytes.byteLength) {
61
+ const wrote = fs.writeSync(fd, bytes, offset, bytes.byteLength - offset);
62
+ if (wrote <= 0)
63
+ runtimeError('RUNTIME_WRITE_FAILED', 'Runtime artifact could not be written completely.');
64
+ offset += wrote;
65
+ }
66
+ }
67
+ export function writeOnce(root, relative, bytes) {
68
+ const target = cachePath(root, relative);
69
+ fs.mkdirSync(path.dirname(target), { recursive: true, mode: 0o700 });
70
+ cachePath(root, relative);
71
+ if (fs.existsSync(target)) {
72
+ if (!fs.lstatSync(target).isFile() || !fs.readFileSync(target).equals(Buffer.from(bytes)))
73
+ runtimeError('RUNTIME_CACHE_CONFLICT', 'An immutable cache record cannot be replaced.');
74
+ return;
75
+ }
76
+ const temp = cachePath(root, `${relative}.${randomUUID()}.tmp`);
77
+ const fd = fs.openSync(temp, 'wx', 0o600);
78
+ try {
79
+ writeAll(fd, bytes);
80
+ fs.fsyncSync(fd);
81
+ }
82
+ finally {
83
+ fs.closeSync(fd);
84
+ }
85
+ try {
86
+ try {
87
+ fs.linkSync(temp, target);
88
+ }
89
+ catch (error) {
90
+ if (error.code !== 'EEXIST')
91
+ throw error;
92
+ if (!fs.readFileSync(target).equals(Buffer.from(bytes)))
93
+ runtimeError('RUNTIME_CACHE_CONFLICT', 'Concurrent cache records disagree.');
94
+ }
95
+ }
96
+ finally {
97
+ fs.unlinkSync(temp);
98
+ }
99
+ }
100
+ export function openRuntimeCache(value, create) {
101
+ const root = canonicalCacheRoot(value);
102
+ const file = cachePath(root, '.runtime-cache.json');
103
+ if (!fs.existsSync(file)) {
104
+ if (fs.existsSync(root) &&
105
+ (!fs.lstatSync(root).isDirectory() || fs.readdirSync(root).length > 0))
106
+ runtimeError('RUNTIME_CACHE_UNOWNED', 'Existing data is not a runtime-manager cache.');
107
+ if (!create)
108
+ return root;
109
+ fs.mkdirSync(root, { recursive: true, mode: 0o700 });
110
+ writeOnce(root, '.runtime-cache.json', marker);
111
+ }
112
+ if (!fs.lstatSync(file).isFile() ||
113
+ fs.lstatSync(file).size !== marker.length ||
114
+ !fs.readFileSync(file).equals(marker))
115
+ runtimeError('RUNTIME_CACHE_UNOWNED', 'Runtime cache ownership marker is invalid.');
116
+ return root;
117
+ }
118
+ export function readCacheJson(root, relative, limit = 1024 * 1024) {
119
+ const file = cachePath(root, relative);
120
+ const stat = fs.lstatSync(file);
121
+ if (!stat.isFile() || stat.size > limit)
122
+ runtimeError('RUNTIME_CACHE_RECORD', 'Runtime cache record must be a bounded regular file.');
123
+ const bytes = fs.readFileSync(file);
124
+ if (bytes.length > limit)
125
+ runtimeError('RUNTIME_CACHE_RECORD', 'Runtime cache record grew while reading.');
126
+ try {
127
+ return JSON.parse(bytes.toString('utf8'));
128
+ }
129
+ catch {
130
+ runtimeError('RUNTIME_CACHE_RECORD', 'Runtime cache record is not complete JSON.');
131
+ }
132
+ }
133
+ export async function ensureRuntimeCache(value) {
134
+ const root = canonicalCacheRoot(value);
135
+ fs.mkdirSync(path.dirname(root), { recursive: true, mode: 0o700 });
136
+ return withBatchRunLock({
137
+ runPath: `${root}.initialize.json`,
138
+ identity: { schema: 'runtime-cache-initialize.v1', root },
139
+ reason: 'Runtime cache initialization',
140
+ }, () => openRuntimeCache(root, true));
141
+ }
142
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../../../src/lib/runtime/storage.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport os from 'node:os';\nimport { randomUUID } from 'node:crypto';\nimport { withBatchRunLock } from '../../batch.js';\nimport { runtimeError } from './files.js';\nconst marker = Buffer.from('{\"schema\":\"tiangong-lca.runtime-cache.v1\"}\\n');\n\nexport function defaultRuntimeCache(\n env: NodeJS.ProcessEnv = process.env,\n platform: NodeJS.Platform = process.platform,\n): string {\n const home = env.HOME || env.USERPROFILE || os.homedir();\n const base =\n platform === 'darwin'\n ? path.join(home, 'Library', 'Caches')\n : platform === 'win32'\n ? env.LOCALAPPDATA || path.join(home, 'AppData', 'Local')\n : env.XDG_CACHE_HOME || path.join(home, '.cache');\n return path.join(base, 'tiangong-lca', 'runtimes', 'v1');\n}\nexport function canonicalCacheRoot(value: string): string {\n if (!path.isAbsolute(value))\n runtimeError('RUNTIME_CACHE_PATH', 'Runtime cache must be an absolute directory.');\n const missing: string[] = [];\n let current = path.resolve(value);\n while (!fs.existsSync(current)) {\n missing.unshift(path.basename(current));\n const parent = path.dirname(current);\n if (parent === current)\n runtimeError('RUNTIME_CACHE_PATH', 'Runtime cache has no existing parent.');\n current = parent;\n }\n if (missing.length && !fs.statSync(current).isDirectory())\n runtimeError('RUNTIME_CACHE_PATH', 'Runtime cache parent must be a directory.');\n const root = path.join(fs.realpathSync(current), ...missing);\n if (root === path.parse(root).root || root === os.homedir())\n runtimeError('RUNTIME_CACHE_PATH', 'A filesystem or home root cannot be a runtime cache.');\n return root;\n}\nexport function cachePath(root: string, relative: string): string {\n if (\n !relative ||\n relative.includes('\\\\') ||\n path.isAbsolute(relative) ||\n relative.split(/[\\\\/]/u).some((part) => !part || part === '.' || part === '..')\n )\n runtimeError('RUNTIME_CACHE_PATH', 'Cache paths must remain within the owned root.');\n let current = root;\n for (const segment of ['', ...relative.split('/')]) {\n if (segment) current = path.join(current, segment);\n try {\n const stat = fs.lstatSync(current);\n if (stat.isSymbolicLink() || (current !== path.join(root, relative) && !stat.isDirectory()))\n runtimeError('RUNTIME_CACHE_PATH', 'Cache paths cannot traverse links or non-directories.');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;\n }\n }\n return current;\n}\nexport function writeAll(fd: number, bytes: Uint8Array): void {\n let offset = 0;\n while (offset < bytes.byteLength) {\n const wrote = fs.writeSync(fd, bytes, offset, bytes.byteLength - offset);\n if (wrote <= 0)\n runtimeError('RUNTIME_WRITE_FAILED', 'Runtime artifact could not be written completely.');\n offset += wrote;\n }\n}\nexport function writeOnce(root: string, relative: string, bytes: Uint8Array): void {\n const target = cachePath(root, relative);\n fs.mkdirSync(path.dirname(target), { recursive: true, mode: 0o700 });\n cachePath(root, relative);\n if (fs.existsSync(target)) {\n if (!fs.lstatSync(target).isFile() || !fs.readFileSync(target).equals(Buffer.from(bytes)))\n runtimeError('RUNTIME_CACHE_CONFLICT', 'An immutable cache record cannot be replaced.');\n return;\n }\n const temp = cachePath(root, `${relative}.${randomUUID()}.tmp`);\n const fd = fs.openSync(temp, 'wx', 0o600);\n try {\n writeAll(fd, bytes);\n fs.fsyncSync(fd);\n } finally {\n fs.closeSync(fd);\n }\n try {\n try {\n fs.linkSync(temp, target);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'EEXIST') throw error;\n if (!fs.readFileSync(target).equals(Buffer.from(bytes)))\n runtimeError('RUNTIME_CACHE_CONFLICT', 'Concurrent cache records disagree.');\n }\n } finally {\n fs.unlinkSync(temp);\n }\n}\nexport function openRuntimeCache(value: string, create: boolean): string {\n const root = canonicalCacheRoot(value);\n const file = cachePath(root, '.runtime-cache.json');\n if (!fs.existsSync(file)) {\n if (\n fs.existsSync(root) &&\n (!fs.lstatSync(root).isDirectory() || fs.readdirSync(root).length > 0)\n )\n runtimeError('RUNTIME_CACHE_UNOWNED', 'Existing data is not a runtime-manager cache.');\n if (!create) return root;\n fs.mkdirSync(root, { recursive: true, mode: 0o700 });\n writeOnce(root, '.runtime-cache.json', marker);\n }\n if (\n !fs.lstatSync(file).isFile() ||\n fs.lstatSync(file).size !== marker.length ||\n !fs.readFileSync(file).equals(marker)\n )\n runtimeError('RUNTIME_CACHE_UNOWNED', 'Runtime cache ownership marker is invalid.');\n return root;\n}\nexport function readCacheJson(root: string, relative: string, limit = 1024 * 1024): unknown {\n const file = cachePath(root, relative);\n const stat = fs.lstatSync(file);\n if (!stat.isFile() || stat.size > limit)\n runtimeError('RUNTIME_CACHE_RECORD', 'Runtime cache record must be a bounded regular file.');\n const bytes = fs.readFileSync(file);\n if (bytes.length > limit)\n runtimeError('RUNTIME_CACHE_RECORD', 'Runtime cache record grew while reading.');\n try {\n return JSON.parse(bytes.toString('utf8'));\n } catch {\n runtimeError('RUNTIME_CACHE_RECORD', 'Runtime cache record is not complete JSON.');\n }\n}\n\nexport async function ensureRuntimeCache(value: string): Promise<string> {\n const root = canonicalCacheRoot(value);\n fs.mkdirSync(path.dirname(root), { recursive: true, mode: 0o700 });\n return withBatchRunLock(\n {\n runPath: `${root}.initialize.json`,\n identity: { schema: 'runtime-cache-initialize.v1', root },\n reason: 'Runtime cache initialization',\n },\n () => openRuntimeCache(root, true),\n );\n}\n"]}
@@ -0,0 +1,45 @@
1
+ export declare const CLI_RUNTIME_DESCRIPTOR_SCHEMA: 'tiangong-lca.cli-runtime-descriptor.v1';
2
+ export declare const CLI_RUNTIME_EXPECTATION_SCHEMA: 'tiangong-lca.cli-runtime-expectation.v1';
3
+ export declare const RUNTIME_PLATFORMS: readonly ["darwin-arm64", "linux-x64", "linux-arm64", "win32-x64"];
4
+ export type RuntimePlatform = (typeof RUNTIME_PLATFORMS)[number];
5
+ export type RuntimeFileFact = Readonly<{
6
+ path: string;
7
+ bytes: number;
8
+ sha256: string;
9
+ }>;
10
+ export type CliRuntimeDescriptor = Readonly<{
11
+ schema: typeof CLI_RUNTIME_DESCRIPTOR_SCHEMA;
12
+ scope: 'cli-package';
13
+ package: Readonly<{
14
+ name: '@tiangong-lca/cli';
15
+ version: string;
16
+ root: string;
17
+ manifest_sha256: string;
18
+ }>;
19
+ platform: RuntimePlatform;
20
+ node: Readonly<{
21
+ version: string;
22
+ executable: string;
23
+ bytes: number;
24
+ sha256: string;
25
+ }>;
26
+ command: Readonly<{
27
+ executable: string;
28
+ argv: readonly string[];
29
+ }>;
30
+ assets: Readonly<{
31
+ tidas_schema_root: string;
32
+ sha256: string;
33
+ }>;
34
+ files: readonly RuntimeFileFact[];
35
+ content_sha256: string;
36
+ }>;
37
+ /** Supplied by an independent trusted release/component manifest, never copied from the observation being checked. */
38
+ export type CliRuntimeExpectation = Readonly<{
39
+ schema: typeof CLI_RUNTIME_EXPECTATION_SCHEMA;
40
+ package_version: string;
41
+ platform: RuntimePlatform;
42
+ content_sha256: string;
43
+ node_version: string;
44
+ node_sha256: string;
45
+ }>;
@@ -0,0 +1,9 @@
1
+ export const CLI_RUNTIME_DESCRIPTOR_SCHEMA = 'tiangong-lca.cli-runtime-descriptor.v1';
2
+ export const CLI_RUNTIME_EXPECTATION_SCHEMA = 'tiangong-lca.cli-runtime-expectation.v1';
3
+ export const RUNTIME_PLATFORMS = Object.freeze([
4
+ 'darwin-arm64',
5
+ 'linux-x64',
6
+ 'linux-arm64',
7
+ 'win32-x64',
8
+ ]);
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/lib/runtime/types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,6BAA6B,GAAG,wCAAiD,CAAC;AAC/F,MAAM,CAAC,MAAM,8BAA8B,GAAG,yCAAkD,CAAC;AACjG,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7C,cAAc;IACd,WAAW;IACX,aAAa;IACb,WAAW;CACH,CAAC,CAAC","sourcesContent":["export const CLI_RUNTIME_DESCRIPTOR_SCHEMA = 'tiangong-lca.cli-runtime-descriptor.v1' as const;\nexport const CLI_RUNTIME_EXPECTATION_SCHEMA = 'tiangong-lca.cli-runtime-expectation.v1' as const;\nexport const RUNTIME_PLATFORMS = Object.freeze([\n 'darwin-arm64',\n 'linux-x64',\n 'linux-arm64',\n 'win32-x64',\n] as const);\nexport type RuntimePlatform = (typeof RUNTIME_PLATFORMS)[number];\n\nexport type RuntimeFileFact = Readonly<{ path: string; bytes: number; sha256: string }>;\nexport type CliRuntimeDescriptor = Readonly<{\n schema: typeof CLI_RUNTIME_DESCRIPTOR_SCHEMA;\n scope: 'cli-package';\n package: Readonly<{\n name: '@tiangong-lca/cli';\n version: string;\n root: string;\n manifest_sha256: string;\n }>;\n platform: RuntimePlatform;\n node: Readonly<{ version: string; executable: string; bytes: number; sha256: string }>;\n command: Readonly<{ executable: string; argv: readonly string[] }>;\n assets: Readonly<{ tidas_schema_root: string; sha256: string }>;\n files: readonly RuntimeFileFact[];\n content_sha256: string;\n}>;\n\n/** Supplied by an independent trusted release/component manifest, never copied from the observation being checked. */\nexport type CliRuntimeExpectation = Readonly<{\n schema: typeof CLI_RUNTIME_EXPECTATION_SCHEMA;\n package_version: string;\n platform: RuntimePlatform;\n content_sha256: string;\n node_version: string;\n node_sha256: string;\n}>;\n"]}
package/dist/src/main.js CHANGED
@@ -4,8 +4,20 @@ import process from 'node:process';
4
4
  import { pathToFileURL } from 'node:url';
5
5
  import { executeCli } from './cli.js';
6
6
  import { loadDotEnv } from './lib/dotenv.js';
7
+ import { isRuntimeCommand } from './lib/runtime/command.js';
8
+ import { runtimePlatform } from './lib/runtime/descriptor.js';
9
+ import { toErrorPayload } from './lib/errors.js';
7
10
  export async function main(argv, env = process.env) {
8
- const dotEnvStatus = loadDotEnv(process.cwd(), env);
11
+ try {
12
+ runtimePlatform(process.platform, process.arch);
13
+ }
14
+ catch (error) {
15
+ process.stderr.write(`${JSON.stringify(toErrorPayload(error))}\n`);
16
+ return 69;
17
+ }
18
+ const dotEnvStatus = isRuntimeCommand(argv)
19
+ ? { loaded: false, path: path.join(process.cwd(), '.env'), count: 0 }
20
+ : loadDotEnv(process.cwd(), env);
9
21
  const result = await executeCli(argv, {
10
22
  env,
11
23
  dotEnvStatus,
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/main.ts"],"names":[],"mappings":";AAEA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,OAAO,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,IAAc,EAAE,GAAG,GAAsB,OAAO,CAAC,GAAG;IAC7E,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE;QACpC,GAAG;QACH,YAAY;QACZ,SAAS,EAAE,KAAK;KACjB,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,MAAM,CAAC,QAAQ,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,aAAqB,EAAE,KAAyB;IAC5E,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,aAAa,KAAK,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACnE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,IAAI,GAAa,OAAO,CAAC,IAAI,EAC7B,GAAG,GAAsB,OAAO,CAAC,GAAG,EACpC,aAAa,GAAW,OAAO,IAAI,CAAC,GAAG;IAEvC,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1B,IAAI,CAAC,aAAa,CAAC,aAAa,EAAE,SAAS,CAAC,EAAE,CAAC;QAC7C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAChD,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC5B,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,mBAAmB,EAAE,CAAC","sourcesContent":["#!/usr/bin/env node\n\nimport path from 'node:path';\nimport process from 'node:process';\nimport { pathToFileURL } from 'node:url';\nimport { executeCli } from './cli.js';\nimport { loadDotEnv } from './lib/dotenv.js';\n\nexport async function main(argv: string[], env: NodeJS.ProcessEnv = process.env): Promise<number> {\n const dotEnvStatus = loadDotEnv(process.cwd(), env);\n const result = await executeCli(argv, {\n env,\n dotEnvStatus,\n fetchImpl: fetch,\n });\n\n if (result.stdout) {\n process.stdout.write(result.stdout);\n }\n if (result.stderr) {\n process.stderr.write(result.stderr);\n }\n return result.exitCode;\n}\n\nexport function isDirectEntry(importMetaUrl: string, argv1: string | undefined): boolean {\n if (!argv1) {\n return false;\n }\n return importMetaUrl === pathToFileURL(path.resolve(argv1)).href;\n}\n\nexport async function maybeRunFromProcess(\n argv: string[] = process.argv,\n env: NodeJS.ProcessEnv = process.env,\n importMetaUrl: string = import.meta.url,\n): Promise<number | null> {\n const entryPath = argv[1];\n if (!isDirectEntry(importMetaUrl, entryPath)) {\n return null;\n }\n\n const exitCode = await main(argv.slice(2), env);\n process.exitCode = exitCode;\n return exitCode;\n}\n\nawait maybeRunFromProcess();\n"]}
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/main.ts"],"names":[],"mappings":";AAEA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,OAAO,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,IAAc,EAAE,GAAG,GAAsB,OAAO,CAAC,GAAG;IAC7E,IAAI,CAAC;QACH,eAAe,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC;QACnE,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,YAAY,GAAG,gBAAgB,CAAC,IAAI,CAAC;QACzC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE;QACrE,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE;QACpC,GAAG;QACH,YAAY;QACZ,SAAS,EAAE,KAAK;KACjB,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,MAAM,CAAC,QAAQ,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,aAAqB,EAAE,KAAyB;IAC5E,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,aAAa,KAAK,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACnE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,IAAI,GAAa,OAAO,CAAC,IAAI,EAC7B,GAAG,GAAsB,OAAO,CAAC,GAAG,EACpC,aAAa,GAAW,OAAO,IAAI,CAAC,GAAG;IAEvC,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1B,IAAI,CAAC,aAAa,CAAC,aAAa,EAAE,SAAS,CAAC,EAAE,CAAC;QAC7C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAChD,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC5B,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,mBAAmB,EAAE,CAAC","sourcesContent":["#!/usr/bin/env node\n\nimport path from 'node:path';\nimport process from 'node:process';\nimport { pathToFileURL } from 'node:url';\nimport { executeCli } from './cli.js';\nimport { loadDotEnv } from './lib/dotenv.js';\nimport { isRuntimeCommand } from './lib/runtime/command.js';\nimport { runtimePlatform } from './lib/runtime/descriptor.js';\nimport { toErrorPayload } from './lib/errors.js';\n\nexport async function main(argv: string[], env: NodeJS.ProcessEnv = process.env): Promise<number> {\n try {\n runtimePlatform(process.platform, process.arch);\n } catch (error) {\n process.stderr.write(`${JSON.stringify(toErrorPayload(error))}\\n`);\n return 69;\n }\n const dotEnvStatus = isRuntimeCommand(argv)\n ? { loaded: false, path: path.join(process.cwd(), '.env'), count: 0 }\n : loadDotEnv(process.cwd(), env);\n const result = await executeCli(argv, {\n env,\n dotEnvStatus,\n fetchImpl: fetch,\n });\n\n if (result.stdout) {\n process.stdout.write(result.stdout);\n }\n if (result.stderr) {\n process.stderr.write(result.stderr);\n }\n return result.exitCode;\n}\n\nexport function isDirectEntry(importMetaUrl: string, argv1: string | undefined): boolean {\n if (!argv1) {\n return false;\n }\n return importMetaUrl === pathToFileURL(path.resolve(argv1)).href;\n}\n\nexport async function maybeRunFromProcess(\n argv: string[] = process.argv,\n env: NodeJS.ProcessEnv = process.env,\n importMetaUrl: string = import.meta.url,\n): Promise<number | null> {\n const entryPath = argv[1];\n if (!isDirectEntry(importMetaUrl, entryPath)) {\n return null;\n }\n\n const exitCode = await main(argv.slice(2), env);\n process.exitCode = exitCode;\n return exitCode;\n}\n\nawait maybeRunFromProcess();\n"]}
@@ -0,0 +1,15 @@
1
+ import type { CliRuntimeDescriptor } from './lib/runtime/types.js';
2
+ export { CLI_RUNTIME_DESCRIPTOR_SCHEMA, CLI_RUNTIME_EXPECTATION_SCHEMA, RUNTIME_PLATFORMS, } from './lib/runtime/types.js';
3
+ export type { CliRuntimeDescriptor, CliRuntimeExpectation, RuntimeFileFact, RuntimePlatform, } from './lib/runtime/types.js';
4
+ /** Observe this installed package without reading user configuration or accessing the network. */
5
+ export declare function describeCliRuntime(): CliRuntimeDescriptor;
6
+ /** The caller supplies independently trusted expected release facts. This grants no account permission. */
7
+ export declare function assertCliRuntimeMatches(expected: unknown): CliRuntimeDescriptor;
8
+ export { parseRuntimeManifest, trustRuntimeManifest, loadTrustedRuntimeManifest, assertWorkspaceCompatibility, } from './lib/runtime/manifest.js';
9
+ export { RUNTIME_MANIFEST_SCHEMA, RUNTIME_BOOTSTRAP_PROTOCOL, RUNTIME_ARCHIVE_FORMAT, } from './lib/runtime/manifest-types.js';
10
+ export type { RuntimeManifest, RuntimeComponent, RuntimeLaunch, ComponentFile, TrustedRuntimeManifest, RuntimeHost, WorkspaceCompatibility, } from './lib/runtime/manifest-types.js';
11
+ export { ensureRuntimeComponents, inspectRuntimeComponents, pruneRuntimeComponents, } from './lib/runtime/manager.js';
12
+ export type { RuntimeManagerOptions, RuntimeManagerReport, RuntimeComponentStatus, } from './lib/runtime/manager.js';
13
+ export { executeRuntimeLaunch } from './lib/runtime/execute.js';
14
+ export type { RuntimeExecutionOptions } from './lib/runtime/execute.js';
15
+ export { writeRuntimeComponentArchive } from './lib/runtime/archive-writer.js';
@@ -0,0 +1,22 @@
1
+ import { inspectCliRuntime, runtimePackageRoot, assertRuntimeObservationMatches, validateRuntimeExpectation, } from './lib/runtime/descriptor.js';
2
+ export { CLI_RUNTIME_DESCRIPTOR_SCHEMA, CLI_RUNTIME_EXPECTATION_SCHEMA, RUNTIME_PLATFORMS, } from './lib/runtime/types.js';
3
+ /** Observe this installed package without reading user configuration or accessing the network. */
4
+ export function describeCliRuntime() {
5
+ return inspectCliRuntime(runtimePackageRoot(import.meta.url), {
6
+ executable: process.execPath,
7
+ version: process.versions.node,
8
+ platform: process.platform,
9
+ arch: process.arch,
10
+ });
11
+ }
12
+ /** The caller supplies independently trusted expected release facts. This grants no account permission. */
13
+ export function assertCliRuntimeMatches(expected) {
14
+ validateRuntimeExpectation(expected);
15
+ return assertRuntimeObservationMatches(describeCliRuntime(), expected);
16
+ }
17
+ export { parseRuntimeManifest, trustRuntimeManifest, loadTrustedRuntimeManifest, assertWorkspaceCompatibility, } from './lib/runtime/manifest.js';
18
+ export { RUNTIME_MANIFEST_SCHEMA, RUNTIME_BOOTSTRAP_PROTOCOL, RUNTIME_ARCHIVE_FORMAT, } from './lib/runtime/manifest-types.js';
19
+ export { ensureRuntimeComponents, inspectRuntimeComponents, pruneRuntimeComponents, } from './lib/runtime/manager.js';
20
+ export { executeRuntimeLaunch } from './lib/runtime/execute.js';
21
+ export { writeRuntimeComponentArchive } from './lib/runtime/archive-writer.js';
22
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,+BAA+B,EAC/B,0BAA0B,GAC3B,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,6BAA6B,EAC7B,8BAA8B,EAC9B,iBAAiB,GAClB,MAAM,wBAAwB,CAAC;AAQhC,kGAAkG;AAClG,MAAM,UAAU,kBAAkB;IAChC,OAAO,iBAAiB,CAAC,kBAAkB,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE;QAC5D,UAAU,EAAE,OAAO,CAAC,QAAQ;QAC5B,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI;QAC9B,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,IAAI,EAAE,OAAO,CAAC,IAAI;KACnB,CAAC,CAAC;AACL,CAAC;AAED,2GAA2G;AAC3G,MAAM,UAAU,uBAAuB,CAAC,QAAiB;IACvD,0BAA0B,CAAC,QAAQ,CAAC,CAAC;IACrC,OAAO,+BAA+B,CAAC,kBAAkB,EAAE,EAAE,QAAQ,CAAC,CAAC;AACzE,CAAC;AAED,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,0BAA0B,EAC1B,4BAA4B,GAC7B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,uBAAuB,EACvB,0BAA0B,EAC1B,sBAAsB,GACvB,MAAM,iCAAiC,CAAC;AAUzC,OAAO,EACL,uBAAuB,EACvB,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAOlC,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAEhE,OAAO,EAAE,4BAA4B,EAAE,MAAM,iCAAiC,CAAC","sourcesContent":["import {\n inspectCliRuntime,\n runtimePackageRoot,\n assertRuntimeObservationMatches,\n validateRuntimeExpectation,\n} from './lib/runtime/descriptor.js';\nimport type { CliRuntimeDescriptor } from './lib/runtime/types.js';\nexport {\n CLI_RUNTIME_DESCRIPTOR_SCHEMA,\n CLI_RUNTIME_EXPECTATION_SCHEMA,\n RUNTIME_PLATFORMS,\n} from './lib/runtime/types.js';\nexport type {\n CliRuntimeDescriptor,\n CliRuntimeExpectation,\n RuntimeFileFact,\n RuntimePlatform,\n} from './lib/runtime/types.js';\n\n/** Observe this installed package without reading user configuration or accessing the network. */\nexport function describeCliRuntime(): CliRuntimeDescriptor {\n return inspectCliRuntime(runtimePackageRoot(import.meta.url), {\n executable: process.execPath,\n version: process.versions.node,\n platform: process.platform,\n arch: process.arch,\n });\n}\n\n/** The caller supplies independently trusted expected release facts. This grants no account permission. */\nexport function assertCliRuntimeMatches(expected: unknown): CliRuntimeDescriptor {\n validateRuntimeExpectation(expected);\n return assertRuntimeObservationMatches(describeCliRuntime(), expected);\n}\n\nexport {\n parseRuntimeManifest,\n trustRuntimeManifest,\n loadTrustedRuntimeManifest,\n assertWorkspaceCompatibility,\n} from './lib/runtime/manifest.js';\nexport {\n RUNTIME_MANIFEST_SCHEMA,\n RUNTIME_BOOTSTRAP_PROTOCOL,\n RUNTIME_ARCHIVE_FORMAT,\n} from './lib/runtime/manifest-types.js';\nexport type {\n RuntimeManifest,\n RuntimeComponent,\n RuntimeLaunch,\n ComponentFile,\n TrustedRuntimeManifest,\n RuntimeHost,\n WorkspaceCompatibility,\n} from './lib/runtime/manifest-types.js';\nexport {\n ensureRuntimeComponents,\n inspectRuntimeComponents,\n pruneRuntimeComponents,\n} from './lib/runtime/manager.js';\nexport type {\n RuntimeManagerOptions,\n RuntimeManagerReport,\n RuntimeComponentStatus,\n} from './lib/runtime/manager.js';\n\nexport { executeRuntimeLaunch } from './lib/runtime/execute.js';\nexport type { RuntimeExecutionOptions } from './lib/runtime/execute.js';\nexport { writeRuntimeComponentArchive } from './lib/runtime/archive-writer.js';\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tiangong-lca/cli",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "description": "Unified TianGong LCA CLI with direct REST adapters and low-entropy command surface.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -24,6 +24,10 @@
24
24
  "types": "./dist/src/command-spec.d.ts",
25
25
  "import": "./dist/src/command-spec.js"
26
26
  },
27
+ "./runtime": {
28
+ "types": "./dist/src/runtime.d.ts",
29
+ "import": "./dist/src/runtime.js"
30
+ },
27
31
  "./batch": {
28
32
  "types": "./dist/src/batch.d.ts",
29
33
  "import": "./dist/src/batch.js"