@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
@@ -2,11 +2,12 @@ import { z } from 'zod'
2
2
  import { commands } from '../command.js'
3
3
  import { CommandOptionsSchema } from '../schemas/base.js'
4
4
  import type { ContainerContext } from '../container.js'
5
- import type { HelperIntrospection } from '../introspection/index.js'
5
+ import type { HelperIntrospection, IntrospectionSection } from '../introspection/index.js'
6
6
  import { __INTROSPECTION__, __BROWSER_INTROSPECTION__ } from '../introspection/index.js'
7
7
  import { features } from '../feature.js'
8
8
  import { ContainerDescriber } from '../container-describer.js'
9
9
  import type { BrowserFeatureData } from '../container-describer.js'
10
+ import { presentIntrospectionAsTypeScript } from '../helper.js'
10
11
 
11
12
  declare module '../command.js' {
12
13
  interface AvailableCommands {
@@ -16,6 +17,8 @@ declare module '../command.js' {
16
17
 
17
18
  export const argsSchema = CommandOptionsSchema.extend({
18
19
  json: z.boolean().default(false).describe('Output introspection data as JSON instead of markdown'),
20
+ typescript: z.boolean().default(false).describe('Output introspection data as TypeScript interface declarations'),
21
+ ts: z.boolean().default(false).describe('Alias for --typescript'),
19
22
  pretty: z.boolean().default(false).describe('Render markdown with terminal styling via ui.markdown'),
20
23
  title: z.boolean().default(true).describe('Include the title header in the output (use --no-title to omit)'),
21
24
  // Clean section flags (can be combined: --description --usage)
@@ -156,7 +159,12 @@ export default async function describe(options: z.infer<typeof argsSchema>, cont
156
159
  platform: options.platform as any,
157
160
  })
158
161
 
159
- if (options.json) {
162
+ const wantsTypeScript = options.typescript || options.ts
163
+
164
+ if (wantsTypeScript) {
165
+ const output = renderResultAsTypeScript(result, targets, describer, sections)
166
+ console.log(output)
167
+ } else if (options.json) {
160
168
  console.log(JSON.stringify(result.json, null, 2))
161
169
  } else if (options.pretty) {
162
170
  const ui = container.feature('ui')
@@ -166,6 +174,63 @@ export default async function describe(options: z.infer<typeof argsSchema>, cont
166
174
  }
167
175
  }
168
176
 
177
+ /**
178
+ * Renders the describe result as TypeScript interface declarations.
179
+ * Handles single helpers, arrays of helpers (registry describes), and the container.
180
+ */
181
+ function renderResultAsTypeScript(result: { json: any; text: string }, targets: string[], describer: ContainerDescriber, sections: (IntrospectionSection | 'description')[]): string {
182
+ const json = result.json
183
+ const section = sections.length === 1 && sections[0] !== 'description' ? sections[0] as IntrospectionSection : undefined
184
+
185
+ // Single helper introspection object (has shortcut = full data, or id = filtered data)
186
+ if (json && (json.shortcut || json.id)) {
187
+ // If sections were applied, the JSON is partial — get full data and pass section to renderer
188
+ const fullData = json.shortcut ? json : __INTROSPECTION__.get(json.id) || json
189
+ return presentIntrospectionAsTypeScript(fullData, section)
190
+ }
191
+
192
+ // Container introspection (has className, registries, factories)
193
+ if (json && json.className && json.registries) {
194
+ const container = (describer as any).container
195
+ return container.inspectAsType()
196
+ }
197
+
198
+ // Array of results (e.g. from registry describe or multiple targets)
199
+ if (Array.isArray(json)) {
200
+ const interfaces = json
201
+ .filter((item: any) => item && (item.shortcut || item.id))
202
+ .map((item: any) => {
203
+ const fullData = item.shortcut ? item : __INTROSPECTION__.get(item.id) || item
204
+ return presentIntrospectionAsTypeScript(fullData, section)
205
+ })
206
+ return interfaces.join('\n\n')
207
+ }
208
+
209
+ // Object keyed by helper id (registry describe format — has _shared and per-helper summaries)
210
+ if (json && typeof json === 'object' && !json._helper && json._shared) {
211
+ const ids = Object.keys(json).filter(k => k !== '_shared')
212
+ const interfaces = ids
213
+ .map((id: string) => {
214
+ // Try qualified key first (e.g. "clients.rest"), then scan the introspection map
215
+ for (const prefix of ['features', 'clients', 'servers', 'commands', 'endpoints']) {
216
+ const data = __INTROSPECTION__.get(`${prefix}.${id}`)
217
+ if (data) return presentIntrospectionAsTypeScript(data, section)
218
+ }
219
+ return null
220
+ })
221
+ .filter(Boolean)
222
+ if (interfaces.length > 0) return interfaces.join('\n\n')
223
+ }
224
+
225
+ // Member-level result (has _helper and _type) — render the full helper interface
226
+ if (json && json._helper) {
227
+ const fullData = __INTROSPECTION__.get(json._helper) || __INTROSPECTION__.get(`features.${json._helper}`)
228
+ if (fullData) return presentIntrospectionAsTypeScript(fullData)
229
+ }
230
+
231
+ return result.text
232
+ }
233
+
169
234
  commands.registerHandler('describe', {
170
235
  description: 'Describe the container, registries, or individual helpers',
171
236
  argsSchema,
@@ -12,7 +12,8 @@ declare module '../command.js' {
12
12
 
13
13
  export const argsSchema = CommandOptionsSchema.extend({
14
14
  model: z.string().optional().describe('Override the LLM model (assistant mode only)'),
15
- 'preserve-frontmatter': z.boolean().default(false).describe('Keep YAML frontmatter in the prompt instead of stripping it before sending to the agent.'),
15
+ 'include-frontmatter': z.boolean().default(false).describe('Keep YAML frontmatter in the prompt instead of stripping it before sending to the agent.'),
16
+ 'skip-eval': z.boolean().default(false).describe('Skip execution of fenced code blocks in the prompt file'),
16
17
  'permission-mode': z.enum(['default', 'acceptEdits', 'bypassPermissions', 'plan']).default('acceptEdits').describe('Permission mode for CLI agents (default: acceptEdits)'),
17
18
  'in-folder': z.string().optional().describe('Run the CLI agent in this directory (resolved via container.paths)'),
18
19
  'out-file': z.string().optional().describe('Save session output as a markdown file'),
@@ -790,12 +791,31 @@ async function preparePrompt(
790
791
  }
791
792
 
792
793
  let promptContent: string
793
- if (options['preserve-frontmatter']) {
794
- promptContent = content
794
+ if (options['skip-eval']) {
795
+ // Strip frontmatter but don't execute code blocks
796
+ if (content.startsWith('---')) {
797
+ const fmEnd = content.indexOf('\n---', 3)
798
+ if (fmEnd !== -1) {
799
+ promptContent = content.slice(fmEnd + 4).trimStart()
800
+ } else {
801
+ promptContent = content
802
+ }
803
+ } else {
804
+ promptContent = content
805
+ }
795
806
  } else {
796
807
  promptContent = await executePromptFile(resolvedPath, container, resolvedInputs)
797
808
  }
798
809
 
810
+ // Re-attach frontmatter if requested
811
+ if (options['include-frontmatter'] && content.startsWith('---')) {
812
+ const fmEnd = content.indexOf('\n---', 3)
813
+ if (fmEnd !== -1) {
814
+ const frontmatter = content.slice(0, fmEnd + 4)
815
+ promptContent = frontmatter + '\n' + promptContent
816
+ }
817
+ }
818
+
799
819
  // Substitute {{key}} placeholders with resolved input values
800
820
  if (Object.keys(resolvedInputs).length) {
801
821
  promptContent = substituteInputs(promptContent, resolvedInputs)