@soederpop/luca 0.0.29 → 0.0.30

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 (46) hide show
  1. package/commands/try-all-challenges.ts +1 -1
  2. package/docs/TABLE-OF-CONTENTS.md +0 -3
  3. package/docs/tutorials/20-browser-esm.md +234 -0
  4. package/package.json +1 -1
  5. package/src/agi/container.server.ts +4 -0
  6. package/src/agi/features/assistant.ts +62 -1
  7. package/src/agi/features/browser-use.ts +623 -0
  8. package/src/bootstrap/generated.ts +236 -308
  9. package/src/cli/build-info.ts +2 -2
  10. package/src/clients/rest.ts +7 -7
  11. package/src/commands/chat.ts +22 -0
  12. package/src/commands/describe.ts +67 -2
  13. package/src/commands/prompt.ts +23 -3
  14. package/src/container.ts +411 -113
  15. package/src/helper.ts +189 -5
  16. package/src/introspection/generated.agi.ts +17148 -11148
  17. package/src/introspection/generated.node.ts +5179 -2200
  18. package/src/introspection/generated.web.ts +379 -291
  19. package/src/introspection/index.ts +7 -0
  20. package/src/introspection/scan.ts +224 -7
  21. package/src/node/container.ts +31 -10
  22. package/src/node/features/content-db.ts +7 -7
  23. package/src/node/features/disk-cache.ts +11 -11
  24. package/src/node/features/esbuild.ts +3 -3
  25. package/src/node/features/file-manager.ts +15 -15
  26. package/src/node/features/fs.ts +23 -22
  27. package/src/node/features/git.ts +10 -10
  28. package/src/node/features/ink.ts +13 -13
  29. package/src/node/features/ipc-socket.ts +8 -8
  30. package/src/node/features/networking.ts +3 -3
  31. package/src/node/features/os.ts +7 -7
  32. package/src/node/features/package-finder.ts +15 -15
  33. package/src/node/features/proc.ts +1 -1
  34. package/src/node/features/ui.ts +13 -13
  35. package/src/node/features/vm.ts +4 -4
  36. package/src/scaffolds/generated.ts +1 -1
  37. package/src/servers/express.ts +6 -6
  38. package/src/servers/mcp.ts +4 -4
  39. package/src/servers/socket.ts +6 -6
  40. package/docs/apis/features/node/window-manager.md +0 -445
  41. package/docs/examples/window-manager-layouts.md +0 -180
  42. package/docs/examples/window-manager.md +0 -125
  43. package/docs/window-manager-fix.md +0 -249
  44. package/scripts/test-window-manager-lifecycle.ts +0 -86
  45. package/scripts/test-window-manager.ts +0 -43
  46. package/src/node/features/window-manager.ts +0 -1603
@@ -148,7 +148,7 @@ export class PackageFinder<
148
148
  * }, '/project/node_modules/lodash/package.json');
149
149
  * ```
150
150
  */
151
- addPackage(manifest: PartialManifest, path: string) {
151
+ addPackage(manifest: PartialManifest, path: string): void {
152
152
  const { name } = manifest
153
153
 
154
154
  if (!this.packages[name]) {
@@ -179,7 +179,7 @@ export class PackageFinder<
179
179
  * });
180
180
  * ```
181
181
  */
182
- get duplicates() {
182
+ get duplicates(): string[] {
183
183
  return Object.keys(
184
184
  pickBy(this.packages, (packages) => packages.length > 1)
185
185
  )
@@ -199,7 +199,7 @@ export class PackageFinder<
199
199
  * console.log(`Found ${finder.packageNames.length} unique packages`);
200
200
  * ```
201
201
  */
202
- async start() {
202
+ async start(): Promise<this | undefined> {
203
203
  if (this.isStarted) {
204
204
  return this;
205
205
  }
@@ -234,7 +234,7 @@ export class PackageFinder<
234
234
  * console.log(`Scanned ${finder.manifests.length} packages`);
235
235
  * ```
236
236
  */
237
- async scan(options: { exclude?: string | string[] } = {}) {
237
+ async scan(options: { exclude?: string | string[] } = {}): Promise<this> {
238
238
  const packageFolders = await this.findAllPackageFolders()
239
239
  const manifestPaths = packageFolders.map((folder) => `${folder}/package.json`)
240
240
 
@@ -256,7 +256,7 @@ export class PackageFinder<
256
256
  *
257
257
  * @returns True if the finder has been started and scanning is complete
258
258
  */
259
- get isStarted() {
259
+ get isStarted(): boolean {
260
260
  return !!this.state.get("started");
261
261
  }
262
262
 
@@ -271,7 +271,7 @@ export class PackageFinder<
271
271
  * console.log(`Found ${names.length} unique packages`);
272
272
  * ```
273
273
  */
274
- get packageNames() {
274
+ get packageNames(): string[] {
275
275
  return Object.keys(this.packages)
276
276
  }
277
277
 
@@ -294,7 +294,7 @@ export class PackageFinder<
294
294
  * });
295
295
  * ```
296
296
  */
297
- get scopes() {
297
+ get scopes(): string[] {
298
298
  return Array.from(
299
299
  new Set(this.packageNames.filter(p => p.startsWith('@')).map(p => p.split('/')[0]))
300
300
  )
@@ -317,7 +317,7 @@ export class PackageFinder<
317
317
  * }
318
318
  * ```
319
319
  */
320
- findByName(name: string) {
320
+ findByName(name: string): PartialManifest | undefined {
321
321
  return this.find((i) => i.name === name)
322
322
  }
323
323
 
@@ -340,7 +340,7 @@ export class PackageFinder<
340
340
  * });
341
341
  * ```
342
342
  */
343
- findDependentsOf(packageName: string) {
343
+ findDependentsOf(packageName: string): PartialManifest[] {
344
344
  return this.filter(({ dependencies = {}, devDependencies = {} }) => {
345
345
  return packageName in dependencies || packageName in devDependencies
346
346
  })
@@ -361,7 +361,7 @@ export class PackageFinder<
361
361
  * const utility = finder.find(pkg => pkg.description?.includes('utility'));
362
362
  * ```
363
363
  */
364
- find(filter: (manifest: PartialManifest) => boolean) {
364
+ find(filter: (manifest: PartialManifest) => boolean): PartialManifest | undefined {
365
365
  return this.manifests.find(filter)
366
366
  }
367
367
 
@@ -383,7 +383,7 @@ export class PackageFinder<
383
383
  * const scoped = finder.filter(pkg => pkg.name.startsWith('@'));
384
384
  * ```
385
385
  */
386
- filter(filter: (manifest: PartialManifest) => boolean) {
386
+ filter(filter: (manifest: PartialManifest) => boolean): PartialManifest[] {
387
387
  return this.manifests.filter(filter)
388
388
  }
389
389
 
@@ -404,7 +404,7 @@ export class PackageFinder<
404
404
  * const unscoped = finder.exclude(pkg => pkg.name.startsWith('@'));
405
405
  * ```
406
406
  */
407
- exclude(filter: (manifest: PartialManifest) => boolean) {
407
+ exclude(filter: (manifest: PartialManifest) => boolean): PartialManifest[] {
408
408
  return this.manifests.filter((m) => !filter(m))
409
409
  }
410
410
 
@@ -428,7 +428,7 @@ export class PackageFinder<
428
428
  * }, {});
429
429
  * ```
430
430
  */
431
- get manifests() {
431
+ get manifests(): (PartialManifest & { __path: string })[] {
432
432
  return Object.values(this.packages).flat()
433
433
  }
434
434
 
@@ -452,7 +452,7 @@ export class PackageFinder<
452
452
  * });
453
453
  * ```
454
454
  */
455
- get counts() {
455
+ get counts(): Record<string, number> {
456
456
  return mapValues(this.packages, (packages) => packages.length)
457
457
  }
458
458
 
@@ -489,7 +489,7 @@ export class PackageFinder<
489
489
  return results;
490
490
  }
491
491
 
492
- async findLocalPackageFolders() {
492
+ async findLocalPackageFolders(): Promise<string[]> {
493
493
  const cmd = "find . -name package.json"
494
494
  const result = this.container.proc.exec(cmd)
495
495
  const all = result.split("\n").filter(Boolean).map((path: string) => this.container.paths.dirname(path))
@@ -233,7 +233,7 @@ export class ChildProcess extends Feature {
233
233
  * Useful when callers need streaming access to stdout/stderr and
234
234
  * direct lifecycle control (for example, cancellation via kill()).
235
235
  */
236
- spawn(command: string, args: string[] = [], options: RawSpawnOptions = {}) {
236
+ spawn(command: string, args: string[] = [], options: RawSpawnOptions = {}): import('child_process').ChildProcess {
237
237
  const cwd = options.cwd ?? this.container.cwd
238
238
  const stdout = options.stdout ?? 'pipe'
239
239
  const stderr = options.stderr ?? 'pipe'
@@ -104,7 +104,7 @@ export class UI<T extends UIState = UIState> extends Feature<T> {
104
104
  * @param text - The markdown string to parse and render
105
105
  * @returns The rendered terminal-formatted string
106
106
  */
107
- markdown(text: string) {
107
+ markdown(text: string): string | Promise<string> {
108
108
  return marked.parse(text)
109
109
  }
110
110
 
@@ -220,7 +220,7 @@ export class UI<T extends UIState = UIState> extends Feature<T> {
220
220
  * });
221
221
  * ```
222
222
  */
223
- get randomColor() {
223
+ get randomColor(): string | undefined {
224
224
  const colors = Object.keys(this.colors);
225
225
  const index = Math.floor(Math.random() * colors.length);
226
226
 
@@ -321,7 +321,7 @@ export class UI<T extends UIState = UIState> extends Feature<T> {
321
321
  * ], { version: '1.0.0' });
322
322
  * ```
323
323
  */
324
- wizard(questions: any[], initialAnswers: any = {}) {
324
+ wizard(questions: any[], initialAnswers: any = {}): Promise<any> {
325
325
  return inquirer.createPromptModule()(questions, initialAnswers);
326
326
  }
327
327
 
@@ -331,7 +331,7 @@ export class UI<T extends UIState = UIState> extends Feature<T> {
331
331
  * @param question - The question message to display
332
332
  * @returns Promise resolving to the answers object with a `question` key
333
333
  */
334
- askQuestion(question: string) {
334
+ askQuestion(question: string): Promise<any> {
335
335
  return inquirer.createPromptModule()([{
336
336
  type: 'input',
337
337
  name: 'question',
@@ -371,7 +371,7 @@ export class UI<T extends UIState = UIState> extends Feature<T> {
371
371
  * const editedMarkdown = await ui.openInEditor(markdown, '.md');
372
372
  * ```
373
373
  */
374
- async openInEditor(text: string, extension = ".ts") {
374
+ async openInEditor(text: string, extension = ".ts"): Promise<unknown> {
375
375
  const results = await new Promise((resolve, reject) => {
376
376
  /*
377
377
  editAsync(
@@ -429,7 +429,7 @@ export class UI<T extends UIState = UIState> extends Feature<T> {
429
429
  * console.log('Available fonts:', ui.fonts.slice(0, 10).join(', '));
430
430
  * ```
431
431
  */
432
- asciiArt(text: string, font: Fonts) {
432
+ asciiArt(text: string, font: Fonts): string {
433
433
  if (!figlet) return text;
434
434
  return figlet.textSync(text, font);
435
435
  }
@@ -481,7 +481,7 @@ export class UI<T extends UIState = UIState> extends Feature<T> {
481
481
  * // Available colors: any chalk color names
482
482
  * ```
483
483
  */
484
- banner(text: string, options: { font: Fonts; colors: Color[] } = { font: 'Star Wars', colors: ['red', 'white', 'blue'] }) {
484
+ banner(text: string, options: { font: Fonts; colors: Color[] } = { font: 'Star Wars', colors: ['red', 'white', 'blue'] }): string {
485
485
  const art = this.asciiArt(text, options.font || 'Star Wars');
486
486
  const colored = this.applyGradient(art, options.colors || ['red', 'white', 'blue']);
487
487
 
@@ -495,7 +495,7 @@ export class UI<T extends UIState = UIState> extends Feature<T> {
495
495
  * @param args - Tagged template literal arguments
496
496
  * @returns The dedented string
497
497
  */
498
- endent(...args: any[]) {
498
+ endent(...args: any[]): string {
499
499
  // @ts-ignore
500
500
  return endent(...args)
501
501
  }
@@ -544,7 +544,7 @@ export class UI<T extends UIState = UIState> extends Feature<T> {
544
544
  text: string,
545
545
  lineColors: Color[] = ["red", "white", "blue"],
546
546
  direction: "horizontal" | "vertical" = "horizontal"
547
- ) {
547
+ ): string {
548
548
  if (direction === "horizontal") {
549
549
  return this.applyHorizontalGradient(text, lineColors);
550
550
  }
@@ -587,7 +587,7 @@ export class UI<T extends UIState = UIState> extends Feature<T> {
587
587
  applyHorizontalGradient(
588
588
  text: string,
589
589
  lineColors: Color[] = ["red", "white", "blue"]
590
- ) {
590
+ ): string {
591
591
  const gColors = Object.fromEntries(
592
592
  lineColors.map((color) => [color, this.colors[color]])
593
593
  );
@@ -639,7 +639,7 @@ export class UI<T extends UIState = UIState> extends Feature<T> {
639
639
  applyVerticalGradient(
640
640
  text: string,
641
641
  lineColors: Color[] = ["red", "white", "blue"]
642
- ) {
642
+ ): string {
643
643
  const gColors = Object.fromEntries(
644
644
  lineColors.map((color) => [color, this.colors[color]])
645
645
  );
@@ -689,7 +689,7 @@ export class UI<T extends UIState = UIState> extends Feature<T> {
689
689
  * const title = ui.padLeft('TITLE', 20, '-'); // '---------------TITLE'
690
690
  * ```
691
691
  */
692
- padLeft(str: string, length: number, padChar = " ") {
692
+ padLeft(str: string, length: number, padChar = " "): string {
693
693
  if (str.length >= length) {
694
694
  return str;
695
695
  }
@@ -744,7 +744,7 @@ export class UI<T extends UIState = UIState> extends Feature<T> {
744
744
  * const menuItem = ui.padRight('Coffee', 20, '.') + '$3.50';
745
745
  * ```
746
746
  */
747
- padRight(str: string, length: number, padChar = " ") {
747
+ padRight(str: string, length: number, padChar = " "): string {
748
748
  if (str.length >= length) {
749
749
  return str;
750
750
  }
@@ -67,7 +67,7 @@ export class VM<
67
67
  * // import { Container } from '@soederpop/luca' → works
68
68
  * ```
69
69
  */
70
- defineModule(id: string, exports: any) {
70
+ defineModule(id: string, exports: any): void {
71
71
  this.modules.set(id, exports)
72
72
  }
73
73
 
@@ -78,7 +78,7 @@ export class VM<
78
78
  * @param filePath - The file path to scope native require resolution to
79
79
  * @returns A require function with `.resolve` preserved from the native require
80
80
  */
81
- createRequireFor(filePath: string) {
81
+ createRequireFor(filePath: string): ((id: string) => any) & { resolve: RequireResolve } {
82
82
  const nodeRequire = createRequire(filePath)
83
83
  const modules = this.modules
84
84
 
@@ -111,7 +111,7 @@ export class VM<
111
111
  * const result2 = script.runInContext(vm.createContext({ a: 10, b: 20 }))
112
112
  * ```
113
113
  */
114
- createScript(code: string, options?: vm.ScriptOptions) {
114
+ createScript(code: string, options?: vm.ScriptOptions): vm.Script {
115
115
  return new vm.Script(code, {
116
116
  ...options
117
117
  })
@@ -152,7 +152,7 @@ export class VM<
152
152
  * const result = vm.runSync('user.name', context)
153
153
  * ```
154
154
  */
155
- createContext(ctx: any = {}) {
155
+ createContext(ctx: any = {}): vm.Context {
156
156
  if (this.isContext(ctx)) return ctx
157
157
  return vm.createContext({
158
158
  console,
@@ -1,5 +1,5 @@
1
1
  // Auto-generated scaffold and MCP readme content
2
- // Generated at: 2026-03-24T01:41:40.005Z
2
+ // Generated at: 2026-03-24T06:38:36.374Z
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
@@ -55,11 +55,11 @@ export class ExpressServer<T extends ServerState = ServerState, K extends Expres
55
55
  _listener?: any
56
56
  _mountedEndpoints: Endpoint[] = []
57
57
 
58
- get express() {
58
+ get express(): typeof express {
59
59
  return express
60
60
  }
61
61
 
62
- get hooks() {
62
+ get hooks(): { create: (app: Express, server: Server) => Express; beforeStart: (options: any, server: Server) => any } {
63
63
  const { create = defaultCreate, beforeStart = () => {} } = this.options
64
64
 
65
65
  return {
@@ -68,7 +68,7 @@ export class ExpressServer<T extends ServerState = ServerState, K extends Expres
68
68
  }
69
69
  }
70
70
 
71
- get app() {
71
+ get app(): Express {
72
72
  if(this._app) {
73
73
  return this._app
74
74
  }
@@ -99,7 +99,7 @@ export class ExpressServer<T extends ServerState = ServerState, K extends Expres
99
99
  *
100
100
  * @param options - Optional runtime overrides for port and host
101
101
  */
102
- override async start(options?: StartOptions) {
102
+ override async start(options?: StartOptions): Promise<this> {
103
103
  if (this.isListening) {
104
104
  return this
105
105
  }
@@ -137,7 +137,7 @@ export class ExpressServer<T extends ServerState = ServerState, K extends Expres
137
137
  return this
138
138
  }
139
139
 
140
- override async stop() {
140
+ override async stop(): Promise<this> {
141
141
  if (this.isStopped) {
142
142
  return this
143
143
  }
@@ -167,7 +167,7 @@ export class ExpressServer<T extends ServerState = ServerState, K extends Expres
167
167
  return this
168
168
  }
169
169
 
170
- override async configure() {
170
+ override async configure(): Promise<this> {
171
171
  this.state.set('configured', true)
172
172
  return this
173
173
  }
@@ -428,7 +428,7 @@ export class MCPServer extends Server<MCPServerState, MCPServerOptions> {
428
428
  * Configure the MCP protocol server and register all protocol handlers.
429
429
  * Called automatically before start() if not already configured.
430
430
  */
431
- override async configure() {
431
+ override async configure(): Promise<this> {
432
432
  if (this.isConfigured) return this
433
433
 
434
434
  const serverName = this.options.serverName || this.container.manifest?.name || 'luca-mcp'
@@ -470,7 +470,7 @@ export class MCPServer extends Server<MCPServerState, MCPServerOptions> {
470
470
  host?: string
471
471
  mcpCompat?: MCPCompatMode
472
472
  stdioCompat?: StdioCompatMode
473
- }) {
473
+ }): Promise<this> {
474
474
  if (this.isListening) return this
475
475
  await this._drainPendingPlugins()
476
476
  if (!this.isConfigured) await this.configure()
@@ -499,7 +499,7 @@ export class MCPServer extends Server<MCPServerState, MCPServerOptions> {
499
499
  /**
500
500
  * Stop the MCP server and close all connections.
501
501
  */
502
- override async stop() {
502
+ override async stop(): Promise<this> {
503
503
  if (this.isStopped) return this
504
504
 
505
505
  if (this._mcpServer) {
@@ -631,7 +631,7 @@ export class MCPServer extends Server<MCPServerState, MCPServerOptions> {
631
631
  }
632
632
 
633
633
  /** Start an HTTP transport using StreamableHTTPServerTransport. */
634
- private async _startHTTPTransport(port: number, compat: MCPCompatMode) {
634
+ private async _startHTTPTransport(port: number, compat: MCPCompatMode): Promise<void> {
635
635
  const { createServer } = await import('node:http')
636
636
  const { StreamableHTTPServerTransport } = await import(
637
637
  '@modelcontextprotocol/sdk/server/streamableHttp.js'
@@ -65,7 +65,7 @@ export class WebsocketServer<T extends ServerState = ServerState, K extends Sock
65
65
 
66
66
  _wss?: BaseServer
67
67
 
68
- get wss() {
68
+ get wss(): BaseServer {
69
69
  if (this._wss) {
70
70
  return this._wss
71
71
  }
@@ -78,7 +78,7 @@ export class WebsocketServer<T extends ServerState = ServerState, K extends Sock
78
78
  connections : Set<any> = new Set()
79
79
  _pending = new Map<string, PendingRequest>()
80
80
 
81
- async broadcast(message: any) {
81
+ async broadcast(message: any): Promise<this> {
82
82
  for(const ws of this.connections) {
83
83
  await ws.send(JSON.stringify(message))
84
84
  }
@@ -86,7 +86,7 @@ export class WebsocketServer<T extends ServerState = ServerState, K extends Sock
86
86
  return this
87
87
  }
88
88
 
89
- async send(ws: any, message: any) {
89
+ async send(ws: any, message: any): Promise<this> {
90
90
  await ws.send(JSON.stringify(message))
91
91
  return this
92
92
  }
@@ -158,7 +158,7 @@ export class WebsocketServer<T extends ServerState = ServerState, K extends Sock
158
158
  *
159
159
  * @param options - Optional runtime overrides for port and host
160
160
  */
161
- override async start(options?: StartOptions) {
161
+ override async start(options?: StartOptions): Promise<this> {
162
162
  if (this.isListening) {
163
163
  return this
164
164
  }
@@ -209,7 +209,7 @@ export class WebsocketServer<T extends ServerState = ServerState, K extends Sock
209
209
  return this
210
210
  }
211
211
 
212
- override async stop() {
212
+ override async stop(): Promise<this> {
213
213
  if (this.isStopped) {
214
214
  return this
215
215
  }
@@ -250,7 +250,7 @@ export class WebsocketServer<T extends ServerState = ServerState, K extends Sock
250
250
  }
251
251
 
252
252
  /** The port this server will bind to. Defaults to 8081 if not set via constructor options or start(). */
253
- override get port() {
253
+ override get port(): number {
254
254
  return this.state.get('port') || this.options.port || 8081
255
255
  }
256
256
  }