@soederpop/luca 0.0.25 → 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.
- package/package.json +1 -1
- package/src/agi/features/assistant.ts +14 -12
- package/src/agi/features/docs-reader.ts +25 -1
- package/src/bootstrap/generated.ts +1 -1
- package/src/cli/build-info.ts +2 -2
- package/src/command.ts +75 -0
- package/src/commands/describe.ts +29 -1089
- package/src/container-describer.ts +1098 -0
- package/src/container.ts +11 -0
- package/src/introspection/generated.agi.ts +513 -429
- package/src/introspection/generated.node.ts +503 -419
- package/src/introspection/generated.web.ts +9 -1
- package/src/node/features/content-db.ts +17 -0
- package/src/node/features/fs.ts +18 -0
- package/src/scaffolds/generated.ts +1 -1
- package/src/server.ts +40 -0
- package/src/servers/express.ts +2 -0
- package/src/servers/mcp.ts +1 -0
- package/src/servers/socket.ts +2 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { setBuildTimeData, setContainerBuildTimeData } from './index.js';
|
|
2
2
|
|
|
3
3
|
// Auto-generated introspection registry data
|
|
4
|
-
// Generated at: 2026-03-
|
|
4
|
+
// Generated at: 2026-03-22T20:57:23.113Z
|
|
5
5
|
|
|
6
6
|
setBuildTimeData('features.containerLink', {
|
|
7
7
|
"id": "features.containerLink",
|
|
@@ -982,6 +982,10 @@ setContainerBuildTimeData('Container', {
|
|
|
982
982
|
"description": "Returns a map of enabled feature shortcut IDs to their instances.",
|
|
983
983
|
"returns": "Partial<AvailableInstanceTypes<Features>>"
|
|
984
984
|
},
|
|
985
|
+
"describer": {
|
|
986
|
+
"description": "Lazy-initialized ContainerDescriber for introspecting registries, helpers, and members.",
|
|
987
|
+
"returns": "ContainerDescriber"
|
|
988
|
+
},
|
|
985
989
|
"context": {
|
|
986
990
|
"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.",
|
|
987
991
|
"returns": "ContainerContext<Features> & Partial<AvailableInstanceTypes<AvailableFeatures>>"
|
|
@@ -2029,6 +2033,10 @@ export const containerIntrospectionData = [
|
|
|
2029
2033
|
"description": "Returns a map of enabled feature shortcut IDs to their instances.",
|
|
2030
2034
|
"returns": "Partial<AvailableInstanceTypes<Features>>"
|
|
2031
2035
|
},
|
|
2036
|
+
"describer": {
|
|
2037
|
+
"description": "Lazy-initialized ContainerDescriber for introspecting registries, helpers, and members.",
|
|
2038
|
+
"returns": "ContainerDescriber"
|
|
2039
|
+
},
|
|
2032
2040
|
"context": {
|
|
2033
2041
|
"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.",
|
|
2034
2042
|
"returns": "ContainerContext<Features> & Partial<AvailableInstanceTypes<AvailableFeatures>>"
|
|
@@ -428,6 +428,23 @@ export class ContentDb extends Feature<ContentDbState, ContentDbOptions> {
|
|
|
428
428
|
async generateModelSummary(options: any) {
|
|
429
429
|
return this.collection.generateModelSummary(options)
|
|
430
430
|
}
|
|
431
|
+
|
|
432
|
+
get modelDefinitionTable() {
|
|
433
|
+
return Object.fromEntries(this.collection.modelDefinitions.map(d => {
|
|
434
|
+
|
|
435
|
+
const prefixPattern = this.container.paths.relative(this.collection.resolve(d.prefix))
|
|
436
|
+
|
|
437
|
+
return [d.name, {
|
|
438
|
+
description: d.name === 'Base' ? 'Any markdown document not matched to a model' : d.description,
|
|
439
|
+
glob: `${prefixPattern}/**/*.md`,
|
|
440
|
+
routePatterns: Array(d.pattern).flatMap(p => p).filter(Boolean).map(p => `${prefixPattern}/${p}`)
|
|
441
|
+
}]
|
|
442
|
+
}))
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
get fileTree() {
|
|
446
|
+
return this.collection.renderFileTree()
|
|
447
|
+
}
|
|
431
448
|
|
|
432
449
|
// ── Search Integration ─────────────────────────────────────────────
|
|
433
450
|
|
package/src/node/features/fs.ts
CHANGED
|
@@ -88,6 +88,16 @@ export class FS extends Feature {
|
|
|
88
88
|
return readFileSync(filePath, encoding ?? 'utf-8')
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Synchronously reads a file and returns its contents as a string.
|
|
93
|
+
* added this method because AI Assistants are understandly confused by this deviation from 2000's era node style
|
|
94
|
+
* @alias readFile
|
|
95
|
+
*/
|
|
96
|
+
readFileSync(path: string, encoding?: BufferEncoding | null): string | Buffer {
|
|
97
|
+
return this.readFile(path,encoding)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
|
|
91
101
|
/**
|
|
92
102
|
* Asynchronously reads a file and returns its contents as a string.
|
|
93
103
|
*
|
|
@@ -126,6 +136,14 @@ export class FS extends Feature {
|
|
|
126
136
|
readJson(path: string) {
|
|
127
137
|
return JSON.parse(this.readFile(path) as string)
|
|
128
138
|
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Read and parse a JSON file synchronously
|
|
142
|
+
* @alias readJson
|
|
143
|
+
*/
|
|
144
|
+
readJsonSync(path: string) {
|
|
145
|
+
return this.readJson(path)
|
|
146
|
+
}
|
|
129
147
|
|
|
130
148
|
/**
|
|
131
149
|
* Asynchronously reads and parses a JSON file.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Auto-generated scaffold and MCP readme content
|
|
2
|
-
// Generated at: 2026-03-
|
|
2
|
+
// Generated at: 2026-03-22T20:57:24.026Z
|
|
3
3
|
// Source: docs/scaffolds/*.md, docs/examples/assistant/, and docs/mcp/readme.md
|
|
4
4
|
//
|
|
5
5
|
// Do not edit manually. Run: luca build-scaffolds
|
package/src/server.ts
CHANGED
|
@@ -79,6 +79,44 @@ export class Server<T extends ServerState = ServerState, K extends ServerOptions
|
|
|
79
79
|
return super.container as NodeContainer
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
+
/** Async functions passed to `.use()` before `start()` — drained in `start()`. */
|
|
83
|
+
_pendingPlugins: Promise<void>[] = []
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Register a setup function against this server. The function receives the
|
|
87
|
+
* server instance and can configure it however it likes.
|
|
88
|
+
*
|
|
89
|
+
* - If the server hasn't started yet, async return values are queued and
|
|
90
|
+
* awaited when `start()` is called.
|
|
91
|
+
* - If the server is already listening, the function is fire-and-forget.
|
|
92
|
+
* - Always returns `this` synchronously for chaining.
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```typescript
|
|
96
|
+
* server
|
|
97
|
+
* .use((s) => s.app.use(cors()))
|
|
98
|
+
* .use(async (s) => { await loadRoutes(s) })
|
|
99
|
+
* await server.start()
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
use(fn: (server: this) => void | Promise<void>): this {
|
|
103
|
+
const result = fn(this)
|
|
104
|
+
if (result && typeof (result as any).then === 'function') {
|
|
105
|
+
if (!this.isListening) {
|
|
106
|
+
this._pendingPlugins.push(result as Promise<void>)
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return this
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** Drain all pending `.use()` promises. Subclasses should call this at the top of `start()`. */
|
|
113
|
+
protected async _drainPendingPlugins() {
|
|
114
|
+
if (this._pendingPlugins.length) {
|
|
115
|
+
await Promise.all(this._pendingPlugins)
|
|
116
|
+
this._pendingPlugins = []
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
82
120
|
get isListening() {
|
|
83
121
|
return !!this.state.get('listening')
|
|
84
122
|
}
|
|
@@ -117,6 +155,8 @@ export class Server<T extends ServerState = ServerState, K extends ServerOptions
|
|
|
117
155
|
return this
|
|
118
156
|
}
|
|
119
157
|
|
|
158
|
+
await this._drainPendingPlugins()
|
|
159
|
+
|
|
120
160
|
if (options?.port) {
|
|
121
161
|
this.state.set('port', options.port)
|
|
122
162
|
}
|
package/src/servers/express.ts
CHANGED
|
@@ -104,6 +104,8 @@ export class ExpressServer<T extends ServerState = ServerState, K extends Expres
|
|
|
104
104
|
return this
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
+
await this._drainPendingPlugins()
|
|
108
|
+
|
|
107
109
|
// Apply runtime port to state so this.port reflects the override
|
|
108
110
|
if (options?.port) {
|
|
109
111
|
this.state.set('port', options.port)
|
package/src/servers/mcp.ts
CHANGED
|
@@ -472,6 +472,7 @@ export class MCPServer extends Server<MCPServerState, MCPServerOptions> {
|
|
|
472
472
|
stdioCompat?: StdioCompatMode
|
|
473
473
|
}) {
|
|
474
474
|
if (this.isListening) return this
|
|
475
|
+
await this._drainPendingPlugins()
|
|
475
476
|
if (!this.isConfigured) await this.configure()
|
|
476
477
|
|
|
477
478
|
const transport = options?.transport || this.options.transport || 'stdio'
|
package/src/servers/socket.ts
CHANGED
|
@@ -89,6 +89,8 @@ export class WebsocketServer<T extends ServerState = ServerState, K extends Sock
|
|
|
89
89
|
return this
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
+
await this._drainPendingPlugins()
|
|
93
|
+
|
|
92
94
|
// Apply runtime port to state before configure/wss touches it
|
|
93
95
|
if (options?.port) {
|
|
94
96
|
this.state.set('port', options.port)
|