@roj-ai/platform-cli 0.1.12 → 0.1.14

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.
@@ -1 +1 @@
1
- {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAGA,wBAAsB,KAAK,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAuC9E"}
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AASA,wBAAsB,KAAK,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqE9E"}
package/dist/build.js CHANGED
@@ -4,24 +4,35 @@ export async function build(configPath, outPath) {
4
4
  const absConfig = resolve(configPath);
5
5
  const absOut = resolve(outPath);
6
6
  const configDir = dirname(absConfig);
7
- // Generate entry next to config (so Bun resolves workspace packages)
7
+ const userConfigModule = await import(absConfig);
8
+ const userConfig = userConfigModule.default;
9
+ const isExternal = userConfig?.runtime?.external === true;
10
+ const lockMinor = userConfig?.runtime?.lockMinor ?? true;
8
11
  const entryPath = join(configDir, '.roj-entry.ts');
9
- await writeFile(entryPath, `
12
+ const entrySource = isExternal
13
+ ? `import config from '${absConfig}'\nexport default config\n`
14
+ : `
10
15
  import config from '${absConfig}'
11
16
  import { startServer } from '@roj-ai/sandbox-runtime/server'
12
17
  startServer({ presets: config.presets }).catch((err) => {
13
18
  console.error('Fatal:', err)
14
19
  process.exit(1)
15
20
  })
16
- `);
21
+ `;
22
+ await writeFile(entryPath, entrySource);
17
23
  try {
18
24
  await mkdir(dirname(absOut), { recursive: true });
19
- const result = await Bun.build({
25
+ const buildOptions = {
20
26
  entrypoints: [entryPath],
21
27
  outdir: dirname(absOut),
22
28
  naming: absOut.split('/').pop(),
23
29
  target: 'bun',
24
- });
30
+ };
31
+ if (isExternal) {
32
+ buildOptions.external = ['@roj-ai/*'];
33
+ buildOptions.format = 'esm';
34
+ }
35
+ const result = await Bun.build(buildOptions);
25
36
  if (!result.success) {
26
37
  for (const log of result.logs) {
27
38
  console.error(log);
@@ -29,10 +40,29 @@ startServer({ presets: config.presets }).catch((err) => {
29
40
  process.exit(1);
30
41
  }
31
42
  const stat = Bun.file(absOut);
32
- console.log(`Built: ${absOut} (${(stat.size / 1024).toFixed(0)} KB)`);
43
+ const sizeKb = stat.size / 1024;
44
+ console.log(`Built: ${absOut} (${sizeKb.toFixed(0)} KB)`);
45
+ const metadata = isExternal
46
+ ? {
47
+ bundleMode: 'externalSdk',
48
+ rojVersion: await resolveSdkVersion(configDir),
49
+ lockMinor,
50
+ }
51
+ : { bundleMode: 'selfContained' };
52
+ const metaPath = `${absOut}.meta.json`;
53
+ await writeFile(metaPath, `${JSON.stringify(metadata, null, 2)}\n`);
54
+ console.log(`Wrote metadata: ${metaPath}`);
55
+ if (isExternal && sizeKb > 200) {
56
+ console.warn(`[warn] external-sdk bundle is ${sizeKb.toFixed(0)} KB — externalization may not have taken full effect; check that user code does not pull @roj-ai/* via re-export.`);
57
+ }
33
58
  }
34
59
  finally {
35
60
  await rm(entryPath).catch(() => { });
36
61
  }
37
62
  }
63
+ async function resolveSdkVersion(configDir) {
64
+ const pkgPath = Bun.resolveSync('@roj-ai/sdk/package.json', configDir);
65
+ const pkg = await Bun.file(pkgPath).json();
66
+ return pkg.version;
67
+ }
38
68
  //# sourceMappingURL=build.js.map
package/dist/build.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"build.js","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAClD,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAEvD,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,UAAkB,EAAE,OAAe;IAC9D,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;IACrC,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAC/B,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAA;IAEpC,qEAAqE;IACrE,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,CAAA;IAElD,MAAM,SAAS,CAAC,SAAS,EAAE;sBACN,SAAS;;;;;;CAM9B,CAAC,CAAA;IAED,IAAI,CAAC;QACJ,MAAM,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QAEjD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC;YAC9B,WAAW,EAAE,CAAC,SAAS,CAAC;YACxB,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC;YACvB,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAG;YAChC,MAAM,EAAE,KAAK;SACb,CAAC,CAAA;QAEF,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACrB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;gBAC/B,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YACnB,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAChB,CAAC;QAED,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAC7B,OAAO,CAAC,GAAG,CAAC,UAAU,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;IACtE,CAAC;YAAS,CAAC;QACV,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;IACpC,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../src/upload.ts"],"names":[],"mappings":"AAAA,wBAAsB,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE;IACzD,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,CAAA;CAChB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsChB"}
1
+ {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../src/upload.ts"],"names":[],"mappings":"AAAA,wBAAsB,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE;IACzD,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,CAAA;CAChB,GAAG,OAAO,CAAC,IAAI,CAAC,CAwChB"}
package/dist/upload.js CHANGED
@@ -7,8 +7,9 @@ export async function upload(bundlePath, options) {
7
7
  const filename = bundlePath.split('/').pop();
8
8
  const buf = await file.arrayBuffer();
9
9
  const contentHash = await sha256Hex(buf);
10
+ const metadata = await readMetadataSidecar(bundlePath);
10
11
  // 1. Preflight: ask server if it already has this content for the org.
11
- let result = await postBundle({ url: options.url, apiKey: options.apiKey, name: options.name, version: options.version, contentHash });
12
+ let result = await postBundle({ url: options.url, apiKey: options.apiKey, name: options.name, version: options.version, contentHash, metadata });
12
13
  // 2. Server reports the bundle bytes are missing — retry with body.
13
14
  if (result.status === 409 && result.body?.error === 'bundle-required') {
14
15
  result = await postBundle({
@@ -17,6 +18,7 @@ export async function upload(bundlePath, options) {
17
18
  name: options.name,
18
19
  version: options.version,
19
20
  contentHash,
21
+ metadata,
20
22
  body: { buf, filename, mimeType: file.type || 'application/javascript' },
21
23
  });
22
24
  }
@@ -37,6 +39,8 @@ async function postBundle(args) {
37
39
  formData.append('contentHash', args.contentHash);
38
40
  if (args.version)
39
41
  formData.append('version', args.version);
42
+ if (args.metadata)
43
+ formData.append('metadata', args.metadata);
40
44
  if (args.body) {
41
45
  formData.append('bundle', new Blob([args.body.buf], { type: args.body.mimeType }), args.body.filename);
42
46
  }
@@ -60,4 +64,12 @@ async function sha256Hex(buf) {
60
64
  function shortHash(hex) {
61
65
  return hex.slice(0, 12);
62
66
  }
67
+ async function readMetadataSidecar(bundlePath) {
68
+ const sidecar = Bun.file(`${bundlePath}.meta.json`);
69
+ if (!(await sidecar.exists()))
70
+ return undefined;
71
+ const text = await sidecar.text();
72
+ JSON.parse(text);
73
+ return text;
74
+ }
63
75
  //# sourceMappingURL=upload.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"upload.js","sourceRoot":"","sources":["../src/upload.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"upload.js","sourceRoot":"","sources":["../src/upload.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@roj-ai/platform-cli",
3
- "version": "0.1.12",
3
+ "version": "0.1.14",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "roj": "./dist/main.js"
@@ -22,7 +22,7 @@
22
22
  "url": "https://github.com/contember/roj/issues"
23
23
  },
24
24
  "dependencies": {
25
- "@roj-ai/sandbox-runtime": "^0.1.12"
25
+ "@roj-ai/sandbox-runtime": "^0.1.14"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@types/bun": "^1.3.3"
package/src/build.ts CHANGED
@@ -1,32 +1,51 @@
1
1
  import { resolve, dirname, join } from 'node:path'
2
2
  import { writeFile, rm, mkdir } from 'node:fs/promises'
3
3
 
4
+ interface BundleMetadata {
5
+ bundleMode: 'selfContained' | 'externalSdk'
6
+ rojVersion?: string
7
+ lockMinor?: boolean
8
+ }
9
+
4
10
  export async function build(configPath: string, outPath: string): Promise<void> {
5
11
  const absConfig = resolve(configPath)
6
12
  const absOut = resolve(outPath)
7
13
  const configDir = dirname(absConfig)
8
14
 
9
- // Generate entry next to config (so Bun resolves workspace packages)
10
- const entryPath = join(configDir, '.roj-entry.ts')
15
+ const userConfigModule = await import(absConfig)
16
+ const userConfig = userConfigModule.default
17
+ const isExternal = userConfig?.runtime?.external === true
18
+ const lockMinor = userConfig?.runtime?.lockMinor ?? true
11
19
 
12
- await writeFile(entryPath, `
20
+ const entryPath = join(configDir, '.roj-entry.ts')
21
+ const entrySource = isExternal
22
+ ? `import config from '${absConfig}'\nexport default config\n`
23
+ : `
13
24
  import config from '${absConfig}'
14
25
  import { startServer } from '@roj-ai/sandbox-runtime/server'
15
26
  startServer({ presets: config.presets }).catch((err) => {
16
27
  console.error('Fatal:', err)
17
28
  process.exit(1)
18
29
  })
19
- `)
30
+ `
31
+
32
+ await writeFile(entryPath, entrySource)
20
33
 
21
34
  try {
22
35
  await mkdir(dirname(absOut), { recursive: true })
23
36
 
24
- const result = await Bun.build({
37
+ const buildOptions: Parameters<typeof Bun.build>[0] = {
25
38
  entrypoints: [entryPath],
26
39
  outdir: dirname(absOut),
27
40
  naming: absOut.split('/').pop()!,
28
41
  target: 'bun',
29
- })
42
+ }
43
+ if (isExternal) {
44
+ buildOptions.external = ['@roj-ai/*']
45
+ buildOptions.format = 'esm'
46
+ }
47
+
48
+ const result = await Bun.build(buildOptions)
30
49
 
31
50
  if (!result.success) {
32
51
  for (const log of result.logs) {
@@ -36,8 +55,31 @@ startServer({ presets: config.presets }).catch((err) => {
36
55
  }
37
56
 
38
57
  const stat = Bun.file(absOut)
39
- console.log(`Built: ${absOut} (${(stat.size / 1024).toFixed(0)} KB)`)
58
+ const sizeKb = stat.size / 1024
59
+ console.log(`Built: ${absOut} (${sizeKb.toFixed(0)} KB)`)
60
+
61
+ const metadata: BundleMetadata = isExternal
62
+ ? {
63
+ bundleMode: 'externalSdk',
64
+ rojVersion: await resolveSdkVersion(configDir),
65
+ lockMinor,
66
+ }
67
+ : { bundleMode: 'selfContained' }
68
+
69
+ const metaPath = `${absOut}.meta.json`
70
+ await writeFile(metaPath, `${JSON.stringify(metadata, null, 2)}\n`)
71
+ console.log(`Wrote metadata: ${metaPath}`)
72
+
73
+ if (isExternal && sizeKb > 200) {
74
+ console.warn(`[warn] external-sdk bundle is ${sizeKb.toFixed(0)} KB — externalization may not have taken full effect; check that user code does not pull @roj-ai/* via re-export.`)
75
+ }
40
76
  } finally {
41
77
  await rm(entryPath).catch(() => {})
42
78
  }
43
79
  }
80
+
81
+ async function resolveSdkVersion(configDir: string): Promise<string> {
82
+ const pkgPath = Bun.resolveSync('@roj-ai/sdk/package.json', configDir)
83
+ const pkg = await Bun.file(pkgPath).json() as { version: string }
84
+ return pkg.version
85
+ }
package/src/upload.ts CHANGED
@@ -13,9 +13,10 @@ export async function upload(bundlePath: string, options: {
13
13
  const filename = bundlePath.split('/').pop()!
14
14
  const buf = await file.arrayBuffer()
15
15
  const contentHash = await sha256Hex(buf)
16
+ const metadata = await readMetadataSidecar(bundlePath)
16
17
 
17
18
  // 1. Preflight: ask server if it already has this content for the org.
18
- let result = await postBundle({ url: options.url, apiKey: options.apiKey, name: options.name, version: options.version, contentHash })
19
+ let result = await postBundle({ url: options.url, apiKey: options.apiKey, name: options.name, version: options.version, contentHash, metadata })
19
20
 
20
21
  // 2. Server reports the bundle bytes are missing — retry with body.
21
22
  if (result.status === 409 && result.body?.error === 'bundle-required') {
@@ -25,6 +26,7 @@ export async function upload(bundlePath: string, options: {
25
26
  name: options.name,
26
27
  version: options.version,
27
28
  contentHash,
29
+ metadata,
28
30
  body: { buf, filename, mimeType: file.type || 'application/javascript' },
29
31
  })
30
32
  }
@@ -49,6 +51,7 @@ interface PostBundleArgs {
49
51
  name: string
50
52
  version?: string
51
53
  contentHash: string
54
+ metadata?: string
52
55
  body?: { buf: ArrayBuffer; filename: string; mimeType: string }
53
56
  }
54
57
 
@@ -70,6 +73,7 @@ async function postBundle(args: PostBundleArgs): Promise<PostBundleResult> {
70
73
  formData.append('name', args.name)
71
74
  formData.append('contentHash', args.contentHash)
72
75
  if (args.version) formData.append('version', args.version)
76
+ if (args.metadata) formData.append('metadata', args.metadata)
73
77
  if (args.body) {
74
78
  formData.append('bundle', new Blob([args.body.buf], { type: args.body.mimeType }), args.body.filename)
75
79
  }
@@ -97,3 +101,11 @@ async function sha256Hex(buf: ArrayBuffer): Promise<string> {
97
101
  function shortHash(hex: string): string {
98
102
  return hex.slice(0, 12)
99
103
  }
104
+
105
+ async function readMetadataSidecar(bundlePath: string): Promise<string | undefined> {
106
+ const sidecar = Bun.file(`${bundlePath}.meta.json`)
107
+ if (!(await sidecar.exists())) return undefined
108
+ const text = await sidecar.text()
109
+ JSON.parse(text)
110
+ return text
111
+ }