@soederpop/luca 0.0.23 → 0.0.26

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 (67) hide show
  1. package/AGENTS.md +1 -1
  2. package/CLAUDE.md +6 -1
  3. package/assistants/codingAssistant/hooks.ts +0 -1
  4. package/assistants/lucaExpert/CORE.md +37 -0
  5. package/assistants/lucaExpert/hooks.ts +9 -0
  6. package/assistants/lucaExpert/tools.ts +177 -0
  7. package/commands/build-bootstrap.ts +41 -1
  8. package/docs/TABLE-OF-CONTENTS.md +0 -1
  9. package/docs/apis/clients/rest.md +5 -5
  10. package/docs/apis/features/agi/assistant.md +1 -1
  11. package/docs/apis/features/agi/conversation-history.md +6 -7
  12. package/docs/apis/features/agi/conversation.md +1 -1
  13. package/docs/apis/features/agi/semantic-search.md +1 -1
  14. package/docs/bootstrap/CLAUDE.md +1 -1
  15. package/docs/bootstrap/SKILL.md +7 -3
  16. package/docs/bootstrap/templates/luca-cli.ts +5 -0
  17. package/docs/mcp/readme.md +1 -1
  18. package/docs/tutorials/00-bootstrap.md +18 -0
  19. package/package.json +2 -2
  20. package/scripts/stamp-build.sh +12 -0
  21. package/scripts/test-docs-reader.ts +10 -0
  22. package/src/agi/container.server.ts +8 -5
  23. package/src/agi/features/assistant.ts +210 -55
  24. package/src/agi/features/assistants-manager.ts +138 -66
  25. package/src/agi/features/conversation.ts +46 -14
  26. package/src/agi/features/docs-reader.ts +166 -0
  27. package/src/agi/features/openapi.ts +1 -1
  28. package/src/agi/features/skills-library.ts +257 -313
  29. package/src/bootstrap/generated.ts +8163 -6
  30. package/src/cli/build-info.ts +4 -0
  31. package/src/cli/cli.ts +2 -1
  32. package/src/command.ts +75 -0
  33. package/src/commands/bootstrap.ts +16 -1
  34. package/src/commands/describe.ts +29 -1089
  35. package/src/commands/eval.ts +6 -1
  36. package/src/commands/sandbox-mcp.ts +17 -7
  37. package/src/container-describer.ts +1098 -0
  38. package/src/container.ts +11 -0
  39. package/src/helper.ts +56 -2
  40. package/src/introspection/generated.agi.ts +1684 -799
  41. package/src/introspection/generated.node.ts +964 -572
  42. package/src/introspection/generated.web.ts +9 -1
  43. package/src/node/container.ts +1 -1
  44. package/src/node/features/content-db.ts +268 -13
  45. package/src/node/features/fs.ts +18 -0
  46. package/src/node/features/git.ts +90 -0
  47. package/src/node/features/grep.ts +1 -1
  48. package/src/node/features/proc.ts +1 -0
  49. package/src/node/features/tts.ts +1 -1
  50. package/src/node/features/vm.ts +48 -0
  51. package/src/scaffolds/generated.ts +2 -2
  52. package/src/server.ts +40 -0
  53. package/src/servers/express.ts +2 -0
  54. package/src/servers/mcp.ts +1 -0
  55. package/src/servers/socket.ts +2 -0
  56. package/assistants/architect/CORE.md +0 -3
  57. package/assistants/architect/hooks.ts +0 -3
  58. package/assistants/architect/tools.ts +0 -10
  59. package/docs/apis/features/agi/skills-library.md +0 -234
  60. package/docs/reports/assistant-bugs.md +0 -38
  61. package/docs/reports/attach-pattern-usage.md +0 -18
  62. package/docs/reports/code-audit-results.md +0 -391
  63. package/docs/reports/console-hmr-design.md +0 -170
  64. package/docs/reports/helper-semantic-search.md +0 -72
  65. package/docs/reports/introspection-audit-tasks.md +0 -378
  66. package/docs/reports/luca-mcp-improvements.md +0 -128
  67. package/test-integration/skills-library.test.ts +0 -157
@@ -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-21T15:48:33.144Z
4
+ // Generated at: 2026-03-22T20:57:23.197Z
5
5
 
6
6
  setBuildTimeData('features.googleDocs', {
7
7
  "id": "features.googleDocs",
@@ -729,6 +729,25 @@ setBuildTimeData('features.git', {
729
729
  }
730
730
  ]
731
731
  },
732
+ "extractFolder": {
733
+ "description": "Extracts a folder (or entire repo) from a remote GitHub repository without cloning. Downloads the repo as a tarball and extracts only the specified subfolder, similar to how degit works. No .git history is included — just the files. Supports shorthand (`user/repo/path`), branch refs (`user/repo/path#branch`), and full GitHub URLs (`https://github.com/user/repo/tree/branch/path`).",
734
+ "parameters": {
735
+ "{ source, destination, branch }": {
736
+ "type": "{ source: string, destination: string, branch?: string }",
737
+ "description": "Parameter { source, destination, branch }"
738
+ }
739
+ },
740
+ "required": [
741
+ "{ source, destination, branch }"
742
+ ],
743
+ "returns": "void",
744
+ "examples": [
745
+ {
746
+ "language": "ts",
747
+ "code": "// Extract a subfolder\nawait git.extractFolder({ source: 'soederpop/luca/src/assistants', destination: './my-assistants' })\n\n// Specific branch\nawait git.extractFolder({ source: 'sveltejs/template', destination: './my-app', branch: 'main' })\n\n// Full GitHub URL\nawait git.extractFolder({ source: 'https://github.com/user/repo/tree/main/examples', destination: './examples' })"
748
+ }
749
+ ]
750
+ },
732
751
  "getChangeHistoryForFiles": {
733
752
  "description": "Gets the commit history for a set of files or glob patterns. Accepts absolute paths, relative paths (resolved from container.cwd), or glob patterns. Returns commits that touched any of the matched files, with each entry noting which of your queried files were in that commit.",
734
753
  "parameters": {
@@ -2299,6 +2318,29 @@ setBuildTimeData('features.vm', {
2299
2318
  ],
2300
2319
  "returns": "Promise<T>"
2301
2320
  },
2321
+ "runCaptured": {
2322
+ "description": "Execute code and capture all console output as structured JSON. Returns both the execution result and an array of every `console.*` call made during execution, each entry recording the method name and arguments.",
2323
+ "parameters": {
2324
+ "code": {
2325
+ "type": "string",
2326
+ "description": "The JavaScript code to execute"
2327
+ },
2328
+ "ctx": {
2329
+ "type": "any",
2330
+ "description": "Context variables to make available to the executing code"
2331
+ }
2332
+ },
2333
+ "required": [
2334
+ "code"
2335
+ ],
2336
+ "returns": "Promise<{\n result: T\n console: Array<{ method: string, args: any[] }>\n context: vm.Context\n }>",
2337
+ "examples": [
2338
+ {
2339
+ "language": "ts",
2340
+ "code": "const { result, console: calls } = await vm.runCaptured('console.log(\"hi\"); console.warn(\"oh\"); 42')\n// result === 42\n// calls === [{ method: 'log', args: ['hi'] }, { method: 'warn', args: ['oh'] }]"
2341
+ }
2342
+ ]
2343
+ },
2302
2344
  "runSync": {
2303
2345
  "description": "Execute JavaScript code synchronously in a controlled environment.",
2304
2346
  "parameters": {
@@ -5256,6 +5298,23 @@ setBuildTimeData('features.fs', {
5256
5298
  }
5257
5299
  ]
5258
5300
  },
5301
+ "readFileSync": {
5302
+ "description": "Synchronously reads a file and returns its contents as a string. added this method because AI Assistants are understandly confused by this deviation from 2000's era node style",
5303
+ "parameters": {
5304
+ "path": {
5305
+ "type": "string",
5306
+ "description": "Parameter path"
5307
+ },
5308
+ "encoding": {
5309
+ "type": "BufferEncoding | null",
5310
+ "description": "Parameter encoding"
5311
+ }
5312
+ },
5313
+ "required": [
5314
+ "path"
5315
+ ],
5316
+ "returns": "string | Buffer"
5317
+ },
5259
5318
  "readFileAsync": {
5260
5319
  "description": "Asynchronously reads a file and returns its contents as a string.",
5261
5320
  "parameters": {
@@ -5298,6 +5357,19 @@ setBuildTimeData('features.fs', {
5298
5357
  }
5299
5358
  ]
5300
5359
  },
5360
+ "readJsonSync": {
5361
+ "description": "Read and parse a JSON file synchronously",
5362
+ "parameters": {
5363
+ "path": {
5364
+ "type": "string",
5365
+ "description": "Parameter path"
5366
+ }
5367
+ },
5368
+ "required": [
5369
+ "path"
5370
+ ],
5371
+ "returns": "void"
5372
+ },
5301
5373
  "readJsonAsync": {
5302
5374
  "description": "Asynchronously reads and parses a JSON file.",
5303
5375
  "parameters": {
@@ -9101,6 +9173,30 @@ setBuildTimeData('features.contentDb', {
9101
9173
  "shortcut": "features.contentDb",
9102
9174
  "className": "ContentDb",
9103
9175
  "methods": {
9176
+ "renderTree": {
9177
+ "description": "Render a tree view of the collection directory structure. Built with container.fs so it works without the `tree` binary.",
9178
+ "parameters": {
9179
+ "options": {
9180
+ "type": "{ depth?: number; dirsOnly?: boolean }",
9181
+ "description": "Parameter options"
9182
+ }
9183
+ },
9184
+ "required": [],
9185
+ "returns": "string"
9186
+ },
9187
+ "grep": {
9188
+ "description": "",
9189
+ "parameters": {
9190
+ "options": {
9191
+ "type": "string | GrepOptions",
9192
+ "description": "Parameter options"
9193
+ }
9194
+ },
9195
+ "required": [
9196
+ "options"
9197
+ ],
9198
+ "returns": "void"
9199
+ },
9104
9200
  "query": {
9105
9201
  "description": "Query documents belonging to a specific model definition.",
9106
9202
  "parameters": {
@@ -9318,6 +9414,90 @@ setBuildTimeData('features.contentDb', {
9318
9414
  },
9319
9415
  "required": [],
9320
9416
  "returns": "void"
9417
+ },
9418
+ "getCollectionOverview": {
9419
+ "description": "Returns a high-level overview of the collection.",
9420
+ "parameters": {},
9421
+ "required": [],
9422
+ "returns": "void"
9423
+ },
9424
+ "listDocuments": {
9425
+ "description": "List document IDs, optionally filtered by model or glob.",
9426
+ "parameters": {
9427
+ "args": {
9428
+ "type": "{ model?: string; glob?: string }",
9429
+ "description": "Parameter args"
9430
+ }
9431
+ },
9432
+ "required": [
9433
+ "args"
9434
+ ],
9435
+ "returns": "void"
9436
+ },
9437
+ "readDocument": {
9438
+ "description": "Read a single document with optional section filtering.",
9439
+ "parameters": {
9440
+ "args": {
9441
+ "type": "{ id: string; include?: string[]; exclude?: string[]; meta?: boolean }",
9442
+ "description": "Parameter args"
9443
+ }
9444
+ },
9445
+ "required": [
9446
+ "args"
9447
+ ],
9448
+ "returns": "void"
9449
+ },
9450
+ "readMultipleDocuments": {
9451
+ "description": "Read multiple documents with optional section filtering.",
9452
+ "parameters": {
9453
+ "args": {
9454
+ "type": "{ ids: string[]; include?: string[]; exclude?: string[]; meta?: boolean }",
9455
+ "description": "Parameter args"
9456
+ }
9457
+ },
9458
+ "required": [
9459
+ "args"
9460
+ ],
9461
+ "returns": "void"
9462
+ },
9463
+ "queryDocuments": {
9464
+ "description": "Query documents by model with filters, sort, limit.",
9465
+ "parameters": {
9466
+ "args": {
9467
+ "type": "{ model: string; where?: string; sort?: string; limit?: number; offset?: number; select?: string[] }",
9468
+ "description": "Parameter args"
9469
+ }
9470
+ },
9471
+ "required": [
9472
+ "args"
9473
+ ],
9474
+ "returns": "void"
9475
+ },
9476
+ "searchContent": {
9477
+ "description": "Grep/text search across the collection.",
9478
+ "parameters": {
9479
+ "args": {
9480
+ "type": "{ pattern: string; caseSensitive?: boolean }",
9481
+ "description": "Parameter args"
9482
+ }
9483
+ },
9484
+ "required": [
9485
+ "args"
9486
+ ],
9487
+ "returns": "void"
9488
+ },
9489
+ "semanticSearch": {
9490
+ "description": "Hybrid semantic search with graceful fallback to grep.",
9491
+ "parameters": {
9492
+ "args": {
9493
+ "type": "{ query: string; limit?: number }",
9494
+ "description": "Parameter args"
9495
+ }
9496
+ },
9497
+ "required": [
9498
+ "args"
9499
+ ],
9500
+ "returns": "void"
9321
9501
  }
9322
9502
  },
9323
9503
  "getters": {
@@ -9341,6 +9521,18 @@ setBuildTimeData('features.contentDb', {
9341
9521
  "description": "Returns an array of all registered model names from the collection.",
9342
9522
  "returns": "string[]"
9343
9523
  },
9524
+ "available": {
9525
+ "description": "Returns the available document ids in the collection",
9526
+ "returns": "string[]"
9527
+ },
9528
+ "modelDefinitionTable": {
9529
+ "description": "",
9530
+ "returns": "any"
9531
+ },
9532
+ "fileTree": {
9533
+ "description": "",
9534
+ "returns": "any"
9535
+ },
9344
9536
  "searchIndexStatus": {
9345
9537
  "description": "Get the current search index status.",
9346
9538
  "returns": "any"
@@ -9687,466 +9879,466 @@ setBuildTimeData('clients.websocket', {
9687
9879
  ]
9688
9880
  });
9689
9881
 
9690
- setBuildTimeData('clients.supabase', {
9691
- "id": "clients.supabase",
9692
- "description": "Supabase client for the Luca container system. Wraps the official `@supabase/supabase-js` SDK and exposes it through Luca's typed state, events, and introspection system. The SDK is isomorphic so this single implementation works in both Node and browser containers. Use `client.sdk` for full SDK access, or use the convenience wrappers for common operations (auth, database queries, storage, edge functions, realtime).",
9693
- "shortcut": "clients.supabase",
9694
- "className": "SupabaseClient",
9882
+ setBuildTimeData('clients.openai', {
9883
+ "id": "clients.openai",
9884
+ "description": "OpenAI client wraps the OpenAI SDK for chat completions, responses API, embeddings, and image generation. Provides convenience methods for common operations while tracking token usage and request counts. Supports both the Chat Completions API and the newer Responses API.",
9885
+ "shortcut": "clients.openai",
9886
+ "className": "OpenAIClient",
9695
9887
  "methods": {
9696
- "from": {
9697
- "description": "Start a query on a Postgres table or view.",
9888
+ "connect": {
9889
+ "description": "Test the API connection by listing models.",
9890
+ "parameters": {},
9891
+ "required": [],
9892
+ "returns": "Promise<this>",
9893
+ "examples": [
9894
+ {
9895
+ "language": "ts",
9896
+ "code": "await openai.connect()"
9897
+ }
9898
+ ]
9899
+ },
9900
+ "createChatCompletion": {
9901
+ "description": "Create a chat completion using the Chat Completions API.",
9698
9902
  "parameters": {
9699
- "table": {
9700
- "type": "string",
9701
- "description": "The table or view name to query"
9903
+ "messages": {
9904
+ "type": "OpenAI.Chat.Completions.ChatCompletionMessageParam[]",
9905
+ "description": "Array of chat messages"
9906
+ },
9907
+ "options": {
9908
+ "type": "Partial<OpenAI.Chat.Completions.ChatCompletionCreateParams>",
9909
+ "description": "Additional parameters for the completion"
9702
9910
  }
9703
9911
  },
9704
9912
  "required": [
9705
- "table"
9913
+ "messages"
9706
9914
  ],
9707
- "returns": "void"
9915
+ "returns": "Promise<OpenAI.Chat.Completions.ChatCompletion>",
9916
+ "examples": [
9917
+ {
9918
+ "language": "ts",
9919
+ "code": "const response = await openai.createChatCompletion([\n { role: 'system', content: 'You are a helpful assistant.' },\n { role: 'user', content: 'Hello!' }\n])\nconsole.log(response.choices[0]?.message?.content)"
9920
+ }
9921
+ ]
9708
9922
  },
9709
- "rpc": {
9710
- "description": "Call a Postgres function (RPC).",
9923
+ "createResponse": {
9924
+ "description": "Create a response using the Responses API.",
9711
9925
  "parameters": {
9712
- "fn": {
9713
- "type": "string",
9714
- "description": "The function name"
9715
- },
9716
- "params": {
9717
- "type": "Record<string, unknown>",
9718
- "description": "Arguments to pass to the function"
9926
+ "input": {
9927
+ "type": "OpenAI.Responses.ResponseInput | string",
9928
+ "description": "The input prompt or message array"
9719
9929
  },
9720
9930
  "options": {
9721
- "type": "{ head?: boolean; get?: boolean; count?: \"exact\" | \"planned\" | \"estimated\" }",
9722
- "description": "Optional settings (head, get, count)"
9931
+ "type": "Partial<OpenAI.Responses.ResponseCreateParamsNonStreaming>",
9932
+ "description": "Additional parameters for the response"
9723
9933
  }
9724
9934
  },
9725
9935
  "required": [
9726
- "fn"
9936
+ "input"
9727
9937
  ],
9728
- "returns": "void"
9938
+ "returns": "Promise<OpenAI.Responses.Response>",
9939
+ "examples": [
9940
+ {
9941
+ "language": "ts",
9942
+ "code": "const response = await openai.createResponse('Explain quantum computing')"
9943
+ }
9944
+ ]
9729
9945
  },
9730
- "signInWithPassword": {
9731
- "description": "Sign in with email and password.",
9946
+ "streamResponse": {
9947
+ "description": "Stream a response using the Responses API.",
9732
9948
  "parameters": {
9733
- "email": {
9734
- "type": "string",
9735
- "description": "Parameter email"
9949
+ "input": {
9950
+ "type": "OpenAI.Responses.ResponseInput | string",
9951
+ "description": "The input prompt or message array"
9736
9952
  },
9737
- "password": {
9738
- "type": "string",
9739
- "description": "Parameter password"
9953
+ "options": {
9954
+ "type": "Partial<OpenAI.Responses.ResponseCreateParamsStreaming>",
9955
+ "description": "Additional parameters for the streaming response"
9740
9956
  }
9741
9957
  },
9742
9958
  "required": [
9743
- "email",
9744
- "password"
9959
+ "input"
9745
9960
  ],
9746
- "returns": "void"
9961
+ "returns": "Promise<AsyncIterable<OpenAI.Responses.ResponseStreamEvent>>",
9962
+ "examples": [
9963
+ {
9964
+ "language": "ts",
9965
+ "code": "const stream = await openai.streamResponse('Write a poem')\nfor await (const event of stream) {\n if (event.type === 'response.output_text.delta') {\n process.stdout.write(event.delta)\n }\n}"
9966
+ }
9967
+ ]
9747
9968
  },
9748
- "signUp": {
9749
- "description": "Create a new user account with email and password.",
9969
+ "createCompletion": {
9970
+ "description": "Create a legacy text completion.",
9750
9971
  "parameters": {
9751
- "email": {
9972
+ "prompt": {
9752
9973
  "type": "string",
9753
- "description": "Parameter email"
9974
+ "description": "The text prompt to complete"
9754
9975
  },
9755
- "password": {
9756
- "type": "string",
9757
- "description": "Parameter password"
9976
+ "options": {
9977
+ "type": "Partial<OpenAI.Completions.CompletionCreateParams>",
9978
+ "description": "Additional parameters for the completion"
9758
9979
  }
9759
9980
  },
9760
9981
  "required": [
9761
- "email",
9762
- "password"
9982
+ "prompt"
9763
9983
  ],
9764
- "returns": "void"
9765
- },
9766
- "signOut": {
9767
- "description": "Sign the current user out.",
9768
- "parameters": {},
9769
- "required": [],
9770
- "returns": "void"
9771
- },
9772
- "getSession": {
9773
- "description": "Get the current session, if any.",
9774
- "parameters": {},
9775
- "required": [],
9776
- "returns": "void"
9777
- },
9778
- "getUser": {
9779
- "description": "Get the current user, if any.",
9780
- "parameters": {},
9781
- "required": [],
9782
- "returns": "void"
9984
+ "returns": "Promise<OpenAI.Completions.Completion>",
9985
+ "examples": [
9986
+ {
9987
+ "language": "ts",
9988
+ "code": "const response = await openai.createCompletion('Once upon a time')"
9989
+ }
9990
+ ]
9783
9991
  },
9784
- "invoke": {
9785
- "description": "Invoke a Supabase Edge Function by name.",
9992
+ "createEmbedding": {
9993
+ "description": "Create text embeddings for semantic search or similarity comparisons.",
9786
9994
  "parameters": {
9787
- "name": {
9788
- "type": "string",
9789
- "description": "Parameter name"
9995
+ "input": {
9996
+ "type": "string | string[]",
9997
+ "description": "A string or array of strings to embed"
9790
9998
  },
9791
- "body": {
9792
- "type": "any",
9793
- "description": "Parameter body"
9999
+ "options": {
10000
+ "type": "Partial<OpenAI.Embeddings.EmbeddingCreateParams>",
10001
+ "description": "Additional parameters (model, etc.)"
9794
10002
  }
9795
10003
  },
9796
10004
  "required": [
9797
- "name"
10005
+ "input"
9798
10006
  ],
9799
- "returns": "void"
10007
+ "returns": "Promise<OpenAI.Embeddings.CreateEmbeddingResponse>",
10008
+ "examples": [
10009
+ {
10010
+ "language": "ts",
10011
+ "code": "const response = await openai.createEmbedding('Hello world')\nconsole.log(response.data[0].embedding.length)"
10012
+ }
10013
+ ]
9800
10014
  },
9801
- "subscribe": {
9802
- "description": "Subscribe to realtime changes on a Postgres table.",
10015
+ "createImage": {
10016
+ "description": "Generate an image from a text prompt using DALL-E.",
9803
10017
  "parameters": {
9804
- "channelName": {
9805
- "type": "string",
9806
- "description": "A name for this subscription channel"
9807
- },
9808
- "table": {
10018
+ "prompt": {
9809
10019
  "type": "string",
9810
- "description": "The table to listen to"
9811
- },
9812
- "callback": {
9813
- "type": "(payload: any) => void",
9814
- "description": "Called with the payload on each change"
10020
+ "description": "Description of the image to generate"
9815
10021
  },
9816
- "event": {
9817
- "type": "\"INSERT\" | \"UPDATE\" | \"DELETE\" | \"*\"",
9818
- "description": "The event type to listen for (default: all changes)"
10022
+ "options": {
10023
+ "type": "Partial<OpenAI.Images.ImageGenerateParams>",
10024
+ "description": "Additional parameters (size, n, etc.)"
9819
10025
  }
9820
10026
  },
9821
10027
  "required": [
9822
- "channelName",
9823
- "table",
9824
- "callback"
10028
+ "prompt"
9825
10029
  ],
9826
- "returns": "RealtimeChannel"
9827
- },
9828
- "unsubscribe": {
9829
- "description": "Unsubscribe and remove a realtime channel by name.",
9830
- "parameters": {
9831
- "channelName": {
9832
- "type": "string",
9833
- "description": "The channel name to remove"
10030
+ "returns": "Promise<OpenAI.Images.ImagesResponse>",
10031
+ "examples": [
10032
+ {
10033
+ "language": "ts",
10034
+ "code": "const response = await openai.createImage('A sunset over mountains')\nconsole.log(response.data[0].url)"
9834
10035
  }
9835
- },
9836
- "required": [
9837
- "channelName"
9838
- ],
9839
- "returns": "void"
9840
- },
9841
- "unsubscribeAll": {
9842
- "description": "Unsubscribe and remove all realtime channels.",
9843
- "parameters": {},
9844
- "required": [],
9845
- "returns": "void"
9846
- },
9847
- "connect": {
9848
- "description": "Connect is a no-op since the Supabase SDK initializes on construction. The client is ready to use immediately after creation.",
9849
- "parameters": {},
9850
- "required": [],
9851
- "returns": "void"
9852
- },
9853
- "disconnect": {
9854
- "description": "Disconnect by signing out and removing all realtime channels.",
9855
- "parameters": {},
9856
- "required": [],
9857
- "returns": "void"
9858
- }
9859
- },
9860
- "getters": {
9861
- "sdk": {
9862
- "description": "Returns the raw Supabase SDK client for full access to all SDK methods.",
9863
- "returns": "SupabaseSDKClient<any, any>"
9864
- },
9865
- "storage": {
9866
- "description": "Returns the Supabase Storage client for managing buckets and files.",
9867
- "returns": "any"
10036
+ ]
9868
10037
  },
9869
- "functions": {
9870
- "description": "Returns the Supabase Functions client.",
9871
- "returns": "any"
9872
- }
9873
- },
9874
- "events": {},
9875
- "state": {},
9876
- "options": {},
9877
- "envVars": [],
9878
- "examples": [
9879
- {
9880
- "language": "ts",
9881
- "code": "const supabase = container.client('supabase', {\n supabaseUrl: 'https://xyz.supabase.co',\n supabaseKey: 'your-anon-key',\n})\n\n// Query data\nconst { data } = await supabase.from('users').select('*')\n\n// Auth\nawait supabase.signInWithPassword('user@example.com', 'password')\n\n// Realtime\nsupabase.subscribe('changes', 'users', (payload) => {\n console.log('Change:', payload)\n})"
9882
- }
9883
- ]
9884
- });
9885
-
9886
- setBuildTimeData('clients.openai', {
9887
- "id": "clients.openai",
9888
- "description": "OpenAI client — wraps the OpenAI SDK for chat completions, responses API, embeddings, and image generation. Provides convenience methods for common operations while tracking token usage and request counts. Supports both the Chat Completions API and the newer Responses API.",
9889
- "shortcut": "clients.openai",
9890
- "className": "OpenAIClient",
9891
- "methods": {
9892
- "connect": {
9893
- "description": "Test the API connection by listing models.",
10038
+ "listModels": {
10039
+ "description": "List all available models.",
9894
10040
  "parameters": {},
9895
10041
  "required": [],
9896
- "returns": "Promise<this>",
10042
+ "returns": "Promise<OpenAI.Models.ModelsPage>",
9897
10043
  "examples": [
9898
10044
  {
9899
10045
  "language": "ts",
9900
- "code": "await openai.connect()"
10046
+ "code": "const models = await openai.listModels()"
9901
10047
  }
9902
10048
  ]
9903
10049
  },
9904
- "createChatCompletion": {
9905
- "description": "Create a chat completion using the Chat Completions API.",
10050
+ "ask": {
10051
+ "description": "Ask a single question and get a text response. Convenience wrapper around `createChatCompletion` for simple Q&A.",
9906
10052
  "parameters": {
9907
- "messages": {
9908
- "type": "OpenAI.Chat.Completions.ChatCompletionMessageParam[]",
9909
- "description": "Array of chat messages"
10053
+ "question": {
10054
+ "type": "string",
10055
+ "description": "The question to ask"
9910
10056
  },
9911
10057
  "options": {
9912
10058
  "type": "Partial<OpenAI.Chat.Completions.ChatCompletionCreateParams>",
9913
- "description": "Additional parameters for the completion"
10059
+ "description": "Additional completion parameters"
9914
10060
  }
9915
10061
  },
9916
10062
  "required": [
9917
- "messages"
10063
+ "question"
9918
10064
  ],
9919
- "returns": "Promise<OpenAI.Chat.Completions.ChatCompletion>",
10065
+ "returns": "Promise<string>",
9920
10066
  "examples": [
9921
10067
  {
9922
10068
  "language": "ts",
9923
- "code": "const response = await openai.createChatCompletion([\n { role: 'system', content: 'You are a helpful assistant.' },\n { role: 'user', content: 'Hello!' }\n])\nconsole.log(response.choices[0]?.message?.content)"
10069
+ "code": "const answer = await openai.ask('What is 2 + 2?')\nconsole.log(answer) // '4'"
9924
10070
  }
9925
10071
  ]
9926
10072
  },
9927
- "createResponse": {
9928
- "description": "Create a response using the Responses API.",
10073
+ "chat": {
10074
+ "description": "Send a multi-turn conversation and get a text response. Convenience wrapper around `createChatCompletion` that returns just the text.",
9929
10075
  "parameters": {
9930
- "input": {
9931
- "type": "OpenAI.Responses.ResponseInput | string",
9932
- "description": "The input prompt or message array"
10076
+ "messages": {
10077
+ "type": "OpenAI.Chat.Completions.ChatCompletionMessageParam[]",
10078
+ "description": "Array of chat messages"
9933
10079
  },
9934
10080
  "options": {
9935
- "type": "Partial<OpenAI.Responses.ResponseCreateParamsNonStreaming>",
9936
- "description": "Additional parameters for the response"
10081
+ "type": "Partial<OpenAI.Chat.Completions.ChatCompletionCreateParams>",
10082
+ "description": "Additional completion parameters"
9937
10083
  }
9938
10084
  },
9939
10085
  "required": [
9940
- "input"
10086
+ "messages"
9941
10087
  ],
9942
- "returns": "Promise<OpenAI.Responses.Response>",
10088
+ "returns": "Promise<string>",
9943
10089
  "examples": [
9944
10090
  {
9945
10091
  "language": "ts",
9946
- "code": "const response = await openai.createResponse('Explain quantum computing')"
10092
+ "code": "const reply = await openai.chat([\n { role: 'system', content: 'You are a pirate.' },\n { role: 'user', content: 'Hello!' }\n])"
9947
10093
  }
9948
10094
  ]
10095
+ }
10096
+ },
10097
+ "getters": {
10098
+ "defaultModel": {
10099
+ "description": "The default model used for completions, from options or 'gpt-4o'.",
10100
+ "returns": "string"
9949
10101
  },
9950
- "streamResponse": {
9951
- "description": "Stream a response using the Responses API.",
10102
+ "raw": {
10103
+ "description": "The underlying OpenAI SDK instance for advanced use cases.",
10104
+ "returns": "OpenAI"
10105
+ }
10106
+ },
10107
+ "events": {
10108
+ "connected": {
10109
+ "name": "connected",
10110
+ "description": "Event emitted by OpenAIClient",
10111
+ "arguments": {}
10112
+ },
10113
+ "failure": {
10114
+ "name": "failure",
10115
+ "description": "Event emitted by OpenAIClient",
10116
+ "arguments": {}
10117
+ },
10118
+ "completion": {
10119
+ "name": "completion",
10120
+ "description": "Event emitted by OpenAIClient",
10121
+ "arguments": {}
10122
+ },
10123
+ "embedding": {
10124
+ "name": "embedding",
10125
+ "description": "Event emitted by OpenAIClient",
10126
+ "arguments": {}
10127
+ },
10128
+ "image": {
10129
+ "name": "image",
10130
+ "description": "Event emitted by OpenAIClient",
10131
+ "arguments": {}
10132
+ },
10133
+ "models": {
10134
+ "name": "models",
10135
+ "description": "Event emitted by OpenAIClient",
10136
+ "arguments": {}
10137
+ }
10138
+ },
10139
+ "state": {},
10140
+ "options": {},
10141
+ "envVars": [],
10142
+ "examples": [
10143
+ {
10144
+ "language": "ts",
10145
+ "code": "const openai = container.client('openai', { defaultModel: 'gpt-4o' })\nconst answer = await openai.ask('What is the meaning of life?')\nconsole.log(answer)"
10146
+ }
10147
+ ]
10148
+ });
10149
+
10150
+ setBuildTimeData('clients.supabase', {
10151
+ "id": "clients.supabase",
10152
+ "description": "Supabase client for the Luca container system. Wraps the official `@supabase/supabase-js` SDK and exposes it through Luca's typed state, events, and introspection system. The SDK is isomorphic so this single implementation works in both Node and browser containers. Use `client.sdk` for full SDK access, or use the convenience wrappers for common operations (auth, database queries, storage, edge functions, realtime).",
10153
+ "shortcut": "clients.supabase",
10154
+ "className": "SupabaseClient",
10155
+ "methods": {
10156
+ "from": {
10157
+ "description": "Start a query on a Postgres table or view.",
9952
10158
  "parameters": {
9953
- "input": {
9954
- "type": "OpenAI.Responses.ResponseInput | string",
9955
- "description": "The input prompt or message array"
9956
- },
9957
- "options": {
9958
- "type": "Partial<OpenAI.Responses.ResponseCreateParamsStreaming>",
9959
- "description": "Additional parameters for the streaming response"
10159
+ "table": {
10160
+ "type": "string",
10161
+ "description": "The table or view name to query"
9960
10162
  }
9961
10163
  },
9962
10164
  "required": [
9963
- "input"
10165
+ "table"
9964
10166
  ],
9965
- "returns": "Promise<AsyncIterable<OpenAI.Responses.ResponseStreamEvent>>",
9966
- "examples": [
9967
- {
9968
- "language": "ts",
9969
- "code": "const stream = await openai.streamResponse('Write a poem')\nfor await (const event of stream) {\n if (event.type === 'response.output_text.delta') {\n process.stdout.write(event.delta)\n }\n}"
9970
- }
9971
- ]
10167
+ "returns": "void"
9972
10168
  },
9973
- "createCompletion": {
9974
- "description": "Create a legacy text completion.",
10169
+ "rpc": {
10170
+ "description": "Call a Postgres function (RPC).",
9975
10171
  "parameters": {
9976
- "prompt": {
10172
+ "fn": {
9977
10173
  "type": "string",
9978
- "description": "The text prompt to complete"
10174
+ "description": "The function name"
10175
+ },
10176
+ "params": {
10177
+ "type": "Record<string, unknown>",
10178
+ "description": "Arguments to pass to the function"
9979
10179
  },
9980
10180
  "options": {
9981
- "type": "Partial<OpenAI.Completions.CompletionCreateParams>",
9982
- "description": "Additional parameters for the completion"
10181
+ "type": "{ head?: boolean; get?: boolean; count?: \"exact\" | \"planned\" | \"estimated\" }",
10182
+ "description": "Optional settings (head, get, count)"
9983
10183
  }
9984
10184
  },
9985
10185
  "required": [
9986
- "prompt"
10186
+ "fn"
9987
10187
  ],
9988
- "returns": "Promise<OpenAI.Completions.Completion>",
9989
- "examples": [
9990
- {
9991
- "language": "ts",
9992
- "code": "const response = await openai.createCompletion('Once upon a time')"
9993
- }
9994
- ]
10188
+ "returns": "void"
9995
10189
  },
9996
- "createEmbedding": {
9997
- "description": "Create text embeddings for semantic search or similarity comparisons.",
10190
+ "signInWithPassword": {
10191
+ "description": "Sign in with email and password.",
9998
10192
  "parameters": {
9999
- "input": {
10000
- "type": "string | string[]",
10001
- "description": "A string or array of strings to embed"
10193
+ "email": {
10194
+ "type": "string",
10195
+ "description": "Parameter email"
10002
10196
  },
10003
- "options": {
10004
- "type": "Partial<OpenAI.Embeddings.EmbeddingCreateParams>",
10005
- "description": "Additional parameters (model, etc.)"
10197
+ "password": {
10198
+ "type": "string",
10199
+ "description": "Parameter password"
10006
10200
  }
10007
10201
  },
10008
10202
  "required": [
10009
- "input"
10203
+ "email",
10204
+ "password"
10010
10205
  ],
10011
- "returns": "Promise<OpenAI.Embeddings.CreateEmbeddingResponse>",
10012
- "examples": [
10013
- {
10014
- "language": "ts",
10015
- "code": "const response = await openai.createEmbedding('Hello world')\nconsole.log(response.data[0].embedding.length)"
10016
- }
10017
- ]
10206
+ "returns": "void"
10018
10207
  },
10019
- "createImage": {
10020
- "description": "Generate an image from a text prompt using DALL-E.",
10208
+ "signUp": {
10209
+ "description": "Create a new user account with email and password.",
10021
10210
  "parameters": {
10022
- "prompt": {
10211
+ "email": {
10023
10212
  "type": "string",
10024
- "description": "Description of the image to generate"
10213
+ "description": "Parameter email"
10025
10214
  },
10026
- "options": {
10027
- "type": "Partial<OpenAI.Images.ImageGenerateParams>",
10028
- "description": "Additional parameters (size, n, etc.)"
10215
+ "password": {
10216
+ "type": "string",
10217
+ "description": "Parameter password"
10029
10218
  }
10030
10219
  },
10031
10220
  "required": [
10032
- "prompt"
10221
+ "email",
10222
+ "password"
10033
10223
  ],
10034
- "returns": "Promise<OpenAI.Images.ImagesResponse>",
10035
- "examples": [
10036
- {
10037
- "language": "ts",
10038
- "code": "const response = await openai.createImage('A sunset over mountains')\nconsole.log(response.data[0].url)"
10039
- }
10040
- ]
10224
+ "returns": "void"
10041
10225
  },
10042
- "listModels": {
10043
- "description": "List all available models.",
10226
+ "signOut": {
10227
+ "description": "Sign the current user out.",
10044
10228
  "parameters": {},
10045
10229
  "required": [],
10046
- "returns": "Promise<OpenAI.Models.ModelsPage>",
10047
- "examples": [
10048
- {
10049
- "language": "ts",
10050
- "code": "const models = await openai.listModels()"
10051
- }
10052
- ]
10230
+ "returns": "void"
10053
10231
  },
10054
- "ask": {
10055
- "description": "Ask a single question and get a text response. Convenience wrapper around `createChatCompletion` for simple Q&A.",
10232
+ "getSession": {
10233
+ "description": "Get the current session, if any.",
10234
+ "parameters": {},
10235
+ "required": [],
10236
+ "returns": "void"
10237
+ },
10238
+ "getUser": {
10239
+ "description": "Get the current user, if any.",
10240
+ "parameters": {},
10241
+ "required": [],
10242
+ "returns": "void"
10243
+ },
10244
+ "invoke": {
10245
+ "description": "Invoke a Supabase Edge Function by name.",
10056
10246
  "parameters": {
10057
- "question": {
10247
+ "name": {
10058
10248
  "type": "string",
10059
- "description": "The question to ask"
10249
+ "description": "Parameter name"
10060
10250
  },
10061
- "options": {
10062
- "type": "Partial<OpenAI.Chat.Completions.ChatCompletionCreateParams>",
10063
- "description": "Additional completion parameters"
10251
+ "body": {
10252
+ "type": "any",
10253
+ "description": "Parameter body"
10064
10254
  }
10065
10255
  },
10066
10256
  "required": [
10067
- "question"
10257
+ "name"
10068
10258
  ],
10069
- "returns": "Promise<string>",
10070
- "examples": [
10071
- {
10072
- "language": "ts",
10073
- "code": "const answer = await openai.ask('What is 2 + 2?')\nconsole.log(answer) // '4'"
10259
+ "returns": "void"
10260
+ },
10261
+ "subscribe": {
10262
+ "description": "Subscribe to realtime changes on a Postgres table.",
10263
+ "parameters": {
10264
+ "channelName": {
10265
+ "type": "string",
10266
+ "description": "A name for this subscription channel"
10267
+ },
10268
+ "table": {
10269
+ "type": "string",
10270
+ "description": "The table to listen to"
10271
+ },
10272
+ "callback": {
10273
+ "type": "(payload: any) => void",
10274
+ "description": "Called with the payload on each change"
10275
+ },
10276
+ "event": {
10277
+ "type": "\"INSERT\" | \"UPDATE\" | \"DELETE\" | \"*\"",
10278
+ "description": "The event type to listen for (default: all changes)"
10074
10279
  }
10075
- ]
10280
+ },
10281
+ "required": [
10282
+ "channelName",
10283
+ "table",
10284
+ "callback"
10285
+ ],
10286
+ "returns": "RealtimeChannel"
10076
10287
  },
10077
- "chat": {
10078
- "description": "Send a multi-turn conversation and get a text response. Convenience wrapper around `createChatCompletion` that returns just the text.",
10288
+ "unsubscribe": {
10289
+ "description": "Unsubscribe and remove a realtime channel by name.",
10079
10290
  "parameters": {
10080
- "messages": {
10081
- "type": "OpenAI.Chat.Completions.ChatCompletionMessageParam[]",
10082
- "description": "Array of chat messages"
10083
- },
10084
- "options": {
10085
- "type": "Partial<OpenAI.Chat.Completions.ChatCompletionCreateParams>",
10086
- "description": "Additional completion parameters"
10291
+ "channelName": {
10292
+ "type": "string",
10293
+ "description": "The channel name to remove"
10087
10294
  }
10088
10295
  },
10089
10296
  "required": [
10090
- "messages"
10297
+ "channelName"
10091
10298
  ],
10092
- "returns": "Promise<string>",
10093
- "examples": [
10094
- {
10095
- "language": "ts",
10096
- "code": "const reply = await openai.chat([\n { role: 'system', content: 'You are a pirate.' },\n { role: 'user', content: 'Hello!' }\n])"
10097
- }
10098
- ]
10099
- }
10100
- },
10101
- "getters": {
10102
- "defaultModel": {
10103
- "description": "The default model used for completions, from options or 'gpt-4o'.",
10104
- "returns": "string"
10105
- },
10106
- "raw": {
10107
- "description": "The underlying OpenAI SDK instance for advanced use cases.",
10108
- "returns": "OpenAI"
10109
- }
10110
- },
10111
- "events": {
10112
- "connected": {
10113
- "name": "connected",
10114
- "description": "Event emitted by OpenAIClient",
10115
- "arguments": {}
10299
+ "returns": "void"
10116
10300
  },
10117
- "failure": {
10118
- "name": "failure",
10119
- "description": "Event emitted by OpenAIClient",
10120
- "arguments": {}
10301
+ "unsubscribeAll": {
10302
+ "description": "Unsubscribe and remove all realtime channels.",
10303
+ "parameters": {},
10304
+ "required": [],
10305
+ "returns": "void"
10121
10306
  },
10122
- "completion": {
10123
- "name": "completion",
10124
- "description": "Event emitted by OpenAIClient",
10125
- "arguments": {}
10307
+ "connect": {
10308
+ "description": "Connect is a no-op since the Supabase SDK initializes on construction. The client is ready to use immediately after creation.",
10309
+ "parameters": {},
10310
+ "required": [],
10311
+ "returns": "void"
10126
10312
  },
10127
- "embedding": {
10128
- "name": "embedding",
10129
- "description": "Event emitted by OpenAIClient",
10130
- "arguments": {}
10313
+ "disconnect": {
10314
+ "description": "Disconnect by signing out and removing all realtime channels.",
10315
+ "parameters": {},
10316
+ "required": [],
10317
+ "returns": "void"
10318
+ }
10319
+ },
10320
+ "getters": {
10321
+ "sdk": {
10322
+ "description": "Returns the raw Supabase SDK client for full access to all SDK methods.",
10323
+ "returns": "SupabaseSDKClient<any, any>"
10131
10324
  },
10132
- "image": {
10133
- "name": "image",
10134
- "description": "Event emitted by OpenAIClient",
10135
- "arguments": {}
10325
+ "storage": {
10326
+ "description": "Returns the Supabase Storage client for managing buckets and files.",
10327
+ "returns": "any"
10136
10328
  },
10137
- "models": {
10138
- "name": "models",
10139
- "description": "Event emitted by OpenAIClient",
10140
- "arguments": {}
10329
+ "functions": {
10330
+ "description": "Returns the Supabase Functions client.",
10331
+ "returns": "any"
10141
10332
  }
10142
10333
  },
10334
+ "events": {},
10143
10335
  "state": {},
10144
10336
  "options": {},
10145
10337
  "envVars": [],
10146
10338
  "examples": [
10147
10339
  {
10148
10340
  "language": "ts",
10149
- "code": "const openai = container.client('openai', { defaultModel: 'gpt-4o' })\nconst answer = await openai.ask('What is the meaning of life?')\nconsole.log(answer)"
10341
+ "code": "const supabase = container.client('supabase', {\n supabaseUrl: 'https://xyz.supabase.co',\n supabaseKey: 'your-anon-key',\n})\n\n// Query data\nconst { data } = await supabase.from('users').select('*')\n\n// Auth\nawait supabase.signInWithPassword('user@example.com', 'password')\n\n// Realtime\nsupabase.subscribe('changes', 'users', (payload) => {\n console.log('Change:', payload)\n})"
10150
10342
  }
10151
10343
  ]
10152
10344
  });
@@ -10977,21 +11169,27 @@ setBuildTimeData('servers.websocket', {
10977
11169
 
10978
11170
  setBuildTimeData('features.assistantsManager', {
10979
11171
  "id": "features.assistantsManager",
10980
- "description": "Discovers and manages assistant definitions by finding all CORE.md files in the project using the fileManager. Each directory containing a CORE.md is treated as an assistant definition that can also contain tools.ts, hooks.ts, voice.yaml, and a docs/ folder. Use `discover()` to scan for available assistants, `list()` to enumerate them, and `create(name)` to instantiate one as a running Assistant feature.",
11172
+ "description": "Discovers and manages assistant definitions by looking for subdirectories in two locations: ~/.luca/assistants/ and cwd/assistants/. Each subdirectory containing a CORE.md is treated as an assistant definition. Use `discover()` to scan for available assistants, `list()` to enumerate them, and `create(name)` to instantiate one as a running Assistant feature.",
10981
11173
  "shortcut": "features.assistantsManager",
10982
11174
  "className": "AssistantsManager",
10983
11175
  "methods": {
10984
- "afterInitialize": {
10985
- "description": "",
11176
+ "discover": {
11177
+ "description": "Discovers assistants by listing subdirectories in ~/.luca/assistants/ and cwd/assistants/. Each subdirectory containing a CORE.md is an assistant.",
10986
11178
  "parameters": {},
10987
11179
  "required": [],
10988
- "returns": "void"
11180
+ "returns": "Promise<this>"
10989
11181
  },
10990
- "discover": {
10991
- "description": "Discovers assistants by finding all CORE.md files in the project using the fileManager. Each directory containing a CORE.md is treated as an assistant definition.",
11182
+ "downloadLucaCoreAssistants": {
11183
+ "description": "Downloads the core assistants that ship with luca from GitHub into ~/.luca/assistants.",
10992
11184
  "parameters": {},
10993
11185
  "required": [],
10994
- "returns": "Promise<this>"
11186
+ "returns": "void",
11187
+ "examples": [
11188
+ {
11189
+ "language": "ts",
11190
+ "code": "const manager = container.feature('assistantsManager')\nawait manager.downloadLucaCoreAssistants()\nawait manager.discover()\nconsole.log(manager.available)"
11191
+ }
11192
+ ]
10995
11193
  },
10996
11194
  "list": {
10997
11195
  "description": "Returns all discovered assistant entries as an array.",
@@ -11004,7 +11202,7 @@ setBuildTimeData('features.assistantsManager', {
11004
11202
  "parameters": {
11005
11203
  "name": {
11006
11204
  "type": "string",
11007
- "description": "The assistant name (e.g. 'assistants/chief-of-staff')"
11205
+ "description": "The assistant name (e.g. 'chief-of-staff')"
11008
11206
  }
11009
11207
  },
11010
11208
  "required": [
@@ -11012,12 +11210,36 @@ setBuildTimeData('features.assistantsManager', {
11012
11210
  ],
11013
11211
  "returns": "AssistantEntry | undefined"
11014
11212
  },
11213
+ "register": {
11214
+ "description": "Registers a factory function that creates an assistant at runtime. Registered factories take precedence over discovered entries when calling `create()`.",
11215
+ "parameters": {
11216
+ "id": {
11217
+ "type": "string",
11218
+ "description": "The assistant identifier"
11219
+ },
11220
+ "factory": {
11221
+ "type": "(options: Record<string, any>) => Assistant",
11222
+ "description": "Factory function that receives create options and returns an Assistant"
11223
+ }
11224
+ },
11225
+ "required": [
11226
+ "id",
11227
+ "factory"
11228
+ ],
11229
+ "returns": "this",
11230
+ "examples": [
11231
+ {
11232
+ "language": "ts",
11233
+ "code": "manager.register('custom-bot', (options) => {\n return container.feature('assistant', {\n systemPrompt: 'You are a custom bot.',\n ...options,\n })\n})\nconst bot = manager.create('custom-bot')"
11234
+ }
11235
+ ]
11236
+ },
11015
11237
  "create": {
11016
- "description": "Creates and returns a new Assistant feature instance for the given name. The assistant is configured with the discovered folder path. Any additional options are merged in.",
11238
+ "description": "Creates and returns a new Assistant feature instance for the given name. Checks runtime-registered factories first, then falls back to discovered entries. The assistant is configured with the discovered folder path. Any additional options are merged in.",
11017
11239
  "parameters": {
11018
11240
  "name": {
11019
11241
  "type": "string",
11020
- "description": "The assistant name (must match a discovered entry)"
11242
+ "description": "The assistant name (must match a registered factory or discovered entry)"
11021
11243
  },
11022
11244
  "options": {
11023
11245
  "type": "Record<string, any>",
@@ -11031,7 +11253,7 @@ setBuildTimeData('features.assistantsManager', {
11031
11253
  "examples": [
11032
11254
  {
11033
11255
  "language": "ts",
11034
- "code": "const assistant = manager.create('assistants/chief-of-staff', { model: 'gpt-4.1' })"
11256
+ "code": "const assistant = manager.create('chief-of-staff', { model: 'gpt-4.1' })"
11035
11257
  }
11036
11258
  ]
11037
11259
  },
@@ -11056,6 +11278,18 @@ setBuildTimeData('features.assistantsManager', {
11056
11278
  }
11057
11279
  },
11058
11280
  "getters": {
11281
+ "entries": {
11282
+ "description": "Discovered assistant entries keyed by name.",
11283
+ "returns": "Record<string, AssistantEntry>"
11284
+ },
11285
+ "instances": {
11286
+ "description": "Active assistant instances keyed by name.",
11287
+ "returns": "Record<string, Assistant>"
11288
+ },
11289
+ "factories": {
11290
+ "description": "Registered factory functions keyed by name.",
11291
+ "returns": "Record<string, (options: Record<string, any>) => Assistant>"
11292
+ },
11059
11293
  "available": {
11060
11294
  "description": "",
11061
11295
  "returns": "any"
@@ -11067,6 +11301,11 @@ setBuildTimeData('features.assistantsManager', {
11067
11301
  "description": "Event emitted by AssistantsManager",
11068
11302
  "arguments": {}
11069
11303
  },
11304
+ "assistantRegistered": {
11305
+ "name": "assistantRegistered",
11306
+ "description": "Event emitted by AssistantsManager",
11307
+ "arguments": {}
11308
+ },
11070
11309
  "assistantCreated": {
11071
11310
  "name": "assistantCreated",
11072
11311
  "description": "Event emitted by AssistantsManager",
@@ -11079,7 +11318,7 @@ setBuildTimeData('features.assistantsManager', {
11079
11318
  "examples": [
11080
11319
  {
11081
11320
  "language": "ts",
11082
- "code": "const manager = container.feature('assistantsManager')\nmanager.discover()\nconsole.log(manager.list()) // [{ name: 'assistants/chief-of-staff', folder: '...', ... }]\nconst assistant = manager.create('assistants/chief-of-staff')\nconst answer = await assistant.ask('Hello!')"
11321
+ "code": "const manager = container.feature('assistantsManager')\nmanager.discover()\nconsole.log(manager.list()) // [{ name: 'chief-of-staff', folder: '...', ... }]\nconst assistant = manager.create('chief-of-staff')\nconst answer = await assistant.ask('Hello!')"
11083
11322
  }
11084
11323
  ]
11085
11324
  });
@@ -11090,6 +11329,64 @@ setBuildTimeData('features.conversation', {
11090
11329
  "shortcut": "features.conversation",
11091
11330
  "className": "Conversation",
11092
11331
  "methods": {
11332
+ "addTool": {
11333
+ "description": "Add or replace a single tool by name. Uses the same format as tools passed at construction time.",
11334
+ "parameters": {
11335
+ "name": {
11336
+ "type": "string",
11337
+ "description": "Parameter name"
11338
+ },
11339
+ "tool": {
11340
+ "type": "ConversationTool",
11341
+ "description": "Parameter tool",
11342
+ "properties": {
11343
+ "handler": {
11344
+ "type": "(...args: any[]) => Promise<any>",
11345
+ "description": ""
11346
+ },
11347
+ "description": {
11348
+ "type": "string",
11349
+ "description": ""
11350
+ },
11351
+ "parameters": {
11352
+ "type": "Record<string, any>",
11353
+ "description": ""
11354
+ }
11355
+ }
11356
+ }
11357
+ },
11358
+ "required": [
11359
+ "name",
11360
+ "tool"
11361
+ ],
11362
+ "returns": "this"
11363
+ },
11364
+ "removeTool": {
11365
+ "description": "Remove a tool by name.",
11366
+ "parameters": {
11367
+ "name": {
11368
+ "type": "string",
11369
+ "description": "Parameter name"
11370
+ }
11371
+ },
11372
+ "required": [
11373
+ "name"
11374
+ ],
11375
+ "returns": "this"
11376
+ },
11377
+ "updateTools": {
11378
+ "description": "Merge new tools into the conversation, replacing any with the same name. Accepts the same Record<string, ConversationTool> format used at construction time.",
11379
+ "parameters": {
11380
+ "tools": {
11381
+ "type": "Record<string, ConversationTool>",
11382
+ "description": "Parameter tools"
11383
+ }
11384
+ },
11385
+ "required": [
11386
+ "tools"
11387
+ ],
11388
+ "returns": "this"
11389
+ },
11093
11390
  "estimateTokens": {
11094
11391
  "description": "Estimate the input token count for the current messages array using the js-tiktoken tokenizer. Updates state.",
11095
11392
  "parameters": {},
@@ -11170,7 +11467,11 @@ setBuildTimeData('features.conversation', {
11170
11467
  "getters": {
11171
11468
  "tools": {
11172
11469
  "description": "Returns the registered tools available for the model to call.",
11173
- "returns": "Record<string, any>"
11470
+ "returns": "Record<string, ConversationTool>"
11471
+ },
11472
+ "availableTools": {
11473
+ "description": "",
11474
+ "returns": "any"
11174
11475
  },
11175
11476
  "mcpServers": {
11176
11477
  "description": "Returns configured remote MCP servers keyed by server label.",
@@ -11424,8 +11725,8 @@ setBuildTimeData('features.openapi', {
11424
11725
  }
11425
11726
  },
11426
11727
  "events": {
11427
- "loaded": {
11428
- "name": "loaded",
11728
+ "started": {
11729
+ "name": "started",
11429
11730
  "description": "Event emitted by OpenAPI",
11430
11731
  "arguments": {}
11431
11732
  }
@@ -11441,160 +11742,253 @@ setBuildTimeData('features.openapi', {
11441
11742
  ]
11442
11743
  });
11443
11744
 
11745
+ setBuildTimeData('features.docsReader', {
11746
+ "id": "features.docsReader",
11747
+ "description": "The DocsReader feature is an AI Assisted wrapper around a ContentDB feature. You can ask it questions about the content, and it will use the ContentDB to find the answers from the documents.",
11748
+ "shortcut": "features.docsReader",
11749
+ "className": "DocsReader",
11750
+ "methods": {
11751
+ "calculateCacheKeyForQuestion": {
11752
+ "description": "",
11753
+ "parameters": {
11754
+ "question": {
11755
+ "type": "string",
11756
+ "description": "Parameter question"
11757
+ }
11758
+ },
11759
+ "required": [
11760
+ "question"
11761
+ ],
11762
+ "returns": "void"
11763
+ },
11764
+ "ask": {
11765
+ "description": "",
11766
+ "parameters": {
11767
+ "question": {
11768
+ "type": "string",
11769
+ "description": "Parameter question"
11770
+ }
11771
+ },
11772
+ "required": [
11773
+ "question"
11774
+ ],
11775
+ "returns": "void"
11776
+ },
11777
+ "askCached": {
11778
+ "description": "",
11779
+ "parameters": {
11780
+ "question": {
11781
+ "type": "string",
11782
+ "description": "Parameter question"
11783
+ }
11784
+ },
11785
+ "required": [
11786
+ "question"
11787
+ ],
11788
+ "returns": "void"
11789
+ },
11790
+ "start": {
11791
+ "description": "Start the docs reader by loading the contentDb and wiring its tools into an assistant.",
11792
+ "parameters": {},
11793
+ "required": [],
11794
+ "returns": "Promise<DocsReader>"
11795
+ }
11796
+ },
11797
+ "getters": {
11798
+ "isStarted": {
11799
+ "description": "Whether the docs reader has been started.",
11800
+ "returns": "boolean"
11801
+ },
11802
+ "answerCache": {
11803
+ "description": "",
11804
+ "returns": "any"
11805
+ },
11806
+ "contentDb": {
11807
+ "description": "",
11808
+ "returns": "ContentDb"
11809
+ }
11810
+ },
11811
+ "events": {
11812
+ "started": {
11813
+ "name": "started",
11814
+ "description": "Event emitted by DocsReader",
11815
+ "arguments": {}
11816
+ }
11817
+ },
11818
+ "state": {},
11819
+ "options": {},
11820
+ "envVars": []
11821
+ });
11822
+
11444
11823
  setBuildTimeData('features.skillsLibrary', {
11445
11824
  "id": "features.skillsLibrary",
11446
- "description": "Manages two contentbase collections of skills following the Claude Code SKILL.md format. Project-level skills live in .claude/skills/ and user-level skills live in ~/.luca/skills/. Skills can be discovered, searched, created, updated, and removed at runtime.",
11825
+ "description": "Manages a registry of skill locations folders containing SKILL.md files. Persists known locations to ~/.luca/skills.json and scans them on start. Each skill folder can be opened as a DocsReader for AI-assisted Q&A. Exposes tools for assistant integration via assistant.use(skillsLibrary).",
11447
11826
  "shortcut": "features.skillsLibrary",
11448
11827
  "className": "SkillsLibrary",
11449
11828
  "methods": {
11450
- "load": {
11451
- "description": "Loads both project and user skill collections from disk. Gracefully handles missing directories.",
11829
+ "start": {
11830
+ "description": "Start the skills library: read config, scan all locations.",
11452
11831
  "parameters": {},
11453
11832
  "required": [],
11454
11833
  "returns": "Promise<SkillsLibrary>"
11455
11834
  },
11456
- "list": {
11457
- "description": "Lists all skills from both collections. Project skills come first.",
11458
- "parameters": {},
11459
- "required": [],
11460
- "returns": "SkillEntry[]"
11461
- },
11462
- "find": {
11463
- "description": "Finds a skill by name. Project skills take precedence over user skills.",
11835
+ "addLocation": {
11836
+ "description": "Add a new skill location folder and scan it for skills.",
11464
11837
  "parameters": {
11465
- "name": {
11838
+ "locationPath": {
11466
11839
  "type": "string",
11467
- "description": "The skill name to find (case-insensitive)"
11840
+ "description": "Path to a directory containing skill subfolders with SKILL.md"
11468
11841
  }
11469
11842
  },
11470
11843
  "required": [
11471
- "name"
11844
+ "locationPath"
11472
11845
  ],
11473
- "returns": "SkillEntry | undefined"
11846
+ "returns": "Promise<void>"
11474
11847
  },
11475
- "search": {
11476
- "description": "Searches skills by substring match against name and description.",
11848
+ "removeLocation": {
11849
+ "description": "Remove a skill location and its skills from the library.",
11477
11850
  "parameters": {
11478
- "query": {
11851
+ "locationPath": {
11479
11852
  "type": "string",
11480
- "description": "The search query"
11853
+ "description": "The location path to remove"
11481
11854
  }
11482
11855
  },
11483
11856
  "required": [
11484
- "query"
11857
+ "locationPath"
11485
11858
  ],
11486
- "returns": "SkillEntry[]"
11859
+ "returns": "Promise<void>"
11487
11860
  },
11488
- "getSkill": {
11489
- "description": "Gets a skill by name. Alias for find().",
11861
+ "scanLocation": {
11862
+ "description": "Scan a location folder for skill subfolders containing SKILL.md.",
11490
11863
  "parameters": {
11491
- "name": {
11864
+ "locationPath": {
11492
11865
  "type": "string",
11493
- "description": "The skill name"
11866
+ "description": "Absolute path to scan"
11494
11867
  }
11495
11868
  },
11496
11869
  "required": [
11497
- "name"
11870
+ "locationPath"
11498
11871
  ],
11499
- "returns": "SkillEntry | undefined"
11872
+ "returns": "Promise<void>"
11500
11873
  },
11501
- "create": {
11502
- "description": "Creates a new SKILL.md file in the specified collection. Maintains the directory-per-skill structure (skill-name/SKILL.md).",
11874
+ "list": {
11875
+ "description": "Return all discovered skills.",
11876
+ "parameters": {},
11877
+ "required": [],
11878
+ "returns": "SkillInfo[]"
11879
+ },
11880
+ "find": {
11881
+ "description": "Find a skill by name.",
11503
11882
  "parameters": {
11504
- "skill": {
11505
- "type": "{\n\t\t\tname: string\n\t\t\tdescription: string\n\t\t\tbody: string\n\t\t\tmeta?: Record<string, unknown>\n\t\t}",
11506
- "description": "The skill to create"
11507
- },
11508
- "target": {
11509
- "type": "'project' | 'user'",
11510
- "description": "Which collection to write to (default: 'project')"
11883
+ "skillName": {
11884
+ "type": "string",
11885
+ "description": "Parameter skillName"
11511
11886
  }
11512
11887
  },
11513
11888
  "required": [
11514
- "skill"
11889
+ "skillName"
11515
11890
  ],
11516
- "returns": "Promise<SkillEntry>"
11891
+ "returns": "SkillInfo | undefined"
11517
11892
  },
11518
- "update": {
11519
- "description": "Updates an existing skill's content or metadata.",
11893
+ "createSkillReader": {
11894
+ "description": "Create a DocsReader for a skill's folder, enabling AI-assisted Q&A.",
11520
11895
  "parameters": {
11521
- "name": {
11896
+ "skillName": {
11522
11897
  "type": "string",
11523
- "description": "The skill name to update"
11524
- },
11525
- "updates": {
11526
- "type": "{\n\t\t\tdescription?: string\n\t\t\tbody?: string\n\t\t\tmeta?: Record<string, unknown>\n\t\t}",
11527
- "description": "Fields to update"
11898
+ "description": "Name of the skill to create a reader for"
11528
11899
  }
11529
11900
  },
11530
11901
  "required": [
11531
- "name",
11532
- "updates"
11902
+ "skillName"
11533
11903
  ],
11534
- "returns": "Promise<SkillEntry>"
11904
+ "returns": "DocsReader"
11535
11905
  },
11536
- "remove": {
11537
- "description": "Removes a skill by name, deleting its SKILL.md and cleaning up the directory.",
11906
+ "ensureFolderCreatedWithSkillsByName": {
11907
+ "description": "Create a tmp directory containing symlinked/copied skill folders by name, suitable for passing to claude --add-dir.",
11538
11908
  "parameters": {
11539
- "name": {
11540
- "type": "string",
11541
- "description": "The skill name to remove"
11909
+ "skillNames": {
11910
+ "type": "string[]",
11911
+ "description": "Array of skill names to include"
11542
11912
  }
11543
11913
  },
11544
11914
  "required": [
11545
- "name"
11915
+ "skillNames"
11546
11916
  ],
11547
- "returns": "Promise<boolean>"
11917
+ "returns": "string"
11548
11918
  },
11549
- "toConversationTools": {
11550
- "description": "Converts all skills into ConversationTool format for use with Conversation. Each skill becomes a tool that returns its instruction body when invoked.",
11551
- "parameters": {},
11919
+ "searchAvailableSkills": {
11920
+ "description": "Search available skills, optionally filtered by a query string.",
11921
+ "parameters": {
11922
+ "{ query }": {
11923
+ "type": "{ query?: string }",
11924
+ "description": "Parameter { query }"
11925
+ }
11926
+ },
11552
11927
  "required": [],
11553
- "returns": "Record<string, ConversationTool>"
11928
+ "returns": "Promise<string>"
11554
11929
  },
11555
- "toSystemPromptBlock": {
11556
- "description": "Generates a markdown block listing all available skills with names and descriptions. Suitable for injecting into a system prompt.",
11557
- "parameters": {},
11558
- "required": [],
11559
- "returns": "string"
11930
+ "loadSkill": {
11931
+ "description": "Load a skill's full SKILL.md content and metadata.",
11932
+ "parameters": {
11933
+ "{ skillName }": {
11934
+ "type": "{ skillName: string }",
11935
+ "description": "Parameter { skillName }"
11936
+ }
11937
+ },
11938
+ "required": [
11939
+ "{ skillName }"
11940
+ ],
11941
+ "returns": "Promise<string>"
11942
+ },
11943
+ "askSkillBasedQuestion": {
11944
+ "description": "Ask a question about a specific skill using a DocsReader.",
11945
+ "parameters": {
11946
+ "{ skillName, question }": {
11947
+ "type": "{ skillName: string; question: string }",
11948
+ "description": "Parameter { skillName, question }"
11949
+ }
11950
+ },
11951
+ "required": [
11952
+ "{ skillName, question }"
11953
+ ],
11954
+ "returns": "Promise<string>"
11560
11955
  }
11561
11956
  },
11562
11957
  "getters": {
11563
- "projectCollection": {
11564
- "description": "Returns the project-level contentbase Collection, lazily initialized.",
11565
- "returns": "Collection"
11958
+ "skills": {
11959
+ "description": "Discovered skills keyed by name.",
11960
+ "returns": "Record<string, SkillInfo>"
11961
+ },
11962
+ "availableSkills": {
11963
+ "description": "",
11964
+ "returns": "any"
11566
11965
  },
11567
- "userCollection": {
11568
- "description": "Returns the user-level contentbase Collection, lazily initialized.",
11569
- "returns": "Collection"
11966
+ "skillsTable": {
11967
+ "description": "",
11968
+ "returns": "Record<string, string>"
11570
11969
  },
11571
- "isLoaded": {
11572
- "description": "Whether the skills library has been loaded.",
11573
- "returns": "boolean"
11970
+ "configPath": {
11971
+ "description": "Resolved path to the skills.json config file.",
11972
+ "returns": "string"
11574
11973
  },
11575
- "skillNames": {
11576
- "description": "Array of all skill names across both collections.",
11577
- "returns": "string[]"
11974
+ "isStarted": {
11975
+ "description": "Whether the library has been loaded.",
11976
+ "returns": "boolean"
11578
11977
  }
11579
11978
  },
11580
11979
  "events": {
11581
- "loaded": {
11582
- "name": "loaded",
11583
- "description": "Event emitted by SkillsLibrary",
11584
- "arguments": {}
11585
- },
11586
- "skillCreated": {
11587
- "name": "skillCreated",
11980
+ "started": {
11981
+ "name": "started",
11588
11982
  "description": "Event emitted by SkillsLibrary",
11589
11983
  "arguments": {}
11590
11984
  },
11591
- "skillUpdated": {
11592
- "name": "skillUpdated",
11985
+ "locationAdded": {
11986
+ "name": "locationAdded",
11593
11987
  "description": "Event emitted by SkillsLibrary",
11594
11988
  "arguments": {}
11595
11989
  },
11596
- "skillRemoved": {
11597
- "name": "skillRemoved",
11990
+ "skillDiscovered": {
11991
+ "name": "skillDiscovered",
11598
11992
  "description": "Event emitted by SkillsLibrary",
11599
11993
  "arguments": {}
11600
11994
  }
@@ -11605,7 +11999,7 @@ setBuildTimeData('features.skillsLibrary', {
11605
11999
  "examples": [
11606
12000
  {
11607
12001
  "language": "ts",
11608
- "code": "const skills = container.feature('skillsLibrary')\nawait skills.load()\n\n// List and search\nconst allSkills = skills.list()\nconst matches = skills.search('code review')\n\n// Create a new skill\nawait skills.create({\n name: 'summarize',\n description: 'Summarize a document',\n body: '## Instructions\\nRead the document and produce a concise summary.'\n})"
12002
+ "code": "const lib = container.feature('skillsLibrary')\nawait lib.start()\nawait lib.addLocation('~/.claude/skills')\nlib.list() // => SkillInfo[]\nconst reader = lib.createSkillReader('my-skill')"
11609
12003
  }
11610
12004
  ]
11611
12005
  });
@@ -11623,27 +12017,31 @@ setBuildTimeData('features.assistant', {
11623
12017
  "returns": "void"
11624
12018
  },
11625
12019
  "use": {
11626
- "description": "Apply a setup function to this assistant. The function receives the assistant instance and can configure tools, hooks, event listeners, etc.",
12020
+ "description": "Apply a setup function or a Helper instance to this assistant. When passed a function, it receives the assistant and can configure tools, hooks, event listeners, etc. When passed a Helper instance that exposes tools via toTools(), those tools are automatically added to this assistant.",
11627
12021
  "parameters": {
11628
- "fn": {
11629
- "type": "(assistant: this) => void | Promise<void>",
11630
- "description": "Setup function that receives this assistant"
12022
+ "fnOrHelper": {
12023
+ "type": "((assistant: this) => void | Promise<void>) | { toTools: () => { schemas: Record<string, z.ZodType>, handlers: Record<string, Function> } } | { schemas: Record<string, z.ZodType>, handlers: Record<string, Function> }",
12024
+ "description": "Setup function or Helper instance"
11631
12025
  }
11632
12026
  },
11633
12027
  "required": [
11634
- "fn"
12028
+ "fnOrHelper"
11635
12029
  ],
11636
12030
  "returns": "this",
11637
12031
  "examples": [
11638
12032
  {
11639
12033
  "language": "ts",
11640
- "code": "assistant\n .use(setupLogging)\n .use(addAnalyticsTools)"
12034
+ "code": "assistant\n .use(setupLogging)\n .use(container.feature('git'))"
11641
12035
  }
11642
12036
  ]
11643
12037
  },
11644
12038
  "addTool": {
11645
12039
  "description": "Add a tool to this assistant. The tool name is derived from the handler's function name.",
11646
12040
  "parameters": {
12041
+ "name": {
12042
+ "type": "string",
12043
+ "description": "Parameter name"
12044
+ },
11647
12045
  "handler": {
11648
12046
  "type": "(...args: any[]) => any",
11649
12047
  "description": "A named function that implements the tool"
@@ -11654,6 +12052,7 @@ setBuildTimeData('features.assistant', {
11654
12052
  }
11655
12053
  },
11656
12054
  "required": [
12055
+ "name",
11657
12056
  "handler"
11658
12057
  ],
11659
12058
  "returns": "this",
@@ -11719,7 +12118,7 @@ setBuildTimeData('features.assistant', {
11719
12118
  "returns": "this"
11720
12119
  },
11721
12120
  "loadSystemPrompt": {
11722
- "description": "Load the system prompt from CORE.md, applying any prepend/append options.",
12121
+ "description": "Load the system prompt from CORE.md, applying any prepend/append options. YAML frontmatter (between --- fences) is stripped from the prompt and stored in `_meta`.",
11723
12122
  "parameters": {},
11724
12123
  "required": [],
11725
12124
  "returns": "string"
@@ -11805,6 +12204,29 @@ setBuildTimeData('features.assistant', {
11805
12204
  },
11806
12205
  "required": [],
11807
12206
  "returns": "void"
12207
+ },
12208
+ "subagent": {
12209
+ "description": "Get or create a subagent assistant. Uses the assistantsManager to discover and create the assistant, then caches the instance for reuse across tool calls.",
12210
+ "parameters": {
12211
+ "id": {
12212
+ "type": "string",
12213
+ "description": "The assistant name (e.g. 'codingAssistant')"
12214
+ },
12215
+ "options": {
12216
+ "type": "Record<string, any>",
12217
+ "description": "Additional options to pass to the assistant constructor"
12218
+ }
12219
+ },
12220
+ "required": [
12221
+ "id"
12222
+ ],
12223
+ "returns": "Promise<Assistant>",
12224
+ "examples": [
12225
+ {
12226
+ "language": "ts",
12227
+ "code": "const researcher = await assistant.subagent('codingAssistant')\nconst answer = await researcher.ask('Find all usages of container.feature(\"fs\")')"
12228
+ }
12229
+ ]
11808
12230
  }
11809
12231
  },
11810
12232
  "getters": {
@@ -11848,6 +12270,10 @@ setBuildTimeData('features.assistant', {
11848
12270
  "description": "",
11849
12271
  "returns": "Conversation"
11850
12272
  },
12273
+ "availableTools": {
12274
+ "description": "",
12275
+ "returns": "any"
12276
+ },
11851
12277
  "messages": {
11852
12278
  "description": "",
11853
12279
  "returns": "any"
@@ -11864,6 +12290,10 @@ setBuildTimeData('features.assistant', {
11864
12290
  "description": "The tools registered with this assistant.",
11865
12291
  "returns": "Record<string, ConversationTool>"
11866
12292
  },
12293
+ "meta": {
12294
+ "description": "Parsed YAML frontmatter from CORE.md, or empty object if none.",
12295
+ "returns": "Record<string, any>"
12296
+ },
11867
12297
  "paths": {
11868
12298
  "description": "Provides a helper for creating paths off of the assistant's base folder",
11869
12299
  "returns": "any"
@@ -11887,6 +12317,10 @@ setBuildTimeData('features.assistant', {
11887
12317
  "currentThreadId": {
11888
12318
  "description": "The active thread ID (undefined in lifecycle mode).",
11889
12319
  "returns": "string | undefined"
12320
+ },
12321
+ "availableSubagents": {
12322
+ "description": "Names of assistants available as subagents, discovered via the assistantsManager.",
12323
+ "returns": "string[]"
11890
12324
  }
11891
12325
  },
11892
12326
  "events": {
@@ -11895,6 +12329,11 @@ setBuildTimeData('features.assistant', {
11895
12329
  "description": "Event emitted by Assistant",
11896
12330
  "arguments": {}
11897
12331
  },
12332
+ "toolsChanged": {
12333
+ "name": "toolsChanged",
12334
+ "description": "Event emitted by Assistant",
12335
+ "arguments": {}
12336
+ },
11898
12337
  "hookFired": {
11899
12338
  "name": "hookFired",
11900
12339
  "description": "Event emitted by Assistant",
@@ -13559,6 +13998,10 @@ setContainerBuildTimeData('Container', {
13559
13998
  "description": "Returns a map of enabled feature shortcut IDs to their instances.",
13560
13999
  "returns": "Partial<AvailableInstanceTypes<Features>>"
13561
14000
  },
14001
+ "describer": {
14002
+ "description": "Lazy-initialized ContainerDescriber for introspecting registries, helpers, and members.",
14003
+ "returns": "ContainerDescriber"
14004
+ },
13562
14005
  "context": {
13563
14006
  "description": "The Container's context is an object that contains the enabled features, the container itself, and any additional context that has been added to the container. All helper instances that are created by the container will have access to the shared context.",
13564
14007
  "returns": "ContainerContext<Features> & Partial<AvailableInstanceTypes<AvailableFeatures>>"
@@ -14418,6 +14861,25 @@ export const introspectionData = [
14418
14861
  }
14419
14862
  ]
14420
14863
  },
14864
+ "extractFolder": {
14865
+ "description": "Extracts a folder (or entire repo) from a remote GitHub repository without cloning. Downloads the repo as a tarball and extracts only the specified subfolder, similar to how degit works. No .git history is included — just the files. Supports shorthand (`user/repo/path`), branch refs (`user/repo/path#branch`), and full GitHub URLs (`https://github.com/user/repo/tree/branch/path`).",
14866
+ "parameters": {
14867
+ "{ source, destination, branch }": {
14868
+ "type": "{ source: string, destination: string, branch?: string }",
14869
+ "description": "Parameter { source, destination, branch }"
14870
+ }
14871
+ },
14872
+ "required": [
14873
+ "{ source, destination, branch }"
14874
+ ],
14875
+ "returns": "void",
14876
+ "examples": [
14877
+ {
14878
+ "language": "ts",
14879
+ "code": "// Extract a subfolder\nawait git.extractFolder({ source: 'soederpop/luca/src/assistants', destination: './my-assistants' })\n\n// Specific branch\nawait git.extractFolder({ source: 'sveltejs/template', destination: './my-app', branch: 'main' })\n\n// Full GitHub URL\nawait git.extractFolder({ source: 'https://github.com/user/repo/tree/main/examples', destination: './examples' })"
14880
+ }
14881
+ ]
14882
+ },
14421
14883
  "getChangeHistoryForFiles": {
14422
14884
  "description": "Gets the commit history for a set of files or glob patterns. Accepts absolute paths, relative paths (resolved from container.cwd), or glob patterns. Returns commits that touched any of the matched files, with each entry noting which of your queried files were in that commit.",
14423
14885
  "parameters": {
@@ -15982,6 +16444,29 @@ export const introspectionData = [
15982
16444
  ],
15983
16445
  "returns": "Promise<T>"
15984
16446
  },
16447
+ "runCaptured": {
16448
+ "description": "Execute code and capture all console output as structured JSON. Returns both the execution result and an array of every `console.*` call made during execution, each entry recording the method name and arguments.",
16449
+ "parameters": {
16450
+ "code": {
16451
+ "type": "string",
16452
+ "description": "The JavaScript code to execute"
16453
+ },
16454
+ "ctx": {
16455
+ "type": "any",
16456
+ "description": "Context variables to make available to the executing code"
16457
+ }
16458
+ },
16459
+ "required": [
16460
+ "code"
16461
+ ],
16462
+ "returns": "Promise<{\n result: T\n console: Array<{ method: string, args: any[] }>\n context: vm.Context\n }>",
16463
+ "examples": [
16464
+ {
16465
+ "language": "ts",
16466
+ "code": "const { result, console: calls } = await vm.runCaptured('console.log(\"hi\"); console.warn(\"oh\"); 42')\n// result === 42\n// calls === [{ method: 'log', args: ['hi'] }, { method: 'warn', args: ['oh'] }]"
16467
+ }
16468
+ ]
16469
+ },
15985
16470
  "runSync": {
15986
16471
  "description": "Execute JavaScript code synchronously in a controlled environment.",
15987
16472
  "parameters": {
@@ -18921,6 +19406,23 @@ export const introspectionData = [
18921
19406
  }
18922
19407
  ]
18923
19408
  },
19409
+ "readFileSync": {
19410
+ "description": "Synchronously reads a file and returns its contents as a string. added this method because AI Assistants are understandly confused by this deviation from 2000's era node style",
19411
+ "parameters": {
19412
+ "path": {
19413
+ "type": "string",
19414
+ "description": "Parameter path"
19415
+ },
19416
+ "encoding": {
19417
+ "type": "BufferEncoding | null",
19418
+ "description": "Parameter encoding"
19419
+ }
19420
+ },
19421
+ "required": [
19422
+ "path"
19423
+ ],
19424
+ "returns": "string | Buffer"
19425
+ },
18924
19426
  "readFileAsync": {
18925
19427
  "description": "Asynchronously reads a file and returns its contents as a string.",
18926
19428
  "parameters": {
@@ -18963,6 +19465,19 @@ export const introspectionData = [
18963
19465
  }
18964
19466
  ]
18965
19467
  },
19468
+ "readJsonSync": {
19469
+ "description": "Read and parse a JSON file synchronously",
19470
+ "parameters": {
19471
+ "path": {
19472
+ "type": "string",
19473
+ "description": "Parameter path"
19474
+ }
19475
+ },
19476
+ "required": [
19477
+ "path"
19478
+ ],
19479
+ "returns": "void"
19480
+ },
18966
19481
  "readJsonAsync": {
18967
19482
  "description": "Asynchronously reads and parses a JSON file.",
18968
19483
  "parameters": {
@@ -22751,6 +23266,30 @@ export const introspectionData = [
22751
23266
  "shortcut": "features.contentDb",
22752
23267
  "className": "ContentDb",
22753
23268
  "methods": {
23269
+ "renderTree": {
23270
+ "description": "Render a tree view of the collection directory structure. Built with container.fs so it works without the `tree` binary.",
23271
+ "parameters": {
23272
+ "options": {
23273
+ "type": "{ depth?: number; dirsOnly?: boolean }",
23274
+ "description": "Parameter options"
23275
+ }
23276
+ },
23277
+ "required": [],
23278
+ "returns": "string"
23279
+ },
23280
+ "grep": {
23281
+ "description": "",
23282
+ "parameters": {
23283
+ "options": {
23284
+ "type": "string | GrepOptions",
23285
+ "description": "Parameter options"
23286
+ }
23287
+ },
23288
+ "required": [
23289
+ "options"
23290
+ ],
23291
+ "returns": "void"
23292
+ },
22754
23293
  "query": {
22755
23294
  "description": "Query documents belonging to a specific model definition.",
22756
23295
  "parameters": {
@@ -22916,57 +23455,141 @@ export const introspectionData = [
22916
23455
  "vectorSearch": {
22917
23456
  "description": "Vector similarity search using embeddings. Finds conceptually related documents even without keyword matches.",
22918
23457
  "parameters": {
22919
- "query": {
22920
- "type": "string",
22921
- "description": "Parameter query"
22922
- },
22923
- "options": {
22924
- "type": "{ limit?: number; model?: string; where?: Record<string, any> }",
22925
- "description": "Parameter options"
23458
+ "query": {
23459
+ "type": "string",
23460
+ "description": "Parameter query"
23461
+ },
23462
+ "options": {
23463
+ "type": "{ limit?: number; model?: string; where?: Record<string, any> }",
23464
+ "description": "Parameter options"
23465
+ }
23466
+ },
23467
+ "required": [
23468
+ "query"
23469
+ ],
23470
+ "returns": "void"
23471
+ },
23472
+ "hybridSearch": {
23473
+ "description": "Combined keyword + semantic search with Reciprocal Rank Fusion. Best for general questions about the collection.",
23474
+ "parameters": {
23475
+ "query": {
23476
+ "type": "string",
23477
+ "description": "Parameter query"
23478
+ },
23479
+ "options": {
23480
+ "type": "{ limit?: number; model?: string; where?: Record<string, any>; ftsWeight?: number; vecWeight?: number }",
23481
+ "description": "Parameter options"
23482
+ }
23483
+ },
23484
+ "required": [
23485
+ "query"
23486
+ ],
23487
+ "returns": "void"
23488
+ },
23489
+ "buildSearchIndex": {
23490
+ "description": "Build the search index from all documents in the collection. Chunks documents and generates embeddings.",
23491
+ "parameters": {
23492
+ "options": {
23493
+ "type": "{ force?: boolean; embeddingProvider?: string; embeddingModel?: string; onProgress?: (indexed: number, total: number) => void }",
23494
+ "description": "Parameter options"
23495
+ }
23496
+ },
23497
+ "required": [],
23498
+ "returns": "void"
23499
+ },
23500
+ "rebuildSearchIndex": {
23501
+ "description": "Rebuild the entire search index from scratch.",
23502
+ "parameters": {
23503
+ "options": {
23504
+ "type": "{ embeddingProvider?: string; embeddingModel?: string; onProgress?: (indexed: number, total: number) => void }",
23505
+ "description": "Parameter options"
23506
+ }
23507
+ },
23508
+ "required": [],
23509
+ "returns": "void"
23510
+ },
23511
+ "getCollectionOverview": {
23512
+ "description": "Returns a high-level overview of the collection.",
23513
+ "parameters": {},
23514
+ "required": [],
23515
+ "returns": "void"
23516
+ },
23517
+ "listDocuments": {
23518
+ "description": "List document IDs, optionally filtered by model or glob.",
23519
+ "parameters": {
23520
+ "args": {
23521
+ "type": "{ model?: string; glob?: string }",
23522
+ "description": "Parameter args"
23523
+ }
23524
+ },
23525
+ "required": [
23526
+ "args"
23527
+ ],
23528
+ "returns": "void"
23529
+ },
23530
+ "readDocument": {
23531
+ "description": "Read a single document with optional section filtering.",
23532
+ "parameters": {
23533
+ "args": {
23534
+ "type": "{ id: string; include?: string[]; exclude?: string[]; meta?: boolean }",
23535
+ "description": "Parameter args"
23536
+ }
23537
+ },
23538
+ "required": [
23539
+ "args"
23540
+ ],
23541
+ "returns": "void"
23542
+ },
23543
+ "readMultipleDocuments": {
23544
+ "description": "Read multiple documents with optional section filtering.",
23545
+ "parameters": {
23546
+ "args": {
23547
+ "type": "{ ids: string[]; include?: string[]; exclude?: string[]; meta?: boolean }",
23548
+ "description": "Parameter args"
22926
23549
  }
22927
23550
  },
22928
23551
  "required": [
22929
- "query"
23552
+ "args"
22930
23553
  ],
22931
23554
  "returns": "void"
22932
23555
  },
22933
- "hybridSearch": {
22934
- "description": "Combined keyword + semantic search with Reciprocal Rank Fusion. Best for general questions about the collection.",
23556
+ "queryDocuments": {
23557
+ "description": "Query documents by model with filters, sort, limit.",
22935
23558
  "parameters": {
22936
- "query": {
22937
- "type": "string",
22938
- "description": "Parameter query"
22939
- },
22940
- "options": {
22941
- "type": "{ limit?: number; model?: string; where?: Record<string, any>; ftsWeight?: number; vecWeight?: number }",
22942
- "description": "Parameter options"
23559
+ "args": {
23560
+ "type": "{ model: string; where?: string; sort?: string; limit?: number; offset?: number; select?: string[] }",
23561
+ "description": "Parameter args"
22943
23562
  }
22944
23563
  },
22945
23564
  "required": [
22946
- "query"
23565
+ "args"
22947
23566
  ],
22948
23567
  "returns": "void"
22949
23568
  },
22950
- "buildSearchIndex": {
22951
- "description": "Build the search index from all documents in the collection. Chunks documents and generates embeddings.",
23569
+ "searchContent": {
23570
+ "description": "Grep/text search across the collection.",
22952
23571
  "parameters": {
22953
- "options": {
22954
- "type": "{ force?: boolean; embeddingProvider?: string; embeddingModel?: string; onProgress?: (indexed: number, total: number) => void }",
22955
- "description": "Parameter options"
23572
+ "args": {
23573
+ "type": "{ pattern: string; caseSensitive?: boolean }",
23574
+ "description": "Parameter args"
22956
23575
  }
22957
23576
  },
22958
- "required": [],
23577
+ "required": [
23578
+ "args"
23579
+ ],
22959
23580
  "returns": "void"
22960
23581
  },
22961
- "rebuildSearchIndex": {
22962
- "description": "Rebuild the entire search index from scratch.",
23582
+ "semanticSearch": {
23583
+ "description": "Hybrid semantic search with graceful fallback to grep.",
22963
23584
  "parameters": {
22964
- "options": {
22965
- "type": "{ embeddingProvider?: string; embeddingModel?: string; onProgress?: (indexed: number, total: number) => void }",
22966
- "description": "Parameter options"
23585
+ "args": {
23586
+ "type": "{ query: string; limit?: number }",
23587
+ "description": "Parameter args"
22967
23588
  }
22968
23589
  },
22969
- "required": [],
23590
+ "required": [
23591
+ "args"
23592
+ ],
22970
23593
  "returns": "void"
22971
23594
  }
22972
23595
  },
@@ -22991,6 +23614,18 @@ export const introspectionData = [
22991
23614
  "description": "Returns an array of all registered model names from the collection.",
22992
23615
  "returns": "string[]"
22993
23616
  },
23617
+ "available": {
23618
+ "description": "Returns the available document ids in the collection",
23619
+ "returns": "string[]"
23620
+ },
23621
+ "modelDefinitionTable": {
23622
+ "description": "",
23623
+ "returns": "any"
23624
+ },
23625
+ "fileTree": {
23626
+ "description": "",
23627
+ "returns": "any"
23628
+ },
22994
23629
  "searchIndexStatus": {
22995
23630
  "description": "Get the current search index status.",
22996
23631
  "returns": "any"
@@ -23281,250 +23916,55 @@ export const introspectionData = [
23281
23916
  "required": [
23282
23917
  "data"
23283
23918
  ],
23284
- "returns": "Promise<void>"
23285
- },
23286
- "disconnect": {
23287
- "description": "Gracefully close the WebSocket connection. Suppresses auto-reconnect and updates connection state to disconnected.",
23288
- "parameters": {},
23289
- "required": [],
23290
- "returns": "Promise<this>"
23291
- }
23292
- },
23293
- "getters": {
23294
- "hasError": {
23295
- "description": "Whether the client is in an error state.",
23296
- "returns": "any"
23297
- }
23298
- },
23299
- "events": {
23300
- "open": {
23301
- "name": "open",
23302
- "description": "Event emitted by WebSocketClient",
23303
- "arguments": {}
23304
- },
23305
- "error": {
23306
- "name": "error",
23307
- "description": "Event emitted by WebSocketClient",
23308
- "arguments": {}
23309
- },
23310
- "message": {
23311
- "name": "message",
23312
- "description": "Event emitted by WebSocketClient",
23313
- "arguments": {}
23314
- },
23315
- "close": {
23316
- "name": "close",
23317
- "description": "Event emitted by WebSocketClient",
23318
- "arguments": {}
23319
- },
23320
- "reconnecting": {
23321
- "name": "reconnecting",
23322
- "description": "Event emitted by WebSocketClient",
23323
- "arguments": {}
23324
- }
23325
- },
23326
- "state": {},
23327
- "options": {},
23328
- "envVars": [],
23329
- "examples": [
23330
- {
23331
- "language": "ts",
23332
- "code": "const ws = container.client('websocket', {\n baseURL: 'ws://localhost:8080',\n reconnect: true,\n maxReconnectAttempts: 5\n})\nws.on('message', (data) => console.log('Received:', data))\nawait ws.connect()\nawait ws.send({ type: 'hello' })"
23333
- }
23334
- ]
23335
- },
23336
- {
23337
- "id": "clients.supabase",
23338
- "description": "Supabase client for the Luca container system. Wraps the official `@supabase/supabase-js` SDK and exposes it through Luca's typed state, events, and introspection system. The SDK is isomorphic so this single implementation works in both Node and browser containers. Use `client.sdk` for full SDK access, or use the convenience wrappers for common operations (auth, database queries, storage, edge functions, realtime).",
23339
- "shortcut": "clients.supabase",
23340
- "className": "SupabaseClient",
23341
- "methods": {
23342
- "from": {
23343
- "description": "Start a query on a Postgres table or view.",
23344
- "parameters": {
23345
- "table": {
23346
- "type": "string",
23347
- "description": "The table or view name to query"
23348
- }
23349
- },
23350
- "required": [
23351
- "table"
23352
- ],
23353
- "returns": "void"
23354
- },
23355
- "rpc": {
23356
- "description": "Call a Postgres function (RPC).",
23357
- "parameters": {
23358
- "fn": {
23359
- "type": "string",
23360
- "description": "The function name"
23361
- },
23362
- "params": {
23363
- "type": "Record<string, unknown>",
23364
- "description": "Arguments to pass to the function"
23365
- },
23366
- "options": {
23367
- "type": "{ head?: boolean; get?: boolean; count?: \"exact\" | \"planned\" | \"estimated\" }",
23368
- "description": "Optional settings (head, get, count)"
23369
- }
23370
- },
23371
- "required": [
23372
- "fn"
23373
- ],
23374
- "returns": "void"
23375
- },
23376
- "signInWithPassword": {
23377
- "description": "Sign in with email and password.",
23378
- "parameters": {
23379
- "email": {
23380
- "type": "string",
23381
- "description": "Parameter email"
23382
- },
23383
- "password": {
23384
- "type": "string",
23385
- "description": "Parameter password"
23386
- }
23387
- },
23388
- "required": [
23389
- "email",
23390
- "password"
23391
- ],
23392
- "returns": "void"
23393
- },
23394
- "signUp": {
23395
- "description": "Create a new user account with email and password.",
23396
- "parameters": {
23397
- "email": {
23398
- "type": "string",
23399
- "description": "Parameter email"
23400
- },
23401
- "password": {
23402
- "type": "string",
23403
- "description": "Parameter password"
23404
- }
23405
- },
23406
- "required": [
23407
- "email",
23408
- "password"
23409
- ],
23410
- "returns": "void"
23411
- },
23412
- "signOut": {
23413
- "description": "Sign the current user out.",
23414
- "parameters": {},
23415
- "required": [],
23416
- "returns": "void"
23417
- },
23418
- "getSession": {
23419
- "description": "Get the current session, if any.",
23420
- "parameters": {},
23421
- "required": [],
23422
- "returns": "void"
23423
- },
23424
- "getUser": {
23425
- "description": "Get the current user, if any.",
23426
- "parameters": {},
23427
- "required": [],
23428
- "returns": "void"
23429
- },
23430
- "invoke": {
23431
- "description": "Invoke a Supabase Edge Function by name.",
23432
- "parameters": {
23433
- "name": {
23434
- "type": "string",
23435
- "description": "Parameter name"
23436
- },
23437
- "body": {
23438
- "type": "any",
23439
- "description": "Parameter body"
23440
- }
23441
- },
23442
- "required": [
23443
- "name"
23444
- ],
23445
- "returns": "void"
23446
- },
23447
- "subscribe": {
23448
- "description": "Subscribe to realtime changes on a Postgres table.",
23449
- "parameters": {
23450
- "channelName": {
23451
- "type": "string",
23452
- "description": "A name for this subscription channel"
23453
- },
23454
- "table": {
23455
- "type": "string",
23456
- "description": "The table to listen to"
23457
- },
23458
- "callback": {
23459
- "type": "(payload: any) => void",
23460
- "description": "Called with the payload on each change"
23461
- },
23462
- "event": {
23463
- "type": "\"INSERT\" | \"UPDATE\" | \"DELETE\" | \"*\"",
23464
- "description": "The event type to listen for (default: all changes)"
23465
- }
23466
- },
23467
- "required": [
23468
- "channelName",
23469
- "table",
23470
- "callback"
23471
- ],
23472
- "returns": "RealtimeChannel"
23473
- },
23474
- "unsubscribe": {
23475
- "description": "Unsubscribe and remove a realtime channel by name.",
23476
- "parameters": {
23477
- "channelName": {
23478
- "type": "string",
23479
- "description": "The channel name to remove"
23480
- }
23481
- },
23482
- "required": [
23483
- "channelName"
23484
- ],
23485
- "returns": "void"
23486
- },
23487
- "unsubscribeAll": {
23488
- "description": "Unsubscribe and remove all realtime channels.",
23489
- "parameters": {},
23490
- "required": [],
23491
- "returns": "void"
23492
- },
23493
- "connect": {
23494
- "description": "Connect is a no-op since the Supabase SDK initializes on construction. The client is ready to use immediately after creation.",
23495
- "parameters": {},
23496
- "required": [],
23497
- "returns": "void"
23919
+ "returns": "Promise<void>"
23498
23920
  },
23499
23921
  "disconnect": {
23500
- "description": "Disconnect by signing out and removing all realtime channels.",
23922
+ "description": "Gracefully close the WebSocket connection. Suppresses auto-reconnect and updates connection state to disconnected.",
23501
23923
  "parameters": {},
23502
23924
  "required": [],
23503
- "returns": "void"
23925
+ "returns": "Promise<this>"
23504
23926
  }
23505
23927
  },
23506
23928
  "getters": {
23507
- "sdk": {
23508
- "description": "Returns the raw Supabase SDK client for full access to all SDK methods.",
23509
- "returns": "SupabaseSDKClient<any, any>"
23510
- },
23511
- "storage": {
23512
- "description": "Returns the Supabase Storage client for managing buckets and files.",
23929
+ "hasError": {
23930
+ "description": "Whether the client is in an error state.",
23513
23931
  "returns": "any"
23932
+ }
23933
+ },
23934
+ "events": {
23935
+ "open": {
23936
+ "name": "open",
23937
+ "description": "Event emitted by WebSocketClient",
23938
+ "arguments": {}
23514
23939
  },
23515
- "functions": {
23516
- "description": "Returns the Supabase Functions client.",
23517
- "returns": "any"
23940
+ "error": {
23941
+ "name": "error",
23942
+ "description": "Event emitted by WebSocketClient",
23943
+ "arguments": {}
23944
+ },
23945
+ "message": {
23946
+ "name": "message",
23947
+ "description": "Event emitted by WebSocketClient",
23948
+ "arguments": {}
23949
+ },
23950
+ "close": {
23951
+ "name": "close",
23952
+ "description": "Event emitted by WebSocketClient",
23953
+ "arguments": {}
23954
+ },
23955
+ "reconnecting": {
23956
+ "name": "reconnecting",
23957
+ "description": "Event emitted by WebSocketClient",
23958
+ "arguments": {}
23518
23959
  }
23519
23960
  },
23520
- "events": {},
23521
23961
  "state": {},
23522
23962
  "options": {},
23523
23963
  "envVars": [],
23524
23964
  "examples": [
23525
23965
  {
23526
23966
  "language": "ts",
23527
- "code": "const supabase = container.client('supabase', {\n supabaseUrl: 'https://xyz.supabase.co',\n supabaseKey: 'your-anon-key',\n})\n\n// Query data\nconst { data } = await supabase.from('users').select('*')\n\n// Auth\nawait supabase.signInWithPassword('user@example.com', 'password')\n\n// Realtime\nsupabase.subscribe('changes', 'users', (payload) => {\n console.log('Change:', payload)\n})"
23967
+ "code": "const ws = container.client('websocket', {\n baseURL: 'ws://localhost:8080',\n reconnect: true,\n maxReconnectAttempts: 5\n})\nws.on('message', (data) => console.log('Received:', data))\nawait ws.connect()\nawait ws.send({ type: 'hello' })"
23528
23968
  }
23529
23969
  ]
23530
23970
  },
@@ -23795,6 +24235,201 @@ export const introspectionData = [
23795
24235
  }
23796
24236
  ]
23797
24237
  },
24238
+ {
24239
+ "id": "clients.supabase",
24240
+ "description": "Supabase client for the Luca container system. Wraps the official `@supabase/supabase-js` SDK and exposes it through Luca's typed state, events, and introspection system. The SDK is isomorphic so this single implementation works in both Node and browser containers. Use `client.sdk` for full SDK access, or use the convenience wrappers for common operations (auth, database queries, storage, edge functions, realtime).",
24241
+ "shortcut": "clients.supabase",
24242
+ "className": "SupabaseClient",
24243
+ "methods": {
24244
+ "from": {
24245
+ "description": "Start a query on a Postgres table or view.",
24246
+ "parameters": {
24247
+ "table": {
24248
+ "type": "string",
24249
+ "description": "The table or view name to query"
24250
+ }
24251
+ },
24252
+ "required": [
24253
+ "table"
24254
+ ],
24255
+ "returns": "void"
24256
+ },
24257
+ "rpc": {
24258
+ "description": "Call a Postgres function (RPC).",
24259
+ "parameters": {
24260
+ "fn": {
24261
+ "type": "string",
24262
+ "description": "The function name"
24263
+ },
24264
+ "params": {
24265
+ "type": "Record<string, unknown>",
24266
+ "description": "Arguments to pass to the function"
24267
+ },
24268
+ "options": {
24269
+ "type": "{ head?: boolean; get?: boolean; count?: \"exact\" | \"planned\" | \"estimated\" }",
24270
+ "description": "Optional settings (head, get, count)"
24271
+ }
24272
+ },
24273
+ "required": [
24274
+ "fn"
24275
+ ],
24276
+ "returns": "void"
24277
+ },
24278
+ "signInWithPassword": {
24279
+ "description": "Sign in with email and password.",
24280
+ "parameters": {
24281
+ "email": {
24282
+ "type": "string",
24283
+ "description": "Parameter email"
24284
+ },
24285
+ "password": {
24286
+ "type": "string",
24287
+ "description": "Parameter password"
24288
+ }
24289
+ },
24290
+ "required": [
24291
+ "email",
24292
+ "password"
24293
+ ],
24294
+ "returns": "void"
24295
+ },
24296
+ "signUp": {
24297
+ "description": "Create a new user account with email and password.",
24298
+ "parameters": {
24299
+ "email": {
24300
+ "type": "string",
24301
+ "description": "Parameter email"
24302
+ },
24303
+ "password": {
24304
+ "type": "string",
24305
+ "description": "Parameter password"
24306
+ }
24307
+ },
24308
+ "required": [
24309
+ "email",
24310
+ "password"
24311
+ ],
24312
+ "returns": "void"
24313
+ },
24314
+ "signOut": {
24315
+ "description": "Sign the current user out.",
24316
+ "parameters": {},
24317
+ "required": [],
24318
+ "returns": "void"
24319
+ },
24320
+ "getSession": {
24321
+ "description": "Get the current session, if any.",
24322
+ "parameters": {},
24323
+ "required": [],
24324
+ "returns": "void"
24325
+ },
24326
+ "getUser": {
24327
+ "description": "Get the current user, if any.",
24328
+ "parameters": {},
24329
+ "required": [],
24330
+ "returns": "void"
24331
+ },
24332
+ "invoke": {
24333
+ "description": "Invoke a Supabase Edge Function by name.",
24334
+ "parameters": {
24335
+ "name": {
24336
+ "type": "string",
24337
+ "description": "Parameter name"
24338
+ },
24339
+ "body": {
24340
+ "type": "any",
24341
+ "description": "Parameter body"
24342
+ }
24343
+ },
24344
+ "required": [
24345
+ "name"
24346
+ ],
24347
+ "returns": "void"
24348
+ },
24349
+ "subscribe": {
24350
+ "description": "Subscribe to realtime changes on a Postgres table.",
24351
+ "parameters": {
24352
+ "channelName": {
24353
+ "type": "string",
24354
+ "description": "A name for this subscription channel"
24355
+ },
24356
+ "table": {
24357
+ "type": "string",
24358
+ "description": "The table to listen to"
24359
+ },
24360
+ "callback": {
24361
+ "type": "(payload: any) => void",
24362
+ "description": "Called with the payload on each change"
24363
+ },
24364
+ "event": {
24365
+ "type": "\"INSERT\" | \"UPDATE\" | \"DELETE\" | \"*\"",
24366
+ "description": "The event type to listen for (default: all changes)"
24367
+ }
24368
+ },
24369
+ "required": [
24370
+ "channelName",
24371
+ "table",
24372
+ "callback"
24373
+ ],
24374
+ "returns": "RealtimeChannel"
24375
+ },
24376
+ "unsubscribe": {
24377
+ "description": "Unsubscribe and remove a realtime channel by name.",
24378
+ "parameters": {
24379
+ "channelName": {
24380
+ "type": "string",
24381
+ "description": "The channel name to remove"
24382
+ }
24383
+ },
24384
+ "required": [
24385
+ "channelName"
24386
+ ],
24387
+ "returns": "void"
24388
+ },
24389
+ "unsubscribeAll": {
24390
+ "description": "Unsubscribe and remove all realtime channels.",
24391
+ "parameters": {},
24392
+ "required": [],
24393
+ "returns": "void"
24394
+ },
24395
+ "connect": {
24396
+ "description": "Connect is a no-op since the Supabase SDK initializes on construction. The client is ready to use immediately after creation.",
24397
+ "parameters": {},
24398
+ "required": [],
24399
+ "returns": "void"
24400
+ },
24401
+ "disconnect": {
24402
+ "description": "Disconnect by signing out and removing all realtime channels.",
24403
+ "parameters": {},
24404
+ "required": [],
24405
+ "returns": "void"
24406
+ }
24407
+ },
24408
+ "getters": {
24409
+ "sdk": {
24410
+ "description": "Returns the raw Supabase SDK client for full access to all SDK methods.",
24411
+ "returns": "SupabaseSDKClient<any, any>"
24412
+ },
24413
+ "storage": {
24414
+ "description": "Returns the Supabase Storage client for managing buckets and files.",
24415
+ "returns": "any"
24416
+ },
24417
+ "functions": {
24418
+ "description": "Returns the Supabase Functions client.",
24419
+ "returns": "any"
24420
+ }
24421
+ },
24422
+ "events": {},
24423
+ "state": {},
24424
+ "options": {},
24425
+ "envVars": [],
24426
+ "examples": [
24427
+ {
24428
+ "language": "ts",
24429
+ "code": "const supabase = container.client('supabase', {\n supabaseUrl: 'https://xyz.supabase.co',\n supabaseKey: 'your-anon-key',\n})\n\n// Query data\nconst { data } = await supabase.from('users').select('*')\n\n// Auth\nawait supabase.signInWithPassword('user@example.com', 'password')\n\n// Realtime\nsupabase.subscribe('changes', 'users', (payload) => {\n console.log('Change:', payload)\n})"
24430
+ }
24431
+ ]
24432
+ },
23798
24433
  {
23799
24434
  "id": "clients.comfyui",
23800
24435
  "description": "ComfyUI client — execute Stable Diffusion workflows via the ComfyUI API. Connects to a ComfyUI instance to queue prompts, track execution via WebSocket or polling, and download generated images. Supports both UI-format and API-format workflows with automatic conversion.",
@@ -24616,21 +25251,27 @@ export const introspectionData = [
24616
25251
  },
24617
25252
  {
24618
25253
  "id": "features.assistantsManager",
24619
- "description": "Discovers and manages assistant definitions by finding all CORE.md files in the project using the fileManager. Each directory containing a CORE.md is treated as an assistant definition that can also contain tools.ts, hooks.ts, voice.yaml, and a docs/ folder. Use `discover()` to scan for available assistants, `list()` to enumerate them, and `create(name)` to instantiate one as a running Assistant feature.",
25254
+ "description": "Discovers and manages assistant definitions by looking for subdirectories in two locations: ~/.luca/assistants/ and cwd/assistants/. Each subdirectory containing a CORE.md is treated as an assistant definition. Use `discover()` to scan for available assistants, `list()` to enumerate them, and `create(name)` to instantiate one as a running Assistant feature.",
24620
25255
  "shortcut": "features.assistantsManager",
24621
25256
  "className": "AssistantsManager",
24622
25257
  "methods": {
24623
- "afterInitialize": {
24624
- "description": "",
25258
+ "discover": {
25259
+ "description": "Discovers assistants by listing subdirectories in ~/.luca/assistants/ and cwd/assistants/. Each subdirectory containing a CORE.md is an assistant.",
24625
25260
  "parameters": {},
24626
25261
  "required": [],
24627
- "returns": "void"
25262
+ "returns": "Promise<this>"
24628
25263
  },
24629
- "discover": {
24630
- "description": "Discovers assistants by finding all CORE.md files in the project using the fileManager. Each directory containing a CORE.md is treated as an assistant definition.",
25264
+ "downloadLucaCoreAssistants": {
25265
+ "description": "Downloads the core assistants that ship with luca from GitHub into ~/.luca/assistants.",
24631
25266
  "parameters": {},
24632
25267
  "required": [],
24633
- "returns": "Promise<this>"
25268
+ "returns": "void",
25269
+ "examples": [
25270
+ {
25271
+ "language": "ts",
25272
+ "code": "const manager = container.feature('assistantsManager')\nawait manager.downloadLucaCoreAssistants()\nawait manager.discover()\nconsole.log(manager.available)"
25273
+ }
25274
+ ]
24634
25275
  },
24635
25276
  "list": {
24636
25277
  "description": "Returns all discovered assistant entries as an array.",
@@ -24643,7 +25284,7 @@ export const introspectionData = [
24643
25284
  "parameters": {
24644
25285
  "name": {
24645
25286
  "type": "string",
24646
- "description": "The assistant name (e.g. 'assistants/chief-of-staff')"
25287
+ "description": "The assistant name (e.g. 'chief-of-staff')"
24647
25288
  }
24648
25289
  },
24649
25290
  "required": [
@@ -24651,12 +25292,36 @@ export const introspectionData = [
24651
25292
  ],
24652
25293
  "returns": "AssistantEntry | undefined"
24653
25294
  },
25295
+ "register": {
25296
+ "description": "Registers a factory function that creates an assistant at runtime. Registered factories take precedence over discovered entries when calling `create()`.",
25297
+ "parameters": {
25298
+ "id": {
25299
+ "type": "string",
25300
+ "description": "The assistant identifier"
25301
+ },
25302
+ "factory": {
25303
+ "type": "(options: Record<string, any>) => Assistant",
25304
+ "description": "Factory function that receives create options and returns an Assistant"
25305
+ }
25306
+ },
25307
+ "required": [
25308
+ "id",
25309
+ "factory"
25310
+ ],
25311
+ "returns": "this",
25312
+ "examples": [
25313
+ {
25314
+ "language": "ts",
25315
+ "code": "manager.register('custom-bot', (options) => {\n return container.feature('assistant', {\n systemPrompt: 'You are a custom bot.',\n ...options,\n })\n})\nconst bot = manager.create('custom-bot')"
25316
+ }
25317
+ ]
25318
+ },
24654
25319
  "create": {
24655
- "description": "Creates and returns a new Assistant feature instance for the given name. The assistant is configured with the discovered folder path. Any additional options are merged in.",
25320
+ "description": "Creates and returns a new Assistant feature instance for the given name. Checks runtime-registered factories first, then falls back to discovered entries. The assistant is configured with the discovered folder path. Any additional options are merged in.",
24656
25321
  "parameters": {
24657
25322
  "name": {
24658
25323
  "type": "string",
24659
- "description": "The assistant name (must match a discovered entry)"
25324
+ "description": "The assistant name (must match a registered factory or discovered entry)"
24660
25325
  },
24661
25326
  "options": {
24662
25327
  "type": "Record<string, any>",
@@ -24670,7 +25335,7 @@ export const introspectionData = [
24670
25335
  "examples": [
24671
25336
  {
24672
25337
  "language": "ts",
24673
- "code": "const assistant = manager.create('assistants/chief-of-staff', { model: 'gpt-4.1' })"
25338
+ "code": "const assistant = manager.create('chief-of-staff', { model: 'gpt-4.1' })"
24674
25339
  }
24675
25340
  ]
24676
25341
  },
@@ -24695,6 +25360,18 @@ export const introspectionData = [
24695
25360
  }
24696
25361
  },
24697
25362
  "getters": {
25363
+ "entries": {
25364
+ "description": "Discovered assistant entries keyed by name.",
25365
+ "returns": "Record<string, AssistantEntry>"
25366
+ },
25367
+ "instances": {
25368
+ "description": "Active assistant instances keyed by name.",
25369
+ "returns": "Record<string, Assistant>"
25370
+ },
25371
+ "factories": {
25372
+ "description": "Registered factory functions keyed by name.",
25373
+ "returns": "Record<string, (options: Record<string, any>) => Assistant>"
25374
+ },
24698
25375
  "available": {
24699
25376
  "description": "",
24700
25377
  "returns": "any"
@@ -24706,6 +25383,11 @@ export const introspectionData = [
24706
25383
  "description": "Event emitted by AssistantsManager",
24707
25384
  "arguments": {}
24708
25385
  },
25386
+ "assistantRegistered": {
25387
+ "name": "assistantRegistered",
25388
+ "description": "Event emitted by AssistantsManager",
25389
+ "arguments": {}
25390
+ },
24709
25391
  "assistantCreated": {
24710
25392
  "name": "assistantCreated",
24711
25393
  "description": "Event emitted by AssistantsManager",
@@ -24718,7 +25400,7 @@ export const introspectionData = [
24718
25400
  "examples": [
24719
25401
  {
24720
25402
  "language": "ts",
24721
- "code": "const manager = container.feature('assistantsManager')\nmanager.discover()\nconsole.log(manager.list()) // [{ name: 'assistants/chief-of-staff', folder: '...', ... }]\nconst assistant = manager.create('assistants/chief-of-staff')\nconst answer = await assistant.ask('Hello!')"
25403
+ "code": "const manager = container.feature('assistantsManager')\nmanager.discover()\nconsole.log(manager.list()) // [{ name: 'chief-of-staff', folder: '...', ... }]\nconst assistant = manager.create('chief-of-staff')\nconst answer = await assistant.ask('Hello!')"
24722
25404
  }
24723
25405
  ]
24724
25406
  },
@@ -24728,6 +25410,64 @@ export const introspectionData = [
24728
25410
  "shortcut": "features.conversation",
24729
25411
  "className": "Conversation",
24730
25412
  "methods": {
25413
+ "addTool": {
25414
+ "description": "Add or replace a single tool by name. Uses the same format as tools passed at construction time.",
25415
+ "parameters": {
25416
+ "name": {
25417
+ "type": "string",
25418
+ "description": "Parameter name"
25419
+ },
25420
+ "tool": {
25421
+ "type": "ConversationTool",
25422
+ "description": "Parameter tool",
25423
+ "properties": {
25424
+ "handler": {
25425
+ "type": "(...args: any[]) => Promise<any>",
25426
+ "description": ""
25427
+ },
25428
+ "description": {
25429
+ "type": "string",
25430
+ "description": ""
25431
+ },
25432
+ "parameters": {
25433
+ "type": "Record<string, any>",
25434
+ "description": ""
25435
+ }
25436
+ }
25437
+ }
25438
+ },
25439
+ "required": [
25440
+ "name",
25441
+ "tool"
25442
+ ],
25443
+ "returns": "this"
25444
+ },
25445
+ "removeTool": {
25446
+ "description": "Remove a tool by name.",
25447
+ "parameters": {
25448
+ "name": {
25449
+ "type": "string",
25450
+ "description": "Parameter name"
25451
+ }
25452
+ },
25453
+ "required": [
25454
+ "name"
25455
+ ],
25456
+ "returns": "this"
25457
+ },
25458
+ "updateTools": {
25459
+ "description": "Merge new tools into the conversation, replacing any with the same name. Accepts the same Record<string, ConversationTool> format used at construction time.",
25460
+ "parameters": {
25461
+ "tools": {
25462
+ "type": "Record<string, ConversationTool>",
25463
+ "description": "Parameter tools"
25464
+ }
25465
+ },
25466
+ "required": [
25467
+ "tools"
25468
+ ],
25469
+ "returns": "this"
25470
+ },
24731
25471
  "estimateTokens": {
24732
25472
  "description": "Estimate the input token count for the current messages array using the js-tiktoken tokenizer. Updates state.",
24733
25473
  "parameters": {},
@@ -24808,7 +25548,11 @@ export const introspectionData = [
24808
25548
  "getters": {
24809
25549
  "tools": {
24810
25550
  "description": "Returns the registered tools available for the model to call.",
24811
- "returns": "Record<string, any>"
25551
+ "returns": "Record<string, ConversationTool>"
25552
+ },
25553
+ "availableTools": {
25554
+ "description": "",
25555
+ "returns": "any"
24812
25556
  },
24813
25557
  "mcpServers": {
24814
25558
  "description": "Returns configured remote MCP servers keyed by server label.",
@@ -25061,8 +25805,8 @@ export const introspectionData = [
25061
25805
  }
25062
25806
  },
25063
25807
  "events": {
25064
- "loaded": {
25065
- "name": "loaded",
25808
+ "started": {
25809
+ "name": "started",
25066
25810
  "description": "Event emitted by OpenAPI",
25067
25811
  "arguments": {}
25068
25812
  }
@@ -25077,160 +25821,252 @@ export const introspectionData = [
25077
25821
  }
25078
25822
  ]
25079
25823
  },
25824
+ {
25825
+ "id": "features.docsReader",
25826
+ "description": "The DocsReader feature is an AI Assisted wrapper around a ContentDB feature. You can ask it questions about the content, and it will use the ContentDB to find the answers from the documents.",
25827
+ "shortcut": "features.docsReader",
25828
+ "className": "DocsReader",
25829
+ "methods": {
25830
+ "calculateCacheKeyForQuestion": {
25831
+ "description": "",
25832
+ "parameters": {
25833
+ "question": {
25834
+ "type": "string",
25835
+ "description": "Parameter question"
25836
+ }
25837
+ },
25838
+ "required": [
25839
+ "question"
25840
+ ],
25841
+ "returns": "void"
25842
+ },
25843
+ "ask": {
25844
+ "description": "",
25845
+ "parameters": {
25846
+ "question": {
25847
+ "type": "string",
25848
+ "description": "Parameter question"
25849
+ }
25850
+ },
25851
+ "required": [
25852
+ "question"
25853
+ ],
25854
+ "returns": "void"
25855
+ },
25856
+ "askCached": {
25857
+ "description": "",
25858
+ "parameters": {
25859
+ "question": {
25860
+ "type": "string",
25861
+ "description": "Parameter question"
25862
+ }
25863
+ },
25864
+ "required": [
25865
+ "question"
25866
+ ],
25867
+ "returns": "void"
25868
+ },
25869
+ "start": {
25870
+ "description": "Start the docs reader by loading the contentDb and wiring its tools into an assistant.",
25871
+ "parameters": {},
25872
+ "required": [],
25873
+ "returns": "Promise<DocsReader>"
25874
+ }
25875
+ },
25876
+ "getters": {
25877
+ "isStarted": {
25878
+ "description": "Whether the docs reader has been started.",
25879
+ "returns": "boolean"
25880
+ },
25881
+ "answerCache": {
25882
+ "description": "",
25883
+ "returns": "any"
25884
+ },
25885
+ "contentDb": {
25886
+ "description": "",
25887
+ "returns": "ContentDb"
25888
+ }
25889
+ },
25890
+ "events": {
25891
+ "started": {
25892
+ "name": "started",
25893
+ "description": "Event emitted by DocsReader",
25894
+ "arguments": {}
25895
+ }
25896
+ },
25897
+ "state": {},
25898
+ "options": {},
25899
+ "envVars": []
25900
+ },
25080
25901
  {
25081
25902
  "id": "features.skillsLibrary",
25082
- "description": "Manages two contentbase collections of skills following the Claude Code SKILL.md format. Project-level skills live in .claude/skills/ and user-level skills live in ~/.luca/skills/. Skills can be discovered, searched, created, updated, and removed at runtime.",
25903
+ "description": "Manages a registry of skill locations folders containing SKILL.md files. Persists known locations to ~/.luca/skills.json and scans them on start. Each skill folder can be opened as a DocsReader for AI-assisted Q&A. Exposes tools for assistant integration via assistant.use(skillsLibrary).",
25083
25904
  "shortcut": "features.skillsLibrary",
25084
25905
  "className": "SkillsLibrary",
25085
25906
  "methods": {
25086
- "load": {
25087
- "description": "Loads both project and user skill collections from disk. Gracefully handles missing directories.",
25907
+ "start": {
25908
+ "description": "Start the skills library: read config, scan all locations.",
25088
25909
  "parameters": {},
25089
25910
  "required": [],
25090
25911
  "returns": "Promise<SkillsLibrary>"
25091
25912
  },
25092
- "list": {
25093
- "description": "Lists all skills from both collections. Project skills come first.",
25094
- "parameters": {},
25095
- "required": [],
25096
- "returns": "SkillEntry[]"
25097
- },
25098
- "find": {
25099
- "description": "Finds a skill by name. Project skills take precedence over user skills.",
25913
+ "addLocation": {
25914
+ "description": "Add a new skill location folder and scan it for skills.",
25100
25915
  "parameters": {
25101
- "name": {
25916
+ "locationPath": {
25102
25917
  "type": "string",
25103
- "description": "The skill name to find (case-insensitive)"
25918
+ "description": "Path to a directory containing skill subfolders with SKILL.md"
25104
25919
  }
25105
25920
  },
25106
25921
  "required": [
25107
- "name"
25922
+ "locationPath"
25108
25923
  ],
25109
- "returns": "SkillEntry | undefined"
25924
+ "returns": "Promise<void>"
25110
25925
  },
25111
- "search": {
25112
- "description": "Searches skills by substring match against name and description.",
25926
+ "removeLocation": {
25927
+ "description": "Remove a skill location and its skills from the library.",
25113
25928
  "parameters": {
25114
- "query": {
25929
+ "locationPath": {
25115
25930
  "type": "string",
25116
- "description": "The search query"
25931
+ "description": "The location path to remove"
25117
25932
  }
25118
25933
  },
25119
25934
  "required": [
25120
- "query"
25935
+ "locationPath"
25121
25936
  ],
25122
- "returns": "SkillEntry[]"
25937
+ "returns": "Promise<void>"
25123
25938
  },
25124
- "getSkill": {
25125
- "description": "Gets a skill by name. Alias for find().",
25939
+ "scanLocation": {
25940
+ "description": "Scan a location folder for skill subfolders containing SKILL.md.",
25126
25941
  "parameters": {
25127
- "name": {
25942
+ "locationPath": {
25128
25943
  "type": "string",
25129
- "description": "The skill name"
25944
+ "description": "Absolute path to scan"
25130
25945
  }
25131
25946
  },
25132
25947
  "required": [
25133
- "name"
25948
+ "locationPath"
25134
25949
  ],
25135
- "returns": "SkillEntry | undefined"
25950
+ "returns": "Promise<void>"
25136
25951
  },
25137
- "create": {
25138
- "description": "Creates a new SKILL.md file in the specified collection. Maintains the directory-per-skill structure (skill-name/SKILL.md).",
25952
+ "list": {
25953
+ "description": "Return all discovered skills.",
25954
+ "parameters": {},
25955
+ "required": [],
25956
+ "returns": "SkillInfo[]"
25957
+ },
25958
+ "find": {
25959
+ "description": "Find a skill by name.",
25139
25960
  "parameters": {
25140
- "skill": {
25141
- "type": "{\n\t\t\tname: string\n\t\t\tdescription: string\n\t\t\tbody: string\n\t\t\tmeta?: Record<string, unknown>\n\t\t}",
25142
- "description": "The skill to create"
25143
- },
25144
- "target": {
25145
- "type": "'project' | 'user'",
25146
- "description": "Which collection to write to (default: 'project')"
25961
+ "skillName": {
25962
+ "type": "string",
25963
+ "description": "Parameter skillName"
25147
25964
  }
25148
25965
  },
25149
25966
  "required": [
25150
- "skill"
25967
+ "skillName"
25151
25968
  ],
25152
- "returns": "Promise<SkillEntry>"
25969
+ "returns": "SkillInfo | undefined"
25153
25970
  },
25154
- "update": {
25155
- "description": "Updates an existing skill's content or metadata.",
25971
+ "createSkillReader": {
25972
+ "description": "Create a DocsReader for a skill's folder, enabling AI-assisted Q&A.",
25156
25973
  "parameters": {
25157
- "name": {
25974
+ "skillName": {
25158
25975
  "type": "string",
25159
- "description": "The skill name to update"
25160
- },
25161
- "updates": {
25162
- "type": "{\n\t\t\tdescription?: string\n\t\t\tbody?: string\n\t\t\tmeta?: Record<string, unknown>\n\t\t}",
25163
- "description": "Fields to update"
25976
+ "description": "Name of the skill to create a reader for"
25164
25977
  }
25165
25978
  },
25166
25979
  "required": [
25167
- "name",
25168
- "updates"
25980
+ "skillName"
25169
25981
  ],
25170
- "returns": "Promise<SkillEntry>"
25982
+ "returns": "DocsReader"
25171
25983
  },
25172
- "remove": {
25173
- "description": "Removes a skill by name, deleting its SKILL.md and cleaning up the directory.",
25984
+ "ensureFolderCreatedWithSkillsByName": {
25985
+ "description": "Create a tmp directory containing symlinked/copied skill folders by name, suitable for passing to claude --add-dir.",
25174
25986
  "parameters": {
25175
- "name": {
25176
- "type": "string",
25177
- "description": "The skill name to remove"
25987
+ "skillNames": {
25988
+ "type": "string[]",
25989
+ "description": "Array of skill names to include"
25178
25990
  }
25179
25991
  },
25180
25992
  "required": [
25181
- "name"
25993
+ "skillNames"
25182
25994
  ],
25183
- "returns": "Promise<boolean>"
25995
+ "returns": "string"
25184
25996
  },
25185
- "toConversationTools": {
25186
- "description": "Converts all skills into ConversationTool format for use with Conversation. Each skill becomes a tool that returns its instruction body when invoked.",
25187
- "parameters": {},
25997
+ "searchAvailableSkills": {
25998
+ "description": "Search available skills, optionally filtered by a query string.",
25999
+ "parameters": {
26000
+ "{ query }": {
26001
+ "type": "{ query?: string }",
26002
+ "description": "Parameter { query }"
26003
+ }
26004
+ },
25188
26005
  "required": [],
25189
- "returns": "Record<string, ConversationTool>"
26006
+ "returns": "Promise<string>"
25190
26007
  },
25191
- "toSystemPromptBlock": {
25192
- "description": "Generates a markdown block listing all available skills with names and descriptions. Suitable for injecting into a system prompt.",
25193
- "parameters": {},
25194
- "required": [],
25195
- "returns": "string"
26008
+ "loadSkill": {
26009
+ "description": "Load a skill's full SKILL.md content and metadata.",
26010
+ "parameters": {
26011
+ "{ skillName }": {
26012
+ "type": "{ skillName: string }",
26013
+ "description": "Parameter { skillName }"
26014
+ }
26015
+ },
26016
+ "required": [
26017
+ "{ skillName }"
26018
+ ],
26019
+ "returns": "Promise<string>"
26020
+ },
26021
+ "askSkillBasedQuestion": {
26022
+ "description": "Ask a question about a specific skill using a DocsReader.",
26023
+ "parameters": {
26024
+ "{ skillName, question }": {
26025
+ "type": "{ skillName: string; question: string }",
26026
+ "description": "Parameter { skillName, question }"
26027
+ }
26028
+ },
26029
+ "required": [
26030
+ "{ skillName, question }"
26031
+ ],
26032
+ "returns": "Promise<string>"
25196
26033
  }
25197
26034
  },
25198
26035
  "getters": {
25199
- "projectCollection": {
25200
- "description": "Returns the project-level contentbase Collection, lazily initialized.",
25201
- "returns": "Collection"
26036
+ "skills": {
26037
+ "description": "Discovered skills keyed by name.",
26038
+ "returns": "Record<string, SkillInfo>"
26039
+ },
26040
+ "availableSkills": {
26041
+ "description": "",
26042
+ "returns": "any"
25202
26043
  },
25203
- "userCollection": {
25204
- "description": "Returns the user-level contentbase Collection, lazily initialized.",
25205
- "returns": "Collection"
26044
+ "skillsTable": {
26045
+ "description": "",
26046
+ "returns": "Record<string, string>"
25206
26047
  },
25207
- "isLoaded": {
25208
- "description": "Whether the skills library has been loaded.",
25209
- "returns": "boolean"
26048
+ "configPath": {
26049
+ "description": "Resolved path to the skills.json config file.",
26050
+ "returns": "string"
25210
26051
  },
25211
- "skillNames": {
25212
- "description": "Array of all skill names across both collections.",
25213
- "returns": "string[]"
26052
+ "isStarted": {
26053
+ "description": "Whether the library has been loaded.",
26054
+ "returns": "boolean"
25214
26055
  }
25215
26056
  },
25216
26057
  "events": {
25217
- "loaded": {
25218
- "name": "loaded",
25219
- "description": "Event emitted by SkillsLibrary",
25220
- "arguments": {}
25221
- },
25222
- "skillCreated": {
25223
- "name": "skillCreated",
26058
+ "started": {
26059
+ "name": "started",
25224
26060
  "description": "Event emitted by SkillsLibrary",
25225
26061
  "arguments": {}
25226
26062
  },
25227
- "skillUpdated": {
25228
- "name": "skillUpdated",
26063
+ "locationAdded": {
26064
+ "name": "locationAdded",
25229
26065
  "description": "Event emitted by SkillsLibrary",
25230
26066
  "arguments": {}
25231
26067
  },
25232
- "skillRemoved": {
25233
- "name": "skillRemoved",
26068
+ "skillDiscovered": {
26069
+ "name": "skillDiscovered",
25234
26070
  "description": "Event emitted by SkillsLibrary",
25235
26071
  "arguments": {}
25236
26072
  }
@@ -25241,7 +26077,7 @@ export const introspectionData = [
25241
26077
  "examples": [
25242
26078
  {
25243
26079
  "language": "ts",
25244
- "code": "const skills = container.feature('skillsLibrary')\nawait skills.load()\n\n// List and search\nconst allSkills = skills.list()\nconst matches = skills.search('code review')\n\n// Create a new skill\nawait skills.create({\n name: 'summarize',\n description: 'Summarize a document',\n body: '## Instructions\\nRead the document and produce a concise summary.'\n})"
26080
+ "code": "const lib = container.feature('skillsLibrary')\nawait lib.start()\nawait lib.addLocation('~/.claude/skills')\nlib.list() // => SkillInfo[]\nconst reader = lib.createSkillReader('my-skill')"
25245
26081
  }
25246
26082
  ]
25247
26083
  },
@@ -25258,27 +26094,31 @@ export const introspectionData = [
25258
26094
  "returns": "void"
25259
26095
  },
25260
26096
  "use": {
25261
- "description": "Apply a setup function to this assistant. The function receives the assistant instance and can configure tools, hooks, event listeners, etc.",
26097
+ "description": "Apply a setup function or a Helper instance to this assistant. When passed a function, it receives the assistant and can configure tools, hooks, event listeners, etc. When passed a Helper instance that exposes tools via toTools(), those tools are automatically added to this assistant.",
25262
26098
  "parameters": {
25263
- "fn": {
25264
- "type": "(assistant: this) => void | Promise<void>",
25265
- "description": "Setup function that receives this assistant"
26099
+ "fnOrHelper": {
26100
+ "type": "((assistant: this) => void | Promise<void>) | { toTools: () => { schemas: Record<string, z.ZodType>, handlers: Record<string, Function> } } | { schemas: Record<string, z.ZodType>, handlers: Record<string, Function> }",
26101
+ "description": "Setup function or Helper instance"
25266
26102
  }
25267
26103
  },
25268
26104
  "required": [
25269
- "fn"
26105
+ "fnOrHelper"
25270
26106
  ],
25271
26107
  "returns": "this",
25272
26108
  "examples": [
25273
26109
  {
25274
26110
  "language": "ts",
25275
- "code": "assistant\n .use(setupLogging)\n .use(addAnalyticsTools)"
26111
+ "code": "assistant\n .use(setupLogging)\n .use(container.feature('git'))"
25276
26112
  }
25277
26113
  ]
25278
26114
  },
25279
26115
  "addTool": {
25280
26116
  "description": "Add a tool to this assistant. The tool name is derived from the handler's function name.",
25281
26117
  "parameters": {
26118
+ "name": {
26119
+ "type": "string",
26120
+ "description": "Parameter name"
26121
+ },
25282
26122
  "handler": {
25283
26123
  "type": "(...args: any[]) => any",
25284
26124
  "description": "A named function that implements the tool"
@@ -25289,6 +26129,7 @@ export const introspectionData = [
25289
26129
  }
25290
26130
  },
25291
26131
  "required": [
26132
+ "name",
25292
26133
  "handler"
25293
26134
  ],
25294
26135
  "returns": "this",
@@ -25354,7 +26195,7 @@ export const introspectionData = [
25354
26195
  "returns": "this"
25355
26196
  },
25356
26197
  "loadSystemPrompt": {
25357
- "description": "Load the system prompt from CORE.md, applying any prepend/append options.",
26198
+ "description": "Load the system prompt from CORE.md, applying any prepend/append options. YAML frontmatter (between --- fences) is stripped from the prompt and stored in `_meta`.",
25358
26199
  "parameters": {},
25359
26200
  "required": [],
25360
26201
  "returns": "string"
@@ -25440,6 +26281,29 @@ export const introspectionData = [
25440
26281
  },
25441
26282
  "required": [],
25442
26283
  "returns": "void"
26284
+ },
26285
+ "subagent": {
26286
+ "description": "Get or create a subagent assistant. Uses the assistantsManager to discover and create the assistant, then caches the instance for reuse across tool calls.",
26287
+ "parameters": {
26288
+ "id": {
26289
+ "type": "string",
26290
+ "description": "The assistant name (e.g. 'codingAssistant')"
26291
+ },
26292
+ "options": {
26293
+ "type": "Record<string, any>",
26294
+ "description": "Additional options to pass to the assistant constructor"
26295
+ }
26296
+ },
26297
+ "required": [
26298
+ "id"
26299
+ ],
26300
+ "returns": "Promise<Assistant>",
26301
+ "examples": [
26302
+ {
26303
+ "language": "ts",
26304
+ "code": "const researcher = await assistant.subagent('codingAssistant')\nconst answer = await researcher.ask('Find all usages of container.feature(\"fs\")')"
26305
+ }
26306
+ ]
25443
26307
  }
25444
26308
  },
25445
26309
  "getters": {
@@ -25483,6 +26347,10 @@ export const introspectionData = [
25483
26347
  "description": "",
25484
26348
  "returns": "Conversation"
25485
26349
  },
26350
+ "availableTools": {
26351
+ "description": "",
26352
+ "returns": "any"
26353
+ },
25486
26354
  "messages": {
25487
26355
  "description": "",
25488
26356
  "returns": "any"
@@ -25499,6 +26367,10 @@ export const introspectionData = [
25499
26367
  "description": "The tools registered with this assistant.",
25500
26368
  "returns": "Record<string, ConversationTool>"
25501
26369
  },
26370
+ "meta": {
26371
+ "description": "Parsed YAML frontmatter from CORE.md, or empty object if none.",
26372
+ "returns": "Record<string, any>"
26373
+ },
25502
26374
  "paths": {
25503
26375
  "description": "Provides a helper for creating paths off of the assistant's base folder",
25504
26376
  "returns": "any"
@@ -25522,6 +26394,10 @@ export const introspectionData = [
25522
26394
  "currentThreadId": {
25523
26395
  "description": "The active thread ID (undefined in lifecycle mode).",
25524
26396
  "returns": "string | undefined"
26397
+ },
26398
+ "availableSubagents": {
26399
+ "description": "Names of assistants available as subagents, discovered via the assistantsManager.",
26400
+ "returns": "string[]"
25525
26401
  }
25526
26402
  },
25527
26403
  "events": {
@@ -25530,6 +26406,11 @@ export const introspectionData = [
25530
26406
  "description": "Event emitted by Assistant",
25531
26407
  "arguments": {}
25532
26408
  },
26409
+ "toolsChanged": {
26410
+ "name": "toolsChanged",
26411
+ "description": "Event emitted by Assistant",
26412
+ "arguments": {}
26413
+ },
25533
26414
  "hookFired": {
25534
26415
  "name": "hookFired",
25535
26416
  "description": "Event emitted by Assistant",
@@ -27192,6 +28073,10 @@ export const containerIntrospectionData = [
27192
28073
  "description": "Returns a map of enabled feature shortcut IDs to their instances.",
27193
28074
  "returns": "Partial<AvailableInstanceTypes<Features>>"
27194
28075
  },
28076
+ "describer": {
28077
+ "description": "Lazy-initialized ContainerDescriber for introspecting registries, helpers, and members.",
28078
+ "returns": "ContainerDescriber"
28079
+ },
27195
28080
  "context": {
27196
28081
  "description": "The Container's context is an object that contains the enabled features, the container itself, and any additional context that has been added to the container. All helper instances that are created by the container will have access to the shared context.",
27197
28082
  "returns": "ContainerContext<Features> & Partial<AvailableInstanceTypes<AvailableFeatures>>"