@soederpop/luca 0.0.36 → 0.1.1
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.
- package/bun.lock +172 -7
- package/package.json +3 -4
- package/src/bootstrap/generated.ts +1 -1
- package/src/cli/build-info.ts +2 -2
- package/src/commands/console.ts +2 -2
- package/src/commands/prompt.ts +2 -2
- package/src/commands/run.ts +5 -45
- package/src/introspection/generated.agi.ts +635 -535
- package/src/introspection/generated.node.ts +1005 -905
- package/src/introspection/generated.web.ts +1 -1
- package/src/node/container.ts +7 -6
- package/src/node/features/figlet-fonts.ts +4 -1
- package/src/node/features/transpiler.ts +111 -0
- package/src/node/features/vm.ts +1 -1
- package/src/python/generated.ts +1 -1
- package/src/scaffolds/generated.ts +1 -1
- package/test/integration.test.ts +5 -5
- package/src/node/features/esbuild.ts +0 -79
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { setBuildTimeData, setContainerBuildTimeData } from './index.js';
|
|
2
2
|
|
|
3
3
|
// Auto-generated introspection registry data
|
|
4
|
-
// Generated at: 2026-03-
|
|
4
|
+
// Generated at: 2026-03-28T06:19:48.239Z
|
|
5
5
|
|
|
6
6
|
setBuildTimeData('features.containerLink', {
|
|
7
7
|
"id": "features.containerLink",
|
package/src/node/container.ts
CHANGED
|
@@ -24,7 +24,7 @@ import { basename, parse, relative, resolve, join } from "path";
|
|
|
24
24
|
import "./features/disk-cache";
|
|
25
25
|
import "./features/content-db";
|
|
26
26
|
import "./features/downloader";
|
|
27
|
-
import "./features/
|
|
27
|
+
import "./features/transpiler";
|
|
28
28
|
import "./features/file-manager";
|
|
29
29
|
import "./features/fs";
|
|
30
30
|
import "./features/git";
|
|
@@ -69,7 +69,7 @@ import type { ChildProcess } from "./features/proc";
|
|
|
69
69
|
import type { DiskCache } from "./features/disk-cache";
|
|
70
70
|
import type { ContentDb } from "./features/content-db";
|
|
71
71
|
import type { Downloader } from "./features/downloader";
|
|
72
|
-
import type {
|
|
72
|
+
import type { Transpiler } from "./features/transpiler";
|
|
73
73
|
import type { FileManager } from "./features/file-manager";
|
|
74
74
|
import type { FS } from "./features/fs";
|
|
75
75
|
import type { Git } from "./features/git";
|
|
@@ -147,6 +147,7 @@ export {
|
|
|
147
147
|
type SemanticSearch,
|
|
148
148
|
type Dns,
|
|
149
149
|
type Redis,
|
|
150
|
+
type Transpiler,
|
|
150
151
|
};
|
|
151
152
|
|
|
152
153
|
export type { FeatureOptions };
|
|
@@ -184,7 +185,7 @@ export interface NodeFeatures extends AvailableFeatures {
|
|
|
184
185
|
packageFinder: typeof PackageFinder;
|
|
185
186
|
repl: typeof Repl;
|
|
186
187
|
yaml: typeof YAML;
|
|
187
|
-
|
|
188
|
+
transpiler: typeof Transpiler;
|
|
188
189
|
diskCache: typeof DiskCache;
|
|
189
190
|
vault: typeof Vault;
|
|
190
191
|
jsonTree: typeof JsonTree;
|
|
@@ -233,7 +234,7 @@ export interface NodeContainerState extends ContainerState {
|
|
|
233
234
|
* Server-side container for Node.js and Bun environments. Extends the base Container with
|
|
234
235
|
* file system access, process management, git integration, and other server-side capabilities.
|
|
235
236
|
*
|
|
236
|
-
* Auto-enables core features on construction: fs, proc, git, grep, os, networking, ui, vm,
|
|
237
|
+
* Auto-enables core features on construction: fs, proc, git, grep, os, networking, ui, vm, transpiler, helpers.
|
|
237
238
|
* Also attaches Client, Server, Command, Endpoint, and Selector helper types, providing
|
|
238
239
|
* `container.client()`, `container.server()`, `container.command()`, etc. factory methods.
|
|
239
240
|
*
|
|
@@ -274,7 +275,7 @@ export class NodeContainer<
|
|
|
274
275
|
yamlTree?: YamlTree;
|
|
275
276
|
packageFinder?: PackageFinder;
|
|
276
277
|
repl?: Repl;
|
|
277
|
-
|
|
278
|
+
transpiler?: Transpiler;
|
|
278
279
|
diskCache?: DiskCache;
|
|
279
280
|
vault?: Vault;
|
|
280
281
|
python?: Python;
|
|
@@ -309,7 +310,7 @@ export class NodeContainer<
|
|
|
309
310
|
this.feature("networking", { enable: true });
|
|
310
311
|
this.feature("ui", { enable: true });
|
|
311
312
|
this.feature("vm", { enable: true, context: {} });
|
|
312
|
-
this.feature("
|
|
313
|
+
this.feature("transpiler", { enable: true });
|
|
313
314
|
this.feature("helpers", { enable: true });
|
|
314
315
|
|
|
315
316
|
const enable = castArray(this.options.enable)
|
|
@@ -294,7 +294,10 @@ import f292 from "figlet/importable-fonts/Whimsy.js";
|
|
|
294
294
|
import f293 from "figlet/importable-fonts/Wow.js";
|
|
295
295
|
import f294 from "figlet/importable-fonts/miniwi.js";
|
|
296
296
|
|
|
297
|
-
|
|
297
|
+
// Use the browser (core) subpath — filesystem-free, works in compiled binaries.
|
|
298
|
+
// figlet 1.11.0 replaced lib/ with dist/ and added an exports map; "./browser" is the stable subpath.
|
|
299
|
+
// @ts-ignore — figlet/browser exists at runtime via the package exports map
|
|
300
|
+
import figlet from "figlet/browser";
|
|
298
301
|
|
|
299
302
|
// Register all fonts with figlet (filesystem-free, works in compiled binaries)
|
|
300
303
|
figlet.parseFont("1Row", f0);
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { Feature } from '../feature.js'
|
|
2
|
+
import { FeatureStateSchema, FeatureOptionsSchema } from '../../schemas/base.js'
|
|
3
|
+
|
|
4
|
+
export interface TransformOptions {
|
|
5
|
+
loader?: 'ts' | 'tsx' | 'jsx' | 'js'
|
|
6
|
+
format?: 'esm' | 'cjs'
|
|
7
|
+
minify?: boolean
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface TransformResult {
|
|
11
|
+
code: string
|
|
12
|
+
map: string
|
|
13
|
+
warnings: any[]
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Convert ESM import/export statements to CJS require/module.exports
|
|
18
|
+
* so the code can run in a vm context that provides `require`.
|
|
19
|
+
*/
|
|
20
|
+
function esmToCjs(code: string): string {
|
|
21
|
+
return code
|
|
22
|
+
// import Foo, { bar, baz } from 'x' → const Foo = require('x').default ?? require('x'); const { bar, baz } = require('x')
|
|
23
|
+
.replace(/^import\s+(\w+)\s*,\s*\{([^}]+)\}\s+from\s+(['"][^'"]+['"])\s*;?$/gm,
|
|
24
|
+
'const $1 = require($3).default ?? require($3); const {$2} = require($3);')
|
|
25
|
+
// import { a, b } from 'x' → const { a, b } = require('x')
|
|
26
|
+
.replace(/^import\s+\{([^}]+)\}\s+from\s+(['"][^'"]+['"])\s*;?$/gm,
|
|
27
|
+
'const {$1} = require($2);')
|
|
28
|
+
// import x from 'y' → const x = require('y').default ?? require('y')
|
|
29
|
+
.replace(/^import\s+(\w+)\s+from\s+(['"][^'"]+['"])\s*;?$/gm,
|
|
30
|
+
'const $1 = require($2).default ?? require($2);')
|
|
31
|
+
// import * as x from 'y' → const x = require('y')
|
|
32
|
+
.replace(/^import\s+\*\s+as\s+(\w+)\s+from\s+(['"][^'"]+['"])\s*;?$/gm,
|
|
33
|
+
'const $1 = require($2);')
|
|
34
|
+
// import 'y' → require('y')
|
|
35
|
+
.replace(/^import\s+(['"][^'"]+['"])\s*;?$/gm,
|
|
36
|
+
'require($1);')
|
|
37
|
+
// export default → module.exports.default =
|
|
38
|
+
.replace(/^export\s+default\s+/gm, 'module.exports.default = ')
|
|
39
|
+
// export { a, b } from 'x' → Object.assign(module.exports, require('x')) (re-exports)
|
|
40
|
+
.replace(/^export\s+\{[^}]*\}\s+from\s+(['"][^'"]+['"])\s*;?$/gm,
|
|
41
|
+
'Object.assign(module.exports, require($1));')
|
|
42
|
+
// export { ... } → strip (vars already in scope)
|
|
43
|
+
.replace(/^export\s+\{[^}]*\}\s*;?$/gm, '')
|
|
44
|
+
// export const/let/var → const/let/var
|
|
45
|
+
.replace(/^export\s+(const|let|var)\s+/gm, '$1 ')
|
|
46
|
+
// export function → function (keep declaration, strip export keyword)
|
|
47
|
+
.replace(/^export\s+(function|class)\s+/gm, '$1 ')
|
|
48
|
+
// export async function → async function
|
|
49
|
+
.replace(/^export\s+(async\s+function)\s+/gm, '$1 ')
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Transpile TypeScript, TSX, and JSX to JavaScript at runtime using Bun's
|
|
54
|
+
* built-in transpiler. Compile code strings on the fly without touching the
|
|
55
|
+
* filesystem or spawning external processes.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* const transpiler = container.feature('transpiler')
|
|
60
|
+
* const result = transpiler.transformSync('const x: number = 1')
|
|
61
|
+
* console.log(result.code) // 'const x = 1;\n'
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export class Transpiler extends Feature {
|
|
65
|
+
static override shortcut = 'features.transpiler' as const
|
|
66
|
+
static override stateSchema = FeatureStateSchema
|
|
67
|
+
static override optionsSchema = FeatureOptionsSchema
|
|
68
|
+
static { Feature.register(this, 'transpiler') }
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Transform code synchronously
|
|
72
|
+
* @param code - The code to transform
|
|
73
|
+
* @param options - Transform options (loader, format, minify)
|
|
74
|
+
* @returns The transformed code as { code, map, warnings }
|
|
75
|
+
*/
|
|
76
|
+
transformSync(code: string, options: TransformOptions = {}): TransformResult {
|
|
77
|
+
const loader = options.loader || 'ts'
|
|
78
|
+
const format = options.format || 'esm'
|
|
79
|
+
|
|
80
|
+
const transpiler = new Bun.Transpiler({ loader })
|
|
81
|
+
let result = transpiler.transformSync(code)
|
|
82
|
+
|
|
83
|
+
if (format === 'cjs') {
|
|
84
|
+
result = esmToCjs(result)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return { code: result, map: '', warnings: [] }
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Transform code asynchronously
|
|
92
|
+
* @param code - The code to transform
|
|
93
|
+
* @param options - Transform options (loader, format, minify)
|
|
94
|
+
* @returns The transformed code as { code, map, warnings }
|
|
95
|
+
*/
|
|
96
|
+
async transform(code: string, options: TransformOptions = {}): Promise<TransformResult> {
|
|
97
|
+
const loader = options.loader || 'ts'
|
|
98
|
+
const format = options.format || 'esm'
|
|
99
|
+
|
|
100
|
+
const transpiler = new Bun.Transpiler({ loader })
|
|
101
|
+
let result = await transpiler.transform(code)
|
|
102
|
+
|
|
103
|
+
if (format === 'cjs') {
|
|
104
|
+
result = esmToCjs(result)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return { code: result, map: '', warnings: [] }
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export default Transpiler
|
package/src/node/features/vm.ts
CHANGED
|
@@ -390,7 +390,7 @@ export class VM<
|
|
|
390
390
|
if (!fs.exists(filePath)) return {}
|
|
391
391
|
|
|
392
392
|
const raw = fs.readFile(filePath)
|
|
393
|
-
const { code } = this.container.feature('
|
|
393
|
+
const { code } = this.container.feature('transpiler').transformSync(raw, { format: 'cjs' })
|
|
394
394
|
|
|
395
395
|
const { context } = this.performSync(code, {
|
|
396
396
|
require: this.createRequireFor(filePath),
|
package/src/python/generated.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Auto-generated scaffold and MCP readme content
|
|
2
|
-
// Generated at: 2026-03-
|
|
2
|
+
// Generated at: 2026-03-28T06:19:49.219Z
|
|
3
3
|
// Source: docs/scaffolds/*.md, docs/examples/assistant/, and docs/mcp/readme.md
|
|
4
4
|
//
|
|
5
5
|
// Do not edit manually. Run: luca build-scaffolds
|
package/test/integration.test.ts
CHANGED
|
@@ -618,27 +618,27 @@ describe('Integration: Proc + FS for script execution', () => {
|
|
|
618
618
|
})
|
|
619
619
|
})
|
|
620
620
|
|
|
621
|
-
describe('Integration:
|
|
621
|
+
describe('Integration: Transpiler + FS for code transformation', () => {
|
|
622
622
|
it('transforms typescript to javascript', async () => {
|
|
623
623
|
const c = new NodeContainer({ cwd: testDir })
|
|
624
|
-
const
|
|
624
|
+
const transpiler = c.feature('transpiler', { enable: true })
|
|
625
625
|
|
|
626
626
|
const tsCode = `
|
|
627
627
|
const greet = (name: string): string => 'Hello, ' + name + '!'
|
|
628
628
|
export default greet
|
|
629
629
|
`
|
|
630
630
|
|
|
631
|
-
const result = await
|
|
631
|
+
const result = await transpiler.transform(tsCode, { loader: 'ts' })
|
|
632
632
|
expect(result.code).toContain('greet')
|
|
633
633
|
expect(result.code).not.toContain(': string')
|
|
634
634
|
})
|
|
635
635
|
|
|
636
636
|
it('reads ts file from disk, transforms it, writes js output', async () => {
|
|
637
637
|
const c = new NodeContainer({ cwd: testDir })
|
|
638
|
-
const
|
|
638
|
+
const transpiler = c.feature('transpiler', { enable: true })
|
|
639
639
|
|
|
640
640
|
const tsSource = c.fs.readFile(join(testDir, 'src', 'utils.ts'))
|
|
641
|
-
const result = await
|
|
641
|
+
const result = await transpiler.transform(tsSource, { loader: 'ts' })
|
|
642
642
|
|
|
643
643
|
const outPath = join(testDir, 'src', 'utils.js')
|
|
644
644
|
await c.fs.writeFileAsync(outPath, result.code)
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import * as esbuild from 'esbuild-wasm'
|
|
2
|
-
import { Feature } from '../feature.js'
|
|
3
|
-
import { FeatureStateSchema, FeatureOptionsSchema } from '../../schemas/base.js'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* A Feature for compiling typescript / esm modules, etc to JavaScript
|
|
7
|
-
* that the container can run at runtime. Uses esbuild for fast, reliable
|
|
8
|
-
* TypeScript/ESM transformation with full format support (esm, cjs, iife).
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* ```typescript
|
|
12
|
-
* const esbuild = container.feature('esbuild')
|
|
13
|
-
* const result = esbuild.transformSync('const x: number = 1')
|
|
14
|
-
* console.log(result.code) // 'const x = 1;\n'
|
|
15
|
-
* ```
|
|
16
|
-
*/
|
|
17
|
-
export class ESBuild extends Feature {
|
|
18
|
-
static override shortcut = 'features.esbuild' as const
|
|
19
|
-
static override stateSchema = FeatureStateSchema
|
|
20
|
-
static override optionsSchema = FeatureOptionsSchema
|
|
21
|
-
static { Feature.register(this, 'esbuild') }
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
/**
|
|
25
|
-
* Transform code synchronously
|
|
26
|
-
* @param code - The code to transform
|
|
27
|
-
* @param options - The options to pass to esbuild
|
|
28
|
-
* @returns The transformed code
|
|
29
|
-
*/
|
|
30
|
-
transformSync(code: string, options?: esbuild.TransformOptions): esbuild.TransformResult {
|
|
31
|
-
return esbuild.transformSync(code, {
|
|
32
|
-
loader: 'ts',
|
|
33
|
-
format: 'esm',
|
|
34
|
-
target: 'esnext',
|
|
35
|
-
sourcemap: false,
|
|
36
|
-
minify: false,
|
|
37
|
-
...options
|
|
38
|
-
})
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Transform code asynchronously
|
|
43
|
-
* @param code - The code to transform
|
|
44
|
-
* @param options - The options to pass to esbuild
|
|
45
|
-
* @returns The transformed code
|
|
46
|
-
*/
|
|
47
|
-
async transform(code: string, options?: esbuild.TransformOptions): Promise<esbuild.TransformResult> {
|
|
48
|
-
return esbuild.transform(code, {
|
|
49
|
-
loader: 'ts',
|
|
50
|
-
format: 'esm',
|
|
51
|
-
target: 'esnext',
|
|
52
|
-
sourcemap: false,
|
|
53
|
-
minify: false,
|
|
54
|
-
...options
|
|
55
|
-
})
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Bundle one or more entry points, resolving imports and requires into a single output.
|
|
60
|
-
* Supports Node platform by default so require() and Node builtins are handled.
|
|
61
|
-
* Returns in-memory output files unless write is enabled in options.
|
|
62
|
-
* @param entryPoints - File paths to bundle from
|
|
63
|
-
* @param options - esbuild BuildOptions overrides
|
|
64
|
-
* @returns The build result with outputFiles when write is false
|
|
65
|
-
*/
|
|
66
|
-
async bundle(entryPoints: string[], options?: esbuild.BuildOptions): Promise<esbuild.BuildResult> {
|
|
67
|
-
return esbuild.build({
|
|
68
|
-
entryPoints,
|
|
69
|
-
bundle: true,
|
|
70
|
-
platform: 'node',
|
|
71
|
-
format: 'esm',
|
|
72
|
-
target: 'esnext',
|
|
73
|
-
write: false,
|
|
74
|
-
...options
|
|
75
|
-
})
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export default ESBuild
|